Commit a96cbe7c authored by smartcontracts's avatar smartcontracts Committed by GitHub

feat(ctb): update L2 contract style (#2764)

Updates L2 contract style to match L1 contract style.
Co-authored-by: default avatarmergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
parent e4b8b702
---
'@eth-optimism/contracts-bedrock': patch
---
Fix style for L2 contracts to match L1 contracts
...@@ -30,8 +30,8 @@ var ( ...@@ -30,8 +30,8 @@ var (
// L1BlockMetaData contains all meta data concerning the L1Block contract. // L1BlockMetaData contains all meta data concerning the L1Block contract.
var L1BlockMetaData = &bind.MetaData{ var L1BlockMetaData = &bind.MetaData{
ABI: "[{\"inputs\":[],\"name\":\"OnlyDepositor\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DEPOSITOR_ACCOUNT\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"basefee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"hash\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"number\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"sequenceNumber\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"_number\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"_timestamp\",\"type\":\"uint64\"},{\"internalType\":\"uint256\",\"name\":\"_basefee\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"_hash\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"_sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"setL1BlockValues\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"timestamp\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", ABI: "[{\"inputs\":[],\"name\":\"DEPOSITOR_ACCOUNT\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"basefee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"hash\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"number\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"sequenceNumber\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"_number\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"_timestamp\",\"type\":\"uint64\"},{\"internalType\":\"uint256\",\"name\":\"_basefee\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"_hash\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"_sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"setL1BlockValues\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"timestamp\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]",
Bin: "0x608060405234801561001057600080fd5b506102b0806100206000396000f3fe608060405234801561001057600080fd5b506004361061007d5760003560e01c806364ca23ef1161005b57806364ca23ef146100bc5780638381f58a146100e9578063b80777ea146100fd578063e591b2821461011d57600080fd5b8063042c2f571461008257806309bd5a60146100975780635cf24969146100b3575b600080fd5b61009561009036600461024c565b61015d565b005b6100a060025481565b6040519081526020015b60405180910390f35b6100a060015481565b6003546100d09067ffffffffffffffff1681565b60405167ffffffffffffffff90911681526020016100aa565b6000546100d09067ffffffffffffffff1681565b6000546100d09068010000000000000000900467ffffffffffffffff1681565b61013873deaddeaddeaddeaddeaddeaddeaddeaddead000181565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100aa565b3373deaddeaddeaddeaddeaddeaddeaddeaddead0001146101aa576040517fce8c104800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000805467ffffffffffffffff9687167fffffffffffffffffffffffffffffffff0000000000000000000000000000000090911617680100000000000000009587169590950294909417909355600191909155600255600380547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001691909216179055565b803567ffffffffffffffff8116811461024757600080fd5b919050565b600080600080600060a0868803121561026457600080fd5b61026d8661022f565b945061027b6020870161022f565b935060408601359250606086013591506102976080870161022f565b9050929550929590935056fea164736f6c634300080a000a", Bin: "0x608060405234801561001057600080fd5b5061030a806100206000396000f3fe608060405234801561001057600080fd5b506004361061007d5760003560e01c806364ca23ef1161005b57806364ca23ef146100bc5780638381f58a146100e9578063b80777ea146100fd578063e591b2821461011d57600080fd5b8063042c2f571461008257806309bd5a60146100975780635cf24969146100b3575b600080fd5b6100956100903660046102a6565b61015d565b005b6100a060025481565b6040519081526020015b60405180910390f35b6100a060015481565b6003546100d09067ffffffffffffffff1681565b60405167ffffffffffffffff90911681526020016100aa565b6000546100d09067ffffffffffffffff1681565b6000546100d09068010000000000000000900467ffffffffffffffff1681565b61013873deaddeaddeaddeaddeaddeaddeaddeaddead000181565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100aa565b3373deaddeaddeaddeaddeaddeaddeaddeaddead000114610204576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603b60248201527f4c31426c6f636b3a206f6e6c7920746865206465706f7369746f72206163636f60448201527f756e742063616e20736574204c3120626c6f636b2076616c7565730000000000606482015260840160405180910390fd5b6000805467ffffffffffffffff9687167fffffffffffffffffffffffffffffffff0000000000000000000000000000000090911617680100000000000000009587169590950294909417909355600191909155600255600380547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001691909216179055565b803567ffffffffffffffff811681146102a157600080fd5b919050565b600080600080600060a086880312156102be57600080fd5b6102c786610289565b94506102d560208701610289565b935060408601359250606086013591506102f160808701610289565b9050929550929590935056fea164736f6c634300080a000a",
} }
// L1BlockABI is the input ABI used to generate the binding from. // L1BlockABI is the input ABI used to generate the binding from.
......
...@@ -2,4 +2,4 @@ ...@@ -2,4 +2,4 @@
// This file is a generated binding and any manual changes will be lost. // This file is a generated binding and any manual changes will be lost.
package bindings package bindings
var L1BlockDeployedBin = "0x608060405234801561001057600080fd5b506004361061007d5760003560e01c806364ca23ef1161005b57806364ca23ef146100bc5780638381f58a146100e9578063b80777ea146100fd578063e591b2821461011d57600080fd5b8063042c2f571461008257806309bd5a60146100975780635cf24969146100b3575b600080fd5b61009561009036600461024c565b61015d565b005b6100a060025481565b6040519081526020015b60405180910390f35b6100a060015481565b6003546100d09067ffffffffffffffff1681565b60405167ffffffffffffffff90911681526020016100aa565b6000546100d09067ffffffffffffffff1681565b6000546100d09068010000000000000000900467ffffffffffffffff1681565b61013873deaddeaddeaddeaddeaddeaddeaddeaddead000181565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100aa565b3373deaddeaddeaddeaddeaddeaddeaddeaddead0001146101aa576040517fce8c104800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000805467ffffffffffffffff9687167fffffffffffffffffffffffffffffffff0000000000000000000000000000000090911617680100000000000000009587169590950294909417909355600191909155600255600380547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001691909216179055565b803567ffffffffffffffff8116811461024757600080fd5b919050565b600080600080600060a0868803121561026457600080fd5b61026d8661022f565b945061027b6020870161022f565b935060408601359250606086013591506102976080870161022f565b9050929550929590935056fea164736f6c634300080a000a" var L1BlockDeployedBin = "0x608060405234801561001057600080fd5b506004361061007d5760003560e01c806364ca23ef1161005b57806364ca23ef146100bc5780638381f58a146100e9578063b80777ea146100fd578063e591b2821461011d57600080fd5b8063042c2f571461008257806309bd5a60146100975780635cf24969146100b3575b600080fd5b6100956100903660046102a6565b61015d565b005b6100a060025481565b6040519081526020015b60405180910390f35b6100a060015481565b6003546100d09067ffffffffffffffff1681565b60405167ffffffffffffffff90911681526020016100aa565b6000546100d09067ffffffffffffffff1681565b6000546100d09068010000000000000000900467ffffffffffffffff1681565b61013873deaddeaddeaddeaddeaddeaddeaddeaddead000181565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100aa565b3373deaddeaddeaddeaddeaddeaddeaddeaddead000114610204576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603b60248201527f4c31426c6f636b3a206f6e6c7920746865206465706f7369746f72206163636f60448201527f756e742063616e20736574204c3120626c6f636b2076616c7565730000000000606482015260840160405180910390fd5b6000805467ffffffffffffffff9687167fffffffffffffffffffffffffffffffff0000000000000000000000000000000090911617680100000000000000009587169590950294909417909355600191909155600255600380547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001691909216179055565b803567ffffffffffffffff811681146102a157600080fd5b919050565b600080600080600060a086880312156102be57600080fd5b6102c786610289565b94506102d560208701610289565b935060408601359250606086013591506102f160808701610289565b9050929550929590935056fea164736f6c634300080a000a"
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
pragma solidity ^0.8.10; pragma solidity ^0.8.10;
/* External Imports */
import { Ownable } from "@openzeppelin/contracts/access/Ownable.sol"; import { Ownable } from "@openzeppelin/contracts/access/Ownable.sol";
import { Lib_PredeployAddresses } from "../libraries/Lib_PredeployAddresses.sol"; import { Lib_PredeployAddresses } from "../libraries/Lib_PredeployAddresses.sol";
import { L1Block } from "../L2/L1Block.sol"; import { L1Block } from "../L2/L1Block.sol";
/** /**
* @custom:proxied
* @custom:predeploy 0x420000000000000000000000000000000000000F
* @title GasPriceOracle * @title GasPriceOracle
* @dev This contract maintains the variables responsible for computing the L1 * @notice This contract maintains the variables responsible for computing the L1 portion of the
* portion of the total fee charged on L2. The values stored in the contract * total fee charged on L2. The values stored in the contract are looked up as part of the
* are looked up as part of the L2 state transition function and used to compute * L2 state transition function and used to compute the total fee paid by the user. The
* the total fee paid by the user. * contract exposes an API that is useful for knowing how large the L1 portion of their
* The contract exposes an API that is useful for knowing how large the L1 * transaction fee will be.
* portion of their transaction fee will be.
* This predeploy is found at 0x420000000000000000000000000000000000000F in the
* L2 state.
* This contract should be behind an upgradable proxy such that when the gas
* prices change, the values can be updated accordingly.
*/ */
contract GasPriceOracle is Ownable { contract GasPriceOracle is Ownable {
/************* /**
* Variables * * @custom:legacy
*************/ * @notice Spacer for backwards compatibility.
*/
// backwards compatibility
uint256 internal spacer0; uint256 internal spacer0;
/**
* @custom:legacy
* @notice Spacer for backwards compatibility.
*/
uint256 internal spacer1; uint256 internal spacer1;
// Amortized cost of batch submission per transaction /**
* @notice Constant L1 gas overhead per transaction.
*/
uint256 public overhead; uint256 public overhead;
// Value to scale the fee up by
/**
* @notice Dynamic L1 gas overhead per transaction.
*/
uint256 public scalar; uint256 public scalar;
// Number of decimals of the scalar
uint256 public decimals;
/*************** /**
* Constructor * * @notice Number of decimals used in the scalar.
***************/ */
uint256 public decimals;
/** /**
* @param _owner Address that will initially own this contract. * @param _owner Address that will initially own this contract.
...@@ -46,70 +50,87 @@ contract GasPriceOracle is Ownable { ...@@ -46,70 +50,87 @@ contract GasPriceOracle is Ownable {
transferOwnership(_owner); transferOwnership(_owner);
} }
/********** /**
* Events * * @notice Emitted when the overhead value is updated.
**********/ */
event OverheadUpdated(uint256 overhead);
event OverheadUpdated(uint256); /**
event ScalarUpdated(uint256); * @notice Emitted when the scalar value is updated.
event DecimalsUpdated(uint256); */
event ScalarUpdated(uint256 scalar);
/******************** /**
* Public Functions * * @notice Emitted when the decimals value is updated.
********************/ */
event DecimalsUpdated(uint256 decimals);
// legacy backwards compat /**
* @notice Retrieves the current gas price (base fee).
*
* @return Current L2 gas price (base fee).
*/
function gasPrice() public returns (uint256) { function gasPrice() public returns (uint256) {
return block.basefee; return block.basefee;
} }
/**
* @notice Retrieves the current base fee.
*
* @return Current L2 base fee.
*/
function baseFee() public returns (uint256) { function baseFee() public returns (uint256) {
return block.basefee; return block.basefee;
} }
/**
* @notice Retrieves the latest known L1 base fee.
*
* @return Latest known L1 base fee.
*/
function l1BaseFee() public view returns (uint256) { function l1BaseFee() public view returns (uint256) {
return L1Block(Lib_PredeployAddresses.L1_BLOCK_ATTRIBUTES).basefee(); return L1Block(Lib_PredeployAddresses.L1_BLOCK_ATTRIBUTES).basefee();
} }
/** /**
* Allows the owner to modify the overhead. * @notice Allows the owner to modify the overhead.
* @param _overhead New overhead *
* @param _overhead New overhead value.
*/ */
// slither-disable-next-line external-function function setOverhead(uint256 _overhead) external onlyOwner {
function setOverhead(uint256 _overhead) public onlyOwner {
overhead = _overhead; overhead = _overhead;
emit OverheadUpdated(_overhead); emit OverheadUpdated(_overhead);
} }
/** /**
* Allows the owner to modify the scalar. * @notice Allows the owner to modify the scalar.
* @param _scalar New scalar *
* @param _scalar New scalar value.
*/ */
// slither-disable-next-line external-function function setScalar(uint256 _scalar) external onlyOwner {
function setScalar(uint256 _scalar) public onlyOwner {
scalar = _scalar; scalar = _scalar;
emit ScalarUpdated(_scalar); emit ScalarUpdated(_scalar);
} }
/** /**
* Allows the owner to modify the decimals. * @notice Allows the owner to modify the decimals.
* @param _decimals New decimals *
* @param _decimals New decimals value.
*/ */
// slither-disable-next-line external-function function setDecimals(uint256 _decimals) external onlyOwner {
function setDecimals(uint256 _decimals) public onlyOwner {
decimals = _decimals; decimals = _decimals;
emit DecimalsUpdated(_decimals); emit DecimalsUpdated(_decimals);
} }
/** /**
* Computes the L1 portion of the fee * @notice Computes the L1 portion of the fee based on the size of the rlp encoded input
* based on the size of the RLP encoded tx * transaction, the current L1 base fee, and the various dynamic parameters.
* and the current l1BaseFee *
* @param _data Unsigned RLP encoded tx, 6 elements * @param _data Unsigned fully RLP-encoded transaction to get the L1 fee for.
*
* @return L1 fee that should be paid for the tx * @return L1 fee that should be paid for the tx
*/ */
// slither-disable-next-line external-function function getL1Fee(bytes memory _data) external view returns (uint256) {
function getL1Fee(bytes memory _data) public view returns (uint256) {
uint256 l1GasUsed = getL1GasUsed(_data); uint256 l1GasUsed = getL1GasUsed(_data);
uint256 l1Fee = l1GasUsed * l1BaseFee(); uint256 l1Fee = l1GasUsed * l1BaseFee();
uint256 divisor = 10**decimals; uint256 divisor = 10**decimals;
...@@ -118,30 +139,16 @@ contract GasPriceOracle is Ownable { ...@@ -118,30 +139,16 @@ contract GasPriceOracle is Ownable {
return scaled; return scaled;
} }
// solhint-disable max-line-length /**
/** * @notice Computes the amount of L1 gas used for a transaction. Adds the overhead which
* Computes the amount of L1 gas used for a transaction * represents the per-transaction gas overhead of posting the transaction and state
* The overhead represents the per batch gas overhead of * roots to L1. Adds 68 bytes of padding to account for the fact that the input does
* posting both transaction and state roots to L1 given larger * not have a signature.
* batch sizes. *
* 4 gas for 0 byte * @param _data Unsigned fully RLP-encoded transaction to get the L1 gas for.
* https://github.com/ethereum/go-ethereum/blob/9ada4a2e2c415e6b0b51c50e901336872e028872/params/protocol_params.go#L33 *
* 16 gas for non zero byte * @return Amount of L1 gas used to publish the transaction.
* https://github.com/ethereum/go-ethereum/blob/9ada4a2e2c415e6b0b51c50e901336872e028872/params/protocol_params.go#L87 */
* This will need to be updated if calldata gas prices change
* Account for the transaction being unsigned
* Padding is added to account for lack of signature on transaction
* 1 byte for RLP V prefix
* 1 byte for V
* 1 byte for RLP R prefix
* 32 bytes for R
* 1 byte for RLP S prefix
* 32 bytes for S
* Total: 68 bytes of padding
* @param _data Unsigned RLP encoded tx, 6 elements
* @return Amount of L1 gas used for a transaction
*/
// solhint-enable max-line-length
function getL1GasUsed(bytes memory _data) public view returns (uint256) { function getL1GasUsed(bytes memory _data) public view returns (uint256) {
uint256 total = 0; uint256 total = 0;
uint256 length = _data.length; uint256 length = _data.length;
......
...@@ -2,56 +2,53 @@ ...@@ -2,56 +2,53 @@
pragma solidity 0.8.10; pragma solidity 0.8.10;
/** /**
* @custom:proxied
* @custom:predeploy 0x4200000000000000000000000000000000000015
* @title L1Block * @title L1Block
* @dev This is an L2 predeploy contract that holds values from the L1 * @notice The L1Block predeploy gives users access to information about the last known L1 block.
* chain. It can only be updated by a special account that has no private * Values within this contract are updated once per epoch (every L1 block) and can only be
* key managed by the L2 system. Transactions sent to this contract can * set by the "depositor" account, a special system address. Depositor account transactions
* be thought of as "L2 system transactions". * are created by the protocol whenever we move to a new epoch.
*/ */
contract L1Block { contract L1Block {
/** /**
* @notice Only the Depositor account may call setL1BlockValues(). * @notice Address of the special depositor account.
*/
error OnlyDepositor();
/**
* @notice The depositor account is a special account that sends
* transactions to this contract.
*/ */
address public constant DEPOSITOR_ACCOUNT = 0xDeaDDEaDDeAdDeAdDEAdDEaddeAddEAdDEAd0001; address public constant DEPOSITOR_ACCOUNT = 0xDeaDDEaDDeAdDeAdDEAdDEaddeAddEAdDEAd0001;
/** /**
* @notice The latest L1 block number known by the L2 system * @notice The latest L1 block number known by the L2 system.
*/ */
uint64 public number; uint64 public number;
/** /**
* @notice The latest L1 timestamp known by the L2 system * @notice The latest L1 timestamp known by the L2 system.
*/ */
uint64 public timestamp; uint64 public timestamp;
/** /**
* @notice The latest L1 basefee * @notice The latest L1 basefee.
*/ */
uint256 public basefee; uint256 public basefee;
/** /**
* @notice The latest L1 blockhash * @notice The latest L1 blockhash.
*/ */
bytes32 public hash; bytes32 public hash;
/** /**
* @notice The number of L2 blocks in the same epoch * @notice The number of L2 blocks in the same epoch.
*/ */
uint64 public sequenceNumber; uint64 public sequenceNumber;
/** /**
* @notice Sets the L1 values * @notice Updates the L1 block values.
* @param _number L1 blocknumber *
* @param _timestamp L1 timestamp * @param _number L1 blocknumber.
* @param _basefee L1 basefee * @param _timestamp L1 timestamp.
* @param _hash L1 blockhash * @param _basefee L1 basefee.
* @param _sequenceNumber Number of L2 blocks since epoch start * @param _hash L1 blockhash.
* @param _sequenceNumber Number of L2 blocks since epoch start.
*/ */
function setL1BlockValues( function setL1BlockValues(
uint64 _number, uint64 _number,
...@@ -60,9 +57,10 @@ contract L1Block { ...@@ -60,9 +57,10 @@ contract L1Block {
bytes32 _hash, bytes32 _hash,
uint64 _sequenceNumber uint64 _sequenceNumber
) external { ) external {
if (msg.sender != DEPOSITOR_ACCOUNT) { require(
revert OnlyDepositor(); msg.sender == DEPOSITOR_ACCOUNT,
} "L1Block: only the depositor account can set L1 block values"
);
number = _number; number = _number;
timestamp = _timestamp; timestamp = _timestamp;
......
...@@ -5,14 +5,19 @@ import { L1Block } from "./L1Block.sol"; ...@@ -5,14 +5,19 @@ import { L1Block } from "./L1Block.sol";
import { Lib_PredeployAddresses } from "../libraries/Lib_PredeployAddresses.sol"; import { Lib_PredeployAddresses } from "../libraries/Lib_PredeployAddresses.sol";
/** /**
* @custom:legacy
* @custom:proxied
* @custom:predeploy 0x4200000000000000000000000000000000000013
* @title L1BlockNumber * @title L1BlockNumber
* @dev L1BlockNumber is a legacy contract that fills the roll of the OVM_L1BlockNumber contract in * @notice L1BlockNumber is a legacy contract that fills the roll of the OVM_L1BlockNumber contract
* the old version of the Optimism system. Only necessary for backwards compatibility. If you want * in the old version of the Optimism system. Only necessary for backwards compatibility.
* to access the L1 block number going forward, you should use the L1Block contract instead. * If you want to access the L1 block number going forward, you should use the L1Block
* * contract instead.
* ADDRESS: 0x4200000000000000000000000000000000000013
*/ */
contract L1BlockNumber { contract L1BlockNumber {
/**
* @notice Returns the L1 block number.
*/
receive() external payable { receive() external payable {
uint256 l1BlockNumber = getL1BlockNumber(); uint256 l1BlockNumber = getL1BlockNumber();
assembly { assembly {
...@@ -21,6 +26,9 @@ contract L1BlockNumber { ...@@ -21,6 +26,9 @@ contract L1BlockNumber {
} }
} }
/**
* @notice Returns the L1 block number.
*/
fallback() external payable { fallback() external payable {
uint256 l1BlockNumber = getL1BlockNumber(); uint256 l1BlockNumber = getL1BlockNumber();
assembly { assembly {
...@@ -29,6 +37,11 @@ contract L1BlockNumber { ...@@ -29,6 +37,11 @@ contract L1BlockNumber {
} }
} }
/**
* @notice Retrieves the latest L1 block number.
*
* @return Latest L1 block number.
*/
function getL1BlockNumber() public view returns (uint256) { function getL1BlockNumber() public view returns (uint256) {
return L1Block(Lib_PredeployAddresses.L1_BLOCK_ATTRIBUTES).number(); return L1Block(Lib_PredeployAddresses.L1_BLOCK_ATTRIBUTES).number();
} }
......
...@@ -6,14 +6,19 @@ import { Lib_PredeployAddresses } from "../libraries/Lib_PredeployAddresses.sol" ...@@ -6,14 +6,19 @@ import { Lib_PredeployAddresses } from "../libraries/Lib_PredeployAddresses.sol"
import { CrossDomainMessenger } from "../universal/CrossDomainMessenger.sol"; import { CrossDomainMessenger } from "../universal/CrossDomainMessenger.sol";
import { L2ToL1MessagePasser } from "./L2ToL1MessagePasser.sol"; import { L2ToL1MessagePasser } from "./L2ToL1MessagePasser.sol";
/**
* @custom:proxied
* @custom:predeploy 0x4200000000000000000000000000000000000007
* @title L2CrossDomainMessenger
* @notice The L2CrossDomainMessenger is a high-level interface for message passing between L1 and
* L2 on the L2 side. Users are generally encouraged to use this contract instead of lower
* level message passing contracts.
*/
contract L2CrossDomainMessenger is CrossDomainMessenger { contract L2CrossDomainMessenger is CrossDomainMessenger {
/********************
* Public Functions *
********************/
/** /**
* @notice initialize the L2CrossDomainMessenger by giving * @notice Initializes the L2CrossDomainMessenger.
* it the address of the L1CrossDomainMessenger on L1 *
* @param _l1CrossDomainMessenger Address of the L1CrossDomainMessenger contract.
*/ */
function initialize(address _l1CrossDomainMessenger) external { function initialize(address _l1CrossDomainMessenger) external {
address[] memory blockedSystemAddresses = new address[](2); address[] memory blockedSystemAddresses = new address[](2);
...@@ -24,31 +29,31 @@ contract L2CrossDomainMessenger is CrossDomainMessenger { ...@@ -24,31 +29,31 @@ contract L2CrossDomainMessenger is CrossDomainMessenger {
} }
/** /**
* @notice Legacy getter for the remote messenger. This is included * @custom:legacy
* to prevent any existing contracts that relay messages from breaking. * @notice Legacy getter for the remote messenger. Use otherMessenger going forward.
* Use `otherMessenger()` for a standard API that works on both *
* the L1 and L2 cross domain messengers. * @return Address of the L1CrossDomainMessenger contract.
*/ */
function l1CrossDomainMessenger() public returns (address) { function l1CrossDomainMessenger() public returns (address) {
return otherMessenger; return otherMessenger;
} }
/**********************
* Internal Functions *
**********************/
/** /**
* @notice Only the L1CrossDomainMessenger can call the * @notice Checks that the message sender is the L1CrossDomainMessenger on L1.
* L2CrossDomainMessenger *
* @return True if the message sender is the L1CrossDomainMessenger on L1.
*/ */
function _isSystemMessageSender() internal view override returns (bool) { function _isSystemMessageSender() internal view override returns (bool) {
return AddressAliasHelper.undoL1ToL2Alias(msg.sender) == otherMessenger; return AddressAliasHelper.undoL1ToL2Alias(msg.sender) == otherMessenger;
} }
/** /**
* @notice Sending a message from L2 to L1 involves calling the L2ToL1MessagePasser * @notice Sends a message from L2 to L1.
* where it stores in a storage slot a commitment to the message being *
* sent to L1. A proof is then verified against that storage slot on L1. * @param _to Address to send the message to.
* @param _gasLimit Minimum gas limit to execute the message with.
* @param _value ETH value to send with the message.
* @param _data Data to trigger the recipient with.
*/ */
function _sendMessage( function _sendMessage(
address _to, address _to,
......
...@@ -6,16 +6,24 @@ import { StandardBridge } from "../universal/StandardBridge.sol"; ...@@ -6,16 +6,24 @@ import { StandardBridge } from "../universal/StandardBridge.sol";
import { OptimismMintableERC20 } from "../universal/OptimismMintableERC20.sol"; import { OptimismMintableERC20 } from "../universal/OptimismMintableERC20.sol";
/** /**
* @custom:proxied
* @custom:predeploy 0x4200000000000000000000000000000000000010
* @title L2StandardBridge * @title L2StandardBridge
* @dev This contract is an L2 predeploy that is responsible for facilitating * @notice The L2StandardBridge is responsible for transfering ETH and ERC20 tokens between L1 and
* deposits of tokens from L1 to L2. * L2. ERC20 tokens sent to L1 are escrowed within this contract.
* TODO: ensure that this has 1:1 backwards compatibility
*/ */
contract L2StandardBridge is StandardBridge { contract L2StandardBridge is StandardBridge {
/********** /**
* Events * * @custom:legacy
**********/ * @notice Emitted whenever a withdrawal from L2 to L1 is initiated.
*
* @param _l1Token Address of the token on L1.
* @param _l2Token Address of the corresponding token on L2.
* @param _from Address of the withdrawer.
* @param _to Address of the recipient on L1.
* @param _amount Amount of the ERC20 withdrawn.
* @param _data Extra data attached to the withdrawal.
*/
event WithdrawalInitiated( event WithdrawalInitiated(
address indexed _l1Token, address indexed _l1Token,
address indexed _l2Token, address indexed _l2Token,
...@@ -25,6 +33,17 @@ contract L2StandardBridge is StandardBridge { ...@@ -25,6 +33,17 @@ contract L2StandardBridge is StandardBridge {
bytes _data bytes _data
); );
/**
* @custom:legacy
* @notice Emitted whenever an ERC20 deposit is finalized.
*
* @param _l1Token Address of the token on L1.
* @param _l2Token Address of the corresponding token on L2.
* @param _from Address of the depositor.
* @param _to Address of the recipient on L2.
* @param _amount Amount of the ERC20 deposited.
* @param _data Extra data attached to the deposit.
*/
event DepositFinalized( event DepositFinalized(
address indexed _l1Token, address indexed _l1Token,
address indexed _l2Token, address indexed _l2Token,
...@@ -34,6 +53,17 @@ contract L2StandardBridge is StandardBridge { ...@@ -34,6 +53,17 @@ contract L2StandardBridge is StandardBridge {
bytes _data bytes _data
); );
/**
* @custom:legacy
* @notice Emitted whenever a deposit fails.
*
* @param _l1Token Address of the token on L1.
* @param _l2Token Address of the corresponding token on L2.
* @param _from Address of the depositor.
* @param _to Address of the recipient on L2.
* @param _amount Amount of the ERC20 deposited.
* @param _data Extra data attached to the deposit.
*/
event DepositFailed( event DepositFailed(
address indexed _l1Token, address indexed _l1Token,
address indexed _l2Token, address indexed _l2Token,
...@@ -43,24 +73,23 @@ contract L2StandardBridge is StandardBridge { ...@@ -43,24 +73,23 @@ contract L2StandardBridge is StandardBridge {
bytes _data bytes _data
); );
/********************
* Public Functions *
********************/
/** /**
* @notice Initialize the L2StandardBridge. This must only be callable * @notice Initializes the L2StandardBridge.
* once. `_initialize` ensures this. *
* @param _otherBridge Address of the L1StandardBridge.
*/ */
function initialize(address payable _otherBridge) public { function initialize(address payable _otherBridge) public {
_initialize(payable(Lib_PredeployAddresses.L2_CROSS_DOMAIN_MESSENGER), _otherBridge); _initialize(payable(Lib_PredeployAddresses.L2_CROSS_DOMAIN_MESSENGER), _otherBridge);
} }
/** /**
* @notice Withdraw tokens to self on L1 * @custom:legacy
* @param _l2Token The L2 token address to withdraw * @notice Initiates a withdrawal from L2 to L1.
* @param _amount The amount of L2 token to withdraw *
* @param _minGasLimit The min gas limit in the withdrawing call * @param _l2Token Address of the L2 token to withdraw.
* @param _data Additional calldata to pass along * @param _amount Amount of the L2 token to withdraw.
* @param _minGasLimit Minimum gas limit to use for the transaction.
* @param _data Extra data attached to the withdrawal.
*/ */
function withdraw( function withdraw(
address _l2Token, address _l2Token,
...@@ -72,12 +101,14 @@ contract L2StandardBridge is StandardBridge { ...@@ -72,12 +101,14 @@ contract L2StandardBridge is StandardBridge {
} }
/** /**
* @notice Withdraw tokens to an address on L1 * @custom:legacy
* @param _l2Token The L2 token address to withdraw * @notice Initiates a withdrawal from L2 to L1 to a target account on L1.
* @param _to The L1 account to withdraw to *
* @param _amount The amount of L2 token to withdraw * @param _l2Token Address of the L2 token to withdraw.
* @param _minGasLimit The min gas limit in the withdrawing call * @param _to Recipient account on L1.
* @param _data Additional calldata to pass along * @param _amount Amount of the L2 token to withdraw.
* @param _minGasLimit Minimum gas limit to use for the transaction.
* @param _data Extra data attached to the withdrawal.
*/ */
function withdrawTo( function withdrawTo(
address _l2Token, address _l2Token,
...@@ -90,14 +121,15 @@ contract L2StandardBridge is StandardBridge { ...@@ -90,14 +121,15 @@ contract L2StandardBridge is StandardBridge {
} }
/** /**
* @notice Finalize the L1 to L2 deposit. This should only be callable by * @custom:legacy
* a deposit through the L1StandardBridge. * @notice Finalizes a deposit from L1 to L2.
* @param _l1Token The L1 token address *
* @param _l2Token The corresponding L2 token address * @param _l1Token Address of the L1 token to deposit.
* @param _from The sender of the tokens * @param _l2Token Address of the corresponding L2 token.
* @param _to The recipient of the tokens * @param _from Address of the depositor.
* @param _amount The amount of tokens * @param _to Address of the recipient.
* @param _data Additional calldata * @param _amount Amount of the tokens being deposited.
* @param _data Extra data attached to the deposit.
*/ */
function finalizeDeposit( function finalizeDeposit(
address _l1Token, address _l1Token,
...@@ -115,14 +147,16 @@ contract L2StandardBridge is StandardBridge { ...@@ -115,14 +147,16 @@ contract L2StandardBridge is StandardBridge {
emit DepositFinalized(_l1Token, _l2Token, _from, _to, _amount, _data); emit DepositFinalized(_l1Token, _l2Token, _from, _to, _amount, _data);
} }
/**********************
* Internal Functions *
**********************/
/** /**
* @notice Handle withdrawals, taking into account the legacy form of ETH * @custom:legacy
* when it was represented as an ERC20 at the OVM_ETH contract. * @notice Internal function to a withdrawal from L2 to L1 to a target account on L1.
* TODO: require(msg.value == _value) for OVM_ETH case? *
* @param _l2Token Address of the L2 token to withdraw.
* @param _from Address of the withdrawer.
* @param _to Recipient account on L1.
* @param _amount Amount of the L2 token to withdraw.
* @param _minGasLimit Minimum gas limit to use for the transaction.
* @param _data Extra data attached to the withdrawal.
*/ */
function _initiateWithdrawal( function _initiateWithdrawal(
address _l2Token, address _l2Token,
......
...@@ -5,22 +5,23 @@ import { WithdrawalVerifier } from "../libraries/Lib_WithdrawalVerifier.sol"; ...@@ -5,22 +5,23 @@ import { WithdrawalVerifier } from "../libraries/Lib_WithdrawalVerifier.sol";
import { Burn } from "../libraries/Burn.sol"; import { Burn } from "../libraries/Burn.sol";
/** /**
* @custom:proxied
* @custom:predeploy 0x4200000000000000000000000000000000000000
* @title L2ToL1MessagePasser * @title L2ToL1MessagePasser
* TODO: should this be renamed to L2OptimismPortal? * @notice The L2ToL1MessagePasser is a dedicated contract where messages that are being sent from
* L2 to L1 can be stored. The storage root of this contract is pulled up to the top level
* of the L2 output to reduce the cost of proving the existence of sent messages.
*/ */
contract L2ToL1MessagePasser { contract L2ToL1MessagePasser {
/**********
* Events *
**********/
/** /**
* @notice Emitted any time a withdrawal is initiated. * @notice Emitted any time a withdrawal is initiated.
* @param nonce Unique value corresponding to each withdrawal. *
* @param sender The L2 account address which initiated the withdrawal. * @param nonce Unique value corresponding to each withdrawal.
* @param target The L1 account address the call will be send to. * @param sender The L2 account address which initiated the withdrawal.
* @param value The ETH value submitted for withdrawal, to be forwarded to the target. * @param target The L1 account address the call will be send to.
* @param value The ETH value submitted for withdrawal, to be forwarded to the target.
* @param gasLimit The minimum amount of gas that must be provided when withdrawing on L1. * @param gasLimit The minimum amount of gas that must be provided when withdrawing on L1.
* @param data The data to be forwarded to the target on L1. * @param data The data to be forwarded to the target on L1.
*/ */
event WithdrawalInitiated( event WithdrawalInitiated(
uint256 indexed nonce, uint256 indexed nonce,
...@@ -33,13 +34,11 @@ contract L2ToL1MessagePasser { ...@@ -33,13 +34,11 @@ contract L2ToL1MessagePasser {
/** /**
* @notice Emitted when the balance of this contract is burned. * @notice Emitted when the balance of this contract is burned.
*
* @param amount Amount of ETh that was burned.
*/ */
event WithdrawerBalanceBurnt(uint256 indexed amount); event WithdrawerBalanceBurnt(uint256 indexed amount);
/*************
* Variables *
*************/
/** /**
* @notice Includes the message hashes for all withdrawals * @notice Includes the message hashes for all withdrawals
*/ */
...@@ -50,26 +49,19 @@ contract L2ToL1MessagePasser { ...@@ -50,26 +49,19 @@ contract L2ToL1MessagePasser {
*/ */
uint256 public nonce; uint256 public nonce;
/********************
* Public Functions *
********************/
/** /**
* @notice Allow users to withdraw by sending ETH * @notice Allows users to withdraw ETH by sending directly to this contract.
* directly to this contract.
* TODO: maybe this should be only EOA
*/ */
receive() external payable { receive() external payable {
initiateWithdrawal(msg.sender, 100000, bytes("")); initiateWithdrawal(msg.sender, 100000, bytes(""));
} }
/** /**
* @notice Initiates a withdrawal to execute on L1. * @notice Sends a message from L2 to L1.
* TODO: message hashes must be migrated since the legacy *
* hashes are computed differently * @param _target Address to call on L1 execution.
* @param _target Address to call on L1 execution. * @param _gasLimit Minimum gas limit for executing the message on L1.
* @param _gasLimit GasLimit to provide on L1. * @param _data Data to forward to L1 target.
* @param _data Data to forward to L1 target.
*/ */
function initiateWithdrawal( function initiateWithdrawal(
address _target, address _target,
...@@ -94,10 +86,10 @@ contract L2ToL1MessagePasser { ...@@ -94,10 +86,10 @@ contract L2ToL1MessagePasser {
} }
/** /**
* @notice Removes all ETH held in this contract from the state, by deploying a contract which * @notice Removes all ETH held by this contract from the state. Used to prevent the amount of
* immediately self destructs. * ETH on L2 inflating when ETH is withdrawn. Currently only way to do this is to
* For simplicity, this call is not incentivized as it costs very little to run. * create a contract and self-destruct it to itself. Anyone can call this function. Not
* Inspired by https://etherscan.io/address/0xb69fba56b2e67e7dda61c8aa057886a8d1468575#code * incentivized since this function is very cheap.
*/ */
function burn() external { function burn() external {
uint256 balance = address(this).balance; uint256 balance = address(this).balance;
......
...@@ -8,34 +8,66 @@ import { Lib_PredeployAddresses } from "../libraries/Lib_PredeployAddresses.sol" ...@@ -8,34 +8,66 @@ import { Lib_PredeployAddresses } from "../libraries/Lib_PredeployAddresses.sol"
import { OptimismMintableERC20 } from "../universal/OptimismMintableERC20.sol"; import { OptimismMintableERC20 } from "../universal/OptimismMintableERC20.sol";
/** /**
* @custom:proxied
* @custom:predeploy 0xDeadDeAddeAddEAddeadDEaDDEAdDeaDDeAD0000
* @title OVM_ETH * @title OVM_ETH
* @dev Deprecated contract that used to hold user ETH balances * @notice Legacy contract which used to hold ETH balances on L2.
*/ */
contract OVM_ETH is OptimismMintableERC20 { contract OVM_ETH is OptimismMintableERC20 {
/*************** /**
* Constructor * * @notice Initializes the contract as an Optimism Mintable ERC20.
***************/ */
constructor() constructor()
OptimismMintableERC20(Lib_PredeployAddresses.L2_STANDARD_BRIDGE, address(0), "Ether", "ETH") OptimismMintableERC20(Lib_PredeployAddresses.L2_STANDARD_BRIDGE, address(0), "Ether", "ETH")
{} {}
/**
* @notice Mints some amount of ETH.
*
* @param _to Address of the recipient.
* @param _amount Amount of ETH to mint.
*/
function mint(address _to, uint256 _amount) public virtual override { function mint(address _to, uint256 _amount) public virtual override {
revert("OVM_ETH: mint is disabled"); revert("OVM_ETH: mint is disabled");
} }
/**
* @notice Burns some amount of ETH.
*
* @param _from Address to burn from.
* @param _amount Amount of ETH to burn.
*/
function burn(address _from, uint256 _amount) public virtual override { function burn(address _from, uint256 _amount) public virtual override {
revert("OVM_ETH: burn is disabled"); revert("OVM_ETH: burn is disabled");
} }
/**
* @notice Transfers some amount of ETH.
*
* @param _recipient Address to send to.
* @param _amount Amount of ETH to send.
*/
function transfer(address _recipient, uint256 _amount) public virtual override returns (bool) { function transfer(address _recipient, uint256 _amount) public virtual override returns (bool) {
revert("OVM_ETH: transfer is disabled"); revert("OVM_ETH: transfer is disabled");
} }
/**
* @notice Approves a spender to spend some amount of ETH.
*
* @param _spender Address of the spender.
* @param _amount Amount of ETH to approve.
*/
function approve(address _spender, uint256 _amount) public virtual override returns (bool) { function approve(address _spender, uint256 _amount) public virtual override returns (bool) {
revert("OVM_ETH: approve is disabled"); revert("OVM_ETH: approve is disabled");
} }
/**
* @notice Transfers funds from some sender account.
*
* @param _sender Address of the sender.
* @param _recipient Address of the recipient.
* @param _amount Amount of ETH to transfer.
*/
function transferFrom( function transferFrom(
address _sender, address _sender,
address _recipient, address _recipient,
...@@ -44,6 +76,12 @@ contract OVM_ETH is OptimismMintableERC20 { ...@@ -44,6 +76,12 @@ contract OVM_ETH is OptimismMintableERC20 {
revert("OVM_ETH: transferFrom is disabled"); revert("OVM_ETH: transferFrom is disabled");
} }
/**
* @notice Increases the allowance of a spender.
*
* @param _spender Address of the spender.
* @param _addedValue Amount of ETH to increase the allowance by.
*/
function increaseAllowance(address _spender, uint256 _addedValue) function increaseAllowance(address _spender, uint256 _addedValue)
public public
virtual virtual
...@@ -53,6 +91,12 @@ contract OVM_ETH is OptimismMintableERC20 { ...@@ -53,6 +91,12 @@ contract OVM_ETH is OptimismMintableERC20 {
revert("OVM_ETH: increaseAllowance is disabled"); revert("OVM_ETH: increaseAllowance is disabled");
} }
/**
* @notice Decreases the allowance of a spender.
*
* @param _spender Address of the spender.
* @param _subtractedValue Amount of ETH to decrease the allowance by.
*/
function decreaseAllowance(address _spender, uint256 _subtractedValue) function decreaseAllowance(address _spender, uint256 _subtractedValue)
public public
virtual virtual
......
...@@ -8,38 +8,32 @@ import { Lib_PredeployAddresses } from "../libraries/Lib_PredeployAddresses.sol" ...@@ -8,38 +8,32 @@ import { Lib_PredeployAddresses } from "../libraries/Lib_PredeployAddresses.sol"
import { L2StandardBridge } from "./L2StandardBridge.sol"; import { L2StandardBridge } from "./L2StandardBridge.sol";
/** /**
* @custom:proxied
* @custom:predeploy 0x4200000000000000000000000000000000000011
* @title SequencerFeeVault * @title SequencerFeeVault
* @dev Simple holding contract for fees paid to the Sequencer * @notice The SequencerFeeVault is the contract that holds any fees paid to the Sequencer during
* transaction processing and block production.
*/ */
contract SequencerFeeVault { contract SequencerFeeVault {
/************* /**
* Constants * * @notice Minimum balance before a withdrawal can be triggered.
*************/ */
// Minimum ETH balance that can be withdrawn in a single withdrawal.
uint256 public constant MIN_WITHDRAWAL_AMOUNT = 15 ether; uint256 public constant MIN_WITHDRAWAL_AMOUNT = 15 ether;
/************* /**
* Variables * * @notice Wallet that will receive the fees on L1.
*************/ */
// Address on L1 that will hold the fees once withdrawn. Dynamically
// initialized in the genesis state
address public l1FeeWallet; address public l1FeeWallet;
/************ /**
* Fallback * * @notice Allow the contract to receive ETH.
************/ */
// slither-disable-next-line locked-ether
receive() external payable {} receive() external payable {}
/******************** /**
* Public Functions * * @notice Triggers a withdrawal of funds to the L1 fee wallet.
********************/ */
function withdraw() external {
// slither-disable-next-line external-function
function withdraw() public {
require( require(
address(this).balance >= MIN_WITHDRAWAL_AMOUNT, address(this).balance >= MIN_WITHDRAWAL_AMOUNT,
// solhint-disable-next-line max-line-length // solhint-disable-next-line max-line-length
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment