docs(cketh): specify ETH deposits on the shared address and sweeper delegate rotation - #11491
docs(cketh): specify ETH deposits on the shared address and sweeper delegate rotation#11491gregorydemay wants to merge 6 commits into
Conversation
…d sweeper delegate rotation Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01X44H4nAU65nAexEUvG15MK
There was a problem hiding this comment.
🟡 Changes recommended
The rotation design has an unresolved in-flight authorization race and contradictory nonce, gas, and re-attestation documentation.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Pull request overview
Documents shared ckETH/ckERC20 deposit addresses and safe sweeper-delegate rotation.
Changes:
- Specifies ETH deposit and balance-scanning flows.
- Defines lazy delegate rotation and nonce tracking.
- Adds rotation testing and delivery plans.
File summaries
| File | Description |
|---|---|
rs/ethereum/cketh/docs/deposit_from_cex.md |
Extends the CEX deposit design for ETH and delegate rotation. |
Review details
Suppressed comments (1)
rs/ethereum/cketh/docs/deposit_from_cex.md:1505
- The claimed saving understates the cost of the currently skipped tuple. EIP-7702 only grants the 12,500 existing-account refund after the tuple passes the nonce check; a stale nonce is skipped before that point and therefore costs the full 25,000 gas.
The second row is new behaviour too: an already-delegated address no longer
pays the 25'000 − 12'500 gas of a skipped tuple on every sweep, which is
- Files reviewed: 1/1 changed files
- Comments generated: 3
- Review effort level: Balanced
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| happen anyway — an address that never receives another deposit is never | ||
| rotated, costs nothing (`R13`) and is harmless on the old delegate. | ||
|
|
||
| 1. **Delegation record.** For every deposit address the minter keeps |
There was a problem hiding this comment.
is this needed? There is already authorizations: BTreeMap<AuthorizationRequest, TransactionSignature> in AutomaticDeposits
There was a problem hiding this comment.
🤖 Not as a separate structure. The existing map records what was signed, and signed is not applied: a tuple may sit in a sweep still in flight or never sent, and after a delegate change the map holds tuples for both delegates at the same nonce. What is missing is only which stored authorizations were applied, and by which sweep, derived from the finalized sweeps. From that mark the delegation follows: the applied tuple with the highest nonce names the current delegate and the nonce is one above it. Reworded in 16ea366 so the record is the existing store annotated with an applied mark, not a new delegation field.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01X44H4nAU65nAexEUvG15MK
There was a problem hiding this comment.
🟡 Changes recommended
Nonce replay ordering, orphaned authorizations, finality, and helper migration can violate the documented rotation guarantees.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Review details
Suppressed comments (3)
rs/ethereum/cketh/docs/deposit_from_cex.md:1532
- Re-anchoring a record derived from finalized transactions to
latestcan import an authorization from an unfinalized block. If that block is reorged, the recorded nonce remains ahead of the chain and the next rotation tuple is skipped, causing another failed sweep. Use the finalized block tag here; the existingfinalized_transaction_countpath already demonstrates that this tag is supported.
is swept again the minter re-reads `eth_getTransactionCount(address,
latest)` with the usual consensus (the `latest_transaction_count` helper
already used for the sweeper's own nonce) and re-anchors the record on it.
rs/ethereum/cketh/docs/deposit_from_cex.md:1574
- Lazy re-attestation alone does not make a helper replacement safe. The minter currently tracks only one
EthOrErc20DepositWithSubaccounthelper address, andUpgradeArgreplaces it in place; meanwhile, an in-flight sweep or the old-tuple re-carry rule above can still execute the old delegate and emit its event from the old helper. Once the scraper switches, that successful deposit event is never observed or minted. Helper rotation needs either a drain/finality barrier plus a defined scrape cutoff, or concurrent scraping of both helpers during migration.
* A new delegate wired to the **same helper** needs no new attestations: the
attestation digest names the helper, never the delegate. A new helper needs
both a new delegate (the helper is one of its immutables) and, since
attestations are keyed by helper, one new attestation per address at its
next sweep — the same lazy pattern, one more signature.
rs/ethereum/cketh/docs/deposit_from_cex.md:1555
- An unapplied stored tuple is not guaranteed to have a sweep that can finalize. The current enqueue flow records
AuthorizedDepositAddressbeforeenqueue_sweep, and that enqueue can return without creating a request when the sweeper lacks gas (src/sweep/mod.rs:158-169). After a delegate change, an address with only an ETH item would then wait forever on this orphaned old-delegate tuple. Specify a path that applies such a tuple (for example, a tuple-only/old-compatible transaction) or distinguish unattached signatures from genuinely in-flight ones.
marked applied, it is still the one that will apply: an ERC-20 item
**re-carries that tuple** (both delegates serve `sweepErc20`, and the
tuple is idempotent — whichever sweep mines first applies it, the other
skips it), while an ETH item **waits** in the queue until that tuple's
sweep is finalized; the rotation is then signed at `n + 1`. Two in-flight
- Files reviewed: 1/1 changed files
- Comments generated: 1
- Review effort level: Balanced
…etried Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01X44H4nAU65nAexEUvG15MK
… record replays Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01X44H4nAU65nAexEUvG15MK
There was a problem hiding this comment.
🟢 Approval recommended
The changes are documentation-only and the only issue found is a minor spelling consistency nit.
Review details
Suppressed comments (1)
Previously missed (1) — in code that hasn't changed since the last review.
rs/ethereum/cketh/docs/deposit_from_cex.md:1516
- Spelling is inconsistent within this doc: nearby occurrences use American English ("behavior"), but this line uses British English ("behaviour"). For consistency, consider using "behavior" here as well.
- Files reviewed: 1/1 changed files
- Comments generated: 0 new
- Review effort level: Lite
…now does Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01X44H4nAU65nAexEUvG15MK
There was a problem hiding this comment.
🟢 Approval recommended
The documentation changes are internally consistent and address the previously identified nonce, concurrency, gas, and attestation issues.
Review details
- Files reviewed: 1/1 changed files
- Comments generated: 0 new
- Review effort level: Balanced
…nt does Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01X44H4nAU65nAexEUvG15MK
There was a problem hiding this comment.
🔵 Needs a closer look
The design governs high-risk fund sweeping, nonce reconstruction, and delegate rotation and warrants final human validation.
Review details
- Files reviewed: 1/1 changed files
- Comments generated: 0 new
- Review effort level: Balanced
Why
What
deposit_eth, the ETH pair in the balance batcher, and anETH | ERC-20asset per registered pair.R18and a section on changing the sweeper delegate: a per-address delegation record derived from finalized sweeps, tuple-less sweeps of delegated addresses, lazy re-delegation at the recorded nonce, a chain re-read only to repair the record after a reverted sweep, and gating of ETH sweeps on the delegate an address actually runs.🤖 Generated with Claude Code
https://claude.ai/code/session_01X44H4nAU65nAexEUvG15MK