Update EIP-8282: Sync specification with sys-asm@83f9801 - #1
Conversation
b28dac6 to
64a1d31
Compare
| | `TARGET_EXIT_REQUESTS_PER_BLOCK` | `2` | Per-block request count above which the fee rises for the exit contract | | ||
| | `MIN_REQUEST_FEE` | `1` | Minimum request fee, in wei | | ||
| | `REQUEST_FEE_UPDATE_FRACTION` | `17` | Controls the fee's rate of change | | ||
| | `EXCESS_INHIBITOR` | `2**256 - 1` | Sentinel value written to the excess slot to inhibit non-system calls | |
There was a problem hiding this comment.
this constant doesn't exist on the EIP-8282 contracts
There was a problem hiding this comment.
Hey, we could rename to INHIBITOR if you'd rather have it match the source verbatim, but I chose the EXCESS_ prefix because I thought it made the spec-side slot semantics easier to understand (since it's the excess slot that is being inhibited). Note that it is the same kind of thing with other names in the constants table: MAX_DEPOSIT_REQUESTS_PER_BLOCK = 64 doesn't exist in the source either, it's just push 64 at src/builder_deposits/main.eas:195. Same for REQUEST_FEE_UPDATE_FRACTION = 17 (push 17) and BUILDER_MIN_DEPOSIT = 1000000000000000000 (push 1000000000000000000).
The value (1 << 256) - 1 is in the audited bytecode: sys-asm defines it as #define INHIBITOR = (1 << 256) - 1 in both src/builder_deposits/main.eas:31 and src/builder_exits/main.eas:32, and the exit constructor writes it inline (src/builder_exits/ctor.eas:7, comment: "Store 0xff..ff as a temporary excess value to avoid requests being queued before the fork"). Happy to do whichever you prefer.
There was a problem hiding this comment.
using EXCESS_INHIBITOR is confusing since this exists in other contracts in that repo is different, but I am not an expert on the contrats tbh, so it would be better to open a PR on the main repo, it would be best to get feedback from Felix on this
- Define INHIBITOR = 2**256 - 1 constant (renamed from EXCESS_INHIBITOR
to match the source-level macro in sys-asm@83f9801)
- Define storage layout: slot 0 stored_excess, slot 1 count,
slot 2 queue_head, slot 3 queue_tail, slot 4+ queued records
- Specify the ordered system-call transition:
1. dequeue (construct request_data, advance head; full drain resets
both head and tail, dequeued slots not cleared)
2. non-empty calldata sets stored_excess to INHIBITOR
3. empty calldata clears INHIBITOR to zero if set, otherwise
updates stored_excess to max(0, stored_excess + count - target)
4. reset count to zero
5. return request_data
- Specify that the inhibition check gates all non-system calls before
dispatch (write path and fee getter)
- Define effective_excess = stored_excess + max(0, count - target)
- Specify the deposit LOG0 emits the 184-byte input verbatim
(amount big-endian in both queue storage and log)
- Add Contract upgrade subsection explaining the rationale for the
reversible inhibition: a future predeploy upgrade can deploy a
new contract, continue draining the old one through empty-calldata
system calls, and reject new requests on the old contract by sending
non-empty calldata (setting INHIBITOR)
- Add EIP-7997 to requires (the CREATE2 factory used for deployment)
- Update reference links to sys-asm@83f9801
- Open question ethereum#2 (pre-fork count accumulation): noted as confirmed
intentional per Felix (2026-08-12) — he confirmed the inhibition
and drain-while-inhibited behaviors, which together imply the
multi-block count accumulation is also intended
64a1d31 to
b759aae
Compare
|
The commit b759aae (as a parent of 771e39e) contains errors. |
Stacked on top of ethereum#11869. This PR syncs the EIP-8282 specification text with the reference implementation at ethereum/sys-asm@83f9801.
Changes
EXCESS_INHIBITORconstant: DefineEXCESS_INHIBITOR = 2**256 - 1as the sentinel value written to the excess slot to inhibit non-system calls.stored_excesstoEXCESS_INHIBITOR(non-system calls inhibited until cleared).countdefinition: Definecountas the number of successful submissions since the last system call, stored inSLOT_COUNTand reset to zero by the system call.effective_excessformula: Specifyeffective_excess = stored_excess + max(0, count - TARGET_REQUESTS_PER_BLOCK), withcountread before incrementing for the current request.max(0, old_excess + count - target); (4) always reset count.builder_exitslabel (was duplicated asbuilder_deposits).requires: Add EIP-7997 torequires(the CREATE2 factory used for deployment).Open questions
Deployment in the activation block: This PR does not take a position on whether contract deployment in the activation block is valid. The specification currently says contracts MUST be deployed before the fork, but the exact validity of same-block deployment is left as an open question for reviewers.
Multi-block pre-fork count accumulation: Because the deposit contract starts with
count = 0and the write path is active from deployment, thecountcan accumulate across multiple pre-fork blocks without being reset (since no system calls occur pre-fork). Whether this behavior is intentional or should be addressed is left as an open question.