FV-SOL-7 Proxy Insecurities
TLDR
Upgradeability is essential for maintaining and improving deployed contracts and fixes over time
Due to their nature, they are often misunderstood or implemented insecurely
Code
Classifications
delegatecall Storage Collision (FV-SOL-7-C1)
delegatecall
is a function call that allows a contract to run code from another contract while preserving the original caller's context, including storage, msg.sender
, and msg.value
Since delegatecall
runs in the storage context of the caller, if the contract calls delegatecall
on user-supplied input, an attacker can input an address to a malicious contract that can manipulate the storage of the calling contract, potentially overwriting sensitive variables or stealing funds
If the target contract has a different storage layout, it may overwrite or corrupt crucial storage variables in the calling contract
Function Selector Collision (FV-SOL-7-C2)
When two functions in the implementation contract have the same function selector, unintended functions can be called, leading to incorrect behavior or security loopholes
Centralized Update Control (FV-SOL-7-C3)
If the upgrade process is too centralized, it creates a single point of failure, and generaly considered unethical to the users
Uninitialized Proxy (FV-SOL-7-C4)
If the initializer function isn’t called during deployment, it may leave critical variables in an unprotected state
Same goes for accidentally allowing initializer functions to be called again in the proxy pattern which can result in re-initializing the contract, doing so gaining ability to modify data
Mitigation Patterns
Validate Addresses Being Called (FV-SOL-7-M1)
Ensure that the address used with delegatecall
is fixed or restricted to trusted sources
Limit State Changes (FV-SOL-7-M2)
Be cautious of contracts that use delegatecall
to avoid unintended storage changes
__gap Array (FV-SOL-7-M3)
The __gap
variable is a common technique used in Solidity's upgradeable contract design to prevent storage layout issues during contract upgrades. It is essentially a reserved area in the contract's storage layout that provides "padding" for future storage variables
Actual Occurrences
Content
https://www.halborn.com/blog/post/delegatecall-vulnerabilities-in-solidity
Last updated