You let an agent pull USDC from a Coinbase Smart Wallet with Spend Permissions, and you want one
daily limit for the agent however many permissions it holds. Spend Permissions count each
allowance per permission and per fixed period, so a second permission, or two payments either
side of a period boundary, can pass the daily budget you meant. AccountCapSpender is a spender
contract that counts every payment through it, from every permission that names it, against one
rolling window.
Unaudited. Testnet only.
AccountCapSpendermoves real tokens on behalf of an agent and has not had an independent audit. Read solidity/README.md before deploying it, and don’t point it at a mainnet SpendPermissionManager until an audit is complete.
$ cd solidity
$ forge create src/AccountCapSpender.sol:AccountCapSpender \
--rpc-url "$BASE_SEPOLIA_RPC_URL" \
--private-key "$DEPLOYER_KEY" \
--constructor-args \
"$SPEND_PERMISSION_MANAGER" \
"$AGENT" \
"$CAP_IN_ATOMIC_UNITS" \
"$WINDOW_SECONDS" \
"$PER_PAYMENT_IN_ATOMIC_UNITS" \
"[\"$PAYEE\"]"
pay(permission, amount, payee), and every permission the account grants the contract shares
one rolling cap.pay, only to an allowlisted payee, at most the per-payment max at a
time.The contract’s checks also run without Foundry, on an in-process EVM:
$ cd solidity/evm && npm install && node check.mjs ..
npx walletcap-crash-test runs Coinbase’s SpendPermissionManager v1.0.0 and Smart Wallet on an
in-process EVM, from the runtime code deployed on Base mainnet. A Smart Wallet holds $1,000 of a
test token that stands in for USDC, and grants the agent permissions of $150 a day. On
walletcap’s side, the wallet grants the same permissions to AccountCapSpender.
| Event | SpendPermissionManager | AccountCapSpender |
|---|---|---|
| a second permission | $300 pulled · $150 over | $150 pulled · $0 over |
| across a period boundary, 1 second apart | $300 pulled · $150 over | $150 pulled · $0 over |
The result was the same in all eight runs on 6 November 2026. Within one permission and one
period the manager holds: the crash test’s suite checks that a fourth $50 is refused with
ExceededSpendPermission. AccountCapSpender refuses the second $150 with OverBudget.