Repository navigation
[simplex] Bundler whitelists in paymaster #1364
Description
Simplex paymaster contract should provide a governance controlled call for whitelisting accepted bundler EOAs.
UserOps from unwhitelisted bundlers should be rejected.
Why
A bundle is an ordinary transaction, and user operations are not tied to the bundler that submits them. On a chain with a public mempool anyone can copy the operations out of a pending bundle and land them first. The original bundle then reverts and the bundler pays the gas for nothing.
If the paymaster only pays when the transaction comes from one of our bundler wallets, a copied operation fails for everyone else. The paymaster address is part of what the solver signs, so it cannot be swapped out.
How it would work
- In
validatePaymasterUserOpthe caller is the EntryPoint, so the only way to see the bundler istx.origin. Reject whentx.originis not on the list. - The list lives in the paymaster's storage, taken from
__gap, and is changed by a new governance request kind handled inonAccept. Append the kind toRequestKind, since the first byte of the request body is its index. - The new kind needs a matching request and extrinsic in
pallet-intents-coprocessorand an encoder in the SDK.
What the design has to handle
- Simulation. A bundler validates an operation with
eth_callbefore accepting it, and in that calltx.originis whatever address the bundler simulates from, not its signing wallet. rundler uses a fixed address,0x0643866dA50efE0b055Cd15aF95191968c8411b5, for validation and gas estimation. That address has to pass the check too, or every sponsored operation is rejected before it reaches a bundle. It is derived from a hash and no one holds a key for it, so listing it does not let anyone send a real transaction. - Only our bundler can carry these operations. ERC-7562 bans
ORIGINduring validation, so bundlers that enforce the validation rules refuse a paymaster that reads it. That is the intent, but it leaves no third-party fallback wherever the list is enforced. Decide whether an empty list means "any bundler", so the check can stay off on a chain. - Bundler wallets must be plain EOAs. EntryPoint v0.9 requires the caller of
handleOpsto be the transaction sender and to have no code. A listed wallet cannot be delegated through EIP-7702 or sit behind a submission proxy. - Key rotation goes through governance. Adding or replacing a bundler wallet takes a governance request per chain. Listing a spare wallet per chain keeps a rotation from stopping sponsorship.
Ship with the v0.9 migration
#1365 also upgrades the paymaster. One governance upgrade per chain can cover both.
Affected files
evm/src/utils/SimplexPaymaster.sol: storage for the list, the check in validation, the new request kindmodules/pallets/intents-coprocessor: request kind and extrinsic- SDK: encoder for the new request
evm/tests/foundry/SimplexPaymasterTest.t.sol
Acceptance
- An operation in a bundle sent by a listed wallet is sponsored
- The same operation sent by any other wallet fails paymaster validation
- The bundler's own validation and gas estimation calls pass
- Governance can add and remove a wallet on each chain
Activity