#59937 [SC-Low] periodattimestamp uses current time instead of inputtimestamp returning wrong period

Submitted on Nov 17th 2025 at 03:42:51 UTC by @IronsideSec for Audit Comp | Firelight

  • Report ID: #59937

  • Report Type: Smart Contract

  • Report severity: Low

  • Target: https://github.com/firelight-protocol/firelight-core/blob/main/contracts/FirelightVault.sol

  • Impacts:

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

Description

Brief/Intro

The vault’s periodAtTimestamp(timestamp) ignores its input timestamp argument and computes using the current block time. This yields incorrect period numbers for historicalqueries, can mis-schedule accounting tied to periods, and enables unfairness between users whose actions are recorded in different periods than intended.

Vulnerability Details

  • Concrete math with the PoC’s numbers:

    • Initial config: epoch = 100, duration = 10

    • Later config: at epoch = 160, duration becomes 20 (unrelated to the bug but present in the PoC)

    • Now = current time: 150

    • Query: periodAtTimestamp( t = 115)

    • Returned (buggy): starting + (now − epoch)/duration = 0 + (150 − 100)/10 = 5 period

    • Correct: starting + (t − epoch)/duration = 0 + (115 − 100)/10 = 1 period

  • Buggy code (uses now timestamp, not input):

  • PoC in tests (exact lines):

Impact Details

  • Incorrect period classification for historical timestamps used by other logic (e.g., scheduling, accounting, limits) can:

    • Allocate or settle amounts in wrong periods.

    • Create unfairness between users whose actions are bucketed into unintended periods.

    • Break assumptions around period-based configuration changes.

References

  • Affected function: periodAtTimestamp in contracts/FirelightVault.sol lines 194–210 (see snippet above).

  • Reproducer: test/X.t.sol lines 87–134 (see snippet above).

https://gist.github.com/IronsideSec/7a44ccd02d3a87d17a19cc9b3e1edf2f

Proof of Concept

Proof of Concept

  1. run forge init --force

  2. Delete test/Counter.t.sol and script/Counter.s.sol

  3. Create test/POC.t.sol and paste the code copied from https://gist.github.com/IronsideSec/7a44ccd02d3a87d17a19cc9b3e1edf2f

  4. then run forge t --mt test_PeriodAtTimestamp_DependsOnNow_NotInput -vvvv

Was this helpful?