@@ -13,6 +13,8 @@ import {
13
13
updateTokenfactoryParamsProposal ,
14
14
AddSchedule ,
15
15
RemoveSchedule ,
16
+ updateGlobalFeeParamsProposal ,
17
+ updateConsumerParamsProposal ,
16
18
} from '@neutron-org/neutronjsplus/dist/proposal' ;
17
19
import { LocalState } from '../../helpers/local_state' ;
18
20
import { RunnerTestSuite , inject } from 'vitest' ;
@@ -23,6 +25,9 @@ import { QueryClientImpl as AdminQueryClient } from '@neutron-org/neutronjs/cosm
23
25
import { QueryClientImpl as TokenfactoryQueryClient } from '@neutron-org/neutronjs/osmosis/tokenfactory/v1beta1/query.rpc.Query' ;
24
26
import { QueryClientImpl as UpgradeQueryClient } from '@neutron-org/neutronjs/cosmos/upgrade/v1beta1/query.rpc.Query' ;
25
27
import { QueryClientImpl as DexQueryClient } from '@neutron-org/neutronjs/neutron/dex/query.rpc.Query' ;
28
+ import { QueryClientImpl as DynamicfeesQueryClient } from '@neutron-org/neutronjs/neutron/dynamicfees/v1/query.rpc.Query' ;
29
+ import { QueryClientImpl as GlobalfeeQueryClient } from '@neutron-org/neutronjs/gaia/globalfee/v1beta1/query.rpc.Query' ;
30
+ import { QueryClientImpl as CCVQueryClient } from '@neutron-org/neutronjs/interchain_security/ccv/consumer/v1/query.rpc.Query' ;
26
31
import { SigningNeutronClient } from '../../helpers/signing_neutron_client' ;
27
32
import config from '../../config.json' ;
28
33
import { Wallet } from '../../helpers/wallet' ;
@@ -39,6 +44,9 @@ describe('Neutron / Chain Manager', () => {
39
44
let cronQuerier : CronQueryClient ;
40
45
let tokenfactoryQuerier : TokenfactoryQueryClient ;
41
46
let dexQuerier : DexQueryClient ;
47
+ let dynamicfeesQuerier : DynamicfeesQueryClient ;
48
+ let globalfeeQuerier : GlobalfeeQueryClient ;
49
+ let ccvQuerier : CCVQueryClient ;
42
50
let upgradeQuerier : UpgradeQueryClient ;
43
51
let chainManagerAddress : string ;
44
52
@@ -97,6 +105,9 @@ describe('Neutron / Chain Manager', () => {
97
105
cronQuerier = new CronQueryClient ( neutronRpcClient ) ;
98
106
dexQuerier = new DexQueryClient ( neutronRpcClient ) ;
99
107
upgradeQuerier = new UpgradeQueryClient ( neutronRpcClient ) ;
108
+ dynamicfeesQuerier = new DynamicfeesQueryClient ( neutronRpcClient ) ;
109
+ globalfeeQuerier = new GlobalfeeQueryClient ( neutronRpcClient ) ;
110
+ ccvQuerier = new CCVQueryClient ( neutronRpcClient ) ;
100
111
} ) ;
101
112
102
113
// We need to do this because the real main dao has a super long voting period.
@@ -205,6 +216,34 @@ describe('Neutron / Chain Manager', () => {
205
216
good_til_purge_allowance : true ,
206
217
} ,
207
218
} ,
219
+ {
220
+ update_ccv_params_permission : {
221
+ blocks_per_distribution_transmission : true ,
222
+ distribution_transmission_channel : true ,
223
+ provider_fee_pool_addr_str : true ,
224
+ ccv_timeout_period : true ,
225
+ transfer_timeout_period : true ,
226
+ consumer_redistribution_fraction : true ,
227
+ historical_entries : true ,
228
+ unbonding_period : true ,
229
+ soft_opt_out_threshold : true ,
230
+ reward_denoms : true ,
231
+ provider_reward_denoms : true ,
232
+ retry_delay_period : true ,
233
+ } ,
234
+ } ,
235
+ {
236
+ update_globalfee_params_permission : {
237
+ minimum_gas_prices : true ,
238
+ bypass_min_fee_msg_types : true ,
239
+ max_total_bypass_min_fee_msg_gas_usage : true ,
240
+ } ,
241
+ } ,
242
+ {
243
+ update_dynamicfees_params_permission : {
244
+ ntrn_prices : true ,
245
+ } ,
246
+ } ,
208
247
] ,
209
248
} ,
210
249
} ,
@@ -252,6 +291,7 @@ describe('Neutron / Chain Manager', () => {
252
291
} ) ;
253
292
254
293
test ( 'execute timelocked: success' , async ( ) => {
294
+ const cronParamsBefore = await cronQuerier . params ( ) ;
255
295
await waitSeconds ( 10 ) ;
256
296
257
297
await subdaoMember1 . executeTimelockedProposal ( proposalId ) ;
@@ -262,6 +302,12 @@ describe('Neutron / Chain Manager', () => {
262
302
263
303
const cronParams = await cronQuerier . params ( ) ;
264
304
expect ( cronParams . params . limit ) . toEqual ( 42n ) ;
305
+ // check that every params field before proposal execution differs from the field after proposal execution
306
+ expect (
307
+ Object . keys ( cronParamsBefore ) . every (
308
+ ( key ) => cronParamsBefore [ key ] !== cronParams [ key ] ,
309
+ ) ,
310
+ ) . toBeTrue ( ) ;
265
311
} ) ;
266
312
} ) ;
267
313
@@ -290,13 +336,13 @@ describe('Neutron / Chain Manager', () => {
290
336
const timelockedProp = await subdaoMember1 . supportAndExecuteProposal (
291
337
proposalId ,
292
338
) ;
293
-
294
339
expect ( timelockedProp . id ) . toEqual ( proposalId ) ;
295
340
expect ( timelockedProp . status ) . toEqual ( 'timelocked' ) ;
296
341
expect ( timelockedProp . msgs ) . toHaveLength ( 1 ) ;
297
342
} ) ;
298
343
299
344
test ( 'execute timelocked: success' , async ( ) => {
345
+ const tokenfactoryParamsBefore = await tokenfactoryQuerier . params ( ) ;
300
346
await waitSeconds ( 10 ) ;
301
347
302
348
await subdaoMember1 . executeTimelockedProposal ( proposalId ) ;
@@ -319,13 +365,21 @@ describe('Neutron / Chain Manager', () => {
319
365
denomCreator : 'neutron1m9l358xunhhwds0568za49mzhvuxx9ux8xafx2' ,
320
366
} ,
321
367
] ) ;
368
+ // check that every params field before proposal execution differs from the field after proposal execution
369
+ expect (
370
+ Object . keys ( tokenfactoryParamsBefore ) . every (
371
+ ( key ) => tokenfactoryParamsBefore [ key ] !== tokenfactoryParams [ key ] ,
372
+ ) ,
373
+ ) . toBeTrue ( ) ;
322
374
} ) ;
323
375
} ) ;
324
376
325
377
describe ( 'ALLOW_ONLY: change DEX parameters' , ( ) => {
326
378
let proposalId : number ;
327
379
const newParams = {
328
- fee_tiers : [ 1 , 2 , 99 ] ,
380
+ // types mixed on purpose, to check contract parser.
381
+ // Numeric types in neutron-std can be deserialized from both number and string
382
+ fee_tiers : [ '1' , '2' , 99 ] ,
329
383
paused : true ,
330
384
max_jits_per_block : 11 ,
331
385
good_til_purge_allowance : 50000 ,
@@ -349,6 +403,7 @@ describe('Neutron / Chain Manager', () => {
349
403
} ) ;
350
404
351
405
test ( 'execute timelocked: success' , async ( ) => {
406
+ const dexParamsBefore = await dexQuerier . params ( ) ;
352
407
await waitSeconds ( 10 ) ;
353
408
354
409
await subdaoMember1 . executeTimelockedProposal ( proposalId ) ;
@@ -362,6 +417,200 @@ describe('Neutron / Chain Manager', () => {
362
417
expect ( dexParams . params . paused ) . toEqual ( true ) ;
363
418
expect ( dexParams . params . maxJitsPerBlock ) . toEqual ( 11n ) ;
364
419
expect ( dexParams . params . goodTilPurgeAllowance ) . toEqual ( 50000n ) ;
420
+ // check that every params field before proposal execution differs from the field after proposal execution
421
+ expect (
422
+ Object . keys ( dexParamsBefore ) . every (
423
+ ( key ) => dexParamsBefore [ key ] !== dexParams [ key ] ,
424
+ ) ,
425
+ ) . toBeTrue ( ) ;
426
+ } ) ;
427
+ } ) ;
428
+
429
+ describe ( 'ALLOW_ONLY: change Dynamicfees parameters' , ( ) => {
430
+ let proposalId : number ;
431
+ beforeAll ( async ( ) => {
432
+ proposalId = await subdaoMember1 . submitDynamicfeesChangeParamsProposal (
433
+ chainManagerAddress ,
434
+ 'Proposal #2' ,
435
+ 'Dynamicfees update params proposal. Will pass' ,
436
+ '1000' ,
437
+ {
438
+ ntrn_prices : [ { denom : 'newdenom' , amount : '0.5' } ] ,
439
+ } ,
440
+ ) ;
441
+
442
+ const timelockedProp = await subdaoMember1 . supportAndExecuteProposal (
443
+ proposalId ,
444
+ ) ;
445
+
446
+ expect ( timelockedProp . id ) . toEqual ( proposalId ) ;
447
+ expect ( timelockedProp . status ) . toEqual ( 'timelocked' ) ;
448
+ expect ( timelockedProp . msgs ) . toHaveLength ( 1 ) ;
449
+ } ) ;
450
+
451
+ test ( 'execute timelocked: success' , async ( ) => {
452
+ const dynamicfeesParamsBefore = await dynamicfeesQuerier . params ( ) ;
453
+ await waitSeconds ( 10 ) ;
454
+
455
+ await subdaoMember1 . executeTimelockedProposal ( proposalId ) ;
456
+ const timelockedProp = await subDao . getTimelockedProposal ( proposalId ) ;
457
+ expect ( timelockedProp . id ) . toEqual ( proposalId ) ;
458
+ expect ( timelockedProp . status ) . toEqual ( 'executed' ) ;
459
+ expect ( timelockedProp . msgs ) . toHaveLength ( 1 ) ;
460
+
461
+ const dynamicfeesParams = await dynamicfeesQuerier . params ( ) ;
462
+ expect ( dynamicfeesParams . params . ntrnPrices ) . toEqual ( [
463
+ { denom : 'newdenom' , amount : '0.5' } ,
464
+ ] ) ;
465
+ // check that every params field before proposal execution differs from the field after proposal execution
466
+ expect (
467
+ Object . keys ( dynamicfeesParamsBefore ) . every (
468
+ ( key ) => dynamicfeesParamsBefore [ key ] !== dynamicfeesParams [ key ] ,
469
+ ) ,
470
+ ) . toBeTrue ( ) ;
471
+ } ) ;
472
+ } ) ;
473
+
474
+ describe ( 'ALLOW_ONLY: change Globalfee parameters' , ( ) => {
475
+ let proposalId : number ;
476
+ beforeAll ( async ( ) => {
477
+ proposalId = await subdaoMember1 . submitUpdateParamsGlobalfeeProposal (
478
+ chainManagerAddress ,
479
+ 'Proposal #3' ,
480
+ 'Globalfee update params proposal. Will pass' ,
481
+ updateGlobalFeeParamsProposal ( {
482
+ minimum_gas_prices : [ { denom : 'untrn' , amount : '0.00111' } ] ,
483
+ bypass_min_fee_msg_types : [ '/gaia.globalfee.v1beta1.MsgUpdateParams' ] ,
484
+ max_total_bypass_min_fee_msg_gas_usage : '12345' ,
485
+ } ) ,
486
+ '1000' ,
487
+ ) ;
488
+
489
+ const timelockedProp = await subdaoMember1 . supportAndExecuteProposal (
490
+ proposalId ,
491
+ ) ;
492
+
493
+ expect ( timelockedProp . id ) . toEqual ( proposalId ) ;
494
+ expect ( timelockedProp . status ) . toEqual ( 'timelocked' ) ;
495
+ expect ( timelockedProp . msgs ) . toHaveLength ( 1 ) ;
496
+ } ) ;
497
+
498
+ test ( 'execute timelocked: success' , async ( ) => {
499
+ const globalfeeParamsBefore = await globalfeeQuerier . params ( ) ;
500
+ await waitSeconds ( 10 ) ;
501
+
502
+ await subdaoMember1 . executeTimelockedProposal ( proposalId ) ;
503
+ const timelockedProp = await subDao . getTimelockedProposal ( proposalId ) ;
504
+ expect ( timelockedProp . id ) . toEqual ( proposalId ) ;
505
+ expect ( timelockedProp . status ) . toEqual ( 'executed' ) ;
506
+ expect ( timelockedProp . msgs ) . toHaveLength ( 1 ) ;
507
+
508
+ const globalfeeParams = await globalfeeQuerier . params ( ) ;
509
+ expect ( globalfeeParams . params . minimumGasPrices ) . toEqual ( [
510
+ { denom : 'untrn' , amount : '0.00111' } ,
511
+ ] ) ;
512
+ expect ( globalfeeParams . params . bypassMinFeeMsgTypes ) . toEqual ( [
513
+ '/gaia.globalfee.v1beta1.MsgUpdateParams' ,
514
+ ] ) ;
515
+ expect ( globalfeeParams . params . maxTotalBypassMinFeeMsgGasUsage ) . toEqual (
516
+ 12345n ,
517
+ ) ;
518
+ // check that every params field before proposal execution differs from the field after proposal execution
519
+ expect (
520
+ Object . keys ( globalfeeParamsBefore ) . every (
521
+ ( key ) => globalfeeParamsBefore [ key ] !== globalfeeParams [ key ] ,
522
+ ) ,
523
+ ) . toBeTrue ( ) ;
524
+ } ) ;
525
+ } ) ;
526
+
527
+ describe ( 'ALLOW_ONLY: change ccv consumer parameters' , ( ) => {
528
+ let proposalId : number ;
529
+ beforeAll ( async ( ) => {
530
+ proposalId = await subdaoMember1 . submitUpdateParamsConsumerProposal (
531
+ chainManagerAddress ,
532
+ 'Proposal #4' ,
533
+ 'Consumer update params proposal. Will pass' ,
534
+ updateConsumerParamsProposal ( {
535
+ enabled : true ,
536
+ blocks_per_distribution_transmission : 321 ,
537
+ distribution_transmission_channel : 'channel-23' ,
538
+ provider_fee_pool_addr_str : chainManagerAddress ,
539
+ ccv_timeout_period : '32s' ,
540
+ transfer_timeout_period : '23s' ,
541
+ consumer_redistribution_fraction : '0.33' ,
542
+ historical_entries : 123 ,
543
+ unbonding_period : '43s' ,
544
+ soft_opt_out_threshold : '0.55' ,
545
+ reward_denoms : [ 'tia' ] ,
546
+ provider_reward_denoms : [ 'tia' ] ,
547
+ retry_delay_period : '43s' ,
548
+ } ) ,
549
+ '1000' ,
550
+ ) ;
551
+
552
+ const timelockedProp = await subdaoMember1 . supportAndExecuteProposal (
553
+ proposalId ,
554
+ ) ;
555
+
556
+ expect ( timelockedProp . id ) . toEqual ( proposalId ) ;
557
+ expect ( timelockedProp . status ) . toEqual ( 'timelocked' ) ;
558
+ expect ( timelockedProp . msgs ) . toHaveLength ( 1 ) ;
559
+ } ) ;
560
+
561
+ test ( 'execute timelocked: success' , async ( ) => {
562
+ const ccvParamsBefore = await ccvQuerier . queryParams ( ) ;
563
+ await waitSeconds ( 10 ) ;
564
+
565
+ await subdaoMember1 . executeTimelockedProposal ( proposalId ) ;
566
+ console . log (
567
+ 'subdao' ,
568
+ subdaoMember1 . dao . contracts . proposals [ 'single' ] . pre_propose . timelock
569
+ . address ,
570
+ ) ;
571
+ const timelockedProp = await subDao . getTimelockedProposal ( proposalId ) ;
572
+ expect ( timelockedProp . id ) . toEqual ( proposalId ) ;
573
+ expect ( timelockedProp . status ) . toEqual ( 'executed' ) ;
574
+ expect ( timelockedProp . msgs ) . toHaveLength ( 1 ) ;
575
+
576
+ const ccvParams = await ccvQuerier . queryParams ( ) ;
577
+ expect ( ccvParams . params . enabled ) . toEqual ( true ) ;
578
+ expect ( ccvParams . params . blocksPerDistributionTransmission ) . toEqual ( 321n ) ;
579
+ expect ( ccvParams . params . distributionTransmissionChannel ) . toEqual (
580
+ 'channel-23' ,
581
+ ) ;
582
+ expect ( ccvParams . params . providerFeePoolAddrStr ) . toEqual (
583
+ chainManagerAddress ,
584
+ ) ;
585
+ expect ( ccvParams . params . ccvTimeoutPeriod ) . toEqual ( {
586
+ nanos : 0 ,
587
+ seconds : 32n ,
588
+ } ) ;
589
+ expect ( ccvParams . params . transferTimeoutPeriod ) . toEqual ( {
590
+ nanos : 0 ,
591
+ seconds : 23n ,
592
+ } ) ;
593
+ expect ( ccvParams . params . consumerRedistributionFraction ) . toEqual ( '0.33' ) ;
594
+ expect ( ccvParams . params . historicalEntries ) . toEqual ( 123n ) ;
595
+ expect ( ccvParams . params . unbondingPeriod ) . toEqual ( {
596
+ nanos : 0 ,
597
+ seconds : 43n ,
598
+ } ) ;
599
+ expect ( ccvParams . params . softOptOutThreshold ) . toEqual ( '0.55' ) ;
600
+ expect ( ccvParams . params . rewardDenoms ) . toEqual ( [ 'tia' ] ) ;
601
+ expect ( ccvParams . params . providerRewardDenoms ) . toEqual ( [ 'tia' ] ) ;
602
+ expect ( ccvParams . params . retryDelayPeriod ) . toEqual ( {
603
+ nanos : 0 ,
604
+ seconds : 43n ,
605
+ } ) ;
606
+ // field 'enabled' is readonly, and should not be changed, always equals true
607
+ delete ccvParamsBefore [ 'enabled' ] ;
608
+ // check that every params field before proposal execution differs from the field after proposal execution
609
+ expect (
610
+ Object . keys ( ccvParamsBefore ) . every (
611
+ ( key ) => ccvParamsBefore [ key ] !== ccvParams [ key ] ,
612
+ ) ,
613
+ ) . toBeTrue ( ) ;
365
614
} ) ;
366
615
} ) ;
367
616
0 commit comments