59124 sc insight inefficient loop direction in periodconfigurationattimestamp causes unnecessary gas consumption
Submitted on Nov 9th 2025 at 01:34:00 UTC by @ZenHunter for Audit Comp | Firelight
Report ID: #59124
Report Type: Smart Contract
Report severity: Insight
Target: https://github.com/firelight-protocol/firelight-core/blob/main/contracts/FirelightVault.sol
Impacts:
Description
Brief/Intro
The periodConfigurationAtTimestamp function iterates through the periodConfigurations array from the beginning (index 0) to find the matching period configuration. Since period configurations are added in chronological order and most queries are for the current or recent periods (via currentPeriodConfiguration(), currentPeriod(), currentPeriodStart(), currentPeriodEnd(), and nextPeriodEnd()), iterating from the end backwards would be significantly more gas-efficient. While periodAtTimestamp() can be called with historical timestamps, these queries for historical periods are less common than queries for the current period. For arrays with many period configurations, this causes unnecessary gas consumption when querying recent periods, as the function must iterate through all older configurations first.
Vulnerability Details
The vulnerability exists in the periodConfigurationAtTimestamp function (lines 205-217):
function periodConfigurationAtTimestamp(uint48 timestamp) public view returns (PeriodConfiguration memory) {
uint256 length = periodConfigurations.length;
if (length == 0) revert InvalidPeriod();
PeriodConfiguration memory periodConfiguration;
for (uint256 i = 0; i < length; i++) { // Iterates from beginning
if (timestamp < periodConfigurations[i].epoch)
break;
periodConfiguration = periodConfigurations[i];
}
if (periodConfiguration.epoch == 0) revert InvalidPeriod();
return periodConfiguration;
}The Problem:
Period configurations are added in chronological order: The
_addPeriodConfigurationfunction (lines 799-825) ensures that new configurations are only added after the last one, confirming they are stored chronologically.Most queries are for recent periods: Functions like
currentPeriod(),currentPeriodConfiguration(),currentPeriodStart(),currentPeriodEnd(), andnextPeriodEnd()all query the current or near-future period, which will be the most recent configuration. WhileperiodAtTimestamp()can accept historical timestamps, these queries for historical periods are less common than queries for the current period.Inefficient iteration: When querying recent periods, the function must iterate through all older configurations first, causing unnecessary gas consumption.
Gas Cost Analysis:
Current approach: For an array with N configurations, querying the last configuration requires N storage reads (SLOAD operations at ~2100 gas each).
Optimized approach: Iterating from the end backwards would require only 1 storage read for the most common case (current period).
Example Scenario:
If there are 10 period configurations:
Querying the current period (the last configuration at index 9) requires 10 iterations and 10 storage reads
With reverse iteration, it would require only 1 iteration and 1 storage read
Impact Details
This gas optimization issue causes unnecessary gas consumption when querying recent period configurations. Since most queries are for the current period (which is the most recent configuration), iterating from the beginning of the array wastes gas by reading through all older configurations. As the vault operates over time and more period configurations are added, this inefficiency compounds, making period-related queries increasingly expensive. The impact is particularly significant for frequently called functions like currentPeriod(), currentPeriodConfiguration(), currentPeriodStart(), and currentPeriodEnd(), all of which call periodConfigurationAtTimestamp internally.
References
contracts/FirelightVault.sol
Recommendation
Optimize the loop to iterate from the end backwards, as period configurations are stored in chronological order and most queries are for recent periods.
Fix for periodConfigurationAtTimestamp:
Proof of Concept
Proof of Concept
A runnable PoC test demonstrates the gas inefficiency by measuring gas costs for querying recent periods with varying numbers of period configurations.
PoC Test Code:
The test file test/gas_optimization_period_configuration_loops_poc.js:
Test Results:
Running npx hardhat test test/gas_optimization_period_configuration_loops_poc.js:
Gas Cost Analysis:
1 configuration: ~34,280 gas
5 configurations: ~51,494 gas (+17,214 gas, +50% increase)
10 configurations: ~76,549 gas (+42,269 gas, +123% increase)
Was this helpful?