From ac872de0252655bbd365eb169eca9e5c652cd487 Mon Sep 17 00:00:00 2001 From: Felix Lange Date: Thu, 5 Sep 2024 17:46:26 +0200 Subject: [PATCH 01/14] test: fix solidity warning --- test/Test.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/Test.sol b/test/Test.sol index d1c8d9e..87a3455 100644 --- a/test/Test.sol +++ b/test/Test.sol @@ -41,7 +41,7 @@ abstract contract Test is StdTest { // assertStorage reads a value from the system contract and asserts it is // equal to the provided value. - function assertStorage(uint256 slot, uint256 value, string memory err) internal { + function assertStorage(uint256 slot, uint256 value, string memory err) internal view { bytes32 got = vm.load(addr, bytes32(slot)); assertEq(got, bytes32(value), err); } From 19dfef83fe557f547a471139470121c58c031528 Mon Sep 17 00:00:00 2001 From: Felix Lange Date: Thu, 5 Sep 2024 17:46:10 +0200 Subject: [PATCH 02/14] withdrawals: whitespace-cleanup --- src/withdrawals/main.eas | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/withdrawals/main.eas b/src/withdrawals/main.eas index b109751..f199ca8 100644 --- a/src/withdrawals/main.eas +++ b/src/withdrawals/main.eas @@ -4,7 +4,7 @@ ;; ██╔╝ ████╔╝██║████╔╝██║██╔═══╝ ██╔══██║╚════██║██║╚██╔╝██║ ;; ██║ ╚██████╔╝╚██████╔╝███████╗ ██║ ██║███████║██║ ╚═╝ ██║ ;; ╚═╝ ╚═════╝ ╚═════╝ ╚══════╝ ╚═╝ ╚═╝╚══════╝╚═╝ ╚═╝ -;; +;; ;; This is an implementation of EIP-7002's pre-deploy contract. It implements an ;; unvalidated withdrawal requests queue for beacon chain validators. The queue ;; is tracked using head and tail index pointers. After the queue is emptied, @@ -45,7 +45,7 @@ .start: ;; Protect the system subroutine by checking if the caller is the system - ;; address. + ;; address. caller ;; [caller] push20 SYSTEM_ADDR ;; [sysaddr, caller] eq ;; [sysaddr == caller] @@ -177,7 +177,7 @@ check_input: ;; with each record being exactly 76 bytes. ;; ;; Withdrawal request record: -;; +;; ;; +------+--------+--------+ ;; | addr | pubkey | amount | ;; +------+--------+--------+ @@ -240,7 +240,7 @@ accum_loop: push QUEUE_OFFSET ;; [offset, 3*(i+head_idx), record_offset, i, ..] add ;; [addr_offset, record_offset, i, ..] - ;; Read address. + ;; Read address. dup1 ;; [addr_offset, addr_offset, record_offset, i, ..] sload ;; [addr, addr_offset, record_offset, i, ..] @@ -259,13 +259,13 @@ accum_loop: ;; Write values to memory flat and contiguously. This require combining the ;; three storage elements (addr, pk[0:32], pk2_am) so there is no padding. - ;; + ;; ;; Each stack element has the following layout: ;; ;; A: addr - ;; 0x00 | 00 00 00 00 00 00 00 00 00 00 00 00 aa aa aa aa + ;; 0x00 | 00 00 00 00 00 00 00 00 00 00 00 00 aa aa aa aa ;; 0x10 | aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa - ;; + ;; ;; B: pk[0:32] ;; 0x00 | bb bb bb bb bb bb bb bb bb bb bb bb bb bb bb bb ;; 0x10 | bb bb bb bb bb bb bb bb bb bb bb bb bb bb bb bb @@ -283,7 +283,7 @@ accum_loop: swap2 ;; [addr, pk[0:32], pk2_am, record_offset, i, ..] push 12*8 ;; [96, addr, pk0:32], pk2_am, record_offset, i, ..] shl ;; [addr<<96, pk[0:32], pk2_am, record_offset, i, ..] - + ;; Store addr at offset = i*RECORD_SIZE. dup4 ;; [record_offset, addr<<96, pk[0:32], pk2_am, record_offset, i, ..] mstore ;; [pk[0:32], pk2_am, record_offset, i, ..] @@ -342,7 +342,7 @@ update_excess: ;; Update the new excess withdrawal requests. push SLOT_EXCESS ;; [excess_slot, count] sload ;; [excess, count] - + ;; Check if excess needs to be reset to 0 for first iteration after ;; activation. dup1 ;; [excess, excess, count, count] @@ -368,11 +368,11 @@ skip_reset: add ;; [count+excess, target, count, excess, count] gt ;; [count+excess > target, count, excess, count] jumpi @compute_excess ;; [count, excess, count] - + ;; Zero out excess. pop ;; [excess, count] pop ;; [count] - push0 + push0 jump @store_excess compute_excess: From c645eed031a244eeeb4cffe52f465ddec7669434 Mon Sep 17 00:00:00 2001 From: Felix Lange Date: Thu, 5 Sep 2024 17:46:36 +0200 Subject: [PATCH 03/14] withdrawals: store amount little-endian --- src/withdrawals/main.eas | 74 +++++++++++++++++++++++++++++++++++++--- 1 file changed, 69 insertions(+), 5 deletions(-) diff --git a/src/withdrawals/main.eas b/src/withdrawals/main.eas index f199ca8..ede64e2 100644 --- a/src/withdrawals/main.eas +++ b/src/withdrawals/main.eas @@ -294,11 +294,24 @@ accum_loop: add ;; [record_offset+20, pk[0:32], pk2_am, record_offset, i, ..] mstore ;; [pk2_am, record_offset, i, ..] - ;; Store pk2_am at offset = i*RECORD_SIZE + 52. - swap1 ;; [record_offset, pk2_am, i, ..] - push 52 ;; [52, record_offset, pk2_am, i, ..] - add ;; [record_offset+52, pk2_am, i, ..] - mstore ;; [i, ..] + ;; Extract pk2 from pk2_am. + dup1 ;; [pk2_am, pk2_am, record_offset, i, ..] + push (1<<16) - 1 ;; [mask, pk2_am, pk2_am, record_offset, i, ..] + and ;; [pk2, pk2_am, record_offset, i, ..] + + ;; Store pk2 at offset = i*RECORD_SIZE + 52. + dup3 ;; [record_offset, pk2, pk2_am, record_offset, i, ..] + push 52 ;; [52, record_offset, pk2, pk2_am, record_offset, i, ..] + add ;; [record_offset+52, pk2, pk2_am, record_offset, i, ..] + mstore ;; [pk2_am, record_offset, i, ..] + + ;; Extract am from pk2_am + push 16*8 ;; [shft, pk2_am, record_offset, i, ..] + shl ;; [am, record_offset, i, ..] + + ;; Store am at offset = i*RECORD_SIZE + 68. + swap1 ;; [record_offset, am, i, ..] + %mstore_uint64_le() ;; [i, ..] ;; Increment i. push 1 ;; [1, i, ..] @@ -401,3 +414,54 @@ revert: push0 push0 revert + +;; ----------------------------------------------------------------------------- +;; MACROS ---------------------------------------------------------------------- +;; ----------------------------------------------------------------------------- + +;; Helper for storing little-endian amount. +#define %mstore_uint64_le() { ;; [offset, value] + dup2 ;; [value, offset, value] + push 7*8 ;; [56, value, offset, value] + shr ;; [value>>56, offset, value] + dup2 ;; [offset, value>>56, offset, value] + mstore8 ;; [offset, value] + + dup2 ;; [value, offset, value] + push 6*8 ;; [48, value, offset, value] + shr ;; [value>>48, offset, value] + dup2 ;; [offset, value>>48, offset, value] + mstore8 ;; [offset, value] + + dup2 ;; [value, offset, value] + push 5*8 ;; [40, value, offset, value] + shr ;; [value>>40, offset, value] + dup2 ;; [offset, value>>40, offset, value] + mstore8 ;; [offset, value] + + dup2 ;; [value, offset, value] + push 4*8 ;; [32, value, offset, value] + shr ;; [value>>32, offset, value] + dup2 ;; [offset, value>>32, offset, value] + mstore8 ;; [offset, value] + + dup2 ;; [value, offset, value] + push 3*8 ;; [24, value, offset, value] + shr ;; [value>>24, offset, value] + dup2 ;; [offset, value>>24, offset, value] + mstore8 ;; [offset, value] + + dup2 ;; [value, offset, value] + push 2*8 ;; [16, value, offset, value] + shr ;; [value>>16, offset, value] + dup2 ;; [offset, value>>16, offset, value] + mstore8 ;; [offset, value] + + dup2 ;; [value, offset, value] + push 8 ;; [8, value, offset, value] + shr ;; [value>>8, offset, value] + dup2 ;; [offset, value>>8, offset, value] + mstore8 ;; [offset, value] + + mstore8 ;; [] +} From b75e4c4d6c139170f0143e52ed7292debac8a6aa Mon Sep 17 00:00:00 2001 From: Felix Lange Date: Thu, 5 Sep 2024 18:50:06 +0200 Subject: [PATCH 04/14] withdrawals: fix mask --- src/withdrawals/main.eas | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/withdrawals/main.eas b/src/withdrawals/main.eas index ede64e2..78c6773 100644 --- a/src/withdrawals/main.eas +++ b/src/withdrawals/main.eas @@ -296,7 +296,7 @@ accum_loop: ;; Extract pk2 from pk2_am. dup1 ;; [pk2_am, pk2_am, record_offset, i, ..] - push (1<<16) - 1 ;; [mask, pk2_am, pk2_am, record_offset, i, ..] + push (1<<(16*8))-1 ;; [mask, pk2_am, pk2_am, record_offset, i, ..] and ;; [pk2, pk2_am, record_offset, i, ..] ;; Store pk2 at offset = i*RECORD_SIZE + 52. From cbec96087076017faa2e7f32c2132058e5150eab Mon Sep 17 00:00:00 2001 From: Felix Lange Date: Thu, 5 Sep 2024 18:50:14 +0200 Subject: [PATCH 05/14] withdrawals: fix offset --- src/withdrawals/main.eas | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/withdrawals/main.eas b/src/withdrawals/main.eas index 78c6773..12f352c 100644 --- a/src/withdrawals/main.eas +++ b/src/withdrawals/main.eas @@ -311,6 +311,8 @@ accum_loop: ;; Store am at offset = i*RECORD_SIZE + 68. swap1 ;; [record_offset, am, i, ..] + push 68 ;; [68, record_offset, am, i, ..] + add ;; [record_offset+68, am, i, ..] %mstore_uint64_le() ;; [i, ..] ;; Increment i. From 010995b855958bae0a0e0c7aebf1ccb4cf229142 Mon Sep 17 00:00:00 2001 From: Felix Lange Date: Thu, 5 Sep 2024 19:13:54 +0200 Subject: [PATCH 06/14] test: WIP changing withdrawal tests for little endian --- test/Withdrawal.t.sol.in | 45 ++++++++++++++++++++++++++-------------- 1 file changed, 30 insertions(+), 15 deletions(-) diff --git a/test/Withdrawal.t.sol.in b/test/Withdrawal.t.sol.in index 7d66895..bdde69b 100644 --- a/test/Withdrawal.t.sol.in +++ b/test/Withdrawal.t.sol.in @@ -33,7 +33,8 @@ contract WithdrawalsTest is Test { // testWithdrawal verifies a single withdrawal request below the target request // count is accepted and read successfully. function testWithdrawal() public { - bytes memory data = hex"1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111112222222222222222"; + bytes memory data = hex"1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111110203040506070809"; + bytes memory exp_req = hex"1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111110908070605040302"; vm.expectEmitAnonymous(false, false, false, false, true); assembly { @@ -51,8 +52,9 @@ contract WithdrawalsTest is Test { bytes memory req = getRequests(); assertEq(req.length, 76); - assertEq(toFixed(req, 20, 52), toFixed(data, 0, 32)); - assertEq(toFixed(req, 52, 76), toFixed(data, 32, 56)); + assertEq(toFixed(req, 20, 52), toFixed(exp_req, 0, 32)); // check pk1 + assertEq(toFixed(req, 52, 68), toFixed(exp_req, 32, 48)); // check pk2 + assertEq(toFixed(req, 68, 76), toFixed(exp_req, 48, 56)); // check amt assertStorage(count_slot, 0, "unexpected request count"); assertExcess(0); } @@ -124,7 +126,7 @@ contract WithdrawalsTest is Test { // counter to decrease by 1 each iteration. for (uint256 i = 0; i < count; i++) { assertExcess(excess); - + uint256 fee = computeFee(excess); addFailedRequest(address(uint160(idx)), makeWithdrawal(idx), fee-1); addRequest(address(uint160(idx)), makeWithdrawal(idx), fee); @@ -190,27 +192,40 @@ contract WithdrawalsTest is Test { function checkWithdrawals(uint256 startIndex, uint256 count) internal returns (uint256) { bytes memory requests = getRequests(); assertEq(requests.length, count*76); + for (uint256 i = 0; i < count; i++) { uint256 offset = i*76; - assertEq(toFixed(requests, offset, offset+20) >> 96, uint256(startIndex+i), "unexpected request address returned"); - assertEq(toFixed(requests, offset+20, offset+52), toFixed(makeWithdrawal(startIndex+i), 0, 32), "unexpected request pk returned"); - assertEq(toFixed(requests, offset+52, offset+68), toFixed(makeWithdrawal(startIndex+i), 32, 48), "unexpected request pk returned"); - assertEq(toFixed(requests, offset+68, offset+76), toFixed(makeWithdrawal(startIndex+i), 48, 56), "unexpected request amount returned"); + uint256 index = startIndex + i; + + // Check address, pubkey. + bytes memory wd = makeWithdrawal(index); + assertEq(toFixed(requests, offset, offset+20) >> 96, uint256(index), "unexpected request address returned"); + assertEq(toFixed(requests, offset+20, offset+52), toFixed(wd, 0, 32), "unexpected request pk returned"); + assertEq(toFixed(requests, offset+52, offset+68), toFixed(wd, 32, 48), "unexpected request pk returned"); + + // Check amount. + uint256 output_amt = getUint64LE(requests, 68); + uint256 want_amt = uint256(index*99); + assertEq(output_amt, want_amt, "unexpected request amount returned"); } + return count; } // makeWithdrawal constructs a withdrawal request with a base of x. function makeWithdrawal(uint256 x) internal pure returns (bytes memory) { - bytes memory out = new bytes(56); - // pubkey + bytes memory pk = new bytes(48); for (uint256 i = 0; i < 48; i++) { - out[i] = bytes1(uint8(x)); - } - // amount - for (uint256 i = 0; i < 8; i++) { - out[48 + i] = bytes1(uint8(x+1)); + pk[i] = bytes1(uint8(x)); } + uint64 amt = uint64(x*99); + bytes memory out = abi.encodePacked(pk, amt); + require(out.length == 56); return out; } + + // getUint64LE reads a little-endian uint64 at the given offset; + function getUint64LE(bytes memory b, uint offset) internal view returns (uint256) { + return uint8(b[offset])<<56 | uint8(b[offset+1])<<48 | uint8(b[offset+2])<<40 | uint8(b[offset+3])<<32 | uint8(b[offset+4])<<24 | uint8(b[offset+5])<<16 | uint8(b[offset+6])<<8 | uint8(b[offset+7]); + } } From 243c4ea5096c48fa51bc2fdef6a9639c3714ead9 Mon Sep 17 00:00:00 2001 From: Felix Lange Date: Thu, 5 Sep 2024 19:33:49 +0200 Subject: [PATCH 07/14] withdrawals: fix mstore offsets in %mstore_uint64_le --- src/withdrawals/main.eas | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/withdrawals/main.eas b/src/withdrawals/main.eas index 12f352c..6b262f0 100644 --- a/src/withdrawals/main.eas +++ b/src/withdrawals/main.eas @@ -427,42 +427,56 @@ revert: push 7*8 ;; [56, value, offset, value] shr ;; [value>>56, offset, value] dup2 ;; [offset, value>>56, offset, value] + push 7 ;; [7, offset, value>>56, offset, value] + add ;; [offset+7, value>>56, offset, value] mstore8 ;; [offset, value] dup2 ;; [value, offset, value] push 6*8 ;; [48, value, offset, value] shr ;; [value>>48, offset, value] dup2 ;; [offset, value>>48, offset, value] + push 6 ;; [6, offset, value>>48, offset, value] + add ;; [offset+6, value>>48, offset, value] mstore8 ;; [offset, value] dup2 ;; [value, offset, value] push 5*8 ;; [40, value, offset, value] shr ;; [value>>40, offset, value] dup2 ;; [offset, value>>40, offset, value] + push 5 ;; [2, offset, value>>40, offset, value] + add ;; [offset+5, value>>40, offset, value] mstore8 ;; [offset, value] dup2 ;; [value, offset, value] push 4*8 ;; [32, value, offset, value] shr ;; [value>>32, offset, value] dup2 ;; [offset, value>>32, offset, value] + push 4 ;; [4, offset, value>>32, offset, value] + add ;; [offset+4, value>>32, offset, value] mstore8 ;; [offset, value] dup2 ;; [value, offset, value] push 3*8 ;; [24, value, offset, value] shr ;; [value>>24, offset, value] dup2 ;; [offset, value>>24, offset, value] + push 3 ;; [3, offset, value>>24, offset, value] + add ;; [offset+3, value>>24, offset, value] mstore8 ;; [offset, value] dup2 ;; [value, offset, value] push 2*8 ;; [16, value, offset, value] shr ;; [value>>16, offset, value] dup2 ;; [offset, value>>16, offset, value] + push 2 ;; [2, offset, value>>16, offset, value] + add ;; [offset+2, value>>16, offset, value] mstore8 ;; [offset, value] dup2 ;; [value, offset, value] - push 8 ;; [8, value, offset, value] + push 1*8 ;; [8, value, offset, value] shr ;; [value>>8, offset, value] dup2 ;; [offset, value>>8, offset, value] + push 1 ;; [1, offset, value>>8, offset, value] + add ;; [offset+1, value>>8, offset, value] mstore8 ;; [offset, value] mstore8 ;; [] From a768688fc0c49849e5854e7dcca3c675a7717d65 Mon Sep 17 00:00:00 2001 From: Felix Lange Date: Thu, 5 Sep 2024 22:01:09 +0200 Subject: [PATCH 08/14] withdrawals: fix comments --- src/withdrawals/main.eas | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/withdrawals/main.eas b/src/withdrawals/main.eas index 6b262f0..b273734 100644 --- a/src/withdrawals/main.eas +++ b/src/withdrawals/main.eas @@ -281,7 +281,7 @@ accum_loop: ;; Shift addr bytes. swap2 ;; [addr, pk[0:32], pk2_am, record_offset, i, ..] - push 12*8 ;; [96, addr, pk0:32], pk2_am, record_offset, i, ..] + push 12*8 ;; [96, addr, pk[0:32], pk2_am, record_offset, i, ..] shl ;; [addr<<96, pk[0:32], pk2_am, record_offset, i, ..] ;; Store addr at offset = i*RECORD_SIZE. @@ -305,7 +305,7 @@ accum_loop: add ;; [record_offset+52, pk2, pk2_am, record_offset, i, ..] mstore ;; [pk2_am, record_offset, i, ..] - ;; Extract am from pk2_am + ;; Extract am from pk2_am. push 16*8 ;; [shft, pk2_am, record_offset, i, ..] shl ;; [am, record_offset, i, ..] From ca2125ecf97068ee0c98141cbae7b8802460faf6 Mon Sep 17 00:00:00 2001 From: Felix Lange Date: Thu, 5 Sep 2024 22:01:16 +0200 Subject: [PATCH 09/14] test: fix offsets in getUint64LE --- test/Withdrawal.t.sol.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/Withdrawal.t.sol.in b/test/Withdrawal.t.sol.in index bdde69b..9385ed9 100644 --- a/test/Withdrawal.t.sol.in +++ b/test/Withdrawal.t.sol.in @@ -226,6 +226,6 @@ contract WithdrawalsTest is Test { // getUint64LE reads a little-endian uint64 at the given offset; function getUint64LE(bytes memory b, uint offset) internal view returns (uint256) { - return uint8(b[offset])<<56 | uint8(b[offset+1])<<48 | uint8(b[offset+2])<<40 | uint8(b[offset+3])<<32 | uint8(b[offset+4])<<24 | uint8(b[offset+5])<<16 | uint8(b[offset+6])<<8 | uint8(b[offset+7]); + return uint8(b[offset+7])<<56 | uint8(b[offset+6])<<48 | uint8(b[offset+5])<<40 | uint8(b[offset+4])<<32 | uint8(b[offset+3])<<24 | uint8(b[offset+2])<<16 | uint8(b[offset+1])<<8 | uint8(b[offset]); } } From 2ab1c5d5d6f408cfc94babf553b27a3b666efe2a Mon Sep 17 00:00:00 2001 From: Felix Lange Date: Thu, 5 Sep 2024 22:18:47 +0200 Subject: [PATCH 10/14] withdrawals: fix extract of pk2 and am --- src/withdrawals/main.eas | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/withdrawals/main.eas b/src/withdrawals/main.eas index b273734..0e6ff6f 100644 --- a/src/withdrawals/main.eas +++ b/src/withdrawals/main.eas @@ -296,7 +296,7 @@ accum_loop: ;; Extract pk2 from pk2_am. dup1 ;; [pk2_am, pk2_am, record_offset, i, ..] - push (1<<(16*8))-1 ;; [mask, pk2_am, pk2_am, record_offset, i, ..] + push pk2_mask ;; [mask, pk2_am, pk2_am, record_offset, i, ..] and ;; [pk2, pk2_am, record_offset, i, ..] ;; Store pk2 at offset = i*RECORD_SIZE + 52. @@ -306,8 +306,8 @@ accum_loop: mstore ;; [pk2_am, record_offset, i, ..] ;; Extract am from pk2_am. - push 16*8 ;; [shft, pk2_am, record_offset, i, ..] - shl ;; [am, record_offset, i, ..] + push 8*8 ;; [shft, pk2_am, record_offset, i, ..] + shr ;; [am, record_offset, i, ..] ;; Store am at offset = i*RECORD_SIZE + 68. swap1 ;; [record_offset, am, i, ..] @@ -421,6 +421,9 @@ revert: ;; MACROS ---------------------------------------------------------------------- ;; ----------------------------------------------------------------------------- +;; This defines a mask for accessing the top 16 bytes of a number. +#define pk2_mask 0xffffffffffffffffffffffffffffffff00000000000000000000000000000000 + ;; Helper for storing little-endian amount. #define %mstore_uint64_le() { ;; [offset, value] dup2 ;; [value, offset, value] From 77f43ab249ce91f3ab00379d25563848077f75ed Mon Sep 17 00:00:00 2001 From: Felix Lange Date: Thu, 5 Sep 2024 22:53:54 +0200 Subject: [PATCH 11/14] test: fix test --- test/Withdrawal.t.sol.in | 26 ++++++++++++-------------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/test/Withdrawal.t.sol.in b/test/Withdrawal.t.sol.in index 9385ed9..cb3dafe 100644 --- a/test/Withdrawal.t.sol.in +++ b/test/Withdrawal.t.sol.in @@ -195,17 +195,20 @@ contract WithdrawalsTest is Test { for (uint256 i = 0; i < count; i++) { uint256 offset = i*76; - uint256 index = startIndex + i; + uint256 wd_index = startIndex + i; // Check address, pubkey. - bytes memory wd = makeWithdrawal(index); - assertEq(toFixed(requests, offset, offset+20) >> 96, uint256(index), "unexpected request address returned"); - assertEq(toFixed(requests, offset+20, offset+52), toFixed(wd, 0, 32), "unexpected request pk returned"); - assertEq(toFixed(requests, offset+52, offset+68), toFixed(wd, 32, 48), "unexpected request pk returned"); + bytes memory wd = makeWithdrawal(wd_index); + assertEq(toFixed(requests, offset, offset+20) >> 96, uint256(wd_index), "unexpected request address returned"); + assertEq(toFixed(requests, offset+20, offset+52), toFixed(wd, 0, 32), "unexpected request pk1 returned"); + assertEq(toFixed(requests, offset+52, offset+68), toFixed(wd, 32, 48), "unexpected request pk2 returned"); // Check amount. - uint256 output_amt = getUint64LE(requests, 68); - uint256 want_amt = uint256(index*99); + bytes memory output_amt = new bytes(8); + for (uint j = 0; j < 8; j++) { + output_amt[j] = requests[offset+68+j]; + } + bytes memory want_amt = hex"de852726f6fb9f2d"; assertEq(output_amt, want_amt, "unexpected request amount returned"); } @@ -218,14 +221,9 @@ contract WithdrawalsTest is Test { for (uint256 i = 0; i < 48; i++) { pk[i] = bytes1(uint8(x)); } - uint64 amt = uint64(x*99); - bytes memory out = abi.encodePacked(pk, amt); + bytes memory amt = hex"2d9ffbf6262785de"; + bytes memory out = bytes.concat(pk, amt); require(out.length == 56); return out; } - - // getUint64LE reads a little-endian uint64 at the given offset; - function getUint64LE(bytes memory b, uint offset) internal view returns (uint256) { - return uint8(b[offset+7])<<56 | uint8(b[offset+6])<<48 | uint8(b[offset+5])<<40 | uint8(b[offset+4])<<32 | uint8(b[offset+3])<<24 | uint8(b[offset+2])<<16 | uint8(b[offset+1])<<8 | uint8(b[offset]); - } } From ef1ade8cef225c6376dd65c2e8420625361ea049 Mon Sep 17 00:00:00 2001 From: Felix Lange Date: Thu, 5 Sep 2024 23:07:03 +0200 Subject: [PATCH 12/14] test: rename variables --- test/Withdrawal.t.sol.in | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/test/Withdrawal.t.sol.in b/test/Withdrawal.t.sol.in index cb3dafe..f0b44cb 100644 --- a/test/Withdrawal.t.sol.in +++ b/test/Withdrawal.t.sol.in @@ -195,21 +195,21 @@ contract WithdrawalsTest is Test { for (uint256 i = 0; i < count; i++) { uint256 offset = i*76; - uint256 wd_index = startIndex + i; + uint256 wdIndex = startIndex + i; + bytes memory wd = makeWithdrawal(wdIndex); // Check address, pubkey. - bytes memory wd = makeWithdrawal(wd_index); - assertEq(toFixed(requests, offset, offset+20) >> 96, uint256(wd_index), "unexpected request address returned"); + assertEq(toFixed(requests, offset, offset+20) >> 96, uint256(wdIndex), "unexpected request address returned"); assertEq(toFixed(requests, offset+20, offset+52), toFixed(wd, 0, 32), "unexpected request pk1 returned"); assertEq(toFixed(requests, offset+52, offset+68), toFixed(wd, 32, 48), "unexpected request pk2 returned"); // Check amount. - bytes memory output_amt = new bytes(8); + bytes memory outputAmount = new bytes(8); for (uint j = 0; j < 8; j++) { - output_amt[j] = requests[offset+68+j]; + outputAmount[j] = requests[offset+68+j]; } - bytes memory want_amt = hex"de852726f6fb9f2d"; - assertEq(output_amt, want_amt, "unexpected request amount returned"); + bytes memory wantAmount = hex"de852726f6fb9f2d"; + assertEq(outputAmount, wantAmount, "unexpected request amount returned"); } return count; From fa1c17f2853e922ad97a3aa9ca85e24dee06c494 Mon Sep 17 00:00:00 2001 From: Felix Lange Date: Thu, 5 Sep 2024 23:12:10 +0200 Subject: [PATCH 13/14] test: check address in testWithdrawal --- test/Withdrawal.t.sol.in | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/test/Withdrawal.t.sol.in b/test/Withdrawal.t.sol.in index f0b44cb..e1742f8 100644 --- a/test/Withdrawal.t.sol.in +++ b/test/Withdrawal.t.sol.in @@ -52,9 +52,10 @@ contract WithdrawalsTest is Test { bytes memory req = getRequests(); assertEq(req.length, 76); - assertEq(toFixed(req, 20, 52), toFixed(exp_req, 0, 32)); // check pk1 - assertEq(toFixed(req, 52, 68), toFixed(exp_req, 32, 48)); // check pk2 - assertEq(toFixed(req, 68, 76), toFixed(exp_req, 48, 56)); // check amt + assertEq(bytes20(req), bytes20(address(this))); // check addr + assertEq(toFixed(req, 20, 52), toFixed(exp_req, 0, 32)); // check pk1 + assertEq(toFixed(req, 52, 68), toFixed(exp_req, 32, 48)); // check pk2 + assertEq(toFixed(req, 68, 76), toFixed(exp_req, 48, 56)); // check amt assertStorage(count_slot, 0, "unexpected request count"); assertExcess(0); } From d841b22c0572298bcf2840abc220a44d33ffaedd Mon Sep 17 00:00:00 2001 From: Felix Lange Date: Thu, 5 Sep 2024 23:24:03 +0200 Subject: [PATCH 14/14] test: use shared amount buffer --- test/Withdrawal.t.sol.in | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/Withdrawal.t.sol.in b/test/Withdrawal.t.sol.in index e1742f8..faabad9 100644 --- a/test/Withdrawal.t.sol.in +++ b/test/Withdrawal.t.sol.in @@ -191,6 +191,7 @@ contract WithdrawalsTest is Test { // It assumes that addresses are stored as uint256(index) and pubkeys are // uint8(index), repeating. function checkWithdrawals(uint256 startIndex, uint256 count) internal returns (uint256) { + bytes memory amountBuffer = new bytes(8); bytes memory requests = getRequests(); assertEq(requests.length, count*76); @@ -205,12 +206,11 @@ contract WithdrawalsTest is Test { assertEq(toFixed(requests, offset+52, offset+68), toFixed(wd, 32, 48), "unexpected request pk2 returned"); // Check amount. - bytes memory outputAmount = new bytes(8); for (uint j = 0; j < 8; j++) { - outputAmount[j] = requests[offset+68+j]; + amountBuffer[j] = requests[offset+68+j]; } bytes memory wantAmount = hex"de852726f6fb9f2d"; - assertEq(outputAmount, wantAmount, "unexpected request amount returned"); + assertEq(amountBuffer, wantAmount, "unexpected request amount returned"); } return count;