Sparkn

CodeFox Inc.
DeFiFoundryProxy
15,000 USDC
View results
Submission Details
Severity: high

Contract calls will run out of gas

Summary

Proxy's fallback function forwards the entire gas left to the delegateCall that might be fully consumed by the call.
And no gas will be left for executing the remaining statements of the fallback function.

Vulnerability Details

Inside Proxy#fallback method, the contract delegates the call to the implementation.

fallback() external {
address implementation = _implementation;
assembly {
let ptr := mload(0x40)
calldatacopy(ptr, 0, calldatasize())
let result := delegatecall(gas(), implementation, ptr, calldatasize(), 0, 0)
let size := returndatasize()
returndatacopy(ptr, 0, size)
switch result
case 0 { revert(ptr, size) }
default { return(ptr, size) }
}
}

in the following line

let result := delegatecall(gas(), implementation, ptr, calldatasize(), 0, 0)

the contract forwards all gas left from the transaction to the delegate call, which will not let the execution complete if the entire gas is consumed by the delegate call

Impact

  • Even if the delegate call transaction is valid and gets completely executed but leaves less gas than needed for the following lines to execute, the transaction will fail and the user will face a denial of service

..
..
let size := returndatasize()
returndatacopy(ptr, 0, size)
switch result
case 0 { revert(ptr, size) }
default { return(ptr, size) }
}

Tools Used

Manual review

Recommendations

There are two possible solutions

  • Either use some magical number or decide a number by your best judgment for reserving the gas amount for executing the next instructions

  • Use the 63/64 gas rule to forward gas to delegate call

Relevant Links:
63/64 rule in ganache : https://github.com/trufflesuite/ganache-cli-archive/issues/367

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.