Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(protocol): refine EIP-1559 basefee calculation and gas excess adjustment in TaikoL2 #17871

Merged
merged 17 commits into from
Aug 6, 2024
Prev Previous commit
improve
  • Loading branch information
dantaik committed Aug 5, 2024
commit 585e5fee9b83ed64039783dbca0e8453ea807996
35 changes: 13 additions & 22 deletions packages/protocol/contracts/L2/Lib1559Math.sol
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,7 @@ library Lib1559Math {
error EIP1559_INVALID_PARAMS();

function calc1559BaseFee(
uint32 _gasTarget,
uint8 _adjustmentQuotient,
uint256 _gasTarget,
uint64 _gasExcess,
uint64 _gasIssuance,
uint32 _parentGasUsed
Expand All @@ -35,7 +34,7 @@ library Lib1559Math {
// bonding curve, regardless the actual amount of gas used by this
// block, however, this block's gas used will affect the next
// block's base fee.
basefee_ = basefee(gasExcess_, uint256(_adjustmentQuotient) * _gasTarget);
basefee_ = basefee(gasExcess_, _gasTarget);
}

/// @dev Returns the new gas excess that will keep the basefee the same.
Expand All @@ -52,38 +51,30 @@ library Lib1559Math {
if (_gasTarget == 0) revert EIP1559_INVALID_PARAMS();

uint256 f = LibFixedPointMath.SCALING_FACTOR;
uint256 ratio;
unchecked {
ratio = f * _newGasTarget / _gasTarget;
}

uint256 ratio = f * _newGasTarget / _gasTarget;
if (ratio > uint256(type(int256).max)) revert EIP1559_INVALID_PARAMS();

int256 lnRatio = LibFixedPointMath.ln(int256(ratio));
int256 lnRatio = LibFixedPointMath.ln(int256(ratio)); // may be negative

uint256 newGasExcess;
assembly {
newGasExcess := sdiv(add(mul(lnRatio, _newGasTarget), mul(ratio, _gasExcess)), f)
switch gt(newGasExcess, 0)
case 1 { newGasExcess := shr(192, shl(192, newGasExcess)) }
default { newGasExcess := 0 }
}

return uint64(newGasExcess);
return uint64(newGasExcess.min(type(uint64).max));
}

/// @dev eth_qty(excess_gas_issued) / (TARGET * ADJUSTMENT_QUOTIENT)
/// @param _gasExcess The gas excess value
/// @param _target The product of gasTarget and adjustmentQuotient
function basefee(uint256 _gasExcess, uint256 _target) internal pure returns (uint256) {
if (_target == 0) revert EIP1559_INVALID_PARAMS();
uint256 fee = ethQty(_gasExcess, _target) / _target;
/// @dev exp(_gasExcess / _gasTarget) / _gasTarget
function basefee(uint256 _gasExcess, uint256 _gasTarget) internal pure returns (uint256) {
uint256 fee = ethQty(_gasExcess, _gasTarget) / _gasTarget;
return fee == 0 ? 1 : fee;
}

/// @dev exp(_gasExcess / _target)
function ethQty(uint256 _gasExcess, uint256 _target) internal pure returns (uint256) {
uint256 input = LibFixedPointMath.SCALING_FACTOR * _gasExcess / _target;
/// @dev exp(_gasExcess / _gasTarget)
function ethQty(uint256 _gasExcess, uint256 _gasTarget) internal pure returns (uint256) {
if (_gasTarget == 0) revert EIP1559_INVALID_PARAMS();

uint256 input = LibFixedPointMath.SCALING_FACTOR * _gasExcess / _gasTarget;
if (input > LibFixedPointMath.MAX_EXP_INPUT) {
input = LibFixedPointMath.MAX_EXP_INPUT;
}
Expand Down
6 changes: 2 additions & 4 deletions packages/protocol/contracts/L2/TaikoL2.sol
Original file line number Diff line number Diff line change
Expand Up @@ -199,8 +199,7 @@ contract TaikoL2 is EssentialContract {
LibL2Config.Config memory config = getConfig();

(basefee_, parentGasExcess_) = Lib1559Math.calc1559BaseFee(
config.gasTargetPerL1Block,
config.basefeeAdjustmentQuotient,
uint256(config.gasTargetPerL1Block) * config.basefeeAdjustmentQuotient,
parentGasExcess,
uint64(_anchorBlockId - lastSyncedBlock) * config.gasTargetPerL1Block,
_parentGasUsed
Expand Down Expand Up @@ -254,8 +253,7 @@ contract TaikoL2 is EssentialContract {
returns (uint256 basefee_, uint64 parentGasExcess_)
{
return Lib1559Math.calc1559BaseFee(
_gasIssuancePerSecond,
_adjustmentQuotient,
uint256(_gasIssuancePerSecond) * _adjustmentQuotient,
_parentGasExcess,
_blocktime * _gasIssuancePerSecond,
_parentGasUsed
Expand Down
2 changes: 2 additions & 0 deletions packages/protocol/test/L2/Lib1559Math.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ contract TestLib1559Math is TaikoTest {
uint64 newTarget = 5 * 2_000_000;
uint64 newExcess = Lib1559Math.adjustExcess(excess, target, newTarget);
basefee = Lib1559Math.basefee(newExcess, newTarget) / unit;
console2.log("old gas excess: ", excess);
console2.log("new gas excess: ", newExcess);
console2.log("basefee: ", basefee);
assertEq(baselineBasefee, basefee);
Expand All @@ -55,6 +56,7 @@ contract TestLib1559Math is TaikoTest {
uint64 newTarget = 3 * 2_000_000;
uint64 newExcess = Lib1559Math.adjustExcess(excess, target, newTarget);
basefee = Lib1559Math.basefee(newExcess, newTarget) / unit;
console2.log("old gas excess: ", excess);
console2.log("new gas excess: ", newExcess);
console2.log("basefee: ", basefee);
assertEq(baselineBasefee, basefee);
Expand Down