@@ -31,45 +31,25 @@ func TestUpfConvertTimelockProposal(t *testing.T) {
3131 t .Parallel ()
3232 ds := datastore .NewMemoryDataStore ()
3333
34- mustAdd := func (chain uint64 , addr , typeAndVersion string ) {
35- tv := deployment .MustTypeAndVersionFromString (typeAndVersion )
36- storeAddr := addr
37- if strings .HasPrefix (addr , "0x" ) {
38- storeAddr = addr
39- }
40- ref := datastore.AddressRef {
41- ChainSelector : chain ,
42- Address : storeAddr ,
43- Type : datastore .ContractType (tv .Type ),
44- Version : & tv .Version ,
45- // Use address+type as a unique Qualifier (avoids clashes)
46- Qualifier : fmt .Sprintf ("%s-%s" , addr , tv .Type ),
47- }
48- if ! tv .Labels .IsEmpty () {
49- ref .Labels = datastore .NewLabelSet (tv .Labels .List ()... )
50- }
51- require .NoError (t , ds .Addresses ().Add (ref ))
52- }
53-
5434 // ---- EVM: ethereum-testnet-sepolia-base-1
55- mustAdd ( 10344971235874465080 , "0x5f077BCeE6e285154473F65699d6F46Fd03D105A" , "RBACTimelock 1.0.0" )
56- mustAdd ( 10344971235874465080 , "0xA5D5B0B844c8f11B61F28AC98BBA84dEA9b80953" , "ProposerManyChainMultisig 1.0.0" )
57- mustAdd ( 10344971235874465080 , "0x76B12C4f3672aA613F1b2302327827B7B74064E1" , "RMNRemote 1.6.0" )
35+ dsAddContract ( t , ds , 10344971235874465080 , "0x5f077BCeE6e285154473F65699d6F46Fd03D105A" , "RBACTimelock 1.0.0" )
36+ dsAddContract ( t , ds , 10344971235874465080 , "0xA5D5B0B844c8f11B61F28AC98BBA84dEA9b80953" , "ProposerManyChainMultisig 1.0.0" )
37+ dsAddContract ( t , ds , 10344971235874465080 , "0x76B12C4f3672aA613F1b2302327827B7B74064E1" , "RMNRemote 1.6.0" )
5838
5939 // ---- EVM: bsc-testnet
60- mustAdd ( 13264668187771770619 , "0x804759c9bdd258A810987FDe21c9E24C5383b722" , "RBACTimelock 1.0.0" )
61- mustAdd ( 13264668187771770619 , "0x9A60462e4CA802E3E945663930Be0d162e662091" , "ProposerManyChainMultisig 1.0.0" )
62- mustAdd ( 13264668187771770619 , "0x76B12C4f3672aA613F1b2302327827B7B74064E1" , "RMNRemote 1.6.0" )
40+ dsAddContract ( t , ds , 13264668187771770619 , "0x804759c9bdd258A810987FDe21c9E24C5383b722" , "RBACTimelock 1.0.0" )
41+ dsAddContract ( t , ds , 13264668187771770619 , "0x9A60462e4CA802E3E945663930Be0d162e662091" , "ProposerManyChainMultisig 1.0.0" )
42+ dsAddContract ( t , ds , 13264668187771770619 , "0x76B12C4f3672aA613F1b2302327827B7B74064E1" , "RMNRemote 1.6.0" )
6343
6444 // ---- Solana: devnet
65- mustAdd ( 16423721717087811551 , "5vNJx78mz7KVMjhuipyr9jKBKcMrKYGdjGkgE4LUmjKk" , "ManyChainMultiSigProgram 1.0.0" )
66- mustAdd ( 16423721717087811551 , "5vNJx78mz7KVMjhuipyr9jKBKcMrKYGdjGkgE4LUmjKk.ID6xwqkfFkH6dx2LF0O2NKfHKwHywEB0" , "ProposerManyChainMultiSig 1.0.0" )
67- mustAdd ( 16423721717087811551 , "DoajfR5tK24xVw51fWcawUZWhAXD8yrBJVacc13neVQA" , "RBACTimelockProgram 1.0.0" )
68- mustAdd ( 16423721717087811551 , "DoajfR5tK24xVw51fWcawUZWhAXD8yrBJVacc13neVQA.E4R6Nwg1K8Zvi6McLdkaGDD5ClX1KkyV" , "RBACTimelock 1.0.0" )
69- mustAdd ( 16423721717087811551 , "FTDusxFg9NmmFGRg5jfA9nHCiCpZ7dJktawfRBcUBhq" , "ProposerAccessControllerAccount 1.0.0" )
70- mustAdd ( 16423721717087811551 , "2hABoxD9U5A4j4x3kNDf4dBJ7ZP384Zbs3TuFn9QUTSs" , "CancellerAccessControllerAccount 1.0.0" )
71- mustAdd ( 16423721717087811551 , "68ds9kDfB6rJfC4zzeeQ8E9ZMwqSzFQEie1886VAPn68" , "BypasserAccessControllerAccount 1.0.0" )
72- mustAdd ( 16423721717087811551 , "RmnXLft1mSEwDgMKu2okYuHkiazxntFFcZFrrcXxYg7" , "RMNRemote 1.0.0" )
45+ dsAddContract ( t , ds , 16423721717087811551 , "5vNJx78mz7KVMjhuipyr9jKBKcMrKYGdjGkgE4LUmjKk" , "ManyChainMultiSigProgram 1.0.0" )
46+ dsAddContract ( t , ds , 16423721717087811551 , "5vNJx78mz7KVMjhuipyr9jKBKcMrKYGdjGkgE4LUmjKk.ID6xwqkfFkH6dx2LF0O2NKfHKwHywEB0" , "ProposerManyChainMultiSig 1.0.0" )
47+ dsAddContract ( t , ds , 16423721717087811551 , "DoajfR5tK24xVw51fWcawUZWhAXD8yrBJVacc13neVQA" , "RBACTimelockProgram 1.0.0" )
48+ dsAddContract ( t , ds , 16423721717087811551 , "DoajfR5tK24xVw51fWcawUZWhAXD8yrBJVacc13neVQA.E4R6Nwg1K8Zvi6McLdkaGDD5ClX1KkyV" , "RBACTimelock 1.0.0" )
49+ dsAddContract ( t , ds , 16423721717087811551 , "FTDusxFg9NmmFGRg5jfA9nHCiCpZ7dJktawfRBcUBhq" , "ProposerAccessControllerAccount 1.0.0" )
50+ dsAddContract ( t , ds , 16423721717087811551 , "2hABoxD9U5A4j4x3kNDf4dBJ7ZP384Zbs3TuFn9QUTSs" , "CancellerAccessControllerAccount 1.0.0" )
51+ dsAddContract ( t , ds , 16423721717087811551 , "68ds9kDfB6rJfC4zzeeQ8E9ZMwqSzFQEie1886VAPn68" , "BypasserAccessControllerAccount 1.0.0" )
52+ dsAddContract ( t , ds , 16423721717087811551 , "RmnXLft1mSEwDgMKu2okYuHkiazxntFFcZFrrcXxYg7" , "RMNRemote 1.0.0" )
7353
7454 env := deployment.Environment {
7555 DataStore : ds .Seal (),
@@ -280,7 +260,7 @@ transactions:
280260 to: "0x5f077BCeE6e285154473F65699d6F46Fd03D105A"
281261 value: 0
282262 data: "0xa944142d00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000773593ff00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000012c0000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002000000000000000000000000076b12c4f3672aa613f1b2302327827b7b74064e1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000064f8bb876e000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000010000000000000000b8159170038f96fb0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
283- txNonce: 2
263+ txNonce: 1
284264 metadata:
285265 contractType: RBACTimelock
286266 decodedCalldata:
@@ -307,7 +287,7 @@ transactions:
307287 to: "0x804759c9bdd258A810987FDe21c9E24C5383b722"
308288 value: 0
309289 data: "0xa944142d00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000773593ff00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000012c0000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002000000000000000000000000076b12c4f3672aa613f1b2302327827b7b74064e1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000064f8bb876e0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000100000000000000008f90b8876dee65380000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
310- txNonce: 3
290+ txNonce: 2
311291 metadata:
312292 contractType: RBACTimelock
313293 decodedCalldata:
@@ -334,7 +314,7 @@ transactions:
334314 to: DoajfR5tK24xVw51fWcawUZWhAXD8yrBJVacc13neVQA
335315 value: 0
336316 data: D2DZq3wEcfNFNFI2TndnMUs4WnZpNk1jTGRrYUdERDVDbFgxS2t5VpAXlZ2LYPhZ+p8F9JucBPQaESwj/lQ3CwCjnNzLdfsEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB3NZP/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAA=
337- txNonce: 4
317+ txNonce: 3
338318 metadata:
339319 contractType: RBACTimelock
340320 decodedCalldata:
@@ -361,7 +341,7 @@ transactions:
361341 to: DoajfR5tK24xVw51fWcawUZWhAXD8yrBJVacc13neVQA
362342 value: 0
363343 data: w+bVh5CUjlVFNFI2TndnMUs4WnZpNk1jTGRrYUdERDVDbFgxS2t5VpAXlZ2LYPhZ+p8F9JucBPQaESwj/lQ3CwCjnNzLdfsEBliT7ZWrhugwWyiYp2G+HCHNv7C39ebv1T6DsoMrGlAEAAAA569Vk65pFF7HVjX5akNsLQQfz9+AaloAzqNrzzoGc1AAAB74fnS+SLFE6OvgAxbo+S+KqA2nm/gNrv6H0f98BW1YAAGvogYtczqE0C5vP92khgtsL3GSUtW9S5XWTvA81tlPygABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==
364- txNonce: 5
344+ txNonce: 4
365345 metadata:
366346 contractType: RBACTimelock
367347 decodedCalldata:
@@ -394,7 +374,7 @@ transactions:
394374 to: DoajfR5tK24xVw51fWcawUZWhAXD8yrBJVacc13neVQA
395375 value: 0
396376 data: TE1mg4gMLQVFNFI2TndnMUs4WnZpNk1jTGRrYUdERDVDbFgxS2t5VpAXlZ2LYPhZ+p8F9JucBPQaESwj/lQ3CwCjnNzLdfsEAAAAABgAAAAKf+LjigPASfuWjwNwkRW4AAAAAAAAAAA=
397- txNonce: 6
377+ txNonce: 5
398378 metadata:
399379 contractType: RBACTimelock
400380 decodedCalldata:
@@ -420,7 +400,7 @@ transactions:
420400 to: DoajfR5tK24xVw51fWcawUZWhAXD8yrBJVacc13neVQA
421401 value: 0
422402 data: P9AgYlW27IxFNFI2TndnMUs4WnZpNk1jTGRrYUdERDVDbFgxS2t5VpAXlZ2LYPhZ+p8F9JucBPQaESwj/lQ3CwCjnNzLdfsE
423- txNonce: 7
403+ txNonce: 6
424404 metadata:
425405 contractType: RBACTimelock
426406 decodedCalldata:
@@ -443,7 +423,7 @@ transactions:
443423 to: DoajfR5tK24xVw51fWcawUZWhAXD8yrBJVacc13neVQA
444424 value: 0
445425 data: 8oxXakfiViBFNFI2TndnMUs4WnZpNk1jTGRrYUdERDVDbFgxS2t5VpAXlZ2LYPhZ+p8F9JucBPQaESwj/lQ3CwCjnNzLdfsELAEAAAAAAAA=
446- txNonce: 8
426+ txNonce: 7
447427 metadata:
448428 contractType: RBACTimelock
449429 decodedCalldata:
@@ -516,6 +496,36 @@ var timelockProposalSui = `{
516496 ]
517497}`
518498
499+ var upfProposalSui = `---
500+ msigType: mcms
501+ proposalHash: "0x1c733d9d09e9d41e1651596078df88b00c68e085cc6bf14b8f346866b1741a28"
502+ mcmsParams:
503+ validUntil: 1999999999
504+ merkleRoot: "0xeeaa854482fdd28dec1ca358c4ba9c7399560b580683c7fa372e9a69eab8ba1d"
505+ asciiProposalHash: '\x93>\x07\xb8>\xce3\xfa\xa7\xccZ\x1e\xea\xf8|\xb39\x9c\x10s\xd7\x98\xc8\xa6\x1d\xe13\x99\xa1u\xe2.'
506+ overridePreviousRoot: false
507+ transactions:
508+ - index: 0
509+ chainFamily: sui
510+ chainId: "2"
511+ chainName: sui-testnet
512+ chainShortName: sui-testnet
513+ msigAddress: "0x4e825a4758064df713762e431c3a16b8105857195214469db0d6985b7d70266d"
514+ timelockAddress: "0x4e825a4758064df713762e431c3a16b8105857195214469db0d6985b7d70266d"
515+ to: ""
516+ value: 0
517+ data: AU6CWkdYBk33E3YuQxw6FrgQWFcZUhRGnbDWmFt9cCZtAQltY21zX3VzZXIBDGZ1bmN0aW9uX29uZQFYi8WcKEL0NsEiFpGjWdxClBwfJeyhP0ut55f7Dg2PS2W5dbWeXl19LUYyEaeuZRHbtJS9IbqY1GNZHOkUhofVcGRhdGVkIEZpZWxkIEEKAQIDBAUGBwgJCiAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACB3NZP/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACwBAAAAAAAA
518+ txNonce: 1
519+ metadata:
520+ contractType: MCMS
521+ decodedCalldata:
522+ functionName: "failed to decode Sui transaction: could not find function in contractInterfaces for mcms::timelock_schedule_batch"
523+ functionArgs: {}
524+ signers:
525+ "9762610643973837292":
526+ - "0xA5D5B0B844c8f11B61F28AC98BBA84dEA9b80953"
527+ `
528+
519529var timelockProposalSuiUnknownModule = `{
520530 "version": "v1",
521531 "kind": "TimelockProposal",
@@ -531,7 +541,7 @@ var timelockProposalSuiUnknownModule = `{
531541 },
532542 "description": "Sui proposal with unknown module",
533543 "action": "schedule",
534- "delay": "5m0s",
544+ "delay": "5m0s",
535545 "timelockAddresses": {
536546 "9762610643973837292": "0x4e825a4758064df713762e431c3a16b8105857195214469db0d6985b7d70266d"
537547 },
@@ -555,32 +565,42 @@ var timelockProposalSuiUnknownModule = `{
555565 ]
556566}`
557567
568+ var upfProposalSuiUnknownModule = `---
569+ msigType: mcms
570+ proposalHash: "0x5433c70ce0b94602235ae03d5485a3ff991b90d35b90f3474af5455f1105c198"
571+ mcmsParams:
572+ validUntil: 1999999999
573+ merkleRoot: "0x0104cddb47805604d82eeab0e02cb33c4374c1e635ab038d2a1ed9038c48e4a9"
574+ asciiProposalHash: 'L\xb9E\x9d\xfeMY\x83\xec3\xba\x00\xa6F0@\x82 \xd4\xc0\x9bj-"C\xcb\xf6\xb6v\xc0B\xbc'
575+ overridePreviousRoot: false
576+ transactions:
577+ - index: 0
578+ chainFamily: sui
579+ chainId: "2"
580+ chainName: sui-testnet
581+ chainShortName: sui-testnet
582+ msigAddress: "0x4e825a4758064df713762e431c3a16b8105857195214469db0d6985b7d70266d"
583+ timelockAddress: "0x4e825a4758064df713762e431c3a16b8105857195214469db0d6985b7d70266d"
584+ to: ""
585+ value: 0
586+ data: AU6CWkdYBk33E3YuQxw6FrgQWFcZUhRGnbDWmFt9cCZtAQ51bmtub3duX21vZHVsZQENc29tZV9mdW5jdGlvbgEJc29tZSBkYXRhIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIHc1k/8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALAEAAAAAAAA=
587+ txNonce: 1
588+ metadata:
589+ contractType: MCMS
590+ decodedCalldata:
591+ functionName: "failed to decode Sui transaction: could not find function in contractInterfaces for mcms::timelock_schedule_batch"
592+ functionArgs: {}
593+ signers:
594+ "9762610643973837292":
595+ - "0xA5D5B0B844c8f11B61F28AC98BBA84dEA9b80953"
596+ `
597+
558598func TestUpfConvertTimelockProposalWithSui (t * testing.T ) {
559599 t .Parallel ()
560600 ds := datastore .NewMemoryDataStore ()
561601
562- mustAdd := func (chain uint64 , addr , typeAndVersion string ) {
563- tv := deployment .MustTypeAndVersionFromString (typeAndVersion )
564- storeAddr := addr
565- if strings .HasPrefix (addr , "0x" ) {
566- storeAddr = addr
567- }
568- ref := datastore.AddressRef {
569- ChainSelector : chain ,
570- Address : storeAddr ,
571- Type : datastore .ContractType (tv .Type ),
572- Version : & tv .Version ,
573- // Use address+type as a unique Qualifier (avoids clashes)
574- Qualifier : fmt .Sprintf ("%s-%s" , addr , tv .Type ),
575- }
576- if ! tv .Labels .IsEmpty () {
577- ref .Labels = datastore .NewLabelSet (tv .Labels .List ()... )
578- }
579- require .NoError (t , ds .Addresses ().Add (ref ))
580- }
581-
582602 // ---- Sui: testnet
583- mustAdd ( chainsel .SUI_TESTNET .Selector , "0x4e825a4758064df713762e431c3a16b8105857195214469db0d6985b7d70266d" , "MCMSUser 1.0.0" )
603+ dsAddContract ( t , ds , chainsel .SUI_TESTNET .Selector , "0x4e825a4758064df713762e431c3a16b8105857195214469db0d6985b7d70266d" , "MCMSUser 1.0.0" )
584604
585605 env := deployment.Environment {
586606 DataStore : ds .Seal (),
@@ -594,18 +614,21 @@ func TestUpfConvertTimelockProposalWithSui(t *testing.T) {
594614 name string
595615 timelockProposal string
596616 signers map [mcmstypes.ChainSelector ][]common.Address
597- want string
598- wantErr string
617+ assertion func (* testing.T , string , error )
599618 }{
600619 {
601620 name : "Sui proposal with valid transaction" ,
602621 timelockProposal : timelockProposalSui ,
603- want : "" , // We'll just verify it doesn't error and contains expected content
604622 signers : map [mcmstypes.ChainSelector ][]common.Address {
605623 mcmstypes .ChainSelector (chainsel .SUI_TESTNET .Selector ): {
606624 common .HexToAddress ("0xA5D5B0B844c8f11B61F28AC98BBA84dEA9b80953" ),
607625 },
608626 },
627+ assertion : func (t * testing.T , gotUpf string , err error ) {
628+ t .Helper ()
629+ require .NoError (t , err )
630+ require .Equal (t , upfProposalSui , gotUpf )
631+ },
609632 },
610633 {
611634 name : "Sui proposal with unknown module" ,
@@ -615,7 +638,11 @@ func TestUpfConvertTimelockProposalWithSui(t *testing.T) {
615638 common .HexToAddress ("0xA5D5B0B844c8f11B61F28AC98BBA84dEA9b80953" ),
616639 },
617640 },
618- wantErr : "" , // Should not error but will have error message in function name
641+ assertion : func (t * testing.T , gotUpf string , err error ) {
642+ t .Helper ()
643+ require .NoError (t , err )
644+ require .Equal (t , upfProposalSuiUnknownModule , gotUpf )
645+ },
619646 },
620647 }
621648
@@ -629,25 +656,32 @@ func TestUpfConvertTimelockProposalWithSui(t *testing.T) {
629656
630657 got , err := UpfConvertTimelockProposal (proposalCtx , timelockProposal , mcmProposal , tt .signers )
631658
632- if tt .wantErr != "" {
633- require .ErrorContains (t , err , tt .wantErr )
634- return
635- }
636-
637- require .NoError (t , err )
638- if tt .want != "" {
639- require .Empty (t , cmp .Diff (tt .want , got ))
640- } else {
641- // For test cases without specific expected output, just verify it contains expected content
642- switch tt .name {
643- case "Sui proposal with valid transaction" :
644- require .Contains (t , got , "chainFamily: sui" )
645- require .Contains (t , got , "chainName: sui-testnet" )
646- case "Sui proposal with unknown module" :
647- // This should contain some error indication
648- require .Contains (t , got , "failed to decode Sui transaction" )
649- }
650- }
659+ tt .assertion (t , got , err )
651660 })
652661 }
653662}
663+
664+ // ----- helpers -----
665+
666+ func dsAddContract (t * testing.T , ds datastore.MutableDataStore , chain uint64 , addr , typeAndVersion string ) {
667+ t .Helper ()
668+
669+ tv := deployment .MustTypeAndVersionFromString (typeAndVersion )
670+ storeAddr := addr
671+ if strings .HasPrefix (addr , "0x" ) {
672+ storeAddr = addr
673+ }
674+ ref := datastore.AddressRef {
675+ ChainSelector : chain ,
676+ Address : storeAddr ,
677+ Type : datastore .ContractType (tv .Type ),
678+ Version : & tv .Version ,
679+ // Use address+type as a unique Qualifier (avoids clashes)
680+ Qualifier : fmt .Sprintf ("%s-%s" , addr , tv .Type ),
681+ }
682+ if ! tv .Labels .IsEmpty () {
683+ ref .Labels = datastore .NewLabelSet (tv .Labels .List ()... )
684+ }
685+
686+ require .NoError (t , ds .Addresses ().Add (ref ))
687+ }
0 commit comments