Do not set freemem pointer when having only fallback function with sole assembly block
- Dominant language
- C++
- Stars
- 25.7k
- Forks
- 6.2k
- Avg merge
- 2d 19h
- Merged PRs (30d)
- 29
Description
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).
Contributor guide
Research direction
Start by reproducing the Solidity 0.8.x compiler output for the UUPS-style contract with only a fallback function and one assembly block. Trace the compiler path that emits the free-memory pointer initialization, then verify that safe sole-assembly fallbacks omit it without changing behavior for cases where memory can still clash.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- cpp, solidity
- Domain
- blockchain, compilers
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100