#46592 [SC-High] The return value of redeemFromAgent/redeemFromAgentInCollateral in the selfCloseExitTo is not checked

Submitted on Jun 2nd 2025 at 05:53:32 UTC by @ox9527 for Audit Comp | Flare | FAssets

  • Report ID: #46592

  • Report Type: Smart Contract

  • Report severity: High

  • Target: https://github.com/flare-foundation/fassets/blob/main/contracts/assetManager/implementation/CollateralPool.sol

  • Impacts:

    • Permanent freezing of funds

Description

Brief/Intro

In CollateralPool.sol::selfCloseExitTo(), the user spends an amount of requiredFAssets to redeem collateral from the agent. However, the actual value redeemed may vary, and the return value is not validated. This could potentially lead to a loss of funds for the user.

Vulnerability Details

From the code CollateralPool.sol->selfCloseExitTo->_selfCloseExitTo()->assetManager.redeemFromAgent()

        // redeem f-assets if necessary
        if (requiredFAssets > 0) {
            if (requiredFAssets < assetManager.lotSize() || _redeemToCollateral) {
                assetManager.redeemFromAgentInCollateral(
                    agentVault, _recipient, requiredFAssets);
            } else {
                // automatically pass `msg.value` to `redeemFromAgent` for the executor fee
                assetManager.redeemFromAgent{ value: msg.value }( //@audit the return value is not checked.
                    agentVault, _recipient, requiredFAssets, _redeemerUnderlyingAddress, _executor);  <@
            }
        }

And then RedemptionRequests.sol->Redemptions.closeTickets()

From the code above, we can see that the loop stops early in two cases: when maxRedeemedTickets is reached, or when there are no more tickets available for this agent.

Both of these cases can result in the actual redeemed amount being smaller than expected.

However, the final closedUBA obtained is not actually verified, which may result in the actual closedUBA being smaller than expected. As a result, the user may end up overpaying in requiredFAssets.

Impact Details

User paid more FAssets then expected

References

Proof of Concept

Proof of Concept

First add console.log to file:RedemptionRequests.sol::redeemFromAgent()

Track the actually closedUBA amount.

add test to Redemption.ts:

We use the amount is 40 ETH, and the output closedUBA is not this value:

Was this helpful?