diff --git a/src/main.eas b/src/main.eas index 94b6b5d..1567347 100644 --- a/src/main.eas +++ b/src/main.eas @@ -25,14 +25,14 @@ #define SLOT_EXCESS 0 #define SLOT_COUNT 1 -#define SLOT_TARGET 2 #define QUEUE_HEAD 2 #define QUEUE_TAIL 3 #define QUEUE_OFFSET 4 #define MIN_FEE 1 -#define MAX_REQS 16 +#define TARGET_PER_BLOCK 2 +#define MAX_PER_BLOCK 16 #define FEE_UPDATE_FRACTION 17 #define INPUT_SIZE 56 ;; the size of (pubkey ++ amount) @@ -187,13 +187,13 @@ read_requests: ;; Determine if count is greater than the max withdrawal requests. dup1 ;; [count, count, head_idx, tail_idx] - push MAX_REQS ;; [reqs_per_block, count, count, head_idx, tail_idx] + push MAX_PER_BLOCK ;; [reqs_per_block, count, count, head_idx, tail_idx] gt ;; [reqs_per_block > count, count, head_idx, tail_idx] jumpi @begin_loop ;; [count, head_idx, tail_idx] ;; Discard count, use the max withdrawal requests per block. pop ;; [head_idx, tail_idx] - push MAX_REQS ;; [count, head_idx, tail_idx] + push MAX_PER_BLOCK ;; [count, head_idx, tail_idx] begin_loop: push0 ;; [i, count, head_idx, tail_idx] @@ -331,7 +331,7 @@ update_excess: ;; If the sum of the previous excess requests and requests added in the ;; current block is greater than the target, subtract the target from the sum ;; and set it as the new excess withdrawal requests value. - push SLOT_TARGET ;; [target, count, excess, count] + push TARGET_PER_BLOCK ;; [target, count, excess, count] dup3 ;; [excess, target, count, excess] dup3 ;; [count, excess, target, count, excess, count] add ;; [count+excess, target, count, excess, count] @@ -346,7 +346,7 @@ update_excess: compute_excess: add ;; [count+excess, count] - push SLOT_TARGET + push TARGET_PER_BLOCK ;; [target, count+excess, count] swap1 ;; [count+excess, target, count] sub ;; [new_excess, count] diff --git a/test/Contract.t.sol.in b/test/Contract.t.sol.in index b5e3acb..4da8e08 100644 --- a/test/Contract.t.sol.in +++ b/test/Contract.t.sol.in @@ -9,14 +9,13 @@ address constant fakeExpo = 0x000000000000000000000000000000000000BbBB; address constant testCaller = 0x000000000000000000000000000000000000CcCc; address constant sysaddr = 0xffffFFFfFFffffffffffffffFfFFFfffFFFfFFfE; -uint256 constant excess_exits_slot = 0; -uint256 constant exit_count_slot = 1; +uint256 constant excess_slot = 0; +uint256 constant count_slot = 1; uint256 constant queue_head_slot = 2; uint256 constant queue_tail_slot = 3; - uint256 constant queue_storage_offset = 4; -uint256 constant target_exits = 2; -uint256 constant max_exits = 16; +uint256 constant target_per_block = 2; +uint256 constant max_per_block = 16; contract ContractTest is Test { address unit; @@ -32,8 +31,8 @@ contract ContractTest is Test { assertEq(callFakeExpo(1, 100, 17), 357); } - // testInvalidExit checks that common invalid exit submissions are rejected. - function testInvalidExit() public { + // testInvalidRequest checks that common invalid withdrawal requests are rejected. + function testInvalidRequest() public { // pubkey too small (bool ret,) = addr.call{value: 1e18}(hex"1234"); assertEq(ret, false); @@ -47,97 +46,97 @@ contract ContractTest is Test { assertEq(ret, false); } - // testExit verifies a single exit below the target exit count is accepted and - // read successfully. - function testExit() public { - bytes memory req = hex"1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111112222222222222222"; - (bool ret,) = addr.call{value: 2}(req); + // testRequest verifies a single withdrawal request below the target request + // count is accepted and read successfully. + function testRequest() public { + bytes memory data = hex"1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111112222222222222222"; + (bool ret,) = addr.call{value: 2}(data); assertEq(ret, true); - assertStorage(exit_count_slot, 1, "unexpected exit count"); + assertStorage(count_slot, 1, "unexpected withdrawal request count"); assertExcess(0); - bytes memory exit = getExits(); - assertEq(exit.length, 76); - assertEq(toFixed(exit, 20, 52), toFixed(req, 0, 32)); - assertEq(toFixed(exit, 52, 76), toFixed(req, 32, 56)); - assertStorage(exit_count_slot, 0, "unexpected exit count"); + 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)); + assertStorage(count_slot, 0, "unexpected request count"); assertExcess(0); } // testQueueReset verifies that after a period of time where there are more - // exits than can be read per block, the queue is eventually cleared and the + // request than can be read per block, the queue is eventually cleared and the // head and tails are reset to zero. function testQueueReset() public { - // Add more exits than the max exits per block (16) so that the queue is not + // Add more requests than the max per block (16) so that the queue is not // immediately emptied. - for (uint256 i = 0; i < max_exits+1; i++) { - addExit(address(uint160(i)), makeRequest(i), 2); + for (uint256 i = 0; i < max_per_block+1; i++) { + addRequest(address(uint160(i)), makeRequest(i), 2); } - assertStorage(exit_count_slot, max_exits+1, "unexpected exit count"); + assertStorage(count_slot, max_per_block+1, "unexpected request count"); - // Simulate syscall, check that max exits per block are read. - checkExits(0, max_exits); + // Simulate syscall, check that max requests per block are read. + checkRequests(0, max_per_block); assertExcess(15); - // Add another batch of max exits per block (16) so the next read leaves a - // single exit in the queue. + // Add another batch of max requests per block (16) so the next read leaves a + // single request in the queue. for (uint256 i = 17; i < 33; i++) { - addExit(address(uint160(i)), makeRequest(i), 2); + addRequest(address(uint160(i)), makeRequest(i), 2); } - assertStorage(exit_count_slot, max_exits, "unexpected exit count"); + assertStorage(count_slot, max_per_block, "unexpected request count"); - // Simulate syscall. Verify first that max exits per block are read. Then - // verify only the single final exit is read. - checkExits(16, max_exits); + // Simulate syscall. Verify first that max per block are read. Then + // verify only the single final requst is read. + checkRequests(16, max_per_block); assertExcess(29); - checkExits(32, 1); + checkRequests(32, 1); assertExcess(27); // Now ensure the queue is empty and has reset to zero. assertStorage(queue_head_slot, 0, "expected queue head reset"); assertStorage(queue_tail_slot, 0, "expected queue tail reset"); - // Add five (5) more exits to check that new exits can be added after the queue + // Add five (5) more requests to check that new requests can be added after the queue // is reset. for (uint256 i = 33; i < 38; i++) { - addExit(address(uint160(i)), makeRequest(i), 4); + addRequest(address(uint160(i)), makeRequest(i), 4); } - assertStorage(exit_count_slot, 5, "unexpected exit count"); + assertStorage(count_slot, 5, "unexpected request count"); - // Simulate syscall, read only the max exits per block. - checkExits(33, 5); + // Simulate syscall, read only the max requests per block. + checkRequests(33, 5); assertExcess(30); } - // testExitFee adds many exits, and verifies the exit fee decreases correctly - // until it returns to 0. - function testExitFee() public { + // testFee adds many requests, and verifies the fee decreases correctly until + // it returns to 0. + function testFee() public { uint256 idx = 0; - uint256 count = max_exits*64; + uint256 count = max_per_block*64; - // Add a bunch of exits. + // Add a bunch of requests. for (; idx < count; idx++) { - addExit(address(uint160(idx)), makeRequest(idx), 1); + addRequest(address(uint160(idx)), makeRequest(idx), 1); } - assertStorage(exit_count_slot, count, "unexpected exit count"); - checkExits(0, max_exits); + assertStorage(count_slot, count, "unexpected request count"); + checkRequests(0, max_per_block); - uint256 read = max_exits; - uint256 excess = count - target_exits; + uint256 read = max_per_block; + uint256 excess = count - target_per_block; - // Attempt to add an expect with fee too low and an exit with fee exactly - // correct. This should cause the excess exits counter to decrease by 1 each + // Attempt to add a request with fee too low and a request with fee exactly + // correct. This should cause the excess requests counter to decrease by 1 each // iteration. for (uint256 i = 0; i < count; i++) { assertExcess(excess); - uint256 fee = computeExitFee(excess); - addFailedExit(address(uint160(idx)), makeRequest(idx), fee-1); - addExit(address(uint160(idx)), makeRequest(idx), fee); + uint256 fee = computeFee(excess); + addFailedRequest(address(uint160(idx)), makeRequest(idx), fee-1); + addRequest(address(uint160(idx)), makeRequest(idx), fee); - uint256 expected = min(idx-read+1, max_exits); - checkExits(read, expected); + uint256 expected = min(idx-read+1, max_per_block); + checkRequests(read, expected); if (excess != 0) { excess--; @@ -155,58 +154,58 @@ contract ContractTest is Test { return y; } - function addFailedExit(address from, bytes memory req, uint256 value) internal { + function addFailedRequest(address from, bytes memory req, uint256 value) internal { vm.deal(from, value); vm.prank(from); (bool ret,) = addr.call{value: value}(req); - assertEq(ret, false, "expected exit to fail"); + assertEq(ret, false, "expected request to fail"); } - // addExit will submit an exit to the system contract with the given values. - function addExit(address from, bytes memory req, uint256 value) internal { - // Load tail index before adding exit. - uint256 exits = load(exit_count_slot); + // addRequest will submit a request to the system contract with the given values. + function addRequest(address from, bytes memory req, uint256 value) internal { + // Load tail index before adding request. + uint256 requests = load(count_slot); uint256 tail = load(queue_tail_slot); - // Send exit from address. + // Send request from address. vm.deal(from, value); vm.prank(from); (bool ret,) = addr.call{value: value}(req); assertEq(ret, true, "expected call to succeed"); // Verify the queue data was updated correctly. - assertStorage(exit_count_slot, exits+1, "unexpected exit count"); + assertStorage(count_slot, requests+1, "unexpected request count"); assertStorage(queue_tail_slot, tail+1, "unexpected tail slot"); - // Verify the exit was written to the queue. + // Verify the request was written to the queue. uint256 idx = queue_storage_offset+tail*3; assertStorage(idx, uint256(uint160(from)), "addr not written to queue"); assertStorage(idx+1, toFixed(req, 0, 32), "pk[0:32] not written to queue"); assertStorage(idx+2, toFixed(req, 32, 56), "pk2_am not written to queue"); } - // getExits will simulate a system call to the system contract. - function getExits() internal returns (bytes memory) { + // getRequests will simulate a system call to the system contract. + function getRequests() internal returns (bytes memory) { vm.prank(sysaddr); (bool ret, bytes memory data) = addr.call(""); assertEq(ret, true); return data; } - // checkExits will simulate a system call to the system contract and verify - // the expected exits are returned. + // checkRequest will simulate a system call to the system contract and verify + // the expected requests are returned. // // It assumes that addresses are stored as uint256(index) and pubkeys are // uint8(index), repeating. - function checkExits(uint256 startIndex, uint256 count) internal returns (uint256) { - bytes memory exits = getExits(); - assertEq(exits.length, count*76); + function checkRequests(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(exits, offset, offset+20) >> 96, uint256(startIndex+i), "unexpected exit address returned"); - assertEq(toFixed(exits, offset+20, offset+52), toFixed(makeRequest(startIndex+i), 0, 32), "unexpected exit pk returned"); - assertEq(toFixed(exits, offset+52, offset+68), toFixed(makeRequest(startIndex+i), 32, 48), "unexpected exit pk returned"); - assertEq(toFixed(exits, offset+68, offset+76), toFixed(makeRequest(startIndex+i), 48, 56), "unexpected exit amount returned"); + assertEq(toFixed(requests, offset, offset+20) >> 96, uint256(startIndex+i), "unexpected request address returned"); + assertEq(toFixed(requests, offset+20, offset+52), toFixed(makeRequest(startIndex+i), 0, 32), "unexpected request pk returned"); + assertEq(toFixed(requests, offset+52, offset+68), toFixed(makeRequest(startIndex+i), 32, 48), "unexpected request pk returned"); + assertEq(toFixed(requests, offset+68, offset+76), toFixed(makeRequest(startIndex+i), 48, 56), "unexpected request amount returned"); } return count; } @@ -221,9 +220,9 @@ contract ContractTest is Test { } function assertExcess(uint256 count) internal { - assertStorage(excess_exits_slot, count, "unexpected excess exits"); + assertStorage(excess_slot, count, "unexpected excess requests"); (, bytes memory data) = addr.call(""); - assertEq(toFixed(data, 0, 32), count, "unexpected excess exits"); + assertEq(toFixed(data, 0, 32), count, "unexpected excess requests"); } function toFixed(bytes memory data, uint256 start, uint256 end) internal pure returns (uint256) { @@ -250,7 +249,7 @@ contract ContractTest is Test { return out; } - function computeExitFee(uint256 excess) internal returns (uint256) { + function computeFee(uint256 excess) internal returns (uint256) { return callFakeExpo(1, int(excess), 17); }