Skip to content

feat: reusable call checkers with a clone factory (ENGR-1440) - #31

Closed
LeoFranklin015 wants to merge 2 commits into
masterfrom
leo/engr-1440-reusable-call-checkers
Closed

LeoFranklin015 wants to merge 2 commits into
masterfrom
leo/engr-1440-reusable-call-checkers

Conversation

@LeoFranklin015

Copy link
Copy Markdown
Contributor

Reusable call checkers for ENGR-1440. A permission entry can already point at a checker. These contracts make checkers reusable: three rule templates written once, and each rule is a small clone of a template with its settings stored in the clone's code.

What's added

  • CheckerBase: implements ICallChecker once. Refuses when called as the bare template, otherwise loads the clone's settings and calls _check.
  • Templates:
    • ArgIn: the argument at a slot is one of a list. CheckerLib.ACCOUNT in the list means the calling wallet.
    • ArgAtMost: the argument at a slot is at most a number, per call.
    • ValueAtMost: the ETH sent is at most a number.
  • CheckerLib: reads the selector and argument slots the same way the manager does.
  • CheckerFactory: deploy and predict with salt 0, so the same rule always lands at the same address. Deploying a rule that already exists returns it instead of reverting.
  • DeployCheckers.s.sol: deploys through the Safe singleton factory.

The manager is unchanged.

Tests

  • 36 unit tests, each going through a real clone.
  • 11 integration tests against the real manager with 7702 wallets: AND across rules, wildcard selectors, the ACCOUNT rule, shared clones and gas budgets.
  • 4 fork tests on Base Sepolia against the real Uniswap router. They skip unless BASE_SEPOLIA_RPC_URL is set.

Full suite: 190 passing, plus the 4 fork tests when the RPC is set.

Base Sepolia

Contract Address
CheckerFactory 0x48C9554e534c84eF5B4dcc1E85371785477DBC1E
ArgIn 0x40F24cbdd8C23699647001d043D005B9b2114479
ArgAtMost 0x70f37b4DBE07b6494Be359b937955bF59f0C330B
ValueAtMost 0x32AB3E19000D0150b89A56a53A2D15CBa71fe535

A live run against the deployed manager:

  • One grant deployed four rules and approved a permission using them.
  • A payment to the allowed recipient went through.
  • A swap paying the wallet went through.
  • Four calls breaking the rules were refused with CheckerRejectedCall.

A second grant reused all four rules without deploying anything.

Left for the SDK

  • Only trust checkers cloned from these three templates. The factory clones anything that has code.
  • Refuse slots on bytes, string or array arguments. There the slot holds an offset, not the value.
  • Add a ValueAtMost rule next to ArgIn or ArgAtMost on payable calls.
  • Show ACCOUNT (0xAcc0…Acc0) as "you".

@linear

linear Bot commented Nov 12, 2026

Copy link
Copy Markdown

ENGR-1440

@justalab-agents justalab-agents Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This PR introduces a suite of reusable, deterministically-deployable call-checker contracts (ArgAtMost, ArgIn, ValueAtMost) built on a clone-based architecture where each checker is an immutable minimal proxy with its settings baked into the bytecode, deployed via CheckerFactory. The contracts are accompanied by unit and integration tests (including a fork test) and a deployment script using the Safe Singleton Deployer for consistent cross-chain addresses. Notably, the CI pipeline is currently failing (exit code 1), which should be resolved before merging.

Findings outside the diff

These sit on lines this PR did not change, but this PR is what makes them wrong. They cannot be posted as inline comments.

Reviewer callouts (2)

Non-blocking observations. Nothing here needs to change before merge.

  • .github:1 — "The ubuntu-latest label will migrate to Ubuntu 26 beginning October 19, 2026. For more information, see actions/runner-images#14748"
  • .github:1 — "The ubuntu-latest label will migrate to Ubuntu 26 beginning October 19, 2026. For more information, see actions/runner-images#14748"

@LeoFranklin015

Copy link
Copy Markdown
Contributor Author

Closing: the call checkers move to their own repo, JustaLab-co/call-checkers, set up like this one for multichain deploys. The manager is unchanged.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant