#59054 [SC-Low] periodattimestamp returns incorrect period number
Submitted on Nov 8th 2025 at 07:41:35 UTC by @dldLambda for Audit Comp | Firelight
Report ID: #59054
Report Type: Smart Contract
Report severity: Low
Target: https://github.com/firelight-protocol/firelight-core/blob/main/contracts/FirelightVault.sol
Impacts:
Description
Brief/Intro
The function periodAtTimestamp(uint48 timestamp) is intended to return the period number corresponding to a given timestamp. It uses _sinceEpoch(periodConfiguration.epoch) to compute the offset.
_sinceEpoch() always uses Time.timestamp() (the current timestamp) instead of the provided timestamp. As a result, no matter what historical timestamp is queried, the function calculates the period offset from the present, always returning the current period or a future period.
Vulnerability Details
The periodAtTimestamp(uint48 timestamp) function promises to return the period number for any timestamp, but in reality it always returns current period:
/**
* @notice Returns the period number for the timestamp given.
* @dev Return value may be unreliable if period number given is far away in the future
* @dev given that new period configurations can be added after nextPeriodEnd().
* @return The period number corresponding to the given timestamp.
*/
function periodAtTimestamp(uint48 timestamp) public view returns (uint256) {
PeriodConfiguration memory periodConfiguration = periodConfigurationAtTimestamp(timestamp);
// solhint-disable-next-line max-line-length
return periodConfiguration.startingPeriod + _sinceEpoch(periodConfiguration.epoch) / periodConfiguration.duration;
}For example:
Vault deployed at epoch = 1,000,000, startingPeriod = 0
Period duration = 100 seconds
Historical timestamp: timestamp = 1,003,600
Correct period calculation: (timestamp - epoch) / duration = (1,003,600 - 1,000,000) / 100 = 36
Contract calculation: _sinceEpoch(epoch) = Time.timestamp() - epoch = 1,010,000 - 1,000,000 = 10,000
Returned period: startingPeriod + _sinceEpoch(epoch)/duration = 0 + 10,000 / 100 = 100
The same problem will occur if you pass a future timestamp.
However, at the moment, the function is only called in the currentPeriod function, which implies the current epoch. However, in the future, it may be used elsewhere, called in other places, and since it doesn't do what it says, this could cause major problems.
Impact Details
The function doesn't perform as expected, always returning the current period. If used elsewhere, any logic that relies on periodAtTimestamp() for historical accounting, rewards, or entitlement calculations will be broken.
References
https://github.com/firelight-protocol/firelight-core/blob/db36312f1fb24efc88c3fde15a760defbc3e6370/contracts/FirelightVault.sol#L246
Proof of Concept
Proof of Concept
Please add and run this test:
You will see:
Was this helpful?