#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?