@@ -39,6 +39,17 @@ contract L1GasPriceOracle is OwnableBase, IL1GasPriceOracle {
3939 /// @dev Thrown when we enable Curie fork after Curie fork.
4040 error ErrAlreadyInCurieFork ();
4141
42+ /// @dev Thrown when the compression penalty threshold exceeds `MAX_PENALTY_THRESHOLD`,
43+ /// or is less than 1 * PRECISION.
44+ error ErrInvalidPenaltyThreshold ();
45+
46+ /// @dev Thrown when the compression penalty factor exceeds `MAX_PENALTY_FACTOR`,
47+ /// or is less than 1 * PRECISION.
48+ error ErrInvalidPenaltyFactor ();
49+
50+ /// @dev Thrown when we enable Feynman fork after Feynman fork.
51+ error ErrAlreadyInFeynmanFork ();
52+
4253 /*************
4354 * Constants *
4455 *************/
@@ -70,6 +81,14 @@ contract L1GasPriceOracle is OwnableBase, IL1GasPriceOracle {
7081 /// So, the value should not exceed 10^9 * 1e9 normally.
7182 uint256 private constant MAX_BLOB_SCALAR = 10 ** 9 * PRECISION;
7283
84+ /// @dev The maximum possible compression penalty threshold after Feynman.
85+ /// The value should not exceed 10^9 * 1e9 normally.
86+ uint256 private constant MAX_PENALTY_THRESHOLD = 10 ** 9 * PRECISION;
87+
88+ /// @dev The maximum possible compression penalty factor after Feynman.
89+ /// The value should not exceed 10^9 * 1e9 normally.
90+ uint256 private constant MAX_PENALTY_FACTOR = 10 ** 9 * PRECISION;
91+
7392 /*************
7493 * Variables *
7594 *************/
@@ -98,6 +117,15 @@ contract L1GasPriceOracle is OwnableBase, IL1GasPriceOracle {
98117 /// @notice Indicates whether the network has gone through the Curie upgrade.
99118 bool public isCurie;
100119
120+ /// @inheritdoc IL1GasPriceOracle
121+ uint256 public override penaltyThreshold;
122+
123+ /// @inheritdoc IL1GasPriceOracle
124+ uint256 public override penaltyFactor;
125+
126+ /// @notice Indicates whether the network has gone through the Feynman upgrade.
127+ bool public isFeynman;
128+
101129 /*************
102130 * Modifiers *
103131 *************/
@@ -121,7 +149,9 @@ contract L1GasPriceOracle is OwnableBase, IL1GasPriceOracle {
121149
122150 /// @inheritdoc IL1GasPriceOracle
123151 function getL1Fee (bytes memory _data ) external view override returns (uint256 ) {
124- if (isCurie) {
152+ if (isFeynman) {
153+ return _getL1FeeFeynman (_data);
154+ } else if (isCurie) {
125155 return _getL1FeeCurie (_data);
126156 } else {
127157 return _getL1FeeBeforeCurie (_data);
@@ -130,7 +160,7 @@ contract L1GasPriceOracle is OwnableBase, IL1GasPriceOracle {
130160
131161 /// @inheritdoc IL1GasPriceOracle
132162 function getL1GasUsed (bytes memory _data ) public view override returns (uint256 ) {
133- if (isCurie) {
163+ if (isFeynman || isCurie) {
134164 // It is near zero since we put all transactions to blob.
135165 return 0 ;
136166 } else {
@@ -202,6 +232,24 @@ contract L1GasPriceOracle is OwnableBase, IL1GasPriceOracle {
202232 emit BlobScalarUpdated (_scalar);
203233 }
204234
235+ /// Allows the owner to modify the penaltyThreshold.
236+ /// @param _threshold New threshold
237+ function setPenaltyThreshold (uint256 _threshold ) external onlyOwner {
238+ if (_threshold < PRECISION || _threshold > MAX_PENALTY_THRESHOLD) revert ErrInvalidPenaltyThreshold ();
239+
240+ penaltyThreshold = _threshold;
241+ emit PenaltyThresholdUpdated (_threshold);
242+ }
243+
244+ /// Allows the owner to modify the penaltyFactor.
245+ /// @param _factor New factor
246+ function setPenaltyFactor (uint256 _factor ) external onlyOwner {
247+ if (_factor < PRECISION || _factor > MAX_PENALTY_FACTOR) revert ErrInvalidPenaltyFactor ();
248+
249+ penaltyFactor = _factor;
250+ emit PenaltyFactorUpdated (_factor);
251+ }
252+
205253 /// @notice Update whitelist contract.
206254 /// @dev This function can only called by contract owner.
207255 /// @param _newWhitelist The address of new whitelist contract.
@@ -222,6 +270,16 @@ contract L1GasPriceOracle is OwnableBase, IL1GasPriceOracle {
222270 isCurie = true ;
223271 }
224272
273+ /// @notice Enable the Feynman fork (callable by contract owner).
274+ ///
275+ /// @dev Since this is a predeploy contract, we will directly set the slot while hard fork
276+ /// to avoid external owner operations.
277+ /// The reason that we keep this function is for easy unit testing.
278+ function enableFeynman () external onlyOwner {
279+ if (isFeynman) revert ErrAlreadyInFeynmanFork ();
280+ isFeynman = true ;
281+ }
282+
225283 /**********************
226284 * Internal Functions *
227285 **********************/
@@ -264,4 +322,16 @@ contract L1GasPriceOracle is OwnableBase, IL1GasPriceOracle {
264322 // We have bounded the value of `commitScalar` and `blobScalar`, the whole expression won't overflow.
265323 return (commitScalar * l1BaseFee + blobScalar * _data.length * l1BlobBaseFee) / PRECISION;
266324 }
325+
326+ /// @dev Internal function to compute the L1 portion of the fee based on the size of the rlp encoded input
327+ /// transaction, the current L1 base fee, and the various dynamic parameters, after the Feynman fork.
328+ /// @param _data Signed fully RLP-encoded transaction to get the L1 fee for.
329+ /// @return L1 fee that should be paid for the tx
330+ function _getL1FeeFeynman (bytes memory _data ) private view returns (uint256 ) {
331+ // We have bounded the value of `commitScalar`, `blobScalar`, and `penalty`, the whole expression won't overflow.
332+ return
333+ ((commitScalar * l1BaseFee + blobScalar * l1BlobBaseFee) * _data.length * penaltyFactor) /
334+ PRECISION /
335+ PRECISION;
336+ }
267337}
0 commit comments