Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
72 changes: 43 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,27 @@ 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.
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 +151,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 +164,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 +236,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 +274,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 +338,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