Skip to content

Changes from CBSWv2 research - #46

Open
amiecorso wants to merge 10 commits into
mainfrom
amie/cbswv2-research
Open

Changes from CBSWv2 research#46
amiecorso wants to merge 10 commits into
mainfrom
amie/cbswv2-research

Conversation

@amiecorso

@amiecorso amiecorso commented Jul 28, 2026

Copy link
Copy Markdown
Collaborator

Captures several changes surfaced while researching a CBSWv1 -> v2 migration on EIP-8130.

1. DefaultAccount: single-call execute

Adds execute(address,uint256,bytes) alongside executeBatch — a single-call convenience with the same authorization and lock-gating. Its selector is 0xb61d27f6, matching the widely deployed execute(address,uint256,bytes) ABI, so integrations that call that ABI directly work against an 8130 account.

2. DefaultAccount is high-rate-payer-safe by default; remove CanonicalHighRatePayerAccount

DefaultAccount now blocks outbound ETH value transfers while the account is locked in AccountConfiguration (on both execute and executeBatch); zero-value calls are unaffected. This makes lock-respecting the default behavior, so the separate CanonicalHighRatePayerAccount is removed. High-rate admission is ultimately a node allowlist over an ERC-1167 clone of DefaultAccount (an immutable proxy or another conforming implementation can be allowlisted later if needed). Deploy.s.sol and the README are updated to the single account.

3. PolicyManager: remove executeAttested

Removes the executeAttested entrypoint. The account-acting execute path is EIP-8130-native: it resolves the acting actorId solely from the transaction-context precompile, and where the precompile is absent the acting actorId is 0 and the call reverts NoActivePolicy. The external-caller paths (executeFor / executeForMany) derive identity from msg.sender and work on any chain. There is deliberately no ERC-4337 / off-8130 path for execute: a policy-gated session key carrying a PAYER scope cannot be safely confined under 4337, so the manager will not accept an account-attested identity.

4. EIP7702ProxyFor8130 (new)

Ports the minimal EIP-8130-native EIP-7702 delegation proxy from base-account-v2 into this repo for audit. It adds no authorization of its own beyond a registry-gated setImplementation recovery function and a default-implementation fallback; it does not override EOA key behavior (that is governed by AccountConfiguration).

Testing

forge test: 331 pass, 0 fail. forge fmt --check clean. Deploy.s.sol compiles and previews. Coverage added for single-call execute (incl. lock-gating), a PolicyManager reentrancy-guard case, and the new proxy (10 cases); removed the executeAttested and CanonicalHighRatePayerAccount suites. Tests and new-contract natspec conform to the team style/test conventions (harness test naming, per-test natspec, fuzz-by-default).

amiecorso and others added 10 commits July 28, 2026 11:03
- DefaultAccount: add single-call execute(address,uint256,bytes) (V1-compatible selector 0xb61d27f6)
- CanonicalHighRatePayerAccount: lock-gate the new execute() outbound value transfer
- PolicyManager: remove executeAttested; resolve the acting actorId from the tx-context
  precompile with a fallback to the account's own ITransactionContext surface, and enforce
  actor expiry on execute()
- Add EIP7702ProxyFor8130: minimal EIP-8130-native 7702 delegation proxy (ported from
  base-account-v2), registry-gated setImplementation + default-implementation fallback,
  no EOA-key override

Unreviewed prototype for team review.
- Require the resolved actor be gated to this manager (getPolicyManager == address(this)),
  mirroring the external path; closes an off-8130 confinement gap
- Reject actorId == 0 explicitly (the "no acting actor" sentinel)
- Require exact 32-byte returns in _resolveActorId so malformed data degrades to "no actor"
  instead of reverting decode
- Document the off-8130 account-side trust assumption in NatSpec
- Tests: add manager-mismatch rejection + execute() reentrancy regression coverage
…tePayerAccount

- DefaultAccount now blocks outbound value transfers while locked (execute + executeBatch)
  via a shared _isLocked() helper, with an AccountLocked error — high-rate-payer-safe by default
- Remove CanonicalHighRatePayerAccount: its lock-gate now lives in the base account. High-rate
  admission is ultimately a node allowlist, so an immutable ERC-1167 clone of DefaultAccount (or
  another allowlisted implementation) is the admission path; an immutable proxy can be added later
  if ever needed
- Deploy.s.sol: deploy only DefaultAccount and log its ERC-1167 match bytecode for high-rate payers
- README: document the single lock-respecting account + allowlist-based admission
- Tests: fold lock-gating + execute() coverage into DefaultAccount.t.sol; drop the
  CanonicalHighRatePayerAccount suite
A policy-gated session key carrying a PAYER scope cannot be safely confined under
ERC-4337, so policies are supported ONLY via native EIP-8130 protocol dispatch.

- Remove the account-exposed ITransactionContext fallback in actor resolution: execute()
  reads the transaction-context precompile only; where it is absent the acting actorId is 0
  and the call reverts NoActivePolicy (it just fails)
- Revert execute() to the protocol-only form: drop the fallback-motivated manager-match,
  actorId==0, and local expiry checks (the 8130 protocol gate already guarantees these on the
  only reachable path)
- Restore _actingActorId (precompile-only); document that there is deliberately no
  account-attested / 4337 policy path
- Tests: drop the account-fallback / precedence / expiry / manager-match cases; keep the
  execute() reentrancy regression test
…o-EOA-fallback invariant

Co-authored-by: OpenCode <opencode-noreply@coinbase.com>
…comment

Co-authored-by: OpenCode <opencode-noreply@coinbase.com>
…r works on any chain

Co-authored-by: OpenCode <opencode-noreply@coinbase.com>
Co-authored-by: OpenCode <opencode-noreply@coinbase.com>
@amiecorso
amiecorso requested a review from chunter-cb July 29, 2026 21:51
@amiecorso
amiecorso marked this pull request as ready for review July 29, 2026 21:51
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