Skip to content
Request an audit

‹ All findings

Fontaine never stops the flows to the tax and recipient, so the buffer component of the flows will be lost

Crit/HighSuperfluid Locker System·Sherlock · Streaming · 20th November 2024CodebaseH-3

Summary

Superfluid flows reserve 4 hours of the stream flow rate as a buffer for liquidations, and returns this when the flow is closed.

However, Fontaine::initialize() never actually stops the flows, which means the deposit buffer will never be reclaimed, taking the recipient and the tax pool the loss.

Root Cause

In Fontaine::initialize(), the flows are never stopped, which means the buffer will not be returned.

Internal pre-conditions

None.

External pre-conditions

None.

Attack Path

  1. User unlocks their Fluid from the Locker by calling FluidLocker::unlock() with a non null unlocking period.

Impact

The recipient and the tax distribution pool take the loss as they do not receive all their funds (the deposit buffer is never sent to them).

PoC

Add the following logs to Fontaine.sol and run forge test --mt testVestUnlock -vvvv. Alice sends 10_000e18 to the fontaine, but only 9996.8e18 are left in the fontaine as a part of them are reserved for the buffer which will never be collected back.

solidity
function initialize(address unlockRecipient, int96 unlockFlowRate, int96 taxFlowRate) external initializer {
    // Ensure recipient is not a SuperApp
    if (ISuperfluid(FLUID.getHost()).isApp(ISuperApp(unlockRecipient))) revert CANNOT_UNLOCK_TO_SUPERAPP();

    console2.log("fontaine balance pre distributeFlow", FLUID.balanceOf(address(this)));

    // Distribute Tax flow to Staker GDA Pool
    FLUID.distributeFlow(address(this), TAX_DISTRIBUTION_POOL, taxFlowRate);

    console2.log("fontaine balance pre createFlow", FLUID.balanceOf(address(this)));

    // Create the unlocking flow from the Fontaine to the locker owner
    FLUID.createFlow(unlockRecipient, unlockFlowRate);

    console2.log("fontaine balance after createFlow", FLUID.balanceOf(address(this)));
}

Mitigation

Add a way to stop the flow and receive the deposit back.