Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 1 addition & 4 deletions src/L2/predeploys/IL1GasPriceOracle.sol
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,6 @@ interface IL1GasPriceOracle {
/// @param scalar The current blob fee scalar updated.
event BlobScalarUpdated(uint256 scalar);

/// @notice Emitted when current compression penalty threshold is updated.
/// @param threshold The new compression penalty threshold.
event PenaltyThresholdUpdated(uint256 threshold);

/// @notice Emitted when current compression penalty factor is updated.
/// @param factor The new compression penalty factor.
event PenaltyFactorUpdated(uint256 factor);
Expand Down Expand Up @@ -56,6 +52,7 @@ interface IL1GasPriceOracle {
function blobScalar() external view returns (uint256);

/// @notice Return the current compression penalty threshold.
/// @custom:deprecated The penalty threshold parameter is deprecated after the Galileo fork.
function penaltyThreshold() external view returns (uint256);

/// @notice Return the current compression penalty factor.
Expand Down
73 changes: 44 additions & 29 deletions src/L2/predeploys/L1GasPriceOracle.sol
Original file line number Diff line number Diff line change
Expand Up @@ -39,17 +39,15 @@ contract L1GasPriceOracle is OwnableBase, IL1GasPriceOracle {
/// @dev Thrown when we enable Curie fork after Curie fork.
error ErrAlreadyInCurieFork();

/// @dev Thrown when the compression penalty threshold exceeds `MAX_PENALTY_THRESHOLD`,
/// or is less than 1 * PRECISION.
error ErrInvalidPenaltyThreshold();

/// @dev Thrown when the compression penalty factor exceeds `MAX_PENALTY_FACTOR`,
/// or is less than 1 * PRECISION.
/// @dev Thrown when the penalty factor is zero.
error ErrInvalidPenaltyFactor();

/// @dev Thrown when we enable Feynman fork after Feynman fork.
error ErrAlreadyInFeynmanFork();

/// @dev Thrown when we enable Galileo fork after Galileo fork.
error ErrAlreadyInGalileoFork();

/*************
* Constants *
*************/
Expand Down Expand Up @@ -81,14 +79,6 @@ contract L1GasPriceOracle is OwnableBase, IL1GasPriceOracle {
/// So, the value should not exceed 10^9 * 1e9 normally.
uint256 private constant MAX_BLOB_SCALAR = 10**9 * PRECISION;

/// @dev The maximum possible compression penalty threshold after Feynman.
/// The value should not exceed 10^9 * 1e9 normally.
uint256 private constant MAX_PENALTY_THRESHOLD = 10**9 * PRECISION;

/// @dev The maximum possible compression penalty factor after Feynman.
/// The value should not exceed 10^9 * 1e9 normally.
uint256 private constant MAX_PENALTY_FACTOR = 10**9 * PRECISION;

/*************
* Variables *
*************/
Expand Down Expand Up @@ -117,15 +107,28 @@ contract L1GasPriceOracle is OwnableBase, IL1GasPriceOracle {
/// @notice Indicates whether the network has gone through the Curie upgrade.
bool public isCurie;

/// @inheritdoc IL1GasPriceOracle
uint256 public override penaltyThreshold;
/// @custom:deprecated The penalty threshold parameter is deprecated after the Galileo fork.
// slither-disable-next-line uninitialized-state
uint256 public __penaltyThreshold;

/// @inheritdoc IL1GasPriceOracle
uint256 public override penaltyFactor;

/// @notice Indicates whether the network has gone through the Feynman upgrade.
bool public isFeynman;

/// @notice Indicates whether the network has gone through the Galileo upgrade.
bool public isGalileo;

/******************
* View functions *
******************/

/// @inheritdoc IL1GasPriceOracle
function penaltyThreshold() external view override returns (uint256) {
return __penaltyThreshold;
}

/*************
* Modifiers *
*************/
Expand All @@ -149,7 +152,9 @@ contract L1GasPriceOracle is OwnableBase, IL1GasPriceOracle {

/// @inheritdoc IL1GasPriceOracle
function getL1Fee(bytes memory _data) external view override returns (uint256) {
if (isFeynman) {
if (isGalileo) {
return _getL1FeeGalileo(_data);
} else if (isFeynman) {
return _getL1FeeFeynman(_data);
} else if (isCurie) {
return _getL1FeeCurie(_data);
Expand All @@ -160,7 +165,7 @@ contract L1GasPriceOracle is OwnableBase, IL1GasPriceOracle {

/// @inheritdoc IL1GasPriceOracle
function getL1GasUsed(bytes memory _data) public view override returns (uint256) {
if (isFeynman || isCurie) {
if (isGalileo || isFeynman || isCurie) {
// It is near zero since we put all transactions to blob.
return 0;
} else {
Expand Down Expand Up @@ -232,20 +237,10 @@ contract L1GasPriceOracle is OwnableBase, IL1GasPriceOracle {
emit BlobScalarUpdated(_scalar);
}

/// Allows the owner to modify the penaltyThreshold.
/// @param _threshold New threshold
function setPenaltyThreshold(uint256 _threshold) external onlyOwner {
if (_threshold < PRECISION || _threshold > MAX_PENALTY_THRESHOLD) revert ErrInvalidPenaltyThreshold();

penaltyThreshold = _threshold;
emit PenaltyThresholdUpdated(_threshold);
}

/// Allows the owner to modify the penaltyFactor.
/// @param _factor New factor
function setPenaltyFactor(uint256 _factor) external onlyOwner {
if (_factor < PRECISION || _factor > MAX_PENALTY_FACTOR) revert ErrInvalidPenaltyFactor();

if (_factor == 0) revert ErrInvalidPenaltyFactor();
penaltyFactor = _factor;
emit PenaltyFactorUpdated(_factor);
}
Expand Down Expand Up @@ -280,6 +275,16 @@ contract L1GasPriceOracle is OwnableBase, IL1GasPriceOracle {
isFeynman = true;
}

/// @notice Enable the Galileo fork (callable by contract owner).
///
/// @dev Since this is a predeploy contract, we will directly set the slot while hard fork
/// to avoid external owner operations.
/// The reason that we keep this function is for easy unit testing.
function enableGalileo() external onlyOwner {
if (isGalileo) revert ErrAlreadyInGalileoFork();
isGalileo = true;
}

/**********************
* Internal Functions *
**********************/
Expand Down Expand Up @@ -334,4 +339,14 @@ contract L1GasPriceOracle is OwnableBase, IL1GasPriceOracle {
PRECISION /
PRECISION;
}

/// @dev Internal function to compute the L1 portion of the fee based on the size of the compressed rlp-
/// encoded input transaction, the current L1 base fee, and the various dynamic parameters, after the Galileo fork.
/// @param _data Signed fully RLP-encoded transaction to get the L1 fee for, compressed using zstd.
/// @return L1 fee that should be paid for the tx
function _getL1FeeGalileo(bytes memory _data) private view returns (uint256) {
uint256 baseTerm = (commitScalar * l1BaseFee + blobScalar * l1BlobBaseFee) * _data.length;
uint256 penaltyTerm = (baseTerm * _data.length) / penaltyFactor;
return (baseTerm + penaltyTerm) / PRECISION;
}
}
33 changes: 30 additions & 3 deletions src/test/L1GasPriceOracle.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -260,22 +260,23 @@ contract L1GasPriceOracleTest is DSTestPlus {
uint256 _blobBaseFee,
uint256 _commitScalar,
uint256 _blobScalar,
uint256 _penaltyThreshold,
uint256 _penaltyFactor,
bytes memory _data
) external {
_baseFee = bound(_baseFee, 0, 1e9 * 20000); // max 20k gwei
_blobBaseFee = bound(_blobBaseFee, 0, 1e9 * 20000); // max 20k gwei
_commitScalar = bound(_commitScalar, 0, MAX_COMMIT_SCALAR);
_blobScalar = bound(_blobScalar, 0, MAX_BLOB_SCALAR);
_penaltyThreshold = bound(_penaltyThreshold, 1e9, 1e9 * 5);
// Note: setPenaltyThreshold is deprecated
// _penaltyThreshold = bound(_penaltyThreshold, 1e9, 1e9 * 5);
_penaltyFactor = bound(_penaltyFactor, 1e9, 1e9 * 10); // min 1x, max 10x penalty

oracle.enableFeynman();
oracle.setCommitScalar(_commitScalar);
oracle.setBlobScalar(_blobScalar);
oracle.setL1BaseFeeAndBlobBaseFee(_baseFee, _blobBaseFee);
oracle.setPenaltyThreshold(_penaltyThreshold);
// Note: setPenaltyThreshold is deprecated
// oracle.setPenaltyThreshold(_penaltyThreshold);
oracle.setPenaltyFactor(_penaltyFactor);

assertEq(
Expand All @@ -285,4 +286,30 @@ contract L1GasPriceOracleTest is DSTestPlus {
PRECISION
);
}

function testGetL1FeeGalileo(
uint256 _baseFee,
uint256 _blobBaseFee,
uint256 _commitScalar,
uint256 _blobScalar,
uint256 _penaltyFactor,
bytes memory _data
) external {
_baseFee = bound(_baseFee, 0, 1e9 * 20000); // max 20k gwei
_blobBaseFee = bound(_blobBaseFee, 0, 1e9 * 20000); // max 20k gwei
_commitScalar = bound(_commitScalar, 0, MAX_COMMIT_SCALAR);
_blobScalar = bound(_blobScalar, 0, MAX_BLOB_SCALAR);
_penaltyFactor = bound(_penaltyFactor, 1, 1e9 * 100);

oracle.enableGalileo();
oracle.setCommitScalar(_commitScalar);
oracle.setBlobScalar(_blobScalar);
oracle.setL1BaseFeeAndBlobBaseFee(_baseFee, _blobBaseFee);
oracle.setPenaltyFactor(_penaltyFactor);

uint256 _baseTerm = (_commitScalar * _baseFee + _blobScalar * _blobBaseFee) * _data.length;
uint256 _penaltyTerm = (_baseTerm * _data.length) / _penaltyFactor;

assertEq(oracle.getL1Fee(_data), (_baseTerm + _penaltyTerm) / PRECISION);
}
}
Loading