EVM: Add settler function to set safeguards with a signature - #84
Draft
alavarello wants to merge 2 commits into
Draft
EVM: Add settler function to set safeguards with a signature#84alavarello wants to merge 2 commits into
alavarello wants to merge 2 commits into
Conversation
Adds setSafeguardWithSignature so a safeguard can be set on behalf of a user by anyone holding the user's EIP-712 signature, instead of requiring the user to be msg.sender. The signature is bound to a per-user nonce and a deadline to prevent replays of stale authorizations. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
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.
What
Adds
Settler.setSafeguardWithSignature, which lets anyone submit a safeguard on a user's behalf as long as they carry that user's EIP-712 signature. Until nowsetSafeguardderived the target user frommsg.sender, so the user had to send the transaction themselves.It rejects a past deadline, consumes the user's nonce, recovers the signer from the EIP-712 hash of
UserSafeguard(address user,bytes safeguard,uint256 nonce,uint256 deadline), and requires that signer to equaluserbefore delegating to the same_setSafeguardinternal thatsetSafeguarduses. Storage, replacement semantics, and theSafeguardSetevent are therefore identical between the two entry points.The signature is bound to a per-user nonce (
getUserSafeguardNonce, a new public mapping appended after the existing storage so the upgrade stays layout-safe) plus a deadline. The nonce stops a signature from being replayed to re-apply a stale safeguard after the user has changed it; the deadline bounds how long a signed-but-never-submitted authorization stays usable. The typed struct and its type hash live incontracts/safeguards/Safeguards.solasUserSafeguardandSafeguardsHelpers, mirroring howValidation/IntentsHelpersare organized inIntents.sol.Two decisions worth review
No ERC-1271 support. The first implementation used OpenZeppelin's
SignatureChecker, which would have accepted signatures from smart-account users. It cost 882 bytes of deployed bytecode and pushedSettlerto 24658 bytes, past the 24576-byte EIP-170 limit even with the optimizer at 1000 runs. It now usesECDSA.recover, which is also how proposal and validation signatures are verified elsewhere in the same contract. Smart-account users aren't locked out:SmartAccountContract.callis callable by its owner, so an owner can still route a call to the plainsetSafeguard.Contract size headroom is nearly gone.
Settleris now 24380 bytes, leaving 196 bytes under the EIP-170 limit, down from 800 before this change. The next addition to this contract will likely need library extraction or a comparable size reduction.Tests
13 new cases in
packages/evm/test/Settler.test.ts, following the nested-contextconvention of the neighbouringsetSafeguardblock. Every case submits the transaction from an account other than the user, so themsg.senderindependence is what's actually exercised.Covered: setting with no prior safeguard, replacing an existing one, nonce consumption (and that it leaves another user's nonce untouched), plus reverts for a replayed signature, a signature from another account, signatures bound to a different user / safeguard / nonce / deadline, and an expired deadline. The signing helper is
signUserSafeguardintest/helpers/safeguards.ts, built the same way as the existingsignProposal.Full EVM suite passes at 460 tests and both linters are clean.
🤖 Generated with Claude Code