For the complete documentation index, see llms.txt. This page is also available as Markdown.

89834 sc medium an attacker can grief commitallocation when the matchingcapacity is calculated at block timestamp periodstart timestamp

Submitted on Aug 21st 2026 at 12:18:52 UTC by @OxG0P1 for Audit Comp | Firelight

  • Report ID: #89834

  • Report Type: Smart Contract

  • Report severity: Medium

  • Target: https://github.com/immunefi-team/audit-comp-firelight/blob/v1_audit_ready/contracts/core/CoverOrderAllocator.sol

  • Impacts:

    • Griefing (e.g. no profit motive for an attacker, but damage to the users or the protocol)

Description

Brief / Introduction

Any user with sufficient assets can cause commitAllocation() to revert by manipulating the totalAssets() of the FirelightVault around the time the off-chain matching engine calculates matchingCapacity.

Specifically, an attacker can front-run the matching engine's calculation by depositing assets into the vault, temporarily inflating totalAssets(). The matching engine then fetches totalAssetsAt(periodStart) and calculates an inflated matchingCapacity based on this value.

The attacker can subsequently back-run the matching engine's transaction by redeeming the shares obtained from the deposit, reducing totalAssets() back to its original value.

Later, when the ALLOCATOR calls commitAllocation(), the on-chain calculation of maxCapacity uses the now-reduced totalAssetsAt(periodStart). As a result, the matchingCapacity calculated off-chain can be greater than the maxCapacity calculated on-chain, causing commitAllocation() to revert.

This allows an attacker to prevent allocations from being committed by manipulating the vault's assets during the matching-capacity calculation.

Vulnerability Details

Consider the following scenario:

  • The current period is 5.

  • periodStart = X.

  • The current timestamp is X.

  • vault.totalAssets() = 1000.

  • vault.totalSupply() = 1000.

At this point, the matching engine needs to calculate the matchingCapacity. To do so, it calls:

Step 1 — Attacker Front-Runs the Matching Engine

Before the matching engine's transaction executes, the attacker deposits 500 assets into the vault.

As a result:

The matching engine's call to:

now observes the inflated totalAssets value of 1500.

Consequently, the matching engine calculates an inflated matchingCapacity.

Step 2 — Attacker Back-Runs the Matching Engine

Immediately after the matching engine's transaction, the attacker redeems the 500 assets they previously deposited.

This brings the vault back to approximately:

The matching engine, however, has already calculated matchingCapacity using the inflated 1500 asset value.

Step 3 — commitAllocation() Is Called

Suppose the ALLOCATOR calls commitAllocation() at timestamp X + 10.

The function calculates maxCapacity using the current value returned by:

which now returns 1000.

Assume both the matching engine and the on-chain contract use the following formula:

Since all parameters other than totalAssetsAt(periodStart) remain unchanged, the matching engine calculates matchingCapacity using the inflated value of 1500, while commitAllocation() calculates maxCapacity using the reduced value of 1000.

Therefore:

This causes the following validation to revert:

The transaction therefore reverts with:

Note : Even if the matchingCapacity calculation off chain slightly differes from the onchain calculation an attacker can with enough capital still grief commitAllocation as long as the calculation happens when the current timestamp is == periodStart timestamp by inflating/deflating totalAssets().

Impact Details

An attacker can temporarily manipulate the vault's totalAssets() by depositing assets immediately before the matching engine calculates matchingCapacity and then redeeming those assets immediately afterward.

Because the off-chain matching engine and the on-chain commitAllocation() can observe different totalAssetsAt(periodStart) values, the resulting matchingCapacity can exceed the on-chain maxCapacity.

This causes commitAllocation() to revert and can therefore prevent the allocation from being committed for the affected period.

The attack does not require the attacker to permanently transfer assets to the vault; the attacker only needs sufficient capital to temporarily inflate the vault's assets around the matching-capacity calculation.

References

https://github.com/immunefi-team/audit-comp-firelight/blob/42f9ea5e43d88b35197b901acc2a8c24b314fa62/contracts/core/CoverOrderAllocator.sol#L394-L403

Proof of Concept

Proof of Concept

Run

###Logs

Was this helpful?