├── .depcheckrc ├── .env.example ├── .eslintrc.base.js ├── .eslintrc.js ├── .gitattributes ├── .gitignore ├── .lintstagedrc.yml ├── .prettierignore ├── .prettierrc.js ├── .solcover.js ├── .solhint.json ├── .solhintignore ├── CHANGELOG.md ├── LICENSE ├── README.md ├── codechecks.yml ├── contracts ├── L1 │ ├── deployment │ │ ├── AddressDictator.sol │ │ └── ChugSplashDictator.sol │ ├── messaging │ │ ├── IL1CrossDomainMessenger.sol │ │ ├── IL1ERC20Bridge.sol │ │ ├── IL1StandardBridge.sol │ │ ├── L1CrossDomainMessenger.sol │ │ └── L1StandardBridge.sol │ ├── rollup │ │ ├── CanonicalTransactionChain.sol │ │ ├── ChainStorageContainer.sol │ │ ├── ICanonicalTransactionChain.sol │ │ ├── IChainStorageContainer.sol │ │ ├── IStateCommitmentChain.sol │ │ └── StateCommitmentChain.sol │ └── verification │ │ ├── BondManager.sol │ │ └── IBondManager.sol ├── L2 │ ├── messaging │ │ ├── IL2CrossDomainMessenger.sol │ │ ├── IL2ERC20Bridge.sol │ │ ├── L2CrossDomainMessenger.sol │ │ ├── L2StandardBridge.sol │ │ └── L2StandardTokenFactory.sol │ └── predeploys │ │ ├── OVM_DeployerWhitelist.sol │ │ ├── OVM_ETH.sol │ │ ├── OVM_GasPriceOracle.sol │ │ ├── OVM_L2ToL1MessagePasser.sol │ │ ├── OVM_SequencerFeeVault.sol │ │ ├── WETH9.sol │ │ ├── iOVM_L1BlockNumber.sol │ │ └── iOVM_L2ToL1MessagePasser.sol ├── chugsplash │ ├── L1ChugSplashProxy.sol │ └── interfaces │ │ └── iL1ChugSplashDeployer.sol ├── libraries │ ├── bridge │ │ ├── CrossDomainEnabled.sol │ │ ├── ICrossDomainMessenger.sol │ │ └── Lib_CrossDomainUtils.sol │ ├── codec │ │ └── Lib_OVMCodec.sol │ ├── constants │ │ ├── Lib_DefaultValues.sol │ │ └── Lib_PredeployAddresses.sol │ ├── resolver │ │ ├── Lib_AddressManager.sol │ │ ├── Lib_AddressResolver.sol │ │ └── Lib_ResolvedDelegateProxy.sol │ ├── rlp │ │ ├── Lib_RLPReader.sol │ │ └── Lib_RLPWriter.sol │ ├── trie │ │ ├── Lib_MerkleTrie.sol │ │ └── Lib_SecureMerkleTrie.sol │ └── utils │ │ ├── Lib_Buffer.sol │ │ ├── Lib_Bytes32Utils.sol │ │ ├── Lib_BytesUtils.sol │ │ └── Lib_MerkleTree.sol ├── standards │ ├── AddressAliasHelper.sol │ ├── IL2StandardERC20.sol │ └── L2StandardERC20.sol ├── test-helpers │ ├── FailingReceiver.sol │ └── TestERC20.sol └── test-libraries │ ├── bridge │ └── TestLib_CrossDomainUtils.sol │ ├── codec │ └── TestLib_OVMCodec.sol │ ├── rlp │ ├── TestLib_RLPReader.sol │ └── TestLib_RLPWriter.sol │ ├── standards │ └── TestLib_AddressAliasHelper.sol │ ├── trie │ ├── TestLib_MerkleTrie.sol │ └── TestLib_SecureMerkleTrie.sol │ └── utils │ ├── TestLib_Buffer.sol │ ├── TestLib_Bytes32Utils.sol │ ├── TestLib_BytesUtils.sol │ └── TestLib_MerkleTree.sol ├── deploy-config ├── goerli-nightly.ts ├── goerli.ts ├── hardhat.ts ├── kovan.ts ├── local.ts └── mainnet.ts ├── deploy ├── 000-hardhat-setup.ts ├── 001-Lib_AddressManager.deploy.ts ├── 002-OVM_ChainStorageContainer_ctc_batches.deploy.ts ├── 003-OVM_ChainStorageContainer_scc_batches.deploy.ts ├── 004-OVM_CanonicalTransactionChain.deploy.ts ├── 005-OVM_StateCommitmentChain.deploy.ts ├── 006-OVM_BondManager.deploy.ts ├── 007-OVM_L1CrossDomainMessenger.deploy.ts ├── 008-Proxy__OVM_L1CrossDomainMessenger.deploy.ts ├── 009-Proxy__OVM_L1StandardBridge.deploy.ts ├── 010-AddressDictator.deploy.ts ├── 011-set-addresses.ts ├── 012-initialize-Proxy__L1CrossDomainMessenger.ts ├── 013-ChugSplashDictator.deploy.ts ├── 014-OVM_L1StandardBridge.deploy.ts ├── 015-finalize.ts └── 016-fund-accounts.ts ├── deployments └── README.md ├── docs ├── Address.md ├── AddressAliasHelper.md ├── AddressDictator.md ├── AddressUpgradeable.md ├── BondManager.md ├── CanonicalTransactionChain.md ├── ChainStorageContainer.md ├── ChugSplashDictator.md ├── Context.md ├── ContextUpgradeable.md ├── CrossDomainEnabled.md ├── ERC165Checker.md ├── ERC20.md ├── FailingReceiver.md ├── IBondManager.md ├── ICanonicalTransactionChain.md ├── IChainStorageContainer.md ├── ICrossDomainMessenger.md ├── IERC165.md ├── IERC20.md ├── IERC20Metadata.md ├── IL1CrossDomainMessenger.md ├── IL1ERC20Bridge.md ├── IL1StandardBridge.md ├── IL2CrossDomainMessenger.md ├── IL2ERC20Bridge.md ├── IL2StandardERC20.md ├── IStateCommitmentChain.md ├── Initializable.md ├── L1ChugSplashProxy.md ├── L1CrossDomainMessenger.md ├── L1StandardBridge.md ├── L2CrossDomainMessenger.md ├── L2StandardBridge.md ├── L2StandardERC20.md ├── L2StandardTokenFactory.md ├── Lib_AddressManager.md ├── Lib_AddressResolver.md ├── Lib_Buffer.md ├── Lib_Bytes32Utils.md ├── Lib_BytesUtils.md ├── Lib_CrossDomainUtils.md ├── Lib_DefaultValues.md ├── Lib_MerkleTree.md ├── Lib_MerkleTrie.md ├── Lib_OVMCodec.md ├── Lib_PredeployAddresses.md ├── Lib_RLPReader.md ├── Lib_RLPWriter.md ├── Lib_ResolvedDelegateProxy.md ├── Lib_SecureMerkleTrie.md ├── OVM_DeployerWhitelist.md ├── OVM_ETH.md ├── OVM_GasPriceOracle.md ├── OVM_L2ToL1MessagePasser.md ├── OVM_SequencerFeeVault.md ├── Ownable.md ├── OwnableUpgradeable.md ├── PausableUpgradeable.md ├── ReentrancyGuardUpgradeable.md ├── SafeERC20.md ├── StateCommitmentChain.md ├── WETH9.md ├── iL1ChugSplashDeployer.md ├── iOVM_L1BlockNumber.md └── iOVM_L2ToL1MessagePasser.md ├── genesis ├── goerli-nightly.json └── goerli.json ├── hardhat.config.ts ├── package-lock.json ├── package.json ├── scripts ├── generate-artifacts.ts ├── generate-deployed-artifacts.ts ├── generate-markdown.ts ├── legacy-bindings.sh └── ovm-gas-oracle.sh ├── slither.config.json ├── src ├── address-names.ts ├── contract-defs.ts ├── deploy-config.ts ├── deploy-utils.ts ├── index.ts ├── predeploys.ts └── validation-utils.ts ├── tasks ├── fetch-batches.ts ├── index.ts ├── inspect.ts ├── set-owner.ts ├── take-dump.ts ├── validate-address-dictator.ts ├── validate-chugsplash-dictator.ts ├── whitelist.ts └── withdraw-fees.ts ├── test ├── contracts │ ├── L1 │ │ ├── deployment │ │ │ ├── AddressDictator.spec.ts │ │ │ └── ChugSplashDictator.spec.ts │ │ ├── messaging │ │ │ ├── L1CrossDomainMessenger.spec.ts │ │ │ ├── L1StandardBridge.spec.ts │ │ │ └── deposit.gas.spec.ts │ │ ├── rollup │ │ │ ├── CanonicalTransactionChain.gas.spec.ts │ │ │ ├── CanonicalTransactionChain.spec.ts │ │ │ ├── ChainStorageContainer.spec.ts │ │ │ └── StateCommitmentChain.spec.ts │ │ └── verification │ │ │ └── BondManager.spec.ts │ ├── L2 │ │ ├── messaging │ │ │ ├── L2CrossDomainMessenger.spec.ts │ │ │ ├── L2StandardBridge.spec.ts │ │ │ └── L2StandardTokenFactory.spec.ts │ │ └── predeploys │ │ │ ├── OVM_ETH.spec.ts │ │ │ ├── OVM_GasPriceOracle.spec.ts │ │ │ ├── OVM_L2ToL1MessagePasser.spec.ts │ │ │ ├── OVM_SequencerFeeVault.spec.ts │ │ │ └── WETH9.spec.ts │ ├── chugsplash │ │ └── L1ChugSplashProxy.spec.ts │ └── libraries │ │ ├── codec │ │ └── Lib_OVMCodec.spec.ts │ │ ├── rlp │ │ ├── Lib_RLPReader.spec.ts │ │ └── Lib_RLPWriter.spec.ts │ │ ├── standards │ │ └── AddressAliasHelper.spec.ts │ │ ├── trie │ │ ├── Lib_MerkleTrie.spec.ts │ │ └── Lib_SecureMerkleTrie.spec.ts │ │ └── utils │ │ ├── Lib_Buffer.spec.ts │ │ ├── Lib_Bytes32Utils.spec.ts │ │ ├── Lib_BytesUtils.spec.ts │ │ └── Lib_MerkleTree.spec.ts ├── data │ ├── index.ts │ └── json │ │ └── libraries │ │ ├── rlp │ │ ├── Lib_RLPReader.test.json │ │ └── Lib_RLPWriter.test.json │ │ ├── trie │ │ ├── trieanyorder.json │ │ └── trietest.json │ │ └── utils │ │ ├── Lib_Bytes32Utils.test.json │ │ └── Lib_BytesUtils.test.json ├── helpers │ ├── codec │ │ ├── bridge.ts │ │ └── index.ts │ ├── constants.ts │ ├── dummy │ │ ├── batches.ts │ │ └── index.ts │ ├── index.ts │ ├── test-runner │ │ ├── index.ts │ │ └── json-test-runner.ts │ ├── trie │ │ ├── index.ts │ │ └── trie-test-generator.ts │ └── utils │ │ ├── deploy.ts │ │ ├── eth-time.ts │ │ ├── impersonation.ts │ │ └── index.ts └── setup.ts └── tsconfig.json /.depcheckrc: -------------------------------------------------------------------------------- 1 | ignores: [ 2 | "@codechecks/client", 3 | "@ethersproject/bytes", 4 | "@openzeppelin/contracts", 5 | "@openzeppelin/contracts-upgradeable", 6 | "@typechain/ethers-v5", 7 | "prettier-plugin-solidity", 8 | "solhint-plugin-prettier", 9 | "ts-generator", 10 | "@babel/eslint-parser", 11 | "@typescript-eslint/parser", 12 | "eslint-plugin-import", 13 | "eslint-plugin-unicorn", 14 | "eslint-plugin-jsdoc", 15 | "eslint-plugin-prefer-arrow", 16 | "eslint-plugin-react", 17 | "@typescript-eslint/eslint-plugin", 18 | "eslint-config-prettier", 19 | "eslint-plugin-prettier" 20 | ] 21 | -------------------------------------------------------------------------------- /.env.example: -------------------------------------------------------------------------------- 1 | # Name for the network to deploy to ("mainnet", "kovan", etc.) 2 | CONTRACTS_TARGET_NETWORK= 3 | 4 | # Private key that will send deployment transactions 5 | CONTRACTS_DEPLOYER_KEY= 6 | 7 | # RPC URL connected to the L1 chain we're deploying to 8 | CONTRACTS_RPC_URL= 9 | 10 | # Your Etherscan API key for the L1 network 11 | ETHERSCAN_API_KEY= 12 | -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | extends: './.eslintrc.base.js', 3 | ignorePatterns: [ 4 | 'src/contract-artifacts.ts', 5 | 'src/contract-deployed-artifacts.ts', 6 | ], 7 | } 8 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | *.sol linguist-language=Solidity 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | src/contract-artifacts.ts 2 | src/contract-deployed-artifacts.ts 3 | /chugsplash 4 | /L1 5 | /L2 6 | /libraries 7 | /standards 8 | node_modules/ 9 | 10 | 11 | .DS_Store 12 | results 13 | temp 14 | .nyc_output 15 | coverage.json 16 | *.tsbuildinfo 17 | **/lcov.info 18 | 19 | yarn-error.log 20 | .yarn/* 21 | !.yarn/releases 22 | !.yarn/plugins 23 | .pnp.* 24 | 25 | dist 26 | artifacts 27 | cache 28 | 29 | l2geth/build/bin 30 | deployments/custom 31 | coverage* 32 | @ens* 33 | @openzeppelin* 34 | 35 | 36 | deployments/devnetL1 37 | deployments/anvil 38 | 39 | # vim 40 | *.sw* 41 | 42 | # jetbrains 43 | .idea/ 44 | 45 | .env 46 | .env* 47 | !.env.example 48 | *.log 49 | 50 | .devnet 51 | .patex-sepolia 52 | # Ignore local fuzzing results 53 | **/testdata/fuzz/ 54 | 55 | coverage.out 56 | 57 | # Ignore bedrock go bindings local output files 58 | pt-bindings/bin 59 | 60 | 61 | __pycache__ 62 | 63 | # Ignore echidna artifacts 64 | crytic-export 65 | -------------------------------------------------------------------------------- /.lintstagedrc.yml: -------------------------------------------------------------------------------- 1 | "*.{ts,js}": 2 | - eslint 3 | "*.sol": 4 | - yarn solhint -f table 5 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | # WETH9 is a standard we should not modify it. 2 | contracts/L2/predeploys/WETH9.sol 3 | contracts/L2/predeploys/IWETH9.sol 4 | coverage 5 | -------------------------------------------------------------------------------- /.prettierrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | $schema: 'http://json.schemastore.org/prettierrc', 3 | trailingComma: 'es5', 4 | tabWidth: 2, 5 | semi: false, 6 | singleQuote: true, 7 | arrowParens: 'always', 8 | overrides: [ 9 | { 10 | files: '*.sol', 11 | options: { 12 | // These options are native to Prettier. 13 | printWidth: 100, 14 | tabWidth: 4, 15 | useTabs: false, 16 | singleQuote: false, 17 | bracketSpacing: true, 18 | // These options are specific to the Solidity Plugin 19 | explicitTypes: 'always', 20 | compiler: '>=0.8.15', 21 | }, 22 | }, 23 | ], 24 | } 25 | -------------------------------------------------------------------------------- /.solcover.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | skipFiles: [ 3 | './test-helpers', 4 | './test-libraries', 5 | './L2/predeploys/OVM_DeployerWhitelist.sol' 6 | ], 7 | mocha: { 8 | grep: "@skip-on-coverage", 9 | invert: true 10 | } 11 | }; 12 | -------------------------------------------------------------------------------- /.solhint.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "solhint:recommended", 3 | "plugins": ["prettier"], 4 | "rules": { 5 | "prettier/prettier": "error", 6 | "compiler-version": "off", 7 | "code-complexity": ["warn", 5], 8 | "max-line-length": ["error", 100], 9 | "func-param-name-mixedcase": "error", 10 | "modifier-name-mixedcase": "error", 11 | "ordering": "warn", 12 | "not-rely-on-time": "off", 13 | "no-complex-fallback": "off", 14 | "not-rely-on-block-hash": "off", 15 | "reentrancy": "off", 16 | "contract-name-camelcase": "off" 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /.solhintignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | 3 | # WETH9 is a standard we should not modify it. 4 | contracts/L2/predeploys/WETH9.sol 5 | contracts/L2/predeploys/IWETH9.sol 6 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/patex-ecosystem/contracts/1f1b90d1ce03ab84e2eef189548c81043b760243/CHANGELOG.md -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | (The MIT License) 2 | 3 | Copyright 2020-2021 Patex 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining 6 | a copy of this software and associated documentation files (the 7 | "Software"), to deal in the Software without restriction, including 8 | without limitation the rights to use, copy, modify, merge, publish, 9 | distribute, sublicense, and/or sell copies of the Software, and to 10 | permit persons to whom the Software is furnished to do so, subject to 11 | the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be 14 | included in all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 19 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 20 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 21 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 22 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23 | -------------------------------------------------------------------------------- /codechecks.yml: -------------------------------------------------------------------------------- 1 | checks: 2 | - name: eth-gas-reporter/codechecks 3 | settings: 4 | speculativeBranchSelection: false 5 | branches: 6 | - develop 7 | - master 8 | -------------------------------------------------------------------------------- /contracts/L1/deployment/AddressDictator.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity ^0.8.9; 3 | 4 | import { Lib_AddressManager } from "../../libraries/resolver/Lib_AddressManager.sol"; 5 | 6 | /** 7 | * @title AddressDictator 8 | * @dev The AddressDictator (glory to Arstotzka) is a contract that allows us to safely manipulate 9 | * many different addresses in the AddressManager without transferring ownership of the 10 | * AddressManager to a hot wallet or hardware wallet. 11 | */ 12 | contract AddressDictator { 13 | /********* 14 | * Types * 15 | *********/ 16 | 17 | struct NamedAddress { 18 | string name; 19 | address addr; 20 | } 21 | 22 | /************* 23 | * Variables * 24 | *************/ 25 | 26 | Lib_AddressManager public manager; 27 | address public finalOwner; 28 | NamedAddress[] namedAddresses; 29 | 30 | /*************** 31 | * Constructor * 32 | ***************/ 33 | 34 | /** 35 | * @param _manager Address of the AddressManager contract. 36 | * @param _finalOwner Address to transfer AddressManager ownership to afterwards. 37 | * @param _names Array of names to associate an address with. 38 | * @param _addresses Array of addresses to associate with the name. 39 | */ 40 | constructor( 41 | Lib_AddressManager _manager, 42 | address _finalOwner, 43 | string[] memory _names, 44 | address[] memory _addresses 45 | ) { 46 | manager = _manager; 47 | finalOwner = _finalOwner; 48 | require( 49 | _names.length == _addresses.length, 50 | "AddressDictator: Must provide an equal number of names and addresses." 51 | ); 52 | for (uint256 i = 0; i < _names.length; i++) { 53 | namedAddresses.push(NamedAddress({ name: _names[i], addr: _addresses[i] })); 54 | } 55 | } 56 | 57 | /******************** 58 | * Public Functions * 59 | ********************/ 60 | 61 | /** 62 | * Called to finalize the transfer, this function is callable by anyone, but will only result in 63 | * an upgrade if this contract is the owner Address Manager. 64 | */ 65 | // slither-disable-next-line calls-loop 66 | function setAddresses() external { 67 | for (uint256 i = 0; i < namedAddresses.length; i++) { 68 | manager.setAddress(namedAddresses[i].name, namedAddresses[i].addr); 69 | } 70 | // note that this will revert if _finalOwner == currentOwner 71 | manager.transferOwnership(finalOwner); 72 | } 73 | 74 | /** 75 | * Transfers ownership of this contract to the finalOwner. 76 | * Only callable by the Final Owner, which is intended to be our multisig. 77 | * This function shouldn't be necessary, but it gives a sense of reassurance that we can recover 78 | * if something really surprising goes wrong. 79 | */ 80 | function returnOwnership() external { 81 | require(msg.sender == finalOwner, "AddressDictator: only callable by finalOwner"); 82 | manager.transferOwnership(finalOwner); 83 | } 84 | 85 | /****************** 86 | * View Functions * 87 | ******************/ 88 | 89 | /** 90 | * Returns the full namedAddresses array. 91 | */ 92 | function getNamedAddresses() external view returns (NamedAddress[] memory) { 93 | return namedAddresses; 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /contracts/L1/deployment/ChugSplashDictator.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity ^0.8.9; 3 | 4 | import { L1ChugSplashProxy } from "../../chugsplash/L1ChugSplashProxy.sol"; 5 | import { iL1ChugSplashDeployer } from "../../chugsplash/interfaces/iL1ChugSplashDeployer.sol"; 6 | 7 | /** 8 | * @title ChugSplashDictator 9 | * @dev Like the AddressDictator, but specifically for the Proxy__OVM_L1StandardBridge. We're 10 | * working on a generalized version of this but this is good enough for the moment. 11 | */ 12 | contract ChugSplashDictator is iL1ChugSplashDeployer { 13 | /************* 14 | * Variables * 15 | *************/ 16 | 17 | // slither-disable-next-line constable-states 18 | bool public isUpgrading = true; 19 | L1ChugSplashProxy public target; 20 | address public finalOwner; 21 | bytes32 public codeHash; 22 | bytes32 public messengerSlotKey; 23 | bytes32 public messengerSlotVal; 24 | bytes32 public bridgeSlotKey; 25 | bytes32 public bridgeSlotVal; 26 | 27 | /*************** 28 | * Constructor * 29 | ***************/ 30 | 31 | constructor( 32 | L1ChugSplashProxy _target, 33 | address _finalOwner, 34 | bytes32 _codeHash, 35 | bytes32 _messengerSlotKey, 36 | bytes32 _messengerSlotVal, 37 | bytes32 _bridgeSlotKey, 38 | bytes32 _bridgeSlotVal 39 | ) { 40 | target = _target; 41 | finalOwner = _finalOwner; 42 | codeHash = _codeHash; 43 | messengerSlotKey = _messengerSlotKey; 44 | messengerSlotVal = _messengerSlotVal; 45 | bridgeSlotKey = _bridgeSlotKey; 46 | bridgeSlotVal = _bridgeSlotVal; 47 | } 48 | 49 | /******************** 50 | * Public Functions * 51 | ********************/ 52 | 53 | function doActions(bytes memory _code) external { 54 | require(keccak256(_code) == codeHash, "ChugSplashDictator: Incorrect code hash."); 55 | 56 | target.setCode(_code); 57 | target.setStorage(messengerSlotKey, messengerSlotVal); 58 | target.setStorage(bridgeSlotKey, bridgeSlotVal); 59 | target.setOwner(finalOwner); 60 | } 61 | 62 | /** 63 | * Transfers ownership of this contract to the finalOwner. 64 | * Only callable by the finalOwner, which is intended to be our multisig. 65 | * This function shouldn't be necessary, but it gives a sense of reassurance that we can 66 | * recover if something really surprising goes wrong. 67 | */ 68 | function returnOwnership() external { 69 | require(msg.sender == finalOwner, "ChugSplashDictator: only callable by finalOwner"); 70 | 71 | target.setOwner(finalOwner); 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /contracts/L1/messaging/IL1CrossDomainMessenger.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity ^0.8.9; 3 | 4 | /* Library Imports */ 5 | import { Lib_OVMCodec } from "../../libraries/codec/Lib_OVMCodec.sol"; 6 | 7 | /* Interface Imports */ 8 | import { ICrossDomainMessenger } from "../../libraries/bridge/ICrossDomainMessenger.sol"; 9 | 10 | /** 11 | * @title IL1CrossDomainMessenger 12 | */ 13 | interface IL1CrossDomainMessenger is ICrossDomainMessenger { 14 | /******************* 15 | * Data Structures * 16 | *******************/ 17 | 18 | struct L2MessageInclusionProof { 19 | bytes32 stateRoot; 20 | Lib_OVMCodec.ChainBatchHeader stateRootBatchHeader; 21 | Lib_OVMCodec.ChainInclusionProof stateRootProof; 22 | bytes stateTrieWitness; 23 | bytes storageTrieWitness; 24 | } 25 | 26 | /******************** 27 | * Public Functions * 28 | ********************/ 29 | 30 | /** 31 | * Relays a cross domain message to a contract. 32 | * @param _target Target contract address. 33 | * @param _sender Message sender address. 34 | * @param _message Message to send to the target. 35 | * @param _messageNonce Nonce for the provided message. 36 | * @param _proof Inclusion proof for the given message. 37 | */ 38 | function relayMessage( 39 | address _target, 40 | address _sender, 41 | bytes memory _message, 42 | uint256 _messageNonce, 43 | L2MessageInclusionProof memory _proof 44 | ) external; 45 | 46 | /** 47 | * Replays a cross domain message to the target messenger. 48 | * @param _target Target contract address. 49 | * @param _sender Original sender address. 50 | * @param _message Message to send to the target. 51 | * @param _queueIndex CTC Queue index for the message to replay. 52 | * @param _oldGasLimit Original gas limit used to send the message. 53 | * @param _newGasLimit New gas limit to be used for this message. 54 | */ 55 | function replayMessage( 56 | address _target, 57 | address _sender, 58 | bytes memory _message, 59 | uint256 _queueIndex, 60 | uint32 _oldGasLimit, 61 | uint32 _newGasLimit 62 | ) external; 63 | } 64 | -------------------------------------------------------------------------------- /contracts/L1/messaging/IL1StandardBridge.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity >0.5.0 <0.9.0; 3 | 4 | import "./IL1ERC20Bridge.sol"; 5 | 6 | /** 7 | * @title IL1StandardBridge 8 | */ 9 | interface IL1StandardBridge is IL1ERC20Bridge { 10 | /********** 11 | * Events * 12 | **********/ 13 | event ETHDepositInitiated( 14 | address indexed _from, 15 | address indexed _to, 16 | uint256 _amount, 17 | bytes _data 18 | ); 19 | 20 | event ETHWithdrawalFinalized( 21 | address indexed _from, 22 | address indexed _to, 23 | uint256 _amount, 24 | bytes _data 25 | ); 26 | 27 | /******************** 28 | * Public Functions * 29 | ********************/ 30 | 31 | /** 32 | * @dev Deposit an amount of the ETH to the caller's balance on L2. 33 | * @param _l2Gas Gas limit required to complete the deposit on L2. 34 | * @param _data Optional data to forward to L2. This data is provided 35 | * solely as a convenience for external contracts. Aside from enforcing a maximum 36 | * length, these contracts provide no guarantees about its content. 37 | */ 38 | function depositETH(uint32 _l2Gas, bytes calldata _data) external payable; 39 | 40 | /** 41 | * @dev Deposit an amount of ETH to a recipient's balance on L2. 42 | * @param _to L2 address to credit the withdrawal to. 43 | * @param _l2Gas Gas limit required to complete the deposit on L2. 44 | * @param _data Optional data to forward to L2. This data is provided 45 | * solely as a convenience for external contracts. Aside from enforcing a maximum 46 | * length, these contracts provide no guarantees about its content. 47 | */ 48 | function depositETHTo( 49 | address _to, 50 | uint32 _l2Gas, 51 | bytes calldata _data 52 | ) external payable; 53 | 54 | /************************* 55 | * Cross-chain Functions * 56 | *************************/ 57 | 58 | /** 59 | * @dev Complete a withdrawal from L2 to L1, and credit funds to the recipient's balance of the 60 | * L1 ETH token. Since only the xDomainMessenger can call this function, it will never be called 61 | * before the withdrawal is finalized. 62 | * @param _from L2 address initiating the transfer. 63 | * @param _to L1 address to credit the withdrawal to. 64 | * @param _amount Amount of the ERC20 to deposit. 65 | * @param _data Optional data to forward to L2. This data is provided 66 | * solely as a convenience for external contracts. Aside from enforcing a maximum 67 | * length, these contracts provide no guarantees about its content. 68 | */ 69 | function finalizeETHWithdrawal( 70 | address _from, 71 | address _to, 72 | uint256 _amount, 73 | bytes calldata _data 74 | ) external; 75 | } 76 | -------------------------------------------------------------------------------- /contracts/L1/rollup/IChainStorageContainer.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity >0.5.0 <0.9.0; 3 | 4 | /** 5 | * @title IChainStorageContainer 6 | */ 7 | interface IChainStorageContainer { 8 | /******************** 9 | * Public Functions * 10 | ********************/ 11 | 12 | /** 13 | * Sets the container's global metadata field. We're using `bytes27` here because we use five 14 | * bytes to maintain the length of the underlying data structure, meaning we have an extra 15 | * 27 bytes to store arbitrary data. 16 | * @param _globalMetadata New global metadata to set. 17 | */ 18 | function setGlobalMetadata(bytes27 _globalMetadata) external; 19 | 20 | /** 21 | * Retrieves the container's global metadata field. 22 | * @return Container global metadata field. 23 | */ 24 | function getGlobalMetadata() external view returns (bytes27); 25 | 26 | /** 27 | * Retrieves the number of objects stored in the container. 28 | * @return Number of objects in the container. 29 | */ 30 | function length() external view returns (uint256); 31 | 32 | /** 33 | * Pushes an object into the container. 34 | * @param _object A 32 byte value to insert into the container. 35 | */ 36 | function push(bytes32 _object) external; 37 | 38 | /** 39 | * Pushes an object into the container. Function allows setting the global metadata since 40 | * we'll need to touch the "length" storage slot anyway, which also contains the global 41 | * metadata (it's an optimization). 42 | * @param _object A 32 byte value to insert into the container. 43 | * @param _globalMetadata New global metadata for the container. 44 | */ 45 | function push(bytes32 _object, bytes27 _globalMetadata) external; 46 | 47 | /** 48 | * Retrieves an object from the container. 49 | * @param _index Index of the particular object to access. 50 | * @return 32 byte object value. 51 | */ 52 | function get(uint256 _index) external view returns (bytes32); 53 | 54 | /** 55 | * Removes all objects after and including a given index. 56 | * @param _index Object index to delete from. 57 | */ 58 | function deleteElementsAfterInclusive(uint256 _index) external; 59 | 60 | /** 61 | * Removes all objects after and including a given index. Also allows setting the global 62 | * metadata field. 63 | * @param _index Object index to delete from. 64 | * @param _globalMetadata New global metadata for the container. 65 | */ 66 | function deleteElementsAfterInclusive(uint256 _index, bytes27 _globalMetadata) external; 67 | } 68 | -------------------------------------------------------------------------------- /contracts/L1/rollup/IStateCommitmentChain.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity >0.5.0 <0.9.0; 3 | 4 | /* Library Imports */ 5 | import { Lib_OVMCodec } from "../../libraries/codec/Lib_OVMCodec.sol"; 6 | 7 | /** 8 | * @title IStateCommitmentChain 9 | */ 10 | interface IStateCommitmentChain { 11 | /********** 12 | * Events * 13 | **********/ 14 | 15 | event StateBatchAppended( 16 | uint256 indexed _batchIndex, 17 | bytes32 _batchRoot, 18 | uint256 _batchSize, 19 | uint256 _prevTotalElements, 20 | bytes _extraData 21 | ); 22 | 23 | event StateBatchDeleted(uint256 indexed _batchIndex, bytes32 _batchRoot); 24 | 25 | /******************** 26 | * Public Functions * 27 | ********************/ 28 | 29 | /** 30 | * Retrieves the total number of elements submitted. 31 | * @return _totalElements Total submitted elements. 32 | */ 33 | function getTotalElements() external view returns (uint256 _totalElements); 34 | 35 | /** 36 | * Retrieves the total number of batches submitted. 37 | * @return _totalBatches Total submitted batches. 38 | */ 39 | function getTotalBatches() external view returns (uint256 _totalBatches); 40 | 41 | /** 42 | * Retrieves the timestamp of the last batch submitted by the sequencer. 43 | * @return _lastSequencerTimestamp Last sequencer batch timestamp. 44 | */ 45 | function getLastSequencerTimestamp() external view returns (uint256 _lastSequencerTimestamp); 46 | 47 | /** 48 | * Appends a batch of state roots to the chain. 49 | * @param _batch Batch of state roots. 50 | * @param _shouldStartAtElement Index of the element at which this batch should start. 51 | */ 52 | function appendStateBatch(bytes32[] calldata _batch, uint256 _shouldStartAtElement) external; 53 | 54 | /** 55 | * Deletes all state roots after (and including) a given batch. 56 | * @param _batchHeader Header of the batch to start deleting from. 57 | */ 58 | function deleteStateBatch(Lib_OVMCodec.ChainBatchHeader memory _batchHeader) external; 59 | 60 | /** 61 | * Verifies a batch inclusion proof. 62 | * @param _element Hash of the element to verify a proof for. 63 | * @param _batchHeader Header of the batch in which the element was included. 64 | * @param _proof Merkle inclusion proof for the element. 65 | * @return _verified Whether or not the batch inclusion proof is verified. 66 | */ 67 | function verifyStateCommitment( 68 | bytes32 _element, 69 | Lib_OVMCodec.ChainBatchHeader memory _batchHeader, 70 | Lib_OVMCodec.ChainInclusionProof memory _proof 71 | ) external view returns (bool _verified); 72 | 73 | /** 74 | * Checks whether a given batch is still inside its fraud proof window. 75 | * @param _batchHeader Header of the batch to check. 76 | * @return _inside Whether or not the batch is inside the fraud proof window. 77 | */ 78 | function insideFraudProofWindow(Lib_OVMCodec.ChainBatchHeader memory _batchHeader) 79 | external 80 | view 81 | returns (bool _inside); 82 | } 83 | -------------------------------------------------------------------------------- /contracts/L1/verification/BondManager.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity ^0.8.9; 3 | 4 | /* Interface Imports */ 5 | import { IBondManager } from "./IBondManager.sol"; 6 | 7 | /* Contract Imports */ 8 | import { Lib_AddressResolver } from "../../libraries/resolver/Lib_AddressResolver.sol"; 9 | 10 | /** 11 | * @title BondManager 12 | * @dev This contract is, for now, a stub of the "real" BondManager that does nothing but 13 | * allow the "OVM_Proposer" to submit state root batches. 14 | * 15 | */ 16 | contract BondManager is IBondManager, Lib_AddressResolver { 17 | /** 18 | * @param _libAddressManager Address of the Address Manager. 19 | */ 20 | constructor(address _libAddressManager) Lib_AddressResolver(_libAddressManager) {} 21 | 22 | /** 23 | * @inheritdoc IBondManager 24 | */ 25 | // slither-disable-next-line external-function 26 | function isCollateralized(address _who) public view returns (bool) { 27 | // Only authenticate sequencer to submit state root batches. 28 | return _who == resolve("OVM_Proposer"); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /contracts/L1/verification/IBondManager.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity ^0.8.9; 3 | 4 | /** 5 | * @title IBondManager 6 | */ 7 | interface IBondManager { 8 | /******************** 9 | * Public Functions * 10 | ********************/ 11 | 12 | /** 13 | * Checks whether a given address is properly collateralized and can perform actions within 14 | * the system. 15 | * @param _who Address to check. 16 | * @return true if the address is properly collateralized, false otherwise. 17 | */ 18 | function isCollateralized(address _who) external view returns (bool); 19 | } 20 | -------------------------------------------------------------------------------- /contracts/L2/messaging/IL2CrossDomainMessenger.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity ^0.8.9; 3 | 4 | /* Interface Imports */ 5 | import { ICrossDomainMessenger } from "../../libraries/bridge/ICrossDomainMessenger.sol"; 6 | 7 | /** 8 | * @title IL2CrossDomainMessenger 9 | */ 10 | interface IL2CrossDomainMessenger is ICrossDomainMessenger { 11 | /******************** 12 | * Public Functions * 13 | ********************/ 14 | 15 | /** 16 | * Relays a cross domain message to a contract. 17 | * @param _target Target contract address. 18 | * @param _sender Message sender address. 19 | * @param _message Message to send to the target. 20 | * @param _messageNonce Nonce for the provided message. 21 | */ 22 | function relayMessage( 23 | address _target, 24 | address _sender, 25 | bytes memory _message, 26 | uint256 _messageNonce 27 | ) external; 28 | } 29 | -------------------------------------------------------------------------------- /contracts/L2/messaging/L2StandardTokenFactory.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity ^0.8.9; 3 | 4 | /* Contract Imports */ 5 | import { L2StandardERC20 } from "../../standards/L2StandardERC20.sol"; 6 | import { Lib_PredeployAddresses } from "../../libraries/constants/Lib_PredeployAddresses.sol"; 7 | 8 | /** 9 | * @title L2StandardTokenFactory 10 | * @dev Factory contract for creating standard L2 token representations of L1 ERC20s 11 | * compatible with and working on the standard bridge. 12 | */ 13 | contract L2StandardTokenFactory { 14 | event StandardL2TokenCreated(address indexed _l1Token, address indexed _l2Token); 15 | 16 | /** 17 | * @dev Creates an instance of the standard ERC20 token on L2. 18 | * @param _l1Token Address of the corresponding L1 token. 19 | * @param _name ERC20 name. 20 | * @param _symbol ERC20 symbol. 21 | */ 22 | function createStandardL2Token( 23 | address _l1Token, 24 | string memory _name, 25 | string memory _symbol 26 | ) external { 27 | require(_l1Token != address(0), "Must provide L1 token address"); 28 | 29 | L2StandardERC20 l2Token = new L2StandardERC20( 30 | Lib_PredeployAddresses.L2_STANDARD_BRIDGE, 31 | _l1Token, 32 | _name, 33 | _symbol 34 | ); 35 | 36 | emit StandardL2TokenCreated(_l1Token, address(l2Token)); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /contracts/L2/predeploys/OVM_DeployerWhitelist.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity ^0.8.9; 3 | 4 | /** 5 | * @title OVM_DeployerWhitelist 6 | * @dev The Deployer Whitelist is a temporary predeploy used to provide additional safety during the 7 | * initial phases of our mainnet roll out. It is owned by the Patex team, and defines accounts 8 | * which are allowed to deploy contracts on Layer2. The Execution Manager will only allow an 9 | * ovmCREATE or ovmCREATE2 operation to proceed if the deployer's address whitelisted. 10 | */ 11 | contract OVM_DeployerWhitelist { 12 | /********** 13 | * Events * 14 | **********/ 15 | 16 | event OwnerChanged(address oldOwner, address newOwner); 17 | event WhitelistStatusChanged(address deployer, bool whitelisted); 18 | event WhitelistDisabled(address oldOwner); 19 | 20 | /********************** 21 | * Contract Constants * 22 | **********************/ 23 | 24 | // WARNING: When owner is set to address(0), the whitelist is disabled. 25 | address public owner; 26 | mapping(address => bool) public whitelist; 27 | 28 | /********************** 29 | * Function Modifiers * 30 | **********************/ 31 | 32 | /** 33 | * Blocks functions to anyone except the contract owner. 34 | */ 35 | modifier onlyOwner() { 36 | require(msg.sender == owner, "Function can only be called by the owner of this contract."); 37 | _; 38 | } 39 | 40 | /******************** 41 | * Public Functions * 42 | ********************/ 43 | 44 | /** 45 | * Adds or removes an address from the deployment whitelist. 46 | * @param _deployer Address to update permissions for. 47 | * @param _isWhitelisted Whether or not the address is whitelisted. 48 | */ 49 | function setWhitelistedDeployer(address _deployer, bool _isWhitelisted) external onlyOwner { 50 | whitelist[_deployer] = _isWhitelisted; 51 | emit WhitelistStatusChanged(_deployer, _isWhitelisted); 52 | } 53 | 54 | /** 55 | * Updates the owner of this contract. 56 | * @param _owner Address of the new owner. 57 | */ 58 | // slither-disable-next-line external-function 59 | function setOwner(address _owner) public onlyOwner { 60 | // Prevent users from setting the whitelist owner to address(0) except via 61 | // enableArbitraryContractDeployment. If you want to burn the whitelist owner, send it to 62 | // any other address that doesn't have a corresponding knowable private key. 63 | require( 64 | _owner != address(0), 65 | "OVM_DeployerWhitelist: can only be disabled via enableArbitraryContractDeployment" 66 | ); 67 | 68 | emit OwnerChanged(owner, _owner); 69 | owner = _owner; 70 | } 71 | 72 | /** 73 | * Permanently enables arbitrary contract deployment and deletes the owner. 74 | */ 75 | function enableArbitraryContractDeployment() external onlyOwner { 76 | emit WhitelistDisabled(owner); 77 | owner = address(0); 78 | } 79 | 80 | /** 81 | * Checks whether an address is allowed to deploy contracts. 82 | * @param _deployer Address to check. 83 | * @return _allowed Whether or not the address can deploy contracts. 84 | */ 85 | function isDeployerAllowed(address _deployer) external view returns (bool) { 86 | return (owner == address(0) || whitelist[_deployer]); 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /contracts/L2/predeploys/OVM_ETH.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity ^0.8.9; 3 | 4 | /* Library Imports */ 5 | import { Lib_PredeployAddresses } from "../../libraries/constants/Lib_PredeployAddresses.sol"; 6 | 7 | /* Contract Imports */ 8 | import { L2StandardERC20 } from "../../standards/L2StandardERC20.sol"; 9 | 10 | /** 11 | * @title OVM_ETH 12 | * @dev The ETH predeploy provides an ERC20 interface for ETH deposited to Layer 2. Note that 13 | * unlike on Layer 1, Layer 2 accounts do not have a balance field. 14 | */ 15 | contract OVM_ETH is L2StandardERC20 { 16 | /*************** 17 | * Constructor * 18 | ***************/ 19 | 20 | constructor() 21 | L2StandardERC20(Lib_PredeployAddresses.L2_STANDARD_BRIDGE, address(0), "Ether", "ETH") 22 | {} 23 | 24 | // ETH ERC20 features are disabled until further notice. 25 | 26 | function transfer(address recipient, uint256 amount) public virtual override returns (bool) { 27 | revert("OVM_ETH: transfer is disabled pending further community discussion."); 28 | } 29 | 30 | function approve(address spender, uint256 amount) public virtual override returns (bool) { 31 | revert("OVM_ETH: approve is disabled pending further community discussion."); 32 | } 33 | 34 | function transferFrom( 35 | address sender, 36 | address recipient, 37 | uint256 amount 38 | ) public virtual override returns (bool) { 39 | revert("OVM_ETH: transferFrom is disabled pending further community discussion."); 40 | } 41 | 42 | function increaseAllowance(address spender, uint256 addedValue) 43 | public 44 | virtual 45 | override 46 | returns (bool) 47 | { 48 | revert("OVM_ETH: increaseAllowance is disabled pending further community discussion."); 49 | } 50 | 51 | function decreaseAllowance(address spender, uint256 subtractedValue) 52 | public 53 | virtual 54 | override 55 | returns (bool) 56 | { 57 | revert("OVM_ETH: decreaseAllowance is disabled pending further community discussion."); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /contracts/L2/predeploys/OVM_L2ToL1MessagePasser.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity ^0.8.9; 3 | 4 | /* Interface Imports */ 5 | import { iOVM_L2ToL1MessagePasser } from "./iOVM_L2ToL1MessagePasser.sol"; 6 | 7 | /** 8 | * @title OVM_L2ToL1MessagePasser 9 | * @dev The L2 to L1 Message Passer is a utility contract which facilitate an L1 proof of the 10 | * of a message on L2. The L1 Cross Domain Messenger performs this proof in its 11 | * _verifyStorageProof function, which verifies the existence of the transaction hash in this 12 | * contract's `sentMessages` mapping. 13 | */ 14 | contract OVM_L2ToL1MessagePasser is iOVM_L2ToL1MessagePasser { 15 | /********************** 16 | * Contract Variables * 17 | **********************/ 18 | 19 | mapping(bytes32 => bool) public sentMessages; 20 | 21 | /******************** 22 | * Public Functions * 23 | ********************/ 24 | 25 | /** 26 | * @inheritdoc iOVM_L2ToL1MessagePasser 27 | */ 28 | // slither-disable-next-line external-function 29 | function passMessageToL1(bytes memory _message) public { 30 | // Note: although this function is public, only messages sent from the 31 | // L2CrossDomainMessenger will be relayed by the L1CrossDomainMessenger. 32 | // This is enforced by a check in L1CrossDomainMessenger._verifyStorageProof(). 33 | sentMessages[keccak256(abi.encodePacked(_message, msg.sender))] = true; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /contracts/L2/predeploys/OVM_SequencerFeeVault.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity ^0.8.9; 3 | 4 | /* Library Imports */ 5 | import { Lib_PredeployAddresses } from "../../libraries/constants/Lib_PredeployAddresses.sol"; 6 | 7 | /* Contract Imports */ 8 | import { L2StandardBridge } from "../messaging/L2StandardBridge.sol"; 9 | 10 | /** 11 | * @title OVM_SequencerFeeVault 12 | * @dev Simple holding contract for fees paid to the Sequencer. Likely to be replaced in the future 13 | * but "good enough for now". 14 | */ 15 | contract OVM_SequencerFeeVault { 16 | /************* 17 | * Constants * 18 | *************/ 19 | 20 | // Minimum ETH balance that can be withdrawn in a single withdrawal. 21 | uint256 public constant MIN_WITHDRAWAL_AMOUNT = 15 ether; 22 | 23 | /************* 24 | * Variables * 25 | *************/ 26 | 27 | // Address on L1 that will hold the fees once withdrawn. Dynamically initialized within l2geth. 28 | address public l1FeeWallet; 29 | 30 | /*************** 31 | * Constructor * 32 | ***************/ 33 | 34 | /** 35 | * @param _l1FeeWallet Initial address for the L1 wallet that will hold fees once withdrawn. 36 | * Currently HAS NO EFFECT in production because l2geth will mutate this storage slot during 37 | * the genesis block. This is ONLY for testing purposes. 38 | */ 39 | constructor(address _l1FeeWallet) { 40 | l1FeeWallet = _l1FeeWallet; 41 | } 42 | 43 | /************ 44 | * Fallback * 45 | ************/ 46 | 47 | // slither-disable-next-line locked-ether 48 | receive() external payable {} 49 | 50 | /******************** 51 | * Public Functions * 52 | ********************/ 53 | 54 | // slither-disable-next-line external-function 55 | function withdraw() public { 56 | require( 57 | address(this).balance >= MIN_WITHDRAWAL_AMOUNT, 58 | // solhint-disable-next-line max-line-length 59 | "OVM_SequencerFeeVault: withdrawal amount must be greater than minimum withdrawal amount" 60 | ); 61 | 62 | L2StandardBridge(Lib_PredeployAddresses.L2_STANDARD_BRIDGE).withdrawTo( 63 | Lib_PredeployAddresses.OVM_ETH, 64 | l1FeeWallet, 65 | address(this).balance, 66 | 0, 67 | bytes("") 68 | ); 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /contracts/L2/predeploys/iOVM_L1BlockNumber.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity ^0.8.9; 3 | 4 | /** 5 | * @title iOVM_L1BlockNumber 6 | */ 7 | interface iOVM_L1BlockNumber { 8 | /******************** 9 | * Public Functions * 10 | ********************/ 11 | 12 | /** 13 | * @return Block number of L1 14 | */ 15 | function getL1BlockNumber() external view returns (uint256); 16 | } 17 | -------------------------------------------------------------------------------- /contracts/L2/predeploys/iOVM_L2ToL1MessagePasser.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity ^0.8.9; 3 | 4 | /** 5 | * @title iOVM_L2ToL1MessagePasser 6 | */ 7 | interface iOVM_L2ToL1MessagePasser { 8 | /********** 9 | * Events * 10 | **********/ 11 | 12 | event L2ToL1Message(uint256 _nonce, address _sender, bytes _data); 13 | 14 | /******************** 15 | * Public Functions * 16 | ********************/ 17 | 18 | /** 19 | * Passes a message to L1. 20 | * @param _message Message to pass to L1. 21 | */ 22 | function passMessageToL1(bytes calldata _message) external; 23 | } 24 | -------------------------------------------------------------------------------- /contracts/chugsplash/interfaces/iL1ChugSplashDeployer.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity ^0.8.9; 3 | 4 | /** 5 | * @title iL1ChugSplashDeployer 6 | */ 7 | interface iL1ChugSplashDeployer { 8 | function isUpgrading() external view returns (bool); 9 | } 10 | -------------------------------------------------------------------------------- /contracts/libraries/bridge/CrossDomainEnabled.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity >0.5.0 <0.9.0; 3 | 4 | /* Interface Imports */ 5 | import { ICrossDomainMessenger } from "./ICrossDomainMessenger.sol"; 6 | 7 | /** 8 | * @title CrossDomainEnabled 9 | * @dev Helper contract for contracts performing cross-domain communications 10 | * 11 | * Compiler used: defined by inheriting contract 12 | */ 13 | contract CrossDomainEnabled { 14 | /************* 15 | * Variables * 16 | *************/ 17 | 18 | // Messenger contract used to send and recieve messages from the other domain. 19 | address public messenger; 20 | 21 | /*************** 22 | * Constructor * 23 | ***************/ 24 | 25 | /** 26 | * @param _messenger Address of the CrossDomainMessenger on the current layer. 27 | */ 28 | constructor(address _messenger) { 29 | messenger = _messenger; 30 | } 31 | 32 | /********************** 33 | * Function Modifiers * 34 | **********************/ 35 | 36 | /** 37 | * Enforces that the modified function is only callable by a specific cross-domain account. 38 | * @param _sourceDomainAccount The only account on the originating domain which is 39 | * authenticated to call this function. 40 | */ 41 | modifier onlyFromCrossDomainAccount(address _sourceDomainAccount) { 42 | require( 43 | msg.sender == address(getCrossDomainMessenger()), 44 | "OVM_XCHAIN: messenger contract unauthenticated" 45 | ); 46 | 47 | require( 48 | getCrossDomainMessenger().xDomainMessageSender() == _sourceDomainAccount, 49 | "OVM_XCHAIN: wrong sender of cross-domain message" 50 | ); 51 | 52 | _; 53 | } 54 | 55 | /********************** 56 | * Internal Functions * 57 | **********************/ 58 | 59 | /** 60 | * Gets the messenger, usually from storage. This function is exposed in case a child contract 61 | * needs to override. 62 | * @return The address of the cross-domain messenger contract which should be used. 63 | */ 64 | function getCrossDomainMessenger() internal virtual returns (ICrossDomainMessenger) { 65 | return ICrossDomainMessenger(messenger); 66 | } 67 | 68 | /**q 69 | * Sends a message to an account on another domain 70 | * @param _crossDomainTarget The intended recipient on the destination domain 71 | * @param _message The data to send to the target (usually calldata to a function with 72 | * `onlyFromCrossDomainAccount()`) 73 | * @param _gasLimit The gasLimit for the receipt of the message on the target domain. 74 | */ 75 | function sendCrossDomainMessage( 76 | address _crossDomainTarget, 77 | uint32 _gasLimit, 78 | bytes memory _message 79 | ) internal { 80 | // slither-disable-next-line reentrancy-events, reentrancy-benign 81 | getCrossDomainMessenger().sendMessage(_crossDomainTarget, _message, _gasLimit); 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /contracts/libraries/bridge/ICrossDomainMessenger.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity >0.5.0 <0.9.0; 3 | 4 | /** 5 | * @title ICrossDomainMessenger 6 | */ 7 | interface ICrossDomainMessenger { 8 | /********** 9 | * Events * 10 | **********/ 11 | 12 | event SentMessage( 13 | address indexed target, 14 | address sender, 15 | bytes message, 16 | uint256 messageNonce, 17 | uint256 gasLimit 18 | ); 19 | event RelayedMessage(bytes32 indexed msgHash); 20 | event FailedRelayedMessage(bytes32 indexed msgHash); 21 | 22 | /************* 23 | * Variables * 24 | *************/ 25 | 26 | function xDomainMessageSender() external view returns (address); 27 | 28 | /******************** 29 | * Public Functions * 30 | ********************/ 31 | 32 | /** 33 | * Sends a cross domain message to the target messenger. 34 | * @param _target Target contract address. 35 | * @param _message Message to send to the target. 36 | * @param _gasLimit Gas limit for the provided message. 37 | */ 38 | function sendMessage( 39 | address _target, 40 | bytes calldata _message, 41 | uint32 _gasLimit 42 | ) external; 43 | } 44 | -------------------------------------------------------------------------------- /contracts/libraries/bridge/Lib_CrossDomainUtils.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity ^0.8.9; 3 | 4 | /** 5 | * @title Lib_CrossDomainUtils 6 | */ 7 | library Lib_CrossDomainUtils { 8 | /** 9 | * Generates the correct cross domain calldata for a message. 10 | * @param _target Target contract address. 11 | * @param _sender Message sender address. 12 | * @param _message Message to send to the target. 13 | * @param _messageNonce Nonce for the provided message. 14 | * @return ABI encoded cross domain calldata. 15 | */ 16 | function encodeXDomainCalldata( 17 | address _target, 18 | address _sender, 19 | bytes memory _message, 20 | uint256 _messageNonce 21 | ) internal pure returns (bytes memory) { 22 | return 23 | abi.encodeWithSignature( 24 | "relayMessage(address,address,bytes,uint256)", 25 | _target, 26 | _sender, 27 | _message, 28 | _messageNonce 29 | ); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /contracts/libraries/constants/Lib_DefaultValues.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity ^0.8.9; 3 | 4 | /** 5 | * @title Lib_DefaultValues 6 | */ 7 | library Lib_DefaultValues { 8 | // The default x-domain message sender being set to a non-zero value makes 9 | // deployment a bit more expensive, but in exchange the refund on every call to 10 | // `relayMessage` by the L1 and L2 messengers will be higher. 11 | address internal constant DEFAULT_XDOMAIN_SENDER = 0x000000000000000000000000000000000000dEaD; 12 | } 13 | -------------------------------------------------------------------------------- /contracts/libraries/constants/Lib_PredeployAddresses.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity ^0.8.9; 3 | 4 | /** 5 | * @title Lib_PredeployAddresses 6 | */ 7 | library Lib_PredeployAddresses { 8 | address internal constant L2_TO_L1_MESSAGE_PASSER = 0x4200000000000000000000000000000000000000; 9 | address internal constant L1_MESSAGE_SENDER = 0x4200000000000000000000000000000000000001; 10 | address internal constant DEPLOYER_WHITELIST = 0x4200000000000000000000000000000000000002; 11 | address payable internal constant OVM_ETH = payable(0xDeadDeAddeAddEAddeadDEaDDEAdDeaDDeAD0000); 12 | address internal constant L2_CROSS_DOMAIN_MESSENGER = 13 | 0x4200000000000000000000000000000000000007; 14 | address internal constant LIB_ADDRESS_MANAGER = 0x4200000000000000000000000000000000000008; 15 | address internal constant PROXY_EOA = 0x4200000000000000000000000000000000000009; 16 | address internal constant L2_STANDARD_BRIDGE = 0x4200000000000000000000000000000000000010; 17 | address internal constant SEQUENCER_FEE_WALLET = 0x4200000000000000000000000000000000000011; 18 | address internal constant L2_STANDARD_TOKEN_FACTORY = 19 | 0x4200000000000000000000000000000000000012; 20 | address internal constant L1_BLOCK_NUMBER = 0x4200000000000000000000000000000000000013; 21 | } 22 | -------------------------------------------------------------------------------- /contracts/libraries/resolver/Lib_AddressManager.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity ^0.8.9; 3 | 4 | /* External Imports */ 5 | import { Ownable } from "@openzeppelin/contracts/access/Ownable.sol"; 6 | 7 | /** 8 | * @title Lib_AddressManager 9 | */ 10 | contract Lib_AddressManager is Ownable { 11 | /********** 12 | * Events * 13 | **********/ 14 | 15 | event AddressSet(string indexed _name, address _newAddress, address _oldAddress); 16 | 17 | /************* 18 | * Variables * 19 | *************/ 20 | 21 | mapping(bytes32 => address) private addresses; 22 | 23 | /******************** 24 | * Public Functions * 25 | ********************/ 26 | 27 | /** 28 | * Changes the address associated with a particular name. 29 | * @param _name String name to associate an address with. 30 | * @param _address Address to associate with the name. 31 | */ 32 | function setAddress(string memory _name, address _address) external onlyOwner { 33 | bytes32 nameHash = _getNameHash(_name); 34 | address oldAddress = addresses[nameHash]; 35 | addresses[nameHash] = _address; 36 | 37 | emit AddressSet(_name, _address, oldAddress); 38 | } 39 | 40 | /** 41 | * Retrieves the address associated with a given name. 42 | * @param _name Name to retrieve an address for. 43 | * @return Address associated with the given name. 44 | */ 45 | function getAddress(string memory _name) external view returns (address) { 46 | return addresses[_getNameHash(_name)]; 47 | } 48 | 49 | /********************** 50 | * Internal Functions * 51 | **********************/ 52 | 53 | /** 54 | * Computes the hash of a name. 55 | * @param _name Name to compute a hash for. 56 | * @return Hash of the given name. 57 | */ 58 | function _getNameHash(string memory _name) internal pure returns (bytes32) { 59 | return keccak256(abi.encodePacked(_name)); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /contracts/libraries/resolver/Lib_AddressResolver.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity ^0.8.9; 3 | 4 | /* Library Imports */ 5 | import { Lib_AddressManager } from "./Lib_AddressManager.sol"; 6 | 7 | /** 8 | * @title Lib_AddressResolver 9 | */ 10 | abstract contract Lib_AddressResolver { 11 | /************* 12 | * Variables * 13 | *************/ 14 | 15 | Lib_AddressManager public libAddressManager; 16 | 17 | /*************** 18 | * Constructor * 19 | ***************/ 20 | 21 | /** 22 | * @param _libAddressManager Address of the Lib_AddressManager. 23 | */ 24 | constructor(address _libAddressManager) { 25 | libAddressManager = Lib_AddressManager(_libAddressManager); 26 | } 27 | 28 | /******************** 29 | * Public Functions * 30 | ********************/ 31 | 32 | /** 33 | * Resolves the address associated with a given name. 34 | * @param _name Name to resolve an address for. 35 | * @return Address associated with the given name. 36 | */ 37 | function resolve(string memory _name) public view returns (address) { 38 | return libAddressManager.getAddress(_name); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /contracts/libraries/resolver/Lib_ResolvedDelegateProxy.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity ^0.8.9; 3 | 4 | /* Library Imports */ 5 | import { Lib_AddressManager } from "./Lib_AddressManager.sol"; 6 | 7 | /** 8 | * @title Lib_ResolvedDelegateProxy 9 | */ 10 | contract Lib_ResolvedDelegateProxy { 11 | /************* 12 | * Variables * 13 | *************/ 14 | 15 | // Using mappings to store fields to avoid overwriting storage slots in the 16 | // implementation contract. For example, instead of storing these fields at 17 | // storage slot `0` & `1`, they are stored at `keccak256(key + slot)`. 18 | // See: https://solidity.readthedocs.io/en/v0.7.0/internals/layout_in_storage.html 19 | // NOTE: Do not use this code in your own contract system. 20 | // There is a known flaw in this contract, and we will remove it from the repository 21 | // in the near future. Due to the very limited way that we are using it, this flaw is 22 | // not an issue in our system. 23 | mapping(address => string) private implementationName; 24 | mapping(address => Lib_AddressManager) private addressManager; 25 | 26 | /*************** 27 | * Constructor * 28 | ***************/ 29 | 30 | /** 31 | * @param _libAddressManager Address of the Lib_AddressManager. 32 | * @param _implementationName implementationName of the contract to proxy to. 33 | */ 34 | constructor(address _libAddressManager, string memory _implementationName) { 35 | addressManager[address(this)] = Lib_AddressManager(_libAddressManager); 36 | implementationName[address(this)] = _implementationName; 37 | } 38 | 39 | /********************* 40 | * Fallback Function * 41 | *********************/ 42 | 43 | fallback() external payable { 44 | address target = addressManager[address(this)].getAddress( 45 | (implementationName[address(this)]) 46 | ); 47 | 48 | require(target != address(0), "Target address must be initialized."); 49 | 50 | // slither-disable-next-line controlled-delegatecall 51 | (bool success, bytes memory returndata) = target.delegatecall(msg.data); 52 | 53 | if (success == true) { 54 | assembly { 55 | return(add(returndata, 0x20), mload(returndata)) 56 | } 57 | } else { 58 | assembly { 59 | revert(add(returndata, 0x20), mload(returndata)) 60 | } 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /contracts/libraries/trie/Lib_SecureMerkleTrie.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity ^0.8.9; 3 | 4 | /* Library Imports */ 5 | import { Lib_MerkleTrie } from "./Lib_MerkleTrie.sol"; 6 | 7 | /** 8 | * @title Lib_SecureMerkleTrie 9 | */ 10 | library Lib_SecureMerkleTrie { 11 | /********************** 12 | * Internal Functions * 13 | **********************/ 14 | 15 | /** 16 | * @notice Verifies a proof that a given key/value pair is present in the 17 | * Merkle trie. 18 | * @param _key Key of the node to search for, as a hex string. 19 | * @param _value Value of the node to search for, as a hex string. 20 | * @param _proof Merkle trie inclusion proof for the desired node. Unlike 21 | * traditional Merkle trees. 22 | * @param _root Known root of the Merkle trie. Used to verify that the 23 | * included proof is correctly constructed. 24 | * @return _verified `true` if the k/v pair exists in the trie, `false` otherwise. 25 | */ 26 | function verifyInclusionProof( 27 | bytes memory _key, 28 | bytes memory _value, 29 | bytes memory _proof, 30 | bytes32 _root 31 | ) internal pure returns (bool _verified) { 32 | bytes memory key = _getSecureKey(_key); 33 | return Lib_MerkleTrie.verifyInclusionProof(key, _value, _proof, _root); 34 | } 35 | 36 | /** 37 | * @notice Retrieves the value associated with a given key. 38 | * @param _key Key to search for, as hex bytes. 39 | * @param _proof Merkle trie inclusion proof for the key. 40 | * @param _root Known root of the Merkle trie. 41 | * @return _exists Whether or not the key exists. 42 | * @return _value Value of the key if it exists. 43 | */ 44 | function get( 45 | bytes memory _key, 46 | bytes memory _proof, 47 | bytes32 _root 48 | ) internal pure returns (bool _exists, bytes memory _value) { 49 | bytes memory key = _getSecureKey(_key); 50 | return Lib_MerkleTrie.get(key, _proof, _root); 51 | } 52 | 53 | /********************* 54 | * Private Functions * 55 | *********************/ 56 | 57 | /** 58 | * Computes the secure counterpart to a key. 59 | * @param _key Key to get a secure key from. 60 | * @return _secureKey Secure version of the key. 61 | */ 62 | function _getSecureKey(bytes memory _key) private pure returns (bytes memory _secureKey) { 63 | return abi.encodePacked(keccak256(_key)); 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /contracts/libraries/utils/Lib_Bytes32Utils.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity ^0.8.9; 3 | 4 | /** 5 | * @title Lib_Byte32Utils 6 | */ 7 | library Lib_Bytes32Utils { 8 | /********************** 9 | * Internal Functions * 10 | **********************/ 11 | 12 | /** 13 | * Converts a bytes32 value to a boolean. Anything non-zero will be converted to "true." 14 | * @param _in Input bytes32 value. 15 | * @return Bytes32 as a boolean. 16 | */ 17 | function toBool(bytes32 _in) internal pure returns (bool) { 18 | return _in != 0; 19 | } 20 | 21 | /** 22 | * Converts a boolean to a bytes32 value. 23 | * @param _in Input boolean value. 24 | * @return Boolean as a bytes32. 25 | */ 26 | function fromBool(bool _in) internal pure returns (bytes32) { 27 | return bytes32(uint256(_in ? 1 : 0)); 28 | } 29 | 30 | /** 31 | * Converts a bytes32 value to an address. Takes the *last* 20 bytes. 32 | * @param _in Input bytes32 value. 33 | * @return Bytes32 as an address. 34 | */ 35 | function toAddress(bytes32 _in) internal pure returns (address) { 36 | return address(uint160(uint256(_in))); 37 | } 38 | 39 | /** 40 | * Converts an address to a bytes32. 41 | * @param _in Input address value. 42 | * @return Address as a bytes32. 43 | */ 44 | function fromAddress(address _in) internal pure returns (bytes32) { 45 | return bytes32(uint256(uint160(_in))); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /contracts/standards/AddressAliasHelper.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | /* 4 | * Copyright 2019-2021, Offchain Labs, Inc. 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | pragma solidity ^0.8.7; 20 | 21 | library AddressAliasHelper { 22 | uint160 constant offset = uint160(0x1111000000000000000000000000000000001111); 23 | 24 | /// @notice Utility function that converts the address in the L1 that submitted a tx to 25 | /// the inbox to the msg.sender viewed in the L2 26 | /// @param l1Address the address in the L1 that triggered the tx to L2 27 | /// @return l2Address L2 address as viewed in msg.sender 28 | function applyL1ToL2Alias(address l1Address) internal pure returns (address l2Address) { 29 | unchecked { 30 | l2Address = address(uint160(l1Address) + offset); 31 | } 32 | } 33 | 34 | /// @notice Utility function that converts the msg.sender viewed in the L2 to the 35 | /// address in the L1 that submitted a tx to the inbox 36 | /// @param l2Address L2 address as viewed in msg.sender 37 | /// @return l1Address the address in the L1 that triggered the tx to L2 38 | function undoL1ToL2Alias(address l2Address) internal pure returns (address l1Address) { 39 | unchecked { 40 | l1Address = address(uint160(l2Address) - offset); 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /contracts/standards/IL2StandardERC20.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity ^0.8.9; 3 | 4 | import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; 5 | import { IERC165 } from "@openzeppelin/contracts/utils/introspection/IERC165.sol"; 6 | 7 | interface IL2StandardERC20 is IERC20, IERC165 { 8 | function l1Token() external returns (address); 9 | 10 | function mint(address _to, uint256 _amount) external; 11 | 12 | function burn(address _from, uint256 _amount) external; 13 | 14 | event Mint(address indexed _account, uint256 _amount); 15 | event Burn(address indexed _account, uint256 _amount); 16 | } 17 | -------------------------------------------------------------------------------- /contracts/standards/L2StandardERC20.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity ^0.8.9; 3 | 4 | import { ERC20 } from "@openzeppelin/contracts/token/ERC20/ERC20.sol"; 5 | import "./IL2StandardERC20.sol"; 6 | 7 | contract L2StandardERC20 is IL2StandardERC20, ERC20 { 8 | address public l1Token; 9 | address public l2Bridge; 10 | 11 | /** 12 | * @param _l2Bridge Address of the L2 standard bridge. 13 | * @param _l1Token Address of the corresponding L1 token. 14 | * @param _name ERC20 name. 15 | * @param _symbol ERC20 symbol. 16 | */ 17 | constructor( 18 | address _l2Bridge, 19 | address _l1Token, 20 | string memory _name, 21 | string memory _symbol 22 | ) ERC20(_name, _symbol) { 23 | l1Token = _l1Token; 24 | l2Bridge = _l2Bridge; 25 | } 26 | 27 | modifier onlyL2Bridge() { 28 | require(msg.sender == l2Bridge, "Only L2 Bridge can mint and burn"); 29 | _; 30 | } 31 | 32 | // slither-disable-next-line external-function 33 | function supportsInterface(bytes4 _interfaceId) public pure returns (bool) { 34 | bytes4 firstSupportedInterface = bytes4(keccak256("supportsInterface(bytes4)")); // ERC165 35 | bytes4 secondSupportedInterface = IL2StandardERC20.l1Token.selector ^ 36 | IL2StandardERC20.mint.selector ^ 37 | IL2StandardERC20.burn.selector; 38 | return _interfaceId == firstSupportedInterface || _interfaceId == secondSupportedInterface; 39 | } 40 | 41 | // slither-disable-next-line external-function 42 | function mint(address _to, uint256 _amount) public virtual onlyL2Bridge { 43 | _mint(_to, _amount); 44 | 45 | emit Mint(_to, _amount); 46 | } 47 | 48 | // slither-disable-next-line external-function 49 | function burn(address _from, uint256 _amount) public virtual onlyL2Bridge { 50 | _burn(_from, _amount); 51 | 52 | emit Burn(_from, _amount); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /contracts/test-helpers/FailingReceiver.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity >=0.8.9; 3 | 4 | contract FailingReceiver { 5 | receive() external payable { 6 | require(false, "FailingReceiver"); 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /contracts/test-helpers/TestERC20.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity ^0.8.9; 3 | 4 | import { ERC20 } from "@openzeppelin/contracts/token/ERC20/ERC20.sol"; 5 | 6 | contract TestERC20 is ERC20 { 7 | constructor() ERC20("TEST", "TST") {} 8 | 9 | function mint(address to, uint256 value) public { 10 | _mint(to, value); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /contracts/test-libraries/bridge/TestLib_CrossDomainUtils.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity ^0.8.9; 3 | 4 | /* Library Imports */ 5 | import { Lib_CrossDomainUtils } from "../../libraries/bridge/Lib_CrossDomainUtils.sol"; 6 | 7 | /** 8 | * @title TestLib_CrossDomainUtils 9 | */ 10 | library TestLib_CrossDomainUtils { 11 | function encodeXDomainCalldata( 12 | address _target, 13 | address _sender, 14 | bytes memory _message, 15 | uint256 _messageNonce 16 | ) public pure returns (bytes memory) { 17 | return 18 | Lib_CrossDomainUtils.encodeXDomainCalldata(_target, _sender, _message, _messageNonce); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /contracts/test-libraries/codec/TestLib_OVMCodec.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity ^0.8.9; 3 | 4 | /* Library Imports */ 5 | import { Lib_OVMCodec } from "../../libraries/codec/Lib_OVMCodec.sol"; 6 | 7 | /** 8 | * @title TestLib_OVMCodec 9 | */ 10 | contract TestLib_OVMCodec { 11 | function encodeTransaction(Lib_OVMCodec.Transaction memory _transaction) 12 | public 13 | pure 14 | returns (bytes memory _encoded) 15 | { 16 | return Lib_OVMCodec.encodeTransaction(_transaction); 17 | } 18 | 19 | function hashTransaction(Lib_OVMCodec.Transaction memory _transaction) 20 | public 21 | pure 22 | returns (bytes32 _hash) 23 | { 24 | return Lib_OVMCodec.hashTransaction(_transaction); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /contracts/test-libraries/rlp/TestLib_RLPReader.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity ^0.8.9; 3 | 4 | /* Library Imports */ 5 | import { Lib_RLPReader } from "../../libraries/rlp/Lib_RLPReader.sol"; 6 | 7 | /** 8 | * @title TestLib_RLPReader 9 | */ 10 | contract TestLib_RLPReader { 11 | function readList(bytes memory _in) public pure returns (bytes[] memory) { 12 | Lib_RLPReader.RLPItem[] memory decoded = Lib_RLPReader.readList(_in); 13 | bytes[] memory out = new bytes[](decoded.length); 14 | for (uint256 i = 0; i < out.length; i++) { 15 | out[i] = Lib_RLPReader.readRawBytes(decoded[i]); 16 | } 17 | return out; 18 | } 19 | 20 | function readString(bytes memory _in) public pure returns (string memory) { 21 | return Lib_RLPReader.readString(_in); 22 | } 23 | 24 | function readBytes(bytes memory _in) public pure returns (bytes memory) { 25 | return Lib_RLPReader.readBytes(_in); 26 | } 27 | 28 | function readBytes32(bytes memory _in) public pure returns (bytes32) { 29 | return Lib_RLPReader.readBytes32(_in); 30 | } 31 | 32 | function readUint256(bytes memory _in) public pure returns (uint256) { 33 | return Lib_RLPReader.readUint256(_in); 34 | } 35 | 36 | function readBool(bytes memory _in) public pure returns (bool) { 37 | return Lib_RLPReader.readBool(_in); 38 | } 39 | 40 | function readAddress(bytes memory _in) public pure returns (address) { 41 | return Lib_RLPReader.readAddress(_in); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /contracts/test-libraries/rlp/TestLib_RLPWriter.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity ^0.8.9; 3 | 4 | /* Library Imports */ 5 | import { Lib_RLPWriter } from "../../libraries/rlp/Lib_RLPWriter.sol"; 6 | import { TestERC20 } from "../../test-helpers/TestERC20.sol"; 7 | 8 | /** 9 | * @title TestLib_RLPWriter 10 | */ 11 | contract TestLib_RLPWriter { 12 | function writeBytes(bytes memory _in) public pure returns (bytes memory _out) { 13 | return Lib_RLPWriter.writeBytes(_in); 14 | } 15 | 16 | function writeList(bytes[] memory _in) public pure returns (bytes memory _out) { 17 | return Lib_RLPWriter.writeList(_in); 18 | } 19 | 20 | function writeString(string memory _in) public pure returns (bytes memory _out) { 21 | return Lib_RLPWriter.writeString(_in); 22 | } 23 | 24 | function writeAddress(address _in) public pure returns (bytes memory _out) { 25 | return Lib_RLPWriter.writeAddress(_in); 26 | } 27 | 28 | function writeUint(uint256 _in) public pure returns (bytes memory _out) { 29 | return Lib_RLPWriter.writeUint(_in); 30 | } 31 | 32 | function writeBool(bool _in) public pure returns (bytes memory _out) { 33 | return Lib_RLPWriter.writeBool(_in); 34 | } 35 | 36 | function writeAddressWithTaintedMemory(address _in) public returns (bytes memory _out) { 37 | new TestERC20(); 38 | return Lib_RLPWriter.writeAddress(_in); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /contracts/test-libraries/standards/TestLib_AddressAliasHelper.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity ^0.8.8; 3 | 4 | /* Library Imports */ 5 | import { AddressAliasHelper } from "../../standards/AddressAliasHelper.sol"; 6 | 7 | /** 8 | * @title TestLib_AddressAliasHelper 9 | */ 10 | contract TestLib_AddressAliasHelper { 11 | function applyL1ToL2Alias(address _address) public pure returns (address) { 12 | return AddressAliasHelper.applyL1ToL2Alias(_address); 13 | } 14 | 15 | function undoL1ToL2Alias(address _address) public pure returns (address) { 16 | return AddressAliasHelper.undoL1ToL2Alias(_address); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /contracts/test-libraries/trie/TestLib_MerkleTrie.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity ^0.8.9; 3 | 4 | /* Library Imports */ 5 | import { Lib_MerkleTrie } from "../../libraries/trie/Lib_MerkleTrie.sol"; 6 | 7 | /** 8 | * @title TestLib_MerkleTrie 9 | */ 10 | contract TestLib_MerkleTrie { 11 | function verifyInclusionProof( 12 | bytes memory _key, 13 | bytes memory _value, 14 | bytes memory _proof, 15 | bytes32 _root 16 | ) public pure returns (bool) { 17 | return Lib_MerkleTrie.verifyInclusionProof(_key, _value, _proof, _root); 18 | } 19 | 20 | function get( 21 | bytes memory _key, 22 | bytes memory _proof, 23 | bytes32 _root 24 | ) public pure returns (bool, bytes memory) { 25 | return Lib_MerkleTrie.get(_key, _proof, _root); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /contracts/test-libraries/trie/TestLib_SecureMerkleTrie.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity ^0.8.9; 3 | 4 | /* Library Imports */ 5 | import { Lib_SecureMerkleTrie } from "../../libraries/trie/Lib_SecureMerkleTrie.sol"; 6 | 7 | /** 8 | * @title TestLib_SecureMerkleTrie 9 | */ 10 | contract TestLib_SecureMerkleTrie { 11 | function verifyInclusionProof( 12 | bytes memory _key, 13 | bytes memory _value, 14 | bytes memory _proof, 15 | bytes32 _root 16 | ) public pure returns (bool) { 17 | return Lib_SecureMerkleTrie.verifyInclusionProof(_key, _value, _proof, _root); 18 | } 19 | 20 | function get( 21 | bytes memory _key, 22 | bytes memory _proof, 23 | bytes32 _root 24 | ) public pure returns (bool, bytes memory) { 25 | return Lib_SecureMerkleTrie.get(_key, _proof, _root); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /contracts/test-libraries/utils/TestLib_Buffer.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity ^0.8.9; 3 | 4 | /* Library Imports */ 5 | import { Lib_Buffer } from "../../libraries/utils/Lib_Buffer.sol"; 6 | 7 | /** 8 | * @title TestLib_Buffer 9 | */ 10 | contract TestLib_Buffer { 11 | using Lib_Buffer for Lib_Buffer.Buffer; 12 | using Lib_Buffer for Lib_Buffer.BufferContext; 13 | 14 | Lib_Buffer.Buffer internal buf; 15 | 16 | function push(bytes32 _value, bytes27 _extraData) public { 17 | buf.push(_value, _extraData); 18 | } 19 | 20 | function push(bytes32 _value) public { 21 | buf.push(_value); 22 | } 23 | 24 | function get(uint256 _index) public view returns (bytes32) { 25 | return buf.get(_index); 26 | } 27 | 28 | function deleteElementsAfterInclusive(uint40 _index) public { 29 | return buf.deleteElementsAfterInclusive(_index); 30 | } 31 | 32 | function deleteElementsAfterInclusive(uint40 _index, bytes27 _extraData) public { 33 | return buf.deleteElementsAfterInclusive(_index, _extraData); 34 | } 35 | 36 | function getLength() public view returns (uint40) { 37 | return buf.getLength(); 38 | } 39 | 40 | function setExtraData(bytes27 _extraData) public { 41 | return buf.setExtraData(_extraData); 42 | } 43 | 44 | function getExtraData() public view returns (bytes27) { 45 | return buf.getExtraData(); 46 | } 47 | 48 | function getContext() public view returns (Lib_Buffer.BufferContext memory) { 49 | return buf.getContext(); 50 | } 51 | 52 | function setContext(uint40 _index, bytes27 _extraData) public { 53 | Lib_Buffer.BufferContext memory _ctx = Lib_Buffer.BufferContext({ 54 | length: _index, 55 | extraData: _extraData 56 | }); 57 | return buf.setContext(_ctx); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /contracts/test-libraries/utils/TestLib_Bytes32Utils.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity ^0.8.9; 3 | 4 | /* Library Imports */ 5 | import { Lib_Bytes32Utils } from "../../libraries/utils/Lib_Bytes32Utils.sol"; 6 | 7 | /** 8 | * @title TestLib_Byte32Utils 9 | */ 10 | contract TestLib_Bytes32Utils { 11 | function toBool(bytes32 _in) public pure returns (bool _out) { 12 | return Lib_Bytes32Utils.toBool(_in); 13 | } 14 | 15 | function fromBool(bool _in) public pure returns (bytes32 _out) { 16 | return Lib_Bytes32Utils.fromBool(_in); 17 | } 18 | 19 | function toAddress(bytes32 _in) public pure returns (address _out) { 20 | return Lib_Bytes32Utils.toAddress(_in); 21 | } 22 | 23 | function fromAddress(address _in) public pure returns (bytes32 _out) { 24 | return Lib_Bytes32Utils.fromAddress(_in); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /contracts/test-libraries/utils/TestLib_BytesUtils.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity ^0.8.9; 3 | 4 | /* Library Imports */ 5 | import { Lib_BytesUtils } from "../../libraries/utils/Lib_BytesUtils.sol"; 6 | import { TestERC20 } from "../../test-helpers/TestERC20.sol"; 7 | 8 | /** 9 | * @title TestLib_BytesUtils 10 | */ 11 | contract TestLib_BytesUtils { 12 | function concat(bytes memory _preBytes, bytes memory _postBytes) 13 | public 14 | pure 15 | returns (bytes memory) 16 | { 17 | return abi.encodePacked(_preBytes, _postBytes); 18 | } 19 | 20 | function slice( 21 | bytes memory _bytes, 22 | uint256 _start, 23 | uint256 _length 24 | ) public pure returns (bytes memory) { 25 | return Lib_BytesUtils.slice(_bytes, _start, _length); 26 | } 27 | 28 | function toBytes32(bytes memory _bytes) public pure returns (bytes32) { 29 | return Lib_BytesUtils.toBytes32(_bytes); 30 | } 31 | 32 | function toUint256(bytes memory _bytes) public pure returns (uint256) { 33 | return Lib_BytesUtils.toUint256(_bytes); 34 | } 35 | 36 | function toNibbles(bytes memory _bytes) public pure returns (bytes memory) { 37 | return Lib_BytesUtils.toNibbles(_bytes); 38 | } 39 | 40 | function fromNibbles(bytes memory _bytes) public pure returns (bytes memory) { 41 | return Lib_BytesUtils.fromNibbles(_bytes); 42 | } 43 | 44 | function equal(bytes memory _bytes, bytes memory _other) public pure returns (bool) { 45 | return Lib_BytesUtils.equal(_bytes, _other); 46 | } 47 | 48 | function sliceWithTaintedMemory( 49 | bytes memory _bytes, 50 | uint256 _start, 51 | uint256 _length 52 | ) public returns (bytes memory) { 53 | new TestERC20(); 54 | return Lib_BytesUtils.slice(_bytes, _start, _length); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /contracts/test-libraries/utils/TestLib_MerkleTree.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity ^0.8.9; 3 | 4 | /* Library Imports */ 5 | import { Lib_MerkleTree } from "../../libraries/utils/Lib_MerkleTree.sol"; 6 | 7 | /** 8 | * @title TestLib_MerkleTree 9 | */ 10 | contract TestLib_MerkleTree { 11 | function getMerkleRoot(bytes32[] memory _elements) public pure returns (bytes32) { 12 | return Lib_MerkleTree.getMerkleRoot(_elements); 13 | } 14 | 15 | function verify( 16 | bytes32 _root, 17 | bytes32 _leaf, 18 | uint256 _index, 19 | bytes32[] memory _siblings, 20 | uint256 _totalLeaves 21 | ) public pure returns (bool) { 22 | return Lib_MerkleTree.verify(_root, _leaf, _index, _siblings, _totalLeaves); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /deploy-config/goerli-nightly.ts: -------------------------------------------------------------------------------- 1 | const config = { 2 | l1BlockTimeSeconds: 15, 3 | l2BlockGasLimit: 15_000_000, 4 | l2ChainId: 421, 5 | ctcL2GasDiscountDivisor: 32, 6 | ctcEnqueueGasCost: 60_000, 7 | sccFaultProofWindowSeconds: 604800, 8 | sccSequencerPublishWindowSeconds: 12592000, 9 | ovmSequencerAddress: '0xba517B809d22D5e27F607c03dEBDe09d5Ad27049', 10 | ovmProposerAddress: '0x69fe6dE5b2Cd205FfC6D0c9F26df681b262A91dd', 11 | ovmBlockSignerAddress: '0x00000398232E2064F896018496b4b44b3D62751F', 12 | ovmFeeWalletAddress: '0xba517B809d22D5e27F607c03dEBDe09d5Ad27049', 13 | ovmAddressManagerOwner: '0x4F3F400c20448D33ECc12E7d289F49dA7fC51736', 14 | ovmGasPriceOracleOwner: '0xc8910a1957d276cE5634B978d908B5ef9fB0e05B', 15 | } 16 | 17 | export default config 18 | -------------------------------------------------------------------------------- /deploy-config/goerli.ts: -------------------------------------------------------------------------------- 1 | const config = { 2 | numDeployConfirmations: 1, 3 | l1BlockTimeSeconds: 15, 4 | l2BlockGasLimit: 15_000_000, 5 | l2ChainId: 420, 6 | ctcL2GasDiscountDivisor: 32, 7 | ctcEnqueueGasCost: 60_000, 8 | sccFaultProofWindowSeconds: 10, 9 | sccSequencerPublishWindowSeconds: 12592000, 10 | ovmSequencerAddress: '0x7431310e026B69BFC676C0013E12A1A11411EEc9', 11 | ovmProposerAddress: '0x02b1786A85Ec3f71fBbBa46507780dB7cF9014f6', 12 | ovmBlockSignerAddress: '0x27770a9694e4B4b1E130Ab91Bc327C36855f612E', 13 | ovmFeeWalletAddress: '0xfd1D2e729aE8eEe2E146c033bf4400fE75284301', 14 | ovmAddressManagerOwner: '0xf80267194936da1E98dB10bcE06F3147D580a62e', 15 | ovmGasPriceOracleOwner: '0xa693B8f8207FF043F6bbC2E2120bbE4C2251Efe9', 16 | } 17 | 18 | export default config 19 | -------------------------------------------------------------------------------- /deploy-config/hardhat.ts: -------------------------------------------------------------------------------- 1 | const config = { 2 | l1BlockTimeSeconds: 15, 3 | l2BlockGasLimit: 15_000_000, 4 | l2ChainId: 17, 5 | ctcL2GasDiscountDivisor: 32, 6 | ctcEnqueueGasCost: 60_000, 7 | sccFaultProofWindowSeconds: 0, 8 | sccSequencerPublishWindowSeconds: 12592000, 9 | ovmSequencerAddress: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8', 10 | ovmProposerAddress: '0x3c44cdddb6a900fa2b585dd299e03d12fa4293bc', 11 | ovmBlockSignerAddress: '0x00000398232E2064F896018496b4b44b3D62751F', 12 | ovmFeeWalletAddress: '0x391716d440c151c42cdf1c95c1d83a5427bca52c', 13 | ovmAddressManagerOwner: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', 14 | ovmGasPriceOracleOwner: '0x9965507d1a55bcc2695c58ba16fb37d819b0a4dc', 15 | } 16 | 17 | export default config 18 | -------------------------------------------------------------------------------- /deploy-config/kovan.ts: -------------------------------------------------------------------------------- 1 | const config = { 2 | numDeployConfirmations: 1, 3 | gasPrice: 5_000_000_000, 4 | l1BlockTimeSeconds: 15, 5 | l2BlockGasLimit: 15_000_000, 6 | l2ChainId: 69, 7 | ctcL2GasDiscountDivisor: 32, 8 | ctcEnqueueGasCost: 60_000, 9 | sccFaultProofWindowSeconds: 10, 10 | sccSequencerPublishWindowSeconds: 12592000, 11 | ovmSequencerAddress: '0xB79f76EF2c5F0286176833E7B2eEe103b1CC3244', 12 | ovmProposerAddress: '0x9A2F243c605e6908D96b18e21Fb82Bf288B19EF3', 13 | ovmBlockSignerAddress: '0x00000398232E2064F896018496b4b44b3D62751F', 14 | ovmFeeWalletAddress: '0xB79f76EF2c5F0286176833E7B2eEe103b1CC3244', 15 | ovmAddressManagerOwner: '0x18394B52d3Cb931dfA76F63251919D051953413d', 16 | ovmGasPriceOracleOwner: '0x84f70449f90300997840eCb0918873745Ede7aE6', 17 | } 18 | 19 | export default config 20 | -------------------------------------------------------------------------------- /deploy-config/local.ts: -------------------------------------------------------------------------------- 1 | const config = { 2 | l1BlockTimeSeconds: 15, 3 | l2BlockGasLimit: 15_000_000, 4 | l2ChainId: 17, 5 | ctcL2GasDiscountDivisor: 32, 6 | ctcEnqueueGasCost: 60_000, 7 | sccFaultProofWindowSeconds: 0, 8 | sccSequencerPublishWindowSeconds: 12592000, 9 | ovmSequencerAddress: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8', 10 | ovmProposerAddress: '0x3c44cdddb6a900fa2b585dd299e03d12fa4293bc', 11 | ovmBlockSignerAddress: '0x00000398232E2064F896018496b4b44b3D62751F', 12 | ovmFeeWalletAddress: '0x391716d440c151c42cdf1c95c1d83a5427bca52c', 13 | ovmAddressManagerOwner: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', 14 | ovmGasPriceOracleOwner: '0x9965507d1a55bcc2695c58ba16fb37d819b0a4dc', 15 | } 16 | 17 | export default config 18 | -------------------------------------------------------------------------------- /deploy-config/mainnet.ts: -------------------------------------------------------------------------------- 1 | const config = { 2 | numDeployConfirmations: 4, 3 | gasPrice: 150_000_000_000, 4 | l1BlockTimeSeconds: 15, 5 | l2BlockGasLimit: 15_000_000, 6 | l2ChainId: 10, 7 | ctcL2GasDiscountDivisor: 32, 8 | ctcEnqueueGasCost: 60_000, 9 | sccFaultProofWindowSeconds: 604800, 10 | sccSequencerPublishWindowSeconds: 12592000, 11 | ovmSequencerAddress: '0x6887246668a3b87F54DeB3b94Ba47a6f63F32985', 12 | ovmProposerAddress: '0x473300df21D047806A082244b417f96b32f13A33', 13 | ovmBlockSignerAddress: '0x00000398232E2064F896018496b4b44b3D62751F', 14 | ovmFeeWalletAddress: '0x391716d440c151c42cdf1c95c1d83a5427bca52c', 15 | ovmAddressManagerOwner: '0x9BA6e03D8B90dE867373Db8cF1A58d2F7F006b3A', 16 | ovmGasPriceOracleOwner: '0x7107142636C85c549690b1Aca12Bdb8052d26Ae6', 17 | ovmWhitelistOwner: '0x648E3e8101BFaB7bf5997Bd007Fb473786019159', 18 | } 19 | 20 | export default config 21 | -------------------------------------------------------------------------------- /deploy/000-hardhat-setup.ts: -------------------------------------------------------------------------------- 1 | /* eslint @typescript-eslint/no-var-requires: "off" */ 2 | import { ethers } from 'ethers' 3 | import { DeployFunction } from 'hardhat-deploy/dist/types' 4 | import { awaitCondition } from '@eth-patex/core-utils' 5 | 6 | import { 7 | getContractFromArtifact, 8 | fundAccount, 9 | sendImpersonatedTx, 10 | BIG_BALANCE, 11 | } from '../src/deploy-utils' 12 | import { names } from '../src/address-names' 13 | 14 | const deployFn: DeployFunction = async (hre) => { 15 | if (!hre.deployConfig.isForkedNetwork) { 16 | return 17 | } 18 | 19 | console.log(`Running custom setup for forked experimental networks`) 20 | const { deployer } = await hre.getNamedAccounts() 21 | 22 | // Fund the deployer account so it can be used for the rest of this deployment. 23 | console.log(`Funding deployer account...`) 24 | await fundAccount(hre, deployer, BIG_BALANCE) 25 | 26 | // Get a reference to the AddressManager contract. 27 | const Lib_AddressManager = await getContractFromArtifact( 28 | hre, 29 | names.unmanaged.Lib_AddressManager 30 | ) 31 | 32 | // Transfer ownership of the AddressManager to the deployer. 33 | console.log(`Setting AddressManager owner to ${deployer}`) 34 | await sendImpersonatedTx({ 35 | hre, 36 | contract: Lib_AddressManager, 37 | fn: 'transferOwnership', 38 | from: await Lib_AddressManager.owner(), 39 | gas: ethers.BigNumber.from(2_000_000).toHexString(), 40 | args: [deployer], 41 | }) 42 | 43 | console.log(`Waiting for owner to be correctly set...`) 44 | await awaitCondition( 45 | async () => { 46 | return (await Lib_AddressManager.owner()) === deployer 47 | }, 48 | 5000, 49 | 100 50 | ) 51 | 52 | // Get a reference to the L1StandardBridge contract. 53 | const Proxy__OVM_L1StandardBridge = await getContractFromArtifact( 54 | hre, 55 | 'Proxy__OVM_L1StandardBridge' 56 | ) 57 | 58 | // Transfer ownership of the L1StandardBridge to the deployer. 59 | console.log(`Setting L1StandardBridge owner to ${deployer}`) 60 | await sendImpersonatedTx({ 61 | hre, 62 | contract: Proxy__OVM_L1StandardBridge, 63 | fn: 'setOwner', 64 | from: await Proxy__OVM_L1StandardBridge.callStatic.getOwner({ 65 | from: hre.ethers.constants.AddressZero, 66 | }), 67 | gas: ethers.BigNumber.from(2_000_000).toHexString(), 68 | args: [deployer], 69 | }) 70 | 71 | console.log(`Waiting for owner to be correctly set...`) 72 | await awaitCondition( 73 | async () => { 74 | return ( 75 | (await Proxy__OVM_L1StandardBridge.callStatic.getOwner({ 76 | from: hre.ethers.constants.AddressZero, 77 | })) === deployer 78 | ) 79 | }, 80 | 5000, 81 | 100 82 | ) 83 | } 84 | 85 | deployFn.tags = ['hardhat', 'upgrade'] 86 | 87 | export default deployFn 88 | -------------------------------------------------------------------------------- /deploy/001-Lib_AddressManager.deploy.ts: -------------------------------------------------------------------------------- 1 | /* Imports: Internal */ 2 | import { DeployFunction } from 'hardhat-deploy/dist/types' 3 | 4 | import { names } from '../src/address-names' 5 | 6 | /* Imports: External */ 7 | 8 | const deployFn: DeployFunction = async (hre) => { 9 | const { deploy } = hre.deployments 10 | const { deployer } = await hre.getNamedAccounts() 11 | 12 | await deploy(names.unmanaged.Lib_AddressManager, { 13 | from: deployer, 14 | args: [], 15 | log: true, 16 | waitConfirmations: hre.deployConfig.numDeployConfirmations, 17 | }) 18 | } 19 | 20 | // This is kept during an upgrade. So no upgrade tag. 21 | deployFn.tags = ['Lib_AddressManager'] 22 | 23 | export default deployFn 24 | -------------------------------------------------------------------------------- /deploy/002-OVM_ChainStorageContainer_ctc_batches.deploy.ts: -------------------------------------------------------------------------------- 1 | /* Imports: External */ 2 | import { DeployFunction } from 'hardhat-deploy/dist/types' 3 | 4 | /* Imports: Internal */ 5 | import { 6 | deployAndVerifyAndThen, 7 | getContractFromArtifact, 8 | } from '../src/deploy-utils' 9 | import { names } from '../src/address-names' 10 | 11 | const deployFn: DeployFunction = async (hre) => { 12 | const Lib_AddressManager = await getContractFromArtifact( 13 | hre, 14 | names.unmanaged.Lib_AddressManager 15 | ) 16 | 17 | await deployAndVerifyAndThen({ 18 | hre, 19 | name: names.managed.contracts.ChainStorageContainer_CTC_batches, 20 | contract: 'ChainStorageContainer', 21 | args: [Lib_AddressManager.address, 'CanonicalTransactionChain'], 22 | }) 23 | } 24 | 25 | deployFn.tags = ['ChainStorageContainer_ctc_batches', 'upgrade'] 26 | 27 | export default deployFn 28 | -------------------------------------------------------------------------------- /deploy/003-OVM_ChainStorageContainer_scc_batches.deploy.ts: -------------------------------------------------------------------------------- 1 | /* Imports: External */ 2 | import { DeployFunction } from 'hardhat-deploy/dist/types' 3 | 4 | /* Imports: Internal */ 5 | import { 6 | deployAndVerifyAndThen, 7 | getContractFromArtifact, 8 | } from '../src/deploy-utils' 9 | import { names } from '../src/address-names' 10 | 11 | const deployFn: DeployFunction = async (hre) => { 12 | const Lib_AddressManager = await getContractFromArtifact( 13 | hre, 14 | names.unmanaged.Lib_AddressManager 15 | ) 16 | 17 | await deployAndVerifyAndThen({ 18 | hre, 19 | name: names.managed.contracts.ChainStorageContainer_SCC_batches, 20 | contract: 'ChainStorageContainer', 21 | args: [Lib_AddressManager.address, 'StateCommitmentChain'], 22 | }) 23 | } 24 | 25 | deployFn.tags = ['ChainStorageContainer_scc_batches', 'upgrade'] 26 | 27 | export default deployFn 28 | -------------------------------------------------------------------------------- /deploy/004-OVM_CanonicalTransactionChain.deploy.ts: -------------------------------------------------------------------------------- 1 | /* Imports: External */ 2 | import { DeployFunction } from 'hardhat-deploy/dist/types' 3 | 4 | /* Imports: Internal */ 5 | import { 6 | deployAndVerifyAndThen, 7 | getContractFromArtifact, 8 | } from '../src/deploy-utils' 9 | import { names } from '../src/address-names' 10 | 11 | const deployFn: DeployFunction = async (hre) => { 12 | const Lib_AddressManager = await getContractFromArtifact( 13 | hre, 14 | names.unmanaged.Lib_AddressManager 15 | ) 16 | 17 | await deployAndVerifyAndThen({ 18 | hre, 19 | name: names.managed.contracts.CanonicalTransactionChain, 20 | args: [ 21 | Lib_AddressManager.address, 22 | hre.deployConfig.l2BlockGasLimit, 23 | hre.deployConfig.ctcL2GasDiscountDivisor, 24 | hre.deployConfig.ctcEnqueueGasCost, 25 | ], 26 | }) 27 | } 28 | 29 | deployFn.tags = ['CanonicalTransactionChain', 'upgrade'] 30 | 31 | export default deployFn 32 | -------------------------------------------------------------------------------- /deploy/005-OVM_StateCommitmentChain.deploy.ts: -------------------------------------------------------------------------------- 1 | /* Imports: External */ 2 | import { DeployFunction } from 'hardhat-deploy/dist/types' 3 | 4 | /* Imports: Internal */ 5 | import { 6 | deployAndVerifyAndThen, 7 | getContractFromArtifact, 8 | } from '../src/deploy-utils' 9 | import { names } from '../src/address-names' 10 | 11 | const deployFn: DeployFunction = async (hre) => { 12 | const Lib_AddressManager = await getContractFromArtifact( 13 | hre, 14 | names.unmanaged.Lib_AddressManager 15 | ) 16 | 17 | await deployAndVerifyAndThen({ 18 | hre, 19 | name: names.managed.contracts.StateCommitmentChain, 20 | args: [ 21 | Lib_AddressManager.address, 22 | hre.deployConfig.sccFaultProofWindowSeconds, 23 | hre.deployConfig.sccSequencerPublishWindowSeconds, 24 | ], 25 | }) 26 | } 27 | 28 | deployFn.tags = ['StateCommitmentChain', 'upgrade'] 29 | 30 | export default deployFn 31 | -------------------------------------------------------------------------------- /deploy/006-OVM_BondManager.deploy.ts: -------------------------------------------------------------------------------- 1 | /* Imports: External */ 2 | import { DeployFunction } from 'hardhat-deploy/dist/types' 3 | 4 | /* Imports: Internal */ 5 | import { 6 | deployAndVerifyAndThen, 7 | getContractFromArtifact, 8 | } from '../src/deploy-utils' 9 | import { names } from '../src/address-names' 10 | 11 | const deployFn: DeployFunction = async (hre) => { 12 | const Lib_AddressManager = await getContractFromArtifact( 13 | hre, 14 | names.unmanaged.Lib_AddressManager 15 | ) 16 | 17 | await deployAndVerifyAndThen({ 18 | hre, 19 | name: names.managed.contracts.BondManager, 20 | args: [Lib_AddressManager.address], 21 | }) 22 | } 23 | 24 | deployFn.tags = ['BondManager', 'upgrade'] 25 | 26 | export default deployFn 27 | -------------------------------------------------------------------------------- /deploy/007-OVM_L1CrossDomainMessenger.deploy.ts: -------------------------------------------------------------------------------- 1 | /* Imports: External */ 2 | import { DeployFunction } from 'hardhat-deploy/dist/types' 3 | import { hexStringEquals, awaitCondition } from '@eth-patex/core-utils' 4 | 5 | /* Imports: Internal */ 6 | import { 7 | deployAndVerifyAndThen, 8 | getContractFromArtifact, 9 | } from '../src/deploy-utils' 10 | import { names } from '../src/address-names' 11 | 12 | const deployFn: DeployFunction = async (hre) => { 13 | const Lib_AddressManager = await getContractFromArtifact( 14 | hre, 15 | names.unmanaged.Lib_AddressManager 16 | ) 17 | 18 | await deployAndVerifyAndThen({ 19 | hre, 20 | name: names.managed.contracts.OVM_L1CrossDomainMessenger, 21 | contract: 'L1CrossDomainMessenger', 22 | args: [], 23 | postDeployAction: async (contract) => { 24 | // Theoretically it's not necessary to initialize this contract since it sits behind 25 | // a proxy. However, it's best practice to initialize it anyway just in case there's 26 | // some unknown security hole. It also prevents another user from appearing like an 27 | // official address because it managed to call the initialization function. 28 | console.log(`Initializing L1CrossDomainMessenger (implementation)...`) 29 | await contract.initialize(Lib_AddressManager.address) 30 | 31 | console.log(`Checking that contract was correctly initialized...`) 32 | await awaitCondition( 33 | async () => { 34 | return hexStringEquals( 35 | await contract.libAddressManager(), 36 | Lib_AddressManager.address 37 | ) 38 | }, 39 | 5000, 40 | 100 41 | ) 42 | 43 | // Same thing as above, we want to transfer ownership of this contract to the owner of the 44 | // AddressManager. Not technically necessary but seems like the right thing to do. 45 | console.log( 46 | `Transferring ownership of L1CrossDomainMessenger (implementation)...` 47 | ) 48 | const owner = hre.deployConfig.ovmAddressManagerOwner 49 | await contract.transferOwnership(owner) 50 | 51 | console.log(`Checking that contract owner was correctly set...`) 52 | await awaitCondition( 53 | async () => { 54 | return hexStringEquals(await contract.owner(), owner) 55 | }, 56 | 5000, 57 | 100 58 | ) 59 | }, 60 | }) 61 | } 62 | 63 | deployFn.tags = ['L1CrossDomainMessenger', 'upgrade'] 64 | 65 | export default deployFn 66 | -------------------------------------------------------------------------------- /deploy/008-Proxy__OVM_L1CrossDomainMessenger.deploy.ts: -------------------------------------------------------------------------------- 1 | /* Imports: External */ 2 | import { DeployFunction } from 'hardhat-deploy/dist/types' 3 | 4 | /* Imports: Internal */ 5 | import { 6 | deployAndVerifyAndThen, 7 | getContractFromArtifact, 8 | } from '../src/deploy-utils' 9 | import { names } from '../src/address-names' 10 | 11 | const deployFn: DeployFunction = async (hre) => { 12 | const Lib_AddressManager = await getContractFromArtifact( 13 | hre, 14 | names.unmanaged.Lib_AddressManager 15 | ) 16 | 17 | await deployAndVerifyAndThen({ 18 | hre, 19 | name: 'Proxy__OVM_L1CrossDomainMessenger', 20 | contract: 'Lib_ResolvedDelegateProxy', 21 | iface: 'L1CrossDomainMessenger', 22 | args: [Lib_AddressManager.address, 'OVM_L1CrossDomainMessenger'], 23 | }) 24 | } 25 | 26 | // This is kept during an upgrade. So no upgrade tag. 27 | deployFn.tags = ['Proxy__OVM_L1CrossDomainMessenger'] 28 | 29 | export default deployFn 30 | -------------------------------------------------------------------------------- /deploy/009-Proxy__OVM_L1StandardBridge.deploy.ts: -------------------------------------------------------------------------------- 1 | /* Imports: External */ 2 | import { DeployFunction } from 'hardhat-deploy/dist/types' 3 | 4 | /* Imports: Internal */ 5 | import { deployAndVerifyAndThen } from '../src/deploy-utils' 6 | import { names } from '../src/address-names' 7 | 8 | const deployFn: DeployFunction = async (hre) => { 9 | const { deployer } = await hre.getNamedAccounts() 10 | 11 | await deployAndVerifyAndThen({ 12 | hre, 13 | name: names.managed.contracts.Proxy__OVM_L1StandardBridge, 14 | contract: 'L1ChugSplashProxy', 15 | iface: 'L1StandardBridge', 16 | args: [deployer], 17 | }) 18 | } 19 | 20 | // This is kept during an upgrade. So no upgrade tag. 21 | deployFn.tags = ['Proxy__OVM_L1StandardBridge'] 22 | 23 | export default deployFn 24 | -------------------------------------------------------------------------------- /deploy/010-AddressDictator.deploy.ts: -------------------------------------------------------------------------------- 1 | /* Imports: External */ 2 | import { DeployFunction } from 'hardhat-deploy/dist/types' 3 | import { hexStringEquals } from '@eth-patex/core-utils' 4 | 5 | /* Imports: Internal */ 6 | import { 7 | deployAndVerifyAndThen, 8 | getContractFromArtifact, 9 | } from '../src/deploy-utils' 10 | import { names } from '../src/address-names' 11 | import { predeploys } from '../src/predeploys' 12 | 13 | const deployFn: DeployFunction = async (hre) => { 14 | const Lib_AddressManager = await getContractFromArtifact( 15 | hre, 16 | names.unmanaged.Lib_AddressManager 17 | ) 18 | 19 | let namesAndAddresses: { 20 | name: string 21 | address: string 22 | }[] = await Promise.all( 23 | Object.values(names.managed.contracts).map(async (name) => { 24 | return { 25 | name, 26 | address: (await getContractFromArtifact(hre, name)).address, 27 | } 28 | }) 29 | ) 30 | 31 | // Add non-deployed addresses to the Address Dictator arguments. 32 | namesAndAddresses = [ 33 | ...namesAndAddresses, 34 | // L2CrossDomainMessenger is the address of the predeploy on L2. We can refactor off-chain 35 | // services such that we can remove the need to set this address, but for now it's easier 36 | // to simply keep setting the address. 37 | { 38 | name: 'L2CrossDomainMessenger', 39 | address: predeploys.L2CrossDomainMessenger, 40 | }, 41 | // OVM_Sequencer is the address allowed to submit "Sequencer" blocks to the 42 | // CanonicalTransactionChain. 43 | { 44 | name: names.managed.accounts.OVM_Sequencer, 45 | address: hre.deployConfig.ovmSequencerAddress, 46 | }, 47 | // OVM_Proposer is the address allowed to submit state roots (transaction results) to the 48 | // StateCommitmentChain. 49 | { 50 | name: names.managed.accounts.OVM_Proposer, 51 | address: hre.deployConfig.ovmProposerAddress, 52 | }, 53 | ] 54 | 55 | // Filter out all addresses that will not change, so that the log statement is maximally 56 | // verifiable and readable. 57 | const existingAddresses = {} 58 | for (const pair of namesAndAddresses) { 59 | existingAddresses[pair.name] = await Lib_AddressManager.getAddress( 60 | pair.name 61 | ) 62 | } 63 | namesAndAddresses = namesAndAddresses.filter(({ name, address }) => { 64 | return !hexStringEquals(existingAddresses[name], address) 65 | }) 66 | 67 | await deployAndVerifyAndThen({ 68 | hre, 69 | name: names.unmanaged.AddressDictator, 70 | args: [ 71 | Lib_AddressManager.address, 72 | hre.deployConfig.ovmAddressManagerOwner, 73 | namesAndAddresses.map((pair) => { 74 | return pair.name 75 | }), 76 | namesAndAddresses.map((pair) => { 77 | return pair.address 78 | }), 79 | ], 80 | }) 81 | } 82 | 83 | deployFn.tags = ['upgrade', 'AddressDictator'] 84 | 85 | export default deployFn 86 | -------------------------------------------------------------------------------- /deploy/012-initialize-Proxy__L1CrossDomainMessenger.ts: -------------------------------------------------------------------------------- 1 | /* Imports: External */ 2 | import { DeployFunction } from 'hardhat-deploy/dist/types' 3 | import { hexStringEquals, awaitCondition } from '@eth-patex/core-utils' 4 | 5 | /* Imports: Internal */ 6 | import { getContractFromArtifact } from '../src/deploy-utils' 7 | import { names } from '../src/address-names' 8 | 9 | const deployFn: DeployFunction = async (hre) => { 10 | const { deployer } = await hre.getNamedAccounts() 11 | 12 | // There's a risk that we could get front-run during a fresh deployment, which would brick this 13 | // contract and require that the proxy be re-deployed. We will not have this risk once we move 14 | // entirely to chugsplash-style deployments. It's unlikely to happen and relatively easy to 15 | // recover from so let's just ignore it for now. 16 | const Proxy__OVM_L1CrossDomainMessenger = await getContractFromArtifact( 17 | hre, 18 | names.managed.contracts.Proxy__OVM_L1CrossDomainMessenger, 19 | { 20 | iface: 'L1CrossDomainMessenger', 21 | signerOrProvider: deployer, 22 | } 23 | ) 24 | 25 | const Lib_AddressManager = await getContractFromArtifact( 26 | hre, 27 | names.unmanaged.Lib_AddressManager 28 | ) 29 | 30 | console.log(`Initializing Proxy__OVM_L1CrossDomainMessenger...`) 31 | await Proxy__OVM_L1CrossDomainMessenger.initialize(Lib_AddressManager.address) 32 | 33 | console.log(`Checking that contract was correctly initialized...`) 34 | await awaitCondition( 35 | async () => { 36 | return hexStringEquals( 37 | await Proxy__OVM_L1CrossDomainMessenger.libAddressManager(), 38 | Lib_AddressManager.address 39 | ) 40 | }, 41 | 5000, 42 | 100 43 | ) 44 | 45 | console.log(`Setting Proxy__OVM_L1CrossDomainMessenger owner...`) 46 | const owner = hre.deployConfig.ovmAddressManagerOwner 47 | await Proxy__OVM_L1CrossDomainMessenger.transferOwnership(owner) 48 | 49 | console.log(`Checking that the contract owner was correctly set...`) 50 | await awaitCondition( 51 | async () => { 52 | return hexStringEquals( 53 | await Proxy__OVM_L1CrossDomainMessenger.owner(), 54 | owner 55 | ) 56 | }, 57 | 5000, 58 | 100 59 | ) 60 | } 61 | 62 | deployFn.tags = ['finalize'] 63 | 64 | export default deployFn 65 | -------------------------------------------------------------------------------- /deploy/013-ChugSplashDictator.deploy.ts: -------------------------------------------------------------------------------- 1 | /* Imports: External */ 2 | import { DeployFunction } from 'hardhat-deploy/dist/types' 3 | import { ethers } from 'ethers' 4 | 5 | /* Imports: Internal */ 6 | import { predeploys } from '../src/predeploys' 7 | import { getContractDefinition } from '../src/contract-defs' 8 | import { 9 | getContractFromArtifact, 10 | deployAndVerifyAndThen, 11 | } from '../src/deploy-utils' 12 | import { names } from '../src/address-names' 13 | 14 | const deployFn: DeployFunction = async (hre) => { 15 | const Proxy__OVM_L1StandardBridge = await getContractFromArtifact( 16 | hre, 17 | 'Proxy__OVM_L1StandardBridge' 18 | ) 19 | 20 | // Note: if the contract being deployed has immutable values this approach would not work. 21 | const bridgeArtifact = getContractDefinition('L1StandardBridge') 22 | const bridgeCode = bridgeArtifact.deployedBytecode 23 | 24 | const Proxy__OVM_L1CrossDomainMessenger = await getContractFromArtifact( 25 | hre, 26 | names.managed.contracts.Proxy__OVM_L1CrossDomainMessenger 27 | ) 28 | 29 | await deployAndVerifyAndThen({ 30 | hre, 31 | name: names.unmanaged.ChugSplashDictator, 32 | args: [ 33 | Proxy__OVM_L1StandardBridge.address, 34 | hre.deployConfig.ovmAddressManagerOwner, 35 | ethers.utils.keccak256(bridgeCode), 36 | ethers.utils.hexZeroPad('0x00', 32), 37 | ethers.utils.hexZeroPad(Proxy__OVM_L1CrossDomainMessenger.address, 32), 38 | ethers.utils.hexZeroPad('0x01', 32), 39 | ethers.utils.hexZeroPad(predeploys.L2StandardBridge, 32), 40 | ], 41 | }) 42 | } 43 | 44 | deployFn.tags = ['upgrade', 'ChugSplashDictator'] 45 | 46 | export default deployFn 47 | -------------------------------------------------------------------------------- /deploy/015-finalize.ts: -------------------------------------------------------------------------------- 1 | /* Imports: External */ 2 | import { DeployFunction } from 'hardhat-deploy/dist/types' 3 | import { hexStringEquals, awaitCondition } from '@eth-patex/core-utils' 4 | 5 | /* Imports: Internal */ 6 | import { getContractFromArtifact } from '../src/deploy-utils' 7 | 8 | const deployFn: DeployFunction = async (hre) => { 9 | const { deployer } = await hre.getNamedAccounts() 10 | 11 | const Lib_AddressManager = await getContractFromArtifact( 12 | hre, 13 | 'Lib_AddressManager', 14 | { 15 | signerOrProvider: deployer, 16 | } 17 | ) 18 | 19 | const owner = hre.deployConfig.ovmAddressManagerOwner 20 | const remoteOwner = await Lib_AddressManager.owner() 21 | if (hexStringEquals(owner, remoteOwner)) { 22 | console.log( 23 | `✓ Not changing owner of Lib_AddressManager because it's already correctly set` 24 | ) 25 | return 26 | } 27 | 28 | console.log(`Transferring ownership of Lib_AddressManager to ${owner}...`) 29 | await Lib_AddressManager.transferOwnership(owner) 30 | 31 | console.log(`Confirming transfer was successful...`) 32 | await awaitCondition( 33 | async () => { 34 | return hexStringEquals(await Lib_AddressManager.owner(), owner) 35 | }, 36 | 5000, 37 | 100 38 | ) 39 | 40 | console.log(`✓ Set owner of Lib_AddressManager to: ${owner}`) 41 | } 42 | 43 | deployFn.tags = ['upgrade', 'finalize'] 44 | 45 | export default deployFn 46 | -------------------------------------------------------------------------------- /deploy/016-fund-accounts.ts: -------------------------------------------------------------------------------- 1 | /* Imports: External */ 2 | import { sleep } from '@eth-patex/core-utils' 3 | import { DeployFunction } from 'hardhat-deploy/dist/types' 4 | import { defaultHardhatNetworkHdAccountsConfigParams } from 'hardhat/internal/core/config/default-config' 5 | import { normalizeHardhatNetworkAccountsConfig } from 'hardhat/internal/core/providers/util' 6 | 7 | /* Imports: Internal */ 8 | import { getContractFromArtifact, isHardhatNode } from '../src/deploy-utils' 9 | import { names } from '../src/address-names' 10 | 11 | // This is a TEMPORARY way to fund the default hardhat accounts on L2. The better way to do this is 12 | // to make a modification to hardhat-ovm. However, I don't have the time right now to figure the 13 | // details of how to make that work cleanly. This is fine in the meantime. 14 | const deployFn: DeployFunction = async (hre) => { 15 | // Only execute this step if we're on the hardhat chain ID. 16 | if (await isHardhatNode(hre)) { 17 | const L1StandardBridge = await getContractFromArtifact( 18 | hre, 19 | names.managed.contracts.Proxy__OVM_L1StandardBridge, 20 | { 21 | iface: 'L1StandardBridge', 22 | } 23 | ) 24 | 25 | // Default has 20 accounts but we restrict to 20 accounts manually as well just to prevent 26 | // future problems if the number of default accounts increases for whatever reason. 27 | const accounts = normalizeHardhatNetworkAccountsConfig( 28 | defaultHardhatNetworkHdAccountsConfigParams 29 | ).slice(0, 20) 30 | 31 | // Set balances on L1 for the predeploy deployers 32 | 33 | // 0xa961b0d6dce82db098cf70a42a14add3ee3db2d5 34 | await hre.network.provider.send('hardhat_setBalance', [ 35 | '0xa961b0d6dce82db098cf70a42a14add3ee3db2d5', 36 | '0x8000000000000000000000', 37 | ]) 38 | accounts.push({ 39 | privateKey: 40 | '0xa6aecc98b63bafb0de3b29ae9964b14acb4086057808be29f90150214ebd4a0f', 41 | balance: '', 42 | }) 43 | 44 | // 0xdfc82d475833a50de90c642770f34a9db7deb725 45 | await hre.network.provider.send('hardhat_setBalance', [ 46 | '0xdfc82d475833a50de90c642770f34a9db7deb725', 47 | '0x8000000000000000000000', 48 | ]) 49 | accounts.push({ 50 | privateKey: 51 | '0x3b8d2345102cce2443acb240db6e87c8edd4bb3f821b17fab8ea2c9da08ea132', 52 | balance: '', 53 | }) 54 | 55 | // Fund the accounts in parallel to speed things up. 56 | await Promise.all( 57 | accounts.map(async (account, index) => { 58 | // Add a sleep here to avoid any potential issues with spamming hardhat. Not sure if this 59 | // is strictly necessary but it can't hurt. 60 | await sleep(200 * index) 61 | 62 | const wallet = new hre.ethers.Wallet( 63 | account.privateKey, 64 | hre.ethers.provider 65 | ) 66 | const balance = await wallet.getBalance() 67 | const depositAmount = balance.div(2) // Deposit half of the wallet's balance into L2. 68 | await L1StandardBridge.connect(wallet).depositETH(8_000_000, '0x', { 69 | value: depositAmount, 70 | gasLimit: 2_000_000, // Idk, gas estimation was broken and this fixes it. 71 | }) 72 | console.log( 73 | `✓ Funded ${wallet.address} on L2 with ${hre.ethers.utils.formatEther( 74 | depositAmount 75 | )} ETH` 76 | ) 77 | }) 78 | ) 79 | } 80 | } 81 | 82 | deployFn.tags = ['fund-accounts'] 83 | 84 | export default deployFn 85 | -------------------------------------------------------------------------------- /deployments/README.md: -------------------------------------------------------------------------------- 1 | # Patex Deployments 2 | - [Patex (mainnet)](./mainnet#readme) 3 | - [Patex Goerli (public testnet)](./goerli#readme) 4 | -------------------------------------------------------------------------------- /docs/Address.md: -------------------------------------------------------------------------------- 1 | # Address 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | *Collection of functions related to the address type* 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /docs/AddressAliasHelper.md: -------------------------------------------------------------------------------- 1 | # AddressAliasHelper 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /docs/AddressDictator.md: -------------------------------------------------------------------------------- 1 | # AddressDictator 2 | 3 | 4 | 5 | > AddressDictator 6 | 7 | 8 | 9 | *The AddressDictator (glory to Arstotzka) is a contract that allows us to safely manipulate many different addresses in the AddressManager without transferring ownership of the AddressManager to a hot wallet or hardware wallet.* 10 | 11 | ## Methods 12 | 13 | ### finalOwner 14 | 15 | ```solidity 16 | function finalOwner() external view returns (address) 17 | ``` 18 | 19 | 20 | 21 | 22 | 23 | 24 | #### Returns 25 | 26 | | Name | Type | Description | 27 | |---|---|---| 28 | | _0 | address | undefined 29 | 30 | ### getNamedAddresses 31 | 32 | ```solidity 33 | function getNamedAddresses() external view returns (struct AddressDictator.NamedAddress[]) 34 | ``` 35 | 36 | Returns the full namedAddresses array. 37 | 38 | 39 | 40 | 41 | #### Returns 42 | 43 | | Name | Type | Description | 44 | |---|---|---| 45 | | _0 | AddressDictator.NamedAddress[] | undefined 46 | 47 | ### manager 48 | 49 | ```solidity 50 | function manager() external view returns (contract Lib_AddressManager) 51 | ``` 52 | 53 | 54 | 55 | 56 | 57 | 58 | #### Returns 59 | 60 | | Name | Type | Description | 61 | |---|---|---| 62 | | _0 | contract Lib_AddressManager | undefined 63 | 64 | ### returnOwnership 65 | 66 | ```solidity 67 | function returnOwnership() external nonpayable 68 | ``` 69 | 70 | Transfers ownership of this contract to the finalOwner. Only callable by the Final Owner, which is intended to be our multisig. This function shouldn't be necessary, but it gives a sense of reassurance that we can recover if something really surprising goes wrong. 71 | 72 | 73 | 74 | 75 | ### setAddresses 76 | 77 | ```solidity 78 | function setAddresses() external nonpayable 79 | ``` 80 | 81 | Called to finalize the transfer, this function is callable by anyone, but will only result in an upgrade if this contract is the owner Address Manager. 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | -------------------------------------------------------------------------------- /docs/AddressUpgradeable.md: -------------------------------------------------------------------------------- 1 | # AddressUpgradeable 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | *Collection of functions related to the address type* 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /docs/BondManager.md: -------------------------------------------------------------------------------- 1 | # BondManager 2 | 3 | 4 | 5 | > BondManager 6 | 7 | 8 | 9 | *This contract is, for now, a stub of the "real" BondManager that does nothing but allow the "OVM_Proposer" to submit state root batches.* 10 | 11 | ## Methods 12 | 13 | ### isCollateralized 14 | 15 | ```solidity 16 | function isCollateralized(address _who) external view returns (bool) 17 | ``` 18 | 19 | Checks whether a given address is properly collateralized and can perform actions within the system. 20 | 21 | 22 | 23 | #### Parameters 24 | 25 | | Name | Type | Description | 26 | |---|---|---| 27 | | _who | address | Address to check. 28 | 29 | #### Returns 30 | 31 | | Name | Type | Description | 32 | |---|---|---| 33 | | _0 | bool | true if the address is properly collateralized, false otherwise. 34 | 35 | ### libAddressManager 36 | 37 | ```solidity 38 | function libAddressManager() external view returns (contract Lib_AddressManager) 39 | ``` 40 | 41 | 42 | 43 | 44 | 45 | 46 | #### Returns 47 | 48 | | Name | Type | Description | 49 | |---|---|---| 50 | | _0 | contract Lib_AddressManager | undefined 51 | 52 | ### resolve 53 | 54 | ```solidity 55 | function resolve(string _name) external view returns (address) 56 | ``` 57 | 58 | Resolves the address associated with a given name. 59 | 60 | 61 | 62 | #### Parameters 63 | 64 | | Name | Type | Description | 65 | |---|---|---| 66 | | _name | string | Name to resolve an address for. 67 | 68 | #### Returns 69 | 70 | | Name | Type | Description | 71 | |---|---|---| 72 | | _0 | address | Address associated with the given name. 73 | 74 | 75 | 76 | 77 | -------------------------------------------------------------------------------- /docs/ChugSplashDictator.md: -------------------------------------------------------------------------------- 1 | # ChugSplashDictator 2 | 3 | 4 | 5 | > ChugSplashDictator 6 | 7 | 8 | 9 | *Like the AddressDictator, but specifically for the Proxy__OVM_L1StandardBridge. We're working on a generalized version of this but this is good enough for the moment.* 10 | 11 | ## Methods 12 | 13 | ### bridgeSlotKey 14 | 15 | ```solidity 16 | function bridgeSlotKey() external view returns (bytes32) 17 | ``` 18 | 19 | 20 | 21 | 22 | 23 | 24 | #### Returns 25 | 26 | | Name | Type | Description | 27 | |---|---|---| 28 | | _0 | bytes32 | undefined 29 | 30 | ### bridgeSlotVal 31 | 32 | ```solidity 33 | function bridgeSlotVal() external view returns (bytes32) 34 | ``` 35 | 36 | 37 | 38 | 39 | 40 | 41 | #### Returns 42 | 43 | | Name | Type | Description | 44 | |---|---|---| 45 | | _0 | bytes32 | undefined 46 | 47 | ### codeHash 48 | 49 | ```solidity 50 | function codeHash() external view returns (bytes32) 51 | ``` 52 | 53 | 54 | 55 | 56 | 57 | 58 | #### Returns 59 | 60 | | Name | Type | Description | 61 | |---|---|---| 62 | | _0 | bytes32 | undefined 63 | 64 | ### doActions 65 | 66 | ```solidity 67 | function doActions(bytes _code) external nonpayable 68 | ``` 69 | 70 | 71 | 72 | 73 | 74 | #### Parameters 75 | 76 | | Name | Type | Description | 77 | |---|---|---| 78 | | _code | bytes | undefined 79 | 80 | ### finalOwner 81 | 82 | ```solidity 83 | function finalOwner() external view returns (address) 84 | ``` 85 | 86 | 87 | 88 | 89 | 90 | 91 | #### Returns 92 | 93 | | Name | Type | Description | 94 | |---|---|---| 95 | | _0 | address | undefined 96 | 97 | ### isUpgrading 98 | 99 | ```solidity 100 | function isUpgrading() external view returns (bool) 101 | ``` 102 | 103 | 104 | 105 | 106 | 107 | 108 | #### Returns 109 | 110 | | Name | Type | Description | 111 | |---|---|---| 112 | | _0 | bool | undefined 113 | 114 | ### messengerSlotKey 115 | 116 | ```solidity 117 | function messengerSlotKey() external view returns (bytes32) 118 | ``` 119 | 120 | 121 | 122 | 123 | 124 | 125 | #### Returns 126 | 127 | | Name | Type | Description | 128 | |---|---|---| 129 | | _0 | bytes32 | undefined 130 | 131 | ### messengerSlotVal 132 | 133 | ```solidity 134 | function messengerSlotVal() external view returns (bytes32) 135 | ``` 136 | 137 | 138 | 139 | 140 | 141 | 142 | #### Returns 143 | 144 | | Name | Type | Description | 145 | |---|---|---| 146 | | _0 | bytes32 | undefined 147 | 148 | ### returnOwnership 149 | 150 | ```solidity 151 | function returnOwnership() external nonpayable 152 | ``` 153 | 154 | Transfers ownership of this contract to the finalOwner. Only callable by the finalOwner, which is intended to be our multisig. This function shouldn't be necessary, but it gives a sense of reassurance that we can recover if something really surprising goes wrong. 155 | 156 | 157 | 158 | 159 | ### target 160 | 161 | ```solidity 162 | function target() external view returns (contract L1ChugSplashProxy) 163 | ``` 164 | 165 | 166 | 167 | 168 | 169 | 170 | #### Returns 171 | 172 | | Name | Type | Description | 173 | |---|---|---| 174 | | _0 | contract L1ChugSplashProxy | undefined 175 | 176 | 177 | 178 | 179 | -------------------------------------------------------------------------------- /docs/Context.md: -------------------------------------------------------------------------------- 1 | # Context 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | *Provides information about the current execution context, including the sender of the transaction and its data. While these are generally available via msg.sender and msg.data, they should not be accessed in such a direct manner, since when dealing with meta-transactions the account sending and paying for execution may not be the actual sender (as far as an application is concerned). This contract is only required for intermediate, library-like contracts.* 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /docs/ContextUpgradeable.md: -------------------------------------------------------------------------------- 1 | # ContextUpgradeable 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | *Provides information about the current execution context, including the sender of the transaction and its data. While these are generally available via msg.sender and msg.data, they should not be accessed in such a direct manner, since when dealing with meta-transactions the account sending and paying for execution may not be the actual sender (as far as an application is concerned). This contract is only required for intermediate, library-like contracts.* 10 | 11 | 12 | ## Events 13 | 14 | ### Initialized 15 | 16 | ```solidity 17 | event Initialized(uint8 version) 18 | ``` 19 | 20 | 21 | 22 | 23 | 24 | #### Parameters 25 | 26 | | Name | Type | Description | 27 | |---|---|---| 28 | | version | uint8 | undefined | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /docs/CrossDomainEnabled.md: -------------------------------------------------------------------------------- 1 | # CrossDomainEnabled 2 | 3 | 4 | 5 | > CrossDomainEnabled 6 | 7 | 8 | 9 | *Helper contract for contracts performing cross-domain communications Compiler used: defined by inheriting contract* 10 | 11 | ## Methods 12 | 13 | ### messenger 14 | 15 | ```solidity 16 | function messenger() external view returns (address) 17 | ``` 18 | 19 | 20 | 21 | 22 | 23 | 24 | #### Returns 25 | 26 | | Name | Type | Description | 27 | |---|---|---| 28 | | _0 | address | undefined 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /docs/ERC165Checker.md: -------------------------------------------------------------------------------- 1 | # ERC165Checker 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | *Library used to query support of an interface declared via {IERC165}. Note that these functions return the actual result of the query: they do not `revert` if an interface is not supported. It is up to the caller to decide what to do in these cases.* 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /docs/FailingReceiver.md: -------------------------------------------------------------------------------- 1 | # FailingReceiver 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /docs/IBondManager.md: -------------------------------------------------------------------------------- 1 | # IBondManager 2 | 3 | 4 | 5 | > IBondManager 6 | 7 | 8 | 9 | 10 | 11 | ## Methods 12 | 13 | ### isCollateralized 14 | 15 | ```solidity 16 | function isCollateralized(address _who) external view returns (bool) 17 | ``` 18 | 19 | Checks whether a given address is properly collateralized and can perform actions within the system. 20 | 21 | 22 | 23 | #### Parameters 24 | 25 | | Name | Type | Description | 26 | |---|---|---| 27 | | _who | address | Address to check. 28 | 29 | #### Returns 30 | 31 | | Name | Type | Description | 32 | |---|---|---| 33 | | _0 | bool | true if the address is properly collateralized, false otherwise. 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /docs/IChainStorageContainer.md: -------------------------------------------------------------------------------- 1 | # IChainStorageContainer 2 | 3 | 4 | 5 | > IChainStorageContainer 6 | 7 | 8 | 9 | 10 | 11 | ## Methods 12 | 13 | ### deleteElementsAfterInclusive 14 | 15 | ```solidity 16 | function deleteElementsAfterInclusive(uint256 _index) external nonpayable 17 | ``` 18 | 19 | Removes all objects after and including a given index. Also allows setting the global metadata field. 20 | 21 | 22 | 23 | #### Parameters 24 | 25 | | Name | Type | Description | 26 | |---|---|---| 27 | | _index | uint256 | Object index to delete from. 28 | 29 | ### get 30 | 31 | ```solidity 32 | function get(uint256 _index) external view returns (bytes32) 33 | ``` 34 | 35 | Retrieves an object from the container. 36 | 37 | 38 | 39 | #### Parameters 40 | 41 | | Name | Type | Description | 42 | |---|---|---| 43 | | _index | uint256 | Index of the particular object to access. 44 | 45 | #### Returns 46 | 47 | | Name | Type | Description | 48 | |---|---|---| 49 | | _0 | bytes32 | 32 byte object value. 50 | 51 | ### getGlobalMetadata 52 | 53 | ```solidity 54 | function getGlobalMetadata() external view returns (bytes27) 55 | ``` 56 | 57 | Retrieves the container's global metadata field. 58 | 59 | 60 | 61 | 62 | #### Returns 63 | 64 | | Name | Type | Description | 65 | |---|---|---| 66 | | _0 | bytes27 | Container global metadata field. 67 | 68 | ### length 69 | 70 | ```solidity 71 | function length() external view returns (uint256) 72 | ``` 73 | 74 | Retrieves the number of objects stored in the container. 75 | 76 | 77 | 78 | 79 | #### Returns 80 | 81 | | Name | Type | Description | 82 | |---|---|---| 83 | | _0 | uint256 | Number of objects in the container. 84 | 85 | ### push 86 | 87 | ```solidity 88 | function push(bytes32 _object) external nonpayable 89 | ``` 90 | 91 | Pushes an object into the container. Function allows setting the global metadata since we'll need to touch the "length" storage slot anyway, which also contains the global metadata (it's an optimization). 92 | 93 | 94 | 95 | #### Parameters 96 | 97 | | Name | Type | Description | 98 | |---|---|---| 99 | | _object | bytes32 | A 32 byte value to insert into the container. 100 | 101 | ### setGlobalMetadata 102 | 103 | ```solidity 104 | function setGlobalMetadata(bytes27 _globalMetadata) external nonpayable 105 | ``` 106 | 107 | Sets the container's global metadata field. We're using `bytes27` here because we use five bytes to maintain the length of the underlying data structure, meaning we have an extra 27 bytes to store arbitrary data. 108 | 109 | 110 | 111 | #### Parameters 112 | 113 | | Name | Type | Description | 114 | |---|---|---| 115 | | _globalMetadata | bytes27 | New global metadata to set. 116 | 117 | 118 | 119 | 120 | -------------------------------------------------------------------------------- /docs/ICrossDomainMessenger.md: -------------------------------------------------------------------------------- 1 | # ICrossDomainMessenger 2 | 3 | 4 | 5 | > ICrossDomainMessenger 6 | 7 | 8 | 9 | 10 | 11 | ## Methods 12 | 13 | ### sendMessage 14 | 15 | ```solidity 16 | function sendMessage(address _target, bytes _message, uint32 _gasLimit) external nonpayable 17 | ``` 18 | 19 | Sends a cross domain message to the target messenger. 20 | 21 | 22 | 23 | #### Parameters 24 | 25 | | Name | Type | Description | 26 | |---|---|---| 27 | | _target | address | Target contract address. 28 | | _message | bytes | Message to send to the target. 29 | | _gasLimit | uint32 | Gas limit for the provided message. 30 | 31 | ### xDomainMessageSender 32 | 33 | ```solidity 34 | function xDomainMessageSender() external view returns (address) 35 | ``` 36 | 37 | 38 | 39 | 40 | 41 | 42 | #### Returns 43 | 44 | | Name | Type | Description | 45 | |---|---|---| 46 | | _0 | address | undefined 47 | 48 | 49 | 50 | ## Events 51 | 52 | ### FailedRelayedMessage 53 | 54 | ```solidity 55 | event FailedRelayedMessage(bytes32 indexed msgHash) 56 | ``` 57 | 58 | 59 | 60 | 61 | 62 | #### Parameters 63 | 64 | | Name | Type | Description | 65 | |---|---|---| 66 | | msgHash `indexed` | bytes32 | undefined | 67 | 68 | ### RelayedMessage 69 | 70 | ```solidity 71 | event RelayedMessage(bytes32 indexed msgHash) 72 | ``` 73 | 74 | 75 | 76 | 77 | 78 | #### Parameters 79 | 80 | | Name | Type | Description | 81 | |---|---|---| 82 | | msgHash `indexed` | bytes32 | undefined | 83 | 84 | ### SentMessage 85 | 86 | ```solidity 87 | event SentMessage(address indexed target, address sender, bytes message, uint256 messageNonce, uint256 gasLimit) 88 | ``` 89 | 90 | 91 | 92 | 93 | 94 | #### Parameters 95 | 96 | | Name | Type | Description | 97 | |---|---|---| 98 | | target `indexed` | address | undefined | 99 | | sender | address | undefined | 100 | | message | bytes | undefined | 101 | | messageNonce | uint256 | undefined | 102 | | gasLimit | uint256 | undefined | 103 | 104 | 105 | 106 | -------------------------------------------------------------------------------- /docs/IERC165.md: -------------------------------------------------------------------------------- 1 | # IERC165 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | *Interface of the ERC165 standard, as defined in the https://eips.ethereum.org/EIPS/eip-165[EIP]. Implementers can declare support of contract interfaces, which can then be queried by others ({ERC165Checker}). For an implementation, see {ERC165}.* 10 | 11 | ## Methods 12 | 13 | ### supportsInterface 14 | 15 | ```solidity 16 | function supportsInterface(bytes4 interfaceId) external view returns (bool) 17 | ``` 18 | 19 | 20 | 21 | *Returns true if this contract implements the interface defined by `interfaceId`. See the corresponding https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] to learn more about how these ids are created. This function call must use less than 30 000 gas.* 22 | 23 | #### Parameters 24 | 25 | | Name | Type | Description | 26 | |---|---|---| 27 | | interfaceId | bytes4 | undefined 28 | 29 | #### Returns 30 | 31 | | Name | Type | Description | 32 | |---|---|---| 33 | | _0 | bool | undefined 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /docs/IL2CrossDomainMessenger.md: -------------------------------------------------------------------------------- 1 | # IL2CrossDomainMessenger 2 | 3 | 4 | 5 | > IL2CrossDomainMessenger 6 | 7 | 8 | 9 | 10 | 11 | ## Methods 12 | 13 | ### relayMessage 14 | 15 | ```solidity 16 | function relayMessage(address _target, address _sender, bytes _message, uint256 _messageNonce) external nonpayable 17 | ``` 18 | 19 | Relays a cross domain message to a contract. 20 | 21 | 22 | 23 | #### Parameters 24 | 25 | | Name | Type | Description | 26 | |---|---|---| 27 | | _target | address | Target contract address. 28 | | _sender | address | Message sender address. 29 | | _message | bytes | Message to send to the target. 30 | | _messageNonce | uint256 | Nonce for the provided message. 31 | 32 | ### sendMessage 33 | 34 | ```solidity 35 | function sendMessage(address _target, bytes _message, uint32 _gasLimit) external nonpayable 36 | ``` 37 | 38 | Sends a cross domain message to the target messenger. 39 | 40 | 41 | 42 | #### Parameters 43 | 44 | | Name | Type | Description | 45 | |---|---|---| 46 | | _target | address | Target contract address. 47 | | _message | bytes | Message to send to the target. 48 | | _gasLimit | uint32 | Gas limit for the provided message. 49 | 50 | ### xDomainMessageSender 51 | 52 | ```solidity 53 | function xDomainMessageSender() external view returns (address) 54 | ``` 55 | 56 | 57 | 58 | 59 | 60 | 61 | #### Returns 62 | 63 | | Name | Type | Description | 64 | |---|---|---| 65 | | _0 | address | undefined 66 | 67 | 68 | 69 | ## Events 70 | 71 | ### FailedRelayedMessage 72 | 73 | ```solidity 74 | event FailedRelayedMessage(bytes32 indexed msgHash) 75 | ``` 76 | 77 | 78 | 79 | 80 | 81 | #### Parameters 82 | 83 | | Name | Type | Description | 84 | |---|---|---| 85 | | msgHash `indexed` | bytes32 | undefined | 86 | 87 | ### RelayedMessage 88 | 89 | ```solidity 90 | event RelayedMessage(bytes32 indexed msgHash) 91 | ``` 92 | 93 | 94 | 95 | 96 | 97 | #### Parameters 98 | 99 | | Name | Type | Description | 100 | |---|---|---| 101 | | msgHash `indexed` | bytes32 | undefined | 102 | 103 | ### SentMessage 104 | 105 | ```solidity 106 | event SentMessage(address indexed target, address sender, bytes message, uint256 messageNonce, uint256 gasLimit) 107 | ``` 108 | 109 | 110 | 111 | 112 | 113 | #### Parameters 114 | 115 | | Name | Type | Description | 116 | |---|---|---| 117 | | target `indexed` | address | undefined | 118 | | sender | address | undefined | 119 | | message | bytes | undefined | 120 | | messageNonce | uint256 | undefined | 121 | | gasLimit | uint256 | undefined | 122 | 123 | 124 | 125 | -------------------------------------------------------------------------------- /docs/Initializable.md: -------------------------------------------------------------------------------- 1 | # Initializable 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | *This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer function so it can only be called once. The {initializer} modifier provided by this contract will have this effect. The initialization functions use a version number. Once a version number is used, it is consumed and cannot be reused. This mechanism prevents re-execution of each "step" but allows the creation of new initialization steps in case an upgrade adds a module that needs to be initialized. For example: [.hljs-theme-light.nopadding] ``` contract MyToken is ERC20Upgradeable { function initialize() initializer public { __ERC20_init("MyToken", "MTK"); } } contract MyTokenV2 is MyToken, ERC20PermitUpgradeable { function initializeV2() reinitializer(2) public { __ERC20Permit_init("MyToken"); } } ``` TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}. CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure that all initializers are idempotent. This is not verified automatically as constructors are by Solidity. [CAUTION] ==== Avoid leaving a contract uninitialized. An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke the {_disableInitializers} function in the constructor to automatically lock it when it is deployed: [.hljs-theme-light.nopadding] ```* 10 | 11 | 12 | ## Events 13 | 14 | ### Initialized 15 | 16 | ```solidity 17 | event Initialized(uint8 version) 18 | ``` 19 | 20 | 21 | 22 | *Triggered when the contract has been initialized or reinitialized.* 23 | 24 | #### Parameters 25 | 26 | | Name | Type | Description | 27 | |---|---|---| 28 | | version | uint8 | undefined | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /docs/L1ChugSplashProxy.md: -------------------------------------------------------------------------------- 1 | # L1ChugSplashProxy 2 | 3 | 4 | 5 | > L1ChugSplashProxy 6 | 7 | 8 | 9 | *Basic ChugSplash proxy contract for L1. Very close to being a normal proxy but has added functions `setCode` and `setStorage` for changing the code or storage of the contract. Nifty! Note for future developers: do NOT make anything in this contract 'public' unless you know what you're doing. Anything public can potentially have a function signature that conflicts with a signature attached to the implementation contract. Public functions SHOULD always have the 'proxyCallIfNotOwner' modifier unless there's some *really* good reason not to have that modifier. And there almost certainly is not a good reason to not have that modifier. Beware!* 10 | 11 | ## Methods 12 | 13 | ### getImplementation 14 | 15 | ```solidity 16 | function getImplementation() external nonpayable returns (address) 17 | ``` 18 | 19 | Queries the implementation address. Can only be called by the owner OR by making an eth_call and setting the "from" address to address(0). 20 | 21 | 22 | 23 | 24 | #### Returns 25 | 26 | | Name | Type | Description | 27 | |---|---|---| 28 | | _0 | address | Implementation address. 29 | 30 | ### getOwner 31 | 32 | ```solidity 33 | function getOwner() external nonpayable returns (address) 34 | ``` 35 | 36 | Queries the owner of the proxy contract. Can only be called by the owner OR by making an eth_call and setting the "from" address to address(0). 37 | 38 | 39 | 40 | 41 | #### Returns 42 | 43 | | Name | Type | Description | 44 | |---|---|---| 45 | | _0 | address | Owner address. 46 | 47 | ### setCode 48 | 49 | ```solidity 50 | function setCode(bytes _code) external nonpayable 51 | ``` 52 | 53 | Sets the code that should be running behind this proxy. Note that this scheme is a bit different from the standard proxy scheme where one would typically deploy the code separately and then set the implementation address. We're doing it this way because it gives us a lot more freedom on the client side. Can only be triggered by the contract owner. 54 | 55 | 56 | 57 | #### Parameters 58 | 59 | | Name | Type | Description | 60 | |---|---|---| 61 | | _code | bytes | New contract code to run inside this contract. 62 | 63 | ### setOwner 64 | 65 | ```solidity 66 | function setOwner(address _owner) external nonpayable 67 | ``` 68 | 69 | Changes the owner of the proxy contract. Only callable by the owner. 70 | 71 | 72 | 73 | #### Parameters 74 | 75 | | Name | Type | Description | 76 | |---|---|---| 77 | | _owner | address | New owner of the proxy contract. 78 | 79 | ### setStorage 80 | 81 | ```solidity 82 | function setStorage(bytes32 _key, bytes32 _value) external nonpayable 83 | ``` 84 | 85 | Modifies some storage slot within the proxy contract. Gives us a lot of power to perform upgrades in a more transparent way. Only callable by the owner. 86 | 87 | 88 | 89 | #### Parameters 90 | 91 | | Name | Type | Description | 92 | |---|---|---| 93 | | _key | bytes32 | Storage key to modify. 94 | | _value | bytes32 | New value for the storage key. 95 | 96 | 97 | 98 | 99 | -------------------------------------------------------------------------------- /docs/L2StandardTokenFactory.md: -------------------------------------------------------------------------------- 1 | # L2StandardTokenFactory 2 | 3 | 4 | 5 | > L2StandardTokenFactory 6 | 7 | 8 | 9 | *Factory contract for creating standard L2 token representations of L1 ERC20s compatible with and working on the standard bridge.* 10 | 11 | ## Methods 12 | 13 | ### createStandardL2Token 14 | 15 | ```solidity 16 | function createStandardL2Token(address _l1Token, string _name, string _symbol) external nonpayable 17 | ``` 18 | 19 | 20 | 21 | *Creates an instance of the standard ERC20 token on L2.* 22 | 23 | #### Parameters 24 | 25 | | Name | Type | Description | 26 | |---|---|---| 27 | | _l1Token | address | Address of the corresponding L1 token. 28 | | _name | string | ERC20 name. 29 | | _symbol | string | ERC20 symbol. 30 | 31 | 32 | 33 | ## Events 34 | 35 | ### StandardL2TokenCreated 36 | 37 | ```solidity 38 | event StandardL2TokenCreated(address indexed _l1Token, address indexed _l2Token) 39 | ``` 40 | 41 | 42 | 43 | 44 | 45 | #### Parameters 46 | 47 | | Name | Type | Description | 48 | |---|---|---| 49 | | _l1Token `indexed` | address | undefined | 50 | | _l2Token `indexed` | address | undefined | 51 | 52 | 53 | 54 | -------------------------------------------------------------------------------- /docs/Lib_AddressManager.md: -------------------------------------------------------------------------------- 1 | # Lib_AddressManager 2 | 3 | 4 | 5 | > Lib_AddressManager 6 | 7 | 8 | 9 | 10 | 11 | ## Methods 12 | 13 | ### getAddress 14 | 15 | ```solidity 16 | function getAddress(string _name) external view returns (address) 17 | ``` 18 | 19 | Retrieves the address associated with a given name. 20 | 21 | 22 | 23 | #### Parameters 24 | 25 | | Name | Type | Description | 26 | |---|---|---| 27 | | _name | string | Name to retrieve an address for. 28 | 29 | #### Returns 30 | 31 | | Name | Type | Description | 32 | |---|---|---| 33 | | _0 | address | Address associated with the given name. 34 | 35 | ### owner 36 | 37 | ```solidity 38 | function owner() external view returns (address) 39 | ``` 40 | 41 | 42 | 43 | *Returns the address of the current owner.* 44 | 45 | 46 | #### Returns 47 | 48 | | Name | Type | Description | 49 | |---|---|---| 50 | | _0 | address | undefined 51 | 52 | ### renounceOwnership 53 | 54 | ```solidity 55 | function renounceOwnership() external nonpayable 56 | ``` 57 | 58 | 59 | 60 | *Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner.* 61 | 62 | 63 | ### setAddress 64 | 65 | ```solidity 66 | function setAddress(string _name, address _address) external nonpayable 67 | ``` 68 | 69 | Changes the address associated with a particular name. 70 | 71 | 72 | 73 | #### Parameters 74 | 75 | | Name | Type | Description | 76 | |---|---|---| 77 | | _name | string | String name to associate an address with. 78 | | _address | address | Address to associate with the name. 79 | 80 | ### transferOwnership 81 | 82 | ```solidity 83 | function transferOwnership(address newOwner) external nonpayable 84 | ``` 85 | 86 | 87 | 88 | *Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner.* 89 | 90 | #### Parameters 91 | 92 | | Name | Type | Description | 93 | |---|---|---| 94 | | newOwner | address | undefined 95 | 96 | 97 | 98 | ## Events 99 | 100 | ### AddressSet 101 | 102 | ```solidity 103 | event AddressSet(string indexed _name, address _newAddress, address _oldAddress) 104 | ``` 105 | 106 | 107 | 108 | 109 | 110 | #### Parameters 111 | 112 | | Name | Type | Description | 113 | |---|---|---| 114 | | _name `indexed` | string | undefined | 115 | | _newAddress | address | undefined | 116 | | _oldAddress | address | undefined | 117 | 118 | ### OwnershipTransferred 119 | 120 | ```solidity 121 | event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) 122 | ``` 123 | 124 | 125 | 126 | 127 | 128 | #### Parameters 129 | 130 | | Name | Type | Description | 131 | |---|---|---| 132 | | previousOwner `indexed` | address | undefined | 133 | | newOwner `indexed` | address | undefined | 134 | 135 | 136 | 137 | -------------------------------------------------------------------------------- /docs/Lib_AddressResolver.md: -------------------------------------------------------------------------------- 1 | # Lib_AddressResolver 2 | 3 | 4 | 5 | > Lib_AddressResolver 6 | 7 | 8 | 9 | 10 | 11 | ## Methods 12 | 13 | ### libAddressManager 14 | 15 | ```solidity 16 | function libAddressManager() external view returns (contract Lib_AddressManager) 17 | ``` 18 | 19 | 20 | 21 | 22 | 23 | 24 | #### Returns 25 | 26 | | Name | Type | Description | 27 | |---|---|---| 28 | | _0 | contract Lib_AddressManager | undefined 29 | 30 | ### resolve 31 | 32 | ```solidity 33 | function resolve(string _name) external view returns (address) 34 | ``` 35 | 36 | Resolves the address associated with a given name. 37 | 38 | 39 | 40 | #### Parameters 41 | 42 | | Name | Type | Description | 43 | |---|---|---| 44 | | _name | string | Name to resolve an address for. 45 | 46 | #### Returns 47 | 48 | | Name | Type | Description | 49 | |---|---|---| 50 | | _0 | address | Address associated with the given name. 51 | 52 | 53 | 54 | 55 | -------------------------------------------------------------------------------- /docs/Lib_Buffer.md: -------------------------------------------------------------------------------- 1 | # Lib_Buffer 2 | 3 | 4 | 5 | > Lib_Buffer 6 | 7 | 8 | 9 | *This library implements a bytes32 storage array with some additional gas-optimized functionality. In particular, it encodes its length as a uint40, and tightly packs this with an overwritable "extra data" field so we can store more information with a single SSTORE.* 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /docs/Lib_Bytes32Utils.md: -------------------------------------------------------------------------------- 1 | # Lib_Bytes32Utils 2 | 3 | 4 | 5 | > Lib_Byte32Utils 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /docs/Lib_BytesUtils.md: -------------------------------------------------------------------------------- 1 | # Lib_BytesUtils 2 | 3 | 4 | 5 | > Lib_BytesUtils 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /docs/Lib_CrossDomainUtils.md: -------------------------------------------------------------------------------- 1 | # Lib_CrossDomainUtils 2 | 3 | 4 | 5 | > Lib_CrossDomainUtils 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /docs/Lib_DefaultValues.md: -------------------------------------------------------------------------------- 1 | # Lib_DefaultValues 2 | 3 | 4 | 5 | > Lib_DefaultValues 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /docs/Lib_MerkleTree.md: -------------------------------------------------------------------------------- 1 | # Lib_MerkleTree 2 | 3 | *River Keefer* 4 | 5 | > Lib_MerkleTree 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /docs/Lib_MerkleTrie.md: -------------------------------------------------------------------------------- 1 | # Lib_MerkleTrie 2 | 3 | 4 | 5 | > Lib_MerkleTrie 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /docs/Lib_OVMCodec.md: -------------------------------------------------------------------------------- 1 | # Lib_OVMCodec 2 | 3 | 4 | 5 | > Lib_OVMCodec 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /docs/Lib_PredeployAddresses.md: -------------------------------------------------------------------------------- 1 | # Lib_PredeployAddresses 2 | 3 | 4 | 5 | > Lib_PredeployAddresses 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /docs/Lib_RLPReader.md: -------------------------------------------------------------------------------- 1 | # Lib_RLPReader 2 | 3 | 4 | 5 | > Lib_RLPReader 6 | 7 | 8 | 9 | *Adapted from "RLPReader" by Hamdi Allam (hamdi.allam97@gmail.com).* 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /docs/Lib_RLPWriter.md: -------------------------------------------------------------------------------- 1 | # Lib_RLPWriter 2 | 3 | *Bakaoh (with modifications)* 4 | 5 | > Lib_RLPWriter 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /docs/Lib_ResolvedDelegateProxy.md: -------------------------------------------------------------------------------- 1 | # Lib_ResolvedDelegateProxy 2 | 3 | 4 | 5 | > Lib_ResolvedDelegateProxy 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /docs/Lib_SecureMerkleTrie.md: -------------------------------------------------------------------------------- 1 | # Lib_SecureMerkleTrie 2 | 3 | 4 | 5 | > Lib_SecureMerkleTrie 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /docs/OVM_L2ToL1MessagePasser.md: -------------------------------------------------------------------------------- 1 | # OVM_L2ToL1MessagePasser 2 | 3 | 4 | 5 | > OVM_L2ToL1MessagePasser 6 | 7 | 8 | 9 | *The L2 to L1 Message Passer is a utility contract which facilitate an L1 proof of the of a message on L2. The L1 Cross Domain Messenger performs this proof in its _verifyStorageProof function, which verifies the existence of the transaction hash in this contract's `sentMessages` mapping.* 10 | 11 | ## Methods 12 | 13 | ### passMessageToL1 14 | 15 | ```solidity 16 | function passMessageToL1(bytes _message) external nonpayable 17 | ``` 18 | 19 | Passes a message to L1. 20 | 21 | 22 | 23 | #### Parameters 24 | 25 | | Name | Type | Description | 26 | |---|---|---| 27 | | _message | bytes | Message to pass to L1. 28 | 29 | ### sentMessages 30 | 31 | ```solidity 32 | function sentMessages(bytes32) external view returns (bool) 33 | ``` 34 | 35 | 36 | 37 | 38 | 39 | #### Parameters 40 | 41 | | Name | Type | Description | 42 | |---|---|---| 43 | | _0 | bytes32 | undefined 44 | 45 | #### Returns 46 | 47 | | Name | Type | Description | 48 | |---|---|---| 49 | | _0 | bool | undefined 50 | 51 | 52 | 53 | ## Events 54 | 55 | ### L2ToL1Message 56 | 57 | ```solidity 58 | event L2ToL1Message(uint256 _nonce, address _sender, bytes _data) 59 | ``` 60 | 61 | 62 | 63 | 64 | 65 | #### Parameters 66 | 67 | | Name | Type | Description | 68 | |---|---|---| 69 | | _nonce | uint256 | undefined | 70 | | _sender | address | undefined | 71 | | _data | bytes | undefined | 72 | 73 | 74 | 75 | -------------------------------------------------------------------------------- /docs/OVM_SequencerFeeVault.md: -------------------------------------------------------------------------------- 1 | # OVM_SequencerFeeVault 2 | 3 | 4 | 5 | > OVM_SequencerFeeVault 6 | 7 | 8 | 9 | *Simple holding contract for fees paid to the Sequencer. Likely to be replaced in the future but "good enough for now".* 10 | 11 | ## Methods 12 | 13 | ### MIN_WITHDRAWAL_AMOUNT 14 | 15 | ```solidity 16 | function MIN_WITHDRAWAL_AMOUNT() external view returns (uint256) 17 | ``` 18 | 19 | 20 | 21 | 22 | 23 | 24 | #### Returns 25 | 26 | | Name | Type | Description | 27 | |---|---|---| 28 | | _0 | uint256 | undefined 29 | 30 | ### l1FeeWallet 31 | 32 | ```solidity 33 | function l1FeeWallet() external view returns (address) 34 | ``` 35 | 36 | 37 | 38 | 39 | 40 | 41 | #### Returns 42 | 43 | | Name | Type | Description | 44 | |---|---|---| 45 | | _0 | address | undefined 46 | 47 | ### withdraw 48 | 49 | ```solidity 50 | function withdraw() external nonpayable 51 | ``` 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | -------------------------------------------------------------------------------- /docs/Ownable.md: -------------------------------------------------------------------------------- 1 | # Ownable 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | *Contract module which provides a basic access control mechanism, where there is an account (an owner) that can be granted exclusive access to specific functions. By default, the owner account will be the one that deploys the contract. This can later be changed with {transferOwnership}. This module is used through inheritance. It will make available the modifier `onlyOwner`, which can be applied to your functions to restrict their use to the owner.* 10 | 11 | ## Methods 12 | 13 | ### owner 14 | 15 | ```solidity 16 | function owner() external view returns (address) 17 | ``` 18 | 19 | 20 | 21 | *Returns the address of the current owner.* 22 | 23 | 24 | #### Returns 25 | 26 | | Name | Type | Description | 27 | |---|---|---| 28 | | _0 | address | undefined 29 | 30 | ### renounceOwnership 31 | 32 | ```solidity 33 | function renounceOwnership() external nonpayable 34 | ``` 35 | 36 | 37 | 38 | *Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner.* 39 | 40 | 41 | ### transferOwnership 42 | 43 | ```solidity 44 | function transferOwnership(address newOwner) external nonpayable 45 | ``` 46 | 47 | 48 | 49 | *Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner.* 50 | 51 | #### Parameters 52 | 53 | | Name | Type | Description | 54 | |---|---|---| 55 | | newOwner | address | undefined 56 | 57 | 58 | 59 | ## Events 60 | 61 | ### OwnershipTransferred 62 | 63 | ```solidity 64 | event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) 65 | ``` 66 | 67 | 68 | 69 | 70 | 71 | #### Parameters 72 | 73 | | Name | Type | Description | 74 | |---|---|---| 75 | | previousOwner `indexed` | address | undefined | 76 | | newOwner `indexed` | address | undefined | 77 | 78 | 79 | 80 | -------------------------------------------------------------------------------- /docs/OwnableUpgradeable.md: -------------------------------------------------------------------------------- 1 | # OwnableUpgradeable 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | *Contract module which provides a basic access control mechanism, where there is an account (an owner) that can be granted exclusive access to specific functions. By default, the owner account will be the one that deploys the contract. This can later be changed with {transferOwnership}. This module is used through inheritance. It will make available the modifier `onlyOwner`, which can be applied to your functions to restrict their use to the owner.* 10 | 11 | ## Methods 12 | 13 | ### owner 14 | 15 | ```solidity 16 | function owner() external view returns (address) 17 | ``` 18 | 19 | 20 | 21 | *Returns the address of the current owner.* 22 | 23 | 24 | #### Returns 25 | 26 | | Name | Type | Description | 27 | |---|---|---| 28 | | _0 | address | undefined 29 | 30 | ### renounceOwnership 31 | 32 | ```solidity 33 | function renounceOwnership() external nonpayable 34 | ``` 35 | 36 | 37 | 38 | *Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner.* 39 | 40 | 41 | ### transferOwnership 42 | 43 | ```solidity 44 | function transferOwnership(address newOwner) external nonpayable 45 | ``` 46 | 47 | 48 | 49 | *Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner.* 50 | 51 | #### Parameters 52 | 53 | | Name | Type | Description | 54 | |---|---|---| 55 | | newOwner | address | undefined 56 | 57 | 58 | 59 | ## Events 60 | 61 | ### Initialized 62 | 63 | ```solidity 64 | event Initialized(uint8 version) 65 | ``` 66 | 67 | 68 | 69 | 70 | 71 | #### Parameters 72 | 73 | | Name | Type | Description | 74 | |---|---|---| 75 | | version | uint8 | undefined | 76 | 77 | ### OwnershipTransferred 78 | 79 | ```solidity 80 | event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) 81 | ``` 82 | 83 | 84 | 85 | 86 | 87 | #### Parameters 88 | 89 | | Name | Type | Description | 90 | |---|---|---| 91 | | previousOwner `indexed` | address | undefined | 92 | | newOwner `indexed` | address | undefined | 93 | 94 | 95 | 96 | -------------------------------------------------------------------------------- /docs/PausableUpgradeable.md: -------------------------------------------------------------------------------- 1 | # PausableUpgradeable 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | *Contract module which allows children to implement an emergency stop mechanism that can be triggered by an authorized account. This module is used through inheritance. It will make available the modifiers `whenNotPaused` and `whenPaused`, which can be applied to the functions of your contract. Note that they will not be pausable by simply including this module, only once the modifiers are put in place.* 10 | 11 | ## Methods 12 | 13 | ### paused 14 | 15 | ```solidity 16 | function paused() external view returns (bool) 17 | ``` 18 | 19 | 20 | 21 | *Returns true if the contract is paused, and false otherwise.* 22 | 23 | 24 | #### Returns 25 | 26 | | Name | Type | Description | 27 | |---|---|---| 28 | | _0 | bool | undefined 29 | 30 | 31 | 32 | ## Events 33 | 34 | ### Initialized 35 | 36 | ```solidity 37 | event Initialized(uint8 version) 38 | ``` 39 | 40 | 41 | 42 | 43 | 44 | #### Parameters 45 | 46 | | Name | Type | Description | 47 | |---|---|---| 48 | | version | uint8 | undefined | 49 | 50 | ### Paused 51 | 52 | ```solidity 53 | event Paused(address account) 54 | ``` 55 | 56 | 57 | 58 | *Emitted when the pause is triggered by `account`.* 59 | 60 | #### Parameters 61 | 62 | | Name | Type | Description | 63 | |---|---|---| 64 | | account | address | undefined | 65 | 66 | ### Unpaused 67 | 68 | ```solidity 69 | event Unpaused(address account) 70 | ``` 71 | 72 | 73 | 74 | *Emitted when the pause is lifted by `account`.* 75 | 76 | #### Parameters 77 | 78 | | Name | Type | Description | 79 | |---|---|---| 80 | | account | address | undefined | 81 | 82 | 83 | 84 | -------------------------------------------------------------------------------- /docs/ReentrancyGuardUpgradeable.md: -------------------------------------------------------------------------------- 1 | # ReentrancyGuardUpgradeable 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | *Contract module that helps prevent reentrant calls to a function. Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier available, which can be applied to functions to make sure there are no nested (reentrant) calls to them. Note that because there is a single `nonReentrant` guard, functions marked as `nonReentrant` may not call one another. This can be worked around by making those functions `private`, and then adding `external` `nonReentrant` entry points to them. TIP: If you would like to learn more about reentrancy and alternative ways to protect against it, check out our blog post https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].* 10 | 11 | 12 | ## Events 13 | 14 | ### Initialized 15 | 16 | ```solidity 17 | event Initialized(uint8 version) 18 | ``` 19 | 20 | 21 | 22 | 23 | 24 | #### Parameters 25 | 26 | | Name | Type | Description | 27 | |---|---|---| 28 | | version | uint8 | undefined | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /docs/SafeERC20.md: -------------------------------------------------------------------------------- 1 | # SafeERC20 2 | 3 | 4 | 5 | > SafeERC20 6 | 7 | 8 | 9 | *Wrappers around ERC20 operations that throw on failure (when the token contract returns false). Tokens that return no value (and instead revert or throw on failure) are also supported, non-reverting calls are assumed to be successful. To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract, which allows you to call the safe operations as `token.safeTransfer(...)`, etc.* 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /docs/iL1ChugSplashDeployer.md: -------------------------------------------------------------------------------- 1 | # iL1ChugSplashDeployer 2 | 3 | 4 | 5 | > iL1ChugSplashDeployer 6 | 7 | 8 | 9 | 10 | 11 | ## Methods 12 | 13 | ### isUpgrading 14 | 15 | ```solidity 16 | function isUpgrading() external view returns (bool) 17 | ``` 18 | 19 | 20 | 21 | 22 | 23 | 24 | #### Returns 25 | 26 | | Name | Type | Description | 27 | |---|---|---| 28 | | _0 | bool | undefined 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /docs/iOVM_L1BlockNumber.md: -------------------------------------------------------------------------------- 1 | # iOVM_L1BlockNumber 2 | 3 | 4 | 5 | > iOVM_L1BlockNumber 6 | 7 | 8 | 9 | 10 | 11 | ## Methods 12 | 13 | ### getL1BlockNumber 14 | 15 | ```solidity 16 | function getL1BlockNumber() external view returns (uint256) 17 | ``` 18 | 19 | 20 | 21 | 22 | 23 | 24 | #### Returns 25 | 26 | | Name | Type | Description | 27 | |---|---|---| 28 | | _0 | uint256 | Block number of L1 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /docs/iOVM_L2ToL1MessagePasser.md: -------------------------------------------------------------------------------- 1 | # iOVM_L2ToL1MessagePasser 2 | 3 | 4 | 5 | > iOVM_L2ToL1MessagePasser 6 | 7 | 8 | 9 | 10 | 11 | ## Methods 12 | 13 | ### passMessageToL1 14 | 15 | ```solidity 16 | function passMessageToL1(bytes _message) external nonpayable 17 | ``` 18 | 19 | Passes a message to L1. 20 | 21 | 22 | 23 | #### Parameters 24 | 25 | | Name | Type | Description | 26 | |---|---|---| 27 | | _message | bytes | Message to pass to L1. 28 | 29 | 30 | 31 | ## Events 32 | 33 | ### L2ToL1Message 34 | 35 | ```solidity 36 | event L2ToL1Message(uint256 _nonce, address _sender, bytes _data) 37 | ``` 38 | 39 | 40 | 41 | 42 | 43 | #### Parameters 44 | 45 | | Name | Type | Description | 46 | |---|---|---| 47 | | _nonce | uint256 | undefined | 48 | | _sender | address | undefined | 49 | | _data | bytes | undefined | 50 | 51 | 52 | 53 | -------------------------------------------------------------------------------- /scripts/generate-artifacts.ts: -------------------------------------------------------------------------------- 1 | import path from 'path' 2 | import fs from 'fs' 3 | 4 | import glob from 'glob' 5 | 6 | /** 7 | * Script for automatically generating a file which has a series of `require` statements for 8 | * importing JSON contract artifacts. We do this to preserve browser compatibility. 9 | */ 10 | const main = async () => { 11 | const contractArtifactsFolder = path.resolve( 12 | __dirname, 13 | `../artifacts/contracts` 14 | ) 15 | 16 | const artifactPaths = glob 17 | .sync(`${contractArtifactsFolder}/**/*.json`) 18 | .filter((match) => { 19 | return [ 20 | 'artifacts/contracts/chugsplash', 21 | 'artifacts/contracts/L1', 22 | 'artifacts/contracts/L2', 23 | 'artifacts/contracts/libraries', 24 | 'artifacts/contracts/standards', 25 | ].some((folder) => match.includes(folder)) 26 | }) 27 | .filter((match) => { 28 | // Filter out the debug outputs. 29 | return !match.endsWith('.dbg.json') 30 | }) 31 | 32 | const content = ` 33 | /* eslint-disable @typescript-eslint/no-var-requires, no-empty */ 34 | /* 35 | THIS FILE IS AUTOMATICALLY GENERATED. 36 | DO NOT EDIT. 37 | */ 38 | 39 | ${artifactPaths 40 | .map((artifactPath) => { 41 | // eslint-disable-next-line @typescript-eslint/no-var-requires 42 | const artifact = require(artifactPath) 43 | // handles the case - '\u' (\utils folder) is considered as an unicode encoded char 44 | const pattern = /\\/g 45 | const relPath = path 46 | .relative(__dirname, artifactPath) 47 | .replace(pattern, '/') 48 | return ` 49 | let ${artifact.contractName} 50 | try { 51 | ${artifact.contractName} = require('${relPath}') 52 | } catch {} 53 | ` 54 | }) 55 | .join('\n')} 56 | 57 | export const getContractArtifact = (name: string): any => { 58 | return { 59 | ${artifactPaths 60 | .map((artifactPath) => { 61 | // eslint-disable-next-line @typescript-eslint/no-var-requires 62 | const artifact = require(artifactPath) 63 | return `${artifact.contractName}` 64 | }) 65 | .join(',\n')} 66 | }[name] 67 | } 68 | ` 69 | 70 | fs.writeFileSync( 71 | path.resolve(__dirname, `../src/contract-artifacts.ts`), 72 | content 73 | ) 74 | } 75 | 76 | main() 77 | -------------------------------------------------------------------------------- /scripts/generate-deployed-artifacts.ts: -------------------------------------------------------------------------------- 1 | import path from 'path' 2 | import fs from 'fs' 3 | 4 | import glob from 'glob' 5 | 6 | /** 7 | * Script for automatically generating a TypeScript file for retrieving deploy artifact JSON files. 8 | * We do this to make sure that this package remains browser compatible. 9 | */ 10 | const main = async () => { 11 | let content = ` 12 | /* eslint-disable */ 13 | /* 14 | THIS FILE IS AUTOMATICALLY GENERATED. 15 | DO NOT EDIT. 16 | */ 17 | ` 18 | 19 | const deploymentNames = fs 20 | .readdirSync(path.resolve(__dirname, '../deployments'), { 21 | withFileTypes: true, 22 | }) 23 | .filter((entry) => { 24 | return entry.isDirectory() 25 | }) 26 | .map((entry) => { 27 | return entry.name 28 | }) 29 | 30 | const artifactNames = [] 31 | const pattern = /\\/g 32 | 33 | for (const deploymentName of deploymentNames) { 34 | const deploymentArtifacts = glob.sync( 35 | path.join( 36 | path.resolve(__dirname, '../deployments'), 37 | deploymentName, 38 | '/*.json' 39 | ) 40 | ) 41 | 42 | for (const artifactPath of deploymentArtifacts) { 43 | const relPath = path 44 | .relative(__dirname, artifactPath) 45 | .replace(pattern, '/') 46 | const contractName = path.basename(artifactPath, '.json') 47 | const artifactName = `${deploymentName}__${contractName}`.replace( 48 | /-/g, 49 | '_' 50 | ) 51 | artifactNames.push(artifactName) 52 | 53 | // eslint-disable-next-line @typescript-eslint/no-var-requires 54 | const artifact = require(relPath) 55 | content += `const ${artifactName} = { abi: ${JSON.stringify( 56 | artifact.abi 57 | )}, address: '${artifact.address}' }\n` 58 | } 59 | } 60 | 61 | content += ` 62 | export const getDeployedContractArtifact = (name: string, network: string): any => { 63 | return { 64 | ${artifactNames.join(',\n')} 65 | }[(network + '__' + name).replace(/-/g, '_')] 66 | } 67 | ` 68 | 69 | fs.writeFileSync(`./src/contract-deployed-artifacts.ts`, content) 70 | } 71 | 72 | main() 73 | -------------------------------------------------------------------------------- /scripts/legacy-bindings.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | OUTDIR="$1" 4 | 5 | if [ ! -d "$OUTDIR" ]; then 6 | echo "Must pass output directory" 7 | exit 1 8 | fi 9 | 10 | CONTRACTS=("CanonicalTransactionChain" "StateCommitmentChain") 11 | PKG=legacy_bindings 12 | 13 | for contract in ${CONTRACTS[@]}; do 14 | TMPFILE=$(mktemp) 15 | npx hardhat inspect $contract bytecode > "$TMPFILE" 16 | ABI=$(npx hardhat inspect $contract abi) 17 | 18 | outfile="$OUTDIR/$contract.go" 19 | 20 | echo "$ABI" | abigen --abi - --pkg "$PKG" --bin "$TMPFILE" --type $contract --out "$outfile" 21 | 22 | rm "$TMPFILE" 23 | done 24 | -------------------------------------------------------------------------------- /scripts/ovm-gas-oracle.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -e 4 | 5 | RPC_URL=${RPC_URL:-http://localhost:8545} 6 | OVM_GAS_ORACLE=0x420000000000000000000000000000000000000F 7 | 8 | function send_tx() { 9 | cast send --rpc-url $RPC_URL \ 10 | --private-key $PRIVATE_KEY \ 11 | --legacy \ 12 | --gas-price 0 \ 13 | $OVM_GAS_ORACLE \ 14 | $1 \ 15 | $2 16 | } 17 | 18 | function call() { 19 | cast call --rpc-url $RPC_URL \ 20 | $OVM_GAS_ORACLE \ 21 | $1 22 | } 23 | 24 | echo "Scalar: $(call 'scalar()(uint256)')" 25 | echo "L2 gas price: $(call 'gasPrice()(uint256)')" 26 | echo "Overhead: $(call 'overhead()(uint256)')" 27 | 28 | if [[ ! -z $PRIVATE_KEY ]]; then 29 | if [[ ! -z $SCALAR ]]; then 30 | echo "Setting scalar to $SCALAR" 31 | send_tx 'setScalar(uint256)' $SCALAR 32 | fi 33 | 34 | if [[ ! -z $OVERHEAD ]]; then 35 | echo "Setting overhead to $OVERHEAD" 36 | send_tx 'setOverhead(uint256)' $OVERHEAD 37 | fi 38 | 39 | if [[ ! -z $L2_GAS_PRICE ]]; then 40 | echo "Setting L2 gas price to $L2_GAS_PRICE" 41 | send_tx 'setGasPrice(uint256)' $L2_GAS_PRICE 42 | fi 43 | fi 44 | 45 | -------------------------------------------------------------------------------- /slither.config.json: -------------------------------------------------------------------------------- 1 | { 2 | "detectors_to_exclude": "conformance-to-solidity-naming-conventions,assembly-usage,low-level-calls,block-timestamp,pragma,solc-version,too-many-digits,boolean-equal,missing-zero-check", 3 | "exclude_informational": false, 4 | "exclude_low": false, 5 | "exclude_medium": false, 6 | "exclude_high": false, 7 | "solc_disable_warnings": false, 8 | "hardhat_ignore_compile": false, 9 | "disable_color": false, 10 | "exclude_dependencies": false, 11 | "filter_paths": "@openzeppelin|hardhat|contracts/test-helpers|contracts/test-libraries|contracts/L2/predeploys/WETH9.sol" 12 | } 13 | -------------------------------------------------------------------------------- /src/address-names.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * This object defines the correct names to be used in the Address Manager and deployment artifacts. 3 | */ 4 | export const names = { 5 | managed: { 6 | contracts: { 7 | ChainStorageContainer_CTC_batches: 'ChainStorageContainer-CTC-batches', 8 | ChainStorageContainer_SCC_batches: 'ChainStorageContainer-SCC-batches', 9 | CanonicalTransactionChain: 'CanonicalTransactionChain', 10 | StateCommitmentChain: 'StateCommitmentChain', 11 | BondManager: 'BondManager', 12 | OVM_L1CrossDomainMessenger: 'OVM_L1CrossDomainMessenger', 13 | Proxy__OVM_L1CrossDomainMessenger: 'Proxy__OVM_L1CrossDomainMessenger', 14 | Proxy__OVM_L1StandardBridge: 'Proxy__OVM_L1StandardBridge', 15 | }, 16 | accounts: { OVM_Sequencer: 'OVM_Sequencer', OVM_Proposer: 'OVM_Proposer' }, 17 | }, 18 | unmanaged: { 19 | AddressDictator: 'AddressDictator', 20 | ChugSplashDictator: 'ChugSplashDictator', 21 | Lib_AddressManager: 'Lib_AddressManager', 22 | }, 23 | } 24 | -------------------------------------------------------------------------------- /src/contract-defs.ts: -------------------------------------------------------------------------------- 1 | import { ethers } from 'ethers' 2 | 3 | /** 4 | * Gets the hardhat artifact for the given contract name. 5 | * Will throw an error if the contract artifact is not found. 6 | * 7 | * @param name Contract name. 8 | * @returns The artifact for the given contract name. 9 | */ 10 | export const getContractDefinition = (name: string): any => { 11 | // We import this using `require` because hardhat tries to build this file when compiling 12 | // the contracts, but we need the contracts to be compiled before the contract-artifacts.ts 13 | // file can be generated. 14 | // eslint-disable-next-line @typescript-eslint/no-var-requires 15 | const { getContractArtifact } = require('./contract-artifacts') 16 | const artifact = getContractArtifact(name) 17 | if (artifact === undefined) { 18 | throw new Error(`Unable to find artifact for contract: ${name}`) 19 | } 20 | return artifact 21 | } 22 | 23 | /** 24 | * Gets the deployed hardhat artifact for the given contract name. 25 | * Will throw an error if the contract artifact is not found. 26 | * 27 | * @param name Contract name. 28 | * @param network Network name. 29 | * @returns The artifact for the given contract name. 30 | */ 31 | export const getDeployedContractDefinition = ( 32 | name: string, 33 | network: string 34 | ): { 35 | address: string 36 | abi: any 37 | } => { 38 | const { 39 | getDeployedContractArtifact, 40 | // eslint-disable-next-line @typescript-eslint/no-var-requires 41 | } = require('./contract-deployed-artifacts') 42 | const artifact = getDeployedContractArtifact(name, network) 43 | if (artifact === undefined) { 44 | throw new Error( 45 | `Unable to find artifact for contract on network ${network}: ${name}` 46 | ) 47 | } 48 | return artifact 49 | } 50 | 51 | /** 52 | * Gets an ethers Interface instance for the given contract name. 53 | * 54 | * @param name Contract name. 55 | * @returns The interface for the given contract name. 56 | */ 57 | export const getContractInterface = (name: string): ethers.utils.Interface => { 58 | const definition = getContractDefinition(name) 59 | return new ethers.utils.Interface(definition.abi) 60 | } 61 | 62 | /** 63 | * Gets an ethers ContractFactory instance for the given contract name. 64 | * 65 | * @param name Contract name. 66 | * @param signer The signer for the ContractFactory to use. 67 | * @returns The contract factory for the given contract name. 68 | */ 69 | export const getContractFactory = ( 70 | name: string, 71 | signer?: ethers.Signer 72 | ): ethers.ContractFactory => { 73 | const definition = getContractDefinition(name) 74 | const contractInterface = getContractInterface(name) 75 | return new ethers.ContractFactory( 76 | contractInterface, 77 | definition.bytecode, 78 | signer 79 | ) 80 | } 81 | -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './contract-defs' 2 | export * from './predeploys' 3 | -------------------------------------------------------------------------------- /src/predeploys.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Predeploys are Solidity contracts that are injected into the initial L2 state and provide 3 | * various useful functions. 4 | * 5 | * Notes: 6 | * 0x42...04 was the address of the OVM_ProxySequencerEntrypoint. This contract is no longer in 7 | * use and has therefore been removed. We may place a new predeployed contract at this address 8 | * in the future. 9 | */ 10 | export const predeploys = { 11 | OVM_L2ToL1MessagePasser: '0x4200000000000000000000000000000000000000', 12 | OVM_DeployerWhitelist: '0x4200000000000000000000000000000000000002', 13 | L2CrossDomainMessenger: '0x4200000000000000000000000000000000000007', 14 | OVM_GasPriceOracle: '0x420000000000000000000000000000000000000F', 15 | L2StandardBridge: '0x4200000000000000000000000000000000000010', 16 | OVM_SequencerFeeVault: '0x4200000000000000000000000000000000000011', 17 | L2StandardTokenFactory: '0x4200000000000000000000000000000000000012', 18 | OVM_L1BlockNumber: '0x4200000000000000000000000000000000000013', 19 | 20 | // We're temporarily disabling OVM_ETH because the jury is still out on whether or not ETH as an 21 | // ERC20 is desirable. 22 | OVM_ETH: '0xDeadDeAddeAddEAddeadDEaDDEAdDeaDDeAD0000', 23 | 24 | // We're also putting WETH9 at the old OVM_ETH address. 25 | WETH9: '0x4200000000000000000000000000000000000006', 26 | } 27 | 28 | export const futurePredeploys = { 29 | // System addresses, for use later 30 | System0: '0x4200000000000000000000000000000000000042', 31 | System1: '0x4200000000000000000000000000000000000014', 32 | } 33 | -------------------------------------------------------------------------------- /src/validation-utils.ts: -------------------------------------------------------------------------------- 1 | import { createInterface } from 'readline' 2 | 3 | import { hexStringEquals } from '@eth-patex/core-utils' 4 | 5 | export const getInput = (query) => { 6 | const rl = createInterface({ 7 | input: process.stdin, 8 | output: process.stdout, 9 | }) 10 | 11 | return new Promise((resolve) => 12 | rl.question(query, (ans) => { 13 | rl.close() 14 | resolve(ans) 15 | }) 16 | ) 17 | } 18 | 19 | const codes = { 20 | reset: '\x1b[0m', 21 | red: '\x1b[0;31m', 22 | green: '\x1b[0;32m', 23 | cyan: '\x1b[0;36m', 24 | yellow: '\x1b[1;33m', 25 | } 26 | 27 | export const color = Object.entries(codes).reduce((obj, [k]) => { 28 | obj[k] = (msg: string) => `${codes[k]}${msg}${codes.reset}` 29 | return obj 30 | }, {}) as any 31 | 32 | // helper for finding the right artifact from the deployed name 33 | const locateArtifact = (name: string) => { 34 | return { 35 | 'ChainStorageContainer-CTC-batches': 36 | 'L1/rollup/ChainStorageContainer.sol/ChainStorageContainer.json', 37 | 'ChainStorageContainer-SCC-batches': 38 | 'L1/rollup/ChainStorageContainer.sol/ChainStorageContainer.json', 39 | CanonicalTransactionChain: 40 | 'L1/rollup/CanonicalTransactionChain.sol/CanonicalTransactionChain.json', 41 | StateCommitmentChain: 42 | 'L1/rollup/StateCommitmentChain.sol/StateCommitmentChain.json', 43 | BondManager: 'L1/verification/BondManager.sol/BondManager.json', 44 | OVM_L1CrossDomainMessenger: 45 | 'L1/messaging/L1CrossDomainMessenger.sol/L1CrossDomainMessenger.json', 46 | Proxy__OVM_L1CrossDomainMessenger: 47 | 'libraries/resolver/Lib_ResolvedDelegateProxy.sol/Lib_ResolvedDelegateProxy.json', 48 | Proxy__OVM_L1StandardBridge: 49 | 'chugsplash/L1ChugSplashProxy.sol/L1ChugSplashProxy.json', 50 | }[name] 51 | } 52 | 53 | export const getArtifactFromManagedName = (name: string) => { 54 | // eslint-disable-next-line @typescript-eslint/no-var-requires 55 | return require(`../artifacts/contracts/${locateArtifact(name)}`) 56 | } 57 | 58 | export const getEtherscanUrl = (network, address: string) => { 59 | const escPrefix = network.chainId !== 1 ? `${network.name}.` : '' 60 | return `https://${escPrefix}etherscan.io/address/${address}` 61 | } 62 | 63 | // Reduces a byte string to first 32 bytes, with a '...' to indicate when it was shortened 64 | const truncateLongString = (value: string): string => { 65 | return value.length > 66 ? `${value.slice(0, 66)}...` : value 66 | } 67 | 68 | export const printSectionHead = (msg: string) => { 69 | console.log(color.cyan(msg)) 70 | console.log( 71 | color.cyan('='.repeat(Math.max(...msg.split('\n').map((s) => s.length)))) 72 | ) 73 | } 74 | 75 | export const printComparison = ( 76 | action: string, 77 | description: string, 78 | expected: { name: string; value: any }, 79 | deployed: { name: string; value: any } 80 | ) => { 81 | console.log(`\n${action}:`) 82 | if (hexStringEquals(expected.value, deployed.value)) { 83 | console.log( 84 | color.green(`${expected.name}: ${truncateLongString(expected.value)}`) 85 | ) 86 | console.log('matches') 87 | console.log( 88 | color.green(`${deployed.name}: ${truncateLongString(deployed.value)}`) 89 | ) 90 | console.log(color.green(`${description} looks good! 😎`)) 91 | } else { 92 | throw new Error( 93 | `${description} looks wrong. ${expected.value}\ndoes not match\n${deployed.value}.` 94 | ) 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /tasks/fetch-batches.ts: -------------------------------------------------------------------------------- 1 | import { ethers } from 'ethers' 2 | import { task } from 'hardhat/config' 3 | import * as types from 'hardhat/internal/core/params/argumentTypes' 4 | import { 5 | BatchType, 6 | SequencerBatch, 7 | calldataCost, 8 | } from '@eth-patex/core-utils' 9 | 10 | import { names } from '../src/address-names' 11 | import { getContractFromArtifact } from '../src/deploy-utils' 12 | 13 | // Need to export env vars 14 | // CONTRACTS_TARGET_NETWORK 15 | // CONTRACTS_DEPLOYER_KEY 16 | // CONTRACTS_RPC_URL 17 | task('fetch-batches') 18 | .addOptionalParam( 19 | 'contractsRpcUrl', 20 | 'Ethereum HTTP Endpoint', 21 | process.env.CONTRACTS_RPC_URL || 'http://127.0.0.1:8545', 22 | types.string 23 | ) 24 | .addOptionalParam('start', 'Start block height', 0, types.int) 25 | .addOptionalParam('end', 'End block height', undefined, types.int) 26 | .setAction(async (args, hre) => { 27 | const provider = new ethers.providers.StaticJsonRpcProvider( 28 | args.contractsRpcUrl 29 | ) 30 | 31 | let CanonicalTransactionChain = await getContractFromArtifact( 32 | hre, 33 | names.managed.contracts.CanonicalTransactionChain 34 | ) 35 | CanonicalTransactionChain = CanonicalTransactionChain.connect(provider) 36 | 37 | const start = args.start 38 | let end = args.end 39 | if (!end) { 40 | end = await provider.getBlockNumber() 41 | } 42 | 43 | const batches = [] 44 | 45 | for (let i = start; i <= end; i += 2001) { 46 | const tip = Math.min(i + 2000, end) 47 | console.error(`Querying events ${i}-${tip}`) 48 | 49 | const events = await CanonicalTransactionChain.queryFilter( 50 | CanonicalTransactionChain.filters.SequencerBatchAppended(), 51 | i, 52 | tip 53 | ) 54 | 55 | for (const event of events) { 56 | const tx = await provider.getTransaction(event.transactionHash) 57 | const batch = (SequencerBatch as any).fromHex(tx.data) 58 | 59 | // Add extra fields to the resulting json 60 | // so that the serialization sizes and gas usage can be observed 61 | const json = batch.toJSON() 62 | json.sizes = { 63 | legacy: 0, 64 | zlib: 0, 65 | } 66 | json.gasUsage = { 67 | legacy: 0, 68 | zlib: 0, 69 | } 70 | 71 | // Create a copy of the batch to serialize in 72 | // the alternative format 73 | const copy = (SequencerBatch as any).fromHex(tx.data) 74 | let legacy: Buffer 75 | let zlib: Buffer 76 | if (batch.type === BatchType.ZLIB) { 77 | copy.type = BatchType.LEGACY 78 | legacy = copy.encode() 79 | zlib = batch.encode() 80 | } else { 81 | copy.type = BatchType.ZLIB 82 | zlib = copy.encode() 83 | legacy = batch.encode() 84 | } 85 | 86 | json.sizes.legacy = legacy.length 87 | json.sizes.zlib = zlib.length 88 | 89 | json.sizes.compressionRatio = json.sizes.zlib / json.sizes.legacy 90 | 91 | json.gasUsage.legacy = calldataCost(legacy).toNumber() 92 | json.gasUsage.zlib = calldataCost(zlib).toNumber() 93 | json.gasUsage.compressionRatio = 94 | json.gasUsage.zlib / json.gasUsage.legacy 95 | 96 | batches.push(json) 97 | } 98 | } 99 | 100 | console.log(JSON.stringify(batches, null, 2)) 101 | }) 102 | -------------------------------------------------------------------------------- /tasks/index.ts: -------------------------------------------------------------------------------- 1 | export * from './set-owner' 2 | export * from './take-dump' 3 | export * from './validate-address-dictator' 4 | export * from './validate-chugsplash-dictator' 5 | export * from './whitelist' 6 | export * from './withdraw-fees' 7 | export * from './fetch-batches' 8 | export * from './inspect' 9 | -------------------------------------------------------------------------------- /tasks/inspect.ts: -------------------------------------------------------------------------------- 1 | import { task } from 'hardhat/config' 2 | import * as types from 'hardhat/internal/core/params/argumentTypes' 3 | 4 | const getFullyQualifiedName = ( 5 | sourceName: string, 6 | contractName: string 7 | ): string => { 8 | return `${sourceName}:${contractName}` 9 | } 10 | 11 | task('inspect') 12 | .addPositionalParam( 13 | 'contractName', 14 | 'Name of the contract to inspect', 15 | undefined, 16 | types.string, 17 | false 18 | ) 19 | .addPositionalParam( 20 | 'field', 21 | 'Compiler output field to inspect', 22 | undefined, 23 | types.string, 24 | false 25 | ) 26 | .setAction(async (args, hre) => { 27 | const artifact = await hre.artifacts.readArtifact(args.contractName) 28 | const fqn = getFullyQualifiedName( 29 | artifact.sourceName, 30 | artifact.contractName 31 | ) 32 | const buildInfo = await hre.artifacts.getBuildInfo(fqn) 33 | const info = 34 | buildInfo.output.contracts[artifact.sourceName][artifact.contractName] 35 | if (!info) { 36 | throw new Error(`Cannot find build info for ${fqn}`) 37 | } 38 | 39 | try { 40 | switch (args.field) { 41 | case 'abi': { 42 | const abi = info.abi 43 | console.log(JSON.stringify(abi, null, 2)) 44 | break 45 | } 46 | case 'bytecode': { 47 | const bytecode = info.evm.bytecode.object 48 | console.log('0x' + bytecode) 49 | break 50 | } 51 | case 'deployedBytecode': { 52 | const bytecode = info.evm.deployedBytecode.object 53 | console.log('0x' + bytecode) 54 | break 55 | } 56 | case 'storageLayout': { 57 | const storageLayout = (info as any).storageLayout 58 | console.log(JSON.stringify(storageLayout, null, 2)) 59 | break 60 | } 61 | case 'methodIdentifiers': { 62 | const methodIdentifiers = info.evm.methodIdentifiers 63 | console.log(JSON.stringify(methodIdentifiers, null, 2)) 64 | break 65 | } 66 | default: { 67 | console.log( 68 | JSON.stringify( 69 | { 70 | error: `Unsupported field ${args.field}`, 71 | }, 72 | null, 73 | 2 74 | ) 75 | ) 76 | break 77 | } 78 | } 79 | } catch (e) { 80 | console.log( 81 | JSON.stringify( 82 | { 83 | error: `Cannot find ${args.field}, be sure to enable it in compiler settings`, 84 | }, 85 | null, 86 | 2 87 | ) 88 | ) 89 | } 90 | }) 91 | -------------------------------------------------------------------------------- /tasks/set-owner.ts: -------------------------------------------------------------------------------- 1 | /* Imports: External */ 2 | import { ethers } from 'ethers' 3 | import { LedgerSigner } from '@ethersproject/hardware-wallets' 4 | import { task } from 'hardhat/config' 5 | import * as types from 'hardhat/internal/core/params/argumentTypes' 6 | 7 | import { predeploys } from '../src/predeploys' 8 | import { getContractFactory } from '../src/contract-defs' 9 | 10 | task('set-owner') 11 | .addParam('owner', 'the new oracle address', 0, types.string) 12 | .addOptionalParam('transactionGasPrice', 'tx.gasPrice', undefined, types.int) 13 | .addOptionalParam( 14 | 'useLedger', 15 | 'use a ledger for signing', 16 | false, 17 | types.boolean 18 | ) 19 | .addOptionalParam( 20 | 'ledgerPath', 21 | 'ledger key derivation path', 22 | ethers.utils.defaultPath, 23 | types.string 24 | ) 25 | .addOptionalParam( 26 | 'contractsRpcUrl', 27 | 'Sequencer HTTP Endpoint', 28 | process.env.CONTRACTS_RPC_URL, 29 | types.string 30 | ) 31 | .addOptionalParam( 32 | 'contractsDeployerKey', 33 | 'Private Key', 34 | process.env.CONTRACTS_DEPLOYER_KEY, 35 | types.string 36 | ) 37 | .addOptionalParam( 38 | 'contractAddress', 39 | 'Address of Ownable contract', 40 | predeploys.OVM_GasPriceOracle, 41 | types.string 42 | ) 43 | .setAction(async (args) => { 44 | const provider = new ethers.providers.JsonRpcProvider(args.contractsRpcUrl) 45 | let signer: ethers.Signer 46 | if (!args.useLedger) { 47 | signer = new ethers.Wallet(args.contractsDeployerKey).connect(provider) 48 | } else { 49 | signer = new LedgerSigner(provider, 'default', args.ledgerPath) 50 | } 51 | 52 | const Ownable = getContractFactory('Ownable') 53 | .attach(args.contractAddress) 54 | .connect(provider) 55 | 56 | const addr = await signer.getAddress() 57 | console.log(`Using signer ${addr}`) 58 | const owner = await Ownable.callStatic.owner() 59 | if (owner !== addr) { 60 | throw new Error(`Incorrect key. Owner ${owner}, Signer ${addr}`) 61 | } 62 | 63 | console.log(`Owner is currently ${owner.toString()}`) 64 | console.log(`Setting owner to ${args.owner}`) 65 | 66 | const tx = await Ownable.connect(signer).transferOwnership(args.owner, { 67 | gasPrice: args.transactionGasPrice, 68 | }) 69 | 70 | const receipt = await tx.wait() 71 | console.log(`Success - ${receipt.transactionHash}`) 72 | }) 73 | -------------------------------------------------------------------------------- /tasks/withdraw-fees.ts: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | import { ethers } from 'ethers' 4 | import { task } from 'hardhat/config' 5 | import * as types from 'hardhat/internal/core/params/argumentTypes' 6 | import { LedgerSigner } from '@ethersproject/hardware-wallets' 7 | 8 | import { getContractFactory } from '../src/contract-defs' 9 | import { predeploys } from '../src/predeploys' 10 | 11 | // Withdraw fees from the FeeVault to L1 12 | // npx hardhat withdraw-fees --dry-run 13 | task('withdraw-fees') 14 | .addOptionalParam('dryRun', 'simulate withdrawing fees', false, types.boolean) 15 | .addOptionalParam( 16 | 'useLedger', 17 | 'use a ledger for signing', 18 | false, 19 | types.boolean 20 | ) 21 | .addOptionalParam( 22 | 'ledgerPath', 23 | 'ledger key derivation path', 24 | ethers.utils.defaultPath, 25 | types.string 26 | ) 27 | .addOptionalParam( 28 | 'contractsRpcUrl', 29 | 'Sequencer HTTP Endpoint', 30 | process.env.CONTRACTS_RPC_URL, 31 | types.string 32 | ) 33 | .addOptionalParam( 34 | 'privateKey', 35 | 'Private Key', 36 | process.env.CONTRACTS_DEPLOYER_KEY, 37 | types.string 38 | ) 39 | .setAction(async (args) => { 40 | const provider = new ethers.providers.JsonRpcProvider(args.contractsRpcUrl) 41 | let signer: ethers.Signer 42 | if (!args.useLedger) { 43 | if (!args.contractsDeployerKey) { 44 | throw new Error('Must pass --contracts-deployer-key') 45 | } 46 | signer = new ethers.Wallet(args.contractsDeployerKey).connect(provider) 47 | } else { 48 | signer = new LedgerSigner(provider, 'default', args.ledgerPath) 49 | } 50 | if (args.dryRun) { 51 | console.log('Performing dry run of fee withdrawal...') 52 | } 53 | 54 | const l2FeeVault = getContractFactory('OVM_SequencerFeeVault') 55 | .connect(signer) 56 | .attach(predeploys.OVM_SequencerFeeVault) 57 | 58 | const signerAddress = await signer.getAddress() 59 | const signerBalance = await provider.getBalance(signerAddress) 60 | const signerBalanceInETH = ethers.utils.formatEther(signerBalance) 61 | console.log( 62 | `Using L2 signer ${signerAddress} with a balance of ${signerBalanceInETH} ETH` 63 | ) 64 | const l1FeeWallet = await l2FeeVault.l1FeeWallet() 65 | const amount = await provider.getBalance(l2FeeVault.address) 66 | const amountInETH = ethers.utils.formatEther(amount) 67 | console.log( 68 | `${ 69 | args.dryRun ? '[DRY RUN] ' : '' 70 | }Withdrawing ${amountInETH} ETH to the L1 address: ${l1FeeWallet}` 71 | ) 72 | if (args.dryRun) { 73 | await l2FeeVault.estimateGas.withdraw() 74 | return 75 | } else { 76 | const withdrawTx = await l2FeeVault.withdraw() 77 | console.log( 78 | `Withdrawal complete: https://optimistic.etherscan.io/tx/${withdrawTx.hash}` 79 | ) 80 | console.log( 81 | `Complete withdrawal in 1 week here: https://optimistic.etherscan.io/address/${predeploys.OVM_SequencerFeeVault}#withdrawaltxs` 82 | ) 83 | } 84 | }) 85 | -------------------------------------------------------------------------------- /test/contracts/L1/deployment/AddressDictator.spec.ts: -------------------------------------------------------------------------------- 1 | import { ethers } from 'hardhat' 2 | import { Contract } from 'ethers' 3 | import { SignerWithAddress } from '@nomiclabs/hardhat-ethers/signers' 4 | 5 | import { expect } from '../../../setup' 6 | import { deploy, NON_ZERO_ADDRESS } from '../../../helpers' 7 | 8 | describe('AddressDictator', () => { 9 | let signer1: SignerWithAddress 10 | let signer2: SignerWithAddress 11 | before(async () => { 12 | ;[signer1, signer2] = await ethers.getSigners() 13 | }) 14 | 15 | let AddressDictator: Contract 16 | let Lib_AddressManager: Contract 17 | beforeEach(async () => { 18 | Lib_AddressManager = await deploy('Lib_AddressManager', { 19 | signer: signer1, 20 | }) 21 | 22 | AddressDictator = await deploy('AddressDictator', { 23 | signer: signer1, 24 | args: [ 25 | Lib_AddressManager.address, 26 | signer1.address, 27 | ['addr1'], 28 | [NON_ZERO_ADDRESS], 29 | ], 30 | }) 31 | 32 | Lib_AddressManager.transferOwnership(AddressDictator.address) 33 | }) 34 | 35 | describe('initialize', () => { 36 | it('should revert when providing wrong arguments', async () => { 37 | await expect( 38 | deploy('AddressDictator', { 39 | signer: signer1, 40 | args: [ 41 | Lib_AddressManager.address, 42 | signer1.address, 43 | ['addr1', 'addr2'], 44 | [NON_ZERO_ADDRESS], 45 | ], 46 | }) 47 | ).to.be.revertedWith( 48 | 'AddressDictator: Must provide an equal number of names and addresses.' 49 | ) 50 | }) 51 | }) 52 | 53 | describe('setAddresses', async () => { 54 | it('should change the addresses associated with a name', async () => { 55 | await AddressDictator.setAddresses() 56 | expect(await Lib_AddressManager.getAddress('addr1')).to.equal( 57 | NON_ZERO_ADDRESS 58 | ) 59 | }) 60 | }) 61 | 62 | describe('getNamedAddresses', () => { 63 | it('should return all the addresses and their names', async () => { 64 | expect(await AddressDictator.getNamedAddresses()).to.deep.equal([ 65 | ['addr1', NON_ZERO_ADDRESS], 66 | ]) 67 | }) 68 | }) 69 | 70 | describe('returnOwnership', () => { 71 | it('should transfer contract ownership to finalOwner', async () => { 72 | await expect(AddressDictator.returnOwnership()).to.not.be.reverted 73 | }) 74 | 75 | it('should revert when called by non-owner', async () => { 76 | await expect( 77 | AddressDictator.connect(signer2).returnOwnership() 78 | ).to.be.revertedWith('AddressDictator: only callable by finalOwner') 79 | }) 80 | }) 81 | }) 82 | -------------------------------------------------------------------------------- /test/contracts/L1/deployment/ChugSplashDictator.spec.ts: -------------------------------------------------------------------------------- 1 | import { ethers } from 'hardhat' 2 | import { Contract } from 'ethers' 3 | import { SignerWithAddress } from '@nomiclabs/hardhat-ethers/signers' 4 | 5 | import { expect } from '../../../setup' 6 | import { deploy } from '../../../helpers' 7 | 8 | describe('ChugSplashDictator', () => { 9 | let signer1: SignerWithAddress 10 | let signer2: SignerWithAddress 11 | before(async () => { 12 | ;[signer1, signer2] = await ethers.getSigners() 13 | }) 14 | 15 | let L1ChugSplashProxy: Contract 16 | let ChugSplashDictator: Contract 17 | beforeEach(async () => { 18 | L1ChugSplashProxy = await deploy('L1ChugSplashProxy', { 19 | signer: signer1, 20 | args: [signer1.address], 21 | }) 22 | 23 | ChugSplashDictator = await deploy('ChugSplashDictator', { 24 | signer: signer1, 25 | args: [ 26 | L1ChugSplashProxy.address, 27 | signer1.address, 28 | ethers.utils.keccak256('0x1111'), 29 | ethers.utils.keccak256('0x1234'), 30 | ethers.utils.keccak256('0x5678'), 31 | ethers.utils.keccak256('0x1234'), 32 | ethers.utils.keccak256('0x1234'), 33 | ], 34 | }) 35 | 36 | await L1ChugSplashProxy.setOwner(ChugSplashDictator.address) 37 | }) 38 | 39 | describe('doActions', () => { 40 | it('should revert when sent wrong code', async () => { 41 | await expect(ChugSplashDictator.doActions('0x2222')).to.be.revertedWith( 42 | 'ChugSplashDictator: Incorrect code hash.' 43 | ) 44 | }) 45 | 46 | it('should set the proxy code, storage & owner', async () => { 47 | await expect(ChugSplashDictator.doActions('0x1111')).to.not.be.reverted 48 | }) 49 | }) 50 | 51 | describe('returnOwnership', () => { 52 | it('should transfer contractc ownership to finalOwner', async () => { 53 | await expect(ChugSplashDictator.returnOwnership()).to.not.be.reverted 54 | }) 55 | 56 | it('should revert when called by non-owner', async () => { 57 | await expect( 58 | ChugSplashDictator.connect(signer2).returnOwnership() 59 | ).to.be.revertedWith('ChugSplashDictator: only callable by finalOwner') 60 | }) 61 | }) 62 | }) 63 | -------------------------------------------------------------------------------- /test/contracts/L1/rollup/ChainStorageContainer.spec.ts: -------------------------------------------------------------------------------- 1 | import { ethers } from 'hardhat' 2 | import { Contract } from 'ethers' 3 | import { SignerWithAddress } from '@nomiclabs/hardhat-ethers/signers' 4 | 5 | import { expect } from '../../../setup' 6 | import { deploy, NON_NULL_BYTES32 } from '../../../helpers' 7 | 8 | describe('ChainStorageContainer', () => { 9 | let signer1: SignerWithAddress 10 | let signer2: SignerWithAddress 11 | before(async () => { 12 | ;[signer1, signer2] = await ethers.getSigners() 13 | }) 14 | 15 | let AddressManager: Contract 16 | let ChainStorageContainer: Contract 17 | beforeEach(async () => { 18 | AddressManager = await deploy('Lib_AddressManager') 19 | ChainStorageContainer = await deploy('ChainStorageContainer', { 20 | signer: signer1, 21 | args: [AddressManager.address, signer1.address], 22 | }) 23 | 24 | // ChainStorageContainer uses name resolution to check the owner address. 25 | await AddressManager.setAddress(signer1.address, signer1.address) 26 | }) 27 | 28 | describe('push', () => { 29 | for (const len of [1, 2, 4, 8, 32]) { 30 | it(`it should be able to add ${len} element(s) to the array`, async () => { 31 | for (let i = 0; i < len; i++) { 32 | await expect(ChainStorageContainer['push(bytes32)'](NON_NULL_BYTES32)) 33 | .to.not.be.reverted 34 | } 35 | }) 36 | } 37 | }) 38 | 39 | describe('setGlobalMetadata', () => { 40 | it('should modify the extra data', async () => { 41 | const globalMetaData = `0x${'11'.repeat(27)}` 42 | await ChainStorageContainer.setGlobalMetadata(globalMetaData) 43 | 44 | expect(await ChainStorageContainer.getGlobalMetadata()).to.equal( 45 | globalMetaData 46 | ) 47 | }) 48 | }) 49 | 50 | describe('deleteElementsAfterInclusive', () => { 51 | it('should revert when the array is empty', async () => { 52 | await expect( 53 | ChainStorageContainer['deleteElementsAfterInclusive(uint256)'](0) 54 | ).to.be.reverted 55 | }) 56 | 57 | it('should revert when called by non-owner', async () => { 58 | await expect( 59 | ChainStorageContainer.connect(signer2)[ 60 | 'deleteElementsAfterInclusive(uint256)' 61 | ](0) 62 | ).to.be.revertedWith( 63 | 'ChainStorageContainer: Function can only be called by the owner.' 64 | ) 65 | }) 66 | 67 | for (const len of [1, 2, 4, 8, 32]) { 68 | describe(`when the array has ${len} element(s)`, () => { 69 | const values = [] 70 | beforeEach(async () => { 71 | for (let i = 0; i < len; i++) { 72 | const value = NON_NULL_BYTES32 73 | values.push(value) 74 | await ChainStorageContainer['push(bytes32)'](value) 75 | } 76 | }) 77 | 78 | for (let i = len - 1; i > 0; i -= Math.max(1, len / 4)) { 79 | it(`should be able to delete everything after and including the ${i}th/st/rd/whatever element`, async () => { 80 | await expect( 81 | ChainStorageContainer['deleteElementsAfterInclusive(uint256)'](i) 82 | ).to.not.be.reverted 83 | 84 | expect(await ChainStorageContainer.length()).to.equal(i) 85 | await expect(ChainStorageContainer.get(i)).to.be.reverted 86 | }) 87 | } 88 | }) 89 | } 90 | }) 91 | }) 92 | -------------------------------------------------------------------------------- /test/contracts/L1/verification/BondManager.spec.ts: -------------------------------------------------------------------------------- 1 | import { ethers } from 'hardhat' 2 | import { Contract } from 'ethers' 3 | import { SignerWithAddress } from '@nomiclabs/hardhat-ethers/signers' 4 | 5 | import { expect } from '../../../setup' 6 | import { deploy } from '../../../helpers' 7 | 8 | describe('BondManager', () => { 9 | let sequencer: SignerWithAddress 10 | let nonSequencer: SignerWithAddress 11 | before(async () => { 12 | ;[sequencer, nonSequencer] = await ethers.getSigners() 13 | }) 14 | 15 | let AddressManager: Contract 16 | let BondManager: Contract 17 | beforeEach(async () => { 18 | AddressManager = await deploy('Lib_AddressManager') 19 | 20 | BondManager = await deploy('BondManager', { 21 | args: [AddressManager.address], 22 | }) 23 | 24 | AddressManager.setAddress('OVM_Proposer', sequencer.address) 25 | }) 26 | 27 | describe('isCollateralized', () => { 28 | it('should return true for OVM_Proposer', async () => { 29 | expect(await BondManager.isCollateralized(sequencer.address)).to.equal( 30 | true 31 | ) 32 | }) 33 | 34 | it('should return false for non-sequencer', async () => { 35 | expect(await BondManager.isCollateralized(nonSequencer.address)).to.equal( 36 | false 37 | ) 38 | }) 39 | }) 40 | }) 41 | -------------------------------------------------------------------------------- /test/contracts/L2/messaging/L2StandardTokenFactory.spec.ts: -------------------------------------------------------------------------------- 1 | import { ethers } from 'hardhat' 2 | import { ContractFactory, Contract } from 'ethers' 3 | import { 4 | smock, 5 | MockContractFactory, 6 | MockContract, 7 | } from '@defi-wonderland/smock' 8 | 9 | import { expect } from '../../../setup' 10 | import { deploy } from '../../../helpers' 11 | import { predeploys } from '../../../../src' 12 | 13 | describe('L2StandardTokenFactory', () => { 14 | let Factory__L1ERC20: MockContractFactory 15 | let L1ERC20: MockContract 16 | let L2StandardTokenFactory: Contract 17 | before(async () => { 18 | Factory__L1ERC20 = await smock.mock('ERC20') 19 | L1ERC20 = await Factory__L1ERC20.deploy('L1ERC20', 'ERC') 20 | L2StandardTokenFactory = await deploy('L2StandardTokenFactory') 21 | }) 22 | 23 | describe('Standard token factory', () => { 24 | it('should be able to create a standard token', async () => { 25 | const tx = await L2StandardTokenFactory.createStandardL2Token( 26 | L1ERC20.address, 27 | 'L2ERC20', 28 | 'ERC' 29 | ) 30 | 31 | // Pull the token creation event from the receipt 32 | const receipt = await tx.wait() 33 | const tokenCreatedEvent = receipt.events[0] 34 | 35 | // Expect there to be an event emitted for the standard token creation 36 | expect(tokenCreatedEvent.event).to.be.eq('StandardL2TokenCreated') 37 | 38 | // Get the L2 token address from the emitted event and check it was created correctly 39 | const l2Token = await ethers.getContractAt( 40 | 'L2StandardERC20', 41 | tokenCreatedEvent.args._l2Token 42 | ) 43 | 44 | expect(await l2Token.l2Bridge()).to.equal(predeploys.L2StandardBridge) 45 | expect(await l2Token.l1Token()).to.equal(L1ERC20.address) 46 | expect(await l2Token.name()).to.equal('L2ERC20') 47 | expect(await l2Token.symbol()).to.equal('ERC') 48 | }) 49 | 50 | it('should not be able to create a standard token with a 0 address for l1 token', async () => { 51 | await expect( 52 | L2StandardTokenFactory.createStandardL2Token( 53 | ethers.constants.AddressZero, 54 | 'L2ERC20', 55 | 'ERC' 56 | ) 57 | ).to.be.revertedWith('Must provide L1 token address') 58 | }) 59 | }) 60 | }) 61 | -------------------------------------------------------------------------------- /test/contracts/L2/predeploys/OVM_ETH.spec.ts: -------------------------------------------------------------------------------- 1 | /* External Imports */ 2 | import { ethers } from 'hardhat' 3 | import { Contract } from 'ethers' 4 | import { SignerWithAddress } from '@nomiclabs/hardhat-ethers/signers' 5 | 6 | import { expect } from '../../../setup' 7 | import { deploy } from '../../../helpers' 8 | 9 | describe('OVM_ETH', () => { 10 | let signer1: SignerWithAddress 11 | let signer2: SignerWithAddress 12 | before(async () => { 13 | ;[signer1, signer2] = await ethers.getSigners() 14 | }) 15 | 16 | let OVM_ETH: Contract 17 | beforeEach(async () => { 18 | OVM_ETH = await deploy('OVM_ETH') 19 | }) 20 | 21 | describe('transfer', () => { 22 | it('should revert', async () => { 23 | await expect(OVM_ETH.transfer(signer2.address, 100)).to.be.revertedWith( 24 | 'OVM_ETH: transfer is disabled pending further community discussion.' 25 | ) 26 | }) 27 | }) 28 | 29 | describe('approve', () => { 30 | it('should revert', async () => { 31 | await expect(OVM_ETH.approve(signer2.address, 100)).to.be.revertedWith( 32 | 'OVM_ETH: approve is disabled pending further community discussion.' 33 | ) 34 | }) 35 | }) 36 | 37 | describe('transferFrom', () => { 38 | it('should revert', async () => { 39 | await expect( 40 | OVM_ETH.transferFrom(signer1.address, signer2.address, 100) 41 | ).to.be.revertedWith( 42 | 'OVM_ETH: transferFrom is disabled pending further community discussion.' 43 | ) 44 | }) 45 | }) 46 | 47 | describe('increaseAllowance', () => { 48 | it('should revert', async () => { 49 | await expect( 50 | OVM_ETH.increaseAllowance(signer2.address, 100) 51 | ).to.be.revertedWith( 52 | 'OVM_ETH: increaseAllowance is disabled pending further community discussion.' 53 | ) 54 | }) 55 | }) 56 | 57 | describe('decreaseAllowance', () => { 58 | it('should revert', async () => { 59 | await expect( 60 | OVM_ETH.decreaseAllowance(signer2.address, 100) 61 | ).to.be.revertedWith( 62 | 'OVM_ETH: decreaseAllowance is disabled pending further community discussion.' 63 | ) 64 | }) 65 | }) 66 | }) 67 | -------------------------------------------------------------------------------- /test/contracts/L2/predeploys/OVM_L2ToL1MessagePasser.spec.ts: -------------------------------------------------------------------------------- 1 | /* External Imports */ 2 | import { ethers } from 'hardhat' 3 | import { ContractFactory, Contract } from 'ethers' 4 | import { smock, FakeContract } from '@defi-wonderland/smock' 5 | import { remove0x } from '@eth-patex/core-utils' 6 | import { keccak256 } from 'ethers/lib/utils' 7 | 8 | /* Internal Imports */ 9 | import { expect } from '../../../setup' 10 | import { NON_ZERO_ADDRESS } from '../../../helpers/constants' 11 | 12 | const ELEMENT_TEST_SIZES = [1, 2, 4, 8, 16] 13 | 14 | const callPredeploy = async ( 15 | Helper_PredeployCaller: Contract, 16 | predeploy: Contract, 17 | functionName: string, 18 | functionParams?: any[] 19 | ): Promise => { 20 | return Helper_PredeployCaller.callPredeploy( 21 | predeploy.address, 22 | predeploy.interface.encodeFunctionData(functionName, functionParams || []) 23 | ) 24 | } 25 | 26 | // TODO: rewrite this test to bypass the execution manager 27 | describe.skip('OVM_L2ToL1MessagePasser', () => { 28 | let Fake__OVM_ExecutionManager: FakeContract 29 | before(async () => { 30 | Fake__OVM_ExecutionManager = await smock.fake( 31 | 'OVM_ExecutionManager' 32 | ) 33 | }) 34 | 35 | let Helper_PredeployCaller: Contract 36 | before(async () => { 37 | Helper_PredeployCaller = await ( 38 | await ethers.getContractFactory('Helper_PredeployCaller') 39 | ).deploy() 40 | 41 | Helper_PredeployCaller.setTarget(Fake__OVM_ExecutionManager.address) 42 | }) 43 | 44 | let Factory__OVM_L2ToL1MessagePasser: ContractFactory 45 | before(async () => { 46 | Factory__OVM_L2ToL1MessagePasser = await ethers.getContractFactory( 47 | 'OVM_L2ToL1MessagePasser' 48 | ) 49 | }) 50 | 51 | let OVM_L2ToL1MessagePasser: Contract 52 | beforeEach(async () => { 53 | OVM_L2ToL1MessagePasser = await Factory__OVM_L2ToL1MessagePasser.deploy() 54 | }) 55 | 56 | describe('passMessageToL1', () => { 57 | before(async () => { 58 | Fake__OVM_ExecutionManager.ovmCALLER.returns(NON_ZERO_ADDRESS) 59 | }) 60 | 61 | for (const size of ELEMENT_TEST_SIZES) { 62 | it(`should be able to pass ${size} messages`, async () => { 63 | for (let i = 0; i < size; i++) { 64 | const message = '0x' + '12' + '34'.repeat(i) 65 | 66 | await callPredeploy( 67 | Helper_PredeployCaller, 68 | OVM_L2ToL1MessagePasser, 69 | 'passMessageToL1', 70 | [message] 71 | ) 72 | 73 | expect( 74 | await OVM_L2ToL1MessagePasser.sentMessages( 75 | keccak256(message + remove0x(Helper_PredeployCaller.address)) 76 | ) 77 | ).to.equal(true) 78 | } 79 | }) 80 | } 81 | }) 82 | }) 83 | -------------------------------------------------------------------------------- /test/contracts/libraries/codec/Lib_OVMCodec.spec.ts: -------------------------------------------------------------------------------- 1 | import { Contract } from 'ethers' 2 | 3 | import { expect } from '../../../setup' 4 | import { NON_ZERO_ADDRESS, deploy } from '../../../helpers' 5 | 6 | describe('Lib_OVMCodec', () => { 7 | let Lib_OVMCodec: Contract 8 | before(async () => { 9 | Lib_OVMCodec = await deploy('TestLib_OVMCodec') 10 | }) 11 | 12 | describe('hashTransaction', () => { 13 | enum QueueOrigin { 14 | SEQUENCER_QUEUE, 15 | L1TOL2_QUEUE, 16 | } 17 | 18 | it('should return the hash of a transaction', async () => { 19 | const tx = { 20 | timestamp: 121212, 21 | blockNumber: 10, 22 | l1QueueOrigin: QueueOrigin.SEQUENCER_QUEUE, 23 | l1TxOrigin: NON_ZERO_ADDRESS, 24 | entrypoint: NON_ZERO_ADDRESS, 25 | gasLimit: 100, 26 | data: '0x1234', 27 | } 28 | 29 | expect(await Lib_OVMCodec.hashTransaction(tx)).to.be.equal( 30 | '0xf07818e2db63d0140e55c9e68cfaa030f9a2d0962f671d6b339edb2207633ebd' 31 | ) 32 | }) 33 | }) 34 | }) 35 | -------------------------------------------------------------------------------- /test/contracts/libraries/rlp/Lib_RLPReader.spec.ts: -------------------------------------------------------------------------------- 1 | import { Lib_RLPReader_TEST_JSON } from '../../../data' 2 | import { runJsonTest } from '../../../helpers' 3 | 4 | describe('Lib_RLPReader', () => { 5 | describe('JSON tests', () => { 6 | runJsonTest('TestLib_RLPReader', Lib_RLPReader_TEST_JSON) 7 | }) 8 | }) 9 | -------------------------------------------------------------------------------- /test/contracts/libraries/rlp/Lib_RLPWriter.spec.ts: -------------------------------------------------------------------------------- 1 | import { Contract } from 'ethers' 2 | 3 | import { expect } from '../../../setup' 4 | import { Lib_RLPWriter_TEST_JSON } from '../../../data' 5 | import { deploy } from '../../../helpers' 6 | 7 | const encode = async (Lib_RLPWriter: Contract, input: any): Promise => { 8 | if (Array.isArray(input)) { 9 | return Lib_RLPWriter.writeList( 10 | await Promise.all( 11 | input.map(async (el) => { 12 | return encode(Lib_RLPWriter, el) 13 | }) 14 | ) 15 | ) 16 | } else if (Number.isInteger(input)) { 17 | return Lib_RLPWriter.writeUint(input) 18 | } else { 19 | return Lib_RLPWriter.writeString(input) 20 | } 21 | } 22 | 23 | describe('Lib_RLPWriter', () => { 24 | let Lib_RLPWriter: Contract 25 | before(async () => { 26 | Lib_RLPWriter = await deploy('TestLib_RLPWriter') 27 | }) 28 | 29 | describe('Official Ethereum RLP Tests', () => { 30 | for (const [key, test] of Object.entries(Lib_RLPWriter_TEST_JSON)) { 31 | it(`should properly encode: ${key}`, async () => { 32 | expect(await encode(Lib_RLPWriter, test.in)).to.equal(test.out) 33 | }) 34 | } 35 | }) 36 | 37 | describe('writeBool', () => { 38 | it(`should encode bool: true`, async () => { 39 | expect(await Lib_RLPWriter.writeBool(true)).to.equal('0x01') 40 | }) 41 | 42 | it(`should encode bool: false`, async () => { 43 | expect(await Lib_RLPWriter.writeBool(false)).to.equal('0x80') 44 | }) 45 | }) 46 | 47 | describe('Use of library with other memory-modifying operations', () => { 48 | it('should allow creation of a contract beforehand and still work', async () => { 49 | expect( 50 | await Lib_RLPWriter.callStatic.writeAddressWithTaintedMemory( 51 | '0x1234123412341234123412341234123412341234' 52 | ) 53 | ).to.eq('0x941234123412341234123412341234123412341234') 54 | }) 55 | }) 56 | }) 57 | -------------------------------------------------------------------------------- /test/contracts/libraries/standards/AddressAliasHelper.spec.ts: -------------------------------------------------------------------------------- 1 | import { Contract } from 'ethers' 2 | import { applyL1ToL2Alias, undoL1ToL2Alias } from '@eth-patex/core-utils' 3 | 4 | import { expect } from '../../../setup' 5 | import { deploy } from '../../../helpers' 6 | 7 | describe('AddressAliasHelper', () => { 8 | let AddressAliasHelper: Contract 9 | before(async () => { 10 | AddressAliasHelper = await deploy('TestLib_AddressAliasHelper') 11 | }) 12 | 13 | describe('applyL1ToL2Alias', () => { 14 | it('should be able to apply the alias to a valid address', async () => { 15 | expect( 16 | await AddressAliasHelper.applyL1ToL2Alias( 17 | '0x0000000000000000000000000000000000000000' 18 | ) 19 | ).to.equal(applyL1ToL2Alias('0x0000000000000000000000000000000000000000')) 20 | }) 21 | 22 | it('should be able to apply the alias even if the operation overflows', async () => { 23 | expect( 24 | await AddressAliasHelper.applyL1ToL2Alias( 25 | '0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF' 26 | ) 27 | ).to.equal(applyL1ToL2Alias('0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF')) 28 | }) 29 | }) 30 | 31 | describe('undoL1ToL2Alias', () => { 32 | it('should be able to undo the alias from a valid address', async () => { 33 | expect( 34 | await AddressAliasHelper.undoL1ToL2Alias( 35 | '0x1111000000000000000000000000000000001111' 36 | ) 37 | ).to.equal(undoL1ToL2Alias('0x1111000000000000000000000000000000001111')) 38 | }) 39 | 40 | it('should be able to undo the alias even if the operation underflows', async () => { 41 | expect( 42 | await AddressAliasHelper.undoL1ToL2Alias( 43 | '0x1111000000000000000000000000000000001110' 44 | ) 45 | ).to.equal(undoL1ToL2Alias('0x1111000000000000000000000000000000001110')) 46 | }) 47 | }) 48 | }) 49 | -------------------------------------------------------------------------------- /test/contracts/libraries/trie/Lib_SecureMerkleTrie.spec.ts: -------------------------------------------------------------------------------- 1 | import { Contract } from 'ethers' 2 | 3 | import { expect } from '../../../setup' 4 | import { deploy, TrieTestGenerator } from '../../../helpers' 5 | 6 | const NODE_COUNTS = [1, 2, 128] 7 | 8 | describe('Lib_SecureMerkleTrie', () => { 9 | let Lib_SecureMerkleTrie: Contract 10 | before(async () => { 11 | Lib_SecureMerkleTrie = await deploy('TestLib_SecureMerkleTrie') 12 | }) 13 | 14 | describe('verifyInclusionProof', () => { 15 | for (const nodeCount of NODE_COUNTS) { 16 | describe(`inside a trie with ${nodeCount} nodes`, () => { 17 | let generator: TrieTestGenerator 18 | before(async () => { 19 | generator = await TrieTestGenerator.fromRandom({ 20 | seed: `seed.incluson.${nodeCount}`, 21 | nodeCount, 22 | secure: true, 23 | }) 24 | }) 25 | 26 | for ( 27 | let i = 0; 28 | i < nodeCount; 29 | i += nodeCount / (nodeCount > 8 ? 8 : 1) 30 | ) { 31 | it(`should correctly prove inclusion for node #${i}`, async () => { 32 | const test = await generator.makeInclusionProofTest(i) 33 | 34 | expect( 35 | await Lib_SecureMerkleTrie.verifyInclusionProof( 36 | test.key, 37 | test.val, 38 | test.proof, 39 | test.root 40 | ) 41 | ).to.equal(true) 42 | }) 43 | } 44 | }) 45 | } 46 | }) 47 | 48 | describe('get', () => { 49 | for (const nodeCount of NODE_COUNTS) { 50 | describe(`inside a trie with ${nodeCount} nodes`, () => { 51 | let generator: TrieTestGenerator 52 | before(async () => { 53 | generator = await TrieTestGenerator.fromRandom({ 54 | seed: `seed.get.${nodeCount}`, 55 | nodeCount, 56 | secure: true, 57 | }) 58 | }) 59 | 60 | for ( 61 | let i = 0; 62 | i < nodeCount; 63 | i += nodeCount / (nodeCount > 8 ? 8 : 1) 64 | ) { 65 | it(`should correctly get the value of node #${i}`, async () => { 66 | const test = await generator.makeInclusionProofTest(i) 67 | 68 | expect( 69 | await Lib_SecureMerkleTrie.get(test.key, test.proof, test.root) 70 | ).to.deep.equal([true, test.val]) 71 | }) 72 | } 73 | }) 74 | } 75 | }) 76 | }) 77 | -------------------------------------------------------------------------------- /test/contracts/libraries/utils/Lib_Bytes32Utils.spec.ts: -------------------------------------------------------------------------------- 1 | import { Lib_Bytes32Utils_TEST_JSON } from '../../../data' 2 | import { runJsonTest } from '../../../helpers' 3 | 4 | describe('Lib_Bytes32Utils', () => { 5 | describe('JSON tests', () => { 6 | runJsonTest('TestLib_Bytes32Utils', Lib_Bytes32Utils_TEST_JSON) 7 | }) 8 | }) 9 | -------------------------------------------------------------------------------- /test/contracts/libraries/utils/Lib_BytesUtils.spec.ts: -------------------------------------------------------------------------------- 1 | import { Contract } from 'ethers' 2 | 3 | import { expect } from '../../../setup' 4 | import { Lib_BytesUtils_TEST_JSON } from '../../../data' 5 | import { deploy, runJsonTest } from '../../../helpers' 6 | 7 | describe('Lib_BytesUtils', () => { 8 | describe('JSON tests', () => { 9 | runJsonTest('TestLib_BytesUtils', Lib_BytesUtils_TEST_JSON) 10 | }) 11 | 12 | describe('Use of library with other memory-modifying operations', () => { 13 | let TestLib_BytesUtils: Contract 14 | before(async () => { 15 | TestLib_BytesUtils = await deploy('TestLib_BytesUtils') 16 | }) 17 | 18 | it('should allow creation of a contract beforehand and still work', async () => { 19 | expect( 20 | await TestLib_BytesUtils.callStatic.sliceWithTaintedMemory( 21 | '0x123412341234', 22 | 0, 23 | 0 24 | ) 25 | ).to.eq('0x') 26 | }) 27 | }) 28 | }) 29 | -------------------------------------------------------------------------------- /test/data/index.ts: -------------------------------------------------------------------------------- 1 | export { tests as Lib_RLPWriter_TEST_JSON } from './json/libraries/rlp/Lib_RLPWriter.test.json' 2 | export { tests as Lib_RLPReader_TEST_JSON } from './json/libraries/rlp/Lib_RLPReader.test.json' 3 | export { tests as Lib_Bytes32Utils_TEST_JSON } from './json/libraries/utils/Lib_Bytes32Utils.test.json' 4 | export { tests as Lib_BytesUtils_TEST_JSON } from './json/libraries/utils/Lib_BytesUtils.test.json' 5 | -------------------------------------------------------------------------------- /test/data/json/libraries/trie/trieanyorder.json: -------------------------------------------------------------------------------- 1 | { 2 | "source": "https://github.com/ethereum/tests/blob/develop/TrieTests/trieanyorder.json", 3 | "commit": "7d66cbfff1e6561d1046e45df8b7918d186b136f", 4 | "date": "2019-01-10", 5 | "tests": { 6 | "singleItem": { 7 | "in": { 8 | "A": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" 9 | }, 10 | "root": "0xd23786fb4a010da3ce639d66d5e904a11dbc02746d1ce25029e53290cabf28ab" 11 | }, 12 | "dogs": { 13 | "in": { 14 | "doe": "reindeer", 15 | "dog": "puppy", 16 | "dogglesworth": "cat" 17 | }, 18 | "root": "0x8aad789dff2f538bca5d8ea56e8abe10f4c7ba3a5dea95fea4cd6e7c3a1168d3" 19 | }, 20 | "puppy": { 21 | "in": { 22 | "do": "verb", 23 | "horse": "stallion", 24 | "doge": "coin", 25 | "dog": "puppy" 26 | }, 27 | "root": "0x5991bb8c6514148a29db676a14ac506cd2cd5775ace63c30a4fe457715e9ac84" 28 | }, 29 | "foo": { 30 | "in": { 31 | "foo": "bar", 32 | "food": "bass" 33 | }, 34 | "root": "0x17beaa1648bafa633cda809c90c04af50fc8aed3cb40d16efbddee6fdf63c4c3" 35 | }, 36 | "smallValues": { 37 | "in": { 38 | "be": "e", 39 | "dog": "puppy", 40 | "bed": "d" 41 | }, 42 | "root": "0x3f67c7a47520f79faa29255d2d3c084a7a6df0453116ed7232ff10277a8be68b" 43 | }, 44 | "testy": { 45 | "in": { 46 | "test": "test", 47 | "te": "testy" 48 | }, 49 | "root": "0x8452568af70d8d140f58d941338542f645fcca50094b20f3c3d8c3df49337928" 50 | }, 51 | "hex": { 52 | "in": { 53 | "0x0045": "0x0123456789", 54 | "0x4500": "0x9876543210" 55 | }, 56 | "root": "0x285505fcabe84badc8aa310e2aae17eddc7d120aabec8a476902c8184b3a3503" 57 | } 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /test/data/json/libraries/trie/trietest.json: -------------------------------------------------------------------------------- 1 | { 2 | "source": "https://github.com/ethereum/tests/blob/develop/TrieTests/trietest.json", 3 | "commit": "7d66cbfff1e6561d1046e45df8b7918d186b136f", 4 | "date": "2019-01-10", 5 | "tests": { 6 | "insert-middle-leaf": { 7 | "in": [ 8 | [ "key1aa", "0123456789012345678901234567890123456789xxx"], 9 | [ "key1", "0123456789012345678901234567890123456789Very_Long"], 10 | [ "key2bb", "aval3"], 11 | [ "key2", "short"], 12 | [ "key3cc", "aval3"], 13 | [ "key3","1234567890123456789012345678901"] 14 | ], 15 | "root": "0xcb65032e2f76c48b82b5c24b3db8f670ce73982869d38cd39a624f23d62a9e89" 16 | }, 17 | "branch-value-update": { 18 | "in": [ 19 | [ "abc", "123" ], 20 | [ "abcd", "abcd" ], 21 | [ "abc", "abc" ] 22 | ], 23 | "root": "0x7a320748f780ad9ad5b0837302075ce0eeba6c26e3d8562c67ccc0f1b273298a" 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /test/data/json/libraries/utils/Lib_Bytes32Utils.test.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": { 3 | "toBool": { 4 | "input bytes32 of 0": { 5 | "in": ["0x0000000000000000000000000000000000000000000000000000000000000000"], 6 | "out": [false] 7 | }, 8 | "input bytes32 of 1": { 9 | "in": ["0x0000000000000000000000000000000000000000000000000000000000000001"], 10 | "out": [true] 11 | }, 12 | "input bytes32 > 1": { 13 | "in": ["0x1212121212121212121212121212121212121212121212121212121212121212"], 14 | "out": [true] 15 | }, 16 | "input bytes32 > 1, last byte 0": { 17 | "in": ["0x1212121212121212121212121212121212121212121212121212121212121200"], 18 | "out": [true] 19 | } 20 | }, 21 | "fromBool": { 22 | "input false": { 23 | "in": [false], 24 | "out": ["0x0000000000000000000000000000000000000000000000000000000000000000"] 25 | }, 26 | "input true": { 27 | "in": [true], 28 | "out": ["0x0000000000000000000000000000000000000000000000000000000000000001"] 29 | } 30 | }, 31 | "toAddress": { 32 | "input bytes32 address": { 33 | "in": ["0x0000000000000000000000001212121212121212121212121212121212121212"], 34 | "out": ["0x1212121212121212121212121212121212121212"] 35 | }, 36 | "input full bytes32": { 37 | "in": ["0x1212121212121212121212121212121212121212121212121212121212121212"], 38 | "out": ["0x1212121212121212121212121212121212121212"] 39 | } 40 | }, 41 | "fromAddress": { 42 | "input address": { 43 | "in": ["0x1212121212121212121212121212121212121212"], 44 | "out": ["0x0000000000000000000000001212121212121212121212121212121212121212"] 45 | } 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /test/helpers/codec/bridge.ts: -------------------------------------------------------------------------------- 1 | /* Imports: Internal */ 2 | import { getContractInterface } from '../../../src/contract-defs' 3 | 4 | export const encodeXDomainCalldata = ( 5 | target: string, 6 | sender: string, 7 | message: string, 8 | messageNonce: number 9 | ): string => { 10 | return getContractInterface('L2CrossDomainMessenger').encodeFunctionData( 11 | 'relayMessage', 12 | [target, sender, message, messageNonce] 13 | ) 14 | } 15 | -------------------------------------------------------------------------------- /test/helpers/codec/index.ts: -------------------------------------------------------------------------------- 1 | export * from './bridge' 2 | -------------------------------------------------------------------------------- /test/helpers/constants.ts: -------------------------------------------------------------------------------- 1 | export const L2_GAS_DISCOUNT_DIVISOR = 32 2 | export const ENQUEUE_GAS_COST = 60_000 3 | export const NON_NULL_BYTES32 = 4 | '0x1111111111111111111111111111111111111111111111111111111111111111' 5 | export const NON_ZERO_ADDRESS = '0x1111111111111111111111111111111111111111' 6 | -------------------------------------------------------------------------------- /test/helpers/dummy/batches.ts: -------------------------------------------------------------------------------- 1 | import { ethers } from 'hardhat' 2 | 3 | import { NON_ZERO_ADDRESS } from '../constants' 4 | 5 | export const DUMMY_BATCH_HEADERS = [ 6 | { 7 | batchIndex: 0, 8 | batchRoot: ethers.constants.HashZero, 9 | batchSize: 0, 10 | prevTotalElements: 0, 11 | extraData: ethers.utils.defaultAbiCoder.encode( 12 | ['uint256', 'address'], 13 | [ethers.constants.HashZero, NON_ZERO_ADDRESS] 14 | ), 15 | }, 16 | { 17 | batchIndex: 1, 18 | batchRoot: ethers.constants.HashZero, 19 | batchSize: 0, 20 | prevTotalElements: 0, 21 | extraData: ethers.utils.defaultAbiCoder.encode( 22 | ['uint256', 'address'], 23 | [ethers.constants.HashZero, NON_ZERO_ADDRESS] 24 | ), 25 | }, 26 | ] 27 | 28 | export const DUMMY_BATCH_PROOFS = [ 29 | { 30 | index: 0, 31 | siblings: [ethers.constants.HashZero], 32 | }, 33 | { 34 | index: 1, 35 | siblings: [ethers.constants.HashZero], 36 | }, 37 | ] 38 | -------------------------------------------------------------------------------- /test/helpers/dummy/index.ts: -------------------------------------------------------------------------------- 1 | export * from './batches' 2 | -------------------------------------------------------------------------------- /test/helpers/index.ts: -------------------------------------------------------------------------------- 1 | export * from './dummy' 2 | export * from './constants' 3 | export * from './utils' 4 | export * from './codec' 5 | export * from './test-runner' 6 | export * from './trie' 7 | -------------------------------------------------------------------------------- /test/helpers/test-runner/index.ts: -------------------------------------------------------------------------------- 1 | export * from './json-test-runner' 2 | -------------------------------------------------------------------------------- /test/helpers/test-runner/json-test-runner.ts: -------------------------------------------------------------------------------- 1 | /* External Imports */ 2 | import { ethers } from 'hardhat' 3 | import { Contract } from 'ethers' 4 | 5 | import { expect } from '../../setup' 6 | 7 | const bigNumberify = (arr: any[]) => { 8 | return arr.map((el: any) => { 9 | if (typeof el === 'number') { 10 | return ethers.BigNumber.from(el) 11 | } else if (typeof el === 'string' && /^\d+n$/gm.test(el)) { 12 | return ethers.BigNumber.from(el.slice(0, el.length - 1)) 13 | } else if (typeof el === 'string' && el.length > 2 && el.startsWith('0x')) { 14 | return ethers.BigNumber.from(el.toLowerCase()) 15 | } else if (Array.isArray(el)) { 16 | return bigNumberify(el) 17 | } else { 18 | return el 19 | } 20 | }) 21 | } 22 | 23 | export const runJsonTest = (contractName: string, json: any): void => { 24 | let contract: Contract 25 | before(async () => { 26 | contract = await (await ethers.getContractFactory(contractName)).deploy() 27 | }) 28 | 29 | for (const [functionName, functionTests] of Object.entries(json)) { 30 | describe(functionName, () => { 31 | for (const [key, test] of Object.entries(functionTests)) { 32 | it(`should run test: ${key}`, async () => { 33 | if (test.revert) { 34 | await expect(contract.functions[functionName](...test.in)).to.be 35 | .reverted 36 | } else { 37 | const result = await contract.functions[functionName](...test.in) 38 | expect(JSON.stringify(bigNumberify(result))).to.deep.equal( 39 | JSON.stringify(bigNumberify(test.out)) 40 | ) 41 | } 42 | }) 43 | } 44 | }) 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /test/helpers/trie/index.ts: -------------------------------------------------------------------------------- 1 | export * from './trie-test-generator' 2 | -------------------------------------------------------------------------------- /test/helpers/utils/deploy.ts: -------------------------------------------------------------------------------- 1 | import hre from 'hardhat' 2 | 3 | export const deploy = async ( 4 | name: string, 5 | opts?: { 6 | args?: any[] 7 | signer?: any 8 | } 9 | ) => { 10 | const factory = await hre.ethers.getContractFactory(name, opts?.signer) 11 | return factory.deploy(...(opts?.args || [])) 12 | } 13 | -------------------------------------------------------------------------------- /test/helpers/utils/eth-time.ts: -------------------------------------------------------------------------------- 1 | export const getEthTime = async (provider: any): Promise => { 2 | return (await provider.getBlock('latest')).timestamp 3 | } 4 | 5 | export const setEthTime = async ( 6 | provider: any, 7 | time: number 8 | ): Promise => { 9 | await provider.send('evm_setNextBlockTimestamp', [time]) 10 | } 11 | 12 | export const increaseEthTime = async ( 13 | provider: any, 14 | amount: number 15 | ): Promise => { 16 | await setEthTime(provider, (await getEthTime(provider)) + amount) 17 | await mineBlock(provider) 18 | } 19 | 20 | const mineBlock = async (provider: any, timestamp?: number): Promise => { 21 | await provider.send('evm_mine', timestamp ? [timestamp] : []) 22 | } 23 | 24 | export const getNextBlockNumber = async (provider: any): Promise => { 25 | return (await provider.getBlock('latest')).number + 1 26 | } 27 | -------------------------------------------------------------------------------- /test/helpers/utils/impersonation.ts: -------------------------------------------------------------------------------- 1 | import { toRpcHexString } from '@eth-patex/core-utils' 2 | import { SignerWithAddress } from '@nomiclabs/hardhat-ethers/signers' 3 | import { BigNumber } from 'ethers' 4 | import hre from 'hardhat' 5 | 6 | export const impersonate = async ( 7 | address: string, 8 | balance?: string | number | BigNumber 9 | ): Promise => { 10 | await hre.network.provider.request({ 11 | method: 'hardhat_impersonateAccount', 12 | params: [address], 13 | }) 14 | 15 | if (balance !== undefined) { 16 | await hre.network.provider.request({ 17 | method: 'hardhat_setBalance', 18 | params: [address, toRpcHexString(BigNumber.from(balance))], 19 | }) 20 | } 21 | 22 | return hre.ethers.getSigner(address) 23 | } 24 | -------------------------------------------------------------------------------- /test/helpers/utils/index.ts: -------------------------------------------------------------------------------- 1 | export * from './eth-time' 2 | export * from './deploy' 3 | export * from './impersonation' 4 | -------------------------------------------------------------------------------- /test/setup.ts: -------------------------------------------------------------------------------- 1 | /* External Imports */ 2 | import chai = require('chai') 3 | import Mocha from 'mocha' 4 | import { solidity } from 'ethereum-waffle' 5 | 6 | chai.use(solidity) 7 | const should = chai.should() 8 | const expect = chai.expect 9 | 10 | export { should, expect, Mocha } 11 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "commonjs", 4 | "target": "es2017", 5 | "sourceMap": true, 6 | "esModuleInterop": true, 7 | "composite": true, 8 | "resolveJsonModule": true, 9 | "declaration": true, 10 | "noImplicitAny": false, 11 | "removeComments": true, 12 | "noLib": false, 13 | "emitDecoratorMetadata": true, 14 | "experimentalDecorators": true, 15 | "typeRoots": [ 16 | "node_modules/@types" 17 | ], 18 | "rootDir": "./src", 19 | "outDir": "./dist" 20 | }, 21 | "exclude": [ 22 | "node_modules", 23 | "dist" 24 | ], 25 | "include": [ 26 | "src/**/*" 27 | ] 28 | } 29 | --------------------------------------------------------------------------------