Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Prototype external storage contract for 7702 CoinbaseSmartWallets #108

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

amiecorso
Copy link

@amiecorso amiecorso commented Feb 22, 2025

TL;DR: Implemented an external storage pattern for the CoinbaseSmartWallet to better handle lacking storage guarantees between EIP-7702 delegate transitions. The solution uses a singleton storage contract that namespaces wallet state by both the wallet's address AND its code hash (EXTCODEHASH). This ensures:

  • Only the intended delegate implementation can access its storage
  • Storage remains isolated even if the EOA switches between different delegates
  • Storage access is protected by EXTCODEHASH validation, preventing unauthorized access from other delegates operating at the same address
  • While proxy upgrades would require storage migration (due to EXTCODEHASH changes), this tradeoff provides stronger guarantees against storage corruption during delegate transitions

The key innovation is using EXTCODEHASH validation to ensure storage can only be accessed by the specific implementation we expect, rather than relying solely on address-based access control or traditional storage namespacing.

Longer discussion from slack:
"Currently, developers are responsible for preventing storage slot collisions when upgrading EOAs to smart accounts. While Storage Namespace solutions can reduce the likelihood of such conflicts, they do not fully eliminate the risk of EOA storage being overwritten."

I keep thinking that it could be interesting to basically use a separate contract to store wallet state (for example, in the case of CBSW, we're just talking about ownership state). The only issue is that access to read/write on this separate storage contract would presumably need to be gated by something like msg.sender == address(this) , or some other EOA-based signature or auth scheme, which isn't really any more robust against meddling from foreign delegates since they also operate as address(this). Perhaps slightly more robust than namespaced storage which is more likely to be interacted with inadvertently, but still lacks true guarantees.

Another possible idea would be to gate access to the separate storage based on msg.sender == address(this) AND msg.sender.EXTCODEHASH == our_expected_eip7702proxy_address_hash . This would at least guarantee that only OUR delegate is able to access storage at this separate storage contract. The issue with that would be that upgrading the proxy (which would lead to a different EXTCODEHASH) would essentially require re-establishing or migrating ownership from the original system's state to a completely blank storage slate. That said, perhaps upgrading the proxy is an unlikely enough situation (after all, natively deployed smart wallets can't upgrade their proxy) that this blank-slate migration/re-initialization of some sort would be considered acceptable.

@cb-heimdall
Copy link
Collaborator

cb-heimdall commented Feb 22, 2025

🟡 Heimdall Review Status

Requirement Status More Info
Reviews 🟡 0/1
Denominator calculation
Show calculation
1 if user is bot 0
1 if user is external 0
From .codeflow.yml 1
Additional review requirements
Show calculation
Max 0
0
From CODEOWNERS 0
Global minimum 0
Max 1
1
1 if commit is unverified 0
Sum 1

@amiecorso amiecorso changed the title prototype external storage contract Prototype external storage contract for 7702 CoinbaseSmartWallets Feb 22, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

2 participants