├── .clabot
├── .env-sample
├── .env.arb1.sample
├── .eslintignore
├── .eslintrc.js
├── .gitattributes
├── .github
├── dependabot.yml
└── workflows
│ ├── build-test.yml
│ └── slither.yml
├── .gitignore
├── .gitmodules
├── .prettierignore
├── .prettierrc.js
├── .solhint.json
├── LICENSE
├── README.md
├── _deployments
├── 11155111_current_deployment.json
├── 11155111_queued-updates.json
├── 1337_current_deployment.json
├── 1337_queued-updates.json
├── 1_42170_current_deployment.json
├── 1_42170_queued-updates.json
├── 1_current_deployment.json
├── 1_queued-updates.json
├── 421611_current_deployment.json
├── 421611_queued-updates.json
├── 421613_current_deployment.json
├── 421613_queued-updates.json
├── 421614_current_deployment.json
├── 421614_queued-updates.json
├── 42161_current_deployment.json
├── 42161_queued-updates.json
├── 42170_current_deployment.json
├── 42170_queued-updates.json
├── 4_current_deployment.json
├── 4_queued-updates.json
├── 5_current_deployment.json
└── 5_queued-updates.json
├── audits
├── ConsenSys_Diligence_Arbitrum_Contracts_11_2021.pdf
└── trail_of_bits_governance_report_1_6_2023.pdf
├── contracts
├── rpc-utils
│ ├── MulticallV2.sol
│ ├── NodeInterface.sol
│ └── RetryableTicketCreator.sol
└── tokenbridge
│ ├── arbitrum
│ ├── IArbToken.sol
│ ├── L2ArbitrumMessenger.sol
│ ├── L2AtomicTokenBridgeFactory.sol
│ ├── ReverseArbToken.sol
│ ├── StandardArbERC20.sol
│ └── gateway
│ │ ├── L2ArbitrumGateway.sol
│ │ ├── L2CustomGateway.sol
│ │ ├── L2ERC20Gateway.sol
│ │ ├── L2GatewayRouter.sol
│ │ ├── L2ReverseCustomGateway.sol
│ │ ├── L2USDCGateway.sol
│ │ └── L2WethGateway.sol
│ ├── ethereum
│ ├── ICustomToken.sol
│ ├── L1ArbitrumMessenger.sol
│ ├── L1AtomicTokenBridgeCreator.sol
│ ├── L1TokenBridgeRetryableSender.sol
│ └── gateway
│ │ ├── IL1ArbitrumGateway.sol
│ │ ├── IL1GatewayRouter.sol
│ │ ├── L1ArbitrumExtendedGateway.sol
│ │ ├── L1ArbitrumGateway.sol
│ │ ├── L1CustomGateway.sol
│ │ ├── L1ERC20Gateway.sol
│ │ ├── L1ForceOnlyReverseCustomGateway.sol
│ │ ├── L1GatewayRouter.sol
│ │ ├── L1OrbitCustomGateway.sol
│ │ ├── L1OrbitERC20Gateway.sol
│ │ ├── L1OrbitGatewayRouter.sol
│ │ ├── L1OrbitReverseCustomGateway.sol
│ │ ├── L1OrbitUSDCGateway.sol
│ │ ├── L1ReverseCustomGateway.sol
│ │ ├── L1USDCGateway.sol
│ │ └── L1WethGateway.sol
│ ├── libraries
│ ├── AddressAliasHelper.sol
│ ├── BytesLib.sol
│ ├── BytesParser.sol
│ ├── ClonableBeaconProxy.sol
│ ├── Cloneable.sol
│ ├── CreationCodeHelper.sol
│ ├── ERC165.sol
│ ├── ERC20Upgradeable.sol
│ ├── ICloneable.sol
│ ├── IERC165.sol
│ ├── IERC20Bridge.sol
│ ├── IFiatToken.sol
│ ├── ITransferAndCall.sol
│ ├── IWETH9.sol
│ ├── L2CustomGatewayToken.sol
│ ├── L2GatewayToken.sol
│ ├── ProxyUtil.sol
│ ├── TransferAndCallToken.sol
│ ├── Whitelist.sol
│ ├── aeERC20.sol
│ ├── aeWETH.sol
│ ├── draft-ERC20PermitUpgradeable.sol
│ └── gateway
│ │ ├── GatewayMessageHandler.sol
│ │ ├── GatewayRouter.sol
│ │ ├── ICustomGateway.sol
│ │ ├── IGatewayRouter.sol
│ │ ├── ITokenGateway.sol
│ │ └── TokenGateway.sol
│ └── test
│ ├── AddressMappingTest.sol
│ ├── ArbSysMock.sol
│ ├── CreationCodeTest.sol
│ ├── InboxMock.sol
│ ├── InterfaceCompatibilityTester.sol
│ ├── TestArbCustomToken.sol
│ ├── TestArbCustomTokenBurnFee.sol
│ ├── TestBytesParser.sol
│ ├── TestCustomTokenL1.sol
│ ├── TestERC20.sol
│ ├── TestPostDepositCall.sol
│ ├── TestWETH9.sol
│ └── UpgradeExecutorForVerification.sol
├── deployment-42161.json
├── deployment-421611.json
├── docs
├── deployment.md
└── mutation_testing.md
├── foundry.toml
├── hardhat.config.ts
├── package.json
├── remappings.txt
├── scripts
├── atomicTokenBridgeDeployer.ts
├── contractVerifier.ts
├── deploy_buddy_deployer.ts
├── deployment
│ ├── createTokenBridge.ts
│ └── deployTokenBridgeCreator.ts
├── local-deployment
│ ├── deployCreatorAndCreateTokenBridge.ts
│ └── localDeploymentLib.ts
├── orbitVerifyOnBlockscout.ts
├── register_custom_token.ts
├── signatures_test.bash
├── storage_layout_test.bash
├── upgradeTemplate.ts
├── usdc-bridge-deployment
│ ├── README.md
│ ├── deployUsdcBridge.ts
│ └── env.example
├── utils.ts
└── verify_upgrade.ts
├── slither.config.json
├── slither.db.json
├── tasks
├── compareBytecode.ts
├── index.ts
├── peripheralsTasks.ts
└── types.ts
├── test-e2e
├── creationCodeTest.ts
├── orbitTokenBridge.ts
└── tokenBridgeDeploymentTest.ts
├── test-foundry
├── AtomicTokenBridgeFactory.t.sol
├── GatewayRouter.t.sol
├── IOwnable.sol
├── L1ArbitrumExtendedGateway.t.sol
├── L1ArbitrumGateway.t.sol
├── L1AtomicTokenBridgeCreator.t.sol
├── L1CustomGateway.t.sol
├── L1ERC20Gateway.t.sol
├── L1ForceOnlyReverseCustomGateway.t.sol
├── L1GatewayRouter.t.sol
├── L1OrbitCustomGateway.t.sol
├── L1OrbitERC20Gateway.t.sol
├── L1OrbitGatewayRouter.t.sol
├── L1OrbitIntegration.t.sol
├── L1OrbitReverseCustomGateway.t.sol
├── L1OrbitUSDCGateway.t.sol
├── L1ReverseCustomGateway.t.sol
├── L1USDCGateway.t.sol
├── L1WethGateway.t.sol
├── L2ArbitrumGateway.t.sol
├── L2AtomicTokenBridgeFactory.t.sol
├── L2CustomGateway.t.sol
├── L2ERC20Gateway.t.sol
├── L2GatewayRouter.t.sol
├── L2ReverseCustomGateway.t.sol
├── L2USDCGateway.t.sol
├── L2WethGateway.t.sol
└── util
│ └── TestUtil.sol
├── test-mutation
├── all-configs
│ ├── config.single.json
│ ├── config.tokenbridge-arbitrum.json
│ └── config.tokenbridge-ethereum.json
├── config.json
└── gambitTester.ts
├── test
├── bytesParser.l1.ts
├── canonicalBridge.e2e.ts
├── canonicalBridge.l1.ts
├── canonicalBridge.l2.ts
├── customGateway.e2e.ts
├── gatewayRouter.l1.ts
├── reverseCustomGateway.e2e.ts
├── signatures
│ ├── L1AtomicTokenBridgeCreator
│ ├── L1CustomGateway
│ ├── L1ERC20Gateway
│ ├── L1GatewayRouter
│ ├── L1OrbitCustomGateway
│ ├── L1OrbitERC20Gateway
│ ├── L1OrbitGatewayRouter
│ ├── L1OrbitReverseCustomGateway
│ ├── L1OrbitUSDCGateway
│ ├── L1ReverseCustomGateway
│ ├── L1TokenBridgeRetryableSender
│ ├── L1USDCGateway
│ ├── L1WethGateway
│ ├── L2AtomicTokenBridgeFactory
│ ├── L2CustomGateway
│ ├── L2ERC20Gateway
│ ├── L2GatewayRouter
│ ├── L2ReverseCustomGateway
│ ├── L2USDCGateway
│ ├── L2WethGateway
│ └── StandardArbERC20
├── storage
│ ├── L1AtomicTokenBridgeCreator
│ ├── L1CustomGateway
│ ├── L1ERC20Gateway
│ ├── L1GatewayRouter
│ ├── L1OrbitCustomGateway
│ ├── L1OrbitERC20Gateway
│ ├── L1OrbitGatewayRouter
│ ├── L1OrbitReverseCustomGateway
│ ├── L1OrbitUSDCGateway
│ ├── L1ReverseCustomGateway
│ ├── L1TokenBridgeRetryableSender
│ ├── L1USDCGateway
│ ├── L1WethGateway
│ ├── L2AtomicTokenBridgeFactory
│ ├── L2CustomGateway
│ ├── L2ERC20Gateway
│ ├── L2GatewayRouter
│ ├── L2ReverseCustomGateway
│ ├── L2USDCGateway
│ ├── L2WethGateway
│ └── StandardArbERC20
├── testhelper.ts
├── unused-errors
│ └── exceptions.txt
├── wethBridge.l1.ts
├── wethBridge.l2.ts
└── wethGateway.e2e.ts
├── tsconfig.json
└── yarn.lock
/.clabot:
--------------------------------------------------------------------------------
1 | {
2 | "contributors": "https://api.github.com/repos/OffchainLabs/clabot-config/contents/apache-contributors.json",
3 | "message": "We require contributors to sign our Contributor License Agreement. In order for us to review and merge your code, please sign one of the linked documents below to get yourself added. If you're an independent Individual please sign this form: https://na3.docusign.net/Member/PowerFormSigning.aspx?PowerFormId=1353a816-a9c1-47ba-847e-ec79f0f23d31&env=na3&acct=6e152afc-6284-44af-a4c1-d8ef291db402&v=2. If you're with a company (corporate) please sign this form: https://na3.docusign.net/Member/PowerFormSigning.aspx?PowerFormId=2b5fe8ba-51d4-4980-b4ee-605d66e675d4&env=na3&acct=6e152afc-6284-44af-a4c1-d8ef291db402&v=2. To agree to the CLA license, please fill out one of the attached forms."
4 | }
5 |
--------------------------------------------------------------------------------
/.env-sample:
--------------------------------------------------------------------------------
1 | ## RPC endpoint
2 | BASECHAIN_RPC=""
3 |
4 | ## Deployer key used for deploying creator or creating token bridge
5 | BASECHAIN_DEPLOYER_KEY=""
6 |
7 | ## WETH address on the basechain. It will be set and used in the TokenBridgeCreator
8 | BASECHAIN_WETH=""
9 |
10 | ## Gas limit for deploying child chain factory needs to be provided to the TokenBridgeCreator when templates are set.
11 | ## If this param is not provided then gas limit will be estimated using SDK from child chain (specified by ORBIT_RPC and ROLLUP_ADDRESS)
12 | GAS_LIMIT_FOR_L2_FACTORY_DEPLOYMENT=6000000
13 |
14 | ## Contract verification
15 | ARBISCAN_API_KEY=""
16 |
17 | ### Vars for creating token bridge from existing TokenBridgeCreator
18 | ## Rollup on top of which token bridge will be created
19 | ROLLUP_ADDRESS=""
20 | ORBIT_RPC=""
21 | ROLLUP_OWNER=""
22 | L1_TOKEN_BRIDGE_CREATOR=""
23 | # needed for verification
24 | L1_RETRYABLE_SENDER=""
--------------------------------------------------------------------------------
/.env.arb1.sample:
--------------------------------------------------------------------------------
1 | ## RPC endpoint
2 | BASECHAIN_RPC="https://arb1.arbitrum.io/rpc"
3 |
4 | ## Deployer key used for deploying creator or creating token bridge
5 | BASECHAIN_DEPLOYER_KEY=""
6 |
7 | ## WETH address on the basechain. It will be set and used in the TokenBridgeCreator
8 | BASECHAIN_WETH="0x82aF49447D8a07e3bd95BD0d56f35241523fBab1"
9 |
10 | ## Gas limit for deploying child chain factory needs to be provided to the TokenBridgeCreator when templates are set.
11 | ## If this param is not provided then gas limit will be estimated using SDK from child chain (specified by ORBIT_RPC and ROLLUP_ADDRESS)
12 | GAS_LIMIT_FOR_L2_FACTORY_DEPLOYMENT=6000000
13 |
14 | ## Contract verification
15 | ARBISCAN_API_KEY=""
16 |
17 |
18 | ### Vars for creating token bridge from existing TokenBridgeCreator
19 | ## Rollup on top of which token bridge will be created
20 | # ROLLUP_ADDRESS=""
21 | # ORBIT_RPC=""
22 | # ROLLUP_OWNER=""
23 | # L1_TOKEN_BRIDGE_CREATOR=""
24 | # # needed for verification
25 | # L1_RETRYABLE_SENDER=""
--------------------------------------------------------------------------------
/.eslintignore:
--------------------------------------------------------------------------------
1 | cache
2 | coverage
3 | build
4 | _deployments
5 | dist
6 | lib
7 | out
--------------------------------------------------------------------------------
/.eslintrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | env: {
3 | commonjs: true,
4 | es6: true,
5 | node: true,
6 | },
7 | plugins: ['prettier'],
8 | extends: [
9 | 'eslint:recommended',
10 | 'plugin:prettier/recommended', // Enables eslint-plugin-prettier and displays prettier errors as ESLint errors. Make sure this is always the last configuration in the extends array.
11 | ],
12 | parserOptions: {
13 | ecmaVersion: 2018, // Allows for the parsing of modern ECMAScript features
14 | sourceType: 'module', // Allows for the use of imports
15 | },
16 | rules: {
17 | 'prettier/prettier': 'error',
18 | 'no-unused-vars': 'off',
19 | 'prefer-const': [2, { destructuring: 'all' }],
20 | 'object-curly-spacing': ['error', 'always'],
21 | },
22 | overrides: [
23 | {
24 | files: [
25 | 'test/**/*.ts',
26 | 'test/**/*.tsx',
27 | 'scripts/**/*.ts',
28 | 'scripts/**/*.tsx',
29 | ],
30 | parser: '@typescript-eslint/parser',
31 | parserOptions: {
32 | project: 'tsconfig.json',
33 | },
34 | extends: [
35 | 'eslint:recommended',
36 | 'plugin:@typescript-eslint/recommended',
37 | 'plugin:prettier/recommended',
38 | ],
39 | plugins: ['@typescript-eslint', 'prettier', '@typescript-eslint/tslint'],
40 | rules: {
41 | 'no-empty-pattern': 'warn',
42 | 'prettier/prettier': ['error', { singleQuote: true }],
43 | '@typescript-eslint/member-delimiter-style': ['off'],
44 | '@typescript-eslint/no-explicit-any': ['off'],
45 | '@typescript-eslint/no-use-before-define': ['off'],
46 | '@typescript-eslint/no-non-null-assertion': ['off'],
47 | '@typescript-eslint/ban-ts-comment': ['warn'],
48 | '@typescript-eslint/no-unused-vars': [
49 | 'warn',
50 | {
51 | argsIgnorePattern: '^_',
52 | varsIgnorePattern: '^_',
53 | caughtErrorsIgnorePattern: '^_',
54 | },
55 | ],
56 | '@typescript-eslint/tslint/config': [
57 | 'error',
58 | {
59 | rules: { 'strict-comparisons': true },
60 | },
61 | ],
62 | 'no-implicit-coercion': 'error',
63 | },
64 | },
65 | ],
66 | }
67 |
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | *.sol linguist-language=Solidity
--------------------------------------------------------------------------------
/.github/dependabot.yml:
--------------------------------------------------------------------------------
1 | version: 2
2 | updates:
3 | - package-ecosystem: gomod
4 | directory: '/packages/arb-node-core'
5 | schedule:
6 | interval: daily
7 | open-pull-requests-limit: 10
8 | target-branch: master
9 | - package-ecosystem: gomod
10 | directory: '/packages/arb-rpc-node'
11 | schedule:
12 | interval: daily
13 | open-pull-requests-limit: 10
14 | target-branch: master
15 | - package-ecosystem: gomod
16 | directory: '/packages/arb-avm-cpp'
17 | schedule:
18 | interval: daily
19 | open-pull-requests-limit: 10
20 | target-branch: master
21 | - package-ecosystem: gomod
22 | directory: '/packages/arb-evm'
23 | schedule:
24 | interval: daily
25 | open-pull-requests-limit: 10
26 | target-branch: master
27 | - package-ecosystem: gomod
28 | directory: '/packages/arb-util'
29 | schedule:
30 | interval: daily
31 | open-pull-requests-limit: 10
32 | target-branch: master
33 | - package-ecosystem: npm
34 | directory: '/'
35 | schedule:
36 | interval: daily
37 | open-pull-requests-limit: 10
38 | target-branch: master
39 | - package-ecosystem: gitsubmodule
40 | directory: '/packages/arb-avm-cpp/external'
41 | schedule:
42 | interval: daily
43 | open-pull-requests-limit: 10
44 | target-branch: master
45 |
--------------------------------------------------------------------------------
/.github/workflows/slither.yml:
--------------------------------------------------------------------------------
1 | name: Slither Analysis
2 |
3 | on:
4 | workflow_dispatch:
5 | pull_request:
6 |
7 | jobs:
8 | analyze:
9 | runs-on: ubuntu-latest
10 | steps:
11 | - uses: actions/checkout@v4
12 |
13 | - name: Run Slither
14 | uses: crytic/slither-action@v0.3.1
15 | id: slither
16 | with:
17 | sarif: results.sarif
18 | fail-on: medium
19 |
20 | - name: Upload SARIF file
21 | if: always()
22 | uses: github/codeql-action/upload-sarif@v3
23 | with:
24 | sarif_file: ${{ steps.slither.outputs.sarif }}
25 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .gitignore
2 | .env
3 | node_modules
4 | .vscode/
5 |
6 | #Hardhat files
7 | cache
8 | build
9 | artifacts
10 | deployment.json
11 |
12 | #Foundry files
13 | out/
14 | forge-cache/
15 |
16 | #Storage layout test files
17 | test/storage/*-old.dot
18 | test/storage/*-old
19 | test/signatures/*-old
20 |
21 | # local deployment files
22 | network.json
23 |
24 | # Gambit (mutation test) files
25 | gambit_out/
26 | test-mutation/mutant_test_env/
27 |
28 | # bridged usdc deployment script
29 | registerUsdcGatewayTx.json
--------------------------------------------------------------------------------
/.gitmodules:
--------------------------------------------------------------------------------
1 | [submodule "lib/forge-std"]
2 | path = lib/forge-std
3 | url = https://github.com/foundry-rs/forge-std
4 | [submodule "lib/nitro-contracts"]
5 | path = lib/nitro-contracts
6 | url = https://github.com/OffchainLabs/nitro-contracts.git
7 | branch = develop
8 |
9 |
--------------------------------------------------------------------------------
/.prettierignore:
--------------------------------------------------------------------------------
1 | cache
2 | build
3 | coverage
4 | deployments
5 | dist
6 | lib
7 | out
--------------------------------------------------------------------------------
/.prettierrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | semi: false,
3 | trailingComma: 'es5',
4 | singleQuote: true,
5 | printWidth: 80,
6 | tabWidth: 2,
7 | arrowParens: 'avoid',
8 | bracketSpacing: true,
9 | overrides: [
10 | {
11 | files: '*.sol',
12 | options: {
13 | printWidth: 100,
14 | tabWidth: 4,
15 | useTabs: false,
16 | singleQuote: false,
17 | bracketSpacing: true,
18 | explicitTypes: 'always',
19 | },
20 | },
21 | ],
22 | }
23 |
--------------------------------------------------------------------------------
/.solhint.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "solhint:recommended",
3 | "plugins": ["prettier"],
4 | "rules": {
5 | "mark-callable-contracts": "none",
6 | "prettier/prettier": "error",
7 | "compiler-version": ["error", "^0.8.0"]
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |

2 |
3 | # Arbitrum Token Bridge Contracts
4 |
5 | The Arbitrum Token Bridge is a decentralized application that uses [Nitro's](https://github.com/OffchainLabs/nitro) arbitrary cross-chain messaging system to implement an ERC20 token bridge between an EVM compatible base-chain and an Arbitrum chain.
6 |
7 | All public Arbitrum chains include a [canonical token bridge deployment](https://developer.arbitrum.io/useful-addresses#token-bridge).
8 |
9 | The Token Bridge includes "Gateway" contracts — pairs of contracts that implement a particular token-bridging flow — as well as "Gateway Router" contracts, which map tokens to their respective gateways.
10 |
11 | See the [developer documentation](https://developer.arbitrum.io/asset-bridging) for more info.
12 |
13 | See security audit reports [here](./audits).
14 |
15 | This repository is offered under the Apache 2.0 license. See LICENSE for details.
16 |
17 | ## Deployment
18 | Check [this doc](./docs/deployment.md) for instructions on deployment and verification of token bridge.
19 |
20 | ## Contact
21 |
22 | Discord - [Arbitrum](https://discord.com/invite/5KE54JwyTs)
23 |
24 | Twitter: [Arbitrum](https://twitter.com/arbitrum)
25 |
--------------------------------------------------------------------------------
/_deployments/11155111_current_deployment.json:
--------------------------------------------------------------------------------
1 | {
2 | "proxyAdminAddress": "0xDBFC2FfB44A5D841aB42b0882711ed6e5A9244b0",
3 | "contracts": {
4 | "L1GatewayRouter": {
5 | "proxyAddress": "0xcE18836b233C83325Cc8848CA4487e94C6288264",
6 | "implAddress": "0xba4F913CEb90ff1a0A8ccf7bd06B807B92B2E34e",
7 | "implDeploymentTxn": "0xfc76c6049cc5cc45dee33ea39c53cecc078cec4805be75d24f11ca1e5bf4fea2",
8 | "implArbitrumCommitHash": "using-sdk-731092406",
9 | "implBuildInfo": ""
10 | },
11 | "L1ERC20Gateway": {
12 | "proxyAddress": "0x902b3E5f8F19571859F4AB1003B960a5dF693aFF",
13 | "implAddress": "0x98431DDc27633f7315Aa2c153233529bb241445a",
14 | "implDeploymentTxn": "0x3992d29147de172635615554ec76354ffdef5f709c43e59df752898e3fbf504a",
15 | "implArbitrumCommitHash": "using-sdk-731092406",
16 | "implBuildInfo": ""
17 | },
18 | "L1CustomGateway": {
19 | "proxyAddress": "0xba2F7B6eAe1F9d174199C5E4867b563E0eaC40F3",
20 | "implAddress": "0x065D10fb680CCEC460051281ed150Ff610ECaAfc",
21 | "implDeploymentTxn": "0x32bf8c2cac0ddd0bcc6e032c63abd29e0a6addda7d149ffc6ea927b30c1a329c",
22 | "implArbitrumCommitHash": "using-sdk-731092406",
23 | "implBuildInfo": ""
24 | },
25 | "L1WethGateway": {
26 | "proxyAddress": "0xA8aD8d7e13cbf556eE75CB0324c13535d8100e1E",
27 | "implAddress": "0x8a3C6102D4435Cd156Ce95d5Dc0cf9df2BAab078",
28 | "implDeploymentTxn": "0xf8af2de122380ce1252f69cf8fe853ef44ef4bfc0ff9825427e1bf591d98d844",
29 | "implArbitrumCommitHash": "using-sdk-731092406",
30 | "implBuildInfo": ""
31 | }
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/_deployments/11155111_queued-updates.json:
--------------------------------------------------------------------------------
1 | {}
2 |
--------------------------------------------------------------------------------
/_deployments/1337_current_deployment.json:
--------------------------------------------------------------------------------
1 | {
2 | "proxyAdminAddress": "0x9aD46fac0Cf7f790E5be05A0F15223935A0c0aDa",
3 | "contracts": {
4 | "L1GatewayRouter": {
5 | "proxyAddress": "0x72Ce9c846789fdB6fC1f34aC4AD25Dd9ef7031ef",
6 |
7 | "implAddress": "0x4b2cf3be8677096310b32a648b0bdb8c5a8ddc94",
8 | "implDeploymentTxn": "0x",
9 | "implArbitrumCommitHash": "0x"
10 | },
11 | "L1ERC20Gateway": {
12 | "proxyAddress": "0xa3A7B6F88361F48403514059F1F16C8E78d60EeC",
13 | "implAddress": "0x41ac92014c66c38bbbdef8ccf5a060cca5634fd5",
14 | "implDeploymentTxn": "0x",
15 | "implArbitrumCommitHash": "0x"
16 | },
17 | "L1CustomGateway": {
18 | "proxyAddress": "0xcEe284F754E854890e311e3280b767F80797180d",
19 | "implAddress": "0xc5199b28d5267f80a7fa7a3313357d50cf4dba6c",
20 | "implDeploymentTxn": "0x",
21 | "implArbitrumCommitHash": "0x"
22 | },
23 | "L1WethGateway": {
24 | "proxyAddress": "0xd92023E9d9911199a6711321D1277285e6d4e2db",
25 | "implAddress": "0xb0e292c2cefd5c897883f16af6453dc111940d85",
26 | "implDeploymentTxn": "0x",
27 | "implArbitrumCommitHash": "0x"
28 | }
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/_deployments/1337_queued-updates.json:
--------------------------------------------------------------------------------
1 | {}
2 |
--------------------------------------------------------------------------------
/_deployments/1_42170_current_deployment.json:
--------------------------------------------------------------------------------
1 | {
2 | "proxyAdminAddress": "0xa8f7DdEd54a726eB873E98bFF2C95ABF2d03e560",
3 | "contracts": {
4 | "L1GatewayRouter": {
5 | "proxyAddress": "0xC840838Bc438d73C16c2f8b22D2Ce3669963cD48",
6 | "implAddress": "0x6D1c576Fe3e54313990450f5Fa322306B4cCB47B",
7 | "implDeploymentTxn": "0x0badea7ff78ffcaee80d8b3686debf2f3172a65aa4df26de5aaccc58bc7a6031",
8 | "implArbitrumCommitHash": "265b5ef6a68f4e6c5d891d61b4c733634e49ac74",
9 | "implBuildInfo": ""
10 | },
11 | "L1ERC20Gateway": {
12 | "proxyAddress": "0xB2535b988dcE19f9D71dfB22dB6da744aCac21bf",
13 | "implAddress": "0xb4299A1F5f26fF6a98B7BA35572290C359fde900",
14 | "implDeploymentTxn": "0x23b0939cffff711071c3270fd7c1e619fd6f464acfbb07ae452f4f091eb0af90",
15 | "implArbitrumCommitHash": "265b5ef6a68f4e6c5d891d61b4c733634e49ac74",
16 | "implBuildInfo": ""
17 | },
18 | "L1CustomGateway": {
19 | "proxyAddress": "0x23122da8C581AA7E0d07A36Ff1f16F799650232f",
20 | "implAddress": "0xC8D26aB9e132C79140b3376a0Ac7932E4680Aa45",
21 | "implDeploymentTxn": "0xd6ae3ba8c58ef4fa22688950c4849085779b0db441d3d68d84cdca5618e0e565",
22 | "implArbitrumCommitHash": "265b5ef6a68f4e6c5d891d61b4c733634e49ac74",
23 | "implBuildInfo": ""
24 | },
25 | "L1WethGateway": {
26 | "proxyAddress": "0xE4E2121b479017955Be0b175305B35f312330BaE",
27 | "implAddress": "0x4B8e9b3F253E68837bf719997B1eeB9E8f1960e2",
28 | "implDeploymentTxn": "0xab2fe7d6a85987ba63986267209e1a7b4b1347c6075230f23c8e6d18aaa1a6b3",
29 | "implArbitrumCommitHash": "dce646c6890ab9c7c91c7d2ec70b4d83fa359a76",
30 | "implBuildInfo": ""
31 | }
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/_deployments/1_42170_queued-updates.json:
--------------------------------------------------------------------------------
1 | {
2 | "L1GatewayRouter": {
3 | "address": "0x52595021fA01B3E14EC6C88953AFc8E35dFf423c",
4 | "deployTxn": "0x2a6dd507b21d4257c8afd00f2590cb5765e29eb371d2b6b2f9a173328b9f2e53",
5 | "arbitrumCommitHash": "162e913442e766b3bcc17e3e62886477313325ac",
6 | "buildInfo": ""
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/_deployments/1_current_deployment.json:
--------------------------------------------------------------------------------
1 | {
2 | "proxyAdminAddress": "0x9aD46fac0Cf7f790E5be05A0F15223935A0c0aDa",
3 | "contracts": {
4 | "L1GatewayRouter": {
5 | "proxyAddress": "0x72Ce9c846789fdB6fC1f34aC4AD25Dd9ef7031ef",
6 | "implAddress": "0x6D1c576Fe3e54313990450f5Fa322306B4cCB47B",
7 | "implDeploymentTxn": "0x0badea7ff78ffcaee80d8b3686debf2f3172a65aa4df26de5aaccc58bc7a6031",
8 | "implArbitrumCommitHash": "265b5ef6a68f4e6c5d891d61b4c733634e49ac74",
9 | "implBuildInfo": ""
10 | },
11 | "L1ERC20Gateway": {
12 | "proxyAddress": "0xa3A7B6F88361F48403514059F1F16C8E78d60EeC",
13 | "implAddress": "0xb4299A1F5f26fF6a98B7BA35572290C359fde900",
14 | "implDeploymentTxn": "0x23b0939cffff711071c3270fd7c1e619fd6f464acfbb07ae452f4f091eb0af90",
15 | "implArbitrumCommitHash": "265b5ef6a68f4e6c5d891d61b4c733634e49ac74",
16 | "implBuildInfo": ""
17 | },
18 | "L1CustomGateway": {
19 | "proxyAddress": "0xcEe284F754E854890e311e3280b767F80797180d",
20 | "implAddress": "0xC8D26aB9e132C79140b3376a0Ac7932E4680Aa45",
21 | "implDeploymentTxn": "0xd6ae3ba8c58ef4fa22688950c4849085779b0db441d3d68d84cdca5618e0e565",
22 | "implArbitrumCommitHash": "265b5ef6a68f4e6c5d891d61b4c733634e49ac74",
23 | "implBuildInfo": ""
24 | },
25 | "L1WethGateway": {
26 | "proxyAddress": "0xd92023E9d9911199a6711321D1277285e6d4e2db",
27 | "implAddress": "0x4B8e9b3F253E68837bf719997B1eeB9E8f1960e2",
28 | "implDeploymentTxn": "0xab2fe7d6a85987ba63986267209e1a7b4b1347c6075230f23c8e6d18aaa1a6b3",
29 | "implArbitrumCommitHash": "dce646c6890ab9c7c91c7d2ec70b4d83fa359a76",
30 | "implBuildInfo": ""
31 | }
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/_deployments/1_queued-updates.json:
--------------------------------------------------------------------------------
1 | {}
2 |
--------------------------------------------------------------------------------
/_deployments/421611_current_deployment.json:
--------------------------------------------------------------------------------
1 | {
2 | "proxyAdminAddress": "0x58816566EB91815Cc07f3Ad5230eE0820fe1A19a",
3 | "contracts": {
4 | "L2GatewayRouter": {
5 | "proxyAddress": "0x9413AD42910c1eA60c737dB5f58d1C504498a3cD",
6 | "implAddress": "0x9BB136adEa1E3dd0B132CAd18d69Ee444aC17bFd",
7 | "implDeploymentTxn": "0xa660838e693561d61189e9ca831d118171509fefdac3ae257c0e422dcc61bcfc",
8 | "implArbitrumCommitHash": "25bf76e8cdd9b00bc181269abcc9b04579a42aca",
9 | "implBuildInfo": ""
10 | },
11 | "L2ERC20Gateway": {
12 | "proxyAddress": "0x195C107F3F75c4C93Eba7d9a1312F19305d6375f",
13 | "implAddress": "0x5574f6Cd9de0F9D224cE85e1cD6C4Be11132A385",
14 | "implDeploymentTxn": "0xd1e86b6a6162b50fc16f4ae47fd4cbc8d4dce4421a5e9f0ac18c3af49aa0c7da",
15 | "implArbitrumCommitHash": "25bf76e8cdd9b00bc181269abcc9b04579a42aca",
16 | "implBuildInfo": ""
17 | },
18 | "L2CustomGateway": {
19 | "proxyAddress": "0x9b014455AcC2Fe90c52803849d0002aeEC184a06",
20 | "implAddress": "0x02F95dFAc9B67EdCD9158c04fe30d114A013d08D",
21 | "implDeploymentTxn": "0x4603823d126f5f78f228d2d3431a01d93a082b75e2e3ff2fb7d754c7b5789506",
22 | "implArbitrumCommitHash": "25bf76e8cdd9b00bc181269abcc9b04579a42aca",
23 | "implBuildInfo": ""
24 | },
25 | "L2WethGateway": {
26 | "proxyAddress": "0xf94bc045c4E926CC0b34e8D1c41Cd7a043304ac9",
27 | "implAddress": "0x675a824f4B940c747caC35DA0CC3f7E441419942",
28 | "implDeploymentTxn": "0x74f56f704a64a0b87306eb9a6480420ea137d043bf4d12c8e9fb490864bb0584",
29 | "implArbitrumCommitHash": "25bf76e8cdd9b00bc181269abcc9b04579a42aca",
30 | "implBuildInfo": ""
31 | },
32 | "StandardArbERC20": {
33 | "proxyAddress": "0x86B4b312140B4117A7b0D252eC53Fa6D0753fE85",
34 | "implAddress": "0xa5a052BC1dc55118754bca1bB700675Edf1031D0",
35 | "implDeploymentTxn": "",
36 | "implBuildInfo": ""
37 | }
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/_deployments/421611_queued-updates.json:
--------------------------------------------------------------------------------
1 | {}
2 |
--------------------------------------------------------------------------------
/_deployments/421613_current_deployment.json:
--------------------------------------------------------------------------------
1 | {
2 | "proxyAdminAddress": "0xeC377B42712608B0356CC54Da81B2be1A4982bAb",
3 | "contracts": {
4 | "L2GatewayRouter": {
5 | "proxyAddress": "0xE5B9d8d42d656d1DcB8065A6c012FE3780246041",
6 | "implAddress": "0xa707480046b0Bd1C602CCd1D83FCf7Bd367217E2",
7 | "implDeploymentTxn": "0x3c2adecca82c874282a694a23faec77ae02cd3a19a17527855554fd77d93e4a9",
8 | "implArbitrumCommitHash": "25bf76e8cdd9b00bc181269abcc9b04579a42aca",
9 | "implBuildInfo": ""
10 | },
11 | "L2ERC20Gateway": {
12 | "proxyAddress": "0x2eC7Bc552CE8E51f098325D2FcF0d3b9d3d2A9a2",
13 | "implAddress": "0xCbD2dC47b287C8324747A5AA2A71A8f939662B3e",
14 | "implDeploymentTxn": "0x07c3734dd047f99ce9955d694517f2fa0b73def14bd46215847a747accb49702",
15 | "implArbitrumCommitHash": "25bf76e8cdd9b00bc181269abcc9b04579a42aca",
16 | "implBuildInfo": ""
17 | },
18 | "L2CustomGateway": {
19 | "proxyAddress": "0x8b6990830cF135318f75182487A4D7698549C717",
20 | "implAddress": "0x43f7637f712Dca8544539Aa399FDC9697c7965e9",
21 | "implDeploymentTxn": "0x306a01a6164915f923b8ea6f5c1f512783f5c2e67e4d6b613029a26bc3623eca",
22 | "implArbitrumCommitHash": "6f61e3aaf3668ad564139f49063028b1b19010bd",
23 | "implBuildInfo": ""
24 | },
25 | "L2WethGateway": {
26 | "proxyAddress": "0xf9F2e89c8347BD96742Cc07095dee490e64301d6",
27 | "implAddress": "0x3BD10e97ECa83B362dA291beFdA0f1ba70D31411",
28 | "implDeploymentTxn": "0xe35957e6aef4d5919b8d7d93ff1b575dd5c50aa3b3dc944be07ac913d46a2846",
29 | "implArbitrumCommitHash": "25bf76e8cdd9b00bc181269abcc9b04579a42aca",
30 | "implBuildInfo": ""
31 | },
32 | "StandardArbERC20": {
33 | "proxyAddress": "0xC0EaEeeb3Bb716ef3e49c2db0331e5bCaAb88865",
34 | "implAddress": "0x2063a7def7614347896c880C0F04788De18A8dEb",
35 | "implDeploymentTxn": "0x7ccdf95b0c6e46d12bfaac47f14343e3c227ad70f03625108e7c300339c63d5e",
36 | "implArbitrumCommitHash": "51dfc9fbe45a0d66c4fcad6ac645386eb50e528a",
37 | "implBuildInfo": ""
38 | }
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/_deployments/421613_queued-updates.json:
--------------------------------------------------------------------------------
1 | {}
2 |
--------------------------------------------------------------------------------
/_deployments/421614_current_deployment.json:
--------------------------------------------------------------------------------
1 | {
2 | "proxyAdminAddress": "0x715D99480b77A8d9D603638e593a539E21345FdF",
3 | "contracts": {
4 | "L2GatewayRouter": {
5 | "proxyAddress": "0x9fDD1C4E4AA24EEc1d913FABea925594a20d43C7",
6 | "implAddress": "0x6f1ef246894b6269e2a98c741c36385f61ee1e32",
7 | "implDeploymentTxn": "0x8ca7e1fbfdae7f5069cc61454efee4bb6b70b8e5a3a831ed49deb7fbbcdf5dc7",
8 | "implArbitrumCommitHash": "using-sdk-731092406",
9 | "implBuildInfo": ""
10 | },
11 | "L2ERC20Gateway": {
12 | "proxyAddress": "0x6e244cD02BBB8a6dbd7F626f05B2ef82151Ab502",
13 | "implAddress": "0x391c9b3cb3cae0a653295f42267dab8b0505e760",
14 | "implDeploymentTxn": "0xb90ab1d2f5ddba546747d298c5e2e99635c9ab94cc157baf7e7fa54c8f194e23",
15 | "implArbitrumCommitHash": "using-sdk-731092406",
16 | "implBuildInfo": ""
17 | },
18 | "L2CustomGateway": {
19 | "proxyAddress": "0x8Ca1e1AC0f260BC4dA7Dd60aCA6CA66208E642C5",
20 | "implAddress": "0xa0a8537a683b49ba4bbe23883d984d4684e0acdd",
21 | "implDeploymentTxn": "0xd47badc672d5173a7c66bb2e2c92fcc4c8c98a27dc30e762f10cd0a73e460eee",
22 | "implArbitrumCommitHash": "using-sdk-731092406",
23 | "implBuildInfo": ""
24 | },
25 | "L2WethGateway": {
26 | "proxyAddress": "0xCFB1f08A4852699a979909e22c30263ca249556D",
27 | "implAddress": "0x572c749de059f5cb5659ba5c1b4576b237871af4",
28 | "implDeploymentTxn": "0x59fc99d7a7df30b432948933ba0bf5108b47df2c99d52a1fda4fd9acf46549ad",
29 | "implArbitrumCommitHash": "using-sdk-731092406",
30 | "implBuildInfo": ""
31 | },
32 | "StandardArbERC20": {
33 | "proxyAddress": "0x07ad36d1911da7116f97cbe7c94bc567834c2a09",
34 | "implAddress": "0xdbb3566cd49e221023cff6e710c2e5e50cb8f832",
35 | "implDeploymentTxn": "0xcda2277668a347c1a063af4fcffe18ed3c99337a86f390c18009fd29d1bbf59c",
36 | "implArbitrumCommitHash": "using-sdk-731092406",
37 | "implBuildInfo": ""
38 | }
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/_deployments/421614_queued-updates.json:
--------------------------------------------------------------------------------
1 | {}
2 |
--------------------------------------------------------------------------------
/_deployments/42161_current_deployment.json:
--------------------------------------------------------------------------------
1 | {
2 | "proxyAdminAddress": "0xd570aCE65C43af47101fC6250FD6fC63D1c22a86",
3 | "contracts": {
4 | "L2GatewayRouter": {
5 | "proxyAddress": "0x5288c571Fd7aD117beA99bF60FE0846C4E84F933",
6 | "implAddress": "0xe80eb0238029333e368e0bDDB7acDf1b9cb28278",
7 | "implDeploymentTxn": "0x42f97c8e518193c04c8aba7b71b08e1c05257070c71b8f5796c4c6fe885a4009",
8 | "implArbitrumCommitHash": "265b5ef6a68f4e6c5d891d61b4c733634e49ac74",
9 | "implBuildInfo": ""
10 | },
11 | "L2ERC20Gateway": {
12 | "proxyAddress": "0x09e9222E96E7B4AE2a407B98d48e330053351EEe",
13 | "implAddress": "0x1DCf7D03574fbC7C205F41f2e116eE094a652e93",
14 | "implDeploymentTxn": "0x386a8c3b2f12d91644faef8483d13c36e283bb23cb2e05ee946474d7383834d9",
15 | "implArbitrumCommitHash": "265b5ef6a68f4e6c5d891d61b4c733634e49ac74",
16 | "implBuildInfo": ""
17 | },
18 | "L2CustomGateway": {
19 | "proxyAddress": "0x096760F208390250649E3e8763348E783AEF5562",
20 | "implAddress": "0x190274fEa8f30e3f48CE43aDCBd9a74110118284",
21 | "implDeploymentTxn": "0x55fc2f66a593e317c7cebcc90d43ef465f64158ce0866af30ff5d471155e75d2",
22 | "implArbitrumCommitHash": "6f61e3aaf3668ad564139f49063028b1b19010bd",
23 | "implBuildInfo": ""
24 | },
25 | "L2WethGateway": {
26 | "proxyAddress": "0x6c411aD3E74De3E7Bd422b94A27770f5B86C623B",
27 | "implAddress": "0x806421D09cDb253aa9d128a658e60c0B95eFFA01",
28 | "implDeploymentTxn": "0xb52586177829d7cb06ca5204994eb63e3ee8245ef8a331e5dc466cba9aa9e35d",
29 | "implArbitrumCommitHash": "dce646c6890ab9c7c91c7d2ec70b4d83fa359a76",
30 | "implBuildInfo": ""
31 | },
32 | "StandardArbERC20": {
33 | "proxyAddress": "0xE72ba9418b5f2Ce0A6a40501Fe77c6839Aa37333",
34 | "implAddress": "0x3f770Ac673856F105b586bb393d122721265aD46",
35 | "implDeploymentTxn": "0xc7006f7e9f716a73ecee7e2939adacf84a122345dca581ed1f78c06be5cd8a5a",
36 | "implArbitrumCommitHash": "7ac9347a41ece951af883d435cbe7d8e84329e36",
37 | "implBuildInfo": ""
38 | }
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/_deployments/42161_queued-updates.json:
--------------------------------------------------------------------------------
1 | {}
2 |
--------------------------------------------------------------------------------
/_deployments/42170_current_deployment.json:
--------------------------------------------------------------------------------
1 | {
2 | "proxyAdminAddress": "0xada790b026097BfB36a5ed696859b97a96CEd92C",
3 | "contracts": {
4 | "L2GatewayRouter": {
5 | "proxyAddress": "0x21903d3F8176b1a0c17E953Cd896610Be9fFDFa8",
6 | "implAddress": "0x8f377770289863DF73Fe665B74460579F82321fb",
7 | "implDeploymentTxn": "0x8c917e27e5aeff1f9f2ae781efc24c4ee3502550f4fd6d451af09756a9fbeb41",
8 | "implArbitrumCommitHash": "265b5ef6a68f4e6c5d891d61b4c733634e49ac74",
9 | "implBuildInfo": ""
10 | },
11 | "L2ERC20Gateway": {
12 | "proxyAddress": "0xcF9bAb7e53DDe48A6DC4f286CB14e05298799257",
13 | "implAddress": "0x466155FD6d8BbF1c0d5ca32818814cB28b6884d8",
14 | "implDeploymentTxn": "0x3d949fdeb42a3ebb04b705358ab5f8559cffbc27d7fbaf3a63649d12e327d592",
15 | "implArbitrumCommitHash": "265b5ef6a68f4e6c5d891d61b4c733634e49ac74",
16 | "implBuildInfo": ""
17 | },
18 | "L2CustomGateway": {
19 | "proxyAddress": "0xbf544970E6BD77b21C6492C281AB60d0770451F4",
20 | "implAddress": "0x554e12DBAa0fBeB8A35583a6Fd9D04BaA4ff597f",
21 | "implDeploymentTxn": "0x62e1143aea4034c75503f6f46722df4871962dc08c69f709c97885b3a7f44008",
22 | "implArbitrumCommitHash": "6f61e3aaf3668ad564139f49063028b1b19010bd",
23 | "implBuildInfo": ""
24 | },
25 | "L2WethGateway": {
26 | "proxyAddress": "0x7626841cB6113412F9c88D3ADC720C9FAC88D9eD",
27 | "implAddress": "0xbe04Ab2728c924D678f9FC833E379688c6eFA317",
28 | "implDeploymentTxn": "0x99333784813d8bcfc7ccc34b7cf258deccec9d160afce25c89a9faf0a1a19a92",
29 | "implArbitrumCommitHash": "dce646c6890ab9c7c91c7d2ec70b4d83fa359a76",
30 | "implBuildInfo": ""
31 | },
32 | "StandardArbERC20": {
33 | "proxyAddress": "0xd31Ed16a8CeCe0A5070AC26024674eB680E3e639",
34 | "implAddress": "0x53923A0d1f4805463584c91b2E55d6c600A94E91",
35 | "implDeploymentTxn": "0x96513ab528683b13d918024d0c410ecaa88b7949cc4a980544af8362f22cc277",
36 | "implArbitrumCommitHash": "51dfc9fbe45a0d66c4fcad6ac645386eb50e528a",
37 | "implBuildInfo": ""
38 | }
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/_deployments/42170_queued-updates.json:
--------------------------------------------------------------------------------
1 | {}
2 |
--------------------------------------------------------------------------------
/_deployments/4_current_deployment.json:
--------------------------------------------------------------------------------
1 | {
2 | "proxyAdminAddress": "0x0DbAF24efA2bc9Dd1a6c0530DD252BCcF883B89A",
3 | "contracts": {
4 | "L1GatewayRouter": {
5 | "proxyAddress": "0x70C143928eCfFaf9F5b406f7f4fC28Dc43d68380",
6 | "implAddress": "0x8b6990830cF135318f75182487A4D7698549C717",
7 | "implDeploymentTxn": "0xee36d85905a0ef010d85f2d023f30dd8cb91eccba755256ede147d6b3f29e8f9",
8 | "implArbitrumCommitHash": "25bf76e8cdd9b00bc181269abcc9b04579a42aca",
9 | "implBuildInfo": ""
10 | },
11 | "L1ERC20Gateway": {
12 | "proxyAddress": "0x91169Dbb45e6804743F94609De50D511C437572E",
13 | "implAddress": "0x185ff5e33c4df31C715B386916A49fc2f80fFe4c",
14 | "implDeploymentTxn": "0x041673dd25b9dbc4a831b0ee4d795563ecd67e21c3b3fe58d07d17698b44df4b",
15 | "implArbitrumCommitHash": "25bf76e8cdd9b00bc181269abcc9b04579a42aca",
16 | "implBuildInfo": ""
17 | },
18 | "L1CustomGateway": {
19 | "proxyAddress": "0x917dc9a69F65dC3082D518192cd3725E1Fa96cA2",
20 | "implAddress": "0xf9F2e89c8347BD96742Cc07095dee490e64301d6",
21 | "implDeploymentTxn": "0xae2522d1fe13f69007fc63869fb8640f69e2ad59df599e284bb39e0ee2f5627e",
22 | "implArbitrumCommitHash": "25bf76e8cdd9b00bc181269abcc9b04579a42aca",
23 | "implBuildInfo": ""
24 | },
25 | "L1WethGateway": {
26 | "proxyAddress": "0x81d1a19cf7071732D4313c75dE8DD5b8CF697eFD",
27 | "implAddress": "0x2063a7def7614347896c880C0F04788De18A8dEb",
28 | "implDeploymentTxn": "0x45078b798a2f6b9cdcd8a98fc1a8c145b278ee9da56ea5d9f12ea9117b94a153",
29 | "implArbitrumCommitHash": "25bf76e8cdd9b00bc181269abcc9b04579a42aca",
30 | "implBuildInfo": ""
31 | }
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/_deployments/4_queued-updates.json:
--------------------------------------------------------------------------------
1 | {}
2 |
--------------------------------------------------------------------------------
/_deployments/5_current_deployment.json:
--------------------------------------------------------------------------------
1 | {
2 | "proxyAdminAddress": "0x16101A84B00344221E2983190718bFAba30D9CeE",
3 | "contracts": {
4 | "L1GatewayRouter": {
5 | "proxyAddress": "0x4c7708168395aEa569453Fc36862D2ffcDaC588c",
6 | "implAddress": "0x5664F1f04bb9f5eF1970D6e12Be073F73AacA854",
7 | "implDeploymentTxn": "0xde3262b207e171ee9ef342aed0d631adc8e23e5783079d7a8a2803fe0ad8b01f",
8 | "implArbitrumCommitHash": "25bf76e8cdd9b00bc181269abcc9b04579a42aca",
9 | "implBuildInfo": ""
10 | },
11 | "L1ERC20Gateway": {
12 | "proxyAddress": "0x715D99480b77A8d9D603638e593a539E21345FdF",
13 | "implAddress": "0xea066056f73156E80090C24ADAC5d47CEc313a2d",
14 | "implDeploymentTxn": "0x02c5ed6eec83e3cc015373f85cb2ca89826d66bf3f5b7caf91d79c4ae561a38f",
15 | "implArbitrumCommitHash": "25bf76e8cdd9b00bc181269abcc9b04579a42aca",
16 | "implBuildInfo": ""
17 | },
18 | "L1CustomGateway": {
19 | "proxyAddress": "0x9fDD1C4E4AA24EEc1d913FABea925594a20d43C7",
20 | "implAddress": "0x161183c42E54F709Bd7b8c12670957f2Ee150299",
21 | "implDeploymentTxn": "0xb071c5c0153295e0c7e177a3d9d9f770206a305680e3461e16b9c92202f8f219",
22 | "implArbitrumCommitHash": "25bf76e8cdd9b00bc181269abcc9b04579a42aca",
23 | "implBuildInfo": ""
24 | },
25 | "L1WethGateway": {
26 | "proxyAddress": "0x6e244cD02BBB8a6dbd7F626f05B2ef82151Ab502",
27 | "implAddress": "0xAA82b5384ef36c5EFdCe36300dc1E85CA45ad1D8",
28 | "implDeploymentTxn": "0x2c349a6110c697aebb2fb0a74c71ec78f04b94ec608443052b61e802420de4b9",
29 | "implArbitrumCommitHash": "25bf76e8cdd9b00bc181269abcc9b04579a42aca",
30 | "implBuildInfo": ""
31 | }
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/_deployments/5_queued-updates.json:
--------------------------------------------------------------------------------
1 | {}
2 |
--------------------------------------------------------------------------------
/audits/ConsenSys_Diligence_Arbitrum_Contracts_11_2021.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OffchainLabs/token-bridge-contracts/5bdf33259d2d9ae52ddc69bc5a9cbc558c4c40c7/audits/ConsenSys_Diligence_Arbitrum_Contracts_11_2021.pdf
--------------------------------------------------------------------------------
/audits/trail_of_bits_governance_report_1_6_2023.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OffchainLabs/token-bridge-contracts/5bdf33259d2d9ae52ddc69bc5a9cbc558c4c40c7/audits/trail_of_bits_governance_report_1_6_2023.pdf
--------------------------------------------------------------------------------
/contracts/rpc-utils/NodeInterface.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: Apache-2.0
2 | // solhint-disable-next-line compiler-version
3 | pragma solidity >=0.4.21 <0.9.0;
4 |
5 | /** @title Interface for providing Outbox proof data
6 | * @notice This contract doesn't exist on-chain. Instead it is a virtual interface accessible at 0x00000000000000000000000000000000000000C8
7 | * This is a cute trick to allow an Arbitrum node to provide data without us having to implement an additional RPC )
8 | */
9 |
10 | interface NodeInterface {
11 | /**
12 | * @notice Returns the proof necessary to redeem a message
13 | * @param batchNum index of outbox entry (i.e., outgoing messages Merkle root) in array of outbox entries
14 | * @param index index of outgoing message in outbox entry
15 | * @return proof Merkle proof of message inclusion in outbox entry
16 | * @return path Merkle path to message
17 | * @return l2Sender sender if original message (i.e., caller of ArbSys.sendTxToL1)
18 | * @return l1Dest destination address for L1 contract call
19 | * @return l2Block l2 block number at which sendTxToL1 call was made
20 | * @return l1Block l1 block number at which sendTxToL1 call was made
21 | * @return timestamp l2 Timestamp at which sendTxToL1 call was made
22 | * @return amount value in L1 message in wei
23 | * @return calldataForL1 abi-encoded L1 message data
24 | */
25 | function lookupMessageBatchProof(uint256 batchNum, uint64 index)
26 | external
27 | view
28 | returns (
29 | bytes32[] memory proof,
30 | uint256 path,
31 | address l2Sender,
32 | address l1Dest,
33 | uint256 l2Block,
34 | uint256 l1Block,
35 | uint256 timestamp,
36 | uint256 amount,
37 | bytes memory calldataForL1
38 | );
39 |
40 | /**
41 | * @notice Estimate the cost of putting a message in the L2 inbox that is reexecuted
42 | * @param sender sender of the L1 and L2 transaction
43 | * @param deposit amount to deposit to sender in L2
44 | * @param destAddr destination L2 contract address
45 | * @param l2CallValue call value for retryable L2 message
46 | * @param maxSubmissionCost Max gas deducted from user's L2 balance to cover base submission fee
47 | * @param excessFeeRefundAddress maxgas x gasprice - execution cost gets credited here on L2 balance
48 | * @param callValueRefundAddress l2Callvalue gets credited here on L2 if retryable txn times out or gets cancelled
49 | * @param maxGas Max gas deducted from user's L2 balance to cover L2 execution
50 | * @param gasPriceBid price bid for L2 execution
51 | * @param data ABI encoded data of L2 message
52 | * @return gas used, and gas price to execute this transaction
53 | */
54 | function estimateRetryableTicket(
55 | address sender,
56 | uint256 deposit,
57 | address destAddr,
58 | uint256 l2CallValue,
59 | uint256 maxSubmissionCost,
60 | address excessFeeRefundAddress,
61 | address callValueRefundAddress,
62 | uint256 maxGas,
63 | uint256 gasPriceBid,
64 | bytes calldata data
65 | ) external pure returns (uint256, uint256);
66 | }
67 |
--------------------------------------------------------------------------------
/contracts/rpc-utils/RetryableTicketCreator.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: Apache-2.0
2 | // solhint-disable-next-line compiler-version
3 | pragma solidity >=0.4.21 <0.9.0;
4 |
5 | interface RetryableTicketCreator {
6 | /**
7 | @notice Put an message in the L2 inbox that can be reexecuted for some fixed amount of time if it reverts
8 | * @dev all msg.value will deposited to callValueRefundAddress on L2
9 | * @param destAddr destination L2 contract address
10 | * @param l2CallValue call value for retryable L2 message
11 | * @param maxSubmissionCost Max gas deducted from user's L2 balance to cover base submission fee
12 | * @param excessFeeRefundAddress maxgas x gasprice - execution cost gets credited here on L2 balance
13 | * @param callValueRefundAddress l2Callvalue gets credited here on L2 if retryable txn times out or gets cancelled
14 | * @param maxGas Max gas deducted from user's L2 balance to cover L2 execution
15 | * @param gasPriceBid price bid for L2 execution
16 | * @param data ABI encoded data of L2 message
17 | */
18 | function createRetryableTicket(
19 | address destAddr,
20 | uint256 l2CallValue,
21 | uint256 maxSubmissionCost,
22 | address excessFeeRefundAddress,
23 | address callValueRefundAddress,
24 | uint256 maxGas,
25 | uint256 gasPriceBid,
26 | bytes calldata data
27 | ) external payable;
28 | }
29 |
--------------------------------------------------------------------------------
/contracts/tokenbridge/arbitrum/IArbToken.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: Apache-2.0
2 |
3 | /*
4 | * Copyright 2020, 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 | /**
20 | * @title Minimum expected interface for L2 token that interacts with the L2 token bridge (this is the interface necessary
21 | * for a custom token that interacts with the bridge, see TestArbCustomToken.sol for an example implementation).
22 | * @dev For the token to be compatible out of the box with the tooling available (e.g., the Arbitrum bridge), it is
23 | * recommended to keep the implementation of this interface as close as possible to the `TestArbCustomToken` example.
24 | */
25 |
26 | // solhint-disable-next-line compiler-version
27 | pragma solidity >=0.6.9 <0.9.0;
28 |
29 | interface IArbToken {
30 | /**
31 | * @notice should increase token supply by amount, and should (probably) only be callable by the L1 bridge.
32 | */
33 | function bridgeMint(address account, uint256 amount) external;
34 |
35 | /**
36 | * @notice should decrease token supply by amount, and should (probably) only be callable by the L1 bridge.
37 | */
38 | function bridgeBurn(address account, uint256 amount) external;
39 |
40 | /**
41 | * @return address of layer 1 token
42 | */
43 | function l1Address() external view returns (address);
44 | }
45 |
--------------------------------------------------------------------------------
/contracts/tokenbridge/arbitrum/L2ArbitrumMessenger.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: Apache-2.0
2 |
3 | /*
4 | * Copyright 2020, 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.0;
20 |
21 | import "@arbitrum/nitro-contracts/src/precompiles/ArbSys.sol";
22 |
23 | /// @notice L2 utility contract to assist with L1 <=> L2 interactions
24 | /// @dev this is an abstract contract instead of library so the functions can be easily overriden when testing
25 | abstract contract L2ArbitrumMessenger {
26 | address internal constant ARB_SYS_ADDRESS = address(100);
27 |
28 | event TxToL1(address indexed _from, address indexed _to, uint256 indexed _id, bytes _data);
29 |
30 | function sendTxToL1(
31 | uint256 _l1CallValue,
32 | address _from,
33 | address _to,
34 | bytes memory _data
35 | ) internal returns (uint256) {
36 | uint256 _id = ArbSys(ARB_SYS_ADDRESS).sendTxToL1{ value: _l1CallValue }(_to, _data);
37 | emit TxToL1(_from, _to, _id, _data);
38 | return _id;
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/contracts/tokenbridge/arbitrum/ReverseArbToken.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: Apache-2.0
2 |
3 | /*
4 | * Copyright 2020, 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 | // solhint-disable-next-line compiler-version
20 | pragma solidity >=0.6.9 <0.9.0;
21 |
22 | import "./IArbToken.sol";
23 |
24 | /// @title Minimum expected interface for L2 token that interacts with the reverse L2 token bridge (this is the interface necessary
25 | /// for a custom token that interacts with the reverse gateway, see TestArbCustomToken.sol for an example implementation).
26 | /// @dev The L2ArbitrumGateway expects objects of type IArbToken, which includes
27 | /// bridgeMint/burn. However when the L2ReverseCustomGateway overrides the functions
28 | /// that make use of bridgeMint/burn and replaces them with safeTransfer/from.
29 | /// We inherit IArbToken so that we fulfil the interface L2ArbitrumGateway expects
30 | /// but since we know that bridgeMint/burn won't/shouldn't be used we override these
31 | /// functions to ensure that if they throw if called during development
32 | abstract contract ReverseArbToken is IArbToken {
33 | function bridgeMint(address, uint256) public override {
34 | revert("BRIDGE_MINT_NOT_IMPLEMENTED");
35 | }
36 |
37 | function bridgeBurn(address, uint256) public override {
38 | revert("BRIDGE_BURN_NOT_IMPLEMENTED");
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/contracts/tokenbridge/arbitrum/gateway/L2CustomGateway.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: Apache-2.0
2 |
3 | /*
4 | * Copyright 2020, 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.0;
20 |
21 | import "./L2ArbitrumGateway.sol";
22 | import "../../libraries/gateway/ICustomGateway.sol";
23 | import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
24 |
25 | contract L2CustomGateway is L2ArbitrumGateway, ICustomGateway {
26 | // stores addresses of L2 tokens to be used
27 | mapping(address => address) public override l1ToL2Token;
28 |
29 | function initialize(address _l1Counterpart, address _router) public {
30 | L2ArbitrumGateway._initialize(_l1Counterpart, _router);
31 | }
32 |
33 | /**
34 | * @notice internal utility function used to handle when no contract is deployed at expected address
35 | */
36 | function handleNoContract(
37 | address _l1Token,
38 | address, /* expectedL2Address */
39 | address _from,
40 | address, /* _to */
41 | uint256 _amount,
42 | bytes memory /* gatewayData */
43 | ) internal override returns (bool shouldHalt) {
44 | // it is assumed that the custom token is deployed in the L2 before deposits are made
45 | // trigger withdrawal
46 | // we don't need the return value from triggerWithdrawal since this is forcing a withdrawal back to the L1
47 | // instead of composing with a L2 dapp
48 | triggerWithdrawal(_l1Token, address(this), _from, _amount, "");
49 | return true;
50 | }
51 |
52 | /**
53 | * @notice Calculate the address used when bridging an ERC20 token
54 | * @dev the L1 and L2 address oracles may not always be in sync.
55 | * For example, a custom token may have been registered but not deploy or the contract self destructed.
56 | * @param l1ERC20 address of L1 token
57 | * @return L2 address of a bridged ERC20 token
58 | */
59 | function calculateL2TokenAddress(address l1ERC20) public view override returns (address) {
60 | return l1ToL2Token[l1ERC20];
61 | }
62 |
63 | function registerTokenFromL1(address[] calldata l1Address, address[] calldata l2Address)
64 | external
65 | onlyCounterpartGateway
66 | {
67 | // we assume both arrays are the same length, safe since its encoded by the L1
68 | for (uint256 i = 0; i < l1Address.length; i++) {
69 | // here we don't check if l2Address is a contract and instead deal with that behaviour
70 | // in `handleNoContract` this way we keep the l1 and l2 address oracles in sync
71 | l1ToL2Token[l1Address[i]] = l2Address[i];
72 | emit TokenSet(l1Address[i], l2Address[i]);
73 | }
74 | }
75 | }
76 |
--------------------------------------------------------------------------------
/contracts/tokenbridge/arbitrum/gateway/L2ERC20Gateway.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: Apache-2.0
2 |
3 | /*
4 | * Copyright 2020, 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.0;
20 |
21 | import "@openzeppelin/contracts/proxy/beacon/UpgradeableBeacon.sol";
22 | import "@openzeppelin/contracts/utils/Create2.sol";
23 | import "./L2ArbitrumGateway.sol";
24 | import "../StandardArbERC20.sol";
25 | import "../../libraries/ClonableBeaconProxy.sol";
26 |
27 | contract L2ERC20Gateway is L2ArbitrumGateway {
28 | address public beaconProxyFactory;
29 |
30 | function initialize(
31 | address _l1Counterpart,
32 | address _router,
33 | address _beaconProxyFactory
34 | ) public {
35 | L2ArbitrumGateway._initialize(_l1Counterpart, _router);
36 | require(_beaconProxyFactory != address(0), "INVALID_BEACON");
37 | beaconProxyFactory = _beaconProxyFactory;
38 | }
39 |
40 | /**
41 | * @notice Calculate the address used when bridging an ERC20 token
42 | * @dev the L1 and L2 address oracles may not always be in sync.
43 | * For example, a custom token may have been registered but not deploy or the contract self destructed.
44 | * @param l1ERC20 address of L1 token
45 | * @return L2 address of a bridged ERC20 token
46 | */
47 | function calculateL2TokenAddress(address l1ERC20)
48 | public
49 | view
50 | virtual
51 | override
52 | returns (address)
53 | {
54 | // this method is marked virtual to be overriden in subclasses used in testing
55 | return
56 | BeaconProxyFactory(beaconProxyFactory).calculateExpectedAddress(
57 | address(this),
58 | getUserSalt(l1ERC20)
59 | );
60 | }
61 |
62 | function cloneableProxyHash() public view returns (bytes32) {
63 | return BeaconProxyFactory(beaconProxyFactory).cloneableProxyHash();
64 | }
65 |
66 | function getUserSalt(address l1ERC20) public pure returns (bytes32) {
67 | return keccak256(abi.encode(l1ERC20));
68 | }
69 |
70 | /**
71 | * @notice internal utility function used to deploy ERC20 tokens with the beacon proxy pattern.
72 | * @dev the transparent proxy implementation by OpenZeppelin can't be used if we want to be able to
73 | * upgrade the token logic.
74 | * @param l1ERC20 L1 address of ERC20
75 | * @param expectedL2Address L2 address of ERC20
76 | * @param deployData encoded symbol/name/decimal data for initial deploy
77 | */
78 | function handleNoContract(
79 | address l1ERC20,
80 | address expectedL2Address,
81 | address _from,
82 | address, /* _to */
83 | uint256 _amount,
84 | bytes memory deployData
85 | ) internal override returns (bool shouldHalt) {
86 | bytes32 userSalt = getUserSalt(l1ERC20);
87 | address createdContract = BeaconProxyFactory(beaconProxyFactory).createProxy(userSalt);
88 |
89 | StandardArbERC20(createdContract).bridgeInit(l1ERC20, deployData);
90 |
91 | if (createdContract == expectedL2Address) {
92 | return false;
93 | } else {
94 | // trigger withdrawal then halt
95 | // this codepath should only be hit if the system is setup incorrectly
96 | // this withdrawal is for error recovery, not composing with L2 dapps, so we ignore the return value
97 | triggerWithdrawal(l1ERC20, address(this), _from, _amount, "");
98 | return true;
99 | }
100 | }
101 | }
102 |
--------------------------------------------------------------------------------
/contracts/tokenbridge/arbitrum/gateway/L2GatewayRouter.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: Apache-2.0
2 |
3 | /*
4 | * Copyright 2020, 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.0;
20 |
21 | import "../../libraries/gateway/GatewayRouter.sol";
22 | import "../../ethereum/gateway/L1GatewayRouter.sol";
23 | import "../L2ArbitrumMessenger.sol";
24 | import "../../libraries/AddressAliasHelper.sol";
25 |
26 | /**
27 | * @title Handles withdrawals from Ethereum into Arbitrum. Tokens are routered to their appropriate L2 gateway (Router itself also conforms to the Gateway interface).
28 | * @notice Router also serves as an L2-L1 token address oracle.
29 | */
30 | contract L2GatewayRouter is GatewayRouter, L2ArbitrumMessenger {
31 | modifier onlyCounterpartGateway() override {
32 | require(
33 | msg.sender == AddressAliasHelper.applyL1ToL2Alias(counterpartGateway),
34 | "ONLY_COUNTERPART_GATEWAY"
35 | );
36 | _;
37 | }
38 |
39 | function initialize(address _counterpartGateway, address _defaultGateway) public {
40 | GatewayRouter._initialize(_counterpartGateway, address(0), _defaultGateway);
41 | }
42 |
43 | function setGateway(address[] memory _l1Token, address[] memory _gateway)
44 | external
45 | onlyCounterpartGateway
46 | {
47 | // counterpart gateway (L1 router) should never allow wrong lengths
48 | assert(_l1Token.length == _gateway.length);
49 |
50 | for (uint256 i = 0; i < _l1Token.length; i++) {
51 | l1TokenToGateway[_l1Token[i]] = _gateway[i];
52 | emit GatewaySet(_l1Token[i], _gateway[i]);
53 | }
54 | }
55 |
56 | function outboundTransfer(
57 | address _l1Token,
58 | address _to,
59 | uint256 _amount,
60 | bytes calldata _data
61 | ) public payable returns (bytes memory) {
62 | return outboundTransfer(_l1Token, _to, _amount, 0, 0, _data);
63 | }
64 |
65 | function setDefaultGateway(address newL2DefaultGateway) external onlyCounterpartGateway {
66 | defaultGateway = newL2DefaultGateway;
67 | emit DefaultGatewayUpdated(newL2DefaultGateway);
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/contracts/tokenbridge/arbitrum/gateway/L2ReverseCustomGateway.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: Apache-2.0
2 |
3 | /*
4 | * Copyright 2020, 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.0;
20 |
21 | import "./L2CustomGateway.sol";
22 | import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
23 |
24 | /**
25 | * @title L2 Gateway for reverse "custom" bridging functionality
26 | * @notice Handles some (but not all!) reverse custom Gateway needs.
27 | * Use the reverse custom gateway instead of the normal custom
28 | * gateway if you want total supply to be tracked on the L2
29 | * rather than the L1.
30 | * @dev The reverse custom gateway burns on the l2 and escrows on the l1
31 | * which is the opposite of the way the normal custom gateway works
32 | * This means that the total supply L2 isn't affected by briding, which
33 | * is helpful for obeservers calculating the total supply especially if
34 | * if minting is also occuring on L2
35 | */
36 | contract L2ReverseCustomGateway is L2CustomGateway {
37 | using SafeERC20 for IERC20;
38 |
39 | function inboundEscrowTransfer(
40 | address _l2Token,
41 | address _dest,
42 | uint256 _amount
43 | ) internal virtual override {
44 | IERC20(_l2Token).safeTransfer(_dest, _amount);
45 | }
46 |
47 | function outboundEscrowTransfer(
48 | address _l2Token,
49 | address _from,
50 | uint256 _amount
51 | ) internal override returns (uint256) {
52 | uint256 prevBalance = IERC20(_l2Token).balanceOf(address(this));
53 | // as in the normal custom gateway, in the reverse custom gateway we check
54 | // for the balances of tokens to ensure that inflationary / deflationary changes in the amount
55 | // are taken into account we ignore the return value since we actually query the token before
56 | // and after to calculate the amount of tokens that were transferred
57 | IERC20(_l2Token).safeTransferFrom(_from, address(this), _amount);
58 | uint256 postBalance = IERC20(_l2Token).balanceOf(address(this));
59 | return postBalance - prevBalance;
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/contracts/tokenbridge/arbitrum/gateway/L2WethGateway.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: Apache-2.0
2 |
3 | /*
4 | * Copyright 2020, 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.0;
20 |
21 | import "./L2ArbitrumGateway.sol";
22 | import "../../libraries/IWETH9.sol";
23 | import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
24 | import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
25 |
26 | contract L2WethGateway is L2ArbitrumGateway {
27 | using SafeERC20 for IERC20;
28 |
29 | address public l1Weth;
30 | address public l2Weth;
31 |
32 | function initialize(
33 | address _l1Counterpart,
34 | address _router,
35 | address _l1Weth,
36 | address _l2Weth
37 | ) public {
38 | L2ArbitrumGateway._initialize(_l1Counterpart, _router);
39 | require(_l1Weth != address(0), "INVALID_L1WETH");
40 | require(_l2Weth != address(0), "INVALID_L2WETH");
41 | l1Weth = _l1Weth;
42 | l2Weth = _l2Weth;
43 | }
44 |
45 | /**
46 | * @notice internal utility function used to handle when no contract is deployed at expected address
47 | * @param l1ERC20 L1 address of ERC20
48 | */
49 | function handleNoContract(
50 | address l1ERC20,
51 | address, /* expectedL2Address */
52 | address _from,
53 | address, /* _to */
54 | uint256 _amount,
55 | bytes memory /* deployData */
56 | ) internal override returns (bool shouldHalt) {
57 | // it is assumed that the custom token is deployed in the L2 before deposits are made
58 | // trigger withdrawal
59 | // this codepath should only be hit if the system is setup incorrectly
60 | // this withdrawal is for error recovery, not composing with L2 dapps, so we ignore the return value
61 | triggerWithdrawal(l1ERC20, address(this), _from, _amount, "");
62 | return true;
63 | }
64 |
65 | /**
66 | * @notice Calculate the address used when bridging an ERC20 token
67 | * @dev the L1 and L2 address oracles may not always be in sync.
68 | * For example, a custom token may have been registered but not deploy or the contract self destructed.
69 | * @param l1ERC20 address of L1 token
70 | * @return L2 address of a bridged ERC20 token
71 | */
72 | function calculateL2TokenAddress(address l1ERC20) public view override returns (address) {
73 | if (l1ERC20 != l1Weth) {
74 | // invalid L1 weth address
75 | return address(0);
76 | }
77 | return l2Weth;
78 | }
79 |
80 | function inboundEscrowTransfer(
81 | address _l2TokenAddress,
82 | address _dest,
83 | uint256 _amount
84 | ) internal override {
85 | IWETH9(_l2TokenAddress).deposit{ value: _amount }();
86 | IERC20(_l2TokenAddress).safeTransfer(_dest, _amount);
87 | }
88 |
89 | function createOutboundTx(
90 | address _from,
91 | uint256 _tokenAmount,
92 | bytes memory _outboundCalldata
93 | ) internal override returns (uint256) {
94 | // exitNum incremented after being included in _outboundCalldata
95 | exitNum++;
96 | return
97 | sendTxToL1(
98 | // we send the amount of weth withdrawn as callvalue to the L1 gateway
99 | _tokenAmount,
100 | _from,
101 | counterpartGateway,
102 | _outboundCalldata
103 | );
104 | }
105 |
106 | receive() external payable {}
107 | }
108 |
--------------------------------------------------------------------------------
/contracts/tokenbridge/ethereum/ICustomToken.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: Apache-2.0
2 |
3 | /*
4 | * Copyright 2020, 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 | // solhint-disable-next-line compiler-version
20 | pragma solidity >=0.6.9 <0.9.0;
21 |
22 | interface ArbitrumEnabledToken {
23 | /// @notice should return `0xb1` if token is enabled for arbitrum gateways
24 | /// @dev Previous implmentation used to return `uint8(0xa4b1)`, however that causes compile time error in Solidity 0.8. due to type mismatch.
25 | /// In current version `uint8(0xb1)` shall be returned, which results in no change as that's the same value as truncated `uint8(0xa4b1)`.
26 | function isArbitrumEnabled() external view returns (uint8);
27 | }
28 |
29 | /**
30 | * @title Minimum expected interface for L1 custom token (see TestCustomTokenL1.sol for an example implementation)
31 | */
32 | interface ICustomToken is ArbitrumEnabledToken {
33 | /**
34 | * @notice Should make an external call to EthERC20Bridge.registerCustomL2Token
35 | */
36 | function registerTokenOnL2(
37 | address l2CustomTokenAddress,
38 | uint256 maxSubmissionCostForCustomBridge,
39 | uint256 maxSubmissionCostForRouter,
40 | uint256 maxGasForCustomBridge,
41 | uint256 maxGasForRouter,
42 | uint256 gasPriceBid,
43 | uint256 valueForGateway,
44 | uint256 valueForRouter,
45 | address creditBackAddress
46 | ) external payable;
47 |
48 | function transferFrom(
49 | address sender,
50 | address recipient,
51 | uint256 amount
52 | ) external returns (bool);
53 |
54 | function balanceOf(address account) external view returns (uint256);
55 | }
56 |
57 | interface L1MintableToken is ICustomToken {
58 | function bridgeMint(address account, uint256 amount) external;
59 | }
60 |
61 | interface L1ReverseToken is L1MintableToken {
62 | function bridgeBurn(address account, uint256 amount) external;
63 | }
64 |
--------------------------------------------------------------------------------
/contracts/tokenbridge/ethereum/gateway/IL1ArbitrumGateway.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: Apache-2.0
2 |
3 | /*
4 | * Copyright 2020, 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 | // solhint-disable-next-line compiler-version
20 | pragma solidity >=0.6.9 <0.9.0;
21 |
22 | import "../../libraries/gateway/ITokenGateway.sol";
23 | import "../../libraries/IERC165.sol";
24 |
25 | /**
26 | * @title Common interface for gatways on L1 messaging to Arbitrum.
27 | */
28 | interface IL1ArbitrumGateway is ITokenGateway, IERC165 {
29 | function inbox() external view returns (address);
30 |
31 | /**
32 | * @notice Deposit ERC20 token from Ethereum into Arbitrum. If L2 side hasn't been deployed yet, includes name/symbol/decimals data for initial L2 deploy. Initiate by GatewayRouter.
33 | * @dev L2 address alias will not be applied to the following types of addresses on L1:
34 | * - an externally-owned account
35 | * - a contract in construction
36 | * - an address where a contract will be created
37 | * - an address where a contract lived, but was destroyed
38 | * @param _l1Token L1 address of ERC20
39 | * @param _refundTo Account, or its L2 alias if it have code in L1, to be credited with excess gas refund in L2
40 | * @param _to Account to be credited with the tokens in the L2 (can be the user's L2 account or a contract), not subject to L2 aliasing
41 | This account, or its L2 alias if it have code in L1, will also be able to cancel the retryable ticket and receive callvalue refund
42 | * @param _amount Token Amount
43 | * @param _maxGas Max gas deducted from user's L2 balance to cover L2 execution
44 | * @param _gasPriceBid Gas price for L2 execution
45 | * @param _data encoded data from router and user
46 | * @return res abi encoded inbox sequence number
47 | */
48 | // * @param maxSubmissionCost Max gas deducted from user's L2 balance to cover base submission fee
49 | function outboundTransferCustomRefund(
50 | address _l1Token,
51 | address _refundTo,
52 | address _to,
53 | uint256 _amount,
54 | uint256 _maxGas,
55 | uint256 _gasPriceBid,
56 | bytes calldata _data
57 | ) external payable returns (bytes memory);
58 | }
59 |
--------------------------------------------------------------------------------
/contracts/tokenbridge/ethereum/gateway/L1ForceOnlyReverseCustomGateway.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: Apache-2.0
2 |
3 | /*
4 | * Copyright 2020, 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.0;
20 |
21 | import "./L1ReverseCustomGateway.sol";
22 |
23 | /**
24 | * @title An L1 Reverse gateway which only allows force registration
25 | */
26 | contract L1ForceOnlyReverseCustomGateway is L1ReverseCustomGateway {
27 | function registerTokenToL2(
28 | address _l2Address,
29 | uint256 _maxGas,
30 | uint256 _gasPriceBid,
31 | uint256 _maxSubmissionCost,
32 | address _creditBackAddress
33 | ) public payable virtual override returns (uint256) {
34 | revert("REGISTER_TOKEN_ON_L2_DISABLED");
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/contracts/tokenbridge/ethereum/gateway/L1OrbitReverseCustomGateway.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: Apache-2.0
2 |
3 | pragma solidity ^0.8.0;
4 |
5 | import { L1OrbitCustomGateway } from "./L1OrbitCustomGateway.sol";
6 | import { IArbToken } from "../../arbitrum/IArbToken.sol";
7 |
8 | /**
9 | * @title L1 Gateway for reverse "custom" bridging functionality in an ERC20-based rollup.
10 | * @notice Handles some (but not all!) reverse custom Gateway needs.
11 | * Use the reverse custom gateway instead of the normal custom
12 | * gateway if you want total supply to be tracked on the L2
13 | * rather than the L1.
14 | * @dev The reverse custom gateway burns on the l2 and escrows on the l1
15 | * which is the opposite of the way the normal custom gateway works
16 | * This means that the total supply L2 isn't affected by bridging, which
17 | * is helpful for observers calculating the total supply especially if
18 | * if minting is also occuring on L2
19 | */
20 | contract L1OrbitReverseCustomGateway is L1OrbitCustomGateway {
21 | function inboundEscrowTransfer(
22 | address _l1Address,
23 | address _dest,
24 | uint256 _amount
25 | ) internal virtual override {
26 | IArbToken(_l1Address).bridgeMint(_dest, _amount);
27 | }
28 |
29 | function outboundEscrowTransfer(
30 | address _l1Token,
31 | address _from,
32 | uint256 _amount
33 | ) internal override returns (uint256) {
34 | IArbToken(_l1Token).bridgeBurn(_from, _amount);
35 | // by default we assume that the amount we send to bridgeBurn is the amount burnt
36 | // this might not be the case for every token
37 | return _amount;
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/contracts/tokenbridge/ethereum/gateway/L1ReverseCustomGateway.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: Apache-2.0
2 |
3 | /*
4 | * Copyright 2020, 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.0;
20 |
21 | import "./L1CustomGateway.sol";
22 | import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
23 |
24 | /**
25 | * @title L1 Gateway for reverse "custom" bridging functionality
26 | * @notice Handles some (but not all!) reverse custom Gateway needs.
27 | * Use the reverse custom gateway instead of the normal custom
28 | * gateway if you want total supply to be tracked on the L2
29 | * rather than the L1.
30 | * @dev The reverse custom gateway burns on the l2 and escrows on the l1
31 | * which is the opposite of the way the normal custom gateway works
32 | * This means that the total supply L2 isn't affected by briding, which
33 | * is helpful for observers calculating the total supply especially if
34 | * if minting is also occuring on L2
35 | */
36 | contract L1ReverseCustomGateway is L1CustomGateway {
37 | function inboundEscrowTransfer(
38 | address _l1Address,
39 | address _dest,
40 | uint256 _amount
41 | ) internal virtual override {
42 | IArbToken(_l1Address).bridgeMint(_dest, _amount);
43 | }
44 |
45 | function outboundEscrowTransfer(
46 | address _l1Token,
47 | address _from,
48 | uint256 _amount
49 | ) internal override returns (uint256) {
50 | IArbToken(_l1Token).bridgeBurn(_from, _amount);
51 | // by default we assume that the amount we send to bridgeBurn is the amount burnt
52 | // this might not be the case for every token
53 | return _amount;
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/contracts/tokenbridge/libraries/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.0;
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/tokenbridge/libraries/BytesLib.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: MIT
2 |
3 | /*
4 | * @title Solidity Bytes Arrays Utils
5 | * @author Gonçalo Sá
6 | *
7 | * @dev Bytes tightly packed arrays utility library for ethereum contracts written in Solidity.
8 | * The library lets you concatenate, slice and type cast bytes arrays both in memory and storage.
9 | */
10 |
11 | pragma solidity ^0.8.0;
12 |
13 | /* solhint-disable no-inline-assembly */
14 | library BytesLib {
15 | function toAddress(bytes memory _bytes, uint256 _start) internal pure returns (address) {
16 | require(_bytes.length >= (_start + 20), "Read out of bounds");
17 | address tempAddress;
18 |
19 | assembly {
20 | tempAddress := div(mload(add(add(_bytes, 0x20), _start)), 0x1000000000000000000000000)
21 | }
22 |
23 | return tempAddress;
24 | }
25 |
26 | function toUint8(bytes memory _bytes, uint256 _start) internal pure returns (uint8) {
27 | require(_bytes.length >= (_start + 1), "Read out of bounds");
28 | uint8 tempUint;
29 |
30 | assembly {
31 | tempUint := mload(add(add(_bytes, 0x1), _start))
32 | }
33 |
34 | return tempUint;
35 | }
36 |
37 | function toUint(bytes memory _bytes, uint256 _start) internal pure returns (uint256) {
38 | require(_bytes.length >= (_start + 32), "Read out of bounds");
39 | uint256 tempUint;
40 |
41 | assembly {
42 | tempUint := mload(add(add(_bytes, 0x20), _start))
43 | }
44 |
45 | return tempUint;
46 | }
47 |
48 | function toBytes32(bytes memory _bytes, uint256 _start) internal pure returns (bytes32) {
49 | require(_bytes.length >= (_start + 32), "Read out of bounds");
50 | bytes32 tempBytes32;
51 |
52 | assembly {
53 | tempBytes32 := mload(add(add(_bytes, 0x20), _start))
54 | }
55 |
56 | return tempBytes32;
57 | }
58 | }
59 | /* solhint-enable no-inline-assembly */
60 |
--------------------------------------------------------------------------------
/contracts/tokenbridge/libraries/BytesParser.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: Apache-2.0
2 |
3 | /*
4 | * Copyright 2020, 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.0;
20 |
21 | import "./BytesLib.sol";
22 |
23 | library BytesParser {
24 | using BytesLib for bytes;
25 |
26 | function toUint8(bytes memory input) internal pure returns (bool success, uint8 res) {
27 | if (input.length != 32) {
28 | return (false, 0);
29 | }
30 | // TODO: try catch to handle error
31 | uint256 inputNum = abi.decode(input, (uint256));
32 | if (inputNum > type(uint8).max) {
33 | return (false, 0);
34 | }
35 | res = uint8(inputNum);
36 | success = true;
37 | }
38 |
39 | function toString(bytes memory input) internal pure returns (bool success, string memory res) {
40 | if (input.length == 0) {
41 | success = false;
42 | // return default value of string
43 | } else if (input.length == 32) {
44 | // TODO: can validate anything other than length and being null terminated?
45 | if (input[31] != bytes1(0x00)) return (false, res);
46 | else success = true;
47 |
48 | // here we assume its a null terminated Bytes32 string
49 | // https://github.com/ethereum/solidity/blob/5852972ec148bc041909400affc778dee66d384d/test/libsolidity/semanticTests/externalContracts/_stringutils/stringutils.sol#L89
50 | // https://github.com/Arachnid/solidity-stringutils
51 | uint256 len = 32;
52 | while (len > 0 && input[len - 1] == bytes1(0x00)) {
53 | len--;
54 | }
55 |
56 | bytes memory inputTruncated = new bytes(len);
57 | for (uint8 i = 0; i < len; i++) {
58 | inputTruncated[i] = input[i];
59 | }
60 | // we can't just do `res := input` because of the null values in the end
61 | // TODO: can we instead use a bitwise AND? build it dynamically with the length
62 | assembly {
63 | res := inputTruncated
64 | }
65 | } else {
66 | // TODO: try catch to handle error
67 | success = true;
68 | res = abi.decode(input, (string));
69 | }
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/contracts/tokenbridge/libraries/ClonableBeaconProxy.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: Apache-2.0
2 | // solhint-disable-next-line compiler-version
3 | pragma solidity >=0.6.0 <0.9.0;
4 |
5 | import "@openzeppelin/contracts/proxy/beacon/BeaconProxy.sol";
6 | import "@openzeppelin/contracts/proxy/beacon/UpgradeableBeacon.sol";
7 | import "@openzeppelin/contracts/utils/Create2.sol";
8 |
9 | interface ProxySetter {
10 | function beacon() external view returns (address);
11 | }
12 |
13 | contract ClonableBeaconProxy is BeaconProxy {
14 | constructor() BeaconProxy(ProxySetter(msg.sender).beacon(), "") {}
15 | }
16 |
17 | contract BeaconProxyFactory is ProxySetter {
18 | bytes32 public constant cloneableProxyHash = keccak256(type(ClonableBeaconProxy).creationCode);
19 |
20 | /**
21 | * @notice utility function used in ClonableBeaconProxy.
22 | * @dev this method makes it possible to use ClonableBeaconProxy.creationCode without encoding constructor parameters
23 | * @return the beacon to be used by the proxy contract.
24 | */
25 | address public override beacon;
26 |
27 | function initialize(address _beacon) external {
28 | require(_beacon != address(0), "INVALID_BEACON");
29 | require(beacon == address(0), "ALREADY_INIT");
30 | beacon = _beacon;
31 | }
32 |
33 | function getSalt(address user, bytes32 userSalt) public pure returns (bytes32) {
34 | return keccak256(abi.encode(user, userSalt));
35 | }
36 |
37 | function createProxy(bytes32 userSalt) external returns (address) {
38 | // deployment will fail and this function will revert if contract `salt` is not unique
39 | bytes32 salt = getSalt(msg.sender, userSalt);
40 | address createdContract = address(new ClonableBeaconProxy{ salt: salt }());
41 | return createdContract;
42 | }
43 |
44 | function calculateExpectedAddress(address user, bytes32 userSalt)
45 | public
46 | view
47 | returns (address)
48 | {
49 | bytes32 salt = getSalt(user, userSalt);
50 | return Create2.computeAddress(salt, cloneableProxyHash, address(this));
51 | }
52 |
53 | function calculateExpectedAddress(bytes32 salt) public view returns (address) {
54 | return Create2.computeAddress(salt, cloneableProxyHash, address(this));
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/contracts/tokenbridge/libraries/Cloneable.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: Apache-2.0
2 |
3 | /*
4 | * Copyright 2019-2020, 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.0;
20 |
21 | import "./ICloneable.sol";
22 |
23 | contract Cloneable is ICloneable {
24 | string private constant NOT_CLONE = "NOT_CLONE";
25 |
26 | bool private isMasterCopy;
27 |
28 | constructor() {
29 | isMasterCopy = true;
30 | }
31 |
32 | function isMaster() external view override returns (bool) {
33 | return isMasterCopy;
34 | }
35 |
36 | function safeSelfDestruct(address payable dest) internal {
37 | require(!isMasterCopy, NOT_CLONE);
38 | selfdestruct(dest);
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/contracts/tokenbridge/libraries/CreationCodeHelper.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: Apache-2.0
2 | pragma solidity ^0.8.0;
3 |
4 | library CreationCodeHelper {
5 | /**
6 | * @notice Generate a creation code that results with a contract with `code` as deployed code.
7 | * Generated creation code shall match the one generated by Solidity compiler with an empty constructor.
8 | * @dev Prepended constructor bytecode consists of:
9 | * - 608060405234801561001057600080fd5b50 - store free memory pointer, then check no callvalue is provided
10 | * - 61xxxx - push 2 bytes of `code` length
11 | * - 806100206000396000f3fe - copy deployed code to memory and return the location of it
12 | * @param runtimeCode Deployed bytecode to which constructor bytecode will be prepended
13 | * @return Creation code of a new contract
14 | */
15 | function getCreationCodeFor(bytes memory runtimeCode) internal pure returns (bytes memory) {
16 | return abi.encodePacked(
17 | hex"608060405234801561001057600080fd5b50",
18 | hex"61",
19 | uint16(runtimeCode.length),
20 | hex"806100206000396000f3fe",
21 | runtimeCode
22 | );
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/contracts/tokenbridge/libraries/ERC165.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: MIT
2 | // OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)
3 |
4 | // With pragma modification to support ^0.6.11
5 | // https://github.com/OpenZeppelin/openzeppelin-contracts/blob/release-v4.6/contracts/utils/introspection/ERC165.sol
6 |
7 | pragma solidity ^0.8.0;
8 |
9 | import "./IERC165.sol";
10 |
11 | /**
12 | * @dev Implementation of the {IERC165} interface.
13 | *
14 | * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check
15 | * for the additional interface id that will be supported. For example:
16 | *
17 | * ```solidity
18 | * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
19 | * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);
20 | * }
21 | * ```
22 | *
23 | * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.
24 | */
25 | abstract contract ERC165 is IERC165 {
26 | /**
27 | * @dev See {IERC165-supportsInterface}.
28 | */
29 | function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
30 | return interfaceId == type(IERC165).interfaceId;
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/contracts/tokenbridge/libraries/ICloneable.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: Apache-2.0
2 |
3 | /*
4 | * Copyright 2019, 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 | // solhint-disable-next-line compiler-version
20 | pragma solidity >=0.6.9 <0.9.0;
21 |
22 | interface ICloneable {
23 | function isMaster() external view returns (bool);
24 | }
25 |
--------------------------------------------------------------------------------
/contracts/tokenbridge/libraries/IERC165.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: MIT
2 | // OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)
3 |
4 | // With pragma modification to allow interface compatibility with >=0.6.9 <0.9.0
5 | // https://github.com/OpenZeppelin/openzeppelin-contracts/blob/release-v4.6/contracts/utils/introspection/IERC165.sol
6 |
7 | // solhint-disable-next-line compiler-version
8 | pragma solidity >=0.6.9 <0.9.0;
9 |
10 | /**
11 | * @dev Interface of the ERC165 standard, as defined in the
12 | * https://eips.ethereum.org/EIPS/eip-165[EIP].
13 | *
14 | * Implementers can declare support of contract interfaces, which can then be
15 | * queried by others ({ERC165Checker}).
16 | *
17 | * For an implementation, see {ERC165}.
18 | */
19 | interface IERC165 {
20 | /**
21 | * @dev Returns true if this contract implements the interface defined by
22 | * `interfaceId`. See the corresponding
23 | * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]
24 | * to learn more about how these ids are created.
25 | *
26 | * This function call must use less than 30 000 gas.
27 | */
28 | function supportsInterface(bytes4 interfaceId) external view returns (bool);
29 | }
30 |
--------------------------------------------------------------------------------
/contracts/tokenbridge/libraries/IERC20Bridge.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: Apache-2.0
2 |
3 | // solhint-disable-next-line compiler-version
4 | pragma solidity >=0.6.9 <0.9.0;
5 |
6 | interface IERC20Bridge {
7 | /**
8 | * @dev token that is escrowed in bridge on L1 side and minted on L2 as native currency. Also fees are paid in this token.
9 | */
10 | function nativeToken() external view returns (address);
11 | }
12 |
--------------------------------------------------------------------------------
/contracts/tokenbridge/libraries/ITransferAndCall.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: MIT
2 | // solhint-disable-next-line compiler-version
3 | pragma solidity >0.6.0 <0.9.0;
4 |
5 | import "@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol";
6 |
7 | interface ITransferAndCall is IERC20Upgradeable {
8 | function transferAndCall(
9 | address to,
10 | uint256 value,
11 | bytes memory data
12 | ) external returns (bool success);
13 |
14 | event Transfer(address indexed from, address indexed to, uint256 value, bytes data);
15 | }
16 |
17 | /**
18 | * @notice note that implementation of ITransferAndCallReceiver is not expected to return a success bool
19 | */
20 | interface ITransferAndCallReceiver {
21 | function onTokenTransfer(
22 | address _sender,
23 | uint256 _value,
24 | bytes memory _data
25 | ) external;
26 | }
27 |
--------------------------------------------------------------------------------
/contracts/tokenbridge/libraries/IWETH9.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: Apache-2.0
2 |
3 | // solhint-disable-next-line compiler-version
4 | pragma solidity >=0.6.9 <0.9.0;
5 |
6 | interface IWETH9 {
7 | function deposit() external payable;
8 |
9 | function withdraw(uint256 _amount) external;
10 | }
11 |
--------------------------------------------------------------------------------
/contracts/tokenbridge/libraries/L2CustomGatewayToken.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: Apache-2.0
2 |
3 | /*
4 | * Copyright 2020, 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.0;
20 |
21 | import "./L2GatewayToken.sol";
22 |
23 | /**
24 | * @title A basic custom token contract that can be used with the custom gateway
25 | */
26 | contract L2CustomGatewayToken is L2GatewayToken {
27 | /**
28 | * @notice initialize the token
29 | * @dev the L2 bridge assumes this does not fail or revert
30 | * @param name_ ERC20 token name
31 | * @param symbol_ ERC20 token symbol
32 | * @param decimals_ ERC20 decimals
33 | * @param l2Gateway_ L2 gateway this token communicates with
34 | * @param l1Counterpart_ L1 address of ERC20
35 | */
36 | function initialize(
37 | string memory name_,
38 | string memory symbol_,
39 | uint8 decimals_,
40 | address l2Gateway_,
41 | address l1Counterpart_
42 | ) public virtual initializer {
43 | _initialize(name_, symbol_, decimals_, l2Gateway_, l1Counterpart_);
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/contracts/tokenbridge/libraries/L2GatewayToken.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: Apache-2.0
2 |
3 | /*
4 | * Copyright 2020, 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.0;
20 |
21 | import "./aeERC20.sol";
22 | import "./BytesParser.sol";
23 | import "../arbitrum/IArbToken.sol";
24 |
25 | /**
26 | * @title Standard (i.e., non-custom) contract used as a base for different L2 Gateways
27 | */
28 | abstract contract L2GatewayToken is aeERC20, IArbToken {
29 | address public l2Gateway;
30 | address public override l1Address;
31 |
32 | modifier onlyGateway() {
33 | require(msg.sender == l2Gateway, "ONLY_GATEWAY");
34 | _;
35 | }
36 |
37 | /**
38 | * @notice initialize the token
39 | * @dev the L2 bridge assumes this does not fail or revert
40 | * @param name_ ERC20 token name
41 | * @param symbol_ ERC20 token symbol
42 | * @param decimals_ ERC20 decimals
43 | * @param l2Gateway_ L2 gateway this token communicates with
44 | * @param l1Counterpart_ L1 address of ERC20
45 | */
46 | function _initialize(
47 | string memory name_,
48 | string memory symbol_,
49 | uint8 decimals_,
50 | address l2Gateway_,
51 | address l1Counterpart_
52 | ) internal virtual {
53 | require(l2Gateway_ != address(0), "INVALID_GATEWAY");
54 | require(l2Gateway == address(0), "ALREADY_INIT");
55 | l2Gateway = l2Gateway_;
56 | l1Address = l1Counterpart_;
57 |
58 | aeERC20._initialize(name_, symbol_, decimals_);
59 | }
60 |
61 | /**
62 | * @notice Mint tokens on L2. Callable path is L1Gateway depositToken (which handles L1 escrow), which triggers L2Gateway, which calls this
63 | * @param account recipient of tokens
64 | * @param amount amount of tokens minted
65 | */
66 | function bridgeMint(address account, uint256 amount) external virtual override onlyGateway {
67 | _mint(account, amount);
68 | }
69 |
70 | /**
71 | * @notice Burn tokens on L2.
72 | * @dev only the token bridge can call this
73 | * @param account owner of tokens
74 | * @param amount amount of tokens burnt
75 | */
76 | function bridgeBurn(address account, uint256 amount) external virtual override onlyGateway {
77 | _burn(account, amount);
78 | }
79 | }
80 |
--------------------------------------------------------------------------------
/contracts/tokenbridge/libraries/ProxyUtil.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: Apache-2.0
2 |
3 | /*
4 | * Copyright 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.0;
20 |
21 | library ProxyUtil {
22 | function getProxyAdmin() internal view returns (address admin) {
23 | // https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v3.4.0/contracts/proxy/TransparentUpgradeableProxy.sol#L48
24 | // Storage slot with the admin of the proxy contract.
25 | // This is the keccak-256 hash of "eip1967.proxy.admin" subtracted by 1, and is
26 | bytes32 slot = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;
27 | assembly {
28 | admin := sload(slot)
29 | }
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/contracts/tokenbridge/libraries/TransferAndCallToken.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: MIT
2 | // solhint-disable-next-line compiler-version
3 | pragma solidity >0.6.0 <0.9.0;
4 |
5 | import "./ERC20Upgradeable.sol";
6 | import "./ITransferAndCall.sol";
7 |
8 | // Implementation from https://github.com/smartcontractkit/LinkToken/blob/master/contracts/v0.6/TransferAndCallToken.sol
9 | /**
10 | * @notice based on Implementation from https://github.com/smartcontractkit/LinkToken/blob/master/contracts/v0.6/ERC677Token.sol
11 | * The implementation doesn't return a bool on onTokenTransfer. This is similar to the proposed 677 standard, but still incompatible - thus we don't refer to it as such.
12 | */
13 | abstract contract TransferAndCallToken is ERC20Upgradeable, ITransferAndCall {
14 | /**
15 | * @dev transfer token to a contract address with additional data if the recipient is a contact.
16 | * @param _to The address to transfer to.
17 | * @param _value The amount to be transferred.
18 | * @param _data The extra data to be passed to the receiving contract.
19 | */
20 | function transferAndCall(
21 | address _to,
22 | uint256 _value,
23 | bytes memory _data
24 | ) public virtual override returns (bool success) {
25 | super.transfer(_to, _value);
26 | emit Transfer(msg.sender, _to, _value, _data);
27 | if (isContract(_to)) {
28 | contractFallback(_to, _value, _data);
29 | }
30 | return true;
31 | }
32 |
33 | // PRIVATE
34 |
35 | function contractFallback(
36 | address _to,
37 | uint256 _value,
38 | bytes memory _data
39 | ) private {
40 | ITransferAndCallReceiver receiver = ITransferAndCallReceiver(_to);
41 | receiver.onTokenTransfer(msg.sender, _value, _data);
42 | }
43 |
44 | function isContract(address _addr) private view returns (bool hasCode) {
45 | uint256 length;
46 | assembly {
47 | length := extcodesize(_addr)
48 | }
49 | return length > 0;
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/contracts/tokenbridge/libraries/Whitelist.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: Apache-2.0
2 |
3 | /*
4 | * Copyright 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.0;
20 |
21 | abstract contract WhitelistConsumer {
22 | address public whitelist;
23 |
24 | event WhitelistSourceUpdated(address newSource);
25 |
26 | modifier onlyWhitelisted() {
27 | if (whitelist != address(0)) {
28 | require(Whitelist(whitelist).isAllowed(msg.sender), "NOT_WHITELISTED");
29 | }
30 | _;
31 | }
32 |
33 | function updateWhitelistSource(address newSource) external {
34 | require(msg.sender == whitelist, "NOT_FROM_LIST");
35 | whitelist = newSource;
36 | emit WhitelistSourceUpdated(newSource);
37 | }
38 | }
39 |
40 | contract Whitelist {
41 | address public owner;
42 | mapping(address => bool) public isAllowed;
43 |
44 | event OwnerUpdated(address newOwner);
45 | event WhitelistUpgraded(address newWhitelist, address[] targets);
46 |
47 | constructor() {
48 | owner = msg.sender;
49 | }
50 |
51 | modifier onlyOwner() {
52 | require(msg.sender == owner, "ONLY_OWNER");
53 | _;
54 | }
55 |
56 | function setOwner(address newOwner) external onlyOwner {
57 | owner = newOwner;
58 | emit OwnerUpdated(newOwner);
59 | }
60 |
61 | function setWhitelist(address[] memory user, bool[] memory val) external onlyOwner {
62 | require(user.length == val.length, "INVALID_INPUT");
63 |
64 | for (uint256 i = 0; i < user.length; i++) {
65 | isAllowed[user[i]] = val[i];
66 | }
67 | }
68 |
69 | // set new whitelist to address(0) to disable whitelist
70 | function triggerConsumers(address newWhitelist, address[] memory targets) external onlyOwner {
71 | for (uint256 i = 0; i < targets.length; i++) {
72 | WhitelistConsumer(targets[i]).updateWhitelistSource(newWhitelist);
73 | }
74 | emit WhitelistUpgraded(newWhitelist, targets);
75 | }
76 | }
77 |
--------------------------------------------------------------------------------
/contracts/tokenbridge/libraries/aeERC20.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: Apache-2.0
2 |
3 | /*
4 | * Copyright 2020, 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.0;
20 |
21 | import "../libraries/draft-ERC20PermitUpgradeable.sol";
22 | import "./TransferAndCallToken.sol";
23 |
24 | /// @title Arbitrum extended ERC20
25 | /// @notice The recommended ERC20 implementation for Layer 2 tokens
26 | /// @dev This implements the ERC20 standard with transferAndCall extenstion/affordances
27 | contract aeERC20 is ERC20PermitUpgradeable, TransferAndCallToken {
28 | using AddressUpgradeable for address;
29 |
30 | constructor() initializer {
31 | // this is expected to be used as the logic contract behind a proxy
32 | // override the constructor if you don't wish to use the initialize method
33 | }
34 |
35 | function _initialize(
36 | string memory name_,
37 | string memory symbol_,
38 | uint8 decimals_
39 | ) internal initializer {
40 | __ERC20Permit_init(name_);
41 | __ERC20_init(name_, symbol_);
42 | _setupDecimals(decimals_);
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/contracts/tokenbridge/libraries/aeWETH.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: Apache-2.0
2 |
3 | /*
4 | * Copyright 2020, 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.0;
20 |
21 | import "./L2GatewayToken.sol";
22 | import "./IWETH9.sol";
23 |
24 | /// @title Arbitrum extended WETH
25 | contract aeWETH is L2GatewayToken, IWETH9 {
26 | function initialize(
27 | string memory name_,
28 | string memory symbol_,
29 | uint8 decimals_,
30 | address l2Gateway_,
31 | address l1Address_
32 | ) external {
33 | L2GatewayToken._initialize(name_, symbol_, decimals_, l2Gateway_, l1Address_);
34 | }
35 |
36 | function bridgeMint(
37 | address, /* account */
38 | uint256 /* amount */
39 | ) external virtual override {
40 | // we want weth to always be fully collaterized
41 | revert("NO_BRIDGE_MINT");
42 | }
43 |
44 | function bridgeBurn(address account, uint256 amount) external virtual override onlyGateway {
45 | _burn(account, amount);
46 | (bool success, ) = msg.sender.call{ value: amount }("");
47 | require(success, "FAIL_TRANSFER");
48 | }
49 |
50 | function deposit() external payable override {
51 | depositTo(msg.sender);
52 | }
53 |
54 | function withdraw(uint256 amount) external override {
55 | withdrawTo(msg.sender, amount);
56 | }
57 |
58 | function depositTo(address account) public payable {
59 | _mint(account, msg.value);
60 | }
61 |
62 | function withdrawTo(address account, uint256 amount) public {
63 | _burn(msg.sender, amount);
64 | (bool success, ) = account.call{ value: amount }("");
65 | require(success, "FAIL_TRANSFER");
66 | }
67 |
68 | receive() external payable {
69 | depositTo(msg.sender);
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/contracts/tokenbridge/libraries/gateway/GatewayMessageHandler.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: Apache-2.0
2 |
3 | /*
4 | * Copyright 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.0;
20 |
21 | /// @notice this library manages encoding and decoding of gateway communication
22 | library GatewayMessageHandler {
23 | // these are for communication from L1 to L2 gateway
24 |
25 | function encodeToL2GatewayMsg(bytes memory gatewayData, bytes memory callHookData)
26 | internal
27 | pure
28 | returns (bytes memory res)
29 | {
30 | res = abi.encode(gatewayData, callHookData);
31 | }
32 |
33 | function parseFromL1GatewayMsg(bytes calldata _data)
34 | internal
35 | pure
36 | returns (bytes memory gatewayData, bytes memory callHookData)
37 | {
38 | // abi decode may revert, but the encoding is done by L1 gateway, so we trust it
39 | (gatewayData, callHookData) = abi.decode(_data, (bytes, bytes));
40 | }
41 |
42 | // these are for communication from L2 to L1 gateway
43 |
44 | function encodeFromL2GatewayMsg(uint256 exitNum, bytes memory callHookData)
45 | internal
46 | pure
47 | returns (bytes memory res)
48 | {
49 | res = abi.encode(exitNum, callHookData);
50 | }
51 |
52 | function parseToL1GatewayMsg(bytes calldata _data)
53 | internal
54 | pure
55 | returns (uint256 exitNum, bytes memory callHookData)
56 | {
57 | // abi decode may revert, but the encoding is done by L1 gateway, so we trust it
58 | (exitNum, callHookData) = abi.decode(_data, (uint256, bytes));
59 | }
60 |
61 | // these are for communication from router to gateway
62 |
63 | function encodeFromRouterToGateway(address _from, bytes calldata _data)
64 | internal
65 | pure
66 | returns (bytes memory res)
67 | {
68 | // abi decode may revert, but the encoding is done by L1 gateway, so we trust it
69 | return abi.encode(_from, _data);
70 | }
71 |
72 | function parseFromRouterToGateway(bytes calldata _data)
73 | internal
74 | pure
75 | returns (address, bytes memory res)
76 | {
77 | // abi decode may revert, but the encoding is done by L1 gateway, so we trust it
78 | return abi.decode(_data, (address, bytes));
79 | }
80 | }
81 |
--------------------------------------------------------------------------------
/contracts/tokenbridge/libraries/gateway/ICustomGateway.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: Apache-2.0
2 |
3 | /*
4 | * Copyright 2020, 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 | // solhint-disable-next-line compiler-version
20 | pragma solidity >=0.6.9 <0.9.0;
21 |
22 | // import "./ITokenGateway.sol";
23 |
24 | interface ICustomGateway {
25 | function l1ToL2Token(address _l1Token) external view returns (address _l2Token);
26 |
27 | event TokenSet(address indexed l1Address, address indexed l2Address);
28 | }
29 |
--------------------------------------------------------------------------------
/contracts/tokenbridge/libraries/gateway/IGatewayRouter.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: Apache-2.0
2 |
3 | /*
4 | * Copyright 2020, 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.0;
20 |
21 | import "../ProxyUtil.sol";
22 | import "@openzeppelin/contracts/utils/Address.sol";
23 | import "./TokenGateway.sol";
24 | import "./GatewayMessageHandler.sol";
25 |
26 | /**
27 | * @title Common interface for L1 and L2 Gateway Routers
28 | */
29 | interface IGatewayRouter is ITokenGateway {
30 | function defaultGateway() external view returns (address gateway);
31 |
32 | event TransferRouted(
33 | address indexed token,
34 | address indexed _userFrom,
35 | address indexed _userTo,
36 | address gateway
37 | );
38 |
39 | event GatewaySet(address indexed l1Token, address indexed gateway);
40 | event DefaultGatewayUpdated(address newDefaultGateway);
41 |
42 | function getGateway(address _token) external view returns (address gateway);
43 | }
44 |
--------------------------------------------------------------------------------
/contracts/tokenbridge/libraries/gateway/ITokenGateway.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: Apache-2.0
2 |
3 | /*
4 | * Copyright 2020, 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 | // solhint-disable-next-line compiler-version
20 | pragma solidity >=0.6.9 <0.9.0;
21 |
22 | interface ITokenGateway {
23 | /// @notice event deprecated in favor of DepositInitiated and WithdrawalInitiated
24 | // event OutboundTransferInitiated(
25 | // address token,
26 | // address indexed _from,
27 | // address indexed _to,
28 | // uint256 indexed _transferId,
29 | // uint256 _amount,
30 | // bytes _data
31 | // );
32 |
33 | /// @notice event deprecated in favor of DepositFinalized and WithdrawalFinalized
34 | // event InboundTransferFinalized(
35 | // address token,
36 | // address indexed _from,
37 | // address indexed _to,
38 | // uint256 indexed _transferId,
39 | // uint256 _amount,
40 | // bytes _data
41 | // );
42 |
43 | function outboundTransfer(
44 | address _token,
45 | address _to,
46 | uint256 _amount,
47 | uint256 _maxGas,
48 | uint256 _gasPriceBid,
49 | bytes calldata _data
50 | ) external payable returns (bytes memory);
51 |
52 | function finalizeInboundTransfer(
53 | address _token,
54 | address _from,
55 | address _to,
56 | uint256 _amount,
57 | bytes calldata _data
58 | ) external payable;
59 |
60 | /**
61 | * @notice Calculate the address used when bridging an ERC20 token
62 | * @dev the L1 and L2 address oracles may not always be in sync.
63 | * For example, a custom token may have been registered but not deploy or the contract self destructed.
64 | * @param l1ERC20 address of L1 token
65 | * @return L2 address of a bridged ERC20 token
66 | */
67 | function calculateL2TokenAddress(address l1ERC20) external view returns (address);
68 |
69 | function getOutboundCalldata(
70 | address _token,
71 | address _from,
72 | address _to,
73 | uint256 _amount,
74 | bytes memory _data
75 | ) external view returns (bytes memory);
76 | }
77 |
--------------------------------------------------------------------------------
/contracts/tokenbridge/libraries/gateway/TokenGateway.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: Apache-2.0
2 |
3 | /*
4 | * Copyright 2020, 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.0;
20 |
21 | import "./ITokenGateway.sol";
22 | import "@openzeppelin/contracts/utils/Address.sol";
23 |
24 | abstract contract TokenGateway is ITokenGateway {
25 | using Address for address;
26 |
27 | address public counterpartGateway;
28 | address public router;
29 |
30 | // This modifier is overriden in gateways to validate the message sender
31 | // For L1 to L2 messages need to be validated against the aliased counterpartGateway
32 | // For L2 to L1 messages need to be validated against the bridge and L2ToL1Sender
33 | // prettier-ignore
34 | modifier onlyCounterpartGateway() virtual;
35 |
36 | function _initialize(address _counterpartGateway, address _router) internal virtual {
37 | // This initializes internal variables of the abstract contract it can be chained together with other functions.
38 | // It is virtual so subclasses can override or wrap around this logic.
39 | // An example where this is useful is different subclasses that validate the router address differently
40 | require(_counterpartGateway != address(0), "INVALID_COUNTERPART");
41 | require(counterpartGateway == address(0), "ALREADY_INIT");
42 | counterpartGateway = _counterpartGateway;
43 | router = _router;
44 | }
45 |
46 | function isRouter(address _target) internal view returns (bool isTargetRouter) {
47 | return _target == router;
48 | }
49 |
50 | /**
51 | * @notice Calculate the address used when bridging an ERC20 token
52 | * @dev the L1 and L2 address oracles may not always be in sync.
53 | * For example, a custom token may have been registered but not deploy or the contract self destructed.
54 | * @param l1ERC20 address of L1 token
55 | * @return L2 address of a bridged ERC20 token
56 | */
57 | function calculateL2TokenAddress(address l1ERC20)
58 | public
59 | view
60 | virtual
61 | override
62 | returns (address);
63 | }
64 |
--------------------------------------------------------------------------------
/contracts/tokenbridge/test/AddressMappingTest.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: Apache-2.0
2 |
3 | /*
4 | * Copyright 2020, 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.0;
20 |
21 | import "../arbitrum/L2ArbitrumMessenger.sol";
22 | import "../libraries/AddressAliasHelper.sol";
23 |
24 | contract AddressMappingTest is L2ArbitrumMessenger {
25 | function getL1AddressTest(address sender) external pure returns (address l1Address) {
26 | return AddressAliasHelper.undoL1ToL2Alias(sender);
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/contracts/tokenbridge/test/ArbSysMock.sol:
--------------------------------------------------------------------------------
1 | pragma solidity ^0.8.0;
2 |
3 | contract ArbSysMock {
4 | event ArbSysL2ToL1Tx(address from, address to, uint256 value, bytes data);
5 | uint256 counter;
6 |
7 | function sendTxToL1(address destination, bytes calldata calldataForL1)
8 | external
9 | payable
10 | returns (uint256 exitNum)
11 | {
12 | exitNum = counter;
13 | counter = exitNum + 1;
14 | emit ArbSysL2ToL1Tx(msg.sender, destination, msg.value, calldataForL1);
15 | return exitNum;
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/contracts/tokenbridge/test/CreationCodeTest.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: Apache-2.0
2 | pragma solidity ^0.8.0;
3 |
4 | import {CreationCodeHelper} from "../libraries/CreationCodeHelper.sol";
5 |
6 | contract CreationCodeTest {
7 | /**
8 | * @dev Wrapper function around CreationCodeHelper.getCreationCodeFor used for testing convenience.
9 | */
10 | function creationCodeFor(bytes memory code) external pure returns (bytes memory) {
11 | return CreationCodeHelper.getCreationCodeFor(code);
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/contracts/tokenbridge/test/InterfaceCompatibilityTester.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: Apache-2.0
2 |
3 | /*
4 | * Copyright 2022, 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 | // solhint-disable-next-line compiler-version
20 | pragma solidity >=0.6.9 <0.9.0;
21 |
22 | import "../arbitrum/IArbToken.sol";
23 | import "../ethereum/ICustomToken.sol";
24 | import "../ethereum/gateway/IL1ArbitrumGateway.sol";
25 | import "../ethereum/gateway/IL1GatewayRouter.sol";
26 | import "../libraries/IWETH9.sol";
27 | import "../libraries/IERC165.sol";
28 | import "../libraries/gateway/ICustomGateway.sol";
29 | import "../libraries/gateway/ITokenGateway.sol";
30 |
--------------------------------------------------------------------------------
/contracts/tokenbridge/test/TestArbCustomToken.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: Apache-2.0
2 |
3 | /*
4 | * Copyright 2020, 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.0;
20 |
21 | import "../arbitrum/IArbToken.sol";
22 | import "../arbitrum/ReverseArbToken.sol";
23 | import "../libraries/aeERC20.sol";
24 |
25 | contract TestArbCustomToken is aeERC20, IArbToken {
26 | address public l2Gateway;
27 | address public override l1Address;
28 |
29 | modifier onlyGateway() {
30 | require(msg.sender == l2Gateway, "ONLY_l2GATEWAY");
31 | _;
32 | }
33 |
34 | constructor(address _l2Gateway, address _l1Address) {
35 | l2Gateway = _l2Gateway;
36 | l1Address = _l1Address;
37 | aeERC20._initialize("TestCustomToken", "CARB", uint8(18));
38 | }
39 |
40 | function someWackyCustomStuff() public {}
41 |
42 | function bridgeMint(address account, uint256 amount) external virtual override onlyGateway {
43 | _mint(account, amount);
44 | }
45 |
46 | function bridgeBurn(address account, uint256 amount) external virtual override onlyGateway {
47 | _burn(account, amount);
48 | }
49 | }
50 |
51 | contract MintableTestArbCustomToken is TestArbCustomToken {
52 | constructor(address _l2Gateway, address _l1Address)
53 | TestArbCustomToken(_l2Gateway, _l1Address)
54 | {}
55 |
56 | function userMint(address account, uint256 amount) external {
57 | _mint(account, amount);
58 | }
59 | }
60 |
61 | contract ReverseTestArbCustomToken is aeERC20, IArbToken, ReverseArbToken {
62 | address public l2Gateway;
63 | address public override l1Address;
64 |
65 | modifier onlyGateway() {
66 | require(msg.sender == l2Gateway, "ONLY_l2GATEWAY");
67 | _;
68 | }
69 |
70 | constructor(address _l2Gateway, address _l1Address) {
71 | l2Gateway = _l2Gateway;
72 | l1Address = _l1Address;
73 | aeERC20._initialize("TestReverseCustomToken", "RARB", uint8(18));
74 | }
75 |
76 | function someWackyCustomStuff() public {}
77 |
78 | function mint() external {
79 | _mint(msg.sender, 50000000);
80 | }
81 | }
82 |
--------------------------------------------------------------------------------
/contracts/tokenbridge/test/TestArbCustomTokenBurnFee.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: Apache-2.0
2 |
3 | /*
4 | * Copyright 2020, 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.0;
20 |
21 | import "./TestArbCustomToken.sol";
22 |
23 | contract TestArbCustomTokenBurnFee is TestArbCustomToken {
24 | constructor(address _l2Gateway, address _l1Address)
25 | TestArbCustomToken(_l2Gateway, _l1Address)
26 | {}
27 |
28 | // this token transfer extra 1 wei from the sender as fee when it burn token
29 | // alternatively, it can also be a callback that pass execution to the user
30 | function _burn(address account, uint256 amount) internal override {
31 | super._burn(account, amount);
32 | _transfer(account, address(1), 1);
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/contracts/tokenbridge/test/TestBytesParser.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: Apache-2.0
2 |
3 | /*
4 | * Copyright 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.0;
20 |
21 | import "../libraries/BytesParser.sol";
22 |
23 | contract TestBytesParser {
24 | function bytesToString(bytes memory input)
25 | public
26 | pure
27 | returns (bool success, string memory res)
28 | {
29 | return BytesParser.toString(input);
30 | }
31 |
32 | function bytesToUint8(bytes memory input) public pure returns (bool, uint8) {
33 | return BytesParser.toUint8(input);
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/contracts/tokenbridge/test/TestERC20.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: Apache-2.0
2 |
3 | /*
4 | * Copyright 2020, 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.0;
20 |
21 | import "../libraries/aeERC20.sol";
22 |
23 | contract TestERC20 is aeERC20 {
24 | constructor() {
25 | aeERC20._initialize("IntArbTestToken", "IARB", uint8(18));
26 | }
27 |
28 | function mint() external {
29 | _mint(msg.sender, 50000000);
30 | }
31 | }
32 |
33 | // test token code inspired from maker
34 | contract Bytes32ERC20 {
35 | mapping(address => uint256) public balanceOf;
36 | mapping(address => mapping(address => uint256)) public allowance;
37 |
38 | function transfer(address dst, uint256 wad) public returns (bool) {
39 | return transferFrom(msg.sender, dst, wad);
40 | }
41 |
42 | function transferFrom(
43 | address src,
44 | address dst,
45 | uint256 wad
46 | ) public returns (bool) {
47 | if (src != msg.sender) {
48 | allowance[src][msg.sender] = allowance[src][msg.sender] - wad;
49 | }
50 |
51 | balanceOf[src] = balanceOf[src] - wad;
52 | balanceOf[dst] = balanceOf[dst] + wad;
53 |
54 | return true;
55 | }
56 |
57 | function approve(address guy, uint256 wad) public returns (bool) {
58 | allowance[msg.sender][guy] = wad;
59 | return true;
60 | }
61 |
62 | function mint() public {
63 | balanceOf[msg.sender] += 1 ether;
64 | }
65 | }
66 |
67 | contract Bytes32ERC20WithMetadata is Bytes32ERC20 {
68 | bytes32 public name = 0x4d616b6572000000000000000000000000000000000000000000000000000000;
69 | bytes32 public symbol = 0x4d4b520000000000000000000000000000000000000000000000000000000000;
70 | // TODO: what if this overflows?
71 | uint8 public decimals = 18;
72 |
73 | // no totalSupply field
74 | // uint256 public totalSupply;
75 | }
76 |
--------------------------------------------------------------------------------
/contracts/tokenbridge/test/TestPostDepositCall.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: Apache-2.0
2 |
3 | /*
4 | * Copyright 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.0;
20 |
21 | import "../libraries/ITransferAndCall.sol";
22 |
23 | contract L2Called is ITransferAndCallReceiver {
24 | event Called(uint256 num);
25 |
26 | constructor() {}
27 |
28 | // This function can be anything
29 | function postDepositHook(uint256 num) public {
30 | emit Called(num);
31 | }
32 |
33 | function onTokenTransfer(
34 | address, /* sender */
35 | uint256, /* amount */
36 | bytes calldata data
37 | ) external override {
38 | uint256 num = abi.decode(data, (uint256));
39 |
40 | if (num == 5) {
41 | postDepositHook(num);
42 | } else if (num == 7) {
43 | revert("should fail because 7");
44 | } else if (num == 9) {
45 | // this should use all gas
46 | while (gasleft() > 0) {}
47 | } else {
48 | revert("should fail");
49 | }
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/contracts/tokenbridge/test/TestWETH9.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: Apache-2.0
2 |
3 | pragma solidity ^0.8.0;
4 |
5 | import "../libraries/IWETH9.sol";
6 | import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
7 | import "@openzeppelin/contracts/proxy/transparent/ProxyAdmin.sol";
8 |
9 | contract TestWETH9 is ERC20, IWETH9 {
10 | constructor(string memory name_, string memory symbol_) ERC20(name_, symbol_) {}
11 |
12 | function deposit() external payable override {
13 | _mint(msg.sender, msg.value);
14 | }
15 |
16 | function withdraw(uint256 _amount) external override {
17 | _burn(msg.sender, _amount);
18 | payable(address(msg.sender)).transfer(_amount);
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/deployment-42161.json:
--------------------------------------------------------------------------------
1 | {
2 | "l1GatewayRouter": "0x72Ce9c846789fdB6fC1f34aC4AD25Dd9ef7031ef",
3 | "l2GatewayRouter": "0x5288c571Fd7aD117beA99bF60FE0846C4E84F933",
4 | "l1ERC20GatewayProxy": "0xa3A7B6F88361F48403514059F1F16C8E78d60EeC",
5 | "l2ERC20GatewayProxy": "0x09e9222E96E7B4AE2a407B98d48e330053351EEe",
6 | "l1ProxyAdmin": "0x9aD46fac0Cf7f790E5be05A0F15223935A0c0aDa",
7 | "l2ProxyAdmin": "0xd570aCE65C43af47101fC6250FD6fC63D1c22a86",
8 | "l1Deployer": "0x5B34380C518da5A8851f762D4fA29605ACc3c0e2",
9 | "l2Deployer": "0xBB1a241DCBd6A3894cB61F659034874Dc9CF65D4",
10 | "inbox": "0x4Dbd4fc535Ac27206064B68FfCf827b0A60BAB3f"
11 | }
12 |
--------------------------------------------------------------------------------
/deployment-421611.json:
--------------------------------------------------------------------------------
1 | {
2 | "l1GatewayRouter": "0x70C143928eCfFaf9F5b406f7f4fC28Dc43d68380",
3 | "l2GatewayRouter": "0x9413AD42910c1eA60c737dB5f58d1C504498a3cD",
4 | "l1ERC20GatewayProxy": "0x91169Dbb45e6804743F94609De50D511C437572E",
5 | "l2ERC20GatewayProxy": "0x195C107F3F75c4C93Eba7d9a1312F19305d6375f",
6 | "l1ProxyAdmin": "0x0DbAF24efA2bc9Dd1a6c0530DD252BCcF883B89A",
7 | "l2ProxyAdmin": "0x58816566EB91815Cc07f3Ad5230eE0820fe1A19a",
8 | "l1Deployer": "0xdF8107D1758D1D7dCfB29511557bC92DAa119174",
9 | "l2Deployer": "0xdF8107D1758D1D7dCfB29511557bC92DAa119174",
10 | "inbox": "0x578BAde599406A8fE3d24Fd7f7211c0911F5B29e"
11 | }
12 |
--------------------------------------------------------------------------------
/foundry.toml:
--------------------------------------------------------------------------------
1 | [profile.default]
2 | src = 'contracts'
3 | out = 'out'
4 | libs = ["node_modules", "lib"]
5 | test = 'test-foundry'
6 | cache_path = 'forge-cache'
7 | optimizer = true
8 | optimizer_runs = 100
9 | via_ir = false
10 | fs_permissions = [{ access = "read", path = "node_modules/@offchainlabs/stablecoin-evm"}]
11 |
12 | [fmt]
13 | number_underscore = 'thousands'
14 | line_length = 100
15 | # See more config options https://github.com/foundry-rs/foundry/tree/master/config
--------------------------------------------------------------------------------
/remappings.txt:
--------------------------------------------------------------------------------
1 | ds-test/=lib/forge-std/lib/ds-test/src/
2 | forge-std/=lib/forge-std/src/
3 | @openzeppelin/contracts-upgradeable/=node_modules/@openzeppelin/contracts-upgradeable/
4 | @openzeppelin/contracts/=node_modules/@openzeppelin/contracts/
5 | @arbitrum=node_modules/@arbitrum
6 | @offchainlabs=node_modules/@offchainlabs
7 |
--------------------------------------------------------------------------------
/scripts/deploy_buddy_deployer.ts:
--------------------------------------------------------------------------------
1 | // import { ethers } from 'hardhat'
2 | // import { writeFileSync } from 'fs'
3 | // import deployments from '../deployment.json'
4 |
5 | // const main = async () => {
6 | // const BuddyDeployer = await ethers.getContractFactory('BuddyDeployer')
7 | // const buddyDeployer = await BuddyDeployer.deploy()
8 | // console.log('BuddyDeployer deployed to:', buddyDeployer.address)
9 |
10 | // const contracts = JSON.stringify({
11 | // ...deployments,
12 | // buddyDeployer: buddyDeployer.address,
13 | // l2ChainId: ethers.BigNumber.from(
14 | // ethers.provider.network.chainId
15 | // ).toHexString(),
16 | // })
17 | // const path = './deployment.json'
18 | // console.log(`Writing to JSON at ${path}`)
19 |
20 | // // TODO: should append/check if previous entries
21 | // writeFileSync(path, contracts)
22 |
23 | // console.log('Done')
24 | // }
25 |
26 | // main()
27 | // .then(() => process.exit(0))
28 | // .catch(error => {
29 | // console.error(error)
30 | // process.exit(1)
31 | // })
32 |
--------------------------------------------------------------------------------
/scripts/local-deployment/deployCreatorAndCreateTokenBridge.ts:
--------------------------------------------------------------------------------
1 | import * as fs from 'fs'
2 | import { setupTokenBridgeInLocalEnv } from './localDeploymentLib'
3 |
4 | async function main() {
5 | const {
6 | l1Network,
7 | l2Network,
8 | l1TokenBridgeCreatorAddress: l1TokenBridgeCreator,
9 | retryableSenderAddress: retryableSender,
10 | } = await setupTokenBridgeInLocalEnv()
11 |
12 | const NETWORK_FILE = 'network.json'
13 | fs.writeFileSync(
14 | NETWORK_FILE,
15 | JSON.stringify(
16 | { l1Network, l2Network, l1TokenBridgeCreator, retryableSender },
17 | null,
18 | 2
19 | )
20 | )
21 | console.log(NETWORK_FILE + ' updated')
22 | }
23 |
24 | main().then(() => console.log('Done.'))
25 |
--------------------------------------------------------------------------------
/scripts/signatures_test.bash:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | output_dir="./test/signatures"
3 | for CONTRACTNAME in L1ERC20Gateway L1CustomGateway L1ReverseCustomGateway L1WethGateway L2ERC20Gateway L2CustomGateway L2ReverseCustomGateway L2WethGateway L1GatewayRouter L2GatewayRouter StandardArbERC20 L1AtomicTokenBridgeCreator L1TokenBridgeRetryableSender L2AtomicTokenBridgeFactory L1OrbitCustomGateway L1OrbitERC20Gateway L1OrbitGatewayRouter L1OrbitReverseCustomGateway L1USDCGateway L1OrbitUSDCGateway L2USDCGateway
4 | do
5 | echo "Checking for signature changes in $CONTRACTNAME"
6 | [ -f "$output_dir/$CONTRACTNAME" ] && mv "$output_dir/$CONTRACTNAME" "$output_dir/$CONTRACTNAME-old"
7 | forge inspect "$CONTRACTNAME" methods > "$output_dir/$CONTRACTNAME"
8 | diff "$output_dir/$CONTRACTNAME-old" "$output_dir/$CONTRACTNAME"
9 | if [[ $? != "0" ]]
10 | then
11 | CHANGED=1
12 | fi
13 | done
14 | if [[ $CHANGED == 1 ]]
15 | then
16 | exit 1
17 | fi
--------------------------------------------------------------------------------
/scripts/storage_layout_test.bash:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | output_dir="./test/storage"
3 | for CONTRACTNAME in L1ERC20Gateway L1CustomGateway L1ReverseCustomGateway L1WethGateway L2ERC20Gateway L2CustomGateway L2ReverseCustomGateway L2WethGateway L1GatewayRouter L2GatewayRouter StandardArbERC20 L1AtomicTokenBridgeCreator L1TokenBridgeRetryableSender L2AtomicTokenBridgeFactory L1OrbitCustomGateway L1OrbitERC20Gateway L1OrbitGatewayRouter L1OrbitReverseCustomGateway L1USDCGateway L1OrbitUSDCGateway L2USDCGateway
4 | do
5 | echo "Checking storage change of $CONTRACTNAME"
6 | [ -f "$output_dir/$CONTRACTNAME" ] && mv "$output_dir/$CONTRACTNAME" "$output_dir/$CONTRACTNAME-old"
7 | forge inspect "$CONTRACTNAME" --pretty storage > "$output_dir/$CONTRACTNAME"
8 | diff "$output_dir/$CONTRACTNAME-old" "$output_dir/$CONTRACTNAME"
9 | if [[ $? != "0" ]]
10 | then
11 | CHANGED=1
12 | fi
13 | done
14 | if [[ $CHANGED == 1 ]]
15 | then
16 | exit 1
17 | fi
--------------------------------------------------------------------------------
/scripts/upgradeTemplate.ts:
--------------------------------------------------------------------------------
1 | import { JsonRpcProvider } from '@ethersproject/providers'
2 | import { L2AtomicTokenBridgeFactory__factory } from '../build/types'
3 | import dotenv from 'dotenv'
4 | import { Wallet } from 'ethers'
5 |
6 | dotenv.config()
7 |
8 | async function main() {
9 | const deployRpc = process.env['BASECHAIN_RPC'] as string
10 | if (deployRpc == undefined) {
11 | throw new Error("Env var 'BASECHAIN_RPC' not set")
12 | }
13 | const rpc = new JsonRpcProvider(deployRpc)
14 |
15 | const deployKey = process.env['BASECHAIN_DEPLOYER_KEY'] as string
16 | if (deployKey == undefined) {
17 | throw new Error("Env var 'BASECHAIN_DEPLOYER_KEY' not set")
18 | }
19 | const deployer = new Wallet(deployKey).connect(rpc)
20 |
21 | console.log(
22 | 'Deploying L2AtomicTokenBridgeFactory to chain',
23 | await deployer.getChainId()
24 | )
25 | const l2TokenBridgeFactory = await new L2AtomicTokenBridgeFactory__factory(
26 | deployer
27 | ).deploy()
28 | await l2TokenBridgeFactory.deployed()
29 |
30 | console.log('l2TokenBridgeFactory:', l2TokenBridgeFactory.address)
31 | }
32 |
33 | main().then(() => console.log('Done.'))
34 |
--------------------------------------------------------------------------------
/scripts/usdc-bridge-deployment/env.example:
--------------------------------------------------------------------------------
1 | PARENT_RPC=
2 | PARENT_DEPLOYER_KEY=
3 | CHILD_RPC=
4 | CHILD_DEPLOYER_KEY=
5 | L1_ROUTER=
6 | L2_ROUTER=
7 | INBOX=
8 | L1_USDC=
9 | ## OPTIONAL arg. If set, script will register the gateway, otherwise it will store TX payload in a file
10 | ROLLUP_OWNER_KEY=
--------------------------------------------------------------------------------
/scripts/verify_upgrade.ts:
--------------------------------------------------------------------------------
1 | import { artifacts } from 'hardhat'
2 |
3 | import {
4 | getStorageLayout,
5 | assertUpgradeSafe,
6 | getContractVersion,
7 | assertStorageUpgradeSafe,
8 | solcInputOutputDecoder,
9 | validate,
10 | RunValidation,
11 | } from '@openzeppelin/upgrades-core'
12 |
13 | const oldContract = 'L1ERC20Gateway'
14 | const newContract = 'L2ERC20Gateway'
15 |
16 | const main = async () => {
17 | const validationContext = {} as RunValidation
18 |
19 | const contracts = (await artifacts.getAllFullyQualifiedNames()).filter(
20 | curr => curr.includes(oldContract) || curr.includes(newContract)
21 | )
22 |
23 | if (contracts.length < 1) {
24 | throw new Error("Can't find artifacts for contracts")
25 | }
26 |
27 | for (const contract of contracts) {
28 | const buildInfo = await artifacts.getBuildInfo(contract)
29 | if (buildInfo === undefined) {
30 | throw new Error(`Build info not found for contract ${contract}`)
31 | }
32 | const solcOutput = buildInfo.output
33 | const solcInput = buildInfo.input
34 | const decodeSrc = solcInputOutputDecoder(solcInput, solcOutput)
35 | Object.assign(validationContext, validate(solcOutput, decodeSrc))
36 | }
37 |
38 | console.log(`Looking at ${oldContract} and ${newContract}`)
39 |
40 | const oldVersion = getContractVersion(validationContext, oldContract)
41 | const newVersion = getContractVersion(validationContext, newContract)
42 |
43 | // verifies for errors such as setting arguments in constructors
44 | assertUpgradeSafe([validationContext], oldVersion, { kind: 'transparent' })
45 | assertUpgradeSafe([validationContext], newVersion, { kind: 'transparent' })
46 |
47 | const oldStorage = getStorageLayout(validationContext, oldVersion)
48 | const newStorage = getStorageLayout(validationContext, newVersion)
49 |
50 | // verifies that storage layouts match
51 | assertStorageUpgradeSafe(oldStorage, newStorage)
52 |
53 | console.log('Upgrade validation complete, all is good.')
54 | }
55 |
56 | main()
57 | .then(() => process.exit(0))
58 | .catch(error => {
59 | console.error(error)
60 | process.exit(1)
61 | })
62 |
--------------------------------------------------------------------------------
/slither.config.json:
--------------------------------------------------------------------------------
1 | {
2 | "exclude_dependencies": true,
3 | "exclude_informational": true,
4 | "exclude_low": true,
5 | "exclude_optimization": true,
6 | "filter_paths": "contracts/tokenbridge/test|node_modules/"
7 | }
8 |
--------------------------------------------------------------------------------
/tasks/compareBytecode.ts:
--------------------------------------------------------------------------------
1 | import { task } from "hardhat/config";
2 | import { ethers } from "ethers";
3 | import "@nomiclabs/hardhat-etherscan"
4 | import { Bytecode } from "@nomiclabs/hardhat-etherscan/dist/src/solc/bytecode"
5 | import { TASK_VERIFY_GET_CONTRACT_INFORMATION, TASK_VERIFY_GET_COMPILER_VERSIONS, TASK_VERIFY_GET_LIBRARIES } from "@nomiclabs/hardhat-etherscan/dist/src/constants"
6 | import fs from "fs";
7 |
8 | task("compareBytecode", "Compares deployed bytecode with local builds")
9 | .addParam("contractAddrs", "A comma-separated list of deployed contract addresses")
10 | .setAction(async ({ contractAddrs }, hre) => {
11 | const addresses = contractAddrs.split(',');
12 |
13 | // Get all local contract artifact paths
14 | const artifactPaths = await hre.artifacts.getArtifactPaths();
15 |
16 | for (const contractAddr of addresses) {
17 |
18 | // Fetch deployed contract bytecode
19 | const deployedBytecode = await hre.ethers.provider.getCode(contractAddr.trim());
20 | const deployedCodeHash = ethers.utils.keccak256(deployedBytecode);
21 | let matchFound = false;
22 |
23 | for (const artifactPath of artifactPaths) {
24 | const artifact = JSON.parse(fs.readFileSync(artifactPath, "utf8"));
25 | if (artifact.deployedBytecode) {
26 | const localCodeHash = ethers.utils.keccak256(artifact.deployedBytecode);
27 |
28 | // Compare codehashes
29 | if (deployedCodeHash === localCodeHash) {
30 | console.log(`Contract Address ${contractAddr.trim()} matches with ${artifact.contractName}`);
31 | matchFound = true;
32 | break;
33 | }
34 | }
35 | }
36 |
37 | if (!matchFound) {
38 | const deployedBytecodeHex = deployedBytecode.startsWith("0x")
39 | ? deployedBytecode.slice(2)
40 | : deployedBytecode;
41 | try {
42 | const info = await hre.run(TASK_VERIFY_GET_CONTRACT_INFORMATION, {
43 | deployedBytecode: new Bytecode(deployedBytecodeHex),
44 | matchingCompilerVersions: await hre.run(
45 | TASK_VERIFY_GET_COMPILER_VERSIONS
46 | ),
47 | libraries: await hre.run(TASK_VERIFY_GET_LIBRARIES),
48 | })
49 | console.log(`Contract Address ${contractAddr.trim()} matches with ${info.contractName} without checking constructor arguments`);
50 | } catch (error) {
51 | console.log(`No matching contract found for address ${contractAddr.trim()}`);
52 | }
53 | }
54 | }
55 | });
56 |
57 | export default {};
58 |
--------------------------------------------------------------------------------
/tasks/peripheralsTasks.ts:
--------------------------------------------------------------------------------
1 | import { task } from 'hardhat/config'
2 | import { initUpgrades } from '.'
3 |
4 | task('deploy-logic-one', 'deploy one logic')
5 | .addParam('contract', 'contract to deploy')
6 | .setAction(async (args, hre) => {
7 | const { contract } = args
8 | const { deployLogic } = initUpgrades(hre, process.cwd())
9 | await deployLogic(contract)
10 | })
11 |
12 | task('deploy-logic-all', 'deploy all logic contracts').setAction(
13 | async (_, hre) => {
14 | const { deployLogicAll } = initUpgrades(hre, process.cwd())
15 | await deployLogicAll()
16 | }
17 | )
18 |
19 | task('trigger-upgrades', 'triggers upgrade').setAction(async (_, hre) => {
20 | const { updateImplementations } = initUpgrades(hre, process.cwd())
21 | await updateImplementations()
22 | })
23 |
24 | task('verify-deployments', 'verifies implementations').setAction(
25 | async (_, hre) => {
26 | const { verifyCurrentImplementations } = initUpgrades(hre, process.cwd())
27 | await verifyCurrentImplementations()
28 | }
29 | )
30 |
31 | task('transfer-owner', 'deploy one logic')
32 | .addParam('proxyaddress', 'proxy address')
33 | .addParam('newadmin', 'address of new admin')
34 | .setAction(async (args, hre) => {
35 | const { contract } = args
36 | const { transferAdmin } = initUpgrades(hre, process.cwd())
37 | await transferAdmin(args.proxyaddress, args.newadmin)
38 | })
39 |
40 | task(
41 | 'remove-build-info',
42 | 'remove giant build info string from current_deployments json'
43 | ).setAction(async (_, hre) => {
44 | const { removeBuildInfoFiles } = initUpgrades(hre, process.cwd())
45 | await removeBuildInfoFiles()
46 | })
47 |
48 | task('etherscan-verify', 'verify current deployments in etherscan').setAction(
49 | async (_, hre) => {
50 | const { verifyDeployments } = await initUpgrades(hre, process.cwd())
51 | await verifyDeployments()
52 | }
53 | )
54 |
--------------------------------------------------------------------------------
/test-foundry/GatewayRouter.t.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: Apache-2.0
2 |
3 | pragma solidity ^0.8.0;
4 |
5 | import "forge-std/Test.sol";
6 | import { GatewayRouter } from "contracts/tokenbridge/libraries/gateway/GatewayRouter.sol";
7 | import { ERC20 } from "@openzeppelin/contracts/token/ERC20/ERC20.sol";
8 |
9 | abstract contract GatewayRouterTest is Test {
10 | GatewayRouter public router;
11 | address public defaultGateway;
12 |
13 | // retryable params
14 | uint256 public maxSubmissionCost;
15 | uint256 public maxGas = 1000000000;
16 | uint256 public gasPriceBid = 3;
17 | uint256 public retryableCost;
18 | address public creditBackAddress = makeAddr("creditBackAddress");
19 |
20 | /* solhint-disable func-name-mixedcase */
21 | function test_getGateway_DefaultGateway(address token) public {
22 | address gateway = router.getGateway(token);
23 | assertEq(gateway, defaultGateway, "Invalid gateway");
24 | }
25 |
26 | function test_finalizeInboundTransfer() public {
27 | vm.expectRevert("ONLY_OUTBOUND_ROUTER");
28 | router.finalizeInboundTransfer(address(1), address(2), address(3), 0, "");
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/test-foundry/IOwnable.sol:
--------------------------------------------------------------------------------
1 | // Copyright 2021-2022, Offchain Labs, Inc.
2 | // For license information, see https://github.com/nitro/blob/master/LICENSE
3 | // SPDX-License-Identifier: BUSL-1.1
4 |
5 | // solhint-disable-next-line compiler-version
6 | pragma solidity >=0.4.21 <0.9.0;
7 |
8 | interface IOwnable {
9 | function owner() external view returns (address);
10 | }
11 |
--------------------------------------------------------------------------------
/test-foundry/L2ArbitrumGateway.t.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: Apache-2.0
2 |
3 | pragma solidity ^0.8.0;
4 |
5 | import "forge-std/Test.sol";
6 |
7 | import {L2ArbitrumGateway} from "contracts/tokenbridge/arbitrum/gateway/L2ArbitrumGateway.sol";
8 | import {ArbSysMock} from "contracts/tokenbridge/test/ArbSysMock.sol";
9 | import {ITokenGateway} from "contracts/tokenbridge/libraries/gateway/ITokenGateway.sol";
10 |
11 | abstract contract L2ArbitrumGatewayTest is Test {
12 | L2ArbitrumGateway public l2Gateway;
13 | ArbSysMock public arbSysMock = new ArbSysMock();
14 |
15 | address public router = makeAddr("router");
16 | address public l1Counterpart = makeAddr("l1Counterpart");
17 |
18 | // token transfer params
19 | address public receiver = makeAddr("to");
20 | address public sender = makeAddr("from");
21 | uint256 public amount = 2400;
22 |
23 | /* solhint-disable func-name-mixedcase */
24 | function test_getOutboundCalldata() public {
25 | address token = makeAddr("token");
26 | bytes memory data = new bytes(340);
27 |
28 | bytes memory expected = abi.encodeWithSelector(
29 | ITokenGateway.finalizeInboundTransfer.selector,
30 | token,
31 | sender,
32 | receiver,
33 | amount,
34 | abi.encode(0, data)
35 | );
36 | bytes memory actual = l2Gateway.getOutboundCalldata(token, sender, receiver, amount, data);
37 |
38 | assertEq(actual, expected, "Invalid outbound calldata");
39 | }
40 |
41 | function test_finalizeInboundTransfer() public virtual;
42 | function test_finalizeInboundTransfer_WithCallHook() public virtual;
43 |
44 | function test_outboundTransfer() public virtual;
45 |
46 | function test_outboundTransfer_4Args() public virtual;
47 |
48 | function test_outboundTransfer_revert_ExtraDataDisabled() public {
49 | vm.expectRevert("EXTRA_DATA_DISABLED");
50 | bytes memory extraData = new bytes(0x1234);
51 | l2Gateway.outboundTransfer(address(100), address(101), 200, 0, 0, extraData);
52 | }
53 |
54 | function test_outboundTransfer_revert_NoValue() public {
55 | vm.expectRevert("NO_VALUE");
56 | l2Gateway.outboundTransfer{value: 1 ether}(
57 | address(100), address(101), 200, 0, 0, new bytes(0)
58 | );
59 | }
60 |
61 | function test_outboundTransfer_revert_NotExpectedL1Token() public virtual;
62 |
63 | function test_outboundTransfer_revert_TokenNotDeployed() public {
64 | address token = makeAddr("someToken");
65 | vm.expectRevert("TOKEN_NOT_DEPLOYED");
66 | l2Gateway.outboundTransfer(token, address(101), 200, 0, 0, new bytes(0));
67 | }
68 |
69 | ////
70 | // Event declarations
71 | ////
72 | event DepositFinalized(
73 | address indexed l1Token, address indexed _from, address indexed _receiver, uint256 _amount
74 | );
75 |
76 | event WithdrawalInitiated(
77 | address l1Token,
78 | address indexed _from,
79 | address indexed _receiver,
80 | uint256 indexed _l2ToL1Id,
81 | uint256 _exitNum,
82 | uint256 _amount
83 | );
84 |
85 | event TxToL1(
86 | address indexed _from, address indexed _receiver, uint256 indexed _id, bytes _data
87 | );
88 | }
89 |
--------------------------------------------------------------------------------
/test-foundry/util/TestUtil.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: Apache-2.0
2 | pragma solidity ^0.8.4;
3 |
4 | import "@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol";
5 | import "@openzeppelin/contracts/proxy/transparent/ProxyAdmin.sol";
6 |
7 | library TestUtil {
8 | function deployProxy(address logic) public returns (address) {
9 | ProxyAdmin pa = new ProxyAdmin();
10 | return address(new TransparentUpgradeableProxy(address(logic), address(pa), ""));
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/test-mutation/all-configs/config.single.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "filename": "../contracts/tokenbridge/ethereum/gateway/L1ERC20Gateway.sol",
4 | "sourceroot": "..",
5 | "solc_remappings": [
6 | "@openzeppelin=../node_modules/@openzeppelin",
7 | "@arbitrum=../node_modules/@arbitrum"
8 | ]
9 | }
10 | ]
11 |
--------------------------------------------------------------------------------
/test-mutation/all-configs/config.tokenbridge-arbitrum.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "filename": "../contracts/tokenbridge/arbitrum/gateway/L2ArbitrumGateway.sol",
4 | "sourceroot": "..",
5 | "solc_remappings": [
6 | "@openzeppelin=../node_modules/@openzeppelin",
7 | "@arbitrum=../node_modules/@arbitrum"
8 | ]
9 | },
10 | {
11 | "filename": "../contracts/tokenbridge/arbitrum/gateway/L2CustomGateway.sol",
12 | "sourceroot": "..",
13 | "solc_remappings": [
14 | "@openzeppelin=../node_modules/@openzeppelin",
15 | "@arbitrum=../node_modules/@arbitrum"
16 | ]
17 | },
18 | {
19 | "filename": "../contracts/tokenbridge/arbitrum/gateway/L2ERC20Gateway.sol",
20 | "sourceroot": "..",
21 | "solc_remappings": [
22 | "@openzeppelin=../node_modules/@openzeppelin",
23 | "@arbitrum=../node_modules/@arbitrum"
24 | ]
25 | },
26 | {
27 | "filename": "../contracts/tokenbridge/arbitrum/gateway/L2GatewayRouter.sol",
28 | "sourceroot": "..",
29 | "solc_remappings": [
30 | "@openzeppelin=../node_modules/@openzeppelin",
31 | "@arbitrum=../node_modules/@arbitrum"
32 | ]
33 | },
34 | {
35 | "filename": "../contracts/tokenbridge/arbitrum/gateway/L2ReverseCustomGateway.sol",
36 | "sourceroot": "..",
37 | "solc_remappings": [
38 | "@openzeppelin=../node_modules/@openzeppelin",
39 | "@arbitrum=../node_modules/@arbitrum"
40 | ]
41 | },
42 | {
43 | "filename": "../contracts/tokenbridge/arbitrum/gateway/L2WethGateway.sol",
44 | "sourceroot": "..",
45 | "solc_remappings": [
46 | "@openzeppelin=../node_modules/@openzeppelin",
47 | "@arbitrum=../node_modules/@arbitrum"
48 | ]
49 | },
50 | {
51 | "filename": "../contracts/tokenbridge/arbitrum/L2ArbitrumMessenger.sol",
52 | "sourceroot": "..",
53 | "solc_remappings": [
54 | "@openzeppelin=../node_modules/@openzeppelin",
55 | "@arbitrum=../node_modules/@arbitrum"
56 | ]
57 | },
58 | {
59 | "filename": "../contracts/tokenbridge/arbitrum/L2AtomicTokenBridgeFactory.sol",
60 | "sourceroot": "..",
61 | "solc_remappings": [
62 | "@openzeppelin=../node_modules/@openzeppelin",
63 | "@arbitrum=../node_modules/@arbitrum"
64 | ]
65 | },
66 | {
67 | "filename": "../contracts/tokenbridge/arbitrum/ReverseArbToken.sol",
68 | "sourceroot": "..",
69 | "solc_remappings": [
70 | "@openzeppelin=../node_modules/@openzeppelin",
71 | "@arbitrum=../node_modules/@arbitrum"
72 | ]
73 | },
74 | {
75 | "filename": "../contracts/tokenbridge/arbitrum/StandardArbERC20.sol",
76 | "sourceroot": "..",
77 | "solc_remappings": [
78 | "@openzeppelin=../node_modules/@openzeppelin",
79 | "@arbitrum=../node_modules/@arbitrum"
80 | ]
81 | }
82 | ]
83 |
--------------------------------------------------------------------------------
/test-mutation/all-configs/config.tokenbridge-ethereum.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "filename": "../contracts/tokenbridge/ethereum/L1ArbitrumMessenger.sol",
4 | "sourceroot": "..",
5 | "solc_remappings": [
6 | "@openzeppelin=../node_modules/@openzeppelin",
7 | "@arbitrum=../node_modules/@arbitrum"
8 | ]
9 | },
10 | {
11 | "filename": "../contracts/tokenbridge/ethereum/gateway/L1ArbitrumExtendedGateway.sol",
12 | "sourceroot": "..",
13 | "solc_remappings": [
14 | "@openzeppelin=../node_modules/@openzeppelin",
15 | "@arbitrum=../node_modules/@arbitrum"
16 | ]
17 | },
18 | {
19 | "filename": "../contracts/tokenbridge/ethereum/gateway/L1ArbitrumGateway.sol",
20 | "sourceroot": "..",
21 | "solc_remappings": [
22 | "@openzeppelin=../node_modules/@openzeppelin",
23 | "@arbitrum=../node_modules/@arbitrum"
24 | ]
25 | },
26 | {
27 | "filename": "../contracts/tokenbridge/ethereum/gateway/L1CustomGateway.sol",
28 | "sourceroot": "..",
29 | "solc_remappings": [
30 | "@openzeppelin=../node_modules/@openzeppelin",
31 | "@arbitrum=../node_modules/@arbitrum"
32 | ]
33 | },
34 | {
35 | "filename": "../contracts/tokenbridge/ethereum/gateway/L1ERC20Gateway.sol",
36 | "sourceroot": "..",
37 | "solc_remappings": [
38 | "@openzeppelin=../node_modules/@openzeppelin",
39 | "@arbitrum=../node_modules/@arbitrum"
40 | ]
41 | },
42 | {
43 | "filename": "../contracts/tokenbridge/ethereum/gateway/L1ForceOnlyReverseCustomGateway.sol",
44 | "sourceroot": "..",
45 | "solc_remappings": [
46 | "@openzeppelin=../node_modules/@openzeppelin",
47 | "@arbitrum=../node_modules/@arbitrum"
48 | ]
49 | },
50 | {
51 | "filename": "../contracts/tokenbridge/ethereum/gateway/L1GatewayRouter.sol",
52 | "sourceroot": "..",
53 | "solc_remappings": [
54 | "@openzeppelin=../node_modules/@openzeppelin",
55 | "@arbitrum=../node_modules/@arbitrum"
56 | ]
57 | },
58 | {
59 | "filename": "../contracts/tokenbridge/ethereum/gateway/L1OrbitCustomGateway.sol",
60 | "sourceroot": "..",
61 | "solc_remappings": [
62 | "@openzeppelin=../node_modules/@openzeppelin",
63 | "@arbitrum=../node_modules/@arbitrum"
64 | ]
65 | },
66 | {
67 | "filename": "../contracts/tokenbridge/ethereum/gateway/L1OrbitERC20Gateway.sol",
68 | "sourceroot": "..",
69 | "solc_remappings": [
70 | "@openzeppelin=../node_modules/@openzeppelin",
71 | "@arbitrum=../node_modules/@arbitrum"
72 | ]
73 | },
74 | {
75 | "filename": "../contracts/tokenbridge/ethereum/gateway/L1OrbitGatewayRouter.sol",
76 | "sourceroot": "..",
77 | "solc_remappings": [
78 | "@openzeppelin=../node_modules/@openzeppelin",
79 | "@arbitrum=../node_modules/@arbitrum"
80 | ]
81 | },
82 | {
83 | "filename": "../contracts/tokenbridge/ethereum/gateway/L1OrbitReverseCustomGateway.sol",
84 | "sourceroot": "..",
85 | "solc_remappings": [
86 | "@openzeppelin=../node_modules/@openzeppelin",
87 | "@arbitrum=../node_modules/@arbitrum"
88 | ]
89 | },
90 | {
91 | "filename": "../contracts/tokenbridge/ethereum/gateway/L1ReverseCustomGateway.sol",
92 | "sourceroot": "..",
93 | "solc_remappings": [
94 | "@openzeppelin=../node_modules/@openzeppelin",
95 | "@arbitrum=../node_modules/@arbitrum"
96 | ]
97 | },
98 | {
99 | "filename": "../contracts/tokenbridge/ethereum/gateway/L1WethGateway.sol",
100 | "sourceroot": "..",
101 | "solc_remappings": [
102 | "@openzeppelin=../node_modules/@openzeppelin",
103 | "@arbitrum=../node_modules/@arbitrum"
104 | ]
105 | }
106 | ]
107 |
--------------------------------------------------------------------------------
/test-mutation/config.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "filename": "../contracts/tokenbridge/arbitrum/gateway/L2ArbitrumGateway.sol",
4 | "sourceroot": "..",
5 | "solc_remappings": [
6 | "@openzeppelin=../node_modules/@openzeppelin",
7 | "@arbitrum=../node_modules/@arbitrum"
8 | ]
9 | },
10 | {
11 | "filename": "../contracts/tokenbridge/arbitrum/gateway/L2CustomGateway.sol",
12 | "sourceroot": "..",
13 | "solc_remappings": [
14 | "@openzeppelin=../node_modules/@openzeppelin",
15 | "@arbitrum=../node_modules/@arbitrum"
16 | ]
17 | },
18 | {
19 | "filename": "../contracts/tokenbridge/arbitrum/gateway/L2ERC20Gateway.sol",
20 | "sourceroot": "..",
21 | "solc_remappings": [
22 | "@openzeppelin=../node_modules/@openzeppelin",
23 | "@arbitrum=../node_modules/@arbitrum"
24 | ]
25 | },
26 | {
27 | "filename": "../contracts/tokenbridge/arbitrum/gateway/L2GatewayRouter.sol",
28 | "sourceroot": "..",
29 | "solc_remappings": [
30 | "@openzeppelin=../node_modules/@openzeppelin",
31 | "@arbitrum=../node_modules/@arbitrum"
32 | ]
33 | },
34 | {
35 | "filename": "../contracts/tokenbridge/arbitrum/gateway/L2ReverseCustomGateway.sol",
36 | "sourceroot": "..",
37 | "solc_remappings": [
38 | "@openzeppelin=../node_modules/@openzeppelin",
39 | "@arbitrum=../node_modules/@arbitrum"
40 | ]
41 | },
42 | {
43 | "filename": "../contracts/tokenbridge/arbitrum/gateway/L2WethGateway.sol",
44 | "sourceroot": "..",
45 | "solc_remappings": [
46 | "@openzeppelin=../node_modules/@openzeppelin",
47 | "@arbitrum=../node_modules/@arbitrum"
48 | ]
49 | },
50 | {
51 | "filename": "../contracts/tokenbridge/arbitrum/L2ArbitrumMessenger.sol",
52 | "sourceroot": "..",
53 | "solc_remappings": [
54 | "@openzeppelin=../node_modules/@openzeppelin",
55 | "@arbitrum=../node_modules/@arbitrum"
56 | ]
57 | },
58 | {
59 | "filename": "../contracts/tokenbridge/arbitrum/L2AtomicTokenBridgeFactory.sol",
60 | "sourceroot": "..",
61 | "solc_remappings": [
62 | "@openzeppelin=../node_modules/@openzeppelin",
63 | "@arbitrum=../node_modules/@arbitrum"
64 | ]
65 | },
66 | {
67 | "filename": "../contracts/tokenbridge/arbitrum/ReverseArbToken.sol",
68 | "sourceroot": "..",
69 | "solc_remappings": [
70 | "@openzeppelin=../node_modules/@openzeppelin",
71 | "@arbitrum=../node_modules/@arbitrum"
72 | ]
73 | },
74 | {
75 | "filename": "../contracts/tokenbridge/arbitrum/StandardArbERC20.sol",
76 | "sourceroot": "..",
77 | "solc_remappings": [
78 | "@openzeppelin=../node_modules/@openzeppelin",
79 | "@arbitrum=../node_modules/@arbitrum"
80 | ]
81 | }
82 | ]
83 |
--------------------------------------------------------------------------------
/test/signatures/L1AtomicTokenBridgeCreator:
--------------------------------------------------------------------------------
1 | {
2 | "canonicalL2FactoryAddress()": "bfd3e518",
3 | "createTokenBridge(address,address,uint256,uint256)": "8277742b",
4 | "gasLimitForL2FactoryDeployment()": "888139d4",
5 | "getRouter(address)": "8369166d",
6 | "inboxToL1Deployment(address)": "d9ce0ef9",
7 | "inboxToL2Deployment(address)": "46052706",
8 | "initialize(address)": "c4d66de8",
9 | "l1Multicall()": "b1460a71",
10 | "l1Templates()": "a5595da9",
11 | "l1Weth()": "146bf4b1",
12 | "l2CustomGatewayTemplate()": "41083186",
13 | "l2MulticallTemplate()": "8c99e31c",
14 | "l2RouterTemplate()": "381c9d99",
15 | "l2StandardGatewayTemplate()": "d7eee6ca",
16 | "l2TokenBridgeFactoryTemplate()": "1aeef2e2",
17 | "l2WethGatewayTemplate()": "9095765e",
18 | "l2WethTemplate()": "fd40ad85",
19 | "owner()": "8da5cb5b",
20 | "renounceOwnership()": "715018a6",
21 | "retryableSender()": "36dddb97",
22 | "setDeployment(address,(address,address,address,address,address),(address,address,address,address,address,address,address,address,address))": "4c149671",
23 | "setTemplates((address,address,address,address,address,address,address,address),address,address,address,address,address,address,address,address,address,uint256)": "81fb9184",
24 | "transferOwnership(address)": "f2fde38b"
25 | }
26 |
--------------------------------------------------------------------------------
/test/signatures/L1CustomGateway:
--------------------------------------------------------------------------------
1 | {
2 | "calculateL2TokenAddress(address)": "a7e28d48",
3 | "counterpartGateway()": "2db09c1c",
4 | "encodeWithdrawal(uint256,address)": "020a6058",
5 | "finalizeInboundTransfer(address,address,address,uint256,bytes)": "2e567b36",
6 | "forceRegisterTokenToL2(address[],address[],uint256,uint256,uint256)": "1d3a689f",
7 | "getExternalCall(uint256,address,bytes)": "f68a9082",
8 | "getOutboundCalldata(address,address,address,uint256,bytes)": "a0c76a96",
9 | "inbox()": "fb0e722b",
10 | "initialize(address,address,address,address)": "f8c8765e",
11 | "l1ToL2Token(address)": "8a2dc014",
12 | "outboundTransfer(address,address,uint256,uint256,uint256,bytes)": "d2ce7d65",
13 | "outboundTransferCustomRefund(address,address,address,uint256,uint256,uint256,bytes)": "4fb1a07b",
14 | "owner()": "8da5cb5b",
15 | "postUpgradeInit()": "95fcea78",
16 | "redirectedExits(bytes32)": "bcf2e6eb",
17 | "registerTokenToL2(address,uint256,uint256,uint256)": "f26bdead",
18 | "registerTokenToL2(address,uint256,uint256,uint256,address)": "ca346d4a",
19 | "router()": "f887ea40",
20 | "setOwner(address)": "13af4035",
21 | "supportsInterface(bytes4)": "01ffc9a7",
22 | "transferExitAndCall(uint256,address,address,bytes,bytes)": "bd5f3e7d",
23 | "whitelist()": "93e59dc1"
24 | }
25 |
--------------------------------------------------------------------------------
/test/signatures/L1ERC20Gateway:
--------------------------------------------------------------------------------
1 | {
2 | "calculateL2TokenAddress(address)": "a7e28d48",
3 | "cloneableProxyHash()": "97881f8d",
4 | "counterpartGateway()": "2db09c1c",
5 | "encodeWithdrawal(uint256,address)": "020a6058",
6 | "finalizeInboundTransfer(address,address,address,uint256,bytes)": "2e567b36",
7 | "getExternalCall(uint256,address,bytes)": "f68a9082",
8 | "getOutboundCalldata(address,address,address,uint256,bytes)": "a0c76a96",
9 | "inbox()": "fb0e722b",
10 | "initialize(address,address,address,bytes32,address)": "a01893bf",
11 | "l2BeaconProxyFactory()": "70fc045f",
12 | "outboundTransfer(address,address,uint256,uint256,uint256,bytes)": "d2ce7d65",
13 | "outboundTransferCustomRefund(address,address,address,uint256,uint256,uint256,bytes)": "4fb1a07b",
14 | "postUpgradeInit()": "95fcea78",
15 | "redirectedExits(bytes32)": "bcf2e6eb",
16 | "router()": "f887ea40",
17 | "supportsInterface(bytes4)": "01ffc9a7",
18 | "transferExitAndCall(uint256,address,address,bytes,bytes)": "bd5f3e7d",
19 | "whitelist()": "93e59dc1"
20 | }
21 |
--------------------------------------------------------------------------------
/test/signatures/L1GatewayRouter:
--------------------------------------------------------------------------------
1 | {
2 | "calculateL2TokenAddress(address)": "a7e28d48",
3 | "counterpartGateway()": "2db09c1c",
4 | "defaultGateway()": "03295802",
5 | "finalizeInboundTransfer(address,address,address,uint256,bytes)": "2e567b36",
6 | "getGateway(address)": "bda009fe",
7 | "getOutboundCalldata(address,address,address,uint256,bytes)": "a0c76a96",
8 | "inbox()": "fb0e722b",
9 | "initialize(address,address,address,address,address)": "1459457a",
10 | "l1TokenToGateway(address)": "ed08fdc6",
11 | "outboundTransfer(address,address,uint256,uint256,uint256,bytes)": "d2ce7d65",
12 | "outboundTransferCustomRefund(address,address,address,uint256,uint256,uint256,bytes)": "4fb1a07b",
13 | "owner()": "8da5cb5b",
14 | "postUpgradeInit()": "95fcea78",
15 | "router()": "f887ea40",
16 | "setDefaultGateway(address,uint256,uint256,uint256)": "5625a952",
17 | "setGateway(address,uint256,uint256,uint256)": "dd614569",
18 | "setGateway(address,uint256,uint256,uint256,address)": "2d67b72d",
19 | "setGateways(address[],address[],uint256,uint256,uint256)": "658b53f4",
20 | "setOwner(address)": "13af4035",
21 | "supportsInterface(bytes4)": "01ffc9a7",
22 | "updateWhitelistSource(address)": "47466f98",
23 | "whitelist()": "93e59dc1"
24 | }
25 |
--------------------------------------------------------------------------------
/test/signatures/L1OrbitCustomGateway:
--------------------------------------------------------------------------------
1 | {
2 | "calculateL2TokenAddress(address)": "a7e28d48",
3 | "counterpartGateway()": "2db09c1c",
4 | "encodeWithdrawal(uint256,address)": "020a6058",
5 | "finalizeInboundTransfer(address,address,address,uint256,bytes)": "2e567b36",
6 | "forceRegisterTokenToL2(address[],address[],uint256,uint256,uint256)": "1d3a689f",
7 | "forceRegisterTokenToL2(address[],address[],uint256,uint256,uint256,uint256)": "85f25597",
8 | "getExternalCall(uint256,address,bytes)": "f68a9082",
9 | "getOutboundCalldata(address,address,address,uint256,bytes)": "a0c76a96",
10 | "inbox()": "fb0e722b",
11 | "initialize(address,address,address,address)": "f8c8765e",
12 | "l1ToL2Token(address)": "8a2dc014",
13 | "outboundTransfer(address,address,uint256,uint256,uint256,bytes)": "d2ce7d65",
14 | "outboundTransferCustomRefund(address,address,address,uint256,uint256,uint256,bytes)": "4fb1a07b",
15 | "owner()": "8da5cb5b",
16 | "postUpgradeInit()": "95fcea78",
17 | "redirectedExits(bytes32)": "bcf2e6eb",
18 | "registerTokenToL2(address,uint256,uint256,uint256)": "f26bdead",
19 | "registerTokenToL2(address,uint256,uint256,uint256,address)": "ca346d4a",
20 | "registerTokenToL2(address,uint256,uint256,uint256,address,uint256)": "37daacad",
21 | "registerTokenToL2(address,uint256,uint256,uint256,uint256)": "3e8ee3df",
22 | "router()": "f887ea40",
23 | "setOwner(address)": "13af4035",
24 | "supportsInterface(bytes4)": "01ffc9a7",
25 | "transferExitAndCall(uint256,address,address,bytes,bytes)": "bd5f3e7d",
26 | "whitelist()": "93e59dc1"
27 | }
28 |
--------------------------------------------------------------------------------
/test/signatures/L1OrbitERC20Gateway:
--------------------------------------------------------------------------------
1 | {
2 | "calculateL2TokenAddress(address)": "a7e28d48",
3 | "cloneableProxyHash()": "97881f8d",
4 | "counterpartGateway()": "2db09c1c",
5 | "encodeWithdrawal(uint256,address)": "020a6058",
6 | "finalizeInboundTransfer(address,address,address,uint256,bytes)": "2e567b36",
7 | "getExternalCall(uint256,address,bytes)": "f68a9082",
8 | "getOutboundCalldata(address,address,address,uint256,bytes)": "a0c76a96",
9 | "inbox()": "fb0e722b",
10 | "initialize(address,address,address,bytes32,address)": "a01893bf",
11 | "l2BeaconProxyFactory()": "70fc045f",
12 | "outboundTransfer(address,address,uint256,uint256,uint256,bytes)": "d2ce7d65",
13 | "outboundTransferCustomRefund(address,address,address,uint256,uint256,uint256,bytes)": "4fb1a07b",
14 | "postUpgradeInit()": "95fcea78",
15 | "redirectedExits(bytes32)": "bcf2e6eb",
16 | "router()": "f887ea40",
17 | "supportsInterface(bytes4)": "01ffc9a7",
18 | "transferExitAndCall(uint256,address,address,bytes,bytes)": "bd5f3e7d",
19 | "whitelist()": "93e59dc1"
20 | }
21 |
--------------------------------------------------------------------------------
/test/signatures/L1OrbitGatewayRouter:
--------------------------------------------------------------------------------
1 | {
2 | "calculateL2TokenAddress(address)": "a7e28d48",
3 | "counterpartGateway()": "2db09c1c",
4 | "defaultGateway()": "03295802",
5 | "finalizeInboundTransfer(address,address,address,uint256,bytes)": "2e567b36",
6 | "getGateway(address)": "bda009fe",
7 | "getOutboundCalldata(address,address,address,uint256,bytes)": "a0c76a96",
8 | "inbox()": "fb0e722b",
9 | "initialize(address,address,address,address,address)": "1459457a",
10 | "l1TokenToGateway(address)": "ed08fdc6",
11 | "outboundTransfer(address,address,uint256,uint256,uint256,bytes)": "d2ce7d65",
12 | "outboundTransferCustomRefund(address,address,address,uint256,uint256,uint256,bytes)": "4fb1a07b",
13 | "owner()": "8da5cb5b",
14 | "postUpgradeInit()": "95fcea78",
15 | "router()": "f887ea40",
16 | "setDefaultGateway(address,uint256,uint256,uint256)": "5625a952",
17 | "setDefaultGateway(address,uint256,uint256,uint256,uint256)": "c9a96997",
18 | "setGateway(address,uint256,uint256,uint256)": "dd614569",
19 | "setGateway(address,uint256,uint256,uint256,address)": "2d67b72d",
20 | "setGateway(address,uint256,uint256,uint256,address,uint256)": "d7f7459c",
21 | "setGateway(address,uint256,uint256,uint256,uint256)": "dc121927",
22 | "setGateways(address[],address[],uint256,uint256,uint256)": "658b53f4",
23 | "setGateways(address[],address[],uint256,uint256,uint256,uint256)": "55654af8",
24 | "setOwner(address)": "13af4035",
25 | "supportsInterface(bytes4)": "01ffc9a7",
26 | "updateWhitelistSource(address)": "47466f98",
27 | "whitelist()": "93e59dc1"
28 | }
29 |
--------------------------------------------------------------------------------
/test/signatures/L1OrbitReverseCustomGateway:
--------------------------------------------------------------------------------
1 | {
2 | "calculateL2TokenAddress(address)": "a7e28d48",
3 | "counterpartGateway()": "2db09c1c",
4 | "encodeWithdrawal(uint256,address)": "020a6058",
5 | "finalizeInboundTransfer(address,address,address,uint256,bytes)": "2e567b36",
6 | "forceRegisterTokenToL2(address[],address[],uint256,uint256,uint256)": "1d3a689f",
7 | "forceRegisterTokenToL2(address[],address[],uint256,uint256,uint256,uint256)": "85f25597",
8 | "getExternalCall(uint256,address,bytes)": "f68a9082",
9 | "getOutboundCalldata(address,address,address,uint256,bytes)": "a0c76a96",
10 | "inbox()": "fb0e722b",
11 | "initialize(address,address,address,address)": "f8c8765e",
12 | "l1ToL2Token(address)": "8a2dc014",
13 | "outboundTransfer(address,address,uint256,uint256,uint256,bytes)": "d2ce7d65",
14 | "outboundTransferCustomRefund(address,address,address,uint256,uint256,uint256,bytes)": "4fb1a07b",
15 | "owner()": "8da5cb5b",
16 | "postUpgradeInit()": "95fcea78",
17 | "redirectedExits(bytes32)": "bcf2e6eb",
18 | "registerTokenToL2(address,uint256,uint256,uint256)": "f26bdead",
19 | "registerTokenToL2(address,uint256,uint256,uint256,address)": "ca346d4a",
20 | "registerTokenToL2(address,uint256,uint256,uint256,address,uint256)": "37daacad",
21 | "registerTokenToL2(address,uint256,uint256,uint256,uint256)": "3e8ee3df",
22 | "router()": "f887ea40",
23 | "setOwner(address)": "13af4035",
24 | "supportsInterface(bytes4)": "01ffc9a7",
25 | "transferExitAndCall(uint256,address,address,bytes,bytes)": "bd5f3e7d",
26 | "whitelist()": "93e59dc1"
27 | }
28 |
--------------------------------------------------------------------------------
/test/signatures/L1OrbitUSDCGateway:
--------------------------------------------------------------------------------
1 | {
2 | "burnAmount()": "486a7e6b",
3 | "burnLockedUSDC()": "8a5e52bb",
4 | "burner()": "27810b6e",
5 | "calculateL2TokenAddress(address)": "a7e28d48",
6 | "counterpartGateway()": "2db09c1c",
7 | "depositsPaused()": "60da3e83",
8 | "encodeWithdrawal(uint256,address)": "020a6058",
9 | "finalizeInboundTransfer(address,address,address,uint256,bytes)": "2e567b36",
10 | "getExternalCall(uint256,address,bytes)": "f68a9082",
11 | "getOutboundCalldata(address,address,address,uint256,bytes)": "a0c76a96",
12 | "inbox()": "fb0e722b",
13 | "initialize(address,address,address,address,address,address)": "cc2a9a5b",
14 | "l1USDC()": "a6f73669",
15 | "l2USDC()": "29e96f9e",
16 | "outboundTransfer(address,address,uint256,uint256,uint256,bytes)": "d2ce7d65",
17 | "outboundTransferCustomRefund(address,address,address,uint256,uint256,uint256,bytes)": "4fb1a07b",
18 | "owner()": "8da5cb5b",
19 | "pauseDeposits()": "02191980",
20 | "postUpgradeInit()": "95fcea78",
21 | "redirectedExits(bytes32)": "bcf2e6eb",
22 | "router()": "f887ea40",
23 | "setBurnAmount(uint256)": "cc43f3d3",
24 | "setBurner(address)": "a996d6ce",
25 | "setOwner(address)": "13af4035",
26 | "supportsInterface(bytes4)": "01ffc9a7",
27 | "transferExitAndCall(uint256,address,address,bytes,bytes)": "bd5f3e7d",
28 | "unpauseDeposits()": "63d8882a"
29 | }
30 |
--------------------------------------------------------------------------------
/test/signatures/L1ReverseCustomGateway:
--------------------------------------------------------------------------------
1 | {
2 | "calculateL2TokenAddress(address)": "a7e28d48",
3 | "counterpartGateway()": "2db09c1c",
4 | "encodeWithdrawal(uint256,address)": "020a6058",
5 | "finalizeInboundTransfer(address,address,address,uint256,bytes)": "2e567b36",
6 | "forceRegisterTokenToL2(address[],address[],uint256,uint256,uint256)": "1d3a689f",
7 | "getExternalCall(uint256,address,bytes)": "f68a9082",
8 | "getOutboundCalldata(address,address,address,uint256,bytes)": "a0c76a96",
9 | "inbox()": "fb0e722b",
10 | "initialize(address,address,address,address)": "f8c8765e",
11 | "l1ToL2Token(address)": "8a2dc014",
12 | "outboundTransfer(address,address,uint256,uint256,uint256,bytes)": "d2ce7d65",
13 | "outboundTransferCustomRefund(address,address,address,uint256,uint256,uint256,bytes)": "4fb1a07b",
14 | "owner()": "8da5cb5b",
15 | "postUpgradeInit()": "95fcea78",
16 | "redirectedExits(bytes32)": "bcf2e6eb",
17 | "registerTokenToL2(address,uint256,uint256,uint256)": "f26bdead",
18 | "registerTokenToL2(address,uint256,uint256,uint256,address)": "ca346d4a",
19 | "router()": "f887ea40",
20 | "setOwner(address)": "13af4035",
21 | "supportsInterface(bytes4)": "01ffc9a7",
22 | "transferExitAndCall(uint256,address,address,bytes,bytes)": "bd5f3e7d",
23 | "whitelist()": "93e59dc1"
24 | }
25 |
--------------------------------------------------------------------------------
/test/signatures/L1TokenBridgeRetryableSender:
--------------------------------------------------------------------------------
1 | {
2 | "initialize()": "8129fc1c",
3 | "owner()": "8da5cb5b",
4 | "renounceOwnership()": "715018a6",
5 | "sendRetryable((address,address,address,address,uint256,uint256,uint256),(address,address,address,address,address,address,address),(address,address,address,address,address),address,address,address,address)": "5fc788d6",
6 | "transferOwnership(address)": "f2fde38b"
7 | }
8 |
--------------------------------------------------------------------------------
/test/signatures/L1USDCGateway:
--------------------------------------------------------------------------------
1 | {
2 | "burnAmount()": "486a7e6b",
3 | "burnLockedUSDC()": "8a5e52bb",
4 | "burner()": "27810b6e",
5 | "calculateL2TokenAddress(address)": "a7e28d48",
6 | "counterpartGateway()": "2db09c1c",
7 | "depositsPaused()": "60da3e83",
8 | "encodeWithdrawal(uint256,address)": "020a6058",
9 | "finalizeInboundTransfer(address,address,address,uint256,bytes)": "2e567b36",
10 | "getExternalCall(uint256,address,bytes)": "f68a9082",
11 | "getOutboundCalldata(address,address,address,uint256,bytes)": "a0c76a96",
12 | "inbox()": "fb0e722b",
13 | "initialize(address,address,address,address,address,address)": "cc2a9a5b",
14 | "l1USDC()": "a6f73669",
15 | "l2USDC()": "29e96f9e",
16 | "outboundTransfer(address,address,uint256,uint256,uint256,bytes)": "d2ce7d65",
17 | "outboundTransferCustomRefund(address,address,address,uint256,uint256,uint256,bytes)": "4fb1a07b",
18 | "owner()": "8da5cb5b",
19 | "pauseDeposits()": "02191980",
20 | "postUpgradeInit()": "95fcea78",
21 | "redirectedExits(bytes32)": "bcf2e6eb",
22 | "router()": "f887ea40",
23 | "setBurnAmount(uint256)": "cc43f3d3",
24 | "setBurner(address)": "a996d6ce",
25 | "setOwner(address)": "13af4035",
26 | "supportsInterface(bytes4)": "01ffc9a7",
27 | "transferExitAndCall(uint256,address,address,bytes,bytes)": "bd5f3e7d",
28 | "unpauseDeposits()": "63d8882a"
29 | }
30 |
--------------------------------------------------------------------------------
/test/signatures/L1WethGateway:
--------------------------------------------------------------------------------
1 | {
2 | "calculateL2TokenAddress(address)": "a7e28d48",
3 | "counterpartGateway()": "2db09c1c",
4 | "encodeWithdrawal(uint256,address)": "020a6058",
5 | "finalizeInboundTransfer(address,address,address,uint256,bytes)": "2e567b36",
6 | "getExternalCall(uint256,address,bytes)": "f68a9082",
7 | "getOutboundCalldata(address,address,address,uint256,bytes)": "a0c76a96",
8 | "inbox()": "fb0e722b",
9 | "initialize(address,address,address,address,address)": "1459457a",
10 | "l1Weth()": "146bf4b1",
11 | "l2Weth()": "247b2768",
12 | "outboundTransfer(address,address,uint256,uint256,uint256,bytes)": "d2ce7d65",
13 | "outboundTransferCustomRefund(address,address,address,uint256,uint256,uint256,bytes)": "4fb1a07b",
14 | "postUpgradeInit()": "95fcea78",
15 | "redirectedExits(bytes32)": "bcf2e6eb",
16 | "router()": "f887ea40",
17 | "supportsInterface(bytes4)": "01ffc9a7",
18 | "transferExitAndCall(uint256,address,address,bytes,bytes)": "bd5f3e7d"
19 | }
20 |
--------------------------------------------------------------------------------
/test/signatures/L2AtomicTokenBridgeFactory:
--------------------------------------------------------------------------------
1 | {
2 | "deployL2Contracts((bytes,bytes,bytes,bytes,bytes,bytes,bytes),address,address,address,address,address,address,address,address)": "b1c7a870"
3 | }
4 |
--------------------------------------------------------------------------------
/test/signatures/L2CustomGateway:
--------------------------------------------------------------------------------
1 | {
2 | "calculateL2TokenAddress(address)": "a7e28d48",
3 | "counterpartGateway()": "2db09c1c",
4 | "exitNum()": "015234ab",
5 | "finalizeInboundTransfer(address,address,address,uint256,bytes)": "2e567b36",
6 | "getOutboundCalldata(address,address,address,uint256,bytes)": "a0c76a96",
7 | "initialize(address,address)": "485cc955",
8 | "l1ToL2Token(address)": "8a2dc014",
9 | "outboundTransfer(address,address,uint256,bytes)": "7b3a3c8b",
10 | "outboundTransfer(address,address,uint256,uint256,uint256,bytes)": "d2ce7d65",
11 | "postUpgradeInit()": "95fcea78",
12 | "registerTokenFromL1(address[],address[])": "d4f5532f",
13 | "router()": "f887ea40"
14 | }
15 |
--------------------------------------------------------------------------------
/test/signatures/L2ERC20Gateway:
--------------------------------------------------------------------------------
1 | {
2 | "beaconProxyFactory()": "c05e6a95",
3 | "calculateL2TokenAddress(address)": "a7e28d48",
4 | "cloneableProxyHash()": "97881f8d",
5 | "counterpartGateway()": "2db09c1c",
6 | "exitNum()": "015234ab",
7 | "finalizeInboundTransfer(address,address,address,uint256,bytes)": "2e567b36",
8 | "getOutboundCalldata(address,address,address,uint256,bytes)": "a0c76a96",
9 | "getUserSalt(address)": "569f26ff",
10 | "initialize(address,address,address)": "c0c53b8b",
11 | "outboundTransfer(address,address,uint256,bytes)": "7b3a3c8b",
12 | "outboundTransfer(address,address,uint256,uint256,uint256,bytes)": "d2ce7d65",
13 | "postUpgradeInit()": "95fcea78",
14 | "router()": "f887ea40"
15 | }
16 |
--------------------------------------------------------------------------------
/test/signatures/L2GatewayRouter:
--------------------------------------------------------------------------------
1 | {
2 | "calculateL2TokenAddress(address)": "a7e28d48",
3 | "counterpartGateway()": "2db09c1c",
4 | "defaultGateway()": "03295802",
5 | "finalizeInboundTransfer(address,address,address,uint256,bytes)": "2e567b36",
6 | "getGateway(address)": "bda009fe",
7 | "getOutboundCalldata(address,address,address,uint256,bytes)": "a0c76a96",
8 | "initialize(address,address)": "485cc955",
9 | "l1TokenToGateway(address)": "ed08fdc6",
10 | "outboundTransfer(address,address,uint256,bytes)": "7b3a3c8b",
11 | "outboundTransfer(address,address,uint256,uint256,uint256,bytes)": "d2ce7d65",
12 | "postUpgradeInit()": "95fcea78",
13 | "router()": "f887ea40",
14 | "setDefaultGateway(address)": "f7c9362f",
15 | "setGateway(address[],address[])": "4201f985"
16 | }
17 |
--------------------------------------------------------------------------------
/test/signatures/L2ReverseCustomGateway:
--------------------------------------------------------------------------------
1 | {
2 | "calculateL2TokenAddress(address)": "a7e28d48",
3 | "counterpartGateway()": "2db09c1c",
4 | "exitNum()": "015234ab",
5 | "finalizeInboundTransfer(address,address,address,uint256,bytes)": "2e567b36",
6 | "getOutboundCalldata(address,address,address,uint256,bytes)": "a0c76a96",
7 | "initialize(address,address)": "485cc955",
8 | "l1ToL2Token(address)": "8a2dc014",
9 | "outboundTransfer(address,address,uint256,bytes)": "7b3a3c8b",
10 | "outboundTransfer(address,address,uint256,uint256,uint256,bytes)": "d2ce7d65",
11 | "postUpgradeInit()": "95fcea78",
12 | "registerTokenFromL1(address[],address[])": "d4f5532f",
13 | "router()": "f887ea40"
14 | }
15 |
--------------------------------------------------------------------------------
/test/signatures/L2USDCGateway:
--------------------------------------------------------------------------------
1 | {
2 | "calculateL2TokenAddress(address)": "a7e28d48",
3 | "counterpartGateway()": "2db09c1c",
4 | "exitNum()": "015234ab",
5 | "finalizeInboundTransfer(address,address,address,uint256,bytes)": "2e567b36",
6 | "getOutboundCalldata(address,address,address,uint256,bytes)": "a0c76a96",
7 | "initialize(address,address,address,address,address)": "1459457a",
8 | "l1USDC()": "a6f73669",
9 | "l2USDC()": "29e96f9e",
10 | "outboundTransfer(address,address,uint256,bytes)": "7b3a3c8b",
11 | "outboundTransfer(address,address,uint256,uint256,uint256,bytes)": "d2ce7d65",
12 | "owner()": "8da5cb5b",
13 | "pauseWithdrawals()": "56bb54a7",
14 | "postUpgradeInit()": "95fcea78",
15 | "router()": "f887ea40",
16 | "setOwner(address)": "13af4035",
17 | "setUsdcOwnershipTransferrer(address)": "54d3a598",
18 | "transferUSDCRoles(address)": "c689fc34",
19 | "unpauseWithdrawals()": "e4c4be58",
20 | "usdcOwnershipTransferrer()": "77403988",
21 | "withdrawalsPaused()": "e9f2838e"
22 | }
23 |
--------------------------------------------------------------------------------
/test/signatures/L2WethGateway:
--------------------------------------------------------------------------------
1 | {
2 | "calculateL2TokenAddress(address)": "a7e28d48",
3 | "counterpartGateway()": "2db09c1c",
4 | "exitNum()": "015234ab",
5 | "finalizeInboundTransfer(address,address,address,uint256,bytes)": "2e567b36",
6 | "getOutboundCalldata(address,address,address,uint256,bytes)": "a0c76a96",
7 | "initialize(address,address,address,address)": "f8c8765e",
8 | "l1Weth()": "146bf4b1",
9 | "l2Weth()": "247b2768",
10 | "outboundTransfer(address,address,uint256,bytes)": "7b3a3c8b",
11 | "outboundTransfer(address,address,uint256,uint256,uint256,bytes)": "d2ce7d65",
12 | "postUpgradeInit()": "95fcea78",
13 | "router()": "f887ea40"
14 | }
15 |
--------------------------------------------------------------------------------
/test/signatures/StandardArbERC20:
--------------------------------------------------------------------------------
1 | {
2 | "DOMAIN_SEPARATOR()": "3644e515",
3 | "allowance(address,address)": "dd62ed3e",
4 | "approve(address,uint256)": "095ea7b3",
5 | "balanceOf(address)": "70a08231",
6 | "bridgeBurn(address,uint256)": "74f4f547",
7 | "bridgeInit(address,bytes)": "189db7d2",
8 | "bridgeMint(address,uint256)": "8c2a993e",
9 | "decimals()": "313ce567",
10 | "decreaseAllowance(address,uint256)": "a457c2d7",
11 | "increaseAllowance(address,uint256)": "39509351",
12 | "isMaster()": "6f791d29",
13 | "l1Address()": "c2eeeebd",
14 | "l2Gateway()": "8fa74a0e",
15 | "name()": "06fdde03",
16 | "nonces(address)": "7ecebe00",
17 | "permit(address,address,uint256,uint256,uint8,bytes32,bytes32)": "d505accf",
18 | "symbol()": "95d89b41",
19 | "totalSupply()": "18160ddd",
20 | "transfer(address,uint256)": "a9059cbb",
21 | "transferAndCall(address,uint256,bytes)": "4000aea0",
22 | "transferFrom(address,address,uint256)": "23b872dd"
23 | }
24 |
--------------------------------------------------------------------------------
/test/storage/L1CustomGateway:
--------------------------------------------------------------------------------
1 | | Name | Type | Slot | Offset | Bytes | Contract |
2 | |--------------------|---------------------------------------------------------------|------|--------|-------|----------------------------------------------------------------------------|
3 | | counterpartGateway | address | 0 | 0 | 20 | contracts/tokenbridge/ethereum/gateway/L1CustomGateway.sol:L1CustomGateway |
4 | | router | address | 1 | 0 | 20 | contracts/tokenbridge/ethereum/gateway/L1CustomGateway.sol:L1CustomGateway |
5 | | inbox | address | 2 | 0 | 20 | contracts/tokenbridge/ethereum/gateway/L1CustomGateway.sol:L1CustomGateway |
6 | | redirectedExits | mapping(bytes32 => struct L1ArbitrumExtendedGateway.ExitData) | 3 | 0 | 32 | contracts/tokenbridge/ethereum/gateway/L1CustomGateway.sol:L1CustomGateway |
7 | | l1ToL2Token | mapping(address => address) | 4 | 0 | 32 | contracts/tokenbridge/ethereum/gateway/L1CustomGateway.sol:L1CustomGateway |
8 | | owner | address | 5 | 0 | 20 | contracts/tokenbridge/ethereum/gateway/L1CustomGateway.sol:L1CustomGateway |
9 | | whitelist | address | 6 | 0 | 20 | contracts/tokenbridge/ethereum/gateway/L1CustomGateway.sol:L1CustomGateway |
10 | | _status | uint256 | 7 | 0 | 32 | contracts/tokenbridge/ethereum/gateway/L1CustomGateway.sol:L1CustomGateway |
11 |
--------------------------------------------------------------------------------
/test/storage/L1ERC20Gateway:
--------------------------------------------------------------------------------
1 | | Name | Type | Slot | Offset | Bytes | Contract |
2 | |----------------------|---------------------------------------------------------------|------|--------|-------|--------------------------------------------------------------------------|
3 | | counterpartGateway | address | 0 | 0 | 20 | contracts/tokenbridge/ethereum/gateway/L1ERC20Gateway.sol:L1ERC20Gateway |
4 | | router | address | 1 | 0 | 20 | contracts/tokenbridge/ethereum/gateway/L1ERC20Gateway.sol:L1ERC20Gateway |
5 | | inbox | address | 2 | 0 | 20 | contracts/tokenbridge/ethereum/gateway/L1ERC20Gateway.sol:L1ERC20Gateway |
6 | | redirectedExits | mapping(bytes32 => struct L1ArbitrumExtendedGateway.ExitData) | 3 | 0 | 32 | contracts/tokenbridge/ethereum/gateway/L1ERC20Gateway.sol:L1ERC20Gateway |
7 | | cloneableProxyHash | bytes32 | 4 | 0 | 32 | contracts/tokenbridge/ethereum/gateway/L1ERC20Gateway.sol:L1ERC20Gateway |
8 | | l2BeaconProxyFactory | address | 5 | 0 | 20 | contracts/tokenbridge/ethereum/gateway/L1ERC20Gateway.sol:L1ERC20Gateway |
9 | | whitelist | address | 6 | 0 | 20 | contracts/tokenbridge/ethereum/gateway/L1ERC20Gateway.sol:L1ERC20Gateway |
10 | | _status | uint256 | 7 | 0 | 32 | contracts/tokenbridge/ethereum/gateway/L1ERC20Gateway.sol:L1ERC20Gateway |
11 |
--------------------------------------------------------------------------------
/test/storage/L1GatewayRouter:
--------------------------------------------------------------------------------
1 | | Name | Type | Slot | Offset | Bytes | Contract |
2 | |--------------------|-----------------------------|------|--------|-------|----------------------------------------------------------------------------|
3 | | whitelist | address | 0 | 0 | 20 | contracts/tokenbridge/ethereum/gateway/L1GatewayRouter.sol:L1GatewayRouter |
4 | | counterpartGateway | address | 1 | 0 | 20 | contracts/tokenbridge/ethereum/gateway/L1GatewayRouter.sol:L1GatewayRouter |
5 | | router | address | 2 | 0 | 20 | contracts/tokenbridge/ethereum/gateway/L1GatewayRouter.sol:L1GatewayRouter |
6 | | l1TokenToGateway | mapping(address => address) | 3 | 0 | 32 | contracts/tokenbridge/ethereum/gateway/L1GatewayRouter.sol:L1GatewayRouter |
7 | | defaultGateway | address | 4 | 0 | 20 | contracts/tokenbridge/ethereum/gateway/L1GatewayRouter.sol:L1GatewayRouter |
8 | | owner | address | 5 | 0 | 20 | contracts/tokenbridge/ethereum/gateway/L1GatewayRouter.sol:L1GatewayRouter |
9 | | inbox | address | 6 | 0 | 20 | contracts/tokenbridge/ethereum/gateway/L1GatewayRouter.sol:L1GatewayRouter |
10 |
--------------------------------------------------------------------------------
/test/storage/L1OrbitCustomGateway:
--------------------------------------------------------------------------------
1 | | Name | Type | Slot | Offset | Bytes | Contract |
2 | |--------------------|---------------------------------------------------------------|------|--------|-------|--------------------------------------------------------------------------------------|
3 | | counterpartGateway | address | 0 | 0 | 20 | contracts/tokenbridge/ethereum/gateway/L1OrbitCustomGateway.sol:L1OrbitCustomGateway |
4 | | router | address | 1 | 0 | 20 | contracts/tokenbridge/ethereum/gateway/L1OrbitCustomGateway.sol:L1OrbitCustomGateway |
5 | | inbox | address | 2 | 0 | 20 | contracts/tokenbridge/ethereum/gateway/L1OrbitCustomGateway.sol:L1OrbitCustomGateway |
6 | | redirectedExits | mapping(bytes32 => struct L1ArbitrumExtendedGateway.ExitData) | 3 | 0 | 32 | contracts/tokenbridge/ethereum/gateway/L1OrbitCustomGateway.sol:L1OrbitCustomGateway |
7 | | l1ToL2Token | mapping(address => address) | 4 | 0 | 32 | contracts/tokenbridge/ethereum/gateway/L1OrbitCustomGateway.sol:L1OrbitCustomGateway |
8 | | owner | address | 5 | 0 | 20 | contracts/tokenbridge/ethereum/gateway/L1OrbitCustomGateway.sol:L1OrbitCustomGateway |
9 | | whitelist | address | 6 | 0 | 20 | contracts/tokenbridge/ethereum/gateway/L1OrbitCustomGateway.sol:L1OrbitCustomGateway |
10 | | _status | uint256 | 7 | 0 | 32 | contracts/tokenbridge/ethereum/gateway/L1OrbitCustomGateway.sol:L1OrbitCustomGateway |
11 |
--------------------------------------------------------------------------------
/test/storage/L1OrbitERC20Gateway:
--------------------------------------------------------------------------------
1 | | Name | Type | Slot | Offset | Bytes | Contract |
2 | |----------------------|---------------------------------------------------------------|------|--------|-------|------------------------------------------------------------------------------------|
3 | | counterpartGateway | address | 0 | 0 | 20 | contracts/tokenbridge/ethereum/gateway/L1OrbitERC20Gateway.sol:L1OrbitERC20Gateway |
4 | | router | address | 1 | 0 | 20 | contracts/tokenbridge/ethereum/gateway/L1OrbitERC20Gateway.sol:L1OrbitERC20Gateway |
5 | | inbox | address | 2 | 0 | 20 | contracts/tokenbridge/ethereum/gateway/L1OrbitERC20Gateway.sol:L1OrbitERC20Gateway |
6 | | redirectedExits | mapping(bytes32 => struct L1ArbitrumExtendedGateway.ExitData) | 3 | 0 | 32 | contracts/tokenbridge/ethereum/gateway/L1OrbitERC20Gateway.sol:L1OrbitERC20Gateway |
7 | | cloneableProxyHash | bytes32 | 4 | 0 | 32 | contracts/tokenbridge/ethereum/gateway/L1OrbitERC20Gateway.sol:L1OrbitERC20Gateway |
8 | | l2BeaconProxyFactory | address | 5 | 0 | 20 | contracts/tokenbridge/ethereum/gateway/L1OrbitERC20Gateway.sol:L1OrbitERC20Gateway |
9 | | whitelist | address | 6 | 0 | 20 | contracts/tokenbridge/ethereum/gateway/L1OrbitERC20Gateway.sol:L1OrbitERC20Gateway |
10 | | _status | uint256 | 7 | 0 | 32 | contracts/tokenbridge/ethereum/gateway/L1OrbitERC20Gateway.sol:L1OrbitERC20Gateway |
11 |
--------------------------------------------------------------------------------
/test/storage/L1OrbitGatewayRouter:
--------------------------------------------------------------------------------
1 | | Name | Type | Slot | Offset | Bytes | Contract |
2 | |--------------------|-----------------------------|------|--------|-------|--------------------------------------------------------------------------------------|
3 | | whitelist | address | 0 | 0 | 20 | contracts/tokenbridge/ethereum/gateway/L1OrbitGatewayRouter.sol:L1OrbitGatewayRouter |
4 | | counterpartGateway | address | 1 | 0 | 20 | contracts/tokenbridge/ethereum/gateway/L1OrbitGatewayRouter.sol:L1OrbitGatewayRouter |
5 | | router | address | 2 | 0 | 20 | contracts/tokenbridge/ethereum/gateway/L1OrbitGatewayRouter.sol:L1OrbitGatewayRouter |
6 | | l1TokenToGateway | mapping(address => address) | 3 | 0 | 32 | contracts/tokenbridge/ethereum/gateway/L1OrbitGatewayRouter.sol:L1OrbitGatewayRouter |
7 | | defaultGateway | address | 4 | 0 | 20 | contracts/tokenbridge/ethereum/gateway/L1OrbitGatewayRouter.sol:L1OrbitGatewayRouter |
8 | | owner | address | 5 | 0 | 20 | contracts/tokenbridge/ethereum/gateway/L1OrbitGatewayRouter.sol:L1OrbitGatewayRouter |
9 | | inbox | address | 6 | 0 | 20 | contracts/tokenbridge/ethereum/gateway/L1OrbitGatewayRouter.sol:L1OrbitGatewayRouter |
10 |
--------------------------------------------------------------------------------
/test/storage/L1OrbitReverseCustomGateway:
--------------------------------------------------------------------------------
1 | | Name | Type | Slot | Offset | Bytes | Contract |
2 | |--------------------|---------------------------------------------------------------|------|--------|-------|----------------------------------------------------------------------------------------------------|
3 | | counterpartGateway | address | 0 | 0 | 20 | contracts/tokenbridge/ethereum/gateway/L1OrbitReverseCustomGateway.sol:L1OrbitReverseCustomGateway |
4 | | router | address | 1 | 0 | 20 | contracts/tokenbridge/ethereum/gateway/L1OrbitReverseCustomGateway.sol:L1OrbitReverseCustomGateway |
5 | | inbox | address | 2 | 0 | 20 | contracts/tokenbridge/ethereum/gateway/L1OrbitReverseCustomGateway.sol:L1OrbitReverseCustomGateway |
6 | | redirectedExits | mapping(bytes32 => struct L1ArbitrumExtendedGateway.ExitData) | 3 | 0 | 32 | contracts/tokenbridge/ethereum/gateway/L1OrbitReverseCustomGateway.sol:L1OrbitReverseCustomGateway |
7 | | l1ToL2Token | mapping(address => address) | 4 | 0 | 32 | contracts/tokenbridge/ethereum/gateway/L1OrbitReverseCustomGateway.sol:L1OrbitReverseCustomGateway |
8 | | owner | address | 5 | 0 | 20 | contracts/tokenbridge/ethereum/gateway/L1OrbitReverseCustomGateway.sol:L1OrbitReverseCustomGateway |
9 | | whitelist | address | 6 | 0 | 20 | contracts/tokenbridge/ethereum/gateway/L1OrbitReverseCustomGateway.sol:L1OrbitReverseCustomGateway |
10 | | _status | uint256 | 7 | 0 | 32 | contracts/tokenbridge/ethereum/gateway/L1OrbitReverseCustomGateway.sol:L1OrbitReverseCustomGateway |
11 |
--------------------------------------------------------------------------------
/test/storage/L1OrbitUSDCGateway:
--------------------------------------------------------------------------------
1 | | Name | Type | Slot | Offset | Bytes | Contract |
2 | |--------------------|---------------------------------------------------------------|------|--------|-------|----------------------------------------------------------------------------------|
3 | | counterpartGateway | address | 0 | 0 | 20 | contracts/tokenbridge/ethereum/gateway/L1OrbitUSDCGateway.sol:L1OrbitUSDCGateway |
4 | | router | address | 1 | 0 | 20 | contracts/tokenbridge/ethereum/gateway/L1OrbitUSDCGateway.sol:L1OrbitUSDCGateway |
5 | | inbox | address | 2 | 0 | 20 | contracts/tokenbridge/ethereum/gateway/L1OrbitUSDCGateway.sol:L1OrbitUSDCGateway |
6 | | redirectedExits | mapping(bytes32 => struct L1ArbitrumExtendedGateway.ExitData) | 3 | 0 | 32 | contracts/tokenbridge/ethereum/gateway/L1OrbitUSDCGateway.sol:L1OrbitUSDCGateway |
7 | | l1USDC | address | 4 | 0 | 20 | contracts/tokenbridge/ethereum/gateway/L1OrbitUSDCGateway.sol:L1OrbitUSDCGateway |
8 | | l2USDC | address | 5 | 0 | 20 | contracts/tokenbridge/ethereum/gateway/L1OrbitUSDCGateway.sol:L1OrbitUSDCGateway |
9 | | owner | address | 6 | 0 | 20 | contracts/tokenbridge/ethereum/gateway/L1OrbitUSDCGateway.sol:L1OrbitUSDCGateway |
10 | | burner | address | 7 | 0 | 20 | contracts/tokenbridge/ethereum/gateway/L1OrbitUSDCGateway.sol:L1OrbitUSDCGateway |
11 | | depositsPaused | bool | 7 | 20 | 1 | contracts/tokenbridge/ethereum/gateway/L1OrbitUSDCGateway.sol:L1OrbitUSDCGateway |
12 | | burnAmount | uint256 | 8 | 0 | 32 | contracts/tokenbridge/ethereum/gateway/L1OrbitUSDCGateway.sol:L1OrbitUSDCGateway |
13 |
--------------------------------------------------------------------------------
/test/storage/L1ReverseCustomGateway:
--------------------------------------------------------------------------------
1 | | Name | Type | Slot | Offset | Bytes | Contract |
2 | |--------------------|---------------------------------------------------------------|------|--------|-------|------------------------------------------------------------------------------------------|
3 | | counterpartGateway | address | 0 | 0 | 20 | contracts/tokenbridge/ethereum/gateway/L1ReverseCustomGateway.sol:L1ReverseCustomGateway |
4 | | router | address | 1 | 0 | 20 | contracts/tokenbridge/ethereum/gateway/L1ReverseCustomGateway.sol:L1ReverseCustomGateway |
5 | | inbox | address | 2 | 0 | 20 | contracts/tokenbridge/ethereum/gateway/L1ReverseCustomGateway.sol:L1ReverseCustomGateway |
6 | | redirectedExits | mapping(bytes32 => struct L1ArbitrumExtendedGateway.ExitData) | 3 | 0 | 32 | contracts/tokenbridge/ethereum/gateway/L1ReverseCustomGateway.sol:L1ReverseCustomGateway |
7 | | l1ToL2Token | mapping(address => address) | 4 | 0 | 32 | contracts/tokenbridge/ethereum/gateway/L1ReverseCustomGateway.sol:L1ReverseCustomGateway |
8 | | owner | address | 5 | 0 | 20 | contracts/tokenbridge/ethereum/gateway/L1ReverseCustomGateway.sol:L1ReverseCustomGateway |
9 | | whitelist | address | 6 | 0 | 20 | contracts/tokenbridge/ethereum/gateway/L1ReverseCustomGateway.sol:L1ReverseCustomGateway |
10 | | _status | uint256 | 7 | 0 | 32 | contracts/tokenbridge/ethereum/gateway/L1ReverseCustomGateway.sol:L1ReverseCustomGateway |
11 |
--------------------------------------------------------------------------------
/test/storage/L1TokenBridgeRetryableSender:
--------------------------------------------------------------------------------
1 | | Name | Type | Slot | Offset | Bytes | Contract |
2 | |---------------|-------------|------|--------|-------|----------------------------------------------------------------------------------------------|
3 | | _initialized | uint8 | 0 | 0 | 1 | contracts/tokenbridge/ethereum/L1TokenBridgeRetryableSender.sol:L1TokenBridgeRetryableSender |
4 | | _initializing | bool | 0 | 1 | 1 | contracts/tokenbridge/ethereum/L1TokenBridgeRetryableSender.sol:L1TokenBridgeRetryableSender |
5 | | __gap | uint256[50] | 1 | 0 | 1600 | contracts/tokenbridge/ethereum/L1TokenBridgeRetryableSender.sol:L1TokenBridgeRetryableSender |
6 | | _owner | address | 51 | 0 | 20 | contracts/tokenbridge/ethereum/L1TokenBridgeRetryableSender.sol:L1TokenBridgeRetryableSender |
7 | | __gap | uint256[49] | 52 | 0 | 1568 | contracts/tokenbridge/ethereum/L1TokenBridgeRetryableSender.sol:L1TokenBridgeRetryableSender |
8 |
--------------------------------------------------------------------------------
/test/storage/L1USDCGateway:
--------------------------------------------------------------------------------
1 | | Name | Type | Slot | Offset | Bytes | Contract |
2 | |--------------------|---------------------------------------------------------------|------|--------|-------|------------------------------------------------------------------------|
3 | | counterpartGateway | address | 0 | 0 | 20 | contracts/tokenbridge/ethereum/gateway/L1USDCGateway.sol:L1USDCGateway |
4 | | router | address | 1 | 0 | 20 | contracts/tokenbridge/ethereum/gateway/L1USDCGateway.sol:L1USDCGateway |
5 | | inbox | address | 2 | 0 | 20 | contracts/tokenbridge/ethereum/gateway/L1USDCGateway.sol:L1USDCGateway |
6 | | redirectedExits | mapping(bytes32 => struct L1ArbitrumExtendedGateway.ExitData) | 3 | 0 | 32 | contracts/tokenbridge/ethereum/gateway/L1USDCGateway.sol:L1USDCGateway |
7 | | l1USDC | address | 4 | 0 | 20 | contracts/tokenbridge/ethereum/gateway/L1USDCGateway.sol:L1USDCGateway |
8 | | l2USDC | address | 5 | 0 | 20 | contracts/tokenbridge/ethereum/gateway/L1USDCGateway.sol:L1USDCGateway |
9 | | owner | address | 6 | 0 | 20 | contracts/tokenbridge/ethereum/gateway/L1USDCGateway.sol:L1USDCGateway |
10 | | burner | address | 7 | 0 | 20 | contracts/tokenbridge/ethereum/gateway/L1USDCGateway.sol:L1USDCGateway |
11 | | depositsPaused | bool | 7 | 20 | 1 | contracts/tokenbridge/ethereum/gateway/L1USDCGateway.sol:L1USDCGateway |
12 | | burnAmount | uint256 | 8 | 0 | 32 | contracts/tokenbridge/ethereum/gateway/L1USDCGateway.sol:L1USDCGateway |
13 |
--------------------------------------------------------------------------------
/test/storage/L1WethGateway:
--------------------------------------------------------------------------------
1 | | Name | Type | Slot | Offset | Bytes | Contract |
2 | |--------------------|---------------------------------------------------------------|------|--------|-------|------------------------------------------------------------------------|
3 | | counterpartGateway | address | 0 | 0 | 20 | contracts/tokenbridge/ethereum/gateway/L1WethGateway.sol:L1WethGateway |
4 | | router | address | 1 | 0 | 20 | contracts/tokenbridge/ethereum/gateway/L1WethGateway.sol:L1WethGateway |
5 | | inbox | address | 2 | 0 | 20 | contracts/tokenbridge/ethereum/gateway/L1WethGateway.sol:L1WethGateway |
6 | | redirectedExits | mapping(bytes32 => struct L1ArbitrumExtendedGateway.ExitData) | 3 | 0 | 32 | contracts/tokenbridge/ethereum/gateway/L1WethGateway.sol:L1WethGateway |
7 | | l1Weth | address | 4 | 0 | 20 | contracts/tokenbridge/ethereum/gateway/L1WethGateway.sol:L1WethGateway |
8 | | l2Weth | address | 5 | 0 | 20 | contracts/tokenbridge/ethereum/gateway/L1WethGateway.sol:L1WethGateway |
9 |
--------------------------------------------------------------------------------
/test/storage/L2AtomicTokenBridgeFactory:
--------------------------------------------------------------------------------
1 | | Name | Type | Slot | Offset | Bytes | Contract |
2 | |------|------|------|--------|-------|----------|
3 |
--------------------------------------------------------------------------------
/test/storage/L2CustomGateway:
--------------------------------------------------------------------------------
1 | | Name | Type | Slot | Offset | Bytes | Contract |
2 | |--------------------|-----------------------------|------|--------|-------|----------------------------------------------------------------------------|
3 | | counterpartGateway | address | 0 | 0 | 20 | contracts/tokenbridge/arbitrum/gateway/L2CustomGateway.sol:L2CustomGateway |
4 | | router | address | 1 | 0 | 20 | contracts/tokenbridge/arbitrum/gateway/L2CustomGateway.sol:L2CustomGateway |
5 | | exitNum | uint256 | 2 | 0 | 32 | contracts/tokenbridge/arbitrum/gateway/L2CustomGateway.sol:L2CustomGateway |
6 | | l1ToL2Token | mapping(address => address) | 3 | 0 | 32 | contracts/tokenbridge/arbitrum/gateway/L2CustomGateway.sol:L2CustomGateway |
7 |
--------------------------------------------------------------------------------
/test/storage/L2ERC20Gateway:
--------------------------------------------------------------------------------
1 | | Name | Type | Slot | Offset | Bytes | Contract |
2 | |--------------------|---------|------|--------|-------|--------------------------------------------------------------------------|
3 | | counterpartGateway | address | 0 | 0 | 20 | contracts/tokenbridge/arbitrum/gateway/L2ERC20Gateway.sol:L2ERC20Gateway |
4 | | router | address | 1 | 0 | 20 | contracts/tokenbridge/arbitrum/gateway/L2ERC20Gateway.sol:L2ERC20Gateway |
5 | | exitNum | uint256 | 2 | 0 | 32 | contracts/tokenbridge/arbitrum/gateway/L2ERC20Gateway.sol:L2ERC20Gateway |
6 | | beaconProxyFactory | address | 3 | 0 | 20 | contracts/tokenbridge/arbitrum/gateway/L2ERC20Gateway.sol:L2ERC20Gateway |
7 |
--------------------------------------------------------------------------------
/test/storage/L2GatewayRouter:
--------------------------------------------------------------------------------
1 | | Name | Type | Slot | Offset | Bytes | Contract |
2 | |--------------------|-----------------------------|------|--------|-------|----------------------------------------------------------------------------|
3 | | counterpartGateway | address | 0 | 0 | 20 | contracts/tokenbridge/arbitrum/gateway/L2GatewayRouter.sol:L2GatewayRouter |
4 | | router | address | 1 | 0 | 20 | contracts/tokenbridge/arbitrum/gateway/L2GatewayRouter.sol:L2GatewayRouter |
5 | | l1TokenToGateway | mapping(address => address) | 2 | 0 | 32 | contracts/tokenbridge/arbitrum/gateway/L2GatewayRouter.sol:L2GatewayRouter |
6 | | defaultGateway | address | 3 | 0 | 20 | contracts/tokenbridge/arbitrum/gateway/L2GatewayRouter.sol:L2GatewayRouter |
7 |
--------------------------------------------------------------------------------
/test/storage/L2ReverseCustomGateway:
--------------------------------------------------------------------------------
1 | | Name | Type | Slot | Offset | Bytes | Contract |
2 | |--------------------|-----------------------------|------|--------|-------|------------------------------------------------------------------------------------------|
3 | | counterpartGateway | address | 0 | 0 | 20 | contracts/tokenbridge/arbitrum/gateway/L2ReverseCustomGateway.sol:L2ReverseCustomGateway |
4 | | router | address | 1 | 0 | 20 | contracts/tokenbridge/arbitrum/gateway/L2ReverseCustomGateway.sol:L2ReverseCustomGateway |
5 | | exitNum | uint256 | 2 | 0 | 32 | contracts/tokenbridge/arbitrum/gateway/L2ReverseCustomGateway.sol:L2ReverseCustomGateway |
6 | | l1ToL2Token | mapping(address => address) | 3 | 0 | 32 | contracts/tokenbridge/arbitrum/gateway/L2ReverseCustomGateway.sol:L2ReverseCustomGateway |
7 |
--------------------------------------------------------------------------------
/test/storage/L2USDCGateway:
--------------------------------------------------------------------------------
1 | | Name | Type | Slot | Offset | Bytes | Contract |
2 | |--------------------------|---------|------|--------|-------|------------------------------------------------------------------------|
3 | | counterpartGateway | address | 0 | 0 | 20 | contracts/tokenbridge/arbitrum/gateway/L2USDCGateway.sol:L2USDCGateway |
4 | | router | address | 1 | 0 | 20 | contracts/tokenbridge/arbitrum/gateway/L2USDCGateway.sol:L2USDCGateway |
5 | | exitNum | uint256 | 2 | 0 | 32 | contracts/tokenbridge/arbitrum/gateway/L2USDCGateway.sol:L2USDCGateway |
6 | | l1USDC | address | 3 | 0 | 20 | contracts/tokenbridge/arbitrum/gateway/L2USDCGateway.sol:L2USDCGateway |
7 | | l2USDC | address | 4 | 0 | 20 | contracts/tokenbridge/arbitrum/gateway/L2USDCGateway.sol:L2USDCGateway |
8 | | owner | address | 5 | 0 | 20 | contracts/tokenbridge/arbitrum/gateway/L2USDCGateway.sol:L2USDCGateway |
9 | | usdcOwnershipTransferrer | address | 6 | 0 | 20 | contracts/tokenbridge/arbitrum/gateway/L2USDCGateway.sol:L2USDCGateway |
10 | | withdrawalsPaused | bool | 6 | 20 | 1 | contracts/tokenbridge/arbitrum/gateway/L2USDCGateway.sol:L2USDCGateway |
11 |
--------------------------------------------------------------------------------
/test/storage/L2WethGateway:
--------------------------------------------------------------------------------
1 | | Name | Type | Slot | Offset | Bytes | Contract |
2 | |--------------------|---------|------|--------|-------|------------------------------------------------------------------------|
3 | | counterpartGateway | address | 0 | 0 | 20 | contracts/tokenbridge/arbitrum/gateway/L2WethGateway.sol:L2WethGateway |
4 | | router | address | 1 | 0 | 20 | contracts/tokenbridge/arbitrum/gateway/L2WethGateway.sol:L2WethGateway |
5 | | exitNum | uint256 | 2 | 0 | 32 | contracts/tokenbridge/arbitrum/gateway/L2WethGateway.sol:L2WethGateway |
6 | | l1Weth | address | 3 | 0 | 20 | contracts/tokenbridge/arbitrum/gateway/L2WethGateway.sol:L2WethGateway |
7 | | l2Weth | address | 4 | 0 | 20 | contracts/tokenbridge/arbitrum/gateway/L2WethGateway.sol:L2WethGateway |
8 |
--------------------------------------------------------------------------------
/test/storage/StandardArbERC20:
--------------------------------------------------------------------------------
1 | | Name | Type | Slot | Offset | Bytes | Contract |
2 | |----------------------------------|--------------------------------------------------------|------|--------|-------|----------------------------------------------------------------------|
3 | | _initialized | uint8 | 0 | 0 | 1 | contracts/tokenbridge/arbitrum/StandardArbERC20.sol:StandardArbERC20 |
4 | | _initializing | bool | 0 | 1 | 1 | contracts/tokenbridge/arbitrum/StandardArbERC20.sol:StandardArbERC20 |
5 | | __gap | uint256[50] | 1 | 0 | 1600 | contracts/tokenbridge/arbitrum/StandardArbERC20.sol:StandardArbERC20 |
6 | | _balances | mapping(address => uint256) | 51 | 0 | 32 | contracts/tokenbridge/arbitrum/StandardArbERC20.sol:StandardArbERC20 |
7 | | _allowances | mapping(address => mapping(address => uint256)) | 52 | 0 | 32 | contracts/tokenbridge/arbitrum/StandardArbERC20.sol:StandardArbERC20 |
8 | | _totalSupply | uint256 | 53 | 0 | 32 | contracts/tokenbridge/arbitrum/StandardArbERC20.sol:StandardArbERC20 |
9 | | _name | string | 54 | 0 | 32 | contracts/tokenbridge/arbitrum/StandardArbERC20.sol:StandardArbERC20 |
10 | | _symbol | string | 55 | 0 | 32 | contracts/tokenbridge/arbitrum/StandardArbERC20.sol:StandardArbERC20 |
11 | | _decimals | uint8 | 56 | 0 | 1 | contracts/tokenbridge/arbitrum/StandardArbERC20.sol:StandardArbERC20 |
12 | | __gap | uint256[44] | 57 | 0 | 1408 | contracts/tokenbridge/arbitrum/StandardArbERC20.sol:StandardArbERC20 |
13 | | _HASHED_NAME | bytes32 | 101 | 0 | 32 | contracts/tokenbridge/arbitrum/StandardArbERC20.sol:StandardArbERC20 |
14 | | _HASHED_VERSION | bytes32 | 102 | 0 | 32 | contracts/tokenbridge/arbitrum/StandardArbERC20.sol:StandardArbERC20 |
15 | | __gap | uint256[50] | 103 | 0 | 1600 | contracts/tokenbridge/arbitrum/StandardArbERC20.sol:StandardArbERC20 |
16 | | _nonces | mapping(address => struct CountersUpgradeable.Counter) | 153 | 0 | 32 | contracts/tokenbridge/arbitrum/StandardArbERC20.sol:StandardArbERC20 |
17 | | _PERMIT_TYPEHASH_DEPRECATED_SLOT | bytes32 | 154 | 0 | 32 | contracts/tokenbridge/arbitrum/StandardArbERC20.sol:StandardArbERC20 |
18 | | __gap | uint256[49] | 155 | 0 | 1568 | contracts/tokenbridge/arbitrum/StandardArbERC20.sol:StandardArbERC20 |
19 | | l2Gateway | address | 204 | 0 | 20 | contracts/tokenbridge/arbitrum/StandardArbERC20.sol:StandardArbERC20 |
20 | | l1Address | address | 205 | 0 | 20 | contracts/tokenbridge/arbitrum/StandardArbERC20.sol:StandardArbERC20 |
21 | | isMasterCopy | bool | 205 | 20 | 1 | contracts/tokenbridge/arbitrum/StandardArbERC20.sol:StandardArbERC20 |
22 | | availableGetters | struct StandardArbERC20.ERC20Getters | 206 | 0 | 32 | contracts/tokenbridge/arbitrum/StandardArbERC20.sol:StandardArbERC20 |
23 |
--------------------------------------------------------------------------------
/test/testhelper.ts:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2019-2020, Offchain Labs, Inc.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | /* eslint-env node, mocha */
18 | import { ethers, network } from 'hardhat'
19 | import { ContractTransaction } from 'ethers'
20 | import {
21 | InboxMock,
22 | InboxMock__factory,
23 | ArbSysMock__factory,
24 | } from '../build/types'
25 |
26 | export const processL1ToL2Tx = async (
27 | tx: Promise | ContractTransaction
28 | ) => {
29 | const receipt = await (await tx).wait()
30 | const iface = InboxMock__factory.createInterface()
31 | const logs = receipt.logs.filter(
32 | log => log.topics[0] === iface.getEventTopic('InboxRetryableTicket')
33 | )
34 | if (logs.length === 0) throw new Error('No L1 to L2 txs')
35 | const l1ToL2Logs = logs.map(log => {
36 | const event = iface.parseLog(log)
37 | const to = event.args.to
38 | const data = event.args.data
39 | const from = event.args.from
40 | const value = event.args.value
41 | const fromAliased = applyAlias(from)
42 |
43 | return network.provider
44 | .request({
45 | // Fund fromAliased to send transaction
46 | method: 'hardhat_setBalance',
47 | params: [fromAliased, '0xffffffffffffffffffff'],
48 | })
49 | .then(() =>
50 | network.provider.request({
51 | method: 'hardhat_impersonateAccount',
52 | params: [fromAliased],
53 | })
54 | )
55 | .then(() => ethers.getSigner(fromAliased))
56 | .then(signer =>
57 | signer.sendTransaction({
58 | to: to,
59 | data: data,
60 | value: value,
61 | })
62 | )
63 | })
64 | return Promise.all(l1ToL2Logs)
65 | }
66 |
67 | export const impersonateAccount = (address: string) =>
68 | network.provider
69 | .request({
70 | // Fund inboxMock to send transaction
71 | method: 'hardhat_setBalance',
72 | params: [address, '0xffffffffffffffffffff'],
73 | })
74 | .then(() =>
75 | network.provider.request({
76 | method: 'hardhat_impersonateAccount',
77 | params: [address],
78 | })
79 | )
80 | .then(() => ethers.getSigner(address))
81 |
82 | export const applyAlias = (address: string) =>
83 | '0x' +
84 | BigInt.asUintN(
85 | 160,
86 | BigInt(address) + BigInt('0x1111000000000000000000000000000000001111')
87 | )
88 | .toString(16)
89 | .padStart(40, '0')
90 |
91 | export const processL2ToL1Tx = async (
92 | tx: Promise | ContractTransaction,
93 | inboxMock: InboxMock
94 | ) => {
95 | const receipt = await (await tx).wait()
96 | const iface = ArbSysMock__factory.createInterface()
97 | const logs = receipt.logs.filter(
98 | log => log.topics[0] === iface.getEventTopic('ArbSysL2ToL1Tx')
99 | )
100 | if (logs.length === 0) throw new Error('No L2 to L1 txs')
101 | const l2ToL1Logs = logs.map(log => {
102 | const event = iface.parseLog(log)
103 | const to = event.args.to
104 | const data = event.args.data
105 | const from = event.args.from
106 | const value = event.args.value
107 | return inboxMock
108 | .setL2ToL1Sender(from, { gasLimit: 5000000 })
109 | .then(() => impersonateAccount(inboxMock.address))
110 | .then(signer =>
111 | signer.sendTransaction({
112 | to: to,
113 | data: data,
114 | value: value,
115 | })
116 | )
117 | })
118 | return Promise.all(l2ToL1Logs)
119 | }
120 |
--------------------------------------------------------------------------------
/test/unused-errors/exceptions.txt:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OffchainLabs/token-bridge-contracts/5bdf33259d2d9ae52ddc69bc5a9cbc558c4c40c7/test/unused-errors/exceptions.txt
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "es2018",
4 | "module": "commonjs",
5 | "strict": true,
6 | "esModuleInterop": true,
7 | "outDir": "dist",
8 | "resolveJsonModule": true
9 | },
10 | "include": ["./scripts", "./test", "./deploy", "./build/**/*.ts"],
11 | "files": ["./hardhat.config.ts"]
12 | }
13 |
--------------------------------------------------------------------------------