# The collateral that liquidators receive is valued below their initial expectations as a result of the price fall

Bug Deep Dive #28 · 24 December 2025

Bug Deep Dives · [The Contest Academy](https://0xsimao.com/the-contest-academy) · 0xSimao

---

| Title | The collateral that liquidators receive is valued below their initial expectations as a result of the price fall |
| Reward | $33790, Unique |
| Contest | FAssets - 19 August 2025 on Code4rena |
| Author | pashap9990 |
| Context | Wrong Tracking |

With no safeguard against a price drop, liquidators receive less collateral than expected from the vault and pool, and lose money.

Suppose:

- F-asset = FXRP
- 1 XRP = 1 USD
- Vault’s collateral is USDC
- 1 NAT = 1 USD
- Liquidation factor = 1.05

Based on the above assumptions, the liquidator is expected to receive 10,000 USDC and 500 NAT for one lot.

1. An agent is established, after which the necessary collateral is deposited into the agent’s vault and collateral pool. The agent is then made publicly accessible.
2. A minter reserves the required collateral and initiates the corresponding payment transaction.
3. The function MintingFacet::executeMinting is invoked, resulting in the minter receiving fassets.
4. The agent executes a decrease transaction on the underlying network without prior notification.
5. An illegal payment is detected, and the challenger submits proof of the illegal payment. As a result, the agent’s status changes to FULL_LIQUIDATION.
6. The liquidator submits the transaction. If the price of XRP falls to 0.90 USD by the time it executes, they receive 9,000 USDC and 450 NAT instead — less than expected.

```solidity
function liquidate(
    address _agentVault,
    uint256 _amountUBA
)
    external
    notEmergencyPaused
    nonReentrant
    returns (uint256 _liquidatedAmountUBA, uint256 _amountPaidVault, uint256 _amountPaidPool)
{
    Agent.State storage agent = Agent.get(_agentVault);
    // calculate both CRs
    Liquidation.CRData memory cr = Liquidation.getCollateralRatiosBIPS(agent);
    // allow one-step liquidation (without calling startLiquidation first)
    bool inLiquidation = _startLiquidation(agent, cr);
    require(inLiquidation, NotInLiquidation());
    // liquidate redemption tickets
    (uint64 liquidatedAmountAMG, uint256 payoutC1Wei, uint256 payoutPoolWei) =
        _performLiquidation(agent, cr, Conversion.convertUBAToAmg(_amountUBA));
    _liquidatedAmountUBA = Conversion.convertAmgToUBA(liquidatedAmountAMG);
    // pay the liquidator
    if (payoutC1Wei > 0) {
        _amountPaidVault = AgentPayout.payoutFromVault(agent, msg.sender, payoutC1Wei);
    }
    if (payoutPoolWei > 0) {
        uint256 agentResponsibilityWei = _agentResponsibilityWei(agent, payoutPoolWei);
        _amountPaidPool = AgentPayout.payoutFromPool(agent, msg.sender, payoutPoolWei, agentResponsibilityWei);
    }
    // if the agent was already safe due to price changes, there should be no LiquidationPerformed event
    // we do not revert, because it still marks agent as healthy (so there will still be a LiquidationEnded event)
    if (_liquidatedAmountUBA > 0) {
        // burn liquidated fassets
        Redemptions.burnFAssets(msg.sender, _liquidatedAmountUBA);
        // notify about liquidation
        emit IAssetManagerEvents.LiquidationPerformed(_agentVault, msg.sender,
            _liquidatedAmountUBA, _amountPaidVault, _amountPaidPool);
    }
    // try to pull agent out of liquidation
    Liquidation.endLiquidationIfHealthy(agent);
}
```

**Alpha:** check for slippage protection wherever a price oracle is used. Oracles update on an interval, and a single update can move the price enough to change the outcome.

**Conclusion**

This finding would earn you **\$33790**. It requires understanding the liquidation process and the oracle-slippage attack vector.

[**Full Report**](https://code4rena.com/reports/2025-08-flare-fasset#m-03-accumulated-rewards-in-fsto-can-be-stolen-by-the-agents-owner)\
[**Codebase**](https://github.com/code-423n4/2025-08-flare/tree/main)

---

Newer: [Chained signature with checkpoint usage disabled can bypass all checkpointer validation](https://0xsimao.com/the-contest-academy/bug-deep-dive-29) · Older: [Accumulated rewards in FSTO can be stolen by the agent's owner](https://0xsimao.com/the-contest-academy/bug-deep-dive-27)
