diff --git a/EIPS/eip-7002.md b/EIPS/eip-7002.md index 9fe721f56f45bd..acc035fc271462 100644 --- a/EIPS/eip-7002.md +++ b/EIPS/eip-7002.md @@ -67,18 +67,22 @@ with type `0x01` and consists of the following fields: 2. `validator_pubkey`: `Bytes48` 3. `amount:` `uint64` -The [EIP-7685](./eip-7685) encoding of a withdrawal request **MUST** be computed as the follows: +The [EIP-7685](./eip-7685) encoding of a withdrawal request is computed as follows. +Note that `amount` is returned by the contract little-endian, and must be encoded as such. ```python -encoded = WITHDRAWAL_REQUEST_TYPE ++ rlp([source_address, validator_pubkey, amount]) +request_type = WITHDRAWAL_REQUEST_TYPE +request_data = source_address ++ validator_pubkey ++ amount ``` +The size of encoded withdrawal `request_data` is 76 bytes. + #### Withdrawal Request Contract The contract has three different code paths, which can be summarized at a high level as follows: 1. Add withdrawal request - requires a `56` byte input, the validator's public - key concatenated with `uint64` amount value. + key concatenated with a big-endian `uint64` amount value. 2. Excess withdrawal requests getter - if the input length is zero, return the current excess withdrawal requests count. 3. System process - if called by system address, pop off the withdrawal requests for the current block from the queue. @@ -111,7 +115,7 @@ def add_withdrawal_request(Bytes48: validator_pubkey, uint64: amount): queue_storage_slot = WITHDRAWAL_REQUEST_QUEUE_STORAGE_OFFSET + queue_tail_index * 3 sstore(WITHDRAWAL_REQUEST_PREDEPLOY_ADDRESS, queue_storage_slot, msg.sender) sstore(WITHDRAWAL_REQUEST_PREDEPLOY_ADDRESS, queue_storage_slot + 1, validator_pubkey[0:32]) - sstore(WITHDRAWAL_REQUEST_PREDEPLOY_ADDRESS, queue_storage_slot + 2, validator_pubkey[32:48] ++ amount) + sstore(WITHDRAWAL_REQUEST_PREDEPLOY_ADDRESS, queue_storage_slot + 2, validator_pubkey[32:48] ++ uint64_to_little_endian(amount)) sstore(WITHDRAWAL_REQUEST_PREDEPLOY_ADDRESS, WITHDRAWAL_REQUEST_QUEUE_TAIL_STORAGE_SLOT, queue_tail_index + 1) ``` @@ -174,6 +178,12 @@ def read_withdrawal_requests(): # Helpers # ########### +def little_endian_to_uint64(data: bytes) -> uint64: + return uint64(int.from_bytes(data, 'little')) + +def uint64_to_little_endian(num: uint64) -> bytes: + return num.to_bytes(8, 'little') + class ValidatorWithdrawalRequest(object): source_address: Bytes20 validator_pubkey: Bytes48 @@ -192,7 +202,7 @@ def dequeue_withdrawal_requests(): validator_pubkey = ( sload(WITHDRAWAL_REQUEST_PREDEPLOY_ADDRESS, queue_storage_slot + 1)[0:32] + sload(WITHDRAWAL_REQUEST_PREDEPLOY_ADDRESS, queue_storage_slot + 2)[0:16] ) - amount = sload(WITHDRAWAL_REQUEST_PREDEPLOY_ADDRESS, queue_storage_slot + 2)[16:24] + amount = little_endian_to_uint64(sload(WITHDRAWAL_REQUEST_PREDEPLOY_ADDRESS, queue_storage_slot + 2)[16:24]) req = ValidatorWithdrawalRequest( source_address=Bytes20(source_address), validator_pubkey=Bytes48(validator_pubkey), @@ -254,7 +264,7 @@ calldatasize push1 0x38 eq iszero -push2 0x013f +push2 0x01ab jumpi push1 0x11 @@ -300,7 +310,7 @@ swap1 div callvalue lt -push2 0x013f +push2 0x01ab jumpi push1 0x01 @@ -373,7 +383,7 @@ jumpdest dup2 dup2 eq -push1 0xed +push2 0x0158 jumpi dup1 @@ -406,10 +416,68 @@ dup3 push1 0x14 add mstore -swap1 +dup1 +push32 0xffffffffffffffffffffffffffffffff00000000000000000000000000000000 +and +dup3 push1 0x34 add mstore +push1 0x40 +shr +swap1 +push1 0x44 +add +dup2 +push1 0x38 +shr +dup2 +push1 0x07 +add +mstore8 +dup2 +push1 0x30 +shr +dup2 +push1 0x06 +add +mstore8 +dup2 +push1 0x28 +shr +dup2 +push1 0x05 +add +mstore8 +dup2 +push1 0x20 +shr +dup2 +push1 0x04 +add +mstore8 +dup2 +push1 0x18 +shr +dup2 +push1 0x03 +add +mstore8 +dup2 +push1 0x10 +shr +dup2 +push1 0x02 +add +mstore8 +dup2 +push1 0x08 +shr +dup2 +push1 0x01 +add +mstore8 +mstore8 push1 0x01 add push1 0xb6 @@ -421,13 +489,13 @@ add dup1 swap3 eq -push1 0xfe +push2 0x016a jumpi swap1 push1 0x02 sstore -push2 0x0109 +push2 0x0175 jump jumpdest @@ -447,7 +515,7 @@ dup1 push2 0x049d eq iszero -push2 0x0118 +push2 0x0184 jumpi pop @@ -461,13 +529,13 @@ dup3 dup3 add gt -push2 0x012d +push2 0x0199 jumpi pop pop push0 -push2 0x0133 +push2 0x019f jump jumpdest @@ -491,7 +559,6 @@ jumpdest push0 push0 revert - ``` ##### Deployment @@ -508,17 +575,17 @@ The withdrawal requests contract is deployed like any other smart contract. A sp "maxPriorityFeePerGas": null, "maxFeePerGas": null, "value": "0x0", - "input": "0x61049d5f5561014380600f5f395ff33373fffffffffffffffffffffffffffffffffffffffe1460a0573615156028575f545f5260205ff35b366038141561013f5760115f54600182026001905f5b5f82111560595781019083028483029004916001019190603e565b90939004341061013f57600154600101600155600354806003026004013381556001015f35815560010160203590553360601b5f5260385f601437604c5fa0600101600355005b6003546002548082038060101160b4575060105b5f5b81811460ed5780604c02838201600302600401805490600101805490600101549160601b83528260140152906034015260010160b6565b910180921460fe5790600255610109565b90505f6002555f6003555b5f548061049d141561011857505f5b60015460028282011161012d5750505f610133565b01600290035b5f555f600155604c025ff35b5f5ffd", + "input": "0x61049d5f556101af80600f5f395ff33373fffffffffffffffffffffffffffffffffffffffe1460a0573615156028575f545f5260205ff35b36603814156101ab5760115f54600182026001905f5b5f82111560595781019083028483029004916001019190603e565b9093900434106101ab57600154600101600155600354806003026004013381556001015f35815560010160203590553360601b5f5260385f601437604c5fa0600101600355005b6003546002548082038060101160b4575060105b5f5b8181146101585780604c02838201600302600401805490600101805490600101549160601b83528260140152807fffffffffffffffffffffffffffffffff0000000000000000000000000000000016826034015260401c906044018160381c81600701538160301c81600601538160281c81600501538160201c81600401538160181c81600301538160101c81600201538160081c81600101535360010160b6565b910180921461016a5790600255610175565b90505f6002555f6003555b5f548061049d141561018457505f5b6001546002828201116101995750505f61019f565b01600290035b5f555f600155604c025ff35b5f5ffd", "v": "0x1b", "r": "0x539", - "s": "0x54ebd8d935ccd710", - "hash": "0x2a81b690e499cd188ec78719659600d2f9bb953692bfd393daaac471e8d89d5b" + "s": "0x48655fec580f6877", + "hash": "0xcf76a9eb8c38b162c697b6e58669dc2546284e84d752d79af9c4e49be6bdcb39" } ``` ``` -Sender: 0x38748F0B5Ece4A246d108BB00eD6F17c3062BbD7 -Address: 0x05F27129610CB42103b665629CB5c8C00296AaAa +Sender: 0xAC6AfB9d8491e8b397F65331Ce41e338cBfe1048 +Address: 0x0511Ce19514e1298Fba96de582652A016E2CAaAa ``` ### Consensus layer