Skip to content

Commit 3375a2a

Browse files
authored
Merge pull request #33 from fjl/withdrawals-return-fee
withdrawals, consolidations: return fee instead of excess requests from read operation
2 parents b5b9f33 + d4a1e93 commit 3375a2a

File tree

3 files changed

+68
-85
lines changed

3 files changed

+68
-85
lines changed

src/consolidations/main.eas

Lines changed: 35 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
;; ▗▄▄▄▖▄▄▄▄ ▄▄▄▄ ▄ ▗▞▀▜▌ ▄▄▄
2-
;; ▐▌ █ █ █ ▝▚▄▟▌▀▄▄ ▄▄▄▄
3-
;; ▐▌█▀▀▀ ▀▀▀█ █ ▄▄▄▀ █ █ █
4-
;; ▐▌█▄▄▄ ▄▄▄█ █ █ █
1+
;; ▗▄▄▄▖▄▄▄▄ ▄▄▄▄ ▄ ▗▞▀▜▌ ▄▄▄
2+
;; ▐▌ █ █ █ ▝▚▄▟▌▀▄▄ ▄▄▄▄
3+
;; ▐▌█▀▀▀ ▀▀▀█ █ ▄▄▄▀ █ █ █
4+
;; ▐▌█▄▄▄ ▄▄▄█ █ █ █
55

66
;; This is an implementation of EIP-7251 style contract handling EL triggerred
77
;; consolidations. It leverages on the fee mechanism and the queue design of the
@@ -50,29 +50,6 @@
5050
;; --------------------------------------------------------------------------
5151
;; USER SUBROUTINE ----------------------------------------------------------
5252
;; --------------------------------------------------------------------------
53-
;;
54-
;; Record new request ~~
55-
;; This is the default code path. It will attempt to record a user's request
56-
;; so long as they pay the required fee.
57-
58-
;; If calldatasize == 0, return the current excess requests.
59-
calldatasize ;; [calldatasize]
60-
iszero ;; [calldatasize == 0]
61-
jumpi @read_excess
62-
63-
;; Input data has the following layout:
64-
;;
65-
;; +--------+--------+
66-
;; | source | target |
67-
;; +--------+--------+
68-
;; 48 48
69-
70-
;; Verify the input is exactly INPUT_SIZE bytes.
71-
calldatasize ;; [calldatasize]
72-
push INPUT_SIZE ;; [INPUT_SIZE, calldatasize]
73-
eq ;; [INPUT_SIZE == calldatasize]
74-
iszero ;; [INPUT_SIZE != calldatasize]
75-
jumpi @revert ;; []
7653

7754
;; Compute the fee using fake expo and the current excess requests.
7855
push FEE_UPDATE_FRACTION
@@ -88,6 +65,37 @@
8865
push MIN_FEE ;; [min_fee, excess, update_fraction]
8966
#include "../common/fake_expo.eas"
9067

68+
;; If calldatasize matches the expected input size, go to adding the request.
69+
calldatasize ;; [calldatasize, req_fee]
70+
push INPUT_SIZE ;; [INPUT_SIZE, calldatasize, req_fee]
71+
eq ;; [INPUT_SIZE == calldatasize, req_fee]
72+
jumpi @handle_input ;; [req_fee]
73+
74+
;; Otherwise calldatasize must be zero.
75+
calldatasize ;; [calldatasize, req_fee]
76+
jumpi @revert ;; [req_fee]
77+
78+
;; This is the read path, where we return the current excess.
79+
;; Reject any callvalue here to prevent lost funds.
80+
callvalue ;; [value, req_fee]
81+
jumpi @revert ;; [req_fee]
82+
83+
;; Return req_fee.
84+
push 0 ;; [0, req_fee]
85+
mstore ;; []
86+
push 32 ;; [32]
87+
push 0 ;; [0, 32]
88+
return ;; []
89+
90+
handle_input:
91+
;; This is the write path. We expect the computed fee on the stack.
92+
;; Input data has the following layout:
93+
;;
94+
;; +--------+--------+
95+
;; | source | target |
96+
;; +--------+--------+
97+
;; 48 48
98+
9199
;; Determine if the fee provided is enough to cover the request fee.
92100
callvalue ;; [callvalue, req_fee]
93101
lt ;; [callvalue < req_fee]
@@ -167,23 +175,6 @@
167175

168176
stop
169177

170-
read_excess:
171-
;; This is the read path, where we return the current excess.
172-
;; Reject any callvalue here to prevent lost funds.
173-
callvalue ;; [value]
174-
iszero ;; [value == 0]
175-
iszero ;; [value != 0]
176-
jumpi @revert
177-
178-
;; Load excess requests and return the value.
179-
push SLOT_EXCESS ;; [excess_reqs_slot]
180-
sload ;; [excess_reqs]
181-
push 0 ;; [0, excess_reqs]
182-
mstore ;; []
183-
push 32 ;; [32]
184-
push 0 ;; [0, 32]
185-
return ;; []
186-
187178
;; ----------------------------------------------------------------------------
188179
;; SYSTEM SUBROUTINE ----------------------------------------------------------
189180
;; ----------------------------------------------------------------------------

src/withdrawals/main.eas

Lines changed: 31 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -55,29 +55,6 @@
5555
;; --------------------------------------------------------------------------
5656
;; USER SUBROUTINE ----------------------------------------------------------
5757
;; --------------------------------------------------------------------------
58-
;;
59-
;; Record new withdrawal request ~~
60-
;; This is the default code path. It will attempt to record a user's request
61-
;; so long as they pay the required fee.
62-
63-
;; If calldatasize == 0, return the current excess requests.
64-
calldatasize ;; [calldatasize]
65-
iszero ;; [calldatasize == 0]
66-
jumpi @read_excess
67-
68-
;; Input data has the following layout:
69-
;;
70-
;; +--------+--------+
71-
;; | pubkey | amount |
72-
;; +--------+--------+
73-
;; 48 8
74-
75-
;; Verify the input is exactly 56 bytes.
76-
calldatasize ;; [calldatasize]
77-
push INPUT_SIZE ;; [INPUT_SIZE, calldatasize]
78-
eq ;; [INPUT_SIZE == calldatasize]
79-
iszero ;; [INPUT_SIZE != calldatasize]
80-
jumpi @revert ;; []
8158

8259
;; Compute the fee using fake expo and the current excess withdrawal requests.
8360
push FEE_UPDATE_FRACTION
@@ -93,6 +70,37 @@
9370
push MIN_FEE ;; [min_fee, excess, update_fraction]
9471
#include "../common/fake_expo.eas"
9572

73+
;; If calldatasize matches the expected input size, go to adding the request.
74+
calldatasize ;; [calldatasize, req_fee]
75+
push INPUT_SIZE ;; [INPUT_SIZE, calldatasize, req_fee]
76+
eq ;; [INPUT_SIZE == calldatasize, req_fee]
77+
jumpi @handle_input
78+
79+
;; Otherwise calldatasize must be zero.
80+
calldatasize ;; [calldatasize, req_fee]
81+
jumpi @revert ;; [req_fee]
82+
83+
;; This is the read path, where we return the current fee.
84+
;; Reject any callvalue here to prevent lost funds.
85+
callvalue ;; [value, req_fee]
86+
jumpi @revert
87+
88+
;; Return req_fee.
89+
push 0 ;; [0, req_fee]
90+
mstore ;; []
91+
push 32 ;; [32]
92+
push 0 ;; [0, 32]
93+
return ;; []
94+
95+
handle_input:
96+
;; This is the write path. We expect the computed fee on the stack.
97+
;; Input data has the following layout:
98+
;;
99+
;; +--------+--------+
100+
;; | pubkey | amount |
101+
;; +--------+--------+
102+
;; 48 8
103+
96104
;; Determine if the fee provided is enough to cover the withdrawal request fee.
97105
callvalue ;; [callvalue, req_fee]
98106
lt ;; [callvalue < req_fee]
@@ -162,23 +170,6 @@
162170

163171
stop
164172

165-
read_excess:
166-
;; This is the read path, where we return the current excess.
167-
;; Reject any callvalue here to prevent lost funds.
168-
callvalue ;; [value]
169-
iszero ;; [value == 0]
170-
iszero ;; [value != 0]
171-
jumpi @revert
172-
173-
;; Load excess withdrawal requests and return the value.
174-
push SLOT_EXCESS ;; [excess_reqs_slot]
175-
sload ;; [excess_reqs]
176-
push 0 ;; [0, excess_reqs]
177-
mstore ;; []
178-
push 32 ;; [32]
179-
push 0 ;; [0, 32]
180-
return ;; []
181-
182173
;; ----------------------------------------------------------------------------
183174
;; SYSTEM SUBROUTINE ----------------------------------------------------------
184175
;; ----------------------------------------------------------------------------

test/Test.sol

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,9 @@ abstract contract Test is StdTest {
5050
// system contract matches count.
5151
function assertExcess(uint256 count) internal {
5252
assertStorage(excess_slot, count, "unexpected excess requests");
53+
uint256 expectedFee = computeFee(count);
5354
(, bytes memory data) = addr.call("");
54-
assertEq(toFixed(data, 0, 32), count, "unexpected excess requests");
55+
assertEq(uint256(bytes32(data)), expectedFee, "unexpected fee returned");
5556
}
5657
}
5758

0 commit comments

Comments
 (0)