#46068 [SC-Low] selfCloseExitTo is lack of slippage protect

Submitted on May 24th 2025 at 12:11:24 UTC by @ox9527 for Audit Comp | Flare | FAssets

  • Report ID: #46068

  • Report Type: Smart Contract

  • Report severity: Low

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

  • Impacts:

    • Direct theft of any user funds, whether at-rest or in-motion, other than unclaimed yield

Description

Brief/Intro

When a user invokes selfCloseExitTo, the calculation of requiredFAssets is non-trivial, as it depends on the current collateral ratio (CR). For simplicity, let’s assume the current CR is below the healthy threshold. In this case, the formula for requiredFAssets becomes:

requiredFAssets = agentBackedFAsset * _natShare / poolNatBalance

The agentBackedFAsset is composed of reservedAMG, mintedAMG, and poolRedeemingAMG.

Importantly, any user can call CollateralReservationsFacet.sol::reserveCollateral() to increase the value of reservedAMG. Since agentBackedFAsset includes reservedAMG, this operation directly increases the agentBackedFAsset value.

As a result, the required amount of f-assets for selfCloseExitTo also increases, potentially making the operation more expensive and allowing malicious actors to exploit the mechanism by inflating the cost for other users.

Vulnerability Details

Firstly CollateralReservationsFacet.sol::reserveCollateral() can increase the value of reservedAMG reserveCollateral()->_reserveCollateral():

And from the selfCloseExitTo()->_selfCloseExitTo()->_getFAssetRequiredToNotSpoilCR():

requiredFAssets is depends on _assetData.agentBackedFAsset

Due to agentBackedFAsset is fetched from assetManager::getFAssetsBackedByPool(agent)->AgentsExternal.getFAssetsBackedByPool():

Impact Details

If user's account can't afford the required fAssets , user have to transfer more fAssets to the protocol. If the max cost fAssets is not checked user may cost more fAssets than expected.

References

Proof of Concept

Proof of Concept

Add the following test to file CollateralPool.ts

Why do i use fAsset.mint ? Cuz from the AssetManagerMock.sol the getFAssetsBackedByPool is total supply :

Add or comment fAsset.mint we can see the output difference is :

Was this helpful?