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

90295 sc low maxmint can return an unmintable share amount causing mint to revert and violating erc 4626

Submitted on Aug 24th 2026 at 09:21:27 UTC by @TrynX for Audit Comp | Firelight

  • Report ID: #90295

  • Report Type: Smart Contract

  • Report severity: Low

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

  • Impacts:

    • Contract fails to deliver promised returns, but doesn't lose value

Description

Description

Summary

maxMint() is intended to return the maximum number of shares mintable via mint() without exceeding depositLimit. However, maxMint() converts the full depositLimit into shares and then subtracts the existing totalSupply, instead of deriving the maximum shares from the remaining asset capacity. Once totalAssets > totalSupply, this can cause maxMint() to return more shares than the vault can actually accept, causing mint(maxMint(receiver), receiver) to revert with DepositLimitExceeded().

Finding description

maxMint() computes:

uint256 sharesLimit = convertToShares(depositLimit); // rounds down
return sharesLimit - shares; // shares = totalSupply()

mint() later converts the returned share amount back into assets using Math.Rounding.Ceil, then checks the result against depositLimit:

Root cause. maxMint() computes its share limit from the entire depositLimit, converted at the vault's current share price, and only then subtracts totalSupply. This is not equivalent to computing the share limit directly from the remaining capacity (depositLimit - totalAssets) due to the vault's conversion formula and rounding. This can cause the floored result to exceed the number of shares the vault can actually accept, which the subsequent ceil-rounded mint() then exposes as a revert.

Impact

This violates the EIP-4626 requirement that maxMint() return a share amount mint() can accept without reverting in the same transaction (EIP-4626). Impact is limited to a reverted mint() call and inaccurate deposit-capacity reporting for integrators.

Recommendation

Derive maxMint() directly from the remaining asset capacity:

References

  • FirelightVault::maxMint

  • FirelightVault::mint

https://gist.github.com/Tryn0x0/7222434ecef9cfff638c4aa30630db5e

Proof of Concept

Proof of Concept

The test demonstrates that maxMint() can return a share amount that mint() subsequently rejects with DepositLimitExceeded().

Add the following function to audit-comp-firelight/test/deposit_and_withdraw.js:

(Also provided in the Gist)

And run:

The output i obtain:

Note: The randomized fuzzing results may vary between runs because the test uses randomly generated states. The deterministic reproduction should produce the same result.

Was this helpful?