Consider the following function:
uint256 mySpecialNumber = 0;
function foo(address callee, uint256 newNumber) public {
mySpecialNumber = newNumber;
// make a low level call to the bar() function on the callee
callee.call{gas: gasleft() - 2000}(
abi.encodeWithSelector(ISomeOtherContract.bar.selector)
);
}
Is it possible for the callee to DOS or prevent execution of foo()? Or is foo() always executable no matter what the callee does (if it reverts, runs out of gas, or some other error)?
If it is possible for the callee to prevent execution of foo(), how would that be done?
Best Answer
Is it possible for a callee to DOS a function call if the caller ignores the success value?
Yes, but only if the caller doesn't ignore the returndata.
For example, consider this calling function:
Even if we ignore
success
, solidity still needs to readreturndata
into memory. Ifcallee
returns a lot of bytes, this passage can fail due to out-of-gas, reverting the whole transaction.In your example, where the caller doesn't retrieve the return value, there's no way for the callee to DOS.
How much gas to pass?
I notice you're making the call with
gas: gasleft() - 2000
. However removing2000
or a similar small amount isn't necessary.Indeed, EIP150 makes it that at max
gasleft()*63/64
is provided to a child call. In other words, the caller contract is guaranteed to retain 1/64 of gas even if the callee tries to consume it all.