Skip to content

[simplex] Bundler whitelists in paymaster #1364

Closed

Description

@Wizdave97

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 validatePaymasterUserOp the caller is the EntryPoint, so the only way to see the bundler is tx.origin. Reject when tx.origin is 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 in onAccept. Append the kind to RequestKind, since the first byte of the request body is its index.
  • The new kind needs a matching request and extrinsic in pallet-intents-coprocessor and an encoder in the SDK.

What the design has to handle

  • Simulation. A bundler validates an operation with eth_call before accepting it, and in that call tx.origin is 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 ORIGIN during 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 handleOps to 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 kind
  • modules/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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions