#45893 [SC-High] Agent role can stolen nat token from protocol users

Submitted on May 22nd 2025 at 04:35:59 UTC by @ox9527 for Audit Comp | Flare | FAssets

  • Report ID: #45893

  • Report Type: Smart Contract

  • Report severity: High

  • 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

The Agent role can invoke claimAirdropDistribution or claimDelegationRewards to claim rewards from an external protocol and increase the value of totalCollateral. However, there are at least two critical vulnerabilities in this design:

1.Unverified Reward Token The contract does not verify the actual token received from the external .claim() function. Instead, it blindly trusts the return value (e.g., the claimed amount) from the external call. This creates a risk if the claimed token is not the expected collateral token.

2.Missing Native Token Receiver The CollateralPool.sol contract does not implement a receive() function, which means it cannot properly receive native tokens (e.g., ETH or MATIC). If the external claim function returns native tokens, they will be lost or misaccounted.

Vulnerability Details

Exploit Scenario: An attacker with Agent privileges can deploy a malicious contract and configure it as the external claim target. When the protocol calls the malicious .claim() function:

The contract does not actually transfer any tokens to CollateralPool.sol. It fakes a large return value, e.g., returns 10_000 ether as the claimed amount. Since the protocol blindly adds the claimed amount to totalCollateral, this inflated value skews the internal accounting. As a result: Any user exiting the pool (redeeming their share) can receive more than they should, especially if the system allows withdrawal of native tokens or stablecoins based on totalCollateral. The malicious Agent can also exit early and receive an outsized portion of the actual collateral. Remaining users are left with under-collateralized or even bad debt.

Impact Details

protocol users lost of funds result in can't exist due to lack of token

References

Proof of Concept

Proof of Concept

Add the following test to file CollateralPool.ts :

Out:

From above test we can see account[0] claim the whole balance from CollateralPool contract

Was this helpful?