mirror of
https://github.com/scroll-tech/scroll.git
synced 2026-04-23 03:00:50 -04:00
add L2GasPriceOracle and Version
This commit is contained in:
@@ -366,6 +366,23 @@ Update layer 2 to layer 2 token mapping.
|
||||
| _l1Token | address | The address of corresponding ERC1155 token in layer 2. |
|
||||
| _l2Token | address | undefined |
|
||||
|
||||
### version
|
||||
|
||||
```solidity
|
||||
function version() external view returns (string)
|
||||
```
|
||||
|
||||
the current contract version.
|
||||
|
||||
|
||||
|
||||
|
||||
#### Returns
|
||||
|
||||
| Name | Type | Description |
|
||||
|---|---|---|
|
||||
| _0 | string | undefined |
|
||||
|
||||
|
||||
|
||||
## Events
|
||||
|
||||
@@ -311,6 +311,23 @@ Update layer 2 to layer 2 token mapping.
|
||||
| _l1Token | address | The address of corresponding ERC721 token in layer 2. |
|
||||
| _l2Token | address | undefined |
|
||||
|
||||
### version
|
||||
|
||||
```solidity
|
||||
function version() external view returns (string)
|
||||
```
|
||||
|
||||
the current contract version.
|
||||
|
||||
|
||||
|
||||
|
||||
#### Returns
|
||||
|
||||
| Name | Type | Description |
|
||||
|---|---|---|
|
||||
| _0 | string | undefined |
|
||||
|
||||
|
||||
|
||||
## Events
|
||||
|
||||
@@ -380,6 +380,23 @@ function transferOwnership(address newOwner) external nonpayable
|
||||
|---|---|---|
|
||||
| newOwner | address | undefined |
|
||||
|
||||
### version
|
||||
|
||||
```solidity
|
||||
function version() external view returns (string)
|
||||
```
|
||||
|
||||
the current contract version.
|
||||
|
||||
|
||||
|
||||
|
||||
#### Returns
|
||||
|
||||
| Name | Type | Description |
|
||||
|---|---|---|
|
||||
| _0 | string | undefined |
|
||||
|
||||
|
||||
|
||||
## Events
|
||||
|
||||
@@ -369,6 +369,23 @@ Update whitelist contract.
|
||||
|---|---|---|
|
||||
| _newWhitelist | address | The address of new whitelist contract. |
|
||||
|
||||
### version
|
||||
|
||||
```solidity
|
||||
function version() external view returns (string)
|
||||
```
|
||||
|
||||
the current contract version.
|
||||
|
||||
|
||||
|
||||
|
||||
#### Returns
|
||||
|
||||
| Name | Type | Description |
|
||||
|---|---|---|
|
||||
| _0 | string | undefined |
|
||||
|
||||
### whitelist
|
||||
|
||||
```solidity
|
||||
|
||||
@@ -226,6 +226,23 @@ The address of L1GatewayRouter/L2GatewayRouter contract.
|
||||
|---|---|---|
|
||||
| _0 | address | undefined |
|
||||
|
||||
### version
|
||||
|
||||
```solidity
|
||||
function version() external view returns (string)
|
||||
```
|
||||
|
||||
the current contract version.
|
||||
|
||||
|
||||
|
||||
|
||||
#### Returns
|
||||
|
||||
| Name | Type | Description |
|
||||
|---|---|---|
|
||||
| _0 | string | undefined |
|
||||
|
||||
|
||||
|
||||
## Events
|
||||
|
||||
@@ -226,6 +226,23 @@ The address of L1GatewayRouter/L2GatewayRouter contract.
|
||||
|---|---|---|
|
||||
| _0 | address | undefined |
|
||||
|
||||
### version
|
||||
|
||||
```solidity
|
||||
function version() external view returns (string)
|
||||
```
|
||||
|
||||
the current contract version.
|
||||
|
||||
|
||||
|
||||
|
||||
#### Returns
|
||||
|
||||
| Name | Type | Description |
|
||||
|---|---|---|
|
||||
| _0 | string | undefined |
|
||||
|
||||
|
||||
|
||||
## Events
|
||||
|
||||
@@ -327,6 +327,23 @@ Update layer 2 to layer 1 token mapping.
|
||||
| _l2Token | address | undefined |
|
||||
| _l1Token | address | The address of ERC1155 token in layer 1. |
|
||||
|
||||
### version
|
||||
|
||||
```solidity
|
||||
function version() external view returns (string)
|
||||
```
|
||||
|
||||
the current contract version.
|
||||
|
||||
|
||||
|
||||
|
||||
#### Returns
|
||||
|
||||
| Name | Type | Description |
|
||||
|---|---|---|
|
||||
| _0 | string | undefined |
|
||||
|
||||
### withdrawERC1155
|
||||
|
||||
```solidity
|
||||
|
||||
@@ -274,6 +274,23 @@ Update layer 2 to layer 1 token mapping.
|
||||
| _l2Token | address | undefined |
|
||||
| _l1Token | address | The address of ERC721 token in layer 1. |
|
||||
|
||||
### version
|
||||
|
||||
```solidity
|
||||
function version() external view returns (string)
|
||||
```
|
||||
|
||||
the current contract version.
|
||||
|
||||
|
||||
|
||||
|
||||
#### Returns
|
||||
|
||||
| Name | Type | Description |
|
||||
|---|---|---|
|
||||
| _0 | string | undefined |
|
||||
|
||||
### withdrawERC721
|
||||
|
||||
```solidity
|
||||
|
||||
@@ -312,6 +312,23 @@ function transferOwnership(address newOwner) external nonpayable
|
||||
|---|---|---|
|
||||
| newOwner | address | undefined |
|
||||
|
||||
### version
|
||||
|
||||
```solidity
|
||||
function version() external view returns (string)
|
||||
```
|
||||
|
||||
the current contract version.
|
||||
|
||||
|
||||
|
||||
|
||||
#### Returns
|
||||
|
||||
| Name | Type | Description |
|
||||
|---|---|---|
|
||||
| _0 | string | undefined |
|
||||
|
||||
### withdrawERC20
|
||||
|
||||
```solidity
|
||||
|
||||
@@ -295,6 +295,23 @@ Update whitelist contract.
|
||||
|---|---|---|
|
||||
| _newWhitelist | address | The address of new whitelist contract. |
|
||||
|
||||
### version
|
||||
|
||||
```solidity
|
||||
function version() external view returns (string)
|
||||
```
|
||||
|
||||
the current contract version.
|
||||
|
||||
|
||||
|
||||
|
||||
#### Returns
|
||||
|
||||
| Name | Type | Description |
|
||||
|---|---|---|
|
||||
| _0 | string | undefined |
|
||||
|
||||
### whitelist
|
||||
|
||||
```solidity
|
||||
|
||||
@@ -173,6 +173,23 @@ The address of ScrollStandardERC20Factory.
|
||||
|---|---|---|
|
||||
| _0 | address | undefined |
|
||||
|
||||
### version
|
||||
|
||||
```solidity
|
||||
function version() external view returns (string)
|
||||
```
|
||||
|
||||
the current contract version.
|
||||
|
||||
|
||||
|
||||
|
||||
#### Returns
|
||||
|
||||
| Name | Type | Description |
|
||||
|---|---|---|
|
||||
| _0 | string | undefined |
|
||||
|
||||
### withdrawERC20
|
||||
|
||||
```solidity
|
||||
|
||||
@@ -191,6 +191,23 @@ The address of L1GatewayRouter/L2GatewayRouter contract.
|
||||
|---|---|---|
|
||||
| _0 | address | undefined |
|
||||
|
||||
### version
|
||||
|
||||
```solidity
|
||||
function version() external view returns (string)
|
||||
```
|
||||
|
||||
the current contract version.
|
||||
|
||||
|
||||
|
||||
|
||||
#### Returns
|
||||
|
||||
| Name | Type | Description |
|
||||
|---|---|---|
|
||||
| _0 | string | undefined |
|
||||
|
||||
### withdrawERC20
|
||||
|
||||
```solidity
|
||||
|
||||
@@ -364,6 +364,23 @@ Update the address of operator.
|
||||
|---|---|---|
|
||||
| _newOperator | address | The new operator address to update. |
|
||||
|
||||
### version
|
||||
|
||||
```solidity
|
||||
function version() external view returns (string)
|
||||
```
|
||||
|
||||
the current contract version.
|
||||
|
||||
|
||||
|
||||
|
||||
#### Returns
|
||||
|
||||
| Name | Type | Description |
|
||||
|---|---|---|
|
||||
| _0 | string | undefined |
|
||||
|
||||
|
||||
|
||||
## Events
|
||||
|
||||
@@ -129,6 +129,7 @@ describe("L1BlockContainer", async () => {
|
||||
test.parentHash,
|
||||
test.blockHeight - 1,
|
||||
test.blockTimestamp - 1,
|
||||
test.baseFee,
|
||||
test.stateRoot
|
||||
);
|
||||
const Whitelist = await ethers.getContractFactory("Whitelist", deployer);
|
||||
@@ -144,6 +145,7 @@ describe("L1BlockContainer", async () => {
|
||||
test.parentHash,
|
||||
test.blockHeight - 1,
|
||||
test.blockTimestamp - 1,
|
||||
test.baseFee,
|
||||
test.stateRoot
|
||||
);
|
||||
const headerRLP = encodeHeader(test);
|
||||
@@ -158,6 +160,7 @@ describe("L1BlockContainer", async () => {
|
||||
test.parentHash,
|
||||
test.blockHeight - 1,
|
||||
test.blockTimestamp - 1,
|
||||
test.baseFee,
|
||||
test.stateRoot
|
||||
);
|
||||
const headerRLP = encodeHeader(test);
|
||||
@@ -172,6 +175,7 @@ describe("L1BlockContainer", async () => {
|
||||
constants.HashZero,
|
||||
test.blockHeight - 1,
|
||||
test.blockTimestamp - 1,
|
||||
test.baseFee,
|
||||
test.stateRoot
|
||||
);
|
||||
const headerRLP = encodeHeader(test);
|
||||
@@ -184,6 +188,7 @@ describe("L1BlockContainer", async () => {
|
||||
test.parentHash,
|
||||
test.blockHeight,
|
||||
test.blockTimestamp - 1,
|
||||
test.baseFee,
|
||||
test.stateRoot
|
||||
);
|
||||
const headerRLP = encodeHeader(test);
|
||||
@@ -196,6 +201,7 @@ describe("L1BlockContainer", async () => {
|
||||
test.parentHash,
|
||||
test.blockHeight - 1,
|
||||
test.blockTimestamp + 1,
|
||||
test.baseFee,
|
||||
test.stateRoot
|
||||
);
|
||||
const headerRLP = encodeHeader(test);
|
||||
@@ -210,16 +216,20 @@ describe("L1BlockContainer", async () => {
|
||||
test.parentHash,
|
||||
test.blockHeight - 1,
|
||||
test.blockTimestamp - 1,
|
||||
test.baseFee,
|
||||
test.stateRoot
|
||||
);
|
||||
expect(await container.latestBlockHash()).to.eq(test.parentHash);
|
||||
const headerRLP = encodeHeader(test);
|
||||
await expect(container.importBlockHeader(test.hash, headerRLP, "0x"))
|
||||
.to.emit(container, "ImportBlock")
|
||||
.withArgs(test.hash, test.blockHeight, test.blockTimestamp, test.stateRoot);
|
||||
.withArgs(test.hash, test.blockHeight, test.blockTimestamp, test.baseFee, test.stateRoot);
|
||||
expect(await container.getStateRoot(test.hash)).to.eq(test.stateRoot);
|
||||
expect(await container.getBlockTimestamp(test.hash)).to.eq(test.blockTimestamp);
|
||||
expect(await container.latestBlockHash()).to.eq(test.hash);
|
||||
expect(await container.latestBaseFee()).to.eq(test.baseFee);
|
||||
expect(await container.latestBlockNumber()).to.eq(test.blockHeight);
|
||||
expect(await container.latestBlockTimestamp()).to.eq(test.blockTimestamp);
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -238,7 +248,14 @@ describe("L1BlockContainer", async () => {
|
||||
await container.deployed();
|
||||
|
||||
const block = await ethers.provider.getBlock("latest");
|
||||
await container.initialize(deployer.address, block.hash, block.number, block.timestamp, block.hash);
|
||||
await container.initialize(
|
||||
deployer.address,
|
||||
block.hash,
|
||||
block.number,
|
||||
block.timestamp,
|
||||
block.baseFeePerGas!,
|
||||
block.hash
|
||||
);
|
||||
});
|
||||
|
||||
it("should revert, when block not imported", async () => {
|
||||
|
||||
@@ -8,6 +8,7 @@ import { PausableUpgradeable } from "@openzeppelin/contracts-upgradeable/securit
|
||||
import { IZKRollup } from "./rollup/IZKRollup.sol";
|
||||
import { L1MessageQueue } from "./rollup/L1MessageQueue.sol";
|
||||
import { IL1ScrollMessenger, IScrollMessenger } from "./IL1ScrollMessenger.sol";
|
||||
import { Version } from "../libraries/common/Version.sol";
|
||||
import { IGasOracle } from "../libraries/oracle/IGasOracle.sol";
|
||||
import { ScrollConstants } from "../libraries/ScrollConstants.sol";
|
||||
import { ScrollMessengerBase } from "../libraries/ScrollMessengerBase.sol";
|
||||
@@ -23,7 +24,7 @@ import { ZkTrieVerifier } from "../libraries/verifier/ZkTrieVerifier.sol";
|
||||
///
|
||||
/// @dev All deposited Ether (including `WETH` deposited throng `L1WETHGateway`) will locked in
|
||||
/// this contract.
|
||||
contract L1ScrollMessenger is OwnableUpgradeable, PausableUpgradeable, ScrollMessengerBase, IL1ScrollMessenger {
|
||||
contract L1ScrollMessenger is Version, OwnableUpgradeable, PausableUpgradeable, ScrollMessengerBase, IL1ScrollMessenger {
|
||||
/*************
|
||||
* Variables *
|
||||
*************/
|
||||
|
||||
@@ -9,6 +9,7 @@ import { SafeERC20Upgradeable } from "@openzeppelin/contracts-upgradeable/token/
|
||||
import { IL1ERC20Gateway, L1ERC20Gateway } from "./L1ERC20Gateway.sol";
|
||||
import { IL1ScrollMessenger } from "../IL1ScrollMessenger.sol";
|
||||
import { IL2ERC20Gateway } from "../../L2/gateways/IL2ERC20Gateway.sol";
|
||||
import { Version } from "../../libraries/common/Version.sol";
|
||||
import { ScrollGatewayBase, IScrollGateway } from "../../libraries/gateway/ScrollGatewayBase.sol";
|
||||
|
||||
/// @title L1CustomERC20Gateway
|
||||
@@ -16,7 +17,7 @@ import { ScrollGatewayBase, IScrollGateway } from "../../libraries/gateway/Scrol
|
||||
/// finalize withdraw the tokens from layer 2.
|
||||
/// @dev The deposited tokens are held in this gateway. On finalizing withdraw, the corresponding
|
||||
/// tokens will be transfer to the recipient directly.
|
||||
contract L1CustomERC20Gateway is OwnableUpgradeable, ScrollGatewayBase, L1ERC20Gateway {
|
||||
contract L1CustomERC20Gateway is Version, OwnableUpgradeable, ScrollGatewayBase, L1ERC20Gateway {
|
||||
using SafeERC20Upgradeable for IERC20Upgradeable;
|
||||
|
||||
/**************************************** Events ****************************************/
|
||||
|
||||
@@ -9,6 +9,7 @@ import { ERC1155HolderUpgradeable } from "@openzeppelin/contracts-upgradeable/to
|
||||
import { IL1ERC1155Gateway } from "./IL1ERC1155Gateway.sol";
|
||||
import { IL1ScrollMessenger } from "../IL1ScrollMessenger.sol";
|
||||
import { IL2ERC1155Gateway } from "../../L2/gateways/IL2ERC1155Gateway.sol";
|
||||
import { Version } from "../../libraries/common/Version.sol";
|
||||
import { ScrollGatewayBase, IScrollGateway } from "../../libraries/gateway/ScrollGatewayBase.sol";
|
||||
|
||||
/// @title L1ERC1155Gateway
|
||||
@@ -19,7 +20,7 @@ import { ScrollGatewayBase, IScrollGateway } from "../../libraries/gateway/Scrol
|
||||
///
|
||||
/// This will be changed if we have more specific scenarios.
|
||||
// @todo Current implementation doesn't support calling from `L1GatewayRouter`.
|
||||
contract L1ERC1155Gateway is OwnableUpgradeable, ERC1155HolderUpgradeable, ScrollGatewayBase, IL1ERC1155Gateway {
|
||||
contract L1ERC1155Gateway is Version, OwnableUpgradeable, ERC1155HolderUpgradeable, ScrollGatewayBase, IL1ERC1155Gateway {
|
||||
/**************************************** Events ****************************************/
|
||||
|
||||
/// @notice Emitted when token mapping for ERC1155 token is updated.
|
||||
|
||||
@@ -2,11 +2,13 @@
|
||||
|
||||
pragma solidity ^0.8.0;
|
||||
|
||||
import { Version } from "../../libraries/common/Version.sol";
|
||||
|
||||
import { IL1ERC20Gateway } from "./IL1ERC20Gateway.sol";
|
||||
|
||||
// solhint-disable no-empty-blocks
|
||||
|
||||
abstract contract L1ERC20Gateway is IL1ERC20Gateway {
|
||||
abstract contract L1ERC20Gateway is Version, IL1ERC20Gateway {
|
||||
/// @inheritdoc IL1ERC20Gateway
|
||||
function depositERC20(
|
||||
address _token,
|
||||
|
||||
@@ -9,6 +9,7 @@ import { ERC721HolderUpgradeable } from "@openzeppelin/contracts-upgradeable/tok
|
||||
import { IL1ERC721Gateway } from "./IL1ERC721Gateway.sol";
|
||||
import { IL1ScrollMessenger } from "../IL1ScrollMessenger.sol";
|
||||
import { IL2ERC721Gateway } from "../../L2/gateways/IL2ERC721Gateway.sol";
|
||||
import { Version } from "../../libraries/common/Version.sol";
|
||||
import { ScrollGatewayBase, IScrollGateway } from "../../libraries/gateway/ScrollGatewayBase.sol";
|
||||
|
||||
/// @title L1ERC721Gateway
|
||||
@@ -19,7 +20,7 @@ import { ScrollGatewayBase, IScrollGateway } from "../../libraries/gateway/Scrol
|
||||
///
|
||||
/// This will be changed if we have more specific scenarios.
|
||||
// @todo Current implementation doesn't support calling from `L1GatewayRouter`.
|
||||
contract L1ERC721Gateway is OwnableUpgradeable, ERC721HolderUpgradeable, ScrollGatewayBase, IL1ERC721Gateway {
|
||||
contract L1ERC721Gateway is Version, OwnableUpgradeable, ERC721HolderUpgradeable, ScrollGatewayBase, IL1ERC721Gateway {
|
||||
/**************************************** Events ****************************************/
|
||||
|
||||
/// @notice Emitted when token mapping for ERC721 token is updated.
|
||||
|
||||
@@ -8,6 +8,7 @@ import { IL1GatewayRouter } from "./IL1GatewayRouter.sol";
|
||||
import { IL1ERC20Gateway } from "./IL1ERC20Gateway.sol";
|
||||
import { IL1ScrollMessenger } from "../IL1ScrollMessenger.sol";
|
||||
import { IL2GatewayRouter } from "../../L2/gateways/IL2GatewayRouter.sol";
|
||||
import { Version } from "../../libraries/common/Version.sol";
|
||||
import { IScrollGateway } from "../../libraries/gateway/IScrollGateway.sol";
|
||||
import { ScrollGatewayBase } from "../../libraries/gateway/ScrollGatewayBase.sol";
|
||||
|
||||
@@ -16,7 +17,7 @@ import { ScrollGatewayBase } from "../../libraries/gateway/ScrollGatewayBase.sol
|
||||
/// All deposited tokens are routed to corresponding gateways.
|
||||
/// @dev One can also use this contract to query L1/L2 token address mapping.
|
||||
/// In the future, ERC-721 and ERC-1155 tokens will be added to the router too.
|
||||
contract L1GatewayRouter is OwnableUpgradeable, ScrollGatewayBase, IL1GatewayRouter {
|
||||
contract L1GatewayRouter is Version, OwnableUpgradeable, ScrollGatewayBase, IL1GatewayRouter {
|
||||
/**************************************** Events ****************************************/
|
||||
|
||||
event SetDefaultERC20Gateway(address indexed _defaultERC20Gateway);
|
||||
|
||||
@@ -11,6 +11,7 @@ import { L1ERC20Gateway, IL1ERC20Gateway } from "./L1ERC20Gateway.sol";
|
||||
import { IL1ScrollMessenger } from "../IL1ScrollMessenger.sol";
|
||||
import { IERC20Metadata } from "../../interfaces/IERC20Metadata.sol";
|
||||
import { IL2ERC20Gateway } from "../../L2/gateways/IL2ERC20Gateway.sol";
|
||||
import { Version } from "../../libraries/common/Version.sol";
|
||||
import { ScrollGatewayBase, IScrollGateway } from "../../libraries/gateway/ScrollGatewayBase.sol";
|
||||
|
||||
/// @title L1StandardERC20Gateway
|
||||
@@ -19,7 +20,7 @@ import { ScrollGatewayBase, IScrollGateway } from "../../libraries/gateway/Scrol
|
||||
/// @dev The deposited ERC20 tokens are held in this gateway. On finalizing withdraw, the corresponding
|
||||
/// token will be transfer to the recipient directly. Any ERC20 that requires non-standard functionality
|
||||
/// should use a separate gateway.
|
||||
contract L1StandardERC20Gateway is Initializable, ScrollGatewayBase, L1ERC20Gateway {
|
||||
contract L1StandardERC20Gateway is Version, Initializable, ScrollGatewayBase, L1ERC20Gateway {
|
||||
using SafeERC20 for IERC20;
|
||||
|
||||
/**************************************** Variables ****************************************/
|
||||
|
||||
@@ -10,6 +10,7 @@ import { L1ERC20Gateway, IL1ERC20Gateway } from "./L1ERC20Gateway.sol";
|
||||
import { IL1ScrollMessenger } from "../IL1ScrollMessenger.sol";
|
||||
import { IWETH } from "../../interfaces/IWETH.sol";
|
||||
import { IL2ERC20Gateway } from "../../L2/gateways/IL2ERC20Gateway.sol";
|
||||
import { Version } from "../../libraries/common/Version.sol";
|
||||
import { ScrollGatewayBase, IScrollGateway } from "../../libraries/gateway/ScrollGatewayBase.sol";
|
||||
|
||||
/// @title L1WETHGateway
|
||||
@@ -19,7 +20,7 @@ import { ScrollGatewayBase, IScrollGateway } from "../../libraries/gateway/Scrol
|
||||
/// as Ether and then the Ether will be sent to the `L1ScrollMessenger` contract.
|
||||
/// On finalizing withdraw, the Ether will be transfered from `L1ScrollMessenger`, then
|
||||
/// wrapped as WETH and finally transfer to recipient.
|
||||
contract L1WETHGateway is Initializable, ScrollGatewayBase, L1ERC20Gateway {
|
||||
contract L1WETHGateway is Version, Initializable, ScrollGatewayBase, L1ERC20Gateway {
|
||||
using SafeERC20 for IERC20;
|
||||
|
||||
/**************************************** Variables ****************************************/
|
||||
|
||||
@@ -2,12 +2,13 @@
|
||||
|
||||
pragma solidity ^0.8.0;
|
||||
|
||||
import { Version } from "../../libraries/common/Version.sol";
|
||||
import { IL1MessageQueue } from "./IL1MessageQueue.sol";
|
||||
|
||||
/// @title L1MessageQueue
|
||||
/// @notice This contract will hold all L1 to L2 messages.
|
||||
/// Each appended message is assigned with a unique and increasing `uint256` index denoting the message nonce.
|
||||
contract L1MessageQueue is IL1MessageQueue {
|
||||
contract L1MessageQueue is Version, IL1MessageQueue {
|
||||
/*************
|
||||
* Constants *
|
||||
*************/
|
||||
|
||||
@@ -5,6 +5,7 @@ pragma solidity ^0.8.0;
|
||||
import { OwnableUpgradeable } from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol";
|
||||
|
||||
import { IZKRollup } from "./IZKRollup.sol";
|
||||
import { Version } from "../../libraries/common/Version.sol";
|
||||
import { RollupVerifier } from "../../libraries/verifier/RollupVerifier.sol";
|
||||
|
||||
// solhint-disable reason-string
|
||||
@@ -16,7 +17,7 @@ import { RollupVerifier } from "../../libraries/verifier/RollupVerifier.sol";
|
||||
/// 2. the block tree generated by layer 2 and it's status.
|
||||
///
|
||||
/// @dev the message queue is not used yet, the offline relayer only use events in `L1ScrollMessenger`.
|
||||
contract ZKRollup is OwnableUpgradeable, IZKRollup {
|
||||
contract ZKRollup is Version, OwnableUpgradeable, IZKRollup {
|
||||
/**********
|
||||
* Events *
|
||||
**********/
|
||||
|
||||
@@ -6,6 +6,7 @@ import { IL2ScrollMessenger, IScrollMessenger } from "./IL2ScrollMessenger.sol";
|
||||
import { L2MessageQueue } from "./predeploys/L2MessageQueue.sol";
|
||||
import { IL1BlockContainer } from "./predeploys/IL1BlockContainer.sol";
|
||||
import { OwnableBase } from "../libraries/common/OwnableBase.sol";
|
||||
import { Version } from "../libraries/common/Version.sol";
|
||||
import { IGasOracle } from "../libraries/oracle/IGasOracle.sol";
|
||||
import { ScrollConstants } from "../libraries/ScrollConstants.sol";
|
||||
import { ScrollMessengerBase } from "../libraries/ScrollMessengerBase.sol";
|
||||
@@ -19,7 +20,7 @@ import { ScrollMessengerBase } from "../libraries/ScrollMessengerBase.sol";
|
||||
///
|
||||
/// @dev It should be a predeployed contract in layer 2 and should hold infinite amount
|
||||
/// of Ether (Specifically, `uint256(-1)`), which can be initialized in Genesis Block.
|
||||
contract L2ScrollMessenger is ScrollMessengerBase, OwnableBase, IL2ScrollMessenger {
|
||||
contract L2ScrollMessenger is Version, ScrollMessengerBase, OwnableBase, IL2ScrollMessenger {
|
||||
/**************************************** Variables ****************************************/
|
||||
|
||||
/// @notice Mapping from relay id to relay status.
|
||||
@@ -36,7 +37,7 @@ contract L2ScrollMessenger is ScrollMessengerBase, OwnableBase, IL2ScrollMesseng
|
||||
|
||||
constructor(address _owner) {
|
||||
ScrollMessengerBase._initialize();
|
||||
owner = _owner;
|
||||
_transferOwnership(_owner);
|
||||
|
||||
// initialize to a nonzero value
|
||||
xDomainMessageSender = ScrollConstants.DEFAULT_XDOMAIN_MESSAGE_SENDER;
|
||||
|
||||
@@ -8,6 +8,7 @@ import { IERC20Upgradeable } from "@openzeppelin/contracts-upgradeable/token/ERC
|
||||
import { IL2ERC20Gateway, L2ERC20Gateway } from "./L2ERC20Gateway.sol";
|
||||
import { IL2ScrollMessenger } from "../IL2ScrollMessenger.sol";
|
||||
import { IL1ERC20Gateway } from "../../L1/gateways/IL1ERC20Gateway.sol";
|
||||
import { Version } from "../../libraries/common/Version.sol";
|
||||
import { ScrollGatewayBase, IScrollGateway } from "../../libraries/gateway/ScrollGatewayBase.sol";
|
||||
import { IScrollStandardERC20 } from "../../libraries/token/IScrollStandardERC20.sol";
|
||||
|
||||
@@ -16,7 +17,7 @@ import { IScrollStandardERC20 } from "../../libraries/token/IScrollStandardERC20
|
||||
/// finalize deposit the tokens from layer 1.
|
||||
/// @dev The withdrawn tokens tokens will be burned directly. On finalizing deposit, the corresponding
|
||||
/// tokens will be minted and transfered to the recipient.
|
||||
contract L2CustomERC20Gateway is OwnableUpgradeable, ScrollGatewayBase, L2ERC20Gateway {
|
||||
contract L2CustomERC20Gateway is Version, OwnableUpgradeable, ScrollGatewayBase, L2ERC20Gateway {
|
||||
/**************************************** Events ****************************************/
|
||||
|
||||
/// @notice Emitted when token mapping for ERC20 token is updated.
|
||||
|
||||
@@ -9,6 +9,7 @@ import { ERC1155HolderUpgradeable } from "@openzeppelin/contracts-upgradeable/to
|
||||
import { IL2ERC1155Gateway } from "./IL2ERC1155Gateway.sol";
|
||||
import { IL2ScrollMessenger } from "../IL2ScrollMessenger.sol";
|
||||
import { IL1ERC1155Gateway } from "../../L1/gateways/IL1ERC1155Gateway.sol";
|
||||
import { Version } from "../../libraries/common/Version.sol";
|
||||
import { ScrollGatewayBase, IScrollGateway } from "../../libraries/gateway/ScrollGatewayBase.sol";
|
||||
import { IScrollERC1155 } from "../../libraries/token/IScrollERC1155.sol";
|
||||
|
||||
@@ -20,7 +21,7 @@ import { IScrollERC1155 } from "../../libraries/token/IScrollERC1155.sol";
|
||||
///
|
||||
/// This will be changed if we have more specific scenarios.
|
||||
// @todo Current implementation doesn't support calling from `L2GatewayRouter`.
|
||||
contract L2ERC1155Gateway is OwnableUpgradeable, ERC1155HolderUpgradeable, ScrollGatewayBase, IL2ERC1155Gateway {
|
||||
contract L2ERC1155Gateway is Version, OwnableUpgradeable, ERC1155HolderUpgradeable, ScrollGatewayBase, IL2ERC1155Gateway {
|
||||
/**************************************** Events ****************************************/
|
||||
|
||||
/// @notice Emitted when token mapping for ERC1155 token is updated.
|
||||
|
||||
@@ -3,10 +3,11 @@
|
||||
pragma solidity ^0.8.0;
|
||||
|
||||
import { IL2ERC20Gateway } from "./IL2ERC20Gateway.sol";
|
||||
import { Version } from "../../libraries/common/Version.sol";
|
||||
|
||||
// solhint-disable no-empty-blocks
|
||||
|
||||
abstract contract L2ERC20Gateway is IL2ERC20Gateway {
|
||||
abstract contract L2ERC20Gateway is Version, IL2ERC20Gateway {
|
||||
/// @inheritdoc IL2ERC20Gateway
|
||||
function withdrawERC20(
|
||||
address _token,
|
||||
|
||||
@@ -9,6 +9,7 @@ import { ERC721HolderUpgradeable } from "@openzeppelin/contracts-upgradeable/tok
|
||||
import { IL2ERC721Gateway } from "./IL2ERC721Gateway.sol";
|
||||
import { IL2ScrollMessenger } from "../IL2ScrollMessenger.sol";
|
||||
import { IL1ERC721Gateway } from "../../L1/gateways/IL1ERC721Gateway.sol";
|
||||
import { Version } from "../../libraries/common/Version.sol";
|
||||
import { ScrollGatewayBase, IScrollGateway } from "../../libraries/gateway/ScrollGatewayBase.sol";
|
||||
import { IScrollERC721 } from "../../libraries/token/IScrollERC721.sol";
|
||||
|
||||
@@ -20,7 +21,7 @@ import { IScrollERC721 } from "../../libraries/token/IScrollERC721.sol";
|
||||
///
|
||||
/// This will be changed if we have more specific scenarios.
|
||||
// @todo Current implementation doesn't support calling from `L2GatewayRouter`.
|
||||
contract L2ERC721Gateway is OwnableUpgradeable, ERC721HolderUpgradeable, ScrollGatewayBase, IL2ERC721Gateway {
|
||||
contract L2ERC721Gateway is Version, OwnableUpgradeable, ERC721HolderUpgradeable, ScrollGatewayBase, IL2ERC721Gateway {
|
||||
/**************************************** Events ****************************************/
|
||||
|
||||
/// @notice Emitted when token mapping for ERC721 token is updated.
|
||||
|
||||
@@ -8,6 +8,7 @@ import { IL2GatewayRouter } from "./IL2GatewayRouter.sol";
|
||||
import { IL2ERC20Gateway } from "./IL2ERC20Gateway.sol";
|
||||
import { IL2ScrollMessenger } from "../IL2ScrollMessenger.sol";
|
||||
import { IL1GatewayRouter } from "../../L1/gateways/IL1GatewayRouter.sol";
|
||||
import { Version } from "../../libraries/common/Version.sol";
|
||||
import { IScrollGateway } from "../../libraries/gateway/IScrollGateway.sol";
|
||||
import { ScrollGatewayBase } from "../../libraries/gateway/ScrollGatewayBase.sol";
|
||||
import { IScrollStandardERC20 } from "../../libraries/token/IScrollStandardERC20.sol";
|
||||
@@ -17,7 +18,7 @@ import { IScrollStandardERC20 } from "../../libraries/token/IScrollStandardERC20
|
||||
/// All deposited tokens are routed to corresponding gateways.
|
||||
/// @dev One can also use this contract to query L1/L2 token address mapping.
|
||||
/// In the future, ERC-721 and ERC-1155 tokens will be added to the router too.
|
||||
contract L2GatewayRouter is OwnableUpgradeable, ScrollGatewayBase, IL2GatewayRouter {
|
||||
contract L2GatewayRouter is Version, OwnableUpgradeable, ScrollGatewayBase, IL2GatewayRouter {
|
||||
/**************************************** Events ****************************************/
|
||||
|
||||
event SetDefaultERC20Gateway(address indexed _defaultERC20Gateway);
|
||||
|
||||
@@ -10,6 +10,7 @@ import { Address } from "@openzeppelin/contracts/utils/Address.sol";
|
||||
import { IL2ERC20Gateway, L2ERC20Gateway } from "./L2ERC20Gateway.sol";
|
||||
import { IL2ScrollMessenger } from "../IL2ScrollMessenger.sol";
|
||||
import { IL1ERC20Gateway } from "../../L1/gateways/IL1ERC20Gateway.sol";
|
||||
import { Version } from "../../libraries/common/Version.sol";
|
||||
import { IScrollStandardERC20 } from "../../libraries/token/IScrollStandardERC20.sol";
|
||||
import { ScrollStandardERC20 } from "../../libraries/token/ScrollStandardERC20.sol";
|
||||
import { IScrollStandardERC20Factory } from "../../libraries/token/IScrollStandardERC20Factory.sol";
|
||||
@@ -21,7 +22,7 @@ import { ScrollGatewayBase, IScrollGateway } from "../../libraries/gateway/Scrol
|
||||
/// @dev The withdrawn ERC20 tokens will be burned directly. On finalizing deposit, the corresponding
|
||||
/// token will be minted and transfered to the recipient. Any ERC20 that requires non-standard functionality
|
||||
/// should use a separate gateway.
|
||||
contract L2StandardERC20Gateway is Initializable, ScrollGatewayBase, L2ERC20Gateway {
|
||||
contract L2StandardERC20Gateway is Version, Initializable, ScrollGatewayBase, L2ERC20Gateway {
|
||||
using SafeERC20 for IERC20;
|
||||
using Address for address;
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@ import { IL2ERC20Gateway, L2ERC20Gateway } from "./L2ERC20Gateway.sol";
|
||||
import { IL2ScrollMessenger } from "../IL2ScrollMessenger.sol";
|
||||
import { IWETH } from "../../interfaces/IWETH.sol";
|
||||
import { IL1ERC20Gateway } from "../../L1/gateways/IL1ERC20Gateway.sol";
|
||||
import { Version } from "../../libraries/common/Version.sol";
|
||||
import { ScrollGatewayBase, IScrollGateway } from "../../libraries/gateway/ScrollGatewayBase.sol";
|
||||
|
||||
/// @title L2WETHGateway
|
||||
@@ -19,7 +20,7 @@ import { ScrollGatewayBase, IScrollGateway } from "../../libraries/gateway/Scrol
|
||||
/// then the Ether will be sent to the `L2ScrollMessenger` contract.
|
||||
/// On finalizing deposit, the Ether will be transfered from `L2ScrollMessenger`, then
|
||||
/// wrapped as WETH and finally transfer to recipient.
|
||||
contract L2WETHGateway is Initializable, ScrollGatewayBase, L2ERC20Gateway {
|
||||
contract L2WETHGateway is Version, Initializable, ScrollGatewayBase, L2ERC20Gateway {
|
||||
using SafeERC20 for IERC20;
|
||||
|
||||
/**************************************** Variables ****************************************/
|
||||
|
||||
@@ -11,27 +11,26 @@ interface IL1BlockContainer {
|
||||
/// @param blockHash The hash of the imported block.
|
||||
/// @param blockHeight The height of the imported block.
|
||||
/// @param blockTimestamp The timestamp of the imported block.
|
||||
/// @param baseFee The base fee of the imported block.
|
||||
/// @param stateRoot The state root of the imported block.
|
||||
event ImportBlock(bytes32 indexed blockHash, uint256 blockHeight, uint256 blockTimestamp, bytes32 stateRoot);
|
||||
|
||||
/***********
|
||||
* Structs *
|
||||
***********/
|
||||
|
||||
/// @dev Compiler will pack this into single `uint256`.
|
||||
struct BlockMetadata {
|
||||
// The block height.
|
||||
uint64 height;
|
||||
// The block timestamp.
|
||||
uint64 timestamp;
|
||||
// The reserved field.
|
||||
uint128 reserved;
|
||||
}
|
||||
event ImportBlock(bytes32 indexed blockHash, uint256 blockHeight, uint256 blockTimestamp, uint256 baseFee, bytes32 stateRoot);
|
||||
|
||||
/*************************
|
||||
* Public View Functions *
|
||||
*************************/
|
||||
|
||||
/// @notice Return the latest imported block hash
|
||||
function latestBlockHash() external view returns (bytes32);
|
||||
|
||||
/// @notice Return the latest imported L1 base fee
|
||||
function latestBaseFee() external view returns (uint256);
|
||||
|
||||
/// @notice Return the latest imported block number
|
||||
function latestBlockNumber() external view returns (uint256);
|
||||
|
||||
/// @notice Return the latest imported block timestamp
|
||||
function latestBlockTimestamp() external view returns (uint256);
|
||||
|
||||
/// @notice Check whether the message is included in the corresponding L1 block.
|
||||
/// @param blockHash The block hash where the message should in.
|
||||
/// @param msgHash The hash of the message to check.
|
||||
|
||||
50
contracts/src/L2/predeploys/IL2GasPriceOracle.sol
Normal file
50
contracts/src/L2/predeploys/IL2GasPriceOracle.sol
Normal file
@@ -0,0 +1,50 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
pragma solidity ^0.8.0;
|
||||
|
||||
interface IL2GasPriceOracle {
|
||||
/**********
|
||||
* Events *
|
||||
**********/
|
||||
|
||||
/// @notice Emitted when current fee overhead is updated.
|
||||
/// @param overhead The current fee overhead updated.
|
||||
event OverheadUpdated(uint256 overhead);
|
||||
|
||||
/// @notice Emitted when current fee scalar is updated.
|
||||
/// @param scalar The current fee scalar updated.
|
||||
event ScalarUpdated(uint256 scalar);
|
||||
|
||||
/*************************
|
||||
* Public View Functions *
|
||||
*************************/
|
||||
|
||||
/// @notice Return the current L2 base fee.
|
||||
function baseFee() external view returns (uint256);
|
||||
|
||||
/// @notice Return the current L2 gas price (base fee).
|
||||
function gasPrice() external view returns (uint256);
|
||||
|
||||
/// @notice Return the current l1 fee overhead.
|
||||
function overhead() external view returns (uint256);
|
||||
|
||||
/// @notice Return the current l1 fee scalar.
|
||||
function scalar() external view returns (uint256);
|
||||
|
||||
/// @notice Return the latest known l1 base fee.
|
||||
function l1BaseFee() external view returns (uint256);
|
||||
|
||||
/// @notice Computes the L1 portion of the fee based on the size of the rlp encoded input
|
||||
/// transaction, the current L1 base fee, and the various dynamic parameters.
|
||||
/// @param data Unsigned fully RLP-encoded transaction to get the L1 fee for.
|
||||
/// @return L1 fee that should be paid for the tx
|
||||
function getL1Fee(bytes memory data) external view returns (uint256);
|
||||
|
||||
/// @notice Computes the amount of L1 gas used for a transaction. Adds the overhead which
|
||||
/// represents the per-transaction gas overhead of posting the transaction and state
|
||||
/// roots to L1. Adds 68 bytes of padding to account for the fact that the input does
|
||||
/// not have a signature.
|
||||
/// @param data Unsigned fully RLP-encoded transaction to get the L1 gas for.
|
||||
/// @return Amount of L1 gas used to publish the transaction.
|
||||
function getL1GasUsed(bytes memory data) external view returns (uint256);
|
||||
}
|
||||
@@ -8,11 +8,12 @@ import { IL1BlockContainer } from "./IL1BlockContainer.sol";
|
||||
|
||||
import { OwnableBase } from "../../libraries/common/OwnableBase.sol";
|
||||
import { IWhitelist } from "../../libraries/common/IWhitelist.sol";
|
||||
import { Version } from "../../libraries/common/Version.sol";
|
||||
import { PatriciaMerkleTrieVerifier } from "../../libraries/verifier/PatriciaMerkleTrieVerifier.sol";
|
||||
|
||||
/// @title L1BlockContainer
|
||||
/// @notice This contract will maintain the list of blocks proposed in L1.
|
||||
contract L1BlockContainer is Initializable, OwnableBase, IL1BlockContainer {
|
||||
contract L1BlockContainer is Version, Initializable, OwnableBase, IL1BlockContainer {
|
||||
/**********
|
||||
* Events *
|
||||
**********/
|
||||
@@ -32,6 +33,20 @@ contract L1BlockContainer is Initializable, OwnableBase, IL1BlockContainer {
|
||||
/// @notice The address of L1ScrollMessenger contract.
|
||||
address public immutable messenger;
|
||||
|
||||
/***********
|
||||
* Structs *
|
||||
***********/
|
||||
|
||||
/// @dev Compiler will pack this into single `uint256`.
|
||||
struct BlockMetadata {
|
||||
// The block height.
|
||||
uint64 height;
|
||||
// The block timestamp.
|
||||
uint64 timestamp;
|
||||
// The base fee in the block.
|
||||
uint128 baseFee;
|
||||
}
|
||||
|
||||
/*************
|
||||
* Variables *
|
||||
*************/
|
||||
@@ -41,8 +56,8 @@ contract L1BlockContainer is Initializable, OwnableBase, IL1BlockContainer {
|
||||
|
||||
// @todo change to ring buffer to save gas usage.
|
||||
|
||||
/// @notice The hash of last imported block.
|
||||
bytes32 public latestBlockHash;
|
||||
/// @inheritdoc IL1BlockContainer
|
||||
bytes32 public override latestBlockHash;
|
||||
|
||||
/// @notice Mapping from block hash to corresponding state root.
|
||||
mapping(bytes32 => bytes32) public stateRoot;
|
||||
@@ -65,21 +80,37 @@ contract L1BlockContainer is Initializable, OwnableBase, IL1BlockContainer {
|
||||
bytes32 _startBlockHash,
|
||||
uint64 _startBlockHeight,
|
||||
uint64 _startBlockTimestamp,
|
||||
uint128 _startBlockBaseFee,
|
||||
bytes32 _startStateRoot
|
||||
) public initializer {
|
||||
owner = _owner;
|
||||
_transferOwnership(_owner);
|
||||
|
||||
latestBlockHash = _startBlockHash;
|
||||
stateRoot[_startBlockHash] = _startStateRoot;
|
||||
metadata[_startBlockHash] = BlockMetadata(_startBlockHeight, _startBlockTimestamp, 0);
|
||||
metadata[_startBlockHash] = BlockMetadata(_startBlockHeight, _startBlockTimestamp, _startBlockBaseFee);
|
||||
|
||||
emit ImportBlock(_startBlockHash, _startBlockHeight, _startBlockTimestamp, _startStateRoot);
|
||||
emit ImportBlock(_startBlockHash, _startBlockHeight, _startBlockTimestamp, _startBlockBaseFee, _startStateRoot);
|
||||
}
|
||||
|
||||
/*************************
|
||||
* Public View Functions *
|
||||
*************************/
|
||||
|
||||
/// @inheritdoc IL1BlockContainer
|
||||
function latestBaseFee() external override view returns (uint256) {
|
||||
return metadata[latestBlockHash].baseFee;
|
||||
}
|
||||
|
||||
/// @inheritdoc IL1BlockContainer
|
||||
function latestBlockNumber() external override view returns (uint256) {
|
||||
return metadata[latestBlockHash].height;
|
||||
}
|
||||
|
||||
/// @inheritdoc IL1BlockContainer
|
||||
function latestBlockTimestamp() external override view returns (uint256) {
|
||||
return metadata[latestBlockHash].timestamp;
|
||||
}
|
||||
|
||||
/// @inheritdoc IL1BlockContainer
|
||||
function verifyMessageInclusionStatus(
|
||||
bytes32 _blockHash,
|
||||
@@ -181,6 +212,7 @@ contract L1BlockContainer is Initializable, OwnableBase, IL1BlockContainer {
|
||||
bytes32 _stateRoot;
|
||||
uint64 _height;
|
||||
uint64 _timestamp;
|
||||
uint128 _baseFee;
|
||||
|
||||
assembly {
|
||||
// reverts with error `msg`.
|
||||
@@ -304,6 +336,8 @@ contract L1BlockContainer is Initializable, OwnableBase, IL1BlockContainer {
|
||||
_height := mload(add(memPtr, 0x100))
|
||||
// load block timestamp, 12-th entry
|
||||
_timestamp := mload(add(memPtr, 0x160))
|
||||
// load base fee, 16-th entry
|
||||
_baseFee := mload(add(memPtr, 0x1e0))
|
||||
}
|
||||
require(stateRoot[_parentHash] != bytes32(0), "Parent not imported");
|
||||
BlockMetadata memory _parentMetadata = metadata[_parentHash];
|
||||
@@ -312,9 +346,9 @@ contract L1BlockContainer is Initializable, OwnableBase, IL1BlockContainer {
|
||||
|
||||
latestBlockHash = _blockHash;
|
||||
stateRoot[_blockHash] = _stateRoot;
|
||||
metadata[_blockHash] = BlockMetadata(_height, _timestamp, 0);
|
||||
metadata[_blockHash] = BlockMetadata(_height, _timestamp, _baseFee);
|
||||
|
||||
emit ImportBlock(_blockHash, _height, _timestamp, _stateRoot);
|
||||
emit ImportBlock(_blockHash, _height, _timestamp, _baseFee, _stateRoot);
|
||||
}
|
||||
|
||||
/************************
|
||||
|
||||
118
contracts/src/L2/predeploys/L2GasPriceOracle.sol
Normal file
118
contracts/src/L2/predeploys/L2GasPriceOracle.sol
Normal file
@@ -0,0 +1,118 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
pragma solidity ^0.8.0;
|
||||
|
||||
import { OwnableBase } from "../../libraries/common/OwnableBase.sol";
|
||||
import { Version } from "../../libraries/common/Version.sol";
|
||||
|
||||
import "./IL1BlockContainer.sol";
|
||||
import "./IL2GasPriceOracle.sol";
|
||||
|
||||
contract L2GasPriceOracle is Version, OwnableBase, IL2GasPriceOracle {
|
||||
/*************
|
||||
* Constants *
|
||||
*************/
|
||||
|
||||
/// @dev The precision used in the scalar.
|
||||
uint256 private constant PRECISION = 1e9;
|
||||
|
||||
/// @dev The maximum possible l1 fee overhead.
|
||||
/// Computed based on current l1 block gas limit.
|
||||
uint256 private constant MAX_OVERHEAD = 30000000/16;
|
||||
|
||||
/// @dev The maximum possible l1 fee scale.
|
||||
/// x1000 should be enough.
|
||||
uint256 private constant MAX_SCALE = 1000 * PRECISION;
|
||||
|
||||
/// @notice The address of L1BlockContainer contract.
|
||||
address public immutable blockContainer;
|
||||
|
||||
/*************
|
||||
* Variables *
|
||||
*************/
|
||||
|
||||
/// @inheritdoc IL2GasPriceOracle
|
||||
uint256 public override overhead;
|
||||
|
||||
/// @inheritdoc IL2GasPriceOracle
|
||||
uint256 public override scalar;
|
||||
|
||||
/***************
|
||||
* Constructor *
|
||||
***************/
|
||||
|
||||
constructor(address _owner, address _blockContainer) {
|
||||
_transferOwnership(_owner);
|
||||
|
||||
blockContainer = _blockContainer;
|
||||
}
|
||||
|
||||
/*************************
|
||||
* Public View Functions *
|
||||
*************************/
|
||||
|
||||
/// @inheritdoc IL2GasPriceOracle
|
||||
function baseFee() external view override returns (uint256) {
|
||||
return block.basefee;
|
||||
}
|
||||
|
||||
/// @inheritdoc IL2GasPriceOracle
|
||||
function gasPrice() external view override returns (uint256) {
|
||||
return block.basefee;
|
||||
}
|
||||
|
||||
/// @notice Return the latest known l1 base fee.
|
||||
function l1BaseFee() public view override returns (uint256) {
|
||||
return IL1BlockContainer(blockContainer).latestBaseFee();
|
||||
}
|
||||
|
||||
/// @inheritdoc IL2GasPriceOracle
|
||||
function getL1Fee(bytes memory _data) external view override returns (uint256) {
|
||||
unchecked {
|
||||
uint256 _l1GasUsed = getL1GasUsed(_data);
|
||||
uint256 _l1Fee = _l1GasUsed * l1BaseFee();
|
||||
return (_l1Fee * scalar) / PRECISION;
|
||||
}
|
||||
}
|
||||
|
||||
/// @inheritdoc IL2GasPriceOracle
|
||||
/// @dev See the comments in `OVM_GasPriceOracle1` for more details
|
||||
/// https://github.com/ethereum-optimism/optimism/blob/develop/packages/contracts/contracts/L2/predeploys/OVM_GasPriceOracle.sol
|
||||
function getL1GasUsed(bytes memory _data) public view override returns (uint256) {
|
||||
uint256 _total = 0;
|
||||
uint256 _length = _data.length;
|
||||
unchecked {
|
||||
for (uint256 i = 0; i < _length; i++) {
|
||||
if (_data[i] == 0) {
|
||||
_total += 4;
|
||||
} else {
|
||||
_total += 16;
|
||||
}
|
||||
}
|
||||
uint256 _unsigned = _total + overhead;
|
||||
return _unsigned + (68 * 16);
|
||||
}
|
||||
}
|
||||
|
||||
/************************
|
||||
* Restricted Functions *
|
||||
************************/
|
||||
|
||||
/// @notice Allows the owner to modify the overhead.
|
||||
/// @param _overhead New overhead
|
||||
function setOverhead(uint256 _overhead) external onlyOwner {
|
||||
require(_overhead <= MAX_OVERHEAD, "exceed maximum overhead");
|
||||
|
||||
overhead = _overhead;
|
||||
emit OverheadUpdated(_overhead);
|
||||
}
|
||||
|
||||
/// Allows the owner to modify the scalar.
|
||||
/// @param _scalar New scalar
|
||||
function setScalar(uint256 _scalar) external onlyOwner {
|
||||
require(_scalar <= MAX_SCALE, "exceed maximum scale");
|
||||
|
||||
scalar = _scalar;
|
||||
emit ScalarUpdated(_scalar);
|
||||
}
|
||||
}
|
||||
@@ -3,6 +3,7 @@
|
||||
pragma solidity ^0.8.0;
|
||||
|
||||
import { AppendOnlyMerkleTree } from "../../libraries/common/AppendOnlyMerkleTree.sol";
|
||||
import { Version } from "../../libraries/common/Version.sol";
|
||||
|
||||
/// @title L2MessageQueue
|
||||
/// @notice The original idea is from Optimism, see [OVM_L2ToL1MessagePasser](https://github.com/ethereum-optimism/optimism/blob/develop/packages/contracts/contracts/L2/predeploys/OVM_L2ToL1MessagePasser.sol).
|
||||
@@ -10,7 +11,7 @@ import { AppendOnlyMerkleTree } from "../../libraries/common/AppendOnlyMerkleTre
|
||||
/// of a message on L2. The L1 Cross Domain Messenger performs this proof in its
|
||||
/// _verifyStorageProof function, which verifies the existence of the transaction hash in this
|
||||
/// contract's `sentMessages` mapping.
|
||||
contract L2MessageQueue is AppendOnlyMerkleTree {
|
||||
contract L2MessageQueue is Version, AppendOnlyMerkleTree {
|
||||
/// @notice Emitted when a new message is added to the merkle tree.
|
||||
/// @param index The index of the corresponding message.
|
||||
/// @param messageHash The hash of the corresponding message.
|
||||
|
||||
8
contracts/src/libraries/common/Version.sol
Normal file
8
contracts/src/libraries/common/Version.sol
Normal file
@@ -0,0 +1,8 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
pragma solidity ^0.8.0;
|
||||
|
||||
abstract contract Version {
|
||||
/// @notice the current contract version.
|
||||
string public constant version = "0.0.1";
|
||||
}
|
||||
98
contracts/src/test/L2GasPriceOracle.t.sol
Normal file
98
contracts/src/test/L2GasPriceOracle.t.sol
Normal file
@@ -0,0 +1,98 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
pragma solidity ^0.8.0;
|
||||
|
||||
import { DSTestPlus } from "solmate/test/utils/DSTestPlus.sol";
|
||||
import { WETH } from "solmate/tokens/WETH.sol";
|
||||
|
||||
import { L1BlockContainer } from "../L2/predeploys/L1BlockContainer.sol";
|
||||
import { L2GasPriceOracle } from "../L2/predeploys/L2GasPriceOracle.sol";
|
||||
|
||||
contract L2GasPriceOracleTest is DSTestPlus {
|
||||
uint256 private constant PRECISION = 1e9;
|
||||
uint256 private constant MAX_OVERHEAD = 30000000 / 16;
|
||||
uint256 private constant MAX_SCALE = 1000 * PRECISION;
|
||||
|
||||
L2GasPriceOracle private oracle;
|
||||
L1BlockContainer private container;
|
||||
|
||||
function setUp() public {
|
||||
container = new L1BlockContainer(address(0), address(0));
|
||||
oracle = new L2GasPriceOracle(address(this), address(container));
|
||||
}
|
||||
|
||||
function testSetOverhead(uint256 _overhead) external {
|
||||
_overhead = bound(_overhead, 0, MAX_OVERHEAD);
|
||||
|
||||
// call by non-owner, should revert
|
||||
hevm.startPrank(address(1));
|
||||
hevm.expectRevert("caller is not the owner");
|
||||
oracle.setOverhead(_overhead);
|
||||
hevm.stopPrank();
|
||||
|
||||
// overhead is too large
|
||||
hevm.expectRevert("exceed maximum overhead");
|
||||
oracle.setOverhead(MAX_OVERHEAD + 1);
|
||||
|
||||
// call by owner, should succeed
|
||||
assertEq(oracle.overhead(), 0);
|
||||
oracle.setOverhead(_overhead);
|
||||
assertEq(oracle.overhead(), _overhead);
|
||||
}
|
||||
|
||||
function testSetScalar(uint256 _scalar) external {
|
||||
_scalar = bound(_scalar, 0, MAX_SCALE);
|
||||
|
||||
// call by non-owner, should revert
|
||||
hevm.startPrank(address(1));
|
||||
hevm.expectRevert("caller is not the owner");
|
||||
oracle.setScalar(_scalar);
|
||||
hevm.stopPrank();
|
||||
|
||||
// scale is too large
|
||||
hevm.expectRevert("exceed maximum scale");
|
||||
oracle.setScalar(MAX_SCALE + 1);
|
||||
|
||||
// call by owner, should succeed
|
||||
assertEq(oracle.scalar(), 0);
|
||||
oracle.setScalar(_scalar);
|
||||
assertEq(oracle.scalar(), _scalar);
|
||||
}
|
||||
|
||||
function testGetL1GasUsed(uint256 _overhead, bytes memory _data) external {
|
||||
_overhead = bound(_overhead, 0, MAX_OVERHEAD);
|
||||
|
||||
oracle.setOverhead(_overhead);
|
||||
|
||||
uint256 _gasUsed = _overhead + 68 * 16;
|
||||
for (uint256 i = 0; i < _data.length; i++) {
|
||||
if (_data[i] == 0) _gasUsed += 4;
|
||||
else _gasUsed += 16;
|
||||
}
|
||||
|
||||
assertEq(oracle.getL1GasUsed(_data), _gasUsed);
|
||||
}
|
||||
|
||||
function testGetL1Fee(
|
||||
uint256 _baseFee,
|
||||
uint256 _overhead,
|
||||
uint256 _scalar,
|
||||
bytes memory _data
|
||||
) external {
|
||||
_overhead = bound(_overhead, 0, MAX_OVERHEAD);
|
||||
_scalar = bound(_scalar, 0, MAX_SCALE);
|
||||
_baseFee = bound(_baseFee, 0, 1e9 * 20000); // max 20k gwei
|
||||
|
||||
oracle.setOverhead(_overhead);
|
||||
oracle.setScalar(_scalar);
|
||||
container.initialize(address(0), bytes32(0), 0, 0, uint128(_baseFee), bytes32(0));
|
||||
|
||||
uint256 _gasUsed = _overhead + 68 * 16;
|
||||
for (uint256 i = 0; i < _data.length; i++) {
|
||||
if (_data[i] == 0) _gasUsed += 4;
|
||||
else _gasUsed += 16;
|
||||
}
|
||||
|
||||
assertEq(oracle.getL1Fee(_data), (_gasUsed * _baseFee * _scalar) / PRECISION);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user