#59879 [SC-Low] logic bug in periodattimestamp

Submitted on Nov 16th 2025 at 16:59:32 UTC by @Immanux2160 for Audit Comp | Firelight

  • Report ID: #59879

  • 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 periodAtTimestamp function in the FirelightVault contract contains a logic flaw where it incorrectly uses the current block.timestamp instead of the provided timestamp parameter when calculating historical periods. This vulnerability completely breaks all historical data queries in the vault, if in production, this would render all historical audit trails unreliable, break any integrations relying on historical data, undermine user confidence in the protocol's accounting.

Vulnerability Details

The bug is in the periodAtTimestamp function which is intended to return the period number for any given historical timestamp. However, the function incorrectly uses the current block.timestamp instead of the parameter timestamp when calculating time elapsed since the epoch.

function periodAtTimestamp(uint48 timestamp) public view returns (uint256) {
        PeriodConfiguration memory periodConfiguration = periodConfigurationAtTimestamp(timestamp);
        // solhint-disable-next-line max-line-length
        //@audit it uses the current block.timestamp in _sinceEpoch calculation intead of the timestamp given in the parameter
        return periodConfiguration.startingPeriod + _sinceEpoch(periodConfiguration.epoch) / periodConfiguration.duration;
    }

The problem: _sinceEpoch(epoch) always returns block.timestamp - epoch regardless of the timestamp parameter, this means periodAtTimestamp(anyTimestamp) always returns the current period number, historical queries become meaningless as they all return current state.

The function also always returns the period of "now," even if you're calculating for an arbitrary timestamp.

Impact Details

The issue with periodAtTimestamp is that it ignores the timestamp passed into the function and instead uses the current block time when calculating the period. This means it returns the current period even when you ask for the period of a past or future timestamp. While it doesn’t cause direct loss of funds, it breaks the core assumption that periods can be computed deterministically from any timestamp.

Also this leads to inconsistencies between on-chain state and off-chain systems that rely on accurate period calculations such as frontends, indexers, or analytic tools that map historical balances (balanceOfAt) or withdrawals to specific periods.

References

https://github.com/firelight-protocol/firelight-core/blob/main/contracts/FirelightVault.sol?#L245

https://github.com/firelight-protocol/firelight-core/blob/main/contracts/FirelightVault.sol?#L795

Proof of Concept

Proof of Concept

Mitigation: use the timestamp as a parameter in _sinceEpoch internal function or change the function like this:

or change _sinceEpoch internal function to this:

Was this helpful?