Page cover image

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

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

// Delegate contract contains logic but no storage
contract Delegate {
    uint public storedData;  // This variable will be ignored when using delegatecall

    // Function to be called via delegatecall
    function setValue(uint _value) public {
        storedData = _value;  // This will set the caller's storage, not Delegate's
    }
}

// Caller contract with storage that will be updated
contract Caller {
    uint public storedData;  // The storage slot used in Delegate

    // Function to execute delegatecall to Delegate contract
    function setDelegateValue(address _delegateAddress, uint _value) public {
        // Prepare data for delegatecall (function selector + argument)
        (bool success, ) = _delegateAddress.delegatecall(
            abi.encodeWithSignature("setValue(uint256)", _value)
        );
        require(success, "Delegatecall failed");
    }
}

Classifications

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

Was this helpful?