Skip to content
Closed
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
35 changes: 33 additions & 2 deletions op-bindings/bindings/l1block.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion op-bindings/bindings/l1block_deployed.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 5 additions & 4 deletions packages/contracts-bedrock/.gas-snapshot
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ DeployerWhitelist_Test:test_owner() (gas: 7647)
DeployerWhitelist_Test:test_storageSlots() (gas: 33483)
GasPriceOracle_Test:test_baseFee() (gas: 8395)
GasPriceOracle_Test:test_gasPrice() (gas: 8384)
GasPriceOracle_Test:test_l1BaseFee() (gas: 10626)
GasPriceOracle_Test:test_l1BaseFee() (gas: 11373)
GasPriceOracle_Test:test_onlyOwnerSetDecimals() (gas: 10575)
GasPriceOracle_Test:test_onlyOwnerSetOverhead() (gas: 10599)
GasPriceOracle_Test:test_onlyOwnerSetScalar() (gas: 10640)
Expand All @@ -14,12 +14,13 @@ GasPriceOracle_Test:test_setL1BaseFeeReverts() (gas: 11658)
GasPriceOracle_Test:test_setOverhead() (gas: 36767)
GasPriceOracle_Test:test_setScalar() (gas: 36840)
GasPriceOracle_Test:test_storageLayout() (gas: 86683)
L1BlockTest:test_basefee() (gas: 7575)
L1BlockTest:test_averageBasefee() (gas: 7946)
L1BlockTest:test_basefee() (gas: 7553)
L1BlockTest:test_hash() (gas: 7552)
L1BlockTest:test_number() (gas: 7651)
L1BlockTest:test_sequenceNumber() (gas: 7596)
L1BlockTest:test_sequenceNumber() (gas: 7661)
L1BlockTest:test_timestamp() (gas: 7683)
L1BlockTest:test_updateValues() (gas: 23144)
L1BlockTest:test_updateValues() (gas: 46016)
L1BlockNumberTest:test_fallback() (gas: 10755)
L1BlockNumberTest:test_getL1BlockNumber() (gas: 10589)
L1BlockNumberTest:test_receive() (gas: 17418)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ contract GasPriceOracle is Ownable {
}

function l1BaseFee() public view returns (uint256) {
return L1Block(Lib_PredeployAddresses.L1_BLOCK_ATTRIBUTES).basefee();
return L1Block(Lib_PredeployAddresses.L1_BLOCK_ATTRIBUTES).averageBasefee();
}

/**
Expand Down
17 changes: 17 additions & 0 deletions packages/contracts-bedrock/contracts/L2/L1Block.sol
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
//SPDX-License-Identifier: MIT
pragma solidity 0.8.10;

import { Lib_FeeSmoothing } from "../libraries/Lib_FeeSmoothing.sol";

/**
* @title L1Block
* @dev This is an L2 predeploy contract that holds values from the L1
Expand Down Expand Up @@ -40,6 +42,11 @@ contract L1Block {
*/
uint256 public basefee;

/**
* @notice The average L1 basefee
*/
uint256 public averageBasefee;

/**
* @notice The latest L1 blockhash
*/
Expand Down Expand Up @@ -75,5 +82,15 @@ contract L1Block {
sstore(basefee.slot, _basefee)
sstore(hash.slot, _hash)
}

averageBasefee = _nextAverageBasefee(_basefee);
}

/**
* @notice Compute the running average L1 basefee
*/

function _nextAverageBasefee(uint256 _basefee) internal returns (uint256) {
return Lib_FeeSmoothing.rollingAverage(averageBasefee, _basefee);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.9;

import { FixedPointMathLib } from "@rari-capital/solmate/src/utils/FixedPointMathLib.sol";

/**
* @title Lib_FeeSmoothing
*/
library Lib_FeeSmoothing {
/**
* @notice Weight applied to average
*/
uint256 constant internal prevWeight = 7e18;

/**
* @notice Weight applied to value being added to average
*/
uint256 constant internal nextWeight = 3e18;

/**
* @notice Computes a rolling average
*/
function rollingAverage(
uint256 prev,
uint256 next
) internal returns (uint256) {
uint256 a = saturatingMul(prev, FixedPointMathLib.divWadDown(prevWeight, 1e19));
uint256 b = saturatingMul(next, FixedPointMathLib.divWadDown(nextWeight, 1e19));
return saturatingAdd(a, b) / 1e18;
}

/**
* @notice Saturating multiplication
*/
function saturatingMul(uint256 a, uint256 b) internal returns (uint256) {
unchecked {
if (a == 0) {
return 0;
}
uint256 c = a * b;
if (c / a != b) {
return type(uint256).max;
}
return c;
}
}

/**
* @notice Saturating addition
*/
function saturatingAdd(uint256 a, uint256 b) internal returns (uint256) {
unchecked {
uint256 c = a + b;
if (c < a) {
return type(uint256).max;
}
return c;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { CommonTest } from "./CommonTest.t.sol";
import { GasPriceOracle } from "../L2/GasPriceOracle.sol";
import { L1Block } from "../L2/L1Block.sol";
import { Lib_PredeployAddresses } from "../libraries/Lib_PredeployAddresses.sol";
import { Lib_FeeSmoothing } from "../libraries/Lib_FeeSmoothing.sol";

contract GasPriceOracle_Test is CommonTest {

Expand Down Expand Up @@ -81,7 +82,8 @@ contract GasPriceOracle_Test is CommonTest {

function test_l1BaseFee() external {
uint256 l1BaseFee = gasOracle.l1BaseFee();
assertEq(l1BaseFee, 100);
uint256 expect = Lib_FeeSmoothing.rollingAverage(0, 100);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The value here is 30 which I believe is realistic if 70% weighted towards prev value and 30% weighted towards next value. We need unit tests for the rollingAverage function, not 100% sure of the best way to go about it

assertEq(l1BaseFee, expect);
}

function test_gasPrice() external {
Expand Down
11 changes: 11 additions & 0 deletions packages/contracts-bedrock/contracts/test/L1Block.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,15 @@ pragma solidity 0.8.10;

import { CommonTest } from "./CommonTest.t.sol";
import { L1Block } from "../L2/L1Block.sol";
import { Lib_FeeSmoothing } from "../libraries/Lib_FeeSmoothing.sol";

contract L1BlockTest is CommonTest {
L1Block lb;
address depositor;
bytes32 immutable NON_ZERO_HASH = keccak256(abi.encode(1));

uint256 averageBasefee;

function setUp() external {
lb = new L1Block();
depositor = lb.DEPOSITOR_ACCOUNT();
Expand All @@ -17,11 +20,14 @@ contract L1BlockTest is CommonTest {
}

function test_updatesValues(uint64 n, uint64 t, uint256 b, bytes32 h, uint64 s) external {
averageBasefee = Lib_FeeSmoothing.rollingAverage(averageBasefee, b);

vm.prank(depositor);
lb.setL1BlockValues(n, t, b, h, s);
assertEq(lb.number(), n);
assertEq(lb.timestamp(), t);
assertEq(lb.basefee(), b);
assertEq(lb.averageBasefee(), averageBasefee);
assertEq(lb.hash(), h);
assertEq(lb.sequenceNumber(), s);
}
Expand All @@ -38,6 +44,11 @@ contract L1BlockTest is CommonTest {
assertEq(lb.basefee(), 3);
}

function test_averageBasefee() external {
uint256 expect = Lib_FeeSmoothing.rollingAverage(0, 3);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not sufficient as a test, we need unit tests that are realistic

assertEq(lb.averageBasefee(), expect);
}

function test_hash() external {
assertEq(lb.hash(), NON_ZERO_HASH);
}
Expand Down
2 changes: 1 addition & 1 deletion packages/contracts-bedrock/contracts/test/Lib_RLP.t.sol
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: Unlicense
pragma solidity >=0.8.0;

import {Bytes32AddressLib} from "solmate/utils/Bytes32AddressLib.sol";
import {Bytes32AddressLib} from "@rari-capital/solmate/src/utils/Bytes32AddressLib.sol";

// prettier-ignore
library LibRLP {
Expand Down
3 changes: 1 addition & 2 deletions packages/contracts-bedrock/foundry.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,7 @@ optimizer_runs = 999999
remappings = [
'@openzeppelin/contracts-upgradeable/=node_modules/@openzeppelin/contracts-upgradeable/',
'@openzeppelin/contracts/=node_modules/@openzeppelin/contracts/',
'excessively-safe-call/=node_modules/excessively-safe-call/src/',
'solmate/=node_modules/@rari-capital/solmate/src',
'@rari-capital/solmate/=node_modules/@rari-capital/solmate',
'forge-std/=node_modules/forge-std/src',
'ds-test/=node_modules/ds-test/src'
]
Expand Down