Commit d82e0af3 authored by mergify[bot]'s avatar mergify[bot] Committed by GitHub

Merge branch 'develop' into cleanup/remove-hh-deploy

parents 6a5bc39d 759473bb
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -31,7 +31,7 @@ var (
// L1BlockNumberMetaData contains all meta data concerning the L1BlockNumber contract.
var L1BlockNumberMetaData = &bind.MetaData{
ABI: "[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"getL1BlockNumber\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"version\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}]",
Bin: "0x60e060405234801561001057600080fd5b5060016080819052600060a081905260c08190528061059461004a8239600061018d015260006101640152600061013b01526105946000f3fe60806040526004361061002d5760003560e01c806354fd4d5014610052578063b9b3efe91461007d57610048565b3661004857600061003c6100a0565b90508060005260206000f35b600061003c6100a0565b34801561005e57600080fd5b50610067610134565b6040516100749190610344565b60405180910390f35b34801561008957600080fd5b506100926100a0565b604051908152602001610074565b600073420000000000000000000000000000000000001573ffffffffffffffffffffffffffffffffffffffff16638381f58a6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610101573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101259190610395565b67ffffffffffffffff16905090565b606061015f7f00000000000000000000000000000000000000000000000000000000000000006101d7565b6101887f00000000000000000000000000000000000000000000000000000000000000006101d7565b6101b17f00000000000000000000000000000000000000000000000000000000000000006101d7565b6040516020016101c3939291906103c6565b604051602081830303815290604052905090565b60608160000361021a57505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b8115610244578061022e8161046b565b915061023d9050600a836104d2565b915061021e565b60008167ffffffffffffffff81111561025f5761025f6104e6565b6040519080825280601f01601f191660200182016040528015610289576020820181803683370190505b5090505b841561030c5761029e600183610515565b91506102ab600a8661052c565b6102b6906030610540565b60f81b8183815181106102cb576102cb610558565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350610305600a866104d2565b945061028d565b949350505050565b60005b8381101561032f578181015183820152602001610317565b8381111561033e576000848401525b50505050565b6020815260008251806020840152610363816040850160208701610314565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b6000602082840312156103a757600080fd5b815167ffffffffffffffff811681146103bf57600080fd5b9392505050565b600084516103d8818460208901610314565b80830190507f2e000000000000000000000000000000000000000000000000000000000000008082528551610414816001850160208a01610314565b6001920191820152835161042f816002840160208801610314565b0160020195945050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361049c5761049c61043c565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000826104e1576104e16104a3565b500490565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000828210156105275761052761043c565b500390565b60008261053b5761053b6104a3565b500690565b600082198211156105535761055361043c565b500190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fdfea164736f6c634300080f000a",
Bin: "0x60e060405234801561001057600080fd5b5060016080819052600060a081905260c08290528161059461004a8339600061018d015260006101640152600061013b01526105946000f3fe60806040526004361061002d5760003560e01c806354fd4d5014610052578063b9b3efe91461007d57610048565b3661004857600061003c6100a0565b90508060005260206000f35b600061003c6100a0565b34801561005e57600080fd5b50610067610134565b6040516100749190610344565b60405180910390f35b34801561008957600080fd5b506100926100a0565b604051908152602001610074565b600073420000000000000000000000000000000000001573ffffffffffffffffffffffffffffffffffffffff16638381f58a6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610101573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101259190610395565b67ffffffffffffffff16905090565b606061015f7f00000000000000000000000000000000000000000000000000000000000000006101d7565b6101887f00000000000000000000000000000000000000000000000000000000000000006101d7565b6101b17f00000000000000000000000000000000000000000000000000000000000000006101d7565b6040516020016101c3939291906103c6565b604051602081830303815290604052905090565b60608160000361021a57505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b8115610244578061022e8161046b565b915061023d9050600a836104d2565b915061021e565b60008167ffffffffffffffff81111561025f5761025f6104e6565b6040519080825280601f01601f191660200182016040528015610289576020820181803683370190505b5090505b841561030c5761029e600183610515565b91506102ab600a8661052c565b6102b6906030610540565b60f81b8183815181106102cb576102cb610558565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350610305600a866104d2565b945061028d565b949350505050565b60005b8381101561032f578181015183820152602001610317565b8381111561033e576000848401525b50505050565b6020815260008251806020840152610363816040850160208701610314565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b6000602082840312156103a757600080fd5b815167ffffffffffffffff811681146103bf57600080fd5b9392505050565b600084516103d8818460208901610314565b80830190507f2e000000000000000000000000000000000000000000000000000000000000008082528551610414816001850160208a01610314565b6001920191820152835161042f816002840160208801610314565b0160020195945050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361049c5761049c61043c565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000826104e1576104e16104a3565b500490565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000828210156105275761052761043c565b500390565b60008261053b5761053b6104a3565b500690565b600082198211156105535761055361043c565b500190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fdfea164736f6c634300080f000a",
}
// L1BlockNumberABI is the input ABI used to generate the binding from.
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -31,7 +31,7 @@ var (
// LegacyMessagePasserMetaData contains all meta data concerning the LegacyMessagePasser contract.
var LegacyMessagePasserMetaData = &bind.MetaData{
ABI: "[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"_message\",\"type\":\"bytes\"}],\"name\":\"passMessageToL1\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"sentMessages\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"version\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]",
Bin: "0x60e060405234801561001057600080fd5b5060016080819052600060a081905260c081905280610698610048823960006101050152600060dc0152600060b301526106986000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c806354fd4d501461004657806382e3702d14610064578063cafa81dc14610097575b600080fd5b61004e6100ac565b60405161005b9190610347565b60405180910390f35b610087610072366004610398565b60006020819052908152604090205460ff1681565b604051901515815260200161005b565b6100aa6100a53660046103e0565b61014f565b005b60606100d77f00000000000000000000000000000000000000000000000000000000000000006101da565b6101007f00000000000000000000000000000000000000000000000000000000000000006101da565b6101297f00000000000000000000000000000000000000000000000000000000000000006101da565b60405160200161013b939291906104af565b604051602081830303815290604052905090565b60016000808333604051602001610167929190610525565b604080518083037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe001815291815281516020928301208352908201929092520160002080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001691151591909117905550565b60608160000361021d57505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b811561024757806102318161059e565b91506102409050600a83610605565b9150610221565b60008167ffffffffffffffff811115610262576102626103b1565b6040519080825280601f01601f19166020018201604052801561028c576020820181803683370190505b5090505b841561030f576102a1600183610619565b91506102ae600a86610630565b6102b9906030610644565b60f81b8183815181106102ce576102ce61065c565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350610308600a86610605565b9450610290565b949350505050565b60005b8381101561033257818101518382015260200161031a565b83811115610341576000848401525b50505050565b6020815260008251806020840152610366816040850160208701610317565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b6000602082840312156103aa57600080fd5b5035919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000602082840312156103f257600080fd5b813567ffffffffffffffff8082111561040a57600080fd5b818401915084601f83011261041e57600080fd5b813581811115610430576104306103b1565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908382118183101715610476576104766103b1565b8160405282815287602084870101111561048f57600080fd5b826020860160208301376000928101602001929092525095945050505050565b600084516104c1818460208901610317565b80830190507f2e0000000000000000000000000000000000000000000000000000000000000080825285516104fd816001850160208a01610317565b60019201918201528351610518816002840160208801610317565b0160020195945050505050565b60008351610537818460208801610317565b60609390931b7fffffffffffffffffffffffffffffffffffffffff000000000000000000000000169190920190815260140192915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036105cf576105cf61056f565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600082610614576106146105d6565b500490565b60008282101561062b5761062b61056f565b500390565b60008261063f5761063f6105d6565b500690565b600082198211156106575761065761056f565b500190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fdfea164736f6c634300080f000a",
Bin: "0x60e060405234801561001057600080fd5b5060016080819052600060a081905260c082905281610698610048833960006101050152600060dc0152600060b301526106986000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c806354fd4d501461004657806382e3702d14610064578063cafa81dc14610097575b600080fd5b61004e6100ac565b60405161005b9190610347565b60405180910390f35b610087610072366004610398565b60006020819052908152604090205460ff1681565b604051901515815260200161005b565b6100aa6100a53660046103e0565b61014f565b005b60606100d77f00000000000000000000000000000000000000000000000000000000000000006101da565b6101007f00000000000000000000000000000000000000000000000000000000000000006101da565b6101297f00000000000000000000000000000000000000000000000000000000000000006101da565b60405160200161013b939291906104af565b604051602081830303815290604052905090565b60016000808333604051602001610167929190610525565b604080518083037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe001815291815281516020928301208352908201929092520160002080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001691151591909117905550565b60608160000361021d57505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b811561024757806102318161059e565b91506102409050600a83610605565b9150610221565b60008167ffffffffffffffff811115610262576102626103b1565b6040519080825280601f01601f19166020018201604052801561028c576020820181803683370190505b5090505b841561030f576102a1600183610619565b91506102ae600a86610630565b6102b9906030610644565b60f81b8183815181106102ce576102ce61065c565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350610308600a86610605565b9450610290565b949350505050565b60005b8381101561033257818101518382015260200161031a565b83811115610341576000848401525b50505050565b6020815260008251806020840152610366816040850160208701610317565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b6000602082840312156103aa57600080fd5b5035919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000602082840312156103f257600080fd5b813567ffffffffffffffff8082111561040a57600080fd5b818401915084601f83011261041e57600080fd5b813581811115610430576104306103b1565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908382118183101715610476576104766103b1565b8160405282815287602084870101111561048f57600080fd5b826020860160208301376000928101602001929092525095945050505050565b600084516104c1818460208901610317565b80830190507f2e0000000000000000000000000000000000000000000000000000000000000080825285516104fd816001850160208a01610317565b60019201918201528351610518816002840160208801610317565b0160020195945050505050565b60008351610537818460208801610317565b60609390931b7fffffffffffffffffffffffffffffffffffffffff000000000000000000000000169190920190815260140192915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036105cf576105cf61056f565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600082610614576106146105d6565b500490565b60008282101561062b5761062b61056f565b500390565b60008261063f5761063f6105d6565b500690565b600082198211156106575761065761056f565b500190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fdfea164736f6c634300080f000a",
}
// LegacyMessagePasserABI is the input ABI used to generate the binding from.
......
This diff is collapsed.
......@@ -4,23 +4,19 @@ pragma solidity 0.8.15;
import { Semver } from "../universal/Semver.sol";
import { FeeVault } from "../universal/FeeVault.sol";
/**
* @custom:proxied
* @custom:predeploy 0x4200000000000000000000000000000000000019
* @title BaseFeeVault
* @notice The BaseFeeVault accumulates the base fee that is paid by transactions.
*/
/// @custom:proxied
/// @custom:predeploy 0x4200000000000000000000000000000000000019
/// @title BaseFeeVault
/// @notice The BaseFeeVault accumulates the base fee that is paid by transactions.
contract BaseFeeVault is FeeVault, Semver {
/**
* @custom:semver 1.2.0
*
* @param _recipient Wallet that will receive the fees.
* @param _minWithdrawalAmount Minimum balance for withdrawals.
* @param _withdrawalNetwork Network which the recipient will receive fees on.
*/
/// @custom:semver 1.2.1
/// @notice Constructs the BaseFeeVault contract.
/// @param _recipient Wallet that will receive the fees.
/// @param _minWithdrawalAmount Minimum balance for withdrawals.
/// @param _withdrawalNetwork Network which the recipient will receive fees on.
constructor(
address _recipient,
uint256 _minWithdrawalAmount,
WithdrawalNetwork _withdrawalNetwork
) FeeVault(_recipient, _minWithdrawalAmount, _withdrawalNetwork) Semver(1, 2, 0) {}
) FeeVault(_recipient, _minWithdrawalAmount, _withdrawalNetwork) Semver(1, 2, 1) {}
}
......@@ -4,18 +4,14 @@ pragma solidity ^0.8.0;
import { Ownable } from "@openzeppelin/contracts/access/Ownable.sol";
import { AddressAliasHelper } from "../vendor/AddressAliasHelper.sol";
/**
* @title CrossDomainOwnable
* @notice This contract extends the OpenZeppelin `Ownable` contract for L2 contracts to be owned
* by contracts on L1. Note that this contract is only safe to be used if the
* CrossDomainMessenger system is bypassed and the caller on L1 is calling the
* OptimismPortal directly.
*/
/// @title CrossDomainOwnable
/// @notice This contract extends the OpenZeppelin `Ownable` contract for L2 contracts to be owned
/// by contracts on L1. Note that this contract is only safe to be used if the
/// CrossDomainMessenger system is bypassed and the caller on L1 is calling the
/// OptimismPortal directly.
abstract contract CrossDomainOwnable is Ownable {
/**
* @notice Overrides the implementation of the `onlyOwner` modifier to check that the unaliased
* `msg.sender` is the owner of the contract.
*/
/// @notice Overrides the implementation of the `onlyOwner` modifier to check that the unaliased
/// `msg.sender` is the owner of the contract.
function _checkOwner() internal view override {
require(
owner() == AddressAliasHelper.undoL1ToL2Alias(msg.sender),
......
......@@ -5,19 +5,15 @@ import { Predeploys } from "../libraries/Predeploys.sol";
import { L2CrossDomainMessenger } from "./L2CrossDomainMessenger.sol";
import { Ownable } from "@openzeppelin/contracts/access/Ownable.sol";
/**
* @title CrossDomainOwnable2
* @notice This contract extends the OpenZeppelin `Ownable` contract for L2 contracts to be owned
* by contracts on L1. Note that this contract is meant to be used with systems that use
* the CrossDomainMessenger system. It will not work if the OptimismPortal is used
* directly.
*/
/// @title CrossDomainOwnable2
/// @notice This contract extends the OpenZeppelin `Ownable` contract for L2 contracts to be owned
/// by contracts on L1. Note that this contract is meant to be used with systems that use
/// the CrossDomainMessenger system. It will not work if the OptimismPortal is used
/// directly.
abstract contract CrossDomainOwnable2 is Ownable {
/**
* @notice Overrides the implementation of the `onlyOwner` modifier to check that the unaliased
* `xDomainMessageSender` is the owner of the contract. This value is set to the caller
* of the L1CrossDomainMessenger.
*/
/// @notice Overrides the implementation of the `onlyOwner` modifier to check that the unaliased
/// `xDomainMessageSender` is the owner of the contract. This value is set to the caller
/// of the L1CrossDomainMessenger.
function _checkOwner() internal view override {
L2CrossDomainMessenger messenger = L2CrossDomainMessenger(
Predeploys.L2_CROSS_DOMAIN_MESSENGER
......
......@@ -5,35 +5,30 @@ import { Predeploys } from "../libraries/Predeploys.sol";
import { L2CrossDomainMessenger } from "./L2CrossDomainMessenger.sol";
import { Ownable } from "@openzeppelin/contracts/access/Ownable.sol";
/**
* @title CrossDomainOwnable3
* @notice This contract extends the OpenZeppelin `Ownable` contract for L2 contracts to be owned
* by contracts on either L1 or L2. Note that this contract is meant to be used with systems
* that use the CrossDomainMessenger system. It will not work if the OptimismPortal is
* used directly.
*/
/// @title CrossDomainOwnable3
/// @notice This contract extends the OpenZeppelin `Ownable` contract for L2 contracts to be owned
/// by contracts on either L1 or L2. Note that this contract is meant to be used with
/// systems that use the CrossDomainMessenger system. It will not work if the
/// OptimismPortal is used directly.
abstract contract CrossDomainOwnable3 is Ownable {
/**
* @notice If true, the contract uses the cross domain _checkOwner function override. If false
* it uses the standard Ownable _checkOwner function.
*/
/// @notice If true, the contract uses the cross domain _checkOwner function override.
/// If false it uses the standard Ownable _checkOwner function.
bool public isLocal = true;
/**
* @notice Emits when ownership of the contract is transferred. Includes the
* isLocal field in addition to the standard `Ownable` OwnershipTransferred event.
*/
/// @notice Emits when ownership of the contract is transferred. Includes the
/// isLocal field in addition to the standard `Ownable` OwnershipTransferred event.
/// @param previousOwner The previous owner of the contract.
/// @param newOwner The new owner of the contract.
/// @param isLocal Configures the `isLocal` contract variable.
event OwnershipTransferred(
address indexed previousOwner,
address indexed newOwner,
bool isLocal
);
/**
* @notice Allows for ownership to be transferred with specifying the locality.
* @param _owner The new owner of the contract.
* @param _isLocal Configures the locality of the ownership.
*/
/// @notice Allows for ownership to be transferred with specifying the locality.
/// @param _owner The new owner of the contract.
/// @param _isLocal Configures the locality of the ownership.
function transferOwnership(address _owner, bool _isLocal) external onlyOwner {
require(_owner != address(0), "CrossDomainOwnable3: new owner is the zero address");
......@@ -44,11 +39,9 @@ abstract contract CrossDomainOwnable3 is Ownable {
emit OwnershipTransferred(oldOwner, _owner, _isLocal);
}
/**
* @notice Overrides the implementation of the `onlyOwner` modifier to check that the unaliased
* `xDomainMessageSender` is the owner of the contract. This value is set to the caller
* of the L1CrossDomainMessenger.
*/
/// @notice Overrides the implementation of the `onlyOwner` modifier to check that the unaliased
/// `xDomainMessageSender` is the owner of the contract. This value is set to the caller
/// of the L1CrossDomainMessenger.
function _checkOwner() internal view override {
if (isLocal) {
require(owner() == msg.sender, "CrossDomainOwnable3: caller is not the owner");
......
......@@ -5,41 +5,32 @@ import { Semver } from "../universal/Semver.sol";
import { Predeploys } from "../libraries/Predeploys.sol";
import { L1Block } from "../L2/L1Block.sol";
/**
* @custom:proxied
* @custom:predeploy 0x420000000000000000000000000000000000000F
* @title GasPriceOracle
* @notice This contract maintains the variables responsible for computing the L1 portion of the
* total fee charged on L2. Before Bedrock, this contract held variables in state that were
* read during the state transition function to compute the L1 portion of the transaction
* fee. After Bedrock, this contract now simply proxies the L1Block contract, which has
* the values used to compute the L1 portion of the fee in its state.
*
* The contract exposes an API that is useful for knowing how large the L1 portion of the
* transaction fee will be. The following events were deprecated with Bedrock:
* - event OverheadUpdated(uint256 overhead);
* - event ScalarUpdated(uint256 scalar);
* - event DecimalsUpdated(uint256 decimals);
*/
/// @custom:proxied
/// @custom:predeploy 0x420000000000000000000000000000000000000F
/// @title GasPriceOracle
/// @notice This contract maintains the variables responsible for computing the L1 portion of the
/// total fee charged on L2. Before Bedrock, this contract held variables in state that were
/// read during the state transition function to compute the L1 portion of the transaction
/// fee. After Bedrock, this contract now simply proxies the L1Block contract, which has
/// the values used to compute the L1 portion of the fee in its state.
///
/// The contract exposes an API that is useful for knowing how large the L1 portion of the
/// transaction fee will be. The following events were deprecated with Bedrock:
/// - event OverheadUpdated(uint256 overhead);
/// - event ScalarUpdated(uint256 scalar);
/// - event DecimalsUpdated(uint256 decimals);
contract GasPriceOracle is Semver {
/**
* @notice Number of decimals used in the scalar.
*/
/// @notice Number of decimals used in the scalar.
uint256 public constant DECIMALS = 6;
/**
* @custom:semver 1.0.0
*/
constructor() Semver(1, 0, 0) {}
/// @custom:semver 1.0.1
/// @notice Constructs the GasPriceOracle contract.
constructor() Semver(1, 0, 1) {}
/**
* @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
*/
/// @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) {
uint256 l1GasUsed = getL1GasUsed(_data);
uint256 l1Fee = l1GasUsed * l1BaseFee();
......@@ -49,71 +40,49 @@ contract GasPriceOracle is Semver {
return scaled;
}
/**
* @notice Retrieves the current gas price (base fee).
*
* @return Current L2 gas price (base fee).
*/
/// @notice Retrieves the current gas price (base fee).
/// @return Current L2 gas price (base fee).
function gasPrice() public view returns (uint256) {
return block.basefee;
}
/**
* @notice Retrieves the current base fee.
*
* @return Current L2 base fee.
*/
/// @notice Retrieves the current base fee.
/// @return Current L2 base fee.
function baseFee() public view returns (uint256) {
return block.basefee;
}
/**
* @notice Retrieves the current fee overhead.
*
* @return Current fee overhead.
*/
/// @notice Retrieves the current fee overhead.
/// @return Current fee overhead.
function overhead() public view returns (uint256) {
return L1Block(Predeploys.L1_BLOCK_ATTRIBUTES).l1FeeOverhead();
}
/**
* @notice Retrieves the current fee scalar.
*
* @return Current fee scalar.
*/
/// @notice Retrieves the current fee scalar.
/// @return Current fee scalar.
function scalar() public view returns (uint256) {
return L1Block(Predeploys.L1_BLOCK_ATTRIBUTES).l1FeeScalar();
}
/**
* @notice Retrieves the latest known L1 base fee.
*
* @return Latest known L1 base fee.
*/
/// @notice Retrieves the latest known L1 base fee.
/// @return Latest known L1 base fee.
function l1BaseFee() public view returns (uint256) {
return L1Block(Predeploys.L1_BLOCK_ATTRIBUTES).basefee();
}
/**
* @custom:legacy
* @notice Retrieves the number of decimals used in the scalar.
*
* @return Number of decimals used in the scalar.
*/
/// @custom:legacy
/// @notice Retrieves the number of decimals used in the scalar.
/// @return Number of decimals used in the scalar.
function decimals() public pure returns (uint256) {
return DECIMALS;
}
/**
* @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.
*/
/// @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) public view returns (uint256) {
uint256 total = 0;
uint256 length = _data.length;
......
......@@ -3,79 +3,54 @@ pragma solidity 0.8.15;
import { Semver } from "../universal/Semver.sol";
/**
* @custom:proxied
* @custom:predeploy 0x4200000000000000000000000000000000000015
* @title L1Block
* @notice The L1Block predeploy gives users access to information about the last known L1 block.
* Values within this contract are updated once per epoch (every L1 block) and can only be
* set by the "depositor" account, a special system address. Depositor account transactions
* are created by the protocol whenever we move to a new epoch.
*/
/// @custom:proxied
/// @custom:predeploy 0x4200000000000000000000000000000000000015
/// @title L1Block
/// @notice The L1Block predeploy gives users access to information about the last known L1 block.
/// Values within this contract are updated once per epoch (every L1 block) and can only be
/// set by the "depositor" account, a special system address. Depositor account transactions
/// are created by the protocol whenever we move to a new epoch.
contract L1Block is Semver {
/**
* @notice Address of the special depositor account.
*/
/// @notice Address of the special depositor account.
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;
/**
* @notice The latest L1 timestamp known by the L2 system.
*/
/// @notice The latest L1 timestamp known by the L2 system.
uint64 public timestamp;
/**
* @notice The latest L1 basefee.
*/
/// @notice The latest L1 basefee.
uint256 public basefee;
/**
* @notice The latest L1 blockhash.
*/
/// @notice The latest L1 blockhash.
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;
/**
* @notice The versioned hash to authenticate the batcher by.
*/
/// @notice The versioned hash to authenticate the batcher by.
bytes32 public batcherHash;
/**
* @notice The overhead value applied to the L1 portion of the transaction
* fee.
*/
/// @notice The overhead value applied to the L1 portion of the transaction fee.
uint256 public l1FeeOverhead;
/**
* @notice The scalar value applied to the L1 portion of the transaction fee.
*/
/// @notice The scalar value applied to the L1 portion of the transaction fee.
uint256 public l1FeeScalar;
/**
* @custom:semver 1.0.0
*/
constructor() Semver(1, 0, 0) {}
/// @custom:semver 1.0.1
/// @notice Constructs the L1Block contract.
constructor() Semver(1, 0, 1) {}
/**
* @notice Updates the L1 block values.
*
* @param _number L1 blocknumber.
* @param _timestamp L1 timestamp.
* @param _basefee L1 basefee.
* @param _hash L1 blockhash.
* @param _sequenceNumber Number of L2 blocks since epoch start.
* @param _batcherHash Versioned hash to authenticate batcher by.
* @param _l1FeeOverhead L1 fee overhead.
* @param _l1FeeScalar L1 fee scalar.
*/
/// @notice Updates the L1 block values.
/// @param _number L1 blocknumber.
/// @param _timestamp L1 timestamp.
/// @param _basefee L1 basefee.
/// @param _hash L1 blockhash.
/// @param _sequenceNumber Number of L2 blocks since epoch start.
/// @param _batcherHash Versioned hash to authenticate batcher by.
/// @param _l1FeeOverhead L1 fee overhead.
/// @param _l1FeeScalar L1 fee scalar.
function setL1BlockValues(
uint64 _number,
uint64 _timestamp,
......
......@@ -4,23 +4,19 @@ pragma solidity 0.8.15;
import { Semver } from "../universal/Semver.sol";
import { FeeVault } from "../universal/FeeVault.sol";
/**
* @custom:proxied
* @custom:predeploy 0x420000000000000000000000000000000000001A
* @title L1FeeVault
* @notice The L1FeeVault accumulates the L1 portion of the transaction fees.
*/
/// @custom:proxied
/// @custom:predeploy 0x420000000000000000000000000000000000001A
/// @title L1FeeVault
/// @notice The L1FeeVault accumulates the L1 portion of the transaction fees.
contract L1FeeVault is FeeVault, Semver {
/**
* @custom:semver 1.2.0
*
* @param _recipient Wallet that will receive the fees.
* @param _minWithdrawalAmount Minimum balance for withdrawals.
* @param _withdrawalNetwork Network which the recipient will receive fees on.
*/
/// @custom:semver 1.2.1
/// @notice Constructs the L1FeeVault contract.
/// @param _recipient Wallet that will receive the fees.
/// @param _minWithdrawalAmount Minimum balance for withdrawals.
/// @param _withdrawalNetwork Network which the recipient will receive fees on.
constructor(
address _recipient,
uint256 _minWithdrawalAmount,
WithdrawalNetwork _withdrawalNetwork
) FeeVault(_recipient, _minWithdrawalAmount, _withdrawalNetwork) Semver(1, 2, 0) {}
) FeeVault(_recipient, _minWithdrawalAmount, _withdrawalNetwork) Semver(1, 2, 1) {}
}
......@@ -7,47 +7,37 @@ import { CrossDomainMessenger } from "../universal/CrossDomainMessenger.sol";
import { Semver } from "../universal/Semver.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.
*/
/// @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, Semver {
/**
* @custom:semver 1.4.0
*
* @param _l1CrossDomainMessenger Address of the L1CrossDomainMessenger contract.
*/
/// @custom:semver 1.4.1
/// @notice Constructs the L2CrossDomainMessenger contract.
/// @param _l1CrossDomainMessenger Address of the L1CrossDomainMessenger contract.
constructor(address _l1CrossDomainMessenger)
Semver(1, 4, 0)
Semver(1, 4, 1)
CrossDomainMessenger(_l1CrossDomainMessenger)
{
initialize();
}
/**
* @notice Initializer.
*/
/// @notice Initializer.
function initialize() public initializer {
__CrossDomainMessenger_init();
}
/**
* @custom:legacy
* @notice Legacy getter for the remote messenger. Use otherMessenger going forward.
*
* @return Address of the L1CrossDomainMessenger contract.
*/
/// @custom:legacy
/// @notice Legacy getter for the remote messenger.
/// Use otherMessenger going forward.
/// @return Address of the L1CrossDomainMessenger contract.
function l1CrossDomainMessenger() public view returns (address) {
return OTHER_MESSENGER;
}
/**
* @inheritdoc CrossDomainMessenger
*/
/// @inheritdoc CrossDomainMessenger
function _sendMessage(
address _to,
uint64 _gasLimit,
......@@ -59,16 +49,12 @@ contract L2CrossDomainMessenger is CrossDomainMessenger, Semver {
}(_to, _gasLimit, _data);
}
/**
* @inheritdoc CrossDomainMessenger
*/
/// @inheritdoc CrossDomainMessenger
function _isOtherMessenger() internal view override returns (bool) {
return AddressAliasHelper.undoL1ToL2Alias(msg.sender) == OTHER_MESSENGER;
}
/**
* @inheritdoc CrossDomainMessenger
*/
/// @inheritdoc CrossDomainMessenger
function _isUnsafeTarget(address _target) internal view override returns (bool) {
return _target == address(this) || _target == address(Predeploys.L2_TO_L1_MESSAGE_PASSER);
}
......
......@@ -7,42 +7,35 @@ import { L1ERC721Bridge } from "../L1/L1ERC721Bridge.sol";
import { IOptimismMintableERC721 } from "../universal/IOptimismMintableERC721.sol";
import { Semver } from "../universal/Semver.sol";
/**
* @title L2ERC721Bridge
* @notice The L2 ERC721 bridge is a contract which works together with the L1 ERC721 bridge to
* make it possible to transfer ERC721 tokens from Ethereum to Optimism. This contract
* acts as a minter for new tokens when it hears about deposits into the L1 ERC721 bridge.
* This contract also acts as a burner for tokens being withdrawn.
* **WARNING**: Do not bridge an ERC721 that was originally deployed on Optimism. This
* bridge ONLY supports ERC721s originally deployed on Ethereum. Users will need to
* wait for the one-week challenge period to elapse before their Optimism-native NFT
* can be refunded on L2.
*/
/// @title L2ERC721Bridge
/// @notice The L2 ERC721 bridge is a contract which works together with the L1 ERC721 bridge to
/// make it possible to transfer ERC721 tokens from Ethereum to Optimism. This contract
/// acts as a minter for new tokens when it hears about deposits into the L1 ERC721 bridge.
/// This contract also acts as a burner for tokens being withdrawn.
/// **WARNING**: Do not bridge an ERC721 that was originally deployed on Optimism. This
/// bridge ONLY supports ERC721s originally deployed on Ethereum. Users will need to
/// wait for the one-week challenge period to elapse before their Optimism-native NFT
/// can be refunded on L2.
contract L2ERC721Bridge is ERC721Bridge, Semver {
/**
* @custom:semver 1.1.0
*
* @param _messenger Address of the CrossDomainMessenger on this network.
* @param _otherBridge Address of the ERC721 bridge on the other network.
*/
/// @custom:semver 1.1.1
/// @notice Constructs the L2ERC721Bridge contract.
/// @param _messenger Address of the CrossDomainMessenger on this network.
/// @param _otherBridge Address of the ERC721 bridge on the other network.
constructor(address _messenger, address _otherBridge)
Semver(1, 1, 0)
Semver(1, 1, 1)
ERC721Bridge(_messenger, _otherBridge)
{}
/**
* @notice Completes an ERC721 bridge from the other domain and sends the ERC721 token to the
* recipient on this domain.
*
* @param _localToken Address of the ERC721 token on this domain.
* @param _remoteToken Address of the ERC721 token on the other domain.
* @param _from Address that triggered the bridge on the other domain.
* @param _to Address to receive the token on this domain.
* @param _tokenId ID of the token being deposited.
* @param _extraData Optional data to forward to L1. Data supplied here will not be used to
* execute any code on L1 and is only emitted as extra data for the
* convenience of off-chain tooling.
*/
/// @notice Completes an ERC721 bridge from the other domain and sends the ERC721 token to the
/// recipient on this domain.
/// @param _localToken Address of the ERC721 token on this domain.
/// @param _remoteToken Address of the ERC721 token on the other domain.
/// @param _from Address that triggered the bridge on the other domain.
/// @param _to Address to receive the token on this domain.
/// @param _tokenId ID of the token being deposited.
/// @param _extraData Optional data to forward to L1.
/// Data supplied here will not be used to execute any code on L1 and is
/// only emitted as extra data for the convenience of off-chain tooling.
function finalizeBridgeERC721(
address _localToken,
address _remoteToken,
......@@ -73,9 +66,7 @@ contract L2ERC721Bridge is ERC721Bridge, Semver {
emit ERC721BridgeFinalized(_localToken, _remoteToken, _from, _to, _tokenId, _extraData);
}
/**
* @inheritdoc ERC721Bridge
*/
/// @inheritdoc ERC721Bridge
function _initiateBridgeERC721(
address _localToken,
address _remoteToken,
......
......@@ -7,46 +7,33 @@ import { Encoding } from "../libraries/Encoding.sol";
import { Burn } from "../libraries/Burn.sol";
import { Semver } from "../universal/Semver.sol";
/**
* @custom:proxied
* @custom:predeploy 0x4200000000000000000000000000000000000016
* @title L2ToL1MessagePasser
* @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.
*/
/// @custom:proxied
/// @custom:predeploy 0x4200000000000000000000000000000000000016
/// @title L2ToL1MessagePasser
/// @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 is Semver {
/**
* @notice The L1 gas limit set when eth is withdrawn using the receive() function.
*/
/// @notice The L1 gas limit set when eth is withdrawn using the receive() function.
uint256 internal constant RECEIVE_DEFAULT_GAS_LIMIT = 100_000;
/**
* @notice Current message version identifier.
*/
/// @notice The current message version identifier.
uint16 public constant MESSAGE_VERSION = 1;
/**
* @notice Includes the message hashes for all withdrawals
*/
/// @notice Includes the message hashes for all withdrawals
mapping(bytes32 => bool) public sentMessages;
/**
* @notice A unique value hashed with each withdrawal.
*/
/// @notice A unique value hashed with each withdrawal.
uint240 internal msgNonce;
/**
* @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 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.
* @param data The data to be forwarded to the target on L1.
* @param withdrawalHash The hash of the withdrawal.
*/
/// @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 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.
/// @param data The data to be forwarded to the target on L1.
/// @param withdrawalHash The hash of the withdrawal.
event MessagePassed(
uint256 indexed nonce,
address indexed sender,
......@@ -57,44 +44,33 @@ contract L2ToL1MessagePasser is Semver {
bytes32 withdrawalHash
);
/**
* @notice Emitted when the balance of this contract is burned.
*
* @param amount Amount of ETh that was burned.
*/
/// @notice Emitted when the balance of this contract is burned.
/// @param amount Amount of ETh that was burned.
event WithdrawerBalanceBurnt(uint256 indexed amount);
/**
* @custom:semver 1.0.0
*/
constructor() Semver(1, 0, 0) {}
/// @custom:semver 1.0.1
/// @notice Constructs the L2ToL1MessagePasser contract.
constructor() Semver(1, 0, 1) {}
/**
* @notice Allows users to withdraw ETH by sending directly to this contract.
*/
/// @notice Allows users to withdraw ETH by sending directly to this contract.
receive() external payable {
initiateWithdrawal(msg.sender, RECEIVE_DEFAULT_GAS_LIMIT, bytes(""));
}
/**
* @notice Removes all ETH held by this contract from the state. Used to prevent the amount of
* ETH on L2 inflating when ETH is withdrawn. Currently only way to do this is to
* create a contract and self-destruct it to itself. Anyone can call this function. Not
* incentivized since this function is very cheap.
*/
/// @notice Removes all ETH held by this contract from the state. Used to prevent the amount of
/// ETH on L2 inflating when ETH is withdrawn. Currently only way to do this is to
/// create a contract and self-destruct it to itself. Anyone can call this function. Not
/// incentivized since this function is very cheap.
function burn() external {
uint256 balance = address(this).balance;
Burn.eth(balance);
emit WithdrawerBalanceBurnt(balance);
}
/**
* @notice Sends a message from L2 to L1.
*
* @param _target Address to call on L1 execution.
* @param _gasLimit Minimum gas limit for executing the message on L1.
* @param _data Data to forward to L1 target.
*/
/// @notice Sends a message from L2 to L1.
/// @param _target Address to call on L1 execution.
/// @param _gasLimit Minimum gas limit for executing the message on L1.
/// @param _data Data to forward to L1 target.
function initiateWithdrawal(
address _target,
uint256 _gasLimit,
......@@ -128,13 +104,10 @@ contract L2ToL1MessagePasser is Semver {
}
}
/**
* @notice Retrieves the next message nonce. Message version will be added to the upper two
* bytes of the message nonce. Message version allows us to treat messages as having
* different structures.
*
* @return Nonce of the next message to be sent, with added message version.
*/
/// @notice Retrieves the next message nonce. Message version will be added to the upper two
/// bytes of the message nonce. Message version allows us to treat messages as having
/// different structures.
/// @return Nonce of the next message to be sent, with added message version.
function messageNonce() public view returns (uint256) {
return Encoding.encodeVersionedNonce(msgNonce, MESSAGE_VERSION);
}
......
......@@ -4,33 +4,26 @@ pragma solidity 0.8.15;
import { Semver } from "../universal/Semver.sol";
import { FeeVault } from "../universal/FeeVault.sol";
/**
* @custom:proxied
* @custom:predeploy 0x4200000000000000000000000000000000000011
* @title SequencerFeeVault
* @notice The SequencerFeeVault is the contract that holds any fees paid to the Sequencer during
* transaction processing and block production.
*/
/// @custom:proxied
/// @custom:predeploy 0x4200000000000000000000000000000000000011
/// @title SequencerFeeVault
/// @notice The SequencerFeeVault is the contract that holds any fees paid to the Sequencer during
/// transaction processing and block production.
contract SequencerFeeVault is FeeVault, Semver {
/**
* @custom:semver 1.2.0
*
* @param _recipient Wallet that will receive the fees.
* @param _minWithdrawalAmount Minimum balance for withdrawals.
* @param _withdrawalNetwork Network which the recipient will receive fees on.
*/
/// @custom:semver 1.2.1
/// @notice Constructs the SequencerFeeVault contract.
/// @param _recipient Wallet that will receive the fees.
/// @param _minWithdrawalAmount Minimum balance for withdrawals.
/// @param _withdrawalNetwork Network which the recipient will receive fees on.
constructor(
address _recipient,
uint256 _minWithdrawalAmount,
WithdrawalNetwork _withdrawalNetwork
) FeeVault(_recipient, _minWithdrawalAmount, _withdrawalNetwork) Semver(1, 2, 0) {}
) FeeVault(_recipient, _minWithdrawalAmount, _withdrawalNetwork) Semver(1, 2, 1) {}
/**
* @custom:legacy
* @notice Legacy getter for the recipient address.
*
* @return The recipient address.
*/
/// @custom:legacy
/// @notice Legacy getter for the recipient address.
/// @return The recipient address.
function l1FeeWallet() public view returns (address) {
return RECIPIENT;
}
......
......@@ -6,34 +6,27 @@ import "@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol";
import "@openzeppelin/contracts/token/ERC20/extensions/ERC20Votes.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
/**
* @custom:predeploy 0x4200000000000000000000000000000000000042
* @title GovernanceToken
* @notice The Optimism token used in governance and supporting voting and delegation. Implements
* EIP 2612 allowing signed approvals. Contract is "owned" by a `MintManager` instance with
* permission to the `mint` function only, for the purposes of enforcing the token inflation
* schedule.
*/
/// @custom:predeploy 0x4200000000000000000000000000000000000042
/// @title GovernanceToken
/// @notice The Optimism token used in governance and supporting voting and delegation. Implements
/// EIP 2612 allowing signed approvals. Contract is "owned" by a `MintManager` instance with
/// permission to the `mint` function only, for the purposes of enforcing the token
/// inflation schedule.
contract GovernanceToken is ERC20Burnable, ERC20Votes, Ownable {
/// @notice Constructs the GovernanceToken contract.
constructor() ERC20("Optimism", "OP") ERC20Permit("Optimism") {}
/**
* @notice Allows the owner to mint tokens.
*
* @param _account The account receiving minted tokens.
* @param _amount The amount of tokens to mint.
*/
/// @notice Allows the owner to mint tokens.
/// @param _account The account receiving minted tokens.
/// @param _amount The amount of tokens to mint.
function mint(address _account, uint256 _amount) public onlyOwner {
_mint(_account, _amount);
}
/**
* @notice Callback called after a token transfer.
*
* @param from The account sending tokens.
* @param to The account receiving tokens.
* @param amount The amount of tokens being transfered.
*/
/// @notice Callback called after a token transfer.
/// @param from The account sending tokens.
/// @param to The account receiving tokens.
/// @param amount The amount of tokens being transfered.
function _afterTokenTransfer(
address from,
address to,
......@@ -42,22 +35,16 @@ contract GovernanceToken is ERC20Burnable, ERC20Votes, Ownable {
super._afterTokenTransfer(from, to, amount);
}
/**
* @notice Internal mint function.
*
* @param to The account receiving minted tokens.
* @param amount The amount of tokens to mint.
*/
/// @notice Internal mint function.
/// @param to The account receiving minted tokens.
/// @param amount The amount of tokens to mint.
function _mint(address to, uint256 amount) internal override(ERC20, ERC20Votes) {
super._mint(to, amount);
}
/**
* @notice Internal burn function.
*
* @param account The account that tokens will be burned from.
* @param amount The amount of tokens that will be burned.
*/
/// @notice Internal burn function.
/// @param account The account that tokens will be burned from.
/// @param amount The amount of tokens that will be burned.
function _burn(address account, uint256 amount) internal override(ERC20, ERC20Votes) {
super._burn(account, amount);
}
......
......@@ -4,57 +4,41 @@ pragma solidity 0.8.15;
import "@openzeppelin/contracts/access/Ownable.sol";
import "./GovernanceToken.sol";
/**
* @title MintManager
* @notice Set as `owner` of the OP token and responsible for the token inflation schedule.
* Contract acts as the token "mint manager" with permission to the `mint` function only.
* Currently permitted to mint once per year of up to 2% of the total token supply.
* Upgradable to allow changes in the inflation schedule.
*/
/// @title MintManager
/// @notice Set as `owner` of the governance token and responsible for the token inflation
/// schedule. Contract acts as the token "mint manager" with permission to the `mint`
/// function only. Currently permitted to mint once per year of up to 2% of the total
/// token supply. Upgradable to allow changes in the inflation schedule.
contract MintManager is Ownable {
/**
* @notice The GovernanceToken that the MintManager can mint tokens
*/
/// @notice The GovernanceToken that the MintManager can mint tokens
GovernanceToken public immutable governanceToken;
/**
* @notice The amount of tokens that can be minted per year. The value is a fixed
* point number with 4 decimals.
*/
/// @notice The amount of tokens that can be minted per year.
/// The value is a fixed point number with 4 decimals.
uint256 public constant MINT_CAP = 20; // 2%
/**
* @notice The number of decimals for the MINT_CAP.
*/
/// @notice The number of decimals for the MINT_CAP.
uint256 public constant DENOMINATOR = 1000;
/**
* @notice The amount of time that must pass before the MINT_CAP number of tokens can
* be minted again.
*/
/// @notice The amount of time that must pass before the MINT_CAP number of tokens can
/// be minted again.
uint256 public constant MINT_PERIOD = 365 days;
/**
* @notice Tracks the time of last mint.
*/
/// @notice Tracks the time of last mint.
uint256 public mintPermittedAfter;
/**
* @param _upgrader The owner of this contract
* @param _governanceToken The governance token this contract can mint
* tokens of
*/
/// @notice Constructs the MintManager contract.
/// @param _upgrader The owner of this contract.
/// @param _governanceToken The governance token this contract can mint tokens of.
constructor(address _upgrader, address _governanceToken) {
transferOwnership(_upgrader);
governanceToken = GovernanceToken(_governanceToken);
}
/**
* @notice Only the token owner is allowed to mint a certain amount of OP per year.
*
* @param _account Address to mint new tokens to.
* @param _amount Amount of tokens to be minted.
*/
/// @notice Only the token owner is allowed to mint a certain amount of the
/// governance token per year.
/// @param _account The account receiving minted tokens.
/// @param _amount The amount of tokens to mint.
function mint(address _account, uint256 _amount) public onlyOwner {
if (mintPermittedAfter > 0) {
require(
......@@ -72,11 +56,8 @@ contract MintManager is Ownable {
governanceToken.mint(_account, _amount);
}
/**
* @notice Upgrade the owner of the governance token to a new MintManager.
*
* @param _newMintManager The MintManager to upgrade to.
*/
/// @notice Upgrade the owner of the governance token to a new MintManager.
/// @param _newMintManager The MintManager to upgrade to.
function upgrade(address _newMintManager) public onlyOwner {
require(
_newMintManager != address(0),
......
......@@ -3,35 +3,25 @@ pragma solidity 0.8.15;
import { Ownable } from "@openzeppelin/contracts/access/Ownable.sol";
/**
* @custom:legacy
* @title AddressManager
* @notice AddressManager is a legacy contract that was used in the old version of the Optimism
* system to manage a registry of string names to addresses. We now use a more standard
* proxy system instead, but this contract is still necessary for backwards compatibility
* with several older contracts.
*/
/// @custom:legacy
/// @title AddressManager
/// @notice AddressManager is a legacy contract that was used in the old version of the Optimism
/// system to manage a registry of string names to addresses. We now use a more standard
/// proxy system instead, but this contract is still necessary for backwards compatibility
/// with several older contracts.
contract AddressManager is Ownable {
/**
* @notice Mapping of the hashes of string names to addresses.
*/
/// @notice Mapping of the hashes of string names to addresses.
mapping(bytes32 => address) private addresses;
/**
* @notice Emitted when an address is modified in the registry.
*
* @param name String name being set in the registry.
* @param newAddress Address set for the given name.
* @param oldAddress Address that was previously set for the given name.
*/
/// @notice Emitted when an address is modified in the registry.
/// @param name String name being set in the registry.
/// @param newAddress Address set for the given name.
/// @param oldAddress Address that was previously set for the given name.
event AddressSet(string indexed name, address newAddress, address oldAddress);
/**
* @notice Changes the address associated with a particular name.
*
* @param _name String name to associate an address with.
* @param _address Address to associate with the name.
*/
/// @notice Changes the address associated with a particular name.
/// @param _name String name to associate an address with.
/// @param _address Address to associate with the name.
function setAddress(string memory _name, address _address) external onlyOwner {
bytes32 nameHash = _getNameHash(_name);
address oldAddress = addresses[nameHash];
......@@ -40,24 +30,16 @@ contract AddressManager is Ownable {
emit AddressSet(_name, _address, oldAddress);
}
/**
* @notice Retrieves the address associated with a given name.
*
* @param _name Name to retrieve an address for.
*
* @return Address associated with the given name.
*/
/// @notice Retrieves the address associated with a given name.
/// @param _name Name to retrieve an address for.
/// @return Address associated with the given name.
function getAddress(string memory _name) external view returns (address) {
return addresses[_getNameHash(_name)];
}
/**
* @notice Computes the hash of a name.
*
* @param _name Name to compute a hash for.
*
* @return Hash of the given name.
*/
/// @notice Computes the hash of a name.
/// @param _name Name to compute a hash for.
/// @return Hash of the given name.
function _getNameHash(string memory _name) internal pure returns (bytes32) {
return keccak256(abi.encodePacked(_name));
}
......
......@@ -3,55 +3,38 @@ pragma solidity 0.8.15;
import { Semver } from "../universal/Semver.sol";
/**
* @custom:legacy
* @custom:proxied
* @custom:predeployed 0x4200000000000000000000000000000000000002
* @title DeployerWhitelist
* @notice DeployerWhitelist is a legacy contract that was originally used to act as a whitelist of
* addresses allowed to the Optimism network. The DeployerWhitelist has since been
* disabled, but the code is kept in state for the sake of full backwards compatibility.
* As of the Bedrock upgrade, the DeployerWhitelist is completely unused by the Optimism
* system and could, in theory, be removed entirely.
*/
/// @custom:legacy
/// @custom:proxied
/// @custom:predeployed 0x4200000000000000000000000000000000000002
/// @title DeployerWhitelist
/// @notice DeployerWhitelist is a legacy contract that was originally used to act as a whitelist of
/// addresses allowed to the Optimism network. The DeployerWhitelist has since been
/// disabled, but the code is kept in state for the sake of full backwards compatibility.
/// As of the Bedrock upgrade, the DeployerWhitelist is completely unused by the Optimism
/// system and could, in theory, be removed entirely.
contract DeployerWhitelist is Semver {
/**
* @notice Address of the owner of this contract. Note that when this address is set to
* address(0), the whitelist is disabled.
*/
/// @notice Address of the owner of this contract. Note that when this address is set to
/// address(0), the whitelist is disabled.
address public owner;
/**
* @notice Mapping of deployer addresses to boolean whitelist status.
*/
/// @notice Mapping of deployer addresses to boolean whitelist status.
mapping(address => bool) public whitelist;
/**
* @notice Emitted when the owner of this contract changes.
*
* @param oldOwner Address of the previous owner.
* @param newOwner Address of the new owner.
*/
/// @notice Emitted when the owner of this contract changes.
/// @param oldOwner Address of the previous owner.
/// @param newOwner Address of the new owner.
event OwnerChanged(address oldOwner, address newOwner);
/**
* @notice Emitted when the whitelist status of a deployer changes.
*
* @param deployer Address of the deployer.
* @param whitelisted Boolean indicating whether the deployer is whitelisted.
*/
/// @notice Emitted when the whitelist status of a deployer changes.
/// @param deployer Address of the deployer.
/// @param whitelisted Boolean indicating whether the deployer is whitelisted.
event WhitelistStatusChanged(address deployer, bool whitelisted);
/**
* @notice Emitted when the whitelist is disabled.
*
* @param oldOwner Address of the final owner of the whitelist.
*/
/// @notice Emitted when the whitelist is disabled.
/// @param oldOwner Address of the final owner of the whitelist.
event WhitelistDisabled(address oldOwner);
/**
* @notice Blocks functions to anyone except the contract owner.
*/
/// @notice Blocks functions to anyone except the contract owner.
modifier onlyOwner() {
require(
msg.sender == owner,
......@@ -60,27 +43,19 @@ contract DeployerWhitelist is Semver {
_;
}
/**
* @custom:semver 1.0.0
*/
constructor() Semver(1, 0, 0) {}
/// @custom:semver 1.0.1
constructor() Semver(1, 0, 1) {}
/**
* @notice Adds or removes an address from the deployment whitelist.
*
* @param _deployer Address to update permissions for.
* @param _isWhitelisted Whether or not the address is whitelisted.
*/
/// @notice Adds or removes an address from the deployment whitelist.
/// @param _deployer Address to update permissions for.
/// @param _isWhitelisted Whether or not the address is whitelisted.
function setWhitelistedDeployer(address _deployer, bool _isWhitelisted) external onlyOwner {
whitelist[_deployer] = _isWhitelisted;
emit WhitelistStatusChanged(_deployer, _isWhitelisted);
}
/**
* @notice Updates the owner of this contract.
*
* @param _owner Address of the new owner.
*/
/// @notice Updates the owner of this contract.
/// @param _owner Address of the new owner.
function setOwner(address _owner) external onlyOwner {
// Prevent users from setting the whitelist owner to address(0) except via
// enableArbitraryContractDeployment. If you want to burn the whitelist owner, send it to
......@@ -94,21 +69,15 @@ contract DeployerWhitelist is Semver {
owner = _owner;
}
/**
* @notice Permanently enables arbitrary contract deployment and deletes the owner.
*/
/// @notice Permanently enables arbitrary contract deployment and deletes the owner.
function enableArbitraryContractDeployment() external onlyOwner {
emit WhitelistDisabled(owner);
owner = address(0);
}
/**
* @notice Checks whether an address is allowed to deploy contracts.
*
* @param _deployer Address to check.
*
* @return Whether or not the address can deploy contracts.
*/
/// @notice Checks whether an address is allowed to deploy contracts.
/// @param _deployer Address to check.
/// @return Whether or not the address can deploy contracts.
function isDeployerAllowed(address _deployer) external view returns (bool) {
return (owner == address(0) || whitelist[_deployer]);
}
......
......@@ -5,25 +5,19 @@ import { L1Block } from "../L2/L1Block.sol";
import { Predeploys } from "../libraries/Predeploys.sol";
import { Semver } from "../universal/Semver.sol";
/**
* @custom:legacy
* @custom:proxied
* @custom:predeploy 0x4200000000000000000000000000000000000013
* @title L1BlockNumber
* @notice L1BlockNumber is a legacy contract that fills the roll of the OVM_L1BlockNumber contract
* in the old version of the Optimism system. Only necessary for backwards compatibility.
* If you want to access the L1 block number going forward, you should use the L1Block
* contract instead.
*/
/// @custom:legacy
/// @custom:proxied
/// @custom:predeploy 0x4200000000000000000000000000000000000013
/// @title L1BlockNumber
/// @notice L1BlockNumber is a legacy contract that fills the roll of the OVM_L1BlockNumber contract
/// in the old version of the Optimism system. Only necessary for backwards compatibility.
/// If you want to access the L1 block number going forward, you should use the L1Block
/// contract instead.
contract L1BlockNumber is Semver {
/**
* @custom:semver 1.0.0
*/
constructor() Semver(1, 0, 0) {}
/// @custom:semver 1.0.1
constructor() Semver(1, 0, 1) {}
/**
* @notice Returns the L1 block number.
*/
/// @notice Returns the L1 block number.
receive() external payable {
uint256 l1BlockNumber = getL1BlockNumber();
assembly {
......@@ -32,9 +26,7 @@ contract L1BlockNumber is Semver {
}
}
/**
* @notice Returns the L1 block number.
*/
/// @notice Returns the L1 block number.
// solhint-disable-next-line no-complex-fallback
fallback() external payable {
uint256 l1BlockNumber = getL1BlockNumber();
......@@ -44,11 +36,8 @@ contract L1BlockNumber is Semver {
}
}
/**
* @notice Retrieves the latest L1 block number.
*
* @return Latest L1 block number.
*/
/// @notice Retrieves the latest L1 block number.
/// @return Latest L1 block number.
function getL1BlockNumber() public view returns (uint256) {
return L1Block(Predeploys.L1_BLOCK_ATTRIBUTES).number();
}
......
......@@ -4,73 +4,55 @@ pragma solidity 0.8.15;
import { Predeploys } from "../libraries/Predeploys.sol";
import { OptimismMintableERC20 } from "../universal/OptimismMintableERC20.sol";
/**
* @custom:legacy
* @custom:proxied
* @custom:predeploy 0xDeadDeAddeAddEAddeadDEaDDEAdDeaDDeAD0000
* @title LegacyERC20ETH
* @notice LegacyERC20ETH is a legacy contract that held ETH balances before the Bedrock upgrade.
* All ETH balances held within this contract were migrated to the state trie as part of
* the Bedrock upgrade. Functions within this contract that mutate state were already
* disabled as part of the EVM equivalence upgrade.
*/
/// @custom:legacy
/// @custom:proxied
/// @custom:predeploy 0xDeadDeAddeAddEAddeadDEaDDEAdDeaDDeAD0000
/// @title LegacyERC20ETH
/// @notice LegacyERC20ETH is a legacy contract that held ETH balances before the Bedrock upgrade.
/// All ETH balances held within this contract were migrated to the state trie as part of
/// the Bedrock upgrade. Functions within this contract that mutate state were already
/// disabled as part of the EVM equivalence upgrade.
contract LegacyERC20ETH is OptimismMintableERC20 {
/**
* @notice Initializes the contract as an Optimism Mintable ERC20.
*/
/// @notice Initializes the contract as an Optimism Mintable ERC20.
constructor()
OptimismMintableERC20(Predeploys.L2_STANDARD_BRIDGE, address(0), "Ether", "ETH")
{}
/**
* @notice Returns the ETH balance of the target account. Overrides the base behavior of the
* contract to preserve the invariant that the balance within this contract always
* matches the balance in the state trie.
*
* @param _who Address of the account to query.
*
* @return The ETH balance of the target account.
*/
/// @notice Returns the ETH balance of the target account. Overrides the base behavior of the
/// contract to preserve the invariant that the balance within this contract always
/// matches the balance in the state trie.
/// @param _who Address of the account to query.
/// @return The ETH balance of the target account.
function balanceOf(address _who) public view virtual override returns (uint256) {
return address(_who).balance;
}
/**
* @custom:blocked
* @notice Mints some amount of ETH.
*/
/// @custom:blocked
/// @notice Mints some amount of ETH.
function mint(address, uint256) public virtual override {
revert("LegacyERC20ETH: mint is disabled");
}
/**
* @custom:blocked
* @notice Burns some amount of ETH.
*/
/// @custom:blocked
/// @notice Burns some amount of ETH.
function burn(address, uint256) public virtual override {
revert("LegacyERC20ETH: burn is disabled");
}
/**
* @custom:blocked
* @notice Transfers some amount of ETH.
*/
/// @custom:blocked
/// @notice Transfers some amount of ETH.
function transfer(address, uint256) public virtual override returns (bool) {
revert("LegacyERC20ETH: transfer is disabled");
}
/**
* @custom:blocked
* @notice Approves a spender to spend some amount of ETH.
*/
/// @custom:blocked
/// @notice Approves a spender to spend some amount of ETH.
function approve(address, uint256) public virtual override returns (bool) {
revert("LegacyERC20ETH: approve is disabled");
}
/**
* @custom:blocked
* @notice Transfers funds from some sender account.
*/
/// @custom:blocked
/// @notice Transfers funds from some sender account.
function transferFrom(
address,
address,
......@@ -79,18 +61,14 @@ contract LegacyERC20ETH is OptimismMintableERC20 {
revert("LegacyERC20ETH: transferFrom is disabled");
}
/**
* @custom:blocked
* @notice Increases the allowance of a spender.
*/
/// @custom:blocked
/// @notice Increases the allowance of a spender.
function increaseAllowance(address, uint256) public virtual override returns (bool) {
revert("LegacyERC20ETH: increaseAllowance is disabled");
}
/**
* @custom:blocked
* @notice Decreases the allowance of a spender.
*/
/// @custom:blocked
/// @notice Decreases the allowance of a spender.
function decreaseAllowance(address, uint256) public virtual override returns (bool) {
revert("LegacyERC20ETH: decreaseAllowance is disabled");
}
......
......@@ -3,30 +3,21 @@ pragma solidity 0.8.15;
import { Semver } from "../universal/Semver.sol";
/**
* @custom:legacy
* @custom:proxied
* @custom:predeploy 0x4200000000000000000000000000000000000000
* @title LegacyMessagePasser
* @notice The LegacyMessagePasser was the low-level mechanism used to send messages from L2 to L1
* before the Bedrock upgrade. It is now deprecated in favor of the new MessagePasser.
*/
/// @custom:legacy
/// @custom:proxied
/// @custom:predeploy 0x4200000000000000000000000000000000000000
/// @title LegacyMessagePasser
/// @notice The LegacyMessagePasser was the low-level mechanism used to send messages from L2 to L1
/// before the Bedrock upgrade. It is now deprecated in favor of the new MessagePasser.
contract LegacyMessagePasser is Semver {
/**
* @notice Mapping of sent message hashes to boolean status.
*/
/// @notice Mapping of sent message hashes to boolean status.
mapping(bytes32 => bool) public sentMessages;
/**
* @custom:semver 1.0.0
*/
constructor() Semver(1, 0, 0) {}
/// @custom:semver 1.0.1
constructor() Semver(1, 0, 1) {}
/**
* @notice Passes a message to L1.
*
* @param _message Message to pass to L1.
*/
/// @notice Passes a message to L1.
/// @param _message Message to pass to L1.
function passMessageToL1(bytes memory _message) external {
sentMessages[keccak256(abi.encodePacked(_message, msg.sender))] = true;
}
......
......@@ -4,38 +4,26 @@ pragma solidity 0.8.15;
import { ERC20 } from "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import { ILegacyMintableERC20 } from "../universal/OptimismMintableERC20.sol";
/**
* @title LegacyMintableERC20
* @notice The legacy implementation of the OptimismMintableERC20. This
* contract is deprecated and should no longer be used.
*/
/// @title LegacyMintableERC20
/// @notice The legacy implementation of the OptimismMintableERC20. This
/// contract is deprecated and should no longer be used.
contract LegacyMintableERC20 is ILegacyMintableERC20, ERC20 {
/**
* @notice Emitted when the token is minted by the bridge.
*/
/// @notice Emitted when the token is minted by the bridge.
event Mint(address indexed _account, uint256 _amount);
/**
* @notice Emitted when a token is burned by the bridge.
*/
/// @notice Emitted when a token is burned by the bridge.
event Burn(address indexed _account, uint256 _amount);
/**
* @notice The token on the remote domain.
*/
/// @notice The token on the remote domain.
address public l1Token;
/**
* @notice The local bridge.
*/
/// @notice The local bridge.
address public l2Bridge;
/**
* @param _l2Bridge Address of the L2 standard bridge.
* @param _l1Token Address of the corresponding L1 token.
* @param _name ERC20 name.
* @param _symbol ERC20 symbol.
*/
/// @param _l2Bridge Address of the L2 standard bridge.
/// @param _l1Token Address of the corresponding L1 token.
/// @param _name ERC20 name.
/// @param _symbol ERC20 symbol.
constructor(
address _l2Bridge,
address _l1Token,
......@@ -46,17 +34,13 @@ contract LegacyMintableERC20 is ILegacyMintableERC20, ERC20 {
l2Bridge = _l2Bridge;
}
/**
* @notice Modifier that requires the contract was called by the bridge.
*/
/// @notice Modifier that requires the contract was called by the bridge.
modifier onlyL2Bridge() {
require(msg.sender == l2Bridge, "Only L2 Bridge can mint and burn");
_;
}
/**
* @notice EIP165 implementation.
*/
/// @notice EIP165 implementation.
function supportsInterface(bytes4 _interfaceId) public pure returns (bool) {
bytes4 firstSupportedInterface = bytes4(keccak256("supportsInterface(bytes4)")); // ERC165
bytes4 secondSupportedInterface = ILegacyMintableERC20.l1Token.selector ^
......@@ -65,22 +49,18 @@ contract LegacyMintableERC20 is ILegacyMintableERC20, ERC20 {
return _interfaceId == firstSupportedInterface || _interfaceId == secondSupportedInterface;
}
/**
* @notice Only the bridge can mint tokens.
* @param _to The account receiving tokens.
* @param _amount The amount of tokens to receive.
*/
/// @notice Only the bridge can mint tokens.
/// @param _to The account receiving tokens.
/// @param _amount The amount of tokens to receive.
function mint(address _to, uint256 _amount) public virtual onlyL2Bridge {
_mint(_to, _amount);
emit Mint(_to, _amount);
}
/**
* @notice Only the bridge can burn tokens.
* @param _from The account having tokens burnt.
* @param _amount The amount of tokens being burnt.
*/
/// @notice Only the bridge can burn tokens.
/// @param _from The account having tokens burnt.
/// @param _amount The amount of tokens being burnt.
function burn(address _from, uint256 _amount) public virtual onlyL2Bridge {
_burn(_from, _amount);
......
......@@ -3,43 +3,33 @@ pragma solidity 0.8.15;
import { AddressManager } from "./AddressManager.sol";
/**
* @custom:legacy
* @title ResolvedDelegateProxy
* @notice ResolvedDelegateProxy is a legacy proxy contract that makes use of the AddressManager to
* resolve the implementation address. We're maintaining this contract for backwards
* compatibility so we can manage all legacy proxies where necessary.
*/
/// @custom:legacy
/// @title ResolvedDelegateProxy
/// @notice ResolvedDelegateProxy is a legacy proxy contract that makes use of the AddressManager to
/// resolve the implementation address. We're maintaining this contract for backwards
/// compatibility so we can manage all legacy proxies where necessary.
contract ResolvedDelegateProxy {
/**
* @notice Mapping used to store the implementation name that corresponds to this contract. A
* mapping was originally used as a way to bypass the same issue normally solved by
* storing the implementation address in a specific storage slot that does not conflict
* with any other storage slot. Generally NOT a safe solution but works as long as the
* implementation does not also keep a mapping in the first storage slot.
*/
/// @notice Mapping used to store the implementation name that corresponds to this contract. A
/// mapping was originally used as a way to bypass the same issue normally solved by
/// storing the implementation address in a specific storage slot that does not conflict
/// with any other storage slot. Generally NOT a safe solution but works as long as the
/// implementation does not also keep a mapping in the first storage slot.
mapping(address => string) private implementationName;
/**
* @notice Mapping used to store the address of the AddressManager contract where the
* implementation address will be resolved from. Same concept here as with the above
* mapping. Also generally unsafe but fine if the implementation doesn't keep a mapping
* in the second storage slot.
*/
/// @notice Mapping used to store the address of the AddressManager contract where the
/// implementation address will be resolved from. Same concept here as with the above
/// mapping. Also generally unsafe but fine if the implementation doesn't keep a mapping
/// in the second storage slot.
mapping(address => AddressManager) private addressManager;
/**
* @param _addressManager Address of the AddressManager.
* @param _implementationName implementationName of the contract to proxy to.
*/
/// @param _addressManager Address of the AddressManager.
/// @param _implementationName implementationName of the contract to proxy to.
constructor(AddressManager _addressManager, string memory _implementationName) {
addressManager[address(this)] = _addressManager;
implementationName[address(this)] = _implementationName;
}
/**
* @notice Fallback, performs a delegatecall to the resolved implementation address.
*/
/// @notice Fallback, performs a delegatecall to the resolved implementation address.
// solhint-disable-next-line no-complex-fallback
fallback() external payable {
address target = addressManager[address(this)].getAddress(
......
......@@ -4,20 +4,14 @@ pragma solidity 0.8.15;
import { SignedMath } from "@openzeppelin/contracts/utils/math/SignedMath.sol";
import { FixedPointMathLib } from "@rari-capital/solmate/src/utils/FixedPointMathLib.sol";
/**
* @title Arithmetic
* @notice Even more math than before.
*/
/// @title Arithmetic
/// @notice Even more math than before.
library Arithmetic {
/**
* @notice Clamps a value between a minimum and maximum.
*
* @param _value The value to clamp.
* @param _min The minimum value.
* @param _max The maximum value.
*
* @return The clamped value.
*/
/// @notice Clamps a value between a minimum and maximum.
/// @param _value The value to clamp.
/// @param _min The minimum value.
/// @param _max The maximum value.
/// @return The clamped value.
function clamp(
int256 _value,
int256 _min,
......@@ -26,16 +20,12 @@ library Arithmetic {
return SignedMath.min(SignedMath.max(_value, _min), _max);
}
/**
* @notice (c)oefficient (d)enominator (exp)onentiation function.
* Returns the result of: c * (1 - 1/d)^exp.
*
* @param _coefficient Coefficient of the function.
* @param _denominator Fractional denominator.
* @param _exponent Power function exponent.
*
* @return Result of c * (1 - 1/d)^exp.
*/
/// @notice (c)oefficient (d)enominator (exp)onentiation function.
/// Returns the result of: c * (1 - 1/d)^exp.
/// @param _coefficient Coefficient of the function.
/// @param _denominator Fractional denominator.
/// @param _exponent Power function exponent.
/// @return Result of c * (1 - 1/d)^exp.
function cdexp(
int256 _coefficient,
int256 _denominator,
......
// SPDX-License-Identifier: MIT
pragma solidity 0.8.15;
/**
* @title Burn
* @notice Utilities for burning stuff.
*/
/// @title Burn
/// @notice Utilities for burning stuff.
library Burn {
/**
* Burns a given amount of ETH.
*
* @param _amount Amount of ETH to burn.
*/
/// @notice Burns a given amount of ETH.
/// @param _amount Amount of ETH to burn.
function eth(uint256 _amount) internal {
new Burner{ value: _amount }();
}
/**
* Burns a given amount of gas.
*
* @param _amount Amount of gas to burn.
*/
/// @notice Burns a given amount of gas.
/// @param _amount Amount of gas to burn.
function gas(uint256 _amount) internal view {
uint256 i = 0;
uint256 initialGas = gasleft();
......@@ -29,12 +21,10 @@ library Burn {
}
}
/**
* @title Burner
* @notice Burner self-destructs on creation and sends all ETH to itself, removing all ETH given to
* the contract from the circulating supply. Self-destructing is the only way to remove ETH
* from the circulating supply.
*/
/// @title Burner
/// @notice Burner self-destructs on creation and sends all ETH to itself, removing all ETH given to
/// the contract from the circulating supply. Self-destructing is the only way to remove ETH
/// from the circulating supply.
contract Burner {
constructor() payable {
selfdestruct(payable(address(this)));
......
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
/**
* @title Bytes
* @notice Bytes is a library for manipulating byte arrays.
*/
/// @title Bytes
/// @notice Bytes is a library for manipulating byte arrays.
library Bytes {
/**
* @custom:attribution https://github.com/GNSPS/solidity-bytes-utils
* @notice Slices a byte array with a given starting index and length. Returns a new byte array
* as opposed to a pointer to the original array. Will throw if trying to slice more
* bytes than exist in the array.
*
* @param _bytes Byte array to slice.
* @param _start Starting index of the slice.
* @param _length Length of the slice.
*
* @return Slice of the input byte array.
*/
/// @custom:attribution https://github.com/GNSPS/solidity-bytes-utils
/// @notice Slices a byte array with a given starting index and length. Returns a new byte array
/// as opposed to a pointer to the original array. Will throw if trying to slice more
/// bytes than exist in the array.
/// @param _bytes Byte array to slice.
/// @param _start Starting index of the slice.
/// @param _length Length of the slice.
/// @return Slice of the input byte array.
function slice(
bytes memory _bytes,
uint256 _start,
......@@ -87,15 +81,11 @@ library Bytes {
return tempBytes;
}
/**
* @notice Slices a byte array with a given starting index up to the end of the original byte
* array. Returns a new array rathern than a pointer to the original.
*
* @param _bytes Byte array to slice.
* @param _start Starting index of the slice.
*
* @return Slice of the input byte array.
*/
/// @notice Slices a byte array with a given starting index up to the end of the original byte
/// array. Returns a new array rathern than a pointer to the original.
/// @param _bytes Byte array to slice.
/// @param _start Starting index of the slice.
/// @return Slice of the input byte array.
function slice(bytes memory _bytes, uint256 _start) internal pure returns (bytes memory) {
if (_start >= _bytes.length) {
return bytes("");
......@@ -103,14 +93,10 @@ library Bytes {
return slice(_bytes, _start, _bytes.length - _start);
}
/**
* @notice Converts a byte array into a nibble array by splitting each byte into two nibbles.
* Resulting nibble array will be exactly twice as long as the input byte array.
*
* @param _bytes Input byte array to convert.
*
* @return Resulting nibble array.
*/
/// @notice Converts a byte array into a nibble array by splitting each byte into two nibbles.
/// Resulting nibble array will be exactly twice as long as the input byte array.
/// @param _bytes Input byte array to convert.
/// @return Resulting nibble array.
function toNibbles(bytes memory _bytes) internal pure returns (bytes memory) {
bytes memory _nibbles;
assembly {
......@@ -158,14 +144,10 @@ library Bytes {
return _nibbles;
}
/**
* @notice Compares two byte arrays by comparing their keccak256 hashes.
*
* @param _bytes First byte array to compare.
* @param _other Second byte array to compare.
*
* @return True if the two byte arrays are equal, false otherwise.
*/
/// @notice Compares two byte arrays by comparing their keccak256 hashes.
/// @param _bytes First byte array to compare.
/// @param _other Second byte array to compare.
/// @return True if the two byte arrays are equal, false otherwise.
function equal(bytes memory _bytes, bytes memory _other) internal pure returns (bool) {
return keccak256(_bytes) == keccak256(_other);
}
......
// SPDX-License-Identifier: BSD
pragma solidity ^0.8.15;
// solhint-disable
/**
* @title Clone
* @author zefram.eth, Saw-mon & Natalie, clabby
* @notice Provides helper functions for reading immutable args from calldata
* @dev Original: https://github.com/Saw-mon-and-Natalie/clones-with-immutable-args/blob/105efee1b9127ed7f6fedf139e1fc796ce8791f2/src/Clone.sol
* @dev MODIFICATIONS:
* - Added `_getArgDynBytes` function.
*/
// solhint-enable
/// @title Clone
/// @author zefram.eth, Saw-mon & Natalie, clabby
/// @notice Provides helper functions for reading immutable args from calldata
/// @dev Original:
/// https://github.com/Saw-mon-and-Natalie/clones-with-immutable-args/
/// blob/105efee1b9127ed7f6fedf139e1fc796ce8791f2/src/Clone.sol
/// @dev MODIFICATIONS:
/// - Added `_getArgDynBytes` function.
contract Clone {
uint256 private constant ONE_WORD = 0x20;
/**
* @notice Reads an immutable arg with type address
* @param argOffset The offset of the arg in the packed data
* @return arg The arg value
*/
/// @notice Reads an immutable arg with type address
/// @param argOffset The offset of the arg in the packed data
/// @return arg The arg value
function _getArgAddress(uint256 argOffset) internal pure returns (address arg) {
uint256 offset = _getImmutableArgsOffset();
assembly {
......@@ -26,11 +22,9 @@ contract Clone {
}
}
/**
* @notice Reads an immutable arg with type uint256
* @param argOffset The offset of the arg in the packed data
* @return arg The arg value
*/
/// @notice Reads an immutable arg with type uint256
/// @param argOffset The offset of the arg in the packed data
/// @return arg The arg value
function _getArgUint256(uint256 argOffset) internal pure returns (uint256 arg) {
uint256 offset = _getImmutableArgsOffset();
assembly {
......@@ -38,11 +32,9 @@ contract Clone {
}
}
/**
* @notice Reads an immutable arg with type bytes32
* @param argOffset The offset of the arg in the packed data
* @return arg The arg value
*/
/// @notice Reads an immutable arg with type bytes32
/// @param argOffset The offset of the arg in the packed data
/// @return arg The arg value
function _getArgFixedBytes(uint256 argOffset) internal pure returns (bytes32 arg) {
uint256 offset = _getImmutableArgsOffset();
assembly {
......@@ -50,12 +42,10 @@ contract Clone {
}
}
/**
* @notice Reads a uint256 array stored in the immutable args.
* @param argOffset The offset of the arg in the packed data
* @param arrLen Number of elements in the array
* @return arr The array
*/
/// @notice Reads a uint256 array stored in the immutable args.
/// @param argOffset The offset of the arg in the packed data
/// @param arrLen Number of elements in the array
/// @return arr The array
function _getArgUint256Array(uint256 argOffset, uint64 arrLen)
internal
pure
......@@ -69,12 +59,10 @@ contract Clone {
}
}
/**
* @notice Reads a dynamic bytes array stored in the immutable args.
* @param argOffset The offset of the arg in the packed data
* @param arrLen Number of elements in the array
* @return arr The array
*/
/// @notice Reads a dynamic bytes array stored in the immutable args.
/// @param argOffset The offset of the arg in the packed data
/// @param arrLen Number of elements in the array
/// @return arr The array
function _getArgDynBytes(uint256 argOffset, uint64 arrLen)
internal
pure
......@@ -88,11 +76,9 @@ contract Clone {
}
}
/**
* @notice Reads an immutable arg with type uint64
* @param argOffset The offset of the arg in the packed data
* @return arg The arg value
*/
/// @notice Reads an immutable arg with type uint64
/// @param argOffset The offset of the arg in the packed data
/// @return arg The arg value
function _getArgUint64(uint256 argOffset) internal pure returns (uint64 arg) {
uint256 offset = _getImmutableArgsOffset();
assembly {
......@@ -100,11 +86,9 @@ contract Clone {
}
}
/**
* @notice Reads an immutable arg with type uint8
* @param argOffset The offset of the arg in the packed data
* @return arg The arg value
*/
/// @notice Reads an immutable arg with type uint8
/// @param argOffset The offset of the arg in the packed data
/// @return arg The arg value
function _getArgUint8(uint256 argOffset) internal pure returns (uint8 arg) {
uint256 offset = _getImmutableArgsOffset();
assembly {
......@@ -112,9 +96,7 @@ contract Clone {
}
}
/**
* @return offset The offset of the packed immutable args in calldata
*/
/// @return offset The offset of the packed immutable args in calldata
function _getImmutableArgsOffset() internal pure returns (uint256 offset) {
assembly {
offset := sub(calldatasize(), shr(0xf0, calldataload(sub(calldatasize(), 2))))
......
......@@ -3,34 +3,26 @@ pragma solidity ^0.8.0;
import { ResourceMetering } from "../L1/ResourceMetering.sol";
/**
* @title Constants
* @notice Constants is a library for storing constants. Simple! Don't put everything in here, just
* the stuff used in multiple contracts. Constants that only apply to a single contract
* should be defined in that contract instead.
*/
/// @title Constants
/// @notice Constants is a library for storing constants. Simple! Don't put everything in here, just
/// the stuff used in multiple contracts. Constants that only apply to a single contract
/// should be defined in that contract instead.
library Constants {
/**
* @notice Special address to be used as the tx origin for gas estimation calls in the
* OptimismPortal and CrossDomainMessenger calls. You only need to use this address if
* the minimum gas limit specified by the user is not actually enough to execute the
* given message and you're attempting to estimate the actual necessary gas limit. We
* use address(1) because it's the ecrecover precompile and therefore guaranteed to
* never have any code on any EVM chain.
*/
/// @notice Special address to be used as the tx origin for gas estimation calls in the
/// OptimismPortal and CrossDomainMessenger calls. You only need to use this address if
/// the minimum gas limit specified by the user is not actually enough to execute the
/// given message and you're attempting to estimate the actual necessary gas limit. We
/// use address(1) because it's the ecrecover precompile and therefore guaranteed to
/// never have any code on any EVM chain.
address internal constant ESTIMATION_ADDRESS = address(1);
/**
* @notice Value used for the L2 sender storage slot in both the OptimismPortal and the
* CrossDomainMessenger contracts before an actual sender is set. This value is
* non-zero to reduce the gas cost of message passing transactions.
*/
/// @notice Value used for the L2 sender storage slot in both the OptimismPortal and the
/// CrossDomainMessenger contracts before an actual sender is set. This value is
/// non-zero to reduce the gas cost of message passing transactions.
address internal constant DEFAULT_L2_SENDER = 0x000000000000000000000000000000000000dEaD;
/**
* @notice Returns the default values for the ResourceConfig. These are the recommended values
* for a production network.
*/
/// @notice Returns the default values for the ResourceConfig. These are the recommended values
/// for a production network.
function DEFAULT_RESOURCE_CONFIG()
internal
pure
......
......@@ -5,20 +5,14 @@ import { Types } from "./Types.sol";
import { Hashing } from "./Hashing.sol";
import { RLPWriter } from "./rlp/RLPWriter.sol";
/**
* @title Encoding
* @notice Encoding handles Optimism's various different encoding schemes.
*/
/// @title Encoding
/// @notice Encoding handles Optimism's various different encoding schemes.
library Encoding {
/**
* @notice RLP encodes the L2 transaction that would be generated when a given deposit is sent
* to the L2 system. Useful for searching for a deposit in the L2 system. The
* transaction is prefixed with 0x7e to identify its EIP-2718 type.
*
* @param _tx User deposit transaction to encode.
*
* @return RLP encoded L2 deposit transaction.
*/
/// @notice RLP encodes the L2 transaction that would be generated when a given deposit is sent
/// to the L2 system. Useful for searching for a deposit in the L2 system. The
/// transaction is prefixed with 0x7e to identify its EIP-2718 type.
/// @param _tx User deposit transaction to encode.
/// @return RLP encoded L2 deposit transaction.
function encodeDepositTransaction(Types.UserDepositTransaction memory _tx)
internal
pure
......@@ -37,19 +31,15 @@ library Encoding {
return abi.encodePacked(uint8(0x7e), RLPWriter.writeList(raw));
}
/**
* @notice Encodes the cross domain message based on the version that is encoded into the
* message nonce.
*
* @param _nonce Message nonce with version encoded into the first two bytes.
* @param _sender Address of the sender of the message.
* @param _target Address of the target of the message.
* @param _value ETH value to send to the target.
* @param _gasLimit Gas limit to use for the message.
* @param _data Data to send with the message.
*
* @return Encoded cross domain message.
*/
/// @notice Encodes the cross domain message based on the version that is encoded into the
/// message nonce.
/// @param _nonce Message nonce with version encoded into the first two bytes.
/// @param _sender Address of the sender of the message.
/// @param _target Address of the target of the message.
/// @param _value ETH value to send to the target.
/// @param _gasLimit Gas limit to use for the message.
/// @param _data Data to send with the message.
/// @return Encoded cross domain message.
function encodeCrossDomainMessage(
uint256 _nonce,
address _sender,
......@@ -68,16 +58,12 @@ library Encoding {
}
}
/**
* @notice Encodes a cross domain message based on the V0 (legacy) encoding.
*
* @param _target Address of the target of the message.
* @param _sender Address of the sender of the message.
* @param _data Data to send with the message.
* @param _nonce Message nonce.
*
* @return Encoded cross domain message.
*/
/// @notice Encodes a cross domain message based on the V0 (legacy) encoding.
/// @param _target Address of the target of the message.
/// @param _sender Address of the sender of the message.
/// @param _data Data to send with the message.
/// @param _nonce Message nonce.
/// @return Encoded cross domain message.
function encodeCrossDomainMessageV0(
address _target,
address _sender,
......@@ -94,18 +80,14 @@ library Encoding {
);
}
/**
* @notice Encodes a cross domain message based on the V1 (current) encoding.
*
* @param _nonce Message nonce.
* @param _sender Address of the sender of the message.
* @param _target Address of the target of the message.
* @param _value ETH value to send to the target.
* @param _gasLimit Gas limit to use for the message.
* @param _data Data to send with the message.
*
* @return Encoded cross domain message.
*/
/// @notice Encodes a cross domain message based on the V1 (current) encoding.
/// @param _nonce Message nonce.
/// @param _sender Address of the sender of the message.
/// @param _target Address of the target of the message.
/// @param _value ETH value to send to the target.
/// @param _gasLimit Gas limit to use for the message.
/// @param _data Data to send with the message.
/// @return Encoded cross domain message.
function encodeCrossDomainMessageV1(
uint256 _nonce,
address _sender,
......@@ -126,14 +108,10 @@ library Encoding {
);
}
/**
* @notice Adds a version number into the first two bytes of a message nonce.
*
* @param _nonce Message nonce to encode into.
* @param _version Version number to encode into the message nonce.
*
* @return Message nonce with version encoded into the first two bytes.
*/
/// @notice Adds a version number into the first two bytes of a message nonce.
/// @param _nonce Message nonce to encode into.
/// @param _version Version number to encode into the message nonce.
/// @return Message nonce with version encoded into the first two bytes.
function encodeVersionedNonce(uint240 _nonce, uint16 _version) internal pure returns (uint256) {
uint256 nonce;
assembly {
......@@ -142,14 +120,10 @@ library Encoding {
return nonce;
}
/**
* @notice Pulls the version out of a version-encoded nonce.
*
* @param _nonce Message nonce with version encoded into the first two bytes.
*
* @return Nonce without encoded version.
* @return Version of the message.
*/
/// @notice Pulls the version out of a version-encoded nonce.
/// @param _nonce Message nonce with version encoded into the first two bytes.
/// @return Nonce without encoded version.
/// @return Version of the message.
function decodeVersionedNonce(uint256 _nonce) internal pure returns (uint240, uint16) {
uint240 nonce;
uint16 version;
......
......@@ -4,20 +4,14 @@ pragma solidity ^0.8.0;
import { Types } from "./Types.sol";
import { Encoding } from "./Encoding.sol";
/**
* @title Hashing
* @notice Hashing handles Optimism's various different hashing schemes.
*/
/// @title Hashing
/// @notice Hashing handles Optimism's various different hashing schemes.
library Hashing {
/**
* @notice Computes the hash of the RLP encoded L2 transaction that would be generated when a
* given deposit is sent to the L2 system. Useful for searching for a deposit in the L2
* system.
*
* @param _tx User deposit transaction to hash.
*
* @return Hash of the RLP encoded L2 deposit transaction.
*/
/// @notice Computes the hash of the RLP encoded L2 transaction that would be generated when a
/// given deposit is sent to the L2 system. Useful for searching for a deposit in the L2
/// system.
/// @param _tx User deposit transaction to hash.
/// @return Hash of the RLP encoded L2 deposit transaction.
function hashDepositTransaction(Types.UserDepositTransaction memory _tx)
internal
pure
......@@ -26,16 +20,12 @@ library Hashing {
return keccak256(Encoding.encodeDepositTransaction(_tx));
}
/**
* @notice Computes the deposit transaction's "source hash", a value that guarantees the hash
* of the L2 transaction that corresponds to a deposit is unique and is
* deterministically generated from L1 transaction data.
*
* @param _l1BlockHash Hash of the L1 block where the deposit was included.
* @param _logIndex The index of the log that created the deposit transaction.
*
* @return Hash of the deposit transaction's "source hash".
*/
/// @notice Computes the deposit transaction's "source hash", a value that guarantees the hash
/// of the L2 transaction that corresponds to a deposit is unique and is
/// deterministically generated from L1 transaction data.
/// @param _l1BlockHash Hash of the L1 block where the deposit was included.
/// @param _logIndex The index of the log that created the deposit transaction.
/// @return Hash of the deposit transaction's "source hash".
function hashDepositSource(bytes32 _l1BlockHash, uint256 _logIndex)
internal
pure
......@@ -45,19 +35,15 @@ library Hashing {
return keccak256(abi.encode(bytes32(0), depositId));
}
/**
* @notice Hashes the cross domain message based on the version that is encoded into the
* message nonce.
*
* @param _nonce Message nonce with version encoded into the first two bytes.
* @param _sender Address of the sender of the message.
* @param _target Address of the target of the message.
* @param _value ETH value to send to the target.
* @param _gasLimit Gas limit to use for the message.
* @param _data Data to send with the message.
*
* @return Hashed cross domain message.
*/
/// @notice Hashes the cross domain message based on the version that is encoded into the
/// message nonce.
/// @param _nonce Message nonce with version encoded into the first two bytes.
/// @param _sender Address of the sender of the message.
/// @param _target Address of the target of the message.
/// @param _value ETH value to send to the target.
/// @param _gasLimit Gas limit to use for the message.
/// @param _data Data to send with the message.
/// @return Hashed cross domain message.
function hashCrossDomainMessage(
uint256 _nonce,
address _sender,
......@@ -76,16 +62,12 @@ library Hashing {
}
}
/**
* @notice Hashes a cross domain message based on the V0 (legacy) encoding.
*
* @param _target Address of the target of the message.
* @param _sender Address of the sender of the message.
* @param _data Data to send with the message.
* @param _nonce Message nonce.
*
* @return Hashed cross domain message.
*/
/// @notice Hashes a cross domain message based on the V0 (legacy) encoding.
/// @param _target Address of the target of the message.
/// @param _sender Address of the sender of the message.
/// @param _data Data to send with the message.
/// @param _nonce Message nonce.
/// @return Hashed cross domain message.
function hashCrossDomainMessageV0(
address _target,
address _sender,
......@@ -95,18 +77,14 @@ library Hashing {
return keccak256(Encoding.encodeCrossDomainMessageV0(_target, _sender, _data, _nonce));
}
/**
* @notice Hashes a cross domain message based on the V1 (current) encoding.
*
* @param _nonce Message nonce.
* @param _sender Address of the sender of the message.
* @param _target Address of the target of the message.
* @param _value ETH value to send to the target.
* @param _gasLimit Gas limit to use for the message.
* @param _data Data to send with the message.
*
* @return Hashed cross domain message.
*/
/// @notice Hashes a cross domain message based on the V1 (current) encoding.
/// @param _nonce Message nonce.
/// @param _sender Address of the sender of the message.
/// @param _target Address of the target of the message.
/// @param _value ETH value to send to the target.
/// @param _gasLimit Gas limit to use for the message.
/// @param _data Data to send with the message.
/// @return Hashed cross domain message.
function hashCrossDomainMessageV1(
uint256 _nonce,
address _sender,
......@@ -128,13 +106,9 @@ library Hashing {
);
}
/**
* @notice Derives the withdrawal hash according to the encoding in the L2 Withdrawer contract
*
* @param _tx Withdrawal transaction to hash.
*
* @return Hashed withdrawal transaction.
*/
/// @notice Derives the withdrawal hash according to the encoding in the L2 Withdrawer contract
/// @param _tx Withdrawal transaction to hash.
/// @return Hashed withdrawal transaction.
function hashWithdrawal(Types.WithdrawalTransaction memory _tx)
internal
pure
......@@ -146,14 +120,10 @@ library Hashing {
);
}
/**
* @notice Hashes the various elements of an output root proof into an output root hash which
* can be used to check if the proof is valid.
*
* @param _outputRootProof Output root proof which should hash to an output root.
*
* @return Hashed output root proof.
*/
/// @notice Hashes the various elements of an output root proof into an output root hash which
/// can be used to check if the proof is valid.
/// @param _outputRootProof Output root proof which should hash to an output root.
/// @return Hashed output root proof.
function hashOutputRootProof(Types.OutputRootProof memory _outputRootProof)
internal
pure
......
......@@ -5,18 +5,15 @@ pragma solidity ^0.8.9;
// so we just copy the library here from
// /packages/contracts/contracts/libraries/bridge/Lib_CrossDomainUtils.sol at commit
// 7866168c
/**
* @title LegacyCrossDomainUtils
*/
/// @title LegacyCrossDomainUtils
library LegacyCrossDomainUtils {
/**
* Generates the correct cross domain calldata for a message.
* @param _target Target contract address.
* @param _sender Message sender address.
* @param _message Message to send to the target.
* @param _messageNonce Nonce for the provided message.
* @return ABI encoded cross domain calldata.
*/
/// @notice Generates the correct cross domain calldata for a message.
/// @param _target Target contract address.
/// @param _sender Message sender address.
/// @param _message Message to send to the target.
/// @param _messageNonce Nonce for the provided message.
/// @return ABI encoded cross domain calldata.
function encodeXDomainCalldata(
address _target,
address _sender,
......
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
/**
* @title Predeploys
* @notice Contains constant addresses for contracts that are pre-deployed to the L2 system.
*/
/// @title Predeploys
/// @notice Contains constant addresses for contracts that are pre-deployed to the L2 system.
library Predeploys {
/**
* @notice Address of the L2ToL1MessagePasser predeploy.
*/
/// @notice Address of the L2ToL1MessagePasser predeploy.
address internal constant L2_TO_L1_MESSAGE_PASSER = 0x4200000000000000000000000000000000000016;
/**
* @notice Address of the L2CrossDomainMessenger predeploy.
*/
/// @notice Address of the L2CrossDomainMessenger predeploy.
address internal constant L2_CROSS_DOMAIN_MESSENGER =
0x4200000000000000000000000000000000000007;
/**
* @notice Address of the L2StandardBridge predeploy.
*/
/// @notice Address of the L2StandardBridge predeploy.
address internal constant L2_STANDARD_BRIDGE = 0x4200000000000000000000000000000000000010;
/**
* @notice Address of the L2ERC721Bridge predeploy.
*/
/// @notice Address of the L2ERC721Bridge predeploy.
address internal constant L2_ERC721_BRIDGE = 0x4200000000000000000000000000000000000014;
/**
* @notice Address of the SequencerFeeWallet predeploy.
*/
//// @notice Address of the SequencerFeeWallet predeploy.
address internal constant SEQUENCER_FEE_WALLET = 0x4200000000000000000000000000000000000011;
/**
* @notice Address of the OptimismMintableERC20Factory predeploy.
*/
/// @notice Address of the OptimismMintableERC20Factory predeploy.
address internal constant OPTIMISM_MINTABLE_ERC20_FACTORY =
0x4200000000000000000000000000000000000012;
/**
* @notice Address of the OptimismMintableERC721Factory predeploy.
*/
/// @notice Address of the OptimismMintableERC721Factory predeploy.
address internal constant OPTIMISM_MINTABLE_ERC721_FACTORY =
0x4200000000000000000000000000000000000017;
/**
* @notice Address of the L1Block predeploy.
*/
/// @notice Address of the L1Block predeploy.
address internal constant L1_BLOCK_ATTRIBUTES = 0x4200000000000000000000000000000000000015;
/**
* @notice Address of the GasPriceOracle predeploy. Includes fee information
* and helpers for computing the L1 portion of the transaction fee.
*/
/// @notice Address of the GasPriceOracle predeploy. Includes fee information
/// and helpers for computing the L1 portion of the transaction fee.
address internal constant GAS_PRICE_ORACLE = 0x420000000000000000000000000000000000000F;
/**
* @custom:legacy
* @notice Address of the L1MessageSender predeploy. Deprecated. Use L2CrossDomainMessenger
* or access tx.origin (or msg.sender) in a L1 to L2 transaction instead.
*/
/// @custom:legacy
/// @notice Address of the L1MessageSender predeploy. Deprecated. Use L2CrossDomainMessenger
/// or access tx.origin (or msg.sender) in a L1 to L2 transaction instead.
address internal constant L1_MESSAGE_SENDER = 0x4200000000000000000000000000000000000001;
/**
* @custom:legacy
* @notice Address of the DeployerWhitelist predeploy. No longer active.
*/
/// @custom:legacy
/// @notice Address of the DeployerWhitelist predeploy. No longer active.
address internal constant DEPLOYER_WHITELIST = 0x4200000000000000000000000000000000000002;
/**
* @custom:legacy
* @notice Address of the LegacyERC20ETH predeploy. Deprecated. Balances are migrated to the
* state trie as of the Bedrock upgrade. Contract has been locked and write functions
* can no longer be accessed.
*/
/// @custom:legacy
/// @notice Address of the LegacyERC20ETH predeploy. Deprecated. Balances are migrated to the
/// state trie as of the Bedrock upgrade. Contract has been locked and write functions
/// can no longer be accessed.
address internal constant LEGACY_ERC20_ETH = 0xDeadDeAddeAddEAddeadDEaDDEAdDeaDDeAD0000;
/**
* @custom:legacy
* @notice Address of the L1BlockNumber predeploy. Deprecated. Use the L1Block predeploy
* instead, which exposes more information about the L1 state.
*/
/// @custom:legacy
/// @notice Address of the L1BlockNumber predeploy. Deprecated. Use the L1Block predeploy
/// instead, which exposes more information about the L1 state.
address internal constant L1_BLOCK_NUMBER = 0x4200000000000000000000000000000000000013;
/**
* @custom:legacy
* @notice Address of the LegacyMessagePasser predeploy. Deprecate. Use the updated
* L2ToL1MessagePasser contract instead.
*/
/// @custom:legacy
/// @notice Address of the LegacyMessagePasser predeploy. Deprecate. Use the updated
/// L2ToL1MessagePasser contract instead.
address internal constant LEGACY_MESSAGE_PASSER = 0x4200000000000000000000000000000000000000;
/**
* @notice Address of the ProxyAdmin predeploy.
*/
/// @notice Address of the ProxyAdmin predeploy.
address internal constant PROXY_ADMIN = 0x4200000000000000000000000000000000000018;
/**
* @notice Address of the BaseFeeVault predeploy.
*/
/// @notice Address of the BaseFeeVault predeploy.
address internal constant BASE_FEE_VAULT = 0x4200000000000000000000000000000000000019;
/**
* @notice Address of the L1FeeVault predeploy.
*/
/// @notice Address of the L1FeeVault predeploy.
address internal constant L1_FEE_VAULT = 0x420000000000000000000000000000000000001A;
/**
* @notice Address of the GovernanceToken predeploy.
*/
/// @notice Address of the GovernanceToken predeploy.
address internal constant GOVERNANCE_TOKEN = 0x4200000000000000000000000000000000000042;
}
// SPDX-License-Identifier: MIT
pragma solidity 0.8.15;
/**
* @title SafeCall
* @notice Perform low level safe calls
*/
/// @title SafeCall
/// @notice Perform low level safe calls
library SafeCall {
/**
* @notice Performs a low level call without copying any returndata.
* @dev Passes no calldata to the call context.
*
* @param _target Address to call
* @param _gas Amount of gas to pass to the call
* @param _value Amount of value to pass to the call
*/
/// @notice Performs a low level call without copying any returndata.
/// @dev Passes no calldata to the call context.
/// @param _target Address to call
/// @param _gas Amount of gas to pass to the call
/// @param _value Amount of value to pass to the call
function send(
address _target,
uint256 _gas,
......@@ -34,14 +29,11 @@ library SafeCall {
return _success;
}
/**
* @notice Perform a low level call without copying any returndata
*
* @param _target Address to call
* @param _gas Amount of gas to pass to the call
* @param _value Amount of value to pass to the call
* @param _calldata Calldata to pass to the call
*/
/// @notice Perform a low level call without copying any returndata
/// @param _target Address to call
/// @param _gas Amount of gas to pass to the call
/// @param _value Amount of value to pass to the call
/// @param _calldata Calldata to pass to the call
function call(
address _target,
uint256 _gas,
......@@ -63,31 +55,29 @@ library SafeCall {
return _success;
}
/**
* @notice Helper function to determine if there is sufficient gas remaining within the context
* to guarantee that the minimum gas requirement for a call will be met as well as
* optionally reserving a specified amount of gas for after the call has concluded.
* @param _minGas The minimum amount of gas that may be passed to the target context.
* @param _reservedGas Optional amount of gas to reserve for the caller after the execution
* of the target context.
* @return `true` if there is enough gas remaining to safely supply `_minGas` to the target
* context as well as reserve `_reservedGas` for the caller after the execution of
* the target context.
* @dev !!!!! FOOTGUN ALERT !!!!!
* 1.) The 40_000 base buffer is to account for the worst case of the dynamic cost of the
* `CALL` opcode's `address_access_cost`, `positive_value_cost`, and
* `value_to_empty_account_cost` factors with an added buffer of 5,700 gas. It is
* still possible to self-rekt by initiating a withdrawal with a minimum gas limit
* that does not account for the `memory_expansion_cost` & `code_execution_cost`
* factors of the dynamic cost of the `CALL` opcode.
* 2.) This function should *directly* precede the external call if possible. There is an
* added buffer to account for gas consumed between this check and the call, but it
* is only 5,700 gas.
* 3.) Because EIP-150 ensures that a maximum of 63/64ths of the remaining gas in the call
* frame may be passed to a subcontext, we need to ensure that the gas will not be
* truncated.
* 4.) Use wisely. This function is not a silver bullet.
*/
/// @notice Helper function to determine if there is sufficient gas remaining within the context
/// to guarantee that the minimum gas requirement for a call will be met as well as
/// optionally reserving a specified amount of gas for after the call has concluded.
/// @param _minGas The minimum amount of gas that may be passed to the target context.
/// @param _reservedGas Optional amount of gas to reserve for the caller after the execution
/// of the target context.
/// @return `true` if there is enough gas remaining to safely supply `_minGas` to the target
/// context as well as reserve `_reservedGas` for the caller after the execution of
/// the target context.
/// @dev !!!!! FOOTGUN ALERT !!!!!
/// 1.) The 40_000 base buffer is to account for the worst case of the dynamic cost of the
/// `CALL` opcode's `address_access_cost`, `positive_value_cost`, and
/// `value_to_empty_account_cost` factors with an added buffer of 5,700 gas. It is
/// still possible to self-rekt by initiating a withdrawal with a minimum gas limit
/// that does not account for the `memory_expansion_cost` & `code_execution_cost`
/// factors of the dynamic cost of the `CALL` opcode.
/// 2.) This function should *directly* precede the external call if possible. There is an
/// added buffer to account for gas consumed between this check and the call, but it
/// is only 5,700 gas.
/// 3.) Because EIP-150 ensures that a maximum of 63/64ths of the remaining gas in the call
/// frame may be passed to a subcontext, we need to ensure that the gas will not be
/// truncated.
/// 4.) Use wisely. This function is not a silver bullet.
function hasMinGas(uint256 _minGas, uint256 _reservedGas) internal view returns (bool) {
bool _hasMinGas;
assembly {
......@@ -99,16 +89,13 @@ library SafeCall {
return _hasMinGas;
}
/**
* @notice Perform a low level call without copying any returndata. This function
* will revert if the call cannot be performed with the specified minimum
* gas.
*
* @param _target Address to call
* @param _minGas The minimum amount of gas that may be passed to the call
* @param _value Amount of value to pass to the call
* @param _calldata Calldata to pass to the call
*/
/// @notice Perform a low level call without copying any returndata. This function
/// will revert if the call cannot be performed with the specified minimum
/// gas.
/// @param _target Address to call
/// @param _minGas The minimum amount of gas that may be passed to the call
/// @param _value Amount of value to pass to the call
/// @param _calldata Calldata to pass to the call
function callWithMinGas(
address _target,
uint256 _minGas,
......
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
/**
* @title Types
* @notice Contains various types used throughout the Optimism contract system.
*/
/// @title Types
/// @notice Contains various types used throughout the Optimism contract system.
library Types {
/**
* @notice OutputProposal represents a commitment to the L2 state. The timestamp is the L1
* timestamp that the output root is posted. This timestamp is used to verify that the
* finalization period has passed since the output root was submitted.
*
* @custom:field outputRoot Hash of the L2 output.
* @custom:field timestamp Timestamp of the L1 block that the output root was submitted in.
* @custom:field l2BlockNumber L2 block number that the output corresponds to.
*/
/// @notice OutputProposal represents a commitment to the L2 state. The timestamp is the L1
/// timestamp that the output root is posted. This timestamp is used to verify that the
/// finalization period has passed since the output root was submitted.
/// @custom:field outputRoot Hash of the L2 output.
/// @custom:field timestamp Timestamp of the L1 block that the output root was submitted in.
/// @custom:field l2BlockNumber L2 block number that the output corresponds to.
struct OutputProposal {
bytes32 outputRoot;
uint128 timestamp;
uint128 l2BlockNumber;
}
/**
* @notice Struct representing the elements that are hashed together to generate an output root
* which itself represents a snapshot of the L2 state.
*
* @custom:field version Version of the output root.
* @custom:field stateRoot Root of the state trie at the block of this output.
* @custom:field messagePasserStorageRoot Root of the message passer storage trie.
* @custom:field latestBlockhash Hash of the block this output was generated from.
*/
/// @notice Struct representing the elements that are hashed together to generate an output root
/// which itself represents a snapshot of the L2 state.
/// @custom:field version Version of the output root.
/// @custom:field stateRoot Root of the state trie at the block of this output.
/// @custom:field messagePasserStorageRoot Root of the message passer storage trie.
/// @custom:field latestBlockhash Hash of the block this output was generated from.
struct OutputRootProof {
bytes32 version;
bytes32 stateRoot;
......@@ -37,20 +29,17 @@ library Types {
bytes32 latestBlockhash;
}
/**
* @notice Struct representing a deposit transaction (L1 => L2 transaction) created by an end
* user (as opposed to a system deposit transaction generated by the system).
*
* @custom:field from Address of the sender of the transaction.
* @custom:field to Address of the recipient of the transaction.
* @custom:field isCreation True if the transaction is a contract creation.
* @custom:field value Value to send to the recipient.
* @custom:field mint Amount of ETH to mint.
* @custom:field gasLimit Gas limit of the transaction.
* @custom:field data Data of the transaction.
* @custom:field l1BlockHash Hash of the block the transaction was submitted in.
* @custom:field logIndex Index of the log in the block the transaction was submitted in.
*/
/// @notice Struct representing a deposit transaction (L1 => L2 transaction) created by an end
/// user (as opposed to a system deposit transaction generated by the system).
/// @custom:field from Address of the sender of the transaction.
/// @custom:field to Address of the recipient of the transaction.
/// @custom:field isCreation True if the transaction is a contract creation.
/// @custom:field value Value to send to the recipient.
/// @custom:field mint Amount of ETH to mint.
/// @custom:field gasLimit Gas limit of the transaction.
/// @custom:field data Data of the transaction.
/// @custom:field l1BlockHash Hash of the block the transaction was submitted in.
/// @custom:field logIndex Index of the log in the block the transaction was submitted in.
struct UserDepositTransaction {
address from;
address to;
......@@ -63,16 +52,13 @@ library Types {
uint256 logIndex;
}
/**
* @notice Struct representing a withdrawal transaction.
*
* @custom:field nonce Nonce of the withdrawal transaction
* @custom:field sender Address of the sender of the transaction.
* @custom:field target Address of the recipient of the transaction.
* @custom:field value Value to send to the recipient.
* @custom:field gasLimit Gas limit of the transaction.
* @custom:field data Data of the transaction.
*/
/// @notice Struct representing a withdrawal transaction.
/// @custom:field nonce Nonce of the withdrawal transaction
/// @custom:field sender Address of the sender of the transaction.
/// @custom:field target Address of the recipient of the transaction.
/// @custom:field value Value to send to the recipient.
/// @custom:field gasLimit Gas limit of the transaction.
/// @custom:field data Data of the transaction.
struct WithdrawalTransaction {
uint256 nonce;
address sender;
......
pragma solidity 0.8.15;
// Testing utilities
import { Test } from "forge-std/Test.sol";
// Target contract
import { Bytes } from "../libraries/Bytes.sol";
contract Bytes_slice_Test is Test {
/**
* @notice Tests that the `slice` function works as expected when starting from index 0.
*/
/// @notice Tests that the `slice` function works as expected when starting from index 0.
function test_slice_fromZeroIdx_works() public {
bytes memory input = hex"11223344556677889900";
......@@ -24,10 +25,8 @@ contract Bytes_slice_Test is Test {
assertEq(Bytes.slice(input, 0, 10), hex"11223344556677889900");
}
/**
* @notice Tests that the `slice` function works as expected when starting from indices [1, 9]
* with lengths [1, 9], in reverse order.
*/
/// @notice Tests that the `slice` function works as expected when starting from indices [1, 9]
/// with lengths [1, 9], in reverse order.
function test_slice_fromNonZeroIdx_works() public {
bytes memory input = hex"11223344556677889900";
......@@ -44,11 +43,9 @@ contract Bytes_slice_Test is Test {
assertEq(Bytes.slice(input, 1, 9), hex"223344556677889900");
}
/**
* @notice Tests that the `slice` function works as expected when slicing between multiple words
* in memory. In this case, we test that a 2 byte slice between the 32nd byte of the
* first word and the 1st byte of the second word is correct.
*/
/// @notice Tests that the `slice` function works as expected when slicing between multiple words
/// in memory. In this case, we test that a 2 byte slice between the 32nd byte of the
/// first word and the 1st byte of the second word is correct.
function test_slice_acrossWords_works() public {
bytes
memory input = hex"00000000000000000000000000000000000000000000000000000000000000112200000000000000000000000000000000000000000000000000000000000000";
......@@ -56,11 +53,9 @@ contract Bytes_slice_Test is Test {
assertEq(Bytes.slice(input, 31, 2), hex"1122");
}
/**
* @notice Tests that the `slice` function works as expected when slicing between multiple
* words in memory. In this case, we test that a 34 byte slice between 3 separate words
* returns the correct result.
*/
/// @notice Tests that the `slice` function works as expected when slicing between multiple
/// words in memory. In this case, we test that a 34 byte slice between 3 separate words
/// returns the correct result.
function test_slice_acrossMultipleWords_works() public {
bytes
memory input = hex"000000000000000000000000000000000000000000000000000000000000001122FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1100000000000000000000000000000000000000000000000000000000000000";
......@@ -70,10 +65,8 @@ contract Bytes_slice_Test is Test {
assertEq(Bytes.slice(input, 31, 34), expected);
}
/**
* @notice Tests that the `slice` function correctly updates the free memory pointer depending
* on the length of the slice.
*/
/// @notice Tests that the `slice` function correctly updates the free memory pointer depending
/// on the length of the slice.
function testFuzz_slice_memorySafety_succeeds(
bytes memory _input,
uint256 _start,
......@@ -129,10 +122,8 @@ contract Bytes_slice_Test is Test {
}
contract Bytes_slice_TestFail is Test {
/**
* @notice Tests that, when given an input bytes array of length `n`, the `slice` function will
* always revert if `_start + _length > n`.
*/
/// @notice Tests that, when given an input bytes array of length `n`, the `slice` function will
/// always revert if `_start + _length > n`.
function testFuzz_slice_outOfBounds_reverts(
bytes memory _input,
uint256 _start,
......@@ -147,10 +138,8 @@ contract Bytes_slice_TestFail is Test {
Bytes.slice(_input, _start, _length);
}
/**
* @notice Tests that, when given a length `n` that is greater than `type(uint256).max - 31`,
* the `slice` function reverts.
*/
/// @notice Tests that, when given a length `n` that is greater than `type(uint256).max - 31`,
/// the `slice` function reverts.
function testFuzz_slice_lengthOverflows_reverts(
bytes memory _input,
uint256 _start,
......@@ -163,10 +152,8 @@ contract Bytes_slice_TestFail is Test {
Bytes.slice(_input, _start, _length);
}
/**
* @notice Tests that, when given a start index `n` that is greater than
* `type(uint256).max - n`, the `slice` function reverts.
*/
/// @notice Tests that, when given a start index `n` that is greater than
/// `type(uint256).max - n`, the `slice` function reverts.
function testFuzz_slice_rangeOverflows_reverts(
bytes memory _input,
uint256 _start,
......@@ -184,10 +171,8 @@ contract Bytes_slice_TestFail is Test {
}
contract Bytes_toNibbles_Test is Test {
/**
* @notice Tests that, given an input of 5 bytes, the `toNibbles` function returns an array of
* 10 nibbles corresponding to the input data.
*/
/// @notice Tests that, given an input of 5 bytes, the `toNibbles` function returns an array of
/// 10 nibbles corresponding to the input data.
function test_toNibbles_expectedResult5Bytes_works() public {
bytes memory input = hex"1234567890";
bytes memory expected = hex"01020304050607080900";
......@@ -198,11 +183,9 @@ contract Bytes_toNibbles_Test is Test {
assertEq(actual, expected);
}
/**
* @notice Tests that, given an input of 128 bytes, the `toNibbles` function returns an array
* of 256 nibbles corresponding to the input data. This test exists to ensure that,
* given a large input, the `toNibbles` function works as expected.
*/
/// @notice Tests that, given an input of 128 bytes, the `toNibbles` function returns an array
/// of 256 nibbles corresponding to the input data. This test exists to ensure that,
/// given a large input, the `toNibbles` function works as expected.
function test_toNibbles_expectedResult128Bytes_works() public {
bytes
memory input = hex"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f";
......@@ -215,10 +198,8 @@ contract Bytes_toNibbles_Test is Test {
assertEq(actual, expected);
}
/**
* @notice Tests that, given an input of 0 bytes, the `toNibbles` function returns a zero
* length array.
*/
/// @notice Tests that, given an input of 0 bytes, the `toNibbles` function returns a zero
/// length array.
function test_toNibbles_zeroLengthInput_works() public {
bytes memory input = hex"";
bytes memory expected = hex"";
......@@ -230,10 +211,8 @@ contract Bytes_toNibbles_Test is Test {
assertEq(actual, expected);
}
/**
* @notice Tests that the `toNibbles` function correctly updates the free memory pointer depending
* on the length of the resulting array.
*/
/// @notice Tests that the `toNibbles` function correctly updates the free memory pointer depending
/// on the length of the resulting array.
function testFuzz_toNibbles_memorySafety_succeeds(bytes memory _input) public {
// Grab the free memory pointer before the `toNibbles` operation
uint64 initPtr;
......@@ -278,14 +257,10 @@ contract Bytes_toNibbles_Test is Test {
}
contract Bytes_equal_Test is Test {
/**
* @notice Manually checks equality of two dynamic `bytes` arrays in memory.
*
* @param _a The first `bytes` array to compare.
* @param _b The second `bytes` array to compare.
*
* @return True if the two `bytes` arrays are equal in memory.
*/
/// @notice Manually checks equality of two dynamic `bytes` arrays in memory.
/// @param _a The first `bytes` array to compare.
/// @param _b The second `bytes` array to compare.
/// @return True if the two `bytes` arrays are equal in memory.
function manualEq(bytes memory _a, bytes memory _b) internal pure returns (bool) {
bool _eq;
assembly {
......@@ -300,19 +275,15 @@ contract Bytes_equal_Test is Test {
return _eq;
}
/**
* @notice Tests that the `equal` function in the `Bytes` library returns `false` if given two
* non-equal byte arrays.
*/
/// @notice Tests that the `equal` function in the `Bytes` library returns `false` if given two
/// non-equal byte arrays.
function testFuzz_equal_notEqual_works(bytes memory _a, bytes memory _b) public {
vm.assume(!manualEq(_a, _b));
assertFalse(Bytes.equal(_a, _b));
}
/**
* @notice Test whether or not the `equal` function in the `Bytes` library is equivalent to
* manually checking equality of the two dynamic `bytes` arrays in memory.
*/
/// @notice Test whether or not the `equal` function in the `Bytes` library is equivalent to
/// manually checking equality of the two dynamic `bytes` arrays in memory.
function testDiff_equal_works(bytes memory _a, bytes memory _b) public {
assertEq(Bytes.equal(_a, _b), manualEq(_a, _b));
}
......
// SPDX-License-Identifier: MIT
pragma solidity 0.8.15;
import { CommonTest, Portal_Initializer } from "./CommonTest.t.sol";
import { CrossDomainOwnable } from "../L2/CrossDomainOwnable.sol";
import { AddressAliasHelper } from "../vendor/AddressAliasHelper.sol";
// Testing utilities
import { Vm, VmSafe } from "forge-std/Vm.sol";
import { CommonTest, Portal_Initializer } from "./CommonTest.t.sol";
// Libraries
import { Bytes32AddressLib } from "@rari-capital/solmate/src/utils/Bytes32AddressLib.sol";
// Target contract dependencies
import { AddressAliasHelper } from "../vendor/AddressAliasHelper.sol";
// Target contract
import { CrossDomainOwnable } from "../L2/CrossDomainOwnable.sol";
contract XDomainSetter is CrossDomainOwnable {
uint256 public value;
......@@ -23,13 +30,13 @@ contract CrossDomainOwnable_Test is CommonTest {
setter = new XDomainSetter();
}
// Check that the revert message is correct
/// @dev Tests that the `onlyOwner` modifier reverts with the correct message.
function test_onlyOwner_notOwner_reverts() external {
vm.expectRevert("CrossDomainOwnable: caller is not the owner");
setter.set(1);
}
// Check that making a call can set the value properly
/// @dev Tests that the `onlyOwner` modifier succeeds when called by the owner.
function test_onlyOwner_succeeds() external {
assertEq(setter.value(), 0);
......@@ -42,6 +49,7 @@ contract CrossDomainOwnable_Test is CommonTest {
contract CrossDomainOwnableThroughPortal_Test is Portal_Initializer {
XDomainSetter setter;
/// @dev Sets up the test suite.
function setUp() public override {
super.setUp();
......@@ -49,6 +57,8 @@ contract CrossDomainOwnableThroughPortal_Test is Portal_Initializer {
setter = new XDomainSetter();
}
/// @dev Tests that `depositTransaction` succeeds when calling the `set` function on the
/// `XDomainSetter` contract.
function test_depositTransaction_crossDomainOwner_succeeds() external {
vm.recordLogs();
......
// SPDX-License-Identifier: MIT
pragma solidity 0.8.15;
import { Bytes32AddressLib } from "@rari-capital/solmate/src/utils/Bytes32AddressLib.sol";
// Testing utilities
import { CommonTest, Messenger_Initializer } from "./CommonTest.t.sol";
import { CrossDomainOwnable2 } from "../L2/CrossDomainOwnable2.sol";
import { AddressAliasHelper } from "../vendor/AddressAliasHelper.sol";
// Libraries
import { Hashing } from "../libraries/Hashing.sol";
import { Encoding } from "../libraries/Encoding.sol";
import { Bytes32AddressLib } from "@rari-capital/solmate/src/utils/Bytes32AddressLib.sol";
// Target contract dependencies
import { AddressAliasHelper } from "../vendor/AddressAliasHelper.sol";
// Target contract
import { CrossDomainOwnable2 } from "../L2/CrossDomainOwnable2.sol";
contract XDomainSetter2 is CrossDomainOwnable2 {
uint256 public value;
......@@ -19,17 +26,20 @@ contract XDomainSetter2 is CrossDomainOwnable2 {
contract CrossDomainOwnable2_Test is Messenger_Initializer {
XDomainSetter2 setter;
/// @dev Sets up the test suite.
function setUp() public override {
super.setUp();
vm.prank(alice);
setter = new XDomainSetter2();
}
/// @dev Tests that the `onlyOwner` modifier reverts when the caller is not the messenger.
function test_onlyOwner_notMessenger_reverts() external {
vm.expectRevert("CrossDomainOwnable2: caller is not the messenger");
setter.set(1);
}
/// @dev Tests that the `onlyOwner` modifier reverts when not called by the owner.
function test_onlyOwner_notOwner_reverts() external {
// set the xDomainMsgSender storage slot
bytes32 key = bytes32(uint256(204));
......@@ -41,6 +51,7 @@ contract CrossDomainOwnable2_Test is Messenger_Initializer {
setter.set(1);
}
/// @dev Tests that the `onlyOwner` modifier causes the relayed message to fail.
function test_onlyOwner_notOwner2_reverts() external {
uint240 nonce = 0;
address sender = bob;
......@@ -76,6 +87,7 @@ contract CrossDomainOwnable2_Test is Messenger_Initializer {
assertEq(setter.value(), 0);
}
/// @dev Tests that the `onlyOwner` modifier succeeds when called by the messenger.
function test_onlyOwner_succeeds() external {
address owner = setter.owner();
......
// SPDX-License-Identifier: MIT
pragma solidity 0.8.15;
import { Bytes32AddressLib } from "@rari-capital/solmate/src/utils/Bytes32AddressLib.sol";
// Testing utilities
import { CommonTest, Messenger_Initializer } from "./CommonTest.t.sol";
import { CrossDomainOwnable3 } from "../L2/CrossDomainOwnable3.sol";
import { AddressAliasHelper } from "../vendor/AddressAliasHelper.sol";
// Libraries
import { Hashing } from "../libraries/Hashing.sol";
import { Encoding } from "../libraries/Encoding.sol";
import { Bytes32AddressLib } from "@rari-capital/solmate/src/utils/Bytes32AddressLib.sol";
// Target contract dependencies
import { AddressAliasHelper } from "../vendor/AddressAliasHelper.sol";
// Target contract
import { CrossDomainOwnable3 } from "../L2/CrossDomainOwnable3.sol";
contract XDomainSetter3 is CrossDomainOwnable3 {
uint256 public value;
......@@ -19,43 +26,45 @@ contract XDomainSetter3 is CrossDomainOwnable3 {
contract CrossDomainOwnable3_Test is Messenger_Initializer {
XDomainSetter3 setter;
/**
* @notice OpenZeppelin Ownable.sol transferOwnership event
*/
/// @dev OpenZeppelin Ownable.sol transferOwnership event
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
/**
* @notice CrossDomainOwnable3.sol transferOwnership event
*/
/// @dev CrossDomainOwnable3.sol transferOwnership event
event OwnershipTransferred(
address indexed previousOwner,
address indexed newOwner,
bool isLocal
);
/// @dev Sets up the test suite.
function setUp() public override {
super.setUp();
vm.prank(alice);
setter = new XDomainSetter3();
}
/// @dev Tests that the constructor sets the correct variables.
function test_constructor_succeeds() public {
assertEq(setter.owner(), alice);
assertEq(setter.isLocal(), true);
}
/// @dev Tests that `set` reverts when the caller is not the owner.
function test_localOnlyOwner_notOwner_reverts() public {
vm.prank(bob);
vm.expectRevert("CrossDomainOwnable3: caller is not the owner");
setter.set(1);
}
/// @dev Tests that `transferOwnership` reverts when the caller is not the owner.
function test_transferOwnership_notOwner_reverts() public {
vm.prank(bob);
vm.expectRevert("CrossDomainOwnable3: caller is not the owner");
setter.transferOwnership({ _owner: bob, _isLocal: true });
}
/// @dev Tests that the `XDomainSetter3` contract reverts after the ownership
/// has been transferred to a new owner.
function test_crossDomainOnlyOwner_notOwner_reverts() public {
vm.expectEmit(true, true, true, true);
......@@ -78,6 +87,8 @@ contract CrossDomainOwnable3_Test is Messenger_Initializer {
setter.set(1);
}
/// @dev Tests that a relayed message to the `XDomainSetter3` contract reverts
/// after its ownership has been transferred to a new owner.
function test_crossDomainOnlyOwner_notOwner2_reverts() public {
vm.expectEmit(true, true, true, true);
......@@ -126,6 +137,8 @@ contract CrossDomainOwnable3_Test is Messenger_Initializer {
assertEq(setter.value(), 0);
}
/// @dev Tests that the `XDomainSetter3` contract reverts for a non-messenger
/// caller after the ownership has been transferred to a new owner.
function test_crossDomainOnlyOwner_notMessenger_reverts() public {
vm.expectEmit(true, true, true, true);
......@@ -143,18 +156,24 @@ contract CrossDomainOwnable3_Test is Messenger_Initializer {
setter.set(1);
}
/// @dev Tests that `transferOwnership` reverts for ownership transfers
/// to the zero address when set locally.
function test_transferOwnership_zeroAddress_reverts() public {
vm.prank(setter.owner());
vm.expectRevert("CrossDomainOwnable3: new owner is the zero address");
setter.transferOwnership({ _owner: address(0), _isLocal: true });
}
/// @dev Tests that `transferOwnership` reverts for ownership transfers
/// to the zero address.
function test_transferOwnership_noLocalZeroAddress_reverts() public {
vm.prank(setter.owner());
vm.expectRevert("Ownable: new owner is the zero address");
setter.transferOwnership(address(0));
}
/// @dev Tests that `onlyOwner` allows the owner to call a protected
/// function locally.
function test_localOnlyOwner_succeeds() public {
assertEq(setter.isLocal(), true);
vm.prank(setter.owner());
......@@ -162,6 +181,8 @@ contract CrossDomainOwnable3_Test is Messenger_Initializer {
assertEq(setter.value(), 1);
}
/// @dev Tests that `transferOwnership` succeeds when the caller is the
/// owner and the ownership is transferred locally.
function test_localTransferOwnership_succeeds() public {
vm.expectEmit(true, true, true, true, address(setter));
emit OwnershipTransferred(alice, bob);
......@@ -177,10 +198,8 @@ contract CrossDomainOwnable3_Test is Messenger_Initializer {
assertEq(setter.value(), 2);
}
/**
* @notice The existing transferOwnership(address) method
* still exists on the contract
*/
/// @dev The existing transferOwnership(address) method still
/// exists on the contract.
function test_transferOwnershipNoLocal_succeeds() public {
bool isLocal = setter.isLocal();
......@@ -198,6 +217,8 @@ contract CrossDomainOwnable3_Test is Messenger_Initializer {
assertEq(setter.value(), 2);
}
/// @dev Tests that `transferOwnership` succeeds when the caller is the
/// owner and the ownership is transferred non-locally.
function test_crossDomainTransferOwnership_succeeds() public {
vm.expectEmit(true, true, true, true, address(setter));
emit OwnershipTransferred(alice, bob);
......
// SPDX-License-Identifier: MIT
pragma solidity 0.8.15;
// Testing utilities
import { CommonTest } from "./CommonTest.t.sol";
// Target contract
import { DeployerWhitelist } from "../legacy/DeployerWhitelist.sol";
contract DeployerWhitelist_Test is CommonTest {
DeployerWhitelist list;
/// @dev Sets up the test suite.
function setUp() public virtual override {
list = new DeployerWhitelist();
}
// The owner should be address(0)
/// @dev Tests that `owner` is initialized to the zero address.
function test_owner_succeeds() external {
assertEq(list.owner(), address(0));
}
// The storage slot for the owner must be the same
/// @dev Tests that `setOwner` correctly sets the contract owner.
function test_storageSlots_succeeds() external {
vm.prank(list.owner());
list.setOwner(address(1));
......
// SPDX-License-Identifier: MIT
pragma solidity 0.8.15;
// Testing utilities
import { CommonTest } from "./CommonTest.t.sol";
// Libraries
import { Types } from "../libraries/Types.sol";
import { Encoding } from "../libraries/Encoding.sol";
import { LegacyCrossDomainUtils } from "../libraries/LegacyCrossDomainUtils.sol";
// Target contract
import { Encoding } from "../libraries/Encoding.sol";
contract Encoding_Test is CommonTest {
/// @dev Tests encoding and decoding a nonce and version.
function testFuzz_nonceVersioning_succeeds(uint240 _nonce, uint16 _version) external {
(uint240 nonce, uint16 version) = Encoding.decodeVersionedNonce(
Encoding.encodeVersionedNonce(_nonce, _version)
......@@ -15,6 +21,7 @@ contract Encoding_Test is CommonTest {
assertEq(nonce, _nonce);
}
/// @dev Tests decoding a versioned nonce.
function testDiff_decodeVersionedNonce_succeeds(uint240 _nonce, uint16 _version) external {
uint256 nonce = uint256(Encoding.encodeVersionedNonce(_nonce, _version));
(uint256 decodedNonce, uint256 decodedVersion) = ffi.decodeVersionedNonce(nonce);
......@@ -24,6 +31,7 @@ contract Encoding_Test is CommonTest {
assertEq(_nonce, uint240(decodedNonce));
}
/// @dev Tests cross domain message encoding.
function testDiff_encodeCrossDomainMessage_succeeds(
uint240 _nonce,
uint8 _version,
......@@ -57,6 +65,7 @@ contract Encoding_Test is CommonTest {
assertEq(encoding, _encoding);
}
/// @dev Tests legacy cross domain message encoding.
function testFuzz_encodeCrossDomainMessageV0_matchesLegacy_succeeds(
uint240 _nonce,
address _sender,
......@@ -83,6 +92,7 @@ contract Encoding_Test is CommonTest {
assertEq(legacyEncoding, bedrockEncoding);
}
/// @dev Tests deposit transaction encoding.
function testDiff_encodeDepositTransaction_succeeds(
address _from,
address _to,
......
// SPDX-License-Identifier: MIT
pragma solidity 0.8.15;
// Testing utilities
import { Bridge_Initializer } from "./CommonTest.t.sol";
import { FeeVault } from "../universal/FeeVault.sol";
import { L1FeeVault } from "../L2/L1FeeVault.sol";
import { BaseFeeVault } from "../L2/BaseFeeVault.sol";
import { StandardBridge } from "../universal/StandardBridge.sol";
// Libraries
import { Predeploys } from "../libraries/Predeploys.sol";
// Target contract dependencies
import { FeeVault } from "../universal/FeeVault.sol";
// Target contract
import { L1FeeVault } from "../L2/L1FeeVault.sol";
// Test the implementations of the FeeVault
contract FeeVault_Test is Bridge_Initializer {
BaseFeeVault baseFeeVault = BaseFeeVault(payable(Predeploys.BASE_FEE_VAULT));
......@@ -16,6 +22,7 @@ contract FeeVault_Test is Bridge_Initializer {
uint256 constant otherMinimumWithdrawalAmount = 10 ether;
/// @dev Sets up the test suite.
function setUp() public override {
super.setUp();
vm.etch(
......@@ -33,6 +40,7 @@ contract FeeVault_Test is Bridge_Initializer {
vm.label(Predeploys.L1_FEE_VAULT, "L1FeeVault");
}
/// @dev Tests that the constructor sets the correct values.
function test_constructor_succeeds() external {
assertEq(baseFeeVault.RECIPIENT(), alice);
assertEq(l1FeeVault.RECIPIENT(), bob);
......
// SPDX-License-Identifier: MIT
pragma solidity 0.8.15;
// Testing utilities
import { CommonTest } from "./CommonTest.t.sol";
import { GasPriceOracle } from "../L2/GasPriceOracle.sol";
// Target contract dependencies
import { L1Block } from "../L2/L1Block.sol";
import { Predeploys } from "../libraries/Predeploys.sol";
// Target contract
import { GasPriceOracle } from "../L2/GasPriceOracle.sol";
contract GasPriceOracle_Test is CommonTest {
event OverheadUpdated(uint256);
event ScalarUpdated(uint256);
......@@ -15,7 +20,7 @@ contract GasPriceOracle_Test is CommonTest {
L1Block l1Block;
address depositor;
// set the initial L1 context values
// The initial L1 context values
uint64 constant number = 10;
uint64 constant timestamp = 11;
uint256 constant basefee = 100;
......@@ -25,6 +30,7 @@ contract GasPriceOracle_Test is CommonTest {
uint256 constant l1FeeOverhead = 310;
uint256 constant l1FeeScalar = 10;
/// @dev Sets up the test suite.
function setUp() public virtual override {
super.setUp();
// place the L1Block contract at the predeploy address
......@@ -51,36 +57,42 @@ contract GasPriceOracle_Test is CommonTest {
});
}
/// @dev Tests that `l1BaseFee` is set correctly.
function test_l1BaseFee_succeeds() external {
assertEq(gasOracle.l1BaseFee(), basefee);
}
/// @dev Tests that `gasPrice` is set correctly.
function test_gasPrice_succeeds() external {
vm.fee(100);
uint256 gasPrice = gasOracle.gasPrice();
assertEq(gasPrice, 100);
}
/// @dev Tests that `baseFee` is set correctly.
function test_baseFee_succeeds() external {
vm.fee(64);
uint256 gasPrice = gasOracle.baseFee();
assertEq(gasPrice, 64);
}
/// @dev Tests that `scalar` is set correctly.
function test_scalar_succeeds() external {
assertEq(gasOracle.scalar(), l1FeeScalar);
}
/// @dev Tests that `overhead` is set correctly.
function test_overhead_succeeds() external {
assertEq(gasOracle.overhead(), l1FeeOverhead);
}
/// @dev Tests that `decimals` is set correctly.
function test_decimals_succeeds() external {
assertEq(gasOracle.decimals(), 6);
assertEq(gasOracle.DECIMALS(), 6);
}
// Removed in bedrock
/// @dev Tests that `setGasPrice` reverts since it was removed in bedrock.
function test_setGasPrice_doesNotExist_reverts() external {
(bool success, bytes memory returndata) = address(gasOracle).call(
abi.encodeWithSignature("setGasPrice(uint256)", 1)
......@@ -90,7 +102,7 @@ contract GasPriceOracle_Test is CommonTest {
assertEq(returndata, hex"");
}
// Removed in bedrock
/// @dev Tests that `setL1BaseFee` reverts since it was removed in bedrock.
function test_setL1BaseFee_doesNotExist_reverts() external {
(bool success, bytes memory returndata) = address(gasOracle).call(
abi.encodeWithSignature("setL1BaseFee(uint256)", 1)
......
// SPDX-License-Identifier: MIT
pragma solidity 0.8.15;
// Testing utilities
import { CommonTest } from "./CommonTest.t.sol";
// Target contract
import { GovernanceToken } from "../governance/GovernanceToken.sol";
contract GovernanceToken_Test is CommonTest {
......@@ -9,12 +12,14 @@ contract GovernanceToken_Test is CommonTest {
address constant rando = address(0x5678);
GovernanceToken internal gov;
/// @dev Sets up the test suite.
function setUp() public virtual override {
super.setUp();
vm.prank(owner);
gov = new GovernanceToken();
}
/// @dev Tests that the constructor sets the correct initial state.
function test_constructor_succeeds() external {
assertEq(gov.owner(), owner);
assertEq(gov.name(), "Optimism");
......@@ -23,6 +28,7 @@ contract GovernanceToken_Test is CommonTest {
assertEq(gov.totalSupply(), 0);
}
/// @dev Tests that the owner can successfully call `mint`.
function test_mint_fromOwner_succeeds() external {
// Mint 100 tokens.
vm.prank(owner);
......@@ -33,6 +39,7 @@ contract GovernanceToken_Test is CommonTest {
assertEq(gov.totalSupply(), 100);
}
/// @dev Tests that `mint` reverts when called by a non-owner.
function test_mint_fromNotOwner_reverts() external {
// Mint 100 tokens as rando.
vm.prank(rando);
......@@ -44,6 +51,7 @@ contract GovernanceToken_Test is CommonTest {
assertEq(gov.totalSupply(), 0);
}
/// @dev Tests that the owner can successfully call `burn`.
function test_burn_succeeds() external {
// Mint 100 tokens to rando.
vm.prank(owner);
......@@ -58,6 +66,7 @@ contract GovernanceToken_Test is CommonTest {
assertEq(gov.totalSupply(), 50);
}
/// @dev Tests that the owner can successfully call `burnFrom`.
function test_burnFrom_succeeds() external {
// Mint 100 tokens to rando.
vm.prank(owner);
......@@ -76,6 +85,7 @@ contract GovernanceToken_Test is CommonTest {
assertEq(gov.totalSupply(), 50);
}
/// @dev Tests that `transfer` correctly transfers tokens.
function test_transfer_succeeds() external {
// Mint 100 tokens to rando.
vm.prank(owner);
......@@ -91,6 +101,7 @@ contract GovernanceToken_Test is CommonTest {
assertEq(gov.totalSupply(), 100);
}
/// @dev Tests that `approve` correctly sets allowances.
function test_approve_succeeds() external {
// Mint 100 tokens to rando.
vm.prank(owner);
......@@ -104,6 +115,7 @@ contract GovernanceToken_Test is CommonTest {
assertEq(gov.allowance(rando, owner), 50);
}
/// @dev Tests that `transferFrom` correctly transfers tokens.
function test_transferFrom_succeeds() external {
// Mint 100 tokens to rando.
vm.prank(owner);
......@@ -123,6 +135,7 @@ contract GovernanceToken_Test is CommonTest {
assertEq(gov.totalSupply(), 100);
}
/// @dev Tests that `increaseAllowance` correctly increases allowances.
function test_increaseAllowance_succeeds() external {
// Mint 100 tokens to rando.
vm.prank(owner);
......@@ -140,6 +153,7 @@ contract GovernanceToken_Test is CommonTest {
assertEq(gov.allowance(rando, owner), 100);
}
/// @dev Tests that `decreaseAllowance` correctly decreases allowances.
function test_decreaseAllowance_succeeds() external {
// Mint 100 tokens to rando.
vm.prank(owner);
......
// SPDX-License-Identifier: MIT
pragma solidity 0.8.15;
// Testing utilities
import { CommonTest } from "./CommonTest.t.sol";
// Libraries
import { Types } from "../libraries/Types.sol";
import { Hashing } from "../libraries/Hashing.sol";
import { Encoding } from "../libraries/Encoding.sol";
import { LegacyCrossDomainUtils } from "../libraries/LegacyCrossDomainUtils.sol";
// Target contract
import { Hashing } from "../libraries/Hashing.sol";
contract Hashing_hashDepositSource_Test is CommonTest {
/**
* @notice Tests that hashDepositSource returns the correct hash in a simple case.
*/
/// @notice Tests that hashDepositSource returns the correct hash in a simple case.
function test_hashDepositSource_succeeds() external {
assertEq(
Hashing.hashDepositSource(
......@@ -23,9 +26,7 @@ contract Hashing_hashDepositSource_Test is CommonTest {
}
contract Hashing_hashCrossDomainMessage_Test is CommonTest {
/**
* @notice Tests that hashCrossDomainMessage returns the correct hash in a simple case.
*/
/// @notice Tests that hashCrossDomainMessage returns the correct hash in a simple case.
function testDiff_hashCrossDomainMessage_succeeds(
uint240 _nonce,
uint16 _version,
......@@ -45,9 +46,7 @@ contract Hashing_hashCrossDomainMessage_Test is CommonTest {
);
}
/**
* @notice Tests that hashCrossDomainMessageV0 matches the hash of the legacy encoding.
*/
/// @notice Tests that hashCrossDomainMessageV0 matches the hash of the legacy encoding.
function testFuzz_hashCrossDomainMessageV0_matchesLegacy_succeeds(
address _target,
address _sender,
......@@ -69,9 +68,7 @@ contract Hashing_hashCrossDomainMessage_Test is CommonTest {
}
contract Hashing_hashWithdrawal_Test is CommonTest {
/**
* @notice Tests that hashWithdrawal returns the correct hash in a simple case.
*/
/// @notice Tests that hashWithdrawal returns the correct hash in a simple case.
function testDiff_hashWithdrawal_succeeds(
uint256 _nonce,
address _sender,
......@@ -90,9 +87,7 @@ contract Hashing_hashWithdrawal_Test is CommonTest {
}
contract Hashing_hashOutputRootProof_Test is CommonTest {
/**
* @notice Tests that hashOutputRootProof returns the correct hash in a simple case.
*/
/// @notice Tests that hashOutputRootProof returns the correct hash in a simple case.
function testDiff_hashOutputRootProof_succeeds(
bytes32 _version,
bytes32 _stateRoot,
......@@ -119,9 +114,7 @@ contract Hashing_hashOutputRootProof_Test is CommonTest {
}
contract Hashing_hashDepositTransaction_Test is CommonTest {
/**
* @notice Tests that hashDepositTransaction returns the correct hash in a simple case.
*/
/// @notice Tests that hashDepositTransaction returns the correct hash in a simple case.
function testDiff_hashDepositTransaction_succeeds(
address _from,
address _to,
......
// SPDX-License-Identifier: MIT
pragma solidity 0.8.15;
// Testing utilities
import { CommonTest } from "./CommonTest.t.sol";
// Target contract
import { L1Block } from "../L2/L1Block.sol";
contract L1BlockTest is CommonTest {
......@@ -9,6 +12,7 @@ contract L1BlockTest is CommonTest {
address depositor;
bytes32 immutable NON_ZERO_HASH = keccak256(abi.encode(1));
/// @dev Sets up the test suite.
function setUp() public virtual override {
super.setUp();
lb = new L1Block();
......@@ -26,6 +30,7 @@ contract L1BlockTest is CommonTest {
});
}
/// @dev Tests that `setL1BlockValues` updates the values correctly.
function testFuzz_updatesValues_succeeds(
uint64 n,
uint64 t,
......@@ -48,26 +53,32 @@ contract L1BlockTest is CommonTest {
assertEq(lb.l1FeeScalar(), fs);
}
/// @dev Tests that `number` returns the correct value.
function test_number_succeeds() external {
assertEq(lb.number(), uint64(1));
}
/// @dev Tests that `timestamp` returns the correct value.
function test_timestamp_succeeds() external {
assertEq(lb.timestamp(), uint64(2));
}
/// @dev Tests that `basefee` returns the correct value.
function test_basefee_succeeds() external {
assertEq(lb.basefee(), 3);
}
/// @dev Tests that `hash` returns the correct value.
function test_hash_succeeds() external {
assertEq(lb.hash(), NON_ZERO_HASH);
}
/// @dev Tests that `sequenceNumber` returns the correct value.
function test_sequenceNumber_succeeds() external {
assertEq(lb.sequenceNumber(), uint64(4));
}
/// @dev Tests that `setL1BlockValues` can set max values.
function test_updateValues_succeeds() external {
vm.prank(depositor);
lb.setL1BlockValues({
......
// SPDX-License-Identifier: MIT
pragma solidity 0.8.15;
// Testing utilities
import { Test } from "forge-std/Test.sol";
// Target contract dependencies
import { L1Block } from "../L2/L1Block.sol";
import { L1BlockNumber } from "../legacy/L1BlockNumber.sol";
import { Predeploys } from "../libraries/Predeploys.sol";
// Target contract
import { L1BlockNumber } from "../legacy/L1BlockNumber.sol";
contract L1BlockNumberTest is Test {
L1Block lb;
L1BlockNumber bn;
uint64 constant number = 99;
/// @dev Sets up the test suite.
function setUp() external {
vm.etch(Predeploys.L1_BLOCK_ATTRIBUTES, address(new L1Block()).code);
lb = L1Block(Predeploys.L1_BLOCK_ATTRIBUTES);
......@@ -30,16 +36,19 @@ contract L1BlockNumberTest is Test {
});
}
/// @dev Tests that `getL1BlockNumber` returns the set block number.
function test_getL1BlockNumber_succeeds() external {
assertEq(bn.getL1BlockNumber(), number);
}
/// @dev Tests that `fallback` is correctly dispatched.
function test_fallback_succeeds() external {
(bool success, bytes memory ret) = address(bn).call(hex"");
assertEq(success, true);
assertEq(ret, abi.encode(number));
}
/// @dev Tests that `receive` is correctly dispatched.
function test_receive_succeeds() external {
(bool success, bytes memory ret) = address(bn).call{ value: 1 }(hex"");
assertEq(success, true);
......
// SPDX-License-Identifier: MIT
pragma solidity 0.8.15;
// Testing utilities
import { Messenger_Initializer, Reverter, ConfigurableCaller } from "./CommonTest.t.sol";
import { AddressAliasHelper } from "../vendor/AddressAliasHelper.sol";
import { L2ToL1MessagePasser } from "../L2/L2ToL1MessagePasser.sol";
import { L2OutputOracle } from "../L1/L2OutputOracle.sol";
import { L2CrossDomainMessenger } from "../L2/L2CrossDomainMessenger.sol";
import { L1CrossDomainMessenger } from "../L1/L1CrossDomainMessenger.sol";
// Libraries
import { Hashing } from "../libraries/Hashing.sol";
import { Encoding } from "../libraries/Encoding.sol";
import { Types } from "../libraries/Types.sol";
// Target contract dependencies
import { L2ToL1MessagePasser } from "../L2/L2ToL1MessagePasser.sol";
import { AddressAliasHelper } from "../vendor/AddressAliasHelper.sol";
import { L1CrossDomainMessenger } from "../L1/L1CrossDomainMessenger.sol";
// Target contract
import { L2CrossDomainMessenger } from "../L2/L2CrossDomainMessenger.sol";
contract L2CrossDomainMessenger_Test is Messenger_Initializer {
// Receiver address for testing
/// @dev Receiver address for testing
address recipient = address(0xabbaacdc);
/// @dev Tests that `messageNonce` can be decoded correctly.
function test_messageVersion_succeeds() external {
(, uint16 version) = Encoding.decodeVersionedNonce(L2Messenger.messageNonce());
assertEq(version, L2Messenger.MESSAGE_VERSION());
}
/// @dev Tests that `sendMessage` executes successfully.
function test_sendMessage_succeeds() external {
bytes memory xDomainCallData = Encoding.encodeCrossDomainMessage(
L2Messenger.messageNonce(),
......@@ -65,6 +72,8 @@ contract L2CrossDomainMessenger_Test is Messenger_Initializer {
L2Messenger.sendMessage(recipient, hex"ff", uint32(100));
}
/// @dev Tests that `sendMessage` can be called twice and that
/// the nonce increments correctly.
function test_sendMessage_twice_succeeds() external {
uint256 nonce = L2Messenger.messageNonce();
L2Messenger.sendMessage(recipient, hex"aa", uint32(500_000));
......@@ -73,11 +82,13 @@ contract L2CrossDomainMessenger_Test is Messenger_Initializer {
assertEq(nonce + 2, L2Messenger.messageNonce());
}
/// @dev Tests that `sendMessage` reverts if the recipient is the zero address.
function test_xDomainSender_senderNotSet_reverts() external {
vm.expectRevert("CrossDomainMessenger: xDomainMessageSender is not set");
L2Messenger.xDomainMessageSender();
}
/// @dev Tests that `sendMessage` reverts if the message version is not supported.
function test_relayMessage_v2_reverts() external {
address target = address(0xabcd);
address sender = address(L1Messenger);
......@@ -100,6 +111,7 @@ contract L2CrossDomainMessenger_Test is Messenger_Initializer {
);
}
/// @dev Tests that `relayMessage` executes successfully.
function test_relayMessage_succeeds() external {
address target = address(0xabcd);
address sender = address(L1Messenger);
......@@ -137,7 +149,8 @@ contract L2CrossDomainMessenger_Test is Messenger_Initializer {
assertEq(L2Messenger.failedMessages(hash), false);
}
// relayMessage: should revert if attempting to relay a message sent to an L1 system contract
/// @dev Tests that `relayMessage` reverts if attempting to relay
/// a message sent to an L1 system contract.
function test_relayMessage_toSystemContract_reverts() external {
address target = address(messagePasser);
address sender = address(L1Messenger);
......@@ -156,7 +169,8 @@ contract L2CrossDomainMessenger_Test is Messenger_Initializer {
);
}
// relayMessage: the xDomainMessageSender is reset to the original value
/// @dev Tests that `relayMessage` correctly resets the `xDomainMessageSender`
/// to the original value after a message is relayed.
function test_xDomainMessageSender_reset_succeeds() external {
vm.expectRevert("CrossDomainMessenger: xDomainMessageSender is not set");
L2Messenger.xDomainMessageSender();
......@@ -176,8 +190,9 @@ contract L2CrossDomainMessenger_Test is Messenger_Initializer {
L2Messenger.xDomainMessageSender();
}
// relayMessage: should send a successful call to the target contract after the first message
// fails and ETH gets stuck, but the second message succeeds
/// @dev Tests that `relayMessage` is able to send a successful call
/// to the target contract after the first message fails and ETH
/// gets stuck, but the second message succeeds.
function test_relayMessage_retry_succeeds() external {
address target = address(0xabcd);
address sender = address(L1Messenger);
......
// SPDX-License-Identifier: MIT
pragma solidity 0.8.15;
import { ERC721 } from "@openzeppelin/contracts/token/ERC721/ERC721.sol";
// Testing utilities
import { Messenger_Initializer } from "./CommonTest.t.sol";
// Target contract dependencies
import { ERC721 } from "@openzeppelin/contracts/token/ERC721/ERC721.sol";
import { L1ERC721Bridge } from "../L1/L1ERC721Bridge.sol";
import { L2ERC721Bridge } from "../L2/L2ERC721Bridge.sol";
import { OptimismMintableERC721 } from "../universal/OptimismMintableERC721.sol";
// Target contract
import { L2ERC721Bridge } from "../L2/L2ERC721Bridge.sol";
contract TestERC721 is ERC721 {
constructor() ERC721("Test", "TST") {}
......@@ -50,6 +55,7 @@ contract L2ERC721Bridge_Test is Messenger_Initializer {
bytes extraData
);
/// @dev Sets up the test suite.
function setUp() public override {
super.setUp();
......@@ -69,6 +75,7 @@ contract L2ERC721Bridge_Test is Messenger_Initializer {
localToken.approve(address(bridge), tokenId);
}
/// @dev Tests that the constructor sets the correct variables.
function test_constructor_succeeds() public {
assertEq(address(bridge.MESSENGER()), address(L2Messenger));
assertEq(address(bridge.OTHER_BRIDGE()), otherBridge);
......@@ -76,6 +83,8 @@ contract L2ERC721Bridge_Test is Messenger_Initializer {
assertEq(address(bridge.otherBridge()), otherBridge);
}
/// @dev Tests that `bridgeERC721` correctly bridges a token and
/// burns it on the origin chain.
function test_bridgeERC721_succeeds() public {
// Expect a call to the messenger.
vm.expectCall(
......@@ -120,6 +129,7 @@ contract L2ERC721Bridge_Test is Messenger_Initializer {
localToken.ownerOf(tokenId);
}
/// @dev Tests that `bridgeERC721` reverts if the owner is not an EOA.
function test_bridgeERC721_fromContract_reverts() external {
// Bridge the token.
vm.etch(alice, hex"01");
......@@ -131,6 +141,7 @@ contract L2ERC721Bridge_Test is Messenger_Initializer {
assertEq(localToken.ownerOf(tokenId), alice);
}
/// @dev Tests that `bridgeERC721` reverts if the local token is the zero address.
function test_bridgeERC721_localTokenZeroAddress_reverts() external {
// Bridge the token.
vm.prank(alice);
......@@ -141,6 +152,7 @@ contract L2ERC721Bridge_Test is Messenger_Initializer {
assertEq(localToken.ownerOf(tokenId), alice);
}
/// @dev Tests that `bridgeERC721` reverts if the remote token is the zero address.
function test_bridgeERC721_remoteTokenZeroAddress_reverts() external {
// Bridge the token.
vm.prank(alice);
......@@ -151,6 +163,7 @@ contract L2ERC721Bridge_Test is Messenger_Initializer {
assertEq(localToken.ownerOf(tokenId), alice);
}
/// @dev Tests that `bridgeERC721` reverts if the caller is not the token owner.
function test_bridgeERC721_wrongOwner_reverts() external {
// Bridge the token.
vm.prank(bob);
......@@ -161,6 +174,8 @@ contract L2ERC721Bridge_Test is Messenger_Initializer {
assertEq(localToken.ownerOf(tokenId), alice);
}
/// @dev Tests that `bridgeERC721To` correctly bridges a token
/// and burns it on the origin chain.
function test_bridgeERC721To_succeeds() external {
// Expect a call to the messenger.
vm.expectCall(
......@@ -205,6 +220,7 @@ contract L2ERC721Bridge_Test is Messenger_Initializer {
localToken.ownerOf(tokenId);
}
/// @dev Tests that `bridgeERC721To` reverts if the local token is the zero address.
function test_bridgeERC721To_localTokenZeroAddress_reverts() external {
// Bridge the token.
vm.prank(alice);
......@@ -215,6 +231,7 @@ contract L2ERC721Bridge_Test is Messenger_Initializer {
assertEq(localToken.ownerOf(tokenId), alice);
}
/// @dev Tests that `bridgeERC721To` reverts if the remote token is the zero address.
function test_bridgeERC721To_remoteTokenZeroAddress_reverts() external {
// Bridge the token.
vm.prank(alice);
......@@ -225,6 +242,7 @@ contract L2ERC721Bridge_Test is Messenger_Initializer {
assertEq(localToken.ownerOf(tokenId), alice);
}
/// @dev Tests that `bridgeERC721To` reverts if the caller is not the token owner.
function test_bridgeERC721To_wrongOwner_reverts() external {
// Bridge the token.
vm.prank(bob);
......@@ -242,6 +260,7 @@ contract L2ERC721Bridge_Test is Messenger_Initializer {
assertEq(localToken.ownerOf(tokenId), alice);
}
/// @dev Tests that `finalizeBridgeERC721` correctly finalizes a bridged token.
function test_finalizeBridgeERC721_succeeds() external {
// Bridge the token.
vm.prank(alice);
......@@ -278,6 +297,8 @@ contract L2ERC721Bridge_Test is Messenger_Initializer {
assertEq(localToken.ownerOf(tokenId), alice);
}
/// @dev Tests that `finalizeBridgeERC721` reverts if the token is not compliant
/// with the `IOptimismMintableERC721` interface.
function test_finalizeBridgeERC721_interfaceNotCompliant_reverts() external {
// Create a non-compliant token
NonCompliantERC721 nonCompliantToken = new NonCompliantERC721(alice);
......@@ -305,6 +326,7 @@ contract L2ERC721Bridge_Test is Messenger_Initializer {
);
}
/// @dev Tests that `finalizeBridgeERC721` reverts when not called by the remote bridge.
function test_finalizeBridgeERC721_notViaLocalMessenger_reverts() external {
// Finalize a withdrawal.
vm.prank(alice);
......@@ -319,6 +341,7 @@ contract L2ERC721Bridge_Test is Messenger_Initializer {
);
}
/// @dev Tests that `finalizeBridgeERC721` reverts when not called by the remote bridge.
function test_finalizeBridgeERC721_notFromRemoteMessenger_reverts() external {
// Finalize a withdrawal.
vm.mockCall(
......@@ -338,6 +361,8 @@ contract L2ERC721Bridge_Test is Messenger_Initializer {
);
}
/// @dev Tests that `finalizeBridgeERC721` reverts when the local token is the
/// address of the bridge itself.
function test_finalizeBridgeERC721_selfToken_reverts() external {
// Finalize a withdrawal.
vm.mockCall(
......@@ -357,6 +382,7 @@ contract L2ERC721Bridge_Test is Messenger_Initializer {
);
}
/// @dev Tests that `finalizeBridgeERC721` reverts when already finalized.
function test_finalizeBridgeERC721_alreadyExists_reverts() external {
// Finalize a withdrawal.
vm.mockCall(
......@@ -377,12 +403,9 @@ contract L2ERC721Bridge_Test is Messenger_Initializer {
}
}
/**
* @dev A non-compliant ERC721 token that does not implement the full ERC721 interface.
*
* This is used to test that the bridge will revert if the token does not claim to support
* the ERC721 interface.
*/
/// @dev A non-compliant ERC721 token that does not implement the full ERC721 interface.
/// This is used to test that the bridge will revert if the token does not claim to
/// support the ERC721 interface.
contract NonCompliantERC721 {
address internal immutable owner;
......
// SPDX-License-Identifier: MIT
pragma solidity 0.8.15;
// Testing utilities
// Target contract is imported by the `Bridge_Initializer`
import { Bridge_Initializer } from "./CommonTest.t.sol";
import { stdStorage, StdStorage } from "forge-std/Test.sol";
import { CrossDomainMessenger } from "../universal/CrossDomainMessenger.sol";
import { OptimismMintableERC20 } from "../universal/OptimismMintableERC20.sol";
import { Predeploys } from "../libraries/Predeploys.sol";
import { console } from "forge-std/console.sol";
import { StandardBridge } from "../universal/StandardBridge.sol";
import { L2ToL1MessagePasser } from "../L2/L2ToL1MessagePasser.sol";
import { ERC20 } from "@openzeppelin/contracts/token/ERC20/ERC20.sol";
// Libraries
import { Hashing } from "../libraries/Hashing.sol";
import { Types } from "../libraries/Types.sol";
import { ERC20 } from "@openzeppelin/contracts/token/ERC20/ERC20.sol";
// Target contract dependencies
import { Predeploys } from "../libraries/Predeploys.sol";
import { StandardBridge } from "../universal/StandardBridge.sol";
import { OptimismMintableERC20 } from "../universal/OptimismMintableERC20.sol";
contract L2StandardBridge_Test is Bridge_Initializer {
using stdStorage for StdStorage;
/// @dev Tests that the bridge is initialized correctly.
function test_initialize_succeeds() external {
assertEq(address(L2Bridge.messenger()), address(L2Messenger));
assertEq(L1Bridge.l2TokenBridge(), address(L2Bridge));
assertEq(address(L2Bridge.OTHER_BRIDGE()), address(L1Bridge));
}
// receive
// - can accept ETH
/// @dev Tests that the bridge receives ETH and successfully initiates a withdrawal.
function test_receive_succeeds() external {
assertEq(address(messagePasser).balance, 0);
uint256 nonce = L2Messenger.messageNonce();
......@@ -109,8 +113,7 @@ contract L2StandardBridge_Test is Bridge_Initializer {
assertEq(address(messagePasser).balance, 100);
}
// withrdraw
// - requires amount == msg.value
/// @dev Tests that `withdraw` reverts if the amount is not equal to the value sent.
function test_withdraw_insufficientValue_reverts() external {
assertEq(address(messagePasser).balance, 0);
......@@ -119,10 +122,8 @@ contract L2StandardBridge_Test is Bridge_Initializer {
L2Bridge.withdraw(address(Predeploys.LEGACY_ERC20_ETH), 100, 1000, hex"");
}
/**
* @notice Use the legacy `withdraw` interface on the L2StandardBridge to
* withdraw ether from L2 to L1.
*/
/// @dev Tests that the legacy `withdraw` interface on the L2StandardBridge
/// successfully initiates a withdrawal.
function test_withdraw_ether_succeeds() external {
assertTrue(alice.balance >= 100);
assertEq(Predeploys.L2_TO_L1_MESSAGE_PASSER.balance, 0);
......@@ -153,8 +154,7 @@ contract L2StandardBridge_Test is Bridge_Initializer {
}
contract PreBridgeERC20 is Bridge_Initializer {
// withdraw and BridgeERC20 should behave the same when transferring ERC20 tokens
// so they should share the same setup and expectEmit calls
/// @dev Sets up expected calls and emits for a successful ERC20 withdrawal.
function _preBridgeERC20(bool _isLegacy, address _l2Token) internal {
// Alice has 100 L2Token
deal(_l2Token, alice, 100, true);
......@@ -430,10 +430,8 @@ contract PreBridgeERC20To is Bridge_Initializer {
}
contract L2StandardBridge_BridgeERC20To_Test is PreBridgeERC20To {
// withdrawTo
// - token is burned
// - emits WithdrawalInitiated w/ correct recipient
// - calls Withdrawer.initiateWithdrawal
/// @dev Tests that `withdrawTo` burns the tokens, emits `WithdrawalInitiated`,
/// and initiates a withdrawal with `Withdrawer.initiateWithdrawal`.
function test_withdrawTo_withdrawingERC20_succeeds() external {
_preBridgeERC20To({ _isLegacy: true, _l2Token: address(L2Token) });
L2Bridge.withdrawTo(address(L2Token), bob, 100, 1000, hex"");
......@@ -441,10 +439,8 @@ contract L2StandardBridge_BridgeERC20To_Test is PreBridgeERC20To {
assertEq(L2Token.balanceOf(alice), 0);
}
// bridgeERC20To
// - token is burned
// - emits WithdrawalInitiated w/ correct recipient
// - calls Withdrawer.initiateWithdrawal
/// @dev Tests that `bridgeERC20To` burns the tokens, emits `WithdrawalInitiated`,
/// and initiates a withdrawal with `Withdrawer.initiateWithdrawal`.
function test_bridgeERC20To_succeeds() external {
_preBridgeERC20To({ _isLegacy: false, _l2Token: address(L2Token) });
L2Bridge.bridgeERC20To(address(L2Token), address(L1Token), bob, 100, 1000, hex"");
......@@ -453,10 +449,10 @@ contract L2StandardBridge_BridgeERC20To_Test is PreBridgeERC20To {
}
contract L2StandardBridge_Bridge_Test is Bridge_Initializer {
// finalizeDeposit
// - only callable by l1TokenBridge
// - supported token pair emits DepositFinalized
// - invalid deposit calls Withdrawer.initiateWithdrawal
/// @dev Tests that `finalizeDeposit` succeeds. It should:
/// - only be callable by the l1TokenBridge
/// - emit `DepositFinalized` if the token pair is supported
/// - call `Withdrawer.initiateWithdrawal` if the token pair is not supported
function test_finalizeDeposit_depositingERC20_succeeds() external {
vm.mockCall(
address(L2Bridge.messenger()),
......@@ -480,6 +476,7 @@ contract L2StandardBridge_Bridge_Test is Bridge_Initializer {
L2Bridge.finalizeDeposit(address(L1Token), address(L2Token), alice, alice, 100, hex"");
}
/// @dev Tests that `finalizeDeposit` succeeds when depositing ETH.
function test_finalizeDeposit_depositingETH_succeeds() external {
vm.mockCall(
address(L2Bridge.messenger()),
......@@ -505,6 +502,7 @@ contract L2StandardBridge_Bridge_Test is Bridge_Initializer {
L2Bridge.finalizeDeposit(address(L1Token), address(L2Token), alice, alice, 100, hex"");
}
/// @dev Tests that `finalizeDeposit` reverts if the amounts do not match.
function test_finalizeBridgeETH_incorrectValue_reverts() external {
vm.mockCall(
address(L2Bridge.messenger()),
......@@ -517,6 +515,7 @@ contract L2StandardBridge_Bridge_Test is Bridge_Initializer {
L2Bridge.finalizeBridgeETH{ value: 50 }(alice, alice, 100, hex"");
}
/// @dev Tests that `finalizeDeposit` reverts if the receipient is the other bridge.
function test_finalizeBridgeETH_sendToSelf_reverts() external {
vm.mockCall(
address(L2Bridge.messenger()),
......@@ -529,6 +528,7 @@ contract L2StandardBridge_Bridge_Test is Bridge_Initializer {
L2Bridge.finalizeBridgeETH{ value: 100 }(alice, address(L2Bridge), 100, hex"");
}
/// @dev Tests that `finalizeDeposit` reverts if the receipient is the messenger.
function test_finalizeBridgeETH_sendToMessenger_reverts() external {
vm.mockCall(
address(L2Bridge.messenger()),
......@@ -543,6 +543,7 @@ contract L2StandardBridge_Bridge_Test is Bridge_Initializer {
}
contract L2StandardBridge_FinalizeBridgeETH_Test is Bridge_Initializer {
/// @dev Tests that `finalizeBridgeETH` succeeds.
function test_finalizeBridgeETH_succeeds() external {
address messenger = address(L2Bridge.messenger());
vm.mockCall(
......
// SPDX-License-Identifier: MIT
pragma solidity 0.8.15;
// Testing utilities
import { CommonTest } from "./CommonTest.t.sol";
import { L2ToL1MessagePasser } from "../L2/L2ToL1MessagePasser.sol";
// Libraries
import { Types } from "../libraries/Types.sol";
import { Hashing } from "../libraries/Hashing.sol";
// Target contract
import { L2ToL1MessagePasser } from "../L2/L2ToL1MessagePasser.sol";
contract L2ToL1MessagePasserTest is CommonTest {
L2ToL1MessagePasser messagePasser;
......@@ -21,11 +26,14 @@ contract L2ToL1MessagePasserTest is CommonTest {
event WithdrawerBalanceBurnt(uint256 indexed amount);
/// @dev Sets up the test suite.
function setUp() public virtual override {
super.setUp();
messagePasser = new L2ToL1MessagePasser();
}
/// @dev Tests that `initiateWithdrawal` succeeds and correctly sets the state
/// of the message passer for the withdrawal hash.
function testFuzz_initiateWithdrawal_succeeds(
address _sender,
address _target,
......@@ -60,7 +68,8 @@ contract L2ToL1MessagePasserTest is CommonTest {
assertEq(vm.load(address(messagePasser), slot), bytes32(uint256(1)));
}
// Test: initiateWithdrawal should emit the correct log when called by a contract
/// @dev Tests that `initiateWithdrawal` succeeds and emits the correct MessagePassed
/// log when called by a contract.
function test_initiateWithdrawal_fromContract_succeeds() external {
bytes32 withdrawalHash = Hashing.hashWithdrawal(
Types.WithdrawalTransaction(
......@@ -88,7 +97,8 @@ contract L2ToL1MessagePasserTest is CommonTest {
messagePasser.initiateWithdrawal{ value: 100 }(address(4), 64000, hex"");
}
// Test: initiateWithdrawal should emit the correct log when called by an EOA
/// @dev Tests that `initiateWithdrawal` succeeds and emits the correct MessagePassed
/// log when called by an EOA.
function test_initiateWithdrawal_fromEOA_succeeds() external {
uint256 gasLimit = 64000;
address target = address(4);
......@@ -114,7 +124,7 @@ contract L2ToL1MessagePasserTest is CommonTest {
assertEq(nonce + 1, messagePasser.messageNonce());
}
// Test: burn should destroy the ETH held in the contract
/// @dev Tests that `burn` succeeds and destroys the ETH held in the contract.
function test_burn_succeeds() external {
messagePasser.initiateWithdrawal{ value: NON_ZERO_VALUE }(
NON_ZERO_ADDRESS,
......
// SPDX-License-Identifier: MIT
pragma solidity 0.8.15;
// Testing utilities
import { CommonTest } from "./CommonTest.t.sol";
import { LegacyERC20ETH } from "../legacy/LegacyERC20ETH.sol";
// Target contract dependencies
import { Predeploys } from "../libraries/Predeploys.sol";
// Target contract
import { LegacyERC20ETH } from "../legacy/LegacyERC20ETH.sol";
contract LegacyERC20ETH_Test is CommonTest {
LegacyERC20ETH eth;
/// @dev Sets up the test suite.
function setUp() public virtual override {
super.setUp();
eth = new LegacyERC20ETH();
}
/// @dev Tests that the default metadata was set correctly.
function test_metadata_succeeds() external {
assertEq(eth.name(), "Ether");
assertEq(eth.symbol(), "ETH");
assertEq(eth.decimals(), 18);
}
/// @dev Tests that `l2Bridge` and `l1Token` return the correct values.
function test_crossDomain_succeeds() external {
assertEq(eth.l2Bridge(), Predeploys.L2_STANDARD_BRIDGE);
assertEq(eth.l1Token(), address(0));
}
/// @dev Tests that `transfer` reverts since it does not exist.
function test_transfer_doesNotExist_reverts() external {
vm.expectRevert("LegacyERC20ETH: transfer is disabled");
eth.transfer(alice, 100);
}
/// @dev Tests that `approve` reverts since it does not exist.
function test_approve_doesNotExist_reverts() external {
vm.expectRevert("LegacyERC20ETH: approve is disabled");
eth.approve(alice, 100);
}
/// @dev Tests that `transferFrom` reverts since it does not exist.
function test_transferFrom_doesNotExist_reverts() external {
vm.expectRevert("LegacyERC20ETH: transferFrom is disabled");
eth.transferFrom(bob, alice, 100);
}
/// @dev Tests that `increaseAllowance` reverts since it does not exist.
function test_increaseAllowance_doesNotExist_reverts() external {
vm.expectRevert("LegacyERC20ETH: increaseAllowance is disabled");
eth.increaseAllowance(alice, 100);
}
/// @dev Tests that `decreaseAllowance` reverts since it does not exist.
function test_decreaseAllowance_doesNotExist_reverts() external {
vm.expectRevert("LegacyERC20ETH: decreaseAllowance is disabled");
eth.decreaseAllowance(alice, 100);
}
/// @dev Tests that `mint` reverts since it does not exist.
function test_mint_doesNotExist_reverts() external {
vm.expectRevert("LegacyERC20ETH: mint is disabled");
eth.mint(alice, 100);
}
/// @dev Tests that `burn` reverts since it does not exist.
function test_burn_doesNotExist_reverts() external {
vm.expectRevert("LegacyERC20ETH: burn is disabled");
eth.burn(alice, 100);
......
// SPDX-License-Identifier: MIT
pragma solidity 0.8.15;
// Testing utilities
import { CommonTest } from "./CommonTest.t.sol";
import { LegacyMessagePasser } from "../legacy/LegacyMessagePasser.sol";
// Testing contract dependencies
import { Predeploys } from "../libraries/Predeploys.sol";
// Target contract
import { LegacyMessagePasser } from "../legacy/LegacyMessagePasser.sol";
contract LegacyMessagePasser_Test is CommonTest {
LegacyMessagePasser messagePasser;
/// @dev Sets up the test suite.
function setUp() public virtual override {
super.setUp();
messagePasser = new LegacyMessagePasser();
}
/// @dev Tests that `passMessageToL1` succeeds.
function test_passMessageToL1_succeeds() external {
vm.prank(alice);
messagePasser.passMessageToL1(hex"ff");
......
// SPDX-License-Identifier: MIT
pragma solidity 0.8.15;
// Testing utilities
import { CommonTest } from "./CommonTest.t.sol";
import { MintManager } from "../governance/MintManager.sol";
// Target contract dependencies
import { GovernanceToken } from "../governance/GovernanceToken.sol";
// Target contract
import { MintManager } from "../governance/MintManager.sol";
contract MintManager_Initializer is CommonTest {
address constant owner = address(0x1234);
address constant rando = address(0x5678);
GovernanceToken internal gov;
MintManager internal manager;
/// @dev Sets up the test suite.
function setUp() public virtual override {
super.setUp();
......@@ -26,9 +32,7 @@ contract MintManager_Initializer is CommonTest {
}
contract MintManager_constructor_Test is MintManager_Initializer {
/**
* @notice Tests that the constructor properly configures the contract.
*/
/// @dev Tests that the constructor properly configures the contract.
function test_constructor_succeeds() external {
assertEq(manager.owner(), owner);
assertEq(address(manager.governanceToken()), address(gov));
......@@ -36,9 +40,7 @@ contract MintManager_constructor_Test is MintManager_Initializer {
}
contract MintManager_mint_Test is MintManager_Initializer {
/**
* @notice Tests that the mint function properly mints tokens when called by the owner.
*/
/// @dev Tests that the mint function properly mints tokens when called by the owner.
function test_mint_fromOwner_succeeds() external {
// Mint once.
vm.prank(owner);
......@@ -48,9 +50,7 @@ contract MintManager_mint_Test is MintManager_Initializer {
assertEq(gov.balanceOf(owner), 100);
}
/**
* @notice Tests that the mint function reverts when called by a non-owner.
*/
/// @dev Tests that the mint function reverts when called by a non-owner.
function test_mint_fromNotOwner_reverts() external {
// Mint from rando fails.
vm.prank(rando);
......@@ -58,10 +58,8 @@ contract MintManager_mint_Test is MintManager_Initializer {
manager.mint(owner, 100);
}
/**
* @notice Tests that the mint function properly mints tokens when called by the owner a second
* time after the mint period has elapsed.
*/
/// @dev Tests that the mint function properly mints tokens when called by the owner a second
/// time after the mint period has elapsed.
function test_mint_afterPeriodElapsed_succeeds() external {
// Mint once.
vm.prank(owner);
......@@ -79,10 +77,8 @@ contract MintManager_mint_Test is MintManager_Initializer {
assertEq(gov.balanceOf(owner), 102);
}
/**
* @notice Tests that the mint function always reverts when called before the mint period has
* elapsed, even if the caller is the owner.
*/
/// @dev Tests that the mint function always reverts when called before the mint period has
/// elapsed, even if the caller is the owner.
function test_mint_beforePeriodElapsed_reverts() external {
// Mint once.
vm.prank(owner);
......@@ -100,9 +96,7 @@ contract MintManager_mint_Test is MintManager_Initializer {
assertEq(gov.balanceOf(owner), 100);
}
/**
* @notice Tests that the owner cannot mint more than the mint cap.
*/
/// @dev Tests that the owner cannot mint more than the mint cap.
function test_mint_moreThanCap_reverts() external {
// Mint once.
vm.prank(owner);
......@@ -123,9 +117,7 @@ contract MintManager_mint_Test is MintManager_Initializer {
}
contract MintManager_upgrade_Test is MintManager_Initializer {
/**
* @notice Tests that the owner can upgrade the mint manager.
*/
/// @dev Tests that the owner can upgrade the mint manager.
function test_upgrade_fromOwner_succeeds() external {
// Upgrade to new manager.
vm.prank(owner);
......@@ -135,9 +127,7 @@ contract MintManager_upgrade_Test is MintManager_Initializer {
assertEq(gov.owner(), rando);
}
/**
* @notice Tests that the upgrade function reverts when called by a non-owner.
*/
/// @dev Tests that the upgrade function reverts when called by a non-owner.
function test_upgrade_fromNotOwner_reverts() external {
// Upgrade from rando fails.
vm.prank(rando);
......@@ -145,10 +135,8 @@ contract MintManager_upgrade_Test is MintManager_Initializer {
manager.upgrade(rando);
}
/**
* @notice Tests that the upgrade function reverts when attempting to update to the zero
* address, even if the caller is the owner.
*/
/// @dev Tests that the upgrade function reverts when attempting to update to the zero
/// address, even if the caller is the owner.
function test_upgrade_toZeroAddress_reverts() external {
// Upgrade to zero address fails.
vm.prank(owner);
......
// SPDX-License-Identifier: MIT
pragma solidity 0.8.15;
// Testing utilities
import { Test } from "forge-std/Test.sol";
// Target contract dependencies
import { AddressManager } from "../legacy/AddressManager.sol";
// Target contract
import { ResolvedDelegateProxy } from "../legacy/ResolvedDelegateProxy.sol";
contract ResolvedDelegateProxy_Test is Test {
......@@ -10,6 +15,7 @@ contract ResolvedDelegateProxy_Test is Test {
SimpleImplementation internal impl;
SimpleImplementation internal proxy;
/// @dev Sets up the test suite.
function setUp() public {
// Set up the address manager.
addressManager = new AddressManager();
......@@ -22,21 +28,21 @@ contract ResolvedDelegateProxy_Test is Test {
);
}
// Tests that the proxy properly bubbles up returndata when the delegatecall succeeds.
/// @dev Tests that the proxy properly bubbles up returndata when the delegatecall succeeds.
function testFuzz_fallback_delegateCallFoo_succeeds(uint256 x) public {
vm.expectCall(address(impl), abi.encodeWithSelector(impl.foo.selector, x));
assertEq(proxy.foo(x), x);
}
// Tests that the proxy properly bubbles up returndata when the delegatecall reverts.
/// @dev Tests that the proxy properly bubbles up returndata when the delegatecall reverts.
function test_fallback_delegateCallBar_reverts() public {
vm.expectRevert("SimpleImplementation: revert");
vm.expectCall(address(impl), abi.encodeWithSelector(impl.bar.selector));
proxy.bar();
}
// Tests that the proxy fallback reverts as expected if the implementation within the
// address manager is not set.
/// @dev Tests that the proxy fallback reverts as expected if the implementation within the
/// address manager is not set.
function test_fallback_addressManagerNotSet_reverts() public {
AddressManager am = new AddressManager();
SimpleImplementation p = SimpleImplementation(
......
// SPDX-License-Identifier: MIT
pragma solidity 0.8.15;
// Testing utilities
import { CommonTest } from "./CommonTest.t.sol";
// Target contract
import { SafeCall } from "../libraries/SafeCall.sol";
contract SafeCall_Test is CommonTest {
/// @dev Tests that the `send` function succeeds.
function testFuzz_send_succeeds(
address from,
address to,
......@@ -44,6 +48,7 @@ contract SafeCall_Test is CommonTest {
}
}
/// @dev Tests that `call` succeeds.
function testFuzz_call_succeeds(
address from,
address to,
......@@ -84,6 +89,7 @@ contract SafeCall_Test is CommonTest {
}
}
/// @dev Tests that `callWithMinGas` succeeds with enough gas.
function testFuzz_callWithMinGas_hasEnough_succeeds(
address from,
address to,
......@@ -127,6 +133,7 @@ contract SafeCall_Test is CommonTest {
}
}
/// @dev Tests that `callWithMinGas` succeeds for the lower gas bounds.
function test_callWithMinGas_noLeakageLow_succeeds() external {
SimpleSafeCaller caller = new SimpleSafeCaller();
......@@ -151,6 +158,7 @@ contract SafeCall_Test is CommonTest {
}
}
/// @dev Tests that `callWithMinGas` succeeds on the upper gas bounds.
function test_callWithMinGas_noLeakageHigh_succeeds() external {
SimpleSafeCaller caller = new SimpleSafeCaller();
......
// SPDX-License-Identifier: MIT
pragma solidity 0.8.15;
// Testing utilities
import { FeeVault_Initializer } from "./CommonTest.t.sol";
import { StandardBridge } from "../universal/StandardBridge.sol";
// Libraries
import { Predeploys } from "../libraries/Predeploys.sol";
// Target contract dependencies
import { FeeVault } from "../universal/FeeVault.sol";
// Target contract
import { SequencerFeeVault } from "../L2/SequencerFeeVault.sol";
import { StandardBridge } from "../universal/StandardBridge.sol";
import { Predeploys } from "../libraries/Predeploys.sol";
contract SequencerFeeVault_Test is FeeVault_Initializer {
/// @dev Sets up the test suite.
function setUp() public override {
super.setUp();
vm.etch(
......@@ -19,14 +26,17 @@ contract SequencerFeeVault_Test is FeeVault_Initializer {
vm.label(Predeploys.SEQUENCER_FEE_WALLET, "SequencerFeeVault");
}
/// @dev Tests that the minimum withdrawal amount is correct.
function test_minWithdrawalAmount_succeeds() external {
assertEq(vault.MIN_WITHDRAWAL_AMOUNT(), NON_ZERO_VALUE);
}
/// @dev Tests that the l1 fee wallet is correct.
function test_constructor_succeeds() external {
assertEq(vault.l1FeeWallet(), recipient);
}
/// @dev Tests that the fee vault is able to receive ETH.
function test_receive_succeeds() external {
uint256 balance = address(vault).balance;
......@@ -37,6 +47,8 @@ contract SequencerFeeVault_Test is FeeVault_Initializer {
assertEq(address(vault).balance, balance + 100);
}
/// @dev Tests that `withdraw` reverts if the balance is less than the minimum
/// withdrawal amount.
function test_withdraw_notEnough_reverts() external {
assert(address(vault).balance < vault.MIN_WITHDRAWAL_AMOUNT());
......@@ -46,6 +58,7 @@ contract SequencerFeeVault_Test is FeeVault_Initializer {
vault.withdraw();
}
/// @dev Tests that `withdraw` successfully initiates a withdrawal to L1.
function test_withdraw_toL1_succeeds() external {
uint256 amount = vault.MIN_WITHDRAWAL_AMOUNT() + 1;
vm.deal(address(vault), amount);
......@@ -85,6 +98,7 @@ contract SequencerFeeVault_Test is FeeVault_Initializer {
}
contract SequencerFeeVault_L2Withdrawal_Test is FeeVault_Initializer {
/// @dev Sets up the test suite.
function setUp() public override {
super.setUp();
vm.etch(
......@@ -95,6 +109,7 @@ contract SequencerFeeVault_L2Withdrawal_Test is FeeVault_Initializer {
vm.label(Predeploys.SEQUENCER_FEE_WALLET, "SequencerFeeVault");
}
/// @dev Tests that `withdraw` successfully initiates a withdrawal to L2.
function test_withdraw_toL2_succeeds() external {
uint256 amount = vault.MIN_WITHDRAWAL_AMOUNT() + 1;
vm.deal(address(vault), amount);
......
This diff is collapsed.
This diff is collapsed.
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