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

Merge branch 'develop' into specs/system-cfg-block-signer

parents c298a80b 0b745597
......@@ -108,7 +108,7 @@ describe('ERC721 Bridge', () => {
expect(await L1ERC721Bridge.otherBridge()).to.equal(L2ERC721Bridge.address)
expect(await L2ERC721Bridge.otherBridge()).to.equal(L1ERC721Bridge.address)
expect(await OptimismMintableERC721Factory.bridge()).to.equal(
expect(await OptimismMintableERC721Factory.BRIDGE()).to.equal(
L2ERC721Bridge.address
)
......
......@@ -84,7 +84,7 @@ func TestBuildL1DeveloperGenesis(t *testing.T) {
factory, err := bindings.NewOptimismMintableERC20(predeploys.DevOptimismMintableERC20FactoryAddr, sim)
require.NoError(t, err)
bridgeAddr, err := factory.Bridge(callOpts)
bridgeAddr, err := factory.BRIDGE(callOpts)
require.NoError(t, err)
require.Equal(t, predeploys.DevL1StandardBridgeAddr, bridgeAddr)
......
This diff is collapsed.
......@@ -13,6 +13,8 @@ import { FeeVault } from "../universal/FeeVault.sol";
contract BaseFeeVault is FeeVault, Semver {
/**
* @custom:semver 0.0.1
*
* @param _recipient Address that will receive the accumulated fees.
*/
constructor(address _recipient) FeeVault(_recipient, 10 ether) Semver(0, 0, 1) {}
}
......@@ -13,6 +13,8 @@ import { FeeVault } from "../universal/FeeVault.sol";
contract L1FeeVault is FeeVault, Semver {
/**
* @custom:semver 0.0.1
*
* @param _recipient Address that will receive the accumulated fees.
*/
constructor(address _recipient) FeeVault(_recipient, 10 ether) Semver(0, 0, 1) {}
}
......@@ -32,12 +32,16 @@ contract SequencerFeeVaultLegacySpacer {
contract SequencerFeeVault is SequencerFeeVaultLegacySpacer, FeeVault, Semver {
/**
* @custom:semver 0.0.1
*
* @param _recipient Address that will receive the accumulated fees.
*/
constructor(address _recipient) FeeVault(_recipient, 10 ether) Semver(0, 0, 1) {}
/**
* @custom:legacy
* @notice: Legacy getter for the recipient
* @notice Legacy getter for the recipient address.
*
* @return The recipient address.
*/
function l1FeeWallet() public view returns (address) {
return RECIPIENT;
......
......@@ -17,7 +17,7 @@ contract OptimismMintableTokenFactory_Test is Bridge_Initializer {
}
function test_bridge_succeeds() external {
assertEq(address(L2TokenFactory.bridge()), address(L2Bridge));
assertEq(address(L2TokenFactory.BRIDGE()), address(L2Bridge));
}
function test_createStandardL2Token_succeeds() external {
......
......@@ -27,22 +27,10 @@ contract OptimismMintableERC721Factory_Test is ERC721Bridge_Initializer {
}
function test_constructor_succeeds() external {
assertEq(factory.bridge(), address(L2Bridge));
assertEq(factory.remoteChainId(), 1);
assertEq(factory.BRIDGE(), address(L2Bridge));
assertEq(factory.REMOTE_CHAIN_ID(), 1);
}
function test_constructor_zeroBridge_reverts() external {
vm.expectRevert("OptimismMintableERC721Factory: bridge cannot be address(0)");
new OptimismMintableERC721Factory(address(0), 1);
}
function test_constructor_zeroRemoteChainId_reverts() external {
vm.expectRevert("OptimismMintableERC721Factory: remote chain id cannot be zero");
new OptimismMintableERC721Factory(address(L2Bridge), 0);
}
function test_createOptimismMintableERC721_succeeds() external {
// Predict the address based on the factory address and nonce.
address predicted = LibRLP.computeAddress(address(factory), 1);
......
pragma solidity 0.8.15;
import { InvariantTest } from "forge-std/InvariantTest.sol";
import { L2OutputOracle_Initializer } from "../CommonTest.t.sol";
contract L2OutputOracle_MonotonicBlockNumIncrease_Invariant is
InvariantTest,
L2OutputOracle_Initializer
{
function setUp() public override {
super.setUp();
// Set the target contract to the oracle proxy
targetContract(address(oracle));
// Set the target sender to the proposer
targetSender(address(proposer));
// Set the target selector for `proposeL2Output`
// `proposeL2Output` is the only function we care about, as it is the only function
// that can modify the `l2Outputs` array in the oracle.
bytes4[] memory selectors = new bytes4[](1);
selectors[0] = oracle.proposeL2Output.selector;
FuzzSelector memory selector = FuzzSelector({
addr: address(oracle),
selectors: selectors
});
targetSelector(selector);
}
/**
* @custom:invariant The block number of the output root proposals should monotonically
* increase.
*
* When a new output is submitted, it should never be allowed to correspond to a block
* number that is less than the current output.
*/
function invariant_monotonicBlockNumIncrease() external {
// Assert that the block number of proposals must monotonically increase.
assertTrue(oracle.nextBlockNumber() >= oracle.latestBlockNumber());
}
}
pragma solidity 0.8.15;
import { InvariantTest } from "forge-std/InvariantTest.sol";
import { Portal_Initializer } from "../CommonTest.t.sol";
import { Types } from "../../libraries/Types.sol";
contract OptimismPortal_Invariant_Harness is Portal_Initializer, InvariantTest {
// Reusable default values for a test withdrawal
Types.WithdrawalTransaction _defaultTx;
uint256 _proposedOutputIndex;
uint256 _proposedBlockNumber;
bytes32 _stateRoot;
bytes32 _storageRoot;
bytes32 _outputRoot;
bytes32 _withdrawalHash;
bytes[] _withdrawalProof;
Types.OutputRootProof internal _outputRootProof;
function setUp() public virtual override {
super.setUp();
_defaultTx = Types.WithdrawalTransaction({
nonce: 0,
sender: alice,
target: bob,
value: 100,
gasLimit: 100_000,
data: hex""
});
// Get withdrawal proof data we can use for testing.
(_stateRoot, _storageRoot, _outputRoot, _withdrawalHash, _withdrawalProof) = ffi
.getProveWithdrawalTransactionInputs(_defaultTx);
// Setup a dummy output root proof for reuse.
_outputRootProof = Types.OutputRootProof({
version: bytes32(uint256(0)),
stateRoot: _stateRoot,
messagePasserStorageRoot: _storageRoot,
latestBlockhash: bytes32(uint256(0))
});
_proposedBlockNumber = oracle.nextBlockNumber();
_proposedOutputIndex = oracle.nextOutputIndex();
// Configure the oracle to return the output root we've prepared.
vm.warp(oracle.computeL2Timestamp(_proposedBlockNumber) + 1);
vm.prank(oracle.PROPOSER());
oracle.proposeL2Output(_outputRoot, _proposedBlockNumber, 0, 0);
// Warp beyond the finalization period for the block we've proposed.
vm.warp(
oracle.getL2Output(_proposedOutputIndex).timestamp +
op.FINALIZATION_PERIOD_SECONDS() +
1
);
// Fund the portal so that we can withdraw ETH.
vm.deal(address(op), 0xFFFFFFFF);
}
}
contract OptimismPortal_CannotTimeTravel is OptimismPortal_Invariant_Harness {
function setUp() public override {
super.setUp();
// Prove the withdrawal transaction
op.proveWithdrawalTransaction(
_defaultTx,
_proposedOutputIndex,
_outputRootProof,
_withdrawalProof
);
// Set the target contract to the portal proxy
targetContract(address(op));
// Exclude the proxy multisig from the senders so that the proxy cannot be upgraded
excludeSender(address(multisig));
}
/**
* @custom:invariant `finalizeWithdrawalTransaction` should revert if the finalization
* period has not elapsed.
*
* A withdrawal that has been proven should not be able to be finalized until after
* the finalization period has elapsed.
*/
function invariant_cannotFinalizeBeforePeriodHasPassed() external {
vm.expectRevert("OptimismPortal: proven withdrawal finalization period has not elapsed");
op.finalizeWithdrawalTransaction(_defaultTx);
}
}
contract OptimismPortal_CannotFinalizeTwice is OptimismPortal_Invariant_Harness {
function setUp() public override {
super.setUp();
// Prove the withdrawal transaction
op.proveWithdrawalTransaction(
_defaultTx,
_proposedOutputIndex,
_outputRootProof,
_withdrawalProof
);
// Warp past the finalization period.
vm.warp(block.timestamp + op.FINALIZATION_PERIOD_SECONDS() + 1);
// Finalize the withdrawal transaction.
op.finalizeWithdrawalTransaction(_defaultTx);
// Set the target contract to the portal proxy
targetContract(address(op));
// Exclude the proxy multisig from the senders so that the proxy cannot be upgraded
excludeSender(address(multisig));
}
/**
* @custom:invariant `finalizeWithdrawalTransaction` should revert if the withdrawal
* has already been finalized.
*
* Ensures that there is no chain of calls that can be made that allows a withdrawal
* to be finalized twice.
*/
function invariant_cannotFinalizeTwice() external {
vm.expectRevert("OptimismPortal: withdrawal has already been finalized");
op.finalizeWithdrawalTransaction(_defaultTx);
}
}
contract OptimismPortal_CanAlwaysFinalizeAfterWindow is OptimismPortal_Invariant_Harness {
function setUp() public override {
super.setUp();
// Prove the withdrawal transaction
op.proveWithdrawalTransaction(
_defaultTx,
_proposedOutputIndex,
_outputRootProof,
_withdrawalProof
);
// Warp past the finalization period.
vm.warp(block.timestamp + op.FINALIZATION_PERIOD_SECONDS() + 1);
// Set the target contract to the portal proxy
targetContract(address(op));
// Exclude the proxy multisig from the senders so that the proxy cannot be upgraded
excludeSender(address(multisig));
}
/**
* @custom:invariant A withdrawal should **always** be able to be finalized
* `FINALIZATION_PERIOD_SECONDS` after it was successfully proven.
*
* This invariant asserts that there is no chain of calls that can be made that
* will prevent a withdrawal from being finalized exactly `FINALIZATION_PERIOD_SECONDS`
* after it was successfully proven.
*/
function invariant_canAlwaysFinalize() external {
uint256 bobBalanceBefore = address(bob).balance;
op.finalizeWithdrawalTransaction(_defaultTx);
assertEq(address(bob).balance, bobBalanceBefore + _defaultTx.value);
}
}
pragma solidity 0.8.15;
import { InvariantTest } from "forge-std/InvariantTest.sol";
import { StdAssertions } from "forge-std/StdAssertions.sol";
import { SystemConfig } from "../../L1/SystemConfig.sol";
contract SystemConfig_GasLimitLowerBound_Invariant is InvariantTest, StdAssertions {
SystemConfig public config;
function setUp() public {
config = new SystemConfig({
_owner: address(0xbeef),
_overhead: 2100,
_scalar: 1000000,
_batcherHash: bytes32(hex"abcd"),
_gasLimit: 8_000_000,
_unsafeBlockSigner: address(1)
});
// Set the target contract to the `config`
targetContract(address(config));
// Set the target sender to the `config`'s owner (0xbeef)
targetSender(address(0xbeef));
// Set the target selector for `setGasLimit`
// `setGasLimit` is the only function we care about, as it is the only function
// that can modify the gas limit within the SystemConfig.
bytes4[] memory selectors = new bytes4[](1);
selectors[0] = config.setGasLimit.selector;
FuzzSelector memory selector = FuzzSelector({
addr: address(config),
selectors: selectors
});
targetSelector(selector);
}
/**
* @custom:invariant The gas limit of the `SystemConfig` contract can never be lower
* than the hard-coded lower bound.
*/
function invariant_gasLimitLowerBound() external {
assertTrue(config.gasLimit() >= config.MINIMUM_GAS_LIMIT());
}
}
......@@ -382,8 +382,8 @@ abstract contract CrossDomainMessenger is
*/
function baseGas(bytes calldata _message, uint32 _minGasLimit) public pure returns (uint64) {
// We peform the following math on uint64s to avoid overflow errors. Multiplying the
// by MIN_GAS_DYNAMIC_OVERHEAD_NUMERATOR would otherwise limit the _mingasLimit to
// approximately 4.2 MM.
// by MIN_GAS_DYNAMIC_OVERHEAD_NUMERATOR would otherwise limit the _minGasLimit to
// type(uint32).max / MIN_GAS_DYNAMIC_OVERHEAD_NUMERATOR ~= 4.2m.
return
// Dynamic overhead
((uint64(_minGasLimit) * MIN_GAS_DYNAMIC_OVERHEAD_NUMERATOR) /
......
......@@ -6,11 +6,16 @@ import { Predeploys } from "../libraries/Predeploys.sol";
/**
* @title FeeVault
* @notice The FeeVault contract has the base logic for handling transaction fees.
* @notice The FeeVault contract contains the basic logic for the various different vault contracts
* used to hold fee revenue generated by the L2 system.
*/
abstract contract FeeVault {
/**
* @notice Emits each time that a withdrawal occurs
* @notice Emits each time that a withdrawal occurs.
*
* @param value Amount that was withdrawn (in wei).
* @param to Address that the funds were sent to.
* @param from Address that triggered the withdrawal.
*/
event Withdrawal(uint256 value, address to, address from);
......@@ -30,9 +35,8 @@ abstract contract FeeVault {
uint256 public totalProcessed;
/**
* @param _recipient - The L1 account that funds can be withdrawn to.
* @param _minWithdrawalAmount - The min amount of funds before a withdrawal
* can be triggered.
* @param _recipient Wallet that will receive the fees on L1.
* @param _minWithdrawalAmount Minimum balance before a withdrawal can be triggered.
*/
constructor(address _recipient, uint256 _minWithdrawalAmount) {
MIN_WITHDRAWAL_AMOUNT = _minWithdrawalAmount;
......
......@@ -50,16 +50,6 @@ contract OptimismMintableERC20Factory is Semver {
BRIDGE = _bridge;
}
/**
* @custom:legacy
* @notice Legacy getter for StandardBridge address.
*
* @return Address of the StandardBridge on this chain.
*/
function bridge() external view returns (address) {
return BRIDGE;
}
/**
* @custom:legacy
* @notice Creates an instance of the OptimismMintableERC20 contract. Legacy version of the
......
......@@ -41,41 +41,13 @@ contract OptimismMintableERC721Factory is Semver {
* @custom:semver 1.0.0
*
* @param _bridge Address of the ERC721 bridge on this network.
* @param _remoteChainId Chain ID for the remote network.
*/
constructor(address _bridge, uint256 _remoteChainId) Semver(1, 0, 0) {
require(
_bridge != address(0),
"OptimismMintableERC721Factory: bridge cannot be address(0)"
);
require(
_remoteChainId != 0,
"OptimismMintableERC721Factory: remote chain id cannot be zero"
);
BRIDGE = _bridge;
REMOTE_CHAIN_ID = _remoteChainId;
}
/**
* @custom:legacy
* @notice Legacy getter for ERC721 bridge address.
*
* @return Address of the ERC721 bridge on this network.
*/
function bridge() external view returns (address) {
return BRIDGE;
}
/**
* @custom:legacy
* @notice Legacy getter for remote chain ID.
*
* @notice Chain ID for the remote network.
*/
function remoteChainId() external view returns (uint256) {
return REMOTE_CHAIN_ID;
}
/**
* @notice Creates an instance of the standard ERC721.
*
......
......@@ -264,7 +264,7 @@ const deployFn: DeployFunction = async (hre) => {
// Check OptimismMintableERC20Factory was initialized properly.
await assertContractVariable(
OptimismMintableERC20Factory,
'bridge',
'BRIDGE',
L1StandardBridge.address
)
......
......@@ -26,7 +26,7 @@
"test": "yarn build:differential && yarn build:fuzz && forge test",
"coverage": "yarn build:differential && yarn build:fuzz && forge coverage",
"coverage:lcov": "yarn build:differential && yarn build:fuzz && forge coverage --report lcov",
"gas-snapshot": "yarn build:differential && yarn build:fuzz && forge snapshot --no-match-test 'testDiff|testFuzz'",
"gas-snapshot": "yarn build:differential && yarn build:fuzz && forge snapshot --no-match-test 'testDiff|testFuzz|invariant'",
"storage-snapshot": "./scripts/storage-snapshot.sh",
"validate-spacers": "hardhat validate-spacers",
"slither": "./scripts/slither.sh",
......@@ -77,7 +77,7 @@
"dotenv": "^16.0.0",
"ds-test": "https://github.com/dapphub/ds-test.git#9310e879db8ba3ea6d5c6489a579118fd264a3f5",
"ethereum-waffle": "^3.0.0",
"forge-std": "https://github.com/foundry-rs/forge-std.git#5bafa16b4a6aa67c503d96294be846a22a6f6efb",
"forge-std": "https://github.com/foundry-rs/forge-std.git#53331f4cb2e313466f72440f3e73af048c454d02",
"glob": "^7.1.6",
"hardhat-deploy": "^0.11.4",
"solhint": "^3.3.7",
......
AssetReceiverTest:testFail_withdrawERC20() (gas: 199441)
AssetReceiverTest:testFail_withdrawERC20withAmount() (gas: 199389)
AssetReceiverTest:testFail_withdrawERC721() (gas: 55930)
AssetReceiverTest:testFail_withdrawETH() (gas: 10523)
AssetReceiverTest:testFail_withdrawETHwithAmount() (gas: 10639)
AssetReceiverTest:test_constructor() (gas: 9845)
AssetReceiverTest:testFail_withdrawERC20() (gas: 199012)
AssetReceiverTest:testFail_withdrawERC20withAmount() (gas: 199092)
AssetReceiverTest:testFail_withdrawERC721() (gas: 55908)
AssetReceiverTest:testFail_withdrawETH() (gas: 10457)
AssetReceiverTest:testFail_withdrawETHwithAmount() (gas: 10594)
AssetReceiverTest:test_constructor() (gas: 9794)
AssetReceiverTest:test_receive() (gas: 18860)
AssetReceiverTest:test_withdrawERC20() (gas: 183388)
AssetReceiverTest:test_withdrawERC20withAmount() (gas: 182436)
AssetReceiverTest:test_withdrawERC721() (gas: 49149)
AssetReceiverTest:test_withdrawETH() (gas: 26121)
AssetReceiverTest:test_withdrawETHwithAmount() (gas: 26161)
TeleportrWithdrawerTest:testFail_setData() (gas: 8546)
TeleportrWithdrawerTest:testFail_setRecipient() (gas: 9952)
TeleportrWithdrawerTest:testFail_setTeleportr() (gas: 9918)
TeleportrWithdrawerTest:test_constructor() (gas: 9790)
TeleportrWithdrawerTest:test_setData() (gas: 41835)
TeleportrWithdrawerTest:test_setRecipient() (gas: 36176)
TeleportrWithdrawerTest:test_setTeleportr() (gas: 38023)
TeleportrWithdrawerTest:test_withdrawFromTeleportrToContract() (gas: 191517)
TeleportrWithdrawerTest:test_withdrawFromTeleportrToEOA() (gas: 78597)
TransactorTest:testFail_CALL() (gas: 15737)
TransactorTest:testFail_DELEGATECALLL() (gas: 15704)
TransactorTest:test_CALL() (gas: 27132)
TransactorTest:test_DELEGATECALL() (gas: 21266)
TransactorTest:test_constructor() (gas: 9823)
AssetReceiverTest:test_withdrawERC20() (gas: 183064)
AssetReceiverTest:test_withdrawERC20withAmount() (gas: 182146)
AssetReceiverTest:test_withdrawERC721() (gas: 49097)
AssetReceiverTest:test_withdrawETH() (gas: 26179)
AssetReceiverTest:test_withdrawETHwithAmount() (gas: 26108)
AssetReceiverTest:test_attest_bulk() (gas: 592013)
AssetReceiverTest:test_attest_single() (gas: 539644)
OptimistTest:test_optimist_baseURI() (gas: 117016)
OptimistTest:test_optimist_burn() (gas: 77691)
OptimistTest:test_optimist_initialize() (gas: 23095)
OptimistTest:test_optimist_is_on_allow_list() (gas: 52822)
OptimistTest:test_optimist_mint_already_minted() (gas: 99125)
OptimistTest:test_optimist_mint_happy_path() (gas: 99381)
OptimistTest:test_optimist_mint_no_attestation() (gas: 15897)
OptimistTest:test_optimist_mint_secondary_minter() (gas: 100782)
OptimistTest:test_optimist_sbt_approve() (gas: 97490)
OptimistTest:test_optimist_sbt_transfer() (gas: 102537)
OptimistTest:test_optimist_set_approval_for_all() (gas: 101119)
OptimistTest:test_optimist_supports_interface() (gas: 5797)
OptimistTest:test_optimist_token_id_of_owner() (gas: 95251)
OptimistTest:test_optimist_token_uri() (gas: 214371)
TransactorTest:testFail_CALL() (gas: 15658)
TransactorTest:testFail_DELEGATECALLL() (gas: 15632)
TransactorTest:test_CALL() (gas: 26977)
TransactorTest:test_DELEGATECALL() (gas: 21122)
TransactorTest:test_constructor() (gas: 9782)
......@@ -77,7 +77,7 @@
"ds-test": "https://github.com/dapphub/ds-test.git#9310e879db8ba3ea6d5c6489a579118fd264a3f5",
"ethereum-waffle": "^3.4.4",
"ethers": "^5.7.0",
"forge-std": "https://github.com/foundry-rs/forge-std.git#5bafa16b4a6aa67c503d96294be846a22a6f6efb",
"forge-std": "https://github.com/foundry-rs/forge-std.git#53331f4cb2e313466f72440f3e73af048c454d02",
"hardhat": "^2.9.6",
"hardhat-deploy": "^0.11.10",
"hardhat-gas-reporter": "^1.0.8",
......
......@@ -9463,9 +9463,9 @@ forever-agent@~0.6.1:
resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91"
integrity sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=
"forge-std@https://github.com/foundry-rs/forge-std.git#5bafa16b4a6aa67c503d96294be846a22a6f6efb":
version "1.0.0"
resolved "https://github.com/foundry-rs/forge-std.git#5bafa16b4a6aa67c503d96294be846a22a6f6efb"
"forge-std@https://github.com/foundry-rs/forge-std.git#53331f4cb2e313466f72440f3e73af048c454d02":
version "1.2.0"
resolved "https://github.com/foundry-rs/forge-std.git#53331f4cb2e313466f72440f3e73af048c454d02"
form-data@^2.2.0:
version "2.5.1"
......
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