Skip to content

Latest commit

 

History

History
60 lines (48 loc) · 2.49 KB

compete.md

File metadata and controls

60 lines (48 loc) · 2.49 KB

Description

The contracts ExecutionManager, TransmitManager, SwitchboardBase and NativeSwitchboardBase have both the functions: withdrawFees() and rescueFunds(). These functions both retrieve all the native tokens from the contract and thus compete with eachother.

Steps to reproduce

  1. Call withdrawFees() and then call rescueFunds(). The second function doesn't retrieve any native token.
  2. Or call rescueFunds() and then call withdrawFees(). The second function doesn't retrieve any native token.

Expected behavior

Consider to allow rescueFunds() only to rescue ERC20 tokens for contracts where withdrawFees() is present.

Actual behavior

The first function call retrieves all the native tokens.

Screenshots

Additional information

ExecutionManager.sol#L112-L128, TransmitManager.sol#L142-L144, TransmitManager.sol#L243-L249, SwitchboardBase.sol#L277-L293, NativeSwitchboardBase.sol#L454-L470:

function withdrawFees(address account_) external onlyRole(WITHDRAW_ROLE) {
    FeesHelper.withdrawFees(account_);
}
function rescueFunds(
    address token_,
    address userAddress_,
    uint256 amount_
) external onlyRole(RESCUE_ROLE) {
    RescueFundsLib.rescueFunds(token_, userAddress_, amount_);
}

FeesHelper.sol#L19-L27:

function withdrawFees(address account_) internal {
    ...
    uint256 amount = address(this).balance;
    (bool success, ) = account_.call{value: amount}("");
    if (!success) revert TransferFailed();
    ...
}

RescueFundsLib.sol#L25-L40:

function rescueFunds(...) internal {
    ...
    if (token_ == ETH_ADDRESS) {
        (bool success, ) = userAddress_.call{value: address(this).balance}("");
        require(success);
    } else {
        ...
    }
}