The Standard

The Standard
DeFiHardhat
20,000 USDC
View results
Submission Details
Severity: low
Invalid

Potential for Loss of Funds in distributeFees

Description

The distributeFees function is designed to distribute fees between the liquidation pool and the protocol. It calculates the fees for the pool based on the poolFeePercentage and then calls approve on the EUROs token to allow the pool to pull the calculated fee amount. If the approve call fails, the contract does not revert or handle the failure, and it proceeds to transfer the remaining EUROs balance to the protocol address. This could result in the pool not receiving its intended fees.

Proof of Concept (PoC):

  • Deploy the LiquidationPoolManager contract.

  • Simulate a scenario where the approve function of the EUROs token contract reverts or returns false (e.g., due to a bug or change in the token contract).

  • Call distributeFees from any account.

  • Observe that the approve call fails, but the contract still attempts to transfer the remaining EUROs balance to the protocol.

Code Snippet

function distributeFees() public {
    IERC20 eurosToken = IERC20(EUROs);
    uint256 _feesForPool = eurosToken.balanceOf(address(this)) * poolFeePercentage / HUNDRED_PC;
    if (_feesForPool > 0) {
        eurosToken.approve(pool, _feesForPool); // No check for return value
        LiquidationPool(pool).distributeFees(_feesForPool);
    }
    eurosToken.transfer(protocol, eurosToken.balanceOf(address(this)));
}

Impact

If the approve call fails and is not handled, the pool will not be able to claim the fees it is entitled to, resulting in a loss of funds for the pool. This could disrupt the intended economic mechanisms of the contract and erode trust in the system.

Recommendation

Ensure that the return value of the approve call is checked and handled appropriately. If the approve call fails, the function should revert to prevent any further actions that could lead to a loss of funds. The following code snippet demonstrates how to add this check:

function distributeFees() public {
    IERC20 eurosToken = IERC20(EUROs);
    uint256 _feesForPool = eurosToken.balanceOf(address(this)) * poolFeePercentage / HUNDRED_PC;
    if (_feesForPool > 0) {
        require(eurosToken.approve(pool, _feesForPool), "Approval failed"); // Check for return value
        LiquidationPool(pool).distributeFees(_feesForPool);
    }
    eurosToken.transfer(protocol, eurosToken.balanceOf(address(this)));
}

By adding the require statement, the contract will revert if the approve call fails, ensuring that the pool will not miss out on receiving its fees and preventing the potential loss of funds.

Updates

Lead Judging Commences

hrishibhat Lead Judge over 1 year ago
Submission Judgement Published
Invalidated
Reason: Non-acceptable severity
Assigned finding tags:

informational/invalid

Support

FAQs

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