#46924 [SC-Low] Last user may exit with almost all of his values, but he'll purposefully leave a small 1e18 or a little more to grief `destroy()`
Submitted on Jun 6th 2025 at 08:56:36 UTC by @onthehunt for Audit Comp | Flare | FAssets
Report ID: #46924
Report Type: Smart Contract
Report severity: Low
Target: https://github.com/flare-foundation/fassets/blob/main/contracts/assetManager/implementation/CollateralPool.sol
Impacts:
Griefing (e.g. no profit motive for an attacker, but damage to the users or the protocol)
Description
Brief/Intro
CollateralPool::destroy()
is used to remove destroy an agent and collateral pool, but he may be griefed from that for a very small amount.
Vulnerability Details
Let's say that agent wants to remove himself from the protocol for some reason and announce destroy via announceDestroyAgent()
, which will make destroying the agent possible after the specified settings.withdrawalWaitMinSeconds
Nothing is left inside the pool and he successfully calls the aforementioned function.
But a malicious user spots that and decides to call CollateralPool.enter()
, with the smaller amount available, which will be no more than a couple of bucks, if not less.
MIN_NAT = 1e18
which is 1e18 of flare native token, costing literal cents.
Via that, a user can block the destruction of an agent and its collateral pool for as I said, a very small amount and accessible amount of money, thus preventing the whole action.
Impact Details
Agent and its collateral pool will never be destroyed, leaving broken functionality the reason of the bug, as we should be able to do so after announcing it, leaving the users responsible for their action (we should just destroy the pool even if there is something left, as the announcement starts only if there's nothing in the pool).
References
https://github.com/flare-labs-ltd/fassets/blob/main/contracts/assetManager/implementation/CollateralPool.sol#L833
https://github.com/flare-labs-ltd/fassets/blob/main/contracts/assetManager/library/AgentsCreateDestroy.sol#L145-L176
https://github.com/flare-labs-ltd/fassets/blob/main/contracts/assetManager/library/AgentsCreateDestroy.sol#L134
Proof of Concept
Agent wants to destroy himself and the collateral pool as they are empty and calls
announceDestroyAgent()
Alice sees that and calls
CollateralPool::enter()
with the smallest value she can enter the poolThe time passes that makes destroying the pool possible, but the agent has been griefed by Alice and can't do that
Was this helpful?