DeFiHardhatFoundry
250,000 USDC
View results
Submission Details
Severity: low
Valid

`ReseedFiled.init()` can revert due out-of-gas error during migration

Summary

ReseedField.init() must be called once because it sets global parameters dependent on input accountPlots:

function init(
MigratedPlotData[] calldata accountPlots,
uint256 totalPods,
uint256 harvestable,
uint256 harvested,
uint256 fieldId,
uint8 initialTemperature
) external {
uint256 calculatedTotalPods;
for (uint i; i < accountPlots.length; i++) {
for (uint j; j < accountPlots[i].plots.length; i++) {
uint256 podIndex = accountPlots[i].plots[j].podIndex;
uint256 podAmount = accountPlots[i].plots[j].podAmounts;
s.accts[accountPlots[i].account].fields[fieldId].plots[podIndex] = podAmount;
s.accts[accountPlots[i].account].fields[fieldId].plotIndexes.push(podIndex);
emit MigratedPlot(accountPlots[i].account, podIndex, podAmount);
calculatedTotalPods += podAmount;
}
}
// perform verfication:
@> require(calculatedTotalPods == totalPods, "ReseedField: totalPods mismatch");
@> require(totalPods >= harvestable, "ReseedField: harvestable mismatch");
@> require(harvestable >= harvested, "ReseedField: harvested mismatch");
@> s.sys.field.pods = totalPods;
@> s.sys.field.harvestable = harvestable;
@> s.sys.field.harvested = harvested;
...
}

Let's calculate how much gas it costs to set all the plots. Every iteration of outer cycle costs 20k + 40k + (20k + 25k) * (n-1), where n is number of plots per account. Let me explain:

  1. 20k is SLOAD here:

s.accts[accountPlots[i].account].fields[fieldId].plots[podIndex] = podAmount;
  1. 40k is 2 SLOAD for initializing array with first value here:

s.accts[accountPlots[i].account].fields[fieldId].plotIndexes.push(podIndex);
  1. (20k + 25k) is for additional plots per account (45k instead of 60k because of altering array length instead of initializing)

Several L2s have block gasLimit 30M such as Optimism, Blast, Polygon. So in case there are more than 30M / 60k = 500 accounts with plots, migration will revert

Impact

Migration cannot be performed on several L2s such as Optimism, Blast, Polygon in case there are more than 500 accounts with plots prior to migration.

Tools Used

Manual Review

Recommendations

Use another way to init plots such that it can be split into multiple transactions.

Updates

Lead Judging Commences

inallhonesty Lead Judge 12 months ago
Submission Judgement Published
Invalidated
Reason: Non-acceptable severity
Assigned finding tags:

init functions will run out of gas on some L2s

Appeal created

T1MOH Submitter
12 months ago
inallhonesty Lead Judge
12 months ago
inallhonesty Lead Judge 11 months ago
Submission Judgement Published
Validated
Assigned finding tags:

init functions will run out of gas on some L2s

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.