Skip to content

Commit 17446ed

Browse files
spalladinoclaude
andcommitted
fix(sequencer-client): decay ethPerFeeAsset per slot for conservative fee prediction
Addresses PR #22116 review comment 7: ethPerFeeAsset was treated as fixed across prediction slots but can change by up to 1% per checkpoint. Now assumes worst-case (decreasing) ethPerFeeAsset for higher fee estimates. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 2e8fc2c commit 17446ed

1 file changed

Lines changed: 15 additions & 6 deletions

File tree

yarn-project/sequencer-client/src/global_variable_builder/fee_predictor.ts

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import type { L1FeeData, RollupContract } from '@aztec/ethereum/contracts';
1+
import { type L1FeeData, MAX_FEE_ASSET_PRICE_MODIFIER_BPS, type RollupContract } from '@aztec/ethereum/contracts';
22
import { SlotNumber } from '@aztec/foundation/branded-types';
33
import { times } from '@aztec/foundation/collection';
44
import { getTimestampForSlot } from '@aztec/stdlib/epoch-helpers';
@@ -92,14 +92,18 @@ export class FeePredictor {
9292

9393
const result: GasFees[] = [];
9494
let { excessMana } = state;
95+
let { ethPerFeeAsset } = state;
9596

9697
// Slot 0: current state (next available slot after last checkpoint)
97-
result.push(this.computeGasFees(state, excessMana, state.l1FeesBySlot[0]));
98+
result.push(this.computeGasFees(state, excessMana, ethPerFeeAsset, state.l1FeesBySlot[0]));
9899

99-
// Slots 1..LAG: advance excessMana with the assumed mana usage per checkpoint
100+
// Slots 1..LAG: advance excessMana with the assumed mana usage per checkpoint,
101+
// and decay ethPerFeeAsset by MAX_FEE_ASSET_PRICE_MODIFIER_BPS per slot for conservative estimates.
102+
// Lower ethPerFeeAsset means higher fees in fee asset terms.
100103
for (let i = 1; i < state.l1FeesBySlot.length; i++) {
101104
excessMana = computeExcessMana(excessMana, assumedManaUsed, state.manaTarget);
102-
result.push(this.computeGasFees(state, excessMana, state.l1FeesBySlot[i]));
105+
ethPerFeeAsset = (ethPerFeeAsset * (10000n - MAX_FEE_ASSET_PRICE_MODIFIER_BPS)) / 10000n;
106+
result.push(this.computeGasFees(state, excessMana, ethPerFeeAsset, state.l1FeesBySlot[i]));
103107
}
104108

105109
return result;
@@ -116,7 +120,12 @@ export class FeePredictor {
116120
}
117121
}
118122

119-
private computeGasFees(state: FeeOracleState, excessMana: bigint, l1Fees: L1FeeData): GasFees {
123+
private computeGasFees(
124+
state: FeeOracleState,
125+
excessMana: bigint,
126+
ethPerFeeAsset: bigint,
127+
l1Fees: L1FeeData,
128+
): GasFees {
120129
return new GasFees(
121130
0,
122131
computeManaMinFee({
@@ -126,7 +135,7 @@ export class FeePredictor {
126135
epochDuration: state.epochDuration,
127136
provingCostPerManaEth: state.provingCostPerManaEth,
128137
excessMana,
129-
ethPerFeeAsset: state.ethPerFeeAsset,
138+
ethPerFeeAsset,
130139
}),
131140
);
132141
}

0 commit comments

Comments
 (0)