Skip to content

Commit 14bb47a

Browse files
committed
Add salt length check 32
1 parent 6e375af commit 14bb47a

11 files changed

Lines changed: 209 additions & 45 deletions

File tree

bindings/curse_mcms/curse_mcms/curse_mcms.go

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

bindings/mcms/mcms/mcms.go

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

contracts/mcms/curse_mcms/sources/curse_mcms.move

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,7 @@ module curse_mcms::curse_mcms {
200200
const E_UNKNOWN_CURSE_MCMS_MODULE_FUNCTION: u64 = 55;
201201
const E_UNKNOWN_CURSE_MCMS_ACCOUNT_FUNCTION: u64 = 56;
202202
const E_INVALID_PREDECESSOR_LEN: u64 = 57;
203+
const E_INVALID_SALT_LEN: u64 = 58;
203204

204205
fun init_module(publisher: &signer) {
205206
let bypasser = create_multisig(publisher, BYPASSER_ROLE);
@@ -1537,6 +1538,8 @@ module curse_mcms::curse_mcms {
15371538
calls: vector<Call>, predecessor: vector<u8>, salt: vector<u8>
15381539
): vector<u8> {
15391540
assert!(predecessor.length() == 32, E_INVALID_PREDECESSOR_LEN);
1541+
assert!(salt.length() == 32, E_INVALID_SALT_LEN);
1542+
15401543
let packed = vector[];
15411544
packed.append(bcs::to_bytes(&calls));
15421545
packed.append(predecessor);

contracts/mcms/curse_mcms/tests/curse_mcms_test.move

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -614,12 +614,32 @@ module curse_mcms::curse_mcms_test {
614614
)
615615
]
616616
fun test_hash_operation_batch__invalid_predecessor_len() {
617-
let calls = curse_mcms::create_calls(
618-
vector[@curse_mcms],
619-
vector[string::utf8(b"curse_mcms")],
620-
vector[string::utf8(b"timelock_update_min_delay")],
621-
vector[vector[0u8]]
622-
);
617+
let calls =
618+
curse_mcms::create_calls(
619+
vector[@curse_mcms],
620+
vector[string::utf8(b"curse_mcms")],
621+
vector[string::utf8(b"timelock_update_min_delay")],
622+
vector[vector[0u8]]
623+
);
623624
let _ = curse_mcms::hash_operation_batch(calls, x"deadbeef", vector[1u8]);
624625
}
626+
627+
#[test]
628+
#[
629+
expected_failure(
630+
abort_code = curse_mcms::curse_mcms::E_INVALID_SALT_LEN,
631+
location = curse_mcms::curse_mcms
632+
)
633+
]
634+
fun test_hash_operation_batch__invalid_salt_len() {
635+
let calls =
636+
curse_mcms::create_calls(
637+
vector[@curse_mcms],
638+
vector[string::utf8(b"curse_mcms")],
639+
vector[string::utf8(b"timelock_update_min_delay")],
640+
vector[vector[0u8]]
641+
);
642+
let _ =
643+
curse_mcms::hash_operation_batch(calls, curse_mcms::zero_hash(), x"deadbeef");
644+
}
625645
}

contracts/mcms/mcms/sources/mcms.move

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,7 @@ module mcms::mcms {
200200
const E_NOT_TIMELOCK_ROLE: u64 = 51;
201201
const E_UNKNOWN_MCMS_MODULE: u64 = 52;
202202
const E_INVALID_PREDECESSOR_LEN: u64 = 53;
203+
const E_INVALID_SALT_LEN: u64 = 54;
203204

204205
fun init_module(publisher: &signer) {
205206
let bypasser = create_multisig(publisher, BYPASSER_ROLE);
@@ -1616,6 +1617,8 @@ module mcms::mcms {
16161617
calls: vector<Call>, predecessor: vector<u8>, salt: vector<u8>
16171618
): vector<u8> {
16181619
assert!(predecessor.length() == 32, E_INVALID_PREDECESSOR_LEN);
1620+
assert!(salt.length() == 32, E_INVALID_SALT_LEN);
1621+
16191622
let packed = vector[];
16201623
packed.append(bcs::to_bytes(&calls));
16211624
packed.append(predecessor);

contracts/mcms/mcms/tests/mcms_executor_test.move

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,11 @@ module mcms::mcms_executor_test {
1717
const TEST_CHAIN_ID: u256 = 4;
1818
const TEST_NONCE: u64 = 0;
1919

20-
const PROPOSER_ADDR1: vector<u8> = x"5916431f0ea809587757df994233861e1271be55";
21-
const PROPOSER_ADDR2: vector<u8> = x"8803c3ed076e57d51e28301933418094bd961cc5";
22-
const PROPOSER_ADDR3: vector<u8> = x"8950e6c6832c9b0591801418684d27b2853b2c74";
20+
const PROPOSER_ADDR1: vector<u8> = x"2b5ad5c4795c026514f8317c7a215e218dccd6cf";
21+
const PROPOSER_ADDR2: vector<u8> = x"6813eb9362372eef6200f3b1dbc3f819671cba69";
22+
const PROPOSER_ADDR3: vector<u8> = x"7e5f4552091a69125d5dfcb7b8c2659029395bdf";
2323

24-
const ROOT: vector<u8> = x"f7a8b0f28b2ae826313604377ecd0dd07dd4107e0777db5d251560aa2dbf760d";
24+
const ROOT: vector<u8> = x"d65e7d9805d6a2943fd5bdaf9f14285788b8ae7fdcb6424f1b0c1fe0e63d90bc";
2525

2626
const TEST_PROOF: vector<vector<u8>> = vector[
2727
x"a619565e90c1c564293b59b344ed0e12ed06eafb3c45b70baf6fdf299a046297",

contracts/mcms/mcms/tests/mcms_test.move

Lines changed: 51 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@ module mcms::mcms_tests {
2020
use mcms::mcms_registry;
2121
use std::code::{PackageRegistry};
2222

23+
// =================== Regenerate test constants ===================
24+
// Run: go test ./relayer/txm -run TestRegenMcmsTestConstants -v
25+
2326
// keccak256("MANY_CHAIN_MULTI_SIG_DOMAIN_SEPARATOR_OP_APTOS")
2427
const MANY_CHAIN_MULTI_SIG_DOMAIN_SEPARATOR_OP: vector<u8> = x"e5a6d1256b00d7ec22512b6b60a3f4d75c559745d2dbf309f77b8b756caabe14";
2528

@@ -28,13 +31,17 @@ module mcms::mcms_tests {
2831

2932
const MIN_DELAY: u64 = 3600; // 1 hour delay
3033
const TEST_TARGET_ADDRESS: address = @0xabc;
31-
const TEST_SALT: vector<u8> = x"1234567890abcdef";
34+
const TEST_SALT: vector<u8> = x"1234567890abcdef000000000000000000000000000000000000000000000000";
35+
const SALT_ONE: vector<u8> = x"0000000000000000000000000000000000000000000000000000000000000001";
36+
const SALT_TWO: vector<u8> = x"0000000000000000000000000000000000000000000000000000000000000002";
37+
const SALT_ABCD: vector<u8> = x"abcd000000000000000000000000000000000000000000000000000000000000";
38+
const SALT_EFAB: vector<u8> = x"efab000000000000000000000000000000000000000000000000000000000000";
3239
const TEST_PREDECESSOR: vector<u8> = x"0000000000000000000000000000000000000000000000000000000000000000";
3340

3441
// Proposer signers from the logs (already in ascending order)
35-
const PROPOSER_ADDR1: vector<u8> = x"5916431f0ea809587757df994233861e1271be55";
36-
const PROPOSER_ADDR2: vector<u8> = x"8803c3ed076e57d51e28301933418094bd961cc5";
37-
const PROPOSER_ADDR3: vector<u8> = x"8950e6c6832c9b0591801418684d27b2853b2c74";
42+
const PROPOSER_ADDR1: vector<u8> = x"2b5ad5c4795c026514f8317c7a215e218dccd6cf";
43+
const PROPOSER_ADDR2: vector<u8> = x"6813eb9362372eef6200f3b1dbc3f819671cba69";
44+
const PROPOSER_ADDR3: vector<u8> = x"7e5f4552091a69125d5dfcb7b8c2659029395bdf";
3845

3946
// test config: 2-of-3 multisig
4047
const SIGNER_GROUPS: vector<u8> = vector[0, 0, 0];
@@ -45,11 +52,11 @@ module mcms::mcms_tests {
4552
const GROUP_PARENTS: vector<u8> = vector[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
4653
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
4754

48-
const ROOT: vector<u8> = x"f7a8b0f28b2ae826313604377ecd0dd07dd4107e0777db5d251560aa2dbf760d";
55+
const ROOT: vector<u8> = x"d65e7d9805d6a2943fd5bdaf9f14285788b8ae7fdcb6424f1b0c1fe0e63d90bc";
4956
const POST_OP_COUNT: u64 = 4;
5057

5158
const METADATA_PROOF: vector<vector<u8>> = vector[
52-
x"66cf50cb9a50c740313fd0f889b676af60d35ef700711d94df6eeff3f1ba66c2",
59+
x"0fff02db76d3a8c1d76a384c90404554d574239dc4e9d5c37c2b6580b6172842",
5360
x"951f1094081a858642cc6635f0885317828a7fddddd00668391c50f1e9e1bb66",
5461
x"597116801e22b18150f2abc4ca2ecd63e147bb67e24e4b5f900d49b909e1919f"
5562
];
@@ -99,7 +106,7 @@ module mcms::mcms_tests {
99106
// },
100107
const LEAVES: vector<vector<u8>> = vector[
101108
x"a619565e90c1c564293b59b344ed0e12ed06eafb3c45b70baf6fdf299a046297", // metadata hash
102-
x"66cf50cb9a50c740313fd0f889b676af60d35ef700711d94df6eeff3f1ba66c2", // op1 hash
109+
x"0fff02db76d3a8c1d76a384c90404554d574239dc4e9d5c37c2b6580b6172842", // op1 hash
103110
x"2feec0e3a232c5c847874246203e62c43db473fe85245095122e166be9114e13", // op2 hash
104111
x"411a4726f8a920fc0a814bd9897a06f3dd0f1c799a047deaa6469f105f5a6705", // op3 hash
105112
x"cb4dffef33843b197cd33346d3339d8432b14789504167c63fb9f74a73baaea5" // op4 hash
@@ -109,13 +116,13 @@ module mcms::mcms_tests {
109116
const PRE_OP_COUNT: u64 = 0;
110117

111118
const SIGNATURES: vector<vector<u8>> = vector[
112-
x"72398e2f325e707217fa8108a08c126f49f4144c30c7e93896d139c9f1d9468c30424b060c19fa5c7820a17b57badb19375207c787878533834618688a4780581c",
113-
x"9bb8ba839f9152cdc61556fcc70b0ebcb4d442654263a3d1c323e1eed85ebc6016e87c8e59f12d850b9d6b789ccafd93f19dcf65eb6fc75fd4351d5970214c1d1c",
114-
x"225739c80de11d50f3dca8fbb8288881abad17439690abd8eee32d48ff2f6dd204c48aff2fac4dfe8ce7176fd12d2633d7892bfb3d3f3cfeb00352773fe55c8c1b"
119+
x"f7fa9f145088415bad762a9b8a34e9219c5a83b5e32fbcd36d54791070b281270d55578ec3754867f6788c1bb98c34f130ad71b3619234019b75a77552e9e0581b",
120+
x"bec2d7b5640661bc84d4c70bb43b9eb3d0b9c16cc67a36429c9393c3406b137619ebcc87dcdfbfa73fa9ba79c0cd10e4add392e2160590d3d2dbbbd2fbddfae51c",
121+
x"04d0b81e83d16a344fb9736c359bdc254b9ce6db2e2185c33327b5091ff1f48d6e92b31c17271439e698ffe992c3483a1b8f44552809c0ac5abc1411ae44a77c1b"
115122
];
116123

117124
const OP1_NONCE: u64 = 0;
118-
const OP1_DATA: vector<u8> = x"01a969156fce9a4f08bcdc07b90f338efc630bff8dfa8340500cb6414aca762a4e010c6d636d735f6163636f756e7401106163636570745f6f776e6572736869700100200000000000000000000000000000000000000000000000000000000000000000000000000000000000";
125+
const OP1_DATA: vector<u8> = x"01a969156fce9a4f08bcdc07b90f338efc630bff8dfa8340500cb6414aca762a4e010c6d636d735f6163636f756e7401106163636570745f6f776e65727368697001002000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000100000000000000";
119126

120127
#[test_only]
121128
fun setup(deployer: &signer, owner: &signer, framework: &signer): address {
@@ -236,7 +243,7 @@ module mcms::mcms_tests {
236243
vector[string::utf8(b"accept_ownership")],
237244
vector[vector[]],
238245
mcms::zero_hash(),
239-
vector[]
246+
mcms::zero_hash()
240247
);
241248

242249
// Verify new owner is now `@mcms`
@@ -1432,6 +1439,19 @@ module mcms::mcms_tests {
14321439
let _ = mcms::hash_operation_batch(calls, x"deadbeef", TEST_SALT);
14331440
}
14341441

1442+
#[test]
1443+
#[expected_failure(abort_code = mcms::mcms::E_INVALID_SALT_LEN, location = mcms::mcms)]
1444+
public fun test_hash_operation_batch__invalid_salt_len() {
1445+
let calls =
1446+
mcms::create_calls(
1447+
vector[@mcms],
1448+
vector[string::utf8(b"mcms")],
1449+
vector[string::utf8(b"timelock_update_min_delay")],
1450+
vector[bcs::to_bytes(&MIN_DELAY)]
1451+
);
1452+
let _ = mcms::hash_operation_batch(calls, TEST_PREDECESSOR, x"deadbeef");
1453+
}
1454+
14351455
#[test(deployer = @mcms, owner = @mcms_owner, framework = @aptos_framework)]
14361456
public fun test_update_min_delay(
14371457
deployer: &signer, owner: &signer, framework: &signer
@@ -1585,7 +1605,7 @@ module mcms::mcms_tests {
15851605
vector[string::utf8(b"test_function")],
15861606
vector[vector[0u8]],
15871607
mcms::zero_hash(),
1588-
vector[],
1608+
mcms::zero_hash(),
15891609
0
15901610
);
15911611
}
@@ -1607,7 +1627,7 @@ module mcms::mcms_tests {
16071627
vector[string::utf8(b"test_function")],
16081628
vector[vector[0u8]],
16091629
mcms::zero_hash(),
1610-
vector[1u8],
1630+
SALT_ONE,
16111631
MIN_DELAY - 1
16121632
);
16131633
}
@@ -1628,7 +1648,7 @@ module mcms::mcms_tests {
16281648
let function_names = vector[string::utf8(b"test_function")];
16291649
let datas = vector[vector[0u8]];
16301650
let predecessor = mcms::zero_hash();
1631-
let salt = vector[1u8];
1651+
let salt = SALT_ONE;
16321652

16331653
mcms::test_timelock_schedule_batch(
16341654
targets,
@@ -1671,7 +1691,7 @@ module mcms::mcms_tests {
16711691
vector[string::utf8(b"test_function")],
16721692
vector[vector[0u8]],
16731693
mcms::zero_hash(),
1674-
vector[],
1694+
mcms::zero_hash(),
16751695
0
16761696
);
16771697
}
@@ -1688,7 +1708,7 @@ module mcms::mcms_tests {
16881708
let function_names = vector[string::utf8(b"test_function")];
16891709
let datas = vector[vector[0u8]];
16901710
let predecessor = mcms::zero_hash();
1691-
let salt = vector[1u8];
1711+
let salt = SALT_ONE;
16921712

16931713
let delay = 100000;
16941714
mcms::test_timelock_update_min_delay(delay);
@@ -1783,7 +1803,7 @@ module mcms::mcms_tests {
17831803
let function_names1 = vector[string::utf8(b"test_function1")];
17841804
let datas1 = vector[vector[0u8]];
17851805
let predecessor1 = mcms::zero_hash();
1786-
let salt1 = vector[1u8];
1806+
let salt1 = SALT_ONE;
17871807

17881808
// First, schedule the first batch
17891809
mcms::test_timelock_schedule_batch(
@@ -1797,7 +1817,7 @@ module mcms::mcms_tests {
17971817
);
17981818

17991819
// Generate a unique identifier for the second batch
1800-
let salt2 = vector[2u8];
1820+
let salt2 = SALT_TWO;
18011821
let predecessor2 =
18021822
x"deadbeef00000000000000000000000000000000000000000000000000000000"; // Non-existent operation ID
18031823

@@ -1845,7 +1865,7 @@ module mcms::mcms_tests {
18451865
let function_names = vector[string::utf8(b"nonexistent_function")];
18461866
let datas = vector[vector[0u8]];
18471867
let predecessor = mcms::zero_hash();
1848-
let salt = vector[1u8];
1868+
let salt = SALT_ONE;
18491869

18501870
// Schedule the batch with the non-existent function
18511871
mcms::test_timelock_schedule_batch(
@@ -1885,7 +1905,7 @@ module mcms::mcms_tests {
18851905
let function_names = vector[string::utf8(b"timelock_update_min_delay")];
18861906
let datas = vector[bcs::to_bytes(&MIN_DELAY)];
18871907
let predecessor = mcms::zero_hash();
1888-
let salt = vector[1u8];
1908+
let salt = SALT_ONE;
18891909

18901910
// Try to execute without scheduling first - should fail with E_OPERATION_NOT_READY
18911911
mcms::timelock_execute_batch(
@@ -1913,7 +1933,7 @@ module mcms::mcms_tests {
19131933
let data = bcs::to_bytes(&MIN_DELAY);
19141934
let datas = vector[data];
19151935
let predecessor = mcms::zero_hash();
1916-
let salt = vector[1u8];
1936+
let salt = SALT_ONE;
19171937

19181938
mcms::test_timelock_schedule_batch(
19191939
targets,
@@ -1993,7 +2013,7 @@ module mcms::mcms_tests {
19932013
let data = bcs::to_bytes(&MIN_DELAY);
19942014
let datas_1 = vector[data];
19952015
let predecessor_1 = mcms::zero_hash();
1996-
let salt_1 = x"abcd";
2016+
let salt_1 = SALT_ABCD;
19972017
let delay = 1; // Small delay for testing
19982018

19992019
mcms::test_timelock_schedule_batch(
@@ -2024,7 +2044,7 @@ module mcms::mcms_tests {
20242044
let data = bcs::to_bytes(&new_delay);
20252045
let datas_2 = vector[data];
20262046
let predecessor_2 = id_1; // Use first operation as predecessor
2027-
let salt_2 = x"efab";
2047+
let salt_2 = SALT_EFAB;
20282048

20292049
mcms::test_timelock_schedule_batch(
20302050
targets_2,
@@ -2105,7 +2125,7 @@ module mcms::mcms_tests {
21052125
let function_names = vector[string::utf8(b"timelock_update_min_delay")];
21062126
let datas = vector[bcs::to_bytes(&MIN_DELAY)];
21072127
let predecessor = mcms::zero_hash();
2108-
let salt = vector[1u8];
2128+
let salt = SALT_ONE;
21092129

21102130
mcms::test_timelock_schedule_batch(
21112131
targets,
@@ -2290,7 +2310,7 @@ module mcms::mcms_tests {
22902310
let data = bcs::to_bytes(&MIN_DELAY);
22912311
let datas = vector[data];
22922312
let predecessor = mcms::zero_hash();
2293-
let salt = vector[1u8];
2313+
let salt = SALT_ONE;
22942314
// Use a delay that is greater than the min_delay to avoid E_INSUFFICIENT_DELAY error
22952315
let delay = 100;
22962316

@@ -2394,7 +2414,7 @@ module mcms::mcms_tests {
23942414
let function_names = vector[string::utf8(b"set_config")];
23952415
let datas = vector[data];
23962416
let predecessor = mcms::zero_hash();
2397-
let salt = vector[1u8];
2417+
let salt = SALT_ONE;
23982418
let delay = 1;
23992419

24002420
dispatch_timelock_schedule_batch(
@@ -2438,7 +2458,7 @@ module mcms::mcms_tests {
24382458

24392459
// test_timelock_cancel
24402460
// First schedule the operation for `set_config`
2441-
let salt = vector[2u8];
2461+
let salt = SALT_TWO;
24422462
dispatch_timelock_schedule_batch(
24432463
targets,
24442464
module_names,
@@ -2465,7 +2485,7 @@ module mcms::mcms_tests {
24652485
vector[string::utf8(b"timelock_update_min_delay")],
24662486
vector[bcs::to_bytes(&100)],
24672487
mcms::zero_hash(), // predecessor
2468-
vector[1u8], // salt
2488+
SALT_ONE, // salt
24692489
delay // delay
24702490
);
24712491
let new_delay = 2;
@@ -2485,7 +2505,7 @@ module mcms::mcms_tests {
24852505
vector[string::utf8(b"timelock_block_function")],
24862506
vector[data],
24872507
mcms::zero_hash(), // predecessor
2488-
vector[1u8], // salt
2508+
SALT_ONE, // salt
24892509
new_delay // delay
24902510
);
24912511
mcms::test_timelock_dispatch(
@@ -2501,7 +2521,7 @@ module mcms::mcms_tests {
25012521
vector[string::utf8(b"timelock_unblock_function")],
25022522
vector[data],
25032523
mcms::zero_hash(), // predecessor
2504-
vector[1u8], // salt
2524+
SALT_ONE, // salt
25052525
new_delay // delay
25062526
);
25072527
mcms::test_timelock_dispatch(

relayer/txm/common.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -757,6 +757,13 @@ func ScheduleBatchOperationsAsDeployer(
757757
}
758758

759759
func HashOperationBatch(targets []aptos.AccountAddress, moduleNames, functionNames []string, datas [][]byte, predecessor, salt []byte) (common.Hash, error) {
760+
if len(predecessor) != 32 {
761+
return common.Hash{}, fmt.Errorf("predecessor must be 32 bytes, got %d", len(predecessor))
762+
}
763+
if len(salt) != 32 {
764+
return common.Hash{}, fmt.Errorf("salt must be 32 bytes, got %d", len(salt))
765+
}
766+
760767
// Verify all arrays have the same length
761768
if len(targets) != len(moduleNames) || len(targets) != len(functionNames) || len(targets) != len(datas) {
762769
return common.Hash{}, fmt.Errorf("mismatched array lengths: targets=%d, moduleNames=%d, functionNames=%d, datas=%d",

0 commit comments

Comments
 (0)