Skip to content

Commit ea64172

Browse files
committed
Fix incorrect SSZ merkelisation in beacon state verifier
1 parent ac5c329 commit ea64172

File tree

3 files changed

+121
-63
lines changed

3 files changed

+121
-63
lines changed

contracts/contract/util/BeaconStateVerifier.sol

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ contract BeaconStateVerifier is RocketBase, BeaconStateVerifierInterface {
1818
function verifyValidator(ValidatorProof calldata _proof) override external view returns(bool) {
1919
// TODO: Extract this out into a parameterised system for updating the gindices alongside hardforks
2020
SSZ.Path memory path = SSZ.from(3, 3); // 0b011 (BeaconBlockHeader -> state_root)
21-
path = SSZ.concat(path, SSZ.from(11, 5)); // 0b01011 (BeaconState -> validators)
21+
path = SSZ.concat(path, SSZ.from(11, 6)); // 0b001011 (BeaconState -> validators)
2222
path = SSZ.concat(path, SSZ.intoVector(_proof.validatorIndex, 40)); // validators -> validators[n]
2323
path = SSZ.concat(path, SSZ.from(0, 2)); // 0b00 (Validator -> pubkey/withdrawal_credentials)
2424
// Compute the withdrawal credential / pubkey branch root
@@ -34,7 +34,7 @@ contract BeaconStateVerifier is RocketBase, BeaconStateVerifierInterface {
3434
function verifyExit(uint256 _validatorIndex, uint256 _withdrawableEpoch, uint64 _slot, bytes32[] calldata _proof) override external view returns(bool) {
3535
// TODO: Extract this out into a parameterised system for updating the gindices alongside hardforks
3636
SSZ.Path memory path = SSZ.from(3, 3); // 0b011 (BeaconBlockHeader -> state_root)
37-
path = SSZ.concat(path, SSZ.from(11, 5)); // 0b01011 (BeaconState -> validators)
37+
path = SSZ.concat(path, SSZ.from(11, 6)); // 0b001011 (BeaconState -> validators)
3838
path = SSZ.concat(path, SSZ.intoVector(_validatorIndex, 40)); // validators -> validators[n]
3939
path = SSZ.concat(path, SSZ.from(7, 3)); // 0b111 (Validator -> withdrawable_epoch)
4040
// Compute the withdrawable epoch leaf
@@ -51,17 +51,17 @@ contract BeaconStateVerifier is RocketBase, BeaconStateVerifierInterface {
5151
// TODO: Extract this out into a parameterised system for updating the gindices alongside hardforks
5252
SSZ.Path memory path = SSZ.from(3, 3); // 0b011 (BeaconBlockHeader -> state_root)
5353
if (isHistorical) {
54-
path = SSZ.concat(path, SSZ.from(27, 5)); // 0b01011 (BeaconState -> historical_summaries)
54+
path = SSZ.concat(path, SSZ.from(27, 6)); // 0b001011 (BeaconState -> historical_summaries)
5555
path = SSZ.concat(path, SSZ.intoVector(uint256(_withdrawalSlot) / SLOTS_PER_HISTORICAL_ROOT, 24)); // historical_summaries -> historical_summaries[n]
5656
path = SSZ.concat(path, SSZ.from(0, 1)); // 0b0 (HistoricalSummary -> block_summary_root)
5757
} else {
58-
path = SSZ.concat(path, SSZ.from(5, 5)); // 0b00101 (BeaconState -> block_roots)
58+
path = SSZ.concat(path, SSZ.from(5, 6)); // 0b000101 (BeaconState -> block_roots)
5959
}
60-
path = SSZ.concat(path, SSZ.intoVector(uint256(_withdrawalSlot) % SLOTS_PER_HISTORICAL_ROOT, 13)); // block_roots -> block_roots[n]
60+
path = SSZ.concat(path, SSZ.intoList(uint256(_withdrawalSlot) % SLOTS_PER_HISTORICAL_ROOT, 13)); // block_roots -> block_roots[n]
6161
path = SSZ.concat(path, SSZ.from(4, 3)); // 0b100 (BeaconBlockHeader -> body_root)
6262
path = SSZ.concat(path, SSZ.from(9, 4)); // 0b1001 (BeaconBlockBody -> execution_payload)
63-
path = SSZ.concat(path, SSZ.from(14, 4)); // 0b1110 (ExecutionPayload -> withdrawals)
64-
path = SSZ.concat(path, SSZ.intoVector(_withdrawalNum, 5)); // withdrawals -> withdrawals[n]
63+
path = SSZ.concat(path, SSZ.from(14, 5)); // 0b01110 (ExecutionPayload -> withdrawals)
64+
path = SSZ.concat(path, SSZ.intoList(_withdrawalNum, 5)); // withdrawals -> withdrawals[n]
6565
// Merkleise the withdrawal struct
6666
bytes32 leaf = merkleiseWithdrawal(_withdrawal);
6767
// Restore the block root for the supplied slot

contracts/contract/util/SSZ.sol

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,10 @@ library SSZ {
2525
return Path((uint256(index) << 8) | uint256(log2Len + 1));
2626
}
2727

28+
function intoList(uint256 index, uint8 log2Len) internal pure returns (Path memory) {
29+
return Path((uint256(index) << 8) | uint256(log2Len));
30+
}
31+
2832
function concat(Path memory a, Path memory b) internal pure returns (Path memory) {
2933
uint8 lenA = uint8(a._data);
3034
uint8 lenB = uint8(b._data);

0 commit comments

Comments
 (0)