This mitigation updates the following AmbireAccount.tryCatch function to execute (bool success, bytes memory returnData) = to.call{ value: value, gas: gasBefore }(data) after uint256 gasBefore = gasleft() and before require(gasleft() > gasBefore/64, 'TRYCATCH_OOG'). Since the upper gas limit for the inner to.call function call is set to gasBefore that is the gas left in the AmbireAccount.tryCatch function's context just before this to.call function call, if this to.call function call consumes more than 63/64 of gasBefore, then there is no way that gasleft() > gasBefore/64 can be true after such to.call function call; in this case, the gas consumption of more than 63/64 of gasBefore is too much comparing to all but one 64th of the maximum allowed amount of gas that would be given to this to.call function if it could be called without inputting gas, which is specified by EIP-150. In order to not revert require(gasleft() > gasBefore/64, 'TRYCATCH_OOG'), enough gas needs to be provided to the inner to.call function so such to.call function call would not revert due to out of gas. As a result, this mitigation makes the malicious relayer's or actor's manipulation of the gas for calling the AmbireAccount.tryCatch function ineffective and prevents such relayer or actor from forcing the inner to.call function call to revert due to out of gas. Therefore, the corresponding issue is mitigated.
Lines of code
Vulnerability details
Issue
M-02: Attacker can force the failure of transactions that use tryCatch
Mitigation
https://github.com/AmbireTech/ambire-common/commit/fca50cd45478ef1ab57ba21bf7e1ccd15b310a05
Assessment of Mitigation
Issue mitigated
Comments
This mitigation updates the following
AmbireAccount.tryCatch
function to execute(bool success, bytes memory returnData) = to.call{ value: value, gas: gasBefore }(data)
afteruint256 gasBefore = gasleft()
and beforerequire(gasleft() > gasBefore/64, 'TRYCATCH_OOG')
. Since the upper gas limit for the innerto.call
function call is set togasBefore
that is the gas left in theAmbireAccount.tryCatch
function's context just before thisto.call
function call, if thisto.call
function call consumes more than 63/64 ofgasBefore
, then there is no way thatgasleft() > gasBefore/64
can be true after suchto.call
function call; in this case, the gas consumption of more than 63/64 ofgasBefore
is too much comparing to all but one 64th of the maximum allowed amount of gas that would be given to thisto.call
function if it could be called without inputtinggas
, which is specified by EIP-150. In order to not revertrequire(gasleft() > gasBefore/64, 'TRYCATCH_OOG')
, enough gas needs to be provided to the innerto.call
function so suchto.call
function call would not revert due to out of gas. As a result, this mitigation makes the malicious relayer's or actor's manipulation of the gas for calling theAmbireAccount.tryCatch
function ineffective and prevents such relayer or actor from forcing the innerto.call
function call to revert due to out of gas. Therefore, the corresponding issue is mitigated.https://github.com/AmbireTech/ambire-common/blob/f56e7dcaaa4ff8950b39fe6d5bced165d0f1c99f/contracts/AmbireAccount.sol#L113-L119