From 935a667d0fbf64777eb4a9e1d92f3897acd14baf Mon Sep 17 00:00:00 2001 From: Alex Gherghisan Date: Tue, 8 Sep 2026 17:41:01 -0300 Subject: [PATCH 01/19] feat: introduce a protocol fee margin (AZIP-23) --- l1-contracts/src/core/Rollup.sol | 8 +- l1-contracts/src/core/RollupCore.sol | 24 + l1-contracts/src/core/interfaces/IRollup.sol | 8 +- l1-contracts/src/core/libraries/Errors.sol | 3 + .../compressed-data/fees/FeeConfig.sol | 12 +- .../compressed-data/fees/FeeStructs.sol | 14 +- .../src/core/libraries/rollup/FeeLib.sol | 103 +- .../src/core/libraries/rollup/ProposeLib.sol | 2 +- .../core/libraries/rollup/RewardExtLib.sol | 16 + .../src/core/libraries/rollup/RewardLib.sol | 36 +- .../src/core/libraries/rollup/STFLib.sol | 2 +- l1-contracts/test/benchmark/happy.t.sol | 2 +- l1-contracts/test/compression/FeeConfig.t.sol | 8 +- .../test/compression/FeeStructs.t.sol | 8 +- .../test/compression/PreHeating.t.sol | 2 +- .../test/fees/FeeHeaderOverflow.t.sol | 36 +- .../test/fees/FeeModelTestPoints.t.sol | 4 +- l1-contracts/test/fees/FeeRollup.t.sol | 61 +- l1-contracts/test/fees/MinimalFeeModel.sol | 2 +- .../fees/ProtocolFeeMarginRateLimit.t.sol | 311 ++ .../test/fees/ProtocolFeeNearCap.t.sol | 93 + .../test/fees/ProtocolFeeRecipient.t.sol | 61 + .../test/fixtures/fee_data_points.json | 2688 ++++++++--------- .../libraries/rewardlib/RewardLibBase.sol | 2 +- .../libraries/rewardlib/RewardLibWrapper.sol | 8 + .../rewardlib/waterfallIdentity.t.sol | 120 + ...roduce-a-protocol-fee-margin-AZIP-23.patch | 720 +++++ 27 files changed, 2936 insertions(+), 1418 deletions(-) create mode 100644 l1-contracts/test/fees/ProtocolFeeMarginRateLimit.t.sol create mode 100644 l1-contracts/test/fees/ProtocolFeeNearCap.t.sol create mode 100644 l1-contracts/test/fees/ProtocolFeeRecipient.t.sol create mode 100644 l1-contracts/test/rollup/libraries/rewardlib/waterfallIdentity.t.sol create mode 100644 labs-patches/0006-feat-introduce-a-protocol-fee-margin-AZIP-23.patch diff --git a/l1-contracts/src/core/Rollup.sol b/l1-contracts/src/core/Rollup.sol index 3abd82078875..d51ecf783b1b 100644 --- a/l1-contracts/src/core/Rollup.sol +++ b/l1-contracts/src/core/Rollup.sol @@ -612,8 +612,12 @@ contract Rollup is IStaking, IValidatorSelection, IRollup, RollupCore { return StakingLib.LEGACY_SLASHER_DRAIN_WINDOW; } - function getBurnAddress() external pure override(IRollup) returns (address) { - return address(bytes20("CUAUHXICALLI")); + function getProtocolFeeRecipient() external view override(IRollup) returns (address) { + return RewardExtLib.getProtocolFeeRecipient(); + } + + function getProtocolFeeMargin() external view override(IRollup) returns (uint16) { + return RewardExtLib.getProtocolFeeMargin(); } /** diff --git a/l1-contracts/src/core/RollupCore.sol b/l1-contracts/src/core/RollupCore.sol index 019b721bb4f9..413242ead786 100644 --- a/l1-contracts/src/core/RollupCore.sol +++ b/l1-contracts/src/core/RollupCore.sol @@ -325,6 +325,30 @@ contract RollupCore is EIP712("Aztec Rollup", "1"), Ownable, IStakingCore, IVali FeeLib.updateProvingCostPerMana(_provingCostPerMana); } + /** + * @notice Updates the protocol fee margin applied on top of operator cost in the mana base fee + * @dev Only callable by owner. Increases are rate-limited (30-day cooldown, x3/2 step on the fee + * multiplier); decreases are immediate. Setting the current value is a no-op and emits no + * event. + * @param _protocolFeeMarginBps The new margin in basis points + */ + function setProtocolFeeMargin(uint16 _protocolFeeMarginBps) external override(IRollupCore) onlyOwner { + (bool changed, uint16 oldBps) = RewardExtLib.updateProtocolFeeMargin(_protocolFeeMarginBps); + if (changed) { + emit IRollupCore.ProtocolFeeMarginUpdated(oldBps, _protocolFeeMarginBps); + } + } + + /** + * @notice Updates the recipient of the protocol fee tranche of the reward waterfall + * @dev Only callable by owner. Rejects the zero address. + * @param _recipient The new protocol fee recipient + */ + function setProtocolFeeRecipient(address _recipient) external override(IRollupCore) onlyOwner { + address oldRecipient = RewardExtLib.updateProtocolFeeRecipient(_recipient); + emit IRollupCore.ProtocolFeeRecipientUpdated(oldRecipient, _recipient); + } + /** * @notice Updates the configuration for the staking entry queue * @dev Only callable by owner. Controls how validators enter the active set. diff --git a/l1-contracts/src/core/interfaces/IRollup.sol b/l1-contracts/src/core/interfaces/IRollup.sol index a15827dca52e..42d01ffbab07 100644 --- a/l1-contracts/src/core/interfaces/IRollup.sol +++ b/l1-contracts/src/core/interfaces/IRollup.sol @@ -118,6 +118,8 @@ interface IRollupCore { event RewardConfigUpdated(MutableRewardConfig rewardConfig); event ManaTargetUpdated(uint256 indexed manaTarget); event PrunedPending(uint256 provenCheckpointNumber, uint256 pendingCheckpointNumber); + event ProtocolFeeMarginUpdated(uint16 oldBps, uint16 newBps); + event ProtocolFeeRecipientUpdated(address oldRecipient, address newRecipient); function claimSequencerRewards(address _recipient) external returns (uint256); function claimProverRewards(address _recipient, Epoch[] memory _epochs) external returns (uint256); @@ -127,6 +129,9 @@ interface IRollupCore { function setProvingCostPerMana(EthValue _provingCostPerMana) external; + function setProtocolFeeMargin(uint16 _protocolFeeMarginBps) external; + function setProtocolFeeRecipient(address _recipient) external; + function propose( ProposeArgs calldata _args, CommitteeAttestations memory _attestations, @@ -231,7 +236,8 @@ interface IRollup is IRollupCore, IHaveVersion { function getFeeAsset() external view returns (IERC20); function getFeeAssetPortal() external view returns (IFeeJuicePortal); function getRewardDistributor() external view returns (IRewardDistributor); - function getBurnAddress() external view returns (address); + function getProtocolFeeRecipient() external view returns (address); + function getProtocolFeeMargin() external view returns (uint16); function getInbox() external view returns (IInbox); function getOutbox() external view returns (IOutbox); diff --git a/l1-contracts/src/core/libraries/Errors.sol b/l1-contracts/src/core/libraries/Errors.sol index 2b620a344329..49aa150742a4 100644 --- a/l1-contracts/src/core/libraries/Errors.sol +++ b/l1-contracts/src/core/libraries/Errors.sol @@ -206,6 +206,8 @@ library Errors { error FeeLib__ProvingCostAboveCeiling(uint256 provided, uint256 maximum); error FeeLib__ProvingCostCooldown(uint256 nextAllowed); error FeeLib__ProvingCostStepExceeded(uint256 current, uint256 requested); + error FeeLib__ProtocolFeeMarginCooldown(uint256 nextAllowed); + error FeeLib__ProtocolFeeMarginStepExceeded(uint256 current, uint256 requested); // SignatureLib (duplicated) error SignatureLib__InvalidSignature(address, address); // 0xd9cbae6c @@ -223,6 +225,7 @@ library Errors { error RewardLib__InvalidSequencerBps(); error RewardLib__ZeroShares(address prover); + error RewardLib__InvalidProtocolFeeRecipient(); // SlashingProposer error SlashingProposer__InvalidSignature(); diff --git a/l1-contracts/src/core/libraries/compressed-data/fees/FeeConfig.sol b/l1-contracts/src/core/libraries/compressed-data/fees/FeeConfig.sol index be7591e5d073..de69b13d6639 100644 --- a/l1-contracts/src/core/libraries/compressed-data/fees/FeeConfig.sol +++ b/l1-contracts/src/core/libraries/compressed-data/fees/FeeConfig.sol @@ -38,13 +38,14 @@ function subEthValue(EthValue _a, EthValue _b) pure returns (EthValue) { using {addEthValue as +, subEthValue as -} for EthValue global; -// 32 bit manaTarget, 128 bit congestionUpdateFraction, 64 bit provingCostPerMana +// 16 bit protocolFeeMarginBps, 32 bit manaTarget, 128 bit congestionUpdateFraction, 64 bit provingCostPerMana type CompressedFeeConfig is uint256; struct FeeConfig { uint256 manaTarget; uint256 congestionUpdateFraction; EthValue provingCostPerMana; + uint256 protocolFeeMarginBps; } /// @notice Library for converting between ETH and fee asset values using the price oracle. @@ -89,6 +90,7 @@ library PriceLib { library FeeConfigLib { using SafeCast for uint256; + uint256 private constant MASK_16_BITS = 0xFFFF; uint256 private constant MASK_32_BITS = 0xFFFFFFFF; uint256 private constant MASK_64_BITS = 0xFFFFFFFFFFFFFFFF; uint256 private constant MASK_128_BITS = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF; @@ -105,11 +107,16 @@ library FeeConfigLib { return EthValue.wrap(CompressedFeeConfig.unwrap(_compressedFeeConfig) & MASK_64_BITS); } + function getProtocolFeeMarginBps(CompressedFeeConfig _compressedFeeConfig) internal pure returns (uint256) { + return (CompressedFeeConfig.unwrap(_compressedFeeConfig) >> 224) & MASK_16_BITS; + } + function compress(FeeConfig memory _config) internal pure returns (CompressedFeeConfig) { uint256 value = 0; value |= uint256(EthValue.unwrap(_config.provingCostPerMana).toUint64()); value |= uint256(_config.congestionUpdateFraction.toUint128()) << 64; value |= uint256(_config.manaTarget.toUint32()) << 192; + value |= uint256(_config.protocolFeeMarginBps.toUint16()) << 224; return CompressedFeeConfig.wrap(value); } @@ -118,7 +125,8 @@ library FeeConfigLib { return FeeConfig({ provingCostPerMana: getProvingCostPerMana(_compressedFeeConfig), congestionUpdateFraction: getCongestionUpdateFraction(_compressedFeeConfig), - manaTarget: getManaTarget(_compressedFeeConfig) + manaTarget: getManaTarget(_compressedFeeConfig), + protocolFeeMarginBps: getProtocolFeeMarginBps(_compressedFeeConfig) }); } } diff --git a/l1-contracts/src/core/libraries/compressed-data/fees/FeeStructs.sol b/l1-contracts/src/core/libraries/compressed-data/fees/FeeStructs.sol index 53745e3effd7..5b2177a699ad 100644 --- a/l1-contracts/src/core/libraries/compressed-data/fees/FeeStructs.sol +++ b/l1-contracts/src/core/libraries/compressed-data/fees/FeeStructs.sol @@ -11,7 +11,7 @@ import {SafeCast} from "@oz/utils/math/SafeCast.sol"; /*struct CompressedFeeHeader { uint1 preHeat; uint63 proverCost; Max value: 9.2233720369E18 - uint64 congestionCost; + uint64 protocolFee; uint48 ethPerFeeAsset; uint48 excessMana; uint32 manaUsed; @@ -22,7 +22,7 @@ struct FeeHeader { uint256 excessMana; uint256 manaUsed; uint256 ethPerFeeAsset; - uint256 congestionCost; + uint256 protocolFee; uint256 proverCost; } @@ -91,7 +91,7 @@ library FeeHeaderLib { return (CompressedFeeHeader.unwrap(_compressedFeeHeader) >> 80) & MASK_48_BITS; } - function getCongestionCost(CompressedFeeHeader _compressedFeeHeader) internal pure returns (uint256) { + function getProtocolFee(CompressedFeeHeader _compressedFeeHeader) internal pure returns (uint256) { return (CompressedFeeHeader.unwrap(_compressedFeeHeader) >> 128) & MASK_64_BITS; } @@ -106,9 +106,9 @@ library FeeHeaderLib { // Cap excessMana to uint48 max to prevent overflow during compression. value |= Math.min(_feeHeader.excessMana, MASK_48_BITS) << 32; value |= uint256(_feeHeader.ethPerFeeAsset.toUint48()) << 80; - // Cap congestionCost to uint64 max to prevent overflow during compression. + // Cap protocolFee to uint64 max to prevent overflow during compression. // The uncapped value is still used for fee validation; this only affects storage. - value |= Math.min(_feeHeader.congestionCost, MASK_64_BITS) << 128; + value |= Math.min(_feeHeader.protocolFee, MASK_64_BITS) << 128; // Cap proverCost to uint63 max to prevent overflow during compression. value |= Math.min(_feeHeader.proverCost, MASK_63_BITS) << 192; @@ -127,7 +127,7 @@ library FeeHeaderLib { value >>= 48; uint256 ethPerFeeAsset = value & MASK_48_BITS; value >>= 48; - uint256 congestionCost = value & MASK_64_BITS; + uint256 protocolFee = value & MASK_64_BITS; value >>= 64; uint256 proverCost = value & MASK_63_BITS; @@ -135,7 +135,7 @@ library FeeHeaderLib { manaUsed: uint256(manaUsed), excessMana: uint256(excessMana), ethPerFeeAsset: uint256(ethPerFeeAsset), - congestionCost: uint256(congestionCost), + protocolFee: uint256(protocolFee), proverCost: uint256(proverCost) }); } diff --git a/l1-contracts/src/core/libraries/rollup/FeeLib.sol b/l1-contracts/src/core/libraries/rollup/FeeLib.sol index 72d42ca7e6c3..4f9e58e8fec1 100644 --- a/l1-contracts/src/core/libraries/rollup/FeeLib.sol +++ b/l1-contracts/src/core/libraries/rollup/FeeLib.sol @@ -60,6 +60,9 @@ uint256 constant MAX_FEE_ASSET_PRICE_MODIFIER_BPS = 100; uint256 constant L1_GAS_PER_CHECKPOINT_PROPOSED = 300_000; uint256 constant L1_GAS_PER_EPOCH_VERIFIED = 3_600_000; +// The uncongested baseline of the congestion multiplier is (1 + mu) * 1e9, where mu is the +// protocol fee margin: congestionMultiplier scales this minimum by (10_000 + marginBps) / 10_000. +// At a margin of 0 the baseline is exactly 1e9. uint256 constant MINIMUM_CONGESTION_MULTIPLIER = 1e9; // The magic values are used to have the fakeExponential case where @@ -94,12 +97,26 @@ uint256 constant MIN_PROVING_COST_PER_MANA = 2; // that proving costs will go down. uint256 constant MAX_INITIAL_PROVING_COST_PER_MANA = 2e8; +/* + * Protocol-fee-margin rate limit + * + * `setProtocolFeeMargin` multiplies the fee users pay, so increases are constrained to a bounded + * multiplicative step per cooldown, mirroring the proving-cost limiter above. The bounded quantity + * is the fee multiplier (10_000 + marginBps), not the margin itself, so each step raises the + * pinned fee by at most x3/2. Decreases are immediate and unrestricted (floor 0 is structural via + * uint16). `protocolMarginLastUpdate == 0` after `initialize`, so the first post-init update is + * not gated by the cooldown; the 30-day cadence engages after that (decreases stamp it too). + */ +uint256 constant PROTOCOL_FEE_MARGIN_UPDATE_INTERVAL = 30 days; +uint256 constant PROTOCOL_FEE_MARGIN_STEP_NUM = 3; +uint256 constant PROTOCOL_FEE_MARGIN_STEP_DEN = 2; + struct OracleInput { int256 feeAssetPriceModifier; } struct ManaMinFeeComponents { - uint256 congestionCost; + uint256 protocolFee; uint256 congestionMultiplier; uint256 sequencerCost; uint256 proverCost; @@ -109,6 +126,7 @@ struct FeeStore { CompressedFeeConfig config; L1GasOracleValues l1GasOracleValues; uint64 provingCostLastUpdate; + uint64 protocolMarginLastUpdate; } library FeeLib { @@ -168,7 +186,8 @@ library FeeLib { feeStore.config = FeeConfig({ manaTarget: _manaTarget, congestionUpdateFraction: _manaTarget * MAGIC_CONGESTION_VALUE_MULTIPLIER / MAGIC_CONGESTION_VALUE_DIVISOR, - provingCostPerMana: _provingCostPerMana + provingCostPerMana: _provingCostPerMana, + protocolFeeMarginBps: 0 }).compress(); feeStore.l1GasOracleValues = L1GasOracleValues({ @@ -220,6 +239,49 @@ library FeeLib { feeStore.provingCostLastUpdate = uint64(block.timestamp); } + /** + * @notice Updates the protocol fee margin (in basis points) applied on top of operator cost. + * @dev Idempotent: setting the current value is a no-op (no state change, no cooldown stamp). + * Increases are gated by the 30-day cooldown (first-ever update exempt) and the x3/2 step + * on the fee multiplier `(10_000 + bps)`. Decreases are immediate and unrestricted but + * still stamp the cooldown. The uint16 parameter makes values above 65535 unrepresentable + * at the ABI boundary, so the reverting `toUint16` inside `compress` can never fire from + * this path and later `compress` round-trips (updateManaTarget, updateProvingCostPerMana) + * never see an out-of-range margin. + * @param _bps The new protocol fee margin in basis points + * @return changed Whether state was mutated (false for the idempotent no-op) + * @return oldBps The margin in effect before this call + */ + function updateProtocolFeeMargin(uint16 _bps) internal returns (bool changed, uint16 oldBps) { + FeeStore storage feeStore = getStorage(); + FeeConfig memory config = feeStore.config.decompress(); + + oldBps = uint16(config.protocolFeeMarginBps); + + if (_bps == oldBps) { + return (false, oldBps); + } + + if (_bps > oldBps) { + uint256 nextAllowed = uint256(feeStore.protocolMarginLastUpdate) + PROTOCOL_FEE_MARGIN_UPDATE_INTERVAL; + require( + feeStore.protocolMarginLastUpdate == 0 || block.timestamp >= nextAllowed, + Errors.FeeLib__ProtocolFeeMarginCooldown(nextAllowed) + ); + require( + (10_000 + uint256(_bps)) * PROTOCOL_FEE_MARGIN_STEP_DEN + <= (10_000 + uint256(oldBps)) * PROTOCOL_FEE_MARGIN_STEP_NUM, + Errors.FeeLib__ProtocolFeeMarginStepExceeded(oldBps, _bps) + ); + } + + config.protocolFeeMarginBps = _bps; + feeStore.config = config.compress(); + feeStore.protocolMarginLastUpdate = uint64(block.timestamp); + + return (true, oldBps); + } + function updateL1GasFeeOracle() internal { Slot slot = Timestamp.wrap(block.timestamp).slotFromTimestamp(); // The slot where we find a new queued value acceptable @@ -242,7 +304,7 @@ library FeeLib { uint256 _checkpointNumber, int256 _feeAssetPriceModifierBps, uint256 _manaUsed, - uint256 _congestionCost, + uint256 _protocolFee, uint256 _proverCost ) internal view returns (FeeHeader memory) { require( @@ -254,7 +316,7 @@ library FeeLib { excessMana: FeeLib.computeExcessMana(parentFeeHeader), ethPerFeeAsset: FeeLib.computeNewEthPerFeeAsset(parentFeeHeader.getEthPerFeeAsset(), _feeAssetPriceModifierBps), manaUsed: _manaUsed, - congestionCost: _congestionCost, + protocolFee: _protocolFee, proverCost: _proverCost }); } @@ -312,7 +374,7 @@ library FeeLib { FeeLib.clampedAdd(parentFeeHeader.getExcessMana() + parentFeeHeader.getManaUsed(), -int256(manaTarget)); uint256 congestionMultiplier_ = congestionMultiplier(excessMana); - EthValue congestionCost = + EthValue protocolFee = EthValue.wrap( Math.mulDiv(EthValue.unwrap(total), congestionMultiplier_, MINIMUM_CONGESTION_MULTIPLIER, Math.Rounding.Floor) ) - total; @@ -324,7 +386,7 @@ library FeeLib { return ManaMinFeeComponents({ sequencerCost: FeeAssetValue.unwrap(sequencerCostPerMana.toFeeAsset(ethPerFeeAsset)), proverCost: FeeAssetValue.unwrap(proverCostPerMana.toFeeAsset(ethPerFeeAsset)), - congestionCost: FeeAssetValue.unwrap(congestionCost.toFeeAsset(ethPerFeeAsset)), + protocolFee: FeeAssetValue.unwrap(protocolFee.toFeeAsset(ethPerFeeAsset)), congestionMultiplier: congestionMultiplier_ }); } @@ -342,6 +404,10 @@ library FeeLib { return getStorage().config.getProvingCostPerMana(); } + function getProtocolFeeMarginBps() internal view returns (uint16) { + return uint16(getStorage().config.getProtocolFeeMarginBps()); + } + function getEthPerFeeAssetAtCheckpoint(uint256 _checkpointNumber) internal view returns (EthPerFeeAssetE12) { return EthPerFeeAssetE12.wrap(STFLib.getFeeHeader(_checkpointNumber).getEthPerFeeAsset()); } @@ -357,7 +423,11 @@ library FeeLib { // Cap the exponent to prevent overflow in the Taylor series. // At e^100, the multiplier is ~2.69e43 * MINIMUM_CONGESTION_MULTIPLIER, more than enough uint256 cappedNumerator = Math.min(_numerator, denominator * 100); - return fakeExponential(MINIMUM_CONGESTION_MULTIPLIER, cappedNumerator, denominator); + // The protocol fee margin scales only this factor: (10_000 + bps) * 1e5 == (1 + mu) * 1e9, + // exactly 1e9 (== MINIMUM_CONGESTION_MULTIPLIER) at mu = 0. The mulDiv divisor in + // getManaMinFeeComponentsAt MUST stay MINIMUM_CONGESTION_MULTIPLIER — scaling both sites + // cancels the margin. + return fakeExponential((10_000 + feeStore.config.getProtocolFeeMarginBps()) * 1e5, cappedNumerator, denominator); } function computeManaLimit(uint256 _manaTarget) internal pure returns (uint256) { @@ -394,7 +464,24 @@ library FeeLib { // Cap at uint128 max to ensure the fee can always be represented in the proposal header's // feePerL2Gas field (uint128). Without this cap, extreme congestion or parameter combinations // could produce fees that no valid header can represent, causing a liveness failure. - return Math.min(_components.sequencerCost + _components.proverCost + _components.congestionCost, type(uint128).max); + return Math.min(_components.sequencerCost + _components.proverCost + _components.protocolFee, type(uint128).max); + } + + /** + * @notice The per-mana protocol fee written to the fee header: the pinned fee minus the two + * converted operator costs, as one subtraction. + * @dev The single subtraction guarantees `fee - protocolFee == cost * manaUsed` holds exactly + * in the reward waterfall; converting the margin and congestion tranches separately could + * drift by a wei because the Ceil conversion is not additive. The subtraction can go + * negative only when the uint128 cap in {summedMinFee} binds, in which case the protocol + * fee is clamped to 0 and operators stay whole. + * @param _components The mana min fee components (in fee asset) + * @return The per-mana protocol fee + */ + function protocolFeePerMana(ManaMinFeeComponents memory _components) internal pure returns (uint256) { + uint256 manaMinFee = summedMinFee(_components); + uint256 operatorCost = _components.sequencerCost + _components.proverCost; + return manaMinFee > operatorCost ? manaMinFee - operatorCost : 0; } function getStorage() internal pure returns (FeeStore storage storageStruct) { diff --git a/l1-contracts/src/core/libraries/rollup/ProposeLib.sol b/l1-contracts/src/core/libraries/rollup/ProposeLib.sol index 6df3377d8259..d2447ce33713 100644 --- a/l1-contracts/src/core/libraries/rollup/ProposeLib.sol +++ b/l1-contracts/src/core/libraries/rollup/ProposeLib.sol @@ -290,7 +290,7 @@ library ProposeLib { checkpointNumber, _args.oracleInput.feeAssetPriceModifier, v.header.totalManaUsed, - components.congestionCost, + FeeLib.protocolFeePerMana(components), components.proverCost ); diff --git a/l1-contracts/src/core/libraries/rollup/RewardExtLib.sol b/l1-contracts/src/core/libraries/rollup/RewardExtLib.sol index 8f62815cde84..a8e83ae78f07 100644 --- a/l1-contracts/src/core/libraries/rollup/RewardExtLib.sol +++ b/l1-contracts/src/core/libraries/rollup/RewardExtLib.sol @@ -30,6 +30,14 @@ library RewardExtLib { RewardLib.updateConfig(_config); } + function updateProtocolFeeMargin(uint16 _bps) external returns (bool changed, uint16 oldBps) { + return FeeLib.updateProtocolFeeMargin(_bps); + } + + function updateProtocolFeeRecipient(address _recipient) external returns (address oldRecipient) { + return RewardLib.updateProtocolFeeRecipient(_recipient); + } + function claimSequencerRewards(address _sequencer) external returns (uint256) { return RewardLib.claimSequencerRewards(_sequencer); } @@ -81,6 +89,14 @@ library RewardExtLib { return RewardLib.getStorage().config.rewardDistributor; } + function getProtocolFeeRecipient() external view returns (address) { + return RewardLib.getProtocolFeeRecipient(); + } + + function getProtocolFeeMargin() external view returns (uint16) { + return FeeLib.getProtocolFeeMarginBps(); + } + // FeeLib/STFLib/ProposeLib view wrappers - overflow from RollupOperationsExtLib function getManaMinFeeComponentsAt(Timestamp _timestamp, bool _inFeeAsset) diff --git a/l1-contracts/src/core/libraries/rollup/RewardLib.sol b/l1-contracts/src/core/libraries/rollup/RewardLib.sol index 9858551510aa..a8556cb890a5 100644 --- a/l1-contracts/src/core/libraries/rollup/RewardLib.sol +++ b/l1-contracts/src/core/libraries/rollup/RewardLib.sol @@ -54,6 +54,7 @@ struct RewardStorage { mapping(Epoch => EpochRewards) epochRewards; mapping(address prover => BitMaps.BitMap claimed) proverClaimed; RewardConfig config; + address protocolFeeRecipient; } struct Values { @@ -66,7 +67,7 @@ struct Values { struct Totals { uint256 feesToClaim; - uint256 totalBurn; + uint256 totalProtocolFee; } library RewardLib { @@ -79,11 +80,6 @@ library RewardLib { bytes32 private constant REWARD_STORAGE_POSITION = keccak256("aztec.reward.storage"); - // A Cuauhxicalli [kʷaːʍʃiˈkalːi] ("eagle gourd bowl") is a ceremonial Aztec vessel or altar used to hold - // offerings, - // such as sacrificial hearts, during rituals performed within temples. - address public constant BURN_ADDRESS = address(bytes20("CUAUHXICALLI")); - /// @notice One-shot writer used during rollup construction. Writes every field of /// {RewardConfig}, including the immutable `rewardDistributor` and `booster`. /// @dev Must only be reachable from the constructor path. Post-deployment updates go through @@ -92,6 +88,18 @@ library RewardLib { require(Bps.unwrap(_config.sequencerBps) <= 10_000, Errors.RewardLib__InvalidSequencerBps()); RewardStorage storage rewardStorage = getStorage(); rewardStorage.config = _config; + // A Cuauhxicalli ("eagle gourd bowl") is a ceremonial Aztec vessel used to hold offerings. + rewardStorage.protocolFeeRecipient = address(bytes20("CUAUHXICALLI")); + } + + /// @notice Owner-gated post-deployment writer for the protocol fee recipient. + /// @param _recipient The new recipient of the protocol fee tranche + /// @return oldRecipient The recipient in effect before this call + function updateProtocolFeeRecipient(address _recipient) internal returns (address oldRecipient) { + require(_recipient != address(0), Errors.RewardLib__InvalidProtocolFeeRecipient()); + RewardStorage storage rewardStorage = getStorage(); + oldRecipient = rewardStorage.protocolFeeRecipient; + rewardStorage.protocolFeeRecipient = _recipient; } /// @notice Owner-gated post-deployment writer. Only updates the mutable subset @@ -216,18 +224,18 @@ library RewardLib { v.manaUsed = feeHeader.getManaUsed(); uint256 fee = _args.headers[i].accumulatedFees; - uint256 burn = feeHeader.getCongestionCost() * v.manaUsed; + uint256 protocolFee = feeHeader.getProtocolFee() * v.manaUsed; t.feesToClaim += fee; - t.totalBurn += burn; + t.totalProtocolFee += protocolFee; // Compute the proving fee in the fee asset - v.proverFee = Math.min(v.manaUsed * feeHeader.getProverCost(), fee - burn); + v.proverFee = Math.min(v.manaUsed * feeHeader.getProverCost(), fee - protocolFee); if (v.proverFee > 0) { $er.rewards += v.proverFee.toUint128(); } - v.sequencerFee = fee - burn - v.proverFee; + v.sequencerFee = fee - protocolFee - v.proverFee; { v.sequencer = _args.headers[i].coinbase; @@ -244,8 +252,8 @@ library RewardLib { rollupStore.config.feeAssetPortal.distributeFees(address(this), t.feesToClaim); } - if (t.totalBurn > 0) { - rollupStore.config.feeAsset.safeTransfer(BURN_ADDRESS, t.totalBurn); + if (t.totalProtocolFee > 0) { + rollupStore.config.feeAsset.safeTransfer(rewardStorage.protocolFeeRecipient, t.totalProtocolFee); } } } @@ -274,6 +282,10 @@ library RewardLib { return getStorage().config.checkpointReward; } + function getProtocolFeeRecipient() internal view returns (address) { + return getStorage().protocolFeeRecipient; + } + function getSpecificProverRewardsForEpoch(Epoch _epoch, address _prover) internal view returns (uint256) { RewardStorage storage rewardStorage = getStorage(); diff --git a/l1-contracts/src/core/libraries/rollup/STFLib.sol b/l1-contracts/src/core/libraries/rollup/STFLib.sol index 44f23b2ae05d..fa9fc2e5c681 100644 --- a/l1-contracts/src/core/libraries/rollup/STFLib.sol +++ b/l1-contracts/src/core/libraries/rollup/STFLib.sol @@ -131,7 +131,7 @@ library STFLib { payloadDigest: bytes32(0), slotNumber: Slot.wrap(0), feeHeader: FeeHeader({ - excessMana: 0, manaUsed: 0, ethPerFeeAsset: _initialEthPerFeeAsset, congestionCost: 0, proverCost: 0 + excessMana: 0, manaUsed: 0, ethPerFeeAsset: _initialEthPerFeeAsset, protocolFee: 0, proverCost: 0 }), // Genesis Inbox consumption base case, matching the Inbox's genesis bucket-0 sentinel {0, 0, 0}, so // checkpoint 1 validates its consumption against it. diff --git a/l1-contracts/test/benchmark/happy.t.sol b/l1-contracts/test/benchmark/happy.t.sol index 6acdb09b7a0c..ceff5ae76dab 100644 --- a/l1-contracts/test/benchmark/happy.t.sol +++ b/l1-contracts/test/benchmark/happy.t.sol @@ -209,7 +209,7 @@ abstract contract BenchmarkRollupBase is FeeModelTestPoints, DecoderBase { vm.label(coinbase, "coinbase"); vm.label(address(rollup), "ROLLUP"); vm.label(address(asset), "ASSET"); - vm.label(rollup.getBurnAddress(), "BURN_ADDRESS"); + vm.label(rollup.getProtocolFeeRecipient(), "BURN_ADDRESS"); } function _installPartialEpochProofGasReporter(RollupBuilder _builder) internal { diff --git a/l1-contracts/test/compression/FeeConfig.t.sol b/l1-contracts/test/compression/FeeConfig.t.sol index f569e4559176..e092654333cb 100644 --- a/l1-contracts/test/compression/FeeConfig.t.sol +++ b/l1-contracts/test/compression/FeeConfig.t.sol @@ -17,12 +17,14 @@ contract FeeConfigTest is Test { function test_compressAndDecompress( uint32 _manaTarget, uint128 _congestionUpdateFraction, - uint64 _provingCostPerMana + uint64 _provingCostPerMana, + uint16 _protocolFeeMarginBps ) public pure { FeeConfig memory a = FeeConfig({ manaTarget: _manaTarget, congestionUpdateFraction: _congestionUpdateFraction, - provingCostPerMana: EthValue.wrap(_provingCostPerMana) + provingCostPerMana: EthValue.wrap(_provingCostPerMana), + protocolFeeMarginBps: _protocolFeeMarginBps }); CompressedFeeConfig b = a.compress(); FeeConfig memory c = b.decompress(); @@ -30,9 +32,11 @@ contract FeeConfigTest is Test { assertEq(c.manaTarget, a.manaTarget, "Mana target"); assertEq(c.congestionUpdateFraction, a.congestionUpdateFraction, "Congestion update fraction"); assertEq(EthValue.unwrap(c.provingCostPerMana), EthValue.unwrap(a.provingCostPerMana), "Proving cost per mana"); + assertEq(c.protocolFeeMarginBps, a.protocolFeeMarginBps, "Protocol fee margin bps"); assertEq(b.getManaTarget(), a.manaTarget, "Mana target"); assertEq(b.getCongestionUpdateFraction(), a.congestionUpdateFraction, "Congestion update fraction"); assertEq(EthValue.unwrap(b.getProvingCostPerMana()), EthValue.unwrap(a.provingCostPerMana), "Proving cost per mana"); + assertEq(b.getProtocolFeeMarginBps(), a.protocolFeeMarginBps, "Protocol fee margin bps"); } } diff --git a/l1-contracts/test/compression/FeeStructs.t.sol b/l1-contracts/test/compression/FeeStructs.t.sol index 1568b95940d2..07e99ba4d3cb 100644 --- a/l1-contracts/test/compression/FeeStructs.t.sol +++ b/l1-contracts/test/compression/FeeStructs.t.sol @@ -11,7 +11,7 @@ contract FeeStructsTest is Test { function test_compressAndDecompress( uint64 _proverCost, - uint64 _congestionCost, + uint64 _protocolFee, uint48 _ethPerFeeAsset, uint48 _excessMana, uint32 _manaUsed @@ -20,7 +20,7 @@ contract FeeStructsTest is Test { excessMana: _excessMana, manaUsed: _manaUsed, ethPerFeeAsset: _ethPerFeeAsset, - congestionCost: _congestionCost, + protocolFee: _protocolFee, proverCost: bound(_proverCost, 0, 2 ** 63 - 1) }); @@ -32,14 +32,14 @@ contract FeeStructsTest is Test { assertEq(compressedFeeHeader.getManaUsed(), feeHeader.manaUsed, "Getter Mana used"); assertEq(compressedFeeHeader.getExcessMana(), feeHeader.excessMana, "Getter Excess mana"); assertEq(compressedFeeHeader.getEthPerFeeAsset(), feeHeader.ethPerFeeAsset, "Getter Eth per fee asset"); - assertEq(compressedFeeHeader.getCongestionCost(), feeHeader.congestionCost, "Getter Congestion cost"); + assertEq(compressedFeeHeader.getProtocolFee(), feeHeader.protocolFee, "Getter Protocol fee"); assertEq(compressedFeeHeader.getProverCost(), feeHeader.proverCost, "Getter Prover cost"); // Check the decompressed value assertEq(decompressedFeeHeader.manaUsed, feeHeader.manaUsed, "Decompressed Mana used"); assertEq(decompressedFeeHeader.excessMana, feeHeader.excessMana, "Decompressed Excess mana"); assertEq(decompressedFeeHeader.ethPerFeeAsset, feeHeader.ethPerFeeAsset, "Decompressed Eth per fee asset"); - assertEq(decompressedFeeHeader.congestionCost, feeHeader.congestionCost, "Decompressed Congestion cost"); + assertEq(decompressedFeeHeader.protocolFee, feeHeader.protocolFee, "Decompressed Protocol fee"); assertEq(decompressedFeeHeader.proverCost, feeHeader.proverCost, "Decompressed Prover cost"); } } diff --git a/l1-contracts/test/compression/PreHeating.t.sol b/l1-contracts/test/compression/PreHeating.t.sol index 7bce6f907c2f..2367427c4bdf 100644 --- a/l1-contracts/test/compression/PreHeating.t.sol +++ b/l1-contracts/test/compression/PreHeating.t.sol @@ -173,7 +173,7 @@ contract PreHeatingTest is FeeModelTestPoints, DecoderBase { vm.label(coinbase, "coinbase"); vm.label(address(rollup), "ROLLUP"); vm.label(address(asset), "ASSET"); - vm.label(rollup.getBurnAddress(), "BURN_ADDRESS"); + vm.label(rollup.getProtocolFeeRecipient(), "BURN_ADDRESS"); _; } diff --git a/l1-contracts/test/fees/FeeHeaderOverflow.t.sol b/l1-contracts/test/fees/FeeHeaderOverflow.t.sol index 4d5057bc1112..638d3d62a9f3 100644 --- a/l1-contracts/test/fees/FeeHeaderOverflow.t.sol +++ b/l1-contracts/test/fees/FeeHeaderOverflow.t.sol @@ -28,7 +28,7 @@ import {console} from "forge-std/console.sol"; * the FeeConfig allows provingCostPerMana up to uint64. Governance can set a * valid config value that always reverts during compression. * - * 2. FeeHeader compression - congestionCost (uint64): with a cheap fee asset (low + * 2. FeeHeader compression - protocolFee (uint64): with a cheap fee asset (low * ethPerFeeAsset) and moderate congestion, the fee-asset conversion amplifies * the congestion cost beyond 64 bits. * @@ -44,7 +44,7 @@ import {console} from "forge-std/console.sol"; * proposer can work around the revert - permanent liveness failure. * * Additionally, even after fixing (1)-(4), the summed mana min fee (sequencerCost + - * proverCost + congestionCost) can exceed the uint128 capacity of the proposal header's + * proverCost + protocolFee) can exceed the uint128 capacity of the proposal header's * feePerL2Gas field. Without capping summedMinFee at type(uint128).max, the proposer * cannot construct a valid header, causing the same liveness failure. */ @@ -60,7 +60,7 @@ contract FeeHeaderOverflowTest is DecoderBase { address internal coinbase = address(bytes20("MONEY MAKER")); uint256 internal constant MAX_PROVER_COST = (1 << 63) - 1; - uint256 internal constant MAX_CONGESTION_COST = type(uint64).max; + uint256 internal constant MAX_PROTOCOL_FEE = type(uint64).max; function setUp() public { // Warp to a timestamp large enough so that setupEpoch's @@ -189,11 +189,11 @@ contract FeeHeaderOverflowTest is DecoderBase { // Verify the stored fee header has capped proverCost FeeHeader memory storedFeeHeader = rollup.getFeeHeader(1); assertEq(storedFeeHeader.proverCost, MAX_PROVER_COST, "stored proverCost should be capped at 63-bit max"); - assertEq(storedFeeHeader.congestionCost, 0, "congestionCost should be zero (no congestion)"); + assertEq(storedFeeHeader.protocolFee, 0, "protocolFee should be zero (no congestion)"); } // ----------------------------------------------------------------------- - // 2. Compression overflow - congestionCost exceeds 64 bits + // 2. Compression overflow - protocolFee exceeds 64 bits // ----------------------------------------------------------------------- /** @@ -208,7 +208,7 @@ contract FeeHeaderOverflowTest is DecoderBase { * Note: proverCost stays within 63 bits here because provingCostPerMana is * at the default (100 wei), so this specifically tests the congestion path. */ - function test_propose_compressOverflow_congestionCost() public { + function test_propose_compressOverflow_protocolFee() public { // excessMana = 1e10 (~100x target): high enough for large congestion multiplier, // but well below the ~975x threshold that would overflow fakeExponential uint256 excessMana = 10_000_000_000; @@ -237,11 +237,11 @@ contract FeeHeaderOverflowTest is DecoderBase { // Warp to slot 1 vm.warp(block.timestamp + SLOT_DURATION); - // Fee computation succeeds (uint256 intermediates), but congestionCost exceeds uint64 + // Fee computation succeeds (uint256 intermediates), but protocolFee exceeds uint64 ManaMinFeeComponents memory components = rollup.getManaMinFeeComponentsAt(Timestamp.wrap(block.timestamp), true); uint256 manaMinFee = rollup.getManaMinFeeAt(Timestamp.wrap(block.timestamp), true); - assertTrue(components.congestionCost > MAX_CONGESTION_COST, "congestionCost should exceed 64-bit limit"); + assertTrue(components.protocolFee > MAX_PROTOCOL_FEE, "protocolFee should exceed 64-bit limit"); assertTrue(components.proverCost <= MAX_PROVER_COST, "proverCost should still fit in 63 bits"); (ProposeArgs memory proposeArgs, CommitteeAttestations memory attestations, address[] memory signers) = @@ -249,14 +249,12 @@ contract FeeHeaderOverflowTest is DecoderBase { skipBlobCheck(address(rollup)); - // propose succeeds because compress() caps congestionCost at 64-bit max instead of reverting. + // propose succeeds because compress() caps protocolFee at 64-bit max instead of reverting. rollup.propose(proposeArgs, attestations, signers, Signature({v: 0, r: 0, s: 0}), full.checkpoint.blobCommitments); - // Verify the stored fee header has capped congestionCost + // Verify the stored fee header has capped protocolFee FeeHeader memory storedFeeHeader = rollup.getFeeHeader(1); - assertEq( - storedFeeHeader.congestionCost, MAX_CONGESTION_COST, "stored congestionCost should be capped at 64-bit max" - ); + assertEq(storedFeeHeader.protocolFee, MAX_PROTOCOL_FEE, "stored protocolFee should be capped at 64-bit max"); assertLe(storedFeeHeader.proverCost, MAX_PROVER_COST, "proverCost should still fit in 63 bits"); } @@ -291,7 +289,7 @@ contract FeeHeaderOverflowTest is DecoderBase { // Construct the modified CompressedFeeHeader with high excessMana. // Bit layout: manaUsed(32) | excessMana(48) | ethPerFeeAsset(48) | - // congestionCost(64) | proverCost(63) | preHeat(1) + // protocolFee(64) | proverCost(63) | preHeat(1) uint256 compressedValue = 0; compressedValue |= excessMana << 32; compressedValue |= ethPerFeeAsset << 80; @@ -317,7 +315,7 @@ contract FeeHeaderOverflowTest is DecoderBase { // The congestion multiplier is capped (excessMana > denominator * 100 threshold) assertTrue(components.congestionMultiplier > 0, "congestionMultiplier should be non-zero"); // Individual components exceed their compressed field widths - assertTrue(components.congestionCost > MAX_CONGESTION_COST, "congestionCost exceeds 64-bit limit"); + assertTrue(components.protocolFee > MAX_PROTOCOL_FEE, "protocolFee exceeds 64-bit limit"); // summedMinFee caps the total at uint128 max, ensuring the header can represent it assertEq(manaMinFee, type(uint128).max, "mana min fee should be capped at uint128 max"); @@ -334,9 +332,7 @@ contract FeeHeaderOverflowTest is DecoderBase { // Verify the stored fee header has capped values FeeHeader memory storedFeeHeader = rollup.getFeeHeader(1); - assertEq( - storedFeeHeader.congestionCost, MAX_CONGESTION_COST, "stored congestionCost should be capped at 64-bit max" - ); + assertEq(storedFeeHeader.protocolFee, MAX_PROTOCOL_FEE, "stored protocolFee should be capped at 64-bit max"); assertLe(storedFeeHeader.proverCost, MAX_PROVER_COST, "proverCost should fit in 63 bits"); } @@ -356,7 +352,7 @@ contract FeeHeaderOverflowTest is DecoderBase { * the result exceeds uint48. * * After fix: compress() caps excessMana at uint48 max (via Math.min) instead - * of reverting, consistent with the congestionCost and proverCost caps. + * of reverting, consistent with the protocolFee and proverCost caps. * At uint48 max, the congestion multiplier is already pinned at the e^100 cap, * so capping excessMana doesn't change observable fee behavior. The system * naturally recovers as manaUsed drops to 0 under extreme fees. @@ -382,7 +378,7 @@ contract FeeHeaderOverflowTest is DecoderBase { uint256 ethPerFeeAsset = genesisFeeHeader.ethPerFeeAsset; // Construct parent header with near-max excessMana and manaUsed > manaTarget. - // Bit layout: preHeat(1) | proverCost(63) | congestionCost(64) | + // Bit layout: preHeat(1) | proverCost(63) | protocolFee(64) | // ethPerFeeAsset(48) | excessMana(48) | manaUsed(32) uint256 compressedValue = 0; compressedValue |= parentManaUsed; // bits 0-31 diff --git a/l1-contracts/test/fees/FeeModelTestPoints.t.sol b/l1-contracts/test/fees/FeeModelTestPoints.t.sol index ba3bab0f4080..26d08337c4cd 100644 --- a/l1-contracts/test/fees/FeeModelTestPoints.t.sol +++ b/l1-contracts/test/fees/FeeModelTestPoints.t.sol @@ -46,8 +46,8 @@ struct L1GasOracleValuesModel { } struct ManaMinFeeComponentsModel { - uint256 congestion_cost; uint256 congestion_multiplier; + uint256 protocol_fee; uint256 prover_cost; uint256 sequencer_cost; } @@ -137,10 +137,10 @@ contract FeeModelTestPoints is TestBase { internal pure { - assertEq(a.congestion_cost, b.congestion_cost, string.concat(_message, " congestion_cost mismatch")); assertEq( a.congestion_multiplier, b.congestion_multiplier, string.concat(_message, " congestion_multiplier mismatch") ); + assertEq(a.protocol_fee, b.protocol_fee, string.concat(_message, " protocol_fee mismatch")); assertEq(a.prover_cost, b.prover_cost, string.concat(_message, " prover_cost mismatch")); assertEq(a.sequencer_cost, b.sequencer_cost, string.concat(_message, " sequencer_cost mismatch")); } diff --git a/l1-contracts/test/fees/FeeRollup.t.sol b/l1-contracts/test/fees/FeeRollup.t.sol index 52219fd3e200..4fc88fec5166 100644 --- a/l1-contracts/test/fees/FeeRollup.t.sol +++ b/l1-contracts/test/fees/FeeRollup.t.sol @@ -119,7 +119,7 @@ contract FeeRollupTest is FeeModelTestPoints, DecoderBase { vm.label(address(rewardDistributor), "REWARD DISTRIBUTOR"); vm.label(address(rollup.getFeeAssetPortal()), "FEE ASSET PORTAL"); vm.label(address(asset), "ASSET"); - vm.label(rollup.getBurnAddress(), "BURN_ADDRESS"); + vm.label(rollup.getProtocolFeeRecipient(), "BURN_ADDRESS"); } function _loadL1Metadata(uint256 index) internal { @@ -153,7 +153,7 @@ contract FeeRollupTest is FeeModelTestPoints, DecoderBase { uint128 manaMinFee = SafeCast.toUint128( point.outputs.mana_min_fee_components_in_fee_asset.sequencer_cost + point.outputs.mana_min_fee_components_in_fee_asset.prover_cost - + point.outputs.mana_min_fee_components_in_fee_asset.congestion_cost + + point.outputs.mana_min_fee_components_in_fee_asset.protocol_fee ); assertEq(rollup.getManaMinFeeAt(Timestamp.wrap(block.timestamp), true), manaMinFee, "mana min fee mismatch"); @@ -209,11 +209,11 @@ contract FeeRollupTest is FeeModelTestPoints, DecoderBase { uint256 minFee = point.outputs.mana_min_fee_components_in_fee_asset.sequencer_cost + point.outputs.mana_min_fee_components_in_fee_asset.prover_cost - + point.outputs.mana_min_fee_components_in_fee_asset.congestion_cost; + + point.outputs.mana_min_fee_components_in_fee_asset.protocol_fee; uint256 manaUsed = rollup.getFeeHeader(_checkpointNumber).manaUsed; fee = manaUsed * minFee; - burn = manaUsed * point.outputs.mana_min_fee_components_in_fee_asset.congestion_cost; + burn = manaUsed * point.outputs.mana_min_fee_components_in_fee_asset.protocol_fee; proverFee = Math.min(manaUsed * point.outputs.mana_min_fee_components_in_fee_asset.prover_cost, fee - burn); } @@ -337,6 +337,51 @@ contract FeeRollupTest is FeeModelTestPoints, DecoderBase { ); } + function test_protocolFeePaidToUpdatedRecipient() public { + // Propose through the first epoch and into the next, mirroring test_FeeModelEquivalence. + Slot nextSlot = Slot.wrap(1); + for (uint256 i = 0; i < SLOT_DURATION / 12 * (EPOCH_DURATION + 1); i++) { + _loadL1Metadata(i); + + if (rollup.getCurrentSlot() == nextSlot) { + TestPoint memory point = points[Slot.unwrap(nextSlot) - 1]; + Checkpoint memory b = getCheckpoint(); + skipBlobCheck(address(rollup)); + checkpointHeaders[rollup.getPendingCheckpointNumber() + 1] = b.header; + rollup.propose( + ProposeArgs({ + header: b.header, + archive: b.archive, + oracleInput: OracleInput({feeAssetPriceModifier: point.oracle_input.fee_asset_price_modifier}) + }), + AttestationLibHelper.packAttestations(b.attestations), + b.signers, + b.attestationsAndSignersSignature, + b.blobInputs + ); + nextSlot = nextSlot + Slot.wrap(1); + } + } + + address burnAddress = rollup.getProtocolFeeRecipient(); + address newRecipient = makeAddr("newProtocolFeeRecipient"); + + vm.prank(rollup.owner()); + rollup.setProtocolFeeRecipient(newRecipient); + assertEq(rollup.getProtocolFeeRecipient(), newRecipient, "recipient not updated"); + + uint256 start = rollup.getProvenCheckpointNumber() + 1; + uint256 used = _getUsedCheckpointsInEpoch(start, rollup.getPendingCheckpointNumber()); + (uint256 protocolFeeSum,,) = _buildEpochFees(start, used); + assertGt(protocolFeeSum, 0, "trace should accrue a protocol fee"); + + uint256 burnBalanceBefore = asset.balanceOf(burnAddress); + _submitEpochProof(start, used); + + assertEq(asset.balanceOf(newRecipient), protocolFeeSum, "protocol fee should be paid to the new recipient"); + assertEq(asset.balanceOf(burnAddress), burnBalanceBefore, "old recipient should receive nothing"); + } + function test_FeeModelEquivalence() public { Slot nextSlot = Slot.wrap(1); Epoch nextEpoch = Epoch.wrap(1); @@ -387,7 +432,7 @@ contract FeeRollupTest is FeeModelTestPoints, DecoderBase { assertEq(minFeePrediction, componentsFeeAsset.summedMinFee(), "mana min fee mismatch"); - assertEq(componentsFeeAsset.congestionCost, feeHeader.congestionCost, "congestion cost mismatch"); + assertEq(componentsFeeAsset.protocolFee, feeHeader.protocolFee, "protocol fee mismatch"); // Want to check the fee header to see if they are as we want them. assertEq(point.checkpoint_header.checkpoint_number, nextSlot, "invalid checkpoint number"); @@ -418,11 +463,11 @@ contract FeeRollupTest is FeeModelTestPoints, DecoderBase { uint256 usedCheckpointsInEpoch = _getUsedCheckpointsInEpoch(start, pendingCheckpointNumber); (uint256 burnSum, uint256 proverFees, uint256 sequencerFees) = _buildEpochFees(start, usedCheckpointsInEpoch); - uint256 burnAddressBalanceBefore = asset.balanceOf(rollup.getBurnAddress()); + uint256 burnAddressBalanceBefore = asset.balanceOf(rollup.getProtocolFeeRecipient()); uint256 sequencerRewardsBefore = rollup.getSequencerRewards(coinbase); _submitEpochProof(start, usedCheckpointsInEpoch); - uint256 burned = asset.balanceOf(rollup.getBurnAddress()) - burnAddressBalanceBefore; + uint256 burned = asset.balanceOf(rollup.getProtocolFeeRecipient()) - burnAddressBalanceBefore; assertEq(burnSum, burned, "Sum of burned does not match"); // The reward is not yet distributed, but only accumulated. @@ -452,8 +497,8 @@ contract FeeRollupTest is FeeModelTestPoints, DecoderBase { pure { ManaMinFeeComponentsModel memory bModel = ManaMinFeeComponentsModel({ - congestion_cost: b.congestionCost, congestion_multiplier: b.congestionMultiplier, + protocol_fee: b.protocolFee, prover_cost: b.proverCost, sequencer_cost: b.sequencerCost }); diff --git a/l1-contracts/test/fees/MinimalFeeModel.sol b/l1-contracts/test/fees/MinimalFeeModel.sol index 3232385e9de1..dfc494de15ad 100644 --- a/l1-contracts/test/fees/MinimalFeeModel.sol +++ b/l1-contracts/test/fees/MinimalFeeModel.sol @@ -94,8 +94,8 @@ contract MinimalFeeModel { FeeLib.getManaMinFeeComponentsAt(populatedThrough, Timestamp.wrap(block.timestamp), _inFeeAsset); return ManaMinFeeComponentsModel({ - congestion_cost: components.congestionCost, congestion_multiplier: components.congestionMultiplier, + protocol_fee: components.protocolFee, prover_cost: components.proverCost, sequencer_cost: components.sequencerCost }); diff --git a/l1-contracts/test/fees/ProtocolFeeMarginRateLimit.t.sol b/l1-contracts/test/fees/ProtocolFeeMarginRateLimit.t.sol new file mode 100644 index 000000000000..8d8803459748 --- /dev/null +++ b/l1-contracts/test/fees/ProtocolFeeMarginRateLimit.t.sol @@ -0,0 +1,311 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2026 Aztec Labs. +pragma solidity >=0.8.27; + +import {RollupBuilder} from "../builder/RollupBuilder.sol"; +import {Rollup} from "@aztec/core/Rollup.sol"; +import {IRollupCore} from "@aztec/core/interfaces/IRollup.sol"; +import {Errors} from "@aztec/core/libraries/Errors.sol"; +import { + FeeLib, + FeeStore, + ManaMinFeeComponents, + PROTOCOL_FEE_MARGIN_STEP_DEN, + PROTOCOL_FEE_MARGIN_STEP_NUM, + PROTOCOL_FEE_MARGIN_UPDATE_INTERVAL, + MINIMUM_CONGESTION_MULTIPLIER, + EthValue +} from "@aztec/core/libraries/rollup/FeeLib.sol"; +import {Timestamp, TimeLib} from "@aztec/core/libraries/TimeLib.sol"; +import { + FeeConfig, + FeeConfigLib, + CompressedFeeConfig, + EthPerFeeAssetE12 +} from "@aztec/core/libraries/compressed-data/fees/FeeConfig.sol"; +import {TestConstants} from "../harnesses/TestConstants.sol"; +import {Ownable} from "@oz/access/Ownable.sol"; +import {Test} from "forge-std/Test.sol"; +import {Vm} from "forge-std/Vm.sol"; + +/** + * @notice Harness exposing FeeLib's margin updater on its own storage, so states that the + * hardcoded mu=0 deployment cannot produce (a nonzero margin with no cooldown stamp, + * i.e. a deployment starting at mu > 0) can still be exercised. + */ +contract FeeLibMarginHarness { + using FeeConfigLib for FeeConfig; + using FeeConfigLib for CompressedFeeConfig; + + constructor() { + TimeLib.initialize( + block.timestamp, + TestConstants.AZTEC_SLOT_DURATION, + TestConstants.AZTEC_EPOCH_DURATION, + TestConstants.AZTEC_PROOF_SUBMISSION_EPOCHS + ); + FeeLib.initialize( + TestConstants.AZTEC_MANA_TARGET, EthValue.wrap(100), TestConstants.AZTEC_INITIAL_ETH_PER_FEE_ASSET + ); + } + + /// @notice Writes the margin directly into config without stamping the cooldown, emulating a + /// deployment that starts at a nonzero margin. + function seedMargin(uint16 _bps) external { + FeeStore storage feeStore = FeeLib.getStorage(); + FeeConfig memory config = feeStore.config.decompress(); + config.protocolFeeMarginBps = _bps; + feeStore.config = config.compress(); + } + + function update(uint16 _bps) external returns (bool, uint16) { + return FeeLib.updateProtocolFeeMargin(_bps); + } + + function getMargin() external view returns (uint16) { + return FeeLib.getProtocolFeeMarginBps(); + } + + function getLastUpdate() external view returns (uint64) { + return FeeLib.getStorage().protocolMarginLastUpdate; + } + + function congestionMultiplierAt(uint256 _excessMana) external view returns (uint256) { + return FeeLib.congestionMultiplier(_excessMana); + } + + /// @notice The components at checkpoint 0 (zero excess mana), in wei. + function components() external view returns (ManaMinFeeComponents memory) { + return FeeLib.getManaMinFeeComponentsAt(0, Timestamp.wrap(block.timestamp), false); + } +} + +/** + * @title ProtocolFeeMarginRateLimitTest + * @notice Exercises the rate limiter on setProtocolFeeMargin: + * + * - multiplicative step cap (3/2) on the fee multiplier (10_000 + bps) + * - cooldown (30 days) between updates, with the first post-init update exempt + * - immediate, unrestricted decreases that still stamp the cooldown + * - idempotent no-op when setting the current value + * + * Tests go through the real Rollup surface so the whole path is validated; the + * first-ever-update-is-a-decrease case uses the FeeLib harness because the deployed + * margin is hardcoded to 0. + */ +contract ProtocolFeeMarginRateLimitTest is Test { + // From 0, the step cap permits (10_000 + new) * 2 <= (10_000 + 0) * 3, i.e. new <= 5000. + uint16 internal constant MAX_FIRST_STEP = 5000; + + Rollup internal rollup; + + function setUp() public { + RollupBuilder builder = new RollupBuilder(address(this)).setMakeGovernance(false).setTargetCommitteeSize(0); + builder.deploy(); + rollup = builder.getConfig().rollup; + } + + function test_initialMarginIsZero() public view { + assertEq(rollup.getProtocolFeeMargin(), 0); + } + + function test_revertsWhen_notOwner(address _caller) public { + vm.assume(_caller != address(this)); + vm.prank(_caller); + vm.expectRevert(abi.encodeWithSelector(Ownable.OwnableUnauthorizedAccount.selector, _caller)); + rollup.setProtocolFeeMargin(1); + + vm.prank(_caller); + vm.expectRevert(abi.encodeWithSelector(Ownable.OwnableUnauthorizedAccount.selector, _caller)); + rollup.setProtocolFeeRecipient(address(0xbeef)); + } + + // --------------------------------------------------------------------- + // Step cap + // --------------------------------------------------------------------- + + function test_firstUpdate_bypassesCooldown_atStepCap() public { + vm.expectEmit(true, true, true, true, address(rollup)); + emit IRollupCore.ProtocolFeeMarginUpdated(0, MAX_FIRST_STEP); + rollup.setProtocolFeeMargin(MAX_FIRST_STEP); + assertEq(rollup.getProtocolFeeMargin(), MAX_FIRST_STEP); + } + + function test_revertsWhen_aboveStepCap() public { + vm.expectRevert( + abi.encodeWithSelector(Errors.FeeLib__ProtocolFeeMarginStepExceeded.selector, 0, MAX_FIRST_STEP + 1) + ); + rollup.setProtocolFeeMargin(MAX_FIRST_STEP + 1); + } + + function test_stepCapBoundsTheFeeMultiplier() public { + rollup.setProtocolFeeMargin(MAX_FIRST_STEP); + + // From 5000, the cap permits (10_000 + new) * 2 <= 15_000 * 3, i.e. new <= 12_500. + uint16 nextMax = + uint16((10_000 + uint256(MAX_FIRST_STEP)) * PROTOCOL_FEE_MARGIN_STEP_NUM / PROTOCOL_FEE_MARGIN_STEP_DEN - 10_000); + assertEq(nextMax, 12_500); + + vm.warp(block.timestamp + PROTOCOL_FEE_MARGIN_UPDATE_INTERVAL); + vm.expectRevert( + abi.encodeWithSelector(Errors.FeeLib__ProtocolFeeMarginStepExceeded.selector, MAX_FIRST_STEP, nextMax + 1) + ); + rollup.setProtocolFeeMargin(nextMax + 1); + + rollup.setProtocolFeeMargin(nextMax); + assertEq(rollup.getProtocolFeeMargin(), nextMax); + } + + // --------------------------------------------------------------------- + // Cooldown + // --------------------------------------------------------------------- + + function test_revertsWhen_withinCooldown() public { + rollup.setProtocolFeeMargin(1000); + + uint256 nextAllowed = block.timestamp + PROTOCOL_FEE_MARGIN_UPDATE_INTERVAL; + vm.expectRevert(abi.encodeWithSelector(Errors.FeeLib__ProtocolFeeMarginCooldown.selector, nextAllowed)); + rollup.setProtocolFeeMargin(1100); + } + + function test_succeedsAt_cooldownBoundary() public { + rollup.setProtocolFeeMargin(1000); + + vm.warp(block.timestamp + PROTOCOL_FEE_MARGIN_UPDATE_INTERVAL); + rollup.setProtocolFeeMargin(1100); + assertEq(rollup.getProtocolFeeMargin(), 1100); + } + + function test_revertsWhen_oneSecondShortOfCooldown() public { + rollup.setProtocolFeeMargin(1000); + + uint256 nextAllowed = block.timestamp + PROTOCOL_FEE_MARGIN_UPDATE_INTERVAL; + vm.warp(nextAllowed - 1); + vm.expectRevert(abi.encodeWithSelector(Errors.FeeLib__ProtocolFeeMarginCooldown.selector, nextAllowed)); + rollup.setProtocolFeeMargin(1100); + } + + // --------------------------------------------------------------------- + // Decreases + // --------------------------------------------------------------------- + + function test_decreaseIsImmediate_butStampsCooldown() public { + rollup.setProtocolFeeMargin(MAX_FIRST_STEP); + + // A decrease is not gated by the cooldown that is still running from the increase. + vm.expectEmit(true, true, true, true, address(rollup)); + emit IRollupCore.ProtocolFeeMarginUpdated(MAX_FIRST_STEP, 1000); + rollup.setProtocolFeeMargin(1000); + assertEq(rollup.getProtocolFeeMargin(), 1000); + + // But it stamps the cooldown: the next increase reverts until 30 days after the DECREASE. + uint256 nextAllowed = block.timestamp + PROTOCOL_FEE_MARGIN_UPDATE_INTERVAL; + vm.expectRevert(abi.encodeWithSelector(Errors.FeeLib__ProtocolFeeMarginCooldown.selector, nextAllowed)); + rollup.setProtocolFeeMargin(1100); + + vm.warp(nextAllowed - 1); + vm.expectRevert(abi.encodeWithSelector(Errors.FeeLib__ProtocolFeeMarginCooldown.selector, nextAllowed)); + rollup.setProtocolFeeMargin(1100); + + vm.warp(nextAllowed); + rollup.setProtocolFeeMargin(1100); + assertEq(rollup.getProtocolFeeMargin(), 1100); + } + + function test_decreaseToZeroIsAlwaysAllowed() public { + rollup.setProtocolFeeMargin(MAX_FIRST_STEP); + rollup.setProtocolFeeMargin(0); + assertEq(rollup.getProtocolFeeMargin(), 0); + } + + /// @notice A decrease as the first-ever update (only reachable on a deployment starting at + /// mu > 0) succeeds unrestricted but consumes the lastUpdate == 0 cooldown bypass. + function test_decreaseAsFirstUpdate_consumesBypass() public { + FeeLibMarginHarness harness = new FeeLibMarginHarness(); + harness.seedMargin(1000); + assertEq(harness.getLastUpdate(), 0, "seeding must not stamp the cooldown"); + + (bool changed, uint16 oldBps) = harness.update(500); + assertTrue(changed); + assertEq(oldBps, 1000); + assertEq(harness.getMargin(), 500); + assertEq(harness.getLastUpdate(), uint64(block.timestamp), "decrease must stamp the cooldown"); + + uint256 nextAllowed = block.timestamp + PROTOCOL_FEE_MARGIN_UPDATE_INTERVAL; + vm.expectRevert(abi.encodeWithSelector(Errors.FeeLib__ProtocolFeeMarginCooldown.selector, nextAllowed)); + harness.update(600); + + vm.warp(nextAllowed); + harness.update(600); + assertEq(harness.getMargin(), 600); + } + + // --------------------------------------------------------------------- + // Idempotency + // --------------------------------------------------------------------- + + function test_idempotentAtZero_noEventNoStamp() public { + vm.recordLogs(); + rollup.setProtocolFeeMargin(0); + Vm.Log[] memory logs = vm.getRecordedLogs(); + assertEq(logs.length, 0, "no-op must emit no events"); + + // The first-update bypass is still available, proving the no-op did not stamp lastUpdate. + rollup.setProtocolFeeMargin(MAX_FIRST_STEP); + assertEq(rollup.getProtocolFeeMargin(), MAX_FIRST_STEP); + } + + function test_idempotentAtNonZero_noRevertNoEventNoStamp() public { + rollup.setProtocolFeeMargin(1000); + uint256 nextAllowed = block.timestamp + PROTOCOL_FEE_MARGIN_UPDATE_INTERVAL; + + // Same-value call inside the cooldown window must not revert, emit, or change state. + vm.warp(block.timestamp + PROTOCOL_FEE_MARGIN_UPDATE_INTERVAL / 2); + vm.recordLogs(); + rollup.setProtocolFeeMargin(1000); + Vm.Log[] memory logs = vm.getRecordedLogs(); + assertEq(logs.length, 0, "no-op must emit no events"); + assertEq(rollup.getProtocolFeeMargin(), 1000); + + // The original cooldown boundary is unchanged: an increase succeeds at the boundary set by + // the FIRST update. Had the no-op stamped lastUpdate, this would still be cooling down. + vm.warp(nextAllowed); + rollup.setProtocolFeeMargin(1100); + assertEq(rollup.getProtocolFeeMargin(), 1100); + } + + // --------------------------------------------------------------------- + // Multiplier scaling + // --------------------------------------------------------------------- + + /// @notice At zero excess mana the congestion multiplier equals the scaled factor exactly: + /// (10_000 + bps) * 1e5, which is (1 + mu) * MINIMUM_CONGESTION_MULTIPLIER. + function test_multiplierAtZeroExcessEqualsScaledFactor(uint16 _bps) public { + FeeLibMarginHarness harness = new FeeLibMarginHarness(); + assertEq(harness.congestionMultiplierAt(0), MINIMUM_CONGESTION_MULTIPLIER, "mu=0 baseline must be 1e9"); + + harness.seedMargin(_bps); + assertEq(harness.congestionMultiplierAt(0), (10_000 + uint256(_bps)) * 1e5, "baseline must scale with (1+mu)"); + } + + /// @notice At mu = 5000 the fee components carry a nonzero margin tranche while operator costs + /// stay untouched. This is the L1-side guard against the silent cancellation where both + /// the fakeExponential factor AND the mulDiv divisor get scaled and mu vanishes. + function test_componentsScaleWithMargin() public { + FeeLibMarginHarness harness = new FeeLibMarginHarness(); + + ManaMinFeeComponents memory base = harness.components(); + assertEq(base.protocolFee, 0, "mu=0 at zero excess must have no protocol fee"); + + harness.seedMargin(5000); + ManaMinFeeComponents memory scaled = harness.components(); + + assertEq(scaled.sequencerCost, base.sequencerCost, "sequencer cost must not scale with mu"); + assertEq(scaled.proverCost, base.proverCost, "prover cost must not scale with mu"); + + // At zero excess mana the entire protocol fee is the margin: floor(cost * 3 / 2) - cost. + uint256 cost = base.sequencerCost + base.proverCost; + assertEq(scaled.protocolFee, cost * 15_000 / 10_000 - cost, "protocol fee must be exactly mu * cost"); + assertGt(scaled.protocolFee, 0, "mu=5000 must produce a nonzero protocol fee"); + } +} diff --git a/l1-contracts/test/fees/ProtocolFeeNearCap.t.sol b/l1-contracts/test/fees/ProtocolFeeNearCap.t.sol new file mode 100644 index 000000000000..fdac3d1633b6 --- /dev/null +++ b/l1-contracts/test/fees/ProtocolFeeNearCap.t.sol @@ -0,0 +1,93 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2026 Aztec Labs. +pragma solidity >=0.8.27; + +import {FeeLib, ManaMinFeeComponents} from "@aztec/core/libraries/rollup/FeeLib.sol"; +import {Test} from "forge-std/Test.sol"; + +/** + * @title ProtocolFeeNearCapTest + * @notice The fee header's per-mana protocol fee moved from the separately-converted congestion + * component to the single subtraction `summedMinFee - sequencerCost - proverCost`. The + * two are identical whenever the uint128 cap in summedMinFee does not bind, which is the + * only place mu = 0 behavior genuinely changes. These fuzzes pin that equivalence and the + * cap-binding/clamp behavior. + */ +contract ProtocolFeeNearCapTest is Test { + uint256 internal constant CAP = type(uint128).max; + + function _components(uint256 _sequencerCost, uint256 _proverCost, uint256 _protocolFee) + internal + pure + returns (ManaMinFeeComponents memory) + { + return ManaMinFeeComponents({ + sequencerCost: _sequencerCost, proverCost: _proverCost, protocolFee: _protocolFee, congestionMultiplier: 0 + }); + } + + /// @notice When the cap does not bind, the header value equals the old behavior (the + /// separately-converted congestion component) exactly. + function test_headerValueUnchangedWhenCapDoesNotBind( + uint128 _sequencerCost, + uint128 _proverCost, + uint128 _protocolFee + ) public pure { + // Bound the sum inside the cap; the components stay near it. + uint256 s = uint256(_sequencerCost); + uint256 p = uint256(_proverCost); + uint256 c = uint256(_protocolFee); + vm.assume(s + p + c <= CAP); + + ManaMinFeeComponents memory components = _components(s, p, c); + assertEq(FeeLib.summedMinFee(components), s + p + c, "cap must not bind"); + assertEq(FeeLib.protocolFeePerMana(components), c, "header value must equal the old congestion component"); + } + + /// @notice When the cap binds but still covers operator cost, the header value is exactly + /// `cap - sequencerCost - proverCost`: the shortfall reduces only the protocol tranche + /// and operators stay whole. + function test_operatorsWholeWhenCapBinds(uint128 _sequencerCost, uint128 _proverCost, uint256 _protocolFee) + public + pure + { + uint256 s = uint256(_sequencerCost); + uint256 p = uint256(_proverCost); + vm.assume(s + p <= CAP); + // Force the cap to bind: the raw sum must exceed the cap. + uint256 c = bound(_protocolFee, CAP + 1 - s - p, type(uint256).max - s - p); + + ManaMinFeeComponents memory components = _components(s, p, c); + uint256 headerValue = FeeLib.protocolFeePerMana(components); + + assertEq(FeeLib.summedMinFee(components), CAP, "cap must bind"); + assertEq(headerValue, CAP - s - p, "shortfall must reduce only the protocol tranche"); + assertEq(FeeLib.summedMinFee(components) - headerValue, s + p, "operators must stay whole"); + assertLt(headerValue, c, "protocol tranche must absorb the shortfall"); + } + + /// @notice When the capped fee cannot even cover operator cost, the header value clamps to 0 + /// instead of underflowing. + function test_negativeClampWhenOperatorCostExceedsCap( + uint256 _sequencerCost, + uint256 _proverCost, + uint256 _protocolFee + ) public pure { + uint256 s = bound(_sequencerCost, 1, CAP); + uint256 p = bound(_proverCost, CAP + 1 - s, CAP); + uint256 c = bound(_protocolFee, 0, CAP); + // Operator cost alone exceeds the cap, so the subtraction would go negative. + assertGt(s + p, CAP, "setup: operator cost must exceed the cap"); + + ManaMinFeeComponents memory components = _components(s, p, c); + assertEq(FeeLib.summedMinFee(components), CAP, "cap must bind"); + assertEq(FeeLib.protocolFeePerMana(components), 0, "header value must clamp to zero"); + } + + /// @notice Boundary: operator cost equal to the capped fee leaves exactly zero for the protocol. + function test_zeroAtExactBoundary() public pure { + ManaMinFeeComponents memory components = _components(CAP - 1, 1, 5); + assertEq(FeeLib.summedMinFee(components), CAP, "cap must bind"); + assertEq(FeeLib.protocolFeePerMana(components), 0, "capped fee == operator cost must give zero"); + } +} diff --git a/l1-contracts/test/fees/ProtocolFeeRecipient.t.sol b/l1-contracts/test/fees/ProtocolFeeRecipient.t.sol new file mode 100644 index 000000000000..d0c3d42822f8 --- /dev/null +++ b/l1-contracts/test/fees/ProtocolFeeRecipient.t.sol @@ -0,0 +1,61 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2026 Aztec Labs. +pragma solidity >=0.8.27; + +import {RollupBuilder} from "../builder/RollupBuilder.sol"; +import {Rollup} from "@aztec/core/Rollup.sol"; +import {IRollupCore} from "@aztec/core/interfaces/IRollup.sol"; +import {Errors} from "@aztec/core/libraries/Errors.sol"; +import {Ownable} from "@oz/access/Ownable.sol"; +import {Test} from "forge-std/Test.sol"; + +/** + * @title ProtocolFeeRecipientTest + * @notice Exercises the protocol fee recipient setter semantics: burn-address default, + * owner gating, zero-address rejection, and event emission. The end-to-end + * "epoch proof pays the new recipient" flow lives in FeeRollup.t.sol, which owns + * the proven-epoch machinery. + */ +contract ProtocolFeeRecipientTest is Test { + address internal constant BURN_ADDRESS = address(bytes20("CUAUHXICALLI")); + + Rollup internal rollup; + + function setUp() public { + RollupBuilder builder = new RollupBuilder(address(this)).setMakeGovernance(false).setTargetCommitteeSize(0); + builder.deploy(); + rollup = builder.getConfig().rollup; + } + + function test_defaultIsBurnAddress() public view { + assertEq(rollup.getProtocolFeeRecipient(), BURN_ADDRESS); + } + + function test_revertsWhen_notOwner(address _caller) public { + vm.assume(_caller != address(this)); + vm.prank(_caller); + vm.expectRevert(abi.encodeWithSelector(Ownable.OwnableUnauthorizedAccount.selector, _caller)); + rollup.setProtocolFeeRecipient(address(0xbeef)); + } + + function test_revertsWhen_zeroAddress() public { + vm.expectRevert(abi.encodeWithSelector(Errors.RewardLib__InvalidProtocolFeeRecipient.selector)); + rollup.setProtocolFeeRecipient(address(0)); + } + + function test_setEmitsEventAndUpdates(address _recipient) public { + vm.assume(_recipient != address(0)); + + vm.expectEmit(true, true, true, true, address(rollup)); + emit IRollupCore.ProtocolFeeRecipientUpdated(BURN_ADDRESS, _recipient); + rollup.setProtocolFeeRecipient(_recipient); + assertEq(rollup.getProtocolFeeRecipient(), _recipient); + + // Setting again (even to the same value) always sets and emits; idempotency is a + // margin-setter property only. + vm.expectEmit(true, true, true, true, address(rollup)); + emit IRollupCore.ProtocolFeeRecipientUpdated(_recipient, _recipient); + rollup.setProtocolFeeRecipient(_recipient); + assertEq(rollup.getProtocolFeeRecipient(), _recipient); + } +} diff --git a/l1-contracts/test/fixtures/fee_data_points.json b/l1-contracts/test/fixtures/fee_data_points.json index 525af1148a0e..8dff8fff3a53 100644 --- a/l1-contracts/test/fixtures/fee_data_points.json +++ b/l1-contracts/test/fixtures/fee_data_points.json @@ -12044,13 +12044,13 @@ "slot_of_change": 5 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 0, + "protocol_fee": 0, "congestion_multiplier": 1000000000, "prover_cost": 18201193100000, "sequencer_cost": 400000100000 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 0, + "protocol_fee": 0, "congestion_multiplier": 1000000000, "prover_cost": 182011931, "sequencer_cost": 4000001 @@ -12098,13 +12098,13 @@ "slot_of_change": 5 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 2324332829961, + "protocol_fee": 2324332829961, "congestion_multiplier": 1124118914, "prover_cost": 18323963656499, "sequencer_cost": 402698177792 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 23087598, + "protocol_fee": 23087598, "congestion_multiplier": 1124118914, "prover_cost": 182011931, "sequencer_cost": 4000001 @@ -12152,13 +12152,13 @@ "slot_of_change": 5 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 4971774534903, + "protocol_fee": 4971774534903, "congestion_multiplier": 1263633325, "prover_cost": 18453135605739, "sequencer_cost": 405536936346 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 49038944, + "protocol_fee": 49038944, "congestion_multiplier": 1263633325, "prover_cost": 182011931, "sequencer_cost": 4000001 @@ -12206,13 +12206,13 @@ "slot_of_change": 5 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 7902350145560, + "protocol_fee": 7902350145560, "congestion_multiplier": 1420454705, "prover_cost": 18390609016628, "sequencer_cost": 404162815333 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 78209591, + "protocol_fee": 78209591, "congestion_multiplier": 1420454705, "prover_cost": 182011931, "sequencer_cost": 4000001 @@ -12260,13 +12260,13 @@ "slot_of_change": 5 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 15590305224342, + "protocol_fee": 15590305224342, "congestion_multiplier": 1596746902, "prover_cost": 20330472542484, "sequencer_cost": 5795017472143 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 154991643, + "protocol_fee": 154991643, "congestion_multiplier": 1596746902, "prover_cost": 202116206, "sequencer_cost": 57611398 @@ -12314,13 +12314,13 @@ "slot_of_change": 5 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 20661586825218, + "protocol_fee": 20661586825218, "congestion_multiplier": 1794892619, "prover_cost": 20227314973689, "sequencer_cost": 5765613339391 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 206455555, + "protocol_fee": 206455555, "congestion_multiplier": 1794892619, "prover_cost": 202116206, "sequencer_cost": 57611398 @@ -12368,13 +12368,13 @@ "slot_of_change": 5 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 26459033982856, + "protocol_fee": 26459033982856, "congestion_multiplier": 2017626606, "prover_cost": 20233385652947, "sequencer_cost": 5767343731653 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 264305720, + "protocol_fee": 264305720, "congestion_multiplier": 2017626606, "prover_cost": 202116206, "sequencer_cost": 57611398 @@ -12422,13 +12422,13 @@ "slot_of_change": 10 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 32943403545421, + "protocol_fee": 32943403545421, "congestion_multiplier": 2268032006, "prover_cost": 20217212681028, "sequencer_cost": 5762733772162 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 329342914, + "protocol_fee": 329342914, "congestion_multiplier": 2268032006, "prover_cost": 202116206, "sequencer_cost": 57611398 @@ -12476,13 +12476,13 @@ "slot_of_change": 10 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 40204640253022, + "protocol_fee": 40204640253022, "congestion_multiplier": 2549537632, "prover_cost": 20190965242557, "sequencer_cost": 5755252177023 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 402457696, + "protocol_fee": 402457696, "congestion_multiplier": 2549537632, "prover_cost": 202116206, "sequencer_cost": 57611398 @@ -12530,13 +12530,13 @@ "slot_of_change": 10 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 45811394730939, + "protocol_fee": 45811394730939, "congestion_multiplier": 2775565163, "prover_cost": 20125189800853, "sequencer_cost": 5675831609382 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 459499742, + "protocol_fee": 459499742, "congestion_multiplier": 2775565163, "prover_cost": 201860685, "sequencer_cost": 56930010 @@ -12584,13 +12584,13 @@ "slot_of_change": 10 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 55002024544558, + "protocol_fee": 55002024544558, "congestion_multiplier": 3120052117, "prover_cost": 20236491766535, "sequencer_cost": 5707221684271 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 548649760, + "protocol_fee": 548649760, "congestion_multiplier": 3120052117, "prover_cost": 201860685, "sequencer_cost": 56930010 @@ -12638,13 +12638,13 @@ "slot_of_change": 10 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 51852768777659, + "protocol_fee": 51852768777659, "congestion_multiplier": 2998064412, "prover_cost": 20242565500312, "sequencer_cost": 5708934636571 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 517080477, + "protocol_fee": 517080477, "congestion_multiplier": 2998064412, "prover_cost": 201860685, "sequencer_cost": 56930010 @@ -12692,13 +12692,13 @@ "slot_of_change": 15 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 61019783490946, + "protocol_fee": 61019783490946, "congestion_multiplier": 3370111057, "prover_cost": 20081911657000, "sequencer_cost": 5663626037196 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 613362687, + "protocol_fee": 613362687, "congestion_multiplier": 3370111057, "prover_cost": 201860685, "sequencer_cost": 56930010 @@ -12746,13 +12746,13 @@ "slot_of_change": 15 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 71430632366953, + "protocol_fee": 71430632366953, "congestion_multiplier": 3788358280, "prover_cost": 19982002301496, "sequencer_cost": 5635448977320 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 721601177, + "protocol_fee": 721601177, "congestion_multiplier": 3788358280, "prover_cost": 201860685, "sequencer_cost": 56930010 @@ -12800,13 +12800,13 @@ "slot_of_change": 15 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 86339730542451, + "protocol_fee": 86339730542451, "congestion_multiplier": 4258548217, "prover_cost": 20283076926138, "sequencer_cost": 6213302707356 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 868115340, + "protocol_fee": 868115340, "congestion_multiplier": 4258548217, "prover_cost": 203939138, "sequencer_cost": 62472553 @@ -12854,13 +12854,13 @@ "slot_of_change": 15 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 100300348873300, + "protocol_fee": 100300348873300, "congestion_multiplier": 4786949836, "prover_cost": 20274968668808, "sequencer_cost": 6210818909784 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 1008887709, + "protocol_fee": 1008887709, "congestion_multiplier": 4786949836, "prover_cost": 203939138, "sequencer_cost": 62472553 @@ -12908,13 +12908,13 @@ "slot_of_change": 15 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 104459385614940, + "protocol_fee": 104459385614940, "congestion_multiplier": 4946739595, "prover_cost": 20260786251776, "sequencer_cost": 6206474418539 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 1051457569, + "protocol_fee": 1051457569, "congestion_multiplier": 4946739595, "prover_cost": 203939138, "sequencer_cost": 62472553 @@ -12962,13 +12962,13 @@ "slot_of_change": 20 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 105687201225103, + "protocol_fee": 105687201225103, "congestion_multiplier": 4969969063, "prover_cost": 20378986192614, "sequencer_cost": 6242682535044 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 1057646171, + "protocol_fee": 1057646171, "congestion_multiplier": 4969969063, "prover_cost": 203939138, "sequencer_cost": 62472553 @@ -13016,13 +13016,13 @@ "slot_of_change": 20 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 103489070990129, + "protocol_fee": 103489070990129, "congestion_multiplier": 4903726632, "prover_cost": 20293753977246, "sequencer_cost": 6216573401975 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 1039998413, + "protocol_fee": 1039998413, "congestion_multiplier": 4903726632, "prover_cost": 203939138, "sequencer_cost": 62472553 @@ -13070,13 +13070,13 @@ "slot_of_change": 20 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 109806009745847, + "protocol_fee": 109806009745847, "congestion_multiplier": 4875108282, "prover_cost": 20820534970420, "sequencer_cost": 7515708001978 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 1101051872, + "protocol_fee": 1101051872, "congestion_multiplier": 4875108282, "prover_cost": 208772626, "sequencer_cost": 75361853 @@ -13124,13 +13124,13 @@ "slot_of_change": 20 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 112592774387203, + "protocol_fee": 112592774387203, "congestion_multiplier": 4964712959, "prover_cost": 20866441263561, "sequencer_cost": 7532279060080 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 1126511650, + "protocol_fee": 1126511650, "congestion_multiplier": 4964712959, "prover_cost": 208772626, "sequencer_cost": 75361853 @@ -13178,13 +13178,13 @@ "slot_of_change": 20 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 112941322429969, + "protocol_fee": 112941322429969, "congestion_multiplier": 4964657304, "prover_cost": 20931330319348, "sequencer_cost": 7555702434960 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 1126495837, + "protocol_fee": 1126495837, "congestion_multiplier": 4964657304, "prover_cost": 208772626, "sequencer_cost": 75361853 @@ -13232,13 +13232,13 @@ "slot_of_change": 25 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 111348587401187, + "protocol_fee": 111348587401187, "congestion_multiplier": 4930635271, "prover_cost": 20814768339538, "sequencer_cost": 7513626388133 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 1116829004, + "protocol_fee": 1116829004, "congestion_multiplier": 4930635271, "prover_cost": 208772626, "sequencer_cost": 75361853 @@ -13286,13 +13286,13 @@ "slot_of_change": 25 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 109292781895253, + "protocol_fee": 109292781895253, "congestion_multiplier": 4864237667, "prover_cost": 20781517990316, "sequencer_cost": 7501623818743 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 1097963156, + "protocol_fee": 1097963156, "congestion_multiplier": 4864237667, "prover_cost": 208772626, "sequencer_cost": 75361853 @@ -13340,13 +13340,13 @@ "slot_of_change": 25 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 112206317006340, + "protocol_fee": 112206317006340, "congestion_multiplier": 4897128589, "prover_cost": 21005808869294, "sequencer_cost": 7786240082431 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 1119905667, + "protocol_fee": 1119905667, "congestion_multiplier": 4897128589, "prover_cost": 209654189, "sequencer_cost": 77712687 @@ -13394,13 +13394,13 @@ "slot_of_change": 25 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 112373187111775, + "protocol_fee": 112373187111775, "congestion_multiplier": 4897850096, "prover_cost": 21033154069365, "sequencer_cost": 7796376149753 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 1120113005, + "protocol_fee": 1120113005, "congestion_multiplier": 4897850096, "prover_cost": 209654189, "sequencer_cost": 77712687 @@ -13448,13 +13448,13 @@ "slot_of_change": 25 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 111933984719410, + "protocol_fee": 111933984719410, "congestion_multiplier": 4909793723, "prover_cost": 20886946641469, "sequencer_cost": 7742181324763 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 1123545207, + "protocol_fee": 1123545207, "congestion_multiplier": 4909793723, "prover_cost": 209654189, "sequencer_cost": 77712687 @@ -13502,13 +13502,13 @@ "slot_of_change": 30 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 111992305615124, + "protocol_fee": 111992305615124, "congestion_multiplier": 4939995825, "prover_cost": 20737636698504, "sequencer_cost": 7686836488016 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 1132224291, + "protocol_fee": 1132224291, "congestion_multiplier": 4939995825, "prover_cost": 209654189, "sequencer_cost": 77712687 @@ -13556,13 +13556,13 @@ "slot_of_change": 30 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 112654997800540, + "protocol_fee": 112654997800540, "congestion_multiplier": 4939926067, "prover_cost": 20860716875929, "sequencer_cost": 7732458716457 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 1132204245, + "protocol_fee": 1132204245, "congestion_multiplier": 4939926067, "prover_cost": 209654189, "sequencer_cost": 77712687 @@ -13610,13 +13610,13 @@ "slot_of_change": 30 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 108794925270861, + "protocol_fee": 108794925270861, "congestion_multiplier": 4848820952, "prover_cost": 20735308951453, "sequencer_cost": 7531769893250 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 1096471268, + "protocol_fee": 1096471268, "congestion_multiplier": 4848820952, "prover_cost": 208977307, "sequencer_cost": 75907670 @@ -13664,13 +13664,13 @@ "slot_of_change": 30 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 110435262774799, + "protocol_fee": 110435262774799, "congestion_multiplier": 4933026498, "prover_cost": 20597308654619, "sequencer_cost": 7481643488893 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 1120460163, + "protocol_fee": 1120460163, "congestion_multiplier": 4933026498, "prover_cost": 208977307, "sequencer_cost": 75907670 @@ -13718,13 +13718,13 @@ "slot_of_change": 30 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 111009253702983, + "protocol_fee": 111009253702983, "congestion_multiplier": 4957817178, "prover_cost": 20574677402761, "sequencer_cost": 7473423048012 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 1127522655, + "protocol_fee": 1127522655, "congestion_multiplier": 4957817178, "prover_cost": 208977307, "sequencer_cost": 75907670 @@ -13772,13 +13772,13 @@ "slot_of_change": 35 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 112348711722159, + "protocol_fee": 112348711722159, "congestion_multiplier": 5009978774, "prover_cost": 20552071573822, "sequencer_cost": 7465211841600 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 1142382710, + "protocol_fee": 1142382710, "congestion_multiplier": 5009978774, "prover_cost": 208977307, "sequencer_cost": 75907670 @@ -13826,13 +13826,13 @@ "slot_of_change": 35 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 111661120539909, + "protocol_fee": 111661120539909, "congestion_multiplier": 5010545122, "prover_cost": 20423405281695, "sequencer_cost": 7418475865417 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 1142544054, + "protocol_fee": 1142544054, "congestion_multiplier": 5010545122, "prover_cost": 208977307, "sequencer_cost": 75907670 @@ -13880,13 +13880,13 @@ "slot_of_change": 35 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 113845851463423, + "protocol_fee": 113845851463423, "congestion_multiplier": 4969411185, "prover_cost": 20578213013282, "sequencer_cost": 8102577705901 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 1171655168, + "protocol_fee": 1171655168, "congestion_multiplier": 4969411185, "prover_cost": 211782593, "sequencer_cost": 83388432 @@ -13934,13 +13934,13 @@ "slot_of_change": 35 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 115884788598170, + "protocol_fee": 115884788598170, "congestion_multiplier": 5015854701, "prover_cost": 20704511099723, "sequencer_cost": 8152307002552 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 1185363948, + "protocol_fee": 1185363948, "congestion_multiplier": 5015854701, "prover_cost": 211782593, "sequencer_cost": 83388432 @@ -13988,13 +13988,13 @@ "slot_of_change": 35 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 115998726647802, + "protocol_fee": 115998726647802, "congestion_multiplier": 5022616891, "prover_cost": 20690028423285, "sequencer_cost": 8146604514627 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 1187359950, + "protocol_fee": 1187359950, "congestion_multiplier": 5022616891, "prover_cost": 211782593, "sequencer_cost": 83388432 @@ -14042,13 +14042,13 @@ "slot_of_change": 40 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 114124767142106, + "protocol_fee": 114124767142106, "congestion_multiplier": 4979794073, "prover_cost": 20574810398420, "sequencer_cost": 8101237941787 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 1174719895, + "protocol_fee": 1174719895, "congestion_multiplier": 4979794073, "prover_cost": 211782593, "sequencer_cost": 83388432 @@ -14096,13 +14096,13 @@ "slot_of_change": 40 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 107874083274598, + "protocol_fee": 107874083274598, "congestion_multiplier": 4761818296, "prover_cost": 20574810398420, "sequencer_cost": 8101237941787 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 1110379762, + "protocol_fee": 1110379762, "congestion_multiplier": 4761818296, "prover_cost": 211782593, "sequencer_cost": 83388432 @@ -14150,13 +14150,13 @@ "slot_of_change": 40 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 105703105410698, + "protocol_fee": 105703105410698, "congestion_multiplier": 4902630819, "prover_cost": 20066105403455, "sequencer_cost": 7018984211454 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 1094452596, + "protocol_fee": 1094452596, "congestion_multiplier": 4902630819, "prover_cost": 207764957, "sequencer_cost": 72674738 @@ -14204,13 +14204,13 @@ "slot_of_change": 40 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 106040097441787, + "protocol_fee": 106040097441787, "congestion_multiplier": 4917421682, "prover_cost": 20054073762985, "sequencer_cost": 7014775627238 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 1098600541, + "protocol_fee": 1098600541, "congestion_multiplier": 4917421682, "prover_cost": 207764957, "sequencer_cost": 72674738 @@ -14258,13 +14258,13 @@ "slot_of_change": 40 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 107752104958614, + "protocol_fee": 107752104958614, "congestion_multiplier": 4965541513, "prover_cost": 20130570122591, "sequencer_cost": 7041533522181 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 1112095252, + "protocol_fee": 1112095252, "congestion_multiplier": 4965541513, "prover_cost": 207764957, "sequencer_cost": 72674738 @@ -14312,13 +14312,13 @@ "slot_of_change": 45 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 106772490242308, + "protocol_fee": 106772490242308, "congestion_multiplier": 4927524331, "prover_cost": 20140641547885, "sequencer_cost": 7045056436753 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 1101433725, + "protocol_fee": 1101433725, "congestion_multiplier": 4927524331, "prover_cost": 207764957, "sequencer_cost": 72674738 @@ -14366,13 +14366,13 @@ "slot_of_change": 45 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 106147346874311, + "protocol_fee": 106147346874311, "congestion_multiplier": 4930298667, "prover_cost": 20008586171331, "sequencer_cost": 6998864383814 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 1102211759, + "protocol_fee": 1102211759, "congestion_multiplier": 4930298667, "prover_cost": 207764957, "sequencer_cost": 72674738 @@ -14420,13 +14420,13 @@ "slot_of_change": 45 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 107061611308926, + "protocol_fee": 107061611308926, "congestion_multiplier": 4937900423, "prover_cost": 20011080375468, "sequencer_cost": 7176405292160 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 1115818596, + "protocol_fee": 1115818596, "congestion_multiplier": 4937900423, "prover_cost": 208559682, "sequencer_cost": 74794003 @@ -14474,13 +14474,13 @@ "slot_of_change": 45 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 107044379348274, + "protocol_fee": 107044379348274, "congestion_multiplier": 4921911123, "prover_cost": 20089429886425, "sequencer_cost": 7204503117691 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 1111287968, + "protocol_fee": 1111287968, "congestion_multiplier": 4921911123, "prover_cost": 208559682, "sequencer_cost": 74794003 @@ -14528,13 +14528,13 @@ "slot_of_change": 45 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 105386016851230, + "protocol_fee": 105386016851230, "congestion_multiplier": 4867329395, "prover_cost": 20057339111400, "sequencer_cost": 7192994673199 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 1095822035, + "protocol_fee": 1095822035, "congestion_multiplier": 4867329395, "prover_cost": 208559682, "sequencer_cost": 74794003 @@ -14582,13 +14582,13 @@ "slot_of_change": 50 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 107931324980889, + "protocol_fee": 107931324980889, "congestion_multiplier": 4957169149, "prover_cost": 20075408222729, "sequencer_cost": 7199474646481 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 1121278460, + "protocol_fee": 1121278460, "congestion_multiplier": 4957169149, "prover_cost": 208559682, "sequencer_cost": 74794003 @@ -14636,13 +14636,13 @@ "slot_of_change": 50 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 107970062437352, + "protocol_fee": 107970062437352, "congestion_multiplier": 4943942480, "prover_cost": 20149963841890, "sequencer_cost": 7226211900536 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 1117530635, + "protocol_fee": 1117530635, "congestion_multiplier": 4943942480, "prover_cost": 208559682, "sequencer_cost": 74794003 @@ -14690,13 +14690,13 @@ "slot_of_change": 50 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 107717059429051, + "protocol_fee": 107717059429051, "congestion_multiplier": 4937451012, "prover_cost": 20077880539125, "sequencer_cost": 7279173331184 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 1120820886, + "protocol_fee": 1120820886, "congestion_multiplier": 4937451012, "prover_cost": 208914985, "sequencer_cost": 75741480 @@ -14744,13 +14744,13 @@ "slot_of_change": 50 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 104578057164120, + "protocol_fee": 104578057164120, "congestion_multiplier": 4838764066, "prover_cost": 19993907989831, "sequencer_cost": 7248729343822 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 1092729008, + "protocol_fee": 1092729008, "congestion_multiplier": 4838764066, "prover_cost": 208914985, "sequencer_cost": 75741480 @@ -14798,13 +14798,13 @@ "slot_of_change": 50 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 105900675055837, + "protocol_fee": 105900675055837, "congestion_multiplier": 4900919120, "prover_cost": 19924173880834, "sequencer_cost": 7223447458840 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 1110421846, + "protocol_fee": 1110421846, "congestion_multiplier": 4900919120, "prover_cost": 208914985, "sequencer_cost": 75741480 @@ -14852,13 +14852,13 @@ "slot_of_change": 55 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 107095771802944, + "protocol_fee": 107095771802944, "congestion_multiplier": 4932317314, "prover_cost": 19988136662359, "sequencer_cost": 7246636966943 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 1119359545, + "protocol_fee": 1119359545, "congestion_multiplier": 4932317314, "prover_cost": 208914985, "sequencer_cost": 75741480 @@ -14906,13 +14906,13 @@ "slot_of_change": 55 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 109229424674767, + "protocol_fee": 109229424674767, "congestion_multiplier": 5010660275, "prover_cost": 19988136662359, "sequencer_cost": 7246636966943 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 1141660376, + "protocol_fee": 1141660376, "congestion_multiplier": 5010660275, "prover_cost": 208914985, "sequencer_cost": 75741480 @@ -14960,13 +14960,13 @@ "slot_of_change": 55 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 110164640387027, + "protocol_fee": 110164640387027, "congestion_multiplier": 4979230751, "prover_cost": 20062105970517, "sequencer_cost": 7622802819977 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 1155925734, + "protocol_fee": 1155925734, "congestion_multiplier": 4979230751, "prover_cost": 210505880, "sequencer_cost": 79983867 @@ -15014,13 +15014,13 @@ "slot_of_change": 55 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 109699664341596, + "protocol_fee": 109699664341596, "congestion_multiplier": 4941434317, "prover_cost": 20169002900136, "sequencer_cost": 7663419404186 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 1144946257, + "protocol_fee": 1144946257, "congestion_multiplier": 4941434317, "prover_cost": 210505880, "sequencer_cost": 79983867 @@ -15068,13 +15068,13 @@ "slot_of_change": 55 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 105265547655218, + "protocol_fee": 105265547655218, "congestion_multiplier": 4772285814, "prover_cost": 20221580059563, "sequencer_cost": 7683396634878 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 1095810351, + "protocol_fee": 1095810351, "congestion_multiplier": 4772285814, "prover_cost": 210505880, "sequencer_cost": 79983867 @@ -15122,13 +15122,13 @@ "slot_of_change": 60 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 110630517517754, + "protocol_fee": 110630517517754, "congestion_multiplier": 4989520684, "prover_cost": 20094983134051, "sequencer_cost": 7635294835285 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 1158914854, + "protocol_fee": 1158914854, "congestion_multiplier": 4989520684, "prover_cost": 210505880, "sequencer_cost": 79983867 @@ -15176,13 +15176,13 @@ "slot_of_change": 60 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 110778183261345, + "protocol_fee": 110778183261345, "congestion_multiplier": 4999240050, "prover_cost": 20072903129159, "sequencer_cost": 7626905311085 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 1161738230, + "protocol_fee": 1161738230, "congestion_multiplier": 4999240050, "prover_cost": 210505880, "sequencer_cost": 79983867 @@ -15230,13 +15230,13 @@ "slot_of_change": 60 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 110796244647894, + "protocol_fee": 110796244647894, "congestion_multiplier": 5027946596, "prover_cost": 20044117204498, "sequencer_cost": 7462763041026 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 1159719915, + "protocol_fee": 1159719915, "congestion_multiplier": 5027946596, "prover_cost": 209804601, "sequencer_cost": 78113793 @@ -15284,13 +15284,13 @@ "slot_of_change": 60 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 109785506496636, + "protocol_fee": 109785506496636, "congestion_multiplier": 4987609377, "prover_cost": 20062174259782, "sequencer_cost": 7469485987386 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 1148106087, + "protocol_fee": 1148106087, "congestion_multiplier": 4987609377, "prover_cost": 209804601, "sequencer_cost": 78113793 @@ -15338,13 +15338,13 @@ "slot_of_change": 60 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 109358684956312, + "protocol_fee": 109358684956312, "congestion_multiplier": 4950259652, "prover_cost": 20173127502716, "sequencer_cost": 7510795751852 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 1137352414, + "protocol_fee": 1137352414, "congestion_multiplier": 4950259652, "prover_cost": 209804601, "sequencer_cost": 78113793 @@ -15392,13 +15392,13 @@ "slot_of_change": 65 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 107855949130628, + "protocol_fee": 107855949130628, "congestion_multiplier": 4923639033, "prover_cost": 20030908885901, "sequencer_cost": 7457845361147 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 1129687849, + "protocol_fee": 1129687849, "congestion_multiplier": 4923639033, "prover_cost": 209804601, "sequencer_cost": 78113793 @@ -15446,13 +15446,13 @@ "slot_of_change": 65 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 108119484606984, + "protocol_fee": 108119484606984, "congestion_multiplier": 4952105396, "prover_cost": 19935220600518, "sequencer_cost": 7422218997944 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 1137883838, + "protocol_fee": 1137883838, "congestion_multiplier": 4952105396, "prover_cost": 209804601, "sequencer_cost": 78113793 @@ -15500,13 +15500,13 @@ "slot_of_change": 65 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 105172305520660, + "protocol_fee": 105172305520660, "congestion_multiplier": 4892716509, "prover_cost": 19901474416873, "sequencer_cost": 7116240676600 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 1101664440, + "protocol_fee": 1101664440, "congestion_multiplier": 4892716509, "prover_cost": 208465019, "sequencer_cost": 74541575 @@ -15554,13 +15554,13 @@ "slot_of_change": 65 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 108747830909328, + "protocol_fee": 108747830909328, "congestion_multiplier": 5022238774, "prover_cost": 19915416354591, "sequencer_cost": 7121225944637 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 1138320095, + "protocol_fee": 1138320095, "congestion_multiplier": 5022238774, "prover_cost": 208465019, "sequencer_cost": 74541575 @@ -15608,13 +15608,13 @@ "slot_of_change": 65 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 106865944519867, + "protocol_fee": 106865944519867, "congestion_multiplier": 4955795841, "prover_cost": 19899496787578, "sequencer_cost": 7115533528690 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 1119516307, + "protocol_fee": 1119516307, "congestion_multiplier": 4955795841, "prover_cost": 208465019, "sequencer_cost": 74541575 @@ -15662,13 +15662,13 @@ "slot_of_change": 70 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 106649436103309, + "protocol_fee": 106649436103309, "congestion_multiplier": 4925278966, "prover_cost": 20013574936918, "sequencer_cost": 7156324856491 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 1110879830, + "protocol_fee": 1110879830, "congestion_multiplier": 4925278966, "prover_cost": 208465019, "sequencer_cost": 74541575 @@ -15716,13 +15716,13 @@ "slot_of_change": 70 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 108494006113292, + "protocol_fee": 108494006113292, "congestion_multiplier": 4987578597, "prover_cost": 20041633891255, "sequencer_cost": 7166357996147 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 1128511037, + "protocol_fee": 1128511037, "congestion_multiplier": 4987578597, "prover_cost": 208465019, "sequencer_cost": 74541575 @@ -15770,13 +15770,13 @@ "slot_of_change": 70 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 110693247558599, + "protocol_fee": 110693247558599, "congestion_multiplier": 4945529361, "prover_cost": 20336157664217, "sequencer_cost": 7719202596432 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 1145629728, + "protocol_fee": 1145629728, "congestion_multiplier": 4945529361, "prover_cost": 210470894, "sequencer_cost": 79890582 @@ -15824,13 +15824,13 @@ "slot_of_change": 70 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 109907165725267, + "protocol_fee": 109907165725267, "congestion_multiplier": 4929262647, "prover_cost": 20275333173164, "sequencer_cost": 7696114824542 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 1140906501, + "protocol_fee": 1140906501, "congestion_multiplier": 4929262647, "prover_cost": 210470894, "sequencer_cost": 79890582 @@ -15878,13 +15878,13 @@ "slot_of_change": 70 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 100286340685931, + "protocol_fee": 100286340685931, "congestion_multiplier": 4578140149, "prover_cost": 20315966523152, "sequencer_cost": 7711538439264 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 1038954054, + "protocol_fee": 1038954054, "congestion_multiplier": 4578140149, "prover_cost": 210470894, "sequencer_cost": 79890582 @@ -15932,13 +15932,13 @@ "slot_of_change": 75 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 109529916167436, + "protocol_fee": 109529916167436, "congestion_multiplier": 4868864341, "prover_cost": 20521178786416, "sequencer_cost": 7789432949208 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 1123369160, + "protocol_fee": 1123369160, "congestion_multiplier": 4868864341, "prover_cost": 210470894, "sequencer_cost": 79890582 @@ -15986,13 +15986,13 @@ "slot_of_change": 75 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 112351725772498, + "protocol_fee": 112351725772498, "congestion_multiplier": 4960600304, "prover_cost": 20562304289158, "sequencer_cost": 7805043375366 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 1150005750, + "protocol_fee": 1150005750, "congestion_multiplier": 4960600304, "prover_cost": 210470894, "sequencer_cost": 79890582 @@ -16040,13 +16040,13 @@ "slot_of_change": 75 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 109393253958720, + "protocol_fee": 109393253958720, "congestion_multiplier": 4983666767, "prover_cost": 20260052625656, "sequencer_cost": 7200390339207 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 1124538256, + "protocol_fee": 1124538256, "congestion_multiplier": 4983666767, "prover_cost": 208268823, "sequencer_cost": 74018407 @@ -16094,13 +16094,13 @@ "slot_of_change": 75 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 108966696569108, + "protocol_fee": 108966696569108, "congestion_multiplier": 4976862941, "prover_cost": 20215579352834, "sequencer_cost": 7184584609089 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 1122617623, + "protocol_fee": 1122617623, "congestion_multiplier": 4976862941, "prover_cost": 208268823, "sequencer_cost": 74018407 @@ -16148,13 +16148,13 @@ "slot_of_change": 75 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 106760731767737, + "protocol_fee": 106760731767737, "congestion_multiplier": 4888560968, "prover_cost": 20256091961447, "sequencer_cost": 7198982725474 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 1097691104, + "protocol_fee": 1097691104, "congestion_multiplier": 4888560968, "prover_cost": 208268823, "sequencer_cost": 74018407 @@ -16202,13 +16202,13 @@ "slot_of_change": 80 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 109102158508278, + "protocol_fee": 109102158508278, "congestion_multiplier": 4963113636, "prover_cost": 20310931823267, "sequencer_cost": 7218472724762 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 1118736370, + "protocol_fee": 1118736370, "congestion_multiplier": 4963113636, "prover_cost": 208268823, "sequencer_cost": 74018407 @@ -16256,13 +16256,13 @@ "slot_of_change": 80 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 107943936327459, + "protocol_fee": 107943936327459, "congestion_multiplier": 4932020265, "prover_cost": 20254220544589, "sequencer_cost": 7198317626912 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 1109959108, + "protocol_fee": 1109959108, "congestion_multiplier": 4932020265, "prover_cost": 208268823, "sequencer_cost": 74018407 @@ -16310,13 +16310,13 @@ "slot_of_change": 80 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 113777067283010, + "protocol_fee": 113777067283010, "congestion_multiplier": 4985527409, "prover_cost": 20426454451583, "sequencer_cost": 8121101656107 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 1181639014, + "protocol_fee": 1181639014, "congestion_multiplier": 4985527409, "prover_cost": 212140250, "sequencer_cost": 84342221 @@ -16364,13 +16364,13 @@ "slot_of_change": 80 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 116403138405721, + "protocol_fee": 116403138405721, "congestion_multiplier": 5057536639, "prover_cost": 20527038395213, "sequencer_cost": 8161091583538 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 1202988488, + "protocol_fee": 1202988488, "congestion_multiplier": 5057536639, "prover_cost": 212140250, "sequencer_cost": 84342221 @@ -16418,13 +16418,13 @@ "slot_of_change": 80 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 113561398685529, + "protocol_fee": 113561398685529, "congestion_multiplier": 4987377208, "prover_cost": 20378277208604, "sequencer_cost": 8101947461302 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 1182187447, + "protocol_fee": 1182187447, "congestion_multiplier": 4987377208, "prover_cost": 212140250, "sequencer_cost": 84342221 @@ -16472,13 +16472,13 @@ "slot_of_change": 85 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 115693733111709, + "protocol_fee": 115693733111709, "congestion_multiplier": 5048029812, "prover_cost": 20449852853583, "sequencer_cost": 8130404337670 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 1200169881, + "protocol_fee": 1200169881, "congestion_multiplier": 5048029812, "prover_cost": 212140250, "sequencer_cost": 84342221 @@ -16526,13 +16526,13 @@ "slot_of_change": 85 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 112573247850473, + "protocol_fee": 112573247850473, "congestion_multiplier": 4919545852, "prover_cost": 20550552468607, "sequencer_cost": 8170440253462 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 1162076639, + "protocol_fee": 1162076639, "congestion_multiplier": 4919545852, "prover_cost": 212140250, "sequencer_cost": 84342221 @@ -16580,13 +16580,13 @@ "slot_of_change": 85 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 106388227024957, + "protocol_fee": 106388227024957, "congestion_multiplier": 4890229573, "prover_cost": 20256604354827, "sequencer_cost": 7090940322087 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 1091310751, + "protocol_fee": 1091310751, "congestion_multiplier": 4890229573, "prover_cost": 207788500, "sequencer_cost": 72737554 @@ -16634,13 +16634,13 @@ "slot_of_change": 85 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 106597419808303, + "protocol_fee": 106597419808303, "congestion_multiplier": 4936857723, "prover_cost": 20056044206046, "sequencer_cost": 7020733093813 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 1104391162, + "protocol_fee": 1104391162, "congestion_multiplier": 4936857723, "prover_cost": 207788500, "sequencer_cost": 72737554 @@ -16688,13 +16688,13 @@ "slot_of_change": 85 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 105687062838554, + "protocol_fee": 105687062838554, "congestion_multiplier": 4918068519, "prover_cost": 19980120698916, "sequencer_cost": 6994155635485 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 1099120300, + "protocol_fee": 1099120300, "congestion_multiplier": 4918068519, "prover_cost": 207788500, "sequencer_cost": 72737554 @@ -16742,13 +16742,13 @@ "slot_of_change": 90 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 107408155630093, + "protocol_fee": 107408155630093, "congestion_multiplier": 5018904606, "prover_cost": 19796019217492, "sequencer_cost": 6929709857944 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 1127407450, + "protocol_fee": 1127407450, "congestion_multiplier": 5018904606, "prover_cost": 207788500, "sequencer_cost": 72737554 @@ -16796,13 +16796,13 @@ "slot_of_change": 90 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 105774674004023, + "protocol_fee": 105774674004023, "congestion_multiplier": 4975989920, "prover_cost": 19705375996159, "sequencer_cost": 6897979679390 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 1115368763, + "protocol_fee": 1115368763, "congestion_multiplier": 4975989920, "prover_cost": 207788500, "sequencer_cost": 72737554 @@ -16850,13 +16850,13 @@ "slot_of_change": 90 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 101292726852671, + "protocol_fee": 101292726852671, "congestion_multiplier": 4972594849, "prover_cost": 19420088285569, "sequencer_cost": 6077786713257 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 1066719075, + "protocol_fee": 1066719075, "congestion_multiplier": 4972594849, "prover_cost": 204513979, "sequencer_cost": 64005494 @@ -16904,13 +16904,13 @@ "slot_of_change": 90 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 99619290760287, + "protocol_fee": 99619290760287, "congestion_multiplier": 4917122269, "prover_cost": 19369728348895, "sequencer_cost": 6062025870696 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 1051823607, + "protocol_fee": 1051823607, "congestion_multiplier": 4917122269, "prover_cost": 204513979, "sequencer_cost": 64005494 @@ -16958,13 +16958,13 @@ "slot_of_change": 90 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 101444477897997, + "protocol_fee": 101444477897997, "congestion_multiplier": 4987693464, "prover_cost": 19375541874127, "sequencer_cost": 6063845294268 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 1070773347, + "protocol_fee": 1070773347, "congestion_multiplier": 4987693464, "prover_cost": 204513979, "sequencer_cost": 64005494 @@ -17012,13 +17012,13 @@ "slot_of_change": 95 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 100405125739807, + "protocol_fee": 100405125739807, "congestion_multiplier": 4956704476, "prover_cost": 19327224111394, "sequencer_cost": 6048723578443 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 1062452200, + "protocol_fee": 1062452200, "congestion_multiplier": 4956704476, "prover_cost": 204513979, "sequencer_cost": 64005494 @@ -17066,13 +17066,13 @@ "slot_of_change": 95 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 99404601211757, + "protocol_fee": 99404601211757, "congestion_multiplier": 4912575672, "prover_cost": 19350444674994, "sequencer_cost": 6055990776761 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 1050602757, + "protocol_fee": 1050602757, "congestion_multiplier": 4912575672, "prover_cost": 204513979, "sequencer_cost": 64005494 @@ -17120,13 +17120,13 @@ "slot_of_change": 95 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 98081182463811, + "protocol_fee": 98081182463811, "congestion_multiplier": 4980830753, "prover_cost": 19111232056423, "sequencer_cost": 5527138315626 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 1039103433, + "protocol_fee": 1039103433, "congestion_multiplier": 4980830753, "prover_cost": 202470508, "sequencer_cost": 58556272 @@ -17174,13 +17174,13 @@ "slot_of_change": 95 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 97556063827448, + "protocol_fee": 97556063827448, "congestion_multiplier": 4959913503, "prover_cost": 19109321903445, "sequencer_cost": 5526585882393 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 1033643470, + "protocol_fee": 1033643470, "congestion_multiplier": 4959913503, "prover_cost": 202470508, "sequencer_cost": 58556272 @@ -17228,13 +17228,13 @@ "slot_of_change": 95 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 98616443088859, + "protocol_fee": 98616443088859, "congestion_multiplier": 5000153367, "prover_cost": 19122708222792, "sequencer_cost": 5530457325027 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 1044147152, + "protocol_fee": 1044147152, "congestion_multiplier": 5000153367, "prover_cost": 202470508, "sequencer_cost": 58556272 @@ -17282,13 +17282,13 @@ "slot_of_change": 100 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 99047245341349, + "protocol_fee": 99047245341349, "congestion_multiplier": 5037715720, "prover_cost": 19027571819342, "sequencer_cost": 5502943030859 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 1053951932, + "protocol_fee": 1053951932, "congestion_multiplier": 5037715720, "prover_cost": 202470508, "sequencer_cost": 58556272 @@ -17336,13 +17336,13 @@ "slot_of_change": 100 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 97349418949539, + "protocol_fee": 97349418949539, "congestion_multiplier": 5001044467, "prover_cost": 18872815421402, "sequencer_cost": 5458186103931 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 1044379753, + "protocol_fee": 1044379753, "congestion_multiplier": 5001044467, "prover_cost": 202470508, "sequencer_cost": 58556272 @@ -17390,13 +17390,13 @@ "slot_of_change": 100 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 99331336083013, + "protocol_fee": 99331336083013, "congestion_multiplier": 4995846347, "prover_cost": 19000832053168, "sequencer_cost": 5857815537406 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 1067027344, + "protocol_fee": 1067027344, "congestion_multiplier": 4995846347, "prover_cost": 204108876, "sequencer_cost": 62925252 @@ -17444,13 +17444,13 @@ "slot_of_change": 100 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 101818747421236, + "protocol_fee": 101818747421236, "congestion_multiplier": 5093860245, "prover_cost": 19010338902068, "sequencer_cost": 5860746428382 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 1093200400, + "protocol_fee": 1093200400, "congestion_multiplier": 5093860245, "prover_cost": 204108876, "sequencer_cost": 62925252 @@ -17498,13 +17498,13 @@ "slot_of_change": 100 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 100122430646174, + "protocol_fee": 100122430646174, "congestion_multiplier": 5039342770, "prover_cost": 18945924315763, "sequencer_cost": 5840887889375 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 1078642374, + "protocol_fee": 1078642374, "congestion_multiplier": 5039342770, "prover_cost": 204108876, "sequencer_cost": 62925252 @@ -17552,13 +17552,13 @@ "slot_of_change": 105 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 96889782205908, + "protocol_fee": 96889782205908, "congestion_multiplier": 4899933960, "prover_cost": 18989601389223, "sequencer_cost": 5854353207043 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 1041415464, + "protocol_fee": 1041415464, "congestion_multiplier": 4899933960, "prover_cost": 204108876, "sequencer_cost": 62925252 @@ -17606,13 +17606,13 @@ "slot_of_change": 105 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 91880305306439, + "protocol_fee": 91880305306439, "congestion_multiplier": 4706802227, "prover_cost": 18946026315731, "sequencer_cost": 5840919335209 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 989842700, + "protocol_fee": 989842700, "congestion_multiplier": 4706802227, "prover_cost": 204108876, "sequencer_cost": 62925252 @@ -17660,13 +17660,13 @@ "slot_of_change": 105 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 92197483344037, + "protocol_fee": 92197483344037, "congestion_multiplier": 4925017743, "prover_cost": 18578842647204, "sequencer_cost": 4910855847729 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 994352255, + "protocol_fee": 994352255, "congestion_multiplier": 4925017743, "prover_cost": 200373301, "sequencer_cost": 52963708 @@ -17714,13 +17714,13 @@ "slot_of_change": 105 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 92280096548742, + "protocol_fee": 92280096548742, "congestion_multiplier": 4926570298, "prover_cost": 18588137555333, "sequencer_cost": 4913312725953 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 994745574, + "protocol_fee": 994745574, "congestion_multiplier": 4926570298, "prover_cost": 200373301, "sequencer_cost": 52963708 @@ -17768,13 +17768,13 @@ "slot_of_change": 105 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 91564053790830, + "protocol_fee": 91564053790830, "congestion_multiplier": 4930387694, "prover_cost": 18425990158806, "sequencer_cost": 4870453086871 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 995712662, + "protocol_fee": 995712662, "congestion_multiplier": 4930387694, "prover_cost": 200373301, "sequencer_cost": 52963708 @@ -17822,13 +17822,13 @@ "slot_of_change": 110 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 91490184501098, + "protocol_fee": 91490184501098, "congestion_multiplier": 4923682015, "prover_cost": 18442590111743, "sequencer_cost": 4874840872348 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 994013865, + "protocol_fee": 994013865, "congestion_multiplier": 4923682015, "prover_cost": 200373301, "sequencer_cost": 52963708 @@ -17876,13 +17876,13 @@ "slot_of_change": 110 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 89583482098358, + "protocol_fee": 89583482098358, "congestion_multiplier": 4838452475, "prover_cost": 18459204696559, "sequencer_cost": 4879232525400 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 972422069, + "protocol_fee": 972422069, "congestion_multiplier": 4838452475, "prover_cost": 200373301, "sequencer_cost": 52963708 @@ -17930,13 +17930,13 @@ "slot_of_change": 110 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 89897597391954, + "protocol_fee": 89897597391954, "congestion_multiplier": 4841333296, "prover_cost": 18451388668638, "sequencer_cost": 4951318295441 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 977880983, + "protocol_fee": 977880983, "congestion_multiplier": 4841333296, "prover_cost": 200709058, "sequencer_cost": 53859059 @@ -17984,13 +17984,13 @@ "slot_of_change": 110 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 93416832522638, + "protocol_fee": 93416832522638, "congestion_multiplier": 4980533633, "prover_cost": 18503198272228, "sequencer_cost": 4965221088491 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 1013316951, + "protocol_fee": 1013316951, "congestion_multiplier": 4980533633, "prover_cost": 200709058, "sequencer_cost": 53859059 @@ -18038,13 +18038,13 @@ "slot_of_change": 110 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 91738188120314, + "protocol_fee": 91738188120314, "congestion_multiplier": 4919559927, "prover_cost": 18453375197099, "sequencer_cost": 4951851368311 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 997794990, + "protocol_fee": 997794990, "congestion_multiplier": 4919559927, "prover_cost": 200709058, "sequencer_cost": 53859059 @@ -18092,13 +18092,13 @@ "slot_of_change": 115 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 91255602388312, + "protocol_fee": 91255602388312, "congestion_multiplier": 4896211803, "prover_cost": 18466302313309, "sequencer_cost": 4955320281581 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 991851302, + "protocol_fee": 991851302, "congestion_multiplier": 4896211803, "prover_cost": 200709058, "sequencer_cost": 53859059 @@ -18146,13 +18146,13 @@ "slot_of_change": 115 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 90729806410156, + "protocol_fee": 90729806410156, "congestion_multiplier": 4878023477, "prover_cost": 18446013106832, "sequencer_cost": 4949875796018 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 987221134, + "protocol_fee": 987221134, "congestion_multiplier": 4878023477, "prover_cost": 200709058, "sequencer_cost": 53859059 @@ -18200,13 +18200,13 @@ "slot_of_change": 115 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 98756255156898, + "protocol_fee": 98756255156898, "congestion_multiplier": 5027710752, "prover_cost": 18718683019904, "sequencer_cost": 5800519403774 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 1077564756, + "protocol_fee": 1077564756, "congestion_multiplier": 5027710752, "prover_cost": 204246233, "sequencer_cost": 63291538 @@ -18254,13 +18254,13 @@ "slot_of_change": 115 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 97075123301999, + "protocol_fee": 97075123301999, "congestion_multiplier": 4948061177, "prover_cost": 18771242844625, "sequencer_cost": 5816806569000 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 1056255487, + "protocol_fee": 1056255487, "congestion_multiplier": 4948061177, "prover_cost": 204246233, "sequencer_cost": 63291538 @@ -18308,13 +18308,13 @@ "slot_of_change": 115 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 96901023468708, + "protocol_fee": 96901023468708, "congestion_multiplier": 4936251321, "prover_cost": 18793795457900, "sequencer_cost": 5823795141367 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 1053095904, + "protocol_fee": 1053095904, "congestion_multiplier": 4936251321, "prover_cost": 204246233, "sequencer_cost": 63291538 @@ -18362,13 +18362,13 @@ "slot_of_change": 120 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 95237329357143, + "protocol_fee": 95237329357143, "congestion_multiplier": 4876406969, "prover_cost": 18756283746437, "sequencer_cost": 5812171064504 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 1037085279, + "protocol_fee": 1037085279, "congestion_multiplier": 4876406969, "prover_cost": 204246233, "sequencer_cost": 63291538 @@ -18416,13 +18416,13 @@ "slot_of_change": 120 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 96531117467576, + "protocol_fee": 96531117467576, "congestion_multiplier": 4948319770, "prover_cost": 18664826894588, "sequencer_cost": 5783830542727 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 1056324670, + "protocol_fee": 1056324670, "congestion_multiplier": 4948319770, "prover_cost": 204246233, "sequencer_cost": 63291538 @@ -18470,13 +18470,13 @@ "slot_of_change": 120 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 96469358939101, + "protocol_fee": 96469358939101, "congestion_multiplier": 4948569861, "prover_cost": 18570831404369, "sequencer_cost": 5860636801455 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 1063566193, + "protocol_fee": 1063566193, "congestion_multiplier": 4948569861, "prover_cost": 204741782, "sequencer_cost": 64613005 @@ -18524,13 +18524,13 @@ "slot_of_change": 120 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 98037722355072, + "protocol_fee": 98037722355072, "congestion_multiplier": 4978254210, "prover_cost": 18731927264690, "sequencer_cost": 5911475899986 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 1071561815, + "protocol_fee": 1071561815, "congestion_multiplier": 4978254210, "prover_cost": 204741782, "sequencer_cost": 64613005 @@ -18578,13 +18578,13 @@ "slot_of_change": 120 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 95851553377548, + "protocol_fee": 95851553377548, "congestion_multiplier": 4892653677, "prover_cost": 18716953834506, "sequencer_cost": 5906750541488 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 1048504902, + "protocol_fee": 1048504902, "congestion_multiplier": 4892653677, "prover_cost": 204741782, "sequencer_cost": 64613005 @@ -18632,13 +18632,13 @@ "slot_of_change": 125 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 97621190862815, + "protocol_fee": 97621190862815, "congestion_multiplier": 4949852080, "prover_cost": 18786464247351, "sequencer_cost": 5928686839047 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 1063911565, + "protocol_fee": 1063911565, "congestion_multiplier": 4949852080, "prover_cost": 204741782, "sequencer_cost": 64613005 @@ -18686,13 +18686,13 @@ "slot_of_change": 125 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 96757166748113, + "protocol_fee": 96757166748113, "congestion_multiplier": 4948169337, "prover_cost": 18628125385827, "sequencer_cost": 5878717802188 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 1063458310, + "protocol_fee": 1063458310, "congestion_multiplier": 4948169337, "prover_cost": 204741782, "sequencer_cost": 64613005 @@ -18740,13 +18740,13 @@ "slot_of_change": 125 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 94712022195763, + "protocol_fee": 94712022195763, "congestion_multiplier": 4930446757, "prover_cost": 18497273764810, "sequencer_cost": 5599738131721 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 1042645631, + "protocol_fee": 1042645631, "congestion_multiplier": 4930446757, "prover_cost": 203628866, "sequencer_cost": 61645210 @@ -18794,13 +18794,13 @@ "slot_of_change": 125 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 95717188564080, + "protocol_fee": 95717188564080, "congestion_multiplier": 4932438433, "prover_cost": 18684115119675, "sequencer_cost": 5656301205432 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 1043173971, + "protocol_fee": 1043173971, "congestion_multiplier": 4932438433, "prover_cost": 203628866, "sequencer_cost": 61645210 @@ -18848,13 +18848,13 @@ "slot_of_change": 125 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 95771815069211, + "protocol_fee": 95771815069211, "congestion_multiplier": 4914222070, "prover_cost": 18781781745498, "sequencer_cost": 5685868131660 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 1038341642, + "protocol_fee": 1038341642, "congestion_multiplier": 4914222070, "prover_cost": 203628866, "sequencer_cost": 61645210 @@ -18902,13 +18902,13 @@ "slot_of_change": 130 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 96377328347938, + "protocol_fee": 96377328347938, "congestion_multiplier": 4938181549, "prover_cost": 18785539952361, "sequencer_cost": 5687005865498 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 1044697471, + "protocol_fee": 1044697471, "congestion_multiplier": 4938181549, "prover_cost": 203628866, "sequencer_cost": 61645210 @@ -18956,13 +18956,13 @@ "slot_of_change": 130 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 96463801684782, + "protocol_fee": 96463801684782, "congestion_multiplier": 4946839060, "prover_cost": 18761151421293, "sequencer_cost": 5679622648429 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 1046994084, + "protocol_fee": 1046994084, "congestion_multiplier": 4946839060, "prover_cost": 203628866, "sequencer_cost": 61645210 @@ -19010,13 +19010,13 @@ "slot_of_change": 130 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 104987616828960, + "protocol_fee": 104987616828960, "congestion_multiplier": 4879769969, "prover_cost": 19488880224900, "sequencer_cost": 7571388211804 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 1138255899, + "protocol_fee": 1138255899, "congestion_multiplier": 4879769969, "prover_cost": 211294756, "sequencer_cost": 82087560 @@ -19064,13 +19064,13 @@ "slot_of_change": 130 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 105033773211812, + "protocol_fee": 105033773211812, "congestion_multiplier": 4877206034, "prover_cost": 19510341614893, "sequencer_cost": 7579725915834 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 1137503685, + "protocol_fee": 1137503685, "congestion_multiplier": 4877206034, "prover_cost": 211294756, "sequencer_cost": 82087560 @@ -19118,13 +19118,13 @@ "slot_of_change": 130 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 110152653733333, + "protocol_fee": 110152653733333, "congestion_multiplier": 5075922388, "prover_cost": 19463630203588, "sequencer_cost": 7561578632623 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 1195803550, + "protocol_fee": 1195803550, "congestion_multiplier": 5075922388, "prover_cost": 211294756, "sequencer_cost": 82087560 @@ -19172,13 +19172,13 @@ "slot_of_change": 135 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 106287728303911, + "protocol_fee": 106287728303911, "congestion_multiplier": 4939989559, "prover_cost": 19428659648514, "sequencer_cost": 7547992646902 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 1155923261, + "protocol_fee": 1155923261, "congestion_multiplier": 4939989559, "prover_cost": 211294756, "sequencer_cost": 82087560 @@ -19226,13 +19226,13 @@ "slot_of_change": 135 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 105823118225263, + "protocol_fee": 105823118225263, "congestion_multiplier": 4920805397, "prover_cost": 19438379360106, "sequencer_cost": 7551768734031 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 1150294967, + "protocol_fee": 1150294967, "congestion_multiplier": 4920805397, "prover_cost": 211294756, "sequencer_cost": 82087560 @@ -19280,13 +19280,13 @@ "slot_of_change": 135 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 101416302977149, + "protocol_fee": 101416302977149, "congestion_multiplier": 4992769828, "prover_cost": 18992634121223, "sequencer_cost": 6407353214323 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 1103495276, + "protocol_fee": 1103495276, "congestion_multiplier": 4992769828, "prover_cost": 206655946, "sequencer_cost": 69717430 @@ -19334,13 +19334,13 @@ "slot_of_change": 135 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 101422118089354, + "protocol_fee": 101422118089354, "congestion_multiplier": 4999387434, "prover_cost": 18962295068129, "sequencer_cost": 6397118034299 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 1105324207, + "protocol_fee": 1105324207, "congestion_multiplier": 4999387434, "prover_cost": 206655946, "sequencer_cost": 69717430 @@ -19388,13 +19388,13 @@ "slot_of_change": 135 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 102049959468407, + "protocol_fee": 102049959468407, "congestion_multiplier": 5001609665, "prover_cost": 19069083275470, "sequencer_cost": 6433144093622 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 1105938372, + "protocol_fee": 1105938372, "congestion_multiplier": 5001609665, "prover_cost": 206655946, "sequencer_cost": 69717430 @@ -19442,13 +19442,13 @@ "slot_of_change": 140 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 102244929146199, + "protocol_fee": 102244929146199, "congestion_multiplier": 4986001154, "prover_cost": 19180329353859, "sequencer_cost": 6470674059892 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 1101624595, + "protocol_fee": 1101624595, "congestion_multiplier": 4986001154, "prover_cost": 206655946, "sequencer_cost": 69717430 @@ -19496,13 +19496,13 @@ "slot_of_change": 140 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 102995415615382, + "protocol_fee": 102995415615382, "congestion_multiplier": 5007629489, "prover_cost": 19216842601338, "sequencer_cost": 6482992165538 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 1107602091, + "protocol_fee": 1107602091, "congestion_multiplier": 5007629489, "prover_cost": 206655946, "sequencer_cost": 69717430 @@ -19550,13 +19550,13 @@ "slot_of_change": 140 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 101079330330887, + "protocol_fee": 101079330330887, "congestion_multiplier": 5012296477, "prover_cost": 19016504142342, "sequencer_cost": 6175884036818 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 1092540302, + "protocol_fee": 1092540302, "congestion_multiplier": 5012296477, "prover_cost": 205544468, "sequencer_cost": 66753531 @@ -19604,13 +19604,13 @@ "slot_of_change": 140 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 103224365696090, + "protocol_fee": 103224365696090, "congestion_multiplier": 5076135739, "prover_cost": 19115907830108, "sequencer_cost": 6208166818337 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 1109923605, + "protocol_fee": 1109923605, "congestion_multiplier": 5076135739, "prover_cost": 205544468, "sequencer_cost": 66753531 @@ -19658,13 +19658,13 @@ "slot_of_change": 140 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 99453725842325, + "protocol_fee": 99453725842325, "congestion_multiplier": 4927240276, "prover_cost": 19115907830108, "sequencer_cost": 6208166818337 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 1069379668, + "protocol_fee": 1069379668, "congestion_multiplier": 4927240276, "prover_cost": 205544468, "sequencer_cost": 66753531 @@ -19712,13 +19712,13 @@ "slot_of_change": 145 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 98465704473351, + "protocol_fee": 98465704473351, "congestion_multiplier": 4862562789, "prover_cost": 19242911527596, "sequencer_cost": 6249413101148 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 1051768118, + "protocol_fee": 1051768118, "congestion_multiplier": 4862562789, "prover_cost": 205544468, "sequencer_cost": 66753531 @@ -19766,13 +19766,13 @@ "slot_of_change": 145 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 101639708477190, + "protocol_fee": 101639708477190, "congestion_multiplier": 4961154747, "prover_cost": 19368810259423, "sequencer_cost": 6290300530421 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 1078614511, + "protocol_fee": 1078614511, "congestion_multiplier": 4961154747, "prover_cost": 205544468, "sequencer_cost": 66753531 @@ -19820,13 +19820,13 @@ "slot_of_change": 145 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 97155354948773, + "protocol_fee": 97155354948773, "congestion_multiplier": 4901814536, "prover_cost": 19161791918066, "sequencer_cost": 5738252436809 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 1031025937, + "protocol_fee": 1031025937, "congestion_multiplier": 4901814536, "prover_cost": 203347561, "sequencer_cost": 60895121 @@ -19874,13 +19874,13 @@ "slot_of_change": 145 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 95246490352619, + "protocol_fee": 95246490352619, "congestion_multiplier": 4811765218, "prover_cost": 19229094692631, "sequencer_cost": 5758407144250 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 1007231064, + "protocol_fee": 1007231064, "congestion_multiplier": 4811765218, "prover_cost": 203347561, "sequencer_cost": 60895121 @@ -19928,13 +19928,13 @@ "slot_of_change": 145 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 98439193601961, + "protocol_fee": 98439193601961, "congestion_multiplier": 4948991749, "prover_cost": 19183057143367, "sequencer_cost": 5744620590238 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 1043492170, + "protocol_fee": 1043492170, "congestion_multiplier": 4948991749, "prover_cost": 203347561, "sequencer_cost": 60895121 @@ -19982,13 +19982,13 @@ "slot_of_change": 150 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 96033363755052, + "protocol_fee": 96033363755052, "congestion_multiplier": 4845930006, "prover_cost": 19215724538364, "sequencer_cost": 5754403274433 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 1016258859, + "protocol_fee": 1016258859, "congestion_multiplier": 4845930006, "prover_cost": 203347561, "sequencer_cost": 60895121 @@ -20036,13 +20036,13 @@ "slot_of_change": 150 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 96588696709809, + "protocol_fee": 96588696709809, "congestion_multiplier": 4880161119, "prover_cost": 19156340410227, "sequencer_cost": 5736619910568 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 1025304180, + "protocol_fee": 1025304180, "congestion_multiplier": 4880161119, "prover_cost": 203347561, "sequencer_cost": 60895121 @@ -20090,13 +20090,13 @@ "slot_of_change": 150 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 94854320481570, + "protocol_fee": 94854320481570, "congestion_multiplier": 4913235385, "prover_cost": 18903102919698, "sequencer_cost": 5336256891328 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 1013035511, + "protocol_fee": 1013035511, "congestion_multiplier": 4913235385, "prover_cost": 201883419, "sequencer_cost": 56990738 @@ -20144,13 +20144,13 @@ "slot_of_change": 150 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 95451908817724, + "protocol_fee": 95451908817724, "congestion_multiplier": 4929225590, "prover_cost": 18944781794775, "sequencer_cost": 5348022641390 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 1017174962, + "protocol_fee": 1017174962, "congestion_multiplier": 4929225590, "prover_cost": 201883419, "sequencer_cost": 56990738 @@ -20198,13 +20198,13 @@ "slot_of_change": 150 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 95280306974734, + "protocol_fee": 95280306974734, "congestion_multiplier": 4908433923, "prover_cost": 19011322412461, "sequencer_cost": 5366806744254 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 1011792537, + "protocol_fee": 1011792537, "congestion_multiplier": 4908433923, "prover_cost": 201883419, "sequencer_cost": 56990738 @@ -20252,13 +20252,13 @@ "slot_of_change": 155 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 94413171907759, + "protocol_fee": 94413171907759, "congestion_multiplier": 4891065871, "prover_cost": 18922388683351, "sequencer_cost": 5341701171542 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 1007296397, + "protocol_fee": 1007296397, "congestion_multiplier": 4891065871, "prover_cost": 201883419, "sequencer_cost": 56990738 @@ -20306,13 +20306,13 @@ "slot_of_change": 155 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 95341079355925, + "protocol_fee": 95341079355925, "congestion_multiplier": 4913197713, "prover_cost": 19000289874687, "sequencer_cost": 5363692310820 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 1013025759, + "protocol_fee": 1013025759, "congestion_multiplier": 4913197713, "prover_cost": 201883419, "sequencer_cost": 56990738 @@ -20360,13 +20360,13 @@ "slot_of_change": 155 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 95503274553431, + "protocol_fee": 95503274553431, "congestion_multiplier": 4997387122, "prover_cost": 18928508876931, "sequencer_cost": 4962916129150 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 1010081215, + "protocol_fee": 1010081215, "congestion_multiplier": 4997387122, "prover_cost": 200195557, "sequencer_cost": 52489806 @@ -20414,13 +20414,13 @@ "slot_of_change": 155 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 95604433437412, + "protocol_fee": 95604433437412, "congestion_multiplier": 4998819898, "prover_cost": 18941769041537, "sequencer_cost": 4966392847006 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 1010443257, + "protocol_fee": 1010443257, "congestion_multiplier": 4998819898, "prover_cost": 200195557, "sequencer_cost": 52489806 @@ -20468,13 +20468,13 @@ "slot_of_change": 155 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 91838771448520, + "protocol_fee": 91838771448520, "congestion_multiplier": 4831326971, "prover_cost": 18991147102126, "sequencer_cost": 4979339412154 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 968120246, + "protocol_fee": 968120246, "congestion_multiplier": 4831326971, "prover_cost": 200195557, "sequencer_cost": 52489806 @@ -20522,13 +20522,13 @@ "slot_of_change": 160 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 93959933920668, + "protocol_fee": 93959933920668, "congestion_multiplier": 4915897563, "prover_cost": 19010158125865, "sequencer_cost": 4984323963074 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 989489997, + "protocol_fee": 989489997, "congestion_multiplier": 4915897563, "prover_cost": 200195557, "sequencer_cost": 52489806 @@ -20576,13 +20576,13 @@ "slot_of_change": 160 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 93559129327744, + "protocol_fee": 93559129327744, "congestion_multiplier": 4938185177, "prover_cost": 18821940118766, "sequencer_cost": 4934974582766 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 995121751, + "protocol_fee": 995121751, "congestion_multiplier": 4938185177, "prover_cost": 200195557, "sequencer_cost": 52489806 @@ -20630,13 +20630,13 @@ "slot_of_change": 160 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 92659399017826, + "protocol_fee": 92659399017826, "congestion_multiplier": 4933971098, "prover_cost": 18768974866748, "sequencer_cost": 4784680387044 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 985354782, + "protocol_fee": 985354782, "congestion_multiplier": 4933971098, "prover_cost": 199592263, "sequencer_cost": 50881052 @@ -20684,13 +20684,13 @@ "slot_of_change": 160 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 93374418994582, + "protocol_fee": 93374418994582, "congestion_multiplier": 4957588468, "prover_cost": 18800938105214, "sequencer_cost": 4792828614706 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 991270302, + "protocol_fee": 991270302, "congestion_multiplier": 4957588468, "prover_cost": 199592263, "sequencer_cost": 50881052 @@ -20738,13 +20738,13 @@ "slot_of_change": 160 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 93569763055805, + "protocol_fee": 93569763055805, "congestion_multiplier": 4971419967, "prover_cost": 18774654494400, "sequencer_cost": 4786128265962 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 994734724, + "protocol_fee": 994734724, "congestion_multiplier": 4971419967, "prover_cost": 199592263, "sequencer_cost": 50881052 @@ -20792,13 +20792,13 @@ "slot_of_change": 165 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 91320467376138, + "protocol_fee": 91320467376138, "congestion_multiplier": 4879440232, "prover_cost": 18757773993707, "sequencer_cost": 4781825004801 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 971696255, + "protocol_fee": 971696255, "congestion_multiplier": 4879440232, "prover_cost": 199592263, "sequencer_cost": 50881052 @@ -20846,13 +20846,13 @@ "slot_of_change": 165 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 91554264913527, + "protocol_fee": 91554264913527, "congestion_multiplier": 4858257010, "prover_cost": 18909048027055, "sequencer_cost": 4820388533473 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 966390423, + "protocol_fee": 966390423, "congestion_multiplier": 4858257010, "prover_cost": 199592263, "sequencer_cost": 50881052 @@ -20900,13 +20900,13 @@ "slot_of_change": 165 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 95663047949164, + "protocol_fee": 95663047949164, "congestion_multiplier": 4984125865, "prover_cost": 18944945315563, "sequencer_cost": 5066105356114 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 1013092341, + "protocol_fee": 1013092341, "congestion_multiplier": 4984125865, "prover_cost": 200631063, "sequencer_cost": 53651150 @@ -20954,13 +20954,13 @@ "slot_of_change": 165 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 95159938625410, + "protocol_fee": 95159938625410, "congestion_multiplier": 4984573693, "prover_cost": 18843192372826, "sequencer_cost": 5038895400128 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 1013206216, + "protocol_fee": 1013206216, "congestion_multiplier": 4984573693, "prover_cost": 200631063, "sequencer_cost": 53651150 @@ -21008,13 +21008,13 @@ "slot_of_change": 165 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 94201381223924, + "protocol_fee": 94201381223924, "congestion_multiplier": 4946408566, "prover_cost": 18833776725319, "sequencer_cost": 5036377543176 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 1003501503, + "protocol_fee": 1003501503, "congestion_multiplier": 4946408566, "prover_cost": 200631063, "sequencer_cost": 53651150 @@ -21062,13 +21062,13 @@ "slot_of_change": 170 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 92926657438812, + "protocol_fee": 92926657438812, "congestion_multiplier": 4889502248, "prover_cost": 18850743361592, "sequencer_cost": 5040914624992 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 989031239, + "protocol_fee": 989031239, "congestion_multiplier": 4889502248, "prover_cost": 200631063, "sequencer_cost": 53651150 @@ -21116,13 +21116,13 @@ "slot_of_change": 170 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 92409153599506, + "protocol_fee": 92409153599506, "congestion_multiplier": 4878671480, "prover_cost": 18798110042427, "sequencer_cost": 5026839844849 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 986277167, + "protocol_fee": 986277167, "congestion_multiplier": 4878671480, "prover_cost": 200631063, "sequencer_cost": 53651150 @@ -21170,13 +21170,13 @@ "slot_of_change": 170 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 92963155816234, + "protocol_fee": 92963155816234, "congestion_multiplier": 4856467458, "prover_cost": 18915424710021, "sequencer_cost": 5190355223776 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 988915743, + "protocol_fee": 988915743, "congestion_multiplier": 4856467458, "prover_cost": 201216935, "sequencer_cost": 55213530 @@ -21224,13 +21224,13 @@ "slot_of_change": 170 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 95569931469952, + "protocol_fee": 95569931469952, "congestion_multiplier": 4961434496, "prover_cost": 18930570637168, "sequencer_cost": 5194511236305 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 1015832489, + "protocol_fee": 1015832489, "congestion_multiplier": 4961434496, "prover_cost": 201216935, "sequencer_cost": 55213530 @@ -21278,13 +21278,13 @@ "slot_of_change": 170 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 94825279166379, + "protocol_fee": 94825279166379, "congestion_multiplier": 4950613729, "prover_cost": 18834516288520, "sequencer_cost": 5168154112534 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 1013057715, + "protocol_fee": 1013057715, "congestion_multiplier": 4950613729, "prover_cost": 201216935, "sequencer_cost": 55213530 @@ -21332,13 +21332,13 @@ "slot_of_change": 175 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 93932380819343, + "protocol_fee": 93932380819343, "congestion_multiplier": 4899325222, "prover_cost": 18902566784466, "sequencer_cost": 5186827034371 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 999905779, + "protocol_fee": 999905779, "congestion_multiplier": 4899325222, "prover_cost": 201216935, "sequencer_cost": 55213530 @@ -21386,13 +21386,13 @@ "slot_of_change": 175 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 96354577494146, + "protocol_fee": 96354577494146, "congestion_multiplier": 4975076221, "prover_cost": 19020494370238, "sequencer_cost": 5219186131257 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 1019330643, + "protocol_fee": 1019330643, "congestion_multiplier": 4975076221, "prover_cost": 201216935, "sequencer_cost": 55213530 @@ -21440,13 +21440,13 @@ "slot_of_change": 175 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 99376841470692, + "protocol_fee": 99376841470692, "congestion_multiplier": 5032674318, "prover_cost": 19125505223617, "sequencer_cost": 5517407566815 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 1051723498, + "protocol_fee": 1051723498, "congestion_multiplier": 5032674318, "prover_cost": 202408760, "sequencer_cost": 58391745 @@ -21494,13 +21494,13 @@ "slot_of_change": 175 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 96917149552111, + "protocol_fee": 96917149552111, "congestion_multiplier": 4960784044, "prover_cost": 18990672549393, "sequencer_cost": 5478510460134 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 1032974478, + "protocol_fee": 1032974478, "congestion_multiplier": 4960784044, "prover_cost": 202408760, "sequencer_cost": 58391745 @@ -21548,13 +21548,13 @@ "slot_of_change": 175 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 96342859710875, + "protocol_fee": 96342859710875, "congestion_multiplier": 4953850482, "prover_cost": 18911247024107, "sequencer_cost": 5455597444813 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 1031166202, + "protocol_fee": 1031166202, "congestion_multiplier": 4953850482, "prover_cost": 202408760, "sequencer_cost": 58391745 @@ -21602,13 +21602,13 @@ "slot_of_change": 180 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 97903356936636, + "protocol_fee": 97903356936636, "congestion_multiplier": 5000213429, "prover_cost": 18994824978804, "sequencer_cost": 5479708370735 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 1043257682, + "protocol_fee": 1043257682, "congestion_multiplier": 5000213429, "prover_cost": 202408760, "sequencer_cost": 58391745 @@ -21656,13 +21656,13 @@ "slot_of_change": 180 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 98516236972338, + "protocol_fee": 98516236972338, "congestion_multiplier": 5028474874, "prover_cost": 18979642682432, "sequencer_cost": 5475328516927 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 1050628281, + "protocol_fee": 1050628281, "congestion_multiplier": 5028474874, "prover_cost": 202408760, "sequencer_cost": 58391745 @@ -21710,13 +21710,13 @@ "slot_of_change": 180 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 100404138030454, + "protocol_fee": 100404138030454, "congestion_multiplier": 4902995999, "prover_cost": 19450329057757, "sequencer_cost": 6274559752708 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 1060054138, + "protocol_fee": 1060054138, "congestion_multiplier": 4902995999, "prover_cost": 205354104, "sequencer_cost": 66246005 @@ -21764,13 +21764,13 @@ "slot_of_change": 180 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 102038233088501, + "protocol_fee": 102038233088501, "congestion_multiplier": 4997853363, "prover_cost": 19297876195345, "sequencer_cost": 6225379371655 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 1085817409, + "protocol_fee": 1085817409, "congestion_multiplier": 4997853363, "prover_cost": 205354104, "sequencer_cost": 66246005 @@ -21818,13 +21818,13 @@ "slot_of_change": 180 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 100607952554659, + "protocol_fee": 100607952554659, "congestion_multiplier": 4963495005, "prover_cost": 19192318515652, "sequencer_cost": 6191327095900 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 1076485675, + "protocol_fee": 1076485675, "congestion_multiplier": 4963495005, "prover_cost": 205354104, "sequencer_cost": 66246005 @@ -21872,13 +21872,13 @@ "slot_of_change": 185 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 93673889852703, + "protocol_fee": 93673889852703, "congestion_multiplier": 4692169373, "prover_cost": 19182728771071, "sequencer_cost": 6188233501689 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 1002793604, + "protocol_fee": 1002793604, "congestion_multiplier": 4692169373, "prover_cost": 205354104, "sequencer_cost": 66246005 @@ -21926,13 +21926,13 @@ "slot_of_change": 185 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 99874036673263, + "protocol_fee": 99874036673263, "congestion_multiplier": 4959380675, "prover_cost": 19072112132677, "sequencer_cost": 6152549236133 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 1075368222, + "protocol_fee": 1075368222, "congestion_multiplier": 4959380675, "prover_cost": 205354104, "sequencer_cost": 66246005 @@ -21980,13 +21980,13 @@ "slot_of_change": 185 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 90615313608431, + "protocol_fee": 90615313608431, "congestion_multiplier": 4957139198, "prover_cost": 18409917930944, "sequencer_cost": 4489279984849 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 977921280, + "protocol_fee": 977921280, "congestion_multiplier": 4957139198, "prover_cost": 198680000, "sequencer_cost": 48448350 @@ -22034,13 +22034,13 @@ "slot_of_change": 185 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 90592785282146, + "protocol_fee": 90592785282146, "congestion_multiplier": 4958924552, "prover_cost": 18397040695073, "sequencer_cost": 4486139855845 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 978362492, + "protocol_fee": 978362492, "congestion_multiplier": 4958924552, "prover_cost": 198680000, "sequencer_cost": 48448350 @@ -22088,13 +22088,13 @@ "slot_of_change": 185 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 90724047393429, + "protocol_fee": 90724047393429, "congestion_multiplier": 4953163123, "prover_cost": 18450547740189, "sequencer_cost": 4499187611277 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 976938679, + "protocol_fee": 976938679, "congestion_multiplier": 4953163123, "prover_cost": 198680000, "sequencer_cost": 48448350 @@ -22142,13 +22142,13 @@ "slot_of_change": 190 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 92686044901513, + "protocol_fee": 92686044901513, "congestion_multiplier": 5005941012, "prover_cost": 18601217992176, "sequencer_cost": 4535928728162 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 989981592, + "protocol_fee": 989981592, "congestion_multiplier": 5005941012, "prover_cost": 198680000, "sequencer_cost": 48448350 @@ -22196,13 +22196,13 @@ "slot_of_change": 190 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 92105829147911, + "protocol_fee": 92105829147911, "congestion_multiplier": 4999971585, "prover_cost": 18512360224366, "sequencer_cost": 4514260657722 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 988506377, + "protocol_fee": 988506377, "congestion_multiplier": 4999971585, "prover_cost": 198680000, "sequencer_cost": 48448350 @@ -22250,13 +22250,13 @@ "slot_of_change": 190 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 88991912113750, + "protocol_fee": 88991912113750, "congestion_multiplier": 4901164896, "prover_cost": 18532518843071, "sequencer_cost": 4279106534547 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 948974332, + "protocol_fee": 948974332, "congestion_multiplier": 4901164896, "prover_cost": 197623405, "sequencer_cost": 45630689 @@ -22304,13 +22304,13 @@ "slot_of_change": 190 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 91534687437091, + "protocol_fee": 91534687437091, "congestion_multiplier": 5031893827, "prover_cost": 18443988200606, "sequencer_cost": 4258665057925 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 980774679, + "protocol_fee": 980774679, "congestion_multiplier": 5031893827, "prover_cost": 197623405, "sequencer_cost": 45630689 @@ -22358,13 +22358,13 @@ "slot_of_change": 190 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 90576717772700, + "protocol_fee": 90576717772700, "congestion_multiplier": 5023210832, "prover_cost": 18290349623607, "sequencer_cost": 4223190342137 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 978662505, + "protocol_fee": 978662505, "congestion_multiplier": 5023210832, "prover_cost": 197623405, "sequencer_cost": 45630689 @@ -22412,13 +22412,13 @@ "slot_of_change": 195 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 89062243125178, + "protocol_fee": 89062243125178, "congestion_multiplier": 4967017811, "prover_cost": 18239280338871, "sequencer_cost": 4211398587768 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 964993323, + "protocol_fee": 964993323, "congestion_multiplier": 4967017811, "prover_cost": 197623405, "sequencer_cost": 45630689 @@ -22466,13 +22466,13 @@ "slot_of_change": 195 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 88986761038162, + "protocol_fee": 88986761038162, "congestion_multiplier": 4973168415, "prover_cost": 18195611049689, "sequencer_cost": 4201315471583 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 966489483, + "protocol_fee": 966489483, "congestion_multiplier": 4973168415, "prover_cost": 197623405, "sequencer_cost": 45630689 @@ -22520,13 +22520,13 @@ "slot_of_change": 195 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 90594399115344, + "protocol_fee": 90594399115344, "congestion_multiplier": 5018998240, "prover_cost": 18201300505406, "sequencer_cost": 4340236908594 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 986705093, + "protocol_fee": 986705093, "congestion_multiplier": 5018998240, "prover_cost": 198238700, "sequencer_cost": 47271508 @@ -22574,13 +22574,13 @@ "slot_of_change": 195 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 89565537566784, + "protocol_fee": 89565537566784, "congestion_multiplier": 4952296438, "prover_cost": 18298281857233, "sequencer_cost": 4363362840861 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 970329120, + "protocol_fee": 970329120, "congestion_multiplier": 4952296438, "prover_cost": 198238700, "sequencer_cost": 47271508 @@ -22628,13 +22628,13 @@ "slot_of_change": 195 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 89552961105776, + "protocol_fee": 89552961105776, "congestion_multiplier": 4935539079, "prover_cost": 18373614856330, "sequencer_cost": 4381326560707 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 966215017, + "protocol_fee": 966215017, "congestion_multiplier": 4935539079, "prover_cost": 198238700, "sequencer_cost": 47271508 @@ -22682,13 +22682,13 @@ "slot_of_change": 200 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 90744853867745, + "protocol_fee": 90744853867745, "congestion_multiplier": 4948039086, "prover_cost": 18559208419855, "sequencer_cost": 4425582740872 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 969283897, + "protocol_fee": 969283897, "congestion_multiplier": 4948039086, "prover_cost": 198238700, "sequencer_cost": 47271508 @@ -22736,13 +22736,13 @@ "slot_of_change": 200 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 91457991668100, + "protocol_fee": 91457991668100, "congestion_multiplier": 5000950154, "prover_cost": 18457692510741, "sequencer_cost": 4401375509338 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 982274104, + "protocol_fee": 982274104, "congestion_multiplier": 5000950154, "prover_cost": 198238700, "sequencer_cost": 47271508 @@ -22790,13 +22790,13 @@ "slot_of_change": 200 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 89613561484121, + "protocol_fee": 89613561484121, "congestion_multiplier": 4991925205, "prover_cost": 18317725928667, "sequencer_cost": 4130981621793 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 964678250, + "protocol_fee": 964678250, "congestion_multiplier": 4991925205, "prover_cost": 197187920, "sequencer_cost": 44469476 @@ -22844,13 +22844,13 @@ "slot_of_change": 200 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 89645150528733, + "protocol_fee": 89645150528733, "congestion_multiplier": 4984147411, "prover_cost": 18359955192262, "sequencer_cost": 4140505091709 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 962798688, + "protocol_fee": 962798688, "congestion_multiplier": 4984147411, "prover_cost": 197187920, "sequencer_cost": 44469476 @@ -22898,13 +22898,13 @@ "slot_of_change": 200 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 87425271226608, + "protocol_fee": 87425271226608, "congestion_multiplier": 4888985031, "prover_cost": 18343446258178, "sequencer_cost": 4136782025671 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 939801995, + "protocol_fee": 939801995, "congestion_multiplier": 4888985031, "prover_cost": 197187920, "sequencer_cost": 44469476 @@ -22952,13 +22952,13 @@ "slot_of_change": 205 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 89930357307331, + "protocol_fee": 89930357307331, "congestion_multiplier": 5004020192, "prover_cost": 18326953359787, "sequencer_cost": 4133062575974 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 967601093, + "protocol_fee": 967601093, "congestion_multiplier": 5004020192, "prover_cost": 197187920, "sequencer_cost": 44469476 @@ -23006,13 +23006,13 @@ "slot_of_change": 205 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 85930566286063, + "protocol_fee": 85930566286063, "congestion_multiplier": 4834352011, "prover_cost": 18286723906136, "sequencer_cost": 4123990099711 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 926599522, + "protocol_fee": 926599522, "congestion_multiplier": 4834352011, "prover_cost": 197187920, "sequencer_cost": 44469476 @@ -23060,13 +23060,13 @@ "slot_of_change": 205 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 86431854923491, + "protocol_fee": 86431854923491, "congestion_multiplier": 4896164432, "prover_cost": 18161867799913, "sequencer_cost": 4021963631788 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 936851384, + "protocol_fee": 936851384, "congestion_multiplier": 4896164432, "prover_cost": 196859954, "sequencer_cost": 43594832 @@ -23114,13 +23114,13 @@ "slot_of_change": 205 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 87839761527144, + "protocol_fee": 87839761527144, "congestion_multiplier": 4952502368, "prover_cost": 18194618879672, "sequencer_cost": 4029216390873 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 950398111, + "protocol_fee": 950398111, "congestion_multiplier": 4952502368, "prover_cost": 196859954, "sequencer_cost": 43594832 @@ -23168,13 +23168,13 @@ "slot_of_change": 205 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 88346450571111, + "protocol_fee": 88346450571111, "congestion_multiplier": 4960195495, "prover_cost": 18264022529901, "sequencer_cost": 4044585898031 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 952247960, + "protocol_fee": 952247960, "congestion_multiplier": 4960195495, "prover_cost": 196859954, "sequencer_cost": 43594832 @@ -23222,13 +23222,13 @@ "slot_of_change": 210 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 90195382245227, + "protocol_fee": 90195382245227, "congestion_multiplier": 5053182768, "prover_cost": 18218477034543, "sequencer_cost": 4034499802925 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 974607195, + "protocol_fee": 974607195, "congestion_multiplier": 5053182768, "prover_cost": 196859954, "sequencer_cost": 43594832 @@ -23276,13 +23276,13 @@ "slot_of_change": 210 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 88374436159691, + "protocol_fee": 88374436159691, "congestion_multiplier": 4986047310, "prover_cost": 18151317814934, "sequencer_cost": 4019627327154 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 958464152, + "protocol_fee": 958464152, "congestion_multiplier": 4986047310, "prover_cost": 196859954, "sequencer_cost": 43594832 @@ -23330,13 +23330,13 @@ "slot_of_change": 210 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 84922359652697, + "protocol_fee": 84922359652697, "congestion_multiplier": 4921056316, "prover_cost": 17968013145993, "sequencer_cost": 3690017964940 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 924340311, + "protocol_fee": 924340311, "congestion_multiplier": 4921056316, "prover_cost": 195573450, "sequencer_cost": 40164126 @@ -23384,13 +23384,13 @@ "slot_of_change": 210 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 85496649107014, + "protocol_fee": 85496649107014, "congestion_multiplier": 4955862266, "prover_cost": 17930360248386, "sequencer_cost": 3682285342114 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 932545381, + "protocol_fee": 932545381, "congestion_multiplier": 4955862266, "prover_cost": 195573450, "sequencer_cost": 40164126 @@ -23438,13 +23438,13 @@ "slot_of_change": 210 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 84261270768150, + "protocol_fee": 84261270768150, "congestion_multiplier": 4924043839, "prover_cost": 17814565639510, "sequencer_cost": 3658505073059 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 925044582, + "protocol_fee": 925044582, "congestion_multiplier": 4924043839, "prover_cost": 195573450, "sequencer_cost": 40164126 @@ -23492,13 +23492,13 @@ "slot_of_change": 215 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 85242195937819, + "protocol_fee": 85242195937819, "congestion_multiplier": 4969725480, "prover_cost": 17814565639510, "sequencer_cost": 3658505073059 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 935813462, + "protocol_fee": 935813462, "congestion_multiplier": 4969725480, "prover_cost": 195573450, "sequencer_cost": 40164126 @@ -23546,13 +23546,13 @@ "slot_of_change": 215 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 83861641890437, + "protocol_fee": 83861641890437, "congestion_multiplier": 4935504678, "prover_cost": 17678442957723, "sequencer_cost": 3630550110140 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 927746333, + "protocol_fee": 927746333, "congestion_multiplier": 4935504678, "prover_cost": 195573450, "sequencer_cost": 40164126 @@ -23600,13 +23600,13 @@ "slot_of_change": 215 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 84996326584126, + "protocol_fee": 84996326584126, "congestion_multiplier": 4933441465, "prover_cost": 17674165633860, "sequencer_cost": 3934475898632 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 947163280, + "protocol_fee": 947163280, "congestion_multiplier": 4933441465, "prover_cost": 196953461, "sequencer_cost": 43844143 @@ -23654,13 +23654,13 @@ "slot_of_change": 215 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 86082771828446, + "protocol_fee": 86082771828446, "congestion_multiplier": 4979735872, "prover_cost": 17691858160412, "sequencer_cost": 3938414461886 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 958310862, + "protocol_fee": 958310862, "congestion_multiplier": 4979735872, "prover_cost": 196953461, "sequencer_cost": 43844143 @@ -23708,13 +23708,13 @@ "slot_of_change": 215 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 85854742534062, + "protocol_fee": 85854742534062, "congestion_multiplier": 4947759784, "prover_cost": 17787914257167, "sequencer_cost": 3959797672015 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 950611097, + "protocol_fee": 950611097, "congestion_multiplier": 4947759784, "prover_cost": 196953461, "sequencer_cost": 43844143 @@ -23762,13 +23762,13 @@ "slot_of_change": 220 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 86599018888331, + "protocol_fee": 86599018888331, "congestion_multiplier": 4975611712, "prover_cost": 17816420996756, "sequencer_cost": 3966143605519 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 957317774, + "protocol_fee": 957317774, "congestion_multiplier": 4975611712, "prover_cost": 196953461, "sequencer_cost": 43844143 @@ -23816,13 +23816,13 @@ "slot_of_change": 220 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 86717592388230, + "protocol_fee": 86717592388230, "congestion_multiplier": 4973092820, "prover_cost": 17852126532054, "sequencer_cost": 3974092075110 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 956711231, + "protocol_fee": 956711231, "congestion_multiplier": 4973092820, "prover_cost": 196953461, "sequencer_cost": 43844143 @@ -23870,13 +23870,13 @@ "slot_of_change": 220 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 85272294052133, + "protocol_fee": 85272294052133, "congestion_multiplier": 4923708845, "prover_cost": 17792178887282, "sequencer_cost": 3940395429088 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 943494189, + "protocol_fee": 943494189, "congestion_multiplier": 4923708845, "prover_cost": 196861332, "sequencer_cost": 43598454 @@ -23924,13 +23924,13 @@ "slot_of_change": 220 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 87725761767300, + "protocol_fee": 87725761767300, "congestion_multiplier": 5003502194, "prover_cost": 17939281329150, "sequencer_cost": 3972973889164 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 962681280, + "protocol_fee": 962681280, "congestion_multiplier": 5003502194, "prover_cost": 196861332, "sequencer_cost": 43598454 @@ -23978,13 +23978,13 @@ "slot_of_change": 220 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 83744914733713, + "protocol_fee": 83744914733713, "congestion_multiplier": 4840938892, "prover_cost": 17850032451912, "sequencer_cost": 3953208133090 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 923591344, + "protocol_fee": 923591344, "congestion_multiplier": 4840938892, "prover_cost": 196861332, "sequencer_cost": 43598454 @@ -24032,13 +24032,13 @@ "slot_of_change": 225 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 85557137216376, + "protocol_fee": 85557137216376, "congestion_multiplier": 4925233019, "prover_cost": 17844679998993, "sequencer_cost": 3952022736902 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 943860691, + "protocol_fee": 943860691, "congestion_multiplier": 4925233019, "prover_cost": 196861332, "sequencer_cost": 43598454 @@ -24086,13 +24086,13 @@ "slot_of_change": 225 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 86982189454164, + "protocol_fee": 86982189454164, "congestion_multiplier": 5007372804, "prover_cost": 17770046003582, "sequencer_cost": 3935493707140 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 963612006, + "protocol_fee": 963612006, "congestion_multiplier": 5007372804, "prover_cost": 196861332, "sequencer_cost": 43598454 @@ -24140,13 +24140,13 @@ "slot_of_change": 225 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 84911691144719, + "protocol_fee": 84911691144719, "congestion_multiplier": 4905988981, "prover_cost": 17729566996105, "sequencer_cost": 4009278552165 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 944625242, + "protocol_fee": 944625242, "congestion_multiplier": 4905988981, "prover_cost": 197237816, "sequencer_cost": 44602406 @@ -24194,13 +24194,13 @@ "slot_of_change": 225 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 87557240292672, + "protocol_fee": 87557240292672, "congestion_multiplier": 5025269183, "prover_cost": 17740211318082, "sequencer_cost": 4011685607667 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 973471992, + "protocol_fee": 973471992, "congestion_multiplier": 5025269183, "prover_cost": 197237816, "sequencer_cost": 44602406 @@ -24248,13 +24248,13 @@ "slot_of_change": 225 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 85717594189374, + "protocol_fee": 85717594189374, "congestion_multiplier": 4914292262, "prover_cost": 17859873416610, "sequencer_cost": 4038745416023 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 946633309, + "protocol_fee": 946633309, "congestion_multiplier": 4914292262, "prover_cost": 197237816, "sequencer_cost": 44602406 @@ -24302,13 +24302,13 @@ "slot_of_change": 230 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 84225799201524, + "protocol_fee": 84225799201524, "congestion_multiplier": 4864630942, "prover_cost": 17774556221443, "sequencer_cost": 4019452198045 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 934623204, + "protocol_fee": 934623204, "congestion_multiplier": 4864630942, "prover_cost": 197237816, "sequencer_cost": 44602406 @@ -24356,13 +24356,13 @@ "slot_of_change": 230 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 84179830684240, + "protocol_fee": 84179830684240, "congestion_multiplier": 4874495329, "prover_cost": 17719626302563, "sequencer_cost": 4007030611793 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 937008810, + "protocol_fee": 937008810, "congestion_multiplier": 4874495329, "prover_cost": 197237816, "sequencer_cost": 44602406 @@ -24410,13 +24410,13 @@ "slot_of_change": 230 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 86240631536065, + "protocol_fee": 86240631536065, "congestion_multiplier": 4922559097, "prover_cost": 17786767215334, "sequencer_cost": 4199040880244 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 960235618, + "protocol_fee": 960235618, "congestion_multiplier": 4922559097, "prover_cost": 198044554, "sequencer_cost": 46753700 @@ -24464,13 +24464,13 @@ "slot_of_change": 230 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 85429879618901, + "protocol_fee": 85429879618901, "congestion_multiplier": 4903168281, "prover_cost": 17707086426906, "sequencer_cost": 4180230104574 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 955488780, + "protocol_fee": 955488780, "congestion_multiplier": 4903168281, "prover_cost": 198044554, "sequencer_cost": 46753700 @@ -24518,13 +24518,13 @@ "slot_of_change": 230 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 86286413964083, + "protocol_fee": 86286413964083, "congestion_multiplier": 4929292429, "prover_cost": 17765713624969, "sequencer_cost": 4194070618613 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 961883926, + "protocol_fee": 961883926, "congestion_multiplier": 4929292429, "prover_cost": 198044554, "sequencer_cost": 46753700 @@ -24572,13 +24572,13 @@ "slot_of_change": 235 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 85183780718587, + "protocol_fee": 85183780718587, "congestion_multiplier": 4886839064, "prover_cost": 17730253344132, "sequencer_cost": 4185699273385 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 951491416, + "protocol_fee": 951491416, "congestion_multiplier": 4886839064, "prover_cost": 198044554, "sequencer_cost": 46753700 @@ -24626,13 +24626,13 @@ "slot_of_change": 235 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 85634776030469, + "protocol_fee": 85634776030469, "congestion_multiplier": 4919921003, "prover_cost": 17673698413001, "sequencer_cost": 4172347973234 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 959589817, + "protocol_fee": 959589817, "congestion_multiplier": 4919921003, "prover_cost": 198044554, "sequencer_cost": 46753700 @@ -24680,13 +24680,13 @@ "slot_of_change": 235 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 82685897147148, + "protocol_fee": 82685897147148, "congestion_multiplier": 4931934878, "prover_cost": 17468553911054, "sequencer_cost": 3560761118262 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 925155966, + "protocol_fee": 925155966, "congestion_multiplier": 4931934878, "prover_cost": 195452156, "sequencer_cost": 39840644 @@ -24734,13 +24734,13 @@ "slot_of_change": 235 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 82746527748475, + "protocol_fee": 82746527748475, "congestion_multiplier": 4917111200, "prover_cost": 17547518371049, "sequencer_cost": 3576857103098 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 921668062, + "protocol_fee": 921668062, "congestion_multiplier": 4917111200, "prover_cost": 195452156, "sequencer_cost": 39840644 @@ -24788,13 +24788,13 @@ "slot_of_change": 235 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 82008774345666, + "protocol_fee": 82008774345666, "congestion_multiplier": 4905479808, "prover_cost": 17442862293491, "sequencer_cost": 3555524181458 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 918931279, + "protocol_fee": 918931279, "congestion_multiplier": 4905479808, "prover_cost": 195452156, "sequencer_cost": 39840644 @@ -24842,13 +24842,13 @@ "slot_of_change": 240 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 81908219267262, + "protocol_fee": 81908219267262, "congestion_multiplier": 4924875133, "prover_cost": 17335384051020, "sequencer_cost": 3533615994392 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 923494859, + "protocol_fee": 923494859, "congestion_multiplier": 4924875133, "prover_cost": 195452156, "sequencer_cost": 39840644 @@ -24896,13 +24896,13 @@ "slot_of_change": 240 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 81745775806767, + "protocol_fee": 81745775806767, "congestion_multiplier": 4940985085, "prover_cost": 17230280846513, "sequencer_cost": 3512191931134 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 927285415, + "protocol_fee": 927285415, "congestion_multiplier": 4940985085, "prover_cost": 195452156, "sequencer_cost": 39840644 @@ -24950,13 +24950,13 @@ "slot_of_change": 240 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 81323024174438, + "protocol_fee": 81323024174438, "congestion_multiplier": 4952910729, "prover_cost": 17193313007105, "sequencer_cost": 3379634321977 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 921751914, + "protocol_fee": 921751914, "congestion_multiplier": 4952910729, "prover_cost": 194876781, "sequencer_cost": 38306303 @@ -25004,13 +25004,13 @@ "slot_of_change": 240 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 81554116543805, + "protocol_fee": 81554116543805, "congestion_multiplier": 4963746947, "prover_cost": 17195033352104, "sequencer_cost": 3379972484669 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 924278737, + "protocol_fee": 924278737, "congestion_multiplier": 4963746947, "prover_cost": 194876781, "sequencer_cost": 38306303 @@ -25058,13 +25058,13 @@ "slot_of_change": 240 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 83738872178665, + "protocol_fee": 83738872178665, "congestion_multiplier": 5051209929, "prover_cost": 17274497162710, "sequencer_cost": 3395592430724 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 944673625, + "protocol_fee": 944673625, "congestion_multiplier": 5051209929, "prover_cost": 194876781, "sequencer_cost": 38306303 @@ -25112,13 +25112,13 @@ "slot_of_change": 245 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 80990507685859, + "protocol_fee": 80990507685859, "congestion_multiplier": 4944498502, "prover_cost": 17159529732362, "sequencer_cost": 3372993652155 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 919790325, + "protocol_fee": 919790325, "congestion_multiplier": 4944498502, "prover_cost": 194876781, "sequencer_cost": 38306303 @@ -25166,13 +25166,13 @@ "slot_of_change": 245 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 81804938004084, + "protocol_fee": 81804938004084, "congestion_multiplier": 4976195391, "prover_cost": 17193918274425, "sequencer_cost": 3379753297431 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 927181503, + "protocol_fee": 927181503, "congestion_multiplier": 4976195391, "prover_cost": 194876781, "sequencer_cost": 38306303 @@ -25220,13 +25220,13 @@ "slot_of_change": 245 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 83620563824147, + "protocol_fee": 83620563824147, "congestion_multiplier": 4993741955, "prover_cost": 17302527464717, "sequencer_cost": 3635371084377 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 947001631, + "protocol_fee": 947001631, "congestion_multiplier": 4993741955, "prover_cost": 195950864, "sequencer_cost": 41170523 @@ -25274,13 +25274,13 @@ "slot_of_change": 245 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 82070336022870, + "protocol_fee": 82070336022870, "congestion_multiplier": 4931461408, "prover_cost": 17250776589651, "sequencer_cost": 3624497896331 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 932233582, + "protocol_fee": 932233582, "congestion_multiplier": 4931461408, "prover_cost": 195950864, "sequencer_cost": 41170523 @@ -25328,13 +25328,13 @@ "slot_of_change": 245 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 82078714029488, + "protocol_fee": 82078714029488, "congestion_multiplier": 4918101004, "prover_cost": 17311367356109, "sequencer_cost": 3637228401791 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 929065544, + "protocol_fee": 929065544, "congestion_multiplier": 4918101004, "prover_cost": 195950864, "sequencer_cost": 41170523 @@ -25382,13 +25382,13 @@ "slot_of_change": 250 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 82957939097442, + "protocol_fee": 82957939097442, "congestion_multiplier": 4949775388, "prover_cost": 17356494356131, "sequencer_cost": 3646709871555 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 936576218, + "protocol_fee": 936576218, "congestion_multiplier": 4949775388, "prover_cost": 195950864, "sequencer_cost": 41170523 @@ -25436,13 +25436,13 @@ "slot_of_change": 250 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 80447663396570, + "protocol_fee": 80447663396570, "congestion_multiplier": 4835618817, "prover_cost": 17332230278915, "sequencer_cost": 3641611834584 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 909507253, + "protocol_fee": 909507253, "congestion_multiplier": 4835618817, "prover_cost": 195950864, "sequencer_cost": 41170523 @@ -25490,13 +25490,13 @@ "slot_of_change": 250 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 79652878801026, + "protocol_fee": 79652878801026, "congestion_multiplier": 4844399909, "prover_cost": 17226895980328, "sequencer_cost": 3492300952752 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 903313349, + "protocol_fee": 903313349, "congestion_multiplier": 4844399909, "prover_cost": 195363750, "sequencer_cost": 39604872 @@ -25544,13 +25544,13 @@ "slot_of_change": 250 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 82926948323732, + "protocol_fee": 82926948323732, "congestion_multiplier": 5011626387, "prover_cost": 17187365698791, "sequencer_cost": 3484287225843 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 942606324, + "protocol_fee": 942606324, "congestion_multiplier": 5011626387, "prover_cost": 195363750, "sequencer_cost": 39604872 @@ -25598,13 +25598,13 @@ "slot_of_change": 250 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 82191641289473, + "protocol_fee": 82191641289473, "congestion_multiplier": 4972079438, "prover_cost": 17204570712987, "sequencer_cost": 3487775090839 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 933314032, + "protocol_fee": 933314032, "congestion_multiplier": 4972079438, "prover_cost": 195363750, "sequencer_cost": 39604872 @@ -25652,13 +25652,13 @@ "slot_of_change": 255 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 81192889453792, + "protocol_fee": 81192889453792, "congestion_multiplier": 4920281215, "prover_cost": 17220069069345, "sequencer_cost": 3490916975757 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 921143074, + "protocol_fee": 921143074, "congestion_multiplier": 4920281215, "prover_cost": 195363750, "sequencer_cost": 39604872 @@ -25706,13 +25706,13 @@ "slot_of_change": 255 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 82327221117698, + "protocol_fee": 82327221117698, "congestion_multiplier": 4994130820, "prover_cost": 17137808458841, "sequencer_cost": 3474240796325 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 938495414, + "protocol_fee": 938495414, "congestion_multiplier": 4994130820, "prover_cost": 195363750, "sequencer_cost": 39604872 @@ -25760,13 +25760,13 @@ "slot_of_change": 255 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 82271887496938, + "protocol_fee": 82271887496938, "congestion_multiplier": 4979975346, "prover_cost": 17039987767479, "sequencer_cost": 3631468811892 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 947243218, + "protocol_fee": 947243218, "congestion_multiplier": 4979975346, "prover_cost": 196191109, "sequencer_cost": 41811174 @@ -25814,13 +25814,13 @@ "slot_of_change": 255 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 81248578355190, + "protocol_fee": 81248578355190, "congestion_multiplier": 4927720360, "prover_cost": 17051924855837, "sequencer_cost": 3634012778746 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 934806412, + "protocol_fee": 934806412, "congestion_multiplier": 4927720360, "prover_cost": 196191109, "sequencer_cost": 41811174 @@ -25868,13 +25868,13 @@ "slot_of_change": 255 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 81661042085240, + "protocol_fee": 81661042085240, "congestion_multiplier": 4940948450, "prover_cost": 17080963430891, "sequencer_cost": 3640201320727 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 937954728, + "protocol_fee": 937954728, "congestion_multiplier": 4940948450, "prover_cost": 196191109, "sequencer_cost": 41811174 @@ -25922,13 +25922,13 @@ "slot_of_change": 260 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 82116969590840, + "protocol_fee": 82116969590840, "congestion_multiplier": 4979991925, "prover_cost": 17007830631781, "sequencer_cost": 3624615659357 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 947247164, + "protocol_fee": 947247164, "congestion_multiplier": 4979991925, "prover_cost": 196191109, "sequencer_cost": 41811174 @@ -25976,13 +25976,13 @@ "slot_of_change": 260 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 80404500887344, + "protocol_fee": 80404500887344, "congestion_multiplier": 4900110606, "prover_cost": 16994235643985, "sequencer_cost": 3621718370060 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 928235228, + "protocol_fee": 928235228, "congestion_multiplier": 4900110606, "prover_cost": 196191109, "sequencer_cost": 41811174 @@ -26030,13 +26030,13 @@ "slot_of_change": 260 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 80329917047102, + "protocol_fee": 80329917047102, "congestion_multiplier": 4989369458, "prover_cost": 16886127370117, "sequencer_cost": 3249866032813 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 925519372, + "protocol_fee": 925519372, "congestion_multiplier": 4989369458, "prover_cost": 194553145, "sequencer_cost": 37443260 @@ -26084,13 +26084,13 @@ "slot_of_change": 260 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 79206346700592, + "protocol_fee": 79206346700592, "congestion_multiplier": 4972905793, "prover_cost": 16718939110875, "sequencer_cost": 3217689357079 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 921699861, + "protocol_fee": 921699861, "congestion_multiplier": 4972905793, "prover_cost": 194553145, "sequencer_cost": 37443260 @@ -26138,13 +26138,13 @@ "slot_of_change": 260 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 78475736106097, + "protocol_fee": 78475736106097, "congestion_multiplier": 4941376047, "prover_cost": 16697233710891, "sequencer_cost": 3213511984696 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 914385073, + "protocol_fee": 914385073, "congestion_multiplier": 4941376047, "prover_cost": 194553145, "sequencer_cost": 37443260 @@ -26192,13 +26192,13 @@ "slot_of_change": 265 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 78165187338511, + "protocol_fee": 78165187338511, "congestion_multiplier": 4947370786, "prover_cost": 16605901260373, "sequencer_cost": 3195934347021 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 915775831, + "protocol_fee": 915775831, "congestion_multiplier": 4947370786, "prover_cost": 194553145, "sequencer_cost": 37443260 @@ -26246,13 +26246,13 @@ "slot_of_change": 265 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 78001374542984, + "protocol_fee": 78001374542984, "congestion_multiplier": 4946188345, "prover_cost": 16576065230342, "sequencer_cost": 3190192171896 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 915501509, + "protocol_fee": 915501509, "congestion_multiplier": 4946188345, "prover_cost": 194553145, "sequencer_cost": 37443260 @@ -26300,13 +26300,13 @@ "slot_of_change": 265 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 79806177937705, + "protocol_fee": 79806177937705, "congestion_multiplier": 5010108084, "prover_cost": 16617358305880, "sequencer_cost": 3283895302003 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 936309782, + "protocol_fee": 936309782, "congestion_multiplier": 5010108084, "prover_cost": 194959783, "sequencer_cost": 38527635 @@ -26354,13 +26354,13 @@ "slot_of_change": 265 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 80608601273039, + "protocol_fee": 80608601273039, "congestion_multiplier": 5054478649, "prover_cost": 16600757968156, "sequencer_cost": 3280614770281 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 946669751, + "protocol_fee": 946669751, "congestion_multiplier": 5054478649, "prover_cost": 194959783, "sequencer_cost": 38527635 @@ -26408,13 +26408,13 @@ "slot_of_change": 265 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 78808981562897, + "protocol_fee": 78808981562897, "congestion_multiplier": 4960393079, "prover_cost": 16615712638533, "sequencer_cost": 3283570087900 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 924701954, + "protocol_fee": 924701954, "congestion_multiplier": 4960393079, "prover_cost": 194959783, "sequencer_cost": 38527635 @@ -26462,13 +26462,13 @@ "slot_of_change": 270 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 78727006250162, + "protocol_fee": 78727006250162, "congestion_multiplier": 4931348975, "prover_cost": 16721055585565, "sequencer_cost": 3304387789637 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 917920521, + "protocol_fee": 917920521, "congestion_multiplier": 4931348975, "prover_cost": 194959783, "sequencer_cost": 38527635 @@ -26516,13 +26516,13 @@ "slot_of_change": 270 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 79036604731690, + "protocol_fee": 79036604731690, "congestion_multiplier": 4939704693, "prover_cost": 16751208956443, "sequencer_cost": 3310346649712 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 919871476, + "protocol_fee": 919871476, "congestion_multiplier": 4939704693, "prover_cost": 194959783, "sequencer_cost": 38527635 @@ -26570,13 +26570,13 @@ "slot_of_change": 270 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 76635012860518, + "protocol_fee": 76635012860518, "congestion_multiplier": 4957033000, "prover_cost": 16465546991343, "sequencer_cost": 2901239419453 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 899590904, + "protocol_fee": 899590904, "congestion_multiplier": 4957033000, "prover_cost": 193283145, "sequencer_cost": 34056608 @@ -26624,13 +26624,13 @@ "slot_of_change": 270 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 76740762009573, + "protocol_fee": 76740762009573, "congestion_multiplier": 4979532003, "prover_cost": 16395048501088, "sequencer_cost": 2888817542485 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 904705822, + "protocol_fee": 904705822, "congestion_multiplier": 4979532003, "prover_cost": 193283145, "sequencer_cost": 34056608 @@ -26678,13 +26678,13 @@ "slot_of_change": 270 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 75607226476864, + "protocol_fee": 75607226476864, "congestion_multiplier": 4931336274, "prover_cost": 16350901920126, "sequencer_cost": 2881038888002 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 893749017, + "protocol_fee": 893749017, "congestion_multiplier": 4931336274, "prover_cost": 193283145, "sequencer_cost": 34056608 @@ -26732,13 +26732,13 @@ "slot_of_change": 275 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 74631554231520, + "protocol_fee": 74631554231520, "congestion_multiplier": 4897290985, "prover_cost": 16280894174478, "sequencer_cost": 2868703480533 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 886009169, + "protocol_fee": 886009169, "congestion_multiplier": 4897290985, "prover_cost": 193283145, "sequencer_cost": 34056608 @@ -26786,13 +26786,13 @@ "slot_of_change": 275 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 74927299849340, + "protocol_fee": 74927299849340, "congestion_multiplier": 4916647422, "prover_cost": 16264630608379, "sequencer_cost": 2865837830269 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 890409657, + "protocol_fee": 890409657, "congestion_multiplier": 4916647422, "prover_cost": 193283145, "sequencer_cost": 34056608 @@ -26840,13 +26840,13 @@ "slot_of_change": 275 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 78535642108372, + "protocol_fee": 78535642108372, "congestion_multiplier": 4963015408, "prover_cost": 16480703127967, "sequencer_cost": 3336439644809 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 930863332, + "protocol_fee": 930863332, "congestion_multiplier": 4963015408, "prover_cost": 195341654, "sequencer_cost": 39545985 @@ -26894,13 +26894,13 @@ "slot_of_change": 275 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 78228115760633, + "protocol_fee": 78228115760633, "congestion_multiplier": 4919469822, "prover_cost": 16598553523170, "sequencer_cost": 3360297894524 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 920635012, + "protocol_fee": 920635012, "congestion_multiplier": 4919469822, "prover_cost": 195341654, "sequencer_cost": 39545985 @@ -26948,13 +26948,13 @@ "slot_of_change": 275 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 78027856175491, + "protocol_fee": 78027856175491, "congestion_multiplier": 4932892628, "prover_cost": 16499556980426, "sequencer_cost": 3340256517203 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 923787863, + "protocol_fee": 923787863, "congestion_multiplier": 4932892628, "prover_cost": 195341654, "sequencer_cost": 39545985 @@ -27002,13 +27002,13 @@ "slot_of_change": 280 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 78169827661478, + "protocol_fee": 78169827661478, "congestion_multiplier": 4948716539, "prover_cost": 16463337988945, "sequencer_cost": 3332924155341 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 927504704, + "protocol_fee": 927504704, "congestion_multiplier": 4948716539, "prover_cost": 195341654, "sequencer_cost": 39545985 @@ -27056,13 +27056,13 @@ "slot_of_change": 280 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 78786540093894, + "protocol_fee": 78786540093894, "congestion_multiplier": 5006534575, "prover_cost": 16353768002995, "sequencer_cost": 3310742234936 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 941085446, + "protocol_fee": 941085446, "congestion_multiplier": 5006534575, "prover_cost": 195341654, "sequencer_cost": 39545985 @@ -27110,13 +27110,13 @@ "slot_of_change": 280 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 77065109301125, + "protocol_fee": 77065109301125, "congestion_multiplier": 4864882002, "prover_cost": 16427757858882, "sequencer_cost": 3512077112707 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 920615403, + "protocol_fee": 920615403, "congestion_multiplier": 4864882002, "prover_cost": 196245059, "sequencer_cost": 41955073 @@ -27164,13 +27164,13 @@ "slot_of_change": 280 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 77209285663491, + "protocol_fee": 77209285663491, "congestion_multiplier": 4887988117, "prover_cost": 16360679574297, "sequencer_cost": 3497736500308 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 926119282, + "protocol_fee": 926119282, "congestion_multiplier": 4887988117, "prover_cost": 196245059, "sequencer_cost": 41955073 @@ -27218,13 +27218,13 @@ "slot_of_change": 280 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 77194787385996, + "protocol_fee": 77194787385996, "congestion_multiplier": 4911747757, "prover_cost": 16258252586122, "sequencer_cost": 3475838717057 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 931778832, + "protocol_fee": 931778832, "congestion_multiplier": 4911747757, "prover_cost": 196245059, "sequencer_cost": 41955073 @@ -27272,13 +27272,13 @@ "slot_of_change": 285 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 77983370194635, + "protocol_fee": 77983370194635, "congestion_multiplier": 4946966007, "prover_cost": 16277786487132, "sequencer_cost": 3480014854010 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 940167823, + "protocol_fee": 940167823, "congestion_multiplier": 4946966007, "prover_cost": 196245059, "sequencer_cost": 41955073 @@ -27326,13 +27326,13 @@ "slot_of_change": 285 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 78297230388699, + "protocol_fee": 78297230388699, "congestion_multiplier": 4964436394, "prover_cost": 16271278517740, "sequencer_cost": 3478623520479 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 944329272, + "protocol_fee": 944329272, "congestion_multiplier": 4964436394, "prover_cost": 196245059, "sequencer_cost": 41955073 @@ -27380,13 +27380,13 @@ "slot_of_change": 285 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 76939942510197, + "protocol_fee": 76939942510197, "congestion_multiplier": 5022241156, "prover_cost": 16061713107591, "sequencer_cost": 3066911839964 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 931392704, + "protocol_fee": 931392704, "congestion_multiplier": 5022241156, "prover_cost": 194434281, "sequencer_cost": 37126351 @@ -27434,13 +27434,13 @@ "slot_of_change": 285 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 75715637848623, + "protocol_fee": 75715637848623, "congestion_multiplier": 4980403315, "prover_cost": 15972269094155, "sequencer_cost": 3049832908098 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 921704707, + "protocol_fee": 921704707, "congestion_multiplier": 4980403315, "prover_cost": 194434281, "sequencer_cost": 37126351 @@ -27488,13 +27488,13 @@ "slot_of_change": 285 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 76586510048831, + "protocol_fee": 76586510048831, "congestion_multiplier": 5022159002, "prover_cost": 15988258349371, "sequencer_cost": 3052885984429 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 931373680, + "protocol_fee": 931373680, "congestion_multiplier": 5022159002, "prover_cost": 194434281, "sequencer_cost": 37126351 @@ -27542,13 +27542,13 @@ "slot_of_change": 290 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 76413587978156, + "protocol_fee": 76413587978156, "congestion_multiplier": 4999834191, "prover_cost": 16041194924319, "sequencer_cost": 3062993985200 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 926204133, + "protocol_fee": 926204133, "congestion_multiplier": 4999834191, "prover_cost": 194434281, "sequencer_cost": 37126351 @@ -27596,13 +27596,13 @@ "slot_of_change": 290 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 75565002391935, + "protocol_fee": 75565002391935, "congestion_multiplier": 4945526614, "prover_cost": 16081399301542, "sequencer_cost": 3070670830111 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 913628636, + "protocol_fee": 913628636, "congestion_multiplier": 4945526614, "prover_cost": 194434281, "sequencer_cost": 37126351 @@ -27650,13 +27650,13 @@ "slot_of_change": 290 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 76664571948923, + "protocol_fee": 76664571948923, "congestion_multiplier": 4950720098, "prover_cost": 16160218713136, "sequencer_cost": 3244996047104 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 926088863, + "protocol_fee": 926088863, "congestion_multiplier": 4950720098, "prover_cost": 195211402, "sequencer_cost": 39198741 @@ -27704,13 +27704,13 @@ "slot_of_change": 290 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 76545894283311, + "protocol_fee": 76545894283311, "congestion_multiplier": 4924881233, "prover_cost": 16241426180166, "sequencer_cost": 3261302627738 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 920031971, + "protocol_fee": 920031971, "congestion_multiplier": 4924881233, "prover_cost": 195211402, "sequencer_cost": 39198741 @@ -27758,13 +27758,13 @@ "slot_of_change": 290 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 75694576985701, + "protocol_fee": 75694576985701, "congestion_multiplier": 4891709288, "prover_cost": 16197692743568, "sequencer_cost": 3252520888369 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 912256130, + "protocol_fee": 912256130, "congestion_multiplier": 4891709288, "prover_cost": 195211402, "sequencer_cost": 39198741 @@ -27812,13 +27812,13 @@ "slot_of_change": 295 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 75850154765131, + "protocol_fee": 75850154765131, "congestion_multiplier": 4914136761, "prover_cost": 16137983104717, "sequencer_cost": 3240531103733 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 917513357, + "protocol_fee": 917513357, "congestion_multiplier": 4914136761, "prover_cost": 195211402, "sequencer_cost": 39198741 @@ -27866,13 +27866,13 @@ "slot_of_change": 295 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 75748148201784, + "protocol_fee": 75748148201784, "congestion_multiplier": 4882683358, "prover_cost": 16246837128646, "sequencer_cost": 3262389154272 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 910140361, + "protocol_fee": 910140361, "congestion_multiplier": 4882683358, "prover_cost": 195211402, "sequencer_cost": 39198741 @@ -27920,13 +27920,13 @@ "slot_of_change": 295 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 75342344953365, + "protocol_fee": 75342344953365, "congestion_multiplier": 4924696227, "prover_cost": 16112729057253, "sequencer_cost": 3084258585150 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 909338179, + "protocol_fee": 909338179, "congestion_multiplier": 4924696227, "prover_cost": 194471246, "sequencer_cost": 37225203 @@ -27974,13 +27974,13 @@ "slot_of_change": 295 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 76289001345942, + "protocol_fee": 76289001345942, "congestion_multiplier": 4958907680, "prover_cost": 16174191272747, "sequencer_cost": 3096023529817 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 917264851, + "protocol_fee": 917264851, "congestion_multiplier": 4958907680, "prover_cost": 194471246, "sequencer_cost": 37225203 @@ -28028,13 +28028,13 @@ "slot_of_change": 295 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 77467419635888, + "protocol_fee": 77467419635888, "congestion_multiplier": 5057848428, "prover_cost": 16023570243135, "sequencer_cost": 3067192026350 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 940189071, + "protocol_fee": 940189071, "congestion_multiplier": 5057848428, "prover_cost": 194471246, "sequencer_cost": 37225203 @@ -28082,13 +28082,13 @@ "slot_of_change": 300 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 75306747054594, + "protocol_fee": 75306747054594, "congestion_multiplier": 4966365100, "prover_cost": 15935922873480, "sequencer_cost": 3050414784496 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 918992709, + "protocol_fee": 918992709, "congestion_multiplier": 4966365100, "prover_cost": 194471246, "sequencer_cost": 37225203 @@ -28136,13 +28136,13 @@ "slot_of_change": 300 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 74063924467713, + "protocol_fee": 74063924467713, "congestion_multiplier": 4898565771, "prover_cost": 15945490174117, "sequencer_cost": 3052246133426 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 903283845, + "protocol_fee": 903283845, "congestion_multiplier": 4898565771, "prover_cost": 194471246, "sequencer_cost": 37225203 @@ -28190,13 +28190,13 @@ "slot_of_change": 300 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 75857344616178, + "protocol_fee": 75857344616178, "congestion_multiplier": 4959426763, "prover_cost": 16084951307331, "sequencer_cost": 3073717159147 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 917015013, + "protocol_fee": 917015013, "congestion_multiplier": 4959426763, "prover_cost": 194445797, "sequencer_cost": 37157177 @@ -28244,13 +28244,13 @@ "slot_of_change": 300 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 77623914637250, + "protocol_fee": 77623914637250, "congestion_multiplier": 5028944824, "prover_cost": 16175534841957, "sequencer_cost": 3091027013520 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 933115603, + "protocol_fee": 933115603, "congestion_multiplier": 5028944824, "prover_cost": 194445797, "sequencer_cost": 37157177 @@ -28298,13 +28298,13 @@ "slot_of_change": 300 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 77227463137585, + "protocol_fee": 77227463137585, "congestion_multiplier": 4983515461, "prover_cost": 16276450075127, "sequencer_cost": 3110311180309 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 922594027, + "protocol_fee": 922594027, "congestion_multiplier": 4983515461, "prover_cost": 194445797, "sequencer_cost": 37157177 @@ -28352,13 +28352,13 @@ "slot_of_change": 305 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 75925235505525, + "protocol_fee": 75925235505525, "congestion_multiplier": 4922218782, "prover_cost": 16252072884078, "sequencer_cost": 3105652876471 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 908397534, + "protocol_fee": 908397534, "congestion_multiplier": 4922218782, "prover_cost": 194445797, "sequencer_cost": 37157177 @@ -28406,13 +28406,13 @@ "slot_of_change": 305 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 74971835989475, + "protocol_fee": 74971835989475, "congestion_multiplier": 4882649272, "prover_cost": 16211545270875, "sequencer_cost": 3097908344470 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 899233118, + "protocol_fee": 899233118, "congestion_multiplier": 4882649272, "prover_cost": 194445797, "sequencer_cost": 37157177 @@ -28460,13 +28460,13 @@ "slot_of_change": 305 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 75434508110886, + "protocol_fee": 75434508110886, "congestion_multiplier": 4958918356, "prover_cost": 16131031586572, "sequencer_cost": 2923291182868 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 905687298, + "protocol_fee": 905687298, "congestion_multiplier": 4958918356, "prover_cost": 193673569, "sequencer_cost": 35097832 @@ -28514,13 +28514,13 @@ "slot_of_change": 305 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 75558011099867, + "protocol_fee": 75558011099867, "congestion_multiplier": 4966589311, "prover_cost": 16126194912620, "sequencer_cost": 2922414673127 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 907442193, + "protocol_fee": 907442193, "congestion_multiplier": 4966589311, "prover_cost": 193673569, "sequencer_cost": 35097832 @@ -28568,13 +28568,13 @@ "slot_of_change": 305 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 77060035946587, + "protocol_fee": 77060035946587, "congestion_multiplier": 5005391559, "prover_cost": 16287440913177, "sequencer_cost": 2951635929633 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 916319038, + "protocol_fee": 916319038, "congestion_multiplier": 5005391559, "prover_cost": 193673569, "sequencer_cost": 35097832 @@ -28622,13 +28622,13 @@ "slot_of_change": 310 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 75253266483982, + "protocol_fee": 75253266483982, "congestion_multiplier": 4919694210, "prover_cost": 16253309032006, "sequencer_cost": 2945450495878 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 896713935, + "protocol_fee": 896713935, "congestion_multiplier": 4919694210, "prover_cost": 193673569, "sequencer_cost": 35097832 @@ -28676,13 +28676,13 @@ "slot_of_change": 310 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 75930030462389, + "protocol_fee": 75930030462389, "congestion_multiplier": 4949407465, "prover_cost": 16276096487985, "sequencer_cost": 2949580074869 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 903511478, + "protocol_fee": 903511478, "congestion_multiplier": 4949407465, "prover_cost": 193673569, "sequencer_cost": 35097832 @@ -28730,13 +28730,13 @@ "slot_of_change": 310 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 74224979558971, + "protocol_fee": 74224979558971, "congestion_multiplier": 4907337732, "prover_cost": 16119470183844, "sequencer_cost": 2876834891224 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 890818292, + "protocol_fee": 890818292, "congestion_multiplier": 4907337732, "prover_cost": 193459385, "sequencer_cost": 34526613 @@ -28784,13 +28784,13 @@ "slot_of_change": 310 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 74961781307870, + "protocol_fee": 74961781307870, "congestion_multiplier": 4920079742, "prover_cost": 16226566142046, "sequencer_cost": 2895948260693 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 893723292, + "protocol_fee": 893723292, "congestion_multiplier": 4920079742, "prover_cost": 193459385, "sequencer_cost": 34526613 @@ -28838,13 +28838,13 @@ "slot_of_change": 310 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 73614424073899, + "protocol_fee": 73614424073899, "congestion_multiplier": 4871178291, "prover_cost": 16136203889667, "sequencer_cost": 2879821348485 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 882574446, + "protocol_fee": 882574446, "congestion_multiplier": 4871178291, "prover_cost": 193459385, "sequencer_cost": 34526613 @@ -28892,13 +28892,13 @@ "slot_of_change": 315 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 73889261584763, + "protocol_fee": 73889261584763, "congestion_multiplier": 4889905407, "prover_cost": 16118473657510, "sequencer_cost": 2876657041599 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 886843966, + "protocol_fee": 886843966, "congestion_multiplier": 4889905407, "prover_cost": 193459385, "sequencer_cost": 34526613 @@ -28946,13 +28946,13 @@ "slot_of_change": 315 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 74285680914822, + "protocol_fee": 74285680914822, "congestion_multiplier": 4930719581, "prover_cost": 16036687790908, "sequencer_cost": 2862060753261 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 896149026, + "protocol_fee": 896149026, "congestion_multiplier": 4930719581, "prover_cost": 193459385, "sequencer_cost": 34526613 @@ -29000,13 +29000,13 @@ "slot_of_change": 315 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 75299238248388, + "protocol_fee": 75299238248388, "congestion_multiplier": 4954198695, "prover_cost": 16129577744498, "sequencer_cost": 2913278739080 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 903925037, + "protocol_fee": 903925037, "congestion_multiplier": 4954198695, "prover_cost": 193626516, "sequencer_cost": 34972274 @@ -29054,13 +29054,13 @@ "slot_of_change": 315 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 76127529043808, + "protocol_fee": 76127529043808, "congestion_multiplier": 4974108170, "prover_cost": 16225308165316, "sequencer_cost": 2930569297089 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 908476318, + "protocol_fee": 908476318, "congestion_multiplier": 4974108170, "prover_cost": 193626516, "sequencer_cost": 34972274 @@ -29108,13 +29108,13 @@ "slot_of_change": 315 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 75359779186063, + "protocol_fee": 75359779186063, "congestion_multiplier": 4917505897, "prover_cost": 16293743024461, "sequencer_cost": 2942929807905 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 895537107, + "protocol_fee": 895537107, "congestion_multiplier": 4917505897, "prover_cost": 193626516, "sequencer_cost": 34972274 @@ -29162,13 +29162,13 @@ "slot_of_change": 320 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 74730932637138, + "protocol_fee": 74730932637138, "congestion_multiplier": 4878600069, "prover_cost": 16319855366546, "sequencer_cost": 2947646145321 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 886643282, + "protocol_fee": 886643282, "congestion_multiplier": 4878600069, "prover_cost": 193626516, "sequencer_cost": 34972274 @@ -29216,13 +29216,13 @@ "slot_of_change": 320 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 76239815187638, + "protocol_fee": 76239815187638, "congestion_multiplier": 4925257014, "prover_cost": 16451467382933, "sequencer_cost": 2971417535696 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 897309003, + "protocol_fee": 897309003, "congestion_multiplier": 4925257014, "prover_cost": 193626516, "sequencer_cost": 34972274 @@ -29270,13 +29270,13 @@ "slot_of_change": 320 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 77534861244612, + "protocol_fee": 77534861244612, "congestion_multiplier": 4915064403, "prover_cost": 16572229997795, "sequencer_cost": 3232006490183 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 911182246, + "protocol_fee": 911182246, "congestion_multiplier": 4915064403, "prover_cost": 194755256, "sequencer_cost": 37982230 @@ -29324,13 +29324,13 @@ "slot_of_change": 320 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 75726794813671, + "protocol_fee": 75726794813671, "congestion_multiplier": 4812296052, "prover_cost": 16622096695233, "sequencer_cost": 3241731764922 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 887264199, + "protocol_fee": 887264199, "congestion_multiplier": 4812296052, "prover_cost": 194755256, "sequencer_cost": 37982230 @@ -29378,13 +29378,13 @@ "slot_of_change": 320 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 78404027308484, + "protocol_fee": 78404027308484, "congestion_multiplier": 4933260324, "prover_cost": 16680479415303, "sequencer_cost": 3253117880743 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 915417119, + "protocol_fee": 915417119, "congestion_multiplier": 4933260324, "prover_cost": 194755256, "sequencer_cost": 37982230 @@ -29432,13 +29432,13 @@ "slot_of_change": 325 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 76987291405304, + "protocol_fee": 76987291405304, "congestion_multiplier": 4852531791, "prover_cost": 16722286423957, "sequencer_cost": 3261271311110 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 896628563, + "protocol_fee": 896628563, "congestion_multiplier": 4852531791, "prover_cost": 194755256, "sequencer_cost": 37982230 @@ -29486,13 +29486,13 @@ "slot_of_change": 325 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 78220810005436, + "protocol_fee": 78220810005436, "congestion_multiplier": 4915823973, "prover_cost": 16715601015423, "sequencer_cost": 3259967486352 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 911359027, + "protocol_fee": 911359027, "congestion_multiplier": 4915823973, "prover_cost": 194755256, "sequencer_cost": 37982230 @@ -29540,13 +29540,13 @@ "slot_of_change": 325 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 80029360729414, + "protocol_fee": 80029360729414, "congestion_multiplier": 4903702451, "prover_cost": 16858869805247, "sequencer_cost": 3642016677042 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 932430645, + "protocol_fee": 932430645, "congestion_multiplier": 4903702451, "prover_cost": 196424496, "sequencer_cost": 42433526 @@ -29594,13 +29594,13 @@ "slot_of_change": 325 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 79667212448680, + "protocol_fee": 79667212448680, "congestion_multiplier": 4906633152, "prover_cost": 16769990105745, "sequencer_cost": 3622816021745 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 933130667, + "protocol_fee": 933130667, "congestion_multiplier": 4906633152, "prover_cost": 196424496, "sequencer_cost": 42433526 @@ -29648,13 +29648,13 @@ "slot_of_change": 325 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 78171924616343, + "protocol_fee": 78171924616343, "congestion_multiplier": 4846341888, "prover_cost": 16713166358652, "sequencer_cost": 3610540404402 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 918729615, + "protocol_fee": 918729615, "congestion_multiplier": 4846341888, "prover_cost": 196424496, "sequencer_cost": 42433526 @@ -29702,13 +29702,13 @@ "slot_of_change": 330 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 79909960703329, + "protocol_fee": 79909960703329, "congestion_multiplier": 4916525125, "prover_cost": 16778603695411, "sequencer_cost": 3624676812983 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 935493444, + "protocol_fee": 935493444, "congestion_multiplier": 4916525125, "prover_cost": 196424496, "sequencer_cost": 42433526 @@ -29756,13 +29756,13 @@ "slot_of_change": 330 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 80623528718388, + "protocol_fee": 80623528718388, "congestion_multiplier": 4934506692, "prover_cost": 16851064092631, "sequencer_cost": 3640330411246 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 939788485, + "protocol_fee": 939788485, "congestion_multiplier": 4934506692, "prover_cost": 196424496, "sequencer_cost": 42433526 @@ -29810,13 +29810,13 @@ "slot_of_change": 330 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 78155087772898, + "protocol_fee": 78155087772898, "congestion_multiplier": 4855599748, "prover_cost": 16820190127520, "sequencer_cost": 3450349585510 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 908646447, + "protocol_fee": 908646447, "congestion_multiplier": 4855599748, "prover_cost": 195554844, "sequencer_cost": 40114444 @@ -29864,13 +29864,13 @@ "slot_of_change": 330 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 77060431563986, + "protocol_fee": 77060431563986, "congestion_multiplier": 4813002026, "prover_cost": 16769881335984, "sequencer_cost": 3440029671364 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 898607472, + "protocol_fee": 898607472, "congestion_multiplier": 4813002026, "prover_cost": 195554844, "sequencer_cost": 40114444 @@ -29918,13 +29918,13 @@ "slot_of_change": 330 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 79705832336608, + "protocol_fee": 79705832336608, "congestion_multiplier": 4904459171, "prover_cost": 16939274443578, "sequencer_cost": 3474777521070 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 920161112, + "protocol_fee": 920161112, "congestion_multiplier": 4904459171, "prover_cost": 195554844, "sequencer_cost": 40114444 @@ -29972,13 +29972,13 @@ "slot_of_change": 335 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 81041870414426, + "protocol_fee": 81041870414426, "congestion_multiplier": 4954026475, "prover_cost": 17007303871204, "sequencer_cost": 3488732494565 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 931842604, + "protocol_fee": 931842604, "congestion_multiplier": 4954026475, "prover_cost": 195554844, "sequencer_cost": 40114444 @@ -30026,13 +30026,13 @@ "slot_of_change": 335 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 80760788785345, + "protocol_fee": 80760788785345, "congestion_multiplier": 4941494452, "prover_cost": 17002203928364, "sequencer_cost": 3487686336019 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 928889191, + "protocol_fee": 928889191, "congestion_multiplier": 4941494452, "prover_cost": 195554844, "sequencer_cost": 40114444 @@ -30080,13 +30080,13 @@ "slot_of_change": 335 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 78613247758240, + "protocol_fee": 78613247758240, "congestion_multiplier": 4924048878, "prover_cost": 16964043796354, "sequencer_cost": 3069663792235 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 897407250, + "protocol_fee": 897407250, "congestion_multiplier": 4924048878, "prover_cost": 193652550, "sequencer_cost": 35041658 @@ -30134,13 +30134,13 @@ "slot_of_change": 335 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 77621098857874, + "protocol_fee": 77621098857874, "congestion_multiplier": 4903583827, "prover_cost": 16837760639495, "sequencer_cost": 3046812705617 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 892727011, + "protocol_fee": 892727011, "congestion_multiplier": 4903583827, "prover_cost": 193652550, "sequencer_cost": 35041658 @@ -30188,13 +30188,13 @@ "slot_of_change": 335 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 76343013863570, + "protocol_fee": 76343013863570, "congestion_multiplier": 4819344101, "prover_cost": 16925775181993, "sequencer_cost": 3062739041197 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 873461874, + "protocol_fee": 873461874, "congestion_multiplier": 4819344101, "prover_cost": 193652550, "sequencer_cost": 35041658 @@ -30242,13 +30242,13 @@ "slot_of_change": 340 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 77712230052699, + "protocol_fee": 77712230052699, "congestion_multiplier": 4896397229, "prover_cost": 16888621422619, "sequencer_cost": 3056016024488 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 891083478, + "protocol_fee": 891083478, "congestion_multiplier": 4896397229, "prover_cost": 193652550, "sequencer_cost": 35041658 @@ -30296,13 +30296,13 @@ "slot_of_change": 340 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 78807524889478, + "protocol_fee": 78807524889478, "congestion_multiplier": 4951708896, "prover_cost": 16886933679306, "sequencer_cost": 3055710625339 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 903732936, + "protocol_fee": 903732936, "congestion_multiplier": 4951708896, "prover_cost": 193652550, "sequencer_cost": 35041658 @@ -30350,13 +30350,13 @@ "slot_of_change": 340 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 79806369435308, + "protocol_fee": 79806369435308, "congestion_multiplier": 4932733376, "prover_cost": 16985880600369, "sequencer_cost": 3306969653938 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 914912669, + "protocol_fee": 914912669, "congestion_multiplier": 4932733376, "prover_cost": 194728785, "sequencer_cost": 37911616 @@ -30404,13 +30404,13 @@ "slot_of_change": 340 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 79143815651921, + "protocol_fee": 79143815651921, "congestion_multiplier": 4918413972, "prover_cost": 16906421207017, "sequencer_cost": 3291499758162 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 911581397, + "protocol_fee": 911581397, "congestion_multiplier": 4918413972, "prover_cost": 194728785, "sequencer_cost": 37911616 @@ -30458,13 +30458,13 @@ "slot_of_change": 340 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 78802577633810, + "protocol_fee": 78802577633810, "congestion_multiplier": 4887473767, "prover_cost": 16967504320977, "sequencer_cost": 3303391988479 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 904383456, + "protocol_fee": 904383456, "congestion_multiplier": 4887473767, "prover_cost": 194728785, "sequencer_cost": 37911616 @@ -30512,13 +30512,13 @@ "slot_of_change": 345 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 79927778239912, + "protocol_fee": 79927778239912, "congestion_multiplier": 4940221727, "prover_cost": 16979390485518, "sequencer_cost": 3305706097848 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 916654762, + "protocol_fee": 916654762, "congestion_multiplier": 4940221727, "prover_cost": 194728785, "sequencer_cost": 37911616 @@ -30566,13 +30566,13 @@ "slot_of_change": 345 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 80640798240120, + "protocol_fee": 80640798240120, "congestion_multiplier": 4965433013, "prover_cost": 17021946323498, "sequencer_cost": 3313991265283 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 922519926, + "protocol_fee": 922519926, "congestion_multiplier": 4965433013, "prover_cost": 194728785, "sequencer_cost": 37911616 @@ -30620,13 +30620,13 @@ "slot_of_change": 345 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 79950275678268, + "protocol_fee": 79950275678268, "congestion_multiplier": 4884763345, "prover_cost": 17173028685087, "sequencer_cost": 3407446527293 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 907943633, + "protocol_fee": 907943633, "congestion_multiplier": 4884763345, "prover_cost": 195022993, "sequencer_cost": 38696169 @@ -30674,13 +30674,13 @@ "slot_of_change": 345 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 68561877347763, + "protocol_fee": 68561877347763, "congestion_multiplier": 4347394589, "prover_cost": 17090992671546, "sequencer_cost": 3391169064850 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 782350258, + "protocol_fee": 782350258, "congestion_multiplier": 4347394589, "prover_cost": 195022993, "sequencer_cost": 38696169 @@ -30728,13 +30728,13 @@ "slot_of_change": 345 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 79682180211033, + "protocol_fee": 79682180211033, "congestion_multiplier": 4861921242, "prover_cost": 17216675447608, "sequencer_cost": 3416106852277 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 902604996, + "protocol_fee": 902604996, "congestion_multiplier": 4861921242, "prover_cost": 195022993, "sequencer_cost": 38696169 @@ -30782,13 +30782,13 @@ "slot_of_change": 350 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 80825806239327, + "protocol_fee": 80825806239327, "congestion_multiplier": 4878175248, "prover_cost": 17390581818481, "sequencer_cost": 3450613092869 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 906403869, + "protocol_fee": 906403869, "congestion_multiplier": 4878175248, "prover_cost": 195022993, "sequencer_cost": 38696169 @@ -30836,13 +30836,13 @@ "slot_of_change": 350 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 79830710382707, + "protocol_fee": 79830710382707, "congestion_multiplier": 4868732654, "prover_cost": 17218399177853, "sequencer_cost": 3416448872240 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 904196953, + "protocol_fee": 904196953, "congestion_multiplier": 4868732654, "prover_cost": 195022993, "sequencer_cost": 38696169 @@ -30890,13 +30890,13 @@ "slot_of_change": 350 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 81820973539040, + "protocol_fee": 81820973539040, "congestion_multiplier": 4930835515, "prover_cost": 17259468158673, "sequencer_cost": 3555692700019 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 927388206, + "protocol_fee": 927388206, "congestion_multiplier": 4930835515, "prover_cost": 195624991, "sequencer_cost": 40301494 @@ -30944,13 +30944,13 @@ "slot_of_change": 350 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 80617092710654, + "protocol_fee": 80617092710654, "congestion_multiplier": 4888877784, "prover_cost": 17188994596879, "sequencer_cost": 3541174157100 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 917489266, + "protocol_fee": 917489266, "congestion_multiplier": 4888877784, "prover_cost": 195624991, "sequencer_cost": 40301494 @@ -30998,13 +30998,13 @@ "slot_of_change": 350 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 82191751191532, + "protocol_fee": 82191751191532, "congestion_multiplier": 4927964443, "prover_cost": 17350353339685, "sequencer_cost": 3574416323001 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 926710844, + "protocol_fee": 926710844, "congestion_multiplier": 4927964443, "prover_cost": 195624991, "sequencer_cost": 40301494 @@ -31052,13 +31052,13 @@ "slot_of_change": 355 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 81754868389611, + "protocol_fee": 81754868389611, "congestion_multiplier": 4916853257, "prover_cost": 17307086337616, "sequencer_cost": 3565502713265 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 924089421, + "protocol_fee": 924089421, "congestion_multiplier": 4916853257, "prover_cost": 195624991, "sequencer_cost": 40301494 @@ -31106,13 +31106,13 @@ "slot_of_change": 355 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 79733392925979, + "protocol_fee": 79733392925979, "congestion_multiplier": 4790972590, "prover_cost": 17439628882898, "sequencer_cost": 3592808338002 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 894390837, + "protocol_fee": 894390837, "congestion_multiplier": 4790972590, "prover_cost": 195624991, "sequencer_cost": 40301494 @@ -31160,13 +31160,13 @@ "slot_of_change": 355 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 79253371509240, + "protocol_fee": 79253371509240, "congestion_multiplier": 4825095514, "prover_cost": 17294847849249, "sequencer_cost": 3424470458761 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 893540235, + "protocol_fee": 893540235, "congestion_multiplier": 4825095514, "prover_cost": 194990347, "sequencer_cost": 38609110 @@ -31214,13 +31214,13 @@ "slot_of_change": 355 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 80236971871555, + "protocol_fee": 80236971871555, "congestion_multiplier": 4893479947, "prover_cost": 17201957538527, "sequencer_cost": 3406077690710 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 909514801, + "protocol_fee": 909514801, "congestion_multiplier": 4893479947, "prover_cost": 194990347, "sequencer_cost": 38609110 @@ -31268,13 +31268,13 @@ "slot_of_change": 355 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 80951962136814, + "protocol_fee": 80951962136814, "congestion_multiplier": 4926996090, "prover_cost": 17207120270577, "sequencer_cost": 3407099938696 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 917344154, + "protocol_fee": 917344154, "congestion_multiplier": 4926996090, "prover_cost": 194990347, "sequencer_cost": 38609110 @@ -31322,13 +31322,13 @@ "slot_of_change": 360 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 80648294635138, + "protocol_fee": 80648294635138, "congestion_multiplier": 4913829753, "prover_cost": 17200241362207, "sequencer_cost": 3405737878809 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 914268505, + "protocol_fee": 914268505, "congestion_multiplier": 4913829753, "prover_cost": 194990347, "sequencer_cost": 38609110 @@ -31376,13 +31376,13 @@ "slot_of_change": 360 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 80259466167895, + "protocol_fee": 80259466167895, "congestion_multiplier": 4902360374, "prover_cost": 17167623376171, "sequencer_cost": 3399279346732 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 911589264, + "protocol_fee": 911589264, "congestion_multiplier": 4902360374, "prover_cost": 194990347, "sequencer_cost": 38609110 @@ -31430,13 +31430,13 @@ "slot_of_change": 360 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 78713301788223, + "protocol_fee": 78713301788223, "congestion_multiplier": 4881000568, "prover_cost": 17030049340949, "sequencer_cost": 3251653902322 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 898676772, + "protocol_fee": 898676772, "congestion_multiplier": 4881000568, "prover_cost": 194433589, "sequencer_cost": 37124422 @@ -31484,13 +31484,13 @@ "slot_of_change": 360 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 79849368932209, + "protocol_fee": 79849368932209, "congestion_multiplier": 4939770533, "prover_cost": 17018138078684, "sequencer_cost": 3249379610471 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 912285428, + "protocol_fee": 912285428, "congestion_multiplier": 4939770533, "prover_cost": 194433589, "sequencer_cost": 37124422 @@ -31538,13 +31538,13 @@ "slot_of_change": 360 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 81290996807197, + "protocol_fee": 81290996807197, "congestion_multiplier": 4990444876, "prover_cost": 17105375632148, "sequencer_cost": 3266036422526 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 924019478, + "protocol_fee": 924019478, "congestion_multiplier": 4990444876, "prover_cost": 194433589, "sequencer_cost": 37124422 @@ -31592,13 +31592,13 @@ "slot_of_change": 365 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 78634138093875, + "protocol_fee": 78634138093875, "congestion_multiplier": 4872375743, "prover_cost": 17050814224272, "sequencer_cost": 3255618671451 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 896679624, + "protocol_fee": 896679624, "congestion_multiplier": 4872375743, "prover_cost": 194433589, "sequencer_cost": 37124422 @@ -31646,13 +31646,13 @@ "slot_of_change": 365 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 73810372446654, + "protocol_fee": 73810372446654, "congestion_multiplier": 4607202158, "prover_cost": 17181394015122, "sequencer_cost": 3280551088144 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 835276556, + "protocol_fee": 835276556, "congestion_multiplier": 4607202158, "prover_cost": 194433589, "sequencer_cost": 37124422 @@ -31700,13 +31700,13 @@ "slot_of_change": 365 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 79406511824924, + "protocol_fee": 79406511824924, "congestion_multiplier": 4913488294, "prover_cost": 17023180664941, "sequencer_cost": 3267288069881 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 907321832, + "protocol_fee": 907321832, "congestion_multiplier": 4913488294, "prover_cost": 194511799, "sequencer_cost": 37332981 @@ -31754,13 +31754,13 @@ "slot_of_change": 365 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 78922739133386, + "protocol_fee": 78922739133386, "congestion_multiplier": 4892368549, "prover_cost": 17011273373559, "sequencer_cost": 3265002683158 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 902425329, + "protocol_fee": 902425329, "congestion_multiplier": 4892368549, "prover_cost": 194511799, "sequencer_cost": 37332981 @@ -31808,13 +31808,13 @@ "slot_of_change": 365 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 73382174393033, + "protocol_fee": 73382174393033, "congestion_multiplier": 4621648362, "prover_cost": 16999373814268, "sequencer_cost": 3262718780469 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 839660267, + "protocol_fee": 839660267, "congestion_multiplier": 4621648362, "prover_cost": 194511799, "sequencer_cost": 37332981 @@ -31862,13 +31862,13 @@ "slot_of_change": 370 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 79332072922004, + "protocol_fee": 79332072922004, "congestion_multiplier": 4894935591, "prover_cost": 17088232746413, "sequencer_cost": 3279773626717 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 903020485, + "protocol_fee": 903020485, "congestion_multiplier": 4894935591, "prover_cost": 194511799, "sequencer_cost": 37332981 @@ -31916,13 +31916,13 @@ "slot_of_change": 370 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 82197235877229, + "protocol_fee": 82197235877229, "congestion_multiplier": 4995249290, "prover_cost": 17260841280530, "sequencer_cost": 3312902676768 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 926277692, + "protocol_fee": 926277692, "congestion_multiplier": 4995249290, "prover_cost": 194511799, "sequencer_cost": 37332981 @@ -31970,13 +31970,13 @@ "slot_of_change": 370 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 78934097352572, + "protocol_fee": 78934097352572, "congestion_multiplier": 4915429627, "prover_cost": 17058916749995, "sequencer_cost": 3100837066029 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 896354692, + "protocol_fee": 896354692, "congestion_multiplier": 4915429627, "prover_cost": 193716538, "sequencer_cost": 35212284 @@ -32024,13 +32024,13 @@ "slot_of_change": 370 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 81778306297979, + "protocol_fee": 81778306297979, "congestion_multiplier": 5052861981, "prover_cost": 17074284867129, "sequencer_cost": 3103630562706 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 927816919, + "protocol_fee": 927816919, "congestion_multiplier": 5052861981, "prover_cost": 193716538, "sequencer_cost": 35212284 @@ -32078,13 +32078,13 @@ "slot_of_change": 370 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 81339536207341, + "protocol_fee": 81339536207341, "congestion_multiplier": 5019023404, "prover_cost": 17125662546103, "sequencer_cost": 3112969597163 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 920070293, + "protocol_fee": 920070293, "congestion_multiplier": 5019023404, "prover_cost": 193716538, "sequencer_cost": 35212284 @@ -32132,13 +32132,13 @@ "slot_of_change": 375 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 80166700143608, + "protocol_fee": 80166700143608, "congestion_multiplier": 4940079293, "prover_cost": 17216912443699, "sequencer_cost": 3129556293076 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 901997711, + "protocol_fee": 901997711, "congestion_multiplier": 4940079293, "prover_cost": 193716538, "sequencer_cost": 35212284 @@ -32186,13 +32186,13 @@ "slot_of_change": 375 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 78409097943826, + "protocol_fee": 78409097943826, "congestion_multiplier": 4879515331, "prover_cost": 17102327192295, "sequencer_cost": 3108727878237 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 888132874, + "protocol_fee": 888132874, "congestion_multiplier": 4879515331, "prover_cost": 193716538, "sequencer_cost": 35212284 @@ -32240,13 +32240,13 @@ "slot_of_change": 375 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 80881920861353, + "protocol_fee": 80881920861353, "congestion_multiplier": 4932742056, "prover_cost": 17269171571876, "sequencer_cost": 3297120272950 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 910645422, + "protocol_fee": 910645422, "congestion_multiplier": 4932742056, "prover_cost": 194432722, "sequencer_cost": 37122109 @@ -32294,13 +32294,13 @@ "slot_of_change": 375 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 77724837430898, + "protocol_fee": 77724837430898, "congestion_multiplier": 4798886231, "prover_cost": 17179837234300, "sequencer_cost": 3280064095456 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 879650459, + "protocol_fee": 879650459, "congestion_multiplier": 4798886231, "prover_cost": 194432722, "sequencer_cost": 37122109 @@ -32348,13 +32348,13 @@ "slot_of_change": 375 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 80136292719423, + "protocol_fee": 80136292719423, "congestion_multiplier": 4935548795, "prover_cost": 17097769415586, "sequencer_cost": 3264395279629 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 911295336, + "protocol_fee": 911295336, "congestion_multiplier": 4935548795, "prover_cost": 194432722, "sequencer_cost": 37122109 @@ -32402,13 +32402,13 @@ "slot_of_change": 380 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 80464238589482, + "protocol_fee": 80464238589482, "congestion_multiplier": 4912137616, "prover_cost": 17270475415077, "sequencer_cost": 3297369209491 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 905874364, + "protocol_fee": 905874364, "congestion_multiplier": 4912137616, "prover_cost": 194432722, "sequencer_cost": 37122109 @@ -32456,13 +32456,13 @@ "slot_of_change": 380 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 80943095581777, + "protocol_fee": 80943095581777, "congestion_multiplier": 4944470687, "prover_cost": 17230845431298, "sequencer_cost": 3289802846369 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 913361243, + "protocol_fee": 913361243, "congestion_multiplier": 4944470687, "prover_cost": 194432722, "sequencer_cost": 37122109 @@ -32510,13 +32510,13 @@ "slot_of_change": 380 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 79898323174115, + "protocol_fee": 79898323174115, "congestion_multiplier": 4971601664, "prover_cost": 17093015401811, "sequencer_cost": 3024390612633 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 903735766, + "protocol_fee": 903735766, "congestion_multiplier": 4971601664, "prover_cost": 193340345, "sequencer_cost": 34209103 @@ -32564,13 +32564,13 @@ "slot_of_change": 380 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 79505115974828, + "protocol_fee": 79505115974828, "congestion_multiplier": 4915301917, "prover_cost": 17253472730388, "sequencer_cost": 3052781486149 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 890924789, + "protocol_fee": 890924789, "congestion_multiplier": 4915301917, "prover_cost": 193340345, "sequencer_cost": 34209103 @@ -32618,13 +32618,13 @@ "slot_of_change": 380 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 81062581686017, + "protocol_fee": 81062581686017, "congestion_multiplier": 4995593430, "prover_cost": 17237959016456, "sequencer_cost": 3050036532746 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 909195079, + "protocol_fee": 909195079, "congestion_multiplier": 4995593430, "prover_cost": 193340345, "sequencer_cost": 34209103 @@ -32672,13 +32672,13 @@ "slot_of_change": 385 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 81195552294968, + "protocol_fee": 81195552294968, "congestion_multiplier": 4991741823, "prover_cost": 17282895300830, "sequencer_cost": 3057987433944 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 908318648, + "protocol_fee": 908318648, "congestion_multiplier": 4991741823, "prover_cost": 193340345, "sequencer_cost": 34209103 @@ -32726,13 +32726,13 @@ "slot_of_change": 385 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 80586609966573, + "protocol_fee": 80586609966573, "congestion_multiplier": 4978048041, "prover_cost": 17212326136587, "sequencer_cost": 3045501122263 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 905202635, + "protocol_fee": 905202635, "congestion_multiplier": 4978048041, "prover_cost": 193340345, "sequencer_cost": 34209103 @@ -32780,13 +32780,13 @@ "slot_of_change": 385 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 79420590774433, + "protocol_fee": 79420590774433, "congestion_multiplier": 4908290537, "prover_cost": 17181848367382, "sequencer_cost": 3139207628241 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 895762685, + "protocol_fee": 895762685, "congestion_multiplier": 4908290537, "prover_cost": 193789274, "sequencer_cost": 35406247 @@ -32834,13 +32834,13 @@ "slot_of_change": 385 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 81088610102805, + "protocol_fee": 81088610102805, "congestion_multiplier": 4953662123, "prover_cost": 17341390337466, "sequencer_cost": 3168356725521 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 906161650, + "protocol_fee": 906161650, "congestion_multiplier": 4953662123, "prover_cost": 193789274, "sequencer_cost": 35406247 @@ -32888,13 +32888,13 @@ "slot_of_change": 385 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 82700760868380, + "protocol_fee": 82700760868380, "congestion_multiplier": 5002023956, "prover_cost": 17472434896927, "sequencer_cost": 3192299206674 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 917245965, + "protocol_fee": 917245965, "congestion_multiplier": 5002023956, "prover_cost": 193789274, "sequencer_cost": 35406247 @@ -32942,13 +32942,13 @@ "slot_of_change": 390 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 82300953068415, + "protocol_fee": 82300953068415, "congestion_multiplier": 4998607107, "prover_cost": 17402824496451, "sequencer_cost": 3179581046467 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 916462839, + "protocol_fee": 916462839, "congestion_multiplier": 4998607107, "prover_cost": 193789274, "sequencer_cost": 35406247 @@ -32996,13 +32996,13 @@ "slot_of_change": 390 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 81976862860868, + "protocol_fee": 81976862860868, "congestion_multiplier": 4982462678, "prover_cost": 17404565655263, "sequencer_cost": 3179899164688 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 912762608, + "protocol_fee": 912762608, "congestion_multiplier": 4982462678, "prover_cost": 193789274, "sequencer_cost": 35406247 @@ -33050,13 +33050,13 @@ "slot_of_change": 390 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 86258935113342, + "protocol_fee": 86258935113342, "congestion_multiplier": 5015962222, "prover_cost": 17641465952158, "sequencer_cost": 3837554605378 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 961017093, + "protocol_fee": 961017093, "congestion_multiplier": 5015962222, "prover_cost": 196544860, "sequencer_cost": 42754476 @@ -33104,13 +33104,13 @@ "slot_of_change": 390 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 85784371953158, + "protocol_fee": 85784371953158, "congestion_multiplier": 5015035213, "prover_cost": 17548460195070, "sequencer_cost": 3817323028682 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 960795260, + "protocol_fee": 960795260, "congestion_multiplier": 5015035213, "prover_cost": 196544860, "sequencer_cost": 42754476 @@ -33158,13 +33158,13 @@ "slot_of_change": 390 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 85083070552016, + "protocol_fee": 85083070552016, "congestion_multiplier": 4961105788, "prover_cost": 17641963173246, "sequencer_cost": 3837662766065 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 947889984, + "protocol_fee": 947889984, "congestion_multiplier": 4961105788, "prover_cost": 196544860, "sequencer_cost": 42754476 @@ -33212,13 +33212,13 @@ "slot_of_change": 395 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 83227375829826, + "protocol_fee": 83227375829826, "congestion_multiplier": 4880524557, "prover_cost": 17615540082116, "sequencer_cost": 3831914941291 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 928606949, + "protocol_fee": 928606949, "congestion_multiplier": 4880524557, "prover_cost": 196544860, "sequencer_cost": 42754476 @@ -33266,13 +33266,13 @@ "slot_of_change": 395 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 83093670860515, + "protocol_fee": 83093670860515, "congestion_multiplier": 4851819367, "prover_cost": 17718307334986, "sequencer_cost": 3854269939770 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 921737816, + "protocol_fee": 921737816, "congestion_multiplier": 4851819367, "prover_cost": 196544860, "sequencer_cost": 42754476 @@ -33320,13 +33320,13 @@ "slot_of_change": 395 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 84469602054185, + "protocol_fee": 84469602054185, "congestion_multiplier": 4961630101, "prover_cost": 17679610636182, "sequencer_cost": 3642319980508 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 934658174, + "protocol_fee": 934658174, "congestion_multiplier": 4961630101, "prover_cost": 195625316, "sequencer_cost": 40302358 @@ -33374,13 +33374,13 @@ "slot_of_change": 395 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 83883345923252, + "protocol_fee": 83883345923252, "congestion_multiplier": 4913676835, "prover_cost": 17772026580096, "sequencer_cost": 3661359338669 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 923344672, + "protocol_fee": 923344672, "congestion_multiplier": 4913676835, "prover_cost": 195625316, "sequencer_cost": 40302358 @@ -33428,13 +33428,13 @@ "slot_of_change": 395 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 85506861256764, + "protocol_fee": 85506861256764, "congestion_multiplier": 4976657691, "prover_cost": 17829079712924, "sequencer_cost": 3673113317301 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 938203599, + "protocol_fee": 938203599, "congestion_multiplier": 4976657691, "prover_cost": 195625316, "sequencer_cost": 40302358 @@ -33482,13 +33482,13 @@ "slot_of_change": 400 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 85263344463690, + "protocol_fee": 85263344463690, "congestion_multiplier": 4949470809, "prover_cost": 17900684008624, "sequencer_cost": 3687865099017 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 931789461, + "protocol_fee": 931789461, "congestion_multiplier": 4949470809, "prover_cost": 195625316, "sequencer_cost": 40302358 @@ -33536,13 +33536,13 @@ "slot_of_change": 400 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 84958536318427, + "protocol_fee": 84958536318427, "congestion_multiplier": 4912133041, "prover_cost": 18006925878228, "sequencer_cost": 3709752848266 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 922980448, + "protocol_fee": 922980448, "congestion_multiplier": 4912133041, "prover_cost": 195625316, "sequencer_cost": 40302358 @@ -33590,13 +33590,13 @@ "slot_of_change": 400 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 80731738810165, + "protocol_fee": 80731738810165, "congestion_multiplier": 4791901605, "prover_cost": 17821030258986, "sequencer_cost": 3469537708901 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 882147879, + "protocol_fee": 882147879, "congestion_multiplier": 4791901605, "prover_cost": 194728669, "sequencer_cost": 37911302 @@ -33644,13 +33644,13 @@ "slot_of_change": 400 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 82779169581585, + "protocol_fee": 82779169581585, "congestion_multiplier": 4901675878, "prover_cost": 17758874459230, "sequencer_cost": 3457436731127 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 907685763, + "protocol_fee": 907685763, "congestion_multiplier": 4901675878, "prover_cost": 194728669, "sequencer_cost": 37911302 @@ -33698,13 +33698,13 @@ "slot_of_change": 400 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 83961689197627, + "protocol_fee": 83961689197627, "congestion_multiplier": 4930897376, "prover_cost": 17878662336757, "sequencer_cost": 3480757973059 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 914483851, + "protocol_fee": 914483851, "congestion_multiplier": 4930897376, "prover_cost": 194728669, "sequencer_cost": 37911302 @@ -33752,13 +33752,13 @@ "slot_of_change": 405 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 83817841861960, + "protocol_fee": 83817841861960, "congestion_multiplier": 4926124546, "prover_cost": 17869728850500, "sequencer_cost": 3479018732006 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 913373500, + "protocol_fee": 913373500, "congestion_multiplier": 4926124546, "prover_cost": 194728669, "sequencer_cost": 37911302 @@ -33806,13 +33806,13 @@ "slot_of_change": 405 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 82772878062135, + "protocol_fee": 82772878062135, "congestion_multiplier": 4867871690, "prover_cost": 17912720859986, "sequencer_cost": 3487388753038 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 899821557, + "protocol_fee": 899821557, "congestion_multiplier": 4867871690, "prover_cost": 194728669, "sequencer_cost": 37911302 @@ -33860,13 +33860,13 @@ "slot_of_change": 405 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 83870281936046, + "protocol_fee": 83870281936046, "congestion_multiplier": 4900920068, "prover_cost": 17882309967152, "sequencer_cost": 3617818338317 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 916127754, + "protocol_fee": 916127754, "congestion_multiplier": 4900920068, "prover_cost": 195331172, "sequencer_cost": 39517976 @@ -33914,13 +33914,13 @@ "slot_of_change": 405 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 85924923939484, + "protocol_fee": 85924923939484, "congestion_multiplier": 4989290449, "prover_cost": 17914556707491, "sequencer_cost": 3624342263289 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 936881463, + "protocol_fee": 936881463, "congestion_multiplier": 4989290449, "prover_cost": 195331172, "sequencer_cost": 39517976 @@ -33968,13 +33968,13 @@ "slot_of_change": 405 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 82139473199089, + "protocol_fee": 82139473199089, "congestion_multiplier": 4805913860, "prover_cost": 17950457659028, "sequencer_cost": 3631605481580 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 893815627, + "protocol_fee": 893815627, "congestion_multiplier": 4805913860, "prover_cost": 195331172, "sequencer_cost": 39517976 @@ -34022,13 +34022,13 @@ "slot_of_change": 410 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 83083837637834, + "protocol_fee": 83083837637834, "congestion_multiplier": 4848900604, "prover_cost": 17954049563836, "sequencer_cost": 3632332169525 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 903911027, + "protocol_fee": 903911027, "congestion_multiplier": 4848900604, "prover_cost": 195331172, "sequencer_cost": 39517976 @@ -34076,13 +34076,13 @@ "slot_of_change": 410 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 85783081556893, + "protocol_fee": 85783081556893, "congestion_multiplier": 5005735976, "prover_cost": 17811557171947, "sequencer_cost": 3603504149577 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 940743681, + "protocol_fee": 940743681, "congestion_multiplier": 5005735976, "prover_cost": 195331172, "sequencer_cost": 39517976 @@ -34130,13 +34130,13 @@ "slot_of_change": 410 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 83127031230202, + "protocol_fee": 83127031230202, "congestion_multiplier": 4968018373, "prover_cost": 17680930059992, "sequencer_cost": 3268325580251 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 911889401, + "protocol_fee": 911889401, "congestion_multiplier": 4968018373, "prover_cost": 193956797, "sequencer_cost": 35852976 @@ -34184,13 +34184,13 @@ "slot_of_change": 410 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 83112996390324, + "protocol_fee": 83112996390324, "congestion_multiplier": 4933229063, "prover_cost": 17834305841329, "sequencer_cost": 3296677142518 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 903894478, + "protocol_fee": 903894478, "congestion_multiplier": 4933229063, "prover_cost": 193956797, "sequencer_cost": 35852976 @@ -34238,13 +34238,13 @@ "slot_of_change": 410 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 82036751798232, + "protocol_fee": 82036751798232, "congestion_multiplier": 4879190947, "prover_cost": 17848585709044, "sequencer_cost": 3299316780635 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 891475990, + "protocol_fee": 891475990, "congestion_multiplier": 4879190947, "prover_cost": 193956797, "sequencer_cost": 35852976 @@ -34292,13 +34292,13 @@ "slot_of_change": 415 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 83353409932994, + "protocol_fee": 83353409932994, "congestion_multiplier": 4936720407, "prover_cost": 17870031151454, "sequencer_cost": 3303280977528 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 904696823, + "protocol_fee": 904696823, "congestion_multiplier": 4936720407, "prover_cost": 193956797, "sequencer_cost": 35852976 @@ -34346,13 +34346,13 @@ "slot_of_change": 415 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 81965898698534, + "protocol_fee": 81965898698534, "congestion_multiplier": 4874673210, "prover_cost": 17853963196995, "sequencer_cost": 3300310811004 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 890437770, + "protocol_fee": 890437770, "congestion_multiplier": 4874673210, "prover_cost": 193956797, "sequencer_cost": 35852976 @@ -34400,13 +34400,13 @@ "slot_of_change": 415 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 83955884406880, + "protocol_fee": 83955884406880, "congestion_multiplier": 4976951645, "prover_cost": 17900341584832, "sequencer_cost": 3210270761245 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 907678130, + "protocol_fee": 907678130, "congestion_multiplier": 4976951645, "prover_cost": 193527216, "sequencer_cost": 34707425 @@ -34454,13 +34454,13 @@ "slot_of_change": 415 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 83404621991113, + "protocol_fee": 83404621991113, "congestion_multiplier": 4957949937, "prover_cost": 17868179631663, "sequencer_cost": 3204502794339 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 903341282, + "protocol_fee": 903341282, "congestion_multiplier": 4957949937, "prover_cost": 193527216, "sequencer_cost": 34707425 @@ -34508,13 +34508,13 @@ "slot_of_change": 415 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 83521520822728, + "protocol_fee": 83521520822728, "congestion_multiplier": 4934167152, "prover_cost": 18001391353720, "sequencer_cost": 3228393159466 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 897913227, + "protocol_fee": 897913227, "congestion_multiplier": 4934167152, "prover_cost": 193527216, "sequencer_cost": 34707425 @@ -34562,13 +34562,13 @@ "slot_of_change": 420 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 88866916019282, + "protocol_fee": 88866916019282, "congestion_multiplier": 5172977887, "prover_cost": 18057370695918, "sequencer_cost": 3238432568192 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 952418109, + "protocol_fee": 952418109, "congestion_multiplier": 5172977887, "prover_cost": 193527216, "sequencer_cost": 34707425 @@ -34616,13 +34616,13 @@ "slot_of_change": 420 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 88241435889065, + "protocol_fee": 88241435889065, "congestion_multiplier": 5102170582, "prover_cost": 18239769187683, "sequencer_cost": 3271144153176 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 936257430, + "protocol_fee": 936257430, "congestion_multiplier": 5102170582, "prover_cost": 193527216, "sequencer_cost": 34707425 @@ -34670,13 +34670,13 @@ "slot_of_change": 420 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 88853423245227, + "protocol_fee": 88853423245227, "congestion_multiplier": 5032332600, "prover_cost": 18355607046810, "sequencer_cost": 3679634619615 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 944824742, + "protocol_fee": 944824742, "congestion_multiplier": 5032332600, "prover_cost": 195184733, "sequencer_cost": 39127472 @@ -34724,13 +34724,13 @@ "slot_of_change": 420 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 88733748356629, + "protocol_fee": 88733748356629, "congestion_multiplier": 4998713088, "prover_cost": 18485002679210, "sequencer_cost": 3705573758941 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 936947280, + "protocol_fee": 936947280, "congestion_multiplier": 4998713088, "prover_cost": 195184733, "sequencer_cost": 39127472 @@ -34778,13 +34778,13 @@ "slot_of_change": 420 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 88419612661550, + "protocol_fee": 88419612661550, "congestion_multiplier": 4968618345, "prover_cost": 18559240795414, "sequencer_cost": 3720455813334 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 929895715, + "protocol_fee": 929895715, "congestion_multiplier": 4968618345, "prover_cost": 195184733, "sequencer_cost": 39127472 @@ -34832,13 +34832,13 @@ "slot_of_change": 425 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 87474775191701, + "protocol_fee": 87474775191701, "congestion_multiplier": 4898726847, "prover_cost": 18690071396487, "sequencer_cost": 3746682611924 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 913519284, + "protocol_fee": 913519284, "congestion_multiplier": 4898726847, "prover_cost": 195184733, "sequencer_cost": 39127472 @@ -34886,13 +34886,13 @@ "slot_of_change": 425 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 89853486888252, + "protocol_fee": 89853486888252, "congestion_multiplier": 4994332810, "prover_cost": 18738793334689, "sequencer_cost": 3756449596480 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 935920928, + "protocol_fee": 935920928, "congestion_multiplier": 4994332810, "prover_cost": 195184733, "sequencer_cost": 39127472 @@ -34940,13 +34940,13 @@ "slot_of_change": 425 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 81483753856400, + "protocol_fee": 81483753856400, "congestion_multiplier": 4658280601, "prover_cost": 18701123336581, "sequencer_cost": 3572661209432 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 847213397, + "protocol_fee": 847213397, "congestion_multiplier": 4658280601, "prover_cost": 194441732, "sequencer_cost": 37146134 @@ -34994,13 +34994,13 @@ "slot_of_change": 425 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 84653937976348, + "protocol_fee": 84653937976348, "congestion_multiplier": 4809729888, "prover_cost": 18656349156548, "sequencer_cost": 3564107553413 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 882287214, + "protocol_fee": 882287214, "congestion_multiplier": 4809729888, "prover_cost": 194441732, "sequencer_cost": 37146134 @@ -35048,13 +35048,13 @@ "slot_of_change": 425 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 85604795463784, + "protocol_fee": 85604795463784, "congestion_multiplier": 4866005335, "prover_cost": 18591281432147, "sequencer_cost": 3551677020190 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 895319925, + "protocol_fee": 895319925, "congestion_multiplier": 4866005335, "prover_cost": 194441732, "sequencer_cost": 37146134 @@ -35102,13 +35102,13 @@ "slot_of_change": 430 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 87457248901238, + "protocol_fee": 87457248901238, "congestion_multiplier": 4920041542, "prover_cost": 18731770259833, "sequencer_cost": 3578515995368 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 907834055, + "protocol_fee": 907834055, "congestion_multiplier": 4920041542, "prover_cost": 194441732, "sequencer_cost": 37146134 @@ -35156,13 +35156,13 @@ "slot_of_change": 430 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 88148229446950, + "protocol_fee": 88148229446950, "congestion_multiplier": 4923355547, "prover_cost": 18863818395164, "sequencer_cost": 3603742461307 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 908601538, + "protocol_fee": 908601538, "congestion_multiplier": 4923355547, "prover_cost": 194441732, "sequencer_cost": 37146134 @@ -35210,13 +35210,13 @@ "slot_of_change": 430 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 92455258897058, + "protocol_fee": 92455258897058, "congestion_multiplier": 5041582565, "prover_cost": 18962489200872, "sequencer_cost": 3913514800695 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 953949848, + "protocol_fee": 953949848, "congestion_multiplier": 5041582565, "prover_cost": 195654243, "sequencer_cost": 40379497 @@ -35264,13 +35264,13 @@ "slot_of_change": 430 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 93101542132280, + "protocol_fee": 93101542132280, "congestion_multiplier": 5058845395, "prover_cost": 19013827461203, "sequencer_cost": 3924110089083 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 958024458, + "protocol_fee": 958024458, "congestion_multiplier": 5058845395, "prover_cost": 195654243, "sequencer_cost": 40379497 @@ -35318,13 +35318,13 @@ "slot_of_change": 430 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 92591940008242, + "protocol_fee": 92591940008242, "congestion_multiplier": 5032591852, "prover_cost": 19032861982301, "sequencer_cost": 3928038469965 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 951827736, + "protocol_fee": 951827736, "congestion_multiplier": 5032591852, "prover_cost": 195654243, "sequencer_cost": 40379497 @@ -35372,13 +35372,13 @@ "slot_of_change": 435 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 91974827409526, + "protocol_fee": 91974827409526, "congestion_multiplier": 4981280257, "prover_cost": 19149675274944, "sequencer_cost": 3952146620790 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 939716469, + "protocol_fee": 939716469, "congestion_multiplier": 4981280257, "prover_cost": 195654243, "sequencer_cost": 40379497 @@ -35426,13 +35426,13 @@ "slot_of_change": 435 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 91008228424713, + "protocol_fee": 91008228424713, "congestion_multiplier": 4946530132, "prover_cost": 19115269266411, "sequencer_cost": 3945045842923 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 931514267, + "protocol_fee": 931514267, "congestion_multiplier": 4946530132, "prover_cost": 195654243, "sequencer_cost": 40379497 @@ -35480,13 +35480,13 @@ "slot_of_change": 435 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 90163112717283, + "protocol_fee": 90163112717283, "congestion_multiplier": 4957553681, "prover_cost": 19169068126958, "sequencer_cost": 3613468776707 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 913635444, + "protocol_fee": 913635444, "congestion_multiplier": 4957553681, "prover_cost": 194242851, "sequencer_cost": 36615785 @@ -35534,13 +35534,13 @@ "slot_of_change": 435 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 89980177892096, + "protocol_fee": 89980177892096, "congestion_multiplier": 4971641179, "prover_cost": 19062320232270, "sequencer_cost": 3593346244831 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 916887665, + "protocol_fee": 916887665, "congestion_multiplier": 4971641179, "prover_cost": 194242851, "sequencer_cost": 36615785 @@ -35588,13 +35588,13 @@ "slot_of_change": 435 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 88711018574542, + "protocol_fee": 88711018574542, "congestion_multiplier": 4939506847, "prover_cost": 18946745638894, "sequencer_cost": 3571559834465 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 909469177, + "protocol_fee": 909469177, "congestion_multiplier": 4939506847, "prover_cost": 194242851, "sequencer_cost": 36615785 @@ -35642,13 +35642,13 @@ "slot_of_change": 440 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 88603506447400, + "protocol_fee": 88603506447400, "congestion_multiplier": 4938273353, "prover_cost": 18929710448094, "sequencer_cost": 3568348612633 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 909184414, + "protocol_fee": 909184414, "congestion_multiplier": 4938273353, "prover_cost": 194242851, "sequencer_cost": 36615785 @@ -35696,13 +35696,13 @@ "slot_of_change": 440 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 89488323809622, + "protocol_fee": 89488323809622, "congestion_multiplier": 4946178530, "prover_cost": 19080447798493, "sequencer_cost": 3596763385096 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 911009392, + "protocol_fee": 911009392, "congestion_multiplier": 4946178530, "prover_cost": 194242851, "sequencer_cost": 36615785 @@ -35750,13 +35750,13 @@ "slot_of_change": 440 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 89658121739203, + "protocol_fee": 89658121739203, "congestion_multiplier": 4958672816, "prover_cost": 19076496865675, "sequencer_cost": 3572033582294 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 912464064, + "protocol_fee": 912464064, "congestion_multiplier": 4958672816, "prover_cost": 194144351, "sequencer_cost": 36353118 @@ -35804,13 +35804,13 @@ "slot_of_change": 440 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 89251075602394, + "protocol_fee": 89251075602394, "congestion_multiplier": 4952916625, "prover_cost": 19017542785574, "sequencer_cost": 3560994555819 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 911137277, + "protocol_fee": 911137277, "congestion_multiplier": 4952916625, "prover_cost": 194144351, "sequencer_cost": 36353118 @@ -35858,13 +35858,13 @@ "slot_of_change": 440 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 87686294990873, + "protocol_fee": 87686294990873, "congestion_multiplier": 4887496076, "prover_cost": 18998545539024, "sequencer_cost": 3557437361691 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 896058006, + "protocol_fee": 896058006, "congestion_multiplier": 4887496076, "prover_cost": 194144351, "sequencer_cost": 36353118 @@ -35912,13 +35912,13 @@ "slot_of_change": 445 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 86453373922146, + "protocol_fee": 86453373922146, "congestion_multiplier": 4822486572, "prover_cost": 19049982269215, "sequencer_cost": 3567068780336 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 881073480, + "protocol_fee": 881073480, "congestion_multiplier": 4822486572, "prover_cost": 194144351, "sequencer_cost": 36353118 @@ -35966,13 +35966,13 @@ "slot_of_change": 445 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 88789772596877, + "protocol_fee": 88789772596877, "congestion_multiplier": 4910871104, "prover_cost": 19122648345688, "sequencer_cost": 3580675349052 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 901445891, + "protocol_fee": 901445891, "congestion_multiplier": 4910871104, "prover_cost": 194144351, "sequencer_cost": 36353118 @@ -36020,13 +36020,13 @@ "slot_of_change": 445 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 90490528044884, + "protocol_fee": 90490528044884, "congestion_multiplier": 4948342002, "prover_cost": 19224177625582, "sequencer_cost": 3694436837805 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 915681164, + "protocol_fee": 915681164, "congestion_multiplier": 4948342002, "prover_cost": 194531049, "sequencer_cost": 37384313 @@ -36074,13 +36074,13 @@ "slot_of_change": 445 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 90393384245851, + "protocol_fee": 90393384245851, "congestion_multiplier": 4934242986, "prover_cost": 19272359080365, "sequencer_cost": 3703696185326 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 912411386, + "protocol_fee": 912411386, "congestion_multiplier": 4934242986, "prover_cost": 194531049, "sequencer_cost": 37384313 @@ -36128,13 +36128,13 @@ "slot_of_change": 445 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 90639197506060, + "protocol_fee": 90639197506060, "congestion_multiplier": 4924427837, "prover_cost": 19373099809716, "sequencer_cost": 3723056194833 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 910135102, + "protocol_fee": 910135102, "congestion_multiplier": 4924427837, "prover_cost": 194531049, "sequencer_cost": 37384313 @@ -36182,13 +36182,13 @@ "slot_of_change": 450 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 90892134013633, + "protocol_fee": 90892134013633, "congestion_multiplier": 4934985412, "prover_cost": 19375038992890, "sequencer_cost": 3723428860436 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 912583566, + "protocol_fee": 912583566, "congestion_multiplier": 4934985412, "prover_cost": 194531049, "sequencer_cost": 37384313 @@ -36236,13 +36236,13 @@ "slot_of_change": 450 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 92533097426974, + "protocol_fee": 92533097426974, "congestion_multiplier": 5002021194, "prover_cost": 19394434795301, "sequencer_cost": 3727156279539 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 928130193, + "protocol_fee": 928130193, "congestion_multiplier": 5002021194, "prover_cost": 194531049, "sequencer_cost": 37384313 @@ -36290,13 +36290,13 @@ "slot_of_change": 450 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 90924110296948, + "protocol_fee": 90924110296948, "congestion_multiplier": 4923773527, "prover_cost": 19383531084927, "sequencer_cost": 3789088263590 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 913724389, + "protocol_fee": 913724389, "congestion_multiplier": 4923773527, "prover_cost": 194791074, "sequencer_cost": 38077715 @@ -36344,13 +36344,13 @@ "slot_of_change": 450 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 91757710785649, + "protocol_fee": 91757710785649, "congestion_multiplier": 4977169548, "prover_cost": 19298618995705, "sequencer_cost": 3772489667633 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 926158656, + "protocol_fee": 926158656, "congestion_multiplier": 4977169548, "prover_cost": 194791074, "sequencer_cost": 38077715 @@ -36398,13 +36398,13 @@ "slot_of_change": 450 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 90538602935327, + "protocol_fee": 90538602935327, "congestion_multiplier": 4909415546, "prover_cost": 19372234655851, "sequencer_cost": 3786880040195 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 910380863, + "protocol_fee": 910380863, "congestion_multiplier": 4909415546, "prover_cost": 194791074, "sequencer_cost": 38077715 @@ -36452,13 +36452,13 @@ "slot_of_change": 455 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 93183716399652, + "protocol_fee": 93183716399652, "congestion_multiplier": 5013571228, "prover_cost": 19420786777308, "sequencer_cost": 3796370997894 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 934635471, + "protocol_fee": 934635471, "congestion_multiplier": 5013571228, "prover_cost": 194791074, "sequencer_cost": 38077715 @@ -36506,13 +36506,13 @@ "slot_of_change": 455 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 91264164210984, + "protocol_fee": 91264164210984, "congestion_multiplier": 4928141047, "prover_cost": 19434392749163, "sequencer_cost": 3799030690189 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 914741448, + "protocol_fee": 914741448, "congestion_multiplier": 4928141047, "prover_cost": 194791074, "sequencer_cost": 38077715 @@ -36560,13 +36560,13 @@ "slot_of_change": 455 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 93346606021097, + "protocol_fee": 93346606021097, "congestion_multiplier": 4858496592, "prover_cost": 19714317899686, "sequencer_cost": 4478163248485 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 934303846, + "protocol_fee": 934303846, "congestion_multiplier": 4858496592, "prover_cost": 197320115, "sequencer_cost": 44821824 @@ -36614,13 +36614,13 @@ "slot_of_change": 455 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 92585466864193, + "protocol_fee": 92585466864193, "congestion_multiplier": 4865304846, "prover_cost": 19519128081493, "sequencer_cost": 4433825327449 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 935952410, + "protocol_fee": 935952410, "congestion_multiplier": 4865304846, "prover_cost": 197320115, "sequencer_cost": 44821824 @@ -36668,13 +36668,13 @@ "slot_of_change": 455 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 93167978253792, + "protocol_fee": 93167978253792, "congestion_multiplier": 4885345230, "prover_cost": 19540622823815, "sequencer_cost": 4438707919157 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 940805027, + "protocol_fee": 940805027, "congestion_multiplier": 4885345230, "prover_cost": 197320115, "sequencer_cost": 44821824 @@ -36722,13 +36722,13 @@ "slot_of_change": 460 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 92934800312502, + "protocol_fee": 92934800312502, "congestion_multiplier": 4870194900, "prover_cost": 19568019753653, "sequencer_cost": 4444931209506 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 937136497, + "protocol_fee": 937136497, "congestion_multiplier": 4870194900, "prover_cost": 197320115, "sequencer_cost": 44821824 @@ -36776,13 +36776,13 @@ "slot_of_change": 460 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 95611387449131, + "protocol_fee": 95611387449131, "congestion_multiplier": 4989224276, "prover_cost": 19530911470049, "sequencer_cost": 4436501957594 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 965958501, + "protocol_fee": 965958501, "congestion_multiplier": 4989224276, "prover_cost": 197320115, "sequencer_cost": 44821824 @@ -36830,13 +36830,13 @@ "slot_of_change": 460 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 93876326518570, + "protocol_fee": 93876326518570, "congestion_multiplier": 4928477757, "prover_cost": 19515433467189, "sequencer_cost": 4380928528840 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 948144702, + "protocol_fee": 948144702, "congestion_multiplier": 4928477757, "prover_cost": 197104590, "sequencer_cost": 44247089 @@ -36884,13 +36884,13 @@ "slot_of_change": 460 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 94603435362425, + "protocol_fee": 94603435362425, "congestion_multiplier": 4950195703, "prover_cost": 19558462365573, "sequencer_cost": 4390587885309 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 953386365, + "protocol_fee": 953386365, "congestion_multiplier": 4950195703, "prover_cost": 197104590, "sequencer_cost": 44247089 @@ -36938,13 +36938,13 @@ "slot_of_change": 460 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 92224109228107, + "protocol_fee": 92224109228107, "congestion_multiplier": 4883193007, "prover_cost": 19395541353264, "sequencer_cost": 4354014508039 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 937215152, + "protocol_fee": 937215152, "congestion_multiplier": 4883193007, "prover_cost": 197104590, "sequencer_cost": 44247089 @@ -36992,13 +36992,13 @@ "slot_of_change": 465 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 91851407653109, + "protocol_fee": 91851407653109, "congestion_multiplier": 4886063880, "prover_cost": 19302888167782, "sequencer_cost": 4333215227088 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 937908042, + "protocol_fee": 937908042, "congestion_multiplier": 4886063880, "prover_cost": 197104590, "sequencer_cost": 44247089 @@ -37046,13 +37046,13 @@ "slot_of_change": 465 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 94577503498522, + "protocol_fee": 94577503498522, "congestion_multiplier": 5010202851, "prover_cost": 19260516011507, "sequencer_cost": 4323703299589 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 967869191, + "protocol_fee": 967869191, "congestion_multiplier": 5010202851, "prover_cost": 197104590, "sequencer_cost": 44247089 @@ -37100,13 +37100,13 @@ "slot_of_change": 465 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 92635924541293, + "protocol_fee": 92635924541293, "congestion_multiplier": 5055957853, "prover_cost": 19039467654756, "sequencer_cost": 3800001580807 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 949327026, + "protocol_fee": 949327026, "congestion_multiplier": 5055957853, "prover_cost": 195115246, "sequencer_cost": 38942173 @@ -37154,13 +37154,13 @@ "slot_of_change": 465 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 81373739774952, + "protocol_fee": 81373739774952, "congestion_multiplier": 4556798959, "prover_cost": 19071890816044, "sequencer_cost": 3806472773509 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 832495184, + "protocol_fee": 832495184, "congestion_multiplier": 4556798959, "prover_cost": 195115246, "sequencer_cost": 38942173 @@ -37208,13 +37208,13 @@ "slot_of_change": 465 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 70110651217253, + "protocol_fee": 70110651217253, "congestion_multiplier": 4095140809, "prover_cost": 18883060469752, "sequencer_cost": 3768784975330 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 724440669, + "protocol_fee": 724440669, "congestion_multiplier": 4095140809, "prover_cost": 195115246, "sequencer_cost": 38942173 @@ -37262,13 +37262,13 @@ "slot_of_change": 470 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 80809874947143, + "protocol_fee": 80809874947143, "congestion_multiplier": 4603148911, "prover_cost": 18696099815383, "sequencer_cost": 3731470340539 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 843343734, + "protocol_fee": 843343734, "congestion_multiplier": 4603148911, "prover_cost": 195115246, "sequencer_cost": 38942173 @@ -37316,13 +37316,13 @@ "slot_of_change": 470 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 86941082404750, + "protocol_fee": 86941082404750, "congestion_multiplier": 4880790949, "prover_cost": 18675558064579, "sequencer_cost": 3727370505032 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 908327913, + "protocol_fee": 908327913, "congestion_multiplier": 4880790949, "prover_cost": 195115246, "sequencer_cost": 38942173 @@ -37370,13 +37370,13 @@ "slot_of_change": 470 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 88840463635765, + "protocol_fee": 88840463635765, "congestion_multiplier": 4898865933, "prover_cost": 18795193294010, "sequencer_cost": 3991038695601 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 927058056, + "protocol_fee": 927058056, "congestion_multiplier": 4898865933, "prover_cost": 196129496, "sequencer_cost": 41646840 @@ -37424,13 +37424,13 @@ "slot_of_change": 470 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 88682725410865, + "protocol_fee": 88682725410865, "congestion_multiplier": 4901673003, "prover_cost": 18748323778161, "sequencer_cost": 3981086254652 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 927725510, + "protocol_fee": 927725510, "congestion_multiplier": 4901673003, "prover_cost": 196129496, "sequencer_cost": 41646840 @@ -37478,13 +37478,13 @@ "slot_of_change": 470 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 90006282922826, + "protocol_fee": 90006282922826, "congestion_multiplier": 4947628216, "prover_cost": 18806624958229, "sequencer_cost": 3993466136146 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 938652573, + "protocol_fee": 938652573, "congestion_multiplier": 4947628216, "prover_cost": 196129496, "sequencer_cost": 41646840 @@ -37532,13 +37532,13 @@ "slot_of_change": 475 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 90006581974235, + "protocol_fee": 90006581974235, "congestion_multiplier": 4978827667, "prover_cost": 18659217294579, "sequencer_cost": 3962165064620 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 946071064, + "protocol_fee": 946071064, "congestion_multiplier": 4978827667, "prover_cost": 196129496, "sequencer_cost": 41646840 @@ -37586,13 +37586,13 @@ "slot_of_change": 475 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 87981877937751, + "protocol_fee": 87981877937751, "congestion_multiplier": 4886212181, "prover_cost": 18674156787721, "sequencer_cost": 3965337370128 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 924049293, + "protocol_fee": 924049293, "congestion_multiplier": 4886212181, "prover_cost": 196129496, "sequencer_cost": 41646840 @@ -37640,13 +37640,13 @@ "slot_of_change": 475 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 85134134958771, + "protocol_fee": 85134134958771, "congestion_multiplier": 4833031780, "prover_cost": 18554701016857, "sequencer_cost": 3655950985562 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 894319019, + "protocol_fee": 894319019, "congestion_multiplier": 4833031780, "prover_cost": 194913850, "sequencer_cost": 38405118 @@ -37694,13 +37694,13 @@ "slot_of_change": 475 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 86784619069796, + "protocol_fee": 86784619069796, "congestion_multiplier": 4897573550, "prover_cost": 18601205700020, "sequencer_cost": 3665114099648 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 909377838, + "protocol_fee": 909377838, "congestion_multiplier": 4897573550, "prover_cost": 194913850, "sequencer_cost": 38405118 @@ -37748,13 +37748,13 @@ "slot_of_change": 475 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 84237471101052, + "protocol_fee": 84237471101052, "congestion_multiplier": 4817605498, "prover_cost": 18433462765066, "sequencer_cost": 3632062640192 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 890719775, + "protocol_fee": 890719775, "congestion_multiplier": 4817605498, "prover_cost": 194913850, "sequencer_cost": 38405118 @@ -37802,13 +37802,13 @@ "slot_of_change": 480 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 85529025118195, + "protocol_fee": 85529025118195, "congestion_multiplier": 4901332901, "prover_cost": 18314419800193, "sequencer_cost": 3608606846194 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 910254966, + "protocol_fee": 910254966, "congestion_multiplier": 4901332901, "prover_cost": 194913850, "sequencer_cost": 38405118 @@ -37856,13 +37856,13 @@ "slot_of_change": 480 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 86185554043074, + "protocol_fee": 86185554043074, "congestion_multiplier": 4939928417, "prover_cost": 18274217923269, "sequencer_cost": 3600685614188 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 919260032, + "protocol_fee": 919260032, "congestion_multiplier": 4939928417, "prover_cost": 194913850, "sequencer_cost": 38405118 @@ -37910,13 +37910,13 @@ "slot_of_change": 480 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 88898168530726, + "protocol_fee": 88898168530726, "congestion_multiplier": 4996731730, "prover_cost": 18323052111438, "sequencer_cost": 3919663828860 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 952175304, + "protocol_fee": 952175304, "congestion_multiplier": 4996731730, "prover_cost": 196255536, "sequencer_cost": 41982947 @@ -37964,13 +37964,13 @@ "slot_of_change": 480 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 88716462835329, + "protocol_fee": 88716462835329, "congestion_multiplier": 4966625300, "prover_cost": 18424386759826, "sequencer_cost": 3941341317604 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 945002794, + "protocol_fee": 945002794, "congestion_multiplier": 4966625300, "prover_cost": 196255536, "sequencer_cost": 41982947 @@ -38018,13 +38018,13 @@ "slot_of_change": 480 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 88707833198211, + "protocol_fee": 88707833198211, "congestion_multiplier": 4945614682, "prover_cost": 18520695928195, "sequencer_cost": 3961943756616 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 939997256, + "protocol_fee": 939997256, "congestion_multiplier": 4945614682, "prover_cost": 196255536, "sequencer_cost": 41982947 @@ -38072,13 +38072,13 @@ "slot_of_change": 485 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 91254572648347, + "protocol_fee": 91254572648347, "congestion_multiplier": 5059702162, "prover_cost": 18516993072340, "sequencer_cost": 3961151642395 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 967177284, + "protocol_fee": 967177284, "congestion_multiplier": 5059702162, "prover_cost": 196255536, "sequencer_cost": 41982947 @@ -38126,13 +38126,13 @@ "slot_of_change": 485 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 91907750198939, + "protocol_fee": 91907750198939, "congestion_multiplier": 5091213677, "prover_cost": 18505889893203, "sequencer_cost": 3958776452422 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 974684540, + "protocol_fee": 974684540, "congestion_multiplier": 5091213677, "prover_cost": 196255536, "sequencer_cost": 41982947 @@ -38180,13 +38180,13 @@ "slot_of_change": 485 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 85819460461627, + "protocol_fee": 85819460461627, "congestion_multiplier": 4932603993, "prover_cost": 18336961476748, "sequencer_cost": 3485591894434 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 909662938, + "protocol_fee": 909662938, "congestion_multiplier": 4932603993, "prover_cost": 194366804, "sequencer_cost": 36946326 @@ -38234,13 +38234,13 @@ "slot_of_change": 485 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 86749229271452, + "protocol_fee": 86749229271452, "congestion_multiplier": 4957321333, "prover_cost": 18419851196391, "sequencer_cost": 3501348034582 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 915380383, + "protocol_fee": 915380383, "congestion_multiplier": 4957321333, "prover_cost": 194366804, "sequencer_cost": 36946326 @@ -38288,13 +38288,13 @@ "slot_of_change": 485 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 86693927075802, + "protocol_fee": 86693927075802, "congestion_multiplier": 4956380172, "prover_cost": 18412487617524, "sequencer_cost": 3499948324448 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 915162681, + "protocol_fee": 915162681, "congestion_multiplier": 4956380172, "prover_cost": 194366804, "sequencer_cost": 36946326 @@ -38342,13 +38342,13 @@ "slot_of_change": 490 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 86188224095780, + "protocol_fee": 86188224095780, "congestion_multiplier": 4928581668, "prover_cost": 18434610024811, "sequencer_cost": 3504153474992 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 908732522, + "protocol_fee": 908732522, "congestion_multiplier": 4928581668, "prover_cost": 194366804, "sequencer_cost": 36946326 @@ -38396,13 +38396,13 @@ "slot_of_change": 490 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 86107030593071, + "protocol_fee": 86107030593071, "congestion_multiplier": 4924095674, "prover_cost": 18438298180748, "sequencer_cost": 3504854540239 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 907694852, + "protocol_fee": 907694852, "congestion_multiplier": 4924095674, "prover_cost": 194366804, "sequencer_cost": 36946326 @@ -38450,13 +38450,13 @@ "slot_of_change": 490 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 85763128177404, + "protocol_fee": 85763128177404, "congestion_multiplier": 4923552109, "prover_cost": 18408999575414, "sequencer_cost": 3449542332600 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 904521586, + "protocol_fee": 904521586, "congestion_multiplier": 4923552109, "prover_cost": 194154969, "sequencer_cost": 36381433 @@ -38504,13 +38504,13 @@ "slot_of_change": 490 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 88403923167240, + "protocol_fee": 88403923167240, "congestion_multiplier": 5028996328, "prover_cost": 18479221282798, "sequencer_cost": 3462700720229 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 928830317, + "protocol_fee": 928830317, "congestion_multiplier": 5028996328, "prover_cost": 194154969, "sequencer_cost": 36381433 @@ -38558,13 +38558,13 @@ "slot_of_change": 490 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 88532186159475, + "protocol_fee": 88532186159475, "congestion_multiplier": 5021930144, "prover_cost": 18538545820785, "sequencer_cost": 3473817158377 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 927201304, + "protocol_fee": 927201304, "congestion_multiplier": 5021930144, "prover_cost": 194154969, "sequencer_cost": 36381433 @@ -38612,13 +38612,13 @@ "slot_of_change": 495 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 86064896439158, + "protocol_fee": 86064896439158, "congestion_multiplier": 4934475554, "prover_cost": 18422484458236, "sequencer_cost": 3452069176818 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 907039837, + "protocol_fee": 907039837, "congestion_multiplier": 4934475554, "prover_cost": 194154969, "sequencer_cost": 36381433 @@ -38666,13 +38666,13 @@ "slot_of_change": 495 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 85363750447135, + "protocol_fee": 85363750447135, "congestion_multiplier": 4900471118, "prover_cost": 18431701164030, "sequencer_cost": 3453796235188 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 899200577, + "protocol_fee": 899200577, "congestion_multiplier": 4900471118, "prover_cost": 194154969, "sequencer_cost": 36381433 @@ -38720,13 +38720,13 @@ "slot_of_change": 495 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 88431921841066, + "protocol_fee": 88431921841066, "congestion_multiplier": 4981905597, "prover_cost": 18440521648181, "sequencer_cost": 3767920949843 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 937481660, + "protocol_fee": 937481660, "congestion_multiplier": 4981905597, "prover_cost": 195491068, "sequencer_cost": 39944363 @@ -38774,13 +38774,13 @@ "slot_of_change": 495 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 87987356997785, + "protocol_fee": 87987356997785, "congestion_multiplier": 4964264639, "prover_cost": 18429465187366, "sequencer_cost": 3765661801695 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 933328353, + "protocol_fee": 933328353, "congestion_multiplier": 4964264639, "prover_cost": 195491068, "sequencer_cost": 39944363 @@ -38828,13 +38828,13 @@ "slot_of_change": 495 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 89379377732684, + "protocol_fee": 89379377732684, "congestion_multiplier": 5039465558, "prover_cost": 18372510986653, "sequencer_cost": 3754024445109 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 951033314, + "protocol_fee": 951033314, "congestion_multiplier": 5039465558, "prover_cost": 195491068, "sequencer_cost": 39944363 @@ -38882,13 +38882,13 @@ "slot_of_change": 500 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 86508641377285, + "protocol_fee": 86508641377285, "congestion_multiplier": 4917151955, "prover_cost": 18337670758015, "sequencer_cost": 3746905599455 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 922236358, + "protocol_fee": 922236358, "congestion_multiplier": 4917151955, "prover_cost": 195491068, "sequencer_cost": 39944363 @@ -38936,13 +38936,13 @@ "slot_of_change": 500 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 88690548034682, + "protocol_fee": 88690548034682, "congestion_multiplier": 5030808605, "prover_cost": 18270072039709, "sequencer_cost": 3733093266391 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 948995161, + "protocol_fee": 948995161, "congestion_multiplier": 5030808605, "prover_cost": 195491068, "sequencer_cost": 39944363 @@ -38990,13 +38990,13 @@ "slot_of_change": 500 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 89834163824199, + "protocol_fee": 89834163824199, "congestion_multiplier": 4987370859, "prover_cost": 18521344529735, "sequencer_cost": 4008329043706 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 952869179, + "protocol_fee": 952869179, "congestion_multiplier": 4987370859, "prover_cost": 196455531, "sequencer_cost": 42516266 @@ -39044,13 +39044,13 @@ "slot_of_change": 500 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 91458332299173, + "protocol_fee": 91458332299173, "congestion_multiplier": 5039975446, "prover_cost": 18610676647911, "sequencer_cost": 4027662009692 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 965440192, + "protocol_fee": 965440192, "congestion_multiplier": 5039975446, "prover_cost": 196455531, "sequencer_cost": 42516266 @@ -39098,13 +39098,13 @@ "slot_of_change": 500 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 88246883475809, + "protocol_fee": 88246883475809, "congestion_multiplier": 4903183816, "prover_cost": 18586515737118, "sequencer_cost": 4022433184091 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 932750850, + "protocol_fee": 932750850, "congestion_multiplier": 4903183816, "prover_cost": 196455531, "sequencer_cost": 42516266 @@ -39152,13 +39152,13 @@ "slot_of_change": 505 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 90623503457646, + "protocol_fee": 90623503457646, "congestion_multiplier": 5010707019, "prover_cost": 18575372047751, "sequencer_cost": 4020021503142 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 958445863, + "protocol_fee": 958445863, "congestion_multiplier": 5010707019, "prover_cost": 196455531, "sequencer_cost": 42516266 @@ -39206,13 +39206,13 @@ "slot_of_change": 505 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 89928799652094, + "protocol_fee": 89928799652094, "congestion_multiplier": 4958867655, "prover_cost": 18674346998477, "sequencer_cost": 4041441339535 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 946057717, + "protocol_fee": 946057717, "congestion_multiplier": 4958867655, "prover_cost": 196455531, "sequencer_cost": 42516266 @@ -39260,13 +39260,13 @@ "slot_of_change": 505 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 89007404450666, + "protocol_fee": 89007404450666, "congestion_multiplier": 4955252409, "prover_cost": 18691803942143, "sequencer_cost": 3811792611883 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 930746334, + "protocol_fee": 930746334, "congestion_multiplier": 4955252409, "prover_cost": 195459334, "sequencer_cost": 39859740 @@ -39314,13 +39314,13 @@ "slot_of_change": 505 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 86717746965321, + "protocol_fee": 86717746965321, "congestion_multiplier": 4853506118, "prover_cost": 18691803942143, "sequencer_cost": 3811792611883 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 906803491, + "protocol_fee": 906803491, "congestion_multiplier": 4853506118, "prover_cost": 195459334, "sequencer_cost": 39859740 @@ -39368,13 +39368,13 @@ "slot_of_change": 505 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 89624397916461, + "protocol_fee": 89624397916461, "congestion_multiplier": 4942843086, "prover_cost": 18880610881513, "sequencer_cost": 3850295738644 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 927826183, + "protocol_fee": 927826183, "congestion_multiplier": 4942843086, "prover_cost": 195459334, "sequencer_cost": 39859740 @@ -39422,13 +39422,13 @@ "slot_of_change": 510 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 91495342288655, + "protocol_fee": 91495342288655, "congestion_multiplier": 5039641794, "prover_cost": 18812885551894, "sequencer_cost": 3836484609880 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 950604766, + "protocol_fee": 950604766, "congestion_multiplier": 5039641794, "prover_cost": 195459334, "sequencer_cost": 39859740 @@ -39476,13 +39476,13 @@ "slot_of_change": 510 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 88332163405141, + "protocol_fee": 88332163405141, "congestion_multiplier": 4921433088, "prover_cost": 18709980812297, "sequencer_cost": 3815499394791 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 922788003, + "protocol_fee": 922788003, "congestion_multiplier": 4921433088, "prover_cost": 195459334, "sequencer_cost": 39859740 @@ -39530,13 +39530,13 @@ "slot_of_change": 510 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 88930790733554, + "protocol_fee": 88930790733554, "congestion_multiplier": 4993387574, "prover_cost": 18694442145180, "sequencer_cost": 3575069412980 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 925046791, + "protocol_fee": 925046791, "congestion_multiplier": 4993387574, "prover_cost": 194457213, "sequencer_cost": 37187418 @@ -39584,13 +39584,13 @@ "slot_of_change": 510 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 89837737192110, + "protocol_fee": 89837737192110, "congestion_multiplier": 5054687267, "prover_cost": 18599585247982, "sequencer_cost": 3556929262600 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 939246535, + "protocol_fee": 939246535, "congestion_multiplier": 5054687267, "prover_cost": 194457213, "sequencer_cost": 37187418 @@ -39638,13 +39638,13 @@ "slot_of_change": 510 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 88780023094413, + "protocol_fee": 88780023094413, "congestion_multiplier": 5011756967, "prover_cost": 18577294105633, "sequencer_cost": 3552666370957 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 929301962, + "protocol_fee": 929301962, "congestion_multiplier": 5011756967, "prover_cost": 194457213, "sequencer_cost": 37187418 @@ -39692,13 +39692,13 @@ "slot_of_change": 515 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 90560920547220, + "protocol_fee": 90560920547220, "congestion_multiplier": 5074225592, "prover_cost": 18659395705572, "sequencer_cost": 3568367236296 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 943772483, + "protocol_fee": 943772483, "congestion_multiplier": 5074225592, "prover_cost": 194457213, "sequencer_cost": 37187418 @@ -39746,13 +39746,13 @@ "slot_of_change": 515 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 89745451393777, + "protocol_fee": 89745451393777, "congestion_multiplier": 5043190801, "prover_cost": 18633310811931, "sequencer_cost": 3563378838960 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 936583441, + "protocol_fee": 936583441, "congestion_multiplier": 5043190801, "prover_cost": 194457213, "sequencer_cost": 37187418 @@ -39800,13 +39800,13 @@ "slot_of_change": 515 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 88491101864928, + "protocol_fee": 88491101864928, "congestion_multiplier": 4985073679, "prover_cost": 18624440099945, "sequencer_cost": 3581197487007 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 924324159, + "protocol_fee": 924324159, "congestion_multiplier": 4985073679, "prover_cost": 194539559, "sequencer_cost": 37407008 @@ -39854,13 +39854,13 @@ "slot_of_change": 515 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 86515038139511, + "protocol_fee": 86515038139511, "congestion_multiplier": 4889071337, "prover_cost": 18658025074164, "sequencer_cost": 3587655368405 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 902056745, + "protocol_fee": 902056745, "congestion_multiplier": 4889071337, "prover_cost": 194539559, "sequencer_cost": 37407008 @@ -39908,13 +39908,13 @@ "slot_of_change": 515 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 85086837748670, + "protocol_fee": 85086837748670, "congestion_multiplier": 4825252337, "prover_cost": 18656160637062, "sequencer_cost": 3587296865415 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 887254147, + "protocol_fee": 887254147, "congestion_multiplier": 4825252337, "prover_cost": 194539559, "sequencer_cost": 37407008 @@ -39962,13 +39962,13 @@ "slot_of_change": 520 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 88783730076756, + "protocol_fee": 88783730076756, "congestion_multiplier": 4983869717, "prover_cost": 18691675719157, "sequencer_cost": 3594125877298 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 924044904, + "protocol_fee": 924044904, "congestion_multiplier": 4983869717, "prover_cost": 194539559, "sequencer_cost": 37407008 @@ -40016,13 +40016,13 @@ "slot_of_change": 520 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 88381154776162, + "protocol_fee": 88381154776162, "congestion_multiplier": 4970167672, "prover_cost": 18671138542773, "sequencer_cost": 3590176889620 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 920866761, + "protocol_fee": 920866761, "congestion_multiplier": 4970167672, "prover_cost": 194539559, "sequencer_cost": 37407008 @@ -40070,13 +40070,13 @@ "slot_of_change": 520 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 89029676880626, + "protocol_fee": 89029676880626, "congestion_multiplier": 4979756691, "prover_cost": 18600953666800, "sequencer_cost": 3769679470456 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 935044865, + "protocol_fee": 935044865, "congestion_multiplier": 4979756691, "prover_cost": 195358748, "sequencer_cost": 39591511 @@ -40124,13 +40124,13 @@ "slot_of_change": 520 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 88462037943462, + "protocol_fee": 88462037943462, "congestion_multiplier": 4948450800, "prover_cost": 18628897136666, "sequencer_cost": 3775342509383 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 927689538, + "protocol_fee": 927689538, "congestion_multiplier": 4948450800, "prover_cost": 195358748, "sequencer_cost": 39591511 @@ -40178,13 +40178,13 @@ "slot_of_change": 520 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 87528901558569, + "protocol_fee": 87528901558569, "congestion_multiplier": 4931803985, "prover_cost": 18510432035078, "sequencer_cost": 3751334306932 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 923778364, + "protocol_fee": 923778364, "congestion_multiplier": 4931803985, "prover_cost": 195358748, "sequencer_cost": 39591511 @@ -40232,13 +40232,13 @@ "slot_of_change": 525 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 87419697362573, + "protocol_fee": 87419697362573, "congestion_multiplier": 4933181426, "prover_cost": 18480863300996, "sequencer_cost": 3745341891068 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 924101994, + "protocol_fee": 924101994, "congestion_multiplier": 4933181426, "prover_cost": 195358748, "sequencer_cost": 39591511 @@ -40286,13 +40286,13 @@ "slot_of_change": 525 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 85191693372884, + "protocol_fee": 85191693372884, "congestion_multiplier": 4849803848, "prover_cost": 18399905136655, "sequencer_cost": 3728934865087 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 904512411, + "protocol_fee": 904512411, "congestion_multiplier": 4849803848, "prover_cost": 195358748, "sequencer_cost": 39591511 @@ -40340,13 +40340,13 @@ "slot_of_change": 525 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 85401342592488, + "protocol_fee": 85401342592488, "congestion_multiplier": 4847029167, "prover_cost": 18448867794775, "sequencer_cost": 3750429101646 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 904562139, + "protocol_fee": 904562139, "congestion_multiplier": 4847029167, "prover_cost": 195408489, "sequencer_cost": 39724155 @@ -40394,13 +40394,13 @@ "slot_of_change": 525 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 85658738407510, + "protocol_fee": 85658738407510, "congestion_multiplier": 4882932927, "prover_cost": 18333369204130, "sequencer_cost": 3726949651288 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 913004285, + "protocol_fee": 913004285, "congestion_multiplier": 4882932927, "prover_cost": 195408489, "sequencer_cost": 39724155 @@ -40448,13 +40448,13 @@ "slot_of_change": 525 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 86661132148979, + "protocol_fee": 86661132148979, "congestion_multiplier": 4958227123, "prover_cost": 18195087465312, "sequencer_cost": 3698838665656 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 930708408, + "protocol_fee": 930708408, "congestion_multiplier": 4958227123, "prover_cost": 195408489, "sequencer_cost": 39724155 @@ -40502,13 +40502,13 @@ "slot_of_change": 530 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 87835868021750, + "protocol_fee": 87835868021750, "congestion_multiplier": 5017098166, "prover_cost": 18171465436194, "sequencer_cost": 3694036596151 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 944550912, + "protocol_fee": 944550912, "congestion_multiplier": 5017098166, "prover_cost": 195408489, "sequencer_cost": 39724155 @@ -40556,13 +40556,13 @@ "slot_of_change": 530 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 88196286388112, + "protocol_fee": 88196286388112, "congestion_multiplier": 5037211727, "prover_cost": 18155126212597, "sequencer_cost": 3690715031903 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 949280267, + "protocol_fee": 949280267, "congestion_multiplier": 5037211727, "prover_cost": 195408489, "sequencer_cost": 39724155 @@ -40610,13 +40610,13 @@ "slot_of_change": 530 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 89181437234700, + "protocol_fee": 89181437234700, "congestion_multiplier": 5017843689, "prover_cost": 18321874047096, "sequencer_cost": 3874469118830 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 954316380, + "protocol_fee": 954316380, "congestion_multiplier": 5017843689, "prover_cost": 196059461, "sequencer_cost": 41460078 @@ -40664,13 +40664,13 @@ "slot_of_change": 530 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 86570572324069, + "protocol_fee": 86570572324069, "congestion_multiplier": 4906847999, "prover_cost": 18290780454803, "sequencer_cost": 3867893854595 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 927952735, + "protocol_fee": 927952735, "congestion_multiplier": 4906847999, "prover_cost": 196059461, "sequencer_cost": 41460078 @@ -40718,13 +40718,13 @@ "slot_of_change": 530 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 86548361821022, + "protocol_fee": 86548361821022, "congestion_multiplier": 4903111319, "prover_cost": 18303594127748, "sequencer_cost": 3870603521739 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 927065201, + "protocol_fee": 927065201, "congestion_multiplier": 4903111319, "prover_cost": 196059461, "sequencer_cost": 41460078 @@ -40772,13 +40772,13 @@ "slot_of_change": 535 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 89769800198545, + "protocol_fee": 89769800198545, "congestion_multiplier": 5076728478, "prover_cost": 18176360783305, "sequencer_cost": 3843697886286 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 968302668, + "protocol_fee": 968302668, "congestion_multiplier": 5076728478, "prover_cost": 196059461, "sequencer_cost": 41460078 @@ -40826,13 +40826,13 @@ "slot_of_change": 535 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 86900702433878, + "protocol_fee": 86900702433878, "congestion_multiplier": 4961429922, "prover_cost": 18107553306878, "sequencer_cost": 3829147385509 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 940917008, + "protocol_fee": 940917008, "congestion_multiplier": 4961429922, "prover_cost": 196059461, "sequencer_cost": 41460078 @@ -40880,13 +40880,13 @@ "slot_of_change": 535 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 85025821090673, + "protocol_fee": 85025821090673, "congestion_multiplier": 4890134458, "prover_cost": 18179843140307, "sequencer_cost": 3676938948211 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 913527965, + "protocol_fee": 913527965, "congestion_multiplier": 4890134458, "prover_cost": 195326489, "sequencer_cost": 39505488 @@ -40934,13 +40934,13 @@ "slot_of_change": 535 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 87744871042246, + "protocol_fee": 87744871042246, "congestion_multiplier": 5018150307, "prover_cost": 18163497195827, "sequencer_cost": 3673632921891 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 943590180, + "protocol_fee": 943590180, "congestion_multiplier": 5018150307, "prover_cost": 195326489, "sequencer_cost": 39505488 @@ -40988,13 +40988,13 @@ "slot_of_change": 535 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 86914518804543, + "protocol_fee": 86914518804543, "congestion_multiplier": 4964602951, "prover_cost": 18234612536226, "sequencer_cost": 3688016256385 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 931015549, + "protocol_fee": 931015549, "congestion_multiplier": 4964602951, "prover_cost": 195326489, "sequencer_cost": 39505488 @@ -41042,13 +41042,13 @@ "slot_of_change": 540 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 88588019435392, + "protocol_fee": 88588019435392, "congestion_multiplier": 5018714157, "prover_cost": 18335458944327, "sequencer_cost": 3708412806722 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 943722590, + "protocol_fee": 943722590, "congestion_multiplier": 5018714157, "prover_cost": 195326489, "sequencer_cost": 39505488 @@ -41096,13 +41096,13 @@ "slot_of_change": 540 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 87608260220864, + "protocol_fee": 87608260220864, "congestion_multiplier": 4979434522, "prover_cost": 18311655198826, "sequencer_cost": 3703598413206 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 934498476, + "protocol_fee": 934498476, "congestion_multiplier": 4979434522, "prover_cost": 195326489, "sequencer_cost": 39505488 @@ -41150,13 +41150,13 @@ "slot_of_change": 540 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 86721794395467, + "protocol_fee": 86721794395467, "congestion_multiplier": 4997748788, "prover_cost": 18192983537308, "sequencer_cost": 3499673772293 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 927355259, + "protocol_fee": 927355259, "congestion_multiplier": 4997748788, "prover_cost": 194545778, "sequencer_cost": 37423590 @@ -41204,13 +41204,13 @@ "slot_of_change": 540 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 87265391382281, + "protocol_fee": 87265391382281, "congestion_multiplier": 5039703424, "prover_cost": 18116893422210, "sequencer_cost": 3485036778884 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 937087450, + "protocol_fee": 937087450, "congestion_multiplier": 5039703424, "prover_cost": 194545778, "sequencer_cost": 37423590 @@ -41258,13 +41258,13 @@ "slot_of_change": 540 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 87950373934285, + "protocol_fee": 87950373934285, "congestion_multiplier": 5033955728, "prover_cost": 18285116597758, "sequencer_cost": 3517396849685 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 935754160, + "protocol_fee": 935754160, "congestion_multiplier": 5033955728, "prover_cost": 194545778, "sequencer_cost": 37423590 @@ -41312,13 +41312,13 @@ "slot_of_change": 545 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 86176503714132, + "protocol_fee": 86176503714132, "congestion_multiplier": 4938365367, "prover_cost": 18351181797422, "sequencer_cost": 3530105410986 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 913580125, + "protocol_fee": 913580125, "congestion_multiplier": 4938365367, "prover_cost": 194545778, "sequencer_cost": 37423590 @@ -41366,13 +41366,13 @@ "slot_of_change": 545 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 84308778472503, + "protocol_fee": 84308778472503, "congestion_multiplier": 4832972384, "prover_cost": 18447107472498, "sequencer_cost": 3548558050624 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 889132181, + "protocol_fee": 889132181, "congestion_multiplier": 4832972384, "prover_cost": 194545778, "sequencer_cost": 37423590 @@ -41420,13 +41420,13 @@ "slot_of_change": 545 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 84835805091858, + "protocol_fee": 84835805091858, "congestion_multiplier": 4910858141, "prover_cost": 18329634465678, "sequencer_cost": 3362741496543 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 897195394, + "protocol_fee": 897195394, "congestion_multiplier": 4910858141, "prover_cost": 193848147, "sequencer_cost": 35563241 @@ -41474,13 +41474,13 @@ "slot_of_change": 545 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 86296046606086, + "protocol_fee": 86296046606086, "congestion_multiplier": 4952713444, "prover_cost": 18447701005255, "sequencer_cost": 3384401898595 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 906797477, + "protocol_fee": 906797477, "congestion_multiplier": 4952713444, "prover_cost": 193848147, "sequencer_cost": 35563241 @@ -41528,13 +41528,13 @@ "slot_of_change": 545 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 88430732505335, + "protocol_fee": 88430732505335, "congestion_multiplier": 5042389832, "prover_cost": 18484670402351, "sequencer_cost": 3391184277477 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 927370262, + "protocol_fee": 927370262, "congestion_multiplier": 5042389832, "prover_cost": 193848147, "sequencer_cost": 35563241 @@ -41582,13 +41582,13 @@ "slot_of_change": 550 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 87700871449884, + "protocol_fee": 87700871449884, "congestion_multiplier": 4989782525, "prover_cost": 18573825746434, "sequencer_cost": 3407540652491 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 915301546, + "protocol_fee": 915301546, "congestion_multiplier": 4989782525, "prover_cost": 193848147, "sequencer_cost": 35563241 @@ -41636,13 +41636,13 @@ "slot_of_change": 550 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 87276567698799, + "protocol_fee": 87276567698799, "congestion_multiplier": 4978817298, "prover_cost": 18534904087050, "sequencer_cost": 3400400112980 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 912785998, + "protocol_fee": 912785998, "congestion_multiplier": 4978817298, "prover_cost": 193848147, "sequencer_cost": 35563241 @@ -41690,13 +41690,13 @@ "slot_of_change": 550 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 88369744909195, + "protocol_fee": 88369744909195, "congestion_multiplier": 4824671544, "prover_cost": 18980756638040, "sequencer_cost": 4124428720992 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 914976804, + "protocol_fee": 914976804, "congestion_multiplier": 4824671544, "prover_cost": 196525995, "sequencer_cost": 42704170 @@ -41744,13 +41744,13 @@ "slot_of_change": 550 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 90481885602863, + "protocol_fee": 90481885602863, "congestion_multiplier": 4951722051, "prover_cost": 18809589439540, "sequencer_cost": 4087234897635 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 945371118, + "protocol_fee": 945371118, "congestion_multiplier": 4951722051, "prover_cost": 196525995, "sequencer_cost": 42704170 @@ -41798,13 +41798,13 @@ "slot_of_change": 550 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 89110137037553, + "protocol_fee": 89110137037553, "congestion_multiplier": 4882860822, "prover_cost": 18852951559600, "sequencer_cost": 4096657281410 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 928897435, + "protocol_fee": 928897435, "congestion_multiplier": 4882860822, "prover_cost": 196525995, "sequencer_cost": 42704170 @@ -41852,13 +41852,13 @@ "slot_of_change": 555 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 91440250227176, + "protocol_fee": 91440250227176, "congestion_multiplier": 5010290719, "prover_cost": 18731200508278, "sequencer_cost": 4070201353310 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 959382510, + "protocol_fee": 959382510, "congestion_multiplier": 5010290719, "prover_cost": 196525995, "sequencer_cost": 42704170 @@ -41906,13 +41906,13 @@ "slot_of_change": 555 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 89654115732477, + "protocol_fee": 89654115732477, "congestion_multiplier": 4959479868, "prover_cost": 18600994155518, "sequencer_cost": 4041908128166 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 947227022, + "protocol_fee": 947227022, "congestion_multiplier": 4959479868, "prover_cost": 196525995, "sequencer_cost": 42704170 @@ -41960,13 +41960,13 @@ "slot_of_change": 555 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 87454992620768, + "protocol_fee": 87454992620768, "congestion_multiplier": 4894614664, "prover_cost": 18494182688924, "sequencer_cost": 3961182026428 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 928150479, + "protocol_fee": 928150479, "congestion_multiplier": 4894614664, "prover_cost": 196276782, "sequencer_cost": 42039601 @@ -42014,13 +42014,13 @@ "slot_of_change": 555 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 90439716202868, + "protocol_fee": 90439716202868, "congestion_multiplier": 5017866624, "prover_cost": 18538675609606, "sequencer_cost": 3970711755893 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 957523441, + "protocol_fee": 957523441, "congestion_multiplier": 5017866624, "prover_cost": 196276782, "sequencer_cost": 42039601 @@ -42068,13 +42068,13 @@ "slot_of_change": 555 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 89301241573499, + "protocol_fee": 89301241573499, "congestion_multiplier": 4932773283, "prover_cost": 18701378358393, "sequencer_cost": 4005560292592 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 937244303, + "protocol_fee": 937244303, "congestion_multiplier": 4932773283, "prover_cost": 196276782, "sequencer_cost": 42039601 @@ -42122,13 +42122,13 @@ "slot_of_change": 560 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 90115102078578, + "protocol_fee": 90115102078578, "congestion_multiplier": 4964646337, "prover_cost": 18720099687024, "sequencer_cost": 4009570125940 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 944840174, + "protocol_fee": 944840174, "congestion_multiplier": 4964646337, "prover_cost": 196276782, "sequencer_cost": 42039601 @@ -42176,13 +42176,13 @@ "slot_of_change": 560 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 88238111455931, + "protocol_fee": 88238111455931, "congestion_multiplier": 4906135958, "prover_cost": 18604751739841, "sequencer_cost": 3984864291524 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 930896193, + "protocol_fee": 930896193, "congestion_multiplier": 4906135958, "prover_cost": 196276782, "sequencer_cost": 42039601 @@ -42230,13 +42230,13 @@ "slot_of_change": 560 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 90177246971783, + "protocol_fee": 90177246971783, "congestion_multiplier": 4907441770, "prover_cost": 18656447868101, "sequencer_cost": 4421886335335 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 957632585, + "protocol_fee": 957632585, "congestion_multiplier": 4907441770, "prover_cost": 198121178, "sequencer_cost": 46957992 @@ -42284,13 +42284,13 @@ "slot_of_change": 560 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 90412109214085, + "protocol_fee": 90412109214085, "congestion_multiplier": 4940340405, "prover_cost": 18548865840780, "sequencer_cost": 4396387617686 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 965695355, + "protocol_fee": 965695355, "congestion_multiplier": 4940340405, "prover_cost": 198121178, "sequencer_cost": 46957992 @@ -42338,13 +42338,13 @@ "slot_of_change": 560 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 95554954195639, + "protocol_fee": 95554954195639, "congestion_multiplier": 5132825809, "prover_cost": 18690916977803, "sequencer_cost": 4430056083739 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 1012869519, + "protocol_fee": 1012869519, "congestion_multiplier": 5132825809, "prover_cost": 198121178, "sequencer_cost": 46957992 @@ -42392,13 +42392,13 @@ "slot_of_change": 565 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 94564660074884, + "protocol_fee": 94564660074884, "congestion_multiplier": 5089994824, "prover_cost": 18690916977803, "sequencer_cost": 4430056083739 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 1002372536, + "protocol_fee": 1002372536, "congestion_multiplier": 5089994824, "prover_cost": 198121178, "sequencer_cost": 46957992 @@ -42446,13 +42446,13 @@ "slot_of_change": 565 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 91780811755531, + "protocol_fee": 91780811755531, "congestion_multiplier": 4989042098, "prover_cost": 18599778647803, "sequencer_cost": 4408454793992 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 977631126, + "protocol_fee": 977631126, "congestion_multiplier": 4989042098, "prover_cost": 198121178, "sequencer_cost": 46957992 @@ -42500,13 +42500,13 @@ "slot_of_change": 565 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 91426454057038, + "protocol_fee": 91426454057038, "congestion_multiplier": 4975105247, "prover_cost": 18541032675966, "sequencer_cost": 4458724164668 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 978336291, + "protocol_fee": 978336291, "congestion_multiplier": 4975105247, "prover_cost": 198403901, "sequencer_cost": 47711920 @@ -42554,13 +42554,13 @@ "slot_of_change": 565 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 91022247641562, + "protocol_fee": 91022247641562, "congestion_multiplier": 4958718038, "prover_cost": 18535472450468, "sequencer_cost": 4457387048650 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 974303140, + "protocol_fee": 974303140, "congestion_multiplier": 4958718038, "prover_cost": 198403901, "sequencer_cost": 47711920 @@ -42608,13 +42608,13 @@ "slot_of_change": 565 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 89701939942403, + "protocol_fee": 89701939942403, "congestion_multiplier": 4910658410, "prover_cost": 18491094904797, "sequencer_cost": 4446715192410 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 962474905, + "protocol_fee": 962474905, "congestion_multiplier": 4910658410, "prover_cost": 198403901, "sequencer_cost": 47711920 @@ -42662,13 +42662,13 @@ "slot_of_change": 570 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 93024052475824, + "protocol_fee": 93024052475824, "congestion_multiplier": 5053056335, "prover_cost": 18502196533108, "sequencer_cost": 4449384897991 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 997521287, + "protocol_fee": 997521287, "congestion_multiplier": 5053056335, "prover_cost": 198403901, "sequencer_cost": 47711920 @@ -42716,13 +42716,13 @@ "slot_of_change": 570 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 91747993285699, + "protocol_fee": 91747993285699, "congestion_multiplier": 5025040732, "prover_cost": 18375407094324, "sequencer_cost": 4418894733586 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 990626204, + "protocol_fee": 990626204, "congestion_multiplier": 5025040732, "prover_cost": 198403901, "sequencer_cost": 47711920 @@ -42770,13 +42770,13 @@ "slot_of_change": 570 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 88203473364905, + "protocol_fee": 88203473364905, "congestion_multiplier": 4949767110, "prover_cost": 18224868160616, "sequencer_cost": 4106441759131 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 954259795, + "protocol_fee": 954259795, "congestion_multiplier": 4949767110, "prover_cost": 197172042, "sequencer_cost": 44426961 @@ -42824,13 +42824,13 @@ "slot_of_change": 570 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 88943272947682, + "protocol_fee": 88943272947682, "congestion_multiplier": 4943066312, "prover_cost": 18408958666122, "sequencer_cost": 4147921177945 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 952640889, + "protocol_fee": 952640889, "congestion_multiplier": 4943066312, "prover_cost": 197172042, "sequencer_cost": 44426961 @@ -42878,13 +42878,13 @@ "slot_of_change": 570 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 89816843634532, + "protocol_fee": 89816843634532, "congestion_multiplier": 4942771985, "prover_cost": 18591152939384, "sequencer_cost": 4188973336205 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 952569780, + "protocol_fee": 952569780, "congestion_multiplier": 4942771985, "prover_cost": 197172042, "sequencer_cost": 44426961 @@ -42932,13 +42932,13 @@ "slot_of_change": 575 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 90269062400974, + "protocol_fee": 90269062400974, "congestion_multiplier": 4943999021, "prover_cost": 18678944414209, "sequencer_cost": 4208754580993 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 952866231, + "protocol_fee": 952866231, "congestion_multiplier": 4943999021, "prover_cost": 197172042, "sequencer_cost": 44426961 @@ -42986,13 +42986,13 @@ "slot_of_change": 575 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 89491713966837, + "protocol_fee": 89491713966837, "congestion_multiplier": 4918637192, "prover_cost": 18637942457497, "sequencer_cost": 4199515987563 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 946738838, + "protocol_fee": 946738838, "congestion_multiplier": 4918637192, "prover_cost": 197172042, "sequencer_cost": 44426961 @@ -43040,13 +43040,13 @@ "slot_of_change": 575 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 94329885282470, + "protocol_fee": 94329885282470, "congestion_multiplier": 5068680035, "prover_cost": 18809981589344, "sequencer_cost": 4374413467059 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 991734985, + "protocol_fee": 991734985, "congestion_multiplier": 5068680035, "prover_cost": 197758290, "sequencer_cost": 45990291 @@ -43094,13 +43094,13 @@ "slot_of_change": 575 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 94330029919464, + "protocol_fee": 94330029919464, "congestion_multiplier": 5041425804, "prover_cost": 18936859830500, "sequencer_cost": 4403920028996 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 985091804, + "protocol_fee": 985091804, "congestion_multiplier": 5041425804, "prover_cost": 197758290, "sequencer_cost": 45990291 @@ -43148,13 +43148,13 @@ "slot_of_change": 575 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 93006482822579, + "protocol_fee": 93006482822579, "congestion_multiplier": 4967984528, "prover_cost": 19016730559562, "sequencer_cost": 4422494613515 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 967190598, + "protocol_fee": 967190598, "congestion_multiplier": 4967984528, "prover_cost": 197758290, "sequencer_cost": 45990291 @@ -43202,13 +43202,13 @@ "slot_of_change": 580 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 90480245712482, + "protocol_fee": 90480245712482, "congestion_multiplier": 4884911400, "prover_cost": 18895798744245, "sequencer_cost": 4394370941038 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 946941641, + "protocol_fee": 946941641, "congestion_multiplier": 4884911400, "prover_cost": 197758290, "sequencer_cost": 45990291 @@ -43256,13 +43256,13 @@ "slot_of_change": 580 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 91634935109910, + "protocol_fee": 91634935109910, "congestion_multiplier": 4925440167, "prover_cost": 18939360768063, "sequencer_cost": 4404501642269 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 956820470, + "protocol_fee": 956820470, "congestion_multiplier": 4925440167, "prover_cost": 197758290, "sequencer_cost": 45990291 @@ -43310,13 +43310,13 @@ "slot_of_change": 580 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 89630360591843, + "protocol_fee": 89630360591843, "congestion_multiplier": 5061344619, "prover_cost": 18542864605723, "sequencer_cost": 3526269897919 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 939539320, + "protocol_fee": 939539320, "congestion_multiplier": 5061344619, "prover_cost": 194373316, "sequencer_cost": 36963694 @@ -43364,13 +43364,13 @@ "slot_of_change": 580 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 86885276311250, + "protocol_fee": 86885276311250, "congestion_multiplier": 4962942608, "prover_cost": 18421285343468, "sequencer_cost": 3503149344443 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 916775293, + "protocol_fee": 916775293, "congestion_multiplier": 4962942608, "prover_cost": 194373316, "sequencer_cost": 36963694 @@ -43418,13 +43418,13 @@ "slot_of_change": 580 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 86030675924879, + "protocol_fee": 86030675924879, "congestion_multiplier": 4910229180, "prover_cost": 18485987238734, "sequencer_cost": 3515453610827 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 904580726, + "protocol_fee": 904580726, "congestion_multiplier": 4910229180, "prover_cost": 194373316, "sequencer_cost": 36963694 @@ -43472,13 +43472,13 @@ "slot_of_change": 585 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 86925215421655, + "protocol_fee": 86925215421655, "congestion_multiplier": 4956418461, "prover_cost": 18460143883526, "sequencer_cost": 3510539017129 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 915266017, + "protocol_fee": 915266017, "congestion_multiplier": 4956418461, "prover_cost": 194373316, "sequencer_cost": 36963694 @@ -43526,13 +43526,13 @@ "slot_of_change": 585 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 87125707818229, + "protocol_fee": 87125707818229, "congestion_multiplier": 4985767931, "prover_cost": 18366476050522, "sequencer_cost": 3492726340018 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 922055635, + "protocol_fee": 922055635, "congestion_multiplier": 4985767931, "prover_cost": 194373316, "sequencer_cost": 36963694 @@ -43580,13 +43580,13 @@ "slot_of_change": 585 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 88478719010577, + "protocol_fee": 88478719010577, "congestion_multiplier": 4929449478, "prover_cost": 18588148400703, "sequencer_cost": 3928674761304 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 933190889, + "protocol_fee": 933190889, "congestion_multiplier": 4929449478, "prover_cost": 196050428, "sequencer_cost": 41435992 @@ -43634,13 +43634,13 @@ "slot_of_change": 585 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 93622290092576, + "protocol_fee": 93622290092576, "congestion_multiplier": 5128776456, "prover_cost": 18719183641045, "sequencer_cost": 3956369549966 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 980528339, + "protocol_fee": 980528339, "congestion_multiplier": 5128776456, "prover_cost": 196050428, "sequencer_cost": 41435992 @@ -43688,13 +43688,13 @@ "slot_of_change": 585 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 91533820700563, + "protocol_fee": 91533820700563, "congestion_multiplier": 5050398902, "prover_cost": 18655754081443, "sequencer_cost": 3942963475054 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 961914734, + "protocol_fee": 961914734, "congestion_multiplier": 5050398902, "prover_cost": 196050428, "sequencer_cost": 41435992 @@ -43742,13 +43742,13 @@ "slot_of_change": 590 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 90003853891976, + "protocol_fee": 90003853891976, "congestion_multiplier": 4983095349, "prover_cost": 18653890262463, "sequencer_cost": 3942569549934 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 945931054, + "protocol_fee": 945931054, "congestion_multiplier": 4983095349, "prover_cost": 196050428, "sequencer_cost": 41435992 @@ -43796,13 +43796,13 @@ "slot_of_change": 590 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 87817911922633, + "protocol_fee": 87817911922633, "congestion_multiplier": 4901513673, "prover_cost": 18581423753823, "sequencer_cost": 3927253482008 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 926556514, + "protocol_fee": 926556514, "congestion_multiplier": 4901513673, "prover_cost": 196050428, "sequencer_cost": 41435992 @@ -43850,13 +43850,13 @@ "slot_of_change": 590 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 87173837962188, + "protocol_fee": 87173837962188, "congestion_multiplier": 4935406288, "prover_cost": 18483920729668, "sequencer_cost": 3667245291224 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 919760965, + "protocol_fee": 919760965, "congestion_multiplier": 4935406288, "prover_cost": 195021685, "sequencer_cost": 38692676 @@ -43904,13 +43904,13 @@ "slot_of_change": 590 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 87116221851405, + "protocol_fee": 87116221851405, "congestion_multiplier": 4921399944, "prover_cost": 18537680775759, "sequencer_cost": 3677911387382 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 916487482, + "protocol_fee": 916487482, "congestion_multiplier": 4921399944, "prover_cost": 195021685, "sequencer_cost": 38692676 @@ -43958,13 +43958,13 @@ "slot_of_change": 590 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 86386101121862, + "protocol_fee": 86386101121862, "congestion_multiplier": 4914198711, "prover_cost": 18416135821559, "sequencer_cost": 3653796635567 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 914804450, + "protocol_fee": 914804450, "congestion_multiplier": 4914198711, "prover_cost": 195021685, "sequencer_cost": 38692676 @@ -44012,13 +44012,13 @@ "slot_of_change": 595 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 84257054064567, + "protocol_fee": 84257054064567, "congestion_multiplier": 4821547964, "prover_cost": 18397739329626, "sequencer_cost": 3650146736317 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 893150640, + "protocol_fee": 893150640, "congestion_multiplier": 4821547964, "prover_cost": 195021685, "sequencer_cost": 38692676 @@ -44066,13 +44066,13 @@ "slot_of_change": 595 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 86003352576448, + "protocol_fee": 86003352576448, "congestion_multiplier": 4927277856, "prover_cost": 18273479817874, "sequencer_cost": 3625493411082 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 917861234, + "protocol_fee": 917861234, "congestion_multiplier": 4927277856, "prover_cost": 195021685, "sequencer_cost": 38692676 @@ -44120,13 +44120,13 @@ "slot_of_change": 595 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 86454475715543, + "protocol_fee": 86454475715543, "congestion_multiplier": 4900377410, "prover_cost": 18365928527863, "sequencer_cost": 3799740749052 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 921199499, + "protocol_fee": 921199499, "congestion_multiplier": 4900377410, "prover_cost": 195694717, "sequencer_cost": 40487427 @@ -44174,13 +44174,13 @@ "slot_of_change": 595 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 86069930790141, + "protocol_fee": 86069930790141, "congestion_multiplier": 4899337344, "prover_cost": 18289114785752, "sequencer_cost": 3783848696247 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 920953854, + "protocol_fee": 920953854, "congestion_multiplier": 4899337344, "prover_cost": 195694717, "sequencer_cost": 40487427 @@ -44228,13 +44228,13 @@ "slot_of_change": 595 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 87420296891290, + "protocol_fee": 87420296891290, "congestion_multiplier": 4952989425, "prover_cost": 18323931757102, "sequencer_cost": 3791052005603 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 933625517, + "protocol_fee": 933625517, "congestion_multiplier": 4952989425, "prover_cost": 195694717, "sequencer_cost": 40487427 @@ -44282,13 +44282,13 @@ "slot_of_change": 600 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 87731844565030, + "protocol_fee": 87731844565030, "congestion_multiplier": 4982151580, "prover_cost": 18254566096746, "sequencer_cost": 3776700892026 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 940513097, + "protocol_fee": 940513097, "congestion_multiplier": 4982151580, "prover_cost": 195694717, "sequencer_cost": 40487427 @@ -44336,13 +44336,13 @@ "slot_of_change": 600 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 86053356974737, + "protocol_fee": 86053356974737, "congestion_multiplier": 4883310307, "prover_cost": 18361060534214, "sequencer_cost": 3798733606189 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 917168554, + "protocol_fee": 917168554, "congestion_multiplier": 4883310307, "prover_cost": 195694717, "sequencer_cost": 40487427 @@ -44390,13 +44390,13 @@ "slot_of_change": 600 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 86897872260360, + "protocol_fee": 86897872260360, "congestion_multiplier": 4956685292, "prover_cost": 18278931512413, "sequencer_cost": 3683359121252 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 928299642, + "protocol_fee": 928299642, "congestion_multiplier": 4956685292, "prover_cost": 195267446, "sequencer_cost": 39348040 @@ -44444,13 +44444,13 @@ "slot_of_change": 600 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 86299174152702, + "protocol_fee": 86299174152702, "congestion_multiplier": 4954572979, "prover_cost": 18162691927156, "sequencer_cost": 3659935862824 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 927804061, + "protocol_fee": 927804061, "congestion_multiplier": 4954572979, "prover_cost": 195267446, "sequencer_cost": 39348040 @@ -44498,13 +44498,13 @@ "slot_of_change": 600 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 86873163735224, + "protocol_fee": 86873163735224, "congestion_multiplier": 4976496188, "prover_cost": 18182694377753, "sequencer_cost": 3663966525601 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 932947585, + "protocol_fee": 932947585, "congestion_multiplier": 4976496188, "prover_cost": 195267446, "sequencer_cost": 39348040 @@ -44552,13 +44552,13 @@ "slot_of_change": 605 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 85266227291588, + "protocol_fee": 85266227291588, "congestion_multiplier": 4902940944, "prover_cost": 18182694377753, "sequencer_cost": 3663966525601 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 915690386, + "protocol_fee": 915690386, "congestion_multiplier": 4902940944, "prover_cost": 195267446, "sequencer_cost": 39348040 @@ -44606,13 +44606,13 @@ "slot_of_change": 605 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 85861012089307, + "protocol_fee": 85861012089307, "congestion_multiplier": 4962000558, "prover_cost": 18036598692854, "sequencer_cost": 3634527010869 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 929546686, + "protocol_fee": 929546686, "congestion_multiplier": 4962000558, "prover_cost": 195267446, "sequencer_cost": 39348040 @@ -44660,13 +44660,13 @@ "slot_of_change": 605 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 82051347653247, + "protocol_fee": 82051347653247, "congestion_multiplier": 4865381990, "prover_cost": 17886503434662, "sequencer_cost": 3340725317290 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 890434435, + "protocol_fee": 890434435, "congestion_multiplier": 4865381990, "prover_cost": 194107215, "sequencer_cost": 36254089 @@ -44714,13 +44714,13 @@ "slot_of_change": 605 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 78123266334620, + "protocol_fee": 78123266334620, "congestion_multiplier": 4643529346, "prover_cost": 18067175842376, "sequencer_cost": 3374470139960 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 839328171, + "protocol_fee": 839328171, "congestion_multiplier": 4643529346, "prover_cost": 194107215, "sequencer_cost": 36254089 @@ -44768,13 +44768,13 @@ "slot_of_change": 605 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 83653390998753, + "protocol_fee": 83653390998753, "congestion_multiplier": 4899493676, "prover_cost": 18076214253194, "sequencer_cost": 3376158275819 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 898292448, + "protocol_fee": 898292448, "congestion_multiplier": 4899493676, "prover_cost": 194107215, "sequencer_cost": 36254089 @@ -44822,13 +44822,13 @@ "slot_of_change": 610 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 85114188440818, + "protocol_fee": 85114188440818, "congestion_multiplier": 4974729924, "prover_cost": 18043737006274, "sequencer_cost": 3370092385892 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 915623968, + "protocol_fee": 915623968, "congestion_multiplier": 4974729924, "prover_cost": 194107215, "sequencer_cost": 36254089 @@ -44876,13 +44876,13 @@ "slot_of_change": 610 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 84119909878286, + "protocol_fee": 84119909878286, "congestion_multiplier": 4919655952, "prover_cost": 18083521242178, "sequencer_cost": 3377523027917 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 902937056, + "protocol_fee": 902937056, "congestion_multiplier": 4919655952, "prover_cost": 194107215, "sequencer_cost": 36254089 @@ -44930,13 +44930,13 @@ "slot_of_change": 610 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 86312335598951, + "protocol_fee": 86312335598951, "congestion_multiplier": 5012696155, "prover_cost": 18175601651348, "sequencer_cost": 3334209295065 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 920540911, + "protocol_fee": 920540911, "congestion_multiplier": 5012696155, "prover_cost": 193846972, "sequencer_cost": 35560109 @@ -44984,13 +44984,13 @@ "slot_of_change": 610 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 85236190010834, + "protocol_fee": 85236190010834, "congestion_multiplier": 4957117716, "prover_cost": 18201084326467, "sequencer_cost": 3338883944844 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 907790824, + "protocol_fee": 907790824, "congestion_multiplier": 4957117716, "prover_cost": 193846972, "sequencer_cost": 35560109 @@ -45038,13 +45038,13 @@ "slot_of_change": 610 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 83683090112539, + "protocol_fee": 83683090112539, "congestion_multiplier": 4904050956, "prover_cost": 18112334669223, "sequencer_cost": 3322603332087 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 895616933, + "protocol_fee": 895616933, "congestion_multiplier": 4904050956, "prover_cost": 193846972, "sequencer_cost": 35560109 @@ -45092,13 +45092,13 @@ "slot_of_change": 615 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 82796244060434, + "protocol_fee": 82796244060434, "congestion_multiplier": 4864994528, "prover_cost": 18101474613885, "sequencer_cost": 3320611117570 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 886657112, + "protocol_fee": 886657112, "congestion_multiplier": 4864994528, "prover_cost": 193846972, "sequencer_cost": 35560109 @@ -45146,13 +45146,13 @@ "slot_of_change": 615 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 82624428545644, + "protocol_fee": 82624428545644, "congestion_multiplier": 4839231950, "prover_cost": 18185126257500, "sequencer_cost": 3335956529130 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 880746994, + "protocol_fee": 880746994, "congestion_multiplier": 4839231950, "prover_cost": 193846972, "sequencer_cost": 35560109 @@ -45200,13 +45200,13 @@ "slot_of_change": 615 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 84206290241292, + "protocol_fee": 84206290241292, "congestion_multiplier": 4869461508, "prover_cost": 18330094108233, "sequencer_cost": 3431665266477 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 891864355, + "protocol_fee": 891864355, "congestion_multiplier": 4869461508, "prover_cost": 194141762, "sequencer_cost": 36346215 @@ -45254,13 +45254,13 @@ "slot_of_change": 615 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 86310821583815, + "protocol_fee": 86310821583815, "congestion_multiplier": 4941975531, "prover_cost": 18442594502003, "sequencer_cost": 3452727007431 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 908577965, + "protocol_fee": 908577965, "congestion_multiplier": 4941975531, "prover_cost": 194141762, "sequencer_cost": 36346215 @@ -45308,13 +45308,13 @@ "slot_of_change": 615 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 87658717917881, + "protocol_fee": 87658717917881, "congestion_multiplier": 5003536460, "prover_cost": 18442594502003, "sequencer_cost": 3452727007431 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 922767019, + "protocol_fee": 922767019, "congestion_multiplier": 5003536460, "prover_cost": 194141762, "sequencer_cost": 36346215 @@ -45362,13 +45362,13 @@ "slot_of_change": 620 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 87589705255363, + "protocol_fee": 87589705255363, "congestion_multiplier": 4997584168, "prover_cost": 18455513765223, "sequencer_cost": 3455145684968 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 921395087, + "protocol_fee": 921395087, "congestion_multiplier": 4997584168, "prover_cost": 194141762, "sequencer_cost": 36346215 @@ -45416,13 +45416,13 @@ "slot_of_change": 620 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 85965605375466, + "protocol_fee": 85965605375466, "congestion_multiplier": 4914044003, "prover_cost": 18499914143035, "sequencer_cost": 3463458093701 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 902140084, + "protocol_fee": 902140084, "congestion_multiplier": 4914044003, "prover_cost": 194141762, "sequencer_cost": 36346215 @@ -45470,13 +45470,13 @@ "slot_of_change": 620 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 87304908592788, + "protocol_fee": 87304908592788, "congestion_multiplier": 4876920421, "prover_cost": 18645235057663, "sequencer_cost": 3873903620620 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 916653086, + "protocol_fee": 916653086, "congestion_multiplier": 4876920421, "prover_cost": 195764620, "sequencer_cost": 40673838 @@ -45524,13 +45524,13 @@ "slot_of_change": 620 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 87587030008051, + "protocol_fee": 87587030008051, "congestion_multiplier": 4869612002, "prover_cost": 18740814694995, "sequencer_cost": 3893762115403 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 914925094, + "protocol_fee": 914925094, "congestion_multiplier": 4869612002, "prover_cost": 195764620, "sequencer_cost": 40673838 @@ -45578,13 +45578,13 @@ "slot_of_change": 620 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 86815574179872, + "protocol_fee": 86815574179872, "congestion_multiplier": 4859692708, "prover_cost": 18623486996307, "sequencer_cost": 3869385045587 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 912579792, + "protocol_fee": 912579792, "congestion_multiplier": 4859692708, "prover_cost": 195764620, "sequencer_cost": 40673838 @@ -45632,13 +45632,13 @@ "slot_of_change": 625 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 89194355307615, + "protocol_fee": 89194355307615, "congestion_multiplier": 4946018873, "prover_cost": 18715192580485, "sequencer_cost": 3888438631850 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 932990617, + "protocol_fee": 932990617, "congestion_multiplier": 4946018873, "prover_cost": 195764620, "sequencer_cost": 40673838 @@ -45686,13 +45686,13 @@ "slot_of_change": 625 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 89224705359899, + "protocol_fee": 89224705359899, "congestion_multiplier": 4977756065, "prover_cost": 18572187666883, "sequencer_cost": 3858726630320 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 940494510, + "protocol_fee": 940494510, "congestion_multiplier": 4977756065, "prover_cost": 195764620, "sequencer_cost": 40673838 @@ -45740,13 +45740,13 @@ "slot_of_change": 625 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 91562952226784, + "protocol_fee": 91562952226784, "congestion_multiplier": 4959662297, "prover_cost": 18764930328393, "sequencer_cost": 4358999288072 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 964851751, + "protocol_fee": 964851751, "congestion_multiplier": 4959662297, "prover_cost": 197736917, "sequencer_cost": 45933295 @@ -45794,13 +45794,13 @@ "slot_of_change": 625 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 90691947846801, + "protocol_fee": 90691947846801, "congestion_multiplier": 4898071038, "prover_cost": 18880100327519, "sequencer_cost": 4385752701776 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 949843796, + "protocol_fee": 949843796, "congestion_multiplier": 4898071038, "prover_cost": 197736917, "sequencer_cost": 45933295 @@ -45848,13 +45848,13 @@ "slot_of_change": 625 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 82385853157595, + "protocol_fee": 82385853157595, "congestion_multiplier": 4534689147, "prover_cost": 18914145905006, "sequencer_cost": 4393661318831 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 861298453, + "protocol_fee": 861298453, "congestion_multiplier": 4534689147, "prover_cost": 197736917, "sequencer_cost": 45933295 @@ -45902,13 +45902,13 @@ "slot_of_change": 630 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 89123625076693, + "protocol_fee": 89123625076693, "congestion_multiplier": 4816501685, "prover_cost": 18950152195843, "sequencer_cost": 4402025399772 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 929967774, + "protocol_fee": 929967774, "congestion_multiplier": 4816501685, "prover_cost": 197736917, "sequencer_cost": 45933295 @@ -45956,13 +45956,13 @@ "slot_of_change": 630 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 91432634450849, + "protocol_fee": 91432634450849, "congestion_multiplier": 4894236227, "prover_cost": 19053039076491, "sequencer_cost": 4425925506602 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 948909367, + "protocol_fee": 948909367, "congestion_multiplier": 4894236227, "prover_cost": 197736917, "sequencer_cost": 45933295 @@ -46010,13 +46010,13 @@ "slot_of_change": 630 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 92637881468346, + "protocol_fee": 92637881468346, "congestion_multiplier": 4973080376, "prover_cost": 18953285330183, "sequencer_cost": 4363102136735 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 965647920, + "protocol_fee": 965647920, "congestion_multiplier": 4973080376, "prover_cost": 197567132, "sequencer_cost": 45480536 @@ -46064,13 +46064,13 @@ "slot_of_change": 630 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 91470111850915, + "protocol_fee": 91470111850915, "congestion_multiplier": 4901420044, "prover_cost": 19058105928414, "sequencer_cost": 4387232147345 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 948231043, + "protocol_fee": 948231043, "congestion_multiplier": 4901420044, "prover_cost": 197567132, "sequencer_cost": 45480536 @@ -46118,13 +46118,13 @@ "slot_of_change": 630 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 91063981032312, + "protocol_fee": 91063981032312, "congestion_multiplier": 4863123261, "prover_cost": 19161579452266, "sequencer_cost": 4411052057463 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 938923099, + "protocol_fee": 938923099, "congestion_multiplier": 4863123261, "prover_cost": 197567132, "sequencer_cost": 45480536 @@ -46172,13 +46172,13 @@ "slot_of_change": 635 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 90812502419357, + "protocol_fee": 90812502419357, "congestion_multiplier": 4851298969, "prover_cost": 19167331183247, "sequencer_cost": 4412376122885 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 936049233, + "protocol_fee": 936049233, "congestion_multiplier": 4851298969, "prover_cost": 197567132, "sequencer_cost": 45480536 @@ -46226,13 +46226,13 @@ "slot_of_change": 635 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 90307120794814, + "protocol_fee": 90307120794814, "congestion_multiplier": 4825652932, "prover_cost": 19188439877648, "sequencer_cost": 4417235406542 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 929816023, + "protocol_fee": 929816023, "congestion_multiplier": 4825652932, "prover_cost": 197567132, "sequencer_cost": 45480536 @@ -46280,13 +46280,13 @@ "slot_of_change": 635 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 93167567783203, + "protocol_fee": 93167567783203, "congestion_multiplier": 4933365666, "prover_cost": 19233469713806, "sequencer_cost": 4453005365056 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 957540858, + "protocol_fee": 957540858, "congestion_multiplier": 4933365666, "prover_cost": 197674293, "sequencer_cost": 45766297 @@ -46334,13 +46334,13 @@ "slot_of_change": 635 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 92006737123252, + "protocol_fee": 92006737123252, "congestion_multiplier": 4892514653, "prover_cost": 19193164072988, "sequencer_cost": 4443673651253 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 947596063, + "protocol_fee": 947596063, "congestion_multiplier": 4892514653, "prover_cost": 197674293, "sequencer_cost": 45766297 @@ -46388,13 +46388,13 @@ "slot_of_change": 635 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 91733464935236, + "protocol_fee": 91733464935236, "congestion_multiplier": 4858443606, "prover_cost": 19305135023142, "sequencer_cost": 4469597587453 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 939301787, + "protocol_fee": 939301787, "congestion_multiplier": 4858443606, "prover_cost": 197674293, "sequencer_cost": 45766297 @@ -46442,13 +46442,13 @@ "slot_of_change": 640 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 92944586112767, + "protocol_fee": 92944586112767, "congestion_multiplier": 4904302666, "prover_cost": 19330265676592, "sequencer_cost": 4475415931013 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 950465744, + "protocol_fee": 950465744, "congestion_multiplier": 4904302666, "prover_cost": 197674293, "sequencer_cost": 45766297 @@ -46496,13 +46496,13 @@ "slot_of_change": 640 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 92742797830685, + "protocol_fee": 92742797830685, "congestion_multiplier": 4871282399, "prover_cost": 19452818860569, "sequencer_cost": 4503789905853 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 942427271, + "protocol_fee": 942427271, "congestion_multiplier": 4871282399, "prover_cost": 197674293, "sequencer_cost": 45766297 @@ -46550,13 +46550,13 @@ "slot_of_change": 640 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 104867099106619, + "protocol_fee": 104867099106619, "congestion_multiplier": 4955829811, "prover_cost": 20199646338176, "sequencer_cost": 6309860929043 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 1061475159, + "protocol_fee": 1061475159, "congestion_multiplier": 4955829811, "prover_cost": 204462820, "sequencer_cost": 63869037 @@ -46604,13 +46604,13 @@ "slot_of_change": 640 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 105732516206493, + "protocol_fee": 105732516206493, "congestion_multiplier": 5014400185, "prover_cost": 20069197828168, "sequencer_cost": 6269112098951 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 1077191456, + "protocol_fee": 1077191456, "congestion_multiplier": 5014400185, "prover_cost": 204462820, "sequencer_cost": 63869037 @@ -46658,13 +46658,13 @@ "slot_of_change": 640 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 106660787270049, + "protocol_fee": 106660787270049, "congestion_multiplier": 5049239278, "prover_cost": 20071205364002, "sequencer_cost": 6269739202600 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 1086539894, + "protocol_fee": 1086539894, "congestion_multiplier": 5049239278, "prover_cost": 204462820, "sequencer_cost": 63869037 @@ -46712,13 +46712,13 @@ "slot_of_change": 645 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 100731604616487, + "protocol_fee": 100731604616487, "congestion_multiplier": 4857033114, "prover_cost": 19900065015456, "sequencer_cost": 6216279266688 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 1034964857, + "protocol_fee": 1034964857, "congestion_multiplier": 4857033114, "prover_cost": 204462820, "sequencer_cost": 63869037 @@ -46766,13 +46766,13 @@ "slot_of_change": 645 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 106523942730624, + "protocol_fee": 106523942730624, "congestion_multiplier": 5076375470, "prover_cost": 19912012827811, "sequencer_cost": 6220011462446 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 1093821399, + "protocol_fee": 1093821399, "congestion_multiplier": 5076375470, "prover_cost": 204462820, "sequencer_cost": 63869037 @@ -46820,13 +46820,13 @@ "slot_of_change": 645 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 110959287185873, + "protocol_fee": 110959287185873, "congestion_multiplier": 4944080691, "prover_cost": 20457765660676, "sequencer_cost": 7675352285161 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 1139364913, + "protocol_fee": 1139364913, "congestion_multiplier": 4944080691, "prover_cost": 210066782, "sequencer_cost": 78812935 @@ -46874,13 +46874,13 @@ "slot_of_change": 645 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 112712267261374, + "protocol_fee": 112712267261374, "congestion_multiplier": 5017608671, "prover_cost": 20400644416575, "sequencer_cost": 7653921515119 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 1160605655, + "protocol_fee": 1160605655, "congestion_multiplier": 5017608671, "prover_cost": 210066782, "sequencer_cost": 78812935 @@ -46928,13 +46928,13 @@ "slot_of_change": 645 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 113385125056922, + "protocol_fee": 113385125056922, "congestion_multiplier": 5054525423, "prover_cost": 20335571793887, "sequencer_cost": 7629507543842 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 1171270156, + "protocol_fee": 1171270156, "congestion_multiplier": 5054525423, "prover_cost": 210066782, "sequencer_cost": 78812935 @@ -46982,13 +46982,13 @@ "slot_of_change": 650 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 110115315306812, + "protocol_fee": 110115315306812, "congestion_multiplier": 4957288651, "prover_cost": 20234399950837, "sequencer_cost": 7591549853367 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 1143180425, + "protocol_fee": 1143180425, "congestion_multiplier": 4957288651, "prover_cost": 210066782, "sequencer_cost": 78812935 @@ -47036,13 +47036,13 @@ "slot_of_change": 650 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 109542112911673, + "protocol_fee": 109542112911673, "congestion_multiplier": 4922123023, "prover_cost": 20309546909469, "sequencer_cost": 7619743517828 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 1133021788, + "protocol_fee": 1133021788, "congestion_multiplier": 4922123023, "prover_cost": 210066782, "sequencer_cost": 78812935 @@ -47090,13 +47090,13 @@ "slot_of_change": 650 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 107088401058012, + "protocol_fee": 107088401058012, "congestion_multiplier": 4989548246, "prover_cost": 19973852943482, "sequencer_cost": 6868384455145 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 1111076108, + "protocol_fee": 1111076108, "congestion_multiplier": 4989548246, "prover_cost": 207235056, "sequencer_cost": 71261666 @@ -47144,13 +47144,13 @@ "slot_of_change": 650 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 106042953019227, + "protocol_fee": 106042953019227, "congestion_multiplier": 4943489127, "prover_cost": 20009871540397, "sequencer_cost": 6880770126145 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 1098248795, + "protocol_fee": 1098248795, "congestion_multiplier": 4943489127, "prover_cost": 207235056, "sequencer_cost": 71261666 @@ -47198,13 +47198,13 @@ "slot_of_change": 650 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 104195961998913, + "protocol_fee": 104195961998913, "congestion_multiplier": 4881778148, "prover_cost": 19973920323323, "sequencer_cost": 6868407624969 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 1081062489, + "protocol_fee": 1081062489, "congestion_multiplier": 4881778148, "prover_cost": 207235056, "sequencer_cost": 71261666 @@ -47252,13 +47252,13 @@ "slot_of_change": 655 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 104893882474211, + "protocol_fee": 104893882474211, "congestion_multiplier": 4914812701, "prover_cost": 19938032839659, "sequencer_cost": 6856067039724 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 1090262504, + "protocol_fee": 1090262504, "congestion_multiplier": 4914812701, "prover_cost": 207235056, "sequencer_cost": 71261666 @@ -47306,13 +47306,13 @@ "slot_of_change": 655 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 105295679690440, + "protocol_fee": 105295679690440, "congestion_multiplier": 4938453746, "prover_cost": 19894266802844, "sequencer_cost": 6841017266013 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 1096846458, + "protocol_fee": 1096846458, "congestion_multiplier": 4938453746, "prover_cost": 207235056, "sequencer_cost": 71261666 @@ -47360,13 +47360,13 @@ "slot_of_change": 655 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 102938128153978, + "protocol_fee": 102938128153978, "congestion_multiplier": 4965769800, "prover_cost": 19604258378670, "sequencer_cost": 6352399062455 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 1078936417, + "protocol_fee": 1078936417, "congestion_multiplier": 4965769800, "prover_cost": 205480211, "sequencer_cost": 66582080 @@ -47414,13 +47414,13 @@ "slot_of_change": 655 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 104265256448033, + "protocol_fee": 104265256448033, "congestion_multiplier": 5007257633, "prover_cost": 19651422962208, "sequencer_cost": 6367681877568 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 1090223692, + "protocol_fee": 1090223692, "congestion_multiplier": 5007257633, "prover_cost": 205480211, "sequencer_cost": 66582080 @@ -47468,13 +47468,13 @@ "slot_of_change": 655 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 104426190443505, + "protocol_fee": 104426190443505, "congestion_multiplier": 4998191679, "prover_cost": 19726383684681, "sequencer_cost": 6391971519847 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 1087757188, + "protocol_fee": 1087757188, "congestion_multiplier": 4998191679, "prover_cost": 205480211, "sequencer_cost": 66582080 @@ -47522,13 +47522,13 @@ "slot_of_change": 660 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 103870507198438, + "protocol_fee": 103870507198438, "congestion_multiplier": 5007935725, "prover_cost": 19573710308814, "sequencer_cost": 6342500522731 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 1090408175, + "protocol_fee": 1090408175, "congestion_multiplier": 5007935725, "prover_cost": 205480211, "sequencer_cost": 66582080 @@ -47576,13 +47576,13 @@ "slot_of_change": 660 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 102442349148892, + "protocol_fee": 102442349148892, "congestion_multiplier": 4961129803, "prover_cost": 19532692225430, "sequencer_cost": 6329209367850 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 1077674049, + "protocol_fee": 1077674049, "congestion_multiplier": 4961129803, "prover_cost": 205480211, "sequencer_cost": 66582080 @@ -47630,13 +47630,13 @@ "slot_of_change": 660 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 97224294980917, + "protocol_fee": 97224294980917, "congestion_multiplier": 5050694705, "prover_cost": 19037906271499, "sequencer_cost": 4963975397006 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 1021758311, + "protocol_fee": 1021758311, "congestion_multiplier": 5050694705, "prover_cost": 200074878, "sequencer_cost": 52167857 @@ -47684,13 +47684,13 @@ "slot_of_change": 660 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 95285846079672, + "protocol_fee": 95285846079672, "congestion_multiplier": 4975490239, "prover_cost": 19011290475687, "sequencer_cost": 4957035550066 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 1002788530, + "protocol_fee": 1002788530, "congestion_multiplier": 4975490239, "prover_cost": 200074878, "sequencer_cost": 52167857 @@ -47738,13 +47738,13 @@ "slot_of_change": 660 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 94411219948862, + "protocol_fee": 94411219948862, "congestion_multiplier": 4930333454, "prover_cost": 19053207883172, "sequencer_cost": 4967965164725 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 991398059, + "protocol_fee": 991398059, "congestion_multiplier": 4930333454, "prover_cost": 200074878, "sequencer_cost": 52167857 @@ -47792,13 +47792,13 @@ "slot_of_change": 665 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 96163334845322, + "protocol_fee": 96163334845322, "congestion_multiplier": 4988861748, "prover_cost": 19122048971208, "sequencer_cost": 4985914904704 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 1006161396, + "protocol_fee": 1006161396, "congestion_multiplier": 4988861748, "prover_cost": 200074878, "sequencer_cost": 52167857 @@ -47846,13 +47846,13 @@ "slot_of_change": 665 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 94227730736008, + "protocol_fee": 94227730736008, "congestion_multiplier": 4925379581, "prover_cost": 19040176390700, "sequencer_cost": 4964567311669 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 990148481, + "protocol_fee": 990148481, "congestion_multiplier": 4925379581, "prover_cost": 200074878, "sequencer_cost": 52167857 @@ -47900,13 +47900,13 @@ "slot_of_change": 665 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 92918839272645, + "protocol_fee": 92918839272645, "congestion_multiplier": 4856211810, "prover_cost": 19042586120141, "sequencer_cost": 5053299668632 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 978152068, + "protocol_fee": 978152068, "congestion_multiplier": 4856211810, "prover_cost": 200460371, "sequencer_cost": 53195838 @@ -47954,13 +47954,13 @@ "slot_of_change": 665 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 95842837473538, + "protocol_fee": 95842837473538, "congestion_multiplier": 4981935324, "prover_cost": 19021663457807, "sequencer_cost": 5047747456240 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 1010042618, + "protocol_fee": 1010042618, "congestion_multiplier": 4981935324, "prover_cost": 200460371, "sequencer_cost": 53195838 @@ -48008,13 +48008,13 @@ "slot_of_change": 665 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 91170824248356, + "protocol_fee": 91170824248356, "congestion_multiplier": 4814344034, "prover_cost": 18889438659805, "sequencer_cost": 5012659179694 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 967532047, + "protocol_fee": 967532047, "congestion_multiplier": 4814344034, "prover_cost": 200460371, "sequencer_cost": 53195838 @@ -48062,13 +48062,13 @@ "slot_of_change": 670 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 91558870008821, + "protocol_fee": 91558870008821, "congestion_multiplier": 4832494068, "prover_cost": 18879998926312, "sequencer_cost": 5010154173187 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 972135916, + "protocol_fee": 972135916, "congestion_multiplier": 4832494068, "prover_cost": 200460371, "sequencer_cost": 53195838 @@ -48116,13 +48116,13 @@ "slot_of_change": 670 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 91564874548351, + "protocol_fee": 91564874548351, "congestion_multiplier": 4859574542, "prover_cost": 18748758035034, "sequencer_cost": 4975326994346 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 979005046, + "protocol_fee": 979005046, "congestion_multiplier": 4859574542, "prover_cost": 200460371, "sequencer_cost": 53195838 @@ -48170,13 +48170,13 @@ "slot_of_change": 670 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 90708737391252, + "protocol_fee": 90708737391252, "congestion_multiplier": 4931087654, "prover_cost": 18517869401280, "sequencer_cost": 4556848178765 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 974118591, + "protocol_fee": 974118591, "congestion_multiplier": 4931087654, "prover_cost": 198862881, "sequencer_cost": 48935865 @@ -48224,13 +48224,13 @@ "slot_of_change": 670 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 92858055272739, + "protocol_fee": 92858055272739, "congestion_multiplier": 5029464922, "prover_cost": 18493828566944, "sequencer_cost": 4550932248061 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 998496354, + "protocol_fee": 998496354, "congestion_multiplier": 5029464922, "prover_cost": 198862881, "sequencer_cost": 48935865 @@ -48278,13 +48278,13 @@ "slot_of_change": 670 }, "mana_base_fee_components_in_fee_asset": { - "congestion_cost": 92133043710234, + "protocol_fee": 92133043710234, "congestion_multiplier": 4959622753, "prover_cost": 18673091728474, "sequencer_cost": 4595045044919 }, "mana_base_fee_components_in_wei": { - "congestion_cost": 981189552, + "protocol_fee": 981189552, "congestion_multiplier": 4959622753, "prover_cost": 198862881, "sequencer_cost": 48935865 diff --git a/l1-contracts/test/rollup/libraries/rewardlib/RewardLibBase.sol b/l1-contracts/test/rollup/libraries/rewardlib/RewardLibBase.sol index fd12ca8cdf24..3c875f9ea243 100644 --- a/l1-contracts/test/rollup/libraries/rewardlib/RewardLibBase.sol +++ b/l1-contracts/test/rollup/libraries/rewardlib/RewardLibBase.sol @@ -55,7 +55,7 @@ contract RewardLibBase is TestBase { // These tests call RewardLib directly instead of going through proposal, so seed the temp checkpoint // logs that proposal would normally write before handleRewardsAndFees reads them. FeeHeader memory feeHeader = - FeeHeader({excessMana: 0, manaUsed: 0, ethPerFeeAsset: 0, congestionCost: 0, proverCost: 0}); + FeeHeader({excessMana: 0, manaUsed: 0, ethPerFeeAsset: 0, protocolFee: 0, proverCost: 0}); for (uint256 i = 0; i < _count; i++) { wrapper.addFeeHeader(feeHeader); diff --git a/l1-contracts/test/rollup/libraries/rewardlib/RewardLibWrapper.sol b/l1-contracts/test/rollup/libraries/rewardlib/RewardLibWrapper.sol index 6f54d87b95c1..658757e68333 100644 --- a/l1-contracts/test/rollup/libraries/rewardlib/RewardLibWrapper.sol +++ b/l1-contracts/test/rollup/libraries/rewardlib/RewardLibWrapper.sol @@ -128,6 +128,14 @@ contract RewardLibWrapper { currentEpoch = _epoch; } + function updateProtocolFeeRecipient(address _recipient) external returns (address) { + return RewardLib.updateProtocolFeeRecipient(_recipient); + } + + function getProtocolFeeRecipient() external view returns (address) { + return RewardLib.getProtocolFeeRecipient(); + } + function handleRewardsAndFees(SubmitEpochRootProofArgs calldata _args, Epoch _endEpoch) external { RewardLib.handleRewardsAndFees(_args, _endEpoch); } diff --git a/l1-contracts/test/rollup/libraries/rewardlib/waterfallIdentity.t.sol b/l1-contracts/test/rollup/libraries/rewardlib/waterfallIdentity.t.sol new file mode 100644 index 000000000000..f75125fa19be --- /dev/null +++ b/l1-contracts/test/rollup/libraries/rewardlib/waterfallIdentity.t.sol @@ -0,0 +1,120 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2026 Aztec Labs. +pragma solidity >=0.8.27; + +import {RewardLibBase} from "./RewardLibBase.sol"; +import {Epoch} from "@aztec/core/libraries/TimeLib.sol"; +import {FeeHeader} from "@aztec/core/libraries/compressed-data/fees/FeeStructs.sol"; +import {FeeLib, ManaMinFeeComponents} from "@aztec/core/libraries/rollup/FeeLib.sol"; + +/** + * @title WaterfallIdentityTest + * @notice The AZIP waterfall identity: for randomized per-mana components (covering every + * (mu, gas, price) combination the fee model can produce), mana used, and injected + * priority tips, + * + * fee - protocolFee == (sequencerCost + proverCost) * manaUsed + tips EXACTLY + * prover tranche == proverCost * manaUsed EXACTLY + * sequencer tranche == sequencerCost * manaUsed + tips EXACTLY + * protocol tranche == headerProtocolFee * manaUsed, paid to the live recipient + * + * The header's per-mana protocol fee is produced by the real one-subtraction helper + * (FeeLib.protocolFeePerMana) and the split by the real waterfall + * (RewardLib.handleRewardsAndFees), so a wei of drift anywhere fails the exact asserts. + */ +contract WaterfallIdentityTest is RewardLibBase { + struct Vals { + uint256 s; + uint256 p; + uint256 c; + uint256 manaUsed; + uint256 tips; + uint256 headerProtocolFee; + uint256 fee; + uint256 protocolTranche; + uint256 proverTranche; + uint256 sequencerTranche; + } + + /// @dev Bounds keep every header field inside its compressed width (proverCost uint63, + /// protocolFee uint64, manaUsed uint32) so compression cannot saturate and mask a drift. + function test_waterfallIdentity( + uint64 _sequencerCost, + uint64 _proverCost, + uint64 _protocolFee, + uint32 _manaUsed, + uint96 _tips, + uint32 _sequencerBps + ) external prepare(0, _sequencerBps) { + Vals memory v; + v.s = bound(_sequencerCost, 0, 2 ** 62); + v.p = bound(_proverCost, 0, 2 ** 62); + v.c = bound(_protocolFee, 0, 2 ** 63); + v.manaUsed = _manaUsed; + v.tips = _tips; + + // The real one-subtraction helper produces the header value from the components. + ManaMinFeeComponents memory components = + ManaMinFeeComponents({sequencerCost: v.s, proverCost: v.p, protocolFee: v.c, congestionMultiplier: 0}); + v.headerProtocolFee = FeeLib.protocolFeePerMana(components); + v.fee = FeeLib.summedMinFee(components) * v.manaUsed + v.tips; + + // Checkpoint 0 keeps the zeroed genesis header; checkpoint 1 carries the fuzzed values. + wrapper.addFeeHeader( + FeeHeader({ + excessMana: 0, manaUsed: v.manaUsed, ethPerFeeAsset: 0, protocolFee: v.headerProtocolFee, proverCost: v.p + }) + ); + _setHeaders(2, sequencer); + args.headers[1].accumulatedFees = v.fee; + args.end = args.start + 1; + + address recipient = makeAddr("protocolFeeRecipient"); + wrapper.updateProtocolFeeRecipient(recipient); + + deal(address(feeAsset), address(feePortal), v.fee); + + wrapper.handleRewardsAndFees(args, Epoch.wrap(0)); + + v.protocolTranche = feeAsset.balanceOf(recipient); + v.proverTranche = wrapper.getCollectiveProverRewardsForEpoch(Epoch.wrap(0)); + v.sequencerTranche = wrapper.getSequencerRewards(sequencer); + + assertEq(v.protocolTranche, v.headerProtocolFee * v.manaUsed, "protocol tranche mismatch"); + assertEq( + v.fee - v.protocolTranche, + (v.s + v.p) * v.manaUsed + v.tips, + "fee - protocolFee must equal cost * manaUsed + tips" + ); + assertEq(v.proverTranche, v.p * v.manaUsed, "prover tranche must be exactly proverCost * manaUsed"); + assertEq(v.sequencerTranche, v.s * v.manaUsed + v.tips, "sequencer tranche must be cost remainder + tips"); + assertEq(v.protocolTranche + v.proverTranche + v.sequencerTranche, v.fee, "waterfall must be exhaustive"); + } + + /// @notice After a recipient change, the very next waterfall run pays the NEW recipient and the + /// old burn-address default receives nothing. + function test_waterfallPaysUpdatedRecipient() external prepare(0, 5000) { + uint256 manaUsed = 1e6; + uint256 protocolFeePerMana = 1e9; + uint256 fee = 5e9 * manaUsed; + + wrapper.addFeeHeader( + FeeHeader({excessMana: 0, manaUsed: manaUsed, ethPerFeeAsset: 0, protocolFee: protocolFeePerMana, proverCost: 0}) + ); + _setHeaders(2, sequencer); + args.headers[1].accumulatedFees = fee; + args.end = args.start + 1; + + address oldRecipient = wrapper.getProtocolFeeRecipient(); + assertEq(oldRecipient, address(bytes20("CUAUHXICALLI")), "default must be the burn address"); + + address newRecipient = makeAddr("newRecipient"); + assertEq(wrapper.updateProtocolFeeRecipient(newRecipient), oldRecipient, "must return the old recipient"); + + deal(address(feeAsset), address(feePortal), fee); + wrapper.handleRewardsAndFees(args, Epoch.wrap(0)); + + assertEq(feeAsset.balanceOf(newRecipient), protocolFeePerMana * manaUsed, "new recipient must be paid"); + assertEq(feeAsset.balanceOf(oldRecipient), 0, "old recipient must receive nothing"); + } +} diff --git a/labs-patches/0006-feat-introduce-a-protocol-fee-margin-AZIP-23.patch b/labs-patches/0006-feat-introduce-a-protocol-fee-margin-AZIP-23.patch new file mode 100644 index 000000000000..5d5977f8db34 --- /dev/null +++ b/labs-patches/0006-feat-introduce-a-protocol-fee-margin-AZIP-23.patch @@ -0,0 +1,720 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: aminsammara +Date: Fri, 28 Aug 2026 00:00:00 +0000 +Subject: [PATCH] feat: introduce a protocol fee margin (AZIP-23) + +--- +diff --git a/yarn-project/aztec-node/src/aztec-node/node_public_calls_simulator.test.ts b/yarn-project/aztec-node/src/aztec-node/node_public_calls_simulator.test.ts +index 3fc1008c01..86dfd888d7 100644 +--- a/yarn-project/aztec-node/src/aztec-node/node_public_calls_simulator.test.ts ++++ b/yarn-project/aztec-node/src/aztec-node/node_public_calls_simulator.test.ts +@@ -445,7 +445,7 @@ describe('NodePublicCallsSimulator', () => { + }); + + function makeFeeHeader(): FeeHeader { +- return { excessMana: 0n, manaUsed: 0n, ethPerFeeAsset: 0n, congestionCost: 0n, proverCost: 0n }; ++ return { excessMana: 0n, manaUsed: 0n, ethPerFeeAsset: 0n, protocolFee: 0n, proverCost: 0n }; + } + + function makeProposedCheckpointData(args: { +diff --git a/yarn-project/end-to-end/src/single-node/fees/fees_test.ts b/yarn-project/end-to-end/src/single-node/fees/fees_test.ts +index 8a0d733c7d..0e661ba2ba 100644 +--- a/yarn-project/end-to-end/src/single-node/fees/fees_test.ts ++++ b/yarn-project/end-to-end/src/single-node/fees/fees_test.ts +@@ -381,13 +381,14 @@ export class FeesTest extends SingleNodeTestContext { + return feeHeader.manaUsed * feeHeader.proverCost; + }; + +- // RewardLib computes sequencerFee = checkpointFee - burn - proverFee where burn = manaUsed * congestionCost. +- // The fixture's typical case keeps congestionCost at zero, but reading it explicitly avoids latent bugs +- // when test load changes excess mana. ++ // RewardLib computes sequencerFee = checkpointFee - protocolFee - proverFee where ++ // protocolFee = manaUsed * feeHeader.protocolFee. The fixture's typical case keeps the ++ // protocol fee at zero, but reading it explicitly avoids latent bugs when test load changes ++ // excess mana. + this.getCommittedBurn = async (blockNumber: BlockNumber) => { + const block = await this.aztecNode.getBlock(blockNumber); + const feeHeader = await this.rollupContract.getFeeHeader(BigInt(block!.checkpointNumber)); +- return feeHeader.manaUsed * feeHeader.congestionCost; ++ return feeHeader.manaUsed * feeHeader.protocolFee; + }; + } + +diff --git a/yarn-project/ethereum/src/contracts/fee_asset_price_oracle.test.ts b/yarn-project/ethereum/src/contracts/fee_asset_price_oracle.test.ts +index 4e56319a2a..a9066db971 100644 +--- a/yarn-project/ethereum/src/contracts/fee_asset_price_oracle.test.ts ++++ b/yarn-project/ethereum/src/contracts/fee_asset_price_oracle.test.ts +@@ -112,7 +112,7 @@ describe('Uniswap Price Oracle', () => { + expect(modifier).toBe(49n); + + const child = RollupContract.computeChildFeeHeader( +- { excessMana: 0n, manaUsed: 0n, ethPerFeeAsset: predictedParentE12, congestionCost: 0n, proverCost: 0n }, ++ { excessMana: 0n, manaUsed: 0n, ethPerFeeAsset: predictedParentE12, protocolFee: 0n, proverCost: 0n }, + 0n, + modifier, + 100n, +diff --git a/yarn-project/ethereum/src/contracts/rollup.test.ts b/yarn-project/ethereum/src/contracts/rollup.test.ts +index 52069c7496..95fd12af0e 100644 +--- a/yarn-project/ethereum/src/contracts/rollup.test.ts ++++ b/yarn-project/ethereum/src/contracts/rollup.test.ts +@@ -22,7 +22,7 @@ import { type FeeHeader, RollupContract, TempCheckpointLogField } from './rollup + describe('compressFeeHeader', () => { + /** Creates a zero fee header with the given overrides. */ + function makeFeeHeader(overrides: Partial = {}): FeeHeader { +- return { manaUsed: 0n, excessMana: 0n, ethPerFeeAsset: 0n, congestionCost: 0n, proverCost: 0n, ...overrides }; ++ return { manaUsed: 0n, excessMana: 0n, ethPerFeeAsset: 0n, protocolFee: 0n, proverCost: 0n, ...overrides }; + } + + it('sets the preheat flag (bit 255)', () => { +@@ -62,15 +62,15 @@ describe('compressFeeHeader', () => { + expect((result >> 80n) & ((1n << 48n) - 1n)).toBe(999n); + }); + +- it('packs congestionCost into bits [128:191]', () => { +- const header = makeFeeHeader({ congestionCost: 42n }); ++ it('packs protocolFee into bits [128:191]', () => { ++ const header = makeFeeHeader({ protocolFee: 42n }); + const result = RollupContract.compressFeeHeader(header); + expect((result >> 128n) & ((1n << 64n) - 1n)).toBe(42n); + }); + +- it('clamps congestionCost to 64 bits', () => { ++ it('clamps protocolFee to 64 bits', () => { + const maxValue = (1n << 64n) - 1n; +- const header = makeFeeHeader({ congestionCost: maxValue + 1n }); ++ const header = makeFeeHeader({ protocolFee: maxValue + 1n }); + const result = RollupContract.compressFeeHeader(header); + expect((result >> 128n) & maxValue).toBe(maxValue); + }); +@@ -93,7 +93,7 @@ describe('compressFeeHeader', () => { + manaUsed: 1000n, + excessMana: 2000n, + ethPerFeeAsset: 3000n, +- congestionCost: 4000n, ++ protocolFee: 4000n, + proverCost: 5000n, + }); + const result = RollupContract.compressFeeHeader(header); +@@ -122,7 +122,7 @@ describe('computeChildFeeHeader', () => { + manaUsed: 5000n, + excessMana: 3000n, + ethPerFeeAsset: 1000n, +- congestionCost: 100n, ++ protocolFee: 100n, + proverCost: 200n, + }; + +@@ -144,9 +144,9 @@ describe('computeChildFeeHeader', () => { + expect(result.manaUsed).toBe(7777n); + }); + +- it('always sets congestionCost and proverCost to zero', () => { ++ it('always sets protocolFee and proverCost to zero', () => { + const result = RollupContract.computeChildFeeHeader(baseFeeHeader, 0n, 0n, manaTarget); +- expect(result.congestionCost).toBe(0n); ++ expect(result.protocolFee).toBe(0n); + expect(result.proverCost).toBe(0n); + }); + +@@ -217,14 +217,14 @@ describe('computeChildFeeHeader', () => { + manaUsed: 8000n, + excessMana: 15000n, + ethPerFeeAsset: 5000n, +- congestionCost: 999n, ++ protocolFee: 999n, + proverCost: 888n, + }; + const result = RollupContract.computeChildFeeHeader(parent, 42n, 250n, manaTarget); + expect(result.excessMana).toBe(13000n); + expect(result.manaUsed).toBe(42n); + expect(result.ethPerFeeAsset).toBe(5125n); +- expect(result.congestionCost).toBe(0n); ++ expect(result.protocolFee).toBe(0n); + expect(result.proverCost).toBe(0n); + }); + }); +@@ -425,7 +425,7 @@ describe('Rollup', () => { + manaUsed: 12345n, + excessMana: 67890n, + ethPerFeeAsset: 1_000_000_000_000n, +- congestionCost: 99999n, ++ protocolFee: 99999n, + proverCost: 55555n, + } as FeeHeader, + }; +@@ -561,7 +561,7 @@ describe('Rollup', () => { + manaUsed: 12345n, + excessMana: 67890n, + ethPerFeeAsset: 1_000_000_000_000n, +- congestionCost: 99999n, ++ protocolFee: 99999n, + proverCost: 55555n, + }; + +@@ -580,7 +580,7 @@ describe('Rollup', () => { + expect(result.manaUsed).toBe(feeHeader.manaUsed); + expect(result.excessMana).toBe(feeHeader.excessMana); + expect(result.ethPerFeeAsset).toBe(feeHeader.ethPerFeeAsset); +- expect(result.congestionCost).toBe(feeHeader.congestionCost); ++ expect(result.protocolFee).toBe(feeHeader.protocolFee); + expect(result.proverCost).toBe(feeHeader.proverCost); + }); + }); +diff --git a/yarn-project/ethereum/src/contracts/rollup.ts b/yarn-project/ethereum/src/contracts/rollup.ts +index af17f8d37c..e17fa5e771 100644 +--- a/yarn-project/ethereum/src/contracts/rollup.ts ++++ b/yarn-project/ethereum/src/contracts/rollup.ts +@@ -114,7 +114,7 @@ export type FeeHeader = { + excessMana: bigint; + manaUsed: bigint; + ethPerFeeAsset: bigint; +- congestionCost: bigint; ++ protocolFee: bigint; + proverCost: bigint; + }; + +@@ -177,7 +177,7 @@ export type TempCheckpointLogOverrideFields = { + export type ManaMinFeeComponents = { + sequencerCost: bigint; + proverCost: bigint; +- congestionCost: bigint; ++ protocolFee: bigint; + congestionMultiplier: bigint; + }; + +@@ -432,6 +432,16 @@ export class RollupContract { + return this.rollup.read.getProvingCostPerManaInFeeAsset(); + } + ++ /** Returns the current protocol fee margin in basis points. Not memoized: governance can change it. */ ++ getProtocolFeeMargin(): Promise { ++ return this.rollup.read.getProtocolFeeMargin(); ++ } ++ ++ /** Returns the current recipient of the protocol fee tranche. Not memoized: governance can change it. */ ++ async getProtocolFeeRecipient(): Promise { ++ return EthAddress.fromString(await this.rollup.read.getProtocolFeeRecipient()); ++ } ++ + @memoize + getManaLimit(): Promise { + return this.rollup.read.getManaLimit(); +@@ -636,7 +646,7 @@ export class RollupContract { + excessMana: result.excessMana, + manaUsed: result.manaUsed, + ethPerFeeAsset: result.ethPerFeeAsset, +- congestionCost: result.congestionCost, ++ protocolFee: result.protocolFee, + proverCost: result.proverCost, + }; + } +@@ -729,7 +739,7 @@ export class RollupContract { + excessMana: result.feeHeader.excessMana, + manaUsed: result.feeHeader.manaUsed, + ethPerFeeAsset: result.feeHeader.ethPerFeeAsset, +- congestionCost: result.feeHeader.congestionCost, ++ protocolFee: result.feeHeader.protocolFee, + proverCost: result.feeHeader.proverCost, + }, + }; +@@ -1079,7 +1089,7 @@ export class RollupContract { + let value = BigInt(feeHeader.manaUsed) & ((1n << 32n) - 1n); // bits [0:31] + value |= (feeHeader.excessMana < MASK_48_BITS ? feeHeader.excessMana : MASK_48_BITS) << 32n; // bits [32:79] + value |= (BigInt(feeHeader.ethPerFeeAsset) & MASK_48_BITS) << 80n; // bits [80:127] +- value |= (feeHeader.congestionCost < MASK_64_BITS ? feeHeader.congestionCost : MASK_64_BITS) << 128n; // bits [128:191] ++ value |= (feeHeader.protocolFee < MASK_64_BITS ? feeHeader.protocolFee : MASK_64_BITS) << 128n; // bits [128:191] + value |= (feeHeader.proverCost < MASK_63_BITS ? feeHeader.proverCost : MASK_63_BITS) << 192n; // bits [192:254] + value |= 1n << 255n; // preheat flag + return value; +@@ -1121,7 +1131,7 @@ export class RollupContract { + excessMana, + manaUsed: childManaUsed, + ethPerFeeAsset: newPrice, +- congestionCost: 0n, ++ protocolFee: 0n, + proverCost: 0n, + }; + } +@@ -1183,7 +1193,7 @@ export class RollupContract { + return { + sequencerCost: result.sequencerCost, + proverCost: result.proverCost, +- congestionCost: result.congestionCost, ++ protocolFee: result.protocolFee, + congestionMultiplier: result.congestionMultiplier, + }; + } +diff --git a/yarn-project/ethereum/src/test/chain_monitor.ts b/yarn-project/ethereum/src/test/chain_monitor.ts +index c73e49f852..302cf4ab36 100644 +--- a/yarn-project/ethereum/src/test/chain_monitor.ts ++++ b/yarn-project/ethereum/src/test/chain_monitor.ts +@@ -12,7 +12,7 @@ import type { ViemClient } from '../types.js'; + + /** L2 fee data reported by the chain monitor. */ + export type L2FeeData = ManaMinFeeComponents & { +- /** Total minimum fee per mana in Fee Juice (sum of sequencerCost + proverCost + congestionCost). */ ++ /** Total minimum fee per mana in Fee Juice (sum of sequencerCost + proverCost + protocolFee). */ + minFeePerMana: bigint; + /** L1 base fee observed by the oracle. */ + l1BaseFee: bigint; +@@ -381,7 +381,7 @@ export class ChainMonitor extends EventEmitter { + return ( + this.l2FeeData.sequencerCost !== newData.sequencerCost || + this.l2FeeData.proverCost !== newData.proverCost || +- this.l2FeeData.congestionCost !== newData.congestionCost || ++ this.l2FeeData.protocolFee !== newData.protocolFee || + this.l2FeeData.l1BaseFee !== newData.l1BaseFee || + this.l2FeeData.l1BlobFee !== newData.l1BlobFee || + this.l2FeeData.ethPerFeeAsset !== newData.ethPerFeeAsset +diff --git a/yarn-project/ethereum/src/test/rollup_cheat_codes.ts b/yarn-project/ethereum/src/test/rollup_cheat_codes.ts +index e2823cd86c..a9fb3f839f 100644 +--- a/yarn-project/ethereum/src/test/rollup_cheat_codes.ts ++++ b/yarn-project/ethereum/src/test/rollup_cheat_codes.ts +@@ -374,6 +374,30 @@ export class RollupCheatCodes { + }); + } + ++ /** ++ * Sets the protocol fee margin (in basis points). Throws if the on-chain tx reverts ++ * (e.g. rate-limit cooldown or step cap) instead of silently succeeding. ++ * @param bps - The new protocol fee margin in basis points ++ */ ++ public async setProtocolFeeMargin(bps: number) { ++ await this.asOwner(async (account, rollup) => { ++ const hash = await rollup.write.setProtocolFeeMargin([bps], { ++ account, ++ chain: this.client.chain, ++ gasLimit: 1000000n, ++ }); ++ const receipt = await this.client.waitForTransactionReceipt({ hash }); ++ if (receipt.status !== 'success') { ++ throw new Error( ++ `setProtocolFeeMargin(${bps}) reverted on L1 (tx ${hash}). ` + ++ `Likely FeeLib rate-limit (30-day cooldown or x3/2 step cap on the fee multiplier); ` + ++ `use clearProvingCostCooldown() between successive updates (it clears both cooldowns).`, ++ ); ++ } ++ this.logger.warn(`Updated protocol fee margin to ${bps} bps`); ++ }); ++ } ++ + /** + * Resets the 30-day proving-cost update cooldown enforced by FeeLib.updateProvingCostPerMana + * by zeroing `FeeStore.provingCostLastUpdate` directly in contract storage. Use between +@@ -384,7 +408,8 @@ export class RollupCheatCodes { + * l1-contracts/src/core/libraries/rollup/FeeLib.sol: + * slot + 0: CompressedFeeConfig config (uint256) + * slot + 1: L1GasOracleValues l1GasOracleValues (14+14+4 bytes, packed) +- * slot + 2: uint64 provingCostLastUpdate (only member — zeroing the slot is safe) ++ * slot + 2: uint64 provingCostLastUpdate + uint64 protocolMarginLastUpdate (packed -- ++ * zeroing the slot clears BOTH the proving-cost and protocol-fee-margin cooldowns) + * If the struct layout changes, update the offset below. + */ + public async clearProvingCostCooldown() { +diff --git a/yarn-project/prover-node/src/prover-node-publisher.test.ts b/yarn-project/prover-node/src/prover-node-publisher.test.ts +index f7a1e248dc..6fb4f20eb0 100644 +--- a/yarn-project/prover-node/src/prover-node-publisher.test.ts ++++ b/yarn-project/prover-node/src/prover-node-publisher.test.ts +@@ -73,7 +73,7 @@ describe('prover-node-publisher', () => { + excessMana: 0n, // unused + manaUsed: 0n, // unused + ethPerFeeAsset: 0n, // unused +- congestionCost: 0n, // unused ++ protocolFee: 0n, // unused + proverCost: 0n, // unused + }, + }), +@@ -244,7 +244,7 @@ describe('prover-node-publisher', () => { + blobCommitmentsHash: Buffer32.ZERO, + outHash: '0x', + slotNumber: SlotNumber(0), +- feeHeader: { excessMana: 0n, manaUsed: 0n, ethPerFeeAsset: 0n, congestionCost: 0n, proverCost: 0n }, ++ feeHeader: { excessMana: 0n, manaUsed: 0n, ethPerFeeAsset: 0n, protocolFee: 0n, proverCost: 0n }, + }), + ); + +@@ -311,7 +311,7 @@ describe('prover-node-publisher', () => { + excessMana: 0n, // unused + manaUsed: 0n, // unused + ethPerFeeAsset: 0n, // unused +- congestionCost: 0n, // unused ++ protocolFee: 0n, // unused + proverCost: 0n, // unused + }, + }), +diff --git a/yarn-project/sequencer-client/src/global_variable_builder/fee_predictor.test.ts b/yarn-project/sequencer-client/src/global_variable_builder/fee_predictor.test.ts +index c2707c9072..5f9ccc0bfb 100644 +--- a/yarn-project/sequencer-client/src/global_variable_builder/fee_predictor.test.ts ++++ b/yarn-project/sequencer-client/src/global_variable_builder/fee_predictor.test.ts +@@ -264,7 +264,7 @@ describe('FeePredictor', () => { + excessMana: newExcessMana, + manaUsed: assumedManaUsed, + ethPerFeeAsset: decayEthPerFeeAsset(currentFeeHeader.ethPerFeeAsset, i + 1), +- congestionCost: 0n, ++ protocolFee: 0n, + proverCost: 0n, + }; + +@@ -341,7 +341,7 @@ describe('FeePredictor', () => { + excessMana: newExcessMana, + manaUsed: 0n, + ethPerFeeAsset: decayedEthPerFeeAsset, +- congestionCost: 0n, ++ protocolFee: 0n, + proverCost: 0n, + }; + +@@ -359,6 +359,33 @@ describe('FeePredictor', () => { + nextCheckpointOffset++; + } + }, 60_000); ++ ++ it('slot 0 matches L1 getManaMinFeeAt with a nonzero protocol fee margin', async () => { ++ // Pin the comparison timestamp so before/after fees differ only by the margin. ++ const startSlot = await getPredictionStartSlot(); ++ const timestamp = getTimestamp(startSlot + 1n); ++ const feeBefore = await rollup.getManaMinFeeAt(timestamp, true); ++ ++ // The first-ever margin update bypasses the 30-day cooldown; from 0 the x3/2 step cap on the ++ // fee multiplier permits up to 5000 bps. ++ await rollupCheatCodes.setProtocolFeeMargin(5000); ++ expect(await rollup.getProtocolFeeMargin()).toBe(5000); ++ ++ // The margin must move the pinned fee. If L1 scaled both the fakeExponential factor and the ++ // mulDiv divisor, mu would cancel silently and this catches it. ++ const l1Fee = await rollup.getManaMinFeeAt(timestamp, true); ++ expect(l1Fee).toBeGreaterThan(feeBefore); ++ ++ // The predictor must agree with L1 exactly at mu != 0. This is the only check that catches ++ // the same factor+divisor double-scaling on the TS side of the mirror. ++ for (const manaUsage of Object.values(ManaUsageEstimate)) { ++ const predictor = new FeePredictor(rollup, dateProvider, feePredictorConfig); ++ const predicted = await predictor.getPredictedMinFees(manaUsage); ++ const predictionStartSlot = await getPredictionStartSlot(); ++ const l1FeeAtStart = await rollup.getManaMinFeeAt(getTimestamp(predictionStartSlot), true); ++ expect(predicted[0].feePerL2Gas).toBe(l1FeeAtStart); ++ } ++ }, 60_000); + }); + + describe('FeePredictor state caching', () => { +diff --git a/yarn-project/sequencer-client/src/global_variable_builder/fee_predictor.ts b/yarn-project/sequencer-client/src/global_variable_builder/fee_predictor.ts +index 86132e3b35..dc1b6389c6 100644 +--- a/yarn-project/sequencer-client/src/global_variable_builder/fee_predictor.ts ++++ b/yarn-project/sequencer-client/src/global_variable_builder/fee_predictor.ts +@@ -21,6 +21,7 @@ type FeeOracleState = { + manaLimit: bigint; + provingCostPerManaEth: bigint; + epochDuration: bigint; ++ protocolFeeMarginBps: bigint; + /** Pre-resolved L1 fees for each slot in the prediction window. */ + l1FeesBySlot: L1FeeData[]; + }; +@@ -75,11 +76,12 @@ export class FeePredictor { + const opts = { blockNumber }; + + // Cached constants don't need pinning +- const [manaTarget, manaLimit, provingCostPerManaEth, epochDuration] = await Promise.all([ ++ const [manaTarget, manaLimit, provingCostPerManaEth, epochDuration, protocolFeeMarginBps] = await Promise.all([ + this.rollupContract.getManaTarget(), + this.rollupContract.getManaLimit(), + this.rollupContract.getProvingCostPerMana(), + this.rollupContract.getEpochDuration(), ++ this.rollupContract.getProtocolFeeMargin(), + ]); + + // First, compute the earliest possible nextSlot independently of the checkpoint, so we can +@@ -115,6 +117,7 @@ export class FeePredictor { + manaLimit, + provingCostPerManaEth, + epochDuration: BigInt(epochDuration), ++ protocolFeeMarginBps: BigInt(protocolFeeMarginBps), + l1FeesBySlot, + }; + } +@@ -170,6 +173,7 @@ export class FeePredictor { + provingCostPerManaEth: state.provingCostPerManaEth, + excessMana, + ethPerFeeAsset, ++ protocolFeeMarginBps: state.protocolFeeMarginBps, + }), + ); + } +diff --git a/yarn-project/sequencer-client/src/sequencer/checkpoint_proposal_job.test.ts b/yarn-project/sequencer-client/src/sequencer/checkpoint_proposal_job.test.ts +index 1f6bf35348..7c73d4369e 100644 +--- a/yarn-project/sequencer-client/src/sequencer/checkpoint_proposal_job.test.ts ++++ b/yarn-project/sequencer-client/src/sequencer/checkpoint_proposal_job.test.ts +@@ -193,7 +193,7 @@ describe('CheckpointProposalJob', () => { + // Default rollup contract reads used by pipelined fee-header derivation. Tests that exercise + // the failure modes override these via jest.spyOn. + jest.spyOn(publisher.rollupContract, 'getCheckpoint').mockResolvedValue({ +- feeHeader: { manaUsed: 0n, excessMana: 0n, ethPerFeeAsset: 1n, congestionCost: 0n, proverCost: 0n }, ++ feeHeader: { manaUsed: 0n, excessMana: 0n, ethPerFeeAsset: 1n, protocolFee: 0n, proverCost: 0n }, + } as any); + jest.spyOn(publisher.rollupContract, 'getManaTarget').mockResolvedValue(10_000n); + publisher.sendRequestsAt.mockResolvedValue({ +diff --git a/yarn-project/sequencer-client/src/sequencer/sequencer.test.ts b/yarn-project/sequencer-client/src/sequencer/sequencer.test.ts +index 4eff6b3476..d2078d8a9e 100644 +--- a/yarn-project/sequencer-client/src/sequencer/sequencer.test.ts ++++ b/yarn-project/sequencer-client/src/sequencer/sequencer.test.ts +@@ -261,7 +261,7 @@ describe('sequencer', () => { + rollupContract.isEscapeHatchOpen.mockResolvedValue(false); + // Default rollup reads used by pipelined fee-header derivation. + rollupContract.getCheckpoint.mockResolvedValue({ +- feeHeader: { manaUsed: 0n, excessMana: 0n, ethPerFeeAsset: 1n, congestionCost: 0n, proverCost: 0n }, ++ feeHeader: { manaUsed: 0n, excessMana: 0n, ethPerFeeAsset: 1n, protocolFee: 0n, proverCost: 0n }, + } as any); + rollupContract.getManaTarget.mockResolvedValue(10_000n); + +diff --git a/yarn-project/stdlib/src/checkpoint/simulation_overrides.test.ts b/yarn-project/stdlib/src/checkpoint/simulation_overrides.test.ts +index 3c7e5bea83..d007259eea 100644 +--- a/yarn-project/stdlib/src/checkpoint/simulation_overrides.test.ts ++++ b/yarn-project/stdlib/src/checkpoint/simulation_overrides.test.ts +@@ -38,7 +38,7 @@ describe('computePipelinedParentFeeHeader', () => { + manaUsed: 3000n, + excessMana: 1000n, + ethPerFeeAsset: 500n, +- congestionCost: 50n, ++ protocolFee: 50n, + proverCost: 10n, + }; + +@@ -139,7 +139,7 @@ describe('buildCheckpointSimulationOverridesPlan', () => { + manaUsed: 3000n, + excessMana: 1000n, + ethPerFeeAsset: 500n, +- congestionCost: 50n, ++ protocolFee: 50n, + proverCost: 10n, + }; + +diff --git a/yarn-project/stdlib/src/gas/README.md b/yarn-project/stdlib/src/gas/README.md +index b98eef59ac..5d1779f772 100644 +--- a/yarn-project/stdlib/src/gas/README.md ++++ b/yarn-project/stdlib/src/gas/README.md +@@ -56,28 +56,35 @@ Updates to `provingCostPerMana` are rate-limited on L1 (`FeeLib.updateProvingCos + at most one update every 30 days, each moving the value by at most ×1.5 (or ÷1.5), with a + floor of 2 wei per mana. + +-### Congestion Cost ++### Protocol Fee + +-An exponential surcharge when the network is congested (inspired by EIP-1559; the +-implementation uses the `fakeExponential` Taylor series approximation from EIP-4844): ++The markup above operator cost: the governance-set protocol fee margin (basis points, applied ++through the congestion multiplier's factor) plus an exponential congestion surcharge when the ++network is congested (inspired by EIP-1559; the implementation uses the `fakeExponential` ++Taylor series approximation from EIP-4844): + + ``` +-baseCost = sequencerCost + proverCost +-congestionCost = floor(baseCost * congestionMultiplier / MINIMUM_CONGESTION_MULTIPLIER) - baseCost ++baseCost = sequencerCost + proverCost ++protocolFee = floor(baseCost * congestionMultiplier / MINIMUM_CONGESTION_MULTIPLIER) - baseCost + ``` + +-When there is no congestion the multiplier equals `MINIMUM_CONGESTION_MULTIPLIER` (1e9) +-and congestion cost is zero. ++At a zero margin and no congestion the multiplier equals `MINIMUM_CONGESTION_MULTIPLIER` (1e9) ++and the protocol fee is zero. + + ### Congestion Multiplier + + ``` + excessMana = max(0, prevExcessMana + prevManaUsed - manaTarget) + denominator = manaTarget * 854,700,854 / 1e8 ≈ 8.547 * manaTarget +-congestionMultiplier = fakeExponential(MINIMUM_CONGESTION_MULTIPLIER, ++congestionMultiplier = fakeExponential((10,000 + protocolFeeMarginBps) * 1e5, + min(excessMana, 100 * denominator), denominator) + ``` + ++The factor `(10,000 + protocolFeeMarginBps) * 1e5` equals `(1 + mu) * 1e9`, so the ++uncongested baseline is `(1 + mu) * MINIMUM_CONGESTION_MULTIPLIER` — exactly 1e9 at a zero ++margin. Only the factor scales with the margin; the divisor in the protocol fee formula stays ++`MINIMUM_CONGESTION_MULTIPLIER` (scaling both would cancel the margin). ++ + Each additional `manaTarget` of excess mana multiplies the fee by `e^(1/8.547) ≈ 1.124`, + i.e. ~12.5%. The exponent is capped at 100 (multiplier ≤ ~2.7e43 × the minimum) to keep + the Taylor series from overflowing. +@@ -85,7 +92,7 @@ the Taylor series from overflowing. + ### Total + + ``` +-minFeePerMana = sequencerCost + proverCost + congestionCost ++minFeePerMana = sequencerCost + proverCost + protocolFee + ``` + + Each component is converted from ETH to the fee asset individually (rounding up) before +diff --git a/yarn-project/stdlib/src/gas/fee_math.test.ts b/yarn-project/stdlib/src/gas/fee_math.test.ts +index e77dfb8a2d..a501fe652e 100644 +--- a/yarn-project/stdlib/src/gas/fee_math.test.ts ++++ b/yarn-project/stdlib/src/gas/fee_math.test.ts +@@ -65,12 +65,12 @@ describe('computeExcessMana', () => { + + describe('computeCongestionMultiplier', () => { + it('returns MINIMUM_CONGESTION_MULTIPLIER when excess is zero', () => { +- expect(computeCongestionMultiplier(0n, 100_000_000n)).toBe(MINIMUM_CONGESTION_MULTIPLIER); ++ expect(computeCongestionMultiplier(0n, 100_000_000n, 0n)).toBe(MINIMUM_CONGESTION_MULTIPLIER); + }); + + it('increases with excess mana', () => { +- const low = computeCongestionMultiplier(100_000n, 100_000_000n); +- const high = computeCongestionMultiplier(200_000n, 100_000_000n); ++ const low = computeCongestionMultiplier(100_000n, 100_000_000n, 0n); ++ const high = computeCongestionMultiplier(200_000n, 100_000_000n, 0n); + expect(high).toBeGreaterThan(low); + expect(low).toBeGreaterThan(MINIMUM_CONGESTION_MULTIPLIER); + }); +@@ -78,11 +78,16 @@ describe('computeCongestionMultiplier', () => { + it('increases by ~12.5% per manaTarget of excess', () => { + // When excessMana = manaTarget, multiplier ≈ 1.125 * MINIMUM_CONGESTION_MULTIPLIER + const manaTarget = 100_000_000n; +- const multiplier = computeCongestionMultiplier(manaTarget, manaTarget); ++ const multiplier = computeCongestionMultiplier(manaTarget, manaTarget, 0n); + const ratio = Number(multiplier) / Number(MINIMUM_CONGESTION_MULTIPLIER); + expect(ratio).toBeGreaterThan(1.12); + expect(ratio).toBeLessThan(1.13); + }); ++ ++ it('scales the zero-excess baseline by exactly (10000 + bps) * 1e5', () => { ++ expect(computeCongestionMultiplier(0n, 100_000_000n, 5000n)).toBe(15_000n * 100_000n); ++ expect(computeCongestionMultiplier(0n, 100_000_000n, 65_535n)).toBe(75_535n * 100_000n); ++ }); + }); + + describe('computeManaMinFee', () => { +@@ -94,6 +99,7 @@ describe('computeManaMinFee', () => { + provingCostPerManaEth: 0n, + excessMana: 0n, + ethPerFeeAsset: 1_000_000_000_000n, // 1:1 ETH:FeeAsset ++ protocolFeeMarginBps: 0n, + }; + + it('returns zero when manaTarget is zero', () => { +@@ -123,12 +129,36 @@ describe('computeManaMinFee', () => { + expect(high).toBeGreaterThan(low); + }); + +- it('has zero congestion cost when excess mana is zero', () => { +- // With zero excess, congestionMultiplier = MINIMUM_CONGESTION_MULTIPLIER, +- // so congestionCost = total * 1 - total = 0 ++ it('has zero protocol fee when excess mana and margin are zero', () => { ++ // With zero excess and zero margin, congestionMultiplier = MINIMUM_CONGESTION_MULTIPLIER, ++ // so protocolFee = total * 1 - total = 0 + const fee = computeManaMinFee(baseParams); + // The fee should equal just sequencer + prover costs + const feeWithExcess = computeManaMinFee({ ...baseParams, excessMana: baseParams.manaTarget }); + expect(feeWithExcess).toBeGreaterThan(fee); + }); ++ ++ it('scales the fee by ~(1 + mu) at zero excess', () => { ++ const base = computeManaMinFee(baseParams); ++ const withMargin = computeManaMinFee({ ...baseParams, protocolFeeMarginBps: 5000n }); ++ // fee = cost + (floor(cost * 3 / 2) - cost) converted per component; allow 1 wei of Ceil slack. ++ const expected = (base * 15_000n) / 10_000n; ++ expect(withMargin).toBeGreaterThanOrEqual(expected - 1n); ++ expect(withMargin).toBeLessThanOrEqual(expected + 1n); ++ expect(withMargin).toBeGreaterThan(base); ++ }); ++ ++ it('applies the margin on top of congestion multiplicatively', () => { ++ const congested = computeManaMinFee({ ...baseParams, excessMana: baseParams.manaTarget * 3n }); ++ const congestedWithMargin = computeManaMinFee({ ++ ...baseParams, ++ excessMana: baseParams.manaTarget * 3n, ++ protocolFeeMarginBps: 5000n, ++ }); ++ expect(congestedWithMargin).toBeGreaterThan(congested); ++ // The margin scales the multiplier's factor, so the marked-up congested fee is ~1.5x. ++ const ratio = Number(congestedWithMargin) / Number(congested); ++ expect(ratio).toBeGreaterThan(1.49); ++ expect(ratio).toBeLessThan(1.51); ++ }); + }); +diff --git a/yarn-project/stdlib/src/gas/fee_math.ts b/yarn-project/stdlib/src/gas/fee_math.ts +index 35ff2842c9..6d1ffa8fa7 100644 +--- a/yarn-project/stdlib/src/gas/fee_math.ts ++++ b/yarn-project/stdlib/src/gas/fee_math.ts +@@ -36,6 +36,7 @@ export type ManaMinFeeParams = { + provingCostPerManaEth: bigint; + excessMana: bigint; + ethPerFeeAsset: bigint; ++ protocolFeeMarginBps: bigint; + }; + + /** +@@ -60,11 +61,21 @@ export function computeExcessMana(prevExcessMana: bigint, prevManaUsed: bigint, + return sum > manaTarget ? sum - manaTarget : 0n; + } + +-/** Computes the congestion multiplier from excess mana (1e9 = no congestion). */ +-export function computeCongestionMultiplier(excessMana: bigint, manaTarget: bigint): bigint { ++/** ++ * Computes the congestion multiplier from excess mana. ++ * The protocol fee margin scales only the fakeExponential factor: (10_000 + bps) * 1e5, which is ++ * (1 + mu) * 1e9 and exactly 1e9 at mu = 0. The uncongested baseline is therefore (1 + mu) * 1e9. ++ * The MINIMUM_CONGESTION_MULTIPLIER divisor in computeManaMinFee MUST NOT be scaled -- scaling ++ * both sites cancels the margin. ++ */ ++export function computeCongestionMultiplier( ++ excessMana: bigint, ++ manaTarget: bigint, ++ protocolFeeMarginBps: bigint, ++): bigint { + const denominator = (manaTarget * MAGIC_CONGESTION_VALUE_MULTIPLIER) / MAGIC_CONGESTION_VALUE_DIVISOR; + const cappedNumerator = excessMana < denominator * 100n ? excessMana : denominator * 100n; +- return fakeExponential(MINIMUM_CONGESTION_MULTIPLIER, cappedNumerator, denominator); ++ return fakeExponential((10_000n + protocolFeeMarginBps) * 100_000n, cappedNumerator, denominator); + } + + /** Ceiling division for positive bigints. */ +@@ -81,11 +92,20 @@ function toFeeAsset(ethValue: bigint, ethPerFeeAsset: bigint): bigint { + } + + /** +- * Computes the full mana min fee (sequencer + prover + congestion) in fee asset terms. ++ * Computes the full mana min fee (sequencer + prover + protocol fee) in fee asset terms. + * Mirrors FeeLib.getManaMinFeeComponentsAt + summedMinFee. + */ + export function computeManaMinFee(params: ManaMinFeeParams): bigint { +- const { l1BaseFee, l1BlobFee, manaTarget, epochDuration, provingCostPerManaEth, excessMana, ethPerFeeAsset } = params; ++ const { ++ l1BaseFee, ++ l1BlobFee, ++ manaTarget, ++ epochDuration, ++ provingCostPerManaEth, ++ excessMana, ++ ethPerFeeAsset, ++ protocolFeeMarginBps, ++ } = params; + + if (manaTarget === 0n) { + return 0n; +@@ -102,17 +122,18 @@ export function computeManaMinFee(params: ManaMinFeeParams): bigint { + // Total base cost in ETH (congestion is computed on this) + const totalEth = sequencerCostEth + proverCostEth; + +- // Congestion multiplier and cost (in ETH) +- const congestionMul = computeCongestionMultiplier(excessMana, manaTarget); +- const congestionCostEth = (totalEth * congestionMul) / MINIMUM_CONGESTION_MULTIPLIER - totalEth; ++ // Congestion multiplier (scaled by the protocol fee margin) and protocol fee (in ETH). ++ // The divisor here stays MINIMUM_CONGESTION_MULTIPLIER; only the multiplier's factor scales. ++ const congestionMul = computeCongestionMultiplier(excessMana, manaTarget, protocolFeeMarginBps); ++ const protocolFeeEth = (totalEth * congestionMul) / MINIMUM_CONGESTION_MULTIPLIER - totalEth; + + // Convert all components to fee asset + const clampedEthPerFeeAsset = ethPerFeeAsset < MIN_ETH_PER_FEE_ASSET ? MIN_ETH_PER_FEE_ASSET : ethPerFeeAsset; + const sequencerCost = toFeeAsset(sequencerCostEth, clampedEthPerFeeAsset); + const proverCost = toFeeAsset(proverCostEth, clampedEthPerFeeAsset); +- const congestionCost = toFeeAsset(congestionCostEth, clampedEthPerFeeAsset); ++ const protocolFee = toFeeAsset(protocolFeeEth, clampedEthPerFeeAsset); + +- const total = sequencerCost + proverCost + congestionCost; ++ const total = sequencerCost + proverCost + protocolFee; + + // Cap at uint128 max (matching FeeLib.summedMinFee) + const UINT128_MAX = (1n << 128n) - 1n; +-- +2.50.1 + From cf796a7e198d2a218970d5eebada86ae3b8f0779 Mon Sep 17 00:00:00 2001 From: Rumata888 Date: Fri, 28 Aug 2026 16:46:08 +0000 Subject: [PATCH 02/19] chore: Update activity score to only track full epoch proofs --- l1-contracts/src/core/RollupCore.sol | 7 ++ l1-contracts/src/core/libraries/Errors.sol | 1 + .../core/libraries/rollup/EpochProofLib.sol | 33 ++++++- .../src/core/libraries/rollup/RewardLib.sol | 12 ++- l1-contracts/test/MultiProof.t.sol | 95 +++++++++++++++++++ .../constructorProofSubmissionEpochs.t.sol | 59 ++++++++++++ .../libraries/rewardlib/RewardLibWrapper.sol | 2 +- 7 files changed, 202 insertions(+), 7 deletions(-) create mode 100644 l1-contracts/test/rollup/constructorProofSubmissionEpochs.t.sol diff --git a/l1-contracts/src/core/RollupCore.sol b/l1-contracts/src/core/RollupCore.sol index 413242ead786..c11485dcb0cc 100644 --- a/l1-contracts/src/core/RollupCore.sol +++ b/l1-contracts/src/core/RollupCore.sol @@ -233,6 +233,13 @@ contract RollupCore is EIP712("Aztec Rollup", "1"), Ownable, IStakingCore, IVali Errors.Staking__ExitDelayAboveSlasherDelay(_config.exitDelaySeconds, StakingLib.SLASHER_EXECUTION_DELAY) ); + // We can only figure out if the epoch is full once it closes, + // so we need to allow proofs to be accepted in a later epoch + require( + _config.aztecProofSubmissionEpochs > 0, + Errors.Rollup__InvalidProofSubmissionEpochs(1, _config.aztecProofSubmissionEpochs) + ); + TimeLib.initialize( block.timestamp, _config.aztecSlotDuration, diff --git a/l1-contracts/src/core/libraries/Errors.sol b/l1-contracts/src/core/libraries/Errors.sol index 49aa150742a4..a5fa0201a8d9 100644 --- a/l1-contracts/src/core/libraries/Errors.sol +++ b/l1-contracts/src/core/libraries/Errors.sol @@ -65,6 +65,7 @@ library Errors { error Rollup__InvalidOutHash(bytes32 expected, bytes32 actual); // 0x8eb39062 error Rollup__InvalidPreviousArchive(bytes32 expected, bytes32 actual); // 0xb682a40e error Rollup__InvalidProof(); // 0xa5b2ba17 + error Rollup__InvalidProofSubmissionEpochs(uint256 minimum, uint256 provided); error Rollup__InvalidProposedArchive(bytes32 expected, bytes32 actual); // 0x32532e73 error Rollup__InvalidTimestamp(Timestamp expected, Timestamp actual); // 0x3132e895 error Rollup__InvalidAttestations(); diff --git a/l1-contracts/src/core/libraries/rollup/EpochProofLib.sol b/l1-contracts/src/core/libraries/rollup/EpochProofLib.sol index dbbf21d55042..0261021c2190 100644 --- a/l1-contracts/src/core/libraries/rollup/EpochProofLib.sol +++ b/l1-contracts/src/core/libraries/rollup/EpochProofLib.sol @@ -140,7 +140,10 @@ library EpochProofLib { } } - RewardLib.handleRewardsAndFees(_args, endEpoch); + bool fullEpochProof = isFullEpochProof(_args.end, endEpoch); + + // Activity score depends on whether the proof is a full epoch proof + RewardLib.handleRewardsAndFees(_args, endEpoch, fullEpochProof); emit IRollupCore.L2ProofVerified(_args.end, _args.args.proverId); } @@ -468,6 +471,34 @@ library EpochProofLib { return endEpoch; } + /* + * @notice Checks if the submitted proof is a full epoch proof + * + * @param _end End checkpoint of the proof + * @param _endEpoch Proof epoch + * @return true if the proof covers the whole epoch + */ + function isFullEpochProof(uint256 _end, Epoch _endEpoch) private view returns (bool) { + Epoch currentEpoch = Timestamp.wrap(block.timestamp).epochFromTimestamp(); + + // Another checkpoint could be proposed if the epoch being proven is the current one, so we can't be sure that the + // proof is a full epoch proof + if (_endEpoch >= currentEpoch) { + return false; + } + + uint256 pendingCheckpointNumber = STFLib.getStorage().tips.getPending(); + + // If the last proof checkpoint is a pending checkpoint while the epoch is closed, then it's the last checkpoint of + // proof epoch + if (_end == pendingCheckpointNumber) { + return true; + } + + // If the next checkpoint is in a different epoch, then this one is the final one in the proof epoch + return STFLib.getEpochForCheckpoint(_end + 1) > _endEpoch; + } + /** * @notice Verifies the validity proof and batched blob proof for an epoch * diff --git a/l1-contracts/src/core/libraries/rollup/RewardLib.sol b/l1-contracts/src/core/libraries/rollup/RewardLib.sol index a8556cb890a5..7590d8085f88 100644 --- a/l1-contracts/src/core/libraries/rollup/RewardLib.sol +++ b/l1-contracts/src/core/libraries/rollup/RewardLib.sol @@ -159,7 +159,9 @@ library RewardLib { return accumulatedRewards; } - function handleRewardsAndFees(SubmitEpochRootProofArgs calldata _args, Epoch _endEpoch) internal { + function handleRewardsAndFees(SubmitEpochRootProofArgs calldata _args, Epoch _endEpoch, bool _fullEpochProof) + internal + { RollupStore storage rollupStore = STFLib.getStorage(); RewardStorage storage rewardStorage = getStorage(); @@ -171,10 +173,10 @@ library RewardLib { address prover = _args.args.proverId; require($sr.shares[prover] == 0, Errors.Rollup__ProverHaveAlreadySubmitted(prover, _endEpoch)); - // Beware that it is possible to get marked active in an epoch even if you did not provide the longest - // proof. This is acceptable, as they were actually active. And boosting this way is not the most - // efficient way to do it, so this is fine. - uint256 shares = rewardStorage.config.booster.updateAndGetShares(prover); + // The prover is only marked active if they have provided a full epoch proof + uint256 shares = _fullEpochProof + ? rewardStorage.config.booster.updateAndGetShares(prover) + : rewardStorage.config.booster.getSharesFor(prover); // The duplicate-submission guard above uses `shares == 0` as the sentinel for "not yet // submitted". A booster that ever returns zero would let the same prover submit again diff --git a/l1-contracts/test/MultiProof.t.sol b/l1-contracts/test/MultiProof.t.sol index 496db0520cda..016681817a4a 100644 --- a/l1-contracts/test/MultiProof.t.sol +++ b/l1-contracts/test/MultiProof.t.sol @@ -258,4 +258,99 @@ contract MultiProofTest is RollupBase { abi.encodeWithSelector(Errors.Rollup__StartAndEndNotSameEpoch.selector, 0, 1) ); } + + function testPartialEpochProofDoesNotUpdateActivityScore() public setUpFor("mixed_checkpoint_1") { + address alice = address(bytes20("alice")); + + // Mint some fee asset to the portal to cover the 30M mana spent. + deal(address(testERC20), address(feeJuicePortal), 30e6 * 1e18); + + // Propose 2 checkpoints (we need 2 to ensure a partial proof is possible) + _proposeCheckpoint("mixed_checkpoint_1", 1, 15e6); + _proposeCheckpoint("mixed_checkpoint_2", 2, 15e6); + + // Close epoch 0 by advancing time to the first slot of epoch 1 + warpToL2Slot(EPOCH_DURATION); + + // Record, prove, record + uint256 activityScoreBefore = rewardBooster.getActivityScore(alice).value; + + _proveCheckpoints("mixed_checkpoint_", 1, 1, alice); + + uint256 activityScoreAfter = rewardBooster.getActivityScore(alice).value; + + assertEq( + activityScoreBefore, activityScoreAfter, "Alice's activity score changed despite not proving a whole epoch" + ); + } + + function testFullEpochProofUpdatesActivityScore() public setUpFor("mixed_checkpoint_1") { + address alice = address(bytes20("alice")); + + // We need to mint some fee asset to the portal to cover the 30M mana spent. + deal(address(testERC20), address(feeJuicePortal), 30e6 * 1e18); + + _proposeCheckpoint("mixed_checkpoint_1", 1, 15e6); + _proposeCheckpoint("mixed_checkpoint_2", 2, 15e6); + + // Close epoch 0 by advancing time to the first slot of epoch 1 + warpToL2Slot(EPOCH_DURATION); + + uint256 activityScoreBefore = rewardBooster.getActivityScore(alice).value; + + _proveCheckpoints("mixed_checkpoint_", 1, 2, alice); + + uint256 activityScoreAfter = rewardBooster.getActivityScore(alice).value; + + assertGt( + activityScoreAfter, activityScoreBefore, "Alice's activity score didn't increase despite proving a whole epoch" + ); + } + + function testSingleCheckpointFullEpochUpdatesActivityScore() public setUpFor("mixed_checkpoint_1") { + address alice = address(bytes20("alice")); + + // We need to mint fee asset to the portal to cover the spent mana + deal(address(testERC20), address(feeJuicePortal), 30e6 * 1e18); + + // Single checkpoint that will constitute the epoch + _proposeCheckpoint("mixed_checkpoint_1", 1, 15e6); + + // Additional checkpoint in the new epoch to move the pending tip and close the previous epoch + _proposeCheckpoint("mixed_checkpoint_2", EPOCH_DURATION, 15e6); + + uint256 activityScoreBefore = rewardBooster.getActivityScore(alice).value; + + _proveCheckpoints("mixed_checkpoint_", 1, 1, alice); + + uint256 activityScoreAfter = rewardBooster.getActivityScore(alice).value; + + assertGt( + activityScoreAfter, + activityScoreBefore, + "Alice's score didn't increase despite proving a whole epoch, though it was only 1 checkpoint" + ); + } + + function testOpenEpochProofDoesNotUpdateActivityScore() public setUpFor("mixed_checkpoint_1") { + address alice = address(bytes20("alice")); + + // We need to mint fee asset to the portal to cover the spend mana + deal(address(testERC20), address(feeJuicePortal), 15e6 * 1e18); + + // Go to epoch 1 immediately. Booster only updates once in an epoch and epoch 0 is chosen as default, so we will not + // be able to update the score without warping + warpToL2Slot(EPOCH_DURATION); + + _proposeCheckpoint("mixed_checkpoint_1", EPOCH_DURATION, 15e6); + + uint256 activityScoreBefore = rewardBooster.getActivityScore(alice).value; + + // Prove without closing + _proveCheckpoints("mixed_checkpoint_", 1, 1, alice); + + uint256 activityScoreAfter = rewardBooster.getActivityScore(alice).value; + + assertEq(activityScoreBefore, activityScoreAfter, "Proving an open epoch should not increase activity score"); + } } diff --git a/l1-contracts/test/rollup/constructorProofSubmissionEpochs.t.sol b/l1-contracts/test/rollup/constructorProofSubmissionEpochs.t.sol new file mode 100644 index 000000000000..d51b6d921c8b --- /dev/null +++ b/l1-contracts/test/rollup/constructorProofSubmissionEpochs.t.sol @@ -0,0 +1,59 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity >=0.8.27; +// solhint-disable func-name-mixedcase +// solhint-disable comprehensive-interface + +import {RollupConfigInput} from "@aztec/core/interfaces/IRollup.sol"; +import {IVerifier} from "@aztec/core/interfaces/IVerifier.sol"; +import {Errors} from "@aztec/core/libraries/Errors.sol"; +import {GenesisState} from "@aztec/core/libraries/rollup/STFLib.sol"; +import {Rollup} from "@aztec/core/Rollup.sol"; +import {GSE} from "@aztec/governance/GSE.sol"; +import {MockVerifier} from "@aztec/mock/MockVerifier.sol"; +import {TestERC20} from "@aztec/mock/TestERC20.sol"; +import {RollupBuilder, Config as BuilderConfig} from "@test/builder/RollupBuilder.sol"; +import {Test} from "forge-std/Test.sol"; + +/// @notice Verifies that it is impossible to set aztecProofSubmissionEpochs to zero +/// since this would cause painful edgecase effects. For example, proof submissions +/// could never update prover activity scores +contract ConstructorProofSubmissionEpochsTest is Test { + RollupBuilder internal builder; + TestERC20 internal token; + GSE internal gse; + GenesisState internal genesisState; + IVerifier internal verifier; + + function test_revertsWhenProofSubmissionEpochIsZero() external { + RollupConfigInput memory config = _buildDefaultConfig(); + config.aztecProofSubmissionEpochs = 0; + + vm.expectRevert(abi.encodeWithSelector(Errors.Rollup__InvalidProofSubmissionEpochs.selector, 1, 0)); + + new Rollup(token, token, gse, verifier, address(this), genesisState, config); + } + + function test_succeedsWithOneProofSubmissionEpoch() external { + RollupConfigInput memory config = _buildDefaultConfig(); + config.aztecProofSubmissionEpochs = 1; + + Rollup rollup = new Rollup(token, token, gse, verifier, address(this), genesisState, config); + + assertEq(rollup.getProofSubmissionEpochs(), 1); + } + + function setUp() public { + builder = new RollupBuilder(address(this)); + builder.deploy(); + + BuilderConfig memory cfg = builder.getConfig(); + token = cfg.testERC20; + gse = cfg.gse; + genesisState = cfg.genesisState; + verifier = new MockVerifier(); + } + + function _buildDefaultConfig() internal view returns (RollupConfigInput memory) { + return builder.getConfig().rollupConfigInput; + } +} diff --git a/l1-contracts/test/rollup/libraries/rewardlib/RewardLibWrapper.sol b/l1-contracts/test/rollup/libraries/rewardlib/RewardLibWrapper.sol index 658757e68333..d825641d64ed 100644 --- a/l1-contracts/test/rollup/libraries/rewardlib/RewardLibWrapper.sol +++ b/l1-contracts/test/rollup/libraries/rewardlib/RewardLibWrapper.sol @@ -137,7 +137,7 @@ contract RewardLibWrapper { } function handleRewardsAndFees(SubmitEpochRootProofArgs calldata _args, Epoch _endEpoch) external { - RewardLib.handleRewardsAndFees(_args, _endEpoch); + RewardLib.handleRewardsAndFees(_args, _endEpoch, true); } function getSequencerRewards(address _sequencer) external view returns (uint256) { From 78b61e62707ab52e09d2387a0f2b1d02a75cf824 Mon Sep 17 00:00:00 2001 From: Santiago Palladino Date: Thu, 3 Sep 2026 14:44:34 -0300 Subject: [PATCH 03/19] refactor(l1): reduce full epoch proof gas overhead (#25386) ## Summary - reuse the current epoch already computed during proof acceptance - cache the packed chain tips for full-proof detection and proven-tip advancement - read the known-existing next checkpoint slot directly instead of repeating checkpoint-number validation - update the gas benchmark results; this saves 1,053 gas per proof submission versus the parent PR implementation, leaving roughly 3,729 gas of net overhead versus the pre-PR baseline ## Tests - `forge fmt --check` - `forge test --offline --match-contract MultiProofTest` - `forge test --offline --match-contract HandleRewardsTest` - `python3 scripts/gas_benchmarks.py` --- l1-contracts/gas_benchmark.md | 8 +-- l1-contracts/gas_benchmark_results.json | 16 +++--- .../core/libraries/rollup/EpochProofLib.sol | 54 ++++++++++--------- 3 files changed, 40 insertions(+), 38 deletions(-) diff --git a/l1-contracts/gas_benchmark.md b/l1-contracts/gas_benchmark.md index 127649a78e40..b2d14ece81fa 100644 --- a/l1-contracts/gas_benchmark.md +++ b/l1-contracts/gas_benchmark.md @@ -15,10 +15,10 @@ | Function | Avg Gas | Max Gas | Calldata Size | Calldata Gas | |----------------------|---------|-----------|---------------|--------------| | propose | 199,366 | 225,550 | 996 | 15,936 | -| submitEpochRootProof | 991,032 | 1,029,525 | 14,148 | 226,368 | +| submitEpochRootProof | 994,761 | 1,033,254 | 14,148 | 226,368 | | setupEpoch | 32,042 | 113,837 | - | - | -**Avg Gas Cost per Second**: 3,643.2 gas/second +**Avg Gas Cost per Second**: 3,646.4 gas/second *Epoch duration*: 0h 38m 24s ## Validators @@ -26,10 +26,10 @@ | Function | Avg Gas | Max Gas | Calldata Size | Calldata Gas | |----------------------|-----------|-----------|---------------|--------------| | propose | 327,774 | 355,591 | 4,516 | 72,256 | -| submitEpochRootProof | 1,572,081 | 1,669,921 | 16,644 | 266,304 | +| submitEpochRootProof | 1,575,811 | 1,673,651 | 16,644 | 266,304 | | aggregate3 | 376,665 | 390,039 | - | - | | setupEpoch | 46,504 | 547,670 | - | - | -**Avg Gas Cost per Second**: 5,937.3 gas/second +**Avg Gas Cost per Second**: 5,940.5 gas/second *Epoch duration*: 0h 38m 24s diff --git a/l1-contracts/gas_benchmark_results.json b/l1-contracts/gas_benchmark_results.json index a742ea9be3a1..f0d045c0b42a 100644 --- a/l1-contracts/gas_benchmark_results.json +++ b/l1-contracts/gas_benchmark_results.json @@ -18,10 +18,10 @@ }, "submitEpochRootProof": { "calls": 4, - "min": 972329, - "mean": 991032, - "median": 981138, - "max": 1029525, + "min": 976058, + "mean": 994761, + "median": 984867, + "max": 1033254, "calldata_size": 14148, "calldata_gas": 226368 } @@ -45,10 +45,10 @@ }, "submitEpochRootProof": { "calls": 4, - "min": 1460323, - "mean": 1572081, - "median": 1579041, - "max": 1669921, + "min": 1464053, + "mean": 1575811, + "median": 1582771, + "max": 1673651, "calldata_size": 16644, "calldata_gas": 266304 }, diff --git a/l1-contracts/src/core/libraries/rollup/EpochProofLib.sol b/l1-contracts/src/core/libraries/rollup/EpochProofLib.sol index 0261021c2190..d80ad215a1f0 100644 --- a/l1-contracts/src/core/libraries/rollup/EpochProofLib.sol +++ b/l1-contracts/src/core/libraries/rollup/EpochProofLib.sol @@ -107,7 +107,7 @@ library EpochProofLib { STFLib.prune(); } - Epoch endEpoch = assertAcceptable(_args.start, _args.end); + (Epoch endEpoch, Epoch currentEpoch) = assertAcceptable(_args.start, _args.end); // Rehash the supplied headers against storage once, here: the public-input assembly below reads the fee // recipient/value out of them and relies on this call having run. @@ -121,10 +121,13 @@ library EpochProofLib { require(verifyEpochRootProof(_args), Errors.Rollup__InvalidProof()); RollupStore storage rollupStore = STFLib.getStorage(); + CompressedChainTips tips = rollupStore.tips; + + bool fullEpochProof = isFullEpochProof(_args.end, endEpoch, currentEpoch, tips.getPending()); // Advance the proven block number and insert the out hash if the chain is extended. - if (_args.end > rollupStore.tips.getProven()) { - rollupStore.tips = rollupStore.tips.updateProven(_args.end); + if (_args.end > tips.getProven()) { + rollupStore.tips = tips.updateProven(_args.end); // Handle L2->L1 message processing. // The circuit outputs an empty out hash tree root if the epoch contains no messages. @@ -140,8 +143,6 @@ library EpochProofLib { } } - bool fullEpochProof = isFullEpochProof(_args.end, endEpoch); - // Activity score depends on whether the proof is a full epoch proof RewardLib.handleRewardsAndFees(_args, endEpoch, fullEpochProof); @@ -432,18 +433,19 @@ library EpochProofLib { * * @param _start The first checkpoint number in the epoch (inclusive) * @param _end The last checkpoint number in the epoch (inclusive) - * @return The epoch number that the proof covers + * @return endEpoch The epoch number that the proof covers + * @return currentEpoch The epoch at the time the proof is submitted */ - function assertAcceptable(uint256 _start, uint256 _end) private view returns (Epoch) { + function assertAcceptable(uint256 _start, uint256 _end) private view returns (Epoch endEpoch, Epoch currentEpoch) { RollupStore storage rollupStore = STFLib.getStorage(); Epoch startEpoch = STFLib.getEpochForCheckpoint(_start); // This also checks for existence of the checkpoint. - Epoch endEpoch = STFLib.getEpochForCheckpoint(_end); + endEpoch = STFLib.getEpochForCheckpoint(_end); require(startEpoch == endEpoch, Errors.Rollup__StartAndEndNotSameEpoch(startEpoch, endEpoch)); - Epoch currentEpoch = Timestamp.wrap(block.timestamp).epochFromTimestamp(); + currentEpoch = Timestamp.wrap(block.timestamp).epochFromTimestamp(); require( startEpoch.isAcceptingProofsAtEpoch(currentEpoch), @@ -467,36 +469,36 @@ library EpochProofLib { claimedNumCheckpointsInEpoch, Errors.Rollup__TooManyCheckpointsInEpoch(Constants.MAX_CHECKPOINTS_PER_EPOCH, _end - _start) ); - - return endEpoch; } - /* - * @notice Checks if the submitted proof is a full epoch proof - * - * @param _end End checkpoint of the proof - * @param _endEpoch Proof epoch - * @return true if the proof covers the whole epoch - */ - function isFullEpochProof(uint256 _end, Epoch _endEpoch) private view returns (bool) { - Epoch currentEpoch = Timestamp.wrap(block.timestamp).epochFromTimestamp(); - + /** + * @notice Checks if the submitted proof is a full epoch proof + * + * @param _end End checkpoint of the proof + * @param _endEpoch Proof epoch + * @param _currentEpoch Epoch at the time the proof is submitted + * @param _pendingCheckpointNumber Current pending checkpoint number + * @return true if the proof covers the whole epoch + */ + function isFullEpochProof(uint256 _end, Epoch _endEpoch, Epoch _currentEpoch, uint256 _pendingCheckpointNumber) + private + view + returns (bool) + { // Another checkpoint could be proposed if the epoch being proven is the current one, so we can't be sure that the // proof is a full epoch proof - if (_endEpoch >= currentEpoch) { + if (_endEpoch >= _currentEpoch) { return false; } - uint256 pendingCheckpointNumber = STFLib.getStorage().tips.getPending(); - // If the last proof checkpoint is a pending checkpoint while the epoch is closed, then it's the last checkpoint of // proof epoch - if (_end == pendingCheckpointNumber) { + if (_end == _pendingCheckpointNumber) { return true; } // If the next checkpoint is in a different epoch, then this one is the final one in the proof epoch - return STFLib.getEpochForCheckpoint(_end + 1) > _endEpoch; + return STFLib.getSlotNumber(_end + 1).epochFromSlot() > _endEpoch; } /** From b4c9c4c3f572efe4b27725b962c57189a3e2ac35 Mon Sep 17 00:00:00 2001 From: Santiago Palladino Date: Mon, 7 Sep 2026 11:00:48 -0300 Subject: [PATCH 04/19] feat(l1): track which prover first proved each checkpoint (#25389) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit There was no on-chain record of who proved a given checkpoint. `L2ProofVerified` carries the prover, but there is nothing queryable, and the reward accounting only tracks per-epoch submissions. Adds a `firstProvenBy` mapping to `RollupStore`, written in `submitEpochRootProof` whenever a proof advances the proven tip. Only the checkpoint the proof ended at gets an entry, so entries are sparse: proofs of 1-10 and then 11-20 record entries at 10 and 20, with nothing in between. Because a proof of an already proven range cannot advance the tip, it never reaches the write and the original prover is preserved. `getFirstProvenBy(checkpointNumber)` resolves an arbitrary checkpoint by walking forward to the next entry. The first entry at or after the requested number belongs to the earliest proof that covered it, since the proven tip only ever advances; the walk is bounded by the epoch duration because a proof covers at most one epoch. The mapping stores the address in its lower 160 bits and sets bit 160 as a presence flag, so `address(0)` remains distinguishable from a sparse, unwritten entry. The getter reverts with `Rollup__CheckpointNotProven` for checkpoint 0 or a checkpoint ahead of the proven tip. The getter is routed through `RewardExtLib` (alongside the other STF getters) rather than inlined in `Rollup.sol` — the Rollup deployed bytecode is within 800 bytes of the size limit. New `IRollup.getFirstProvenBy(uint256) returns (address)` and `Errors.Rollup__CheckpointNotProven(uint256 proven, uint256 requested)`. Fixes A-1927 --- l1-contracts/gas_benchmark.md | 22 ++++---- l1-contracts/gas_benchmark_results.json | 56 +++++++++---------- l1-contracts/src/core/Rollup.sol | 47 ++++++++-------- l1-contracts/src/core/interfaces/IRollup.sol | 4 ++ l1-contracts/src/core/libraries/Errors.sol | 1 + .../core/libraries/rollup/EpochProofLib.sol | 4 ++ .../core/libraries/rollup/RewardExtLib.sol | 4 ++ .../rollup/RollupOperationsExtLib.sol | 26 +++++++-- .../src/core/libraries/rollup/STFLib.sol | 47 ++++++++++++++++ l1-contracts/test/MultiProof.t.sol | 55 ++++++++++++++++++ ...roduce-a-protocol-fee-margin-AZIP-23.patch | 4 +- 11 files changed, 201 insertions(+), 69 deletions(-) diff --git a/l1-contracts/gas_benchmark.md b/l1-contracts/gas_benchmark.md index b2d14ece81fa..acb41156847e 100644 --- a/l1-contracts/gas_benchmark.md +++ b/l1-contracts/gas_benchmark.md @@ -12,24 +12,24 @@ ## No Validators -| Function | Avg Gas | Max Gas | Calldata Size | Calldata Gas | -|----------------------|---------|-----------|---------------|--------------| -| propose | 199,366 | 225,550 | 996 | 15,936 | -| submitEpochRootProof | 994,761 | 1,033,254 | 14,148 | 226,368 | -| setupEpoch | 32,042 | 113,837 | - | - | +| Function | Avg Gas | Max Gas | Calldata Size | Calldata Gas | +|----------------------|-----------|-----------|---------------|--------------| +| propose | 200,097 | 226,280 | 996 | 15,936 | +| submitEpochRootProof | 1,035,434 | 1,074,129 | 14,148 | 226,368 | +| setupEpoch | 32,020 | 113,815 | - | - | -**Avg Gas Cost per Second**: 3,646.4 gas/second +**Avg Gas Cost per Second**: 3,691.8 gas/second *Epoch duration*: 0h 38m 24s ## Validators | Function | Avg Gas | Max Gas | Calldata Size | Calldata Gas | |----------------------|-----------|-----------|---------------|--------------| -| propose | 327,774 | 355,591 | 4,516 | 72,256 | -| submitEpochRootProof | 1,575,811 | 1,673,651 | 16,644 | 266,304 | -| aggregate3 | 376,665 | 390,039 | - | - | -| setupEpoch | 46,504 | 547,670 | - | - | +| propose | 328,507 | 356,323 | 4,516 | 72,256 | +| submitEpochRootProof | 1,616,774 | 1,714,815 | 16,644 | 266,304 | +| aggregate3 | 377,506 | 390,880 | - | - | +| setupEpoch | 46,482 | 547,648 | - | - | -**Avg Gas Cost per Second**: 5,940.5 gas/second +**Avg Gas Cost per Second**: 5,986.2 gas/second *Epoch duration*: 0h 38m 24s diff --git a/l1-contracts/gas_benchmark_results.json b/l1-contracts/gas_benchmark_results.json index f0d045c0b42a..eed057dc063a 100644 --- a/l1-contracts/gas_benchmark_results.json +++ b/l1-contracts/gas_benchmark_results.json @@ -2,26 +2,26 @@ "no_validators": { "propose": { "calls": 150, - "min": 185722, - "mean": 199366, - "median": 195111, - "max": 225550, + "min": 186452, + "mean": 200097, + "median": 195841, + "max": 226280, "calldata_size": 996, "calldata_gas": 15936 }, "setupEpoch": { "calls": 150, - "min": 29309, - "mean": 32042, - "median": 29309, - "max": 113837 + "min": 29287, + "mean": 32020, + "median": 29287, + "max": 113815 }, "submitEpochRootProof": { "calls": 4, - "min": 976058, - "mean": 994761, - "median": 984867, - "max": 1033254, + "min": 1015256, + "mean": 1035434, + "median": 1026177, + "max": 1074129, "calldata_size": 14148, "calldata_gas": 226368 } @@ -29,35 +29,35 @@ "validators": { "propose": { "calls": 150, - "min": 305434, - "mean": 327774, - "median": 327227, - "max": 355591, + "min": 306166, + "mean": 328507, + "median": 327959, + "max": 356323, "calldata_size": 4516, "calldata_gas": 72256 }, "setupEpoch": { "calls": 150, - "min": 29309, - "mean": 46504, - "median": 29309, - "max": 547670 + "min": 29287, + "mean": 46482, + "median": 29287, + "max": 547648 }, "submitEpochRootProof": { "calls": 4, - "min": 1464053, - "mean": 1575811, - "median": 1582771, - "max": 1673651, + "min": 1505653, + "mean": 1616774, + "median": 1623315, + "max": 1714815, "calldata_size": 16644, "calldata_gas": 266304 }, "aggregate3": { "calls": 55, - "min": 365547, - "mean": 376665, - "median": 376350, - "max": 390039 + "min": 366388, + "mean": 377506, + "median": 377191, + "max": 390880 } } } \ No newline at end of file diff --git a/l1-contracts/src/core/Rollup.sol b/l1-contracts/src/core/Rollup.sol index d51ecf783b1b..d7a641f3719f 100644 --- a/l1-contracts/src/core/Rollup.sol +++ b/l1-contracts/src/core/Rollup.sol @@ -28,7 +28,6 @@ import {IRewardDistributor} from "@aztec/governance/interfaces/IRewardDistributo import {CompressedSlot, CompressedTimestamp, CompressedTimeMath} from "@aztec/shared/libraries/CompressedTimeMath.sol"; import {Signature} from "@aztec/shared/libraries/SignatureLib.sol"; import {ChainTipsLib, CompressedChainTips} from "./libraries/compressed-data/Tips.sol"; -import {ValidateHeaderArgs} from "./libraries/rollup/ProposeLib.sol"; import {RewardExtLib, RewardConfig} from "./libraries/rollup/RewardExtLib.sol"; import {DepositArgs} from "./libraries/StakingQueue.sol"; import { @@ -90,24 +89,15 @@ contract Rollup is IStaking, IValidatorSelection, IRollup, RollupCore { */ function validateHeaderWithAttestations( ProposedHeader calldata _header, - CommitteeAttestations memory _attestations, + CommitteeAttestations calldata _attestations, address[] calldata _signers, - Signature memory _attestationsAndSignersSignature, + Signature calldata _attestationsAndSignersSignature, bytes32 _digest, bytes32 _blobsHash, - CheckpointHeaderValidationFlags memory _flags + CheckpointHeaderValidationFlags calldata _flags ) external override(IRollup) { RollupOperationsExtLib.validateHeaderWithAttestations( - ValidateHeaderArgs({ - header: _header, - digest: _digest, - manaMinFee: getManaMinFeeAt(Timestamp.wrap(block.timestamp), true), - blobsHashesCommitment: _blobsHash, - flags: _flags - }), - _attestations, - _signers, - _attestationsAndSignersSignature + _header, _attestations, _signers, _attestationsAndSignersSignature, _digest, _blobsHash, _flags ); } @@ -335,6 +325,19 @@ contract Rollup is IStaking, IValidatorSelection, IRollup, RollupCore { return STFLib.getStorage().tips.getPending(); } + /** + * @notice Get the prover that first proved a given checkpoint + * + * @dev Reverts if the checkpoint is not proven yet + * + * @param _checkpointNumber - The checkpoint number to look up + * + * @return address - The prover that first proved the checkpoint + */ + function getFirstProvenBy(uint256 _checkpointNumber) external view override(IRollup) returns (address) { + return RewardExtLib.getFirstProvenBy(_checkpointNumber); + } + function getCheckpoint(uint256 _checkpointNumber) external view override(IRollup) returns (CheckpointLog memory) { TempCheckpointLog memory tempCheckpointLog = STFLib.getTempCheckpointLog(_checkpointNumber); return CheckpointLog({ @@ -604,14 +607,6 @@ contract Rollup is IStaking, IValidatorSelection, IRollup, RollupCore { return ValidatorOperationsExtLib.getEntryQueueAt(_index); } - function getSlasherExecutionDelay() external pure override(IStaking) returns (uint256) { - return StakingLib.SLASHER_EXECUTION_DELAY; - } - - function getLegacySlasherDrainWindow() external pure override(IStaking) returns (uint256) { - return StakingLib.LEGACY_SLASHER_DRAIN_WINDOW; - } - function getProtocolFeeRecipient() external view override(IRollup) returns (address) { return RewardExtLib.getProtocolFeeRecipient(); } @@ -620,6 +615,14 @@ contract Rollup is IStaking, IValidatorSelection, IRollup, RollupCore { return RewardExtLib.getProtocolFeeMargin(); } + function getSlasherExecutionDelay() external pure override(IStaking) returns (uint256) { + return StakingLib.SLASHER_EXECUTION_DELAY; + } + + function getLegacySlasherDrainWindow() external pure override(IStaking) returns (uint256) { + return StakingLib.LEGACY_SLASHER_DRAIN_WINDOW; + } + /** * @notice Get the validator set for a given epoch * diff --git a/l1-contracts/src/core/interfaces/IRollup.sol b/l1-contracts/src/core/interfaces/IRollup.sol index 42d01ffbab07..7bc6755b0d31 100644 --- a/l1-contracts/src/core/interfaces/IRollup.sol +++ b/l1-contracts/src/core/interfaces/IRollup.sol @@ -103,6 +103,9 @@ struct RollupStore { // The following represents a circular buffer. Key is `checkpointNumber % size`. mapping(uint256 circularIndex => CompressedTempCheckpointLog temp) tempCheckpointLogs; RollupConfig config; + // Only written at the checkpoint a proof ended at, so entries are sparse: a proof of checkpoints 1-10 followed by + // one of 11-20 records entries at 10 and 20 only. Use getFirstProvenBy to resolve an arbitrary checkpoint number. + mapping(uint256 checkpointNumber => uint256 encodedProverId) firstProvenBy; } interface IRollupCore { @@ -208,6 +211,7 @@ interface IRollup is IRollupCore, IHaveVersion { function getEthPerFeeAsset() external view returns (EthPerFeeAssetE12); function getEpochForCheckpoint(uint256 _checkpointNumber) external view returns (Epoch); + function getFirstProvenBy(uint256 _checkpointNumber) external view returns (address); function canPruneAtTime(Timestamp _ts) external view returns (bool); function archive() external view returns (bytes32); diff --git a/l1-contracts/src/core/libraries/Errors.sol b/l1-contracts/src/core/libraries/Errors.sol index a5fa0201a8d9..e5ba67475e93 100644 --- a/l1-contracts/src/core/libraries/Errors.sol +++ b/l1-contracts/src/core/libraries/Errors.sol @@ -104,6 +104,7 @@ library Errors { error Rollup__CannotInvalidateEscapeHatch(); error Rollup__InvalidEscapeHatchProposer(address expected, address actual); error Rollup__FieldElementOutOfRange(bytes32 value); + error Rollup__CheckpointNotProven(uint256 proven, uint256 requested); // EscapeHatch error EscapeHatch__AlreadyInCandidateSet(address candidate); diff --git a/l1-contracts/src/core/libraries/rollup/EpochProofLib.sol b/l1-contracts/src/core/libraries/rollup/EpochProofLib.sol index d80ad215a1f0..d67d36352010 100644 --- a/l1-contracts/src/core/libraries/rollup/EpochProofLib.sol +++ b/l1-contracts/src/core/libraries/rollup/EpochProofLib.sol @@ -129,6 +129,10 @@ library EpochProofLib { if (_args.end > tips.getProven()) { rollupStore.tips = tips.updateProven(_args.end); + // Record who proved this range. Only the end checkpoint gets an entry, so lookups for the checkpoints in + // between walk forward to it; a later proof of an already proven range cannot reach here and overwrite it. + STFLib.recordFirstProvenBy(_args.end, _args.args.proverId); + // Handle L2->L1 message processing. // The circuit outputs an empty out hash tree root if the epoch contains no messages. // Since the out hash tree is append-only, with the first checkpoint at index 0, the second at index 1, and so on, diff --git a/l1-contracts/src/core/libraries/rollup/RewardExtLib.sol b/l1-contracts/src/core/libraries/rollup/RewardExtLib.sol index a8e83ae78f07..8b0aacd3dd03 100644 --- a/l1-contracts/src/core/libraries/rollup/RewardExtLib.sol +++ b/l1-contracts/src/core/libraries/rollup/RewardExtLib.sol @@ -115,6 +115,10 @@ library RewardExtLib { return STFLib.getEpochForCheckpoint(_checkpointNumber); } + function getFirstProvenBy(uint256 _checkpointNumber) external view returns (address) { + return STFLib.getFirstProvenBy(_checkpointNumber); + } + function getL1FeesAt(Timestamp _timestamp) external view returns (L1FeeData memory) { return FeeLib.getL1FeesAt(_timestamp); } diff --git a/l1-contracts/src/core/libraries/rollup/RollupOperationsExtLib.sol b/l1-contracts/src/core/libraries/rollup/RollupOperationsExtLib.sol index 8d3a5a5e93b2..d6b72a142598 100644 --- a/l1-contracts/src/core/libraries/rollup/RollupOperationsExtLib.sol +++ b/l1-contracts/src/core/libraries/rollup/RollupOperationsExtLib.sol @@ -4,10 +4,12 @@ pragma solidity >=0.8.27; import {Errors} from "@aztec/core/libraries/Errors.sol"; +import {CheckpointHeaderValidationFlags} from "@aztec/core/interfaces/IRollup.sol"; import {STFLib} from "@aztec/core/libraries/rollup/STFLib.sol"; import {Timestamp, TimeLib, Slot, Epoch} from "@aztec/core/libraries/TimeLib.sol"; import {BlobLib} from "@aztec-blob-lib/BlobLib.sol"; import {AttestationLib} from "@aztec/core/libraries/rollup/AttestationLib.sol"; +import {FeeLib} from "@aztec/core/libraries/rollup/FeeLib.sol"; import { ProposeLib, ProposeArgs, @@ -15,6 +17,7 @@ import { ValidateHeaderArgs, ValidatorSelectionLib } from "./ProposeLib.sol"; +import {ProposedHeader} from "./ProposedHeaderLib.sol"; import {Signature} from "@aztec/shared/libraries/SignatureLib.sol"; /** @@ -37,21 +40,32 @@ library RollupOperationsExtLib { using AttestationLib for CommitteeAttestations; function validateHeaderWithAttestations( - ValidateHeaderArgs calldata _args, + ProposedHeader calldata _header, CommitteeAttestations calldata _attestations, address[] calldata _signers, - Signature calldata _attestationsAndSignersSignature + Signature calldata _attestationsAndSignersSignature, + bytes32 _digest, + bytes32 _blobsHash, + CheckpointHeaderValidationFlags calldata _flags ) external { - ProposeLib.validateHeader(_args); + ProposeLib.validateHeader( + ValidateHeaderArgs({ + header: _header, + digest: _digest, + manaMinFee: FeeLib.summedMinFee(ProposeLib.getManaMinFeeComponentsAt(Timestamp.wrap(block.timestamp), true)), + blobsHashesCommitment: _blobsHash, + flags: _flags + }) + ); if (_attestations.isEmpty()) { return; // No attestations to validate } - Slot slot = _args.header.slotNumber; + Slot slot = _header.slotNumber; Epoch epoch = slot.epochFromSlot(); - ValidatorSelectionLib.verifyAttestations(epoch, _attestations, _args.digest); + ValidatorSelectionLib.verifyAttestations(epoch, _attestations, _digest); ValidatorSelectionLib.verifyProposer( - slot, epoch, _attestations, _signers, _args.digest, _attestationsAndSignersSignature, false + slot, epoch, _attestations, _signers, _digest, _attestationsAndSignersSignature, false ); } diff --git a/l1-contracts/src/core/libraries/rollup/STFLib.sol b/l1-contracts/src/core/libraries/rollup/STFLib.sol index fa9fc2e5c681..29a834f3dba6 100644 --- a/l1-contracts/src/core/libraries/rollup/STFLib.sol +++ b/l1-contracts/src/core/libraries/rollup/STFLib.sol @@ -89,6 +89,8 @@ library STFLib { using CompressedTimeMath for CompressedSlot; using FeeHeaderLib for CompressedFeeHeader; + uint256 private constant PROVER_ID_PRESENT_BIT = 1 << 160; + // @note This is also used in the cheatcodes, so if updating, please also update the cheatcode. bytes32 private constant STF_STORAGE_POSITION = keccak256("aztec.stf.storage"); @@ -189,6 +191,17 @@ library STFLib { emit IRollupCore.PrunedPending(proven, pending); } + /** + * @notice Records the prover that proved up to the given checkpoint + * @dev Only ever called with a checkpoint number above the proven tip, and the proven tip never moves backwards, + * so an entry for `_checkpointNumber` cannot already exist and the write is unconditional. + * @param _checkpointNumber The last checkpoint number covered by the proof + * @param _proverId The prover that submitted the proof + */ + function recordFirstProvenBy(uint256 _checkpointNumber, address _proverId) internal { + getStorage().firstProvenBy[_checkpointNumber] = uint256(uint160(_proverId)) | PROVER_ID_PRESENT_BIT; + } + /** * @notice Calculates the size of the circular storage buffer for temporary checkpoint logs * @dev The roundabout size determines how many checkpoints can be stored in the circular buffer @@ -362,6 +375,40 @@ library STFLib { return getSlotNumber(_checkpointNumber).epochFromSlot(); } + /** + * @notice Returns the prover that first proved the given checkpoint + * + * @dev Entries are only written at the checkpoint a proof ended at, so this walks forward from + * `_checkpointNumber` until it hits one. The first entry found at or after `_checkpointNumber` belongs to the + * earliest proof that covered the checkpoint, since the proven tip only ever advances. Proofs cover at most + * one epoch, so the walk terminates within `epochDuration` steps. + * + * @dev Errors Thrown: + * - Rollup__CheckpointNotProven: The checkpoint is beyond the proven tip, so no prover exists for it + * + * @param _checkpointNumber The checkpoint number to look up + * @return The prover that first proved the checkpoint + */ + function getFirstProvenBy(uint256 _checkpointNumber) internal view returns (address) { + RollupStore storage rollupStore = STFLib.getStorage(); + uint256 proven = rollupStore.tips.getProven(); + require( + 0 < _checkpointNumber && _checkpointNumber <= proven, + Errors.Rollup__CheckpointNotProven(proven, _checkpointNumber) + ); + + for (uint256 i = _checkpointNumber; i <= proven; i++) { + uint256 encodedProverId = rollupStore.firstProvenBy[i]; + if (encodedProverId != 0) { + return address(uint160(encodedProverId)); + } + } + + // Unreachable: the proof that advanced the proven tip past `_checkpointNumber` ended at some checkpoint in + // [_checkpointNumber, proven] and wrote its entry there. + revert Errors.Rollup__CheckpointNotProven(proven, _checkpointNumber); + } + /** * @notice Determines if the chain can be pruned at a given timestamp * @dev Checks whether the proof submission window has expired for the oldest pending checkpoints. diff --git a/l1-contracts/test/MultiProof.t.sol b/l1-contracts/test/MultiProof.t.sol index 016681817a4a..d287712a3923 100644 --- a/l1-contracts/test/MultiProof.t.sol +++ b/l1-contracts/test/MultiProof.t.sol @@ -245,6 +245,61 @@ contract MultiProofTest is RollupBase { ); } + function testFirstProvenByRecordsFirstProver() public setUpFor("mixed_checkpoint_1") { + address alice = address(bytes20("alice")); + address bob = address(bytes20("bob")); + + deal(address(testERC20), address(feeJuicePortal), 30e6 * 1e18); + + _proposeCheckpoint("mixed_checkpoint_1", 1, 15e6); + _proposeCheckpoint("mixed_checkpoint_2", 2, 15e6); + + vm.expectRevert(abi.encodeWithSelector(Errors.Rollup__CheckpointNotProven.selector, 0, 1)); + rollup.getFirstProvenBy(1); + + string memory name = "mixed_checkpoint_"; + _proveCheckpoints(name, 1, 1, alice); + // Bob proving the same range again must not take credit for checkpoint 1. + _proveCheckpoints(name, 1, 1, bob); + _proveCheckpoints(name, 1, 2, bob); + + assertEq(rollup.getFirstProvenBy(1), alice, "Checkpoint 1 not credited to alice"); + assertEq(rollup.getFirstProvenBy(2), bob, "Checkpoint 2 not credited to bob"); + + vm.expectRevert(abi.encodeWithSelector(Errors.Rollup__CheckpointNotProven.selector, 2, 3)); + rollup.getFirstProvenBy(3); + } + + function testFirstProvenByWalksForwardToNextEntry() public setUpFor("mixed_checkpoint_1") { + address alice = address(bytes20("alice")); + + deal(address(testERC20), address(feeJuicePortal), 30e6 * 1e18); + + _proposeCheckpoint("mixed_checkpoint_1", 1, 15e6); + _proposeCheckpoint("mixed_checkpoint_2", 2, 15e6); + + // A single proof of 1-2 only records an entry at checkpoint 2, so a lookup of 1 walks forward to it. + string memory name = "mixed_checkpoint_"; + _proveCheckpoints(name, 1, 2, alice); + + assertEq(rollup.getFirstProvenBy(1), alice, "Checkpoint 1 not credited to alice"); + assertEq(rollup.getFirstProvenBy(2), alice, "Checkpoint 2 not credited to alice"); + } + + function testFirstProvenByRecordsZeroAddress() public setUpFor("mixed_checkpoint_1") { + deal(address(testERC20), address(feeJuicePortal), 30e6 * 1e18); + + _proposeCheckpoint("mixed_checkpoint_1", 1, 15e6); + + string memory name = "mixed_checkpoint_"; + _proveCheckpoints(name, 1, 1, address(0)); + + assertEq(rollup.getFirstProvenBy(1), address(0), "Checkpoint 1 not credited to zero address"); + + vm.expectRevert(abi.encodeWithSelector(Errors.Rollup__CheckpointNotProven.selector, 1, 0)); + rollup.getFirstProvenBy(0); + } + function testProofsAreInOneEpoch() public setUpFor("mixed_checkpoint_1") { _proposeCheckpoint("mixed_checkpoint_1", 1, 15e6); _proposeCheckpoint("mixed_checkpoint_2", TestConstants.AZTEC_EPOCH_DURATION + 1, 15e6); diff --git a/labs-patches/0006-feat-introduce-a-protocol-fee-margin-AZIP-23.patch b/labs-patches/0006-feat-introduce-a-protocol-fee-margin-AZIP-23.patch index 5d5977f8db34..631e557780d2 100644 --- a/labs-patches/0006-feat-introduce-a-protocol-fee-margin-AZIP-23.patch +++ b/labs-patches/0006-feat-introduce-a-protocol-fee-margin-AZIP-23.patch @@ -388,8 +388,8 @@ index c2707c9072..5f9ccc0bfb 100644 + // The predictor must agree with L1 exactly at mu != 0. This is the only check that catches + // the same factor+divisor double-scaling on the TS side of the mirror. + for (const manaUsage of Object.values(ManaUsageEstimate)) { -+ const predictor = new FeePredictor(rollup, dateProvider, feePredictorConfig); -+ const predicted = await predictor.getPredictedMinFees(manaUsage); ++ const predictor = await makeRefreshedPredictor(); ++ const predicted = predictor.getPredictedMinFees(manaUsage); + const predictionStartSlot = await getPredictionStartSlot(); + const l1FeeAtStart = await rollup.getManaMinFeeAt(getTimestamp(predictionStartSlot), true); + expect(predicted[0].feePerL2Gas).toBe(l1FeeAtStart); From c8227bb29d4aea18d0cd55104238d4a04c348a21 Mon Sep 17 00:00:00 2001 From: Santiago Palladino Date: Fri, 4 Sep 2026 09:44:38 -0300 Subject: [PATCH 05/19] perf(l1): hold the rollup config in immutables instead of storage (#25314) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is the bottom of the Fast Inbox stack: it targets `project/fast-inbox` directly and is independently mergeable — nothing in it depends on the inbox work above it. Every field of `RollupConfig` — `vkTreeRoot`, `protocolContractsHash`, `version`, `feeAsset`, `feeAssetPortal`, `epochProofVerifier`, `inbox`, `outbox` — is written exactly once in the Rollup's constructor and has no setter anywhere in `src/`. They were nonetheless kept in storage, so every read paid a cold `SLOAD`. `propose` paid one, `submitEpochRootProof` paid six. Move all eight into immutables and drop `config` from `RollupStore`. Libraries cannot read a contract's immutables, and the `*ExtLib` libraries here are `external` (delegatecalled), so they cannot either. The values are assembled into a memory `RollupConfig` by `RollupCore._getRollupConfig()` and threaded down as parameters: the full struct into the epoch-proof path, the `IInbox` into propose, and the fee asset into the reward claims. Propose needed its `IInbox` bundled with the existing `checkBlob` flag into a `ProposeConfig` struct — a seventh scalar parameter pushed `ProposeLib.propose` over the stack limit, and a memory struct costs one slot instead of two. `config` was the last member of `RollupStore`, so `tips`, `archives` and `tempCheckpointLogs` keep slots 0–2 and every raw-slot consumer of `keccak256("aztec.stf.storage")` is unaffected — all of them use offsets ≤ +2. The two that used `+3`/`+4` were `RollupContract.getVkTreeRoot` and `getProtocolContractsHash` in the TS client, which now call the contract getters that `IRollup` has exposed since #22563. The second commit is bytecode budget, not gas. Each immutable read inlines a 32-byte push, which grew `Rollup`'s runtime code to within 148 bytes of the EIP-170 limit. `Rollup.validateHeaderWithAttestations` was decoding seven parameters, building a `ValidateHeaderArgs` (which embeds a full `ProposedHeader`) in memory, resolving the mana min fee through two delegatecall hops, and re-encoding four arguments — all in the Rollup's own runtime code. Forwarding the parameters straight through and assembling the struct in `RollupOperationsExtLib` frees 629 bytes. The fee value is unchanged: `RewardExtLib.summedMinFee` and `.getManaMinFeeComponentsAt` are one-line forwarders to the `FeeLib` / `ProposeLib` functions the ExtLib now calls directly. | Benchmark | Before | After | Δ | |---|---|---|---| | `propose` (no validators) | 199,366 | 197,433 | **−1,933** | | `submitEpochRootProof` (no validators) | 991,032 | 980,225 | **−10,807** | | `propose` (100 validators) | 327,774 | 325,847 | **−1,927** | | `submitEpochRootProof` (100 validators) | 1,572,081 | 1,561,291 | **−10,790** | | `aggregate3` (100 validators) | 376,665 | 374,738 | **−1,927** | The config getters lose their cold `SLOAD` outright — `getInbox` 2,543 → 878, `getVersion` 1,447 → 852, `getOutbox` 2,521 → 856. A handful of unrelated views move by 22–44 gas as the Rollup's selector dispatch shifts. Deployment also drops eight `SSTORE`s. `Rollup` runtime bytecode ends at 23,799 against the 24,576 limit — 777 bytes of margin, against 886 before this change. Note on the regenerated `gas_report.json`: call counts on a few entries drop by 36 because the three tests that fail only under `FORGE_GAS_REPORT` (`testExtraBlobs`, `testRevertInvalidCoinbase`, `testRevertInvalidTimestamp` — all failing identically on the base commit) abort at a slightly different point. Per-call gas for those entries is unchanged. Node binaries already in the field read `vkTreeRoot` and `protocolContractsHash` from raw slots `+3`/`+4`. Against a rollup deployed from this branch those slots are zero, so such a node's `waitForCompatibleRollup` reports a VK mismatch and sits in standby. it work against a rollup deployed from either version; it does nothing for binaries already released, so this needs sequencing against any node rollout. --- l1-contracts/src/core/Rollup.sol | 27 ++++---- l1-contracts/src/core/RollupCore.sol | 66 ++++++++++++------- l1-contracts/src/core/interfaces/IRollup.sol | 7 +- .../libraries/rollup/EpochProofExtLib.sol | 11 ++-- .../core/libraries/rollup/EpochProofLib.sol | 46 ++++++++----- .../src/core/libraries/rollup/ProposeLib.sol | 20 ++++-- .../core/libraries/rollup/RewardExtLib.sol | 9 +-- .../src/core/libraries/rollup/RewardLib.sol | 26 ++++---- .../rollup/RollupOperationsExtLib.sol | 19 +++++- .../src/core/libraries/rollup/STFLib.sol | 14 ++-- l1-contracts/test/RollupWithPreheating.sol | 3 +- .../libraries/rewardlib/RewardLibWrapper.sol | 17 +++-- 12 files changed, 168 insertions(+), 97 deletions(-) diff --git a/l1-contracts/src/core/Rollup.sol b/l1-contracts/src/core/Rollup.sol index d7a641f3719f..e3adf00c52b6 100644 --- a/l1-contracts/src/core/Rollup.sol +++ b/l1-contracts/src/core/Rollup.sol @@ -13,7 +13,8 @@ import { EthPerFeeAssetE12, CheckpointHeaderValidationFlags, FeeHeader, - RollupConfigInput + RollupConfigInput, + RollupStore } from "@aztec/core/interfaces/IRollup.sol"; import {IStaking, AttesterConfig, Exit, AttesterView, Status} from "@aztec/core/interfaces/IStaking.sol"; import {IValidatorSelection, IEmperor} from "@aztec/core/interfaces/IValidatorSelection.sol"; @@ -45,7 +46,6 @@ import { ValidatorOperationsExtLib, EthValue, STFLib, - RollupStore, IInbox, IOutbox } from "./RollupCore.sol"; @@ -291,7 +291,9 @@ contract Rollup is IStaking, IValidatorSelection, IRollup, RollupCore { ProposedHeader[] calldata _headers, bytes calldata _blobPublicInputs ) external view override(IRollup) returns (bytes32[] memory) { - return EpochProofExtLib.getEpochProofPublicInputs(_start, _end, _args, _headers, _blobPublicInputs); + return EpochProofExtLib.getEpochProofPublicInputs( + _start, _end, _args, _headers, _blobPublicInputs, _getRollupConfig() + ); } /** @@ -543,36 +545,39 @@ contract Rollup is IStaking, IValidatorSelection, IRollup, RollupCore { return RewardExtLib.getProvingCostPerMana().toFeeAsset(getEthPerFeeAsset()); } + // The config getters below go through {_getRollupConfig} rather than reading their immutable + // directly. Each direct read inlines a 32-byte push into this contract's runtime code, and Rollup + // sits close to the EIP-170 limit; sharing one assembly across all of them is ~95 bytes cheaper. function getVersion() external view override(IHaveVersion) returns (uint256) { - return STFLib.getStorage().config.version; + return _getRollupConfig().version; } function getInbox() external view override(IRollup) returns (IInbox) { - return STFLib.getStorage().config.inbox; + return _getRollupConfig().inbox; } function getOutbox() external view override(IRollup) returns (IOutbox) { - return STFLib.getStorage().config.outbox; + return _getRollupConfig().outbox; } function getFeeAsset() external view override(IRollup) returns (IERC20) { - return STFLib.getStorage().config.feeAsset; + return _getRollupConfig().feeAsset; } function getFeeAssetPortal() external view override(IRollup) returns (IFeeJuicePortal) { - return STFLib.getStorage().config.feeAssetPortal; + return _getRollupConfig().feeAssetPortal; } function getVkTreeRoot() external view override(IRollup) returns (bytes32) { - return STFLib.getStorage().config.vkTreeRoot; + return _getRollupConfig().vkTreeRoot; } function getProtocolContractsHash() external view override(IRollup) returns (bytes32) { - return STFLib.getStorage().config.protocolContractsHash; + return _getRollupConfig().protocolContractsHash; } function getEpochProofVerifier() external view override(IRollup) returns (IVerifier) { - return STFLib.getStorage().config.epochProofVerifier; + return _getRollupConfig().epochProofVerifier; } function getRewardDistributor() external view override(IRollup) returns (IRewardDistributor) { diff --git a/l1-contracts/src/core/RollupCore.sol b/l1-contracts/src/core/RollupCore.sol index c11485dcb0cc..46a344e7ad61 100644 --- a/l1-contracts/src/core/RollupCore.sol +++ b/l1-contracts/src/core/RollupCore.sol @@ -6,7 +6,7 @@ pragma solidity >=0.8.27; import {IFeeJuicePortal} from "@aztec/core/interfaces/IFeeJuicePortal.sol"; import { IRollupCore, - RollupStore, + RollupConfig, SubmitEpochRootProofArgs, RollupConfigInput } from "@aztec/core/interfaces/IRollup.sol"; @@ -189,6 +189,18 @@ contract RollupCore is EIP712("Aztec Rollup", "1"), Ownable, IStakingCore, IVali */ uint256 public immutable L1_BLOCK_AT_GENESIS; + // The deployment-time rollup configuration. Every value is fixed at construction, so it is held in + // immutables rather than storage; {_getRollupConfig} assembles it for the libraries, which cannot read + // a contract's immutables themselves. + bytes32 internal immutable VK_TREE_ROOT; + bytes32 internal immutable PROTOCOL_CONTRACTS_HASH; + uint32 internal immutable VERSION; + IERC20 internal immutable FEE_ASSET; + IFeeJuicePortal internal immutable FEE_ASSET_PORTAL; + IVerifier internal immutable EPOCH_PROOF_VERIFIER; + IInbox internal immutable INBOX; + IOutbox internal immutable OUTBOX; + /** * @dev Storage gap to ensure checkBlob is in its own storage slot */ @@ -266,7 +278,20 @@ contract RollupCore is EIP712("Aztec Rollup", "1"), Ownable, IStakingCore, IVali L1_BLOCK_AT_GENESIS = block.number; - _initializeStore(_feeAsset, _epochProofVerifier, _genesisState, _config); + // Immutables must be assigned directly in the constructor body, so the store setup cannot be + // factored out into a helper the way the slasher and reward setup are. + VK_TREE_ROOT = _genesisState.vkTreeRoot; + PROTOCOL_CONTRACTS_HASH = _genesisState.protocolContractsHash; + VERSION = _config.version; + FEE_ASSET = _feeAsset; + EPOCH_PROOF_VERIFIER = _epochProofVerifier; + + IInbox inbox = IInbox(address(new Inbox(address(this), _feeAsset, _config.version, INBOX_BUCKET_RING_SIZE))); + INBOX = inbox; + OUTBOX = IOutbox(address(new Outbox(address(this), _config.version))); + FEE_ASSET_PORTAL = IFeeJuicePortal(inbox.getFeeAssetPortal()); + + STFLib.initialize(_genesisState); FeeLib.initialize(_config.manaTarget, _config.provingCostPerMana, _config.initialEthPerFeeAsset); } @@ -385,7 +410,7 @@ contract RollupCore is EIP712("Aztec Rollup", "1"), Ownable, IStakingCore, IVali * @return The amount of rewards claimed */ function claimSequencerRewards(address _coinbase) external override(IRollupCore) returns (uint256) { - return RewardExtLib.claimSequencerRewards(_coinbase); + return RewardExtLib.claimSequencerRewards(_coinbase, FEE_ASSET); } /** @@ -401,7 +426,7 @@ contract RollupCore is EIP712("Aztec Rollup", "1"), Ownable, IStakingCore, IVali override(IRollupCore) returns (uint256) { - return RewardExtLib.claimProverRewards(_coinbase, _epochs); + return RewardExtLib.claimProverRewards(_coinbase, _epochs, FEE_ASSET); } /** @@ -501,7 +526,7 @@ contract RollupCore is EIP712("Aztec Rollup", "1"), Ownable, IStakingCore, IVali * @param _args Contains the epoch range, public inputs, fees, attestations, and the ZK proof */ function submitEpochRootProof(SubmitEpochRootProofArgs calldata _args) external override(IRollupCore) { - EpochProofExtLib.submitEpochRootProof(_args); + EpochProofExtLib.submitEpochRootProof(_args, _getRollupConfig()); } /** @@ -524,7 +549,7 @@ contract RollupCore is EIP712("Aztec Rollup", "1"), Ownable, IStakingCore, IVali bytes calldata _blobInput ) external override(IRollupCore) { RollupOperationsExtLib.propose( - _args, _attestations, _signers, _attestationsAndSignersSignature, _blobInput, checkBlob + _args, _attestations, _signers, _attestationsAndSignersSignature, _blobInput, checkBlob, INBOX ); } @@ -641,23 +666,16 @@ contract RollupCore is EIP712("Aztec Rollup", "1"), Ownable, IStakingCore, IVali RewardExtLib.initializeConfig(rewardConfig); } - function _initializeStore( - IERC20 _feeAsset, - IVerifier _epochProofVerifier, - GenesisState memory _genesisState, - RollupConfigInput memory _config - ) internal { - STFLib.initialize(_genesisState); - RollupStore storage rollupStore = STFLib.getStorage(); - - rollupStore.config.feeAsset = _feeAsset; - rollupStore.config.epochProofVerifier = _epochProofVerifier; - rollupStore.config.version = _config.version; - - IInbox inbox = IInbox(address(new Inbox(address(this), _feeAsset, _config.version, INBOX_BUCKET_RING_SIZE))); - - rollupStore.config.inbox = inbox; - rollupStore.config.outbox = IOutbox(address(new Outbox(address(this), _config.version))); - rollupStore.config.feeAssetPortal = IFeeJuicePortal(inbox.getFeeAssetPortal()); + function _getRollupConfig() internal view returns (RollupConfig memory) { + return RollupConfig({ + vkTreeRoot: VK_TREE_ROOT, + protocolContractsHash: PROTOCOL_CONTRACTS_HASH, + version: VERSION, + feeAsset: FEE_ASSET, + feeAssetPortal: FEE_ASSET_PORTAL, + epochProofVerifier: EPOCH_PROOF_VERIFIER, + inbox: INBOX, + outbox: OUTBOX + }); } } diff --git a/l1-contracts/src/core/interfaces/IRollup.sol b/l1-contracts/src/core/interfaces/IRollup.sol index 7bc6755b0d31..1173348f4e52 100644 --- a/l1-contracts/src/core/interfaces/IRollup.sol +++ b/l1-contracts/src/core/interfaces/IRollup.sol @@ -86,6 +86,12 @@ struct RollupConfigInput { uint256 ethereumSlotDuration; } +/** + * @notice The rollup's deployment-time configuration. + * @dev Every field is fixed at construction, so the values live in the Rollup's immutables rather than + * in storage. This struct is assembled in memory and threaded down into the libraries, which cannot + * read the contract's immutables themselves. + */ struct RollupConfig { bytes32 vkTreeRoot; bytes32 protocolContractsHash; @@ -102,7 +108,6 @@ struct RollupStore { mapping(uint256 checkpointNumber => bytes32 archive) archives; // The following represents a circular buffer. Key is `checkpointNumber % size`. mapping(uint256 circularIndex => CompressedTempCheckpointLog temp) tempCheckpointLogs; - RollupConfig config; // Only written at the checkpoint a proof ended at, so entries are sparse: a proof of checkpoints 1-10 followed by // one of 11-20 records entries at 10 and 20 only. Use getFirstProvenBy to resolve an arbitrary checkpoint number. mapping(uint256 checkpointNumber => uint256 encodedProverId) firstProvenBy; diff --git a/l1-contracts/src/core/libraries/rollup/EpochProofExtLib.sol b/l1-contracts/src/core/libraries/rollup/EpochProofExtLib.sol index a71251c19a7b..bda2a0bf61d8 100644 --- a/l1-contracts/src/core/libraries/rollup/EpochProofExtLib.sol +++ b/l1-contracts/src/core/libraries/rollup/EpochProofExtLib.sol @@ -2,7 +2,7 @@ // Copyright 2024 Aztec Labs. pragma solidity >=0.8.27; -import {SubmitEpochRootProofArgs, PublicInputArgs} from "@aztec/core/interfaces/IRollup.sol"; +import {SubmitEpochRootProofArgs, PublicInputArgs, RollupConfig} from "@aztec/core/interfaces/IRollup.sol"; import {ProposedHeader} from "@aztec/core/libraries/rollup/ProposedHeaderLib.sol"; import {EpochProofLib} from "./EpochProofLib.sol"; @@ -20,8 +20,8 @@ import {EpochProofLib} from "./EpochProofLib.sol"; * - Epoch proof public input computation */ library EpochProofExtLib { - function submitEpochRootProof(SubmitEpochRootProofArgs calldata _args) external { - EpochProofLib.submitEpochRootProof(_args); + function submitEpochRootProof(SubmitEpochRootProofArgs calldata _args, RollupConfig memory _config) external { + EpochProofLib.submitEpochRootProof(_args, _config); } function getEpochProofPublicInputs( @@ -29,8 +29,9 @@ library EpochProofExtLib { uint256 _end, PublicInputArgs calldata _args, ProposedHeader[] calldata _headers, - bytes calldata _blobPublicInputs + bytes calldata _blobPublicInputs, + RollupConfig memory _config ) external view returns (bytes32[] memory) { - return EpochProofLib.getEpochProofPublicInputs(_start, _end, _args, _headers, _blobPublicInputs); + return EpochProofLib.getEpochProofPublicInputs(_start, _end, _args, _headers, _blobPublicInputs, _config); } } diff --git a/l1-contracts/src/core/libraries/rollup/EpochProofLib.sol b/l1-contracts/src/core/libraries/rollup/EpochProofLib.sol index d67d36352010..c696254019db 100644 --- a/l1-contracts/src/core/libraries/rollup/EpochProofLib.sol +++ b/l1-contracts/src/core/libraries/rollup/EpochProofLib.sol @@ -4,7 +4,13 @@ pragma solidity >=0.8.27; import {BlobLib} from "@aztec-blob-lib/BlobLib.sol"; import {IEscapeHatch} from "@aztec/core/interfaces/IEscapeHatch.sol"; -import {SubmitEpochRootProofArgs, PublicInputArgs, IRollupCore, RollupStore} from "@aztec/core/interfaces/IRollup.sol"; +import { + SubmitEpochRootProofArgs, + PublicInputArgs, + IRollupCore, + RollupStore, + RollupConfig +} from "@aztec/core/interfaces/IRollup.sol"; import {CompressedTempCheckpointLog} from "@aztec/core/libraries/compressed-data/CheckpointLog.sol"; import {CompressedFeeHeader, FeeHeaderLib} from "@aztec/core/libraries/compressed-data/fees/FeeStructs.sol"; import {ChainTipsLib, CompressedChainTips} from "@aztec/core/libraries/compressed-data/Tips.sol"; @@ -101,8 +107,9 @@ library EpochProofLib { * - attestations: Committee attestations for the last checkpoint in the epoch * - blobInputs: Batched blob data for EIP-4844 point evaluation precompile * - proof: The validity proof bytes for the root rollup circuit + * @param _config The rollup's deployment-time configuration */ - function submitEpochRootProof(SubmitEpochRootProofArgs calldata _args) internal { + function submitEpochRootProof(SubmitEpochRootProofArgs calldata _args, RollupConfig memory _config) internal { if (STFLib.canPruneAtTime(Timestamp.wrap(block.timestamp))) { STFLib.prune(); } @@ -118,7 +125,7 @@ library EpochProofLib { // ensuring committee agreement on the epoch's validity alongside the cryptographic proof verification below. verifyLastCheckpointAttestationsAndOutHash(_args.end, _args.attestations, _args.args.outHash); - require(verifyEpochRootProof(_args), Errors.Rollup__InvalidProof()); + require(verifyEpochRootProof(_args, _config), Errors.Rollup__InvalidProof()); RollupStore storage rollupStore = STFLib.getStorage(); CompressedChainTips tips = rollupStore.tips; @@ -143,12 +150,12 @@ library EpochProofLib { // the number of checkpoints proven in this epoch so off-chain consumers can map a tx's // position-within-epoch directly to the smallest proof that covers it. uint256 numCheckpointsInEpoch = _args.end - _args.start + 1; - rollupStore.config.outbox.insert(endEpoch, numCheckpointsInEpoch, _args.args.outHash); + _config.outbox.insert(endEpoch, numCheckpointsInEpoch, _args.args.outHash); } } // Activity score depends on whether the proof is a full epoch proof - RewardLib.handleRewardsAndFees(_args, endEpoch, fullEpochProof); + RewardLib.handleRewardsAndFees(_args, endEpoch, _config, fullEpochProof); emit IRollupCore.L2ProofVerified(_args.end, _args.args.proverId); } @@ -170,16 +177,18 @@ library EpochProofLib { * @param _args - Array of public inputs to the proof (previousArchive, endArchive, endTimestamp, outHash, proverId) * @param _headers - The proposed checkpoint headers supplying the fee recipient and value for each checkpoint * @param _blobPublicInputs- The blob public inputs for the proof + * @param _config - The rollup's deployment-time configuration */ function getEpochProofPublicInputs( uint256 _start, uint256 _end, PublicInputArgs calldata _args, ProposedHeader[] calldata _headers, - bytes calldata _blobPublicInputs + bytes calldata _blobPublicInputs, + RollupConfig memory _config ) internal view returns (bytes32[] memory) { verifyHeaders(_start, _end, _headers); - return computeEpochProofPublicInputs(_start, _end, _args, _headers, _blobPublicInputs); + return computeEpochProofPublicInputs(_start, _end, _args, _headers, _blobPublicInputs, _config); } /** @@ -248,13 +257,15 @@ library EpochProofLib { * @param _args - Array of public inputs to the proof (previousArchive, endArchive, endTimestamp, outHash, proverId) * @param _headers - The proposed checkpoint headers supplying the fee recipient and value for each checkpoint * @param _blobPublicInputs- The blob public inputs for the proof + * @param _config - The rollup's deployment-time configuration */ function computeEpochProofPublicInputs( uint256 _start, uint256 _end, PublicInputArgs calldata _args, ProposedHeader[] calldata _headers, - bytes calldata _blobPublicInputs + bytes calldata _blobPublicInputs, + RollupConfig memory _config ) private view returns (bytes32[] memory) { RollupStore storage rollupStore = STFLib.getStorage(); @@ -347,15 +358,15 @@ library EpochProofLib { publicInputs[offset] = bytes32(block.chainid); offset += 1; - publicInputs[offset] = bytes32(uint256(rollupStore.config.version)); + publicInputs[offset] = bytes32(uint256(_config.version)); offset += 1; // vk_tree_root - publicInputs[offset] = rollupStore.config.vkTreeRoot; + publicInputs[offset] = _config.vkTreeRoot; offset += 1; // protocol_contracts_hash - publicInputs[offset] = rollupStore.config.protocolContractsHash; + publicInputs[offset] = _config.protocolContractsHash; offset += 1; // prover_id: id of current epoch's prover @@ -523,17 +534,20 @@ library EpochProofLib { * - Rollup__InvalidArchive: End archive root mismatch in public inputs * * @param _args The epoch proof submission arguments containing proof data and public inputs + * @param _config The rollup's deployment-time configuration * @return True if both blob proof and validity proof verification succeed */ - function verifyEpochRootProof(SubmitEpochRootProofArgs calldata _args) private view returns (bool) { - RollupStore storage rollupStore = STFLib.getStorage(); - + function verifyEpochRootProof(SubmitEpochRootProofArgs calldata _args, RollupConfig memory _config) + private + view + returns (bool) + { BlobLib.validateBatchedBlob(_args.blobInputs); bytes32[] memory publicInputs = - computeEpochProofPublicInputs(_args.start, _args.end, _args.args, _args.headers, _args.blobInputs); + computeEpochProofPublicInputs(_args.start, _args.end, _args.args, _args.headers, _args.blobInputs, _config); - require(rollupStore.config.epochProofVerifier.verify(_args.proof, publicInputs), Errors.Rollup__InvalidProof()); + require(_config.epochProofVerifier.verify(_args.proof, publicInputs), Errors.Rollup__InvalidProof()); return true; } diff --git a/l1-contracts/src/core/libraries/rollup/ProposeLib.sol b/l1-contracts/src/core/libraries/rollup/ProposeLib.sol index d2447ce33713..83a0004a14e5 100644 --- a/l1-contracts/src/core/libraries/rollup/ProposeLib.sol +++ b/l1-contracts/src/core/libraries/rollup/ProposeLib.sol @@ -39,6 +39,17 @@ struct ProposePayload { bytes32 headerHash; } +/** + * @notice The caller-supplied context for a proposal, bundled to keep `propose` off the stack limit. + * @param inbox - The Inbox the header's streaming message consumption is validated against + * @param checkBlob - Whether to run blob related checks. Hardcoded to true in RollupCore, exists only to be + * overridden in tests + */ +struct ProposeConfig { + IInbox inbox; + bool checkBlob; +} + struct InterimProposeValues { ProposedHeader header; bytes32[] blobHashes; @@ -168,8 +179,7 @@ library ProposeLib { * @param _blobsInput - The bytes to verify our input blob commitments match real blobs: * - input[:1] - num blobs in checkpoint * - input[1:] - blob commitments (48 bytes * num blobs in checkpoint) - * @param _checkBlob - Whether to skip blob related checks. Hardcoded to true in RollupCore, exists only to be - * overridden in tests + * @param _config - The Inbox to validate message consumption against, and the blob check flag */ function propose( ProposeArgs calldata _args, @@ -177,7 +187,7 @@ library ProposeLib { address[] memory _signers, Signature calldata _attestationsAndSignersSignature, bytes calldata _blobsInput, - bool _checkBlob + ProposeConfig memory _config ) internal { // Prune unproven checkpoints if the proof submission window has passed if (STFLib.canPruneAtTime(Timestamp.wrap(block.timestamp))) { @@ -192,7 +202,7 @@ library ProposeLib { // Validate blob commitments against actual blob data and extract hashes // TODO(#13430): The below blobsHashesCommitment known as blobsHash elsewhere in the code. The name is confusingly // similar to blobCommitmentsHash, see comment in BlobLib.sol -> validateBlobs(). - (v.blobHashes, v.blobsHashesCommitment, v.blobCommitments) = BlobLib.validateBlobs(_blobsInput, _checkBlob); + (v.blobHashes, v.blobsHashesCommitment, v.blobCommitments) = BlobLib.validateBlobs(_blobsInput, _config.checkBlob); v.header = _args.header; @@ -269,7 +279,7 @@ library ProposeLib { // child validates against it and, since temp-log records rewind with the pending chain on a prune, the record // stays prune-consistent. v.consumedInboxMsgTotal = validateInboxConsumption( - rollupStore.config.inbox, + _config.inbox, v.header.inboxRollingHash, _args.bucketHint, v.header.slotNumber, diff --git a/l1-contracts/src/core/libraries/rollup/RewardExtLib.sol b/l1-contracts/src/core/libraries/rollup/RewardExtLib.sol index 8b0aacd3dd03..59df10cc37e4 100644 --- a/l1-contracts/src/core/libraries/rollup/RewardExtLib.sol +++ b/l1-contracts/src/core/libraries/rollup/RewardExtLib.sol @@ -20,6 +20,7 @@ import { IValidatorSelection } from "@aztec/core/reward-boost/RewardBooster.sol"; import {IRewardDistributor} from "@aztec/governance/interfaces/IRewardDistributor.sol"; +import {IERC20} from "@oz/token/ERC20/IERC20.sol"; library RewardExtLib { function initializeConfig(RewardConfig memory _config) external { @@ -38,12 +39,12 @@ library RewardExtLib { return RewardLib.updateProtocolFeeRecipient(_recipient); } - function claimSequencerRewards(address _sequencer) external returns (uint256) { - return RewardLib.claimSequencerRewards(_sequencer); + function claimSequencerRewards(address _sequencer, IERC20 _feeAsset) external returns (uint256) { + return RewardLib.claimSequencerRewards(_sequencer, _feeAsset); } - function claimProverRewards(address _prover, Epoch[] memory _epochs) external returns (uint256) { - return RewardLib.claimProverRewards(_prover, _epochs); + function claimProverRewards(address _prover, Epoch[] memory _epochs, IERC20 _feeAsset) external returns (uint256) { + return RewardLib.claimProverRewards(_prover, _epochs, _feeAsset); } function deployRewardBooster(RewardBoostConfig memory _config) external returns (IBoosterCore) { diff --git a/l1-contracts/src/core/libraries/rollup/RewardLib.sol b/l1-contracts/src/core/libraries/rollup/RewardLib.sol index 7590d8085f88..5bcb21e51895 100644 --- a/l1-contracts/src/core/libraries/rollup/RewardLib.sol +++ b/l1-contracts/src/core/libraries/rollup/RewardLib.sol @@ -2,7 +2,7 @@ // Copyright 2024 Aztec Labs. pragma solidity >=0.8.27; -import {RollupStore, SubmitEpochRootProofArgs} from "@aztec/core/interfaces/IRollup.sol"; +import {RollupConfig, SubmitEpochRootProofArgs} from "@aztec/core/interfaces/IRollup.sol"; import {CompressedFeeHeader, FeeHeaderLib} from "@aztec/core/libraries/compressed-data/fees/FeeStructs.sol"; import {Errors} from "@aztec/core/libraries/Errors.sol"; import {STFLib} from "@aztec/core/libraries/rollup/STFLib.sol"; @@ -113,22 +113,20 @@ library RewardLib { rewardStorage.config.checkpointReward = _config.checkpointReward; } - function claimSequencerRewards(address _sequencer) internal returns (uint256) { + function claimSequencerRewards(address _sequencer, IERC20 _feeAsset) internal returns (uint256) { RewardStorage storage rewardStorage = getStorage(); - RollupStore storage rollupStore = STFLib.getStorage(); uint256 amount = rewardStorage.sequencerRewards[_sequencer]; if (amount > 0) { rewardStorage.sequencerRewards[_sequencer] = 0; - rollupStore.config.feeAsset.safeTransfer(_sequencer, amount); + _feeAsset.safeTransfer(_sequencer, amount); } return amount; } - function claimProverRewards(address _prover, Epoch[] memory _epochs) internal returns (uint256) { + function claimProverRewards(address _prover, Epoch[] memory _epochs, IERC20 _feeAsset) internal returns (uint256) { Epoch currentEpoch = Timestamp.wrap(block.timestamp).epochFromTimestamp(); - RollupStore storage rollupStore = STFLib.getStorage(); RewardStorage storage rewardStorage = getStorage(); @@ -153,16 +151,18 @@ library RewardLib { } if (accumulatedRewards > 0) { - rollupStore.config.feeAsset.safeTransfer(_prover, accumulatedRewards); + _feeAsset.safeTransfer(_prover, accumulatedRewards); } return accumulatedRewards; } - function handleRewardsAndFees(SubmitEpochRootProofArgs calldata _args, Epoch _endEpoch, bool _fullEpochProof) - internal - { - RollupStore storage rollupStore = STFLib.getStorage(); + function handleRewardsAndFees( + SubmitEpochRootProofArgs calldata _args, + Epoch _endEpoch, + RollupConfig memory _config, + bool _fullEpochProof + ) internal { RewardStorage storage rewardStorage = getStorage(); uint256 length = _args.end - _args.start + 1; @@ -251,11 +251,11 @@ library RewardLib { $er.longestProvenLength = length.toUint128(); if (t.feesToClaim > 0) { - rollupStore.config.feeAssetPortal.distributeFees(address(this), t.feesToClaim); + _config.feeAssetPortal.distributeFees(address(this), t.feesToClaim); } if (t.totalProtocolFee > 0) { - rollupStore.config.feeAsset.safeTransfer(rewardStorage.protocolFeeRecipient, t.totalProtocolFee); + _config.feeAsset.safeTransfer(rewardStorage.protocolFeeRecipient, t.totalProtocolFee); } } } diff --git a/l1-contracts/src/core/libraries/rollup/RollupOperationsExtLib.sol b/l1-contracts/src/core/libraries/rollup/RollupOperationsExtLib.sol index d6b72a142598..20837d10f2dd 100644 --- a/l1-contracts/src/core/libraries/rollup/RollupOperationsExtLib.sol +++ b/l1-contracts/src/core/libraries/rollup/RollupOperationsExtLib.sol @@ -5,6 +5,7 @@ pragma solidity >=0.8.27; import {Errors} from "@aztec/core/libraries/Errors.sol"; import {CheckpointHeaderValidationFlags} from "@aztec/core/interfaces/IRollup.sol"; +import {IInbox} from "@aztec/core/interfaces/messagebridge/IInbox.sol"; import {STFLib} from "@aztec/core/libraries/rollup/STFLib.sol"; import {Timestamp, TimeLib, Slot, Epoch} from "@aztec/core/libraries/TimeLib.sol"; import {BlobLib} from "@aztec-blob-lib/BlobLib.sol"; @@ -13,6 +14,7 @@ import {FeeLib} from "@aztec/core/libraries/rollup/FeeLib.sol"; import { ProposeLib, ProposeArgs, + ProposeConfig, CommitteeAttestations, ValidateHeaderArgs, ValidatorSelectionLib @@ -39,6 +41,11 @@ library RollupOperationsExtLib { using TimeLib for Slot; using AttestationLib for CommitteeAttestations; + /** + * @dev Assembles `ValidateHeaderArgs` here rather than in the Rollup: building that struct + * (which embeds a full `ProposedHeader`) in the Rollup's own code costs several hundred + * bytes of runtime bytecode it cannot spare. + */ function validateHeaderWithAttestations( ProposedHeader calldata _header, CommitteeAttestations calldata _attestations, @@ -75,9 +82,17 @@ library RollupOperationsExtLib { address[] calldata _signers, Signature calldata _attestationsAndSignersSignature, bytes calldata _blobInput, - bool _checkBlob + bool _checkBlob, + IInbox _inbox ) external { - ProposeLib.propose(_args, _attestations, _signers, _attestationsAndSignersSignature, _blobInput, _checkBlob); + ProposeLib.propose( + _args, + _attestations, + _signers, + _attestationsAndSignersSignature, + _blobInput, + ProposeConfig({inbox: _inbox, checkBlob: _checkBlob}) + ); } function prune() external { diff --git a/l1-contracts/src/core/libraries/rollup/STFLib.sol b/l1-contracts/src/core/libraries/rollup/STFLib.sol index 29a834f3dba6..ecf4b651c040 100644 --- a/l1-contracts/src/core/libraries/rollup/STFLib.sol +++ b/l1-contracts/src/core/libraries/rollup/STFLib.sol @@ -95,21 +95,15 @@ library STFLib { bytes32 private constant STF_STORAGE_POSITION = keccak256("aztec.stf.storage"); /** - * @notice Initializes the rollup state with genesis configuration - * @dev Sets up the initial state of the rollup including verification keys and the genesis archive root. - * This function should only be called once during rollup deployment. + * @notice Writes the genesis archive root at checkpoint 0 + * @dev Should only be called once during rollup deployment. The remaining genesis fields + * (vkTreeRoot, protocolContractsHash) are held in the Rollup's immutables. * - * @param _genesisState The initial state configuration containing: - * - vkTreeRoot: Root of the verification key tree for circuit verification - * - protocolContractsHash: Root containing protocol contract addresses and configurations - * - genesisArchiveRoot: Initial archive root representing the genesis state + * @param _genesisState The initial state configuration; only `genesisArchiveRoot` is read here */ function initialize(GenesisState memory _genesisState) internal { RollupStore storage rollupStore = STFLib.getStorage(); - rollupStore.config.vkTreeRoot = _genesisState.vkTreeRoot; - rollupStore.config.protocolContractsHash = _genesisState.protocolContractsHash; - // The genesis archive root is decoded as an Fr off chain and propagates into the first header's lastArchiveRoot, // so it must be a valid field element. FieldLib.requireValidFieldElement(_genesisState.genesisArchiveRoot); diff --git a/l1-contracts/test/RollupWithPreheating.sol b/l1-contracts/test/RollupWithPreheating.sol index 1636a6ea0a5d..a41e269b5d33 100644 --- a/l1-contracts/test/RollupWithPreheating.sol +++ b/l1-contracts/test/RollupWithPreheating.sol @@ -7,7 +7,8 @@ import {IERC20} from "@aztec/core/interfaces/IRollup.sol"; import {IRollupCore} from "@aztec/core/interfaces/IRollup.sol"; import {GSE} from "@aztec/governance/GSE.sol"; import {IVerifier} from "@aztec/core/interfaces/IVerifier.sol"; -import {STFLib, RollupStore, RollupCore} from "@aztec/core/RollupCore.sol"; +import {STFLib, RollupCore} from "@aztec/core/RollupCore.sol"; +import {RollupStore} from "@aztec/core/interfaces/IRollup.sol"; import {CompressedFeeHeader, FeeHeaderLib} from "@aztec/core/libraries/compressed-data/fees/FeeStructs.sol"; import { CompressedTempCheckpointLogLib, diff --git a/l1-contracts/test/rollup/libraries/rewardlib/RewardLibWrapper.sol b/l1-contracts/test/rollup/libraries/rewardlib/RewardLibWrapper.sol index d825641d64ed..efbc6a2b2a73 100644 --- a/l1-contracts/test/rollup/libraries/rewardlib/RewardLibWrapper.sol +++ b/l1-contracts/test/rollup/libraries/rewardlib/RewardLibWrapper.sol @@ -7,7 +7,7 @@ import {Timestamp, Slot, Epoch} from "@aztec/core/libraries/TimeLib.sol"; import {RewardBooster, IBoosterCore, RewardBoostConfig} from "@aztec/core/reward-boost/RewardBooster.sol"; import {IValidatorSelection} from "@aztec/core/interfaces/IValidatorSelection.sol"; import {Bps} from "@aztec/core/libraries/rollup/RewardLib.sol"; -import {SubmitEpochRootProofArgs} from "@aztec/core/interfaces/IRollup.sol"; +import {SubmitEpochRootProofArgs, RollupConfig} from "@aztec/core/interfaces/IRollup.sol"; import {STFLib, RollupStore} from "@aztec/core/libraries/rollup/STFLib.sol"; import {IERC20} from "@oz/token/ERC20/IERC20.sol"; import {IRewardDistributor} from "@aztec/governance/interfaces/IRewardDistributor.sol"; @@ -63,6 +63,8 @@ contract RewardLibWrapper { RewardBooster internal booster; Epoch internal currentEpoch; + IERC20 internal immutable FEE_ASSET; + IFeeJuicePortal internal immutable FEE_ASSET_PORTAL; FakeRewardDistributor public rewardDistributor; FakeFeePortal public feePortal; @@ -83,9 +85,8 @@ contract RewardLibWrapper { RewardLib.initializeConfig(config); - RollupStore storage rollupStore = STFLib.getStorage(); - rollupStore.config.feeAsset = _feeAsset; - rollupStore.config.feeAssetPortal = IFeeJuicePortal(address(feePortal)); + FEE_ASSET = _feeAsset; + FEE_ASSET_PORTAL = IFeeJuicePortal(address(feePortal)); TimeLib.initialize( block.timestamp, @@ -137,13 +138,19 @@ contract RewardLibWrapper { } function handleRewardsAndFees(SubmitEpochRootProofArgs calldata _args, Epoch _endEpoch) external { - RewardLib.handleRewardsAndFees(_args, _endEpoch, true); + RewardLib.handleRewardsAndFees(_args, _endEpoch, _rollupConfig(), true); } function getSequencerRewards(address _sequencer) external view returns (uint256) { return RewardLib.getSequencerRewards(_sequencer); } + // Only the fields handleRewardsAndFees reads are populated; the rest stay zero. + function _rollupConfig() internal view returns (RollupConfig memory config) { + config.feeAsset = FEE_ASSET; + config.feeAssetPortal = FEE_ASSET_PORTAL; + } + function getCollectiveProverRewardsForEpoch(Epoch _epoch) external view returns (uint256) { return RewardLib.getCollectiveProverRewardsForEpoch(_epoch); } From cdb8e8e84ec825972f001bd19d795bf85f1862eb Mon Sep 17 00:00:00 2001 From: Santiago Palladino Date: Tue, 8 Sep 2026 17:48:38 -0300 Subject: [PATCH 06/19] refactor(ethereum): read rollup config via getters --- ...m-read-vkTreeRoot-and-protocolContra.patch | 49 +++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 labs-patches/0011-refactor-ethereum-read-vkTreeRoot-and-protocolContra.patch diff --git a/labs-patches/0011-refactor-ethereum-read-vkTreeRoot-and-protocolContra.patch b/labs-patches/0011-refactor-ethereum-read-vkTreeRoot-and-protocolContra.patch new file mode 100644 index 000000000000..395ed117e172 --- /dev/null +++ b/labs-patches/0011-refactor-ethereum-read-vkTreeRoot-and-protocolContra.patch @@ -0,0 +1,49 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Santiago Palladino +Date: Tue, 8 Sep 2026 17:46:57 -0300 +Subject: [PATCH] refactor(ethereum): read vkTreeRoot and protocolContractsHash + via their getters + + +diff --git a/yarn-project/ethereum/src/contracts/rollup.test.ts b/yarn-project/ethereum/src/contracts/rollup.test.ts +index 2262d7755c2938fd1cf066743c63196e77fab7a9..54744f5474fa00832e9eb0abc510bea8a90bbaec 100644 +--- a/yarn-project/ethereum/src/contracts/rollup.test.ts ++++ b/yarn-project/ethereum/src/contracts/rollup.test.ts +@@ -362,12 +362,12 @@ describe('Rollup', () => { + }); + + describe('getVkTreeRoot and getProtocolContractsHash', () => { +- it('reads vkTreeRoot from storage', async () => { ++ it('reads vkTreeRoot', async () => { + const result = await rollup.getVkTreeRoot(); + expect(result).toEqual(vkTreeRoot); + }); + +- it('reads protocolContractsHash from storage', async () => { ++ it('reads protocolContractsHash', async () => { + const result = await rollup.getProtocolContractsHash(); + expect(result).toEqual(protocolContractsHash); + }); +diff --git a/yarn-project/ethereum/src/contracts/rollup.ts b/yarn-project/ethereum/src/contracts/rollup.ts +index cd27a307a7c8c8182b9f0e19647914424a20f5e6..6ac1639751d082d633487d7dcf04fa58714f82d1 100644 +--- a/yarn-project/ethereum/src/contracts/rollup.ts ++++ b/yarn-project/ethereum/src/contracts/rollup.ts +@@ -459,16 +459,12 @@ export class RollupContract { + + @memoize + async getVkTreeRoot(): Promise { +- const slot = BigInt(RollupContract.stfStorageSlot) + 3n; +- const value = await this.client.getStorageAt({ address: this.address, slot: `0x${slot.toString(16)}` }); +- return Fr.fromString(value ?? '0x0'); ++ return Fr.fromString(await this.rollup.read.getVkTreeRoot()); + } + + @memoize + async getProtocolContractsHash(): Promise { +- const slot = BigInt(RollupContract.stfStorageSlot) + 4n; +- const value = await this.client.getStorageAt({ address: this.address, slot: `0x${slot.toString(16)}` }); +- return Fr.fromString(value ?? '0x0'); ++ return Fr.fromString(await this.rollup.read.getProtocolContractsHash()); + } + + /** From 7a5b777993b5d086a6a47261f67259f59a04b3f5 Mon Sep 17 00:00:00 2001 From: Santiago Palladino Date: Tue, 8 Sep 2026 17:51:20 -0300 Subject: [PATCH 07/19] fix(l1): resolve v6 integration conflicts --- .../test/benchmark/PartialEpochProofGasReporter.sol | 10 +++++----- l1-contracts/test/fees/FeeRollup.t.sol | 5 ++++- .../test/fees/ProtocolFeeMarginRateLimit.t.sol | 3 ++- 3 files changed, 11 insertions(+), 7 deletions(-) diff --git a/l1-contracts/test/benchmark/PartialEpochProofGasReporter.sol b/l1-contracts/test/benchmark/PartialEpochProofGasReporter.sol index 14fc704eecc3..31ab591eb221 100644 --- a/l1-contracts/test/benchmark/PartialEpochProofGasReporter.sol +++ b/l1-contracts/test/benchmark/PartialEpochProofGasReporter.sol @@ -25,34 +25,34 @@ contract PartialEpochProofGasReporter is RollupWithPreheating { * Reports submission gas for a fresh one-checkpoint epoch prefix. */ function gasReportSubmit1Checkpoint(SubmitEpochRootProofArgs calldata _args) external { - EpochProofExtLib.submitEpochRootProof(_args); + EpochProofExtLib.submitEpochRootProof(_args, _getRollupConfig()); } /** * Reports submission gas for a fresh eight-checkpoint epoch prefix. */ function gasReportSubmit8Checkpoints(SubmitEpochRootProofArgs calldata _args) external { - EpochProofExtLib.submitEpochRootProof(_args); + EpochProofExtLib.submitEpochRootProof(_args, _getRollupConfig()); } /** * Reports submission gas for checkpoints nine through sixteen after an eight-checkpoint prefix. */ function gasReportSubmit8MoreCheckpoints(SubmitEpochRootProofArgs calldata _args) external { - EpochProofExtLib.submitEpochRootProof(_args); + EpochProofExtLib.submitEpochRootProof(_args, _getRollupConfig()); } /** * Reports submission gas for a fresh sixteen-checkpoint epoch prefix. */ function gasReportSubmit16Checkpoints(SubmitEpochRootProofArgs calldata _args) external { - EpochProofExtLib.submitEpochRootProof(_args); + EpochProofExtLib.submitEpochRootProof(_args, _getRollupConfig()); } /** * Reports submission gas for a complete thirty-two-checkpoint epoch. */ function gasReportSubmit32Checkpoints(SubmitEpochRootProofArgs calldata _args) external { - EpochProofExtLib.submitEpochRootProof(_args); + EpochProofExtLib.submitEpochRootProof(_args, _getRollupConfig()); } } diff --git a/l1-contracts/test/fees/FeeRollup.t.sol b/l1-contracts/test/fees/FeeRollup.t.sol index 4fc88fec5166..5370189d34c9 100644 --- a/l1-contracts/test/fees/FeeRollup.t.sol +++ b/l1-contracts/test/fees/FeeRollup.t.sol @@ -346,13 +346,16 @@ contract FeeRollupTest is FeeModelTestPoints, DecoderBase { if (rollup.getCurrentSlot() == nextSlot) { TestPoint memory point = points[Slot.unwrap(nextSlot) - 1]; Checkpoint memory b = getCheckpoint(); + uint256 bucketHint = rollup.getInbox().getCurrentBucketSeq(); + b.header.inboxRollingHash = rollup.getInbox().getBucket(bucketHint).rollingHash; skipBlobCheck(address(rollup)); checkpointHeaders[rollup.getPendingCheckpointNumber() + 1] = b.header; rollup.propose( ProposeArgs({ header: b.header, archive: b.archive, - oracleInput: OracleInput({feeAssetPriceModifier: point.oracle_input.fee_asset_price_modifier}) + oracleInput: OracleInput({feeAssetPriceModifier: point.oracle_input.fee_asset_price_modifier}), + bucketHint: bucketHint }), AttestationLibHelper.packAttestations(b.attestations), b.signers, diff --git a/l1-contracts/test/fees/ProtocolFeeMarginRateLimit.t.sol b/l1-contracts/test/fees/ProtocolFeeMarginRateLimit.t.sol index 8d8803459748..64c4874b71d6 100644 --- a/l1-contracts/test/fees/ProtocolFeeMarginRateLimit.t.sol +++ b/l1-contracts/test/fees/ProtocolFeeMarginRateLimit.t.sol @@ -42,7 +42,8 @@ contract FeeLibMarginHarness { block.timestamp, TestConstants.AZTEC_SLOT_DURATION, TestConstants.AZTEC_EPOCH_DURATION, - TestConstants.AZTEC_PROOF_SUBMISSION_EPOCHS + TestConstants.AZTEC_PROOF_SUBMISSION_EPOCHS, + TestConstants.ETHEREUM_SLOT_DURATION ); FeeLib.initialize( TestConstants.AZTEC_MANA_TARGET, EthValue.wrap(100), TestConstants.AZTEC_INITIAL_ETH_PER_FEE_ASSET From dff14494168843f2bd4856a674fd562ce9871d32 Mon Sep 17 00:00:00 2001 From: Santiago Palladino Date: Tue, 8 Sep 2026 18:07:01 -0300 Subject: [PATCH 08/19] fix(l1): preserve config for gas reporter --- l1-contracts/src/core/RollupCore.sol | 2 +- .../PartialEpochProofGasReporter.sol | 26 ++++++++++++++++--- l1-contracts/test/benchmark/happy.t.sol | 4 ++- 3 files changed, 27 insertions(+), 5 deletions(-) diff --git a/l1-contracts/src/core/RollupCore.sol b/l1-contracts/src/core/RollupCore.sol index 46a344e7ad61..1f0610da09ed 100644 --- a/l1-contracts/src/core/RollupCore.sol +++ b/l1-contracts/src/core/RollupCore.sol @@ -666,7 +666,7 @@ contract RollupCore is EIP712("Aztec Rollup", "1"), Ownable, IStakingCore, IVali RewardExtLib.initializeConfig(rewardConfig); } - function _getRollupConfig() internal view returns (RollupConfig memory) { + function _getRollupConfig() internal view virtual returns (RollupConfig memory) { return RollupConfig({ vkTreeRoot: VK_TREE_ROOT, protocolContractsHash: PROTOCOL_CONTRACTS_HASH, diff --git a/l1-contracts/test/benchmark/PartialEpochProofGasReporter.sol b/l1-contracts/test/benchmark/PartialEpochProofGasReporter.sol index 31ab591eb221..731103ac03d7 100644 --- a/l1-contracts/test/benchmark/PartialEpochProofGasReporter.sol +++ b/l1-contracts/test/benchmark/PartialEpochProofGasReporter.sol @@ -5,12 +5,21 @@ pragma solidity >=0.8.27; import {RollupWithPreheating} from "../RollupWithPreheating.sol"; import {GenesisState, RollupConfigInput} from "@aztec/core/Rollup.sol"; -import {IERC20, SubmitEpochRootProofArgs} from "@aztec/core/interfaces/IRollup.sol"; +import { + IERC20, + IFeeJuicePortal, + IOutbox, + RollupConfig, + SubmitEpochRootProofArgs +} from "@aztec/core/interfaces/IRollup.sol"; import {IVerifier} from "@aztec/core/interfaces/IVerifier.sol"; import {EpochProofExtLib} from "@aztec/core/libraries/rollup/EpochProofExtLib.sol"; import {GSE} from "@aztec/governance/GSE.sol"; contract PartialEpochProofGasReporter is RollupWithPreheating { + IOutbox private immutable ORIGINAL_OUTBOX; + IFeeJuicePortal private immutable ORIGINAL_FEE_ASSET_PORTAL; + constructor( IERC20 _feeAsset, IERC20 _stakingAsset, @@ -18,8 +27,19 @@ contract PartialEpochProofGasReporter is RollupWithPreheating { IVerifier _epochProofVerifier, address _governance, GenesisState memory _genesisState, - RollupConfigInput memory _config - ) RollupWithPreheating(_feeAsset, _stakingAsset, _gse, _epochProofVerifier, _governance, _genesisState, _config) {} + RollupConfigInput memory _config, + IOutbox _originalOutbox, + IFeeJuicePortal _originalFeeAssetPortal + ) RollupWithPreheating(_feeAsset, _stakingAsset, _gse, _epochProofVerifier, _governance, _genesisState, _config) { + ORIGINAL_OUTBOX = _originalOutbox; + ORIGINAL_FEE_ASSET_PORTAL = _originalFeeAssetPortal; + } + + function _getRollupConfig() internal view override returns (RollupConfig memory config) { + config = super._getRollupConfig(); + config.outbox = ORIGINAL_OUTBOX; + config.feeAssetPortal = ORIGINAL_FEE_ASSET_PORTAL; + } /** * Reports submission gas for a fresh one-checkpoint epoch prefix. diff --git a/l1-contracts/test/benchmark/happy.t.sol b/l1-contracts/test/benchmark/happy.t.sol index ceff5ae76dab..ce291c9d2e59 100644 --- a/l1-contracts/test/benchmark/happy.t.sol +++ b/l1-contracts/test/benchmark/happy.t.sol @@ -221,7 +221,9 @@ abstract contract BenchmarkRollupBase is FeeModelTestPoints, DecoderBase { rollup.getEpochProofVerifier(), address(this), config.genesisState, - config.rollupConfigInput + config.rollupConfigInput, + rollup.getOutbox(), + rollup.getFeeAssetPortal() ); // Keep the initialized rollup storage while exposing named gas-report entrypoints. vm.etch(address(rollup), address(reporter).code); From 3395e3384aa2fc7e81a9be59d4d8df5c062b42c3 Mon Sep 17 00:00:00 2001 From: Santiago Palladino Date: Tue, 8 Sep 2026 18:19:27 -0300 Subject: [PATCH 09/19] refactor(l1): keep rollup within code size limit --- l1-contracts/src/core/Rollup.sol | 10 ++++++---- .../src/core/libraries/rollup/RewardExtLib.sol | 16 ---------------- 2 files changed, 6 insertions(+), 20 deletions(-) diff --git a/l1-contracts/src/core/Rollup.sol b/l1-contracts/src/core/Rollup.sol index e3adf00c52b6..d7fad9afdc23 100644 --- a/l1-contracts/src/core/Rollup.sol +++ b/l1-contracts/src/core/Rollup.sol @@ -30,6 +30,8 @@ import {CompressedSlot, CompressedTimestamp, CompressedTimeMath} from "@aztec/sh import {Signature} from "@aztec/shared/libraries/SignatureLib.sol"; import {ChainTipsLib, CompressedChainTips} from "./libraries/compressed-data/Tips.sol"; import {RewardExtLib, RewardConfig} from "./libraries/rollup/RewardExtLib.sol"; +import {FeeLib} from "./libraries/rollup/FeeLib.sol"; +import {RewardLib} from "./libraries/rollup/RewardLib.sol"; import {DepositArgs} from "./libraries/StakingQueue.sol"; import { RollupCore, @@ -236,11 +238,11 @@ contract Rollup is IStaking, IValidatorSelection, IRollup, RollupCore { } function getManaTarget() external view override(IRollup) returns (uint256) { - return RewardExtLib.getManaTarget(); + return FeeLib.getManaTarget(); } function getManaLimit() external view override(IRollup) returns (uint256) { - return RewardExtLib.getManaLimit(); + return FeeLib.getManaLimit(); } function getTips() external view override(IRollup) returns (ChainTips memory) { @@ -613,11 +615,11 @@ contract Rollup is IStaking, IValidatorSelection, IRollup, RollupCore { } function getProtocolFeeRecipient() external view override(IRollup) returns (address) { - return RewardExtLib.getProtocolFeeRecipient(); + return RewardLib.getProtocolFeeRecipient(); } function getProtocolFeeMargin() external view override(IRollup) returns (uint16) { - return RewardExtLib.getProtocolFeeMargin(); + return FeeLib.getProtocolFeeMarginBps(); } function getSlasherExecutionDelay() external pure override(IStaking) returns (uint256) { diff --git a/l1-contracts/src/core/libraries/rollup/RewardExtLib.sol b/l1-contracts/src/core/libraries/rollup/RewardExtLib.sol index 59df10cc37e4..19e1d5a719be 100644 --- a/l1-contracts/src/core/libraries/rollup/RewardExtLib.sol +++ b/l1-contracts/src/core/libraries/rollup/RewardExtLib.sol @@ -90,14 +90,6 @@ library RewardExtLib { return RewardLib.getStorage().config.rewardDistributor; } - function getProtocolFeeRecipient() external view returns (address) { - return RewardLib.getProtocolFeeRecipient(); - } - - function getProtocolFeeMargin() external view returns (uint16) { - return FeeLib.getProtocolFeeMarginBps(); - } - // FeeLib/STFLib/ProposeLib view wrappers - overflow from RollupOperationsExtLib function getManaMinFeeComponentsAt(Timestamp _timestamp, bool _inFeeAsset) @@ -132,14 +124,6 @@ library RewardExtLib { return FeeLib.getProvingCostPerMana(); } - function getManaTarget() external view returns (uint256) { - return FeeLib.getManaTarget(); - } - - function getManaLimit() external view returns (uint256) { - return FeeLib.getManaLimit(); - } - function summedMinFee(ManaMinFeeComponents memory _components) external pure returns (uint256) { return FeeLib.summedMinFee(_components); } From 8af227713cf1077fd2dd0ac88d9a798cc9e7add7 Mon Sep 17 00:00:00 2001 From: Santiago Palladino Date: Tue, 8 Sep 2026 18:21:56 -0300 Subject: [PATCH 10/19] chore(l1): update gas reports --- l1-contracts/gas_benchmark.md | 14 +- l1-contracts/gas_benchmark_results.json | 40 ++-- l1-contracts/gas_report.json | 216 +++++++++--------- .../partial_epoch_proof_gas_report.json | 42 ++-- .../partial_epoch_proof_gas_report.md | 12 +- 5 files changed, 162 insertions(+), 162 deletions(-) diff --git a/l1-contracts/gas_benchmark.md b/l1-contracts/gas_benchmark.md index acb41156847e..4313a89acaed 100644 --- a/l1-contracts/gas_benchmark.md +++ b/l1-contracts/gas_benchmark.md @@ -14,22 +14,22 @@ | Function | Avg Gas | Max Gas | Calldata Size | Calldata Gas | |----------------------|-----------|-----------|---------------|--------------| -| propose | 200,097 | 226,280 | 996 | 15,936 | -| submitEpochRootProof | 1,035,434 | 1,074,129 | 14,148 | 226,368 | +| propose | 198,220 | 224,403 | 996 | 15,936 | +| submitEpochRootProof | 1,007,926 | 1,046,916 | 14,148 | 226,368 | | setupEpoch | 32,020 | 113,815 | - | - | -**Avg Gas Cost per Second**: 3,691.8 gas/second +**Avg Gas Cost per Second**: 3,641.9 gas/second *Epoch duration*: 0h 38m 24s ## Validators | Function | Avg Gas | Max Gas | Calldata Size | Calldata Gas | |----------------------|-----------|-----------|---------------|--------------| -| propose | 328,507 | 356,323 | 4,516 | 72,256 | -| submitEpochRootProof | 1,616,774 | 1,714,815 | 16,644 | 266,304 | -| aggregate3 | 377,506 | 390,880 | - | - | +| propose | 326,630 | 354,402 | 4,516 | 72,256 | +| submitEpochRootProof | 1,588,977 | 1,687,377 | 16,644 | 266,304 | +| aggregate3 | 375,623 | 388,983 | - | - | | setupEpoch | 46,482 | 547,648 | - | - | -**Avg Gas Cost per Second**: 5,986.2 gas/second +**Avg Gas Cost per Second**: 5,936.0 gas/second *Epoch duration*: 0h 38m 24s diff --git a/l1-contracts/gas_benchmark_results.json b/l1-contracts/gas_benchmark_results.json index eed057dc063a..de2e01a735ba 100644 --- a/l1-contracts/gas_benchmark_results.json +++ b/l1-contracts/gas_benchmark_results.json @@ -2,10 +2,10 @@ "no_validators": { "propose": { "calls": 150, - "min": 186452, - "mean": 200097, - "median": 195841, - "max": 226280, + "min": 184575, + "mean": 198220, + "median": 193964, + "max": 224403, "calldata_size": 996, "calldata_gas": 15936 }, @@ -18,10 +18,10 @@ }, "submitEpochRootProof": { "calls": 4, - "min": 1015256, - "mean": 1035434, - "median": 1026177, - "max": 1074129, + "min": 987727, + "mean": 1007926, + "median": 998531, + "max": 1046916, "calldata_size": 14148, "calldata_gas": 226368 } @@ -29,10 +29,10 @@ "validators": { "propose": { "calls": 150, - "min": 306166, - "mean": 328507, - "median": 327959, - "max": 356323, + "min": 304233, + "mean": 326630, + "median": 326074, + "max": 354402, "calldata_size": 4516, "calldata_gas": 72256 }, @@ -45,19 +45,19 @@ }, "submitEpochRootProof": { "calls": 4, - "min": 1505653, - "mean": 1616774, - "median": 1623315, - "max": 1714815, + "min": 1477673, + "mean": 1588977, + "median": 1595430, + "max": 1687377, "calldata_size": 16644, "calldata_gas": 266304 }, "aggregate3": { "calls": 55, - "min": 366388, - "mean": 377506, - "median": 377191, - "max": 390880 + "min": 364444, + "mean": 375623, + "median": 375366, + "max": 388983 } } } \ No newline at end of file diff --git a/l1-contracts/gas_report.json b/l1-contracts/gas_report.json index 6d7c967d5aef..ad883eb1e8e3 100644 --- a/l1-contracts/gas_report.json +++ b/l1-contracts/gas_report.json @@ -76,7 +76,7 @@ }, "functions": { "getCanonicalRollup()": { - "calls": 1780, + "calls": 1720, "min": 1073, "mean": 4073, "median": 4073, @@ -106,7 +106,7 @@ }, "functions": { "availableTo(address)": { - "calls": 890, + "calls": 860, "min": 20573, "mean": 20573, "median": 20573, @@ -118,7 +118,7 @@ "contract": "test/RollupWithPreheating.sol:RollupWithPreheating", "deployment": { "gas": 0, - "size": 42950 + "size": 43814 }, "functions": { "archive()": { @@ -130,13 +130,13 @@ }, "checkBlob()": { "calls": 1, - "min": 2509, - "mean": 2509, - "median": 2509, - "max": 2509 + "min": 2465, + "mean": 2465, + "median": 2465, + "max": 2465 }, "getCheckpoint(uint256)": { - "calls": 900, + "calls": 870, "min": 27185, "mean": 27185, "median": 27185, @@ -144,101 +144,101 @@ }, "getCheckpointReward()": { "calls": 2589, - "min": 1128, - "mean": 1133, - "median": 1128, - "max": 5628 + "min": 1258, + "mean": 1263, + "median": 1258, + "max": 5758 }, "getCollectiveProverRewardsForEpoch(uint256)": { "calls": 3, - "min": 5837, - "mean": 5837, - "median": 5837, - "max": 5837 + "min": 5926, + "mean": 5926, + "median": 5926, + "max": 5926 }, "getCurrentEpoch()": { - "calls": 891, - "min": 915, - "mean": 915, - "median": 915, - "max": 915 + "calls": 861, + "min": 893, + "mean": 893, + "median": 893, + "max": 893 }, "getCurrentSlot()": { "calls": 100, - "min": 2737, - "mean": 2737, - "median": 2737, - "max": 2737 + "min": 2715, + "mean": 2715, + "median": 2715, + "max": 2715 }, "getEpochDuration()": { "calls": 2, - "min": 2486, - "mean": 2486, - "median": 2486, - "max": 2486 + "min": 2420, + "mean": 2420, + "median": 2420, + "max": 2420 }, "getEpochProofPublicInputs(uint256,uint256,(bytes32,bytes32,bytes32,bytes32,bytes32,address),(bytes32,bytes32,bytes32,bytes32,bytes32,uint256,uint256,address,bytes32,(uint128,uint128),uint256,uint256)[],bytes)": { "calls": 4, - "min": 16751, - "mean": 45593, - "median": 47624, - "max": 70374 + "min": 18578, + "mean": 44270, + "median": 46301, + "max": 65899 }, "getEthPerFeeAsset()": { "calls": 2, - "min": 11043, - "mean": 11043, - "median": 11043, - "max": 11043 + "min": 11021, + "mean": 11021, + "median": 11021, + "max": 11021 }, "getFeeAssetPortal()": { "calls": 4660, - "min": 566, - "mean": 1456, - "median": 566, - "max": 2566 + "min": 857, + "mean": 857, + "median": 857, + "max": 857 }, "getInbox()": { "calls": 9073, - "min": 2543, - "mean": 2543, - "median": 2543, - "max": 2543 + "min": 856, + "mean": 856, + "median": 856, + "max": 856 }, "getL1FeesAt(uint256)": { "calls": 2, - "min": 9086, - "mean": 9086, - "median": 9086, - "max": 9086 + "min": 9020, + "mean": 9020, + "median": 9020, + "max": 9020 }, "getManaMinFeeAt(uint256,bool)": { "calls": 2336, - "min": 27032, - "mean": 28689, - "median": 27032, - "max": 32050 + "min": 27463, + "mean": 29120, + "median": 27463, + "max": 32481 }, "getManaTarget()": { "calls": 1026, - "min": 5526, - "mean": 5526, - "median": 5526, - "max": 5526 + "min": 2612, + "mean": 2612, + "median": 2612, + "max": 2612 }, "getOutbox()": { "calls": 2, - "min": 2521, - "mean": 2521, - "median": 2521, - "max": 2521 + "min": 834, + "mean": 834, + "median": 834, + "max": 834 }, "getPendingCheckpointNumber()": { "calls": 1679, - "min": 2462, - "mean": 2462, - "median": 2462, - "max": 2462 + "min": 2418, + "mean": 2418, + "median": 2418, + "max": 2418 }, "getProvenCheckpointNumber()": { "calls": 1684, @@ -249,80 +249,80 @@ }, "getProvingCostPerManaInEth()": { "calls": 1, - "min": 5729, - "mean": 5729, - "median": 5729, - "max": 5729 + "min": 5685, + "mean": 5685, + "median": 5685, + "max": 5685 }, "getProvingCostPerManaInFeeAsset()": { "calls": 1, - "min": 14475, - "mean": 14475, - "median": 14475, - "max": 14475 + "min": 14431, + "mean": 14431, + "median": 14431, + "max": 14431 }, "getSequencerRewards(address)": { "calls": 2, - "min": 5981, - "mean": 5981, - "median": 5981, - "max": 5981 + "min": 6111, + "mean": 6111, + "median": 6111, + "max": 6111 }, "getTimestampForSlot(uint256)": { "calls": 2442, - "min": 2808, - "mean": 2808, - "median": 2808, - "max": 2808 + "min": 2786, + "mean": 2786, + "median": 2786, + "max": 2786 }, "getVersion()": { "calls": 4919, - "min": 499, - "mean": 1447, - "median": 499, - "max": 2499 + "min": 852, + "mean": 852, + "median": 852, + "max": 852 }, "owner()": { "calls": 5173, - "min": 533, - "mean": 533, - "median": 533, - "max": 2533 + "min": 489, + "mean": 489, + "median": 489, + "max": 2489 }, "propose((bytes32,(int256),(bytes32,bytes32,bytes32,bytes32,bytes32,uint256,uint256,address,bytes32,(uint128,uint128),uint256,uint256),uint256),(bytes,bytes),address[],(uint8,bytes32,bytes32),bytes)": { "calls": 2339, "min": 0, - "mean": 266764, - "median": 284282, - "max": 325392 + "mean": 265620, + "median": 283135, + "max": 324245 }, "prune()": { "calls": 6, - "min": 26689, - "mean": 33247, - "median": 33682, - "max": 38274 + "min": 26667, + "mean": 33225, + "median": 33660, + "max": 38252 }, "setProvingCostPerMana(uint256)": { "calls": 1, - "min": 52474, - "mean": 52474, - "median": 52474, - "max": 52474 + "min": 52597, + "mean": 52597, + "median": 52597, + "max": 52597 }, "submitEpochRootProof((uint256,uint256,(bytes32,bytes32,bytes32,bytes32,bytes32,address),(bytes32,bytes32,bytes32,bytes32,bytes32,uint256,uint256,address,bytes32,(uint128,uint128),uint256,uint256)[],(bytes,bytes),bytes,bytes))": { - "calls": 897, - "min": 58286, - "mean": 374005, - "median": 379619, - "max": 418311 + "calls": 867, + "min": 60150, + "mean": 387517, + "median": 393184, + "max": 429854 }, "updateManaTarget(uint256)": { "calls": 512, "min": 26051, - "mean": 28651, - "median": 27293, - "max": 31299 + "mean": 28724, + "median": 27365, + "max": 31444 } } }, diff --git a/l1-contracts/partial_epoch_proof_gas_report.json b/l1-contracts/partial_epoch_proof_gas_report.json index 10e5964f5a7c..34556de24ad2 100644 --- a/l1-contracts/partial_epoch_proof_gas_report.json +++ b/l1-contracts/partial_epoch_proof_gas_report.json @@ -3,43 +3,43 @@ "contract": "test/RollupWithPreheating.sol:RollupWithPreheating", "deployment": { "gas": 0, - "size": 42950 + "size": 43814 }, "functions": { "gasReportSubmit16Checkpoints((uint256,uint256,(bytes32,bytes32,bytes32,bytes32,bytes32,address),(bytes32,bytes32,bytes32,bytes32,bytes32,uint256,uint256,address,bytes32,(uint128,uint128),uint256,uint256)[],(bytes,bytes),bytes,bytes))": { "calls": 1, - "min": 1291434, - "mean": 1291434, - "median": 1291434, - "max": 1291434 + "min": 1288398, + "mean": 1288398, + "median": 1288398, + "max": 1288398 }, "gasReportSubmit1Checkpoint((uint256,uint256,(bytes32,bytes32,bytes32,bytes32,bytes32,address),(bytes32,bytes32,bytes32,bytes32,bytes32,uint256,uint256,address,bytes32,(uint128,uint128),uint256,uint256)[],(bytes,bytes),bytes,bytes))": { "calls": 1, - "min": 661209, - "mean": 661209, - "median": 661209, - "max": 661209 + "min": 656119, + "mean": 656119, + "median": 656119, + "max": 656119 }, "gasReportSubmit32Checkpoints((uint256,uint256,(bytes32,bytes32,bytes32,bytes32,bytes32,address),(bytes32,bytes32,bytes32,bytes32,bytes32,uint256,uint256,address,bytes32,(uint128,uint128),uint256,uint256)[],(bytes,bytes),bytes,bytes))": { "calls": 1, - "min": 1805036, - "mean": 1805036, - "median": 1805036, - "max": 1805036 + "min": 1819288, + "mean": 1819288, + "median": 1819288, + "max": 1819288 }, "gasReportSubmit8Checkpoints((uint256,uint256,(bytes32,bytes32,bytes32,bytes32,bytes32,address),(bytes32,bytes32,bytes32,bytes32,bytes32,uint256,uint256,address,bytes32,(uint128,uint128),uint256,uint256)[],(bytes,bytes),bytes,bytes))": { "calls": 1, - "min": 980313, - "mean": 980313, - "median": 980313, - "max": 980313 + "min": 977258, + "mean": 977258, + "median": 977258, + "max": 977258 }, "gasReportSubmit8MoreCheckpoints((uint256,uint256,(bytes32,bytes32,bytes32,bytes32,bytes32,address),(bytes32,bytes32,bytes32,bytes32,bytes32,uint256,uint256,address,bytes32,(uint128,uint128),uint256,uint256)[],(bytes,bytes),bytes,bytes))": { "calls": 1, - "min": 988027, - "mean": 988027, - "median": 988027, - "max": 988027 + "min": 1003405, + "mean": 1003405, + "median": 1003405, + "max": 1003405 } } } diff --git a/l1-contracts/partial_epoch_proof_gas_report.md b/l1-contracts/partial_epoch_proof_gas_report.md index 6867f0249955..aaccb50ac1c4 100644 --- a/l1-contracts/partial_epoch_proof_gas_report.md +++ b/l1-contracts/partial_epoch_proof_gas_report.md @@ -2,10 +2,10 @@ | Proof submission | Gas | |---|---:| -| 1 Checkpoint | 661,209 | -| 8 Checkpoints | 980,313 | -| 8 More Checkpoints | 988,027 | -| 16 Checkpoints | 1,291,434 | -| 32 Checkpoints | 1,805,036 | +| 1 Checkpoint | 656,119 | +| 8 Checkpoints | 977,258 | +| 8 More Checkpoints | 1,003,405 | +| 16 Checkpoints | 1,288,398 | +| 32 Checkpoints | 1,819,288 | -Uses the mock epoch proof verifier. +_Uses the mock epoch proof verifier; real ZK verification and top-level transaction calldata gas are not included._ From 1e70324520e708241ce15bc8aa30664e6bc34a9e Mon Sep 17 00:00:00 2001 From: Alex Date: Wed, 9 Sep 2026 14:52:23 +0100 Subject: [PATCH 11/19] feat: checkpoint reward overrides (#25312) Fix A-1800 --- l1-contracts/.gitignore | 2 + .../partial_epoch_proof_gas_report.json | 70 ++++-- .../partial_epoch_proof_gas_report.md | 16 +- .../script/deploy/RollupConfiguration.sol | 22 +- l1-contracts/scripts/network-defaults.json | 2 + .../render_partial_epoch_proof_gas_report.py | 2 +- l1-contracts/src/core/RollupCore.sol | 30 ++- l1-contracts/src/core/interfaces/IRollup.sol | 8 +- .../core/interfaces/IValidatorSelection.sol | 2 + l1-contracts/src/core/libraries/Errors.sol | 6 + .../libraries/rollup/EpochProofExtLib.sol | 9 +- .../core/libraries/rollup/EpochProofLib.sol | 24 +- .../core/libraries/rollup/RewardExtLib.sol | 14 +- .../src/core/libraries/rollup/RewardLib.sol | 206 +++++++++++++++++- .../rollup/ValidatorSelectionLib.sol | 10 +- .../PartialEpochProofGasReporter.sol | 38 +++- l1-contracts/test/benchmark/happy.t.sol | 70 +++++- l1-contracts/test/builder/RollupBuilder.sol | 40 +++- .../libraries/rewardlib/RewardLibWrapper.sol | 53 ++++- .../libraries/rewardlib/registryReward.t.sol | 193 ++++++++++++++++ .../libraries/rewardlib/tryGetRegistry.t.sol | 131 +++++++++++ .../test/rollup/registryRewardOverrides.t.sol | 159 ++++++++++++++ .../test/script/DeployAztecL1Contracts.t.sol | 41 ++++ .../test/script/DeployRollupForUpgrade.t.sol | 3 + 24 files changed, 1085 insertions(+), 66 deletions(-) create mode 100644 l1-contracts/test/rollup/libraries/rewardlib/registryReward.t.sol create mode 100644 l1-contracts/test/rollup/libraries/rewardlib/tryGetRegistry.t.sol create mode 100644 l1-contracts/test/rollup/registryRewardOverrides.t.sol diff --git a/l1-contracts/.gitignore b/l1-contracts/.gitignore index 5913ec3eb1c4..a12c27384498 100644 --- a/l1-contracts/.gitignore +++ b/l1-contracts/.gitignore @@ -44,3 +44,5 @@ gas_benchmark.diff /bench-out /coverage + +.solidity-language-server/ diff --git a/l1-contracts/partial_epoch_proof_gas_report.json b/l1-contracts/partial_epoch_proof_gas_report.json index 34556de24ad2..cf8cb6d47dbe 100644 --- a/l1-contracts/partial_epoch_proof_gas_report.json +++ b/l1-contracts/partial_epoch_proof_gas_report.json @@ -3,43 +3,71 @@ "contract": "test/RollupWithPreheating.sol:RollupWithPreheating", "deployment": { "gas": 0, - "size": 43814 + "size": 44750 }, "functions": { "gasReportSubmit16Checkpoints((uint256,uint256,(bytes32,bytes32,bytes32,bytes32,bytes32,address),(bytes32,bytes32,bytes32,bytes32,bytes32,uint256,uint256,address,bytes32,(uint128,uint128),uint256,uint256)[],(bytes,bytes),bytes,bytes))": { "calls": 1, - "min": 1288398, - "mean": 1288398, - "median": 1288398, - "max": 1288398 + "min": 1298507, + "mean": 1298507, + "median": 1298507, + "max": 1298507 + }, + "gasReportSubmit16CheckpointsWithTwoOverrides((uint256,uint256,(bytes32,bytes32,bytes32,bytes32,bytes32,address),(bytes32,bytes32,bytes32,bytes32,bytes32,uint256,uint256,address,bytes32,(uint128,uint128),uint256,uint256)[],(bytes,bytes),bytes,bytes))": { + "calls": 1, + "min": 1463518, + "mean": 1463518, + "median": 1463518, + "max": 1463518 }, "gasReportSubmit1Checkpoint((uint256,uint256,(bytes32,bytes32,bytes32,bytes32,bytes32,address),(bytes32,bytes32,bytes32,bytes32,bytes32,uint256,uint256,address,bytes32,(uint128,uint128),uint256,uint256)[],(bytes,bytes),bytes,bytes))": { "calls": 1, - "min": 656119, - "mean": 656119, - "median": 656119, - "max": 656119 + "min": 659719, + "mean": 659719, + "median": 659719, + "max": 659719 + }, + "gasReportSubmit1CheckpointWithTwoOverrides((uint256,uint256,(bytes32,bytes32,bytes32,bytes32,bytes32,address),(bytes32,bytes32,bytes32,bytes32,bytes32,uint256,uint256,address,bytes32,(uint128,uint128),uint256,uint256)[],(bytes,bytes),bytes,bytes))": { + "calls": 1, + "min": 686472, + "mean": 686472, + "median": 686472, + "max": 686472 }, "gasReportSubmit32Checkpoints((uint256,uint256,(bytes32,bytes32,bytes32,bytes32,bytes32,address),(bytes32,bytes32,bytes32,bytes32,bytes32,uint256,uint256,address,bytes32,(uint128,uint128),uint256,uint256)[],(bytes,bytes),bytes,bytes))": { "calls": 1, - "min": 1819288, - "mean": 1819288, - "median": 1819288, - "max": 1819288 + "min": 1836386, + "mean": 1836386, + "median": 1836386, + "max": 1836386 + }, + "gasReportSubmit32CheckpointsWithTwoOverrides((uint256,uint256,(bytes32,bytes32,bytes32,bytes32,bytes32,address),(bytes32,bytes32,bytes32,bytes32,bytes32,uint256,uint256,address,bytes32,(uint128,uint128),uint256,uint256)[],(bytes,bytes),bytes,bytes))": { + "calls": 1, + "min": 2094127, + "mean": 2094127, + "median": 2094127, + "max": 2094127 }, "gasReportSubmit8Checkpoints((uint256,uint256,(bytes32,bytes32,bytes32,bytes32,bytes32,address),(bytes32,bytes32,bytes32,bytes32,bytes32,uint256,uint256,address,bytes32,(uint128,uint128),uint256,uint256)[],(bytes,bytes),bytes,bytes))": { "calls": 1, - "min": 977258, - "mean": 977258, - "median": 977258, - "max": 977258 + "min": 983949, + "mean": 983949, + "median": 983949, + "max": 983949 + }, + "gasReportSubmit8CheckpointsWithTwoOverrides((uint256,uint256,(bytes32,bytes32,bytes32,bytes32,bytes32,address),(bytes32,bytes32,bytes32,bytes32,bytes32,uint256,uint256,address,bytes32,(uint128,uint128),uint256,uint256)[],(bytes,bytes),bytes,bytes))": { + "calls": 1, + "min": 1080528, + "mean": 1080528, + "median": 1080528, + "max": 1080528 }, "gasReportSubmit8MoreCheckpoints((uint256,uint256,(bytes32,bytes32,bytes32,bytes32,bytes32,address),(bytes32,bytes32,bytes32,bytes32,bytes32,uint256,uint256,address,bytes32,(uint128,uint128),uint256,uint256)[],(bytes,bytes),bytes,bytes))": { "calls": 1, - "min": 1003405, - "mean": 1003405, - "median": 1003405, - "max": 1003405 + "min": 1010042, + "mean": 1010042, + "median": 1010042, + "max": 1010042 } } } diff --git a/l1-contracts/partial_epoch_proof_gas_report.md b/l1-contracts/partial_epoch_proof_gas_report.md index aaccb50ac1c4..6ebdce8d7820 100644 --- a/l1-contracts/partial_epoch_proof_gas_report.md +++ b/l1-contracts/partial_epoch_proof_gas_report.md @@ -2,10 +2,14 @@ | Proof submission | Gas | |---|---:| -| 1 Checkpoint | 656,119 | -| 8 Checkpoints | 977,258 | -| 8 More Checkpoints | 1,003,405 | -| 16 Checkpoints | 1,288,398 | -| 32 Checkpoints | 1,819,288 | +| 1 Checkpoint | 659,719 | +| 1 Checkpoint With Two Overrides | 686,472 | +| 8 Checkpoints | 983,949 | +| 8 Checkpoints With Two Overrides | 1,080,528 | +| 8 More Checkpoints | 1,010,042 | +| 16 Checkpoints | 1,298,507 | +| 16 Checkpoints With Two Overrides | 1,463,518 | +| 32 Checkpoints | 1,836,386 | +| 32 Checkpoints With Two Overrides | 2,094,127 | -_Uses the mock epoch proof verifier; real ZK verification and top-level transaction calldata gas are not included._ +_Uses the mock epoch proof verifier._ diff --git a/l1-contracts/script/deploy/RollupConfiguration.sol b/l1-contracts/script/deploy/RollupConfiguration.sol index 146a8c61d71d..f67308870980 100644 --- a/l1-contracts/script/deploy/RollupConfiguration.sol +++ b/l1-contracts/script/deploy/RollupConfiguration.sol @@ -9,10 +9,11 @@ import {CheatDepositArgs} from "@aztec/mock/MultiAdder.sol"; import {IRewardDistributor} from "@aztec/governance/interfaces/IRewardDistributor.sol"; import {IBoosterCore} from "@aztec/core/reward-boost/RewardBooster.sol"; import {EthValue, EthPerFeeAssetE12} from "@aztec/core/libraries/rollup/FeeLib.sol"; -import {GenesisState, RollupConfigInput} from "@aztec/core/interfaces/IRollup.sol"; +import {GenesisState, RegistryRewardOverride, RollupConfigInput} from "@aztec/core/interfaces/IRollup.sol"; import {RewardBoostConfig} from "@aztec/core/reward-boost/RewardBooster.sol"; import {StakingQueueConfig} from "@aztec/core/libraries/compressed-data/StakingQueueConfig.sol"; import {RewardConfig, Bps} from "@aztec/core/libraries/rollup/RewardLib.sol"; +import {SafeCast} from "@oz/utils/math/SafeCast.sol"; interface IRollupConfiguration { function loadConfig() external; @@ -28,6 +29,7 @@ interface IRollupConfiguration { contract RollupConfiguration is IRollupConfiguration, Test { using stdJson for string; + using SafeCast for uint256; // Storage for loaded config string public networkName; @@ -127,6 +129,24 @@ contract RollupConfiguration is IRollupConfiguration, Test { config.version = 0; // Computed below config.provingCostPerMana = EthValue.wrap(vm.envUint("AZTEC_PROVING_COST_PER_MANA")); config.initialEthPerFeeAsset = EthPerFeeAssetE12.wrap(vm.envUint("AZTEC_INITIAL_ETH_PER_FEE_ASSET")); + config.registryRewardOverrides[0] = _getRegistryRewardOverride("AZTEC_REGISTRY_REWARD_OVERRIDE_0"); + config.registryRewardOverrides[1] = _getRegistryRewardOverride("AZTEC_REGISTRY_REWARD_OVERRIDE_1"); + } + + function _getRegistryRewardOverride(string memory _envName) + internal + view + returns (RegistryRewardOverride memory registryRewardOverride) + { + string memory value = vm.envOr(_envName, string("")); + if (bytes(value).length == 0) { + return registryRewardOverride; + } + + string[] memory fields = vm.split(value, ","); + require(fields.length == 2, "Invalid registry reward override"); + registryRewardOverride.registry = vm.parseAddress(fields[0]); + registryRewardOverride.sequencerReward = vm.parseUint(fields[1]).toUint96(); } /// @notice Compute rollup config version by hashing config + genesis state diff --git a/l1-contracts/scripts/network-defaults.json b/l1-contracts/scripts/network-defaults.json index 96bc9ce58497..e8b63b046c4e 100644 --- a/l1-contracts/scripts/network-defaults.json +++ b/l1-contracts/scripts/network-defaults.json @@ -18,6 +18,8 @@ "AZTEC_MANA_TARGET": 100000000, "AZTEC_PROVING_COST_PER_MANA": 100, "AZTEC_INITIAL_ETH_PER_FEE_ASSET": 10000000, + "AZTEC_REGISTRY_REWARD_OVERRIDE_0": "", + "AZTEC_REGISTRY_REWARD_OVERRIDE_1": "", "AZTEC_SLASHER_ENABLED": true, "AZTEC_SLASHING_ROUND_SIZE_IN_EPOCHS": 4, "AZTEC_SLASHING_QUORUM": 65, diff --git a/l1-contracts/scripts/render_partial_epoch_proof_gas_report.py b/l1-contracts/scripts/render_partial_epoch_proof_gas_report.py index c9cb372a9cec..fbe3a26637ae 100644 --- a/l1-contracts/scripts/render_partial_epoch_proof_gas_report.py +++ b/l1-contracts/scripts/render_partial_epoch_proof_gas_report.py @@ -44,7 +44,7 @@ def render(input_path: Path, output_path: Path) -> None: lines.extend( [ "", - "_Uses the mock epoch proof verifier; real ZK verification and top-level transaction calldata gas are not included._", + "_Uses the mock epoch proof verifier._", "", ] ) diff --git a/l1-contracts/src/core/RollupCore.sol b/l1-contracts/src/core/RollupCore.sol index 1f0610da09ed..d71444adf28e 100644 --- a/l1-contracts/src/core/RollupCore.sol +++ b/l1-contracts/src/core/RollupCore.sol @@ -8,7 +8,9 @@ import { IRollupCore, RollupConfig, SubmitEpochRootProofArgs, - RollupConfigInput + RollupConfigInput, + MAX_REGISTRY_REWARD_OVERRIDES, + RegistryRewardOverride } from "@aztec/core/interfaces/IRollup.sol"; import {IVerifier} from "@aztec/core/interfaces/IVerifier.sol"; import {IStakingCore} from "@aztec/core/interfaces/IStaking.sol"; @@ -201,6 +203,11 @@ contract RollupCore is EIP712("Aztec Rollup", "1"), Ownable, IStakingCore, IVali IInbox internal immutable INBOX; IOutbox internal immutable OUTBOX; + address internal immutable REGISTRY_REWARD_OVERRIDE_0_REGISTRY; + uint96 internal immutable REGISTRY_REWARD_OVERRIDE_0_SEQUENCER_REWARD; + address internal immutable REGISTRY_REWARD_OVERRIDE_1_REGISTRY; + uint96 internal immutable REGISTRY_REWARD_OVERRIDE_1_SEQUENCER_REWARD; + /** * @dev Storage gap to ensure checkBlob is in its own storage slot */ @@ -275,6 +282,10 @@ contract RollupCore is EIP712("Aztec Rollup", "1"), Ownable, IStakingCore, IVali ); _initializeRewards(_config); + REGISTRY_REWARD_OVERRIDE_0_REGISTRY = _config.registryRewardOverrides[0].registry; + REGISTRY_REWARD_OVERRIDE_0_SEQUENCER_REWARD = _config.registryRewardOverrides[0].sequencerReward; + REGISTRY_REWARD_OVERRIDE_1_REGISTRY = _config.registryRewardOverrides[1].registry; + REGISTRY_REWARD_OVERRIDE_1_SEQUENCER_REWARD = _config.registryRewardOverrides[1].sequencerReward; L1_BLOCK_AT_GENESIS = block.number; @@ -526,7 +537,7 @@ contract RollupCore is EIP712("Aztec Rollup", "1"), Ownable, IStakingCore, IVali * @param _args Contains the epoch range, public inputs, fees, attestations, and the ZK proof */ function submitEpochRootProof(SubmitEpochRootProofArgs calldata _args) external override(IRollupCore) { - EpochProofExtLib.submitEpochRootProof(_args, _getRollupConfig()); + EpochProofExtLib.submitEpochRootProof(_args, _getRollupConfig(), _getRegistryRewardOverrides()); } /** @@ -663,7 +674,7 @@ contract RollupCore is EIP712("Aztec Rollup", "1"), Ownable, IStakingCore, IVali } // Constructor-only writer; post-deployment updates go through {setRewardConfig}. - RewardExtLib.initializeConfig(rewardConfig); + RewardExtLib.initializeConfig(rewardConfig, _config.registryRewardOverrides); } function _getRollupConfig() internal view virtual returns (RollupConfig memory) { @@ -678,4 +689,17 @@ contract RollupCore is EIP712("Aztec Rollup", "1"), Ownable, IStakingCore, IVali outbox: OUTBOX }); } + + function _getRegistryRewardOverrides() + internal + view + returns (RegistryRewardOverride[MAX_REGISTRY_REWARD_OVERRIDES] memory overrides) + { + overrides[0] = RegistryRewardOverride({ + registry: REGISTRY_REWARD_OVERRIDE_0_REGISTRY, sequencerReward: REGISTRY_REWARD_OVERRIDE_0_SEQUENCER_REWARD + }); + overrides[1] = RegistryRewardOverride({ + registry: REGISTRY_REWARD_OVERRIDE_1_REGISTRY, sequencerReward: REGISTRY_REWARD_OVERRIDE_1_SEQUENCER_REWARD + }); + } } diff --git a/l1-contracts/src/core/interfaces/IRollup.sol b/l1-contracts/src/core/interfaces/IRollup.sol index 1173348f4e52..c973c19f36f7 100644 --- a/l1-contracts/src/core/interfaces/IRollup.sol +++ b/l1-contracts/src/core/interfaces/IRollup.sol @@ -15,7 +15,12 @@ import {CommitteeAttestations} from "@aztec/core/libraries/rollup/AttestationLib import {ManaMinFeeComponents} from "@aztec/core/libraries/rollup/FeeLib.sol"; import {ProposedHeader} from "@aztec/core/libraries/rollup/ProposedHeaderLib.sol"; import {ProposeArgs} from "@aztec/core/libraries/rollup/ProposeLib.sol"; -import {RewardConfig, MutableRewardConfig} from "@aztec/core/libraries/rollup/RewardLib.sol"; +import { + RewardConfig, + MutableRewardConfig, + RegistryRewardOverride, + MAX_REGISTRY_REWARD_OVERRIDES +} from "@aztec/core/libraries/rollup/RewardLib.sol"; import {RewardBoostConfig} from "@aztec/core/reward-boost/RewardBooster.sol"; import {IHaveVersion} from "@aztec/governance/interfaces/IRegistry.sol"; import {IRewardDistributor} from "@aztec/governance/interfaces/IRewardDistributor.sol"; @@ -84,6 +89,7 @@ struct RollupConfigInput { StakingQueueConfig stakingQueueConfig; uint256 localEjectionThreshold; uint256 ethereumSlotDuration; + RegistryRewardOverride[MAX_REGISTRY_REWARD_OVERRIDES] registryRewardOverrides; } /** diff --git a/l1-contracts/src/core/interfaces/IValidatorSelection.sol b/l1-contracts/src/core/interfaces/IValidatorSelection.sol index 8607c43b0267..7d4b9ff40206 100644 --- a/l1-contracts/src/core/interfaces/IValidatorSelection.sol +++ b/l1-contracts/src/core/interfaces/IValidatorSelection.sol @@ -7,6 +7,8 @@ import {IEmperor} from "@aztec/governance/interfaces/IEmpire.sol"; import {Timestamp, Slot, Epoch} from "@aztec/shared/libraries/TimeMath.sol"; import {Checkpoints} from "@oz/utils/structs/Checkpoints.sol"; +uint256 constant MAXIMUM_COMMITTEE_SIZE = 256; + struct ValidatorSelectionStorage { // A mapping to snapshots of the validator set mapping(Epoch => bytes32 committeeCommitment) committeeCommitments; diff --git a/l1-contracts/src/core/libraries/Errors.sol b/l1-contracts/src/core/libraries/Errors.sol index e5ba67475e93..8e9eb3c1fd22 100644 --- a/l1-contracts/src/core/libraries/Errors.sol +++ b/l1-contracts/src/core/libraries/Errors.sol @@ -226,6 +226,12 @@ library Errors { error RewardBooster__InvalidConfig(); error RewardLib__InvalidSequencerBps(); + error RewardLib__InvalidRegistryRewardOverride(address registry, uint256 sequencerReward); + error RewardLib__DuplicateRegistryRewardOverride(address registry); + error RewardLib__RegistryRewardOverrideAboveDefault( + address registry, uint256 sequencerReward, uint256 defaultSequencerReward + ); + error RewardLib__CheckpointRewardsAboveMaximum(uint256 checkpointRewards, uint256 maximumCheckpointRewards); error RewardLib__ZeroShares(address prover); error RewardLib__InvalidProtocolFeeRecipient(); diff --git a/l1-contracts/src/core/libraries/rollup/EpochProofExtLib.sol b/l1-contracts/src/core/libraries/rollup/EpochProofExtLib.sol index bda2a0bf61d8..3a7843072220 100644 --- a/l1-contracts/src/core/libraries/rollup/EpochProofExtLib.sol +++ b/l1-contracts/src/core/libraries/rollup/EpochProofExtLib.sol @@ -4,6 +4,7 @@ pragma solidity >=0.8.27; import {SubmitEpochRootProofArgs, PublicInputArgs, RollupConfig} from "@aztec/core/interfaces/IRollup.sol"; import {ProposedHeader} from "@aztec/core/libraries/rollup/ProposedHeaderLib.sol"; +import {RegistryRewardOverride, MAX_REGISTRY_REWARD_OVERRIDES} from "@aztec/core/libraries/rollup/RewardLib.sol"; import {EpochProofLib} from "./EpochProofLib.sol"; /** @@ -20,8 +21,12 @@ import {EpochProofLib} from "./EpochProofLib.sol"; * - Epoch proof public input computation */ library EpochProofExtLib { - function submitEpochRootProof(SubmitEpochRootProofArgs calldata _args, RollupConfig memory _config) external { - EpochProofLib.submitEpochRootProof(_args, _config); + function submitEpochRootProof( + SubmitEpochRootProofArgs calldata _args, + RollupConfig memory _config, + RegistryRewardOverride[MAX_REGISTRY_REWARD_OVERRIDES] memory _registryRewardOverrides + ) external { + EpochProofLib.submitEpochRootProof(_args, _config, _registryRewardOverrides); } function getEpochProofPublicInputs( diff --git a/l1-contracts/src/core/libraries/rollup/EpochProofLib.sol b/l1-contracts/src/core/libraries/rollup/EpochProofLib.sol index c696254019db..61b321891247 100644 --- a/l1-contracts/src/core/libraries/rollup/EpochProofLib.sol +++ b/l1-contracts/src/core/libraries/rollup/EpochProofLib.sol @@ -18,7 +18,11 @@ import {Constants} from "@aztec/core/libraries/ConstantsGen.sol"; import {Errors} from "@aztec/core/libraries/Errors.sol"; import {AttestationLib, CommitteeAttestations} from "@aztec/core/libraries/rollup/AttestationLib.sol"; import {ProposedHeader, ProposedHeaderLib} from "@aztec/core/libraries/rollup/ProposedHeaderLib.sol"; -import {RewardLib} from "@aztec/core/libraries/rollup/RewardLib.sol"; +import { + RewardLib, + RegistryRewardOverride, + MAX_REGISTRY_REWARD_OVERRIDES +} from "@aztec/core/libraries/rollup/RewardLib.sol"; import {STFLib} from "@aztec/core/libraries/rollup/STFLib.sol"; import {ValidatorSelectionLib} from "@aztec/core/libraries/rollup/ValidatorSelectionLib.sol"; import {Timestamp, Slot, Epoch, TimeLib} from "@aztec/core/libraries/TimeLib.sol"; @@ -109,7 +113,11 @@ library EpochProofLib { * - proof: The validity proof bytes for the root rollup circuit * @param _config The rollup's deployment-time configuration */ - function submitEpochRootProof(SubmitEpochRootProofArgs calldata _args, RollupConfig memory _config) internal { + function submitEpochRootProof( + SubmitEpochRootProofArgs calldata _args, + RollupConfig memory _config, + RegistryRewardOverride[MAX_REGISTRY_REWARD_OVERRIDES] memory _registryRewardOverrides + ) internal { if (STFLib.canPruneAtTime(Timestamp.wrap(block.timestamp))) { STFLib.prune(); } @@ -123,7 +131,8 @@ library EpochProofLib { // Verify attestations for the last checkpoint in the epoch // -> This serves as training wheels for the public part of the system (proving systems used in public and AVM) // ensuring committee agreement on the epoch's validity alongside the cryptographic proof verification below. - verifyLastCheckpointAttestationsAndOutHash(_args.end, _args.attestations, _args.args.outHash); + address[] memory committee = + verifyLastCheckpointAttestationsAndOutHash(_args.end, _args.attestations, _args.args.outHash); require(verifyEpochRootProof(_args, _config), Errors.Rollup__InvalidProof()); @@ -155,7 +164,7 @@ library EpochProofLib { } // Activity score depends on whether the proof is a full epoch proof - RewardLib.handleRewardsAndFees(_args, endEpoch, _config, fullEpochProof); + RewardLib.handleRewardsAndFees(_args, endEpoch, _config, fullEpochProof, committee, _registryRewardOverrides); emit IRollupCore.L2ProofVerified(_args.end, _args.args.proverId); } @@ -208,12 +217,13 @@ library EpochProofLib { * * @param _endCheckpointNumber The last checkpoint number in the epoch to verify attestations for * @param _attestations The committee attestations containing signatures and validator information + * @return The reconstructed committee */ function verifyLastCheckpointAttestationsAndOutHash( uint256 _endCheckpointNumber, CommitteeAttestations memory _attestations, bytes32 _outHash - ) private { + ) private returns (address[] memory) { // Get the stored attestation hash and payload digest for the last checkpoint CompressedTempCheckpointLog storage checkpointLog = STFLib.getStorageTempCheckpointLog(_endCheckpointNumber); @@ -238,12 +248,12 @@ library EpochProofLib { (bool isOpen,) = escapeHatch.isHatchOpen(epoch); if (isOpen) { // Skip attestation verification for escape hatch epochs - return; + return new address[](0); } } } - ValidatorSelectionLib.verifyAttestations(epoch, _attestations, checkpointLog.payloadDigest); + return ValidatorSelectionLib.verifyAttestations(epoch, _attestations, checkpointLog.payloadDigest); } /** diff --git a/l1-contracts/src/core/libraries/rollup/RewardExtLib.sol b/l1-contracts/src/core/libraries/rollup/RewardExtLib.sol index 19e1d5a719be..1bf3f7774fd5 100644 --- a/l1-contracts/src/core/libraries/rollup/RewardExtLib.sol +++ b/l1-contracts/src/core/libraries/rollup/RewardExtLib.sol @@ -10,7 +10,13 @@ import { EthValue } from "@aztec/core/libraries/rollup/FeeLib.sol"; import {ProposeLib} from "@aztec/core/libraries/rollup/ProposeLib.sol"; -import {RewardLib, RewardConfig, MutableRewardConfig} from "@aztec/core/libraries/rollup/RewardLib.sol"; +import { + RewardLib, + RewardConfig, + MutableRewardConfig, + RegistryRewardOverride, + MAX_REGISTRY_REWARD_OVERRIDES +} from "@aztec/core/libraries/rollup/RewardLib.sol"; import {STFLib} from "@aztec/core/libraries/rollup/STFLib.sol"; import {Epoch, Timestamp} from "@aztec/core/libraries/TimeLib.sol"; import { @@ -23,7 +29,11 @@ import {IRewardDistributor} from "@aztec/governance/interfaces/IRewardDistributo import {IERC20} from "@oz/token/ERC20/IERC20.sol"; library RewardExtLib { - function initializeConfig(RewardConfig memory _config) external { + function initializeConfig( + RewardConfig memory _config, + RegistryRewardOverride[MAX_REGISTRY_REWARD_OVERRIDES] memory _registryRewardOverrides + ) external { + RewardLib.validateRegistryRewardOverrides(_registryRewardOverrides, _config); RewardLib.initializeConfig(_config); } diff --git a/l1-contracts/src/core/libraries/rollup/RewardLib.sol b/l1-contracts/src/core/libraries/rollup/RewardLib.sol index 5bcb21e51895..f74627533474 100644 --- a/l1-contracts/src/core/libraries/rollup/RewardLib.sol +++ b/l1-contracts/src/core/libraries/rollup/RewardLib.sol @@ -5,10 +5,13 @@ pragma solidity >=0.8.27; import {RollupConfig, SubmitEpochRootProofArgs} from "@aztec/core/interfaces/IRollup.sol"; import {CompressedFeeHeader, FeeHeaderLib} from "@aztec/core/libraries/compressed-data/fees/FeeStructs.sol"; import {Errors} from "@aztec/core/libraries/Errors.sol"; +import {StakingLib} from "@aztec/core/libraries/rollup/StakingLib.sol"; import {STFLib} from "@aztec/core/libraries/rollup/STFLib.sol"; +import {ValidatorSelectionLib} from "@aztec/core/libraries/rollup/ValidatorSelectionLib.sol"; import {Epoch, Timestamp, TimeLib} from "@aztec/core/libraries/TimeLib.sol"; import {IBoosterCore} from "@aztec/core/reward-boost/RewardBooster.sol"; import {IRewardDistributor} from "@aztec/governance/interfaces/IRewardDistributor.sol"; +import {GSE} from "@aztec/governance/GSE.sol"; import {IERC20} from "@oz/token/ERC20/IERC20.sol"; import {SafeERC20} from "@oz/token/ERC20/utils/SafeERC20.sol"; import {Math} from "@oz/utils/math/Math.sol"; @@ -17,6 +20,10 @@ import {BitMaps} from "@oz/utils/structs/BitMaps.sol"; type Bps is uint32; +interface IRegistryProvider { + function getRegistry() external view returns (address); +} + library BpsLib { function mul(uint256 _a, Bps _b) internal pure returns (uint256) { return _a * uint256(Bps.unwrap(_b)) / 10_000; @@ -34,6 +41,13 @@ struct EpochRewards { mapping(uint256 length => SubEpochRewards) subEpoch; } +uint256 constant MAX_REGISTRY_REWARD_OVERRIDES = 2; + +struct RegistryRewardOverride { + address registry; + uint96 sequencerReward; +} + struct RewardConfig { IRewardDistributor rewardDistributor; Bps sequencerBps; @@ -61,10 +75,17 @@ struct Values { address sequencer; uint256 proverFee; uint256 sequencerFee; - uint256 sequencerCheckpointReward; + uint256[] sequencerCheckpointRewards; uint256 manaUsed; } +struct SequencerRewardContext { + uint256[] proposerRewards; + uint256 cachedProposers; + GSE gse; + RegistryRewardOverride[MAX_REGISTRY_REWARD_OVERRIDES] registryRewardOverrides; +} + struct Totals { uint256 feesToClaim; uint256 totalProtocolFee; @@ -80,6 +101,8 @@ library RewardLib { bytes32 private constant REWARD_STORAGE_POSITION = keccak256("aztec.reward.storage"); + uint256 private constant REGISTRY_PROBE_GAS_LIMIT = 50_000; + /// @notice One-shot writer used during rollup construction. Writes every field of /// {RewardConfig}, including the immutable `rewardDistributor` and `booster`. /// @dev Must only be reachable from the constructor path. Post-deployment updates go through @@ -161,7 +184,9 @@ library RewardLib { SubmitEpochRootProofArgs calldata _args, Epoch _endEpoch, RollupConfig memory _config, - bool _fullEpochProof + bool _fullEpochProof, + address[] memory _committee, + RegistryRewardOverride[MAX_REGISTRY_REWARD_OVERRIDES] memory _registryRewardOverrides ) internal { RewardStorage storage rewardStorage = getStorage(); @@ -191,11 +216,32 @@ library RewardLib { if (length > $er.longestProvenLength) { Values memory v; - Totals memory t; { uint256 added = length - $er.longestProvenLength; - uint256 checkpointRewardsDesired = added * getCheckpointReward(); + uint256 checkpointReward = getCheckpointReward(); + uint256 defaultSequencerRewardPerCheckpoint = BpsLib.mul(checkpointReward, rewardStorage.config.sequencerBps); + + (uint256 desiredSequencerRewardsTotal, uint256[] memory sequencerCheckpointRewards) = computeDesiredSequencerRewards( + _args, + _endEpoch, + _committee, + _registryRewardOverrides, + $er.longestProvenLength, + defaultSequencerRewardPerCheckpoint + ); + + v.sequencerCheckpointRewards = sequencerCheckpointRewards; + + uint256 proverRewardPerCheckpoint = checkpointReward - defaultSequencerRewardPerCheckpoint; + uint256 checkpointRewardsDesired = proverRewardPerCheckpoint * added + desiredSequencerRewardsTotal; + uint256 maximumCheckpointRewards = added * checkpointReward; + + require( + checkpointRewardsDesired <= maximumCheckpointRewards, + Errors.RewardLib__CheckpointRewardsAboveMaximum(checkpointRewardsDesired, maximumCheckpointRewards) + ); + uint256 checkpointRewardsAvailable = 0; if (checkpointRewardsDesired > 0) { @@ -210,17 +256,26 @@ library RewardLib { } } - uint256 sequenceCheckpointRewards = BpsLib.mul(checkpointRewardsAvailable, rewardStorage.config.sequencerBps); - v.sequencerCheckpointReward = sequenceCheckpointRewards / added; + uint256 sequencerCheckpointRewardTotal = desiredSequencerRewardsTotal; + if (checkpointRewardsAvailable < checkpointRewardsDesired) { + sequencerCheckpointRewardTotal = 0; + for (uint256 i = $er.longestProvenLength; i < length; i++) { + uint256 index = i - $er.longestProvenLength; + sequencerCheckpointRewards[index] = + Math.mulDiv(v.sequencerCheckpointRewards[index], checkpointRewardsAvailable, checkpointRewardsDesired); + sequencerCheckpointRewardTotal += v.sequencerCheckpointRewards[index]; + } + } - uint256 dust = sequenceCheckpointRewards - (v.sequencerCheckpointReward * added); - uint256 proverCheckpointRewards = checkpointRewardsAvailable - sequenceCheckpointRewards + dust; + uint256 proverCheckpointRewards = checkpointRewardsAvailable - sequencerCheckpointRewardTotal; if (proverCheckpointRewards > 0) { $er.rewards += proverCheckpointRewards.toUint128(); } } + Totals memory t; for (uint256 i = $er.longestProvenLength; i < length; i++) { + uint256 index = i - $er.longestProvenLength; CompressedFeeHeader feeHeader = STFLib.getFeeHeader(_args.start + i); v.manaUsed = feeHeader.getManaUsed(); @@ -241,7 +296,7 @@ library RewardLib { { v.sequencer = _args.headers[i].coinbase; - uint256 toSequencer = v.sequencerCheckpointReward + v.sequencerFee; + uint256 toSequencer = v.sequencerCheckpointRewards[index] + v.sequencerFee; if (toSequencer > 0) { rewardStorage.sequencerRewards[v.sequencer] += toSequencer; } @@ -307,10 +362,143 @@ library RewardLib { return (se.shares[_prover] * er.rewards / se.summedShares); } + function tryGetRegistry(address _withdrawer) internal view returns (bool responded, address registry) { + if (_withdrawer.code.length == 0) { + return (false, address(0)); + } + + uint256 selector = uint32(IRegistryProvider.getRegistry.selector); + + assembly ("memory-safe") { + mstore(0x00, shl(224, selector)) + let callSucceeded := staticcall(REGISTRY_PROBE_GAS_LIMIT, _withdrawer, 0x00, 0x04, 0x20, 0x20) + let result := mload(0x20) + responded := and(and(callSucceeded, eq(returndatasize(), 0x20)), iszero(shr(160, result))) + registry := 0 + if responded { + registry := and(result, sub(shl(160, 1), 1)) + } + } + } + + function validateRegistryRewardOverrides( + RegistryRewardOverride[MAX_REGISTRY_REWARD_OVERRIDES] memory _overrides, + RewardConfig memory _rewardConfig + ) internal pure { + uint256 defaultSequencerReward = BpsLib.mul(_rewardConfig.checkpointReward, _rewardConfig.sequencerBps); + + for (uint256 i = 0; i < MAX_REGISTRY_REWARD_OVERRIDES; i++) { + RegistryRewardOverride memory current = _overrides[i]; + if (current.registry == address(0)) { + require( + current.sequencerReward == 0, + Errors.RewardLib__InvalidRegistryRewardOverride(current.registry, current.sequencerReward) + ); + continue; + } + + require( + current.sequencerReward <= defaultSequencerReward, + Errors.RewardLib__RegistryRewardOverrideAboveDefault( + current.registry, current.sequencerReward, defaultSequencerReward + ) + ); + + for (uint256 j = 0; j < i; j++) { + require( + _overrides[j].registry != current.registry, + Errors.RewardLib__DuplicateRegistryRewardOverride(current.registry) + ); + } + } + } + function getStorage() internal pure returns (RewardStorage storage storageStruct) { bytes32 position = REWARD_STORAGE_POSITION; assembly { storageStruct.slot := position } } + + function computeDesiredSequencerRewards( + SubmitEpochRootProofArgs calldata _args, + Epoch _endEpoch, + address[] memory _committee, + RegistryRewardOverride[MAX_REGISTRY_REWARD_OVERRIDES] memory _registryRewardOverrides, + uint256 _from, + uint256 _defaultSequencerRewardPerCheckpoint + ) private view returns (uint256, uint256[] memory) { + uint256[] memory desiredSequencerCheckpointRewards = new uint256[](_args.end - _args.start + 1 - _from); + + if (_committee.length == 0 || !hasRegistryRewardOverrides(_registryRewardOverrides)) { + for (uint256 i = 0; i < desiredSequencerCheckpointRewards.length; i++) { + desiredSequencerCheckpointRewards[i] = _defaultSequencerRewardPerCheckpoint; + } + + return ( + _defaultSequencerRewardPerCheckpoint * desiredSequencerCheckpointRewards.length, + desiredSequencerCheckpointRewards + ); + } + + uint256 seed = ValidatorSelectionLib.getSampleSeed(_endEpoch); + uint256 desiredSequencerRewardsTotal = 0; + SequencerRewardContext memory context; + context.proposerRewards = new uint256[](_committee.length); + context.gse = StakingLib.getStorage().gse; + context.registryRewardOverrides = _registryRewardOverrides; + for (uint256 i = 0; i < desiredSequencerCheckpointRewards.length; i++) { + uint256 proposerIndex = ValidatorSelectionLib.computeProposerIndex( + _endEpoch, _args.headers[_from + i].slotNumber, seed, _committee.length + ); + uint256 proposerMask = uint256(1) << proposerIndex; + if (context.cachedProposers & proposerMask == 0) { + context.proposerRewards[proposerIndex] = getDesiredSequencerRewardForProposer( + _committee[proposerIndex], context, _defaultSequencerRewardPerCheckpoint + ); + context.cachedProposers |= proposerMask; + } + + uint256 reward = context.proposerRewards[proposerIndex]; + desiredSequencerCheckpointRewards[i] = reward; + desiredSequencerRewardsTotal += reward; + } + + return (desiredSequencerRewardsTotal, desiredSequencerCheckpointRewards); + } + + function getDesiredSequencerRewardForProposer( + address _proposer, + SequencerRewardContext memory _context, + uint256 _defaultSequencerRewardPerCheckpoint + ) private view returns (uint256) { + address withdrawer = _context.gse.getWithdrawer(_proposer); + (bool responded, address registry) = tryGetRegistry(withdrawer); + if (!responded || registry == address(0)) { + return _defaultSequencerRewardPerCheckpoint; + } + + for (uint256 i = 0; i < MAX_REGISTRY_REWARD_OVERRIDES; i++) { + RegistryRewardOverride memory current = _context.registryRewardOverrides[i]; + if (current.registry == registry) { + return Math.min(_defaultSequencerRewardPerCheckpoint, current.sequencerReward); + } + } + + return _defaultSequencerRewardPerCheckpoint; + } + + function hasRegistryRewardOverrides(RegistryRewardOverride[MAX_REGISTRY_REWARD_OVERRIDES] memory _registryRewardOverrides) + private + pure + returns (bool) + { + for (uint256 i = 0; i < MAX_REGISTRY_REWARD_OVERRIDES; i++) { + if (_registryRewardOverrides[i].registry != address(0)) { + return true; + } + } + + return false; + } } diff --git a/l1-contracts/src/core/libraries/rollup/ValidatorSelectionLib.sol b/l1-contracts/src/core/libraries/rollup/ValidatorSelectionLib.sol index c9197de49fe2..44505e421b2e 100644 --- a/l1-contracts/src/core/libraries/rollup/ValidatorSelectionLib.sol +++ b/l1-contracts/src/core/libraries/rollup/ValidatorSelectionLib.sol @@ -4,7 +4,7 @@ pragma solidity >=0.8.27; import {IEscapeHatch} from "@aztec/core/interfaces/IEscapeHatch.sol"; import {RollupStore} from "@aztec/core/interfaces/IRollup.sol"; -import {ValidatorSelectionStorage} from "@aztec/core/interfaces/IValidatorSelection.sol"; +import {ValidatorSelectionStorage, MAXIMUM_COMMITTEE_SIZE} from "@aztec/core/interfaces/IValidatorSelection.sol"; import {SampleLib} from "@aztec/core/libraries/crypto/SampleLib.sol"; import {Errors} from "@aztec/core/libraries/Errors.sol"; import {AttestationLib, CommitteeAttestations} from "@aztec/core/libraries/rollup/AttestationLib.sol"; @@ -140,6 +140,8 @@ library ValidatorSelectionLib { Errors.ValidatorSelection__InvalidLagInEpochs(_lagInEpochsForValidatorSet, _lagInEpochsForRandao) ); ValidatorSelectionStorage storage store = getStorage(); + // RewardLib uses one bit per committee member in a uint256 cache, so changing this limit requires updating it. + require(_targetCommitteeSize <= MAXIMUM_COMMITTEE_SIZE); store.targetCommitteeSize = _targetCommitteeSize.toUint32(); store.lagInEpochsForValidatorSet = _lagInEpochsForValidatorSet.toUint32(); store.lagInEpochsForRandao = _lagInEpochsForRandao.toUint32(); @@ -325,9 +327,11 @@ library ValidatorSelectionLib { * @custom:reverts Errors.ValidatorSelection__InvalidCommitteeCommitment if reconstructed committee doesn't match * stored commitment * @custom:reverts Errors.ValidatorSelection__EpochNotStable if the requested epoch is not stable + * @return The reconstructed committee */ function verifyAttestations(Epoch _epochNumber, CommitteeAttestations memory _attestations, bytes32 _digest) internal + returns (address[] memory) { (bytes32 committeeCommitment, uint256 targetCommitteeSize) = getCommitteeCommitmentAt(_epochNumber); @@ -335,7 +339,7 @@ library ValidatorSelectionLib { // Note: This generally only happens in test setups; In production, the target committee is non-zero, // and one can see in `sampleValidators` that we will revert if the target committee size is not met. if (targetCommitteeSize == 0) { - return; + return new address[](0); } VerifyStack memory stack = VerifyStack({ @@ -392,6 +396,8 @@ library ValidatorSelectionLib { if (reconstructedCommitment != committeeCommitment) { revert Errors.ValidatorSelection__InvalidCommitteeCommitment(reconstructedCommitment, committeeCommitment); } + + return stack.reconstructedCommittee; } /** diff --git a/l1-contracts/test/benchmark/PartialEpochProofGasReporter.sol b/l1-contracts/test/benchmark/PartialEpochProofGasReporter.sol index 731103ac03d7..c0543f740873 100644 --- a/l1-contracts/test/benchmark/PartialEpochProofGasReporter.sol +++ b/l1-contracts/test/benchmark/PartialEpochProofGasReporter.sol @@ -45,34 +45,62 @@ contract PartialEpochProofGasReporter is RollupWithPreheating { * Reports submission gas for a fresh one-checkpoint epoch prefix. */ function gasReportSubmit1Checkpoint(SubmitEpochRootProofArgs calldata _args) external { - EpochProofExtLib.submitEpochRootProof(_args, _getRollupConfig()); + EpochProofExtLib.submitEpochRootProof(_args, _getRollupConfig(), _getRegistryRewardOverrides()); } /** * Reports submission gas for a fresh eight-checkpoint epoch prefix. */ function gasReportSubmit8Checkpoints(SubmitEpochRootProofArgs calldata _args) external { - EpochProofExtLib.submitEpochRootProof(_args, _getRollupConfig()); + EpochProofExtLib.submitEpochRootProof(_args, _getRollupConfig(), _getRegistryRewardOverrides()); } /** * Reports submission gas for checkpoints nine through sixteen after an eight-checkpoint prefix. */ function gasReportSubmit8MoreCheckpoints(SubmitEpochRootProofArgs calldata _args) external { - EpochProofExtLib.submitEpochRootProof(_args, _getRollupConfig()); + EpochProofExtLib.submitEpochRootProof(_args, _getRollupConfig(), _getRegistryRewardOverrides()); } /** * Reports submission gas for a fresh sixteen-checkpoint epoch prefix. */ function gasReportSubmit16Checkpoints(SubmitEpochRootProofArgs calldata _args) external { - EpochProofExtLib.submitEpochRootProof(_args, _getRollupConfig()); + EpochProofExtLib.submitEpochRootProof(_args, _getRollupConfig(), _getRegistryRewardOverrides()); } /** * Reports submission gas for a complete thirty-two-checkpoint epoch. */ function gasReportSubmit32Checkpoints(SubmitEpochRootProofArgs calldata _args) external { - EpochProofExtLib.submitEpochRootProof(_args, _getRollupConfig()); + EpochProofExtLib.submitEpochRootProof(_args, _getRollupConfig(), _getRegistryRewardOverrides()); + } + + /** + * Reports submission gas for a fresh one-checkpoint epoch prefix with two registry reward overrides. + */ + function gasReportSubmit1CheckpointWithTwoOverrides(SubmitEpochRootProofArgs calldata _args) external { + EpochProofExtLib.submitEpochRootProof(_args, _getRollupConfig(), _getRegistryRewardOverrides()); + } + + /** + * Reports submission gas for a fresh eight-checkpoint epoch prefix with two registry reward overrides. + */ + function gasReportSubmit8CheckpointsWithTwoOverrides(SubmitEpochRootProofArgs calldata _args) external { + EpochProofExtLib.submitEpochRootProof(_args, _getRollupConfig(), _getRegistryRewardOverrides()); + } + + /** + * Reports submission gas for a fresh sixteen-checkpoint epoch prefix with two registry reward overrides. + */ + function gasReportSubmit16CheckpointsWithTwoOverrides(SubmitEpochRootProofArgs calldata _args) external { + EpochProofExtLib.submitEpochRootProof(_args, _getRollupConfig(), _getRegistryRewardOverrides()); + } + + /** + * Reports submission gas for a complete thirty-two-checkpoint epoch with two registry reward overrides. + */ + function gasReportSubmit32CheckpointsWithTwoOverrides(SubmitEpochRootProofArgs calldata _args) external { + EpochProofExtLib.submitEpochRootProof(_args, _getRollupConfig(), _getRegistryRewardOverrides()); } } diff --git a/l1-contracts/test/benchmark/happy.t.sol b/l1-contracts/test/benchmark/happy.t.sol index ce291c9d2e59..b56213727a9f 100644 --- a/l1-contracts/test/benchmark/happy.t.sol +++ b/l1-contracts/test/benchmark/happy.t.sol @@ -67,6 +67,7 @@ import {StakingQueueConfig} from "@aztec/core/libraries/compressed-data/StakingQ import {BN254Lib, G1Point, G2Point} from "@aztec/shared/libraries/BN254Lib.sol"; import {SlashRound} from "@aztec/core/libraries/SlashRoundLib.sol"; import {AttestationLibHelper} from "@test/helper_libraries/AttestationLibHelper.sol"; +import {IRegistryProvider, RegistryRewardOverride} from "@aztec/core/libraries/rollup/RewardLib.sol"; // solhint-disable comprehensive-interface @@ -104,6 +105,20 @@ contract FakeCanonical is IRewardDistributor { } } +contract GasReportRegistryProvider is IRegistryProvider { + address internal immutable REGISTRY; + + constructor(address _registry) { + REGISTRY = _registry; + } + + /// @notice Returns the registry represented by this benchmark withdrawer. + /// @return The configured registry address. + function getRegistry() external view returns (address) { + return REGISTRY; + } +} + abstract contract BenchmarkRollupBase is FeeModelTestPoints, DecoderBase { using stdStorage for StdStorage; using TimeLib for Slot; @@ -174,7 +189,7 @@ abstract contract BenchmarkRollupBase is FeeModelTestPoints, DecoderBase { initialValidators[i - 1] = CheatDepositArgs({ attester: attester, - withdrawer: address(this), + withdrawer: _validatorWithdrawer(i - 1), publicKeyInG1: BN254Lib.g1Zero(), publicKeyInG2: BN254Lib.g2Zero(), proofOfPossession: BN254Lib.g1Zero() @@ -189,6 +204,8 @@ abstract contract BenchmarkRollupBase is FeeModelTestPoints, DecoderBase { .setValidators(initialValidators).setTargetCommitteeSize(_noValidators ? 0 : TARGET_COMMITTEE_SIZE) .setStakingQueueConfig(stakingQueueConfig); + _configureRollupBuilder(builder); + if (_slashing == TestSlash.TALLY) { // For tally slashing, we need a round size that's a multiple of epoch duration uint256 tallyRoundSize = EPOCH_DURATION * 2; // 64; // 2 * EPOCH_DURATION (32) = 64 @@ -212,6 +229,12 @@ abstract contract BenchmarkRollupBase is FeeModelTestPoints, DecoderBase { vm.label(rollup.getProtocolFeeRecipient(), "BURN_ADDRESS"); } + function _validatorWithdrawer(uint256) internal view virtual returns (address) { + return address(this); + } + + function _configureRollupBuilder(RollupBuilder) internal virtual {} + function _installPartialEpochProofGasReporter(RollupBuilder _builder) internal { Config memory config = _builder.getConfig(); PartialEpochProofGasReporter reporter = new PartialEpochProofGasReporter( @@ -689,6 +712,51 @@ contract PartialEpochProofGasReportTest is PartialEpochProofGasReportBase { } } +contract PartialEpochProofWithTwoOverridesGasReportTest is PartialEpochProofGasReportBase { + GasReportRegistryProvider internal firstProvider; + GasReportRegistryProvider internal secondProvider; + + function setUp() public override { + firstProvider = new GasReportRegistryProvider(makeAddr("firstRegistry")); + secondProvider = new GasReportRegistryProvider(makeAddr("secondRegistry")); + super.setUp(); + } + + function _configureRollupBuilder(RollupBuilder _builder) internal override { + Config memory config = _builder.getConfig(); + RollupConfigInput memory rollupConfig = config.rollupConfigInput; + rollupConfig.registryRewardOverrides[0] = + RegistryRewardOverride({registry: firstProvider.getRegistry(), sequencerReward: 10e18}); + rollupConfig.registryRewardOverrides[1] = + RegistryRewardOverride({registry: secondProvider.getRegistry(), sequencerReward: 20e18}); + _builder.setRollupConfigInput(rollupConfig); + } + + function _validatorWithdrawer(uint256 _validatorIndex) internal view override returns (address) { + return _validatorIndex % 2 == 0 ? address(firstProvider) : address(secondProvider); + } + + function testGasReportSubmit1CheckpointWithTwoOverrides() public { + _gasReporter().gasReportSubmit1CheckpointWithTwoOverrides(_getGasReportSubmission(1)); + assertEq(rollup.getProvenCheckpointNumber(), 1); + } + + function testGasReportSubmit8CheckpointsWithTwoOverrides() public { + _gasReporter().gasReportSubmit8CheckpointsWithTwoOverrides(_getGasReportSubmission(8)); + assertEq(rollup.getProvenCheckpointNumber(), 8); + } + + function testGasReportSubmit16CheckpointsWithTwoOverrides() public { + _gasReporter().gasReportSubmit16CheckpointsWithTwoOverrides(_getGasReportSubmission(16)); + assertEq(rollup.getProvenCheckpointNumber(), 16); + } + + function testGasReportSubmit32CheckpointsWithTwoOverrides() public { + _gasReporter().gasReportSubmit32CheckpointsWithTwoOverrides(_getGasReportSubmission(32)); + assertEq(rollup.getProvenCheckpointNumber(), 32); + } +} + contract PartialEpochProofExtensionGasReportTest is PartialEpochProofGasReportBase { function setUp() public override { super.setUp(); diff --git a/l1-contracts/test/builder/RollupBuilder.sol b/l1-contracts/test/builder/RollupBuilder.sol index e32fa8f97f58..7ed6cfc15e17 100644 --- a/l1-contracts/test/builder/RollupBuilder.sol +++ b/l1-contracts/test/builder/RollupBuilder.sol @@ -68,7 +68,7 @@ contract RollupBuilder is Test { config.deployer = _deployer; config.genesisState = TestConstants.getGenesisState(); - config.rollupConfigInput = TestConstants.getRollupConfigInput(); + _setRollupConfigInput(TestConstants.getRollupConfigInput()); config.values.govProposerN = 1; config.values.govProposerM = 1; @@ -101,8 +101,42 @@ contract RollupBuilder is Test { } function setRollupConfigInput(RollupConfigInput memory _rollupConfigInput) public returns (RollupBuilder) { - config.rollupConfigInput = _rollupConfigInput; - return this; + _setRollupConfigInput(_rollupConfigInput); + return this; + } + + function _setRollupConfigInput(RollupConfigInput memory _source) private { + RollupConfigInput storage target = config.rollupConfigInput; + target.aztecSlotDuration = _source.aztecSlotDuration; + target.aztecEpochDuration = _source.aztecEpochDuration; + target.targetCommitteeSize = _source.targetCommitteeSize; + target.lagInEpochsForValidatorSet = _source.lagInEpochsForValidatorSet; + target.lagInEpochsForRandao = _source.lagInEpochsForRandao; + target.aztecProofSubmissionEpochs = _source.aztecProofSubmissionEpochs; + target.slashingQuorum = _source.slashingQuorum; + target.slashingRoundSize = _source.slashingRoundSize; + target.slashingLifetimeInRounds = _source.slashingLifetimeInRounds; + target.slashingExecutionDelayInRounds = _source.slashingExecutionDelayInRounds; + target.slashAmounts = _source.slashAmounts; + target.slashingOffsetInRounds = _source.slashingOffsetInRounds; + target.slasherEnabled = _source.slasherEnabled; + target.slashingVetoer = _source.slashingVetoer; + target.slashingDisableDuration = _source.slashingDisableDuration; + target.manaTarget = _source.manaTarget; + target.exitDelaySeconds = _source.exitDelaySeconds; + target.version = _source.version; + target.provingCostPerMana = _source.provingCostPerMana; + target.initialEthPerFeeAsset = _source.initialEthPerFeeAsset; + target.rewardConfig = _source.rewardConfig; + target.rewardBoostConfig = _source.rewardBoostConfig; + target.stakingQueueConfig = _source.stakingQueueConfig; + target.localEjectionThreshold = _source.localEjectionThreshold; + target.ethereumSlotDuration = _source.ethereumSlotDuration; + + for (uint256 i = 0; i < _source.registryRewardOverrides.length; i++) { + target.registryRewardOverrides[i].registry = _source.registryRewardOverrides[i].registry; + target.registryRewardOverrides[i].sequencerReward = _source.registryRewardOverrides[i].sequencerReward; + } } function setRewardDistributor(RewardDistributor _rewardDistributor) public returns (RollupBuilder) { diff --git a/l1-contracts/test/rollup/libraries/rewardlib/RewardLibWrapper.sol b/l1-contracts/test/rollup/libraries/rewardlib/RewardLibWrapper.sol index efbc6a2b2a73..84f4fd832850 100644 --- a/l1-contracts/test/rollup/libraries/rewardlib/RewardLibWrapper.sol +++ b/l1-contracts/test/rollup/libraries/rewardlib/RewardLibWrapper.sol @@ -2,7 +2,14 @@ // Copyright 2024 Aztec Labs. pragma solidity >=0.8.27; -import {RewardLib, RewardConfig, RewardStorage} from "@aztec/core/libraries/rollup/RewardLib.sol"; +import { + RewardLib, + RewardConfig, + MutableRewardConfig, + RewardStorage, + RegistryRewardOverride, + MAX_REGISTRY_REWARD_OVERRIDES +} from "@aztec/core/libraries/rollup/RewardLib.sol"; import {Timestamp, Slot, Epoch} from "@aztec/core/libraries/TimeLib.sol"; import {RewardBooster, IBoosterCore, RewardBoostConfig} from "@aztec/core/reward-boost/RewardBooster.sol"; import {IValidatorSelection} from "@aztec/core/interfaces/IValidatorSelection.sol"; @@ -16,9 +23,24 @@ import {TempCheckpointLog} from "@aztec/core/libraries/compressed-data/Checkpoin import {FeeHeader} from "@aztec/core/libraries/compressed-data/fees/FeeStructs.sol"; import {CompressedChainTips, ChainTipsLib} from "@aztec/core/libraries/compressed-data/Tips.sol"; import {FeeLib} from "@aztec/core/libraries/rollup/FeeLib.sol"; +import {StakingLib} from "@aztec/core/libraries/rollup/StakingLib.sol"; +import {ValidatorSelectionLib} from "@aztec/core/libraries/rollup/ValidatorSelectionLib.sol"; import {TimeLib} from "@aztec/core/libraries/TimeLib.sol"; import {TestConstants} from "@test/harnesses/TestConstants.sol"; import {IFeeJuicePortal} from "@aztec/core/interfaces/IFeeJuicePortal.sol"; +import {GSE} from "@aztec/governance/GSE.sol"; + +contract RewardLibFakeGSE { + mapping(address attester => address withdrawer) internal withdrawers; + + function setWithdrawer(address _attester, address _withdrawer) external { + withdrawers[_attester] = _withdrawer; + } + + function getWithdrawer(address _attester) external view returns (address) { + return withdrawers[_attester]; + } +} contract FakeFeePortal { IERC20 public feeAsset; @@ -67,6 +89,7 @@ contract RewardLibWrapper { IFeeJuicePortal internal immutable FEE_ASSET_PORTAL; FakeRewardDistributor public rewardDistributor; FakeFeePortal public feePortal; + RewardLibFakeGSE public gse; constructor(IERC20 _feeAsset, uint96 _checkpointReward, uint32 _sequencerBps) { booster = new RewardBooster( @@ -76,6 +99,7 @@ contract RewardLibWrapper { rewardDistributor = new FakeRewardDistributor(_feeAsset); feePortal = new FakeFeePortal(_feeAsset); + gse = new RewardLibFakeGSE(); RewardConfig memory config = RewardConfig({ rewardDistributor: IRewardDistributor(address(rewardDistributor)), sequencerBps: Bps.wrap(_sequencerBps), @@ -87,6 +111,7 @@ contract RewardLibWrapper { FEE_ASSET = _feeAsset; FEE_ASSET_PORTAL = IFeeJuicePortal(address(feePortal)); + StakingLib.getStorage().gse = GSE(address(gse)); TimeLib.initialize( block.timestamp, @@ -137,8 +162,32 @@ contract RewardLibWrapper { return RewardLib.getProtocolFeeRecipient(); } + function setWithdrawer(address _attester, address _withdrawer) external { + gse.setWithdrawer(_attester, _withdrawer); + } + + function getProposerIndex(Epoch _epoch, Slot _slot, uint256 _committeeSize) external view returns (uint256) { + return ValidatorSelectionLib.computeProposerIndex( + _epoch, _slot, ValidatorSelectionLib.getSampleSeed(_epoch), _committeeSize + ); + } + function handleRewardsAndFees(SubmitEpochRootProofArgs calldata _args, Epoch _endEpoch) external { - RewardLib.handleRewardsAndFees(_args, _endEpoch, _rollupConfig(), true); + RegistryRewardOverride[MAX_REGISTRY_REWARD_OVERRIDES] memory registryRewardOverrides; + RewardLib.handleRewardsAndFees(_args, _endEpoch, _rollupConfig(), true, new address[](0), registryRewardOverrides); + } + + function handleRewardsAndFees( + SubmitEpochRootProofArgs calldata _args, + Epoch _endEpoch, + address[] memory _committee, + RegistryRewardOverride[MAX_REGISTRY_REWARD_OVERRIDES] memory _registryRewardOverrides + ) external { + RewardLib.handleRewardsAndFees(_args, _endEpoch, _rollupConfig(), true, _committee, _registryRewardOverrides); + } + + function updateRewardConfig(MutableRewardConfig memory _config) external { + RewardLib.updateConfig(_config); } function getSequencerRewards(address _sequencer) external view returns (uint256) { diff --git a/l1-contracts/test/rollup/libraries/rewardlib/registryReward.t.sol b/l1-contracts/test/rollup/libraries/rewardlib/registryReward.t.sol new file mode 100644 index 000000000000..ea655ddfc528 --- /dev/null +++ b/l1-contracts/test/rollup/libraries/rewardlib/registryReward.t.sol @@ -0,0 +1,193 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2026 Aztec Labs. +pragma solidity >=0.8.27; + +import {RewardLibBase} from "./RewardLibBase.sol"; +import { + IRegistryProvider, + Bps, + MutableRewardConfig, + RegistryRewardOverride, + MAX_REGISTRY_REWARD_OVERRIDES +} from "@aztec/core/libraries/rollup/RewardLib.sol"; +import {Epoch, Slot} from "@aztec/core/libraries/TimeLib.sol"; +import {MAXIMUM_COMMITTEE_SIZE} from "@aztec/core/interfaces/IValidatorSelection.sol"; + +contract RewardRegistryProvider is IRegistryProvider { + address internal immutable registry; + + constructor(address _registry) { + registry = _registry; + } + + function getRegistry() external view returns (address) { + return registry; + } +} + +contract RegistryRewardTest is RewardLibBase { + function test_WhenWithdrawerRegistryMatchesOverride() external prepare(100e18, 5000) { + address attester = makeAddr("attester"); + address registry = makeAddr("registry"); + RewardRegistryProvider provider = new RewardRegistryProvider(registry); + wrapper.setWithdrawer(attester, address(provider)); + + RegistryRewardOverride[MAX_REGISTRY_REWARD_OVERRIDES] memory overrides; + overrides[1] = RegistryRewardOverride({registry: registry, sequencerReward: 10e18}); + + wrapper.handleRewardsAndFees(args, Epoch.wrap(0), _singletonCommittee(attester), overrides); + + _assertRewards(10e18, 50e18); + } + + function test_WhenOverrideExceedsUpdatedDefaultReward_CapsAtDefault() external prepare(100e18, 5000) { + address attester = makeAddr("attester"); + address registry = makeAddr("registry"); + RewardRegistryProvider provider = new RewardRegistryProvider(registry); + wrapper.setWithdrawer(attester, address(provider)); + + RegistryRewardOverride[MAX_REGISTRY_REWARD_OVERRIDES] memory overrides; + overrides[0] = RegistryRewardOverride({registry: registry, sequencerReward: 40e18}); + + wrapper.updateRewardConfig(MutableRewardConfig({sequencerBps: Bps.wrap(5000), checkpointReward: 60e18})); + wrapper.handleRewardsAndFees(args, Epoch.wrap(0), _singletonCommittee(attester), overrides); + + _assertRewards(30e18, 30e18); + } + + function test_WhenWithdrawerRegistryMatchesZeroRewardOverrideAcrossCheckpoints() external prepare(100e18, 5000) { + address attester = makeAddr("attester"); + address registry = makeAddr("registry"); + RewardRegistryProvider provider = new RewardRegistryProvider(registry); + wrapper.setWithdrawer(attester, address(provider)); + + args.end = args.start + 1; + _setHeaders(2, sequencer); + _addFeeHeaders(1); + + RegistryRewardOverride[MAX_REGISTRY_REWARD_OVERRIDES] memory overrides; + overrides[0] = RegistryRewardOverride({registry: registry, sequencerReward: 0}); + + vm.expectCall(address(wrapper.gse()), abi.encodeWithSignature("getWithdrawer(address)", attester), 1); + vm.expectCall(address(provider), abi.encodeWithSelector(IRegistryProvider.getRegistry.selector), 1); + wrapper.handleRewardsAndFees(args, Epoch.wrap(0), _singletonCommittee(attester), overrides); + + _assertRewards(0, 100e18); + } + + function test_WhenZeroRewardProposerAtIndex255Repeats_CachesReward() external prepare(100e18, 5000) { + address registry = makeAddr("registry"); + RewardRegistryProvider provider = new RewardRegistryProvider(registry); + + address[] memory committee = new address[](MAXIMUM_COMMITTEE_SIZE); + for (uint256 i = 0; i < committee.length; i++) { + committee[i] = address(uint160(0x1000 + i)); + } + committee[255] = makeAddr("attester255"); + wrapper.setWithdrawer(committee[255], address(provider)); + + Slot firstSlot = _findSlotForProposerIndex(255, committee.length, 0); + Slot secondSlot = _findSlotForProposerIndex(255, committee.length, Slot.unwrap(firstSlot) + 1); + + args.end = args.start + 1; + _setHeaders(2, sequencer); + _addFeeHeaders(1); + args.headers[0].slotNumber = firstSlot; + args.headers[1].slotNumber = secondSlot; + + RegistryRewardOverride[MAX_REGISTRY_REWARD_OVERRIDES] memory overrides; + overrides[0] = RegistryRewardOverride({registry: registry, sequencerReward: 0}); + + vm.expectCall(address(wrapper.gse()), abi.encodeWithSignature("getWithdrawer(address)", committee[255]), 1); + vm.expectCall(address(provider), abi.encodeWithSelector(IRegistryProvider.getRegistry.selector), 1); + wrapper.handleRewardsAndFees(args, Epoch.wrap(0), committee, overrides); + + _assertRewards(0, 100e18); + } + + function test_WhenCommitteeMembersShareWithdrawer_AppliesOverrideToBoth() external prepare(100e18, 5000) { + address registry = makeAddr("registry"); + RewardRegistryProvider provider = new RewardRegistryProvider(registry); + address[] memory committee = new address[](2); + committee[0] = makeAddr("attester0"); + committee[1] = makeAddr("attester1"); + wrapper.setWithdrawer(committee[0], address(provider)); + wrapper.setWithdrawer(committee[1], address(provider)); + + args.end = args.start + 1; + _setHeaders(2, sequencer); + _addFeeHeaders(1); + args.headers[0].slotNumber = Slot.wrap(0); + + uint256 firstProposerIndex = wrapper.getProposerIndex(Epoch.wrap(0), Slot.wrap(0), committee.length); + bool foundDistinctProposer; + // look for the first slot with the other attester + for (uint256 slotNumber = 1; slotNumber < 256; slotNumber++) { + Slot slot = Slot.wrap(slotNumber); + if (wrapper.getProposerIndex(Epoch.wrap(0), slot, committee.length) != firstProposerIndex) { + args.headers[1].slotNumber = slot; + foundDistinctProposer = true; + break; + } + } + assertTrue(foundDistinctProposer); + + RegistryRewardOverride[MAX_REGISTRY_REWARD_OVERRIDES] memory overrides; + overrides[0] = RegistryRewardOverride({registry: registry, sequencerReward: 10e18}); + + wrapper.handleRewardsAndFees(args, Epoch.wrap(0), committee, overrides); + + _assertRewards(20e18, 100e18); + } + + function test_WhenWithdrawerRegistryDoesNotMatchOverride() external prepare(100e18, 5000) { + address attester = makeAddr("attester"); + RewardRegistryProvider provider = new RewardRegistryProvider(makeAddr("unknownRegistry")); + wrapper.setWithdrawer(attester, address(provider)); + + RegistryRewardOverride[MAX_REGISTRY_REWARD_OVERRIDES] memory overrides; + overrides[0] = RegistryRewardOverride({registry: makeAddr("configuredRegistry"), sequencerReward: 10e18}); + + wrapper.handleRewardsAndFees(args, Epoch.wrap(0), _singletonCommittee(attester), overrides); + + // the override was 10e18 so we check the reward was not the overriden value + _assertRewards(50e18, 50e18); + } + + function test_WhenWithdrawerDoesNotRespondWithRegistry() external prepare(100e18, 5000) { + address attester = makeAddr("attester"); + wrapper.setWithdrawer(attester, makeAddr("eoaWithdrawer")); + + RegistryRewardOverride[MAX_REGISTRY_REWARD_OVERRIDES] memory overrides; + overrides[0] = RegistryRewardOverride({registry: makeAddr("configuredRegistry"), sequencerReward: 10e18}); + + wrapper.handleRewardsAndFees(args, Epoch.wrap(0), _singletonCommittee(attester), overrides); + + _assertRewards(50e18, 50e18); + } + + function _singletonCommittee(address _attester) internal pure returns (address[] memory committee) { + committee = new address[](1); + committee[0] = _attester; + } + + function _findSlotForProposerIndex(uint256 _targetIndex, uint256 _committeeSize, uint256 _from) + internal + view + returns (Slot) + { + for (uint256 slotNumber = _from; slotNumber < _from + 10_000; slotNumber++) { + Slot slot = Slot.wrap(slotNumber); + if (wrapper.getProposerIndex(Epoch.wrap(0), slot, _committeeSize) == _targetIndex) { + return slot; + } + } + + revert("proposer index not found"); + } + + function _assertRewards(uint256 _sequencerReward, uint256 _proverReward) internal view { + assertEq(wrapper.getSequencerRewards(sequencer), _sequencerReward); + assertEq(wrapper.getCollectiveProverRewardsForEpoch(Epoch.wrap(0)), _proverReward); + } +} diff --git a/l1-contracts/test/rollup/libraries/rewardlib/tryGetRegistry.t.sol b/l1-contracts/test/rollup/libraries/rewardlib/tryGetRegistry.t.sol new file mode 100644 index 000000000000..3274b1eef92b --- /dev/null +++ b/l1-contracts/test/rollup/libraries/rewardlib/tryGetRegistry.t.sol @@ -0,0 +1,131 @@ +// SPDX-License-Identifier: MIT +// Copyright 2026 Aztec Labs. +pragma solidity >=0.8.27; + +import {TestBase} from "@test/base/Base.sol"; +import {IRegistryProvider, RewardLib} from "@aztec/core/libraries/rollup/RewardLib.sol"; + +contract RegistryProvider is IRegistryProvider { + address private immutable registry; + + constructor(address _registry) { + registry = _registry; + } + + function getRegistry() external view override returns (address) { + return registry; + } +} + +contract RevertingRegistryProvider is IRegistryProvider { + function getRegistry() external pure override returns (address) { + assembly ("memory-safe") { + mstore(0x00, 0x42) + revert(0x00, 0x20) + } + } +} + +contract VariableReturnDataRegistryProvider { + uint256 private immutable returnDataSize; + + constructor(uint256 _returnDataSize) { + returnDataSize = _returnDataSize; + } + + fallback() external { + uint256 size = returnDataSize; + + assembly { + mstore(0x00, 0x42) + return(0x00, size) + } + } +} + +contract DirtyAddressRegistryProvider is IRegistryProvider { + function getRegistry() external pure override returns (address) { + assembly ("memory-safe") { + mstore(0x00, or(shl(160, 1), 0x42)) + return(0x00, 0x20) + } + } +} + +contract GasBurningRegistryProvider is IRegistryProvider { + function getRegistry() external view override returns (address) { + uint256 startingGas = gasleft(); + while (startingGas - gasleft() < 100_000) {} + revert(); + } +} + +contract TryGetRegistryTest is TestBase { + function test_WhenWithdrawerReturnsRegistry() external { + address expectedRegistry = makeAddr("registry"); + RegistryProvider provider = new RegistryProvider(expectedRegistry); + + (bool responded, address registry) = RewardLib.tryGetRegistry(address(provider)); + + assertTrue(responded); + assertEq(registry, expectedRegistry); + } + + function test_WhenWithdrawerIsEOA() external { + (bool responded, address registry) = RewardLib.tryGetRegistry(makeAddr("eoa")); + assertFalse(responded); + assertEq(registry, address(0)); + } + + function test_WhenWithdrawerReturnsZeroRegistry() external { + RegistryProvider provider = new RegistryProvider(address(0)); + + (bool responded, address registry) = RewardLib.tryGetRegistry(address(provider)); + + assertTrue(responded); + assertEq(registry, address(0)); + } + + function test_WhenWithdrawerReverts() external { + RevertingRegistryProvider provider = new RevertingRegistryProvider(); + _assertInvalidRegistryResponse(address(provider)); + } + + function test_WhenWithdrawerReturnsTooLittleData() external { + VariableReturnDataRegistryProvider provider = new VariableReturnDataRegistryProvider(31); + _assertInvalidRegistryResponse(address(provider)); + } + + function test_WhenWithdrawerReturnsTooMuchData() external { + VariableReturnDataRegistryProvider provider = new VariableReturnDataRegistryProvider(33); + _assertInvalidRegistryResponse(address(provider)); + } + + function test_WhenWithdrawerReturnsDirtyAddress() external { + DirtyAddressRegistryProvider provider = new DirtyAddressRegistryProvider(); + _assertInvalidRegistryResponse(address(provider)); + } + + function test_WhenWithdrawerBurnsProbeGas() external { + GasBurningRegistryProvider provider = new GasBurningRegistryProvider(); + + uint256 gasBefore = gasleft(); + (bool responded, address registry) = RewardLib.tryGetRegistry(address(provider)); + uint256 gasUsed = gasBefore - gasleft(); + + assertFalse(responded); + assertEq(registry, address(0)); + assertLt(gasUsed, 75_000); + } + + function test_WhenWithdrawerReturnsLargeData() external { + VariableReturnDataRegistryProvider provider = new VariableReturnDataRegistryProvider(65_536); + _assertInvalidRegistryResponse(address(provider)); + } + + function _assertInvalidRegistryResponse(address _withdrawer) internal view { + (bool responded, address registry) = RewardLib.tryGetRegistry(_withdrawer); + assertFalse(responded); + assertEq(registry, address(0)); + } +} diff --git a/l1-contracts/test/rollup/registryRewardOverrides.t.sol b/l1-contracts/test/rollup/registryRewardOverrides.t.sol new file mode 100644 index 000000000000..2eb3e63932d5 --- /dev/null +++ b/l1-contracts/test/rollup/registryRewardOverrides.t.sol @@ -0,0 +1,159 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2026 Aztec Labs. +pragma solidity >=0.8.27; + +import {Test} from "forge-std/Test.sol"; +import {RollupCore} from "@aztec/core/RollupCore.sol"; +import { + GenesisState, + RollupConfigInput, + RegistryRewardOverride, + MAX_REGISTRY_REWARD_OVERRIDES +} from "@aztec/core/interfaces/IRollup.sol"; +import {IVerifier} from "@aztec/core/interfaces/IVerifier.sol"; +import {MAXIMUM_COMMITTEE_SIZE} from "@aztec/core/interfaces/IValidatorSelection.sol"; +import {Errors} from "@aztec/core/libraries/Errors.sol"; +import {Bps, MutableRewardConfig, RewardConfig} from "@aztec/core/libraries/rollup/RewardLib.sol"; +import {RewardExtLib} from "@aztec/core/libraries/rollup/RewardExtLib.sol"; +import {GSE} from "@aztec/governance/GSE.sol"; +import {MockVerifier} from "@aztec/mock/MockVerifier.sol"; +import {TestERC20} from "@aztec/mock/TestERC20.sol"; +import {RollupBuilder, Config as BuilderConfig} from "@test/builder/RollupBuilder.sol"; + +contract RegistryRewardOverridesRollupHarness is RollupCore { + constructor( + TestERC20 _token, + GSE _gse, + IVerifier _verifier, + address _governance, + GenesisState memory _genesisState, + RollupConfigInput memory _config + ) RollupCore(_token, _token, _gse, _verifier, _governance, _genesisState, _config) {} + + function getRegistryRewardOverrides() + external + view + returns (RegistryRewardOverride[MAX_REGISTRY_REWARD_OVERRIDES] memory overrides) + { + return _getRegistryRewardOverrides(); + } + + function getRewardConfig() external view returns (RewardConfig memory) { + return RewardExtLib.getRewardConfig(); + } +} + +contract RegistryRewardOverridesTest is Test { + TestERC20 internal token; + GSE internal gse; + GenesisState internal genesisState; + IVerifier internal verifier; + RollupBuilder internal builder; + + function setUp() public { + builder = new RollupBuilder(address(this)); + builder.deploy(); + BuilderConfig memory config = builder.getConfig(); + + token = config.testERC20; + gse = config.gse; + genesisState = config.genesisState; + verifier = new MockVerifier(); + } + + function test_exposesConfiguredRegistryRewardOverrides() external { + RegistryRewardOverride memory saleOverride = + RegistryRewardOverride({registry: makeAddr("saleRegistry"), sequencerReward: 10e18}); + RegistryRewardOverride memory genesisOverride = + RegistryRewardOverride({registry: makeAddr("genesisRegistry"), sequencerReward: 0}); + + RollupConfigInput memory config = builder.getConfig().rollupConfigInput; + config.registryRewardOverrides[0] = saleOverride; + config.registryRewardOverrides[1] = genesisOverride; + + RegistryRewardOverridesRollupHarness rollup = _deploy(config); + RegistryRewardOverride[MAX_REGISTRY_REWARD_OVERRIDES] memory actual = rollup.getRegistryRewardOverrides(); + + assertEq(actual[0].registry, saleOverride.registry); + assertEq(actual[0].sequencerReward, saleOverride.sequencerReward); + assertEq(actual[1].registry, genesisOverride.registry); + assertEq(actual[1].sequencerReward, genesisOverride.sequencerReward); + } + + function test_revertsWhenRegistryRewardOverridesContainDuplicateRegistry() external { + address registry = makeAddr("registry"); + RollupConfigInput memory config = builder.getConfig().rollupConfigInput; + config.registryRewardOverrides[0] = RegistryRewardOverride({registry: registry, sequencerReward: 10e18}); + config.registryRewardOverrides[1] = RegistryRewardOverride({registry: registry, sequencerReward: 5e18}); + + vm.expectRevert(abi.encodeWithSelector(Errors.RewardLib__DuplicateRegistryRewardOverride.selector, registry)); + _deploy(config); + } + + function test_revertsWhenRegistryRewardOverrideExceedsDefaultSequencerReward() external { + address registry = makeAddr("registry"); + RollupConfigInput memory config = builder.getConfig().rollupConfigInput; + uint256 defaultSequencerReward = 25e18; + uint96 overrideReward = uint96(defaultSequencerReward + 1); + config.registryRewardOverrides[0] = RegistryRewardOverride({registry: registry, sequencerReward: overrideReward}); + + vm.expectRevert( + abi.encodeWithSelector( + Errors.RewardLib__RegistryRewardOverrideAboveDefault.selector, registry, overrideReward, defaultSequencerReward + ) + ); + _deploy(config); + } + + function test_revertsWhenZeroRegistryHasNonZeroReward() external { + RollupConfigInput memory config = builder.getConfig().rollupConfigInput; + config.registryRewardOverrides[0] = RegistryRewardOverride({registry: address(0), sequencerReward: 1}); + + vm.expectRevert(abi.encodeWithSelector(Errors.RewardLib__InvalidRegistryRewardOverride.selector, address(0), 1)); + _deploy(config); + } + + function test_deploysWhenTargetCommitteeSizeIsMaximum() external { + RollupConfigInput memory config = builder.getConfig().rollupConfigInput; + config.targetCommitteeSize = MAXIMUM_COMMITTEE_SIZE; + + _deploy(config); + } + + function test_revertsWhenTargetCommitteeSizeExceedsMaximum() external { + RollupConfigInput memory config = builder.getConfig().rollupConfigInput; + config.targetCommitteeSize = MAXIMUM_COMMITTEE_SIZE + 1; + + vm.expectRevert(); + _deploy(config); + } + + function test_rewardConfigUpdateAllowsDefaultRewardBelowOverride() external { + address registry = makeAddr("registry"); + RollupConfigInput memory config = builder.getConfig().rollupConfigInput; + config.registryRewardOverrides[0] = RegistryRewardOverride({registry: registry, sequencerReward: 10e18}); + RegistryRewardOverridesRollupHarness rollup = _deploy(config); + + MutableRewardConfig memory updated = MutableRewardConfig({sequencerBps: Bps.wrap(5000), checkpointReward: 10e18}); + + rollup.setRewardConfig(updated); + + assertEq(rollup.getRewardConfig().checkpointReward, updated.checkpointReward); + } + + function test_rewardConfigUpdateAllowsOverrideAtDefaultRewardBoundary() external { + address registry = makeAddr("registry"); + RollupConfigInput memory config = builder.getConfig().rollupConfigInput; + config.registryRewardOverrides[0] = RegistryRewardOverride({registry: registry, sequencerReward: 10e18}); + RegistryRewardOverridesRollupHarness rollup = _deploy(config); + + MutableRewardConfig memory updated = MutableRewardConfig({sequencerBps: Bps.wrap(5000), checkpointReward: 20e18}); + rollup.setRewardConfig(updated); + + assertEq(rollup.getRewardConfig().checkpointReward, updated.checkpointReward); + } + + function _deploy(RollupConfigInput memory _config) internal returns (RegistryRewardOverridesRollupHarness) { + return new RegistryRewardOverridesRollupHarness(token, gse, verifier, address(this), genesisState, _config); + } +} diff --git a/l1-contracts/test/script/DeployAztecL1Contracts.t.sol b/l1-contracts/test/script/DeployAztecL1Contracts.t.sol index a867b29a34b8..599b01785246 100644 --- a/l1-contracts/test/script/DeployAztecL1Contracts.t.sol +++ b/l1-contracts/test/script/DeployAztecL1Contracts.t.sol @@ -6,6 +6,15 @@ import {Test} from "forge-std/Test.sol"; import {stdJson} from "forge-std/StdJson.sol"; import {DeployAztecL1Contracts} from "../../script/deploy/DeployAztecL1Contracts.s.sol"; +import {RollupConfiguration} from "../../script/deploy/RollupConfiguration.sol"; +import {RegistryRewardOverride, RollupConfigInput} from "@aztec/core/interfaces/IRollup.sol"; +import {IRewardDistributor} from "@aztec/governance/interfaces/IRewardDistributor.sol"; + +contract RollupConfigurationHarness is RollupConfiguration { + function getRegistryRewardOverride(string memory _envName) external view returns (RegistryRewardOverride memory) { + return _getRegistryRewardOverride(_envName); + } +} contract DeployAztecL1ContractsTest is Test { using stdJson for string; @@ -61,6 +70,9 @@ contract DeployAztecL1ContractsTest is Test { vm.setEnv("AZTEC_PROVING_COST_PER_MANA", vm.toString(json.readUint(".AZTEC_PROVING_COST_PER_MANA"))); vm.setEnv("AZTEC_INITIAL_ETH_PER_FEE_ASSET", vm.toString(json.readUint(".AZTEC_INITIAL_ETH_PER_FEE_ASSET"))); + vm.setEnv("AZTEC_REGISTRY_REWARD_OVERRIDE_0", json.readString(".AZTEC_REGISTRY_REWARD_OVERRIDE_0")); + vm.setEnv("AZTEC_REGISTRY_REWARD_OVERRIDE_1", json.readString(".AZTEC_REGISTRY_REWARD_OVERRIDE_1")); + // Slashing config vm.setEnv("AZTEC_SLASHER_ENABLED", vm.toString(json.readBool(".AZTEC_SLASHER_ENABLED"))); vm.setEnv("AZTEC_SLASHING_ROUND_SIZE_IN_EPOCHS", vm.toString(json.readUint(".AZTEC_SLASHING_ROUND_SIZE_IN_EPOCHS"))); @@ -82,4 +94,33 @@ contract DeployAztecL1ContractsTest is Test { DeployAztecL1Contracts deployScript = new DeployAztecL1Contracts(); deployScript.run(); } + + function test_RegistryRewardOverridesConfiguration() public { + address registry0 = makeAddr("registry0"); + address registry1 = makeAddr("registry1"); + uint256 sequencerReward0 = 10e18; + uint256 sequencerReward1 = 20e18; + + vm.setEnv( + "AZTEC_REGISTRY_REWARD_OVERRIDE_0", string.concat(vm.toString(registry0), ",", vm.toString(sequencerReward0)) + ); + vm.setEnv("AZTEC_REGISTRY_REWARD_OVERRIDE_1", string.concat(vm.toString(registry1), ",0x1158e460913d00000")); + + RollupConfigInput memory config = + new RollupConfiguration().getRollupConfiguration(IRewardDistributor(makeAddr("rewardDistributor"))); + + assertEq(config.registryRewardOverrides[0].registry, registry0); + assertEq(config.registryRewardOverrides[0].sequencerReward, sequencerReward0); + assertEq(config.registryRewardOverrides[1].registry, registry1); + assertEq(config.registryRewardOverrides[1].sequencerReward, sequencerReward1); + } + + function test_RevertWhenRegistryRewardOverrideIsMalformed() public { + string memory envName = "TEST_MALFORMED_REGISTRY_REWARD_OVERRIDE"; + vm.setEnv(envName, vm.toString(makeAddr("registry"))); + RollupConfigurationHarness configuration = new RollupConfigurationHarness(); + + vm.expectRevert("Invalid registry reward override"); + configuration.getRegistryRewardOverride(envName); + } } diff --git a/l1-contracts/test/script/DeployRollupForUpgrade.t.sol b/l1-contracts/test/script/DeployRollupForUpgrade.t.sol index 3a358a5326b3..0a0b93da073f 100644 --- a/l1-contracts/test/script/DeployRollupForUpgrade.t.sol +++ b/l1-contracts/test/script/DeployRollupForUpgrade.t.sol @@ -72,6 +72,9 @@ contract DeployRollupForUpgradeTest is Test { vm.setEnv("AZTEC_PROVING_COST_PER_MANA", vm.toString(json.readUint(".AZTEC_PROVING_COST_PER_MANA"))); vm.setEnv("AZTEC_INITIAL_ETH_PER_FEE_ASSET", vm.toString(json.readUint(".AZTEC_INITIAL_ETH_PER_FEE_ASSET"))); + vm.setEnv("AZTEC_REGISTRY_REWARD_OVERRIDE_0", json.readString(".AZTEC_REGISTRY_REWARD_OVERRIDE_0")); + vm.setEnv("AZTEC_REGISTRY_REWARD_OVERRIDE_1", json.readString(".AZTEC_REGISTRY_REWARD_OVERRIDE_1")); + // Slashing config vm.setEnv("AZTEC_SLASHER_ENABLED", vm.toString(json.readBool(".AZTEC_SLASHER_ENABLED"))); vm.setEnv("AZTEC_SLASHING_ROUND_SIZE_IN_EPOCHS", vm.toString(json.readUint(".AZTEC_SLASHING_ROUND_SIZE_IN_EPOCHS"))); From c45729a258ce451095496d1929d4c543ecf47709 Mon Sep 17 00:00:00 2001 From: Alex Date: Wed, 9 Sep 2026 14:52:23 +0100 Subject: [PATCH 12/19] feat: only verify new headers (#25404) This PR changes the checkpoint header verification from always verifying from index 0 (in the epoch) up to the current proven tip to verifying from the last proven index to up the new proven tip. This reduces the gas cost for partial epoch proofs by about ~3-4k per previously verified checkpoint header. Fix A-1802 --- .../partial_epoch_proof_gas_report.json | 72 +++++++++--------- .../partial_epoch_proof_gas_report.md | 18 ++--- .../core/libraries/rollup/EpochProofLib.sol | 48 ++++++++---- .../src/core/libraries/rollup/RewardLib.sol | 4 + l1-contracts/test/Rollup.t.sol | 73 +++++++++++++++++++ 5 files changed, 156 insertions(+), 59 deletions(-) diff --git a/l1-contracts/partial_epoch_proof_gas_report.json b/l1-contracts/partial_epoch_proof_gas_report.json index cf8cb6d47dbe..d941f9396147 100644 --- a/l1-contracts/partial_epoch_proof_gas_report.json +++ b/l1-contracts/partial_epoch_proof_gas_report.json @@ -8,66 +8,66 @@ "functions": { "gasReportSubmit16Checkpoints((uint256,uint256,(bytes32,bytes32,bytes32,bytes32,bytes32,address),(bytes32,bytes32,bytes32,bytes32,bytes32,uint256,uint256,address,bytes32,(uint128,uint128),uint256,uint256)[],(bytes,bytes),bytes,bytes))": { "calls": 1, - "min": 1298507, - "mean": 1298507, - "median": 1298507, - "max": 1298507 + "min": 1298643, + "mean": 1298643, + "median": 1298643, + "max": 1298643 }, "gasReportSubmit16CheckpointsWithTwoOverrides((uint256,uint256,(bytes32,bytes32,bytes32,bytes32,bytes32,address),(bytes32,bytes32,bytes32,bytes32,bytes32,uint256,uint256,address,bytes32,(uint128,uint128),uint256,uint256)[],(bytes,bytes),bytes,bytes))": { "calls": 1, - "min": 1463518, - "mean": 1463518, - "median": 1463518, - "max": 1463518 + "min": 1463654, + "mean": 1463654, + "median": 1463654, + "max": 1463654 }, "gasReportSubmit1Checkpoint((uint256,uint256,(bytes32,bytes32,bytes32,bytes32,bytes32,address),(bytes32,bytes32,bytes32,bytes32,bytes32,uint256,uint256,address,bytes32,(uint128,uint128),uint256,uint256)[],(bytes,bytes),bytes,bytes))": { "calls": 1, - "min": 659719, - "mean": 659719, - "median": 659719, - "max": 659719 + "min": 659855, + "mean": 659855, + "median": 659855, + "max": 659855 }, "gasReportSubmit1CheckpointWithTwoOverrides((uint256,uint256,(bytes32,bytes32,bytes32,bytes32,bytes32,address),(bytes32,bytes32,bytes32,bytes32,bytes32,uint256,uint256,address,bytes32,(uint128,uint128),uint256,uint256)[],(bytes,bytes),bytes,bytes))": { "calls": 1, - "min": 686472, - "mean": 686472, - "median": 686472, - "max": 686472 + "min": 686608, + "mean": 686608, + "median": 686608, + "max": 686608 }, "gasReportSubmit32Checkpoints((uint256,uint256,(bytes32,bytes32,bytes32,bytes32,bytes32,address),(bytes32,bytes32,bytes32,bytes32,bytes32,uint256,uint256,address,bytes32,(uint128,uint128),uint256,uint256)[],(bytes,bytes),bytes,bytes))": { "calls": 1, - "min": 1836386, - "mean": 1836386, - "median": 1836386, - "max": 1836386 + "min": 1836522, + "mean": 1836522, + "median": 1836522, + "max": 1836522 }, "gasReportSubmit32CheckpointsWithTwoOverrides((uint256,uint256,(bytes32,bytes32,bytes32,bytes32,bytes32,address),(bytes32,bytes32,bytes32,bytes32,bytes32,uint256,uint256,address,bytes32,(uint128,uint128),uint256,uint256)[],(bytes,bytes),bytes,bytes))": { "calls": 1, - "min": 2094127, - "mean": 2094127, - "median": 2094127, - "max": 2094127 + "min": 2094263, + "mean": 2094263, + "median": 2094263, + "max": 2094263 }, "gasReportSubmit8Checkpoints((uint256,uint256,(bytes32,bytes32,bytes32,bytes32,bytes32,address),(bytes32,bytes32,bytes32,bytes32,bytes32,uint256,uint256,address,bytes32,(uint128,uint128),uint256,uint256)[],(bytes,bytes),bytes,bytes))": { "calls": 1, - "min": 983949, - "mean": 983949, - "median": 983949, - "max": 983949 + "min": 984085, + "mean": 984085, + "median": 984085, + "max": 984085 }, "gasReportSubmit8CheckpointsWithTwoOverrides((uint256,uint256,(bytes32,bytes32,bytes32,bytes32,bytes32,address),(bytes32,bytes32,bytes32,bytes32,bytes32,uint256,uint256,address,bytes32,(uint128,uint128),uint256,uint256)[],(bytes,bytes),bytes,bytes))": { "calls": 1, - "min": 1080528, - "mean": 1080528, - "median": 1080528, - "max": 1080528 + "min": 1080664, + "mean": 1080664, + "median": 1080664, + "max": 1080664 }, "gasReportSubmit8MoreCheckpoints((uint256,uint256,(bytes32,bytes32,bytes32,bytes32,bytes32,address),(bytes32,bytes32,bytes32,bytes32,bytes32,uint256,uint256,address,bytes32,(uint128,uint128),uint256,uint256)[],(bytes,bytes),bytes,bytes))": { "calls": 1, - "min": 1010042, - "mean": 1010042, - "median": 1010042, - "max": 1010042 + "min": 974194, + "mean": 974194, + "median": 974194, + "max": 974194 } } } diff --git a/l1-contracts/partial_epoch_proof_gas_report.md b/l1-contracts/partial_epoch_proof_gas_report.md index 6ebdce8d7820..503248a5900d 100644 --- a/l1-contracts/partial_epoch_proof_gas_report.md +++ b/l1-contracts/partial_epoch_proof_gas_report.md @@ -2,14 +2,14 @@ | Proof submission | Gas | |---|---:| -| 1 Checkpoint | 659,719 | -| 1 Checkpoint With Two Overrides | 686,472 | -| 8 Checkpoints | 983,949 | -| 8 Checkpoints With Two Overrides | 1,080,528 | -| 8 More Checkpoints | 1,010,042 | -| 16 Checkpoints | 1,298,507 | -| 16 Checkpoints With Two Overrides | 1,463,518 | -| 32 Checkpoints | 1,836,386 | -| 32 Checkpoints With Two Overrides | 2,094,127 | +| 1 Checkpoint | 659,855 | +| 1 Checkpoint With Two Overrides | 686,608 | +| 8 Checkpoints | 984,085 | +| 8 Checkpoints With Two Overrides | 1,080,664 | +| 8 More Checkpoints | 974,194 | +| 16 Checkpoints | 1,298,643 | +| 16 Checkpoints With Two Overrides | 1,463,654 | +| 32 Checkpoints | 1,836,522 | +| 32 Checkpoints With Two Overrides | 2,094,263 | _Uses the mock epoch proof verifier._ diff --git a/l1-contracts/src/core/libraries/rollup/EpochProofLib.sol b/l1-contracts/src/core/libraries/rollup/EpochProofLib.sol index 61b321891247..b96092c342f8 100644 --- a/l1-contracts/src/core/libraries/rollup/EpochProofLib.sol +++ b/l1-contracts/src/core/libraries/rollup/EpochProofLib.sol @@ -122,11 +122,17 @@ library EpochProofLib { STFLib.prune(); } - (Epoch endEpoch, Epoch currentEpoch) = assertAcceptable(_args.start, _args.end); + (Epoch endEpoch, Epoch currentEpoch, uint256 provenBeforeSubmission) = assertAcceptable(_args.start, _args.end); + uint256 firstHeaderToVerify; + if (provenBeforeSubmission >= _args.start) { + uint256 provenPrefixLength = provenBeforeSubmission - _args.start + 1; + uint256 accountedPrefixLength = RewardLib.getLongestProvenLength(endEpoch); + firstHeaderToVerify = provenPrefixLength < accountedPrefixLength ? provenPrefixLength : accountedPrefixLength; + } - // Rehash the supplied headers against storage once, here: the public-input assembly below reads the fee - // recipient/value out of them and relies on this call having run. - verifyHeaders(_args.start, _args.end, _args.headers); + // The skipped calldata prefix is untrusted, but rewards have already consumed it and proof verification binds its + // fee data to the canonical checkpoint headers. We only verify new headers since the last proof + verifyHeaders(_args.start, _args.end, _args.headers, firstHeaderToVerify); // Verify attestations for the last checkpoint in the epoch // -> This serves as training wheels for the public part of the system (proving systems used in public and AVM) @@ -178,8 +184,8 @@ library EpochProofLib { * * @dev The fee recipient/value public inputs are sourced from the supplied headers, so this entry point rehashes * them against storage before assembling: an off-chain caller must not walk away with public inputs built from - * unverified fee fields and only discover the mismatch when the on-chain proof reverts. The submit path verifies - * the headers up front and assembles via computeEpochProofPublicInputs to avoid rehashing them twice. + * unverified fee fields and only discover the mismatch when the on-chain proof reverts. The submit path separately + * validates headers that have not already been proven and accounted for. * * @param _start - The start of the epoch (inclusive) * @param _end - The end of the epoch (inclusive) @@ -196,7 +202,7 @@ library EpochProofLib { bytes calldata _blobPublicInputs, RollupConfig memory _config ) internal view returns (bytes32[] memory) { - verifyHeaders(_start, _end, _headers); + verifyHeaders(_start, _end, _headers, 0); return computeEpochProofPublicInputs(_start, _end, _args, _headers, _blobPublicInputs, _config); } @@ -416,19 +422,25 @@ library EpochProofLib { } /** - * @notice Rehashes each provided checkpoint header and requires it to match the stored header hash + * @notice Rehashes a suffix of the provided checkpoint headers and requires it to match the stored header hashes * * @param _start The first checkpoint number in the epoch (inclusive) * @param _end The last checkpoint number in the epoch (inclusive) * @param _headers The proposed headers for each checkpoint in [_start, _end] + * @param _firstHeaderToVerify The index of the first header that has not already been proven and accounted for */ - function verifyHeaders(uint256 _start, uint256 _end, ProposedHeader[] calldata _headers) private view { + function verifyHeaders( + uint256 _start, + uint256 _end, + ProposedHeader[] calldata _headers, + uint256 _firstHeaderToVerify + ) private view { uint256 numCheckpoints = _end - _start + 1; require( _headers.length == numCheckpoints, Errors.Rollup__InvalidCheckpointHeaderCount(numCheckpoints, _headers.length) ); - for (uint256 i = 0; i < numCheckpoints; i++) { + for (uint256 i = _firstHeaderToVerify; i < numCheckpoints; i++) { bytes32 expectedHeaderHash = STFLib.getHeaderHash(_start + i); bytes32 providedHeaderHash = ProposedHeaderLib.hash(_headers[i]); require( @@ -460,8 +472,13 @@ library EpochProofLib { * @param _end The last checkpoint number in the epoch (inclusive) * @return endEpoch The epoch number that the proof covers * @return currentEpoch The epoch at the time the proof is submitted + * @return provenBeforeSubmission The proven checkpoint number observed while checking the submission */ - function assertAcceptable(uint256 _start, uint256 _end) private view returns (Epoch endEpoch, Epoch currentEpoch) { + function assertAcceptable(uint256 _start, uint256 _end) + private + view + returns (Epoch endEpoch, Epoch currentEpoch, uint256 provenBeforeSubmission) + { RollupStore storage rollupStore = STFLib.getStorage(); Epoch startEpoch = STFLib.getEpochForCheckpoint(_start); @@ -486,7 +503,8 @@ library EpochProofLib { bool isStartOfEpoch = _start == 1 || parentEpoch <= startEpoch - Epoch.wrap(1); require(isStartOfEpoch, Errors.Rollup__StartIsNotFirstCheckpointOfEpoch()); - bool isStartBuildingOnProven = _start - 1 <= rollupStore.tips.getProven(); + provenBeforeSubmission = rollupStore.tips.getProven(); + bool isStartBuildingOnProven = _start - 1 <= provenBeforeSubmission; require(isStartBuildingOnProven, Errors.Rollup__StartIsNotBuildingOnProven()); bool claimedNumCheckpointsInEpoch = _end - _start + 1 <= Constants.MAX_CHECKPOINTS_PER_EPOCH; @@ -494,6 +512,8 @@ library EpochProofLib { claimedNumCheckpointsInEpoch, Errors.Rollup__TooManyCheckpointsInEpoch(Constants.MAX_CHECKPOINTS_PER_EPOCH, _end - _start) ); + + return (endEpoch, currentEpoch, provenBeforeSubmission); } /** @@ -534,8 +554,8 @@ library EpochProofLib { * 2. Assembling the public inputs for the root rollup circuit * 3. Verifying the validity proof against the assembled public inputs using the configured verifier * - * @dev Assumes the caller has already verified the supplied checkpoint headers against storage, so assembly skips - * rehashing them. + * @dev Assumes the caller has completed the submit path's required header checks, so assembly does not rehash + * headers. * * @dev Errors Thrown: * - Rollup__InvalidBlobProof: Batched blob proof verification failed diff --git a/l1-contracts/src/core/libraries/rollup/RewardLib.sol b/l1-contracts/src/core/libraries/rollup/RewardLib.sol index f74627533474..101bebeed97b 100644 --- a/l1-contracts/src/core/libraries/rollup/RewardLib.sol +++ b/l1-contracts/src/core/libraries/rollup/RewardLib.sol @@ -327,6 +327,10 @@ library RewardLib { return getStorage().epochRewards[_epoch].rewards; } + function getLongestProvenLength(Epoch _epoch) internal view returns (uint256) { + return getStorage().epochRewards[_epoch].longestProvenLength; + } + function getHasSubmitted(Epoch _epoch, uint256 _length, address _prover) internal view returns (bool) { return getStorage().epochRewards[_epoch].subEpoch[_length].shares[_prover] > 0; } diff --git a/l1-contracts/test/Rollup.t.sol b/l1-contracts/test/Rollup.t.sol index b5667b07dadb..2ffc20309797 100644 --- a/l1-contracts/test/Rollup.t.sol +++ b/l1-contracts/test/Rollup.t.sol @@ -864,6 +864,79 @@ contract RollupTest is RollupBase { assertEq(outbox.getRootData(Epoch.wrap(0), 2), outHash2, "Root at K=2 should be outHash2"); } + function testLongerEpochProofAllowsModifiedPreviouslyProvenHeader() public setUpFor("mixed_checkpoint_1") { + _proposeCheckpoint("mixed_checkpoint_1", 1); + _proposeCheckpoint("mixed_checkpoint_2", 2); + + DecoderBase.Data memory checkpoint1Data = load("mixed_checkpoint_1").checkpoint; + DecoderBase.Data memory checkpoint2Data = load("mixed_checkpoint_2").checkpoint; + CheckpointLog memory checkpoint = rollup.getCheckpoint(0); + + _submitEpochProof( + 1, + 1, + checkpoint.archive, + checkpoint1Data.archive, + checkpoint1Data.batchedBlobInputs, + checkpoint1Data.header.outHash + ); + + address modifiedCoinbase = makeAddr("modifiedCoinbase"); + + // even though his header was tampered with the next _submitEpochProof call will succeed (with a MockVerifier): + // the correct header for slot 1 was correct when the previous proof was sent + // the fact that it is now bogus does no matter because its rewards will not be processed again + // with a RealVerifier the proof will fail because the header's hash is sent as a public input + proposedHeaders[1].coinbase = modifiedCoinbase; + + _submitEpochProof( + 1, + 2, + checkpoint.archive, + checkpoint2Data.archive, + checkpoint2Data.batchedBlobInputs, + checkpoint2Data.header.outHash + ); + + assertEq(rollup.getProvenCheckpointNumber(), 2); + assertEq(rollup.getSequencerRewards(modifiedCoinbase), 0); + } + + function testLongerEpochProofRejectsModifiedNewHeader() public setUpFor("mixed_checkpoint_1") { + _proposeCheckpoint("mixed_checkpoint_1", 1); + _proposeCheckpoint("mixed_checkpoint_2", 2); + + DecoderBase.Data memory checkpoint1Data = load("mixed_checkpoint_1").checkpoint; + DecoderBase.Data memory checkpoint2Data = load("mixed_checkpoint_2").checkpoint; + CheckpointLog memory checkpoint = rollup.getCheckpoint(0); + + _submitEpochProof( + 1, + 1, + checkpoint.archive, + checkpoint1Data.archive, + checkpoint1Data.batchedBlobInputs, + checkpoint1Data.header.outHash + ); + + bytes32 expectedHeaderHash = ProposedHeaderLib.hash(proposedHeaders[2]); + // send bogus header + proposedHeaders[2].accumulatedFees += 1; + bytes32 providedHeaderHash = ProposedHeaderLib.hash(proposedHeaders[2]); + + vm.expectRevert( + abi.encodeWithSelector(Errors.Rollup__InvalidCheckpointHeader.selector, expectedHeaderHash, providedHeaderHash) + ); + _submitEpochProof( + 1, + 2, + checkpoint.archive, + checkpoint2Data.archive, + checkpoint2Data.batchedBlobInputs, + checkpoint2Data.header.outHash + ); + } + // getEpochProofPublicInputs is the view that the prover-publisher calls off-chain to validate its inputs before // submitting. Because the fee recipient/value public inputs are taken from the supplied headers, the header check // must run here too - not only on the submit path - so a mismatch is caught before publishing rather than reverting From 1d9fcac96e742dfa515238e8cdc01e5a74ea9712 Mon Sep 17 00:00:00 2001 From: Alex Date: Wed, 9 Sep 2026 14:52:24 +0100 Subject: [PATCH 13/19] feat: optimize proof submission (#25406) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Further optimize the proof submission flow: 1. hash haeader from calldata instead of memory (avoids a copy) 2. read header hashes in bulk (avoid checks run on every iteration of a loop) 3. reuse already read header hashes Other than submitting a proof of the first checkpoint (which is +2k gas compared to next) every other scenario is cheaper than the code on next. | Scenario | Current gas | vs #25404 | vs origin/next | |------------------|-------------|--------------------|--------------------| | 1 fresh | 663,452 | −1,506 (−0.23%) | +2,243 (+0.34%) | | 8 fresh | 965,328 | −21,594 (−2.19%) | −14,985 (−1.53%) | | 8→16 extension | 930,160 | −28,490 (−2.97%) | −57,867 (−5.86%) | | 16 fresh | 1,256,565 | −44,700 (−3.44%) | −34,869 (−2.70%) | | 32 fresh | 1,729,965 | −91,388 (−5.02%) | −75,071 (−4.16%) | --- .../partial_epoch_proof_gas_report.json | 72 +++++++++---------- .../partial_epoch_proof_gas_report.md | 18 ++--- .../core/libraries/rollup/EpochProofLib.sol | 56 ++++++++------- .../libraries/rollup/ProposedHeaderLib.sol | 20 ++++++ .../src/core/libraries/rollup/STFLib.sol | 25 +++++++ l1-contracts/test/Rollup.t.sol | 26 +++++++ .../proposedheaderlib/hashCalldata.t.sol | 24 +++++++ 7 files changed, 172 insertions(+), 69 deletions(-) create mode 100644 l1-contracts/test/rollup/libraries/proposedheaderlib/hashCalldata.t.sol diff --git a/l1-contracts/partial_epoch_proof_gas_report.json b/l1-contracts/partial_epoch_proof_gas_report.json index d941f9396147..3f55b6331289 100644 --- a/l1-contracts/partial_epoch_proof_gas_report.json +++ b/l1-contracts/partial_epoch_proof_gas_report.json @@ -8,66 +8,66 @@ "functions": { "gasReportSubmit16Checkpoints((uint256,uint256,(bytes32,bytes32,bytes32,bytes32,bytes32,address),(bytes32,bytes32,bytes32,bytes32,bytes32,uint256,uint256,address,bytes32,(uint128,uint128),uint256,uint256)[],(bytes,bytes),bytes,bytes))": { "calls": 1, - "min": 1298643, - "mean": 1298643, - "median": 1298643, - "max": 1298643 + "min": 1251816, + "mean": 1251816, + "median": 1251816, + "max": 1251816 }, "gasReportSubmit16CheckpointsWithTwoOverrides((uint256,uint256,(bytes32,bytes32,bytes32,bytes32,bytes32,address),(bytes32,bytes32,bytes32,bytes32,bytes32,uint256,uint256,address,bytes32,(uint128,uint128),uint256,uint256)[],(bytes,bytes),bytes,bytes))": { "calls": 1, - "min": 1463654, - "mean": 1463654, - "median": 1463654, - "max": 1463654 + "min": 1416995, + "mean": 1416995, + "median": 1416995, + "max": 1416995 }, "gasReportSubmit1Checkpoint((uint256,uint256,(bytes32,bytes32,bytes32,bytes32,bytes32,address),(bytes32,bytes32,bytes32,bytes32,bytes32,uint256,uint256,address,bytes32,(uint128,uint128),uint256,uint256)[],(bytes,bytes),bytes,bytes))": { "calls": 1, - "min": 659855, - "mean": 659855, - "median": 659855, - "max": 659855 + "min": 656546, + "mean": 656546, + "median": 656546, + "max": 656546 }, "gasReportSubmit1CheckpointWithTwoOverrides((uint256,uint256,(bytes32,bytes32,bytes32,bytes32,bytes32,address),(bytes32,bytes32,bytes32,bytes32,bytes32,uint256,uint256,address,bytes32,(uint128,uint128),uint256,uint256)[],(bytes,bytes),bytes,bytes))": { "calls": 1, - "min": 686608, - "mean": 686608, - "median": 686608, - "max": 686608 + "min": 683299, + "mean": 683299, + "median": 683299, + "max": 683299 }, "gasReportSubmit32Checkpoints((uint256,uint256,(bytes32,bytes32,bytes32,bytes32,bytes32,address),(bytes32,bytes32,bytes32,bytes32,bytes32,uint256,uint256,address,bytes32,(uint128,uint128),uint256,uint256)[],(bytes,bytes),bytes,bytes))": { "calls": 1, - "min": 1836522, - "mean": 1836522, - "median": 1836522, - "max": 1836522 + "min": 1742662, + "mean": 1742662, + "median": 1742662, + "max": 1742662 }, "gasReportSubmit32CheckpointsWithTwoOverrides((uint256,uint256,(bytes32,bytes32,bytes32,bytes32,bytes32,address),(bytes32,bytes32,bytes32,bytes32,bytes32,uint256,uint256,address,bytes32,(uint128,uint128),uint256,uint256)[],(bytes,bytes),bytes,bytes))": { "calls": 1, - "min": 2094263, - "mean": 2094263, - "median": 2094263, - "max": 2094263 + "min": 2001294, + "mean": 2001294, + "median": 2001294, + "max": 2001294 }, "gasReportSubmit8Checkpoints((uint256,uint256,(bytes32,bytes32,bytes32,bytes32,bytes32,address),(bytes32,bytes32,bytes32,bytes32,bytes32,uint256,uint256,address,bytes32,(uint128,uint128),uint256,uint256)[],(bytes,bytes),bytes,bytes))": { "calls": 1, - "min": 984085, - "mean": 984085, - "median": 984085, - "max": 984085 + "min": 960537, + "mean": 960537, + "median": 960537, + "max": 960537 }, "gasReportSubmit8CheckpointsWithTwoOverrides((uint256,uint256,(bytes32,bytes32,bytes32,bytes32,bytes32,address),(bytes32,bytes32,bytes32,bytes32,bytes32,uint256,uint256,address,bytes32,(uint128,uint128),uint256,uint256)[],(bytes,bytes),bytes,bytes))": { "calls": 1, - "min": 1080664, - "mean": 1080664, - "median": 1080664, - "max": 1080664 + "min": 1057116, + "mean": 1057116, + "median": 1057116, + "max": 1057116 }, "gasReportSubmit8MoreCheckpoints((uint256,uint256,(bytes32,bytes32,bytes32,bytes32,bytes32,address),(bytes32,bytes32,bytes32,bytes32,bytes32,uint256,uint256,address,bytes32,(uint128,uint128),uint256,uint256)[],(bytes,bytes),bytes,bytes))": { "calls": 1, - "min": 974194, - "mean": 974194, - "median": 974194, - "max": 974194 + "min": 943741, + "mean": 943741, + "median": 943741, + "max": 943741 } } } diff --git a/l1-contracts/partial_epoch_proof_gas_report.md b/l1-contracts/partial_epoch_proof_gas_report.md index 503248a5900d..46babb89f886 100644 --- a/l1-contracts/partial_epoch_proof_gas_report.md +++ b/l1-contracts/partial_epoch_proof_gas_report.md @@ -2,14 +2,14 @@ | Proof submission | Gas | |---|---:| -| 1 Checkpoint | 659,855 | -| 1 Checkpoint With Two Overrides | 686,608 | -| 8 Checkpoints | 984,085 | -| 8 Checkpoints With Two Overrides | 1,080,664 | -| 8 More Checkpoints | 974,194 | -| 16 Checkpoints | 1,298,643 | -| 16 Checkpoints With Two Overrides | 1,463,654 | -| 32 Checkpoints | 1,836,522 | -| 32 Checkpoints With Two Overrides | 2,094,263 | +| 1 Checkpoint | 656,546 | +| 1 Checkpoint With Two Overrides | 683,299 | +| 8 Checkpoints | 960,537 | +| 8 Checkpoints With Two Overrides | 1,057,116 | +| 8 More Checkpoints | 943,741 | +| 16 Checkpoints | 1,251,816 | +| 16 Checkpoints With Two Overrides | 1,416,995 | +| 32 Checkpoints | 1,742,662 | +| 32 Checkpoints With Two Overrides | 2,001,294 | _Uses the mock epoch proof verifier._ diff --git a/l1-contracts/src/core/libraries/rollup/EpochProofLib.sol b/l1-contracts/src/core/libraries/rollup/EpochProofLib.sol index b96092c342f8..2b1a1b98e4b2 100644 --- a/l1-contracts/src/core/libraries/rollup/EpochProofLib.sol +++ b/l1-contracts/src/core/libraries/rollup/EpochProofLib.sol @@ -130,9 +130,13 @@ library EpochProofLib { firstHeaderToVerify = provenPrefixLength < accountedPrefixLength ? provenPrefixLength : accountedPrefixLength; } - // The skipped calldata prefix is untrusted, but rewards have already consumed it and proof verification binds its - // fee data to the canonical checkpoint headers. We only verify new headers since the last proof - verifyHeaders(_args.start, _args.end, _args.headers, firstHeaderToVerify); + { + // The skipped calldata prefix is untrusted, but rewards have already consumed it and proof verification binds its + // fee data to the canonical checkpoint headers. We only verify new headers since the last proof + bytes32[] memory headerHashes = verifyHeaders(_args.start, _args.end, _args.headers, firstHeaderToVerify); + + require(verifyEpochRootProof(_args, _config, headerHashes), Errors.Rollup__InvalidProof()); + } // Verify attestations for the last checkpoint in the epoch // -> This serves as training wheels for the public part of the system (proving systems used in public and AVM) @@ -140,8 +144,6 @@ library EpochProofLib { address[] memory committee = verifyLastCheckpointAttestationsAndOutHash(_args.end, _args.attestations, _args.args.outHash); - require(verifyEpochRootProof(_args, _config), Errors.Rollup__InvalidProof()); - RollupStore storage rollupStore = STFLib.getStorage(); CompressedChainTips tips = rollupStore.tips; @@ -202,8 +204,8 @@ library EpochProofLib { bytes calldata _blobPublicInputs, RollupConfig memory _config ) internal view returns (bytes32[] memory) { - verifyHeaders(_start, _end, _headers, 0); - return computeEpochProofPublicInputs(_start, _end, _args, _headers, _blobPublicInputs, _config); + bytes32[] memory headerHashes = verifyHeaders(_start, _end, _headers, 0); + return computeEpochProofPublicInputs(_start, _end, _args, _headers, _blobPublicInputs, _config, headerHashes); } /** @@ -263,17 +265,18 @@ library EpochProofLib { } /** - * @notice Assembles the root rollup public inputs, taking the supplied checkpoint headers as already verified + * @notice Assembles the root rollup public inputs from supplied headers and canonical stored header hashes * - * @dev Callers must have rehashed `_headers` against the stored header hashes beforehand, since the fee - * recipient/value public inputs are read straight out of them. + * @dev Callers must ensure the supplied fee fields are either rehashed against `_headerHashes` or bound to those + * canonical hashes by proof verification. * * @param _start - The start of the epoch (inclusive) * @param _end - The end of the epoch (inclusive) * @param _args - Array of public inputs to the proof (previousArchive, endArchive, endTimestamp, outHash, proverId) * @param _headers - The proposed checkpoint headers supplying the fee recipient and value for each checkpoint - * @param _blobPublicInputs- The blob public inputs for the proof - * @param _config - The rollup's deployment-time configuration + * @param _blobPublicInputs - The blob public inputs for the proof + * @param _config - The rollup's deployment-time configuration + * @param _headerHashes - The canonical stored header hashes returned by verifyHeaders */ function computeEpochProofPublicInputs( uint256 _start, @@ -281,7 +284,8 @@ library EpochProofLib { PublicInputArgs calldata _args, ProposedHeader[] calldata _headers, bytes calldata _blobPublicInputs, - RollupConfig memory _config + RollupConfig memory _config, + bytes32[] memory _headerHashes ) private view returns (bytes32[] memory) { RollupStore storage rollupStore = STFLib.getStorage(); @@ -358,7 +362,7 @@ library EpochProofLib { uint256 numCheckpoints = _end - _start + 1; for (uint256 i = 0; i < numCheckpoints; i++) { - publicInputs[5 + i] = STFLib.getHeaderHash(_start + i); + publicInputs[5 + i] = _headerHashes[i]; } uint256 offset = 5 + Constants.MAX_CHECKPOINTS_PER_EPOCH; @@ -428,21 +432,23 @@ library EpochProofLib { * @param _end The last checkpoint number in the epoch (inclusive) * @param _headers The proposed headers for each checkpoint in [_start, _end] * @param _firstHeaderToVerify The index of the first header that has not already been proven and accounted for + * @return headerHashes The canonical stored header hashes for the checkpoint range */ function verifyHeaders( uint256 _start, uint256 _end, ProposedHeader[] calldata _headers, uint256 _firstHeaderToVerify - ) private view { + ) private view returns (bytes32[] memory headerHashes) { uint256 numCheckpoints = _end - _start + 1; require( _headers.length == numCheckpoints, Errors.Rollup__InvalidCheckpointHeaderCount(numCheckpoints, _headers.length) ); + headerHashes = STFLib.getHeaderHashes(_start, _end); for (uint256 i = _firstHeaderToVerify; i < numCheckpoints; i++) { - bytes32 expectedHeaderHash = STFLib.getHeaderHash(_start + i); - bytes32 providedHeaderHash = ProposedHeaderLib.hash(_headers[i]); + bytes32 expectedHeaderHash = headerHashes[i]; + bytes32 providedHeaderHash = ProposedHeaderLib.hashCalldata(_headers[i]); require( providedHeaderHash == expectedHeaderHash, Errors.Rollup__InvalidCheckpointHeader(expectedHeaderHash, providedHeaderHash) @@ -565,17 +571,19 @@ library EpochProofLib { * * @param _args The epoch proof submission arguments containing proof data and public inputs * @param _config The rollup's deployment-time configuration + * @param _headerHashes The canonical stored header hashes returned by verifyHeaders * @return True if both blob proof and validity proof verification succeed */ - function verifyEpochRootProof(SubmitEpochRootProofArgs calldata _args, RollupConfig memory _config) - private - view - returns (bool) - { + function verifyEpochRootProof( + SubmitEpochRootProofArgs calldata _args, + RollupConfig memory _config, + bytes32[] memory _headerHashes + ) private view returns (bool) { BlobLib.validateBatchedBlob(_args.blobInputs); - bytes32[] memory publicInputs = - computeEpochProofPublicInputs(_args.start, _args.end, _args.args, _args.headers, _args.blobInputs, _config); + bytes32[] memory publicInputs = computeEpochProofPublicInputs( + _args.start, _args.end, _args.args, _args.headers, _args.blobInputs, _config, _headerHashes + ); require(_config.epochProofVerifier.verify(_args.proof, publicInputs), Errors.Rollup__InvalidProof()); diff --git a/l1-contracts/src/core/libraries/rollup/ProposedHeaderLib.sol b/l1-contracts/src/core/libraries/rollup/ProposedHeaderLib.sol index 374752f646f9..f7da0807464a 100644 --- a/l1-contracts/src/core/libraries/rollup/ProposedHeaderLib.sol +++ b/l1-contracts/src/core/libraries/rollup/ProposedHeaderLib.sol @@ -68,4 +68,24 @@ library ProposedHeaderLib { ) ); } + + function hashCalldata(ProposedHeader calldata _header) internal pure returns (bytes32) { + return Hash.sha256ToField( + abi.encodePacked( + _header.lastArchiveRoot, + _header.blockHeadersHash, + _header.blobsHash, + _header.inboxRollingHash, + _header.outHash, + _header.slotNumber, + Timestamp.unwrap(_header.timestamp).toUint64(), + _header.coinbase, + _header.feeRecipient, + _header.gasFees.feePerDaGas, + _header.gasFees.feePerL2Gas, + _header.totalManaUsed, + _header.accumulatedFees + ) + ); + } } diff --git a/l1-contracts/src/core/libraries/rollup/STFLib.sol b/l1-contracts/src/core/libraries/rollup/STFLib.sol index ecf4b651c040..a92199b4e470 100644 --- a/l1-contracts/src/core/libraries/rollup/STFLib.sol +++ b/l1-contracts/src/core/libraries/rollup/STFLib.sol @@ -283,6 +283,31 @@ library STFLib { return getStorageTempCheckpointLog(_checkpointNumber).headerHash; } + /** + * @notice Retrieves the stored header hashes for a contiguous checkpoint range. + * @dev Checking the newest checkpoint is not in the future and the oldest has not been overwritten proves every + * checkpoint between them is available. + * @param _start The first checkpoint number in the range (inclusive) + * @param _end The last checkpoint number in the range (inclusive) + * @return headerHashes The stored header hashes in checkpoint order + */ + function getHeaderHashes(uint256 _start, uint256 _end) internal view returns (bytes32[] memory headerHashes) { + uint256 numCheckpoints = _end - _start + 1; + RollupStore storage rollupStore = getStorage(); + uint256 pending = rollupStore.tips.getPending(); + uint256 size = roundaboutSize(); + + uint256 upperLimit = _start + size; + require( + _end <= pending && pending < upperLimit, Errors.Rollup__UnavailableTempCheckpointLog(_start, pending, upperLimit) + ); + + headerHashes = new bytes32[](numCheckpoints); + for (uint256 i = 0; i < numCheckpoints; i++) { + headerHashes[i] = rollupStore.tempCheckpointLogs[(_start + i) % size].headerHash; + } + } + /** * @notice Retrieves the compressed fee header for a specific checkpoint number * @dev Returns the fee information including base fee components and mana costs. diff --git a/l1-contracts/test/Rollup.t.sol b/l1-contracts/test/Rollup.t.sol index 2ffc20309797..bd2c07b5129c 100644 --- a/l1-contracts/test/Rollup.t.sol +++ b/l1-contracts/test/Rollup.t.sol @@ -983,6 +983,32 @@ contract RollupTest is RollupBase { rollup.getEpochProofPublicInputs(1, 1, args, headers, data.batchedBlobInputs); } + function testGetEpochProofPublicInputsReturnsCanonicalHeaderHashes() public setUpFor("mixed_checkpoint_1") { + _proposeCheckpoint("mixed_checkpoint_1", 1); + _proposeCheckpoint("mixed_checkpoint_2", 2); + + DecoderBase.Data memory data = load("mixed_checkpoint_2").checkpoint; + CheckpointLog memory checkpoint = rollup.getCheckpoint(0); + + PublicInputArgs memory args = PublicInputArgs({ + previousArchive: checkpoint.archive, + endArchive: data.archive, + outHash: data.header.outHash, + previousInboxRollingHash: 0, + endInboxRollingHash: proposedHeaders[2].inboxRollingHash, + proverId: address(0) + }); + + ProposedHeader[] memory headers = new ProposedHeader[](2); + headers[0] = proposedHeaders[1]; + headers[1] = proposedHeaders[2]; + + bytes32[] memory publicInputs = rollup.getEpochProofPublicInputs(1, 2, args, headers, data.batchedBlobInputs); + + assertEq(publicInputs[5], ProposedHeaderLib.hash(headers[0]), "Unexpected first header hash"); + assertEq(publicInputs[6], ProposedHeaderLib.hash(headers[1]), "Unexpected second header hash"); + } + // The epoch-proof anchoring pins the rolling-hash chain start to the record written at propose for checkpoint // start - 1, mirroring previousArchive. A wrong previousInboxRollingHash must be rejected. function testGetEpochProofPublicInputsRejectsWrongPreviousInboxRollingHash() public setUpFor("empty_checkpoint_1") { diff --git a/l1-contracts/test/rollup/libraries/proposedheaderlib/hashCalldata.t.sol b/l1-contracts/test/rollup/libraries/proposedheaderlib/hashCalldata.t.sol new file mode 100644 index 000000000000..c7a899a9a3af --- /dev/null +++ b/l1-contracts/test/rollup/libraries/proposedheaderlib/hashCalldata.t.sol @@ -0,0 +1,24 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2026 Aztec Labs. +pragma solidity >=0.8.27; + +import {Test} from "forge-std/Test.sol"; +import {Timestamp} from "@aztec/core/libraries/TimeLib.sol"; +import {ProposedHeader, ProposedHeaderLib} from "@aztec/core/libraries/rollup/ProposedHeaderLib.sol"; + +contract ProposedHeaderHashHarness { + function hashBoth(ProposedHeader calldata _header) external pure returns (bytes32 memoryHash, bytes32 calldataHash) { + ProposedHeader memory copiedHeader = _header; + return (ProposedHeaderLib.hash(copiedHeader), ProposedHeaderLib.hashCalldata(_header)); + } +} + +contract ProposedHeaderHashCalldataTest is Test { + ProposedHeaderHashHarness internal immutable harness = new ProposedHeaderHashHarness(); + + function testFuzz_HashCalldataMatchesMemory(ProposedHeader memory _header) public view { + _header.timestamp = Timestamp.wrap(uint64(Timestamp.unwrap(_header.timestamp))); + (bytes32 memoryHash, bytes32 calldataHash) = harness.hashBoth(_header); + assertEq(calldataHash, memoryHash); + } +} From 8070afbb446e4573c75fb76f5cc9f495ff4d4b64 Mon Sep 17 00:00:00 2001 From: Alex Date: Wed, 9 Sep 2026 14:52:24 +0100 Subject: [PATCH 14/19] feat: submitProof takes only new headers (#25419) This PR optimized the partial proof flow by enabling provers to only send the headers for new checkpoints that are proven by the proof. The provers can send smaller payloads (just fees + coinbase) for the already proven checkpoints (which also have their rewards accounted for). This PR slightly increases gas costs for full epoch proofs (because of all the new checks we have to run on the proven-prefix) but it reduces gas costs on partial epoch proofs that build on previously submitted proof by about ~3.5K/already proven checkpoint (so in the scneario where we prove 8 checkpoints and then another 8 checkpoints we save approx 27k on the second proof) This PR requires changes to be made to aztec-node to make it compatible with the new contracts. --- .../scripts/generate-artifacts.sh | 1 + .../partial_epoch_proof_gas_report.json | 92 +++---- .../partial_epoch_proof_gas_report.md | 18 +- l1-contracts/src/core/interfaces/IRollup.sol | 8 +- l1-contracts/src/core/libraries/Errors.sol | 1 + .../core/libraries/rollup/EpochProofLib.sol | 60 +++-- .../src/core/libraries/rollup/RewardLib.sol | 22 +- l1-contracts/test/Rollup.t.sol | 3 + l1-contracts/test/base/RollupBase.sol | 3 + .../test/benchmark/CompactEpochProof.t.sol | 176 ++++++++++++ l1-contracts/test/benchmark/happy.t.sol | 40 ++- .../test/compression/PreHeating.t.sol | 3 + .../EscapeHatchIntegrationBase.sol | 3 + .../regression/OutHashValidationSkipped.t.sol | 3 + .../integration/submitEpochRootProof.t.sol | 3 + l1-contracts/test/fees/FeeRollup.t.sol | 3 + .../ValidatorSelection.t.sol | 3 + .../test/validator-selection/tmnt207.t.sol | 3 + ...-proof-library-when-deploying-rollup.patch | 51 ++++ ...-compact-fees-for-proven-checkpoints.patch | 255 ++++++++++++++++++ 20 files changed, 665 insertions(+), 86 deletions(-) create mode 100644 l1-contracts/test/benchmark/CompactEpochProof.t.sol create mode 100644 labs-patches/0002-fix-link-epoch-proof-library-when-deploying-rollup.patch create mode 100644 labs-patches/0003-feat-submit-compact-fees-for-proven-checkpoints.patch diff --git a/l1-contracts/l1-artifacts/scripts/generate-artifacts.sh b/l1-contracts/l1-artifacts/scripts/generate-artifacts.sh index 8a224afdcdb0..dc699e35e978 100755 --- a/l1-contracts/l1-artifacts/scripts/generate-artifacts.sh +++ b/l1-contracts/l1-artifacts/scripts/generate-artifacts.sh @@ -16,6 +16,7 @@ contracts=( "SlashingProposer" "EmpireBase" "RollupOperationsExtLib" + "EpochProofExtLib" "ValidatorOperationsExtLib" "RewardExtLib" "SlasherDeploymentExtLib" diff --git a/l1-contracts/partial_epoch_proof_gas_report.json b/l1-contracts/partial_epoch_proof_gas_report.json index 3f55b6331289..97e65f67fbda 100644 --- a/l1-contracts/partial_epoch_proof_gas_report.json +++ b/l1-contracts/partial_epoch_proof_gas_report.json @@ -3,71 +3,71 @@ "contract": "test/RollupWithPreheating.sol:RollupWithPreheating", "deployment": { "gas": 0, - "size": 44750 + "size": 44946 }, "functions": { - "gasReportSubmit16Checkpoints((uint256,uint256,(bytes32,bytes32,bytes32,bytes32,bytes32,address),(bytes32,bytes32,bytes32,bytes32,bytes32,uint256,uint256,address,bytes32,(uint128,uint128),uint256,uint256)[],(bytes,bytes),bytes,bytes))": { + "gasReportSubmit16Checkpoints((uint256,uint256,(bytes32,bytes32,bytes32,bytes32,bytes32,address),(address,uint256)[],(bytes32,bytes32,bytes32,bytes32,bytes32,uint256,uint256,address,bytes32,(uint128,uint128),uint256,uint256)[],(bytes,bytes),bytes,bytes))": { "calls": 1, - "min": 1251816, - "mean": 1251816, - "median": 1251816, - "max": 1251816 + "min": 1255881, + "mean": 1255881, + "median": 1255881, + "max": 1255881 }, - "gasReportSubmit16CheckpointsWithTwoOverrides((uint256,uint256,(bytes32,bytes32,bytes32,bytes32,bytes32,address),(bytes32,bytes32,bytes32,bytes32,bytes32,uint256,uint256,address,bytes32,(uint128,uint128),uint256,uint256)[],(bytes,bytes),bytes,bytes))": { + "gasReportSubmit16CheckpointsWithTwoOverrides((uint256,uint256,(bytes32,bytes32,bytes32,bytes32,bytes32,address),(address,uint256)[],(bytes32,bytes32,bytes32,bytes32,bytes32,uint256,uint256,address,bytes32,(uint128,uint128),uint256,uint256)[],(bytes,bytes),bytes,bytes))": { "calls": 1, - "min": 1416995, - "mean": 1416995, - "median": 1416995, - "max": 1416995 + "min": 1421159, + "mean": 1421159, + "median": 1421159, + "max": 1421159 }, - "gasReportSubmit1Checkpoint((uint256,uint256,(bytes32,bytes32,bytes32,bytes32,bytes32,address),(bytes32,bytes32,bytes32,bytes32,bytes32,uint256,uint256,address,bytes32,(uint128,uint128),uint256,uint256)[],(bytes,bytes),bytes,bytes))": { + "gasReportSubmit1Checkpoint((uint256,uint256,(bytes32,bytes32,bytes32,bytes32,bytes32,address),(address,uint256)[],(bytes32,bytes32,bytes32,bytes32,bytes32,uint256,uint256,address,bytes32,(uint128,uint128),uint256,uint256)[],(bytes,bytes),bytes,bytes))": { "calls": 1, - "min": 656546, - "mean": 656546, - "median": 656546, - "max": 656546 + "min": 658412, + "mean": 658412, + "median": 658412, + "max": 658412 }, - "gasReportSubmit1CheckpointWithTwoOverrides((uint256,uint256,(bytes32,bytes32,bytes32,bytes32,bytes32,address),(bytes32,bytes32,bytes32,bytes32,bytes32,uint256,uint256,address,bytes32,(uint128,uint128),uint256,uint256)[],(bytes,bytes),bytes,bytes))": { + "gasReportSubmit1CheckpointWithTwoOverrides((uint256,uint256,(bytes32,bytes32,bytes32,bytes32,bytes32,address),(address,uint256)[],(bytes32,bytes32,bytes32,bytes32,bytes32,uint256,uint256,address,bytes32,(uint128,uint128),uint256,uint256)[],(bytes,bytes),bytes,bytes))": { "calls": 1, - "min": 683299, - "mean": 683299, - "median": 683299, - "max": 683299 + "min": 685559, + "mean": 685559, + "median": 685559, + "max": 685559 }, - "gasReportSubmit32Checkpoints((uint256,uint256,(bytes32,bytes32,bytes32,bytes32,bytes32,address),(bytes32,bytes32,bytes32,bytes32,bytes32,uint256,uint256,address,bytes32,(uint128,uint128),uint256,uint256)[],(bytes,bytes),bytes,bytes))": { + "gasReportSubmit32Checkpoints((uint256,uint256,(bytes32,bytes32,bytes32,bytes32,bytes32,address),(address,uint256)[],(bytes32,bytes32,bytes32,bytes32,bytes32,uint256,uint256,address,bytes32,(uint128,uint128),uint256,uint256)[],(bytes,bytes),bytes,bytes))": { "calls": 1, - "min": 1742662, - "mean": 1742662, - "median": 1742662, - "max": 1742662 + "min": 1748763, + "mean": 1748763, + "median": 1748763, + "max": 1748763 }, - "gasReportSubmit32CheckpointsWithTwoOverrides((uint256,uint256,(bytes32,bytes32,bytes32,bytes32,bytes32,address),(bytes32,bytes32,bytes32,bytes32,bytes32,uint256,uint256,address,bytes32,(uint128,uint128),uint256,uint256)[],(bytes,bytes),bytes,bytes))": { + "gasReportSubmit32CheckpointsWithTwoOverrides((uint256,uint256,(bytes32,bytes32,bytes32,bytes32,bytes32,address),(address,uint256)[],(bytes32,bytes32,bytes32,bytes32,bytes32,uint256,uint256,address,bytes32,(uint128,uint128),uint256,uint256)[],(bytes,bytes),bytes,bytes))": { "calls": 1, - "min": 2001294, - "mean": 2001294, - "median": 2001294, - "max": 2001294 + "min": 2007827, + "mean": 2007827, + "median": 2007827, + "max": 2007827 }, - "gasReportSubmit8Checkpoints((uint256,uint256,(bytes32,bytes32,bytes32,bytes32,bytes32,address),(bytes32,bytes32,bytes32,bytes32,bytes32,uint256,uint256,address,bytes32,(uint128,uint128),uint256,uint256)[],(bytes,bytes),bytes,bytes))": { + "gasReportSubmit8Checkpoints((uint256,uint256,(bytes32,bytes32,bytes32,bytes32,bytes32,address),(address,uint256)[],(bytes32,bytes32,bytes32,bytes32,bytes32,uint256,uint256,address,bytes32,(uint128,uint128),uint256,uint256)[],(bytes,bytes),bytes,bytes))": { "calls": 1, - "min": 960537, - "mean": 960537, - "median": 960537, - "max": 960537 + "min": 963262, + "mean": 963262, + "median": 963262, + "max": 963262 }, - "gasReportSubmit8CheckpointsWithTwoOverrides((uint256,uint256,(bytes32,bytes32,bytes32,bytes32,bytes32,address),(bytes32,bytes32,bytes32,bytes32,bytes32,uint256,uint256,address,bytes32,(uint128,uint128),uint256,uint256)[],(bytes,bytes),bytes,bytes))": { + "gasReportSubmit8CheckpointsWithTwoOverrides((uint256,uint256,(bytes32,bytes32,bytes32,bytes32,bytes32,address),(address,uint256)[],(bytes32,bytes32,bytes32,bytes32,bytes32,uint256,uint256,address,bytes32,(uint128,uint128),uint256,uint256)[],(bytes,bytes),bytes,bytes))": { "calls": 1, - "min": 1057116, - "mean": 1057116, - "median": 1057116, - "max": 1057116 + "min": 1060278, + "mean": 1060278, + "median": 1060278, + "max": 1060278 }, - "gasReportSubmit8MoreCheckpoints((uint256,uint256,(bytes32,bytes32,bytes32,bytes32,bytes32,address),(bytes32,bytes32,bytes32,bytes32,bytes32,uint256,uint256,address,bytes32,(uint128,uint128),uint256,uint256)[],(bytes,bytes),bytes,bytes))": { + "gasReportSubmit8MoreCheckpoints((uint256,uint256,(bytes32,bytes32,bytes32,bytes32,bytes32,address),(address,uint256)[],(bytes32,bytes32,bytes32,bytes32,bytes32,uint256,uint256,address,bytes32,(uint128,uint128),uint256,uint256)[],(bytes,bytes),bytes,bytes))": { "calls": 1, - "min": 943741, - "mean": 943741, - "median": 943741, - "max": 943741 + "min": 916794, + "mean": 916794, + "median": 916794, + "max": 916794 } } } diff --git a/l1-contracts/partial_epoch_proof_gas_report.md b/l1-contracts/partial_epoch_proof_gas_report.md index 46babb89f886..f7e3395741cf 100644 --- a/l1-contracts/partial_epoch_proof_gas_report.md +++ b/l1-contracts/partial_epoch_proof_gas_report.md @@ -2,14 +2,14 @@ | Proof submission | Gas | |---|---:| -| 1 Checkpoint | 656,546 | -| 1 Checkpoint With Two Overrides | 683,299 | -| 8 Checkpoints | 960,537 | -| 8 Checkpoints With Two Overrides | 1,057,116 | -| 8 More Checkpoints | 943,741 | -| 16 Checkpoints | 1,251,816 | -| 16 Checkpoints With Two Overrides | 1,416,995 | -| 32 Checkpoints | 1,742,662 | -| 32 Checkpoints With Two Overrides | 2,001,294 | +| 1 Checkpoint | 658,412 | +| 1 Checkpoint With Two Overrides | 685,559 | +| 8 Checkpoints | 963,262 | +| 8 Checkpoints With Two Overrides | 1,060,278 | +| 8 More Checkpoints | 916,794 | +| 16 Checkpoints | 1,255,881 | +| 16 Checkpoints With Two Overrides | 1,421,159 | +| 32 Checkpoints | 1,748,763 | +| 32 Checkpoints With Two Overrides | 2,007,827 | _Uses the mock epoch proof verifier._ diff --git a/l1-contracts/src/core/interfaces/IRollup.sol b/l1-contracts/src/core/interfaces/IRollup.sol index c973c19f36f7..1dd57391d298 100644 --- a/l1-contracts/src/core/interfaces/IRollup.sol +++ b/l1-contracts/src/core/interfaces/IRollup.sol @@ -39,11 +39,17 @@ struct PublicInputArgs { address proverId; } +struct ProvenCheckpointFees { + address coinbase; + uint256 accumulatedFees; +} + struct SubmitEpochRootProofArgs { uint256 start; // inclusive uint256 end; // inclusive PublicInputArgs args; - ProposedHeader[] headers; // Must match what was proposed by the committee + ProvenCheckpointFees[] provenCheckpointFees; // Optional prefix already proven and accounted for + ProposedHeader[] headers; // Remaining suffix; must match what was proposed by the committee CommitteeAttestations attestations; // attestations for the last checkpoint in epoch bytes blobInputs; bytes proof; diff --git a/l1-contracts/src/core/libraries/Errors.sol b/l1-contracts/src/core/libraries/Errors.sol index 8e9eb3c1fd22..25544a75faea 100644 --- a/l1-contracts/src/core/libraries/Errors.sol +++ b/l1-contracts/src/core/libraries/Errors.sol @@ -55,6 +55,7 @@ library Errors { error Rollup__InvalidArchive(bytes32 expected, bytes32 actual); // 0xb682a40e error Rollup__InvalidCheckpointHeader(bytes32 expected, bytes32 actual); error Rollup__InvalidCheckpointHeaderCount(uint256 expected, uint256 actual); + error Rollup__InvalidProvenCheckpointCount(uint256 maximum, uint256 actual); error Rollup__InvalidCheckpointNumber(uint256 expected, uint256 actual); // 0xd1ba9bfa error Rollup__InvalidInboxRollingHash(bytes32 expected, bytes32 actual); // 0xed1f7bb5 error Rollup__InvalidPreviousInboxRollingHash(bytes32 expected, bytes32 actual); // 0x2fe7cae5 diff --git a/l1-contracts/src/core/libraries/rollup/EpochProofLib.sol b/l1-contracts/src/core/libraries/rollup/EpochProofLib.sol index 2b1a1b98e4b2..05cc0a7a5c54 100644 --- a/l1-contracts/src/core/libraries/rollup/EpochProofLib.sol +++ b/l1-contracts/src/core/libraries/rollup/EpochProofLib.sol @@ -6,6 +6,7 @@ import {BlobLib} from "@aztec-blob-lib/BlobLib.sol"; import {IEscapeHatch} from "@aztec/core/interfaces/IEscapeHatch.sol"; import { SubmitEpochRootProofArgs, + ProvenCheckpointFees, PublicInputArgs, IRollupCore, RollupStore, @@ -107,7 +108,8 @@ library EpochProofLib { * - start: First checkpoint number in the epoch (inclusive) * - end: Last checkpoint number in the epoch (inclusive) * - args: Public inputs (previousArchive, endArchive, endTimestamp, proverId) - * - headers: Proposed headers for each checkpoint, supplying the fee recipient and value + * - provenCheckpointFees: Fee recipient and value for an already proven and accounted prefix + * - headers: Proposed headers for the remaining checkpoints * - attestations: Committee attestations for the last checkpoint in the epoch * - blobInputs: Batched blob data for EIP-4844 point evaluation precompile * - proof: The validity proof bytes for the root rollup circuit @@ -123,17 +125,23 @@ library EpochProofLib { } (Epoch endEpoch, Epoch currentEpoch, uint256 provenBeforeSubmission) = assertAcceptable(_args.start, _args.end); - uint256 firstHeaderToVerify; - if (provenBeforeSubmission >= _args.start) { - uint256 provenPrefixLength = provenBeforeSubmission - _args.start + 1; - uint256 accountedPrefixLength = RewardLib.getLongestProvenLength(endEpoch); - firstHeaderToVerify = provenPrefixLength < accountedPrefixLength ? provenPrefixLength : accountedPrefixLength; - } - { - // The skipped calldata prefix is untrusted, but rewards have already consumed it and proof verification binds its - // fee data to the canonical checkpoint headers. We only verify new headers since the last proof - bytes32[] memory headerHashes = verifyHeaders(_args.start, _args.end, _args.headers, firstHeaderToVerify); + uint256 firstHeaderToVerify; + if (provenBeforeSubmission >= _args.start) { + uint256 provenPrefixLength = provenBeforeSubmission - _args.start + 1; + uint256 accountedPrefixLength = RewardLib.getLongestProvenLength(endEpoch); + firstHeaderToVerify = provenPrefixLength < accountedPrefixLength ? provenPrefixLength : accountedPrefixLength; + } + + uint256 prefixLength = _args.provenCheckpointFees.length; + require( + prefixLength <= firstHeaderToVerify, + Errors.Rollup__InvalidProvenCheckpointCount(firstHeaderToVerify, prefixLength) + ); + + // Proof verification binds compact fee data to canonical header hashes. Rewards may only consume full headers. + bytes32[] memory headerHashes = + verifyHeaders(_args.start, _args.end, _args.headers, prefixLength, firstHeaderToVerify); require(verifyEpochRootProof(_args, _config, headerHashes), Errors.Rollup__InvalidProof()); } @@ -204,7 +212,7 @@ library EpochProofLib { bytes calldata _blobPublicInputs, RollupConfig memory _config ) internal view returns (bytes32[] memory) { - bytes32[] memory headerHashes = verifyHeaders(_start, _end, _headers, 0); + bytes32[] memory headerHashes = verifyHeaders(_start, _end, _headers, 0, 0); return computeEpochProofPublicInputs(_start, _end, _args, _headers, _blobPublicInputs, _config, headerHashes); } @@ -273,7 +281,7 @@ library EpochProofLib { * @param _start - The start of the epoch (inclusive) * @param _end - The end of the epoch (inclusive) * @param _args - Array of public inputs to the proof (previousArchive, endArchive, endTimestamp, outHash, proverId) - * @param _headers - The proposed checkpoint headers supplying the fee recipient and value for each checkpoint + * @param _headers - The proposed checkpoint headers supplying fee data for the remaining suffix * @param _blobPublicInputs - The blob public inputs for the proof * @param _config - The rollup's deployment-time configuration * @param _headerHashes - The canonical stored header hashes returned by verifyHeaders @@ -367,11 +375,11 @@ library EpochProofLib { uint256 offset = 5 + Constants.MAX_CHECKPOINTS_PER_EPOCH; - // Taking recipient/value from the checkpoint headers rather than the prover - // as defense in depth. Slots past numCheckpoints stay zero. - for (uint256 i = 0; i < numCheckpoints; i++) { - publicInputs[offset + 2 * i] = addressToField(_headers[i].coinbase); - publicInputs[offset + 2 * i + 1] = bytes32(_headers[i].accumulatedFees); + // The submit path fills the compact prefix directly from calldata before verifying the proof. + uint256 suffixOffset = offset + 2 * (numCheckpoints - _headers.length); + for (uint256 i = 0; i < _headers.length; i++) { + publicInputs[suffixOffset + 2 * i] = addressToField(_headers[i].coinbase); + publicInputs[suffixOffset + 2 * i + 1] = bytes32(_headers[i].accumulatedFees); } offset += Constants.MAX_CHECKPOINTS_PER_EPOCH * 2; @@ -430,7 +438,8 @@ library EpochProofLib { * * @param _start The first checkpoint number in the epoch (inclusive) * @param _end The last checkpoint number in the epoch (inclusive) - * @param _headers The proposed headers for each checkpoint in [_start, _end] + * @param _headers The proposed headers after the compact prefix + * @param _prefixLength The number of checkpoints represented by compact fee data * @param _firstHeaderToVerify The index of the first header that has not already been proven and accounted for * @return headerHashes The canonical stored header hashes for the checkpoint range */ @@ -438,17 +447,19 @@ library EpochProofLib { uint256 _start, uint256 _end, ProposedHeader[] calldata _headers, + uint256 _prefixLength, uint256 _firstHeaderToVerify ) private view returns (bytes32[] memory headerHashes) { uint256 numCheckpoints = _end - _start + 1; require( - _headers.length == numCheckpoints, Errors.Rollup__InvalidCheckpointHeaderCount(numCheckpoints, _headers.length) + _headers.length + _prefixLength == numCheckpoints, + Errors.Rollup__InvalidCheckpointHeaderCount(numCheckpoints, _headers.length + _prefixLength) ); headerHashes = STFLib.getHeaderHashes(_start, _end); for (uint256 i = _firstHeaderToVerify; i < numCheckpoints; i++) { bytes32 expectedHeaderHash = headerHashes[i]; - bytes32 providedHeaderHash = ProposedHeaderLib.hashCalldata(_headers[i]); + bytes32 providedHeaderHash = ProposedHeaderLib.hashCalldata(_headers[i - _prefixLength]); require( providedHeaderHash == expectedHeaderHash, Errors.Rollup__InvalidCheckpointHeader(expectedHeaderHash, providedHeaderHash) @@ -585,6 +596,13 @@ library EpochProofLib { _args.start, _args.end, _args.args, _args.headers, _args.blobInputs, _config, _headerHashes ); + uint256 offset = 5 + Constants.MAX_CHECKPOINTS_PER_EPOCH; + ProvenCheckpointFees[] calldata provenFees = _args.provenCheckpointFees; + for (uint256 i = 0; i < provenFees.length; i++) { + publicInputs[offset + 2 * i] = addressToField(provenFees[i].coinbase); + publicInputs[offset + 2 * i + 1] = bytes32(provenFees[i].accumulatedFees); + } + require(_config.epochProofVerifier.verify(_args.proof, publicInputs), Errors.Rollup__InvalidProof()); return true; diff --git a/l1-contracts/src/core/libraries/rollup/RewardLib.sol b/l1-contracts/src/core/libraries/rollup/RewardLib.sol index 101bebeed97b..f743c0bfaff9 100644 --- a/l1-contracts/src/core/libraries/rollup/RewardLib.sol +++ b/l1-contracts/src/core/libraries/rollup/RewardLib.sol @@ -5,6 +5,7 @@ pragma solidity >=0.8.27; import {RollupConfig, SubmitEpochRootProofArgs} from "@aztec/core/interfaces/IRollup.sol"; import {CompressedFeeHeader, FeeHeaderLib} from "@aztec/core/libraries/compressed-data/fees/FeeStructs.sol"; import {Errors} from "@aztec/core/libraries/Errors.sol"; +import {ProposedHeader} from "@aztec/core/libraries/rollup/ProposedHeaderLib.sol"; import {StakingLib} from "@aztec/core/libraries/rollup/StakingLib.sol"; import {STFLib} from "@aztec/core/libraries/rollup/STFLib.sol"; import {ValidatorSelectionLib} from "@aztec/core/libraries/rollup/ValidatorSelectionLib.sol"; @@ -73,6 +74,8 @@ struct RewardStorage { struct Values { address sequencer; + uint256 fee; + uint256 protocolFee; uint256 proverFee; uint256 sequencerFee; uint256[] sequencerCheckpointRewards; @@ -275,27 +278,29 @@ library RewardLib { Totals memory t; for (uint256 i = $er.longestProvenLength; i < length; i++) { + { + ProposedHeader calldata header = _args.headers[i - _args.provenCheckpointFees.length]; + v.fee = header.accumulatedFees; + v.sequencer = header.coinbase; + } uint256 index = i - $er.longestProvenLength; CompressedFeeHeader feeHeader = STFLib.getFeeHeader(_args.start + i); v.manaUsed = feeHeader.getManaUsed(); + v.protocolFee = feeHeader.getProtocolFee() * v.manaUsed; - uint256 fee = _args.headers[i].accumulatedFees; - uint256 protocolFee = feeHeader.getProtocolFee() * v.manaUsed; - - t.feesToClaim += fee; - t.totalProtocolFee += protocolFee; + t.feesToClaim += v.fee; + t.totalProtocolFee += v.protocolFee; // Compute the proving fee in the fee asset - v.proverFee = Math.min(v.manaUsed * feeHeader.getProverCost(), fee - protocolFee); + v.proverFee = Math.min(v.manaUsed * feeHeader.getProverCost(), v.fee - v.protocolFee); if (v.proverFee > 0) { $er.rewards += v.proverFee.toUint128(); } - v.sequencerFee = fee - protocolFee - v.proverFee; + v.sequencerFee = v.fee - v.protocolFee - v.proverFee; { - v.sequencer = _args.headers[i].coinbase; uint256 toSequencer = v.sequencerCheckpointRewards[index] + v.sequencerFee; if (toSequencer > 0) { rewardStorage.sequencerRewards[v.sequencer] += toSequencer; @@ -451,6 +456,7 @@ library RewardLib { context.proposerRewards = new uint256[](_committee.length); context.gse = StakingLib.getStorage().gse; context.registryRewardOverrides = _registryRewardOverrides; + _from -= _args.provenCheckpointFees.length; for (uint256 i = 0; i < desiredSequencerCheckpointRewards.length; i++) { uint256 proposerIndex = ValidatorSelectionLib.computeProposerIndex( _endEpoch, _args.headers[_from + i].slotNumber, seed, _committee.length diff --git a/l1-contracts/test/Rollup.t.sol b/l1-contracts/test/Rollup.t.sol index bd2c07b5129c..5d914dd4c5c0 100644 --- a/l1-contracts/test/Rollup.t.sol +++ b/l1-contracts/test/Rollup.t.sol @@ -2,6 +2,8 @@ // Copyright 2024 Aztec Labs. pragma solidity >=0.8.27; +import {ProvenCheckpointFees} from "@aztec/core/interfaces/IRollup.sol"; + import {DecoderBase} from "./base/DecoderBase.sol"; import {Constants} from "@aztec/core/libraries/ConstantsGen.sol"; @@ -1108,6 +1110,7 @@ contract RollupTest is RollupBase { start: _start, end: _end, args: args, + provenCheckpointFees: new ProvenCheckpointFees[](0), headers: headers, attestations: CommitteeAttestations({signatureIndices: "", signaturesOrAddresses: ""}), blobInputs: _blobInputs, diff --git a/l1-contracts/test/base/RollupBase.sol b/l1-contracts/test/base/RollupBase.sol index cdf6ee4014a2..3482402ec517 100644 --- a/l1-contracts/test/base/RollupBase.sol +++ b/l1-contracts/test/base/RollupBase.sol @@ -1,6 +1,8 @@ // SPDX-License-Identifier: UNLICENSED pragma solidity >=0.8.27; +import {ProvenCheckpointFees} from "@aztec/core/interfaces/IRollup.sol"; + import {DecoderBase} from "./DecoderBase.sol"; import {IInstance} from "@aztec/core/interfaces/IInstance.sol"; @@ -102,6 +104,7 @@ contract RollupBase is DecoderBase { start: startCheckpointNumber, end: endCheckpointNumber, args: args, + provenCheckpointFees: new ProvenCheckpointFees[](0), headers: headers, attestations: CommitteeAttestations({signatureIndices: "", signaturesOrAddresses: ""}), blobInputs: endFull.checkpoint.batchedBlobInputs, diff --git a/l1-contracts/test/benchmark/CompactEpochProof.t.sol b/l1-contracts/test/benchmark/CompactEpochProof.t.sol new file mode 100644 index 000000000000..5ae8297e68e3 --- /dev/null +++ b/l1-contracts/test/benchmark/CompactEpochProof.t.sol @@ -0,0 +1,176 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2026 Aztec Labs. +pragma solidity >=0.8.27; + +import {PartialEpochProofGasReportBase} from "./happy.t.sol"; +import {SubmitEpochRootProofArgs, PublicInputArgs} from "@aztec/core/interfaces/IRollup.sol"; +import {ProposedHeader, ProposedHeaderLib} from "@aztec/core/libraries/rollup/ProposedHeaderLib.sol"; +import {CommitteeAttestations} from "@aztec/core/libraries/rollup/AttestationLib.sol"; +import {Errors} from "@aztec/core/libraries/Errors.sol"; +import {Epoch} from "@aztec/core/libraries/TimeLib.sol"; + +contract ExpectedEpochPublicInputsVerifier { + bytes32 private immutable expected; + + constructor(bytes32[] memory _inputs) { + expected = keccak256(abi.encode(_inputs)); + } + + function verify(bytes calldata, bytes32[] calldata _inputs) external view returns (bool) { + return keccak256(abi.encode(_inputs)) == expected; + } +} + +contract CompactEpochProofTest is PartialEpochProofGasReportBase { + struct LegacySubmission { + uint256 start; + uint256 end; + PublicInputArgs args; + ProposedHeader[] headers; + CommitteeAttestations attestations; + bytes blobInputs; + bytes proof; + } + + function _bindPublicInputs(SubmitEpochRootProofArgs memory _args) internal { + bytes32[] memory inputs = + rollup.getEpochProofPublicInputs(_args.start, _args.end, _args.args, _args.headers, _args.blobInputs); + ExpectedEpochPublicInputsVerifier verifier = new ExpectedEpochPublicInputsVerifier(inputs); + vm.etch(address(rollup.getEpochProofVerifier()), address(verifier).code); + } + + function testCompactExtensionPreservesPublicInputsAndRewards() public { + rollup.submitEpochRootProof(_getGasReportSubmission(8)); + SubmitEpochRootProofArgs memory fullArgs = _getGasReportSubmission(16); + _bindPublicInputs(fullArgs); + uint256 snapshot = vm.snapshotState(); + rollup.submitEpochRootProof(fullArgs); + uint256 rewards = rollup.getCollectiveProverRewardsForEpoch(Epoch.wrap(GAS_REPORT_EPOCH)); + uint256[] memory sequencerRewards = new uint256[](16); + for (uint256 i = 0; i < 16; i++) { + sequencerRewards[i] = rollup.getSequencerRewards(checkpointHeaders[i + 1].coinbase); + } + vm.revertToState(snapshot); + rollup.submitEpochRootProof(_compactSubmission(fullArgs, 8)); + assertEq(rollup.getProvenCheckpointNumber(), 16); + assertEq(rollup.getCollectiveProverRewardsForEpoch(Epoch.wrap(GAS_REPORT_EPOCH)), rewards); + for (uint256 i = 0; i < 16; i++) { + assertEq(rollup.getSequencerRewards(checkpointHeaders[i + 1].coinbase), sequencerRewards[i]); + } + } + + function testCompactPrefixRejectsUnprovenCheckpoints() public { + SubmitEpochRootProofArgs memory args = _compactSubmission(_getGasReportSubmission(8), 1); + vm.expectRevert(abi.encodeWithSelector(Errors.Rollup__InvalidProvenCheckpointCount.selector, 0, 1)); + rollup.submitEpochRootProof(args); + } + + function testCompactPrefixCannotExtendPastProvenTip() public { + rollup.submitEpochRootProof(_getGasReportSubmission(8)); + SubmitEpochRootProofArgs memory args = _compactSubmission(_getGasReportSubmission(16), 9); + vm.expectRevert(abi.encodeWithSelector(Errors.Rollup__InvalidProvenCheckpointCount.selector, 8, 9)); + rollup.submitEpochRootProof(args); + } + + function testCompactPrefixCannotOmitUnaccountedCheckpoints() public { + rollup.submitEpochRootProof(_getGasReportSubmission(8)); + bytes32 epochRewardsSlot = keccak256(abi.encode(GAS_REPORT_EPOCH, uint256(keccak256("aztec.reward.storage")) + 1)); + uint256 rewards = uint256(vm.load(address(rollup), epochRewardsSlot)); + vm.store(address(rollup), epochRewardsSlot, bytes32((rewards & ~uint256(type(uint128).max)) | 4)); + SubmitEpochRootProofArgs memory args = _compactSubmission(_getGasReportSubmission(16), 8); + vm.expectRevert(abi.encodeWithSelector(Errors.Rollup__InvalidProvenCheckpointCount.selector, 4, 8)); + rollup.submitEpochRootProof(args); + } + + function testFuzzCompactPrefix(uint256 _proven, uint256 _prefix, uint256 _end) public { + uint256 proven = bound(_proven, 1, 31); + uint256 prefix = bound(_prefix, 0, proven); + uint256 end = bound(_end, proven + 1, 32); + rollup.submitEpochRootProof(_getGasReportSubmission(proven)); + SubmitEpochRootProofArgs memory args = _getGasReportSubmission(end); + _bindPublicInputs(args); + rollup.submitEpochRootProof(_compactSubmission(args, prefix)); + assertEq(rollup.getProvenCheckpointNumber(), end); + } + + function testCompactPrefixRejectsMissingHeader() public { + rollup.submitEpochRootProof(_getGasReportSubmission(8)); + SubmitEpochRootProofArgs memory args = _compactSubmission(_getGasReportSubmission(15), 8); + args.end = 16; + vm.expectRevert(abi.encodeWithSelector(Errors.Rollup__InvalidCheckpointHeaderCount.selector, 16, 15)); + rollup.submitEpochRootProof(args); + } + + function testCompactPrefixRejectsChangedNewHeader() public { + rollup.submitEpochRootProof(_getGasReportSubmission(8)); + SubmitEpochRootProofArgs memory args = _compactSubmission(_getGasReportSubmission(16), 8); + bytes32 expected = ProposedHeaderLib.hash(args.headers[0]); + args.headers[0].accumulatedFees++; + vm.expectRevert( + abi.encodeWithSelector( + Errors.Rollup__InvalidCheckpointHeader.selector, expected, ProposedHeaderLib.hash(args.headers[0]) + ) + ); + rollup.submitEpochRootProof(args); + } + + function testCompactPrefixBindsFeesToProof() public { + rollup.submitEpochRootProof(_getGasReportSubmission(8)); + SubmitEpochRootProofArgs memory args = _getGasReportSubmission(16); + _bindPublicInputs(args); + args = _compactSubmission(args, 8); + args.provenCheckpointFees[0].accumulatedFees++; + vm.expectRevert(Errors.Rollup__InvalidProof.selector); + rollup.submitEpochRootProof(args); + } + + function testCompactPrefixBindsCoinbaseToProof() public { + rollup.submitEpochRootProof(_getGasReportSubmission(8)); + SubmitEpochRootProofArgs memory args = _getGasReportSubmission(16); + _bindPublicInputs(args); + args = _compactSubmission(args, 8); + args.provenCheckpointFees[0].coinbase = address(0xdead); + vm.expectRevert(Errors.Rollup__InvalidProof.selector); + rollup.submitEpochRootProof(args); + } + + function testCompactPrefixAllowsProvenTipToAdvanceBeforeInclusion() public { + rollup.submitEpochRootProof(_getGasReportSubmission(8)); + SubmitEpochRootProofArgs memory args = _compactSubmission(_getGasReportSubmission(16), 8); + rollup.submitEpochRootProof(_getGasReportSubmission(12)); + rollup.submitEpochRootProof(args); + assertEq(rollup.getProvenCheckpointNumber(), 16); + } + + function testCompactRepeatedAndShorterProofs() public { + rollup.submitEpochRootProof(_getGasReportSubmission(16)); + SubmitEpochRootProofArgs memory repeated = _compactSubmission(_getGasReportSubmission(16), 16); + repeated.args.proverId = address(0xbeef); + rollup.submitEpochRootProof(repeated); + rollup.submitEpochRootProof(_compactSubmission(_getGasReportSubmission(8), 8)); + assertEq(rollup.getProvenCheckpointNumber(), 16); + } + + function testCompactCalldataSavings() public { + uint256[5] memory prefixes = [uint256(0), 1, 8, 16, 31]; + uint256[5] memory lengths = [uint256(1), 2, 16, 32, 32]; + for (uint256 i = 0; i < prefixes.length; i++) { + SubmitEpochRootProofArgs memory args = _getGasReportSubmission(lengths[i]); + bytes memory legacy = abi.encode( + LegacySubmission(args.start, args.end, args.args, args.headers, args.attestations, args.blobInputs, args.proof) + ); + bytes memory compact = abi.encode(_compactSubmission(args, prefixes[i])); + assertEq(int256(legacy.length) - int256(compact.length), int256(352 * prefixes[i]) - 64); + emit log_named_uint("Compact checkpoints", prefixes[i]); + emit log_named_uint("Checkpoints in proof", lengths[i]); + emit log_named_int("Calldata bytes saved", int256(legacy.length) - int256(compact.length)); + emit log_named_int("Calldata gas saved (4/16)", int256(_calldataGas(legacy)) - int256(_calldataGas(compact))); + } + } + + function _calldataGas(bytes memory _data) private pure returns (uint256 result) { + for (uint256 i = 0; i < _data.length; i++) { + result += _data[i] == 0 ? 4 : 16; + } + } +} diff --git a/l1-contracts/test/benchmark/happy.t.sol b/l1-contracts/test/benchmark/happy.t.sol index b56213727a9f..b270183aace8 100644 --- a/l1-contracts/test/benchmark/happy.t.sol +++ b/l1-contracts/test/benchmark/happy.t.sol @@ -2,6 +2,8 @@ // Copyright 2024 Aztec Labs. pragma solidity >=0.8.27; +import {ProvenCheckpointFees} from "@aztec/core/interfaces/IRollup.sol"; + import {DecoderBase} from "../base/DecoderBase.sol"; import {stdStorage, StdStorage} from "forge-std/StdStorage.sol"; @@ -553,6 +555,7 @@ abstract contract BenchmarkRollupBase is FeeModelTestPoints, DecoderBase { start: start, end: start + epochSize - 1, args: args, + provenCheckpointFees: new ProvenCheckpointFees[](0), headers: headers, attestations: checkpointAttestations[start + epochSize - 1], blobInputs: full.checkpoint.batchedBlobInputs, @@ -678,6 +681,7 @@ abstract contract PartialEpochProofGasReportBase is BenchmarkRollupBase { start: 1, end: _length, args: args, + provenCheckpointFees: new ProvenCheckpointFees[](0), headers: headers, attestations: checkpointAttestations[_length], blobInputs: full.checkpoint.batchedBlobInputs, @@ -688,6 +692,23 @@ abstract contract PartialEpochProofGasReportBase is BenchmarkRollupBase { function _gasReporter() internal view returns (PartialEpochProofGasReporter) { return PartialEpochProofGasReporter(address(rollup)); } + + function _compactSubmission(SubmitEpochRootProofArgs memory _args, uint256 _prefixLength) + internal + pure + returns (SubmitEpochRootProofArgs memory) + { + _args.provenCheckpointFees = new ProvenCheckpointFees[](_prefixLength); + ProposedHeader[] memory headers = new ProposedHeader[](_args.headers.length - _prefixLength); + for (uint256 i = 0; i < _prefixLength; i++) { + _args.provenCheckpointFees[i] = ProvenCheckpointFees(_args.headers[i].coinbase, _args.headers[i].accumulatedFees); + } + for (uint256 i = 0; i < headers.length; i++) { + headers[i] = _args.headers[_prefixLength + i]; + } + _args.headers = headers; + return _args; + } } contract PartialEpochProofGasReportTest is PartialEpochProofGasReportBase { @@ -755,6 +776,23 @@ contract PartialEpochProofWithTwoOverridesGasReportTest is PartialEpochProofGasR _gasReporter().gasReportSubmit32CheckpointsWithTwoOverrides(_getGasReportSubmission(32)); assertEq(rollup.getProvenCheckpointNumber(), 32); } + + function testCompactExtensionWithTwoOverridesPreservesRewards() public { + rollup.submitEpochRootProof(_getGasReportSubmission(8)); + uint256 snapshot = vm.snapshotState(); + rollup.submitEpochRootProof(_getGasReportSubmission(16)); + uint256 rewards = rollup.getCollectiveProverRewardsForEpoch(Epoch.wrap(GAS_REPORT_EPOCH)); + uint256[] memory sequencerRewards = new uint256[](16); + for (uint256 i = 0; i < 16; i++) { + sequencerRewards[i] = rollup.getSequencerRewards(checkpointHeaders[i + 1].coinbase); + } + vm.revertToState(snapshot); + rollup.submitEpochRootProof(_compactSubmission(_getGasReportSubmission(16), 8)); + assertEq(rollup.getCollectiveProverRewardsForEpoch(Epoch.wrap(GAS_REPORT_EPOCH)), rewards); + for (uint256 i = 0; i < 16; i++) { + assertEq(rollup.getSequencerRewards(checkpointHeaders[i + 1].coinbase), sequencerRewards[i]); + } + } } contract PartialEpochProofExtensionGasReportTest is PartialEpochProofGasReportBase { @@ -765,7 +803,7 @@ contract PartialEpochProofExtensionGasReportTest is PartialEpochProofGasReportBa } function testGasReportSubmit8MoreCheckpoints() public { - _gasReporter().gasReportSubmit8MoreCheckpoints(_getGasReportSubmission(16)); + _gasReporter().gasReportSubmit8MoreCheckpoints(_compactSubmission(_getGasReportSubmission(16), 8)); assertEq(rollup.getProvenCheckpointNumber(), 16); } } diff --git a/l1-contracts/test/compression/PreHeating.t.sol b/l1-contracts/test/compression/PreHeating.t.sol index 2367427c4bdf..612b8c165267 100644 --- a/l1-contracts/test/compression/PreHeating.t.sol +++ b/l1-contracts/test/compression/PreHeating.t.sol @@ -2,6 +2,8 @@ // Copyright 2024 Aztec Labs. pragma solidity >=0.8.27; +import {ProvenCheckpointFees} from "@aztec/core/interfaces/IRollup.sol"; + import {DecoderBase} from "../base/DecoderBase.sol"; import {stdStorage, StdStorage} from "forge-std/StdStorage.sol"; @@ -274,6 +276,7 @@ contract PreHeatingTest is FeeModelTestPoints, DecoderBase { start: start, end: start + epochSize - 1, args: args, + provenCheckpointFees: new ProvenCheckpointFees[](0), headers: headers, attestations: checkpointAttestations[start + epochSize - 1], blobInputs: full.checkpoint.batchedBlobInputs, diff --git a/l1-contracts/test/escape-hatch/integration/EscapeHatchIntegrationBase.sol b/l1-contracts/test/escape-hatch/integration/EscapeHatchIntegrationBase.sol index ea22ac757e75..07dc93aab1e5 100644 --- a/l1-contracts/test/escape-hatch/integration/EscapeHatchIntegrationBase.sol +++ b/l1-contracts/test/escape-hatch/integration/EscapeHatchIntegrationBase.sol @@ -2,6 +2,8 @@ // Copyright 2025 Aztec Labs. pragma solidity >=0.8.27; +import {ProvenCheckpointFees} from "@aztec/core/interfaces/IRollup.sol"; + import {ValidatorSelectionTestBase} from "@test/validator-selection/ValidatorSelectionBase.sol"; import {DecoderBase} from "@test/base/DecoderBase.sol"; import {IEscapeHatchCore, Status, CandidateInfo, Hatch} from "@aztec/core/interfaces/IEscapeHatch.sol"; @@ -351,6 +353,7 @@ abstract contract EscapeHatchIntegrationBase is ValidatorSelectionTestBase { start: _start, end: _end, args: args, + provenCheckpointFees: new ProvenCheckpointFees[](0), headers: headers, attestations: CommitteeAttestations({signatureIndices: "", signaturesOrAddresses: ""}), blobInputs: endFull.checkpoint.batchedBlobInputs, diff --git a/l1-contracts/test/escape-hatch/integration/regression/OutHashValidationSkipped.t.sol b/l1-contracts/test/escape-hatch/integration/regression/OutHashValidationSkipped.t.sol index 5baa9903924d..db6df14dd621 100644 --- a/l1-contracts/test/escape-hatch/integration/regression/OutHashValidationSkipped.t.sol +++ b/l1-contracts/test/escape-hatch/integration/regression/OutHashValidationSkipped.t.sol @@ -2,6 +2,8 @@ // Copyright 2025 Aztec Labs. pragma solidity >=0.8.27; +import {ProvenCheckpointFees} from "@aztec/core/interfaces/IRollup.sol"; + import {EscapeHatchIntegrationBase} from "../EscapeHatchIntegrationBase.sol"; import {Errors} from "@aztec/core/libraries/Errors.sol"; import {Epoch} from "@aztec/shared/libraries/TimeMath.sol"; @@ -74,6 +76,7 @@ contract OutHashValidationSkippedTest is EscapeHatchIntegrationBase { start: 1, end: 1, args: args, + provenCheckpointFees: new ProvenCheckpointFees[](0), headers: headers, attestations: CommitteeAttestations({signatureIndices: "", signaturesOrAddresses: ""}), blobInputs: full.checkpoint.batchedBlobInputs, diff --git a/l1-contracts/test/escape-hatch/integration/submitEpochRootProof.t.sol b/l1-contracts/test/escape-hatch/integration/submitEpochRootProof.t.sol index 6e46a60fad48..4866a0d84f5d 100644 --- a/l1-contracts/test/escape-hatch/integration/submitEpochRootProof.t.sol +++ b/l1-contracts/test/escape-hatch/integration/submitEpochRootProof.t.sol @@ -2,6 +2,8 @@ // Copyright 2025 Aztec Labs. pragma solidity >=0.8.27; +import {ProvenCheckpointFees} from "@aztec/core/interfaces/IRollup.sol"; + import {EscapeHatchIntegrationBase} from "./EscapeHatchIntegrationBase.sol"; import {IEscapeHatchCore, Status, CandidateInfo, Hatch} from "@aztec/core/interfaces/IEscapeHatch.sol"; import {Errors} from "@aztec/core/libraries/Errors.sol"; @@ -128,6 +130,7 @@ contract submitEpochRootProofTest is EscapeHatchIntegrationBase { start: 1, end: 1, args: args, + provenCheckpointFees: new ProvenCheckpointFees[](0), headers: headers, attestations: AttestationLibHelper.packAttestations(_attestations), blobInputs: full.checkpoint.batchedBlobInputs, diff --git a/l1-contracts/test/fees/FeeRollup.t.sol b/l1-contracts/test/fees/FeeRollup.t.sol index 5370189d34c9..002b90b64800 100644 --- a/l1-contracts/test/fees/FeeRollup.t.sol +++ b/l1-contracts/test/fees/FeeRollup.t.sol @@ -2,6 +2,8 @@ // Copyright 2024 Aztec Labs. pragma solidity >=0.8.27; +import {ProvenCheckpointFees} from "@aztec/core/interfaces/IRollup.sol"; + import {DecoderBase} from "../base/DecoderBase.sol"; import {stdStorage, StdStorage} from "forge-std/StdStorage.sol"; @@ -251,6 +253,7 @@ contract FeeRollupTest is FeeModelTestPoints, DecoderBase { start: _start, end: _start + _epochSize - 1, args: args, + provenCheckpointFees: new ProvenCheckpointFees[](0), headers: headers, attestations: CommitteeAttestations({signatureIndices: "", signaturesOrAddresses: ""}), blobInputs: full.checkpoint.batchedBlobInputs, diff --git a/l1-contracts/test/validator-selection/ValidatorSelection.t.sol b/l1-contracts/test/validator-selection/ValidatorSelection.t.sol index a968be6d803f..f170d31223f9 100644 --- a/l1-contracts/test/validator-selection/ValidatorSelection.t.sol +++ b/l1-contracts/test/validator-selection/ValidatorSelection.t.sol @@ -3,6 +3,8 @@ // solhint-disable imports-order pragma solidity >=0.8.27; +import {ProvenCheckpointFees} from "@aztec/core/interfaces/IRollup.sol"; + import {Strings} from "@oz/utils/Strings.sol"; import {Constants} from "@aztec/core/libraries/ConstantsGen.sol"; import { @@ -771,6 +773,7 @@ contract ValidatorSelectionTest is ValidatorSelectionTestBase { start: startCheckpointNumber, end: endCheckpointNumber, args: args, + provenCheckpointFees: new ProvenCheckpointFees[](0), headers: headers, attestations: _attestations, blobInputs: endFull.checkpoint.batchedBlobInputs, diff --git a/l1-contracts/test/validator-selection/tmnt207.t.sol b/l1-contracts/test/validator-selection/tmnt207.t.sol index b919447c79c4..ac38e6b55ef4 100644 --- a/l1-contracts/test/validator-selection/tmnt207.t.sol +++ b/l1-contracts/test/validator-selection/tmnt207.t.sol @@ -2,6 +2,8 @@ // Copyright 2024 Aztec Labs. pragma solidity >=0.8.27; +import {ProvenCheckpointFees} from "@aztec/core/interfaces/IRollup.sol"; + import {DecoderBase} from "../base/DecoderBase.sol"; import {Registry} from "@aztec/governance/Registry.sol"; @@ -235,6 +237,7 @@ contract Tmnt207Test is RollupBase { endInboxRollingHash: 0, proverId: address(0) }), + provenCheckpointFees: new ProvenCheckpointFees[](0), headers: headers, attestations: AttestationLibHelper.packAttestations(l2CheckpointReal.attestations), blobInputs: full.checkpoint.batchedBlobInputs, diff --git a/labs-patches/0002-fix-link-epoch-proof-library-when-deploying-rollup.patch b/labs-patches/0002-fix-link-epoch-proof-library-when-deploying-rollup.patch new file mode 100644 index 000000000000..6ca4c5618d04 --- /dev/null +++ b/labs-patches/0002-fix-link-epoch-proof-library-when-deploying-rollup.patch @@ -0,0 +1,51 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Alex Gherghisan +Date: Mon, 7 Sep 2026 09:54:14 +0000 +Subject: [PATCH] fix: link epoch proof library when deploying rollup + +Register EpochProofExtLib with the Rollup deployment artifacts and verify that every link reference has deployable bytecode. Requires regenerated foundation L1 artifacts exporting the epoch proof library. + +diff --git a/yarn-project/ethereum/src/l1_artifacts.test.ts b/yarn-project/ethereum/src/l1_artifacts.test.ts +new file mode 100644 +index 0000000000000000000000000000000000000000..570d2852ce95b796c9614638303dc6708e8a0dd7 +--- /dev/null ++++ b/yarn-project/ethereum/src/l1_artifacts.test.ts +@@ -0,0 +1,13 @@ ++import { RollupArtifact } from './l1_artifacts.js'; ++ ++describe('Rollup deployment artifacts', () => { ++ it('supplies deployable bytecode for every linked library', () => { ++ const libraries: Record = RollupArtifact.libraries.libraryCode; ++ for (const references of Object.values(RollupArtifact.libraries.linkReferences)) { ++ for (const name of Object.keys(references)) { ++ expect(libraries[name]).toBeDefined(); ++ expect(libraries[name]?.contractBytecode).toMatch(/^0x[0-9a-f]+$/i); ++ } ++ } ++ }); ++}); +diff --git a/yarn-project/ethereum/src/l1_artifacts.ts b/yarn-project/ethereum/src/l1_artifacts.ts +index d404aac730012d52c0c095fdddbf6a816b8ec705..2e6979daa1c516ddb8741772f705985674bf0f4c 100644 +--- a/yarn-project/ethereum/src/l1_artifacts.ts ++++ b/yarn-project/ethereum/src/l1_artifacts.ts +@@ -3,6 +3,8 @@ import { + CoinIssuerBytecode, + DateGatedRelayerAbi, + DateGatedRelayerBytecode, ++ EpochProofExtLibAbi, ++ EpochProofExtLibBytecode, + FeeAssetHandlerAbi, + FeeAssetHandlerBytecode, + FeeJuicePortalAbi, +@@ -91,6 +93,11 @@ export const RollupArtifact = { + contractAbi: RollupOperationsExtLibAbi, + contractBytecode: RollupOperationsExtLibBytecode as Hex, + }, ++ EpochProofExtLib: { ++ name: 'EpochProofExtLib', ++ contractAbi: EpochProofExtLibAbi, ++ contractBytecode: EpochProofExtLibBytecode as Hex, ++ }, + ValidatorOperationsExtLib: { + name: 'ValidatorOperationsExtLib', + contractAbi: ValidatorOperationsExtLibAbi, diff --git a/labs-patches/0003-feat-submit-compact-fees-for-proven-checkpoints.patch b/labs-patches/0003-feat-submit-compact-fees-for-proven-checkpoints.patch new file mode 100644 index 000000000000..eaefe1e98d4f --- /dev/null +++ b/labs-patches/0003-feat-submit-compact-fees-for-proven-checkpoints.patch @@ -0,0 +1,255 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Alex Gherghisan +Date: Mon, 7 Sep 2026 09:55:13 +0000 +Subject: [PATCH] feat: submit compact fees for proven checkpoints + +Use the proven tip observed during validation to send only coinbase and accumulated fees for the proven prefix. Keep full headers for the suffix and for public-input validation. Apply the same encoding to gas estimation and test fresh, partial, and fully proven prefixes. + +diff --git a/yarn-project/prover-node/src/prover-node-publisher.test.ts b/yarn-project/prover-node/src/prover-node-publisher.test.ts +index 390a9d84f0082ae241c9a38dc2b37b75f98579b8..8d78e336101d82bfe1ad2ccc3c5dd9339c01c1cb 100644 +--- a/yarn-project/prover-node/src/prover-node-publisher.test.ts ++++ b/yarn-project/prover-node/src/prover-node-publisher.test.ts +@@ -1,3 +1,5 @@ ++import { RollupAbi } from '@aztec-foundation/l1-artifacts'; ++ + import { BatchedBlob } from '@aztec-labs/blob-lib/types'; + import type { RollupContract } from '@aztec-labs/ethereum/contracts'; + import { randomL1ContractAddresses } from '@aztec-labs/ethereum/l1-contract-addresses'; +@@ -13,6 +15,7 @@ import { Proof } from '@aztec-labs/stdlib/proofs'; + import { CheckpointHeader, RootRollupPublicInputs } from '@aztec-labs/stdlib/rollup'; + import { jest } from '@jest/globals'; + import { type MockProxy, mock } from 'jest-mock-extended'; ++import { decodeFunctionData, getAddress } from 'viem'; + + import { ProverNodePublisher } from './prover-node-publisher.js'; + +@@ -197,6 +200,30 @@ describe('prover-node-publisher', () => { + }, + ); + ++ describe('compact checkpoint headers', () => { ++ it.each([ ++ { proven: 32, end: 48, prefixLength: 0 }, ++ { proven: 40, end: 48, prefixLength: 8 }, ++ { proven: 48, end: 48, prefixLength: 16 }, ++ ])('encodes $prefixLength compact entries when proven is $proven', async ({ proven, end, prefixLength }) => { ++ const args = setupPublishData(64, proven, 33, end); ++ await publisher.submitEpochProof(args); ++ const [{ data }] = l1Utils.sendAndMonitorTransaction.mock.calls[0]; ++ const decoded = decodeFunctionData({ abi: RollupAbi, data: data! }); ++ if (decoded.functionName !== 'submitEpochRootProof') { ++ throw new Error(`Unexpected function ${decoded.functionName}`); ++ } ++ const [submission] = decoded.args; ++ const fullHeaders = args.headers.map(header => header.toViem()); ++ const headers = fullHeaders.map(header => ({ ...header, coinbase: getAddress(header.coinbase) })); ++ expect(submission.provenCheckpointFees).toEqual( ++ headers.slice(0, prefixLength).map(({ coinbase, accumulatedFees }) => ({ coinbase, accumulatedFees })), ++ ); ++ expect(submission.headers).toEqual(headers.slice(prefixLength)); ++ expect(rollup.getEpochProofPublicInputs.mock.calls[0][0][3]).toEqual(fullHeaders); ++ }); ++ }); ++ + describe('proof submission target', () => { + it('defaults the submit tx target to the rollup address', async () => { + const rollupAddress = EthAddress.random().toString(); +@@ -227,11 +254,11 @@ describe('prover-node-publisher', () => { + }); + }); + +- it('analyzeEpochProofSubmission validates, estimates, and does not send tx', async () => { ++ it.each([32, 40, 64])('estimates compact calldata without sending when proven is %i', async proven => { + const fromCheckpoint = 33; + const toCheckpoint = 64; + +- rollup.getTips.mockResolvedValue({ pending: CheckpointNumber(65), proven: CheckpointNumber(32) }); ++ rollup.getTips.mockResolvedValue({ pending: CheckpointNumber(65), proven: CheckpointNumber(proven) }); + + const checkpoints = Array.from({ length: 100 }, () => RootRollupPublicInputs.random()); + rollup.getCheckpoint.mockImplementation((n: CheckpointNumber) => +@@ -271,18 +298,33 @@ describe('prover-node-publisher', () => { + ourPublicInputs.blobPublicInputs.c.negate(), + ); + ++ const headers = makeHeadersForRange(fromCheckpoint, toCheckpoint); + await publisher.analyzeEpochProofSubmission({ + epochNumber: EpochNumber(2), + fromCheckpoint: CheckpointNumber(fromCheckpoint), + toCheckpoint: CheckpointNumber(toCheckpoint), + publicInputs: ourPublicInputs, +- headers: makeHeadersForRange(fromCheckpoint, toCheckpoint), ++ headers, + proof: Proof.empty(), + batchedBlobInputs: batchedBlob, + attestations: [], + }); + +- expect(l1Utils.estimateGas).toHaveBeenCalled(); ++ const [, { data }] = l1Utils.estimateGas.mock.calls[0]; ++ const decoded = decodeFunctionData({ abi: RollupAbi, data: data! }); ++ if (decoded.functionName !== 'submitEpochRootProof') { ++ throw new Error(`Unexpected function ${decoded.functionName}`); ++ } ++ const [submission] = decoded.args; ++ const prefixLength = proven - fromCheckpoint + 1; ++ const expectedHeaders = headers.map(header => { ++ const viem = header.toViem(); ++ return { ...viem, coinbase: getAddress(viem.coinbase) }; ++ }); ++ expect(submission.provenCheckpointFees).toEqual( ++ expectedHeaders.slice(0, prefixLength).map(({ coinbase, accumulatedFees }) => ({ coinbase, accumulatedFees })), ++ ); ++ expect(submission.headers).toEqual(expectedHeaders.slice(prefixLength)); + expect(l1Utils.getFeesPerGas).toHaveBeenCalled(); + expect(l1Utils.sendAndMonitorTransaction).not.toHaveBeenCalled(); + }); +diff --git a/yarn-project/prover-node/src/prover-node-publisher.ts b/yarn-project/prover-node/src/prover-node-publisher.ts +index 3b66d55bcfff92c4d79498c691e76d001d2be749..086ab3340b18fb88489444723153c6a5f8846dec 100644 +--- a/yarn-project/prover-node/src/prover-node-publisher.ts ++++ b/yarn-project/prover-node/src/prover-node-publisher.ts +@@ -89,9 +89,9 @@ export class ProverNodePublisher { + + const timer = new Timer(); + // Validate epoch proof range and hashes are correct before submitting +- await this.validateEpochProofSubmission(args); ++ const provenPrefixLength = await this.validateEpochProofSubmission(args); + +- const txReceipt = await this.sendSubmitEpochProofTx(args); ++ const txReceipt = await this.sendSubmitEpochProofTx(args, provenPrefixLength); + if (!txReceipt) { + this.log.error(`Failed to mine submitEpochProof tx`, undefined, ctx); + return false; +@@ -138,7 +138,7 @@ export class ProverNodePublisher { + batchedBlobInputs: BatchedBlob; + attestations: ViemCommitteeAttestation[]; + headers: CheckpointHeader[]; +- }) { ++ }): Promise { + const { fromCheckpoint, toCheckpoint, publicInputs, batchedBlobInputs } = args; + + // Check that the checkpoint numbers match the expected epoch to be proven +@@ -196,6 +196,10 @@ export class ProverNodePublisher { + log: this.log, + }); + } ++ ++ // The production rollup advances the proven tip and accounts for rewards atomically. A later proof may ++ // advance it further before inclusion; the contract accepts any already-proven prefix, including a shorter one. ++ return Math.max(0, proven - fromCheckpoint + 1); + } + + /** +@@ -215,9 +219,9 @@ export class ProverNodePublisher { + }): Promise { + const { epochNumber, fromCheckpoint, toCheckpoint } = args; + +- await this.validateEpochProofSubmission(args); ++ const provenPrefixLength = await this.validateEpochProofSubmission(args); + +- const data = this.encodeSubmitEpochProofCalldata(args); ++ const data = this.encodeSubmitEpochProofCalldata(args, provenPrefixLength); + const senderAddress = this.l1TxUtils.getSenderAddress(); + + const [gasLimit, feesPerGas, latestBlock] = await Promise.all([ +@@ -252,33 +256,39 @@ export class ProverNodePublisher { + this.metrics.recordEstimatedSubmitProof(stats); + } + +- private encodeSubmitEpochProofCalldata(args: { +- fromCheckpoint: CheckpointNumber; +- toCheckpoint: CheckpointNumber; +- publicInputs: RootRollupPublicInputs; +- proof: Proof; +- batchedBlobInputs: BatchedBlob; +- attestations: ViemCommitteeAttestation[]; +- headers: CheckpointHeader[]; +- }): Hex { ++ private encodeSubmitEpochProofCalldata( ++ args: { ++ fromCheckpoint: CheckpointNumber; ++ toCheckpoint: CheckpointNumber; ++ publicInputs: RootRollupPublicInputs; ++ proof: Proof; ++ batchedBlobInputs: BatchedBlob; ++ attestations: ViemCommitteeAttestation[]; ++ headers: CheckpointHeader[]; ++ }, ++ provenPrefixLength: number, ++ ): Hex { + return encodeFunctionData({ + abi: RollupAbi, + functionName: 'submitEpochRootProof', +- args: [this.getSubmitEpochProofArgs(args)], ++ args: [this.getSubmitEpochProofArgs(args, provenPrefixLength)], + }); + } + +- private async sendSubmitEpochProofTx(args: { +- fromCheckpoint: CheckpointNumber; +- toCheckpoint: CheckpointNumber; +- deadline?: Date; +- publicInputs: RootRollupPublicInputs; +- proof: Proof; +- batchedBlobInputs: BatchedBlob; +- attestations: ViemCommitteeAttestation[]; +- headers: CheckpointHeader[]; +- }): Promise { +- const txArgs = [this.getSubmitEpochProofArgs(args)] as const; ++ private async sendSubmitEpochProofTx( ++ args: { ++ fromCheckpoint: CheckpointNumber; ++ toCheckpoint: CheckpointNumber; ++ deadline?: Date; ++ publicInputs: RootRollupPublicInputs; ++ proof: Proof; ++ batchedBlobInputs: BatchedBlob; ++ attestations: ViemCommitteeAttestation[]; ++ headers: CheckpointHeader[]; ++ }, ++ provenPrefixLength: number, ++ ): Promise { ++ const txArgs = [this.getSubmitEpochProofArgs(args, provenPrefixLength)] as const; + + this.log.info(`Submitting epoch proof to L1 rollup contract`, { + proofSize: args.proof.withoutPublicInputs().length, +@@ -342,15 +352,18 @@ export class ProverNodePublisher { + ] as const; + } + +- private getSubmitEpochProofArgs(args: { +- fromCheckpoint: CheckpointNumber; +- toCheckpoint: CheckpointNumber; +- publicInputs: RootRollupPublicInputs; +- proof: Proof; +- batchedBlobInputs: BatchedBlob; +- attestations: ViemCommitteeAttestation[]; +- headers: CheckpointHeader[]; +- }) { ++ private getSubmitEpochProofArgs( ++ args: { ++ fromCheckpoint: CheckpointNumber; ++ toCheckpoint: CheckpointNumber; ++ publicInputs: RootRollupPublicInputs; ++ proof: Proof; ++ batchedBlobInputs: BatchedBlob; ++ attestations: ViemCommitteeAttestation[]; ++ headers: CheckpointHeader[]; ++ }, ++ provenPrefixLength: number, ++ ) { + // Returns arguments for EpochProofLib.sol -> submitEpochRootProof() + const proofHex: Hex = `0x${args.proof.withoutPublicInputs().toString('hex')}`; + const argsArray = this.getEpochProofPublicInputsArgs(args); +@@ -358,7 +371,10 @@ export class ProverNodePublisher { + start: argsArray[0], + end: argsArray[1], + args: argsArray[2], +- headers: argsArray[3], ++ provenCheckpointFees: argsArray[3] ++ .slice(0, provenPrefixLength) ++ .map(({ coinbase, accumulatedFees }) => ({ coinbase, accumulatedFees })), ++ headers: argsArray[3].slice(provenPrefixLength), + attestations: CommitteeAttestationsAndSigners.packAttestations( + args.attestations.map(a => CommitteeAttestation.fromViem(a)), + ), From 6d5d8ee78a0b4be03e8d2b24395d07e42354b737 Mon Sep 17 00:00:00 2001 From: Santiago Palladino Date: Wed, 9 Sep 2026 10:52:25 -0300 Subject: [PATCH 15/19] fix: resolve ATP registry through the staker for reward overrides (#25426) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Registry reward overrides never applied to ATP-backed validators, because the lookup probed the wrong contract. ## Context ATP stakers (the `ATPWithdrawableAndClaimableStaker` family in ignition-contracts) register themselves as the GSE withdrawer when they deposit, both on the direct path and through the `StakingRegistry` provider path. The staker only exposes `getATP()`; `getRegistry()` lives on the ATP. `RewardLib` called `getRegistry()` on the withdrawer directly, so on the deployed stakers the probe reverted and every ATP-backed proposer silently fell back to the default sequencer reward. ## Approach - `RewardLib.tryGetRegistry` now resolves `withdrawer.getATP()` and then `atp.getRegistry()`, through a shared defensive probe (`tryGetAddress`) that keeps the fixed gas cap, exact 32-byte return and clean-address checks per hop. A withdrawer that answers `getRegistry()` itself no longer matches, since no deployed staker does. - Unit tests and the partial-epoch-proof gas benchmark now model the real shape (staker → ATP → registry) with shared mocks in `test/mock/ATPMocks.sol`. The two-hop lookup adds ~3.2k gas for one checkpoint and ~23k for a full 32-checkpoint epoch with two overrides. - New `test/fork/MainnetATPRewardOverride.t.sol` checks the lookup against real mainnet ATP stakers: v1 and v2 staker implementations, the auction and genesis-sale ATP registries, and both the direct and the `StakingRegistry` provider staking paths. It asserts the attester is validating on the canonical rollup, that the GSE withdrawer is the staker, that the staker does not answer `getRegistry()`, that the two-hop lookup resolves the registry, and that `handleRewardsAndFees` applies the override. Against the pre-fix code the last two assertions fail (default 50e18 paid instead of the 10e18 override). - The fork test runs offline in CI. `setUp` loads a state snapshot (`test/fixtures/mainnet_atp_reward_override.json`) produced by `vm.dumpState` from a mainnet fork at block 25934884; the dump only contains the accounts and slots the test touches (13 accounts, ~190KB). Set `MAINNET_ATP_FIXTURE_RPC_URL` to a mainnet RPC to refresh the snapshot; regeneration is deterministic. - Fixes the solhint `imports-order` errors in `RewardLib.sol` that were failing CI on the stack. --- l1-contracts/foundry.toml | 1 + .../partial_epoch_proof_gas_report.json | 32 ++-- .../partial_epoch_proof_gas_report.md | 8 +- .../src/core/libraries/rollup/RewardLib.sol | 57 +++++- l1-contracts/test/benchmark/happy.t.sol | 35 ++-- .../fixtures/mainnet_atp_reward_override.json | 1 + .../test/fork/MainnetATPRewardOverride.t.sol | 175 ++++++++++++++++++ l1-contracts/test/mock/ATPMocks.sol | 44 +++++ .../libraries/rewardlib/registryReward.t.sol | 62 ++++--- .../libraries/rewardlib/tryGetRegistry.t.sol | 140 +++++++++----- 10 files changed, 431 insertions(+), 124 deletions(-) create mode 100644 l1-contracts/test/fixtures/mainnet_atp_reward_override.json create mode 100644 l1-contracts/test/fork/MainnetATPRewardOverride.t.sol create mode 100644 l1-contracts/test/mock/ATPMocks.sol diff --git a/l1-contracts/foundry.toml b/l1-contracts/foundry.toml index 66413819bfa5..26d287f746fa 100644 --- a/l1-contracts/foundry.toml +++ b/l1-contracts/foundry.toml @@ -47,6 +47,7 @@ remappings = [ # See more config options https://github.com/foundry-rs/foundry/tree/master/config fs_permissions = [ + { access = "read-write", path = "./test/fixtures/mainnet_atp_reward_override.json" }, { access = "read", path = "./test/fixtures/bn254_constants.json" }, { access = "read", path = "./test/fixtures/mixed_checkpoint_1.json" }, { access = "read", path = "./test/fixtures/mixed_checkpoint_2.json" }, diff --git a/l1-contracts/partial_epoch_proof_gas_report.json b/l1-contracts/partial_epoch_proof_gas_report.json index 97e65f67fbda..80164e2b147d 100644 --- a/l1-contracts/partial_epoch_proof_gas_report.json +++ b/l1-contracts/partial_epoch_proof_gas_report.json @@ -15,10 +15,10 @@ }, "gasReportSubmit16CheckpointsWithTwoOverrides((uint256,uint256,(bytes32,bytes32,bytes32,bytes32,bytes32,address),(address,uint256)[],(bytes32,bytes32,bytes32,bytes32,bytes32,uint256,uint256,address,bytes32,(uint128,uint128),uint256,uint256)[],(bytes,bytes),bytes,bytes))": { "calls": 1, - "min": 1421159, - "mean": 1421159, - "median": 1421159, - "max": 1421159 + "min": 1437655, + "mean": 1437655, + "median": 1437655, + "max": 1437655 }, "gasReportSubmit1Checkpoint((uint256,uint256,(bytes32,bytes32,bytes32,bytes32,bytes32,address),(address,uint256)[],(bytes32,bytes32,bytes32,bytes32,bytes32,uint256,uint256,address,bytes32,(uint128,uint128),uint256,uint256)[],(bytes,bytes),bytes,bytes))": { "calls": 1, @@ -29,10 +29,10 @@ }, "gasReportSubmit1CheckpointWithTwoOverrides((uint256,uint256,(bytes32,bytes32,bytes32,bytes32,bytes32,address),(address,uint256)[],(bytes32,bytes32,bytes32,bytes32,bytes32,uint256,uint256,address,bytes32,(uint128,uint128),uint256,uint256)[],(bytes,bytes),bytes,bytes))": { "calls": 1, - "min": 685559, - "mean": 685559, - "median": 685559, - "max": 685559 + "min": 688835, + "mean": 688835, + "median": 688835, + "max": 688835 }, "gasReportSubmit32Checkpoints((uint256,uint256,(bytes32,bytes32,bytes32,bytes32,bytes32,address),(address,uint256)[],(bytes32,bytes32,bytes32,bytes32,bytes32,uint256,uint256,address,bytes32,(uint128,uint128),uint256,uint256)[],(bytes,bytes),bytes,bytes))": { "calls": 1, @@ -43,10 +43,10 @@ }, "gasReportSubmit32CheckpointsWithTwoOverrides((uint256,uint256,(bytes32,bytes32,bytes32,bytes32,bytes32,address),(address,uint256)[],(bytes32,bytes32,bytes32,bytes32,bytes32,uint256,uint256,address,bytes32,(uint128,uint128),uint256,uint256)[],(bytes,bytes),bytes,bytes))": { "calls": 1, - "min": 2007827, - "mean": 2007827, - "median": 2007827, - "max": 2007827 + "min": 2031127, + "mean": 2031127, + "median": 2031127, + "max": 2031127 }, "gasReportSubmit8Checkpoints((uint256,uint256,(bytes32,bytes32,bytes32,bytes32,bytes32,address),(address,uint256)[],(bytes32,bytes32,bytes32,bytes32,bytes32,uint256,uint256,address,bytes32,(uint128,uint128),uint256,uint256)[],(bytes,bytes),bytes,bytes))": { "calls": 1, @@ -57,10 +57,10 @@ }, "gasReportSubmit8CheckpointsWithTwoOverrides((uint256,uint256,(bytes32,bytes32,bytes32,bytes32,bytes32,address),(address,uint256)[],(bytes32,bytes32,bytes32,bytes32,bytes32,uint256,uint256,address,bytes32,(uint128,uint128),uint256,uint256)[],(bytes,bytes),bytes,bytes))": { "calls": 1, - "min": 1060278, - "mean": 1060278, - "median": 1060278, - "max": 1060278 + "min": 1071402, + "mean": 1071402, + "median": 1071402, + "max": 1071402 }, "gasReportSubmit8MoreCheckpoints((uint256,uint256,(bytes32,bytes32,bytes32,bytes32,bytes32,address),(address,uint256)[],(bytes32,bytes32,bytes32,bytes32,bytes32,uint256,uint256,address,bytes32,(uint128,uint128),uint256,uint256)[],(bytes,bytes),bytes,bytes))": { "calls": 1, diff --git a/l1-contracts/partial_epoch_proof_gas_report.md b/l1-contracts/partial_epoch_proof_gas_report.md index f7e3395741cf..00d2a4dee4c2 100644 --- a/l1-contracts/partial_epoch_proof_gas_report.md +++ b/l1-contracts/partial_epoch_proof_gas_report.md @@ -3,13 +3,13 @@ | Proof submission | Gas | |---|---:| | 1 Checkpoint | 658,412 | -| 1 Checkpoint With Two Overrides | 685,559 | +| 1 Checkpoint With Two Overrides | 688,835 | | 8 Checkpoints | 963,262 | -| 8 Checkpoints With Two Overrides | 1,060,278 | +| 8 Checkpoints With Two Overrides | 1,071,402 | | 8 More Checkpoints | 916,794 | | 16 Checkpoints | 1,255,881 | -| 16 Checkpoints With Two Overrides | 1,421,159 | +| 16 Checkpoints With Two Overrides | 1,437,655 | | 32 Checkpoints | 1,748,763 | -| 32 Checkpoints With Two Overrides | 2,007,827 | +| 32 Checkpoints With Two Overrides | 2,031,127 | _Uses the mock epoch proof verifier._ diff --git a/l1-contracts/src/core/libraries/rollup/RewardLib.sol b/l1-contracts/src/core/libraries/rollup/RewardLib.sol index f743c0bfaff9..04f1c3250835 100644 --- a/l1-contracts/src/core/libraries/rollup/RewardLib.sol +++ b/l1-contracts/src/core/libraries/rollup/RewardLib.sol @@ -11,8 +11,8 @@ import {STFLib} from "@aztec/core/libraries/rollup/STFLib.sol"; import {ValidatorSelectionLib} from "@aztec/core/libraries/rollup/ValidatorSelectionLib.sol"; import {Epoch, Timestamp, TimeLib} from "@aztec/core/libraries/TimeLib.sol"; import {IBoosterCore} from "@aztec/core/reward-boost/RewardBooster.sol"; -import {IRewardDistributor} from "@aztec/governance/interfaces/IRewardDistributor.sol"; import {GSE} from "@aztec/governance/GSE.sol"; +import {IRewardDistributor} from "@aztec/governance/interfaces/IRewardDistributor.sol"; import {IERC20} from "@oz/token/ERC20/IERC20.sol"; import {SafeERC20} from "@oz/token/ERC20/utils/SafeERC20.sol"; import {Math} from "@oz/utils/math/Math.sol"; @@ -21,7 +21,19 @@ import {BitMaps} from "@oz/utils/structs/BitMaps.sol"; type Bps is uint32; -interface IRegistryProvider { +/** + * @notice The subset of an Aztec Token Position (ATP) staker contract that the reward computation relies on. + * @dev ATP stakers register themselves as the GSE withdrawer when they deposit, so the withdrawer of an ATP-backed + * validator is the staker, not the ATP. The staker only exposes the ATP it belongs to. + */ +interface IATPStaker { + function getATP() external view returns (address); +} + +/** + * @notice The subset of an Aztec Token Position (ATP) contract that the reward computation relies on. + */ +interface IATP { function getRegistry() external view returns (address); } @@ -371,21 +383,48 @@ library RewardLib { return (se.shares[_prover] * er.rewards / se.summedShares); } + /** + * @notice Resolves the ATP registry that an attester's withdrawer belongs to. + * @dev ATP-backed validators register their staker contract as the GSE withdrawer. The staker exposes the ATP it + * belongs to, and the ATP exposes the registry it was created from, so the lookup is + * `withdrawer.getATP()` followed by `atp.getRegistry()`. Both hops are probed defensively so that arbitrary + * withdrawer contracts cannot make the reward computation revert or burn unbounded gas. + * @param _withdrawer The withdrawer registered in the GSE for the attester. + * @return responded Whether both hops returned a well-formed address. + * @return registry The registry the withdrawer's ATP belongs to, or zero when the lookup did not resolve. + */ function tryGetRegistry(address _withdrawer) internal view returns (bool responded, address registry) { - if (_withdrawer.code.length == 0) { + (bool atpResponded, address atp) = tryGetAddress(_withdrawer, IATPStaker.getATP.selector); + if (!atpResponded || atp == address(0)) { + return (false, address(0)); + } + return tryGetAddress(atp, IATP.getRegistry.selector); + } + + /** + * @notice Probes `_target` with a zero-argument view call that is expected to return a single address. + * @dev Runs with a fixed gas cap and requires exactly 32 bytes of return data holding a clean address, so a + * misbehaving target can only make the probe fail, never revert the caller or consume unbounded gas. + * @param _target The contract to probe. Accounts without code are treated as not responding. + * @param _selector The selector of the zero-argument getter to call. + * @return responded Whether the call succeeded and returned a well-formed address. + * @return result The returned address, or zero when the probe failed. + */ + function tryGetAddress(address _target, bytes4 _selector) internal view returns (bool responded, address result) { + if (_target.code.length == 0) { return (false, address(0)); } - uint256 selector = uint32(IRegistryProvider.getRegistry.selector); + uint256 selector = uint32(_selector); assembly ("memory-safe") { mstore(0x00, shl(224, selector)) - let callSucceeded := staticcall(REGISTRY_PROBE_GAS_LIMIT, _withdrawer, 0x00, 0x04, 0x20, 0x20) - let result := mload(0x20) - responded := and(and(callSucceeded, eq(returndatasize(), 0x20)), iszero(shr(160, result))) - registry := 0 + let callSucceeded := staticcall(REGISTRY_PROBE_GAS_LIMIT, _target, 0x00, 0x04, 0x20, 0x20) + let word := mload(0x20) + responded := and(and(callSucceeded, eq(returndatasize(), 0x20)), iszero(shr(160, word))) + result := 0 if responded { - registry := and(result, sub(shl(160, 1), 1)) + result := and(word, sub(shl(160, 1), 1)) } } } diff --git a/l1-contracts/test/benchmark/happy.t.sol b/l1-contracts/test/benchmark/happy.t.sol index b270183aace8..41eee6d52974 100644 --- a/l1-contracts/test/benchmark/happy.t.sol +++ b/l1-contracts/test/benchmark/happy.t.sol @@ -69,7 +69,8 @@ import {StakingQueueConfig} from "@aztec/core/libraries/compressed-data/StakingQ import {BN254Lib, G1Point, G2Point} from "@aztec/shared/libraries/BN254Lib.sol"; import {SlashRound} from "@aztec/core/libraries/SlashRoundLib.sol"; import {AttestationLibHelper} from "@test/helper_libraries/AttestationLibHelper.sol"; -import {IRegistryProvider, RegistryRewardOverride} from "@aztec/core/libraries/rollup/RewardLib.sol"; +import {RegistryRewardOverride} from "@aztec/core/libraries/rollup/RewardLib.sol"; +import {MockATP, MockATPStaker} from "@test/mock/ATPMocks.sol"; // solhint-disable comprehensive-interface @@ -107,20 +108,6 @@ contract FakeCanonical is IRewardDistributor { } } -contract GasReportRegistryProvider is IRegistryProvider { - address internal immutable REGISTRY; - - constructor(address _registry) { - REGISTRY = _registry; - } - - /// @notice Returns the registry represented by this benchmark withdrawer. - /// @return The configured registry address. - function getRegistry() external view returns (address) { - return REGISTRY; - } -} - abstract contract BenchmarkRollupBase is FeeModelTestPoints, DecoderBase { using stdStorage for StdStorage; using TimeLib for Slot; @@ -734,27 +721,27 @@ contract PartialEpochProofGasReportTest is PartialEpochProofGasReportBase { } contract PartialEpochProofWithTwoOverridesGasReportTest is PartialEpochProofGasReportBase { - GasReportRegistryProvider internal firstProvider; - GasReportRegistryProvider internal secondProvider; + address internal firstRegistry = makeAddr("firstRegistry"); + address internal secondRegistry = makeAddr("secondRegistry"); + MockATPStaker internal firstStaker; + MockATPStaker internal secondStaker; function setUp() public override { - firstProvider = new GasReportRegistryProvider(makeAddr("firstRegistry")); - secondProvider = new GasReportRegistryProvider(makeAddr("secondRegistry")); + firstStaker = new MockATPStaker(address(new MockATP(firstRegistry))); + secondStaker = new MockATPStaker(address(new MockATP(secondRegistry))); super.setUp(); } function _configureRollupBuilder(RollupBuilder _builder) internal override { Config memory config = _builder.getConfig(); RollupConfigInput memory rollupConfig = config.rollupConfigInput; - rollupConfig.registryRewardOverrides[0] = - RegistryRewardOverride({registry: firstProvider.getRegistry(), sequencerReward: 10e18}); - rollupConfig.registryRewardOverrides[1] = - RegistryRewardOverride({registry: secondProvider.getRegistry(), sequencerReward: 20e18}); + rollupConfig.registryRewardOverrides[0] = RegistryRewardOverride({registry: firstRegistry, sequencerReward: 10e18}); + rollupConfig.registryRewardOverrides[1] = RegistryRewardOverride({registry: secondRegistry, sequencerReward: 20e18}); _builder.setRollupConfigInput(rollupConfig); } function _validatorWithdrawer(uint256 _validatorIndex) internal view override returns (address) { - return _validatorIndex % 2 == 0 ? address(firstProvider) : address(secondProvider); + return _validatorIndex % 2 == 0 ? address(firstStaker) : address(secondStaker); } function testGasReportSubmit1CheckpointWithTwoOverrides() public { diff --git a/l1-contracts/test/fixtures/mainnet_atp_reward_override.json b/l1-contracts/test/fixtures/mainnet_atp_reward_override.json new file mode 100644 index 000000000000..68d7d27b58dd --- /dev/null +++ b/l1-contracts/test/fixtures/mainnet_atp_reward_override.json @@ -0,0 +1 @@ +{"0x02cbf45ba5e6364c53f0623c2200f40746a735b9":{"nonce":"0x1","balance":"0x0","code":"0x6080604052600a600c565b005b60186014601a565b6050565b565b5f604b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc546001600160a01b031690565b905090565b365f5f375f5f365f845af43d5f5f3e8080156069573d5ff35b3d5ffdfea2646970667358221220ff7a924880ea92a37f0c8e7854a593fcaec3ad0775a3ae0d1c087cd168a411d964736f6c634300081e0033","storage":{"0x0000000000000000000000000000000000000000000000000000000000000000":"0x00000000000000000000000004623f9f5e51e11906e7480f0faa1443974f2506","0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc":"0x0000000000000000000000007c009ae557234d094d798a03d21e3c1c1cad3b42"}},"0x04623f9f5e51e11906e7480f0faa1443974f2506":{"nonce":"0x2","balance":"0x0","code":"0x363d3d373d3d3d363d733e214e2a587770a0259fce1c7211efbd39c1698a5af43d82803e903d91602b57fd5bf3","storage":{}},"0x11ed6b4a9d44cf8bc4e1763d08304ef20c998c95":{"nonce":"0x1","balance":"0x0","code":"0x608060405260043610610147575f3560e01c806352d1902d116100b3578063c4d66de81161006d578063c4d66de8146103d4578063d0e48cad146103f3578063e7f43c6814610412578063eeff76dd14610426578063f1048aa814610445578063f8dc4f9614610464575f5ffd5b806352d1902d14610320578063aaf10f4214610334578063ad3cb1cc14610348578063af43ecb614610385578063bbffb4f5146103a1578063bc1bea84146103c0575f5ffd5b8063425ca87011610104578063425ca8701461025a578063450cc1b0146102795780634ac3a713146102ac5780634ef0a2df146102cb5780634f1ef286146102f95780634f3851311461030c575f5ffd5b806303c230e31461014b5780630962ef791461019b5780631317d1b8146101bc57806332367ba0146101ef57806334ac94a21461021c578063362bd7bd1461023b575b5f5ffd5b348015610156575f5ffd5b5061017e7f000000000000000000000000a27ec0006e59f245217ff08cd52a7e8b169e62d281565b6040516001600160a01b0390911681526020015b60405180910390f35b3480156101a6575f5ffd5b506101ba6101b5366004611f30565b610497565b005b3480156101c7575f5ffd5b5061017e7f00000000000000000000000035b22e09ee0390539439e24f06da43d83f90e29881565b3480156101fa575f5ffd5b5061020e610209366004611f30565b6105d7565b604051908152602001610192565b348015610227575f5ffd5b506101ba610236366004611f7b565b610725565b348015610246575f5ffd5b506101ba610255366004611fdc565b6107c0565b348015610265575f5ffd5b506101ba61027436600461200a565b6108a0565b348015610284575f5ffd5b5061017e7f000000000000000000000000042df8f42790d6943f41c25c2132400fd727f45281565b3480156102b7575f5ffd5b506101ba6102c6366004611fdc565b6109ca565b3480156102d6575f5ffd5b505f5160206123d45f395f51905f525460ff166040519015158152602001610192565b6101ba6103073660046120ae565b610ad2565b348015610317575f5ffd5b506101ba610af1565b34801561032b575f5ffd5b5061020e610bfd565b34801561033f575f5ffd5b5061017e610c18565b348015610353575f5ffd5b50610378604051806040016040528060058152602001640352e302e360dc1b81525081565b6040516101929190612155565b348015610390575f5ffd5b505f546001600160a01b031661017e565b3480156103ac575f5ffd5b5061020e6103bb36600461218a565b610c3c565b3480156103cb575f5ffd5b506101ba610d3d565b3480156103df575f5ffd5b506101ba6103ee36600461218a565b610f6e565b3480156103fe575f5ffd5b506101ba61040d3660046121ac565b610fde565b34801561041d575f5ffd5b5061017e61124c565b348015610431575f5ffd5b506101ba610440366004611f30565b6112c0565b348015610450575f5ffd5b506101ba61045f36600461222d565b61147c565b34801561046f575f5ffd5b5061020e7f00000000000000000000000000000000000000000000000000000000696a937381565b5f6104a061124c565b905033816001600160a01b03811682146104d8576040516311ce341560e21b81526004016104cf9291906122d1565b60405180910390fd5b5050604051636e8ac1e160e11b8152600481018390525f907f00000000000000000000000035b22e09ee0390539439e24f06da43d83f90e2986001600160a01b03169063dd1583c290602401602060405180830381865afa15801561053f573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061056391906122eb565b90505f6105775f546001600160a01b031690565b60405163c7523d7960e01b81526001600160a01b0380831660048301529192509083169063c7523d79906024015f604051808303815f87803b1580156105bb575f5ffd5b505af11580156105cd573d5f5f3e3d5ffd5b5050505050505050565b5f5f6105e161124c565b905033816001600160a01b0381168214610610576040516311ce341560e21b81526004016104cf9291906122d1565b50505f7f00000000000000000000000035b22e09ee0390539439e24f06da43d83f90e2986001600160a01b031663289b3c0d6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561066f573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061069391906122eb565b90505f6106a75f546001600160a01b031690565b60405163625f849b60e11b81526001600160a01b038083166004830152602482018890529192509083169063c4bf0936906044015b6020604051808303815f875af11580156106f8573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061071c9190612306565b95945050505050565b5f61072e61124c565b905033816001600160a01b038116821461075d576040516311ce341560e21b81526004016104cf9291906122d1565b505061076c8686868686611518565b5f5160206123d45f395f51905f52805460ff166107b757805460ff191660011781556040517f4a127bffecc76f032d16b6fd22e796c618e3b2a48448f86852eaafd57f2ac0bc905f90a15b50505050505050565b604051636e8ac1e160e11b8152600481018390525f907f00000000000000000000000035b22e09ee0390539439e24f06da43d83f90e2986001600160a01b03169063dd1583c290602401602060405180830381865afa158015610825573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061084991906122eb565b604051637c2a4a6f60e11b81526001600160a01b0384811660048301529192509082169063f85494de906024015b5f604051808303815f87803b15801561088e575f5ffd5b505af11580156107b7573d5f5f3e3d5ffd5b5f6108a961124c565b905033816001600160a01b03811682146108d8576040516311ce341560e21b81526004016104cf9291906122d1565b50505f7f00000000000000000000000035b22e09ee0390539439e24f06da43d83f90e2986001600160a01b031663289b3c0d6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610937573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061095b91906122eb565b60405163350c7fbd60e11b8152600481018790526024810186905284151560448201529091506001600160a01b03821690636a18ff7a906064015b5f604051808303815f87803b1580156109ad575f5ffd5b505af11580156109bf573d5f5f3e3d5ffd5b505050505050505050565b5f6109d361124c565b905033816001600160a01b0381168214610a02576040516311ce341560e21b81526004016104cf9291906122d1565b5050604051636e8ac1e160e11b8152600481018490525f907f00000000000000000000000035b22e09ee0390539439e24f06da43d83f90e2986001600160a01b03169063dd1583c290602401602060405180830381865afa158015610a69573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610a8d91906122eb565b90505f610aa15f546001600160a01b031690565b60405163771dc6e160e11b81529091506001600160a01b0383169063ee3b8dc29061099690879085906004016122d1565b610ada6117d2565b610ae382611878565b610aed82826118a7565b5050565b5f610afa61124c565b905033816001600160a01b0381168214610b29576040516311ce341560e21b81526004016104cf9291906122d1565b50505f80546001600160a01b03166040516370a0823160e01b81523060048201529091505f906001600160a01b037f000000000000000000000000a27ec0006e59f245217ff08cd52a7e8b169e62d216906370a0823190602401602060405180830381865afa158015610b9e573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610bc29190612306565b9050610bf86001600160a01b037f000000000000000000000000a27ec0006e59f245217ff08cd52a7e8b169e62d2168383611963565b505050565b5f610c06611998565b505f5160206123b45f395f51905f5290565b5f610c375f5160206123b45f395f51905f52546001600160a01b031690565b905090565b5f5f610c4661124c565b905033816001600160a01b0381168214610c75576040516311ce341560e21b81526004016104cf9291906122d1565b50505f7f00000000000000000000000035b22e09ee0390539439e24f06da43d83f90e2986001600160a01b031663289b3c0d6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610cd4573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610cf891906122eb565b90505f610d0c5f546001600160a01b031690565b6040516330eb4bdd60e01b81529091506001600160a01b038316906330eb4bdd906106dc90889085906004016122d1565b5f610d4661124c565b905033816001600160a01b0381168214610d75576040516311ce341560e21b81526004016104cf9291906122d1565b50505f546001600160a01b0316610d9a5f5160206123d45f395f51905f525460ff1690565b610db75760405163ab9d5e2b60e01b815260040160405180910390fd5b7f00000000000000000000000000000000000000000000000000000000696a9373421015610df8576040516303ec244760e51b815260040160405180910390fd5b6040516370a0823160e01b81526001600160a01b0382811660048301525f917f000000000000000000000000a27ec0006e59f245217ff08cd52a7e8b169e62d2909116906370a0823190602401602060405180830381865afa158015610e60573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610e849190612306565b90505f826001600160a01b031663565a2e2c6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610ec3573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610ee791906122eb565b90508115610f6857610f246001600160a01b037f000000000000000000000000a27ec0006e59f245217ff08cd52a7e8b169e62d2168483856119e1565b806001600160a01b03167fdf800f68559bc54bc11df67fe8f6c8130a869bd79a4d8a6805f8ca38ae9b7b1a83604051610f5f91815260200190565b60405180910390a25b50505050565b6001600160a01b038116610f9557604051632a68e88960e21b815260040160405180910390fd5b5f546001600160a01b031615610fbd5760405162dc149f60e41b815260040160405180910390fd5b5f80546001600160a01b0319166001600160a01b0392909216919091179055565b5f610fe761124c565b905033816001600160a01b0381168214611016576040516311ce341560e21b81526004016104cf9291906122d1565b5050604051636e8ac1e160e11b8152600481018590525f907f00000000000000000000000035b22e09ee0390539439e24f06da43d83f90e2986001600160a01b03169063dd1583c290602401602060405180830381865afa15801561107d573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906110a191906122eb565b90505f816001600160a01b031663ed9187b76040518163ffffffff1660e01b8152600401602060405180830381865afa1580156110e0573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061110491906122eb565b60405163d3da927f60e01b815290915082906001600160a01b0383169063d3da927f906111379084908a906004016122d1565b602060405180830381865afa158015611152573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611176919061231d565b6111dd57816001600160a01b0316639f6bc70c6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156111b6573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906111da91906122eb565b90505b604051630171a0e760e51b81526001600160a01b03828116600483015287811660248301528681166044830152831690632e341ce0906064015f604051808303815f87803b15801561122d575f5ffd5b505af115801561123f573d5f5f3e3d5ffd5b5050505050505050505050565b5f5f5f9054906101000a90046001600160a01b03166001600160a01b031663e7f43c686040518163ffffffff1660e01b8152600401602060405180830381865afa15801561129c573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610c3791906122eb565b5f6112c961124c565b905033816001600160a01b03811682146112f8576040516311ce341560e21b81526004016104cf9291906122d1565b50505f7f00000000000000000000000035b22e09ee0390539439e24f06da43d83f90e2986001600160a01b031663289b3c0d6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611357573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061137b91906122eb565b5f549091506113b8906001600160a01b037f000000000000000000000000a27ec0006e59f245217ff08cd52a7e8b169e62d28116911630866119e1565b60405163095ea7b360e01b81526001600160a01b038281166004830152602482018590527f000000000000000000000000a27ec0006e59f245217ff08cd52a7e8b169e62d2169063095ea7b3906044016020604051808303815f875af1158015611424573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611448919061231d565b506040516311f9fbc960e21b8152306004820152602481018490526001600160a01b038216906347e7ef2490604401610877565b5f61148561124c565b905033816001600160a01b03811682146114b4576040516311ce341560e21b81526004016104cf9291906122d1565b50506114c4878787878787611a17565b5f5160206123d45f395f51905f52805460ff166105cd57805460ff191660011781556040517f4a127bffecc76f032d16b6fd22e796c618e3b2a48448f86852eaafd57f2ac0bc905f90a15050505050505050565b5f61152161124c565b905033816001600160a01b0381168214611550576040516311ce341560e21b81526004016104cf9291906122d1565b5050604051636e8ac1e160e11b8152600481018790525f907f00000000000000000000000035b22e09ee0390539439e24f06da43d83f90e2986001600160a01b03169063dd1583c290602401602060405180830381865afa1580156115b7573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906115db91906122eb565b90505f816001600160a01b031663aa10df4c6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561161a573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061163e9190612306565b5f5490915061167b906001600160a01b037f000000000000000000000000a27ec0006e59f245217ff08cd52a7e8b169e62d28116911630846119e1565b60405163095ea7b360e01b81526001600160a01b037f000000000000000000000000042df8f42790d6943f41c25c2132400fd727f45281166004830152602482018390527f000000000000000000000000a27ec0006e59f245217ff08cd52a7e8b169e62d2169063095ea7b3906044016020604051808303815f875af1158015611707573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061172b919061231d565b50604051636fde931560e01b8152600481018890526024810189905230604482015261ffff871660648201526001600160a01b03868116608483015285151560a48301527f000000000000000000000000042df8f42790d6943f41c25c2132400fd727f4521690636fde93159060c4015f604051808303815f87803b1580156117b2575f5ffd5b505af11580156117c4573d5f5f3e3d5ffd5b505050505050505050505050565b306001600160a01b037f00000000000000000000000011ed6b4a9d44cf8bc4e1763d08304ef20c998c9516148061185857507f00000000000000000000000011ed6b4a9d44cf8bc4e1763d08304ef20c998c956001600160a01b031661184c5f5160206123b45f395f51905f52546001600160a01b031690565b6001600160a01b031614155b156118765760405163703e46dd60e11b815260040160405180910390fd5b565b5f5433906001600160a01b0316818114610bf85760405163f5f64b6760e01b81526004016104cf9291906122d1565b816001600160a01b03166352d1902d6040518163ffffffff1660e01b8152600401602060405180830381865afa925050508015611901575060408051601f3d908101601f191682019092526118fe91810190612306565b60015b61192957604051634c9c8ce360e01b81526001600160a01b03831660048201526024016104cf565b5f5160206123b45f395f51905f52811461195957604051632a87526960e21b8152600481018290526024016104cf565b610bf88383611cb2565b6119708383836001611d07565b610bf857604051635274afe760e01b81526001600160a01b03841660048201526024016104cf565b306001600160a01b037f00000000000000000000000011ed6b4a9d44cf8bc4e1763d08304ef20c998c9516146118765760405163703e46dd60e11b815260040160405180910390fd5b6119ef848484846001611d69565b610f6857604051635274afe760e01b81526001600160a01b03851660048201526024016104cf565b5f611a2061124c565b905033816001600160a01b0381168214611a4f576040516311ce341560e21b81526004016104cf9291906122d1565b5050604051636e8ac1e160e11b8152600481018890525f907f00000000000000000000000035b22e09ee0390539439e24f06da43d83f90e2986001600160a01b03169063dd1583c290602401602060405180830381865afa158015611ab6573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611ada91906122eb565b90505f816001600160a01b031663aa10df4c6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611b19573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611b3d9190612306565b5f54909150611b7a906001600160a01b037f000000000000000000000000a27ec0006e59f245217ff08cd52a7e8b169e62d28116911630846119e1565b60405163095ea7b360e01b81526001600160a01b038381166004830152602482018390527f000000000000000000000000a27ec0006e59f245217ff08cd52a7e8b169e62d2169063095ea7b3906044016020604051808303815f875af1158015611be6573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611c0a919061231d565b50604051636902c67b60e01b81526001600160a01b03831690636902c67b90611c41908b9030908c908c908c908c90600401612338565b5f604051808303815f87803b158015611c58575f5ffd5b505af1158015611c6a573d5f5f3e3d5ffd5b50506040516001600160a01b0380861693508b16915030907fb2718d32c10b5a7d94c75d01205a0b819d5fdb7854640c8e9b94e647fedc6e17905f90a4505050505050505050565b611cbb82611dd6565b6040516001600160a01b038316907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b905f90a2805115611cff57610bf88282611e39565b610aed611eda565b60405163a9059cbb60e01b5f8181526001600160a01b038616600452602485905291602083604481808b5af1925060015f51148316611d5d578383151615611d51573d5f823e3d81fd5b5f873b113d1516831692505b60405250949350505050565b6040516323b872dd60e01b5f8181526001600160a01b038781166004528616602452604485905291602083606481808c5af1925060015f51148316611dc5578383151615611db9573d5f823e3d81fd5b5f883b113d1516831692505b604052505f60605295945050505050565b806001600160a01b03163b5f03611e0b57604051634c9c8ce360e01b81526001600160a01b03821660048201526024016104cf565b5f5160206123b45f395f51905f5280546001600160a01b0319166001600160a01b0392909216919091179055565b60605f611e468484611ef9565b9050808015611e6757505f3d1180611e6757505f846001600160a01b03163b115b15611e7c57611e74611f0c565b915050611ed4565b8015611ea657604051639996b31560e01b81526001600160a01b03851660048201526024016104cf565b3d15611eb957611eb4611f25565b611ed2565b60405163d6bda27560e01b815260040160405180910390fd5b505b92915050565b34156118765760405163b398979f60e01b815260040160405180910390fd5b5f5f5f835160208501865af49392505050565b6040513d81523d5f602083013e3d602001810160405290565b6040513d5f823e3d81fd5b5f60208284031215611f40575f5ffd5b5035919050565b6001600160a01b0381168114611f5b575f5ffd5b50565b8015158114611f5b575f5ffd5b8035611f7681611f5e565b919050565b5f5f5f5f5f60a08688031215611f8f575f5ffd5b8535945060208601359350604086013561ffff81168114611fae575f5ffd5b92506060860135611fbe81611f47565b91506080860135611fce81611f5e565b809150509295509295909350565b5f5f60408385031215611fed575f5ffd5b823591506020830135611fff81611f47565b809150509250929050565b5f5f5f6060848603121561201c575f5ffd5b8335925060208401359150604084013561203581611f5e565b809150509250925092565b634e487b7160e01b5f52604160045260245ffd5b6040516080810167ffffffffffffffff8111828210171561207757612077612040565b60405290565b604051601f8201601f1916810167ffffffffffffffff811182821017156120a6576120a6612040565b604052919050565b5f5f604083850312156120bf575f5ffd5b82356120ca81611f47565b9150602083013567ffffffffffffffff8111156120e5575f5ffd5b8301601f810185136120f5575f5ffd5b803567ffffffffffffffff81111561210f5761210f612040565b612122601f8201601f191660200161207d565b818152866020838501011115612136575f5ffd5b816020840160208301375f602083830101528093505050509250929050565b602081525f82518060208401528060208501604085015e5f604082850101526040601f19601f83011684010191505092915050565b5f6020828403121561219a575f5ffd5b81356121a581611f47565b9392505050565b5f5f5f606084860312156121be575f5ffd5b8335925060208401356121d081611f47565b9150604084013561203581611f47565b5f604082840312156121f0575f5ffd5b6040805190810167ffffffffffffffff8111828210171561221357612213612040565b604052823581526020928301359281019290925250919050565b5f5f5f5f5f5f868803610160811215612244575f5ffd5b87359650602088013561225681611f47565b95506122658960408a016121e0565b94506080607f1982011215612278575f5ffd5b50612281612054565b6080880135815260a0880135602082015260c0880135604082015260e0880135606082015292506122b68861010089016121e0565b91506122c56101408801611f6b565b90509295509295509295565b6001600160a01b0392831681529116602082015260400190565b5f602082840312156122fb575f5ffd5b81516121a581611f47565b5f60208284031215612316575f5ffd5b5051919050565b5f6020828403121561232d575f5ffd5b81516121a581611f5e565b6001600160a01b038781168252861660208201526101608101612368604083018780518252602090810151910152565b8451608083015260208086015160a0840152604086015160c0840152606086015160e0840152845161010084015284015161012083015282151561014083015297965050505050505056fe360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc2527cfd5830db0c841b72084c1ec066be32b8320e2ee2b8cb438bb32af8d8500a264697066735822122032e7281002eca6b4522b7f7f32e38b38f508848d9e7a1605dd49869a5fdf40dd64736f6c634300081e0033","storage":{}},"0x1f37cf7a4bb4a54838b67d3a19a586230e8d0d34":{"nonce":"0x2","balance":"0x0","code":"0x363d3d373d3d3d363d73c4a8530aeb89da98cd11178930b39c2aa272874e5af43d82803e903d91602b57fd5bf3","storage":{}},"0x3e214e2a587770a0259fce1c7211efbd39c1698a":{"nonce":"0x1","balance":"0x0","code":"0x608060405234801561000f575f5ffd5b5060043610610187575f3560e01c8063802ac8b6116100d9578063ce828b0611610093578063e7f43c681161006e578063e7f43c6814610404578063ec99499b14610415578063ee28b74414610428578063fdbcf3dc14610430575f5ffd5b8063ce828b06146103e1578063d7927824146103e9578063da62dfa4146103f1575f5ffd5b8063802ac8b6146102d55780638fff3cec146102e65780639b74026c146102ee578063ae3bb460146102f6578063b6549f75146102fe578063c2722ecc14610306575f5ffd5b80634e71d92d116101445780635ab1bd531161011f5780635ab1bd531461026e5780636d08aea71461029457806372b45a55146102b157806374743769146102c2575f5ffd5b80634e71d92d1461024d578063565a2e2c14610255578063592b07cd14610266575f5ffd5b80630c9e1e8e1461018b57806315dae03e146101a15780631ff9b6f2146101b057806321df0da7146101c557806324374197146101ff578063355723f114610212575b5f5ffd5b5f545b6040519081526020015b60405180910390f35b60026040516101989190611640565b6101c36101be36600461167d565b610457565b005b7f000000000000000000000000a27ec0006e59f245217ff08cd52a7e8b169e62d25b6040516001600160a01b039091168152602001610198565b6101c361020d3660046116b4565b6105d2565b61021a610669565b60405161019891908151815260208083015190820152604080830151908201526060918201519181019190915260800190565b61018e61071f565b6001546001600160a01b03166101e7565b61018e61077d565b7f0000000000000000000000008f778768aded86ab778a47cd81b3b42b4b3f655b6101e7565b600554600160601b900460ff166040519015158152602001610198565b6002546001600160a01b03166101e7565b6101c36102d03660046116cf565b61082e565b6006546001600160a01b03166101e7565b61021a610a2f565b61018e610ac2565b60045461018e565b61018e610b43565b61038f6040805160a0810182525f80825260208201819052918101829052606081018290526080810191909152506040805160a08101825260055463ffffffff8082168352640100000000820481166020840152600160401b82041692820192909252600160601b90910460ff16151560608201526006546001600160a01b0316608082015290565b60408051825163ffffffff90811682526020808501518216908301528383015116918101919091526060808301511515908201526080918201516001600160a01b03169181019190915260a001610198565b61018e610cf0565b6101e7610d26565b6101c36103ff36600461174a565b610da7565b6003546001600160a01b03166101e7565b6101c36104233660046116cf565b610fb5565b61018e6111b0565b61018e7f0000000000000000000000000000000000000000000000000000000069152cb781565b60015433906001600160a01b031681811461049d57604051635a8e8fa360e01b81526001600160a01b039283166004820152911660248201526044015b60405180910390fd5b50507f000000000000000000000000a27ec0006e59f245217ff08cd52a7e8b169e62d26001600160a01b0316826001600160a01b031614158290610500576040516337bce3c560e11b81526001600160a01b039091166004820152602401610494565b506040516370a0823160e01b815230600482015282905f906001600160a01b038316906370a0823190602401602060405180830381865afa158015610547573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061056b91906117e4565b90506105816001600160a01b0383168483611294565b604080516001600160a01b038087168252851660208201529081018290527f3af790fafda720819b2fc6e15090606e81154e0ac9a92d38ecad006d99d20ecc9060600160405180910390a150505050565b60015433906001600160a01b031681811461061357604051635a8e8fa360e01b81526001600160a01b03928316600482015291166024820152604401610494565b5050600380546001600160a01b0319166001600160a01b0383169081179091556040519081527f9da9e13718fdfd82ad5556bc47d08a237d650e068d8e9646a05362d2458eff3b9060200160405180910390a150565b61069060405180608001604052805f81526020015f81526020015f81526020015f81525090565b61071a7f0000000000000000000000008f778768aded86ab778a47cd81b3b42b4b3f655b6001600160a01b0316639601ddde6040518163ffffffff1660e01b8152600401606060405180830381865afa1580156106ef573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061071391906117fb565b5f546112e6565b905090565b6001545f9033906001600160a01b031681811461076257604051635a8e8fa360e01b81526001600160a01b03928316600482015291166024820152604401610494565b5050604051631129777360e21b815260040160405180910390fd5b6005545f90600160601b900460ff1661079657505f1990565b61079e610cf0565b6040516370a0823160e01b81523060048201527f000000000000000000000000a27ec0006e59f245217ff08cd52a7e8b169e62d26001600160a01b0316906370a0823190602401602060405180830381865afa158015610800573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061082491906117e4565b61071a919061184a565b60015433906001600160a01b031681811461086f57604051635a8e8fa360e01b81526001600160a01b03928316600482015291166024820152604401610494565b5050604051630e26d24360e31b8152600481018290525f907f0000000000000000000000008f778768aded86ab778a47cd81b3b42b4b3f655b6001600160a01b031690637136921890602401602060405180830381865afa1580156108d6573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906108fa919061185d565b6002546040805163278f794360e11b81526001600160a01b03808516600483015260248201929092525f60448201529293501690634f1ef286906064015f604051808303815f87803b15801561094e575f5ffd5b505af1158015610960573d5f5f3e3d5ffd5b5050600254604080516357a1f65b60e11b815290513094506001600160a01b03909216925063af43ecb69160048083019260209291908290030181865afa1580156109ad573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906109d1919061185d565b6001600160a01b0316146109f85760405163012fa17760e61b815260040160405180910390fd5b6040518281527f692235ce380b51290c9c1bf0c1eea4cb73dc28803f84dffa7837c175a51a9a789060200160405180910390a15050565b610a5660405180608001604052805f81526020015f81526020015f81526020015f81525090565b600554600160601b900460ff16610a8057604051633c34e69d60e01b815260040160405180910390fd5b6040805160608101825260055463ffffffff8082168352640100000000820481166020840152600160401b90910416918101919091525f5461071a91906112e6565b5f7f0000000000000000000000008f778768aded86ab778a47cd81b3b42b4b3f655b6001600160a01b0316639b74026c6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610b1f573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061071a91906117e4565b6005545f90600160601b900460ff16610b6f57604051633c34e69d60e01b815260040160405180910390fd5b5f7f0000000000000000000000008f778768aded86ab778a47cd81b3b42b4b3f655b6001600160a01b031663d79278246040518163ffffffff1660e01b8152600401602060405180830381865afa158015610bcc573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610bf0919061185d565b905033816001600160a01b0381168214610c30576040516319516ce560e31b81526001600160a01b03928316600482015291166024820152604401610494565b50505f610c3b610a2f565b60408101519091504210610c625760405163226a243d60e01b815260040160405180910390fd5b5f610c6b610cf0565b6005805460ff60601b19169055600654909150610cb5906001600160a01b037f000000000000000000000000a27ec0006e59f245217ff08cd52a7e8b169e62d28116911683611294565b6040518181527f61e27b0bfd8e18e6b92ec32ce1c28bb698d27bfe93e84c7e94d4db0a3135c760906020015b60405180910390a19392505050565b6005545f90600160601b900460ff16610d0857505f90565b610d1a42610d14610a2f565b90611366565b5f5461071a919061184a565b5f7f0000000000000000000000008f778768aded86ab778a47cd81b3b42b4b3f655b6001600160a01b031663d79278246040518163ffffffff1660e01b8152600401602060405180830381865afa158015610d83573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061071a919061185d565b6002546001600160a01b031615610dd05760405162dc149f60e41b815260040160405180910390fd5b5f6001600160a01b038416610e0457604051631a3b45fd60e01b81526001600160a01b039091166004820152602401610494565b505f8211610e2557604051634529276560e11b815260040160405180910390fd5b600180546001600160a01b0319166001600160a01b0385161790555f829055610e4c6113cd565b600280546001600160a01b0319166001600160a01b0392831617905581511615610f8657610e7d8160200151611502565b6040518060a00160405280610e9883602001515f015161155b565b63ffffffff168152602001610eb483602001516020015161155b565b63ffffffff168152602001610ed083602001516040015161155b565b63ffffffff9081168252600160208084019190915293516001600160a01b03908116604093840152835160058054968601519486015160608701511515600160601b0260ff60601b19918616600160401b02919091166cffffffffff0000000000000000199686166401000000000267ffffffffffffffff199099169390951692909217969096179390931691909117919091179092556080015160068054919092166001600160a01b03199091161790555050565b610f93816020015161158f565b610fb057604051630c66fa3f60e11b815260040160405180910390fd5b505050565b60015433906001600160a01b0316818114610ff657604051635a8e8fa360e01b81526001600160a01b03928316600482015291166024820152604401610494565b50505f7f0000000000000000000000008f778768aded86ab778a47cd81b3b42b4b3f655b6001600160a01b0316639b74026c6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611055573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061107991906117e4565b90504281808210156110a757604051631b1f1ffd60e01b815260048101929092526024820152604401610494565b50505f6110b261077d565b90508083808210156110e057604051631c4b371f60e31b815260048101929092526024820152604401610494565b505060025460405163095ea7b360e01b81526001600160a01b039182166004820152602481018590527f000000000000000000000000a27ec0006e59f245217ff08cd52a7e8b169e62d29091169063095ea7b3906044016020604051808303815f875af1158015611153573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906111779190611878565b506040518381527f55cf824239470134f920524d953607077f3ab00df4201f49629b29e864e0da409060200160405180910390a1505050565b5f5f6111ba610669565b60408101519091505f904210156111e7576004546111d88342611366565b6111e2919061184a565b6111ea565b5f195b905061128d6111f7610cf0565b6040516370a0823160e01b81523060048201527f000000000000000000000000a27ec0006e59f245217ff08cd52a7e8b169e62d26001600160a01b0316906370a0823190602401602060405180830381865afa158015611259573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061127d91906117e4565b611287919061184a565b826115b2565b9250505090565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b179052610fb09084906115c1565b61130d60405180608001604052805f81526020015f81526020015f81526020015f81525090565b61131683611502565b6040518060800160405280845f015181526020018460200151855f015161133d9190611897565b81526020018460400151855f01516113559190611897565b815260200183905290505b92915050565b5f826020015182101561137a57505f611360565b8260400151821061139057506060820151611360565b825160408401516113a1919061184a565b83516113ad908461184a565b84606001516113bc91906118aa565b6113c691906118c1565b9392505050565b604051630e26d24360e31b81525f600482018190529081906001600160a01b037f0000000000000000000000008f778768aded86ab778a47cd81b3b42b4b3f655b1690637136921890602401602060405180830381865afa158015611434573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611458919061185d565b6040513060248201529091505f90829060440160408051601f198184030181529181526020820180516001600160e01b031663189acdbd60e31b1790525161149f90611633565b6114aa9291906118e0565b604051809103905ff0801580156114c3573d5f5f3e3d5ffd5b506040516001600160a01b038216815290915081907fcb6c92f3827201df9fbbd40b7e8766a5742f09e4dafe6c85167325b7eaf0b76990602001610ce1565b5f816040015111611526576040516314c6911f60e11b815260040160405180910390fd5b602081015160408201519080821015610fb05760405163d3e33a4f60e01b815260048101929092526024820152604401610494565b5f63ffffffff82111561158b576040516306dfcc6560e41b81526020600482015260248101839052604401610494565b5090565b80515f901580156115a257506020820151155b8015611360575050604001511590565b5f8282188284100282186113c6565b5f5f60205f8451602086015f885af1806115e0576040513d5f823e3d81fd5b50505f513d915081156115f7578060011415611604565b6001600160a01b0384163b155b1561162d57604051635274afe760e01b81526001600160a01b0385166004820152602401610494565b50505050565b6103d08061192583390190565b602081016003831061166057634e487b7160e01b5f52602160045260245ffd5b91905290565b6001600160a01b038116811461167a575f5ffd5b50565b5f5f6040838503121561168e575f5ffd5b823561169981611666565b915060208301356116a981611666565b809150509250929050565b5f602082840312156116c4575f5ffd5b81356113c681611666565b5f602082840312156116df575f5ffd5b5035919050565b6040805190810167ffffffffffffffff8111828210171561171557634e487b7160e01b5f52604160045260245ffd5b60405290565b6040516060810167ffffffffffffffff8111828210171561171557634e487b7160e01b5f52604160045260245ffd5b5f5f5f83850360c081121561175d575f5ffd5b843561176881611666565b9350602085013592506080603f1982011215611782575f5ffd5b61178a6116e6565b604086013561179881611666565b81526060605f19830112156117ab575f5ffd5b6117b361171b565b60608701358152608087013560208083019190915260a0909701356040820152958101959095525091949093509050565b5f602082840312156117f4575f5ffd5b5051919050565b5f606082840312801561180c575f5ffd5b5061181561171b565b82518152602080840151908201526040928301519281019290925250919050565b634e487b7160e01b5f52601160045260245ffd5b8181038181111561136057611360611836565b5f6020828403121561186d575f5ffd5b81516113c681611666565b5f60208284031215611888575f5ffd5b815180151581146113c6575f5ffd5b8082018082111561136057611360611836565b808202811582820484141761136057611360611836565b5f826118db57634e487b7160e01b5f52601260045260245ffd5b500490565b60018060a01b0383168152604060208201525f82518060408401528060208501606085015e5f606082850101526060601f19601f830116840101915050939250505056fe60806040526040516103d03803806103d08339810160408190526100229161023c565b61002c8282610033565b5050610321565b61003c82610091565b6040516001600160a01b038316907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b905f90a280511561008557610080828261010c565b505050565b61008d61017f565b5050565b806001600160a01b03163b5f036100cb57604051634c9c8ce360e01b81526001600160a01b03821660048201526024015b60405180910390fd5b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc80546001600160a01b0319166001600160a01b0392909216919091179055565b60605f5f846001600160a01b031684604051610128919061030b565b5f60405180830381855af49150503d805f8114610160576040519150601f19603f3d011682016040523d82523d5f602084013e610165565b606091505b5090925090506101768583836101a0565b95945050505050565b341561019e5760405163b398979f60e01b815260040160405180910390fd5b565b6060826101b5576101b0826101ff565b6101f8565b81511580156101cc57506001600160a01b0384163b155b156101f557604051639996b31560e01b81526001600160a01b03851660048201526024016100c2565b50805b9392505050565b80511561020f5780518082602001fd5b60405163d6bda27560e01b815260040160405180910390fd5b634e487b7160e01b5f52604160045260245ffd5b5f5f6040838503121561024d575f5ffd5b82516001600160a01b0381168114610263575f5ffd5b60208401519092506001600160401b0381111561027e575f5ffd5b8301601f8101851361028e575f5ffd5b80516001600160401b038111156102a7576102a7610228565b604051601f8201601f19908116603f011681016001600160401b03811182821017156102d5576102d5610228565b6040528181528282016020018710156102ec575f5ffd5b8160208401602083015e5f602083830101528093505050509250929050565b5f82518060208501845e5f920191825250919050565b60a38061032d5f395ff3fe6080604052600a600c565b005b60186014601a565b6050565b565b5f604b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc546001600160a01b031690565b905090565b365f5f375f5f365f845af43d5f5f3e8080156069573d5ff35b3d5ffdfea2646970667358221220ff7a924880ea92a37f0c8e7854a593fcaec3ad0775a3ae0d1c087cd168a411d964736f6c634300081e0033a2646970667358221220922fccf242b11d6431c32a9674686d4e58b01dec5eac65e5ce49fa8e4bcd45ac64736f6c634300081e0033","storage":{}},"0x56860f956899139c65d4686b74bfc8238c6d8f57":{"nonce":"0x1","balance":"0x0","code":"0x6080604052600a600c565b005b60186014601a565b6050565b565b5f604b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc546001600160a01b031690565b905090565b365f5f375f5f365f845af43d5f5f3e8080156069573d5ff35b3d5ffdfea2646970667358221220ff7a924880ea92a37f0c8e7854a593fcaec3ad0775a3ae0d1c087cd168a411d964736f6c634300081e0033","storage":{"0x0000000000000000000000000000000000000000000000000000000000000000":"0x000000000000000000000000f749391f145a83f64cf788e1d6b55d225c004ff7","0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc":"0x00000000000000000000000011ed6b4a9d44cf8bc4e1763d08304ef20c998c95"}},"0x7c009ae557234d094d798a03d21e3c1c1cad3b42":{"nonce":"0x1","balance":"0x0","code":"0x608060405260043610610147575f3560e01c806352d1902d116100b3578063c4d66de81161006d578063c4d66de8146103d4578063d0e48cad146103f3578063e7f43c6814610412578063eeff76dd14610426578063f1048aa814610445578063f8dc4f9614610464575f5ffd5b806352d1902d14610320578063aaf10f4214610334578063ad3cb1cc14610348578063af43ecb614610385578063bbffb4f5146103a1578063bc1bea84146103c0575f5ffd5b8063425ca87011610104578063425ca8701461025a578063450cc1b0146102795780634ac3a713146102ac5780634ef0a2df146102cb5780634f1ef286146102f95780634f3851311461030c575f5ffd5b806303c230e31461014b5780630962ef791461019b5780631317d1b8146101bc57806332367ba0146101ef57806334ac94a21461021c578063362bd7bd1461023b575b5f5ffd5b348015610156575f5ffd5b5061017e7f000000000000000000000000a27ec0006e59f245217ff08cd52a7e8b169e62d281565b6040516001600160a01b0390911681526020015b60405180910390f35b3480156101a6575f5ffd5b506101ba6101b5366004611e40565b610497565b005b3480156101c7575f5ffd5b5061017e7f00000000000000000000000035b22e09ee0390539439e24f06da43d83f90e29881565b3480156101fa575f5ffd5b5061020e610209366004611e40565b6105d7565b604051908152602001610192565b348015610227575f5ffd5b506101ba610236366004611e88565b610725565b348015610246575f5ffd5b506101ba610255366004611ee9565b6107c0565b348015610265575f5ffd5b506101ba610274366004611f17565b6108a0565b348015610284575f5ffd5b5061017e7f000000000000000000000000042df8f42790d6943f41c25c2132400fd727f45281565b3480156102b7575f5ffd5b506101ba6102c6366004611ee9565b6109ca565b3480156102d6575f5ffd5b505f5160206122f05f395f51905f525460ff166040519015158152602001610192565b6101ba610307366004611fbb565b610ad2565b348015610317575f5ffd5b506101ba610af1565b34801561032b575f5ffd5b5061020e610bfd565b34801561033f575f5ffd5b5061017e610c18565b348015610353575f5ffd5b50610378604051806040016040528060058152602001640352e302e360dc1b81525081565b6040516101929190612062565b348015610390575f5ffd5b505f546001600160a01b031661017e565b3480156103ac575f5ffd5b5061020e6103bb366004612097565b610c3c565b3480156103cb575f5ffd5b506101ba610d3d565b3480156103df575f5ffd5b506101ba6103ee366004612097565b610f6e565b3480156103fe575f5ffd5b506101ba61040d3660046120b2565b610fde565b34801561041d575f5ffd5b5061017e611176565b348015610431575f5ffd5b506101ba610440366004611e40565b6111ea565b348015610450575f5ffd5b506101ba61045f366004612133565b6113a6565b34801561046f575f5ffd5b5061020e7f000000000000000000000000000000000000000000000000000000006af717e081565b5f6104a0611176565b905033816001600160a01b03811682146104d8576040516311ce341560e21b81526004016104cf9291906121d7565b60405180910390fd5b5050604051636e8ac1e160e11b8152600481018390525f907f00000000000000000000000035b22e09ee0390539439e24f06da43d83f90e2986001600160a01b03169063dd1583c290602401602060405180830381865afa15801561053f573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061056391906121f1565b90505f6105775f546001600160a01b031690565b60405163c7523d7960e01b81526001600160a01b0380831660048301529192509083169063c7523d79906024015f604051808303815f87803b1580156105bb575f5ffd5b505af11580156105cd573d5f5f3e3d5ffd5b5050505050505050565b5f5f6105e1611176565b905033816001600160a01b0381168214610610576040516311ce341560e21b81526004016104cf9291906121d7565b50505f7f00000000000000000000000035b22e09ee0390539439e24f06da43d83f90e2986001600160a01b031663289b3c0d6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561066f573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061069391906121f1565b90505f6106a75f546001600160a01b031690565b60405163625f849b60e11b81526001600160a01b038083166004830152602482018890529192509083169063c4bf0936906044015b6020604051808303815f875af11580156106f8573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061071c919061220c565b95945050505050565b5f61072e611176565b905033816001600160a01b038116821461075d576040516311ce341560e21b81526004016104cf9291906121d7565b505061076c8686868686611442565b5f5160206122f05f395f51905f52805460ff166107b757805460ff191660011781556040517f4a127bffecc76f032d16b6fd22e796c618e3b2a48448f86852eaafd57f2ac0bc905f90a15b50505050505050565b604051636e8ac1e160e11b8152600481018390525f907f00000000000000000000000035b22e09ee0390539439e24f06da43d83f90e2986001600160a01b03169063dd1583c290602401602060405180830381865afa158015610825573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061084991906121f1565b604051630942ee0160e31b81526001600160a01b03848116600483015291925090821690634a177008906024015b5f604051808303815f87803b15801561088e575f5ffd5b505af11580156107b7573d5f5f3e3d5ffd5b5f6108a9611176565b905033816001600160a01b03811682146108d8576040516311ce341560e21b81526004016104cf9291906121d7565b50505f7f00000000000000000000000035b22e09ee0390539439e24f06da43d83f90e2986001600160a01b031663289b3c0d6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610937573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061095b91906121f1565b60405163350c7fbd60e11b8152600481018790526024810186905284151560448201529091506001600160a01b03821690636a18ff7a906064015b5f604051808303815f87803b1580156109ad575f5ffd5b505af11580156109bf573d5f5f3e3d5ffd5b505050505050505050565b5f6109d3611176565b905033816001600160a01b0381168214610a02576040516311ce341560e21b81526004016104cf9291906121d7565b5050604051636e8ac1e160e11b8152600481018490525f907f00000000000000000000000035b22e09ee0390539439e24f06da43d83f90e2986001600160a01b03169063dd1583c290602401602060405180830381865afa158015610a69573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610a8d91906121f1565b90505f610aa15f546001600160a01b031690565b60405163771dc6e160e11b81529091506001600160a01b0383169063ee3b8dc29061099690879085906004016121d7565b610ada6116fc565b610ae3826117a2565b610aed82826117d1565b5050565b5f610afa611176565b905033816001600160a01b0381168214610b29576040516311ce341560e21b81526004016104cf9291906121d7565b50505f80546001600160a01b03166040516370a0823160e01b81523060048201529091505f906001600160a01b037f000000000000000000000000a27ec0006e59f245217ff08cd52a7e8b169e62d216906370a0823190602401602060405180830381865afa158015610b9e573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610bc2919061220c565b9050610bf86001600160a01b037f000000000000000000000000a27ec0006e59f245217ff08cd52a7e8b169e62d216838361188d565b505050565b5f610c066118ec565b505f5160206122d05f395f51905f5290565b5f610c375f5160206122d05f395f51905f52546001600160a01b031690565b905090565b5f5f610c46611176565b905033816001600160a01b0381168214610c75576040516311ce341560e21b81526004016104cf9291906121d7565b50505f7f00000000000000000000000035b22e09ee0390539439e24f06da43d83f90e2986001600160a01b031663289b3c0d6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610cd4573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610cf891906121f1565b90505f610d0c5f546001600160a01b031690565b6040516330eb4bdd60e01b81529091506001600160a01b038316906330eb4bdd906106dc90889085906004016121d7565b5f610d46611176565b905033816001600160a01b0381168214610d75576040516311ce341560e21b81526004016104cf9291906121d7565b50505f546001600160a01b0316610d9a5f5160206122f05f395f51905f525460ff1690565b610db75760405163ab9d5e2b60e01b815260040160405180910390fd5b7f000000000000000000000000000000000000000000000000000000006af717e0421015610df8576040516303ec244760e51b815260040160405180910390fd5b6040516370a0823160e01b81526001600160a01b0382811660048301525f917f000000000000000000000000a27ec0006e59f245217ff08cd52a7e8b169e62d2909116906370a0823190602401602060405180830381865afa158015610e60573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610e84919061220c565b90505f826001600160a01b031663565a2e2c6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610ec3573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610ee791906121f1565b90508115610f6857610f246001600160a01b037f000000000000000000000000a27ec0006e59f245217ff08cd52a7e8b169e62d216848385611935565b806001600160a01b03167fdf800f68559bc54bc11df67fe8f6c8130a869bd79a4d8a6805f8ca38ae9b7b1a83604051610f5f91815260200190565b60405180910390a25b50505050565b6001600160a01b038116610f9557604051632a68e88960e21b815260040160405180910390fd5b5f546001600160a01b031615610fbd5760405162dc149f60e41b815260040160405180910390fd5b5f80546001600160a01b0319166001600160a01b0392909216919091179055565b5f610fe7611176565b905033816001600160a01b0381168214611016576040516311ce341560e21b81526004016104cf9291906121d7565b5050604051636e8ac1e160e11b8152600481018590525f907f00000000000000000000000035b22e09ee0390539439e24f06da43d83f90e2986001600160a01b03169063dd1583c290602401602060405180830381865afa15801561107d573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906110a191906121f1565b90505f816001600160a01b031663ed9187b76040518163ffffffff1660e01b8152600401602060405180830381865afa1580156110e0573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061110491906121f1565b604051630171a0e760e51b81526001600160a01b0384811660048301528781166024830152868116604483015291925090821690632e341ce0906064015f604051808303815f87803b158015611158575f5ffd5b505af115801561116a573d5f5f3e3d5ffd5b50505050505050505050565b5f5f5f9054906101000a90046001600160a01b03166001600160a01b031663e7f43c686040518163ffffffff1660e01b8152600401602060405180830381865afa1580156111c6573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610c3791906121f1565b5f6111f3611176565b905033816001600160a01b0381168214611222576040516311ce341560e21b81526004016104cf9291906121d7565b50505f7f00000000000000000000000035b22e09ee0390539439e24f06da43d83f90e2986001600160a01b031663289b3c0d6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611281573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906112a591906121f1565b5f549091506112e2906001600160a01b037f000000000000000000000000a27ec0006e59f245217ff08cd52a7e8b169e62d2811691163086611935565b60405163095ea7b360e01b81526001600160a01b038281166004830152602482018590527f000000000000000000000000a27ec0006e59f245217ff08cd52a7e8b169e62d2169063095ea7b3906044016020604051808303815f875af115801561134e573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906113729190612223565b506040516311f9fbc960e21b8152306004820152602481018490526001600160a01b038216906347e7ef2490604401610877565b5f6113af611176565b905033816001600160a01b03811682146113de576040516311ce341560e21b81526004016104cf9291906121d7565b50506113ee87878787878761196e565b5f5160206122f05f395f51905f52805460ff166105cd57805460ff191660011781556040517f4a127bffecc76f032d16b6fd22e796c618e3b2a48448f86852eaafd57f2ac0bc905f90a15050505050505050565b5f61144b611176565b905033816001600160a01b038116821461147a576040516311ce341560e21b81526004016104cf9291906121d7565b5050604051636e8ac1e160e11b8152600481018790525f907f00000000000000000000000035b22e09ee0390539439e24f06da43d83f90e2986001600160a01b03169063dd1583c290602401602060405180830381865afa1580156114e1573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061150591906121f1565b90505f816001600160a01b031663aa10df4c6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611544573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611568919061220c565b5f549091506115a5906001600160a01b037f000000000000000000000000a27ec0006e59f245217ff08cd52a7e8b169e62d2811691163084611935565b60405163095ea7b360e01b81526001600160a01b037f000000000000000000000000042df8f42790d6943f41c25c2132400fd727f45281166004830152602482018390527f000000000000000000000000a27ec0006e59f245217ff08cd52a7e8b169e62d2169063095ea7b3906044016020604051808303815f875af1158015611631573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906116559190612223565b50604051636fde931560e01b8152600481018890526024810189905230604482015261ffff871660648201526001600160a01b03868116608483015285151560a48301527f000000000000000000000000042df8f42790d6943f41c25c2132400fd727f4521690636fde93159060c4015f604051808303815f87803b1580156116dc575f5ffd5b505af11580156116ee573d5f5f3e3d5ffd5b505050505050505050505050565b306001600160a01b037f0000000000000000000000007c009ae557234d094d798a03d21e3c1c1cad3b4216148061178257507f0000000000000000000000007c009ae557234d094d798a03d21e3c1c1cad3b426001600160a01b03166117765f5160206122d05f395f51905f52546001600160a01b031690565b6001600160a01b031614155b156117a05760405163703e46dd60e11b815260040160405180910390fd5b565b5f5433906001600160a01b0316818114610bf85760405163f5f64b6760e01b81526004016104cf9291906121d7565b816001600160a01b03166352d1902d6040518163ffffffff1660e01b8152600401602060405180830381865afa92505050801561182b575060408051601f3d908101601f191682019092526118289181019061220c565b60015b61185357604051634c9c8ce360e01b81526001600160a01b03831660048201526024016104cf565b5f5160206122d05f395f51905f52811461188357604051632a87526960e21b8152600481018290526024016104cf565b610bf88383611c09565b6040516001600160a01b03838116602483015260448201839052610bf891859182169063a9059cbb906064015b604051602081830303815290604052915060e01b6020820180516001600160e01b038381831617835250505050611c5e565b306001600160a01b037f0000000000000000000000007c009ae557234d094d798a03d21e3c1c1cad3b4216146117a05760405163703e46dd60e11b815260040160405180910390fd5b6040516001600160a01b038481166024830152838116604483015260648201839052610f689186918216906323b872dd906084016118ba565b5f611977611176565b905033816001600160a01b03811682146119a6576040516311ce341560e21b81526004016104cf9291906121d7565b5050604051636e8ac1e160e11b8152600481018890525f907f00000000000000000000000035b22e09ee0390539439e24f06da43d83f90e2986001600160a01b03169063dd1583c290602401602060405180830381865afa158015611a0d573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611a3191906121f1565b90505f816001600160a01b031663aa10df4c6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611a70573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611a94919061220c565b5f54909150611ad1906001600160a01b037f000000000000000000000000a27ec0006e59f245217ff08cd52a7e8b169e62d2811691163084611935565b60405163095ea7b360e01b81526001600160a01b038381166004830152602482018390527f000000000000000000000000a27ec0006e59f245217ff08cd52a7e8b169e62d2169063095ea7b3906044016020604051808303815f875af1158015611b3d573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611b619190612223565b50604051636902c67b60e01b81526001600160a01b03831690636902c67b90611b98908b9030908c908c908c908c9060040161223e565b5f604051808303815f87803b158015611baf575f5ffd5b505af1158015611bc1573d5f5f3e3d5ffd5b50506040516001600160a01b0380861693508b16915030907fb2718d32c10b5a7d94c75d01205a0b819d5fdb7854640c8e9b94e647fedc6e17905f90a4505050505050505050565b611c1282611cca565b6040516001600160a01b038316907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b905f90a2805115611c5657610bf88282611d2d565b610aed611d96565b5f5f60205f8451602086015f885af180611c7d576040513d5f823e3d81fd5b50505f513d91508115611c94578060011415611ca1565b6001600160a01b0384163b155b15610f6857604051635274afe760e01b81526001600160a01b03851660048201526024016104cf565b806001600160a01b03163b5f03611cff57604051634c9c8ce360e01b81526001600160a01b03821660048201526024016104cf565b5f5160206122d05f395f51905f5280546001600160a01b0319166001600160a01b0392909216919091179055565b60605f5f846001600160a01b031684604051611d4991906122b9565b5f60405180830381855af49150503d805f8114611d81576040519150601f19603f3d011682016040523d82523d5f602084013e611d86565b606091505b509150915061071c858383611db5565b34156117a05760405163b398979f60e01b815260040160405180910390fd5b606082611dca57611dc582611e14565b611e0d565b8151158015611de157506001600160a01b0384163b155b15611e0a57604051639996b31560e01b81526001600160a01b03851660048201526024016104cf565b50805b9392505050565b805115611e245780518082602001fd5b60405163d6bda27560e01b815260040160405180910390fd5b50565b5f60208284031215611e50575f5ffd5b5035919050565b6001600160a01b0381168114611e3d575f5ffd5b8015158114611e3d575f5ffd5b8035611e8381611e6b565b919050565b5f5f5f5f5f60a08688031215611e9c575f5ffd5b8535945060208601359350604086013561ffff81168114611ebb575f5ffd5b92506060860135611ecb81611e57565b91506080860135611edb81611e6b565b809150509295509295909350565b5f5f60408385031215611efa575f5ffd5b823591506020830135611f0c81611e57565b809150509250929050565b5f5f5f60608486031215611f29575f5ffd5b83359250602084013591506040840135611f4281611e6b565b809150509250925092565b634e487b7160e01b5f52604160045260245ffd5b6040516080810167ffffffffffffffff81118282101715611f8457611f84611f4d565b60405290565b604051601f8201601f1916810167ffffffffffffffff81118282101715611fb357611fb3611f4d565b604052919050565b5f5f60408385031215611fcc575f5ffd5b8235611fd781611e57565b9150602083013567ffffffffffffffff811115611ff2575f5ffd5b8301601f81018513612002575f5ffd5b803567ffffffffffffffff81111561201c5761201c611f4d565b61202f601f8201601f1916602001611f8a565b818152866020838501011115612043575f5ffd5b816020840160208301375f602083830101528093505050509250929050565b602081525f82518060208401528060208501604085015e5f604082850101526040601f19601f83011684010191505092915050565b5f602082840312156120a7575f5ffd5b8135611e0d81611e57565b5f5f5f606084860312156120c4575f5ffd5b8335925060208401356120d681611e57565b91506040840135611f4281611e57565b5f604082840312156120f6575f5ffd5b6040805190810167ffffffffffffffff8111828210171561211957612119611f4d565b604052823581526020928301359281019290925250919050565b5f5f5f5f5f5f86880361016081121561214a575f5ffd5b87359650602088013561215c81611e57565b955061216b8960408a016120e6565b94506080607f198201121561217e575f5ffd5b50612187611f61565b6080880135815260a0880135602082015260c0880135604082015260e0880135606082015292506121bc8861010089016120e6565b91506121cb6101408801611e78565b90509295509295509295565b6001600160a01b0392831681529116602082015260400190565b5f60208284031215612201575f5ffd5b8151611e0d81611e57565b5f6020828403121561221c575f5ffd5b5051919050565b5f60208284031215612233575f5ffd5b8151611e0d81611e6b565b6001600160a01b03878116825286166020820152610160810161226e604083018780518252602090810151910152565b8451608083015260208086015160a0840152604086015160c0840152606086015160e08401528451610100840152840151610120830152821515610140830152979650505050505050565b5f82518060208501845e5f92019182525091905056fe360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc2527cfd5830db0c841b72084c1ec066be32b8320e2ee2b8cb438bb32af8d8500a26469706673582212209e455086820e9668f90b9d661723e7f59ed2d52d0895ddb2e3499cd2cdf58e7864736f6c634300081e0033","storage":{}},"0x91ff8bbd8ebb07893010d50a48a1609e5ebd8e34":{"nonce":"0x6","balance":"0x0","code":"0x608060405234801561000f575f5ffd5b506004361061063d575f3560e01c8063850bee3511610334578063c2d6286a116101b9578063e09e424e11610101578063ec147806116100a5578063ec14780614610d92578063ed9187b714610de7578063ede57c3414610def578063ee3b8dc214610df7578063f0b724c014610e0a578063f2fde38b14610e12578063f85494de14610e25578063fd55f8a314610e38575f5ffd5b8063e09e424e14610d0e578063e0fae2a914610d16578063e199c05914610d29578063e3380b7914610d3c578063e3682cde14610d44578063e48a5f7b14610d4c578063e6e2844014610d6c578063eb80a09414610d7f575f5ffd5b8063ce139d1c11610168578063ce139d1c14610ca1578063cf20d87214610caa578063d03b2bae14610cb2578063d0c80f1314610cc5578063d768df6e14610ccd578063d8e3784c14610ce0578063dc1bb8f414610ce8578063dfff3ebc14610cfb575f5ffd5b8063c2d6286a14610c3b578063c30d876c14610c5b578063c4014c1214610c63578063c7523d7914610c6b578063c85b995714610c7e578063c9d1e01214610c86578063ca3dc9ec14610c99575f5ffd5b8063a08a32831161027c578063ae8955811161022b578063ae89558114610bc4578063af584dd314610bd7578063b1ba85ab14610bea578063b97dd9e214610bf2578063b9d0916314610bfa578063c1203a0e14610c0d578063c27f08b514610c20578063c2cac49d14610c33575f5ffd5b8063a08a328314610b6a578063a229474814610b73578063a2429e8814610b7b578063a32fbb7b14610b8e578063a7f8e64614610b96578063aa10df4c14610ba9578063ae36b7be14610bb1575f5ffd5b806390a3b386116102e357806390a3b38614610aed578063966ab4ee14610af55780639724931714610afd5780639891be8e14610b105780639ca0370214610b185780639e0fedd814610b385780639f2b315414610b5a578063a011f6a914610b62575f5ffd5b8063850bee3514610aa157806386a0d76314610aa95780638789a13214610ab157806388e4a07314610ac45780638990cf6914610acc5780638ccf6b9514610ad45780638da5cb5b14610adc575f5ffd5b80633b10244b116104c55780636902c67b1161040d57806374af185e116103b157806374af185e146109e057806374e0a89d146109f3578063766d01b414610a1b57806376d0fc7014610a2e57806379ed8ead14610a445780637afeed2814610a6b5780637de3ca8914610a7e57806384b0196e14610a86575f5ffd5b80636902c67b1461096257806369457a6f14610975578063715018a614610988578063723d8e9614610990578063725d5b8e1461099857806372636df9146109a057806372c6c710146109b35780637468582f146109d3575f5ffd5b8063508ac49b11610474578063508ac49b146108d15780635a97eaa1146108d95780635c82926c146108ec5780635d3ea8f1146108f45780635dc0ff94146108fc5780635f82401f1461091c57806365e50a3e1461093c57806368faa7781461094f575f5ffd5b80633b10244b1461084b5780633f47ad06146108535780634267d0bd1461085b57806342d21ef714610863578063483315b3146108a357806348b5de18146108b65780634eb4a4d6146108c9575f5ffd5b806320fc48811161058857806330ccebb51161053757806330ccebb5146107b85780633334f7dc146107d857806334a51ed5146107eb578063368c093c1461080b578063375fae1f146108135780633777e8631461081b578063386f56fc1461082e57806338b39d2914610836575f5ffd5b806320fc48811461075257806325b223661461077257806328e07ac31461077a578063291766251461078d5780632980c31e146107a057806329c24030146107a85780632eb5af0a146107b0575f5ffd5b806311704430116105ef57806311704430146106bf57806313b487f4146106df57806315d3bc7b146106f45780631b34c564146107075780631b56a0e71461071a5780631cfe2878146107225780631d934975146107425780631f8352e91461074a575f5ffd5b80630121b93f1461064157806302a214601461065657806302fb4d8514610671578063069d1525146106945780630d8e6e2c146106a757806310073ff0146106af57806310a2aa55146106b7575b5f5ffd5b61065461064f366004613da3565b610e4b565b005b61065e610eae565b6040519081526020015b60405180910390f35b61068461067f366004613dde565b610ee0565b6040519015158152602001610668565b6106546106a2366004613e08565b610f63565b61065e610f9a565b61065e610fb2565b610654611023565b6106d26106cd366004613e57565b61107d565b6040516106689190613eab565b6106e761111e565b6040516106689190613eb9565b6106e7610702366004613da3565b611139565b610654610715366004613fe7565b6111ae565b61065e611253565b610735610730366004613da3565b61129b565b6040516106689190614028565b6106546112a9565b61065e6112f2565b610765610760366004613da3565b61130b565b60405161066891906140a3565b61065e611396565b610684610788366004613dde565b6113b2565b61065e61079b366004613da3565b6113ed565b61065e61146e565b61065e6114b6565b6106546114fe565b6107cb6107c6366004614104565b611548565b6040516106689190614153565b6106846107e6366004614161565b6115c0565b6107fe6107f9366004614104565b611646565b6040516106689190614206565b6106e76116c5565b61065e6116e0565b61065e610829366004613da3565b611746565b61065e611778565b6b4355415548584943414c4c4960401b6106e7565b6106e7611798565b61065e6117a2565b61065e6117ea565b610876610871366004613da3565b611867565b604080519687526020870195909552938501929092526060840152608083015260a082015260c001610668565b61065e6108b1366004613da3565b6118d7565b6106546108c4366004614104565b611911565b61065e6119ab565b6106546119f3565b61065e6108e7366004613da3565b6119fd565b61065e611a37565b61065e611a4b565b61090f61090a366004614104565b611a67565b6040516106689190614249565b61092f61092a366004613da3565b611ae5565b6040516106689190614257565b61065461094a36600461426e565b611b67565b61065e61095d3660046142da565b611ba6565b61065461097036600461432c565b611c2a565b610735610983366004613da3565b611c9f565b610654611d16565b61065e611d27565b61065e611d3f565b6106546109ae366004614543565b611d51565b6109c66109c1366004613da3565b611dd1565b6040516106689190614611565b6004546106849060ff1681565b61065e6109ee366004613da3565b611dea565b610a06610a01366004613da3565b611df4565b60408051928352602083019190915201610668565b61065e610a29366004613e57565b611e73565b610a36611eb4565b60405161066892919061461f565b61065e7f00000000000000000000000000000000000000000000000000000000018403a681565b61065e610a79366004613da3565b611ef2565b61065e611f16565b610a8e611f5e565b6040516106689796959493929190614666565b6106e7611fa0565b61065e611fc3565b61065e610abf366004614104565b61200b565b61092f612044565b610684612068565b6106e7612084565b6002546001600160a01b03166106e7565b61065e61209f565b6107356120a9565b61065e610b0b366004613da3565b6120b6565b61065e6120c0565b610b2b610b26366004613da3565b6120cc565b60405161066891906146fc565b610b4b610b46366004614777565b612147565b604051610668939291906147ef565b6106546121db565b6106e761221d565b624f1a0061065e565b6106e7612235565b610654610b89366004613da3565b6122a1565b6106e76122b5565b6106e7610ba4366004613da3565b6122d0565b61065e61230a565b610a06610bbf366004614161565b612364565b610654610bd23660046148fb565b6123eb565b610654610be536600461496e565b61245a565b61065e6124c6565b61065e612520565b61065e610c08366004613da3565b61252a565b610654610c1b366004614a2c565b612534565b6106e7610c2e366004613da3565b6125e9565b61065461262b565b610c4e610c49366004614b18565b61266d565b6040516106689190614bc7565b61065e612700565b61065e612748565b61065e610c79366004614104565b612764565b61065e61279d565b61065e610c94366004613da3565b6127af565b61065e6127b9565b62278d0061065e565b6106e7612801565b61065e610cc0366004613da3565b612849565b6106e7612853565b61065e610cdb366004614bd9565b61286e565b61065e6128a9565b610684610cf6366004613da3565b6128b3565b61065e610d09366004614104565b612927565b61065e612960565b610a06610d24366004613da3565b612982565b610654610d37366004613da3565b6129c5565b6106546129fd565b61065e612a3f565b610d5f610d5a366004614104565b612a87565b6040516106689190614c7e565b610654610d7a366004613da3565b612b1b565b610654610d8d366004614104565b612ba8565b610d9a612be7565b6040805182516001600160a01b03908116825260208085015163ffffffff16908301528383015116918101919091526060918201516001600160601b031691810191909152608001610668565b6106e7612c75565b61065e612c90565b610684610e05366004614c8c565b612cb3565b610a36612cfd565b610654610e20366004614104565b612d35565b610654610e33366004614104565b612d6f565b61065e610e46366004613da3565b612da6565b604051630121b93f60e01b81526004810182905273e4f0b9769ca04a6e3d93b5ba732b5ad80797d41190630121b93f906024015b5f6040518083038186803b158015610e95575f5ffd5b505af4158015610ea7573d5f5f3e3d5ffd5b5050505050565b5f5f610eb8612db0565b9050806001015f610ecc835f015460801c90565b81526020019081526020015f205491505090565b6040516302fb4d8560e01b81525f9073e4f0b9769ca04a6e3d93b5ba732b5ad80797d411906302fb4d8590610f1b908690869060040161461f565b602060405180830381865af4158015610f36573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610f5a9190614cb8565b90505b92915050565b604051630f484ad560e01b815273516f010c9ab452d70e0c6f78b9e698249a66d2ac90630f484ad590610e7f908490600401614ee7565b5f610fa3612db0565b6005015463ffffffff16919050565b5f73e4f0b9769ca04a6e3d93b5ba732b5ad80797d4116310073ff06040518163ffffffff1660e01b8152600401602060405180830381865af4158015610ffa573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061101e9190614fe4565b905090565b73e4f0b9769ca04a6e3d93b5ba732b5ad80797d4116310a2aa556040518163ffffffff1660e01b81526004015f6040518083038186803b158015611065575f5ffd5b505af4158015611077573d5f5f3e3d5ffd5b50505050565b6110a460405180608001604052805f81526020015f81526020015f81526020015f81525090565b604051630117044360e41b815260048101849052821515602482015273d6e890c615d6f99681a00771c20ed0451628889890631170443090604401608060405180830381865af41580156110fa573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610f5a919061503e565b5f611127612db0565b600701546001600160a01b0316919050565b6040516315d3bc7b60e01b8152600481018290525f9073e4f0b9769ca04a6e3d93b5ba732b5ad80797d411906315d3bc7b906024015b602060405180830381865af415801561118a573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610f5d9190615058565b6111b6612dd4565b604051638841c46760e01b815273d6e890c615d6f99681a00771c20ed0451628889890638841c467906111ed908490600401615073565b5f6040518083038186803b158015611203575f5ffd5b505af4158015611215573d5f5f3e3d5ffd5b505050507f24ea90802d5c1d10fd3da4b05f2415af510be55a0e3b385831be1851c3975869816040516112489190615073565b60405180910390a150565b5f73e4f0b9769ca04a6e3d93b5ba732b5ad80797d411631b56a0e76040518163ffffffff1660e01b8152600401602060405180830381865af4158015610ffa573d5f5f3e3d5ffd5b6060610f5d610983836127af565b60405163e199c05960e01b81525f19600482015273e4f0b9769ca04a6e3d93b5ba732b5ad80797d4119063e199c059906024015f6040518083038186803b158015611065575f5ffd5b5f61101e6112fe612db0565b546001600160801b031690565b611313613bdb565b5f61131d83612e01565b9050604051806101000160405280611333612db0565b6001015f8681526020019081526020015f20548152602001825f01518152602001826020015181526020018260400151815260200182606001518152602001826080015181526020018260a0015181526020018260c00151815250915050919050565b5f61139f612e6d565b54600160c01b900463ffffffff16919050565b6040516328e07ac360e01b81525f9073d6e890c615d6f99681a00771c20ed04516288898906328e07ac390610f1b908690869060040161461f565b5f73e4f0b9769ca04a6e3d93b5ba732b5ad80797d4116329176625611411846127af565b6040518263ffffffff1660e01b815260040161142f91815260200190565b602060405180830381865af415801561144a573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610f5d9190614fe4565b5f73e4f0b9769ca04a6e3d93b5ba732b5ad80797d411632980c31e6040518163ffffffff1660e01b8152600401602060405180830381865af4158015610ffa573d5f5f3e3d5ffd5b5f73d6e890c615d6f99681a00771c20ed045162888986329c240306040518163ffffffff1660e01b8152600401602060405180830381865af4158015610ffa573d5f5f3e3d5ffd5b611506612dd4565b73e4f0b9769ca04a6e3d93b5ba732b5ad80797d411632eb5af0a6040518163ffffffff1660e01b81526004015f6040518083038186803b158015611065575f5ffd5b6040516330ccebb560e01b81525f9073e4f0b9769ca04a6e3d93b5ba732b5ad80797d411906330ccebb590611581908590600401613eb9565b602060405180830381865af415801561159c573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610f5d91906150a7565b604051630ccd3df760e21b81525f9073d6e890c615d6f99681a00771c20ed0451628889890633334f7dc906115fd908790879087906004016150c0565b602060405180830381865af4158015611618573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061163c9190614cb8565b90505b9392505050565b61164e613c1e565b6040516334a51ed560e01b815273e4f0b9769ca04a6e3d93b5ba732b5ad80797d411906334a51ed590611685908590600401613eb9565b61016060405180830381865af41580156116a1573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610f5d91906151bf565b5f6116ce612db0565b600801546001600160a01b0316919050565b5f73d6e890c615d6f99681a00771c20ed045162888986316a7ced561170d611706612db0565b5460801c90565b6040518263ffffffff1660e01b815260040161172b91815260200190565b602060405180830381865af4158015610ffa573d5f5f3e3d5ffd5b5f5f611750612db0565b805490915060801c831115611765575f61163f565b5f92835260010160205250604090205490565b5f61101e611784612e91565b60030154600160a01b900463ffffffff1690565b5f61101e426125e9565b5f73d6e890c615d6f99681a00771c20ed04516288898633f47ad066040518163ffffffff1660e01b8152600401602060405180830381865af4158015610ffa573d5f5f3e3d5ffd5b5f61101e6117f66116e0565b73d6e890c615d6f99681a00771c20ed0451628889863fe2a92d06040518163ffffffff1660e01b8152600401602060405180830381865af415801561183d573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906118619190614fe4565b90612eb5565b5f5f5f5f5f5f5f611876612db0565b90505f611885825f0154612ec8565b6020808201515f818152600186019092526040808320548451808552919093205493945090926118b48d611746565b6118c186602001516118d7565b949e939d50919b50995097509095509350505050565b60405163483315b360e01b8152600481018290525f9073d6e890c615d6f99681a00771c20ed045162888989063483315b39060240161142f565b611919612dd4565b604051630916bbc360e31b815273e4f0b9769ca04a6e3d93b5ba732b5ad80797d411906348b5de1890611950908490600401613eb9565b5f6040518083038186803b158015611966575f5ffd5b505af4158015611978573d5f5f3e3d5ffd5b505050507f17a1cb124ae226925a506c45bbf4e49c701b0fb60a32cad8106a58846250573c816040516112489190613eb9565b5f73d6e890c615d6f99681a00771c20ed0451628889863fe2a92d06040518163ffffffff1660e01b8152600401602060405180830381865af4158015610ffa573d5f5f3e3d5ffd5b6119fb612f08565b565b604051635a97eaa160e01b8152600481018290525f9073d6e890c615d6f99681a00771c20ed0451628889890635a97eaa19060240161142f565b5f61101e611a46611706612db0565b613026565b5f611a54612e6d565b54600160a01b900463ffffffff16919050565b611a6f613c69565b6040516317703fe560e21b815273e4f0b9769ca04a6e3d93b5ba732b5ad80797d41190635dc0ff9490611aa6908590600401613eb9565b60c060405180830381865af4158015611ac1573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610f5d919061521b565b6040805180820182525f80825260208201529051635f82401f60e01b81526004810183905273d6e890c615d6f99681a00771c20ed0451628889890635f82401f906024016040805180830381865af4158015611b43573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610f5d9190615235565b611b6f612dd4565b6040516347817b3960e11b815273e4f0b9769ca04a6e3d93b5ba732b5ad80797d41190638f02f67290610e7f908490600401614611565b604051630d1f54ef60e31b8152600481018390526001600160a01b03821660248201525f9073d6e890c615d6f99681a00771c20ed04516288898906368faa778906044015b602060405180830381865af4158015611c06573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610f5a9190614fe4565b604051630f0ec5ad60e41b815273e4f0b9769ca04a6e3d93b5ba732b5ad80797d4119063f0ec5ad090611c6b9089908990899089908990899060040161524f565b5f6040518083038186803b158015611c81575f5ffd5b505af4158015611c93573d5f5f3e3d5ffd5b50505050505050505050565b60405163039fc50f60e31b81526004810182905260609073e4f0b9769ca04a6e3d93b5ba732b5ad80797d41190631cfe2878906024015f60405180830381865af4158015611cef573d5f5f3e3d5ffd5b505050506040513d5f823e601f3d908101601f19168201604052610f5d91908101906152b2565b611d1e612dd4565b6119fb5f61303a565b5f611d30612e6d565b546001600160801b0316919050565b5f611d48612db0565b60040154919050565b60048054604051630a8f70b360e31b815273516f010c9ab452d70e0c6f78b9e698249a66d2ac9263547b859892611d9c928c928c928c928c928c928c928c9260ff90921691016153ac565b5f6040518083038186803b158015611db2575f5ffd5b505af4158015611dc4573d5f5f3e3d5ffd5b5050505050505050505050565b611dd9613ca6565b610f5d611de58361308b565b61309f565b5f610f5d8261310b565b60405163e0fae2a960e01b8152600481018290525f90819073e4f0b9769ca04a6e3d93b5ba732b5ad80797d4119063e0fae2a9906024015b6040805180830381865af4158015611e46573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611e6a9190615453565b91509150915091565b5f73d6e890c615d6f99681a00771c20ed0451628889863e068d95a611e98858561107d565b6040518263ffffffff1660e01b8152600401611beb9190613eab565b5f5f611ebe612e91565b600201546001600160a01b03169150611eec611ed8612e91565b60020154600160a01b900463ffffffff1690565b90509091565b5f73e4f0b9769ca04a6e3d93b5ba732b5ad80797d411637afeed28611411846127af565b5f73e4f0b9769ca04a6e3d93b5ba732b5ad80797d411637de3ca896040518163ffffffff1660e01b8152600401602060405180830381865af4158015610ffa573d5f5f3e3d5ffd5b5f6060805f5f5f6060611f6f61312c565b611f77613158565b604080515f80825260208201909252600f60f81b9b939a50919850469750309650945092509050565b5f611fa9612db0565b6005015464010000000090046001600160a01b0316919050565b5f73d6e890c615d6f99681a00771c20ed045162888986386a0d7636040518163ffffffff1660e01b8152600401602060405180830381865af4158015610ffa573d5f5f3e3d5ffd5b6040516343c4d09960e11b81525f9073d6e890c615d6f99681a00771c20ed0451628889890638789a1329061142f908590600401613eb9565b604080518082019091525f808252602082015261101e612062612db0565b54612ec8565b5f612071612e91565b60080154600160401b900460ff16919050565b5f61208d612db0565b600601546001600160a01b0316919050565b5f61101e42613185565b606061101e610983612520565b5f610f5d826131dc565b5f61101e611706612db0565b6120d4613cd0565b604051634e501b8160e11b81526004810183905273e4f0b9769ca04a6e3d93b5ba732b5ad80797d41190639ca037029060240161016060405180830381865af4158015612123573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610f5d9190615475565b6004805460405163f711e6c360e01b81526060925f92849273516f010c9ab452d70e0c6f78b9e698249a66d2ac9263f711e6c39261218d928a928a9260ff169101615502565b5f60405180830381865af41580156121a7573d5f5f3e3d5ffd5b505050506040513d5f823e601f3d908101601f191682016040526121ce9190810190615582565b9250925092509250925092565b73516f010c9ab452d70e0c6f78b9e698249a66d2ac639f2b31546040518163ffffffff1660e01b81526004015f6040518083038186803b158015611065575f5ffd5b5f612226612e91565b546001600160a01b0316919050565b5f73e4f0b9769ca04a6e3d93b5ba732b5ad80797d41163a22947486040518163ffffffff1660e01b8152600401602060405180830381865af415801561227d573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061101e9190615058565b6122a9612dd4565b6122b2816131ee565b50565b5f6122be612db0565b600901546001600160a01b0316919050565b6040516353fc732360e11b8152600481018290525f9073e4f0b9769ca04a6e3d93b5ba732b5ad80797d4119063a7f8e6469060240161116f565b5f612313612e91565b6003015f9054906101000a90046001600160a01b03166001600160a01b031663b4ac45366040518163ffffffff1660e01b8152600401602060405180830381865afa158015610ffa573d5f5f3e3d5ffd5b5f5f73e4f0b9769ca04a6e3d93b5ba732b5ad80797d41163ae36b7be8686866040518463ffffffff1660e01b81526004016123a1939291906150c0565b6040805180830381865af41580156123bb573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906123df9190615453565b91509150935093915050565b60405163029553b560e21b815273e4f0b9769ca04a6e3d93b5ba732b5ad80797d41190630a554ed4906124289087908790879087906004016156e0565b5f6040518083038186803b15801561243e575f5ffd5b505af4158015612450573d5f5f3e3d5ffd5b5050505050505050565b6040516333ab76ab60e01b815273e4f0b9769ca04a6e3d93b5ba732b5ad80797d411906333ab76ab906124959086908690869060040161571c565b5f6040518083038186803b1580156124ab575f5ffd5b505af41580156124bd573d5f5f3e3d5ffd5b50505050505050565b5f6124cf612e91565b6003015f9054906101000a90046001600160a01b03166001600160a01b031663dbc857526040518163ffffffff1660e01b8152600401602060405180830381865afa158015610ffa573d5f5f3e3d5ffd5b5f61101e42613338565b5f610f5d82613390565b73516f010c9ab452d70e0c6f78b9e698249a66d2ac63f436059e6040518060a001604052808b80360381019061256a9190615777565b8152602001868152602001612580426001611e73565b815260200185815260200184815250898989896040518663ffffffff1660e01b81526004016125b3959493929190615823565b5f6040518083038186803b1580156125c9575f5ffd5b505af41580156125db573d5f5f3e3d5ffd5b505050505050505050505050565b5f73e4f0b9769ca04a6e3d93b5ba732b5ad80797d41163c27f08b561260d84613390565b6040518263ffffffff1660e01b815260040161116f91815260200190565b73e4f0b9769ca04a6e3d93b5ba732b5ad80797d41163c2cac49d6040518163ffffffff1660e01b81526004015f6040518083038186803b158015611065575f5ffd5b604051631174ed2f60e21b815260609073516f010c9ab452d70e0c6f78b9e698249a66d2ac906345d3b4bc906126b3908b908b908b908b908b908b908b9060040161595d565b5f60405180830381865af41580156126cd573d5f5f3e3d5ffd5b505050506040513d5f823e601f3d908101601f191682016040526126f491908101906159d5565b98975050505050505050565b5f73e4f0b9769ca04a6e3d93b5ba732b5ad80797d41163c30d876c6040518163ffffffff1660e01b8152600401602060405180830381865af4158015610ffa573d5f5f3e3d5ffd5b5f612751612e6d565b54600160801b900463ffffffff16919050565b60405163c7523d7960e01b81525f9073d6e890c615d6f99681a00771c20ed045162888989063c7523d799061142f908590600401613eb9565b5f6127a6612db0565b60030154919050565b5f610f5d82613338565b5f73e4f0b9769ca04a6e3d93b5ba732b5ad80797d41163ca3dc9ec6040518163ffffffff1660e01b8152600401602060405180830381865af4158015610ffa573d5f5f3e3d5ffd5b5f73d6e890c615d6f99681a00771c20ed0451628889863cf20d8726040518163ffffffff1660e01b8152600401602060405180830381865af415801561227d573d5f5f3e3d5ffd5b5f610f5d826133c0565b5f61285c612e91565b600101546001600160a01b0316919050565b604051636bb46fb760e11b81525f9073d6e890c615d6f99681a00771c20ed045162888989063d768df6e90611beb9086908690600401615a0e565b5f61101e42613390565b604051633706ee3d60e21b8152600481018290525f9073d6e890c615d6f99681a00771c20ed045162888989063dc1bb8f490602401602060405180830381865af4158015612903573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610f5d9190614cb8565b6040516337ffcfaf60e21b81525f9073d6e890c615d6f99681a00771c20ed045162888989063dfff3ebc9061142f908590600401613eb9565b5f612969612e91565b60010154600160a01b90046001600160601b0316919050565b5f5f73e4f0b9769ca04a6e3d93b5ba732b5ad80797d41163e0fae2a96129a7856127af565b6040518263ffffffff1660e01b8152600401611e2c91815260200190565b60405163e199c05960e01b81526004810182905273e4f0b9769ca04a6e3d93b5ba732b5ad80797d4119063e199c05990602401610e7f565b73e4f0b9769ca04a6e3d93b5ba732b5ad80797d41163e3380b796040518163ffffffff1660e01b81526004015f6040518083038186803b158015611065575f5ffd5b5f73e4f0b9769ca04a6e3d93b5ba732b5ad80797d41163e3682cde6040518163ffffffff1660e01b8152600401602060405180830381865af4158015610ffa573d5f5f3e3d5ffd5b604080516080810182525f8183018181526060830182905282526020820152905163e48a5f7b60e01b815273e4f0b9769ca04a6e3d93b5ba732b5ad80797d4119063e48a5f7b90612adc908590600401613eb9565b606060405180830381865af4158015612af7573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610f5d9190615a63565b612b23612dd4565b5f612b3c612b2f6133f5565b5460c01c63ffffffff1690565b9050808281811015612b6f57604051630d1bff9560e21b8152600481019290925260248201526044015b60405180910390fd5b5050612b7a82613419565b60405182907faaa1053539ab4621b2aecf54a7ccf2096610ff768f32261f667aca9ae3069482905f90a25050565b612bb0612dd4565b604051633ae0282560e21b815273e4f0b9769ca04a6e3d93b5ba732b5ad80797d4119063eb80a09490610e7f908490600401613eb9565b604080516080810182525f80825260208201819052918101829052606081019190915273d6e890c615d6f99681a00771c20ed0451628889863ec1478066040518163ffffffff1660e01b8152600401608060405180830381865af4158015612c51573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061101e9190615a7d565b5f612c7e612e91565b600301546001600160a01b0316919050565b5f73e4f0b9769ca04a6e3d93b5ba732b5ad80797d411637afeed2861170d612520565b60405163771dc6e160e11b81526001600160a01b038084166004830152821660248201525f9073e4f0b9769ca04a6e3d93b5ba732b5ad80797d4119063ee3b8dc290604401610f1b565b5f5f612d07612e91565b60080154600160481b90046001600160a01b03169150611eec612d28612e91565b6009015463ffffffff1690565b612d3d612dd4565b6001600160a01b038116612d66575f604051631e4fbdf760e01b8152600401612b669190613eb9565b6122b28161303a565b604051637c2a4a6f60e11b815273e4f0b9769ca04a6e3d93b5ba732b5ad80797d4119063f85494de90610e7f908490600401613eb9565b5f610f5d82613026565b7f0958201b72d64259285941dffd868dac55267471fcc73e8a06e1fd9cf870636190565b6002546001600160a01b031633146119fb573360405163118cdaa760e01b8152600401612b669190613eb9565b612e09613d6c565b610f5d612e1583613472565b6040805160e08101825282548152600183015460208201526002830154918101919091526003820154606082015260048201546080820152600582015463ffffffff1660a082015260069091015460c082015261350e565b7fcc2bde3d21ba778aa5c156bb6fc47381978b0054c8a1ef73f44234164324cbe090565b7fbba4a4d3c3eeb229c4f06863ce3d3d8cddab9e4dee538d785fc67e2ed9d68cad90565b5f610f5a8364e8d4a5100084600161357b565b604080518082019091525f80825260208201526040518060400160405280612ef08460801c90565b81526020016001600160801b0384165b905292915050565b5f612f1242613390565b90505f612f1d6133f5565b60018101549091505f90612f4990600160e01b900463ffffffff16612f44600560026135c6565b6135d1565b905082811115612f5857505050565b604080516060810182526001840154600160701b90046001600160701b03168152815180830190925248825290602080830191612fa0918101612f996135dc565b90526136d9565b6001600160701b03168152602001612fc1612fbc8660026135d1565b61371e565b63ffffffff9081169091528151600190940180546020840151604090940151909216600160e01b026001600160e01b036001600160701b03948516600160701b026001600160e01b031990941694909616939093179190911793909316179091555050565b5f61303082613472565b6001015492915050565b600280546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0905f90a35050565b5f61309582613472565b6006015492915050565b6130a7613ca6565b506040805160a081018252602083811c65ffffffffffff908116835263ffffffff851691830191909152605084901c1691810191909152608082811c6001600160401b0316606083015260c09290921c677fffffffffffffff169181019190915290565b5f613114612e6d565b54610f5d90600160a01b900463ffffffff1683615b00565b606061101e7f417a74656320526f6c6c7570000000000000000000000000000000000000000c5f613728565b606061101e7f31000000000000000000000000000000000000000000000000000000000000016001613728565b5f61318e612e91565b6003015460405163ec6e69db60e01b81526001600160a01b039091169063ec6e69db906131c1903090869060040161461f565b602060405180830381865afa15801561144a573d5f5f3e3d5ffd5b5f610f5d6131e9836137d1565b6133c0565b5f6131f76133f5565b90505f613206825f01546137f2565b6040810151909150838060028082101561323c57604051631ad480f960e11b815260048101929092526024820152604401612b66565b505060028401545f9061325c9062278d00906001600160401b0316615b13565b60028601549091506001600160401b031615806132795750804210155b819061329b576040516344331fd960e01b8152600401612b6691815260200190565b506132a7600384615b26565b6132b2600284615b26565b111580156132d457506132c6600284615b26565b6132d1600384615b26565b10155b838390916132fe57604051637e42087560e01b815260048101929092526024820152604401612b66565b5050604084018690526133108461385a565b85555050506002909101805467ffffffffffffffff1916426001600160401b03161790555050565b5f5f613342612e6d565b80549091506133679063ffffffff600160801b8204811691600160a01b900416615b3d565b815463ffffffff9190911690613386906001600160801b031685615b5c565b61163f9190615b00565b5f5f61339a612e6d565b805490915063ffffffff600160801b82041690613386906001600160801b031685615b5c565b5f5f6133ca612e6d565b805490915061163f906001600160801b03811690612f4490600160801b900463ffffffff1686615b26565b7f2e57d696f4035f6dfbf369d367f6b4aaf23baac5f6ee9a3a5207d71c56de652c90565b613422816138b4565b505f61342c6133f5565b90505f61343b825f01546137f2565b83815290506305f5e1006134536332f1b33685615b26565b61345d9190615b00565b602082015261346b8161385a565b9091555050565b5f5f61347f611706612db0565b90505f61348a61392e565b90505f6134978286615b13565b90505f8386111580156134a957508184105b9050858483836134dd57604051638711786b60e01b8152600481019390935260248301919091526044820152606401612b66565b5050506134e8612db0565b6002015f6134f68589615b6f565b81526020019081526020015f20945050505050919050565b613516613d6c565b6040518060e00160405280835f01518152602001836020015181526020018360400151815260200183606001518152602001836080015181526020016135698460a0015163ffffffff1663ffffffff1690565b8152602001612f008460c0015161309f565b5f6135a861358883613942565b80156135a357505f848061359e5761359e615ad8565b868809115b151590565b6135b386868661396e565b6135bd9190615b13565b95945050505050565b5f610f5a8284615b5c565b5f610f5a8284615b13565b5f617a6946148080156136035750737109709ecfa91a80626ff3989d68f67f5b1dd12d3b15155b156136d15760408051600481526024810182526020810180516001600160e01b0316631f6d6ef760e01b17905290515f918291737109709ecfa91a80626ff3989d68f67f5b1dd12d9161365591615b82565b5f60405180830381855afa9150503d805f811461368d576040519150601f19603f3d011682016040523d82523d5f602084013e613692565b606091505b50915091508180156136a657506020815110155b156136c757808060200190518101906136bf9190614fe4565b935050505090565b6001935050505090565b4a5b91505090565b5f5f5f90505f6136ec8460200151613a24565b66ffffffffffffff16901b811790506038613709845f0151613a24565b66ffffffffffffff16901b1761163f81613a5b565b5f610f5d82613a8e565b606060ff83146137425761373b83613abe565b9050610f5d565b81805461374e90615b98565b80601f016020809104026020016040519081016040528092919081815260200182805461377a90615b98565b80156137c55780601f1061379c576101008083540402835291602001916137c5565b820191905f5260205f20905b8154815290600101906020018083116137a857829003601f168201915b50505050509050610f5d565b5f6137da612e6d565b54610f5d90600160a01b900463ffffffff1683615b26565b61381360405180606001604052805f81526020015f81526020015f81525090565b604051806060016040528061382e8460c01c63ffffffff1690565b81526020016138468460401c6001600160801b031690565b81526020016001600160401b038416612f00565b5f5f5f905061386c8360400151613afb565b6001600160401b03168117905060406138888460200151613b30565b6001600160801b0316901b8117905060c06138a5845f0151613a8e565b63ffffffff16901b1792915050565b5f600182806138df576040516372e1574f60e01b815260048101929092526024820152604401612b66565b505f90506138ee836002615b26565b905063ffffffff8181811115613925576040516303fd5c0b60e41b815263ffffffff90921660048301526024820152604401612b66565b50909392505050565b5f613937613b63565b61101e906001615b13565b5f60028260038111156139575761395761411f565b6139619190615bd0565b60ff166001149050919050565b5f838302815f1985870982811083820303915050805f036139a25783828161399857613998615ad8565b049250505061163f565b8084116139b9576139b96003851502601118613ba3565b5f848688095f868103871696879004966002600389028118808a02820302808a02820302808a02820302808a02820302808a02820302808a02909103029181900381900460010186841190950394909402919094039290920491909117919091029150509392505050565b5f66ffffffffffffff821115613a57576040516306dfcc6560e41b81526038600482015260248101839052604401612b66565b5090565b5f6001600160701b03821115613a57576040516306dfcc6560e41b81526070600482015260248101839052604401612b66565b5f63ffffffff821115613a57576040516306dfcc6560e41b81526020600482015260248101839052604401612b66565b60605f613aca83613bb4565b6040805160208082528183019092529192505f91906020820181803683375050509182525060208101929092525090565b5f6001600160401b03821115613a5757604080516306dfcc6560e41b8152600481019190915260248101839052604401612b66565b5f6001600160801b03821115613a57576040516306dfcc6560e41b81526080600482015260248101839052604401612b66565b5f5f613b6d612e6d565b8054909150613b8a90600160c01b900463ffffffff166001615b13565b81546136d39190600160a01b900463ffffffff16615b26565b634e487b715f52806020526024601cfd5b5f60ff8216601f811115610f5d57604051632cd44ac360e21b815260040160405180910390fd5b6040518061010001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f8152602001613c19613ca6565b905290565b604080516080810182525f8082526020820152908101613c3c613c69565b8152602001613c19604080516080810182525f918101828152606082018390528152602081019190915290565b6040518060c001604052805f81526020015f81526020015f81526020015f6001600160a01b031681526020015f151581526020015f151581525090565b6040518060a001604052805f81526020015f81526020015f81526020015f81526020015f81525090565b6040518060c001604052805f6001600160a01b031681526020015f6001600160a01b03168152602001613d1460405180604001604052805f81526020015f81525090565b8152602001613d4060405180608001604052805f81526020015f81526020015f81526020015f81525090565b8152602001613d6060405180604001604052805f81526020015f81525090565b81525f60209091015290565b6040518060e001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f8152602001613c19613ca6565b5f60208284031215613db3575f5ffd5b5035919050565b6001600160a01b03811681146122b2575f5ffd5b8035613dd981613dba565b919050565b5f5f60408385031215613def575f5ffd5b8235613dfa81613dba565b946020939093013593505050565b5f60208284031215613e18575f5ffd5b81356001600160401b03811115613e2d575f5ffd5b8201610140818503121561163f575f5ffd5b80151581146122b2575f5ffd5b8035613dd981613e3f565b5f5f60408385031215613e68575f5ffd5b823591506020830135613e7a81613e3f565b809150509250929050565b805182526020810151602083015260408101516040830152606081015160608301525050565b60808101610f5d8284613e85565b6001600160a01b0391909116815260200190565b634e487b7160e01b5f52604160045260245ffd5b604080519081016001600160401b0381118282101715613f0357613f03613ecd565b60405290565b604051608081016001600160401b0381118282101715613f0357613f03613ecd565b604051606081016001600160401b0381118282101715613f0357613f03613ecd565b60405160c081016001600160401b0381118282101715613f0357613f03613ecd565b60405161018081016001600160401b0381118282101715613f0357613f03613ecd565b604051601f8201601f191681016001600160401b0381118282101715613fba57613fba613ecd565b604052919050565b63ffffffff811681146122b2575f5ffd5b6001600160601b03811681146122b2575f5ffd5b5f6040828403128015613ff8575f5ffd5b50614001613ee1565b823561400c81613fc2565b8152602083013561401c81613fd3565b60208201529392505050565b602080825282518282018190525f918401906040840190835b818110156140685783516001600160a01b0316835260209384019390920191600101614041565b509095945050505050565b80518252602081015160208301526040810151604083015260608101516060830152608081015160808301525050565b5f61018082019050825182526020830151602083015260408301516040830152606083015160608301526080830151608083015260a083015160a083015260c083015160c083015260e08301516140fd60e0840182614073565b5092915050565b5f60208284031215614114575f5ffd5b813561163f81613dba565b634e487b7160e01b5f52602160045260245ffd5b6004811061414f57634e487b7160e01b5f52602160045260245ffd5b9052565b60208101610f5d8284614133565b5f5f5f60608486031215614173575f5ffd5b8335925060208401359150604084013561418c81613dba565b809150509250925092565b8051825260208082015190830152604080820151908301526060808201516001600160a01b03169083015260808082015115159083015260a0908101511515910152565b6141f082825180518252602090810151910152565b602001516001600160a01b031660409190910152565b5f61016082019050614219828451614133565b6020830151602083015260408301516142356040840182614197565b5060608301516140fd6101008401826141db565b60c08101610f5d8284614197565b815181526020808301519082015260408101610f5d565b5f60a082840312801561427f575f5ffd5b5060405160a081016001600160401b03811182821017156142a2576142a2613ecd565b604090815283358252602080850135908301528381013590820152606080840135908201526080928301359281019290925250919050565b5f5f604083850312156142eb575f5ffd5b823591506020830135613e7a81613dba565b5f6040828403121561430d575f5ffd5b614315613ee1565b823581526020928301359281019290925250919050565b5f5f5f5f5f5f868803610160811215614343575f5ffd5b873561434e81613dba565b9650602088013561435e81613dba565b955061436d8960408a016142fd565b94506080607f1982011215614380575f5ffd5b50614389613f09565b6080880135815260a0880135602082015260c0880135604082015260e0880135606082015292506143be8861010089016142fd565b91506143cd6101408801613e4c565b90509295509295509295565b5f6001600160401b038211156143f1576143f1613ecd565b50601f01601f191660200190565b5f82601f83011261440e575f5ffd5b813561442161441c826143d9565b613f92565b818152846020838601011115614435575f5ffd5b816020850160208301375f918101602001919091529392505050565b5f60408284031215614461575f5ffd5b614469613ee1565b905081356001600160401b03811115614480575f5ffd5b61448c848285016143ff565b82525060208201356001600160401b038111156144a7575f5ffd5b6144b3848285016143ff565b60208301525092915050565b5f5f83601f8401126144cf575f5ffd5b5081356001600160401b038111156144e5575f5ffd5b6020830191508360208260051b85010111156144ff575f5ffd5b9250929050565b5f5f83601f840112614516575f5ffd5b5081356001600160401b0381111561452c575f5ffd5b6020830191508360208285010111156144ff575f5ffd5b5f5f5f5f5f5f5f8789036102a081121561455b575f5ffd5b6101e0811215614569575f5ffd5b8897506101e08901356001600160401b03811115614585575f5ffd5b6145918b828c01614451565b9750506102008901356001600160401b038111156145ad575f5ffd5b6145b98b828c016144bf565b909750955050606061021f19820112156145d1575f5ffd5b50610220880192506102808801356001600160401b038111156145f2575f5ffd5b6145fe8a828b01614506565b989b979a50959850939692959293505050565b60a08101610f5d8284614073565b6001600160a01b03929092168252602082015260400190565b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b60ff60f81b8816815260e060208201525f61468460e0830189614638565b82810360408401526146968189614638565b606084018890526001600160a01b038716608085015260a0840186905283810360c0850152845180825260208087019350909101905f5b818110156146eb5783518352602093840193909201916001016146cd565b50909b9a5050505050505050505050565b81516001600160a01b0390811682526020808401519091169082015260408083015161016083019161473a9084018280518252602090810151910152565b50606083015161474d6080840182613e85565b50608083015180516101008401526020015161012083015260a09092015115156101409091015290565b5f5f60208385031215614788575f5ffd5b82356001600160401b0381111561479d575f5ffd5b6147a985828601614506565b90969095509350505050565b5f8151808452602084019350602083015f5b828110156147e55781518652602095860195909101906001016147c7565b5093949350505050565b606081525f61480160608301866147b5565b846020840152828103604084015280845180835260208301915060208160051b840101602087015f5b8381101561485c57601f19868403018552614846838351614638565b602095860195909350919091019060010161482a565b50909998505050505050505050565b5f6001600160401b0382111561488357614883613ecd565b5060051b60200190565b5f82601f83011261489c575f5ffd5b81356148aa61441c8261486b565b8082825260208201915060208360051b8601019250858311156148cb575f5ffd5b602085015b838110156148f15780356148e381613dba565b8352602092830192016148d0565b5095945050505050565b5f5f5f5f6080858703121561490e575f5ffd5b8435935060208501356001600160401b0381111561492a575f5ffd5b61493687828801614451565b93505060408501356001600160401b03811115614951575f5ffd5b61495d8782880161488d565b949793965093946060013593505050565b5f5f5f60608486031215614980575f5ffd5b8335925060208401356001600160401b0381111561499c575f5ffd5b6149a886828701614451565b92505060408401356001600160401b038111156149c3575f5ffd5b6149cf8682870161488d565b9150509250925092565b803560ff81168114613dd9575f5ffd5b5f602082840312156149f9575f5ffd5b604051602081016001600160401b0381118282101715614a1b57614a1b613ecd565b6040529050808235612f0081613e3f565b5f5f5f5f5f5f5f5f888a036102a0811215614a45575f5ffd5b6101a0811215614a53575f5ffd5b8998506101a08a01356001600160401b03811115614a6f575f5ffd5b614a7b8c828d01614451565b9850506101c08a01356001600160401b03811115614a97575f5ffd5b614aa38c828d016144bf565b90985096505060606101df1982011215614abb575f5ffd5b50614ac4613f2b565b614ad16101e08b016149d9565b81526102008a013560208201526102208a01356040820152935061024089013592506102608901359150614b098a6102808b016149e9565b90509295985092959890939650565b5f5f5f5f5f5f5f878903610100811215614b30575f5ffd5b88359750602089013596506080603f1982011215614b4c575f5ffd5b5060408801945060c08801356001600160401b03811115614b6b575f5ffd5b8801601f81018a13614b7b575f5ffd5b80356001600160401b03811115614b90575f5ffd5b8a60206101a083028401011115614ba5575f5ffd5b6020919091019450925060e08801356001600160401b038111156145f2575f5ffd5b602081525f610f5a60208301846147b5565b5f5f60408385031215614bea575f5ffd5b8235614bf581613dba565b915060208301356001600160401b03811115614c0f575f5ffd5b8301601f81018513614c1f575f5ffd5b8035614c2d61441c8261486b565b8082825260208201915060208360051b850101925087831115614c4e575f5ffd5b6020840193505b82841015614c70578335825260209384019390910190614c55565b809450505050509250929050565b60608101610f5d82846141db565b5f5f60408385031215614c9d575f5ffd5b8235614ca881613dba565b91506020830135613e7a81613dba565b5f60208284031215614cc8575f5ffd5b815161163f81613e3f565b8035825260208082013590830152604080820135908301526060810135614cf981613dba565b6001600160a01b03166060929092019190915250565b80356001600160801b0381168114613dd9575f5ffd5b6001600160801b03614d3682614d0f565b1682526001600160801b03614d4d60208301614d0f565b1660208301525050565b803582526020808201359083015260408082013590830152606080820135908301526080808201359083015260a0808201359083015260c08082013590830152614da360e08201613dce565b6001600160a01b031660e08301526101008181013590830152614dcd610120808401908301614d25565b610160818101359083015261018090810135910152565b8183526020830192505f815f5b848110156147e557614e038683614d57565b6101a0958601959190910190600101614df1565b5f8235603e19833603018112614e2b575f5ffd5b90910192915050565b5f5f8335601e19843603018112614e49575f5ffd5b83016020810192503590506001600160401b03811115614e67575f5ffd5b8036038213156144ff575f5ffd5b81835281816020850137505f828201602090810191909152601f909101601f19169091010190565b5f614ea88283614e34565b60408552614eba604086018284614e75565b915050614eca6020840184614e34565b8583036020870152614edd838284614e75565b9695505050505050565b60208082528235828201528201356040808301919091525f90614f109060608401908501614cd3565b60c0830135601e19843603018112614f26575f5ffd5b83016020810190356001600160401b03811115614f41575f5ffd5b6101a081023603821315614f53575f5ffd5b61014060e0850152614f6a61016085018284614de4565b915050614f7a60e0850185614e17565b838203601f1901610100850152614f918282614e9d565b915050614fa2610100850185614e34565b848303601f1901610120860152614fba838284614e75565b92505050614fcc610120850185614e34565b848303601f1901610140860152614edd838284614e75565b5f60208284031215614ff4575f5ffd5b5051919050565b5f6080828403121561500b575f5ffd5b615013613f09565b8251815260208084015190820152604080840151908201526060928301519281019290925250919050565b5f6080828403121561504e575f5ffd5b610f5a8383614ffb565b5f60208284031215615068575f5ffd5b815161163f81613dba565b815163ffffffff1681526020808301516001600160601b03169082015260408101610f5d565b805160048110613dd9575f5ffd5b5f602082840312156150b7575f5ffd5b610f5a82615099565b92835260208301919091526001600160a01b0316604082015260600190565b5f60c082840312156150ef575f5ffd5b6150f7613f4d565b825181526020808401519082015260408084015190820152606083015190915061512081613dba565b6060820152608082015161513381613e3f565b608082015260a082015161514681613e3f565b60a082015292915050565b5f60408284031215615161575f5ffd5b615169613ee1565b825181526020928301519281019290925250919050565b5f60608284031215615190575f5ffd5b615198613ee1565b90506151a48383615151565b815260408201516151b481613dba565b602082015292915050565b5f6101608284031280156151d1575f5ffd5b506151da613f09565b6151e383615099565b8152602083810151908201526151fc84604085016150df565b604082015261520f846101008501615180565b60608201529392505050565b5f60c0828403121561522b575f5ffd5b610f5a83836150df565b5f60408284031215615245575f5ffd5b610f5a8383615151565b6001600160a01b03878116825286166020820152610160810161527f604083018780518252602090810151910152565b61528c6080830186613e85565b835161010083015260209093015161012082015290151561014090910152949350505050565b5f602082840312156152c2575f5ffd5b81516001600160401b038111156152d7575f5ffd5b8201601f810184136152e7575f5ffd5b80516152f561441c8261486b565b8082825260208201915060208360051b850101925086831115615316575f5ffd5b6020840193505b82841015614edd57835161533081613dba565b82526020938401939091019061531d565b5f8151604084526153556040850182614638565b9050602083015184820360208601526135bd8282614638565b8183526020830192505f815f5b848110156147e557813561538e81613dba565b6001600160a01b03168652602095860195919091019060010161537b565b883581526020808a0135908201525f6153cb6040808401908c01614d57565b6102c06101e08301526153e26102c083018a615341565b8281036102008401526153f681898b61536e565b905060ff615403886149d9565b1661022084015260208701356102408401526040870135610260840152828103610280840152615434818688614e75565b9150506154466102a083018415159052565b9998505050505050505050565b5f5f60408385031215615464575f5ffd5b505080516020909101519092909150565b5f610160828403128015615487575f5ffd5b50615490613f4d565b825161549b81613dba565b815260208301516154ab81613dba565b60208201526154bd8460408501615151565b60408201526154cf8460808501614ffb565b60608201526154e2846101008501615151565b60808201526101408301516154f681613e3f565b60a08201529392505050565b604081525f615515604083018587614e75565b90508215156020830152949350505050565b5f82601f830112615536575f5ffd5b815161554461441c8261486b565b8082825260208201915060208360051b860101925085831115615565575f5ffd5b602085015b838110156148f157805183526020928301920161556a565b5f5f5f60608486031215615594575f5ffd5b83516001600160401b038111156155a9575f5ffd5b6155b586828701615527565b60208601516040870151919550935090506001600160401b038111156155d9575f5ffd5b8401601f810186136155e9575f5ffd5b80516155f761441c8261486b565b8082825260208201915060208360051b850101925088831115615618575f5ffd5b602084015b838110156156985780516001600160401b0381111561563a575f5ffd5b8501603f81018b1361564a575f5ffd5b602081015161565b61441c826143d9565b8181526040838301018d101561566f575f5ffd5b8160408401602083015e5f6020838301015280865250505060208301925060208101905061561d565b50809450505050509250925092565b5f8151808452602084019350602083015f5b828110156147e55781516001600160a01b03168652602095860195909101906001016156b9565b848152608060208201525f6156f86080830186615341565b828103604084015261570a81866156a7565b91505082606083015295945050505050565b838152606060208201525f6157346060830185615341565b8281036040840152614edd81856156a7565b5f60408284031215615756575f5ffd5b61575e613ee1565b905061576982614d0f565b81526151b460208301614d0f565b5f6101a0828403128015615789575f5ffd5b50615792613f6f565b823581526020808401359082015260408084013590820152606080840135908201526080808401359082015260a0808401359082015260c080840135908201526157de60e08401613dce565b60e082015261010083810135908201526157fc846101208501615746565b61012082015261016083810135610140830152610180909301359281019290925250919050565b5f8651805183526020810151602084015260408101516040840152606081015160608401526080810151608084015260a081015160a084015260c081015160c084015260e081015161588060e08501826001600160a01b03169052565b506101008101516101008401526101208101516158b761012085018280516001600160801b03908116835260209182015116910152565b506101408101516101608401526101608101516101808401525060208701516101a083015260408701516101c083015260608701516101e083015260808701516159076102008401825115159052565b506102c061022083015261591f6102c0830187615341565b82810361024084015261593381868861536e565b845160ff16610260850152602085015161028085015260408501516102a08501529150614edd9050565b5f61010082018983528860208401526159796040840189614cd3565b61010060c08401528590528561012083015f5b878110156159b25761599e8284614d57565b6101a092830192919091019060010161598c565b5083810360e08501526159c6818688614e75565b9b9a5050505050505050505050565b5f602082840312156159e5575f5ffd5b81516001600160401b038111156159fa575f5ffd5b615a0684828501615527565b949350505050565b6001600160a01b03831681526040602080830182905283519183018290525f91908401906060840190835b81811015615a57578351835260209384019390920191600101615a39565b50909695505050505050565b5f60608284031215615a73575f5ffd5b610f5a8383615180565b5f6080828403128015615a8e575f5ffd5b50615a97613f09565b8251615aa281613dba565b81526020830151615ab281613fc2565b60208201526040830151615ac581613dba565b6040820152606083015161520f81613fd3565b634e487b7160e01b5f52601260045260245ffd5b634e487b7160e01b5f52601160045260245ffd5b5f82615b0e57615b0e615ad8565b500490565b80820180821115610f5d57610f5d615aec565b8082028115828204841417610f5d57610f5d615aec565b63ffffffff81811683821602908116908181146140fd576140fd615aec565b81810381811115610f5d57610f5d615aec565b5f82615b7d57615b7d615ad8565b500690565b5f82518060208501845e5f920191825250919050565b600181811c90821680615bac57607f821691505b602082108103615bca57634e487b7160e01b5f52602260045260245ffd5b50919050565b5f60ff831680615be257615be2615ad8565b8060ff8416069150509291505056fea2646970667358221220fc8126ba8b35174b1c0c00e123ea7418dc33eff02983da448f022fbf1fdb5a3f64736f6c634300081e0033","storage":{"0x44d338c3c657f55bfc66dd486699dd11b07387331cdbf4ae6d6a52c36490cf92":"0x0000000000000000000000000000000000000000000000000000000000000000","0x44d338c3c657f55bfc66dd486699dd11b07387331cdbf4ae6d6a52c36490cf93":"0x0000000000000000000000000000000000000000000000000000000000000000","0x44d338c3c657f55bfc66dd486699dd11b07387331cdbf4ae6d6a52c36490cf94":"0x0000000000000000000000000000000000000000000000000000000000000000","0x44d338c3c657f55bfc66dd486699dd11b07387331cdbf4ae6d6a52c36490cf95":"0x0000000000000000000000000000000000000000000000000000000000000000","0x65e1013f050426e117df94dd011a8bc86d5ce5bb69bb6886a088ee83873c28b4":"0x0000000000000000000000000000000000000000000000000000000000000000","0x65e1013f050426e117df94dd011a8bc86d5ce5bb69bb6886a088ee83873c28b5":"0x0000000000000000000000000000000000000000000000000000000000000000","0x65e1013f050426e117df94dd011a8bc86d5ce5bb69bb6886a088ee83873c28b6":"0x0000000000000000000000000000000000000000000000000000000000000000","0x65e1013f050426e117df94dd011a8bc86d5ce5bb69bb6886a088ee83873c28b7":"0x0000000000000000000000000000000000000000000000000000000000000000","0xbba4a4d3c3eeb229c4f06863ce3d3d8cddab9e4dee538d785fc67e2ed9d68cb0":"0x000000000000000000054600a92ecfd0e70c9cd5e5cd76c50af0f7da93567a4f","0xcd7da8b1adc10f2337cb408d08575af119c2ab912052d8dd2e079547ac7a89b6":"0x0000000000000000000000000000000000000000000000000000000000000000","0xcd7da8b1adc10f2337cb408d08575af119c2ab912052d8dd2e079547ac7a89b7":"0x0000000000000000000000000000000000000000000000000000000000000000","0xcd7da8b1adc10f2337cb408d08575af119c2ab912052d8dd2e079547ac7a89b8":"0x0000000000000000000000000000000000000000000000000000000000000000","0xcd7da8b1adc10f2337cb408d08575af119c2ab912052d8dd2e079547ac7a89b9":"0x0000000000000000000000000000000000000000000000000000000000000000"}},"0x9c8bf8fa4e88316ade54b201b64007afda68fab4":{"nonce":"0x1","balance":"0x0","code":"0x6080604052600a600c565b005b60186014601a565b6050565b565b5f604b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc546001600160a01b031690565b905090565b365f5f375f5f365f845af43d5f5f3e8080156069573d5ff35b3d5ffdfea2646970667358221220ff7a924880ea92a37f0c8e7854a593fcaec3ad0775a3ae0d1c087cd168a411d964736f6c634300081e0033","storage":{"0x0000000000000000000000000000000000000000000000000000000000000000":"0x0000000000000000000000001f37cf7a4bb4a54838b67d3a19a586230e8d0d34","0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc":"0x00000000000000000000000011ed6b4a9d44cf8bc4e1763d08304ef20c998c95"}},"0xa92ecfd0e70c9cd5e5cd76c50af0f7da93567a4f":{"nonce":"0x2","balance":"0x0","code":"0x608060405234801561000f575f5ffd5b506004361061023e575f3560e01c80636a91551611610135578063bb4d4436116100b4578063ec6e69db11610079578063ec6e69db14610658578063f2fde38b1461066b578063f3fef3a31461067e578063f7888aec146106ac578063f852fef9146106bf575f5ffd5b8063bb4d443614610550578063d3da927f14610563578063dbc8575214610576578063e48a5f7b1461059d578063eaeded5f14610645575f5ffd5b80639f6bc70c116100fa5780639f6bc70c146104e8578063a9cd26c9146104fb578063ab033ea91461050e578063b35186a814610521578063b4ac453614610529575f5ffd5b80636a91551614610489578063710ca3541461049c578063715018a6146104b05780638da5cb5b146104b85780639796d977146104c8575f5ffd5b80634800d97f116101c157806359264f001161018657806359264f001461042a57806362400e4c1461043d578063671431c3146104505780636902c67b146104635780636a18ff7a14610476575f5ffd5b80634800d97f1461037d5780634bd96ece146103a457806352097e4e146103d657806352f44a14146103e95780635338c75814610417575f5ffd5b806318160ddd1161020757806318160ddd14610310578063289b3c0d146103265780632e341ce01461033757806330eb4bdd1461034a5780633fd20fe11461035d575f5ffd5b806215eaaa146102425780630928d152146102725780630e9f7e43146102875780630f9f54101461029a57806311d66fee146102f0575b5f5ffd5b610255610250366004612d01565b6106f1565b6040516001600160a01b0390911681526020015b60405180910390f35b610285610280366004612d38565b610727565b005b610285610295366004612d4f565b610806565b6102556102a8366004612d75565b6001600160a01b039081165f90815260036020908152604091829020825160808101845281549381019384526001820154606082015292835260020154909216910181905290565b6103036102fe366004612eb4565b61083b565b6040516102699190612ece565b6103186108d6565b604051908152602001610269565b6008546001600160a01b0316610255565b610285610345366004612ee5565b6108e6565b610318610358366004612d01565b61099d565b61037061036b366004612f4f565b610bb7565b6040516102699190612fe3565b6102557f000000000000000000000000a27ec0006e59f245217ff08cd52a7e8b169e62d281565b6103c66103b2366004612d38565b60046020525f908152604090205460ff1681565b6040519015158152602001610269565b6102856103e4366004613057565b610cad565b6103c66103f7366004612d75565b6001600160a01b03165f9081526002602052604090206003015460ff1690565b610318610425366004612d01565b610d12565b610285610438366004612d75565b610d6e565b61031861044b366004612d75565b610e3d565b61031861045e366004613082565b610e49565b6102856104713660046130ac565b610e71565b610285610484366004613057565b611294565b610255610497366004612d38565b6112a0565b6102555f5160206135eb5f395f51905f5281565b6102856112c6565b5f546001600160a01b0316610255565b6104db6104d6366004613159565b6112d9565b6040516102699190613206565b5f5160206135eb5f395f51905f52610255565b610255610509366004613246565b6112ee565b61028561051c366004612d75565b61135f565b6102556113b2565b6103187f000000000000000000000000000000000000000000002a5a058fc295ed00000081565b61031861055e366004612d75565b6113c0565b6103c6610571366004612d01565b6113cc565b6103187f00000000000000000000000000000000000000000000152d02c7e14af680000081565b6106186105ab366004612d75565b604080516080810182525f9181018281526060820183905281526020810191909152506001600160a01b039081165f908152600360209081526040918290208251608081018452815493810193845260018201546060820152928352600201549092169181019190915290565b6040805182518051825260209081015181830152909201516001600160a01b031690820152606001610269565b610318610653366004613082565b6113fe565b610318610666366004613082565b61140b565b610285610679366004612d75565b6114b6565b61069161068c366004613082565b6114f3565b60408051938452911515602084015290820152606001610269565b6103186106ba366004612d01565b61179f565b6008546106d990600160a01b90046001600160401b031681565b6040516001600160401b039091168152602001610269565b6001600160a01b038083165f90815260056020908152604080832084861684529091528120600101549091165b90505b92915050565b5f61073a6008546001600160a01b031690565b604051634527d8b560e11b8152600481018490529091506001600160a01b03821690638a4fb16a90602401608060405180830381865afa158015610780573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906107a49190613283565b606001516108025760405163049468a960e11b8152600481018390526001600160a01b03821690630928d152906024015f604051808303815f87803b1580156107eb575f5ffd5b505af11580156107fd573d5f5f3e3d5ffd5b505050505b5050565b61080e6117ac565b600880546001600160401b03909216600160a01b0267ffffffffffffffff60a01b19909216919091179055565b6040805180820182525f80825260208201529051633a62f11160e21b81527f000000000000000000000000656f9140b9e2d3769d47b575512d46039dcab4d36001600160a01b03169063e98bc44490610898908590600401612ece565b6040805180830381865afa1580156108b2573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906107219190613307565b5f6108e160056117d8565b905090565b6001600160a01b0383165f9081526002602052604090206003015460ff168390610934576040516330d32d8760e21b81526001600160a01b0390911660048201526024015b60405180910390fd5b506001600160a01b038083165f9081526003602052604090206002015416803380821461098757604051630257d8d760e41b81526001600160a01b0392831660048201529116602482015260440161092b565b50610997905060058585856117e5565b50505050565b5f5f6109b16008546001600160a01b031690565b90505f816001600160a01b0316636bd50cef6040518163ffffffff1660e01b815260040161012060405180830381865afa1580156109f1573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610a159190613321565b51602001519050610a516001600160a01b037f000000000000000000000000a27ec0006e59f245217ff08cd52a7e8b169e62d2163330846118b3565b60405163095ea7b360e01b81526001600160a01b038381166004830152602482018390527f000000000000000000000000a27ec0006e59f245217ff08cd52a7e8b169e62d2169063095ea7b3906044016020604051808303815f875af1158015610abd573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610ae191906133c7565b506040516311f9fbc960e21b8152306004820152602481018290526001600160a01b038316906347e7ef24906044015f604051808303815f87803b158015610b27575f5ffd5b505af1158015610b39573d5f5f3e3d5ffd5b50506040516330eb4bdd60e01b81526001600160a01b0388811660048301528781166024830152851692506330eb4bdd91506044016020604051808303815f875af1158015610b8a573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610bae91906133e2565b95945050505050565b60605f82516001600160401b03811115610bd357610bd3612d90565b604051908082528060200260200182016040528015610c1757816020015b604080518082019091525f8082526020820152815260200190600190039081610bf15790505b5090505f5b8351811015610ca65760035f858381518110610c3a57610c3a6133f9565b60200260200101516001600160a01b03166001600160a01b031681526020019081526020015f205f016040518060400160405290815f8201548152602001600182015481525050828281518110610c9357610c936133f9565b6020908102919091010152600101610c1c565b5092915050565b5f610cb78461190d565b9050610cc2816112a0565b33906001600160a01b03168114610cf8576040516305df8ea560e31b81526001600160a01b03909116600482015260240161092b565b506109975f5160206135eb5f395f51905f528585856119a9565b5f80610d2060058585611a3c565b905080158015610d485750836001600160a01b0316610d3d6113b2565b6001600160a01b0316145b1561071e57610d6660055f5160206135eb5f395f51905f5285611a3c565b915050610721565b610d766117ac565b806001600160a01b038116610daa576040516327bac29760e21b81526001600160a01b03909116600482015260240161092b565b506001600160a01b0381165f90815260026020526040902060030154819060ff1615610df45760405162cea8b160e11b81526001600160a01b03909116600482015260240161092b565b506001600160a01b0381165f908152600260205260409020600301805460ff19166001179055610e38610e2642611a63565b6001906001600160a01b038416611a97565b505050565b5f610721600583611ab1565b6001600160a01b0382165f90815260066020908152604080832084845290915281205461071e565b335f8181526002602052604090206003015460ff16610eaf576040516319aaa75960e11b81526001600160a01b03909116600482015260240161092b565b505f33610eba6113b2565b6001600160a01b03161490508115610ef9573381610ef7576040516305df8ea560e31b81526001600160a01b03909116600482015260240161092b565b505b610f0333886113cc565b1533889091610f3857604051630d75cd7760e11b81526001600160a01b0392831660048201529116602482015260440161092b565b50508015610f9c57610f575f5160206135eb5f395f51905f52886113cc565b5f5160206135eb5f395f51905f5290889015610f9957604051630d75cd7760e11b81526001600160a01b0392831660048201529116602482015260440161092b565b50505b5f82610fa85733610fb7565b5f5160206135eb5f395f51905f525b6001600160a01b0381165f908152600260205260409020909150610fdb9089611ad4565b8189909161100f57604051630d75cd7760e11b81526001600160a01b0392831660048201529116602482015260440161092b565b505061101d88878787611c0e565b6040805180820182528781526001600160a01b0389811660208084019182528c83165f90815260038252949094209251805184559093015160018301559151600290910180546001600160a01b031916919092161790556110816005828a816117e5565b6110ae6005828a7f000000000000000000000000000000000000000000002a5a058fc295ed000000611dd2565b6111036001600160a01b037f000000000000000000000000a27ec0006e59f245217ff08cd52a7e8b169e62d21633307f000000000000000000000000000000000000000000002a5a058fc295ed0000006118b3565b5f6111166008546001600160a01b031690565b60405163095ea7b360e01b81526001600160a01b0380831660048301527f000000000000000000000000000000000000000000002a5a058fc295ed00000060248301529192507f000000000000000000000000a27ec0006e59f245217ff08cd52a7e8b169e62d29091169063095ea7b3906044016020604051808303815f875af11580156111a6573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906111ca91906133c7565b506040516311f9fbc960e21b81523060048201527f000000000000000000000000000000000000000000002a5a058fc295ed00000060248201526001600160a01b038216906347e7ef24906044015f604051808303815f87803b15801561122f575f5ffd5b505af1158015611241573d5f5f3e3d5ffd5b50506040516001600160a01b038b81168252808d169350851691507f7986a8ff398d9a6be88df9dfc6e3c9a83e4da5544241aad420d1cf7c214e43459060200160405180910390a3505050505050505050565b610e38338484846119a9565b5f6107216112b86112b084611a63565b600190611e61565b6001600160e01b0316611eb6565b6112ce6117ac565b6112d75f611ee9565b565b60606112e6848385611f38565b949350505050565b6040805160018082528183019092525f918291906020808301908036833701905050905083815f81518110611325576113256133f9565b60200260200101818152505061133c858285611f38565b5f8151811061134d5761134d6133f9565b60200260200101519150509392505050565b6113676117ac565b6008546001600160a01b031615611390576040516296bb9f60e21b815260040160405180910390fd5b600880546001600160a01b0319166001600160a01b0392909216919091179055565b5f6108e16112b86001612139565b5f610721600583612170565b6001600160a01b038281165f90815260026020818152604080842094861684529390910190529081205460ff1661071e565b5f61071e60058484612194565b6001600160a01b0382165f9081526002602052604081208161142c84611a63565b90505f61143983836121b9565b9050856001600160a01b031661144e866112a0565b6001600160a01b031603610bae57739064fb41156d300196d5eb95e0b3c1f08ebc39a85f5260026020526114a27f45cd5d767d29724415e078f0a4044a337b39cef8f25b5496e43151dbca56c517836121b9565b6114ac9082613421565b9695505050505050565b6114be6117ac565b6001600160a01b0381166114e757604051631e4fbdf760e01b81525f600482015260240161092b565b6114f081611ee9565b50565b335f908152600260205260408120600301548190819060ff163390611537576040516319aaa75960e11b81526001600160a01b03909116600482015260240161092b565b50335f8181526002602081815260408084206001600160a01b038b1685529283019091529091205460ff168015801561157f5750336115746113b2565b6001600160a01b0316145b80156115c157506001600160a01b0388165f9081527f45cd5d767d29724415e078f0a4044a337b39cef8f25b5496e43151dbca56c519602052604090205460ff165b15611617575050739064fb41156d300196d5eb95e0b3c1f08ebc39a85f525060026020525f5160206135eb5f395f51905f527f45cd5d767d29724415e078f0a4044a337b39cef8f25b5496e43151dbca56c51760015b87816116425760405163417f3a0560e01b81526001600160a01b03909116600482015260240161092b565b505f6116506005858b611a3c565b905080888082101561167e57604051635087517f60e11b81526004810192909252602482015260440161092b565b508890505f7f00000000000000000000000000000000000000000000152d02c7e14af68000006116ae8385613434565b10905080156116fc576116c1858c6121d4565b8b906116ec576040516304ca9e7360e31b81526001600160a01b03909116600482015260240161092b565b508291506116fc6005878d612235565b6117096005878d85612241565b5f61171c6008546001600160a01b031690565b60405163625f849b60e11b8152336004820152602481018590526001600160a01b03919091169063c4bf0936906044016020604051808303815f875af1158015611768573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061178c91906133e2565b929c919b50919950975050505050505050565b5f61071e60058484611a3c565b5f546001600160a01b031633146112d75760405163118cdaa760e01b815233600482015260240161092b565b5f610721826002016122c8565b6001600160a01b038381165f9081526020868152604080832086851684529091529020600101548116908216810361181d5750610997565b6001600160a01b038481165f908152602087815260408083208785168085529083529281902060010180546001600160a01b031916878616908117909155815194861685529184019190915290917f3134e8a2e6d97e929a7e54011ea5485d7d196dd5f0ba4d4ef95803e8e3fc257f910160405180910390a26118ac8582846118a7898989611a3c565b6122e1565b5050505050565b604080516001600160a01b0385811660248301528416604482015260648082018490528251808303909101815260849091019091526020810180516001600160e01b03166323b872dd60e01b17905261099790859061241a565b5f5f6119216008546001600160a01b031690565b6001600160a01b031663c7f758a8846040518263ffffffff1660e01b815260040161194e91815260200190565b6101a060405180830381865afa15801561196a573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061198e9190613455565b60808101518151519192506119a291612486565b9392505050565b5f6119b38461190d565b90506119c3600586868487612491565b6008546001600160a01b031660405163350c7fbd60e11b8152600481018690526024810185905283151560448201526001600160a01b039190911690636a18ff7a906064015f604051808303815f87803b158015611a1f575f5ffd5b505af1158015611a31573d5f5f3e3d5ffd5b505050505050505050565b6001600160a01b039182165f90815260209384526040808220929093168152925290205490565b5f63ffffffff821115611a93576040516306dfcc6560e41b8152602060048201526024810183905260440161092b565b5090565b5f80611aa485858561255c565b915091505b935093915050565b6001600160a01b0381165f90815260208390526040812061071e906001016122c8565b5f6001600160a01b038216611afb5760405162979f6d60e11b815260040160405180910390fd5b6001600160a01b0382165f90815260028401602052604090205460ff1615611b2457505f610721565b5f611b2e84612139565b604080518082018252600181526001600160e01b0383811660208084019182526001600160a01b0389165f90815260028b019091529384209251835491516001600160e81b0319909216901515610100600160e81b031916176101009190921602179055909150611b9e42611a63565b9050611bd681611bb6866001600160a01b03166126a0565b6001600160e01b0385165f90815260018901602052604090209190611a97565b50611c01905081611bf9611beb85600161352a565b6001600160e01b03166126a0565b879190611a97565b5060019695505050505050565b6001600160a01b0384165f908152600360209081526040918290208251808401909352805480845260019091015491830191909152158015611c5257506020810151155b815160208301519091611c81576040516312d6323b60e11b81526004810192909252602482015260440161092b565b50505f845f01518560200151604051602001611ca7929190918252602082015260400190565b60408051601f1981840301815291815281516020928301205f8181526004909352912054909150819060ff1615611cf457604051636ab4baeb60e11b815260040161092b91815260200190565b505f818152600460208190526040918290208054600160ff199091161790556008549151633f78271d60e01b81527f000000000000000000000000656f9140b9e2d3769d47b575512d46039dcab4d36001600160a01b031692633f78271d92600160a01b9091046001600160401b031691611d75918a918a918a9101613549565b6020604051808303818786fa158015611d90573d5f5f3e3d5ffd5b50505050506040513d601f19601f82011682018060405250810190611db591906133c7565b6107fd5760405163df4ff27b60e01b815260040160405180910390fd5b8015610997576001600160a01b038084165f9081526020868152604080832093861683529083905281208054849290611e0c908490613421565b90915550506001600160a01b038084165f90815260208390526040812060010154611e3b9288929116856122e1565b611e4860018201836126d3565b50611e58905060028601836126d3565b50505050505050565b81545f9081611e728585838561274d565b90508015611eac57611e9685611e89600184613434565b5f91825260209091200190565b54600160201b90046001600160e01b0316610bae565b505f949350505050565b5f6001600160a01b03821115611a93576040516306dfcc6560e41b815260a060048201526024810183905260440161092b565b5f80546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b60605f83516001600160401b03811115611f5457611f54612d90565b604051908082528060200260200182016040528015611f7d578160200160208202803683370190505b506001600160a01b0386165f818152600260205260408120739064fb41156d300196d5eb95e0b3c1f08ebc39a882529293507f45cd5d767d29724415e078f0a4044a337b39cef8f25b5496e43151dbca56c51791611fda876112a0565b6001600160a01b03161490505f611ff087611a63565b90505f611ffd85836121b9565b90505f8361200b575f612015565b61201585846121b9565b90505f6120228284613421565b90505f5b8b51811015612128575f8c8281518110612042576120426133f9565b602002602001015190508281108184909161207957604051635d4bf88360e01b81526004810192909252602482015260440161092b565b5050848110156120c55761208e8982886127a8565b8a83815181106120a0576120a06133f9565b60200260200101906001600160a01b031690816001600160a01b03168152505061211f565b86156120e05761208e6120d88683613434565b8990886127a8565b604051633d6a4a3b60e21b815260206004820152601360248201527229a427aaa622102722ab22a9102420a82822a760691b604482015260640161092b565b50600101612026565b50969b9a5050505050505050505050565b80545f9080156121685761215283611e89600184613434565b54600160201b90046001600160e01b03166119a2565b5f9392505050565b6001600160a01b0381165f90815260018084016020526040822061071e91016122c8565b6001600160a01b0382165f9081526001808501602052604082206112e69101836127d7565b5f6121c48383611e61565b6001600160e01b03169392505050565b6001600160a01b0381165f908152600283016020908152604080832081518083019092525460ff811615158083526101009091046001600160e01b03169282019290925290612226575f915050610721565b6112e684826020015185612811565b610e388383835f6117e5565b8015610997576001600160a01b038084165f908152602086815260408083209386168352908390528120805484929061227b908490613434565b90915550506001600160a01b038084165f908152602083905260408120600101546122ab928892911690856122e1565b6122b86001820183612a2e565b50611e5890506002860183612a2e565b5f6122d282612139565b6001600160e01b031692915050565b816001600160a01b0316836001600160a01b031614806122ff575080155b610997576001600160a01b0383161561238c576001600160a01b0383165f9081526001808601602052604082208291612339910184612a2e565b91509150846001600160a01b03167fdec2bacdd2f05b59de34da9b523dff8be42e5e38e818c82fdb0bae774387a7248383604051612381929190918252602082015260400190565b60405180910390a250505b6001600160a01b03821615610997576001600160a01b0382165f90815260018086016020526040822082916123c29101846126d3565b91509150836001600160a01b03167fdec2bacdd2f05b59de34da9b523dff8be42e5e38e818c82fdb0bae774387a724838360405161240a929190918252602082015260400190565b60405180910390a2505050505050565b5f5f60205f8451602086015f885af180612439576040513d5f823e3d81fd5b50505f513d9150811561245057806001141561245d565b6001600160a01b0384163b155b1561099757604051635274afe760e01b81526001600160a01b038516600482015260240161092b565b5f61071e8284613421565b5f61249d868685612194565b6001600160a01b0386165f90815260018801602090815260408083208884529091529020549091506124cf8382613421565b82101586836124de8685613421565b9091926125175760405163dd99c2ab60e01b81526001600160a01b0390931660048401526024830191909152604482015260640161092b565b5050506001600160a01b0386165f90815260018801602090815260408083208884529091528120805485929061254e908490613421565b909155505050505050505050565b82545f9081908015612648575f61257887611e89600185613434565b805490915063ffffffff80821691600160201b90046001600160e01b03169088168211156125b957604051632520601d60e01b815260040160405180910390fd5b8763ffffffff168263ffffffff16036125ec57825463ffffffff16600160201b6001600160e01b0389160217835561263a565b6040805180820190915263ffffffff808a1682526001600160e01b03808a1660208085019182528d54600181018f555f8f81529190912094519151909216600160201b029216919091179101555b9450859350611aa992505050565b50506040805180820190915263ffffffff80851682526001600160e01b0380851660208085019182528854600181018a555f8a815291822095519251909316600160201b029190931617920191909155905081611aa9565b5f6001600160e01b03821115611a93576040516306dfcc6560e41b815260e060048201526024810183905260440161092b565b5f5f5f6126df85612139565b9050835f036126fb576001600160e01b03169150819050612746565b5f612705856126a0565b905061272561271342611a63565b61271d838561352a565b889190611a97565b50829050612733828261352a565b6001600160e01b03918216955016925050505b9250929050565b5f5b818310156127a0575f6127628484612adb565b5f8781526020902090915063ffffffff86169082015463ffffffff16111561278c5780925061279a565b612797816001613421565b93505b5061274f565b509392505050565b5f828152600184016020526040812081906127c39084612af5565b9050610bae816001600160e01b0316611eb6565b5f6127e182421190565b6127fe576040516334dcb7d760e21b815260040160405180910390fd5b6121c461280a83611a63565b8490612af5565b5f8061281c85612139565b9050806001600160e01b0316846001600160e01b03161061286357604051636bc4db8d60e11b81526001600160e01b0380861660048301528216602482015260440161092b565b6040805180820182525f80825260208083018281526001600160a01b038816835260028a019091529281209151825493516001600160e81b0319909416901515610100600160e81b031916176101006001600160e01b03909416939093029290921790556128d2600183613598565b90505f6128de42611a63565b9050856001600160e01b0316826001600160e01b0316146129db576001600160e01b0382165f908152600188016020526040812061291f906112b890612139565b90506040518060400160405280600115158152602001612947896001600160e01b03166126a0565b6001600160e01b039081169091526001600160a01b0383165f81815260028c016020908152604090912084518154959092015190931661010002610100600160e81b0319911515919091166001600160e81b0319909416939093179290921790556129d79083906129b7906126a0565b6001600160e01b038a165f90815260018c01602052604090209190611a97565b5050505b6001600160e01b0382165f90815260018801602052604081206129ff918390611a97565b5050612a1f81612a17846001600160e01b03166126a0565b899190611a97565b50600198975050505050505050565b5f5f5f612a3a85612139565b9050835f03612a56576001600160e01b03169150819050612746565b5f612a60856126a0565b90503382826001600160e01b038082169083161015612ab45760405163b3d9568f60e01b81526001600160a01b0390931660048401526001600160e01b03918216602484015216604482015260640161092b565b505050612acd612ac342611a63565b61271d8385613598565b508290506127338282613598565b5f612ae960028484186135cb565b61071e90848416613421565b81545f9081816005811115612b4f575f612b0e84612b96565b612b189085613434565b5f8881526020902090915081015463ffffffff9081169087161015612b3f57809150612b4d565b612b4a816001613421565b92505b505b5f612b5c8787858561274d565b90508015612b8957612b7387611e89600184613434565b54600160201b90046001600160e01b0316612b8b565b5f5b979650505050505050565b5f60018211612ba3575090565b816001600160801b8210612bbc5760809190911c9060401b5b680100000000000000008210612bd75760409190911c9060201b5b600160201b8210612bed5760209190911c9060101b5b620100008210612c025760109190911c9060081b5b6101008210612c165760089190911c9060041b5b60108210612c295760049190911c9060021b5b60048210612c355760011b5b600302600190811c90818581612c4d57612c4d6135b7565b048201901c90506001818581612c6557612c656135b7565b048201901c90506001818581612c7d57612c7d6135b7565b048201901c90506001818581612c9557612c956135b7565b048201901c90506001818581612cad57612cad6135b7565b048201901c90506001818581612cc557612cc56135b7565b048201901c9050612ce4818581612cde57612cde6135b7565b04821190565b90039392505050565b6001600160a01b03811681146114f0575f5ffd5b5f5f60408385031215612d12575f5ffd5b8235612d1d81612ced565b91506020830135612d2d81612ced565b809150509250929050565b5f60208284031215612d48575f5ffd5b5035919050565b5f60208284031215612d5f575f5ffd5b81356001600160401b038116811461071e575f5ffd5b5f60208284031215612d85575f5ffd5b813561071e81612ced565b634e487b7160e01b5f52604160045260245ffd5b604080519081016001600160401b0381118282101715612dc657612dc6612d90565b60405290565b604051608081016001600160401b0381118282101715612dc657612dc6612d90565b60405161010081016001600160401b0381118282101715612dc657612dc6612d90565b60405160c081016001600160401b0381118282101715612dc657612dc6612d90565b60405160e081016001600160401b0381118282101715612dc657612dc6612d90565b604051601f8201601f191681016001600160401b0381118282101715612e7d57612e7d612d90565b604052919050565b5f60408284031215612e95575f5ffd5b612e9d612da4565b823581526020928301359281019290925250919050565b5f60408284031215612ec4575f5ffd5b61071e8383612e85565b815181526020808301519082015260408101610721565b5f5f5f60608486031215612ef7575f5ffd5b8335612f0281612ced565b92506020840135612f1281612ced565b91506040840135612f2281612ced565b809150509250925092565b5f6001600160401b03821115612f4557612f45612d90565b5060051b60200190565b5f60208284031215612f5f575f5ffd5b81356001600160401b03811115612f74575f5ffd5b8201601f81018413612f84575f5ffd5b8035612f97612f9282612f2d565b612e55565b8082825260208201915060208360051b850101925086831115612fb8575f5ffd5b6020840193505b828410156114ac578335612fd281612ced565b825260209384019390910190612fbf565b602080825282518282018190525f918401906040840190835b8181101561302f5761301983855180518252602090810151910152565b6020939093019260409290920191600101612ffc565b509095945050505050565b80151581146114f0575f5ffd5b80356130528161303a565b919050565b5f5f5f60608486031215613069575f5ffd5b83359250602084013591506040840135612f228161303a565b5f5f60408385031215613093575f5ffd5b823561309e81612ced565b946020939093013593505050565b5f5f5f5f5f5f8688036101608112156130c3575f5ffd5b87356130ce81612ced565b965060208801356130de81612ced565b95506130ed8960408a01612e85565b94506080607f1982011215613100575f5ffd5b50613109612dcc565b6080880135815260a0880135602082015260c0880135604082015260e08801356060820152925061313e886101008901612e85565b915061314d6101408801613047565b90509295509295509295565b5f5f5f6060848603121561316b575f5ffd5b833561317681612ced565b92506020840135915060408401356001600160401b03811115613197575f5ffd5b8401601f810186136131a7575f5ffd5b80356131b5612f9282612f2d565b8082825260208201915060208360051b8501019250888311156131d6575f5ffd5b6020840193505b828410156131f85783358252602093840193909101906131dd565b809450505050509250925092565b602080825282518282018190525f918401906040840190835b8181101561302f5783516001600160a01b031683526020938401939092019160010161321f565b5f5f5f60608486031215613258575f5ffd5b833561326381612ced565b95602085013595506040909401359392505050565b805161305281612ced565b5f6080828403128015613294575f5ffd5b5061329d612dcc565b825181526020808401519082015260408301516132b981612ced565b604082015260608301516132cc8161303a565b60608201529392505050565b5f604082840312156132e8575f5ffd5b6132f0612da4565b825181526020928301519281019290925250919050565b5f60408284031215613317575f5ffd5b61071e83836132d8565b5f81830361012081128015613334575f5ffd5b5061333d612dee565b604082121561334a575f5ffd5b613352612da4565b845181526020808601518183015290825260408086015191830191909152606080860151918301919091526080808601519183019190915260a0808601519183019190915260c0808601519183019190915260e080860151918301919091526101009094015193810193909352509092915050565b5f602082840312156133d7575f5ffd5b815161071e8161303a565b5f602082840312156133f2575f5ffd5b5051919050565b634e487b7160e01b5f52603260045260245ffd5b634e487b7160e01b5f52601160045260245ffd5b808201808211156107215761072161340d565b818103818111156107215761072161340d565b805160098110613052575f5ffd5b5f8183036101a081128015613468575f5ffd5b50613471612e11565b60e082121561347e575f5ffd5b613486612e33565b845181526020808601519082015260408086015190820152606080860151908201526080808601519082015260a0808601519082015260c0808601519082015280825291506134d760e08501613447565b60208201526134e96101008501613278565b60408201526134fb6101208501613278565b606082015261014084015160808201819052915061351d8561016086016132d8565b60a0820152949350505050565b6001600160e01b0381811683821601908111156107215761072161340d565b83518152602080850151908201526101008101835160408301526020840151606083015260408401516080830152606084015160a08301526112e660c083018480518252602090810151910152565b6001600160e01b0382811682821603908111156107215761072161340d565b634e487b7160e01b5f52601260045260245ffd5b5f826135e557634e487b7160e01b5f52601260045260245ffd5b50049056fe213a5ea1b59775ba625834509064fb41156d300196d5eb95e0b3c1f08ebc39a8a2646970667358221220dedf8e50dbb5e76c009a9db7945946eb3c7bf704856499f9a4dbbce27804376a64736f6c634300081e0033","storage":{"0x0000000000000000000000000000000000000000000000000000000000000001":"0x0000000000000000000000000000000000000000000000000000000000000003","0x19b5088911e79262ac5a67b3ce99768c442b67663d25697f0620823dfafa3c24":"0x0000000000000000000000000000000000000000000029ed99fc670a2fc00000","0x264b1a546ce0c3fbd86b3df85824d368ddfe3dd2a56253732c60d7bfcfb52fa5":"0x2f1b65d04a9533b0ec7a8598242edb357c0a1bdfc404211100955a24d26760ac","0x264b1a546ce0c3fbd86b3df85824d368ddfe3dd2a56253732c60d7bfcfb52fa6":"0x1c6cca5310223051da991aeb0c43c354f0e04580b1c53425a29ed96cf6a28d54","0x264b1a546ce0c3fbd86b3df85824d368ddfe3dd2a56253732c60d7bfcfb52fa7":"0x00000000000000000000000056860f956899139c65d4686b74bfc8238c6d8f57","0x35bf82182d2bf721d6eb6bb3634c23a59da88a8651dd323d400618a5d3465f3f":"0x05521472744d3d5b97dc990225d7ac85108ca78a598a0c236f44a3bff30ba0d2","0x35bf82182d2bf721d6eb6bb3634c23a59da88a8651dd323d400618a5d3465f40":"0x267ab9ac7dc282e1c986e62890bd028e12836d58113f7c5d9315a65dcdbb6bed","0x35bf82182d2bf721d6eb6bb3634c23a59da88a8651dd323d400618a5d3465f41":"0x00000000000000000000000002cbf45ba5e6364c53f0623c2200f40746a735b9","0x3f15e2825f4bf889dab06d1392eafdbb0a0bd536e5217f0b3b1e7a35de3076e8":"0x0000000000000000000000000000000000000000000029ed99fc670a2fc00000","0x5245078fa0025b234af522f978761b00d9a9e4d274aa23bd141d58b8c70b493c":"0x0000000000000000000000000000000000000000000000000000000000000000","0x57b4348938240372f1afa225cdca71d2ea7c7b6e435298e07c00de84bcd8a4d2":"0x058828a264e4b833e6367e7dfb951fdc365295a577e944ae96288d1f5524929e","0x57b4348938240372f1afa225cdca71d2ea7c7b6e435298e07c00de84bcd8a4d3":"0x0fb8755d2b2ff114941b079842955e873070621afbd5beb4930460f6233c52e4","0x57b4348938240372f1afa225cdca71d2ea7c7b6e435298e07c00de84bcd8a4d4":"0x0000000000000000000000009c8bf8fa4e88316ade54b201b64007afda68fab4","0x8720d7cd2e06c32b73029244d0c4fb05fbe35add6bbf32d23c7d2f40857963bc":"0x0000000000000000000000000000000000000000000000000000000000000000","0xb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf8":"0x000000000000000091ff8bbd8ebb07893010d50a48a1609e5ebd8e346a569a97","0xc33585bb56e8e4c08af193736df1217b3b102aedb4a93ddf5f248c9de0eadfef":"0x000000000000000000000000000000000000000000002a5a058fc295ed000000","0xf664041300090707b88ca5d1eaab5f3b03585765880785e558439e73c5e5e59a":"0x0000000000000000000000000000000000000000000000000000000000000000"}},"0xc4a8530aeb89da98cd11178930b39c2aa272874e":{"nonce":"0x1","balance":"0x0","code":"0x608060405234801561000f575f5ffd5b5060043610610187575f3560e01c8063802ac8b6116100d9578063ce828b0611610093578063e7f43c681161006e578063e7f43c6814610404578063ec99499b14610415578063ee28b74414610428578063fdbcf3dc14610430575f5ffd5b8063ce828b06146103e1578063d7927824146103e9578063da62dfa4146103f1575f5ffd5b8063802ac8b6146102d55780638fff3cec146102e65780639b74026c146102ee578063ae3bb460146102f6578063b6549f75146102fe578063c2722ecc14610306575f5ffd5b80634e71d92d116101445780635ab1bd531161011f5780635ab1bd531461026e5780636d08aea71461029457806372b45a55146102b157806374743769146102c2575f5ffd5b80634e71d92d1461024d578063565a2e2c14610255578063592b07cd14610266575f5ffd5b80630c9e1e8e1461018b57806315dae03e146101a15780631ff9b6f2146101b057806321df0da7146101c557806324374197146101ff578063355723f114610212575b5f5ffd5b5f545b6040519081526020015b60405180910390f35b60026040516101989190611640565b6101c36101be36600461167d565b610457565b005b7f000000000000000000000000a27ec0006e59f245217ff08cd52a7e8b169e62d25b6040516001600160a01b039091168152602001610198565b6101c361020d3660046116b4565b6105d2565b61021a610669565b60405161019891908151815260208083015190820152604080830151908201526060918201519181019190915260800190565b61018e61071f565b6001546001600160a01b03166101e7565b61018e61077d565b7f00000000000000000000000063841bad6b35b6419e15ca9bbbbdf446d4dc3dde6101e7565b600554600160601b900460ff166040519015158152602001610198565b6002546001600160a01b03166101e7565b6101c36102d03660046116cf565b61082e565b6006546001600160a01b03166101e7565b61021a610a2f565b61018e610ac2565b60045461018e565b61018e610b43565b61038f6040805160a0810182525f80825260208201819052918101829052606081018290526080810191909152506040805160a08101825260055463ffffffff8082168352640100000000820481166020840152600160401b82041692820192909252600160601b90910460ff16151560608201526006546001600160a01b0316608082015290565b60408051825163ffffffff90811682526020808501518216908301528383015116918101919091526060808301511515908201526080918201516001600160a01b03169181019190915260a001610198565b61018e610cf0565b6101e7610d26565b6101c36103ff36600461174a565b610da7565b6003546001600160a01b03166101e7565b6101c36104233660046116cf565b610fb5565b61018e6111b0565b61018e7f0000000000000000000000000000000000000000000000000000000069152dd781565b60015433906001600160a01b031681811461049d57604051635a8e8fa360e01b81526001600160a01b039283166004820152911660248201526044015b60405180910390fd5b50507f000000000000000000000000a27ec0006e59f245217ff08cd52a7e8b169e62d26001600160a01b0316826001600160a01b031614158290610500576040516337bce3c560e11b81526001600160a01b039091166004820152602401610494565b506040516370a0823160e01b815230600482015282905f906001600160a01b038316906370a0823190602401602060405180830381865afa158015610547573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061056b91906117e4565b90506105816001600160a01b0383168483611294565b604080516001600160a01b038087168252851660208201529081018290527f3af790fafda720819b2fc6e15090606e81154e0ac9a92d38ecad006d99d20ecc9060600160405180910390a150505050565b60015433906001600160a01b031681811461061357604051635a8e8fa360e01b81526001600160a01b03928316600482015291166024820152604401610494565b5050600380546001600160a01b0319166001600160a01b0383169081179091556040519081527f9da9e13718fdfd82ad5556bc47d08a237d650e068d8e9646a05362d2458eff3b9060200160405180910390a150565b61069060405180608001604052805f81526020015f81526020015f81526020015f81525090565b61071a7f00000000000000000000000063841bad6b35b6419e15ca9bbbbdf446d4dc3dde6001600160a01b0316639601ddde6040518163ffffffff1660e01b8152600401606060405180830381865afa1580156106ef573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061071391906117fb565b5f546112e6565b905090565b6001545f9033906001600160a01b031681811461076257604051635a8e8fa360e01b81526001600160a01b03928316600482015291166024820152604401610494565b5050604051631129777360e21b815260040160405180910390fd5b6005545f90600160601b900460ff1661079657505f1990565b61079e610cf0565b6040516370a0823160e01b81523060048201527f000000000000000000000000a27ec0006e59f245217ff08cd52a7e8b169e62d26001600160a01b0316906370a0823190602401602060405180830381865afa158015610800573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061082491906117e4565b61071a919061184a565b60015433906001600160a01b031681811461086f57604051635a8e8fa360e01b81526001600160a01b03928316600482015291166024820152604401610494565b5050604051630e26d24360e31b8152600481018290525f907f00000000000000000000000063841bad6b35b6419e15ca9bbbbdf446d4dc3dde6001600160a01b031690637136921890602401602060405180830381865afa1580156108d6573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906108fa919061185d565b6002546040805163278f794360e11b81526001600160a01b03808516600483015260248201929092525f60448201529293501690634f1ef286906064015f604051808303815f87803b15801561094e575f5ffd5b505af1158015610960573d5f5f3e3d5ffd5b5050600254604080516357a1f65b60e11b815290513094506001600160a01b03909216925063af43ecb69160048083019260209291908290030181865afa1580156109ad573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906109d1919061185d565b6001600160a01b0316146109f85760405163012fa17760e61b815260040160405180910390fd5b6040518281527f692235ce380b51290c9c1bf0c1eea4cb73dc28803f84dffa7837c175a51a9a789060200160405180910390a15050565b610a5660405180608001604052805f81526020015f81526020015f81526020015f81525090565b600554600160601b900460ff16610a8057604051633c34e69d60e01b815260040160405180910390fd5b6040805160608101825260055463ffffffff8082168352640100000000820481166020840152600160401b90910416918101919091525f5461071a91906112e6565b5f7f00000000000000000000000063841bad6b35b6419e15ca9bbbbdf446d4dc3dde6001600160a01b0316639b74026c6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610b1f573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061071a91906117e4565b6005545f90600160601b900460ff16610b6f57604051633c34e69d60e01b815260040160405180910390fd5b5f7f00000000000000000000000063841bad6b35b6419e15ca9bbbbdf446d4dc3dde6001600160a01b031663d79278246040518163ffffffff1660e01b8152600401602060405180830381865afa158015610bcc573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610bf0919061185d565b905033816001600160a01b0381168214610c30576040516319516ce560e31b81526001600160a01b03928316600482015291166024820152604401610494565b50505f610c3b610a2f565b60408101519091504210610c625760405163226a243d60e01b815260040160405180910390fd5b5f610c6b610cf0565b6005805460ff60601b19169055600654909150610cb5906001600160a01b037f000000000000000000000000a27ec0006e59f245217ff08cd52a7e8b169e62d28116911683611294565b6040518181527f61e27b0bfd8e18e6b92ec32ce1c28bb698d27bfe93e84c7e94d4db0a3135c760906020015b60405180910390a19392505050565b6005545f90600160601b900460ff16610d0857505f90565b610d1a42610d14610a2f565b90611366565b5f5461071a919061184a565b5f7f00000000000000000000000063841bad6b35b6419e15ca9bbbbdf446d4dc3dde6001600160a01b031663d79278246040518163ffffffff1660e01b8152600401602060405180830381865afa158015610d83573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061071a919061185d565b6002546001600160a01b031615610dd05760405162dc149f60e41b815260040160405180910390fd5b5f6001600160a01b038416610e0457604051631a3b45fd60e01b81526001600160a01b039091166004820152602401610494565b505f8211610e2557604051634529276560e11b815260040160405180910390fd5b600180546001600160a01b0319166001600160a01b0385161790555f829055610e4c6113cd565b600280546001600160a01b0319166001600160a01b0392831617905581511615610f8657610e7d8160200151611502565b6040518060a00160405280610e9883602001515f015161155b565b63ffffffff168152602001610eb483602001516020015161155b565b63ffffffff168152602001610ed083602001516040015161155b565b63ffffffff9081168252600160208084019190915293516001600160a01b03908116604093840152835160058054968601519486015160608701511515600160601b0260ff60601b19918616600160401b02919091166cffffffffff0000000000000000199686166401000000000267ffffffffffffffff199099169390951692909217969096179390931691909117919091179092556080015160068054919092166001600160a01b03199091161790555050565b610f93816020015161158f565b610fb057604051630c66fa3f60e11b815260040160405180910390fd5b505050565b60015433906001600160a01b0316818114610ff657604051635a8e8fa360e01b81526001600160a01b03928316600482015291166024820152604401610494565b50505f7f00000000000000000000000063841bad6b35b6419e15ca9bbbbdf446d4dc3dde6001600160a01b0316639b74026c6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611055573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061107991906117e4565b90504281808210156110a757604051631b1f1ffd60e01b815260048101929092526024820152604401610494565b50505f6110b261077d565b90508083808210156110e057604051631c4b371f60e31b815260048101929092526024820152604401610494565b505060025460405163095ea7b360e01b81526001600160a01b039182166004820152602481018590527f000000000000000000000000a27ec0006e59f245217ff08cd52a7e8b169e62d29091169063095ea7b3906044016020604051808303815f875af1158015611153573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906111779190611878565b506040518381527f55cf824239470134f920524d953607077f3ab00df4201f49629b29e864e0da409060200160405180910390a1505050565b5f5f6111ba610669565b60408101519091505f904210156111e7576004546111d88342611366565b6111e2919061184a565b6111ea565b5f195b905061128d6111f7610cf0565b6040516370a0823160e01b81523060048201527f000000000000000000000000a27ec0006e59f245217ff08cd52a7e8b169e62d26001600160a01b0316906370a0823190602401602060405180830381865afa158015611259573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061127d91906117e4565b611287919061184a565b826115b2565b9250505090565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b179052610fb09084906115c1565b61130d60405180608001604052805f81526020015f81526020015f81526020015f81525090565b61131683611502565b6040518060800160405280845f015181526020018460200151855f015161133d9190611897565b81526020018460400151855f01516113559190611897565b815260200183905290505b92915050565b5f826020015182101561137a57505f611360565b8260400151821061139057506060820151611360565b825160408401516113a1919061184a565b83516113ad908461184a565b84606001516113bc91906118aa565b6113c691906118c1565b9392505050565b604051630e26d24360e31b81525f600482018190529081906001600160a01b037f00000000000000000000000063841bad6b35b6419e15ca9bbbbdf446d4dc3dde1690637136921890602401602060405180830381865afa158015611434573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611458919061185d565b6040513060248201529091505f90829060440160408051601f198184030181529181526020820180516001600160e01b031663189acdbd60e31b1790525161149f90611633565b6114aa9291906118e0565b604051809103905ff0801580156114c3573d5f5f3e3d5ffd5b506040516001600160a01b038216815290915081907fcb6c92f3827201df9fbbd40b7e8766a5742f09e4dafe6c85167325b7eaf0b76990602001610ce1565b5f816040015111611526576040516314c6911f60e11b815260040160405180910390fd5b602081015160408201519080821015610fb05760405163d3e33a4f60e01b815260048101929092526024820152604401610494565b5f63ffffffff82111561158b576040516306dfcc6560e41b81526020600482015260248101839052604401610494565b5090565b80515f901580156115a257506020820151155b8015611360575050604001511590565b5f8282188284100282186113c6565b5f5f60205f8451602086015f885af1806115e0576040513d5f823e3d81fd5b50505f513d915081156115f7578060011415611604565b6001600160a01b0384163b155b1561162d57604051635274afe760e01b81526001600160a01b0385166004820152602401610494565b50505050565b6103d08061192583390190565b602081016003831061166057634e487b7160e01b5f52602160045260245ffd5b91905290565b6001600160a01b038116811461167a575f5ffd5b50565b5f5f6040838503121561168e575f5ffd5b823561169981611666565b915060208301356116a981611666565b809150509250929050565b5f602082840312156116c4575f5ffd5b81356113c681611666565b5f602082840312156116df575f5ffd5b5035919050565b6040805190810167ffffffffffffffff8111828210171561171557634e487b7160e01b5f52604160045260245ffd5b60405290565b6040516060810167ffffffffffffffff8111828210171561171557634e487b7160e01b5f52604160045260245ffd5b5f5f5f83850360c081121561175d575f5ffd5b843561176881611666565b9350602085013592506080603f1982011215611782575f5ffd5b61178a6116e6565b604086013561179881611666565b81526060605f19830112156117ab575f5ffd5b6117b361171b565b60608701358152608087013560208083019190915260a0909701356040820152958101959095525091949093509050565b5f602082840312156117f4575f5ffd5b5051919050565b5f606082840312801561180c575f5ffd5b5061181561171b565b82518152602080840151908201526040928301519281019290925250919050565b634e487b7160e01b5f52601160045260245ffd5b8181038181111561136057611360611836565b5f6020828403121561186d575f5ffd5b81516113c681611666565b5f60208284031215611888575f5ffd5b815180151581146113c6575f5ffd5b8082018082111561136057611360611836565b808202811582820484141761136057611360611836565b5f826118db57634e487b7160e01b5f52601260045260245ffd5b500490565b60018060a01b0383168152604060208201525f82518060408401528060208501606085015e5f606082850101526060601f19601f830116840101915050939250505056fe60806040526040516103d03803806103d08339810160408190526100229161023c565b61002c8282610033565b5050610321565b61003c82610091565b6040516001600160a01b038316907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b905f90a280511561008557610080828261010c565b505050565b61008d61017f565b5050565b806001600160a01b03163b5f036100cb57604051634c9c8ce360e01b81526001600160a01b03821660048201526024015b60405180910390fd5b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc80546001600160a01b0319166001600160a01b0392909216919091179055565b60605f5f846001600160a01b031684604051610128919061030b565b5f60405180830381855af49150503d805f8114610160576040519150601f19603f3d011682016040523d82523d5f602084013e610165565b606091505b5090925090506101768583836101a0565b95945050505050565b341561019e5760405163b398979f60e01b815260040160405180910390fd5b565b6060826101b5576101b0826101ff565b6101f8565b81511580156101cc57506001600160a01b0384163b155b156101f557604051639996b31560e01b81526001600160a01b03851660048201526024016100c2565b50805b9392505050565b80511561020f5780518082602001fd5b60405163d6bda27560e01b815260040160405180910390fd5b634e487b7160e01b5f52604160045260245ffd5b5f5f6040838503121561024d575f5ffd5b82516001600160a01b0381168114610263575f5ffd5b60208401519092506001600160401b0381111561027e575f5ffd5b8301601f8101851361028e575f5ffd5b80516001600160401b038111156102a7576102a7610228565b604051601f8201601f19908116603f011681016001600160401b03811182821017156102d5576102d5610228565b6040528181528282016020018710156102ec575f5ffd5b8160208401602083015e5f602083830101528093505050509250929050565b5f82518060208501845e5f920191825250919050565b60a38061032d5f395ff3fe6080604052600a600c565b005b60186014601a565b6050565b565b5f604b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc546001600160a01b031690565b905090565b365f5f375f5f365f845af43d5f5f3e8080156069573d5ff35b3d5ffdfea2646970667358221220ff7a924880ea92a37f0c8e7854a593fcaec3ad0775a3ae0d1c087cd168a411d964736f6c634300081e0033a2646970667358221220922fccf242b11d6431c32a9674686d4e58b01dec5eac65e5ce49fa8e4bcd45ac64736f6c634300081e0033","storage":{}},"0xe4f0b9769ca04a6e3d93b5ba732b5ad80797d411":{"nonce":"0x1","balance":"0x0","code":"0x73e4f0b9769ca04a6e3d93b5ba732b5ad80797d41130146080604052600436106101fc575f3560e01c80638f02f67211610126578063ca3dc9ec116100bf578063e48a5f7b11610084578063e48a5f7b14610524578063eb80a09414610544578063ee3b8dc214610563578063f0ec5ad014610582578063f85494de146105a1575f5ffd5b8063ca3dc9ec146104c2578063e0fae2a9146104ca578063e199c059146104e9578063e3380b7914610508578063e3682cde1461051c575f5ffd5b80638f02f672146103da5780639ca03702146103f9578063a229474814610419578063a7f8e64614610421578063ae36b7be14610434578063c008f5da14610468578063c27f08b514610487578063c2cac49d146104a6578063c30d876c146104ba575f5ffd5b80632980c31e116101985780632980c31e146103055780632eb5af0a1461030d57806330ccebb51461032157806333ab76ab1461034157806334a51ed51461036057806348b5de18146103805780635dc0ff941461039f5780637afeed28146103bf5780637de3ca89146103d2575f5ffd5b80630121b93f1461020057806302fb4d85146102215780630a554ed41461025557806310073ff01461027457806310a2aa551461028a57806315d3bc7b1461029e5780631b56a0e7146102be5780631cfe2878146102c657806329176625146102f2575b5f5ffd5b81801561020b575f5ffd5b5061021f61021a366004614e6a565b6105c0565b005b81801561022c575f5ffd5b5061024061023b366004614e95565b6105cc565b60405190151581526020015b60405180910390f35b818015610260575f5ffd5b5061021f61026f3660046150ff565b6105e0565b61027c6105f2565b60405190815260200161024c565b818015610295575f5ffd5b5061021f61060e565b6102b16102ac366004614e6a565b610618565b60405161024c9190615172565b61027c610622565b8180156102d1575f5ffd5b506102e56102e0366004614e6a565b610630565b60405161024c9190615186565b61027c610300366004614e6a565b61063b565b61027c610645565b818015610318575f5ffd5b5061021f61064e565b61033461032f3660046151c6565b610656565b60405161024c9190615215565b81801561034c575f5ffd5b5061021f61035b366004615223565b610660565b61037361036e3660046151c6565b610670565b60405161024c91906152fd565b81801561038b575f5ffd5b5061021f61039a3660046151c6565b610681565b6103b26103ad3660046151c6565b61068a565b60405161024c9190615340565b61027c6103cd366004614e6a565b61069b565b61027c6106a5565b8180156103e5575f5ffd5b5061021f6103f436600461534e565b6106bd565b61040c610407366004614e6a565b6106c6565b60405161024c91906153e0565b6102b16106d7565b6102b161042f366004614e6a565b6106e0565b81801561043f575f5ffd5b5061045361044e36600461545b565b6106ea565b6040805192835260208301919091520161024c565b818015610473575f5ffd5b5061021f610482366004615491565b610704565b818015610492575f5ffd5b506102b16104a1366004614e6a565b61070f565b8180156104b1575f5ffd5b5061021f610720565b61027c610735565b61027c61073e565b8180156104d5575f5ffd5b506104536104e4366004614e6a565b610747565b8180156104f4575f5ffd5b5061021f610503366004614e6a565b61075b565b818015610513575f5ffd5b5061021f610764565b61027c610779565b6105376105323660046151c6565b610782565b60405161024c91906154ba565b81801561054f575f5ffd5b5061021f61055e3660046151c6565b610793565b81801561056e575f5ffd5b5061024061057d3660046154c8565b61079c565b81801561058d575f5ffd5b5061021f61059c36600461554b565b6107a7565b8180156105ac575f5ffd5b5061021f6105bb3660046151c6565b6107bd565b6105c9816107c6565b50565b5f6105d78383610d65565b90505b92915050565b6105ec84848484610d8d565b50505050565b5f5f6105fd42610e66565b905061060881610ee1565b91505090565b610616610f93565b565b5f6105da826111b9565b5f61062b6111e2565b905090565b60606105da826111f6565b5f6105da8261120e565b5f61062b61122a565b61061661123d565b5f6105da826112c8565b61066b838383611392565b505050565b610678614d3c565b6105da82611426565b6105c9816114f6565b610692614d6c565b6105da82611613565b5f6105da8261169d565b5f6106ae611706565b6002015463ffffffff16919050565b6105c98161172a565b6106ce614da9565b6105da826117a5565b5f61062b6117c2565b5f6105da826117d6565b5f5f6106f7858585611853565b915091505b935093915050565b61066b83838361194c565b5f61071982611a09565b5092915050565b5f61072a42611ac0565b90506105c981611b18565b5f61062b611b6a565b5f61062b611b89565b5f5f61075283611ba2565b91509150915091565b6105c981611bf7565b5f61076e42611ac0565b90506105c98161206a565b5f61062b6120cf565b61078a614e45565b6105da826120ee565b6105c98161216e565b5f6105d783836122af565b6107b586868686868661270c565b505050505050565b6105c98161288a565b5f6107cf612a94565b90505f816003015f9054906101000a90046001600160a01b03166001600160a01b031663289b3c0d6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610824573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061084891906155f8565b90505f816001600160a01b031663c3a505156040518163ffffffff1660e01b8152600401602060405180830381865afa158015610887573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906108ab91906155f8565b9050806001600160a01b031663de7b5d146040518163ffffffff1660e01b8152600401602060405180830381865afa1580156108e9573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061090d91906155f8565b30906001600160a01b0316811461094157604051633122109760e11b81526004016109389190615172565b60405180910390fd5b50604051632fc8579560e11b8152600481018590525f906001600160a01b03831690635f90af2a90602401602060405180830381865afa158015610987573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906109ab91906155f8565b90508430826001600160a01b03811682146109f357604051635fce3e5f60e11b815260048101939093526001600160a01b039182166024840152166044820152606401610938565b50506040516318feeb1560e31b8152600481018790525f91506001600160a01b0385169063c7f758a8906024016101a060405180830381865afa158015610a3c573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610a60919061565b565b9050826001600160a01b031681606001516001600160a01b0316148690610a9d5760405163524f39ab60e01b815260040161093891815260200190565b5060808101518151515f91610ab191612ab8565b600387015460405163eaeded5f60e01b81529192505f916001600160a01b039091169063eaeded5f90610aea9030908690600401615730565b602060405180830381865afa158015610b05573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610b299190615749565b600388015460405163350c7fbd60e11b8152600481018b905260248101839052600160448201529192506001600160a01b031690636a18ff7a906064015f604051808303815f87803b158015610b7d575f5ffd5b505af1158015610b8f573d5f5f3e3d5ffd5b505050506003870154604051633548aa8b60e11b81526004810184905230916001600160a01b031690636a91551690602401602060405180830381865afa158015610bdc573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610c0091906155f8565b6001600160a01b031603610d5b576003870154604080516327daf1c360e21b815290515f926001600160a01b031691639f6bc70c9160048083019260209291908290030181865afa158015610c57573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610c7b91906155f8565b600389015460405163eaeded5f60e01b81529192506001600160a01b03169063eaeded5f90610cb09084908790600401615730565b602060405180830381865afa158015610ccb573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610cef9190615749565b6003890154604051632904bf2760e11b8152600481018c905260248101839052600160448201529193506001600160a01b0316906352097e4e906064015f604051808303815f87803b158015610d43575f5ffd5b505af1158015610d55573d5f5f3e3d5ffd5b50505050505b5050505050505050565b5f610d6f83612ac3565b610d7a57505f6105da565b610d848383612b88565b50600192915050565b5f5f610d9a868686613024565b91509150808310610dbe576040516303e8324160e21b815260040160405180910390fd5b5f610dc98685613220565b610dde57610dd78685613278565b9050610e09565b5f610de987866132f4565b9050610e0284825f0151836020015184604001516133ba565b5090925050505b848481518110610e1b57610e1b615760565b60200260200101516001600160a01b0316816001600160a01b031603610e545760405163045fbdd960e01b815260040160405180910390fd5b610e5d87613478565b50505050505050565b5f610e6f612a94565b6003015460405163ec6e69db60e01b81526001600160a01b039091169063ec6e69db90610ea29030908690600401615730565b602060405180830381865afa158015610ebd573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906105da9190615749565b5f5f610eeb612a94565b90505f610efb82600501546134c9565b90505f610f0a83600601613557565b825190915015801590610f2957506008830154600160401b900460ff16155b15610f605784158015610f3c5750815181105b15610f4b57505f949350505050565b8151851015610f605750602001519392505050565b610f8a610f80836060015187610f76919061579c565b846040015161358a565b8360800151613599565b95945050505050565b5f610f9c612a94565b6002810154909150600160a01b900463ffffffff165f03610fd0576040516307e3807560e31b815260040160405180910390fd5b6002810154600160a01b900463ffffffff1680428111156110075760405163172d344b60e21b815260040161093891815260200190565b5060028201546040805163bffa7f0f60e01b815290516001600160a01b03909216915f91839163bffa7f0f916004808201926020929091908290030181865afa158015611056573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061107a91906155f8565b6001600160a01b0316141581906110a557604051630585518760e01b81526004016109389190615172565b5060018301546001600160a01b03165f6110c262278d00426157af565b600886018054600160481b600160e81b031916600160481b6001600160a01b0386160217905590506110f3816135a8565b60098601805463ffffffff191663ffffffff929092169190911790556001850180546001600160a01b0319166001600160a01b038581169182179092556002870180546001600160c01b031916905560405190918416907fe0d49a54274423183dadecbdf239eaac6e06ba88320b26fe8cc5ec9d050a6395905f90a3816001600160a01b03167f8bd67b063847df48d2b78a3e7258233f0b3acda956b4d531ecf624f6ff11d4cf826040516111aa91815260200190565b60405180910390a25050505050565b5f5f6111c4836135b2565b90506111db816111d2611706565b600301906135c4565b9392505050565b5f61062b6111ee612a94565b600601613557565b60605f6112028361169d565b90506111db8382613675565b5f5f61121983613697565b90506111db8163ffffffff16610e66565b5f5f611234613725565b50909392505050565b5f611246612a94565b6002810154909150600160a01b900463ffffffff165f0361127a576040516307e3807560e31b815260040160405180910390fd5b6002810180546001600160c01b031981169091556040516001600160a01b039091169081907ff44290297bfd8ce2714bc60045350551f0b25d675ca8ef74a67e27f525548334905f90a25050565b5f5f6112d383611613565b90505f6112de612a94565b60030154604051630a6718eb60e31b81526001600160a01b0390911690635338c7589061131190309088906004016157c2565b602060405180830381865afa15801561132c573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906113509190615749565b90505f8260a001511561137757826080015161136d576002611370565b60035b905061138a565b5f8211611384575f611387565b60015b90505b949350505050565b5f61139e848484613024565b91505f9050805b828110156113d2576113b78582613220565b156113ca57816113c6816157dc565b9250505b6001016113a5565b505f6113e36003600185901b61579c565b6113ee9060016157af565b9050808281811061141b5760405163af47297f60e01b815260048101929092526024820152604401610938565b50506107b586613478565b61142e614d3c565b6040518060800160405280611442846112c8565b6003811115611453576114536151e1565b8152602001611460612a94565b60030154604051630a6718eb60e31b81526001600160a01b0390911690635338c7589061149390309088906004016157c2565b602060405180830381865afa1580156114ae573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906114d29190615749565b81526020016114e084611613565b81526020016114ee846120ee565b905292915050565b6001600160a01b03811661151d576040516379179b2160e11b815260040160405180910390fd5b5f816001600160a01b031663a4d2342a6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561155a573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061157e91906155f8565b905030816001600160a01b03811682146115ad57604051630373ca6360e51b81526004016109389291906157c2565b50505f6115b8611706565b90506115c5816003015490565b156115e357604051630ac6e42b60e01b815260040160405180910390fd5b5f6115f76115f042611ac0565b6001612ab8565b90505f611603826135b2565b9050610e5d600384018287613790565b61161b614d6c565b611623612a94565b6001600160a01b039283165f9081526004919091016020908152604091829020825160c08101845281548152600182015492810192909252600281015492820192909252600390910154928316606082015260ff600160a01b8404811615156080830152600160a81b909304909216151560a08301525090565b5f5f6116a7611706565b90505f6116b38461379d565b9050836116c360018401836137cd565b6040516020016116e69291909182526001600160e01b0316602082015260400190565b60408051601f198184030181529190528051602090910120949350505050565b7f9bd0cd65f3d2d8103fe75b0f150f04a46bd0e603fd1819b64700ff42b24ee3aa90565b61173381613815565b61173c816138e4565b611744612a94565b600501556040805182518152602080840151908201528282015181830152606080840151908201526080808401519082015290517f7b26e3a042027ef0e1dae742558aa6568eee81e5ab3452dd6540496f9a03eb599181900360a00190a150565b6117ad614da9565b6105da826117b9612a94565b6006019061396e565b5f61062b6117ce611706565b600301613a4e565b5f6117df612a94565b6003015460405163a9cd26c960e01b81526001600160a01b039091169063a9cd26c990611814903090869042906004016157f4565b602060405180830381865afa15801561182f573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906105da91906155f8565b5f5f5f61185f86613a85565b90505f61186a613ab5565b90505f61187688613ad9565b90505f61188282613b13565b905080848082106118af5760405163083510bd60e41b815260048101929092526024820152604401610938565b50505f82815260018401602052604090205480898082146118ec57604051635b41520760e11b815260048101929092526024820152604401610938565b50505f6118f886611a09565b50905080896001600160a01b038083169082161461192b57604051631510874d60e31b81526004016109389291906157c2565b5086905061193a8560016157af565b97509750505050505050935093915050565b818180821015611978576040516338987de960e11b815260048101929092526024820152604401610938565b50505f611983611706565b905061198e84613b2d565b60028201805463ffffffff191663ffffffff929092169190911790556119b383613b2d565b8160020160046101000a81548163ffffffff021916908363ffffffff1602179055506119de82613b2d565b8160020160086101000a81548163ffffffff021916908363ffffffff1602179055506105ec5f611b18565b5f5f5f5f611a1685613b61565b90925090506001600160a01b03821615611a34579094909350915050565b5f611a3e86613bb2565b90505f611a4a8261169d565b90505f5f611a588484613bd3565b805191935091505f819003611a7857505f998a9950975050505050505050565b5f611a85868c8785613c78565b9050611ab0838281518110611a9c57611a9c615760565b60200260200101518563ffffffff16613cb9565b9b909a5098505050505050505050565b5f5f611aca613d36565b8054909150611aef9063ffffffff600160801b8204811691600160a01b900416615815565b815463ffffffff9190911690611b0e906001600160801b031685615834565b6111db919061579c565b5f611b21611706565b90505f611b3082600101613d5a565b509150505f611b46611b41856135b2565b613b2d565b90508063ffffffff168263ffffffff1610156105ec576107b5600184018244613db7565b5f611b73611706565b60020154600160401b900463ffffffff16919050565b5f61062b611b95612a94565b6008015463ffffffff1690565b5f5f5f611bad611706565b5f858152602082905260408120549450909150839003611be457611be1611bdc85611bd78761169d565b613675565b613dc4565b92505b60020154919363ffffffff909216925050565b5f611c00613df3565b9050805f03611c0d575050565b5f611c16612a94565b90505f611c2582600601613557565b90505f611c3b611c358584613599565b86613599565b9050805f03611c4b575050505050565b600383015460408051635a56229b60e11b815290515f926001600160a01b03169163b4ac45369160048083019260209291908290030181865afa158015611c94573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611cb89190615749565b845460038601549192506001600160a01b039081169163095ea7b39116611cdf8585615847565b6040518363ffffffff1660e01b8152600401611cfc929190615730565b6020604051808303815f875af1158015611d18573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611d3c919061585e565b505f805b83811015611f52575f611d5587600601613e7a565b6003880154815160208301516040808501516060860151608087015160a088015193519798505f9788976001600160a01b031696636902c67b60e01b96611da9969195909490939092909190602401615879565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b0319909416939093179092529051611de791906158dc565b5f604051808303815f865af19150503d805f8114611e20576040519150601f19603f3d011682016040523d82523d5f602084013e611e25565b606091505b50915091508115611ea65784611e3a816157dc565b95505082602001516001600160a01b0316835f01516001600160a01b03167f21d790cf15da7e78046dbc1cf401d93aff7e1df9c8ab8905c9db0c7a3ed569e38560400151866060015187608001518b604051611e9994939291906158f2565b60405180910390a3611f47565b5f815111611ec7576040516306d2a3a560e51b815260040160405180910390fd5b60208301518954611ee4916001600160a01b039091169088613fb0565b82602001516001600160a01b0316835f01516001600160a01b03167fae63502829232952025378f85719b4e2278e77cbf06b29f68618470cd4ae5887856040015186606001518760800151604051611f3e9392919061592f565b60405180910390a35b505050600101611d40565b508454600386015460405163095ea7b360e01b81526001600160a01b039283169263095ea7b392611f8a929116905f90600401615730565b6020604051808303815f875af1158015611fa6573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611fca919061585e565b50611fd481613b2d565b600886018054600490611ff5908490600160201b900463ffffffff16615965565b92506101000a81548163ffffffff021916908363ffffffff1602179055508460080160089054906101000a900460ff16158015612047575061203a85600501546134c9565b5161204442610e66565b10155b15610e5d5760088501805460ff60401b1916600160401b17905550505050505050565b5f612073611706565b5f83815260208290526040902054909150801561208f57505050565b5f6120998461169d565b90506120a484611b18565b5f6120af8583613675565b90506120ba81613dc4565b5f958652602094909452505060409092205550565b5f6120d8611706565b60020154600160201b900463ffffffff16919050565b6120f6614e45565b6120fe612a94565b6003015460405163e48a5f7b60e01b81526001600160a01b039091169063e48a5f7b9061212f908590600401615172565b606060405180830381865afa15801561214a573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906105da9190615981565b5f612177612a94565b90505f6001600160a01b0316826001600160a01b031663bffa7f0f6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156121bf573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906121e391906155f8565b6001600160a01b03161415829061220e57604051630585518760e01b81526004016109389190615172565b505f61221d624f1a00426157af565b6002830180546001600160a01b0319166001600160a01b0386161790559050612245816135a8565b8260020160146101000a81548163ffffffff021916908363ffffffff160217905550826001600160a01b03167f850651f622abde225b1015023a88815eb8220854cb90ad6daf977e2f6df42806826040516122a291815260200190565b60405180910390a2505050565b5f816001600160a01b0381166122d957604051634faf423360e01b81526004016109389190615172565b505f6122e3612a94565b6001600160a01b0385165f908152600482016020526040902060030154909150600160a81b900460ff161561241b576001600160a01b0384165f9081526004820160205260409020600301548490600160a01b900460ff161561235a5760405163695564db60e11b81526004016109389190615172565b506001600160a01b038481165f908152600483016020526040902060030154163381811461239d57604051638e668e5d60e01b81526004016109389291906157c2565b50506001600160a01b038085165f818152600484016020526040908190206003810180546001600160a81b031916948816948517600160a01b1790556001015490517f1577e4658cc494bc5768745d541f9bcc8be48a5a33a380b62ee4e89730d2bb629161240e9190815260200190565b60405180910390a3612702565b6003810154604051630a6718eb60e31b81525f916001600160a01b031690635338c7589061244f90309089906004016157c2565b602060405180830381865afa15801561246a573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061248e9190615749565b905084816124b05760405163695564db60e11b81526004016109389190615172565b50600382015460405162f9f54160e41b81525f916001600160a01b031690630f9f5410906124e2908990600401615172565b602060405180830381865afa1580156124fd573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061252191906155f8565b905080336001600160a01b038216811461255057604051638e668e5d60e01b81526004016109389291906157c2565b5050600383015460405163f3fef3a360e01b81525f91829182916001600160a01b03169063f3fef3a39061258a908c908990600401615730565b6060604051808303815f875af11580156125a6573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906125ca91906159c1565b9250925092508189906125f15760405163377422c160e01b81526004016109389190615172565b506040805160c081018252828152602081018590526003880154909182019061262d904290600160a01b900463ffffffff16612ab8565b612ab8565b81526001600160a01b038a811660208084018290526001604080860182905260609586018290528f85165f81815260048f0185528290208851815588850151938101939093558782015160028401559587015160039092018054608089015160a0909901511515600160a81b0260ff60a81b19991515600160a01b026001600160a81b0319909216949097169390931792909217969096169390931790925592518681527f1577e4658cc494bc5768745d541f9bcc8be48a5a33a380b62ee4e89730d2bb62910160405180910390a350505050505b5060019392505050565b6001600160a01b0386161580159061272c57506001600160a01b03851615155b8686909161274f5760405163799ff46360e11b81526004016109389291906157c2565b50505f61275a612a94565b6001600160a01b0388165f9081526004820160205260409020600301549091508790600160a81b900460ff16156127a55760405163088d88b760e21b81526004016109389190615172565b50600381015460408051635a56229b60e11b815290515f926001600160a01b03169163b4ac45369160048083019260209291908290030181865afa1580156127ef573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906128139190615749565b825490915061282d906001600160a01b0316333084614008565b61283f60068301898989898989614041565b50866001600160a01b0316886001600160a01b03167f676247b4195b3fe545499177befc02b4b4bebd3805a2283b30defcae63d5466160405160405180910390a35050505050505050565b5f612893612a94565b6001600160a01b038084165f908152600483016020908152604091829020825160c08101845281548152600182015492810192909252600281015492820192909252600390910154918216606082015260ff600160a01b8304811615156080830152600160a81b909204909116151560a0820181905291925090839061292d5760405163077ab37760e51b81526004016109389190615172565b50806080015183906129535760405163029af69f60e11b81526004016109389190615172565b50604081015142908082101561298557604051632238609b60e21b815260048101929092526024820152604401610938565b50506001600160a01b038381165f90815260048481016020526040808320838155600181018490556002810193909355600392830180546001600160b01b0319169055918501548451925163049468a960e11b815291820192909252911690630928d152906024015f604051808303815f87803b158015612a04575f5ffd5b505af1158015612a16573d5f5f3e3d5ffd5b505050606082015160208301518454612a3a93506001600160a01b03169190613fb0565b80606001516001600160a01b0316836001600160a01b03167f72454d8aaed6ae02f8c53e38ea0eb6b262eae6125e7dafbd4ab27103101f21228360200151604051612a8791815260200190565b60405180910390a3505050565b7fbba4a4d3c3eeb229c4f06863ce3d3d8cddab9e4dee538d785fc67e2ed9d68cad90565b5f6105d782846157af565b5f5f612acd612a94565b6001600160a01b0384165f9081526004820160205260409020600381015491925090600160a81b900460ff1615612b0a576002810154421061138a565b6003820154604051630a6718eb60e31b81525f916001600160a01b031690635338c75890612b3e90309089906004016157c2565b602060405180830381865afa158015612b59573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612b7d9190615749565b151595945050505050565b5f612b91612a94565b9050612b9d81336141d4565b60018201546001600160a01b0316903390612bcd576040516311d37a1960e11b81526004016109389291906157c2565b50506001600160a01b0383165f90815260048201602052604090206003810154600160a81b900460ff1615612ce357600281015442108490612c2357604051630116fd2560e61b81526004016109389190615172565b505f612c33848360010154613599565b905080826001015403612c81576001600160a01b0385165f908152600484016020526040812081815560018101829055600281019190915560030180546001600160b01b0319169055612c9a565b80826001015f828254612c949190615834565b90915550505b846001600160a01b03167f4ed05e9673c26d2ed44f7ef6a7f2942df0ee3b5e1e17db4b99f9dcd261a339cd82604051612cd591815260200190565b60405180910390a2506105ec565b6003820154604051630a6718eb60e31b81525f916001600160a01b031690635338c75890612d1790309089906004016157c2565b602060405180830381865afa158015612d32573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612d569190615749565b90508481612d7857604051631f8bdfc760e21b81526004016109389190615172565b50600383015460405162f9f54160e41b81525f916001600160a01b031690630f9f541090612daa908990600401615172565b602060405180830381865afa158015612dc5573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612de991906155f8565b90505f612df68684613599565b60018601549091505f90600160a01b90046001600160601b0316612e1a8386615834565b10612e255781612e27565b835b600387015460405163f3fef3a360e01b81529192505f91829182916001600160a01b039091169063f3fef3a390612e64908e908890600401615730565b6060604051808303815f875af1158015612e80573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612ea491906159c1565b919450925090505f612eb68685615834565b9050828015612ec457505f81115b15612fd3576040805160c0810182528381526020810183905260038c01549091820190612eff904290600160a01b900463ffffffff16612ab8565b8152602001886001600160a01b031681526020015f15158152602001600115158152508a6004015f8e6001600160a01b03166001600160a01b031681526020019081526020015f205f820151815f015560208201518160010155604082015181600201556060820151816003015f6101000a8154816001600160a01b0302191690836001600160a01b0316021790555060808201518160030160146101000a81548160ff02191690831515021790555060a08201518160030160156101000a81548160ff0219169083151502179055509050505b8b6001600160a01b03167f4ed05e9673c26d2ed44f7ef6a7f2942df0ee3b5e1e17db4b99f9dcd261a339cd8760405161300e91815260200190565b60405180910390a2505050505050505050505050565b5f5f5f61302f613ab5565b805490915060801c861115613057576040516308a339fb60e21b815260040160405180910390fd5b80546001600160801b0316861161308157604051633ecc4abd60e11b815260040160405180910390fd5b5f61308b8761424d565b90505f8660405160200161309f9190615a27565b604051602081830303815290604052805190602001209050816003015481146130db576040516347c1767160e11b815260040160405180910390fd5b60058201545f906130f69063ffffffff16613bb2565b613bb2565b90505f613102826111b9565b90506001600160a01b0381161561319f57604051631d18577f60e11b8152600481018390525f906001600160a01b03831690633a30aefe906024016040805180830381865afa158015613157573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061317b9190615a5f565b509050801561319d5760405163d251b18b60e01b815260040160405180910390fd5b505b505f5f6131ab83611ba2565b915091505f896040516020016131c19190615186565b60405160208183030381529060405280519060200120905080831481849091613206576040516332a3565560e21b815260048101929092526024820152604401610938565b505050600490940154965092945050505050935093915050565b5f8061322d60088461579c565b90505f61323b600885615a8c565b613246906007615834565b905080855f0151838151811061325e5761325e615760565b60209101015160f81c901c60019081161495945050505050565b60208201515f906132898484613220565b1583906132ac57604051635a5f19b360e11b815260040161093891815260200190565b50602081015f5b848110156132e7576132c58682613220565b6132d05760146132d3565b60415b6132dd90836157af565b91506001016132b3565b505160601c949350505050565b61331860405180606001604052805f60ff1681526020015f81526020015f81525090565b60208301516133278484613220565b839061334957604051637346e14f60e11b815260040161093891815260200190565b50602081015f5b84811015613384576133628682613220565b61336d576014613370565b60415b61337a90836157af565b9150600101613350565b5080516001820151602190920151604080516060810182525f9390931a8352602083019390935291810191909152949350505050565b5f80806fa2a8918ca85bafe22016d0b997e4df60600160ff1b038411156133e957505f9150600390508261346e565b604080515f808252602082018084528a905260ff891692820192909252606081018790526080810186905260019060a0016020604051602081039080840390855afa15801561343a573d5f5f3e3d5ffd5b5050604051601f1901519150506001600160a01b03811661346557505f92506001915082905061346e565b92505f91508190505b9450945094915050565b5f613481613ab5565b9050613499613491600184615834565b8254906142f0565b815560405182907f4271377505594adadc599508fc7e64ce82bfc79e5040857399a7cd1159e1353f905f90a25050565b6134f66040518060a001604052805f81526020015f81526020015f81526020015f81526020015f81525090565b5f8290506040518060a0016040528063ffffffff608084901c16815260200163ffffffff606084901c16815260200163ffffffff604084901c16815260200163ffffffff602084901c16815260200163ffffffff8316815250915050919050565b60018101545f9061357b906001600160801b0380821691600160801b900416615a9f565b6001600160801b031692915050565b5f8282188284110282186105d7565b5f8282188284100282186105d7565b5f6105da82613b2d565b5f6105da6135bf83614319565b61433a565b81545f9081816005811115613621575f6135dd8461436f565b6135e79085615834565b5f888152602090209091508101546001600160601b0390811690871610156136115780915061361f565b61361c8160016157af565b92505b505b5f61362e878785856144c1565b905080156136685761365287613645600184615834565b5f91825260209091200190565b54600160601b90046001600160a01b031661366a565b5f5b979650505050505050565b60605f5f6136838585613bd3565b91509150610f8a8263ffffffff1682614522565b5f5f6136a4611b416145a2565b6136ac611706565b600201546136c79190600160201b900463ffffffff16615815565b90505f816136d7611b41866135b2565b6136e19190615965565b9050834263ffffffff831681101561371b57604051633c6dd5d760e11b8152600481019290925263ffffffff166024820152604401610938565b5090949350505050565b5f5f5f5f613731612a94565b905061373c42611ac0565b600882015490935063ffffffff1683101561376c5760080154600160201b900463ffffffff16939192505f919050565b5f61377642610e66565b90505f61378282610ee1565b969495506001949350505050565b5f806106f78585856145dd565b5f5f6137aa611b416145a2565b6137b2611706565b600201546136c79190600160401b900463ffffffff16615815565b81545f90816137de85858385614733565b9050801561380b576137f585613645600184615834565b54600160201b90046001600160e01b0316610f8a565b505f949350505050565b5f81604001511161383957604051632c171d3d60e01b815260040160405180910390fd5b5f81606001511161385d5760405163087d960960e41b815260040160405180910390fd5b5f816080015111613881576040516366ab021160e01b815260040160405180910390fd5b8051158061389257505f8160200151115b6138af57604051638b9f9f0160e01b815260040160405180910390fd5b60808101516020820151908082111561066b5760405163dda88d2d60e01b815260048101929092526024820152604401610938565b5f5f5f90506138f68360800151613b2d565b63ffffffff1681179050602061390f8460600151613b2d565b63ffffffff16901b81179050604061392a8460400151613b2d565b63ffffffff16901b8117905060606139458460200151613b2d565b63ffffffff16901b81179050608061395f845f0151613b2d565b63ffffffff16901b1792915050565b613976614da9565b600183015483905f906139939085906001600160801b03166157af565b815260208082019290925260409081015f20815160c08101835281546001600160a01b0390811682526001830154168185015282518084018452600283015481526003830154818601528184015282516080808201855260048401548252600584015482870152600684015482860152600784015460608381019190915283019190915283518085019094526008830154845260098301549484019490945292830191909152600a015460ff16151560a08201529392505050565b80545f908015613a7d57613a6783613645600184615834565b54600160601b90046001600160a01b03166111db565b5f9392505050565b5f5f613a8f613d36565b805490915063ffffffff600160801b82041690611b0e906001600160801b031685615834565b7f0958201b72d64259285941dffd868dac55267471fcc73e8a06e1fd9cf870636190565b5f5f613ae3613ab5565b8054909150613af184614786565b613b0457613aff8160801c90565b61138a565b6001600160801b03811661138a565b5f6105da613b208361424d565b6005015463ffffffff1690565b5f63ffffffff821115613b5d576040516306dfcc6560e41b81526020600482015260248101839052604401610938565b5090565b5f5f5f613ba4613ba0613b9d86613b8f6040518060600160405280602c8152602001615c04602c91396147f7565b5f9182526020526040902090565b90565b5c90565b9460a086901c945092505050565b5f613bbb613d36565b546105da90600160a01b900463ffffffff168361579c565b5f60605f613bdf611706565b90505f613beb86613697565b90505f613bfd8263ffffffff16610e66565b600284015490915063ffffffff16818180821015613c375760405163f4f28e9960e01b815260048101929092526024820152604401610938565b5050805f03613c5c575050604080515f8152602081019091529093509150613c719050565b82613c6882848a61480e565b95509550505050505b9250929050565b6040805160208101869052908101849052606081018390525f908290608001604051602081830303815290604052805190602001205f1c6113879190615a8c565b5f613cc2612a94565b6003015460405163a9cd26c960e01b81526001600160a01b039091169063a9cd26c990613cf7903090879087906004016157f4565b602060405180830381865afa158015613d12573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906105d791906155f8565b7fcc2bde3d21ba778aa5c156bb6fc47381978b0054c8a1ef73f44234164324cbe090565b80545f9081908190808203613d78575f5f5f93509350935050613db0565b5f613d8886613645600185615834565b546001955063ffffffff81169450600160201b90046001600160e01b03169250613db0915050565b9193909250565b5f806106f7858585614964565b5f81604051602001613dd69190615186565b604051602081830303815290604052805190602001209050919050565b5f5f5f5f613dff613725565b9250925092508015613e72575f613e14612a94565b9050613e29613e24846001612ab8565b6135a8565b60088201805463ffffffff191663ffffffff92909216919091179055613e4e84613b2d565b8160080160046101000a81548163ffffffff021916908363ffffffff160217905550505b509092915050565b613e82614da9565b60018201546001600160801b03808216600160801b9092041611613eb9576040516360fa223760e11b815260040160405180910390fd5b50600180820180546001600160801b03165f81815260208581526040808320815160c08101835281546001600160a01b03908116825282890154168185015282518084018452600283015481526003830154818601528184015282516080808201855260048401548252600584015482870152600684015482860152600784015460608381019190915283019190915283518085019094526008830154845260098301549484019490945292830191909152600a015460ff16151560a0820152939291613f87908490615abe565b92506101000a8154816001600160801b0302191690836001600160801b03160217905550919050565b61066b83846001600160a01b031663a9059cbb8585604051602401613fd6929190615730565b604051602081830303815290604052915060e01b6020820180516001600160e01b038381831617835250505050614aa7565b6040516001600160a01b0384811660248301528381166044830152606482018390526105ec9186918216906323b872dd90608401613fd6565b5f5f8860010160109054906101000a90046001600160801b031690506040518060c00160405280896001600160a01b03168152602001886001600160a01b03168152602001878152602001868152602001858152602001841515815250895f015f836001600160801b031681526020019081526020015f205f820151815f015f6101000a8154816001600160a01b0302191690836001600160a01b031602179055506020820151816001015f6101000a8154816001600160a01b0302191690836001600160a01b031602179055506040820151816002015f820151815f01556020820151816001015550506060820151816004015f820151815f015560208201518160010155604082015181600201556060820151816003015550506080820151816008015f820151815f015560208201518160010155505060a082015181600a015f6101000a81548160ff0219169083151502179055509050508060016141a99190615abe565b60018a0180546001600160801b03928316600160801b02908316179055169050979650505050505050565b60018201545f906001600160a01b03908116908316036141f6575060016105da565b6008830154600160481b90046001600160a01b031680158061422a5750806001600160a01b0316836001600160a01b031614155b15614238575f9150506105da565b60098401544263ffffffff909116101561138a565b5f5f61426161425a613ab5565b5460801c90565b90505f61426c614b0a565b90505f61427982866157af565b90505f83861115801561428b57508184105b9050858483836142bf57604051638711786b60e01b8152600481019390935260248301919091526044820152606401610938565b5050506142ca613ab5565b6002015f6142d88589615a8c565b81526020019081526020015f20945050505050919050565b5f6001600160801b038316608061430684614b1e565b6001600160801b0316901b179392505050565b5f614322613d36565b546105da90600160a01b900463ffffffff1683615847565b5f5f614344613d36565b80549091506111db906001600160801b0381169061262890600160801b900463ffffffff1686615847565b5f6001821161437c575090565b816001600160801b82106143955760809190911c9060401b5b600160401b82106143ab5760409190911c9060201b5b600160201b82106143c15760209190911c9060101b5b6201000082106143d65760109190911c9060081b5b61010082106143ea5760089190911c9060041b5b601082106143fd5760049190911c9060021b5b600482106144095760011b5b600302600190811c9081858161442157614421615774565b048201901c9050600181858161443957614439615774565b048201901c9050600181858161445157614451615774565b048201901c9050600181858161446957614469615774565b048201901c9050600181858161448157614481615774565b048201901c9050600181858161449957614499615774565b048201901c90506144b88185816144b2576144b2615774565b04821190565b90039392505050565b5f5b8183101561451a575f6144d68484614b51565b5f878152602090209091506001600160601b038616908201546001600160601b0316111561450657809250614514565b6145118160016157af565b93505b506144c3565b509392505050565b606061452c612a94565b60030154604051639796d97760e01b81526001600160a01b0390911690639796d9779061456190309087908790600401615add565b5f60405180830381865afa15801561457b573d5f5f3e3d5ffd5b505050506040513d5f823e601f3d908101601f191682016040526105d79190810190615b39565b5f5f6145ac613d36565b80549091506145d19063ffffffff600160801b8204811691600160a01b900416615815565b63ffffffff1691505090565b82545f90819080156146d8575f6145f987613645600185615834565b80549091506001600160601b0380821691600160601b90046001600160a01b031690881682111561463d57604051632520601d60e01b815260040160405180910390fd5b876001600160601b0316826001600160601b0316036146795782546001600160601b0316600160601b6001600160a01b038916021783556146ca565b604080518082019091526001600160601b03808a1682526001600160a01b03808a1660208085019182528d54600181018f555f8f81529190912094519151909216600160601b029216919091179101555b94508593506106fc92505050565b5050604080518082019091526001600160601b0380851682526001600160a01b0380851660208085019182528854600181018a555f8a815291822095519251909316600160601b0291909316179201919091559050816106fc565b5f5b8183101561451a575f6147488484614b51565b5f8781526020902090915063ffffffff86169082015463ffffffff16111561477257809250614780565b61477d8160016157af565b93505b50614735565b5f5f614790613ab5565b80549091506001600160801b0381166147a98260801c90565b036147b757505f9392505050565b5f6147d46147cf6001600160801b03841660016157af565b614b6b565b90505f6147e086611ac0565b90506147ec8282614bb6565b159695505050505050565b80516020918201205f19015f9081522060ff191690565b606083838082111561483c57604051631723245360e31b815260048101929092526024820152604401610938565b5050835f036148595750604080515f8152602081019091526111db565b5f846001600160401b0381111561487257614872614ebf565b60405190808252806020026020018201604052801561489b578160200160208202803683370190505b5090505f6148aa600186615834565b90505f5b86811015614923575f6148cc826148c68560016157af565b88614bc8565b90506148d781614c0b565b8483815181106148e9576148e9615760565b6020908102919091010152821561491a5761490c8161490785614c0b565b614c2b565b8261491681615bd2565b9350505b506001016148ae565b505f5b868110156149595761495183828151811061494357614943615760565b60200260200101515f614c2b565b600101614926565b509095945050505050565b82545f9081908015614a4f575f61498087613645600185615834565b805490915063ffffffff80821691600160201b90046001600160e01b03169088168211156149c157604051632520601d60e01b815260040160405180910390fd5b8763ffffffff168263ffffffff16036149f457825463ffffffff16600160201b6001600160e01b038916021783556146ca565b6040805180820190915263ffffffff808a1682526001600160e01b03808a1660208085019182528d54600181018f555f8f81529190912094519151909216600160201b0292169190911791015594508593506106fc92505050565b50506040805180820190915263ffffffff80851682526001600160e01b0380851660208085019182528854600181018a555f8a815291822095519251909316600160201b0291909316179201919091559050816106fc565b5f5f60205f8451602086015f885af180614ac6576040513d5f823e3d81fd5b50505f513d91508115614add578060011415614aea565b6001600160a01b0384163b155b156105ec5783604051635274afe760e01b81526004016109389190615172565b5f614b13614c79565b61062b9060016157af565b5f6001600160801b03821115613b5d576040516306dfcc6560e41b81526080600482015260248101839052604401610938565b5f614b5f600284841861579c565b6105d7908484166157af565b5f5f614b75613ab5565b805490915060801c8381811115614ba8576040516368dd4dfd60e11b815260048101929092526024820152604401610938565b50506111db6130f184613b13565b5f6105d782614bc485614cb9565b1190565b5f60018311614bd857505f6111db565b6040805160208082018590528183018790528251808303840181526060909201909252805191012061138a908490615a8c565b5f5f614c1683614cf1565b90508015614c245792915050565b5090919050565b614c7581614c6f613b9d85613b8f60405180604001604052806018815260200177417a7465632e53616d706c654c69622e4f7665727269646560401b8152506147f7565b90614d35565b5050565b5f5f614c83613d36565b8054909150614ca090600160c01b900463ffffffff1660016157af565b81546106089190600160a01b900463ffffffff16615847565b5f5f614cc3613d36565b80549091506111db908490614ce690600160c01b900463ffffffff166001615be7565b63ffffffff16612ab8565b5f6105da613ba0613b9d84613b8f60405180604001604052806018815260200177417a7465632e53616d706c654c69622e4f7665727269646560401b8152506147f7565b80825d5050565b604080516080810182525f8082526020820152908101614d5a614d6c565b8152602001614d67614e45565b905290565b6040518060c001604052805f81526020015f81526020015f81526020015f6001600160a01b031681526020015f151581526020015f151581525090565b6040518060c001604052805f6001600160a01b031681526020015f6001600160a01b03168152602001614ded60405180604001604052805f81526020015f81525090565b8152602001614e1960405180608001604052805f81526020015f81526020015f81526020015f81525090565b8152602001614e3960405180604001604052805f81526020015f81525090565b81525f60209091015290565b604080516080810182525f918101828152606082018390528152602081019190915290565b5f60208284031215614e7a575f5ffd5b5035919050565b6001600160a01b03811681146105c9575f5ffd5b5f5f60408385031215614ea6575f5ffd5b8235614eb181614e81565b946020939093013593505050565b634e487b7160e01b5f52604160045260245ffd5b604080519081016001600160401b0381118282101715614ef557614ef5614ebf565b60405290565b604051608081016001600160401b0381118282101715614ef557614ef5614ebf565b60405160c081016001600160401b0381118282101715614ef557614ef5614ebf565b60405160e081016001600160401b0381118282101715614ef557614ef5614ebf565b604051601f8201601f191681016001600160401b0381118282101715614f8957614f89614ebf565b604052919050565b5f82601f830112614fa0575f5ffd5b81356001600160401b03811115614fb957614fb9614ebf565b614fcc601f8201601f1916602001614f61565b818152846020838601011115614fe0575f5ffd5b816020850160208301375f918101602001919091529392505050565b5f6040828403121561500c575f5ffd5b615014614ed3565b905081356001600160401b0381111561502b575f5ffd5b61503784828501614f91565b82525060208201356001600160401b03811115615052575f5ffd5b61505e84828501614f91565b60208301525092915050565b5f6001600160401b0382111561508257615082614ebf565b5060051b60200190565b5f82601f83011261509b575f5ffd5b81356150ae6150a98261506a565b614f61565b8082825260208201915060208360051b8601019250858311156150cf575f5ffd5b602085015b838110156150f55780356150e781614e81565b8352602092830192016150d4565b5095945050505050565b5f5f5f5f60808587031215615112575f5ffd5b8435935060208501356001600160401b0381111561512e575f5ffd5b61513a87828801614ffc565b93505060408501356001600160401b03811115615155575f5ffd5b6151618782880161508c565b949793965093946060013593505050565b6001600160a01b0391909116815260200190565b602080825282518282018190525f918401906040840190835b818110156149595783516001600160a01b031683526020938401939092019160010161519f565b5f602082840312156151d6575f5ffd5b81356111db81614e81565b634e487b7160e01b5f52602160045260245ffd5b6004811061521157634e487b7160e01b5f52602160045260245ffd5b9052565b602081016105da82846151f5565b5f5f5f60608486031215615235575f5ffd5b8335925060208401356001600160401b03811115615251575f5ffd5b61525d86828701614ffc565b92505060408401356001600160401b03811115615278575f5ffd5b6152848682870161508c565b9150509250925092565b8051825260208082015190830152604080820151908301526060808201516001600160a01b03169083015260808082015115159083015260a0908101511515910152565b6152e782825180518252602090810151910152565b602001516001600160a01b031660409190910152565b5f610160820190506153108284516151f5565b60208301516020830152604083015161532c604084018261528e565b5060608301516107196101008401826152d2565b60c081016105da828461528e565b5f60a082840312801561535f575f5ffd5b5060405160a081016001600160401b038111828210171561538257615382614ebf565b604090815283358252602080850135908301528381013590820152606080840135908201526080928301359281019290925250919050565b805182526020810151602083015260408101516040830152606081015160608301525050565b81516001600160a01b0390811682526020808401519091169082015260408083015161016083019161541e9084018280518252602090810151910152565b50606083015161543160808401826153ba565b50608083015180516101008401526020015161012083015260a09092015115156101409091015290565b5f5f5f6060848603121561546d575f5ffd5b8335925060208401359150604084013561548681614e81565b809150509250925092565b5f5f5f606084860312156154a3575f5ffd5b505081359360208301359350604090920135919050565b606081016105da82846152d2565b5f5f604083850312156154d9575f5ffd5b82356154e481614e81565b915060208301356154f481614e81565b809150509250929050565b5f6040828403121561550f575f5ffd5b615517614ed3565b823581526020928301359281019290925250919050565b80151581146105c9575f5ffd5b80356155468161552e565b919050565b5f5f5f5f5f5f868803610160811215615562575f5ffd5b873561556d81614e81565b9650602088013561557d81614e81565b955061558c8960408a016154ff565b94506080607f198201121561559f575f5ffd5b506155a8614efb565b6080880135815260a0880135602082015260c0880135604082015260e0880135606082015292506155dd8861010089016154ff565b91506155ec610140880161553b565b90509295509295509295565b5f60208284031215615608575f5ffd5b81516111db81614e81565b805161554681614e81565b805160098110615546575f5ffd5b5f6040828403121561563c575f5ffd5b615644614ed3565b825181526020928301519281019290925250919050565b5f8183036101a08112801561566e575f5ffd5b50615677614f1d565b60e0821215615684575f5ffd5b61568c614f3f565b845181526020808601519082015260408086015190820152606080860151908201526080808601519082015260a0808601519082015260c0808601519082015280825291506156dd60e0850161561e565b60208201526156ef6101008501615613565b60408201526157016101208501615613565b606082015261014084015160808201819052915061572385610160860161562c565b60a0820152949350505050565b6001600160a01b03929092168252602082015260400190565b5f60208284031215615759575f5ffd5b5051919050565b634e487b7160e01b5f52603260045260245ffd5b634e487b7160e01b5f52601260045260245ffd5b634e487b7160e01b5f52601160045260245ffd5b5f826157aa576157aa615774565b500490565b808201808211156105da576105da615788565b6001600160a01b0392831681529116602082015260400190565b5f600182016157ed576157ed615788565b5060010190565b6001600160a01b039390931683526020830191909152604082015260600190565b63ffffffff818116838216029081169081811461071957610719615788565b818103818111156105da576105da615788565b80820281158282048414176105da576105da615788565b5f6020828403121561586e575f5ffd5b81516111db8161552e565b6001600160a01b0387811682528616602082015261016081016158a9604083018780518252602090810151910152565b6158b660808301866153ba565b835161010083015260209093015161012082015290151561014090910152949350505050565b5f82518060208501845e5f920191825250919050565b8451815260208086015190820152610120810161591260408301866153ba565b835160c083015260209093015160e0820152610100015292915050565b8351815260208085015190820152610100810161594f60408301856153ba565b825160c0830152602083015160e083015261138a565b63ffffffff82811682821603908111156105da576105da615788565b5f6060828403128015615992575f5ffd5b5061599b614ed3565b6159a5848461562c565b815260408301516159b581614e81565b60208201529392505050565b5f5f5f606084860312156159d3575f5ffd5b835160208501519093506159e68161552e565b6040949094015192959394509192915050565b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b602081525f825160406020840152615a4260608401826159f9565b90506020840151601f19848303016040850152610f8a82826159f9565b5f5f60408385031215615a70575f5ffd5b8251615a7b8161552e565b60208401519092506154f481614e81565b5f82615a9a57615a9a615774565b500690565b6001600160801b0382811682821603908111156105da576105da615788565b6001600160801b0381811683821601908111156105da576105da615788565b6001600160a01b0384168152602080820184905260606040830181905283519083018190525f918401906080840190835b81811015615b2c578351835260209384019390920191600101615b0e565b5090979650505050505050565b5f60208284031215615b49575f5ffd5b81516001600160401b03811115615b5e575f5ffd5b8201601f81018413615b6e575f5ffd5b8051615b7c6150a98261506a565b8082825260208201915060208360051b850101925086831115615b9d575f5ffd5b6020840193505b82841015615bc8578351615bb781614e81565b825260209384019390910190615ba4565b9695505050505050565b5f81615be057615be0615788565b505f190190565b63ffffffff81811683821601908111156105da576105da61578856fe617a7465632e76616c696461746f725f73656c656374696f6e2e7472616e7369656e742e70726f706f736572a26469706673582212202875dac4fb81aff6fc26c82777f622ab60ccef6328095b6bfadac1fff11981f164736f6c634300081e0033","storage":{}},"0xf749391f145a83f64cf788e1d6b55d225c004ff7":{"nonce":"0x2","balance":"0x0","code":"0x363d3d373d3d3d363d73c4a8530aeb89da98cd11178930b39c2aa272874e5af43d82803e903d91602b57fd5bf3","storage":{}}} \ No newline at end of file diff --git a/l1-contracts/test/fork/MainnetATPRewardOverride.t.sol b/l1-contracts/test/fork/MainnetATPRewardOverride.t.sol new file mode 100644 index 000000000000..d206852d9d27 --- /dev/null +++ b/l1-contracts/test/fork/MainnetATPRewardOverride.t.sol @@ -0,0 +1,175 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2026 Aztec Labs. +pragma solidity >=0.8.27; + +import {RewardLibBase} from "@test/rollup/libraries/rewardlib/RewardLibBase.sol"; +import { + IATP, + IATPStaker, + RewardLib, + RegistryRewardOverride, + MAX_REGISTRY_REWARD_OVERRIDES +} from "@aztec/core/libraries/rollup/RewardLib.sol"; +import {Epoch} from "@aztec/core/libraries/TimeLib.sol"; +import {TestConstants} from "@test/harnesses/TestConstants.sol"; + +interface IMainnetGSE { + function getWithdrawer(address _attester) external view returns (address); +} + +interface IMainnetRollup { + function getStatus(address _attester) external view returns (uint8); +} + +/** + * @notice Exercises the registry reward override lookup against the real Aztec Token Position (ATP) contracts + * deployed on Ethereum mainnet, using validators whose stake is held by an ATP staker. + * + * @dev The test runs offline by default: `setUp` loads a snapshot of the mainnet accounts and storage slots it + * touches from `MAINNET_FIXTURE`. To refresh the snapshot, run with `MAINNET_ATP_FIXTURE_RPC_URL` set to a + * mainnet RPC url: `setUp` then forks mainnet at `MAINNET_BLOCK`, replays the reads that the tests perform + * so the relevant accounts and slots are pulled into the fork state, and dumps them back into the fixture + * with `vm.dumpState`. The cases below cover both deployed staker implementations (the v1 and v2 + * `ATPWithdrawableAndClaimableStaker`), both ATP registries that stake, and both the direct and the + * `StakingRegistry` provider staking paths. + */ +contract MainnetATPRewardOverrideTest is RewardLibBase { + struct MainnetATPCase { + string name; + address attester; + address staker; + address atp; + address registry; + } + + string internal constant MAINNET_FIXTURE = "./test/fixtures/mainnet_atp_reward_override.json"; + string internal constant MAINNET_RPC_URL_ENV = "MAINNET_ATP_FIXTURE_RPC_URL"; + + uint256 internal constant MAINNET_BLOCK = 25_934_884; + address internal constant MAINNET_GSE = 0xa92ecFD0E70c9cd5E5cd76c50Af0F7Da93567a4f; + address internal constant MAINNET_ROLLUP = 0x91fF8bbD8Ebb07893010D50A48A1609e5EBd8E34; + address internal constant AUCTION_ATP_REGISTRY = 0x63841bAD6B35b6419e15cA9bBBbDf446D4dC3dde; + address internal constant GENESIS_SALE_ATP_REGISTRY = 0x8F778768aDed86AB778a47cd81b3b42B4b3F655B; + + uint8 internal constant STATUS_VALIDATING = 1; + + MainnetATPCase[] internal cases; + + function setUp() public { + cases.push( + MainnetATPCase({ + name: "auction ATP, v2 staker, staked directly", + attester: 0x87094307212E6A10AA62c0cc45bAa8e9182A980d, + staker: 0x9c8bF8Fa4E88316ADe54b201b64007Afda68fAB4, + atp: 0x1F37cF7a4BB4a54838b67D3A19a586230e8d0D34, + registry: AUCTION_ATP_REGISTRY + }) + ); + cases.push( + MainnetATPCase({ + name: "genesis sale ATP, v1 staker, staked directly", + attester: 0x11eb3f22E78700396a952bCc35D74886b61984C1, + staker: 0x02Cbf45ba5e6364C53F0623c2200F40746a735b9, + atp: 0x04623F9F5e51e11906e7480F0faA1443974f2506, + registry: GENESIS_SALE_ATP_REGISTRY + }) + ); + cases.push( + MainnetATPCase({ + name: "auction ATP, v2 staker, staked through StakingRegistry provider", + attester: 0x2721A10C4aCd94d0830Bda103c0Da4F796E5E93e, + staker: 0x56860f956899139C65d4686b74BfC8238C6D8F57, + atp: 0xf749391F145a83f64Cf788e1D6b55d225c004FF7, + registry: AUCTION_ATP_REGISTRY + }) + ); + + string memory rpcUrl = vm.envOr(MAINNET_RPC_URL_ENV, string("")); + if (bytes(rpcUrl).length == 0) { + vm.loadAllocs(MAINNET_FIXTURE); + return; + } + + vm.createSelectFork(rpcUrl, MAINNET_BLOCK); + _readMainnetState(); + vm.dumpState(MAINNET_FIXTURE); + } + + function test_MainnetATPValidatorsHaveStakerAsWithdrawer() external view { + for (uint256 i = 0; i < cases.length; i++) { + MainnetATPCase memory c = cases[i]; + assertEq(IMainnetRollup(MAINNET_ROLLUP).getStatus(c.attester), STATUS_VALIDATING, c.name); + assertEq(IMainnetGSE(MAINNET_GSE).getWithdrawer(c.attester), c.staker, c.name); + assertEq(IATPStaker(c.staker).getATP(), c.atp, c.name); + assertEq(IATP(c.atp).getRegistry(), c.registry, c.name); + } + } + + function test_MainnetATPStakersDoNotExposeRegistryDirectly() external view { + for (uint256 i = 0; i < cases.length; i++) { + (bool responded,) = RewardLib.tryGetAddress(cases[i].staker, IATP.getRegistry.selector); + assertFalse(responded, cases[i].name); + } + } + + function test_ResolvesRegistryFromMainnetATPStakers() external view { + for (uint256 i = 0; i < cases.length; i++) { + (bool responded, address registry) = RewardLib.tryGetRegistry(cases[i].staker); + assertTrue(responded, cases[i].name); + assertEq(registry, cases[i].registry, cases[i].name); + } + } + + function test_MainnetATPValidatorsReceiveRegistryRewardOverride() external prepare(100e18, 5000) { + RegistryRewardOverride[MAX_REGISTRY_REWARD_OVERRIDES] memory overrides; + overrides[0] = RegistryRewardOverride({registry: AUCTION_ATP_REGISTRY, sequencerReward: 10e18}); + overrides[1] = RegistryRewardOverride({registry: GENESIS_SALE_ATP_REGISTRY, sequencerReward: 20e18}); + + _settleEachCaseAndAssertSequencerRewards(overrides, 10e18, 20e18); + } + + function test_OnlyMainnetATPValidatorsOfOverriddenRegistryReceiveOverride() external prepare(100e18, 5000) { + RegistryRewardOverride[MAX_REGISTRY_REWARD_OVERRIDES] memory overrides; + overrides[0] = RegistryRewardOverride({registry: AUCTION_ATP_REGISTRY, sequencerReward: 10e18}); + + // The genesis sale registry has no override, so its validator keeps the default 50% of 100e18. + _settleEachCaseAndAssertSequencerRewards(overrides, 10e18, 50e18); + } + + function _settleEachCaseAndAssertSequencerRewards( + RegistryRewardOverride[MAX_REGISTRY_REWARD_OVERRIDES] memory _overrides, + uint256 _auctionSequencerReward, + uint256 _genesisSaleSequencerReward + ) internal { + // Each case settles a different epoch, so move past them to make their sample seeds stable. + vm.warp( + block.timestamp + (cases.length + 1) * TestConstants.AZTEC_EPOCH_DURATION * TestConstants.AZTEC_SLOT_DURATION + ); + + uint256 expectedSequencerRewards = 0; + for (uint256 i = 0; i < cases.length; i++) { + MainnetATPCase memory c = cases[i]; + wrapper.setWithdrawer(c.attester, IMainnetGSE(MAINNET_GSE).getWithdrawer(c.attester)); + + address[] memory committee = new address[](1); + committee[0] = c.attester; + wrapper.handleRewardsAndFees(args, Epoch.wrap(i), committee, _overrides); + + expectedSequencerRewards += c.registry == AUCTION_ATP_REGISTRY + ? _auctionSequencerReward + : _genesisSaleSequencerReward; + assertEq(wrapper.getSequencerRewards(sequencer), expectedSequencerRewards, c.name); + assertEq(wrapper.getCollectiveProverRewardsForEpoch(Epoch.wrap(i)), 50e18, c.name); + } + } + + function _readMainnetState() internal view { + for (uint256 i = 0; i < cases.length; i++) { + MainnetATPCase memory c = cases[i]; + IMainnetRollup(MAINNET_ROLLUP).getStatus(c.attester); + address withdrawer = IMainnetGSE(MAINNET_GSE).getWithdrawer(c.attester); + RewardLib.tryGetAddress(withdrawer, IATP.getRegistry.selector); + RewardLib.tryGetRegistry(withdrawer); + } + } +} diff --git a/l1-contracts/test/mock/ATPMocks.sol b/l1-contracts/test/mock/ATPMocks.sol new file mode 100644 index 000000000000..4976a281bdab --- /dev/null +++ b/l1-contracts/test/mock/ATPMocks.sol @@ -0,0 +1,44 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2026 Aztec Labs. +pragma solidity >=0.8.27; + +import {IATP, IATPStaker} from "@aztec/core/libraries/rollup/RewardLib.sol"; + +/** + * @notice Minimal stand-in for an Aztec Token Position (ATP): the vesting contract that knows its registry. + */ +contract MockATP is IATP { + address internal immutable REGISTRY; + + constructor(address _registry) { + REGISTRY = _registry; + } + + function getRegistry() external view override(IATP) returns (address) { + return REGISTRY; + } +} + +/** + * @notice Minimal stand-in for an ATP staker: the contract an ATP stakes through, which registers itself as the + * GSE withdrawer and only exposes the ATP it belongs to. + */ +contract MockATPStaker is IATPStaker { + address internal immutable ATP; + + constructor(address _atp) { + ATP = _atp; + } + + function getATP() external view override(IATPStaker) returns (address) { + return ATP; + } +} + +/** + * @notice Deploys a mock ATP for `_registry` and a mock staker pointing at it. + */ +function deployMockATPStaker(address _registry) returns (MockATPStaker staker, MockATP atp) { + atp = new MockATP(_registry); + staker = new MockATPStaker(address(atp)); +} diff --git a/l1-contracts/test/rollup/libraries/rewardlib/registryReward.t.sol b/l1-contracts/test/rollup/libraries/rewardlib/registryReward.t.sol index ea655ddfc528..31e4671bac54 100644 --- a/l1-contracts/test/rollup/libraries/rewardlib/registryReward.t.sol +++ b/l1-contracts/test/rollup/libraries/rewardlib/registryReward.t.sol @@ -4,7 +4,8 @@ pragma solidity >=0.8.27; import {RewardLibBase} from "./RewardLibBase.sol"; import { - IRegistryProvider, + IATP, + IATPStaker, Bps, MutableRewardConfig, RegistryRewardOverride, @@ -12,25 +13,14 @@ import { } from "@aztec/core/libraries/rollup/RewardLib.sol"; import {Epoch, Slot} from "@aztec/core/libraries/TimeLib.sol"; import {MAXIMUM_COMMITTEE_SIZE} from "@aztec/core/interfaces/IValidatorSelection.sol"; - -contract RewardRegistryProvider is IRegistryProvider { - address internal immutable registry; - - constructor(address _registry) { - registry = _registry; - } - - function getRegistry() external view returns (address) { - return registry; - } -} +import {MockATP, MockATPStaker, deployMockATPStaker} from "@test/mock/ATPMocks.sol"; contract RegistryRewardTest is RewardLibBase { function test_WhenWithdrawerRegistryMatchesOverride() external prepare(100e18, 5000) { address attester = makeAddr("attester"); address registry = makeAddr("registry"); - RewardRegistryProvider provider = new RewardRegistryProvider(registry); - wrapper.setWithdrawer(attester, address(provider)); + (MockATPStaker staker,) = deployMockATPStaker(registry); + wrapper.setWithdrawer(attester, address(staker)); RegistryRewardOverride[MAX_REGISTRY_REWARD_OVERRIDES] memory overrides; overrides[1] = RegistryRewardOverride({registry: registry, sequencerReward: 10e18}); @@ -43,8 +33,8 @@ contract RegistryRewardTest is RewardLibBase { function test_WhenOverrideExceedsUpdatedDefaultReward_CapsAtDefault() external prepare(100e18, 5000) { address attester = makeAddr("attester"); address registry = makeAddr("registry"); - RewardRegistryProvider provider = new RewardRegistryProvider(registry); - wrapper.setWithdrawer(attester, address(provider)); + (MockATPStaker staker,) = deployMockATPStaker(registry); + wrapper.setWithdrawer(attester, address(staker)); RegistryRewardOverride[MAX_REGISTRY_REWARD_OVERRIDES] memory overrides; overrides[0] = RegistryRewardOverride({registry: registry, sequencerReward: 40e18}); @@ -58,8 +48,8 @@ contract RegistryRewardTest is RewardLibBase { function test_WhenWithdrawerRegistryMatchesZeroRewardOverrideAcrossCheckpoints() external prepare(100e18, 5000) { address attester = makeAddr("attester"); address registry = makeAddr("registry"); - RewardRegistryProvider provider = new RewardRegistryProvider(registry); - wrapper.setWithdrawer(attester, address(provider)); + (MockATPStaker staker, MockATP atp) = deployMockATPStaker(registry); + wrapper.setWithdrawer(attester, address(staker)); args.end = args.start + 1; _setHeaders(2, sequencer); @@ -69,7 +59,8 @@ contract RegistryRewardTest is RewardLibBase { overrides[0] = RegistryRewardOverride({registry: registry, sequencerReward: 0}); vm.expectCall(address(wrapper.gse()), abi.encodeWithSignature("getWithdrawer(address)", attester), 1); - vm.expectCall(address(provider), abi.encodeWithSelector(IRegistryProvider.getRegistry.selector), 1); + vm.expectCall(address(staker), abi.encodeWithSelector(IATPStaker.getATP.selector), 1); + vm.expectCall(address(atp), abi.encodeWithSelector(IATP.getRegistry.selector), 1); wrapper.handleRewardsAndFees(args, Epoch.wrap(0), _singletonCommittee(attester), overrides); _assertRewards(0, 100e18); @@ -77,14 +68,14 @@ contract RegistryRewardTest is RewardLibBase { function test_WhenZeroRewardProposerAtIndex255Repeats_CachesReward() external prepare(100e18, 5000) { address registry = makeAddr("registry"); - RewardRegistryProvider provider = new RewardRegistryProvider(registry); + (MockATPStaker staker, MockATP atp) = deployMockATPStaker(registry); address[] memory committee = new address[](MAXIMUM_COMMITTEE_SIZE); for (uint256 i = 0; i < committee.length; i++) { committee[i] = address(uint160(0x1000 + i)); } committee[255] = makeAddr("attester255"); - wrapper.setWithdrawer(committee[255], address(provider)); + wrapper.setWithdrawer(committee[255], address(staker)); Slot firstSlot = _findSlotForProposerIndex(255, committee.length, 0); Slot secondSlot = _findSlotForProposerIndex(255, committee.length, Slot.unwrap(firstSlot) + 1); @@ -99,7 +90,8 @@ contract RegistryRewardTest is RewardLibBase { overrides[0] = RegistryRewardOverride({registry: registry, sequencerReward: 0}); vm.expectCall(address(wrapper.gse()), abi.encodeWithSignature("getWithdrawer(address)", committee[255]), 1); - vm.expectCall(address(provider), abi.encodeWithSelector(IRegistryProvider.getRegistry.selector), 1); + vm.expectCall(address(staker), abi.encodeWithSelector(IATPStaker.getATP.selector), 1); + vm.expectCall(address(atp), abi.encodeWithSelector(IATP.getRegistry.selector), 1); wrapper.handleRewardsAndFees(args, Epoch.wrap(0), committee, overrides); _assertRewards(0, 100e18); @@ -107,12 +99,12 @@ contract RegistryRewardTest is RewardLibBase { function test_WhenCommitteeMembersShareWithdrawer_AppliesOverrideToBoth() external prepare(100e18, 5000) { address registry = makeAddr("registry"); - RewardRegistryProvider provider = new RewardRegistryProvider(registry); + (MockATPStaker staker,) = deployMockATPStaker(registry); address[] memory committee = new address[](2); committee[0] = makeAddr("attester0"); committee[1] = makeAddr("attester1"); - wrapper.setWithdrawer(committee[0], address(provider)); - wrapper.setWithdrawer(committee[1], address(provider)); + wrapper.setWithdrawer(committee[0], address(staker)); + wrapper.setWithdrawer(committee[1], address(staker)); args.end = args.start + 1; _setHeaders(2, sequencer); @@ -142,8 +134,8 @@ contract RegistryRewardTest is RewardLibBase { function test_WhenWithdrawerRegistryDoesNotMatchOverride() external prepare(100e18, 5000) { address attester = makeAddr("attester"); - RewardRegistryProvider provider = new RewardRegistryProvider(makeAddr("unknownRegistry")); - wrapper.setWithdrawer(attester, address(provider)); + (MockATPStaker staker,) = deployMockATPStaker(makeAddr("unknownRegistry")); + wrapper.setWithdrawer(attester, address(staker)); RegistryRewardOverride[MAX_REGISTRY_REWARD_OVERRIDES] memory overrides; overrides[0] = RegistryRewardOverride({registry: makeAddr("configuredRegistry"), sequencerReward: 10e18}); @@ -154,6 +146,20 @@ contract RegistryRewardTest is RewardLibBase { _assertRewards(50e18, 50e18); } + function test_WhenWithdrawerIsATPInsteadOfStaker_UsesDefault() external prepare(100e18, 5000) { + address attester = makeAddr("attester"); + address registry = makeAddr("registry"); + MockATP atp = new MockATP(registry); + wrapper.setWithdrawer(attester, address(atp)); + + RegistryRewardOverride[MAX_REGISTRY_REWARD_OVERRIDES] memory overrides; + overrides[0] = RegistryRewardOverride({registry: registry, sequencerReward: 10e18}); + + wrapper.handleRewardsAndFees(args, Epoch.wrap(0), _singletonCommittee(attester), overrides); + + _assertRewards(50e18, 50e18); + } + function test_WhenWithdrawerDoesNotRespondWithRegistry() external prepare(100e18, 5000) { address attester = makeAddr("attester"); wrapper.setWithdrawer(attester, makeAddr("eoaWithdrawer")); diff --git a/l1-contracts/test/rollup/libraries/rewardlib/tryGetRegistry.t.sol b/l1-contracts/test/rollup/libraries/rewardlib/tryGetRegistry.t.sol index 3274b1eef92b..4ff1f3c3705c 100644 --- a/l1-contracts/test/rollup/libraries/rewardlib/tryGetRegistry.t.sol +++ b/l1-contracts/test/rollup/libraries/rewardlib/tryGetRegistry.t.sol @@ -3,22 +3,19 @@ pragma solidity >=0.8.27; import {TestBase} from "@test/base/Base.sol"; -import {IRegistryProvider, RewardLib} from "@aztec/core/libraries/rollup/RewardLib.sol"; +import {IATP, IATPStaker, RewardLib} from "@aztec/core/libraries/rollup/RewardLib.sol"; +import {MockATP, MockATPStaker, deployMockATPStaker} from "@test/mock/ATPMocks.sol"; -contract RegistryProvider is IRegistryProvider { - address private immutable registry; - - constructor(address _registry) { - registry = _registry; +contract RevertingAddressGetter is IATP, IATPStaker { + function getRegistry() external pure override(IATP) returns (address) { + _revert(); } - function getRegistry() external view override returns (address) { - return registry; + function getATP() external pure override(IATPStaker) returns (address) { + _revert(); } -} -contract RevertingRegistryProvider is IRegistryProvider { - function getRegistry() external pure override returns (address) { + function _revert() internal pure { assembly ("memory-safe") { mstore(0x00, 0x42) revert(0x00, 0x20) @@ -26,7 +23,7 @@ contract RevertingRegistryProvider is IRegistryProvider { } } -contract VariableReturnDataRegistryProvider { +contract VariableReturnDataAddressGetter { uint256 private immutable returnDataSize; constructor(uint256 _returnDataSize) { @@ -43,8 +40,16 @@ contract VariableReturnDataRegistryProvider { } } -contract DirtyAddressRegistryProvider is IRegistryProvider { - function getRegistry() external pure override returns (address) { +contract DirtyAddressGetter is IATP, IATPStaker { + function getRegistry() external pure override(IATP) returns (address) { + _returnDirty(); + } + + function getATP() external pure override(IATPStaker) returns (address) { + _returnDirty(); + } + + function _returnDirty() internal pure { assembly ("memory-safe") { mstore(0x00, or(shl(160, 1), 0x42)) return(0x00, 0x20) @@ -52,8 +57,16 @@ contract DirtyAddressRegistryProvider is IRegistryProvider { } } -contract GasBurningRegistryProvider is IRegistryProvider { - function getRegistry() external view override returns (address) { +contract GasBurningAddressGetter is IATP, IATPStaker { + function getRegistry() external view override(IATP) returns (address) { + _burn(); + } + + function getATP() external view override(IATPStaker) returns (address) { + _burn(); + } + + function _burn() internal view { uint256 startingGas = gasleft(); while (startingGas - gasleft() < 100_000) {} revert(); @@ -61,56 +74,82 @@ contract GasBurningRegistryProvider is IRegistryProvider { } contract TryGetRegistryTest is TestBase { - function test_WhenWithdrawerReturnsRegistry() external { + function test_WhenStakerAndATPRespond() external { address expectedRegistry = makeAddr("registry"); - RegistryProvider provider = new RegistryProvider(expectedRegistry); + (MockATPStaker staker,) = deployMockATPStaker(expectedRegistry); - (bool responded, address registry) = RewardLib.tryGetRegistry(address(provider)); + (bool responded, address registry) = RewardLib.tryGetRegistry(address(staker)); assertTrue(responded); assertEq(registry, expectedRegistry); } function test_WhenWithdrawerIsEOA() external { - (bool responded, address registry) = RewardLib.tryGetRegistry(makeAddr("eoa")); - assertFalse(responded); - assertEq(registry, address(0)); + _assertInvalidRegistryResponse(makeAddr("eoa")); + } + + function test_WhenWithdrawerExposesRegistryDirectly() external { + // An ATP itself, or any contract that only answers getRegistry(), is not a staker and must not match. + MockATP atp = new MockATP(makeAddr("registry")); + _assertInvalidRegistryResponse(address(atp)); + } + + function test_WhenStakerReturnsZeroATP() external { + MockATPStaker staker = new MockATPStaker(address(0)); + _assertInvalidRegistryResponse(address(staker)); + } + + function test_WhenStakerReturnsEOAAsATP() external { + MockATPStaker staker = new MockATPStaker(makeAddr("eoa")); + _assertInvalidRegistryResponse(address(staker)); } - function test_WhenWithdrawerReturnsZeroRegistry() external { - RegistryProvider provider = new RegistryProvider(address(0)); + function test_WhenATPReturnsZeroRegistry() external { + (MockATPStaker staker,) = deployMockATPStaker(address(0)); - (bool responded, address registry) = RewardLib.tryGetRegistry(address(provider)); + (bool responded, address registry) = RewardLib.tryGetRegistry(address(staker)); assertTrue(responded); assertEq(registry, address(0)); } - function test_WhenWithdrawerReverts() external { - RevertingRegistryProvider provider = new RevertingRegistryProvider(); - _assertInvalidRegistryResponse(address(provider)); + function test_WhenStakerReverts() external { + _assertInvalidRegistryResponse(address(new RevertingAddressGetter())); } - function test_WhenWithdrawerReturnsTooLittleData() external { - VariableReturnDataRegistryProvider provider = new VariableReturnDataRegistryProvider(31); - _assertInvalidRegistryResponse(address(provider)); + function test_WhenATPReverts() external { + _assertInvalidRegistryResponse(address(new MockATPStaker(address(new RevertingAddressGetter())))); } - function test_WhenWithdrawerReturnsTooMuchData() external { - VariableReturnDataRegistryProvider provider = new VariableReturnDataRegistryProvider(33); - _assertInvalidRegistryResponse(address(provider)); + function test_WhenStakerReturnsTooLittleData() external { + _assertInvalidRegistryResponse(address(new VariableReturnDataAddressGetter(31))); } - function test_WhenWithdrawerReturnsDirtyAddress() external { - DirtyAddressRegistryProvider provider = new DirtyAddressRegistryProvider(); - _assertInvalidRegistryResponse(address(provider)); + function test_WhenATPReturnsTooLittleData() external { + _assertInvalidRegistryResponse(address(new MockATPStaker(address(new VariableReturnDataAddressGetter(31))))); } - function test_WhenWithdrawerBurnsProbeGas() external { - GasBurningRegistryProvider provider = new GasBurningRegistryProvider(); + function test_WhenStakerReturnsTooMuchData() external { + _assertInvalidRegistryResponse(address(new VariableReturnDataAddressGetter(33))); + } + + function test_WhenATPReturnsTooMuchData() external { + _assertInvalidRegistryResponse(address(new MockATPStaker(address(new VariableReturnDataAddressGetter(33))))); + } + + function test_WhenStakerReturnsDirtyAddress() external { + _assertInvalidRegistryResponse(address(new DirtyAddressGetter())); + } + + function test_WhenATPReturnsDirtyAddress() external { + _assertInvalidRegistryResponse(address(new MockATPStaker(address(new DirtyAddressGetter())))); + } + + function test_WhenStakerBurnsProbeGas() external { + GasBurningAddressGetter staker = new GasBurningAddressGetter(); uint256 gasBefore = gasleft(); - (bool responded, address registry) = RewardLib.tryGetRegistry(address(provider)); + (bool responded, address registry) = RewardLib.tryGetRegistry(address(staker)); uint256 gasUsed = gasBefore - gasleft(); assertFalse(responded); @@ -118,9 +157,24 @@ contract TryGetRegistryTest is TestBase { assertLt(gasUsed, 75_000); } - function test_WhenWithdrawerReturnsLargeData() external { - VariableReturnDataRegistryProvider provider = new VariableReturnDataRegistryProvider(65_536); - _assertInvalidRegistryResponse(address(provider)); + function test_WhenATPBurnsProbeGas() external { + MockATPStaker staker = new MockATPStaker(address(new GasBurningAddressGetter())); + + uint256 gasBefore = gasleft(); + (bool responded, address registry) = RewardLib.tryGetRegistry(address(staker)); + uint256 gasUsed = gasBefore - gasleft(); + + assertFalse(responded); + assertEq(registry, address(0)); + assertLt(gasUsed, 100_000); + } + + function test_WhenStakerReturnsLargeData() external { + _assertInvalidRegistryResponse(address(new VariableReturnDataAddressGetter(65_536))); + } + + function test_WhenATPReturnsLargeData() external { + _assertInvalidRegistryResponse(address(new MockATPStaker(address(new VariableReturnDataAddressGetter(65_536))))); } function _assertInvalidRegistryResponse(address _withdrawer) internal view { From b2e96e2c3f4460da399a604f01282fd1428a6019 Mon Sep 17 00:00:00 2001 From: Santiago Palladino Date: Wed, 9 Sep 2026 11:41:52 -0300 Subject: [PATCH 16/19] fix(l1): restore solhint import order in Rollup.sol Co-Authored-By: Claude Opus 5 (1M context) --- l1-contracts/src/core/Rollup.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/l1-contracts/src/core/Rollup.sol b/l1-contracts/src/core/Rollup.sol index d7fad9afdc23..74bcd1f06c4f 100644 --- a/l1-contracts/src/core/Rollup.sol +++ b/l1-contracts/src/core/Rollup.sol @@ -29,8 +29,8 @@ import {IRewardDistributor} from "@aztec/governance/interfaces/IRewardDistributo import {CompressedSlot, CompressedTimestamp, CompressedTimeMath} from "@aztec/shared/libraries/CompressedTimeMath.sol"; import {Signature} from "@aztec/shared/libraries/SignatureLib.sol"; import {ChainTipsLib, CompressedChainTips} from "./libraries/compressed-data/Tips.sol"; -import {RewardExtLib, RewardConfig} from "./libraries/rollup/RewardExtLib.sol"; import {FeeLib} from "./libraries/rollup/FeeLib.sol"; +import {RewardExtLib, RewardConfig} from "./libraries/rollup/RewardExtLib.sol"; import {RewardLib} from "./libraries/rollup/RewardLib.sol"; import {DepositArgs} from "./libraries/StakingQueue.sol"; import { From 8c65270f3040ad8a51802fa7038130b463bcd35d Mon Sep 17 00:00:00 2001 From: Santiago Palladino Date: Wed, 9 Sep 2026 12:34:31 -0300 Subject: [PATCH 17/19] refactor(l1): move fee admin paths into RewardExtLib to fit EIP-170 Rollup was 25,097 bytes, 521 over the 24,576 limit, so deploying it reverted. The owner-only fee and reward setters now do their validation, mutation and event emission inside RewardExtLib instead of the Rollup: each emit site cost the Rollup ~75 bytes of topic hash and argument encoding, and the inlined FeeLib mutators cost several hundred more. Rollup drops to 23,023 (1,553 bytes of margin, more than the 886 on next). Behaviour is unchanged: a delegatecall preserves msg.sender, storage and the log's emitting address, and the external ABI is identical. Only cold admin calls pay the extra delegatecall -- propose reaches FeeLib through ProposeLib, so the hot paths are untouched. Co-Authored-By: Claude Opus 5 (1M context) --- .../partial_epoch_proof_gas_report.json | 2 +- l1-contracts/src/core/RollupCore.sol | 20 +++------ .../core/libraries/rollup/RewardExtLib.sol | 42 +++++++++++++++++-- .../rollup/ValidatorOperationsExtLib.sol | 2 + 4 files changed, 46 insertions(+), 20 deletions(-) diff --git a/l1-contracts/partial_epoch_proof_gas_report.json b/l1-contracts/partial_epoch_proof_gas_report.json index 80164e2b147d..2b99575d0134 100644 --- a/l1-contracts/partial_epoch_proof_gas_report.json +++ b/l1-contracts/partial_epoch_proof_gas_report.json @@ -3,7 +3,7 @@ "contract": "test/RollupWithPreheating.sol:RollupWithPreheating", "deployment": { "gas": 0, - "size": 44946 + "size": 42872 }, "functions": { "gasReportSubmit16Checkpoints((uint256,uint256,(bytes32,bytes32,bytes32,bytes32,bytes32,address),(address,uint256)[],(bytes32,bytes32,bytes32,bytes32,bytes32,uint256,uint256,address,bytes32,(uint128,uint128),uint256,uint256)[],(bytes,bytes),bytes,bytes))": { diff --git a/l1-contracts/src/core/RollupCore.sol b/l1-contracts/src/core/RollupCore.sol index d71444adf28e..41357d259ce3 100644 --- a/l1-contracts/src/core/RollupCore.sol +++ b/l1-contracts/src/core/RollupCore.sol @@ -317,7 +317,6 @@ contract RollupCore is EIP712("Aztec Rollup", "1"), Ownable, IStakingCore, IVali */ function setRewardConfig(MutableRewardConfig memory _config) external override(IRollupCore) onlyOwner { RewardExtLib.updateConfig(_config); - emit RewardConfigUpdated(_config); } /** @@ -328,11 +327,7 @@ contract RollupCore is EIP712("Aztec Rollup", "1"), Ownable, IStakingCore, IVali * @param _manaTarget The new target mana per slot */ function updateManaTarget(uint256 _manaTarget) external override(IRollupCore) onlyOwner { - uint256 currentManaTarget = FeeLib.getStorage().config.getManaTarget(); - require(_manaTarget >= currentManaTarget, Errors.Rollup__InvalidManaTarget(currentManaTarget, _manaTarget)); - FeeLib.updateManaTarget(_manaTarget); - - emit IRollupCore.ManaTargetUpdated(_manaTarget); + RewardExtLib.updateManaTarget(_manaTarget); } /** @@ -365,7 +360,7 @@ contract RollupCore is EIP712("Aztec Rollup", "1"), Ownable, IStakingCore, IVali * @param _provingCostPerMana The cost in ETH per unit of mana for proving */ function setProvingCostPerMana(EthValue _provingCostPerMana) external override(IRollupCore) onlyOwner { - FeeLib.updateProvingCostPerMana(_provingCostPerMana); + RewardExtLib.updateProvingCostPerMana(_provingCostPerMana); } /** @@ -376,10 +371,7 @@ contract RollupCore is EIP712("Aztec Rollup", "1"), Ownable, IStakingCore, IVali * @param _protocolFeeMarginBps The new margin in basis points */ function setProtocolFeeMargin(uint16 _protocolFeeMarginBps) external override(IRollupCore) onlyOwner { - (bool changed, uint16 oldBps) = RewardExtLib.updateProtocolFeeMargin(_protocolFeeMarginBps); - if (changed) { - emit IRollupCore.ProtocolFeeMarginUpdated(oldBps, _protocolFeeMarginBps); - } + RewardExtLib.updateProtocolFeeMargin(_protocolFeeMarginBps); } /** @@ -388,8 +380,7 @@ contract RollupCore is EIP712("Aztec Rollup", "1"), Ownable, IStakingCore, IVali * @param _recipient The new protocol fee recipient */ function setProtocolFeeRecipient(address _recipient) external override(IRollupCore) onlyOwner { - address oldRecipient = RewardExtLib.updateProtocolFeeRecipient(_recipient); - emit IRollupCore.ProtocolFeeRecipientUpdated(oldRecipient, _recipient); + RewardExtLib.updateProtocolFeeRecipient(_recipient); } /** @@ -411,7 +402,6 @@ contract RollupCore is EIP712("Aztec Rollup", "1"), Ownable, IStakingCore, IVali */ function setEscapeHatch(address _escapeHatch) external override(IValidatorSelectionCore) onlyOwner { ValidatorOperationsExtLib.setEscapeHatch(_escapeHatch); - emit IValidatorSelectionCore.EscapeHatchSet(_escapeHatch); } /** @@ -637,7 +627,7 @@ contract RollupCore is EIP712("Aztec Rollup", "1"), Ownable, IStakingCore, IVali * Uses current L1 gas price and blob gas price for calculations. */ function updateL1GasFeeOracle() public override(IRollupCore) { - FeeLib.updateL1GasFeeOracle(); + RewardExtLib.updateL1GasFeeOracle(); } /** diff --git a/l1-contracts/src/core/libraries/rollup/RewardExtLib.sol b/l1-contracts/src/core/libraries/rollup/RewardExtLib.sol index 1bf3f7774fd5..2ea8d7e07f1f 100644 --- a/l1-contracts/src/core/libraries/rollup/RewardExtLib.sol +++ b/l1-contracts/src/core/libraries/rollup/RewardExtLib.sol @@ -2,6 +2,9 @@ // Copyright 2024 Aztec Labs. pragma solidity >=0.8.27; +import {IRollupCore} from "@aztec/core/interfaces/IRollup.sol"; +import {FeeConfigLib, CompressedFeeConfig} from "@aztec/core/libraries/compressed-data/fees/FeeConfig.sol"; +import {Errors} from "@aztec/core/libraries/Errors.sol"; import { FeeLib, ManaMinFeeComponents, @@ -29,6 +32,8 @@ import {IRewardDistributor} from "@aztec/governance/interfaces/IRewardDistributo import {IERC20} from "@oz/token/ERC20/IERC20.sol"; library RewardExtLib { + using FeeConfigLib for CompressedFeeConfig; + function initializeConfig( RewardConfig memory _config, RegistryRewardOverride[MAX_REGISTRY_REWARD_OVERRIDES] memory _registryRewardOverrides @@ -37,16 +42,45 @@ library RewardExtLib { RewardLib.initializeConfig(_config); } + /** + * @dev The owner-only fee and reward setters below hold their validation, mutation and event + * emission here rather than in the Rollup. The Rollup sits close to the EIP-170 limit, and + * an event's topic hash plus its argument encoding costs it ~75 bytes per emit site; the + * `FeeLib` mutators inline another few hundred. A delegatecall keeps `msg.sender`, storage + * and the log's emitting address, so moving them across this boundary is behaviour + * preserving, and it only costs gas on cold admin paths. `ProposeLib` calls `FeeLib` + * directly, so `propose` is unaffected. + */ function updateConfig(MutableRewardConfig memory _config) external { RewardLib.updateConfig(_config); + emit IRollupCore.RewardConfigUpdated(_config); + } + + function updateL1GasFeeOracle() external { + FeeLib.updateL1GasFeeOracle(); + } + + function updateProvingCostPerMana(EthValue _provingCostPerMana) external { + FeeLib.updateProvingCostPerMana(_provingCostPerMana); + } + + function updateManaTarget(uint256 _manaTarget) external { + uint256 currentManaTarget = FeeLib.getStorage().config.getManaTarget(); + require(_manaTarget >= currentManaTarget, Errors.Rollup__InvalidManaTarget(currentManaTarget, _manaTarget)); + FeeLib.updateManaTarget(_manaTarget); + emit IRollupCore.ManaTargetUpdated(_manaTarget); } - function updateProtocolFeeMargin(uint16 _bps) external returns (bool changed, uint16 oldBps) { - return FeeLib.updateProtocolFeeMargin(_bps); + function updateProtocolFeeMargin(uint16 _bps) external { + (bool changed, uint16 oldBps) = FeeLib.updateProtocolFeeMargin(_bps); + if (changed) { + emit IRollupCore.ProtocolFeeMarginUpdated(oldBps, _bps); + } } - function updateProtocolFeeRecipient(address _recipient) external returns (address oldRecipient) { - return RewardLib.updateProtocolFeeRecipient(_recipient); + function updateProtocolFeeRecipient(address _recipient) external { + address oldRecipient = RewardLib.updateProtocolFeeRecipient(_recipient); + emit IRollupCore.ProtocolFeeRecipientUpdated(oldRecipient, _recipient); } function claimSequencerRewards(address _sequencer, IERC20 _feeAsset) external returns (uint256) { diff --git a/l1-contracts/src/core/libraries/rollup/ValidatorOperationsExtLib.sol b/l1-contracts/src/core/libraries/rollup/ValidatorOperationsExtLib.sol index 946b6f6d2d86..737b764855fe 100644 --- a/l1-contracts/src/core/libraries/rollup/ValidatorOperationsExtLib.sol +++ b/l1-contracts/src/core/libraries/rollup/ValidatorOperationsExtLib.sol @@ -4,6 +4,7 @@ pragma solidity >=0.8.27; import {IEscapeHatch} from "@aztec/core/interfaces/IEscapeHatch.sol"; +import {IValidatorSelectionCore} from "@aztec/core/interfaces/IValidatorSelection.sol"; import {Epoch, Slot, Timestamp, TimeLib} from "@aztec/core/libraries/TimeLib.sol"; import {StakingQueueConfig} from "@aztec/core/libraries/compressed-data/StakingQueueConfig.sol"; import {StakingLib, Exit, Status, AttesterView} from "./StakingLib.sol"; @@ -97,6 +98,7 @@ library ValidatorOperationsExtLib { function setEscapeHatch(address _escapeHatch) external { ValidatorSelectionLib.setEscapeHatch(_escapeHatch); + emit IValidatorSelectionCore.EscapeHatchSet(_escapeHatch); } function invalidateBadAttestation( From 32664b72778975ca7d3e90a2023508fe291e9761 Mon Sep 17 00:00:00 2001 From: Santiago Palladino Date: Wed, 9 Sep 2026 13:53:46 -0300 Subject: [PATCH 18/19] ci: fail l1-contracts CI on EIP-170 contract size overage Rollup silently grew past the 24576-byte runtime limit and it only surfaced much later as a deploy revert naming an anonymous CREATE index ("`Unknown11` is above the contract size limit (25097 > 24576)"), which is close to undiagnosable. scripts/check_contract_sizes.sh runs `forge build --sizes` under both the default and the production profile (they remap @aztec-blob-lib differently and so produce different sizes) and fails naming the contract, its size against the limit and the overage. It also warns, without failing, when a contract has less than 1024 bytes left. Co-Authored-By: Claude Opus 5 (1M context) --- l1-contracts/bootstrap.sh | 1 + l1-contracts/scripts/check_contract_sizes.sh | 82 ++++++++++++++++++++ 2 files changed, 83 insertions(+) create mode 100755 l1-contracts/scripts/check_contract_sizes.sh diff --git a/l1-contracts/bootstrap.sh b/l1-contracts/bootstrap.sh index 1dd8d3a098c0..27fc2330bc16 100755 --- a/l1-contracts/bootstrap.sh +++ b/l1-contracts/bootstrap.sh @@ -136,6 +136,7 @@ function build { function test_cmds { echo "$hash cd l1-contracts && solhint --config ./.solhint.json \"src/**/*.sol\"" echo "$hash cd l1-contracts && forge fmt --check" + echo "$hash cd l1-contracts && scripts/check_contract_sizes.sh" echo "$hash cd l1-contracts && forge test" echo "$hash cd l1-contracts && forge test --no-match-contract UniswapPortalTest --match-contract MerkleCheck --ffi" echo "$hash:ISOLATE=1 cd l1-contracts && scripts/test_rollup_upgrade.sh" diff --git a/l1-contracts/scripts/check_contract_sizes.sh b/l1-contracts/scripts/check_contract_sizes.sh new file mode 100755 index 000000000000..6486434d2c04 --- /dev/null +++ b/l1-contracts/scripts/check_contract_sizes.sh @@ -0,0 +1,82 @@ +#!/usr/bin/env bash +set -euo pipefail + +# Fail if any deployable contract exceeds the EIP-170 runtime bytecode limit. +# +# An oversized contract compiles fine and only breaks at deploy time, where foundry reports the +# anonymous CREATE index instead of the contract ("`Unknown11` is above the contract size limit +# (25097 > 24576)"), so the overage is close to undiagnosable. Checking sizes directly names the +# contract instead. +# +# Both deploy profiles are checked, because they produce different sizes: `production` remaps +# @aztec-blob-lib to the real BlobLib and is used for mainnet deploys, while the default profile +# remaps it to the mock and is what every other network and scripts/test_rollup_upgrade.sh deploy. + +cd "$(dirname "$0")/.." + +# EIP-170 runtime bytecode limit. +limit=24576 +# Report, without failing, contracts with less than this much room left. +warn_margin=1024 + +paths=(src) +# Present only after bootstrap's build_verifier; it is a deployed contract, so check it when it is. +[ -f generated/HonkVerifier.sol ] && paths+=(generated/HonkVerifier.sol) + +workdir=$(mktemp -d) +trap 'rm -rf "$workdir"' EXIT + +status=0 +for profile in default production; do + echo "=== Checking contract sizes ($profile profile) ===" + + sizes=$workdir/$profile.json + # Build into a dedicated out/cache so this never clobbers the artifacts shared with concurrently + # running forge test commands. forge's exit code is not usable here: it is non-zero when a + # contract is oversized but zero when compilation fails outright, so the report drives the + # verdict and an empty report means the build failed. + FOUNDRY_PROFILE=$profile forge build --sizes --json \ + -o "$workdir/out-$profile" --cache-path "$workdir/cache-$profile" \ + "${paths[@]}" > "$sizes" || true + + report=$(jq -r --argjson limit "$limit" --argjson warn "$warn_margin" ' + to_entries + | map(select(.value.runtime_size != null)) + | sort_by(-.value.runtime_size) + | if length == 0 then "NONE" + else + (.[0] | select($limit - .value.runtime_size >= $warn) + | "INFO largest contract: \(.key) at \(.value.runtime_size) bytes, \($limit - .value.runtime_size) below the \($limit) byte limit"), + (.[] | select(.value.runtime_size > $limit) + | "FAIL \(.key) is above the EIP-170 contract size limit (\(.value.runtime_size) > \($limit)), over by \(.value.runtime_size - $limit) bytes"), + (.[] | select(.value.runtime_size <= $limit and $limit - .value.runtime_size < $warn) + | "WARN \(.key) is close to the EIP-170 contract size limit: \(.value.runtime_size) bytes, only \($limit - .value.runtime_size) to spare") + end + ' "$sizes" 2>/dev/null) || report=NONE + + if [ "$report" = "NONE" ]; then + # `forge build --sizes --json` reports an empty object and still exits 0 when compilation + # fails, so rerun without --json to surface the compiler error. + echo "ERROR: forge build produced no contract sizes under the $profile profile. Rerunning to show why:" + FOUNDRY_PROFILE=$profile forge build \ + -o "$workdir/out-$profile" --cache-path "$workdir/cache-$profile" "${paths[@]}" + exit 1 + fi + + while IFS= read -r line; do + case "$line" in + "INFO "*) echo " ${line#INFO }" ;; + "WARN "*) echo " WARNING: ${line#WARN } ($profile profile)" ;; + "FAIL "*) echo " ERROR: ${line#FAIL } ($profile profile)"; status=1 ;; + esac + done <<< "$report" +done + +if [ "$status" -ne 0 ]; then + echo + echo "One or more contracts are above the EIP-170 runtime bytecode limit of $limit bytes and cannot be" + echo "deployed. Shrink them, or move logic into an external library." + exit 1 +fi + +echo "All contracts are within the EIP-170 runtime bytecode limit of $limit bytes." From cf0d363931171459bec90718699ce1d3104582ed Mon Sep 17 00:00:00 2001 From: Santiago Palladino Date: Wed, 9 Sep 2026 14:02:52 -0300 Subject: [PATCH 19/19] chore(l1): refresh gas reports, fix them under FORGE_GAS_REPORT `./bootstrap.sh gas_report` aborted before writing its output because three RollupTest tests failed only under `FORGE_GAS_REPORT=true`, so the tracked reports could not be regenerated. Forge runs every top level call in its own transaction while taking a gas report, and `vm.blobhashes` does not survive that isolation (foundry-rs/foundry#10074) - the isolated transaction reverts before reaching the callee. `RollupBase` already worked around this by clearing `checkBlob` instead; extract that into `setBlobHashesOrSkipCheck` and use it in `testRevertInvalidTimestamp` and `testRevertInvalidCoinbase`, which reverted at the wrong depth for `vm.expectRevert`. `testExtraBlobs` asserts on the blob hashes themselves, so it cannot run without them and is now skipped under a gas report, like the already excluded `testInvalidBlobHash` and `testInvalidBlobProof`. Its `checkBlob()` line therefore drops out of `gas_report.json`. Refreshed numbers: `propose` is unchanged (median 283,135, max 324,245; its old min of 0 was an artifact of the broken isolated calls), while `submitEpochRootProof` drops ~67k gas on both benchmark profiles (941,136 avg without validators, 1,521,554 with) after this branch's proof submission work, and its calldata grows 64 bytes for the new `provenCheckpointFees` argument. The owner-only setters pay for the move of the fee admin paths into `RewardExtLib`: `setProvingCostPerMana` 52,597 -> 55,843 and `updateManaTarget` 26,051 -> 29,233. Preheated rollup deployment size drops 43,814 -> 42,872. Co-Authored-By: Claude Opus 5 (1M context) --- l1-contracts/gas_benchmark.md | 16 +- l1-contracts/gas_benchmark_results.json | 24 +-- l1-contracts/gas_report.json | 213 ++++++++++++------------ l1-contracts/test/Rollup.t.sol | 6 +- l1-contracts/test/base/Base.sol | 27 +++ l1-contracts/test/base/RollupBase.sol | 10 +- 6 files changed, 154 insertions(+), 142 deletions(-) diff --git a/l1-contracts/gas_benchmark.md b/l1-contracts/gas_benchmark.md index 4313a89acaed..10a31c284b0e 100644 --- a/l1-contracts/gas_benchmark.md +++ b/l1-contracts/gas_benchmark.md @@ -12,13 +12,13 @@ ## No Validators -| Function | Avg Gas | Max Gas | Calldata Size | Calldata Gas | -|----------------------|-----------|-----------|---------------|--------------| -| propose | 198,220 | 224,403 | 996 | 15,936 | -| submitEpochRootProof | 1,007,926 | 1,046,916 | 14,148 | 226,368 | -| setupEpoch | 32,020 | 113,815 | - | - | +| Function | Avg Gas | Max Gas | Calldata Size | Calldata Gas | +|----------------------|---------|---------|---------------|--------------| +| propose | 198,220 | 224,403 | 996 | 15,936 | +| submitEpochRootProof | 941,136 | 981,877 | 14,212 | 227,392 | +| setupEpoch | 32,020 | 113,815 | - | - | -**Avg Gas Cost per Second**: 3,641.9 gas/second +**Avg Gas Cost per Second**: 3,583.9 gas/second *Epoch duration*: 0h 38m 24s ## Validators @@ -26,10 +26,10 @@ | Function | Avg Gas | Max Gas | Calldata Size | Calldata Gas | |----------------------|-----------|-----------|---------------|--------------| | propose | 326,630 | 354,402 | 4,516 | 72,256 | -| submitEpochRootProof | 1,588,977 | 1,687,377 | 16,644 | 266,304 | +| submitEpochRootProof | 1,521,554 | 1,621,733 | 16,708 | 267,328 | | aggregate3 | 375,623 | 388,983 | - | - | | setupEpoch | 46,482 | 547,648 | - | - | -**Avg Gas Cost per Second**: 5,936.0 gas/second +**Avg Gas Cost per Second**: 5,877.5 gas/second *Epoch duration*: 0h 38m 24s diff --git a/l1-contracts/gas_benchmark_results.json b/l1-contracts/gas_benchmark_results.json index de2e01a735ba..12df1ddd8f50 100644 --- a/l1-contracts/gas_benchmark_results.json +++ b/l1-contracts/gas_benchmark_results.json @@ -18,12 +18,12 @@ }, "submitEpochRootProof": { "calls": 4, - "min": 987727, - "mean": 1007926, - "median": 998531, - "max": 1046916, - "calldata_size": 14148, - "calldata_gas": 226368 + "min": 920354, + "mean": 941136, + "median": 931158, + "max": 981877, + "calldata_size": 14212, + "calldata_gas": 227392 } }, "validators": { @@ -45,12 +45,12 @@ }, "submitEpochRootProof": { "calls": 4, - "min": 1477673, - "mean": 1588977, - "median": 1595430, - "max": 1687377, - "calldata_size": 16644, - "calldata_gas": 266304 + "min": 1409659, + "mean": 1521554, + "median": 1527412, + "max": 1621733, + "calldata_size": 16708, + "calldata_gas": 267328 }, "aggregate3": { "calls": 55, diff --git a/l1-contracts/gas_report.json b/l1-contracts/gas_report.json index ad883eb1e8e3..0e2808d39c98 100644 --- a/l1-contracts/gas_report.json +++ b/l1-contracts/gas_report.json @@ -7,30 +7,30 @@ }, "functions": { "getBucket(uint256)": { - "calls": 4667, + "calls": 4677, "min": 7414, "mean": 7414, "median": 7414, "max": 7414 }, "getCurrentBucketSeq()": { - "calls": 4667, + "calls": 4677, "min": 408, "mean": 1407, "median": 408, "max": 2408 }, "getFeeAssetPortal()": { - "calls": 2586, + "calls": 2588, "min": 212, "mean": 212, "median": 212, "max": 212 }, "sendL2Message((bytes32,uint256),bytes32,bytes32)": { - "calls": 37328, + "calls": 37408, "min": 43269, - "mean": 46585, + "mean": 46584, "median": 43269, "max": 102022 } @@ -60,7 +60,7 @@ }, "functions": { "owner()": { - "calls": 5172, + "calls": 5176, "min": 397, "mean": 397, "median": 397, @@ -76,21 +76,21 @@ }, "functions": { "getCanonicalRollup()": { - "calls": 1720, + "calls": 1780, "min": 1073, "mean": 4073, "median": 4073, "max": 7073 }, "getRewardDistributor()": { - "calls": 2586, + "calls": 2588, "min": 420, "mean": 420, "median": 420, "max": 420 }, "owner()": { - "calls": 7758, + "calls": 7764, "min": 353, "mean": 353, "median": 353, @@ -106,7 +106,7 @@ }, "functions": { "availableTo(address)": { - "calls": 860, + "calls": 890, "min": 20573, "mean": 20573, "median": 20573, @@ -118,50 +118,43 @@ "contract": "test/RollupWithPreheating.sol:RollupWithPreheating", "deployment": { "gas": 0, - "size": 43814 + "size": 42872 }, "functions": { "archive()": { - "calls": 2333, + "calls": 2338, "min": 4641, "mean": 4641, "median": 4641, "max": 4641 }, - "checkBlob()": { - "calls": 1, - "min": 2465, - "mean": 2465, - "median": 2465, - "max": 2465 - }, "getCheckpoint(uint256)": { - "calls": 870, + "calls": 900, "min": 27185, "mean": 27185, "median": 27185, "max": 27185 }, "getCheckpointReward()": { - "calls": 2589, - "min": 1258, - "mean": 1263, - "median": 1258, - "max": 5758 + "calls": 2591, + "min": 1170, + "mean": 1175, + "median": 1170, + "max": 5670 }, "getCollectiveProverRewardsForEpoch(uint256)": { "calls": 3, - "min": 5926, - "mean": 5926, - "median": 5926, - "max": 5926 + "min": 5970, + "mean": 5970, + "median": 5970, + "max": 5970 }, "getCurrentEpoch()": { - "calls": 861, - "min": 893, - "mean": 893, - "median": 893, - "max": 893 + "calls": 891, + "min": 915, + "mean": 915, + "median": 915, + "max": 915 }, "getCurrentSlot()": { "calls": 100, @@ -178,11 +171,11 @@ "max": 2420 }, "getEpochProofPublicInputs(uint256,uint256,(bytes32,bytes32,bytes32,bytes32,bytes32,address),(bytes32,bytes32,bytes32,bytes32,bytes32,uint256,uint256,address,bytes32,(uint128,uint128),uint256,uint256)[],bytes)": { - "calls": 4, - "min": 18578, - "mean": 44270, - "median": 46301, - "max": 65899 + "calls": 5, + "min": 18669, + "mean": 49449, + "median": 64958, + "max": 71849 }, "getEthPerFeeAsset()": { "calls": 2, @@ -192,14 +185,14 @@ "max": 11021 }, "getFeeAssetPortal()": { - "calls": 4660, - "min": 857, - "mean": 857, - "median": 857, - "max": 857 + "calls": 4664, + "min": 879, + "mean": 879, + "median": 879, + "max": 879 }, "getInbox()": { - "calls": 9073, + "calls": 9090, "min": 856, "mean": 856, "median": 856, @@ -207,17 +200,17 @@ }, "getL1FeesAt(uint256)": { "calls": 2, - "min": 9020, - "mean": 9020, - "median": 9020, - "max": 9020 + "min": 9086, + "mean": 9086, + "median": 9086, + "max": 9086 }, "getManaMinFeeAt(uint256,bool)": { - "calls": 2336, - "min": 27463, - "mean": 29120, - "median": 27463, - "max": 32481 + "calls": 2341, + "min": 27308, + "mean": 28968, + "median": 27308, + "max": 32326 }, "getManaTarget()": { "calls": 1026, @@ -228,20 +221,20 @@ }, "getOutbox()": { "calls": 2, - "min": 834, - "mean": 834, - "median": 834, - "max": 834 + "min": 856, + "mean": 856, + "median": 856, + "max": 856 }, "getPendingCheckpointNumber()": { "calls": 1679, - "min": 2418, - "mean": 2418, - "median": 2418, - "max": 2418 + "min": 2440, + "mean": 2440, + "median": 2440, + "max": 2440 }, "getProvenCheckpointNumber()": { - "calls": 1684, + "calls": 1685, "min": 2585, "mean": 2585, "median": 2585, @@ -249,80 +242,80 @@ }, "getProvingCostPerManaInEth()": { "calls": 1, - "min": 5685, - "mean": 5685, - "median": 5685, - "max": 5685 + "min": 5729, + "mean": 5729, + "median": 5729, + "max": 5729 }, "getProvingCostPerManaInFeeAsset()": { "calls": 1, - "min": 14431, - "mean": 14431, - "median": 14431, - "max": 14431 + "min": 14479, + "mean": 14479, + "median": 14479, + "max": 14479 }, "getSequencerRewards(address)": { - "calls": 2, - "min": 6111, - "mean": 6111, - "median": 6111, - "max": 6111 + "calls": 3, + "min": 5981, + "mean": 5981, + "median": 5981, + "max": 5981 }, "getTimestampForSlot(uint256)": { - "calls": 2442, - "min": 2786, - "mean": 2786, - "median": 2786, - "max": 2786 + "calls": 2447, + "min": 2808, + "mean": 2808, + "median": 2808, + "max": 2808 }, "getVersion()": { - "calls": 4919, + "calls": 4926, "min": 852, "mean": 852, "median": 852, "max": 852 }, "owner()": { - "calls": 5173, - "min": 489, - "mean": 489, - "median": 489, - "max": 2489 + "calls": 5177, + "min": 511, + "mean": 511, + "median": 511, + "max": 2511 }, "propose((bytes32,(int256),(bytes32,bytes32,bytes32,bytes32,bytes32,uint256,uint256,address,bytes32,(uint128,uint128),uint256,uint256),uint256),(bytes,bytes),address[],(uint8,bytes32,bytes32),bytes)": { - "calls": 2339, - "min": 0, - "mean": 265620, + "calls": 2344, + "min": 55404, + "mean": 265738, "median": 283135, "max": 324245 }, "prune()": { "calls": 6, - "min": 26667, - "mean": 33225, - "median": 33660, - "max": 38252 + "min": 26689, + "mean": 33247, + "median": 33682, + "max": 38274 }, "setProvingCostPerMana(uint256)": { "calls": 1, - "min": 52597, - "mean": 52597, - "median": 52597, - "max": 52597 - }, - "submitEpochRootProof((uint256,uint256,(bytes32,bytes32,bytes32,bytes32,bytes32,address),(bytes32,bytes32,bytes32,bytes32,bytes32,uint256,uint256,address,bytes32,(uint128,uint128),uint256,uint256)[],(bytes,bytes),bytes,bytes))": { - "calls": 867, - "min": 60150, - "mean": 387517, - "median": 393184, - "max": 429854 + "min": 55843, + "mean": 55843, + "median": 55843, + "max": 55843 + }, + "submitEpochRootProof((uint256,uint256,(bytes32,bytes32,bytes32,bytes32,bytes32,address),(address,uint256)[],(bytes32,bytes32,bytes32,bytes32,bytes32,uint256,uint256,address,bytes32,(uint128,uint128),uint256,uint256)[],(bytes,bytes),bytes,bytes))": { + "calls": 898, + "min": 62703, + "mean": 391461, + "median": 396973, + "max": 431395 }, "updateManaTarget(uint256)": { "calls": 512, - "min": 26051, - "mean": 28724, - "median": 27365, - "max": 31444 + "min": 29233, + "mean": 31905, + "median": 30546, + "max": 34624 } } }, @@ -334,7 +327,7 @@ }, "functions": { "isAllBeneficiariesAllowed()": { - "calls": 2586, + "calls": 2588, "min": 404, "mean": 404, "median": 404, diff --git a/l1-contracts/test/Rollup.t.sol b/l1-contracts/test/Rollup.t.sol index 5d914dd4c5c0..bb4619c90c22 100644 --- a/l1-contracts/test/Rollup.t.sol +++ b/l1-contracts/test/Rollup.t.sol @@ -232,7 +232,7 @@ contract RollupTest is RollupBase { ); } - function testExtraBlobs() public setUpFor("mixed_checkpoint_1") { + function testExtraBlobs() public skipWhenGasReport setUpFor("mixed_checkpoint_1") { bytes32[] memory originalBlobHashes = this.getBlobHashes(load("mixed_checkpoint_1").checkpoint.blobCommitments); bytes32[] memory extraBlobHashes = new bytes32[](6); @@ -644,7 +644,7 @@ contract RollupTest is RollupBase { function testRevertInvalidTimestamp() public setUpFor("empty_checkpoint_1") { DecoderBase.Data memory data = load("empty_checkpoint_1").checkpoint; ProposedHeader memory header = data.header; - vm.blobhashes(this.getBlobHashes(data.blobCommitments)); + setBlobHashesOrSkipCheck(address(rollup), this.getBlobHashes(data.blobCommitments)); bytes32 archive = data.archive; Timestamp realTs = header.timestamp; @@ -681,7 +681,7 @@ contract RollupTest is RollupBase { header.coinbase = address(0); bytes32[] memory blobHashes = this.getBlobHashes(data.blobCommitments); - vm.blobhashes(blobHashes); + setBlobHashesOrSkipCheck(address(rollup), blobHashes); skipBlobCheck(address(rollup)); vm.expectRevert(abi.encodeWithSelector(Errors.Rollup__InvalidCoinbase.selector)); ProposeArgs memory args = diff --git a/l1-contracts/test/base/Base.sol b/l1-contracts/test/base/Base.sol index c6ac9a0f850d..441a53133c9c 100644 --- a/l1-contracts/test/base/Base.sol +++ b/l1-contracts/test/base/Base.sol @@ -25,6 +25,17 @@ contract TestBase is Test { return vm.envOr("FORGE_COVERAGE", false); } + modifier skipWhenGasReport() { + if (isGasReport()) { + vm.skip(true); + } + _; + } + + function isGasReport() internal view returns (bool) { + return vm.envOr("FORGE_GAS_REPORT", false); + } + function assertGt(Timestamp a, Timestamp b) internal { if (a <= b) { emit log("Error: a > b not satisfied [Timestamp]"); @@ -276,6 +287,22 @@ contract TestBase is Test { // Blobs + /** + * @notice Sets the blob hashes seen by the next call, or bypasses the rollup's blob check if it cannot. + * @dev Gas reports run every top level call in its own transaction, and `vm.blobhashes` does not survive + * that isolation (foundry-rs/foundry#10074): the isolated transaction reverts before it reaches the + * callee. Clearing `checkBlob` instead keeps such calls executable while a gas report is being taken. + * @param rollup The rollup whose blob check may be bypassed + * @param blobHashes The blob hashes to expose to the next call + */ + function setBlobHashesOrSkipCheck(address rollup, bytes32[] memory blobHashes) internal { + if (isGasReport()) { + skipBlobCheck(rollup); + } else { + vm.blobhashes(blobHashes); + } + } + function skipBlobCheck(address rollup) internal { // For not entirely clear reasons, the checked_write and find in stdStore breaks with // under/overflow errors if using them. But we can still use them to find the slot diff --git a/l1-contracts/test/base/RollupBase.sol b/l1-contracts/test/base/RollupBase.sol index 3482402ec517..13c1f6bbf76a 100644 --- a/l1-contracts/test/base/RollupBase.sol +++ b/l1-contracts/test/base/RollupBase.sol @@ -194,15 +194,7 @@ contract RollupBase is DecoderBase { } } - // https://github.com/foundry-rs/foundry/issues/10074 - // don't add blob hashes if forge gas report is true - if (!vm.envOr("FORGE_GAS_REPORT", false)) { - emit log("Setting blob hashes"); - vm.blobhashes(blobHashes); - } else { - // skip blob check if forge gas report is true - skipBlobCheck(address(rollup)); - } + setBlobHashesOrSkipCheck(address(rollup), blobHashes); } proposedHeaders[full.checkpoint.checkpointNumber] = full.checkpoint.header;