28792 - [SC - Low] Return value of low level isnt checked executio...
Submitted on Feb 27th 2024 at 14:20:17 UTC by @Kenzo for Boost | Puffer Finance
Report ID: #28792
Report type: Smart Contract
Report severity: Low
Target: https://etherscan.io/address/0x3C28B7c7Ba1A1f55c9Ce66b263B33B204f2126eA#code
Impacts:
Contract fails to deliver promised returns, but doesn't lose value
Description
Brief/Intro
Return value of low level isn't checked, execution will resume even if the called contract throws an exception.
Vulnerability Details
The function executeTransaction
in the TimeLock
contract is used to Executes a transaction after the delay period for Operations Multisig and Community multisig which can execute transactions without any delay. The problem occuring in the low level call made to target
in _executeTransaction
function. With a low level call we must verify the return value whether is false or true. Otherwise a false entry of transaction may register.
function executeTransaction(address target, bytes calldata callData, uint256 operationId)
external
returns (bool success, bytes memory returnData)
{
// Community Multisig can do things without any delay
if (msg.sender == COMMUNITY_MULTISIG) {
@> return _executeTransaction(target, callData);
}
// Operations multisig needs to queue it and then execute after a delay
if (msg.sender != OPERATIONS_MULTISIG) {
revert Unauthorized();
}
bytes32 txHash = keccak256(abi.encode(target, callData, operationId));
uint256 lockedUntil = queue[txHash];
// slither-disable-next-line incorrect-equality
if (lockedUntil == 0) {
revert InvalidTransaction(txHash);
}
if (block.timestamp < lockedUntil) {
revert Locked(txHash, lockedUntil);
}
queue[txHash] = 0;
@> (success, returnData) = _executeTransaction(target, callData);
emit TransactionExecuted(txHash, target, callData, operationId);
return (success, returnData);
}
function _executeTransaction(address target, bytes calldata callData) internal returns (bool, bytes memory) {
// slither-disable-next-line arbitrary-send-eth
@> return target.call(callData);
}
Impact Details
Severity: Low
Similar Incident: https://www.kingoftheether.com/postmortem.html?source=post_page-----fe794a7cdb6f--------------------------------
Recommendation:
Check the bool returned by the .call
function call and revert if it is false.
Proof of Concept
Execution will resume even if the called contract throws an exception. If the call fails accidentally or an attacker forces the call to fail, this may cause unexpected behavior in the subsequent program logic.
Affected Code:
function _executeTransaction(address target, bytes calldata callData) internal returns (bool, bytes memory) {
// slither-disable-next-line arbitrary-send-eth
@> return target.call(callData);
}
Last updated
Was this helpful?