Delegate Call Analyzer
Analyze storage layout compatibility for upgradeable proxy contracts
1. What is Delegatecall?
Delegatecall executes code from another contract in the context of the calling contract. This means it uses the caller's storage, making it essential for upgradeable proxy patterns.
2. How does it work?
Delegatecall preserves msg.sender and msg.value while executing another contract's code in the caller's storage context. Storage slots are accessed by position (0, 1, 2...), not by variable names. This enables proxies to run implementation logic while maintaining proxy state, but requires careful storage layout alignment.
Storage Layout Compatibility
When upgrading a proxy, the new implementation must maintain storage compatibility with the old one. Variables must be in the same order, and new variables should only be appended at the end.
Storage Collisions
Storage collisions occur when proxy and implementation contracts use the same storage slots. This can lead to data corruption and security vulnerabilities. Always ensure proxy uses different slots.
Storage Gaps
A storage gap (e.g., uint256[50] private __gap) reserves storage slots for future variables in upgradeable contracts, allowing you to add new state variables without affecting existing storage layout.
3. Examples
Aave V3 Pool (0x87870Bca3F3fD6335C3F4ce8392D69350B4fA4E2)
EIP-1967 Transparent Proxy with complex storage. Implementation extends base contracts with __gap[50] to allow safe future upgrades.Compound III (0xc3d67e4b63a3c385042d8d6b13e3e0ff485e0994)
Safe Storage Gap Pattern
Add uint256[50] private __gap; at end of implementation. This reserves slots for future vars without breaking existing storage layout.