feat: replace executor bond with execution signature#27
Draft
ozwaldorf wants to merge 6 commits into
Draft
Conversation
Recover the transfer tx's from on-chain from raw signed RLP, tx-type aware (legacy/EIP-2930/EIP-1559). Reconstructs the per-type signing hash and ecrecovers via the vendored ECDSA. Adds RLPParser.itemBounds and readScalar helpers.
Adds the ExecutionAuth typed-data domain (MirageEscrow/1/chainId/escrow) and digest, plus signer recovery, matching the off-chain nomad signer. Bond machinery is untouched here and removed in a follow-up.
Remove the bond from EscrowBase, EscrowNative, and EscrowERC20. collect() now takes (proof, targetBlockNumber, payoutAddress, executionSig) and is gated on an EIP-712 ExecutionAuth signature that must come from the transfer sender -- recovered tx `from` for native, Transfer event `from` for ERC20 -- instead of a bonded-executor claim. A single-shot `collected` flag replaces the bond lifecycle. Payout (reward + payment) goes to the signed payoutAddress. Tests ported: bond/deadline tests removed; collect happy-paths and the front-run/replay/double-collect cases added with a hermetic single-leaf proof fixture; real-fixture MPT validation preserved at the library level.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Implements the escrow side of
docs/builder-funded-escrow-spec.md: removes the executor bond and gatescollect()on an MPT proof plus an EIP-712 execution signature from the account that performed the transfer.What changed
collect()no longer requires a bond or a bonded-executor claim. Instead:recoverTxSender, tx-type aware: legacy / EIP-2930 / EIP-1559),ExecutionAuthsignature from that sender authorizes thepayoutAddress,collectedflag replaces the bond lifecycle as the anti-race guard.New
collectsignature (both flavors), matching the nomad bindings byte-for-byte:collect(proof, targetBlockNumber, payoutAddress, executionSig)This restores executor exclusivity (only the real transfer sender can direct the payout, defeating proof-replay front-running) without locking up capital.
Commits
feat: vendor OpenZeppelin ECDSA libraryfeat: add tx sender recovery to ReceiptValidatorfromrecovery from raw signed RLPfeat: add EIP-712 execution-signature verification to EscrowBaseMirageEscrow/1domain +ExecutionAuthdigestfeat: replace executor bond with execution signatureDesign notes
crates/types/src/contracts.rs): domainMirageEscrow/1/chainId/escrow, structExecutionAuth(address expectedRecipient,uint256 expectedAmount,address payoutAddress).collectselectors verified:0x3fbcc464(Native),0xec6b8596(ERC20).Gas
collect()costs ~+19k gas (~2%) for the signature work — but removingbond()drops a whole ~92-96k-gas transaction, so a full execution cycle is ~73-77k gas cheaper and requires zero locked capital.Testing
47 tests pass. Spec cases covered: wrong-signer revert, observer-cannot-redirect, wrong-escrow replay, double-collect, payout-to-signed-address. Happy paths use a hermetic single-leaf MPT fixture built from a controlled key (so on-chain
recoverTxSender == signerruns end-to-end). Real mainnet/Sepolia/Tempo fixtures still validate multi-node MPT branches at the library level.Out of scope
EscrowERC20Delayed(deferred per spec) and all Titan/sponsorship/EOA-tier logic (nomad-side; zero Titan references insrc/).