Solidity theorytheory 0/50 · 0%
Patterns · hard

32. Proxies and upgradeability

Separating storage from logic.

A proxy holds the storage and forwards all calls by `delegatecall` to an implementation address. Upgrading means pointing at new logic. Storage layout must stay append-only, and EIP-1967 defines fixed slots for the implementation and admin so they cannot collide.

fallback() external payable {
    address impl = _implementation();
    assembly {
        calldatacopy(0, 0, calldatasize())
        let ok := delegatecall(gas(), impl, 0, calldatasize(), 0, 0)
        returndatacopy(0, 0, returndatasize())
        switch ok case 0 { revert(0, returndatasize()) } default { return(0, returndatasize()) }
    }
}

Implementations use `initialize()` instead of a constructor, guarded so it can run only once.

Check your understanding

  1. 1. Where does a proxy keep state?

  2. 2. Why does an implementation use `initialize()`?

  3. 3. What must be true of upgrades?