Skip to content

Do not set freemem pointer when having only fallback function with sole assembly block #15627

Open
@radeksvarz

Description

@radeksvarz

Some contracts having only 1 function aim to be as gas efficient as possible. Such contracts use only fallback() function.

Currently (0.8.x) Solidity compiles freemem pointer allocation even for cases it is not needed.

Here is the UUPS proxy example with the mentioned issue https://eth-sepolia.blockscout.com/address/0xC0bf4d3F67B0B516930B28A90fe4022F20bEbE96?tab=contract

    /**
     * @dev Fallback function that delegates calls to the current implementation address.
     * Will run if no other function in the contract matches the call data.
     * This function will return directly to the external caller.
     */
    fallback() external payable {
        assembly {
            // Copy msg.data. We take full control of memory in this inline assembly
            // block because it will not return to Solidity code. We overwrite the
            // Solidity scratch pad at memory position 0.
            calldatacopy(0, 0, calldatasize())

            // Call the implementation.
            // out and outsize are 0 because we don't know the size yet.
            let result := delegatecall(gas(), sload(_IMPLEMENTATION_SLOT), 0, calldatasize(), 0, 0)

            // Copy the returned data.
            returndatacopy(0, 0, returndatasize())

            switch result
            // delegatecall returns 0 on error.
            case 0 { revert(0, returndatasize()) }
            default { return(0, returndatasize()) }
        }
    }

This compiles into:

# this part is not needed
PUSH1 80
PUSH1 40
MSTORE
# end of not needed part
CALLDATASIZE
PUSH1 00
...

Proposal is to avoid compiling not needed part when the contract has: only fallback function and such function does not risk having memory clash (such as when having only assembly block).

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions