diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 00000000..865fbb3b --- /dev/null +++ b/.editorconfig @@ -0,0 +1,15 @@ +# top-most EditorConfig file +root = true + +# Unix-style newlines with a newline ending every file +[*] +end_of_line = lf +insert_final_newline = true +trim_trailing_whitespace = true +charset = utf-8 +indent_style = space +indent_size = 4 + +[*.{js,ts,yml,json,cjs}] +indent_size = 2 +max_line_length = 120 diff --git a/.env.example b/.env.example index 2f00c733..8f5446e9 100644 --- a/.env.example +++ b/.env.example @@ -5,31 +5,57 @@ # ############################ RPC_ETH_MAINNET= -RPC_ETH_GOERLI= +RPC_ETH_SEPOLIA= RPC_OPT_MAINNET=https://mainnet.optimism.io -RPC_OPT_GOERLI=https://goerli.optimism.io - -RPC_ARB_MAINNET=https://arb1.arbitrum.io/rpc -RPC_ARB_GOERLI=https://goerli-rollup.arbitrum.io/rpc +RPC_OPT_SEPOLIA=https://sepolia.optimism.io # ############################ # Etherscan # ############################ ETHERSCAN_API_KEY_ETH= -ETHERSCAN_API_KEY_ARB= ETHERSCAN_API_KEY_OPT= # ############################ # Bridge/Gateway Deployment # ############################ -# Address of the token to deploy the bridge/gateway for +# Address of the token on L1 to deploy the bridge/gateway for TOKEN= +# Address of the rebasable token on L1 to deploy the bridge/gateway for +REBASABLE_TOKEN= + +# Address of token rate pusher. Required to config TokenRateOracle. +L1_OP_STACK_TOKEN_RATE_PUSHER= + +# Gas limit required to complete pushing token rate on L2. +# Default is: 300_000. +# This value was calculated by formula: +# l2GasLimit = (gas cost of L2Bridge.finalizeDeposit() + OptimismPortal.minimumGasLimit(depositData.length)) * 1.5 +L2_GAS_LIMIT_FOR_PUSHING_TOKEN_RATE=300000 + +# A time period when token rate can be considered outdated. +TOKEN_RATE_OUTDATED_DELAY=86400 # default is 86400 (24 hours) + +# Address of L1 token bridge proxy. +L1_TOKEN_BRIDGE= + +# Address of L2 token bridge proxy. +L2_TOKEN_BRIDGE= + +# Address of the non-rebasable token proxy on L2. +L2_TOKEN= + +# Address of token rate oracle on L2 +L2_TOKEN_RATE_ORACLE= + +# Address of bridge executor. +GOV_BRIDGE_EXECUTOR= + # Name of the network environments used by deployment scripts. -# Might be one of: "mainnet", "goerli". +# Might be one of: "mainnet", "sepolia". NETWORK=mainnet # Run deployment in the forking network instead of public ones @@ -38,7 +64,6 @@ FORKING=true # Private key of the deployer account used for deployment process ETH_DEPLOYER_PRIVATE_KEY= OPT_DEPLOYER_PRIVATE_KEY= -ARB_DEPLOYER_PRIVATE_KEY= L1_DEV_MULTISIG= L1_PROXY_ADMIN= @@ -63,17 +88,13 @@ L2_WITHDRAWALS_DISABLERS=[] # Integration Acceptance & E2E Testing # ############################ -TESTING_ARB_NETWORK= -TESTING_ARB_L1_TOKEN=0x7AEE39c46f20135114e85A03C02aB4FE73fB8127 -TESTING_ARB_L2_TOKEN=0x775ede8029C117effce283b3391E420EacF3c85F -TESTING_ARB_L1_ERC20_TOKEN_GATEWAY=0x0A7e12b563Ba623646a31a09F0182e8aD45D6cfD -TESTING_ARB_L2_ERC20_TOKEN_GATEWAY=0x8c269989D839eE9DaEe64D57C8c41404DF87F722 -TESTING_ARB_L1_GATEWAY_ROUTER=0xa2a8F940752aDc4A3278B63B96d56D72D2b075B1 -TESTING_ARB_L2_GATEWAY_ROUTER=0x57f54f87C44d816f60b92864e23b8c0897D4d81D - TESTING_OPT_NETWORK= TESTING_OPT_L1_TOKEN=0xaF8a2F0aE374b03376155BF745A3421Dac711C12 TESTING_OPT_L2_TOKEN=0xAED5F9aaF167923D34174b8E636aaF040A11f6F7 +TESTING_OPT_L1_TOKEN_RATE_NOTIFIER=0x554f2C7D58522c050d38Ebea4FF072ED7C4e61cb +TESTING_OPT_L1_REBASABLE_TOKEN=0xB82381A3fBD3FaFA77B3a7bE693342618240067b +TESTING_OPT_L2_REBASABLE_TOKEN=0x6696Cb7bb602FC744254Ad9E07EfC474FBF78857 +TESTING_OPT_L2_TOKEN_RATE_ORACLE=0x8ea513d1e5Be31fb5FC2f2971897594720de9E70 TESTING_OPT_L1_ERC20_TOKEN_BRIDGE=0x243b661276670bD17399C488E7287ea4D416115b TESTING_OPT_L2_ERC20_TOKEN_BRIDGE=0x447CD1794d209Ac4E6B4097B34658bc00C4d0a51 @@ -84,7 +105,6 @@ TESTING_OPT_L2_ERC20_TOKEN_BRIDGE=0x447CD1794d209Ac4E6B4097B34658bc00C4d0a51 TESTING_USE_DEPLOYED_CONTRACTS=false TESTING_L1_TOKENS_HOLDER= -TESTING_ARB_GOV_BRIDGE_EXECUTOR= TESTING_OPT_GOV_BRIDGE_EXECUTOR= # ############################ @@ -93,4 +113,3 @@ TESTING_OPT_GOV_BRIDGE_EXECUTOR= TESTING_PRIVATE_KEY= TESTING_OPT_LDO_HOLDER_PRIVATE_KEY= -TESTING_ARB_LDO_HOLDER_PRIVATE_KEY= diff --git a/.env.wsteth.arb_goerli b/.env.wsteth.arb_goerli deleted file mode 100644 index 6694eda7..00000000 --- a/.env.wsteth.arb_goerli +++ /dev/null @@ -1,75 +0,0 @@ -# Detailed info: https://github.com/lidofinance/lido-l2#Project-Configuration - -# ############################ -# RPCs -# ############################ - -RPC_ETH_GOERLI= -RPC_ARB_GOERLI=https://goerli-rollup.arbitrum.io/rpc - -# ############################ -# Etherscan -# ############################ - -ETHERSCAN_API_KEY_ETH= -ETHERSCAN_API_KEY_ARB= - -# ############################ -# Bridge/Gateway Deployment -# ############################ - -# Address of the token to deploy the bridge/gateway for -TOKEN=0x6320cd32aa674d2898a68ec82e869385fc5f7e2f - -# Name of the network environments used by deployment scripts. -# Might be one of: "mainnet", "goerli". -NETWORK=goerli - -# Run deployment in the forking network instead of public ones -FORKING=true - -# Private key of the deployer account used for deployment process - -ETH_DEPLOYER_PRIVATE_KEY= -ARB_DEPLOYER_PRIVATE_KEY= - -L1_PROXY_ADMIN=0x4333218072D5d7008546737786663c38B4D561A4 -L1_BRIDGE_ADMIN=0x4333218072D5d7008546737786663c38B4D561A4 -L1_DEPOSITS_ENABLED=true -L1_WITHDRAWALS_ENABLED=true -L1_DEPOSITS_ENABLERS=["0x4333218072D5d7008546737786663c38B4D561A4"] -L1_DEPOSITS_DISABLERS=["0x4333218072D5d7008546737786663c38B4D561A4","0x7fE7fa4EF7D134Dbf8B616Ba7B675F26286BC2cd"] -L1_WITHDRAWALS_ENABLERS=["0x4333218072D5d7008546737786663c38B4D561A4"] -L1_WITHDRAWALS_DISABLERS=["0x4333218072D5d7008546737786663c38B4D561A4","0x7fE7fa4EF7D134Dbf8B616Ba7B675F26286BC2cd"] - -L2_PROXY_ADMIN=0x43De3B7115baA4EbAbd7c5Eaf4cB2856238C6A50 -L2_BRIDGE_ADMIN=0x43De3B7115baA4EbAbd7c5Eaf4cB2856238C6A50 -L2_DEPOSITS_ENABLED=true -L2_WITHDRAWALS_ENABLED=true -L2_DEPOSITS_ENABLERS=["0x43De3B7115baA4EbAbd7c5Eaf4cB2856238C6A50"] -L2_DEPOSITS_DISABLERS=["0x43De3B7115baA4EbAbd7c5Eaf4cB2856238C6A50","0x7fE7fa4EF7D134Dbf8B616Ba7B675F26286BC2cd"] -L2_WITHDRAWALS_ENABLERS=["0x43De3B7115baA4EbAbd7c5Eaf4cB2856238C6A50"] -L2_WITHDRAWALS_DISABLERS=["0x43De3B7115baA4EbAbd7c5Eaf4cB2856238C6A50","0x7fE7fa4EF7D134Dbf8B616Ba7B675F26286BC2cd"] - -# ############################ -# Integration Acceptance & E2E Testing -# ############################ - -TESTING_ARB_NETWORK=goerli -TESTING_ARB_L1_TOKEN=0x6320cd32aa674d2898a68ec82e869385fc5f7e2f -TESTING_ARB_L2_TOKEN=0xbED18985eC648Ce4b0C5Fc3061d1323116702BC4 -TESTING_ARB_L1_ERC20_TOKEN_GATEWAY=0x0ecCFbBEe34f04187361818832385EB4cC11b678 -TESTING_ARB_L2_ERC20_TOKEN_GATEWAY=0x12dD5832Fd7e02e49d97D1CBBd14579794945c1E - -# ############################ -# Integration Testing -# ############################ - -TESTING_USE_DEPLOYED_CONTRACTS=true -TESTING_L1_TOKENS_HOLDER= - -# ############################ -# E2E Testing -# ############################ - -TESTING_PRIVATE_KEY= diff --git a/.env.wsteth.arb_mainnet b/.env.wsteth.arb_mainnet deleted file mode 100644 index 782ee7a1..00000000 --- a/.env.wsteth.arb_mainnet +++ /dev/null @@ -1,75 +0,0 @@ -# Detailed info: https://github.com/lidofinance/lido-l2#Project-Configuration - -# ############################ -# RPCs -# ############################ - -RPC_ETH_MAINNET= -RPC_ARB_MAINNET= - -# ############################ -# Etherscan -# ############################ - -ETHERSCAN_API_KEY_ETH= -ETHERSCAN_API_KEY_ARB= - -# ############################ -# Bridge/Gateway Deployment -# ############################ - -# Address of the token to deploy the bridge/gateway for -TOKEN=0x7f39C581F595B53c5cb19bD0b3f8dA6c935E2Ca0 - -# Name of the network environments used by deployment scripts. -# Might be one of: "mainnet", "goerli". -NETWORK=mainnet - -# Run deployment in the forking network instead of public ones -FORKING=true - -# Private key of the deployer account used for deployment process - -ETH_DEPLOYER_PRIVATE_KEY= -ARB_DEPLOYER_PRIVATE_KEY= - -L1_PROXY_ADMIN=0x3e40D73EB977Dc6a537aF587D48316feE66E9C8c -L1_BRIDGE_ADMIN=0x3e40D73EB977Dc6a537aF587D48316feE66E9C8c -L1_DEPOSITS_ENABLED=false -L1_WITHDRAWALS_ENABLED=true -L1_DEPOSITS_ENABLERS=["0x3e40D73EB977Dc6a537aF587D48316feE66E9C8c","0x3cd9F71F80AB08ea5a7Dca348B5e94BC595f26A0"] -L1_DEPOSITS_DISABLERS=["0x3e40D73EB977Dc6a537aF587D48316feE66E9C8c","0x73b047fe6337183A454c5217241D780a932777bD"] -L1_WITHDRAWALS_ENABLERS=["0x3e40D73EB977Dc6a537aF587D48316feE66E9C8c"] -L1_WITHDRAWALS_DISABLERS=["0x3e40D73EB977Dc6a537aF587D48316feE66E9C8c","0x73b047fe6337183A454c5217241D780a932777bD"] - -L2_PROXY_ADMIN=0x1dcA41859Cd23b526CBe74dA8F48aC96e14B1A29 -L2_BRIDGE_ADMIN=0x1dcA41859Cd23b526CBe74dA8F48aC96e14B1A29 -L2_DEPOSITS_ENABLED=true -L2_WITHDRAWALS_ENABLED=true -L2_DEPOSITS_ENABLERS=["0x1dcA41859Cd23b526CBe74dA8F48aC96e14B1A29"] -L2_DEPOSITS_DISABLERS=["0x1dcA41859Cd23b526CBe74dA8F48aC96e14B1A29","0xfDCf209A213a0b3C403d543F87E74FCbcA11de34"] -L2_WITHDRAWALS_ENABLERS=["0x1dcA41859Cd23b526CBe74dA8F48aC96e14B1A29"] -L2_WITHDRAWALS_DISABLERS=["0x1dcA41859Cd23b526CBe74dA8F48aC96e14B1A29","0xfDCf209A213a0b3C403d543F87E74FCbcA11de34"] - -# ############################ -# Integration Acceptance & E2E Testing -# ############################ - -TESTING_ARB_NETWORK=mainnet -TESTING_ARB_L1_TOKEN=0x7f39C581F595B53c5cb19bD0b3f8dA6c935E2Ca0 -TESTING_ARB_L2_TOKEN=0x5979D7b546E38E414F7E9822514be443A4800529 -TESTING_ARB_L1_ERC20_TOKEN_GATEWAY=0x0F25c1DC2a9922304f2eac71DCa9B07E310e8E5a -TESTING_ARB_L2_ERC20_TOKEN_GATEWAY=0x07D4692291B9E30E326fd31706f686f83f331B82 - -# ############################ -# Integration Testing -# ############################ - -TESTING_USE_DEPLOYED_CONTRACTS=true -TESTING_L1_TOKENS_HOLDER= - -# ############################ -# E2E Testing -# ############################ - -TESTING_PRIVATE_KEY= diff --git a/.env.wsteth.opt_goerli b/.env.wsteth.opt_goerli deleted file mode 100644 index 18eb8378..00000000 --- a/.env.wsteth.opt_goerli +++ /dev/null @@ -1,71 +0,0 @@ -# Detailed info: https://github.com/lidofinance/lido-l2#Project-Configuration - -# ############################ -# RPCs -# ############################ - -RPC_ETH_GOERLI= -RPC_OPT_GOERLI=https://goerli.optimism.io - -# ############################ -# Etherscan -# ############################ - -ETHERSCAN_API_KEY_ETH= -ETHERSCAN_API_KEY_OPT= - -# ############################ -# Bridge/Gateway Deployment -# ############################ - -# Address of the token to deploy the bridge/gateway for -TOKEN=0x6320cd32aa674d2898a68ec82e869385fc5f7e2f - -# Name of the network environments used by deployment scripts. -# Might be one of: "mainnet", "goerli". -NETWORK=goerli - -# Private key of the deployer account used for deployment process -ETH_DEPLOYER_PRIVATE_KEY= -OPT_DEPLOYER_PRIVATE_KEY= - -L1_PROXY_ADMIN=0x4333218072D5d7008546737786663c38B4D561A4 -L1_BRIDGE_ADMIN=0x4333218072D5d7008546737786663c38B4D561A4 -L1_DEPOSITS_ENABLED=true -L1_WITHDRAWALS_ENABLED=true -L1_DEPOSITS_ENABLERS=["0x4333218072D5d7008546737786663c38B4D561A4"] -L1_DEPOSITS_DISABLERS="["0x4333218072D5d7008546737786663c38B4D561A4", "0x7fE7fa4EF7D134Dbf8B616Ba7B675F26286BC2cd"]" -L1_WITHDRAWALS_ENABLERS=["0x4333218072D5d7008546737786663c38B4D561A4"] -L1_WITHDRAWALS_DISABLERS="["0x4333218072D5d7008546737786663c38B4D561A4", "0x7fE7fa4EF7D134Dbf8B616Ba7B675F26286BC2cd"]" - -L2_PROXY_ADMIN=0x55C39356C714Cde16F8a80302c1Ce9DfAC6f5a35 -L2_BRIDGE_ADMIN=0x55C39356C714Cde16F8a80302c1Ce9DfAC6f5a35 -L2_DEPOSITS_ENABLED=true -L2_WITHDRAWALS_ENABLED=true -L2_DEPOSITS_ENABLERS=["0x55C39356C714Cde16F8a80302c1Ce9DfAC6f5a35"] -L2_DEPOSITS_DISABLERS="["0x55C39356C714Cde16F8a80302c1Ce9DfAC6f5a35", "0x7fE7fa4EF7D134Dbf8B616Ba7B675F26286BC2cd"]" -L2_WITHDRAWALS_ENABLERS=["0x55C39356C714Cde16F8a80302c1Ce9DfAC6f5a35"] -L2_WITHDRAWALS_DISABLERS="["0x55C39356C714Cde16F8a80302c1Ce9DfAC6f5a35", "0x7fE7fa4EF7D134Dbf8B616Ba7B675F26286BC2cd"]" - -# ############################ -# Integration & E2E Testing -# ############################ - -TESTING_OPT_NETWORK=goerli -TESTING_OPT_L1_TOKEN=0x6320cd32aa674d2898a68ec82e869385fc5f7e2f -TESTING_OPT_L2_TOKEN=0xe8964a99d5DE7cEE2743B20113a52C953b0916E9 -TESTING_OPT_L1_ERC20_TOKEN_BRIDGE=0xDdC89Bd27F9A1C47A5c20dF0783dE52f55513598 -TESTING_OPT_L2_ERC20_TOKEN_BRIDGE=0x423702bC3Fb92f59Be440354456f0481934bF1f5 - -# ############################ -# Integration Testing -# ############################ - -TESTING_USE_DEPLOYED_CONTRACTS=true -TESTING_L1_TOKENS_HOLDER= - -# ############################ -# E2E Testing -# ############################ - -TESTING_PRIVATE_KEY= diff --git a/.env.wsteth.opt_mainnet b/.env.wsteth.opt_mainnet index 6bf3ae55..0e3e3e4a 100644 --- a/.env.wsteth.opt_mainnet +++ b/.env.wsteth.opt_mainnet @@ -21,8 +21,11 @@ ETHERSCAN_API_KEY_OPT= # Address of the token to deploy the bridge/gateway for TOKEN=0x7f39C581F595B53c5cb19bD0b3f8dA6c935E2Ca0 +# Address of the rebasable token to deploy the bridge/gateway for +REBASABLE_TOKEN= + # Name of the network environments used by deployment scripts. -# Might be one of: "mainnet", "goerli". +# Might be one of: "mainnet", "sepolia". NETWORK=mainnet # Run deployment in the forking network instead of public ones diff --git a/.github/workflows/verify-bytecode.yml b/.github/workflows/verify-bytecode.yml index a9185fd4..55630fdd 100644 --- a/.github/workflows/verify-bytecode.yml +++ b/.github/workflows/verify-bytecode.yml @@ -49,9 +49,3 @@ jobs: file: artifacts-opt.json rpcUrl: ${{ secrets.OPTIMISM_RPC }} - - name: Verify bytecode of contracts on Arbitrum chain - uses: lidofinance/action-verify-bytecode@master - if: always() - with: - file: artifacts-arb.json - rpcUrl: ${{ secrets.ARBITRUM_RPC }} diff --git a/.solcover.js b/.solcover.js index 7554c821..108d686a 100644 --- a/.solcover.js +++ b/.solcover.js @@ -1,3 +1,3 @@ module.exports = { - skipFiles: ["stubs", "optimism/stubs", "proxy/stubs", "arbitrum/stubs"], + skipFiles: ["stubs", "optimism/stubs", "proxy/stubs"], }; diff --git a/.storage-layout b/.storage-layout index 393bb17e..50deee78 100644 --- a/.storage-layout +++ b/.storage-layout @@ -1,13 +1,6 @@ 👁👁 STORAGE LAYOUT snapshot 👁👁 ======================= -======================= -➡ BridgeableTokens -======================= - -| Name | Type | Slot | Offset | Bytes | Contract | -|------|------|------|--------|-------|----------| - ======================= ➡ BridgingManager ======================= @@ -33,6 +26,16 @@ | balanceOf | mapping(address => uint256) | 1 | 0 | 32 | contracts/token/ERC20Bridged.sol:ERC20Bridged | | allowance | mapping(address => mapping(address => uint256)) | 2 | 0 | 32 | contracts/token/ERC20Bridged.sol:ERC20Bridged | +======================= +➡ ERC20BridgedPermit +======================= + +| Name | Type | Slot | Offset | Bytes | Contract | +|-------------|-------------------------------------------------|------|--------|-------|-----------------------------------------------------------| +| totalSupply | uint256 | 0 | 0 | 32 | contracts/token/ERC20BridgedPermit.sol:ERC20BridgedPermit | +| balanceOf | mapping(address => uint256) | 1 | 0 | 32 | contracts/token/ERC20BridgedPermit.sol:ERC20BridgedPermit | +| allowance | mapping(address => mapping(address => uint256)) | 2 | 0 | 32 | contracts/token/ERC20BridgedPermit.sol:ERC20BridgedPermit | + ======================= ➡ ERC20Core ======================= @@ -51,53 +54,74 @@ |------|------|------|--------|-------|----------| ======================= -➡ L1CrossDomainEnabled +➡ ERC20RebasableBridged +======================= + +| Name | Type | Slot | Offset | Bytes | Contract | +|------|------|------|--------|-------|----------| + +======================= +➡ ERC20RebasableBridgedPermit ======================= | Name | Type | Slot | Offset | Bytes | Contract | |------|------|------|--------|-------|----------| ======================= -➡ L1ERC20TokenBridge +➡ L1LidoTokensBridge ======================= | Name | Type | Slot | Offset | Bytes | Contract | |--------|---------------------------------------------------|------|--------|-------|--------------------------------------------------------------| -| _roles | mapping(bytes32 => struct AccessControl.RoleData) | 0 | 0 | 32 | contracts/optimism/L1ERC20TokenBridge.sol:L1ERC20TokenBridge | +| _roles | mapping(bytes32 => struct AccessControl.RoleData) | 0 | 0 | 32 | contracts/optimism/L1LidoTokensBridge.sol:L1LidoTokensBridge | + +======================= +➡ L2ERC20ExtendedTokensBridge +======================= + +| Name | Type | Slot | Offset | Bytes | Contract | +|--------|---------------------------------------------------|------|--------|-------|--------------------------------------------------------------------------------| +| _roles | mapping(bytes32 => struct AccessControl.RoleData) | 0 | 0 | 32 | contracts/optimism/L2ERC20ExtendedTokensBridge.sol:L2ERC20ExtendedTokensBridge | ======================= -➡ L1ERC20TokenGateway +➡ OpStackTokenRatePusher ======================= -| Name | Type | Slot | Offset | Bytes | Contract | -|--------|---------------------------------------------------|------|--------|-------|----------------------------------------------------------------| -| _roles | mapping(bytes32 => struct AccessControl.RoleData) | 0 | 0 | 32 | contracts/arbitrum/L1ERC20TokenGateway.sol:L1ERC20TokenGateway | +| Name | Type | Slot | Offset | Bytes | Contract | +|------|------|------|--------|-------|----------| ======================= -➡ L2CrossDomainEnabled +➡ OssifiableProxy ======================= | Name | Type | Slot | Offset | Bytes | Contract | |------|------|------|--------|-------|----------| ======================= -➡ L2ERC20TokenBridge +➡ RebasableAndNonRebasableTokens ======================= -| Name | Type | Slot | Offset | Bytes | Contract | -|--------|---------------------------------------------------|------|--------|-------|--------------------------------------------------------------| -| _roles | mapping(bytes32 => struct AccessControl.RoleData) | 0 | 0 | 32 | contracts/optimism/L2ERC20TokenBridge.sol:L2ERC20TokenBridge | +| Name | Type | Slot | Offset | Bytes | Contract | +|------|------|------|--------|-------|----------| ======================= -➡ L2ERC20TokenGateway +➡ TokenRateNotifier ======================= -| Name | Type | Slot | Offset | Bytes | Contract | -|--------|---------------------------------------------------|------|--------|-------|----------------------------------------------------------------| -| _roles | mapping(bytes32 => struct AccessControl.RoleData) | 0 | 0 | 32 | contracts/arbitrum/L2ERC20TokenGateway.sol:L2ERC20TokenGateway | +| Name | Type | Slot | Offset | Bytes | Contract | +|-----------|-----------|------|--------|-------|--------------------------------------------------------| +| _owner | address | 0 | 0 | 20 | contracts/lido/TokenRateNotifier.sol:TokenRateNotifier | +| observers | address[] | 1 | 0 | 32 | contracts/lido/TokenRateNotifier.sol:TokenRateNotifier | ======================= -➡ OssifiableProxy +➡ TokenRateOracle +======================= + +| Name | Type | Slot | Offset | Bytes | Contract | +|------|------|------|--------|-------|----------| + +======================= +➡ Versioned ======================= | Name | Type | Slot | Offset | Bytes | Contract | diff --git a/README.md b/README.md index 5f9ca478..19ab276d 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,11 @@ # Lido L2 -This project contains the implementations of the L2 ERC20 token bridges for Arbitrum and Optimism chains. The current solution allows transferring ERC20 tokens between L1 and L2 chains. +This project contains the implementations of the L2 ERC20 token bridge for Optimism chain. The current solution allows transferring ERC20 tokens between L1 and L2 chains. To retrieve more detailed info about the bridging process, see the specifications for certain chains: -- [Lido's Arbitrum Gateway](https://github.com/lidofinance/lido-l2/blob/main/contracts/arbitrum/README.md). - [Lido's Optimism Bridge](https://github.com/lidofinance/lido-l2/blob/main/contracts/optimism/README.md). +- [wstETH Bridging Guide](https://docs.lido.fi/token-guides/wsteth-bridging-guide/#r-5-bridging-l1-lido-dao-decisions) ## Project setup @@ -42,12 +42,20 @@ Fill the newly created `.env` file with the required variables. See the [Project The configuration of the deployment scripts happens via the ENV variables. The following variables are required: -- [`TOKEN`](#TOKEN) - address of the token to deploy a new bridge on the Ethereum chain. -- [`NETWORK`](#NETWORK) - name of the network environments used by deployment scripts. Allowed values: `mainnet`, `goerli`. +- [`TOKEN`](#TOKEN) - address of the non-rebasable token to deploy a new bridge on the Ethereum chain. +- [`REBASABLE_TOKEN`] (#REBASABLE_TOKEN) - address of the rebasable token to deploy new bridge on the Ethereum chain. +- [`L1_OP_STACK_TOKEN_RATE_PUSHER`](#L1_OP_STACK_TOKEN_RATE_PUSHER) - address of token rate pusher. Required to config TokenRateOracle. +- [`L2_GAS_LIMIT_FOR_PUSHING_TOKEN_RATE`](#L2_GAS_LIMIT_FOR_PUSHING_TOKEN_RATE) - gas limit required to complete pushing token rate on L2.This value was calculated by formula: l2GasLimit = (gas cost of L2Bridge.finalizeDeposit() + OptimismPortal.minimumGasLimit(depositData.length)) * 1.5 +- [`TOKEN_RATE_OUTDATED_DELAY`](#TOKEN_RATE_OUTDATED_DELAY) - a time period when token rate can be considered outdated. Default is 86400 (24 hours). +- [`L1_TOKEN_BRIDGE`](#L1_TOKEN_BRIDGE) - address of L1 token bridge. +- [`L2_TOKEN_BRIDGE`](#L2_TOKEN_BRIDGE) - address of L2 token bridge. +- [`L2_TOKEN`](#L2_TOKEN) - address of the non-rebasable token on L2. +- [`L2_TOKEN_RATE_ORACLE`](#L2_TOKEN_RATE_ORACLE) - address of token rate oracle on L2. +- [`GOV_BRIDGE_EXECUTOR`](#GOV_BRIDGE_EXECUTOR) - address of bridge executor. +- [`NETWORK`](#NETWORK) - name of the network environments used by deployment scripts. Allowed values: `mainnet`, `sepolia`. - [`FORKING`](#FORKING) - run deployment in the forking network instead of real ones - [`ETH_DEPLOYER_PRIVATE_KEY`](#ETH_DEPLOYER_PRIVATE_KEY) - The private key of the deployer account in the Ethereum network is used during the deployment process. -- [`ARB_DEPLOYER_PRIVATE_KEY`](#ARB_DEPLOYER_PRIVATE_KEY) - The private key of the deployer account in the Arbitrum network is used during the deployment process. -- [`OPT_DEPLOYER_PRIVATE_KEY`](#ARB_DEPLOYER_PRIVATE_KEY) - The private key of the deployer account in the Optimism network is used during the deployment process. +- [`OPT_DEPLOYER_PRIVATE_KEY`](#OPT_DEPLOYER_PRIVATE_KEY) - The private key of the deployer account in the Optimism network is used during the deployment process. - [`L1_PROXY_ADMIN`](#L1_PROXY_ADMIN) - The address to grant admin rights of the `OssifiableProxy` on the L1 bridge - [`L1_BRIDGE_ADMIN`](#L1_BRIDGE_ADMIN) - Address to grant the `DEFAULT_ADMIN_ROLE` on the L1 bridge - [`L2_PROXY_ADMIN`](#L2_PROXY_ADMIN) - The address to grant admin rights of the `OssifiableProxy` on the L2 bridge @@ -68,14 +76,6 @@ The following ENV variables are optional and might be used to make an additional - [`L2_WITHDRAWALS_ENABLERS`](#L2_WITHDRAWALS_ENABLES) - array of addresses to grant `WITHDRAWALS_ENABLER_ROLE` on the L2 bridge. - [`L2_WITHDRAWALS_DISABLERS`](#L2_WITHDRAWALS_DISABLERS) - array of addresses to grant `WITHDRAWALS_DISABLER_ROLE` on the L2 bridge. -### Deploying Arbitrum gateway - -To run the deployment of the ERC20 token gateway for the Ethereum <-> Arbitrum chains use the following command: - -```bash -npm run arbitrum:deploy -``` - ### Deploying Optimism bridge To run the deployment of the ERC20 token gateway for the Ethereum <-> Optimism chains use the following command: @@ -92,40 +92,30 @@ To run unit tests use one of the following commands: ```bash -# Run tests for both Arbitrum and Optimism bridges +# Run tests for Optimism bridge npm run test:unit -# Run tests only for Arbitrum gateway -npm run arbitrum:test:unit - # Run tests only for Optimism bridge npm run optimism:test:unit ``` ### Integration tests -Before running integration tests, run the hardhat forked nodes in the standalone tabs corresponding to `TESTING_ARB_NETWORK` \ `TESTING_OPT_NETWORK` env variable or if it's not set use `mainnet` network. Example of the commands for the `mainnet` network: +Before running integration tests, run the hardhat forked nodes in the standalone tabs corresponding to `TESTING_OPT_NETWORK` env variable or if it's not set use `mainnet` network. Example of the commands for the `mainnet` network: ```bash -# Required to run both Arbitrum and Optimism integraton tests +# Required to run Optimism integraton tests npm run fork:eth:mainnet # Required to run Optimism integration tests npm run fork:opt:mainnet -# Required to run Arbitrum integration tests -npm run fork:arb:mainnet -``` - The integration tests might be run via the following commands: ```bash -# Run integration tests for both Arbitrum and Optimism bridges +# Run integration tests for Optimism bridge npm run test:integration -# Run integration tests for Arbitrum bridge -npm run arbitrum:test:integration - # Run integration tests for Optimism bridge npm run optimism:test:integration ``` @@ -138,17 +128,6 @@ TESTING_USE_DEPLOYED_CONTRACTS=true # Address of the account which has tokens to test TESTING_L1_TOKENS_HOLDER= -# Addresses of the Arbitrum gateway -TESTING_ARB_NETWORK= -TESTING_ARB_L1_TOKEN= -TESTING_ARB_L2_TOKEN= -TESTING_ARB_L1_ERC20_TOKEN_GATEWAY= -TESTING_ARB_L2_ERC20_TOKEN_GATEWAY= - -# Below addresses are not required when the gateway uses the default Arbitrum router -TESTING_ARB_L1_GATEWAY_ROUTER= -TESTING_ARB_L2_GATEWAY_ROUTER= - # Addresses of the Optimism bridge TESTING_OPT_NETWORK= TESTING_OPT_L1_TOKEN= @@ -163,17 +142,13 @@ E2E tests run on the real contracts deployed on the testnet networks. To run suc [`TESTING_PRIVATE_KEY`](#TESTING_PRIVATE_KEY) [`TESTING_OPT_LDO_HOLDER_PRIVATE_KEY`](#TESTING_OPT_LDO_HOLDER_PRIVATE_KEY) -[`TESTING_ARB_LDO_HOLDER_PRIVATE_KEY`](#TESTING_ARB_LDO_HOLDER_PRIVATE_KEY) To run E2E tests use the following commands: ```bash -# Run E2E tests for both Arbitrum and Optimism bridges +# Run E2E tests for Optimism bridge npm run test:e2e -# Run E2E tests for Arbitrum bridge -npm run arbitrum:test:e2e - # Run E2E tests for Optimism bridge npm run optimism:test:e2e ``` @@ -184,17 +159,6 @@ Additionally, tests might be run on the deployed contracts. To do it, set the fo # private key of the tester. It must have tokens for testing TESTING_PRIVATE_KEY= -# Addresses of the Arbitrum gateway -TESTING_ARB_NETWORK= -TESTING_ARB_L1_TOKEN= -TESTING_ARB_L2_TOKEN= -TESTING_ARB_L1_ERC20_TOKEN_GATEWAY= -TESTING_ARB_L2_ERC20_TOKEN_GATEWAY= - -# Below addresses are not required when the gateway uses the default Arbitrum router -TESTING_ARB_L1_GATEWAY_ROUTER= -TESTING_ARB_L2_GATEWAY_ROUTER= - # Addresses of the Optimism bridge TESTING_OPT_NETWORK= TESTING_OPT_L1_TOKEN= @@ -210,16 +174,6 @@ The acceptance tests might be run after the deployment to validate that the brid The following ENV variables must be set before the tests running: ```bash -# Addresses of the Arbitrum gateway -TESTING_ARB_L1_TOKEN= -TESTING_ARB_L2_TOKEN= -TESTING_ARB_L1_ERC20_TOKEN_GATEWAY= -TESTING_ARB_L2_ERC20_TOKEN_GATEWAY= - -# Below addresses are not required when the gateway uses the default Arbitrum router -TESTING_ARB_L1_GATEWAY_ROUTER= -TESTING_ARB_L2_GATEWAY_ROUTER= - # Addresses of the Optimism bridge TESTING_OPT_L1_TOKEN= TESTING_OPT_L2_TOKEN= @@ -232,9 +186,6 @@ To run the acceptance tests, use the following commands: ```bash # Optimism bridge npm run optimism:test:acceptance - -# Arbitrum bridge -npm run arbitrum:test:acceptance ``` ## Code Coverage @@ -255,31 +206,13 @@ The configuration of the project happens via set of ENV variables. The full list Address of the RPC node for **Mainnet** Ethereum network. -#### `RPC_ETH_GOERLI` - -Address of the RPC node for **Goerli** Ethereum network. - -#### `RPC_ARB_MAINNET` - -> **Warning** -> -> Please, don't use the default value for production deployments! The default RPC node might not be available or fail suddenly during the request. - -Address of the RPC node for **Mainnet** Arbitrum network. - -> Default value: `https://arb1.arbitrum.io/rpc` - -#### `RPC_ARB_GOERLI` - -Address of the RPC node for **Goerli** Arbitrum network. - -> Default value: `https://goerli-rollup.arbitrum.io/rpc` +#### `RPC_ETH_SEPOLIA` -#### `RPC_OPT_GOERLI` +Address of the RPC node for **Sepolia** Ethereum network. -Address of the RPC node for **Goerli** Optimism network. +#### `RPC_OPT_SEPOLIA` -> Default value: `https://goerli-rollup.arbitrum.io/rpc` +Address of the RPC node for **Sepolia** Optimism network. #### `RPC_OPT_MAINNET` @@ -300,9 +233,6 @@ Below variables are required for successfull verification of the contracts on bl API key from the [Etherscan](https://etherscan.io/) block explorer. See details here: https://info.etherscan.com/api-keys/ -#### `ETHERSCAN_API_KEY_ARB` - -API key from the [Arbiscan](https://arbiscan.io/) block explorer. #### `ETHERSCAN_API_KEY_OPT` @@ -310,17 +240,21 @@ API key from the [Optimistic Ethereum](https://optimistic.etherscan.io/) block e ### Bridge/Gateway Deployment -Below variables used in the Arbitrum/Optimism bridge deployment process. +Below variables used in the Optimism bridge deployment process. #### `TOKEN` -Address of the token to deploy a new bridge on the Ethereum chain. +Address of the existing non-rebasable token to deploy a new bridge for on the Ethereum chain. + +#### `REBASABLE_TOKEN` + +Address of the existing rebasable token to deploy new bridge for on the Ethereum chain. #### `NETWORK` > Default value: `mainnet` -Name of the network environments used by deployment scripts. Might be one of: `mainnet`, `goerli`. +Name of the network environments used by deployment scripts. Might be one of: `mainnet`, `sepolia`. #### `FORKING` @@ -332,10 +266,6 @@ Run deployment in the forking network instead of public ones The private key of the deployer account in the Ethereum network is used during the deployment process. -#### `ARB_DEPLOYER_PRIVATE_KEY` - -The private key of the deployer account in the Arbitrum network is used during the deployment process. - #### `OPT_DEPLOYER_PRIVATE_KEY` The private key of the deployer account in the Optimism network is used during the deployment process. @@ -440,49 +370,9 @@ The array of addresses to grant `WITHDRAWALS_DISABLER_ROLE` on L2 bridge/gateway The following variables are used in the process of the Integration & E2E testing. -#### `TESTING_ARB_NETWORK` - -Name of the network environments used for Arbitrum Integration & E2E testing. Might be one of: `mainnet`, `goerli`. - -#### `TESTING_ARB_L1_TOKEN` - -Address of the token to use in the Acceptance Integration & E2E (when `TESTING_USE_DEPLOYED_CONTRACTS` is set to true) testing of the bridging between Ethereum and Arbitrum networks. - -> Default value: `0x7AEE39c46f20135114e85A03C02aB4FE73fB8127` - -#### `TESTING_ARB_L2_TOKEN` - -Address of the token minted on L2 in the Acceptance Integration & E2E (when `TESTING_USE_DEPLOYED_CONTRACTS` is set to true) testing of the bridging between Ethereum and Arbitrum networks. - -> Default value: `0x775ede8029C117effce283b3391E420EacF3c85F` - -#### `TESTING_ARB_L1_ERC20_TOKEN_GATEWAY` - -Address of the L1 ERC20 token gateway used in the Acceptance Integration & E2E (when `TESTING_USE_DEPLOYED_CONTRACTS` is set to true) testing of the bridging between Ethereum and Arbitrum networks. - -> Default value: `0x0A7e12b563Ba623646a31a09F0182e8aD45D6cfD` - -#### `TESTING_ARB_L2_ERC20_TOKEN_GATEWAY` - -Address of the L2 ERC20 token gateway used in the Acceptance Integration & E2E (when `TESTING_USE_DEPLOYED_CONTRACTS` is set to true) testing of the bridging between Ethereum and Arbitrum networks. - -> Default value: `0x8c269989D839eE9DaEe64D57C8c41404DF87F722` - -#### `TESTING_ARB_L1_GATEWAY_ROUTER` - -Address of the L1 gateway router used in the Acceptance Integration & E2E (when `TESTING_USE_DEPLOYED_CONTRACTS` is set to true) testing of the bridging between Ethereum and Arbitrum networks. If not set, will be used default Arbitrum's L1 Gateway Router - -> Default value: `0xa2a8F940752aDc4A3278B63B96d56D72D2b075B1` - -#### `TESTING_ARB_L2_GATEWAY_ROUTER` - -Address of the L2 gateway router used in the Acceptance Integration & E2E (when `TESTING_USE_DEPLOYED_CONTRACTS` is set to true) testing of the bridging between Ethereum and Arbitrum networks. If not set, will be used default Arbitrum's L2 Gateway Router - -> Default value: `0x57f54f87C44d816f60b92864e23b8c0897D4d81D` - #### `TESTING_OPT_NETWORK` -Name of the network environments used for Optimism Integration & E2E testing. Might be one of: `mainnet`, `goerli`. +Name of the network environments used for Optimism Integration & E2E testing. Might be one of: `mainnet`, `sepolia`. #### `TESTING_OPT_L1_TOKEN` @@ -518,10 +408,6 @@ When set to `true` integration tests will use addresses of deployed contracts se When `TESTING_USE_DEPLOYED_CONTRACTS` is set to true, this address will be used as the holder of the tokens, bridged between L1 and L2. -#### `TESTING_ARB_GOV_BRIDGE_EXECUTOR` - -Address of the deployed Governance Bridge Executor in the Arbitrum network. If set, this contract will be used for integration tests of Governance Bridge. - #### `TESTING_OPT_GOV_BRIDGE_EXECUTOR` Address of the deployed Governance Bridge Executor in the Optimism network. If set, this contract will be used for integration tests of Governance Bridge. @@ -532,7 +418,7 @@ Address of the deployed Governance Bridge Executor in the Optimism network. If s The private key from the address which holds: -- Goerli and Arbitrum/Optimistic Goerli Ether to launch Arbitrum/Optimism E2E tests +- Sepolia and Optimistic Sepolia Ether to launch Optimism E2E tests The test Ether might be retrived via [Paradigm Faucet](https://faucet.paradigm.xyz/). @@ -540,6 +426,3 @@ The test Ether might be retrived via [Paradigm Faucet](https://faucet.paradigm.x The private key from the address which holds 50+% TLDO -#### `TESTING_ARB_LDO_HOLDER_PRIVATE_KEY` - -The private key from the address which holds 50+% TLDO diff --git a/abi/arbitrum/L1GatewayRouter.json b/abi/arbitrum/L1GatewayRouter.json deleted file mode 100644 index c3fd4bcf..00000000 --- a/abi/arbitrum/L1GatewayRouter.json +++ /dev/null @@ -1,362 +0,0 @@ -[ - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "address", - "name": "newDefaultGateway", - "type": "address" - } - ], - "name": "DefaultGatewayUpdated", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "l1Token", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "gateway", - "type": "address" - } - ], - "name": "GatewaySet", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "token", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "_userFrom", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "_userTo", - "type": "address" - }, - { - "indexed": false, - "internalType": "address", - "name": "gateway", - "type": "address" - } - ], - "name": "TransferRouted", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "_from", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "_to", - "type": "address" - }, - { - "indexed": true, - "internalType": "uint256", - "name": "_seqNum", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "bytes", - "name": "_data", - "type": "bytes" - } - ], - "name": "TxToL2", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "address", - "name": "newSource", - "type": "address" - } - ], - "name": "WhitelistSourceUpdated", - "type": "event" - }, - { - "inputs": [ - { "internalType": "address", "name": "l1ERC20", "type": "address" } - ], - "name": "calculateL2TokenAddress", - "outputs": [{ "internalType": "address", "name": "", "type": "address" }], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "counterpartGateway", - "outputs": [{ "internalType": "address", "name": "", "type": "address" }], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "defaultGateway", - "outputs": [{ "internalType": "address", "name": "", "type": "address" }], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { "internalType": "address", "name": "", "type": "address" }, - { "internalType": "address", "name": "", "type": "address" }, - { "internalType": "address", "name": "", "type": "address" }, - { "internalType": "uint256", "name": "", "type": "uint256" }, - { "internalType": "bytes", "name": "", "type": "bytes" } - ], - "name": "finalizeInboundTransfer", - "outputs": [], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [ - { "internalType": "address", "name": "_token", "type": "address" } - ], - "name": "getGateway", - "outputs": [ - { "internalType": "address", "name": "gateway", "type": "address" } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { "internalType": "address", "name": "_token", "type": "address" }, - { "internalType": "address", "name": "_from", "type": "address" }, - { "internalType": "address", "name": "_to", "type": "address" }, - { "internalType": "uint256", "name": "_amount", "type": "uint256" }, - { "internalType": "bytes", "name": "_data", "type": "bytes" } - ], - "name": "getOutboundCalldata", - "outputs": [{ "internalType": "bytes", "name": "", "type": "bytes" }], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "inbox", - "outputs": [{ "internalType": "address", "name": "", "type": "address" }], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { "internalType": "address", "name": "_owner", "type": "address" }, - { - "internalType": "address", - "name": "_defaultGateway", - "type": "address" - }, - { "internalType": "address", "name": "", "type": "address" }, - { - "internalType": "address", - "name": "_counterpartGateway", - "type": "address" - }, - { "internalType": "address", "name": "_inbox", "type": "address" } - ], - "name": "initialize", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [{ "internalType": "address", "name": "", "type": "address" }], - "name": "l1TokenToGateway", - "outputs": [{ "internalType": "address", "name": "", "type": "address" }], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { "internalType": "address", "name": "_token", "type": "address" }, - { "internalType": "address", "name": "_to", "type": "address" }, - { "internalType": "uint256", "name": "_amount", "type": "uint256" }, - { "internalType": "uint256", "name": "_maxGas", "type": "uint256" }, - { "internalType": "uint256", "name": "_gasPriceBid", "type": "uint256" }, - { "internalType": "bytes", "name": "_data", "type": "bytes" } - ], - "name": "outboundTransfer", - "outputs": [{ "internalType": "bytes", "name": "", "type": "bytes" }], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [ - { "internalType": "address", "name": "_token", "type": "address" }, - { "internalType": "address", "name": "_refundTo", "type": "address" }, - { "internalType": "address", "name": "_to", "type": "address" }, - { "internalType": "uint256", "name": "_amount", "type": "uint256" }, - { "internalType": "uint256", "name": "_maxGas", "type": "uint256" }, - { "internalType": "uint256", "name": "_gasPriceBid", "type": "uint256" }, - { "internalType": "bytes", "name": "_data", "type": "bytes" } - ], - "name": "outboundTransferCustomRefund", - "outputs": [{ "internalType": "bytes", "name": "", "type": "bytes" }], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [], - "name": "owner", - "outputs": [{ "internalType": "address", "name": "", "type": "address" }], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "postUpgradeInit", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "router", - "outputs": [{ "internalType": "address", "name": "", "type": "address" }], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "newL1DefaultGateway", - "type": "address" - }, - { "internalType": "uint256", "name": "_maxGas", "type": "uint256" }, - { "internalType": "uint256", "name": "_gasPriceBid", "type": "uint256" }, - { - "internalType": "uint256", - "name": "_maxSubmissionCost", - "type": "uint256" - } - ], - "name": "setDefaultGateway", - "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [ - { "internalType": "address", "name": "_gateway", "type": "address" }, - { "internalType": "uint256", "name": "_maxGas", "type": "uint256" }, - { "internalType": "uint256", "name": "_gasPriceBid", "type": "uint256" }, - { - "internalType": "uint256", - "name": "_maxSubmissionCost", - "type": "uint256" - }, - { - "internalType": "address", - "name": "_creditBackAddress", - "type": "address" - } - ], - "name": "setGateway", - "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [ - { "internalType": "address", "name": "_gateway", "type": "address" }, - { "internalType": "uint256", "name": "_maxGas", "type": "uint256" }, - { "internalType": "uint256", "name": "_gasPriceBid", "type": "uint256" }, - { - "internalType": "uint256", - "name": "_maxSubmissionCost", - "type": "uint256" - } - ], - "name": "setGateway", - "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [ - { "internalType": "address[]", "name": "_token", "type": "address[]" }, - { "internalType": "address[]", "name": "_gateway", "type": "address[]" }, - { "internalType": "uint256", "name": "_maxGas", "type": "uint256" }, - { "internalType": "uint256", "name": "_gasPriceBid", "type": "uint256" }, - { - "internalType": "uint256", - "name": "_maxSubmissionCost", - "type": "uint256" - } - ], - "name": "setGateways", - "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [ - { "internalType": "address", "name": "newOwner", "type": "address" } - ], - "name": "setOwner", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { "internalType": "bytes4", "name": "interfaceId", "type": "bytes4" } - ], - "name": "supportsInterface", - "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { "internalType": "address", "name": "newSource", "type": "address" } - ], - "name": "updateWhitelistSource", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "whitelist", - "outputs": [{ "internalType": "address", "name": "", "type": "address" }], - "stateMutability": "view", - "type": "function" - } -] diff --git a/abi/arbitrum/L2GatewayRouter.json b/abi/arbitrum/L2GatewayRouter.json deleted file mode 100644 index c03fa729..00000000 --- a/abi/arbitrum/L2GatewayRouter.json +++ /dev/null @@ -1,244 +0,0 @@ -[ - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "address", - "name": "newDefaultGateway", - "type": "address" - } - ], - "name": "DefaultGatewayUpdated", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "l1Token", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "gateway", - "type": "address" - } - ], - "name": "GatewaySet", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "token", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "_userFrom", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "_userTo", - "type": "address" - }, - { - "indexed": false, - "internalType": "address", - "name": "gateway", - "type": "address" - } - ], - "name": "TransferRouted", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "_from", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "_to", - "type": "address" - }, - { - "indexed": true, - "internalType": "uint256", - "name": "_id", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "bytes", - "name": "_data", - "type": "bytes" - } - ], - "name": "TxToL1", - "type": "event" - }, - { - "inputs": [ - { "internalType": "address", "name": "l1ERC20", "type": "address" } - ], - "name": "calculateL2TokenAddress", - "outputs": [{ "internalType": "address", "name": "", "type": "address" }], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "counterpartGateway", - "outputs": [{ "internalType": "address", "name": "", "type": "address" }], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "defaultGateway", - "outputs": [{ "internalType": "address", "name": "", "type": "address" }], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { "internalType": "address", "name": "", "type": "address" }, - { "internalType": "address", "name": "", "type": "address" }, - { "internalType": "address", "name": "", "type": "address" }, - { "internalType": "uint256", "name": "", "type": "uint256" }, - { "internalType": "bytes", "name": "", "type": "bytes" } - ], - "name": "finalizeInboundTransfer", - "outputs": [], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [ - { "internalType": "address", "name": "_token", "type": "address" } - ], - "name": "getGateway", - "outputs": [ - { "internalType": "address", "name": "gateway", "type": "address" } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { "internalType": "address", "name": "_token", "type": "address" }, - { "internalType": "address", "name": "_from", "type": "address" }, - { "internalType": "address", "name": "_to", "type": "address" }, - { "internalType": "uint256", "name": "_amount", "type": "uint256" }, - { "internalType": "bytes", "name": "_data", "type": "bytes" } - ], - "name": "getOutboundCalldata", - "outputs": [{ "internalType": "bytes", "name": "", "type": "bytes" }], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_counterpartGateway", - "type": "address" - }, - { - "internalType": "address", - "name": "_defaultGateway", - "type": "address" - } - ], - "name": "initialize", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [{ "internalType": "address", "name": "", "type": "address" }], - "name": "l1TokenToGateway", - "outputs": [{ "internalType": "address", "name": "", "type": "address" }], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { "internalType": "address", "name": "_l1Token", "type": "address" }, - { "internalType": "address", "name": "_to", "type": "address" }, - { "internalType": "uint256", "name": "_amount", "type": "uint256" }, - { "internalType": "bytes", "name": "_data", "type": "bytes" } - ], - "name": "outboundTransfer", - "outputs": [{ "internalType": "bytes", "name": "", "type": "bytes" }], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [ - { "internalType": "address", "name": "_token", "type": "address" }, - { "internalType": "address", "name": "_to", "type": "address" }, - { "internalType": "uint256", "name": "_amount", "type": "uint256" }, - { "internalType": "uint256", "name": "_maxGas", "type": "uint256" }, - { "internalType": "uint256", "name": "_gasPriceBid", "type": "uint256" }, - { "internalType": "bytes", "name": "_data", "type": "bytes" } - ], - "name": "outboundTransfer", - "outputs": [{ "internalType": "bytes", "name": "", "type": "bytes" }], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [], - "name": "postUpgradeInit", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "router", - "outputs": [{ "internalType": "address", "name": "", "type": "address" }], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "newL2DefaultGateway", - "type": "address" - } - ], - "name": "setDefaultGateway", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { "internalType": "address[]", "name": "_l1Token", "type": "address[]" }, - { "internalType": "address[]", "name": "_gateway", "type": "address[]" } - ], - "name": "setGateway", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - } -] diff --git a/artifacts-arb.json b/artifacts-arb.json deleted file mode 100644 index d27f07ba..00000000 --- a/artifacts-arb.json +++ /dev/null @@ -1,28 +0,0 @@ -[ - { - "artifactPath": "artifacts/contracts/proxy/OssifiableProxy.sol/OssifiableProxy.json", - "sourcePath": "contracts/proxy/OssifiableProxy.sol", - "name": "L2ERC20TokenGateway proxy", - "address": "0x07D4692291B9E30E326fd31706f686f83f331B82" - }, - { - "artifactPath": "artifacts/contracts/arbitrum/L2ERC20TokenGateway.sol/L2ERC20TokenGateway.json", - "sourcePath": "contracts/arbitrum/L2ERC20TokenGateway.sol", - "name": "L2ERC20TokenGateway", - "address": "0xe75886DE20dF66827e321EfdB88726e6Baa4b0A7", - "txHash": "0xe99cd25baf61300dcf57466bead148dac28fd975076593a8874bbdc64973696d" - }, - { - "artifactPath": "artifacts/contracts/proxy/OssifiableProxy.sol/OssifiableProxy.json", - "sourcePath": "contracts/proxy/OssifiableProxy.sol", - "name": "WstETH ERC20Bridged proxy", - "address": "0x5979D7b546E38E414F7E9822514be443A4800529" - }, - { - "artifactPath": "artifacts/contracts/token/ERC20Bridged.sol/ERC20Bridged.json", - "sourcePath": "contracts/token/ERC20Bridged.sol", - "name": "WstETH ERC20Bridged", - "address": "0x0fBcbaEA96Ce0cF7Ee00A8c19c3ab6f5Dc8E1921", - "txHash": "0x517ea5c206473d2116324939ab42f93ca1079a6388c0db41684e926e36e1a411" - } -] diff --git a/artifacts-eth.json b/artifacts-eth.json index 24dd4b91..c6f6ab47 100644 --- a/artifacts-eth.json +++ b/artifacts-eth.json @@ -1,18 +1,4 @@ [ - { - "artifactPath": "artifacts/contracts/proxy/OssifiableProxy.sol/OssifiableProxy.json", - "sourcePath": "contracts/proxy/OssifiableProxy.sol", - "name": "L1ERC20TokenGateway proxy", - "address": "0x0F25c1DC2a9922304f2eac71DCa9B07E310e8E5a", - "txHash": "0x912fc5992f5a24c2ffe5e230ac51fcc4724cb3e4a23535b04eec34f99f77e3a8" - }, - { - "artifactPath": "artifacts/contracts/arbitrum/L1ERC20TokenGateway.sol/L1ERC20TokenGateway.json", - "sourcePath": "contracts/arbitrum/L1ERC20TokenGateway.sol", - "name": "L1ERC20TokenGateway", - "address": "0xc4E3ff0b5B106f88Fc64c43031BE8b076ee9F21C", - "txHash": "0xce43376cd317471806c6ac2a8efbd5dc6dcfb7201ba643e447f446e50354edcf" - }, { "artifactPath": "artifacts/contracts/proxy/OssifiableProxy.sol/OssifiableProxy.json", "sourcePath": "contracts/proxy/OssifiableProxy.sol", diff --git a/artifacts-opt.json b/artifacts-opt.json index b97c0d24..7a302e37 100644 --- a/artifacts-opt.json +++ b/artifacts-opt.json @@ -2,13 +2,13 @@ { "artifactPath": "artifacts/contracts/proxy/OssifiableProxy.sol/OssifiableProxy.json", "sourcePath": "contracts/proxy/OssifiableProxy.sol", - "name": "L2ERC20TokenBridge proxy", + "name": "L2ERC20ExtendedTokensBridge proxy", "address": "0x8E01013243a96601a86eb3153F0d9Fa4fbFb6957" }, { - "artifactPath": "artifacts/contracts/optimism/L2ERC20TokenBridge.sol/L2ERC20TokenBridge.json", - "sourcePath": "contracts/optimism/L2ERC20TokenBridge.sol", - "name": "L2ERC20TokenBridge", + "artifactPath": "artifacts/contracts/optimism/L2ERC20ExtendedTokensBridge.sol/L2ERC20ExtendedTokensBridge.json", + "sourcePath": "contracts/optimism/L2ERC20ExtendedTokensBridge.sol", + "name": "L2ERC20ExtendedTokensBridge", "address": "0x23B96aDD54c479C6784Dd504670B5376B808f4C7", "txHash": "0x5d69e9c6ec1d634f0d90812c2189c925993d1fffbc9b0b416fdc123e15407c56" }, diff --git a/contracts/BridgeableTokens.sol b/contracts/BridgeableTokens.sol deleted file mode 100644 index 52ec31af..00000000 --- a/contracts/BridgeableTokens.sol +++ /dev/null @@ -1,49 +0,0 @@ -// SPDX-FileCopyrightText: 2022 Lido -// SPDX-License-Identifier: GPL-3.0 - -pragma solidity 0.8.10; - -/// @author psirex -/// @notice Contains the logic for validation of tokens used in the bridging process -contract BridgeableTokens { - /// @notice Address of the bridged token in the L1 chain - address public immutable l1Token; - - /// @notice Address of the token minted on the L2 chain when token bridged - address public immutable l2Token; - - /// @param l1Token_ Address of the bridged token in the L1 chain - /// @param l2Token_ Address of the token minted on the L2 chain when token bridged - constructor(address l1Token_, address l2Token_) { - l1Token = l1Token_; - l2Token = l2Token_; - } - - /// @dev Validates that passed l1Token_ is supported by the bridge - modifier onlySupportedL1Token(address l1Token_) { - if (l1Token_ != l1Token) { - revert ErrorUnsupportedL1Token(); - } - _; - } - - /// @dev Validates that passed l2Token_ is supported by the bridge - modifier onlySupportedL2Token(address l2Token_) { - if (l2Token_ != l2Token) { - revert ErrorUnsupportedL2Token(); - } - _; - } - - /// @dev validates that account_ is not zero address - modifier onlyNonZeroAccount(address account_) { - if (account_ == address(0)) { - revert ErrorAccountIsZeroAddress(); - } - _; - } - - error ErrorUnsupportedL1Token(); - error ErrorUnsupportedL2Token(); - error ErrorAccountIsZeroAddress(); -} diff --git a/contracts/BridgingManager.sol b/contracts/BridgingManager.sol index abffef4d..bb844aff 100644 --- a/contracts/BridgingManager.sol +++ b/contracts/BridgingManager.sol @@ -1,11 +1,11 @@ -// SPDX-FileCopyrightText: 2022 Lido +// SPDX-FileCopyrightText: 2024 Lido // SPDX-License-Identifier: GPL-3.0 pragma solidity 0.8.10; import {AccessControl} from "@openzeppelin/contracts/access/AccessControl.sol"; -/// @author psirex +/// @author psirex, kovalgek /// @notice Contains administrative methods to retrieve and control the state of the bridging contract BridgingManager is AccessControl { /// @dev Stores the state of the bridging @@ -13,6 +13,9 @@ contract BridgingManager is AccessControl { /// @param isDepositsEnabled Stores the state of the deposits /// @param isWithdrawalsEnabled Stores the state of the withdrawals struct State { + /// @dev This variable is used to determine whether the contract has been initialized or not. + /// At the same time, bridges have their own code for initialization and storage versioning. + /// Therefore, it is recommended to base upgrade logic on new mechanisms since v2. bool isInitialized; bool isDepositsEnabled; bool isWithdrawalsEnabled; @@ -34,12 +37,15 @@ contract BridgingManager is AccessControl { /// @notice Initializes the contract to grant DEFAULT_ADMIN_ROLE to the admin_ address /// @dev This method might be called only once /// @param admin_ Address of the account to grant the DEFAULT_ADMIN_ROLE - function initialize(address admin_) external { + function _initializeBridgingManager(address admin_) internal { + if (admin_ == address(0)) { + revert ErrorZeroAddressAdmin(); + } State storage s = _loadState(); if (s.isInitialized) { revert ErrorAlreadyInitialized(); } - _setupRole(DEFAULT_ADMIN_ROLE, admin_); + _grantRole(DEFAULT_ADMIN_ROLE, admin_); s.isInitialized = true; emit Initialized(admin_); } @@ -97,6 +103,11 @@ contract BridgingManager is AccessControl { emit WithdrawalsDisabled(msg.sender); } + function _isBridgingManagerInitialized() internal view returns (bool) { + State storage s = _loadState(); + return s.isInitialized; + } + /// @dev Returns the reference to the slot with State struct function _loadState() private pure returns (State storage r) { bytes32 slot = STATE_SLOT; @@ -127,9 +138,11 @@ contract BridgingManager is AccessControl { event WithdrawalsDisabled(address indexed disabler); event Initialized(address indexed admin); + error ErrorZeroAddressAdmin(); error ErrorDepositsEnabled(); error ErrorDepositsDisabled(); error ErrorWithdrawalsEnabled(); error ErrorWithdrawalsDisabled(); error ErrorAlreadyInitialized(); + error ErrorBridgingManagerIsNotInitialized(); } diff --git a/contracts/arbitrum/InterchainERC20TokenGateway.sol b/contracts/arbitrum/InterchainERC20TokenGateway.sol deleted file mode 100644 index 329f4c87..00000000 --- a/contracts/arbitrum/InterchainERC20TokenGateway.sol +++ /dev/null @@ -1,71 +0,0 @@ -// SPDX-FileCopyrightText: 2022 Lido -// SPDX-License-Identifier: GPL-3.0 - -pragma solidity 0.8.10; - -import {BridgingManager} from "../BridgingManager.sol"; -import {BridgeableTokens} from "../BridgeableTokens.sol"; - -import {IInterchainTokenGateway} from "./interfaces/IInterchainTokenGateway.sol"; - -/// @author psirex -/// @notice The contract keeps logic shared among both L1 and L2 gateways, adding the methods for -/// bridging management: enabling and disabling withdrawals/deposits -abstract contract InterchainERC20TokenGateway is - BridgingManager, - BridgeableTokens, - IInterchainTokenGateway -{ - /// @notice Address of the router in the corresponding chain - address public immutable router; - - /// @inheritdoc IInterchainTokenGateway - address public immutable counterpartGateway; - - /// @param router_ Address of the router in the corresponding chain - /// @param counterpartGateway_ Address of the counterpart gateway used in the bridging process - /// @param l1Token_ Address of the bridged token in the Ethereum chain - /// @param l2Token_ Address of the token minted on the Arbitrum chain when token bridged - constructor( - address router_, - address counterpartGateway_, - address l1Token_, - address l2Token_ - ) BridgeableTokens(l1Token_, l2Token_) { - router = router_; - counterpartGateway = counterpartGateway_; - } - - /// @inheritdoc IInterchainTokenGateway - /// @dev The current implementation returns the l2Token address when passed l1Token_ equals - /// to l1Token declared in the contract and address(0) in other cases - function calculateL2TokenAddress(address l1Token_) - external - view - returns (address) - { - if (l1Token_ == l1Token) { - return l2Token; - } - return address(0); - } - - /// @inheritdoc IInterchainTokenGateway - function getOutboundCalldata( - address l1Token_, - address from_, - address to_, - uint256 amount_, - bytes memory // data_ - ) public pure returns (bytes memory) { - return - abi.encodeWithSelector( - IInterchainTokenGateway.finalizeInboundTransfer.selector, - l1Token_, - from_, - to_, - amount_, - "" - ); - } -} diff --git a/contracts/arbitrum/L1CrossDomainEnabled.sol b/contracts/arbitrum/L1CrossDomainEnabled.sol deleted file mode 100644 index 5a7b4e06..00000000 --- a/contracts/arbitrum/L1CrossDomainEnabled.sol +++ /dev/null @@ -1,104 +0,0 @@ -// SPDX-FileCopyrightText: 2022 Lido -// SPDX-License-Identifier: GPL-3.0 - -pragma solidity 0.8.10; - -import {IInbox} from "./interfaces/IInbox.sol"; -import {IBridge} from "./interfaces/IBridge.sol"; -import {IOutbox} from "./interfaces/IOutbox.sol"; - -/// @author psirex -/// @notice A helper contract to simplify Ethereum to Arbitrum communication process process -/// via Retryable Tickets -contract L1CrossDomainEnabled { - /// @notice Address of the Arbitrum's Inbox contract - IInbox public immutable inbox; - - /// @param inbox_ Address of the Arbitrum's Inbox contract - constructor(address inbox_) { - inbox = IInbox(inbox_); - } - - /// @dev Properties required to create RetryableTicket - /// @param maxGas Gas limit for immediate L2 execution attempt - /// @param callValue Call-value for L2 transaction - /// @param gasPriceBid L2 Gas price bid for immediate L2 execution attempt - /// @param maxSubmissionCost Amount of ETH allocated to pay for the base submission fee - struct CrossDomainMessageOptions { - uint256 maxGas; - uint256 callValue; - uint256 gasPriceBid; - uint256 maxSubmissionCost; - } - - /// @notice Creates a Retryable Ticket via Inbox.createRetryableTicket function using - /// the provided arguments - /// @param sender_ Address of the sender of the message - /// @param recipient_ Address of the recipient of the message on the L2 chain - /// @param data_ Data passed to the recipient_ in the message - /// @param msgOptions_ Instance of the `CrossDomainMessageOptions` struct - /// @return seqNum Unique id of created Retryable Ticket. - function sendCrossDomainMessage( - address sender_, - address recipient_, - bytes memory data_, - CrossDomainMessageOptions memory msgOptions_ - ) internal returns (uint256 seqNum) { - if (msgOptions_.maxSubmissionCost == 0) { - revert ErrorNoMaxSubmissionCost(); - } - - uint256 minEthValue = msgOptions_.callValue + - msgOptions_.maxSubmissionCost + - (msgOptions_.maxGas * msgOptions_.gasPriceBid); - - if (msg.value < minEthValue) { - revert ErrorETHValueTooLow(); - } - - seqNum = inbox.createRetryableTicket{value: msg.value}( - recipient_, - msgOptions_.callValue, - msgOptions_.maxSubmissionCost, - sender_, - sender_, - msgOptions_.maxGas, - msgOptions_.gasPriceBid, - data_ - ); - - emit TxToL2(sender_, recipient_, seqNum, data_); - } - - /// @notice Validates that transaction was initiated by the crossDomainAccount_ address from - /// the L2 chain - modifier onlyFromCrossDomainAccount(address crossDomainAccount_) { - address bridge = inbox.bridge(); - - // a message coming from the counterpart gateway was executed by the bridge - if (msg.sender != bridge) { - revert ErrorUnauthorizedBridge(); - } - - address l2ToL1Sender = IOutbox(IBridge(bridge).activeOutbox()) - .l2ToL1Sender(); - - // and the outbox reports that the L2 address of the sender is the counterpart gateway - if (l2ToL1Sender != crossDomainAccount_) { - revert ErrorWrongCrossDomainSender(); - } - _; - } - - event TxToL2( - address indexed from, - address indexed to, - uint256 indexed seqNum, - bytes data - ); - - error ErrorETHValueTooLow(); - error ErrorUnauthorizedBridge(); - error ErrorNoMaxSubmissionCost(); - error ErrorWrongCrossDomainSender(); -} diff --git a/contracts/arbitrum/L1ERC20TokenGateway.sol b/contracts/arbitrum/L1ERC20TokenGateway.sol deleted file mode 100644 index 1be951aa..00000000 --- a/contracts/arbitrum/L1ERC20TokenGateway.sol +++ /dev/null @@ -1,120 +0,0 @@ -// SPDX-FileCopyrightText: 2022 Lido -// SPDX-License-Identifier: GPL-3.0 - -pragma solidity 0.8.10; - -import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; -import {SafeERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; - -import {IL1TokenGateway, IInterchainTokenGateway} from "./interfaces/IL1TokenGateway.sol"; - -import {L1CrossDomainEnabled} from "./L1CrossDomainEnabled.sol"; -import {L1OutboundDataParser} from "./libraries/L1OutboundDataParser.sol"; -import {InterchainERC20TokenGateway} from "./InterchainERC20TokenGateway.sol"; - -/// @author psirex -/// @notice Contract implements ITokenGateway interface and with counterpart L2ERC20TokenGatewy -/// allows bridging registered ERC20 compatible tokens between Ethereum and Arbitrum chains -contract L1ERC20TokenGateway is - InterchainERC20TokenGateway, - L1CrossDomainEnabled, - IL1TokenGateway -{ - using SafeERC20 for IERC20; - - /// @param inbox_ Address of the Arbitrum’s Inbox contract in the L1 chain - /// @param router_ Address of the router in the L1 chain - /// @param counterpartGateway_ Address of the counterpart L2 gateway - /// @param l1Token_ Address of the bridged token in the L1 chain - /// @param l2Token_ Address of the token minted on the Arbitrum chain when token bridged - constructor( - address inbox_, - address router_, - address counterpartGateway_, - address l1Token_, - address l2Token_ - ) - InterchainERC20TokenGateway( - router_, - counterpartGateway_, - l1Token_, - l2Token_ - ) - L1CrossDomainEnabled(inbox_) - {} - - /// @inheritdoc IL1TokenGateway - function outboundTransfer( - address l1Token_, - address to_, - uint256 amount_, - uint256 maxGas_, - uint256 gasPriceBid_, - bytes calldata data_ - ) - external - payable - whenDepositsEnabled - onlyNonZeroAccount(to_) - onlySupportedL1Token(l1Token_) - returns (bytes memory) - { - (address from, uint256 maxSubmissionCost) = L1OutboundDataParser.decode( - router, - data_ - ); - - IERC20(l1Token_).safeTransferFrom(from, address(this), amount_); - - uint256 retryableTicketId = _sendOutboundTransferMessage( - from, - to_, - amount_, - CrossDomainMessageOptions({ - maxGas: maxGas_, - callValue: 0, - gasPriceBid: gasPriceBid_, - maxSubmissionCost: maxSubmissionCost - }) - ); - - emit DepositInitiated(l1Token, from, to_, retryableTicketId, amount_); - - return abi.encode(retryableTicketId); - } - - /// @inheritdoc IInterchainTokenGateway - function finalizeInboundTransfer( - address l1Token_, - address from_, - address to_, - uint256 amount_, - bytes calldata // data_ - ) - external - whenWithdrawalsEnabled - onlySupportedL1Token(l1Token_) - onlyFromCrossDomainAccount(counterpartGateway) - { - IERC20(l1Token_).safeTransfer(to_, amount_); - - // The current implementation doesn't support fast withdrawals, so we - // always use 0 for the exitNum argument in the event - emit WithdrawalFinalized(l1Token_, from_, to_, 0, amount_); - } - - function _sendOutboundTransferMessage( - address from_, - address to_, - uint256 amount_, - CrossDomainMessageOptions memory messageOptions - ) private returns (uint256) { - return - sendCrossDomainMessage( - from_, - counterpartGateway, - getOutboundCalldata(l1Token, from_, to_, amount_, ""), - messageOptions - ); - } -} diff --git a/contracts/arbitrum/L2CrossDomainEnabled.sol b/contracts/arbitrum/L2CrossDomainEnabled.sol deleted file mode 100644 index b3ec7fea..00000000 --- a/contracts/arbitrum/L2CrossDomainEnabled.sol +++ /dev/null @@ -1,64 +0,0 @@ -// SPDX-FileCopyrightText: 2022 Lido -// SPDX-License-Identifier: GPL-3.0 - -pragma solidity 0.8.10; - -import {IArbSys} from "./interfaces/IArbSys.sol"; - -/// @author psirex -/// @notice A helper contract to simplify Arbitrum to Ethereum communication process -contract L2CrossDomainEnabled { - uint160 private constant ADDRESS_OFFSET = - uint160(0x1111000000000000000000000000000000001111); - - /// @notice Address of the Arbitrum’s ArbSys contract - IArbSys public immutable arbSys; - - /// @param arbSys_ Address of the Arbitrum’s ArbSys contract - constructor(address arbSys_) { - arbSys = IArbSys(arbSys_); - } - - /// @notice Sends the message to the Ethereum chain - /// @param sender_ Address of the sender of the message - /// @param recipient_ Address of the recipient of the message on the Ethereum chain - /// @param data_ Data passed to the recipient in the message - /// @return id Unique identifier for this L2-to-L1 transaction - function sendCrossDomainMessage( - address sender_, - address recipient_, - bytes memory data_ - ) internal returns (uint256 id) { - id = IArbSys(arbSys).sendTxToL1(recipient_, data_); - emit TxToL1(sender_, recipient_, id, data_); - } - - /// @dev L1 addresses are transformed durng l1 -> l2 calls - function applyL1ToL2Alias(address l1Address_) - private - pure - returns (address l1Address) - { - unchecked { - l1Address = address(uint160(l1Address_) + ADDRESS_OFFSET); - } - } - - /// @notice Validates that the sender address with applied Arbitrum's aliasing is equal to - /// the crossDomainAccount_ address - modifier onlyFromCrossDomainAccount(address crossDomainAccount_) { - if (msg.sender != applyL1ToL2Alias(crossDomainAccount_)) { - revert ErrorWrongCrossDomainSender(); - } - _; - } - - event TxToL1( - address indexed from, - address indexed to, - uint256 indexed id, - bytes data - ); - - error ErrorWrongCrossDomainSender(); -} diff --git a/contracts/arbitrum/L2ERC20TokenGateway.sol b/contracts/arbitrum/L2ERC20TokenGateway.sol deleted file mode 100644 index 5853d0ac..00000000 --- a/contracts/arbitrum/L2ERC20TokenGateway.sol +++ /dev/null @@ -1,90 +0,0 @@ -// SPDX-FileCopyrightText: 2022 Lido -// SPDX-License-Identifier: GPL-3.0 - -pragma solidity 0.8.10; - -import {IERC20Bridged} from "../token/interfaces/IERC20Bridged.sol"; -import {IL2TokenGateway, IInterchainTokenGateway} from "./interfaces/IL2TokenGateway.sol"; - -import {L2CrossDomainEnabled} from "./L2CrossDomainEnabled.sol"; -import {L2OutboundDataParser} from "./libraries/L2OutboundDataParser.sol"; -import {InterchainERC20TokenGateway} from "./InterchainERC20TokenGateway.sol"; - -/// @author psirex -/// @notice Contract implements ITokenGateway interface and with counterpart L1ERC20TokenGateway -/// allows bridging registered ERC20 compatible tokens between Arbitrum and Ethereum chains -contract L2ERC20TokenGateway is - InterchainERC20TokenGateway, - L2CrossDomainEnabled, - IL2TokenGateway -{ - /// @param arbSys_ Address of the Arbitrum’s ArbSys contract in the L2 chain - /// @param router_ Address of the router in the L2 chain - /// @param counterpartGateway_ Address of the counterpart L1 gateway - /// @param l1Token_ Address of the bridged token in the L1 chain - /// @param l2Token_ Address of the token minted on the Arbitrum chain when token bridged - constructor( - address arbSys_, - address router_, - address counterpartGateway_, - address l1Token_, - address l2Token_ - ) - InterchainERC20TokenGateway( - router_, - counterpartGateway_, - l1Token_, - l2Token_ - ) - L2CrossDomainEnabled(arbSys_) - {} - - /// @inheritdoc IL2TokenGateway - function outboundTransfer( - address l1Token_, - address to_, - uint256 amount_, - uint256, // maxGas - uint256, // gasPriceBid - bytes calldata data_ - ) - external - whenWithdrawalsEnabled - onlySupportedL1Token(l1Token_) - returns (bytes memory res) - { - address from = L2OutboundDataParser.decode(router, data_); - - IERC20Bridged(l2Token).bridgeBurn(from, amount_); - - uint256 id = sendCrossDomainMessage( - from, - counterpartGateway, - getOutboundCalldata(l1Token_, from, to_, amount_, "") - ); - - // The current implementation doesn't support fast withdrawals, so we - // always use 0 for the exitNum argument in the event - emit WithdrawalInitiated(l1Token_, from, to_, id, 0, amount_); - - return abi.encode(id); - } - - /// @inheritdoc IInterchainTokenGateway - function finalizeInboundTransfer( - address l1Token_, - address from_, - address to_, - uint256 amount_, - bytes calldata - ) - external - whenDepositsEnabled - onlySupportedL1Token(l1Token_) - onlyFromCrossDomainAccount(counterpartGateway) - { - IERC20Bridged(l2Token).bridgeMint(to_, amount_); - - emit DepositFinalized(l1Token_, from_, to_, amount_); - } -} diff --git a/contracts/arbitrum/README.md b/contracts/arbitrum/README.md deleted file mode 100644 index cf76c5c1..00000000 --- a/contracts/arbitrum/README.md +++ /dev/null @@ -1,910 +0,0 @@ -# Lido's Arbitrum Gateway - -The document details implementation of the bridging of the ERC20 compatible tokens[^*] between Ethereum and Arbitrum chains via Arbitrum's “Canonical Bridge”. - -It's the first step of the Lido's integration into the Arbitrum protocol. The main goal of the current implementation is to be the strong foundation for the long-term goals of the Lido expansion in the Arbitrum chain. The long-run picture of the Lido's integration into L2s includes: - -- Bridging of Lido's tokens from L1 to L2 chains -- Instant ETH staking on L2 chains with receiving stETH/wstETH on the corresponding L2 immediately -- Keeping UX on L2 as close as possible to the UX on Ethereum mainnet - -At this point, the implementation must provide a scalable and reliable solution for Lido to bridge ERC20 compatible tokens between Arbitrum and Ethereum chain. - -[^*]: The current implementation might not support the non-standard functionality of the ERC20 tokens. For example, rebasable tokens or tokens with transfers fee will work incorrectly. In case your token implements some non-typical ERC20 logic, make sure it is compatible with the gateway before usage. - -## Arbitrum's Bridging Flow - -Arbitrum’s “Canonical Bridge” tokens-bridging architecture consists of three types of contracts: - -1. **Asset contracts**: these are the token contracts themselves, i.e., an ERC20 on L1 and it's counterpart on Arbitrum. -2. **Gateways**: Pairs of contracts (one on L1, one on L2) that implement a particular type of cross chain asset bridging. -3. **Routers**: Exactly two contracts - (one on L1, one on L2) that route each asset to its designated Gateway. - -All Ethereum to Arbitrum token transfers are initiated via the `L1GatewayRouter` contract. `L1GatewayRouter` is responsible for mapping L1 token addresses to `L1Gateway`, thus acting as an L1/L2 address oracle and ensuring that each token corresponds to only one gateway. The `L1Gateway` communicates to an `L2Gateway` (typically/expectedly via retryable tickets). - -Similarly, Arbitrum to Ethereum transfers are initiated via the `L2GatewayRouter` contract, which forwards calls the token's `L2Gateway`, which in turn communicates to its corresponding `L1Gateway` (typically/expectedly via sending messages to the Outbox.) - -To be compatible with Arbitrum's `GatewayRouter`, both L1 and L2 gateways must conform to the `ITokenGateway` interface. - -```solidity -interface ITokenGateway { - function calculateL2TokenAddress(address l1ERC20) - external - view - returns (address); - - function outboundTransfer( - address _token, - address _to, - uint256 _amount, - uint256 _maxGas, - uint256 _gasPriceBid, - bytes calldata _data - ) external returns (bytes memory); - - function getOutboundCalldata( - address _token, - address _from, - address _to, - uint256 _amount, - bytes memory _data - ) external view returns (bytes memory); - - function finalizeInboundTransfer( - address _token, - address _from, - address _to, - uint256 _amount, - bytes calldata _data - ) external virtual override; -} - -``` - -The general process of tokens bridging via Arbitrum's `GatewayRouter` consists of next steps: - -### Deposits - -1. A user calls `L1GatewayRouter.outboundTransfer()` (with `L1Token`'s L1 address as an argument). -2. `L1GatewayRouter` looks up `L1Token`'s gateway. -3. `L1GatewayRouter` calls `L1TokensGateway.outboundTransfer()`, forwarding the appropriate parameters. -4. `L1TokensGateway` escrows tokens and triggers `L2TokensGateway.finalizeInboundTransfer()` method on L2 (typically via a creation of a retryable ticket). -5. `finalizeInboundTransfer` mints the appropriate amount of tokens at the `L2Token` contract on L2. - -![](https://i.imgur.com/A8B1xgI.png) - -### Withdrawals - -1. On Arbitrum, a user calls `L2GatewayRouter.outboundTransfer()`, which in turn calls `outboundTransfer` on `L2Token`'s gateway (i.e., `L2TokensGateway`). -2. This burns `L2Token` tokens and calls [`ArbSys`](https://developer.offchainlabs.com/docs/arbsys) with an encoded message to `L1TokensGateway.finalizeInboundTransfer()`, which will be eventually executed on L1. -3. After the dispute window expires and the assertion with the user's transaction is confirmed, a user can call `Outbox.executeTransaction()`, which in turn calls the encoded `L1ERC20Gateway.finalizeInboundTransfer()` message, releasing the user's tokens from the `L1TokensGateway` contract's escrow. - -![](https://i.imgur.com/KOPguoa.png) - -The `L1GatewayRouter` allows registering custom gateways for certain tokens via `setGateways()` method, which might be called by the OffchainLabs team manually. - -The rest of the document provides a technical specification of the gateways Lido will use to transfer tokens between Arbitrum and Ethereum chains. - -## Lido's Gateways Implementation - -The current implementation of the gateways provides functionality to bridge the specified type of ERC20 compatible token between Ethereum and Arbitrum chains. Additionally, the bridge provides some administrative features, like the **temporary disabling of the deposits and withdrawals**. It's necessary when bridging must be disabled fast because of the malicious usage of the bridge or vulnerability in the contracts. Also, it might be helpful in the implementation upgrade process. - -The technical implementation focuses on the following requirements for the contracts: - -- **Scalability** - current implementation must provide the ability to be extended with new functionality in the future. -- **Simplicity** - implemented contracts must be clear, simple, and expressive for developers who will work with code in the future. -- **Gas efficiency** - implemented solution must be efficient in terms of gas costs for the end-user, but at the same time, it must not violate the previous requirement. - -A high-level overview of the proposed solution might be found in the below diagram: - -![](https://i.imgur.com/TPfEr29.png) - -- Libraries: - - [**`L1OutboundDataParser`**](#L1OutboundDataParser) - a helper library to parse data passed to `outboundTransfer()` of `L1ERC20TokenGateway`. - - [**`L2OutboundDataParser`**](#L2OutboundDataParser) - a helper library to parse data passed to `outboundTransfer()` of `L2ERC20TokenGateway`. -- Abstract Contracts: - - [_**`InterchainERC20TokenGateway`**_](#InterchainERC20TokenGateway) - an abstract contract that implements logic shared between L1 and L2 gateways. -- Contracts: - - [**`AccessControl`**](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/access/AccessControl.sol) - contract from the @openzeppelin package that allows children to implement role-based access. - - [**`BridgingManager`**](#BridgingManager) - contains administrative methods to retrieve and control the state of the bridging process. - - [**`BridgeableTokens`**](#BridgeableTokens) - contains the logic for validation of tokens used in the bridging process. - - [**`L1CrossDomainEnabled`**](#L1CrossDomainEnabled) - helper contract for contracts performing Ethereum to Arbitrum communication process via Retryable Tickets. - - [**`L1ERC20TokenGateway`**](#L1ERC20TokenGateway) - Ethereum's counterpart of the gateway to bridge registered ERC20 compatible tokens between Ethereum and Arbitrum chains. - - [**`L2CrossDomainEnabled`**](#L2Messenger) - helper contract to simplify Arbitrum to Ethereum communication process - - [**`L2ERC20TokenGateway`**](#L2ERC20TokenGateway) - Arbitrum's counterpart of the gateway to bridge registered ERC20 compatible tokens between Ethereum and Arbitrum chains - - [**`ERC20Bridged`**](#ERC20Bridged) - an implementation of the `ERC20` token with administrative methods to mint and burn tokens. - - [**`OssifiableProxy`**](#OssifiableProxy) - the ERC1967 proxy with extra admin functionality. - -## L1OutboundDataParser - -A helper library to parse data passed to `outboundTransfer()` of `L1ERC20TokenGateway`. - -### Functions - -#### `decode(address,bytes memory)` - -> **Visibility:**     `internal` -> -> **Mutability:**   `view` -> -> **Returns:**       `(address, uint256)` -> -> **Arguments:** -> -> - **`router_`** - an address of the Arbitrum's `L1GatewayRouter` -> - **`data_`** - bytes array encoded via the following rules: -> - If the `msg.sender` of the method is the `router_` address, `data_` must contain the result of the function call: `abi.encode(address from, abi.encode(uint256 maxSubmissionCost, bytes emptyData))`, where `emptyData` - is an empty bytes array. -> - In other cases, data must contain the result of the function call: `abi.encode(uint256 maxSubmissionCost, bytes emptyData)` where `emptyData` - is an empty bytes array. - -Decodes value contained in `data_` bytes array and returns decoded value: `(address from, uint256 maxSubmissionCost)`. Such encoding rules are required to be compatible with the `L1GatewaysRouter`. - -## L2OutboundDataParser - -A helper library to parse data passed to `outboundTransfer()` of `L2ERC20TokenGateway`. - -### Functions - -#### decode(address,bytes memory) - -> **Visibility:**     `internal` -> -> **Mutability:**   `view` -> -> **Returns**        `(address)` -> -> **Arguments:** -> -> - **`router_`** - an address of the Arbitrum's `L1GatewayRouter` -> - **`data_`** - bytes array encoded via the following rules: -> - If the `msg.sender` of the method is the `router_` address, `data_` must contain the result of the function call: `abi.encode(address from, bytes emptyData)`, where `emptyData` - is an empty bytes array. -> - In other cases, `data` must be empty bytes array. - -Decodes value contained in `data_` bytes array and returns decoded value: `(address from)`. Such encoding rules are required to be compatible with the `L2GatewaysRouter`. - -## BridgingManager - -- **inherits:** [`@openzeppelin/AccessControl`](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/d4fb3a89f9d0a39c7ee6f2601d33ffbf30085322/contracts/access/AccessControl.sol) - -Contains administrative methods to retrieve and control the state of the bridging process. Allows to enable/disable withdrawals or deposits and check whether the gateway functionality is suspended or not. Allows granting standalone privileges to certain accounts to enable/disable deposits or withdrawals of the gateway. The rights to grant permissions have accounts with an admin role. - -### Constants - -- **DEPOSITS_ENABLER_ROLE** - a `bytes32` equal to a result of the `keccak256()` hashing of the string `"BridgingManager.DEPOSITS_ENABLER_ROLE"`. This role must be used when grants/revokes privileges to enable deposits. -- **DEPOSITS_DISABLER_ROLE** - a `bytes32` equal to a result of the `keccak256()` hashing of the string `"BridgingManager.DEPOSITS_DISABLER_ROLE"`. This role must be used when grants/revokes privileges to disable deposits. -- **WITHDRAWALS_ENABLER_ROLE** - a `bytes32` equal to a result of the `keccak256()` hashing of the string `"BridgingManager.WITHDRAWALS_ENABLER_ROLE"`. This role must be used when grants/revokes privileges to enable withdrawals. -- **WITHDRAWALS_DISABLER_ROLE** - a `bytes32` equal to a result of the `keccak256()` hashing of the string `"BridgingManager.WITHDRAWALS_DISABLER_ROLE"`. This role must be used when grants/revokes privileges to disable withdrawals. - -### Variables - -The contract uses the Unstructured Storage pattern to store the current state of the bridge using the struct `BridgingState`. `BridgingState` struct has the next type: - -```solidity= -struct BridgingState { - bool isInitialized; // Shows whether the contract is initialized or not. - bool isDepositsEnabled; // Stores the state of the deposits - bool isWithdrawalsEnabled; // Stores the state of the withdrawals -} -``` - -### Functions - -#### `initialize(address)` - -> **Visibility:**     `public` -> -> **Arguments:** -> -> - **`admin_`** - an address of the account to grant the `DEFAULT_ADMIN_ROLE` -> -> **Emits:** `RoleGranted(bytes32 indexed role, address indexed account, address indexed sender)` - -Initializes the contract to grant `DEFAULT_ADMIN_ROLE` to the `admin_` address. The method might be called only once. Reverts with error `ErrorAlreadyInitialized()` when called on the already initialized contract. Allows using this contract with the proxy pattern. - -#### `isDepositsEnabled()` - -> **Visibility:**     `public` -> -> **Mutability:**   `view` -> -> **Returns**        `(bool)` - -Returns whether the deposits enabled or not. - -#### `isWithdrawalsEnabled()` - -> **Visibility:**     `public` -> -> **Mutability:**   `view` -> -> **Returns**        `(bool)` - -Returns whether the withdrawals enabled or not. - -#### `enableDeposits()` - -> **Visibility:**     `external` -> -> **Modifiers:**    [`onlyRole(DEPOSITS_ENABLER_ROLE)`](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/d4fb3a89f9d0a39c7ee6f2601d33ffbf30085322/contracts/access/AccessControl.sol#L69) -> -> **Emits:**           `DepositsEnabled(address account)` - -Enables the deposits if they are disabled. Reverts with the error `ErrorDepositsEnabled()` if deposits aren't enabled. Only accounts with the granted `DEPOSITS_ENABLER_ROLE` can call this method. - -#### `disableDeposits()` - -> **Visibility:**     `external` -> -> **Modifiers:**    [`whenDepositsEnabled`](#whenDepositsEnabled) [`onlyRole(DEPOSITS_DISABLER_ROLE)`](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/d4fb3a89f9d0a39c7ee6f2601d33ffbf30085322/contracts/access/AccessControl.sol#L69) -> -> **Emits:**           `DepositsDisabled(address account)` - -Disables the deposits if they aren't disabled yet. Reverts with the error `ErrorDepositsDisabled()` if deposits have already disabled. Only accounts with the granted `DEPOSITS_DISABLER_ROLE` can call this method. - -#### `enableWithdrawals()` - -> **Visibility:**     `external` -> -> **Modifiers:**    [`onlyRole(WITHDRAWALS_ENABLER_ROLE)`](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/d4fb3a89f9d0a39c7ee6f2601d33ffbf30085322/contracts/access/AccessControl.sol#L69) -> -> **Emits:**           `WithdrawalsEnabled(address account)` - -Enables the withdrawals if they are disabled. Reverts with the error `ErrorWithdrawalsEnabled()` if withdrawals are enabled. Only accounts with the granted `WITHDRAWALS_ENABLER_ROLE` can call this method. - -#### `disableWithdrawals()` - -> **Visibility:**     `external` -> -> **Modifiers:**    [`whenWithdrawalsEnabled`](#whenWithdrawalsEnabled)[`onlyRole(WITHDRAWALS_DISABLER_ROLE)`](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/d4fb3a89f9d0a39c7ee6f2601d33ffbf30085322/contracts/access/AccessControl.sol#L69) -> -> **Emits:**           `WithdrawalsDisabled(address account)` - -Disables the withdrawals if they aren't disabled yet. Reverts with the error `ErrorWithdrawalsDisabled()` if withdrawals have already disabled. Only accounts with the granted `WITHDRAWALS_DISABLER_ROLE` can call this method. - -#### `_loadState()` - -> **Visibility:**     `private` -> -> **Mutability:**   `pure` -> -> **Returns**        `(BridgingState storage)` - -Loads and returns the `BridgingState` variable from the slot at address `keccak256("BridgingManager.bridgingState")`. - -### Modifiers - -#### `whenDepositsEnabled()` - -Validates that deposits are enabled. Reverts with the error `ErrorDepositsDisabled()` when called on contract with disabled deposits. - -#### `whenWithdrawalsEnabled()` - -Validates that withdrawals are enabled. Reverts with the error `ErrorWithdrawalsDisabled()` when called on contract with disabled withdrawals. - -## BridgeableTokens - -Contains the logic for validation of tokens used in the bridging process - -### Variables - -The contract keeps the addresses of L1/L2 tokens used in the bridging: - -- **`l1Token`** - an immutable address of the bridged token in the L1 chain -- **`l2Token`** - an immutable address of the token minted on the L2 chain when token bridged - -### Modifiers - -#### `onlySupportedL1Token(address l1Token_)` - -Validates that passed `l1Token_` is supported by the bridge. Reverts with error `ErrorUnsupportedL1Token()` when addresses mismatch. - -#### `onlySupportedL2Token(address l2Token_)` - -Validates that passed `l2Token_` is supported by the bridge. Reverts with error `ErrorUnsupportedL2Token()` when addresses mismatch. - -## InterchainERC20TokenGateway - -**Implements:** `IInterchainERC20TokenGateway` -**Inherits:** [`BridgingManager`](#BridgingManager) [`BridgeableTokens`](#BridgeableTokens) - -The contract keeps logic shared among both L1 and L2 gateways, adding the methods for bridging management: enabling and disabling withdrawals/deposits. - -### Variables - -The contract keeps the variables required by both L1/L2 gateways: - -- **`router`** - an address of the router in the corresponding chain -- **`counterpartGateway`** - an address of the counterpart gateway used in the bridging process - -All variables are declared as `immutable` to reduce transactions gas costs. - -### Functions - -#### `calculateL2TokenAddress(address)` - -> **Visibility:**     `external` -> -> **Mutability:**   `view` -> -> **Returns**        `(address)` -> -> **Arguments:** -> -> - **l1Token\_** - an address of the token on the Ethereum chain - -Returns an address of token, which will be minted on the Arbitrum chain, on `l1Token_` bridging. The current implementation returns the `l2Token` address when passed `l1Token_` equals to `l1Token` declared in the contract and `address(0)` in other cases. - -#### `getOutboundCalldata(address,address,address,uint256,bytes memory)` - -> **Visibility:**     `public` -> -> **Mutability:**   `view` -> -> **Returns**        `(bytes memory)` -> -> **Arguments:** -> -> - **`l1Token_`** - an address in the Ethereum chain of the token to bridge -> - **`from_`** - an address in the Ethereum chain of the account initiated bridging -> - **`to_`** - an address in the Ethereum chain of the recipient of the token on the corresponding chain -> - **`amount_`** - an amount of tokens to bridge -> - **`data_`** - Custom data to pass into finalizeInboundTransfer method. Unused, required to be compatible with @arbitrum/sdk package. - -Returns encoded transaction data to send into the corresponding gateway to finalize the tokens bridging process. The result of this method might be used to estimate the amount of ether required to pass to the `outboundTransfer()` method call. In the current implementation returns the transaction data of `finalizeInboundTransfer(token_, from_, to_, amount_)`. - -## L1CrossDomainEnabled - -A helper contract for contracts performing Ethereum to Arbitrum communication process via Retryable Tickets. - -### Variables - -The contract declares one immutable variable **`inbox_`** - an address of the Arbitrum's [`Inbox`](https://developer.offchainlabs.com/docs/sol_contract_docs/md_docs/arb-bridge-eth/bridge/inbox) contract - -### Functions - -#### `sendCrossDomainMessage(address, address, bytes memory, CrossDomainMessageOptions memory)` - -> **Visibility:**     `internal` -> -> **Returns**        `(uint256)` -> -> **Arguments**: -> -> - **`sender_`** - an address of the sender of the message. It's also the address to credit all excess ETH from gas and call-value on the Arbitrum chain. Call-value is refunded if the retryable ticket times out or is canceled. `sender_` is also the address with the right to cancel a Retryable Ticket. -> - **`recipient_`** - an address of the recipient of the message on the Arbitrum chain -> - **`data_`** - data passed to the `recipient_` in the message -> - **`msgOptions_`** - an instance of the `CrossDomainMessageOptions` struct. The `CrossDomainMessageOptions` struct has the following properties: -> - **`maxGas`** - gas limit for immediate L2 execution attempt (can be estimated via `NodeInterface.estimateRetryableTicket()`) -> - **`callValue`** - call-value for L2 transaction -> - **`gasPriceBid`** - L2 Gas price bid for immediate L2 execution attempt (queryable via standard `eth_gasPrice` RPC) -> - **`maxSubmissionCost`** - an amount of ETH allocated to pay for the base submission fee -> -> **Emits:** `TxToL2(address indexed from, address indexed to, uint256 indexed seqNum, bytes data)` - -Creates a Retryable Ticket via [`Inbox.createRetryableTicket`](https://github.com/OffchainLabs/arbitrum/blob/52356eeebc573de8c4dd571c8f1c2a6f5585f359/packages/arb-bridge-eth/contracts/bridge/Inbox.sol#L325) function using the provided arguments. Sends all passed ether with Retryable Ticket into Arbitrum chain. Reverts with error `ErrorETHValueTooLow()` if passed `msg.value` is less than `msgOptions_.callVaue + msgOptions_.maxSubmissionCost + (msgOptions_.maxGas * msgOptions_.gasPriceBid)` and with error `ErrorNoMaxSubmissionCost()` when `msgOptions_.maxSubmissionCost` is equal to 0. Returns a unique id of created Retryable Ticket. - -### Modifiers - -#### `onlyFromCrossDomainAccount(address crossDomainAccount_)` - -Validates that transaction was initiated by the `crossDomainAccount_` address from the L2 chain. Reverts with error `ErrorUnauthorizedBridge()` if called not by Arbitrum's bridge and with error `ErrorWrongCrossDomainSender()` if the transaction was sent not from the `crossDomainAccount_` address. - -## L1ERC20TokenGateway - -- **Inherits**: [`InterchainERC20TokenGateway`](#InterchainERC20TokenGateway) [`L1CrossDomainEnabled`](#L1CrossDomainEnabled) -- **Implements**: `IL1TokenGateway` - -Contract implements `ITokenGateway` interface and with counterpart `L2TokensGatewy` allows bridging registered ERC20 compatible tokens between Ethereum and Arbitrum chains. The contract is compatible with `L1GatewayRouter` and might be used to transfer tokens via the "canonical" Arbitrum's bridge. - -Additionally, the contract provides administrative methods to temporarily disable bridging from Ethereum to Arbitrum via the `BridgingManager` contract. - -### Functions - -#### `outboundTransfer(address,address,uint256,uint256, uint256,bytes calldata)` - -> **Visibility:**     `external` -> -> **Mutability:**   `payble` -> -> **Modifiers:**    [`whenDepositsEnabled()`](#whenDepositsEnabled) [`onlySupportedL1Token(l1Token_)`](#onlySupportedL1Tokenaddress-l1Token_) -> -> **Returns**        `(bytes memory)` -> -> **Arguments:** -> -> - **l1Token\_** - an address in the Ethereum chain of the token to bridge. It must be equal to the `l1Token` address. The method will be reverted with the error `ErrorUnsupportedL1Token()` if would be called with a different address. -> - **to\_** - an address of the recipient of the token on the corresponding chain -> - **amount\_** - an amount of tokens to bridge. The user has to approve spending of the `l1Token` for the gateway or the transaction will be reverted. -> - **maxGas\_** - a gas limit for immediate L2 execution attempt (can be estimated via `_NodeInterface.estimateRetryableTicket`). -> - **gasPriceBid\_** - an L2 gas price bid for immediate L2 execution attempt (queryable via standard eth\*gasPrice RPC). -> - **data** - stores an additional data required for the transaction. Data will be decoded via the `L1OutboundDataParser.decode()` method to retrieve the `maxSubmissionCost` value and `from` address, where `from` - contains an address of the sender, and `maxSubmissionCost` - is an amount of ETH allocated to pay for the base submission fee. -> -> **Emits:** `DepositInitiated(address l1Token, address indexed from, address indexed to, uint256 indexed sequenceNumber, uint256 amount)` - -Initiates the tokens bridging from the Ethereum into the Arbitrum chain. Escrows the `amount_` of `l1Token_` from the user on the address of the gateway and creates a Retryable Ticket via the `sendCrossDomainMessage()` method: - -```solidity= -sendCrossDomainMessage( - counterpartGateway, // recipient - getOutboundCalldata(l1Token, from, to, amount, ""), // data - CrossDomainMessageOptions({ - maxGas: maxGas, - callValue: 0, - gasPriceBid: gasPriceBid_, - refundAddress: from, - maxSubmissionCost: maxSubmissionCost - }) -) -``` - -Returns an encoded value of the id for created Retryable Ticket. Same value is used as `sequenceNumber` in `DepositInitiated` event. - -#### `finalizeInboundTransfer(address,address,address,uint256,bytes calldata)` - -> **Visibility:**     `internal` -> -> **Modifiers:**    [`whenWithdrawalsEnabled()`](#whenWithdrawalsEnabled) [`onlySupportedL1Token(l1Token_)`](#onlySupportedL1Tokenaddress-l1Token_) [`onlyFromCrossDomainAccount(counterpartGateway)`](#onlyFromCrossDomainAccountaddress-crossDomainAccount_) -> -> **Arguments:** -> -> - **`l1Token_`** - an address in the Ethereum chain of the token to withdraw -> - **`from_`** - an address of the account initiated bridging -> - **`to_`** - an address of the recipient of the tokens -> - **`amount_`** - an amount of tokens to withdraw -> - **`data_`** - unused variable, required to be compatible with `L1GatewayRouter` and `L2GatewayRouter` -> -> **Emits:** `WithdrawalFinalized(address l1Token, address indexed from, address indexed to, uint256 indexed exitNum, uint256 amount)` - -This method is called to finalize the withdrawal of the tokens from the L2 chain. It transfers the `amount_` of tokens from the gateway to the `to_` address via `safeTransfer()` method. - -**Note**: `exitNum` - always is equal to 0 in the `WithdrawalFinalized` event cause the current implementation doesn't support fast withdraws. To read more about fast withdrawals, see [Offchain Labs Docs](https://developer.offchainlabs.com/docs/withdrawals). - -## L2CrossDomainEnabled - -A helper contract to simplify Arbitrum to Ethereum communication process. - -### Variables - -The contract declares one immutable variable **`arbSys`** - an address of the Arbitrum's [`ArbSys`](https://developer.offchainlabs.com/docs/arbsys) contract - -### Functions - -#### `sendCrossDomainMessage(address,address,bytes memory)` - -> **Visibility:**     `internal` -> -> **Returns**        `(uint256)` -> -> **Arguments**: -> -> - **`sender_`** - an address of the sender of the message -> - **`recipient_`** - an address of the recipient of the message on the Ethereum chain -> - **`data_`** - Data passed to the `recipient_` in the message -> -> **Emits**: `event TxToL1(address indexed from, address indexed to, uint256 indexed id, bytes data)` - -Sends the message to the Ethereum chain via `ArbSys.sendTxToL1()` method. - -#### `applyL1ToL2Alias(address)` - -> **Visibility:**     `private` -> -> **Returns**        `(address)` -> -> **Arguments**: -> -> - **`l1Address_`** - an L1 address to apply aliasing - -Applies the [Arbitrum's L1 -> L2 aliasing](https://developer.offchainlabs.com/docs/l1_l2_messages#address-aliasing) to the address. - -### Modifiers - -#### `onlyFromCrossDomainAccount(address crossDomainAccount_)` - -Validates that the `msg.sender` is equal to the `crossDomainAccount_` with applied [Arbitrum's aliasing](https://developer.offchainlabs.com/docs/l1_l2_messages#address-aliasing). Reverts with the error `ErrorWrongCrossDomainSender()` if validation fails. - -## L2ERC20TokenGateway - -- **Inherits**: [`InterchainERC20TokenGateway`](#InterchainERC20TokenGateway) [`L2CrossDomainEnabled`](#L2CrossDomainEnabled) -- **Implements**: `IL2TokenGateway` - -Contract implements `ITokenGateway` interface and with counterpart `L1ERC20TokenGateway` allows bridging registered ERC20 compatible tokens between Arbitrum and Ethereum chains. The contract is compatible with `L2GatewayRouter` and might be used to transfer tokens via the “canonical” Arbitrum’s bridge. - -Additionally, the contract provides administrative methods to temporarily disable bridging from Arbitrum to Ethereum via the `BridgingManager` contract. - -### Functions - -#### `outboundTransfer(address,address,uint256,uint256, uint256,bytes memory)` - -> **Visibility:**     `external` -> -> **Modifiers:**    [`whenWithdrawalsEnabled()`](#whenWithdrawalsEnabled) [`onlySupportedL1Token(l1Token_)`](#onlySupportedL1Tokenaddress-l1Token_) -> -> **Returns**        `(bytes memory)` -> -> **Arguments:** -> -> - **l1Token\_** - an address in the Ethereum chain of the token to bridge. It must be equal to the `l1Token` address. The method will be reverted with the error `ErrorUnsupportedL1Token()` if would be called with a different address. -> - **to\_** - an address of the recipient of the token on the corresponding chain -> - **amount\_** - an amount of tokens to bridge. The user has to approve spending of the `l1Token` for the gateway or the transaction will be reverted. -> - **maxGas\_** - Doesn't used -> - **gasPriceBid\_** - Doesn't used -> - **data** - stores an additional data required for transaction. Data will be decoded via `L2OutboundDataParser.decode()` method to retrieve `from` address - an address of the sender. -> -> **Emits:** `WithdrawalInitiated(address l1Token, address indexed from, address indexed to, uint256 indexed l2ToL1Id, uint256 exitNum, uint256 amount)` - -Initiates the withdrawing process from the Arbitrum chain into the Ethereum chain. The method burns the `amount_` of `l2Token` on the `from_` account, sends message to the Ethereum chain via `sendCrossDomainMessage()` method: - -```solidity= -sendCrossDomainMessage( - counterpartGateway, - getOutboundCalldata(l1Token_, from_, to_, amount_, "") -); -``` - -Returns encoded value of the unique id for L2-to-L1 transaction. Same value is used as `l2ToL1Id` in the `WithdrawalInitiated` event. - -**Note**: `exitNum` - always is equal to 0 in the `WithdrawalInitiated` event cause the current implementation doesn't support fast withdraws. To read more about fast withdrawals, see [Offchain Labs Docs](https://developer.offchainlabs.com/docs/withdrawals). - -#### `finalizeInboundTransfer(address,address,address,uint256,bytes calldata)` - -> **Visibility:**     `internal` -> -> **Modifiers:**    [`whenDepositsEnabled()`](#whenDepositsEnabled) [`onlySupportedL1Token(l1Token_)`](#onlySupportedL1Tokenaddress-l1Token_) [`onlyFromCrossDomainAccount(counterpartGateway)`](#onlyFromCrossDomainAccountaddress-crossDomainAccount_1) -> -> **Arguments:** -> -> - **`l1Token_`** - an address in the Ethereum chain of the token to bridge -> - **`from_`** - an address of the account initiated bridging -> - **`to_`** - an address of the recipient of the tokens -> - **`amount_`** - an amount of tokens to bridge -> - **`data_`** - unused variable, required to be compatible with `L1GatewayRouter` and `L2GatewayRouter` -> -> **Emits:** `DepositFinalized(address indexed l1Token, address indexed from, address indexed to, uint256 amount)` - -This method is called on the finalizing of the bridging from the Ethereum chain. This method mints the `amount_` of `l2Token` token to the `to_` address. - -## `ERC20Metadata` - -Contains optional methods for the `ERC20` tokens. It uses the UnstructuredStorage pattern to store strings with name and symbol info. Might be used with the upgradable proxies. - -### Variables - -Contract declares `public` and `immutable` variable **`decimals`** of type `uint8`. - -The `name` and `symbol` info are stored in the structure: - -```solidity= -struct DynamicMetadata { - string name; - string symbol; -} -``` - -### Funcations - -#### `name()` - -> **Visibility:**     `external` -> -> **Mutability:**   `view` -> -> **Returns**        `(string memory)` - -Returns the name of the token. - -#### `symbol()` - -> **Visibility:**     `external` -> -> **Mutability:**   `view` -> -> **Returns**        `(string memory)` - -Returns the symbol of the token. - -#### `_setERC20MetadataName(string memory)` - -> **Visibility:**     `internal` -> -> **Arguments:** -> -> - **`name_`** - string with name of the token - -Sets the `name` of the token. Might be called only when the `name` is empty. - -#### `_setERC20MetadataSymbol(string memory)` - -> **Visibility:**     `internal` -> -> **Arguments:** -> -> - **`symbol_`** - string with symbol of the token - -Sets the `symbol` of the token. Might be called only when the `symbol` is empty. - -#### `_loadDynamicMetadata()` - -> **Visibility:**     `private` -> -> **Mutability:**   `pure` -> -> **Returns**        `(DynamicMetadata storage r)` - -Returns the reference to the slot with `DynamicMetadta` struct - -## `ERC20Core` - -- **Implements:** [`@openzeppelin/IERC20`](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/d4fb3a89f9d0a39c7ee6f2601d33ffbf30085322/contracts/token/ERC20/IERC20.sol) - -Contains the required variables and logic of the `ERC20` token. The contract is a slightly modified version of the [`ERC20`](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/d4fb3a89f9d0a39c7ee6f2601d33ffbf30085322/contracts/token/ERC20/ERC20.sol) contract from the OpenZeppelin package. - -### Variables - -Contract declares the following variables to store state of the token: - -- **`uint256 public totalSupply`** - the total supply of the token -- **`mapping(address => uint256) public balanceOf`** - stores balances of the token holders -- **`mapping(address => mapping(address => uint256)) public allowance`** - stores allowances of the token holders - -### Functions - -#### `approve(address,uint256)` - -> **Visibility:**     `external` -> -> **Returns**        `(bool)` -> -> **Arguments:** -> -> - **`spender_`** - an address of the tokens spender -> - **`amount_`** - a number of tokens to allow to spend -> -> **Emits:** `Approval(address indexed owner, address indexed spender, uint256 value)` - -Allows _spender to withdraw from the `msg.sender` account multiple times, up to the `amount_`. If this function is called again it overwrites the current allowance with `amount\_`. Returns a `bool` value indicating whether the operation succeeded. - -#### `transfer(address,uint256)` - -> **Visibility:**     `external` -> -> **Returns**        `(bool)` -> -> **Arguments:** -> -> - **`to_`** - an address of the recipient of the tokens -> - **`amount_`** - a number of tokens to transfer -> -> **Emits:** `Transfer(address indexed from, address indexed to, uint256 value)` - -Transfers `amount` of tokens from sender to `to` account. -Returns a `bool` value indicating whether the operation succeeded. - -#### `transferFrom(address,address,uint256)` - -> **Visibility:**     `external` -> -> **Returns**        `(bool)` -> -> **Arguments:** -> -> - **`from_`** - an address to transfer tokens from -> - **`to_`** - an address of the recipient of the tokens -> - **`amount_`** - a number of tokens to transfer -> -> **Emits:** `Transfer(address indexed from, address indexed to, uint256 value)` `Approval(address indexed owner, address indexed spender, uint256 value)` - -Transfers `amount` of token from the `from_` account to `to_` using the allowance mechanism. `amount_` is then deducted from the caller's allowance. Returns a `bool` value indicating whether the operation succeed. - -#### `increaseAllowance(address,uint256)` - -> **Visibility:**     `external` -> -> **Returns**        `(bool)` -> -> **Arguments:** -> -> - **`spender_`** - an address of the tokens spender -> - **`addedValue_`** - a number to increase allowance -> -> **Emits:** `Approval(address indexed owner, address indexed spender, uint256 value)` - -Atomically increases the allowance granted to `spender` by the caller. Returns a `bool` value indicating whether the operation succeed. - -#### `decreaseAllowance(address,uint256)` - -> **Visibility:**     `external` -> -> **Returns**        `(bool)` -> -> **Arguments:** -> -> - **`spender_`** - an address of the tokens spender -> - **`subtractedValue_`** - a number to decrease allowance -> -> **Emits:** `Approval(address indexed owner, address indexed spender, uint256 value)` - -Atomically decreases the allowance granted to `spender` by the caller. Returns a `bool` value indicating whether the operation succeed. - -## `ERC20Bridged` - -**Implements:** [`IERC20Bridged`](https://github.com/lidofinance/lido-l2/blob/main/contracts/token/interfaces/IERC20Bridged.sol) -**Inherits:** [`ERC20Metadata`](#ERC20Metadata) [`ERC20Core`](#ERC20CoreLogic) - -Inherits the `ERC20` default functionality that allows the bridge to mint and burn tokens. - -### Variables - -Contract declares an immutable variable **`bridge`** which can mint/burn the token. - -### Functions - -#### `mint(address,uint256)` - -> **Visibility:**     `external` -> -> **Modifiers:**    [`onlyBridge`](#onlybridge) -> -> **Arguments:** -> -> - **`account_`** - an address of the tokens recipient -> - **`amount_`** - a number to mint -> -> **Emits:** `Transfer(address indexed from, address indexed to, uint256 value)` - -Mints the `amount_` of tokens to the `account_`. The method might be called only by the bridge. Reverts with the error `ErrorNotBridge()` when called not by bridge. - -#### `burn(address,uint256)` - -> **Visibility:**     `external` -> -> **Modifiers:**    [`onlyBridge`](#onlybridge) -> -> **Arguments:** -> -> - **`account_`** - an address of the tokens recipient -> - **`amount_`** - a number to burn -> -> **Emits:** `Transfer(address indexed from, address indexed to, uint256 value)` - -Destroys the `amount_` of tokens from the `account_`. The method might be called only by the bridge. Reverts with the error `ErrorNotBridge()` when called not by bridge. - -### Modifiers - -#### `onlyBridge()` - -Validates that the `msg.sender` of the method is the `bridge`. Reverts with error `ErrorNotBridge()` in other cases. - -## `OssifiableProxy` - -- **Inherits:** [`@openzeppelin/ERC1967Proxy`](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/d4fb3a89f9d0a39c7ee6f2601d33ffbf30085322/contracts/proxy/ERC1967/ERC1967Proxy.sol) - -Extends the [`ERC1967Proxy`](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/d4fb3a89f9d0a39c7ee6f2601d33ffbf30085322/contracts/proxy/ERC1967/ERC1967Proxy.sol) contract from the OpenZeppelin package and adds some admin methods. In contrast to [`UUPSUpgradableProxy`](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/d4fb3a89f9d0a39c7ee6f2601d33ffbf30085322/contracts/proxy/utils/UUPSUpgradeable.sol), it doesn't increase the inheritance chain of the implementation contracts. And allows saving one extra `SLOAD` operation on every user request in contrast to [`TransparentUpgradeableProxy`](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/d4fb3a89f9d0a39c7ee6f2601d33ffbf30085322/contracts/proxy/transparent/TransparentUpgradeableProxy.sol). But adding any external methods to the `ERC1967Proxy` creates the risk of selectors clashing, as described in the OpenZepplin [proxies docs](https://docs.openzeppelin.com/upgrades-plugins/1.x/proxies#transparent-proxies-and-function-clashes). To avoid the risk of clashing, the implementation upgrade process must contain a step with a search of the collisions between proxy and implementation. - -### Functions - -#### `proxy__getAdmin()` - -> **Visibility:**     `external` -> -> **Mutability:**   `view` -> -> **Returns**        `(address)` - -Returns the admin of the proxy. - -#### `proxy__getImplementation()` - -> **Visibility:**     `external` -> -> **Mutability:**   `view` -> -> **Returns**        `(address)` - -Returns the address of the implementation. - -#### `proxy__getIsOssified()` - -> **Visibility:**     `external` -> -> **Mutability:**   `view` -> -> **Returns**        `(bool)` - -Returns whether the proxy is ossified or not. - -#### `proxy__ossify()` - -> **Visibility:**     `external` -> -> **Modifiers:**    [`onlyAdmin`](#onlyAdmin) -> -> **Emits:**           `AdminChanged(address previousAdmin, address newAdmin)` - -Allows to transfer admin rights to zero address and prevent future upgrades of the proxy. - -#### `proxy__changeAdmin(address)` - -> **Visibility:**     `external` -> -> **Modifiers:**    [`onlyAdmin`](#onlyAdmin) -> -> **Arguments:** -> -> - **`newAdmin_`** - an address of the new admin. Must not be zero address. -> -> **Emits:** `AdminChanged(address previousAdmin, address newAdmin)` - -Changes the admin of the proxy. Reverts with message "ERC1967: new admin is the zero address" if `newAdmin_` is zero address. - -#### `proxy__upgradeTo(address)` - -> **Visibility:**     `external` -> -> **Modifiers:**    [`onlyAdmin`](#onlyAdmin) -> -> **Arguments:** -> -> - **`newImplementation_`** - an address of the new implementation. Must be a contract. -> -> **Emits:** `Upgraded(address indexed implementation)` - -Upgrades the implementation of the proxy. Reverts with the error "ERC1967: new implementation is not a contract" if the `newImplementation_` is not a contract. - -#### `proxy__upgradeToAndCall(address,bytes memory,bool)` - -> **Visibility:**     `external` -> -> **Modifiers:**    [`onlyAdmin`](#onlyAdmin) -> -> **Arguments:** -> -> - **`newImplementation_`** - an address of the new implementation. Must be a contract. -> - **`setupCalldata_`** - a data to pass into setup call after implementation upgrade. -> - **`forceCall_`** - forces make delegate call to the implementation even with empty `setupCalldata_` -> -> **Emits:** `Upgraded(address indexed implementation)` - -Upgrades the implementation of the proxy with an additional setup call. Reverts with the error "ERC1967: new implementation is not a contract" if the `newImplementation_` is not a contract. If `setupCalldata_.length` equals zero setup step will be skipped, if forceCall is false. - -### Modifiers - -#### `onlyAdmin()` - -Validates that that proxy is not ossified and that method is called by the admin of the proxy. Reverts with error `ErrorProxyIsOssified()` when called on ossified contract and with error `ErrorNotAdmin()` when called not by admin. - -## Deployment Process - -To reduce the gas costs for users, contracts `L1ERC20TokenGateway`, `L2ERC20TokenGateway`, and `L2TokensToken` use immutable variables as much as possible. But some of those variables are cross-referred. For example, `L1ERC20TokenGateway` has reference to `L2ERC20TokenGateway` and vice versa. As we use proxies, we can deploy proxies at first and stub the implementation with an empty contract. Then deploy actual implementations with addresses of deployed proxies and then upgrade proxies with new implementations. For stub might be used next contract: - -``` -pragma solidity ^0.8.0; -contract EmptyContract {} -``` - -Another option - pre-calculate the future address of the deployed contract offchain and deployed the implementation using pre-calculated addresses. But it is less fault-tolerant than the solution with an implementation stub. - -## Integration Risks - -As an additional link in the tokens flow chain, the Arbitrum and gateways possibly add points of failure. Below are the main risks of the current integration: - -### Minting of uncollateralized `L2Token` - -Such an attack might happen if an attacker obtains the right to call `L2ERC20TokenGateway.finalizeOutboundTransfer()` directly to mint uncollateralized L2Token. In such a scenario, an attacker can mint tokens on L2 and initiate withdrawal of those tokens. - -The best way to detect such an attack is an offchain monitoring of the minting and depositing/withdrawal events. Based on such events might be tracked following stats: - -- `l1GatewayBalance` - a total number of locked tokens on the L1 gateway -- `l2TokenTotalSupply` - total number of minted L2 tokens -- `l2TokenNotWithdrawn` - total number of burned L2 tokens which aren't withdrawn from the L1 gateway - -At any time following invariant must be sutisfied: `l1GatewayBalance == l2TokenTotalSupply + l2TokenNotWithdrawn`. - -In the case of invariant violation, Lido will have a dispute period to suspend L1 and L2 gateways. Paused gateways forbid minting of L2Token and withdrawing of minted tokens till the resolution of the issue. - -### Attack on fraud-proof system - -Such an attack might be seeking to take control over validators or abuse the fraud-proof system to submit incorrect state root. In such a case, the proposed incorrect block will be subject to a dispute period. Lido may run its validator with a "watchtower" strategy, which will ring the alarm when an invalid block is proposed. When it happens, the gateway must be suspended to protect users from potential funds lost till the resolution of the issue. - -### Attack on `L1GatewaysRouter` - -Theoretical situation, when an attacker takes control over `L1GatewaysRouter` and replaces an address of the gateway responsible for token bridging on some malicious contract. It potentially allows to steal the tokens transferred after the gateway substitution. To react to such an attack fastly, Lido has to monitor the `GatewaySet` event with the address of the Lido token. In case such an event was emitted, the Offchain Labs Team must be reached out to investigate the details and fix an issue asap to minimize the damage. diff --git a/contracts/arbitrum/interfaces/IArbSys.sol b/contracts/arbitrum/interfaces/IArbSys.sol deleted file mode 100644 index f7221e8a..00000000 --- a/contracts/arbitrum/interfaces/IArbSys.sol +++ /dev/null @@ -1,17 +0,0 @@ -// SPDX-FileCopyrightText: 2022 Lido -// SPDX-License-Identifier: GPL-3.0 - -pragma solidity 0.8.10; - -/// @title Precompiled contract that exists in every Arbitrum chain at address(100), -/// 0x0000000000000000000000000000000000000064. Exposes a variety of system-level functionality -interface IArbSys { - /// @notice Send a transaction to L1 - /// @param destination_ Recipient address on L1 - /// @param calldataForL1_ (optional) Calldata for L1 contract call - /// @return Unique identifier for this L2-to-L1 transaction - function sendTxToL1(address destination_, bytes calldata calldataForL1_) - external - payable - returns (uint256); -} diff --git a/contracts/arbitrum/interfaces/IBridge.sol b/contracts/arbitrum/interfaces/IBridge.sol deleted file mode 100644 index 4b6e8a42..00000000 --- a/contracts/arbitrum/interfaces/IBridge.sol +++ /dev/null @@ -1,8 +0,0 @@ -// SPDX-FileCopyrightText: 2022 Lido -// SPDX-License-Identifier: GPL-3.0 - -pragma solidity 0.8.10; - -interface IBridge { - function activeOutbox() external view returns (address); -} diff --git a/contracts/arbitrum/interfaces/IInbox.sol b/contracts/arbitrum/interfaces/IInbox.sol deleted file mode 100644 index 372182ec..00000000 --- a/contracts/arbitrum/interfaces/IInbox.sol +++ /dev/null @@ -1,31 +0,0 @@ -// SPDX-FileCopyrightText: 2022 Lido -// SPDX-License-Identifier: GPL-3.0 - -pragma solidity >=0.4.21; - -interface IInbox { - /// @notice Put an message in the L2 inbox that can be reexecuted for some fixed amount of time - /// if it reverts all msg.value will deposited to callValueRefundAddress on L2 - /// @param destAddr_ Destination L2 contract address - /// @param arbTxCallValue_ Call value for retryable L2 message - /// @param maxSubmissionCost_ Max gas deducted from user's L2 balance to cover base submission fee - /// @param submissionRefundAddress_ maxGas x gasprice - execution cost gets credited here on L2 balance - /// @param valueRefundAddress_ l2Callvalue gets credited here on L2 if retryable txn times out or gets cancelled - /// @param maxGas_ Max gas deducted from user's L2 balance to cover L2 execution - /// @param gasPriceBid_ Price bid for L2 execution - /// @param data_ ABI encoded data of L2 message - /// @return unique id for retryable transaction (keccak256(requestID, uint(0) ) - function createRetryableTicket( - address destAddr_, - uint256 arbTxCallValue_, - uint256 maxSubmissionCost_, - address submissionRefundAddress_, - address valueRefundAddress_, - uint256 maxGas_, - uint256 gasPriceBid_, - bytes calldata data_ - ) external payable returns (uint256); - - /// @notice Returns address of the Arbitumr's bridge - function bridge() external view returns (address); -} diff --git a/contracts/arbitrum/interfaces/IInterchainTokenGateway.sol b/contracts/arbitrum/interfaces/IInterchainTokenGateway.sol deleted file mode 100644 index 0915eac5..00000000 --- a/contracts/arbitrum/interfaces/IInterchainTokenGateway.sol +++ /dev/null @@ -1,50 +0,0 @@ -// SPDX-FileCopyrightText: 2022 Lido -// SPDX-License-Identifier: GPL-3.0 - -pragma solidity 0.8.10; - -/// @author psirex -/// @notice Keeps logic shared among both L1 and L2 gateways. -interface IInterchainTokenGateway { - /// @notice Finalizes the bridging of the tokens between chains - /// @param l1Token_ Address in the L1 chain of the token to withdraw - /// @param from_ Address of the account initiated withdrawing - /// @param to_ Address of the recipient of the tokens - /// @param amount_ Amount of tokens to withdraw - /// @param data_ Additional data required for the transaction - function finalizeInboundTransfer( - address l1Token_, - address from_, - address to_, - uint256 amount_, - bytes calldata data_ - ) external; - - /// @notice Calculates address of token, which will be minted on the Arbitrum chain, - /// on l1Token_ bridging - /// @param l1Token_ Address of the token on the Ethereum chain - /// @return Address of the token minted on the L2 on bridging - function calculateL2TokenAddress(address l1Token_) - external - view - returns (address); - - /// @notice Returns address of the counterpart gateway used in the bridging process - function counterpartGateway() external view returns (address); - - /// @notice Returns encoded transaction data to send into the counterpart gateway to finalize - /// the tokens bridging process. - /// @param l1Token_ Address in the Ethereum chain of the token to bridge - /// @param from_ Address of the account initiated bridging in the current chain - /// @param to_ Address of the recipient of the token in the counterpart chain - /// @param amount_ Amount of tokens to bridge - /// @param data_ Custom data to pass into finalizeInboundTransfer method - /// @return Encoded transaction data of finalizeInboundTransfer call - function getOutboundCalldata( - address l1Token_, - address from_, - address to_, - uint256 amount_, - bytes memory data_ - ) external view returns (bytes memory); -} diff --git a/contracts/arbitrum/interfaces/IL1TokenGateway.sol b/contracts/arbitrum/interfaces/IL1TokenGateway.sol deleted file mode 100644 index 2ec88be5..00000000 --- a/contracts/arbitrum/interfaces/IL1TokenGateway.sol +++ /dev/null @@ -1,42 +0,0 @@ -// SPDX-FileCopyrightText: 2022 Lido -// SPDX-License-Identifier: GPL-3.0 - -pragma solidity 0.8.10; - -import {IInterchainTokenGateway} from "./IInterchainTokenGateway.sol"; - -/// @author psirex -/// @notice L1 part of the tokens bridge compatible with Arbitrum's GatewayRouter -interface IL1TokenGateway is IInterchainTokenGateway { - /// @notice Initiates the tokens bridging from the Ethereum into the Arbitrum chain - /// @param l1Token_ Address in the L1 chain of the token to bridge - /// @param to_ Address of the recipient of the token on the corresponding chain - /// @param amount_ Amount of tokens to bridge - /// @param maxGas_ Gas limit for immediate L2 execution attempt - /// @param gasPriceBid_ L2 gas price bid for immediate L2 execution attempt - /// @param data_ Additional data required for the transaction - function outboundTransfer( - address l1Token_, - address to_, - uint256 amount_, - uint256 maxGas_, - uint256 gasPriceBid_, - bytes calldata data_ - ) external payable returns (bytes memory); - - event DepositInitiated( - address l1Token, - address indexed from, - address indexed to, - uint256 indexed sequenceNumber, - uint256 amount - ); - - event WithdrawalFinalized( - address l1Token, - address indexed from, - address indexed to, - uint256 indexed exitNum, - uint256 amount - ); -} diff --git a/contracts/arbitrum/interfaces/IL2TokenGateway.sol b/contracts/arbitrum/interfaces/IL2TokenGateway.sol deleted file mode 100644 index 182e157b..00000000 --- a/contracts/arbitrum/interfaces/IL2TokenGateway.sol +++ /dev/null @@ -1,40 +0,0 @@ -// SPDX-FileCopyrightText: 2022 Lido -// SPDX-License-Identifier: GPL-3.0 - -pragma solidity 0.8.10; - -import {IInterchainTokenGateway} from "./IInterchainTokenGateway.sol"; - -/// @author psirex -/// @notice L2 part of the tokens bridge compatible with Arbitrum's GatewayRouter -interface IL2TokenGateway is IInterchainTokenGateway { - /// @notice Initiates the withdrawing process from the Arbitrum chain into the Ethereum chain - /// @param l1Token_ Address in the L1 chain of the token to withdraw - /// @param to_ Address of the recipient of the token on the corresponding chain - /// @param amount_ Amount of tokens to bridge - /// @param data_ Additional data required for transaction - function outboundTransfer( - address l1Token_, - address to_, - uint256 amount_, - uint256 maxGas_, - uint256 gasPriceBid_, - bytes calldata data_ - ) external returns (bytes memory); - - event DepositFinalized( - address indexed l1Token, - address indexed from, - address indexed to, - uint256 amount - ); - - event WithdrawalInitiated( - address l1Token, - address indexed from, - address indexed to, - uint256 indexed l2ToL1Id, - uint256 exitNum, - uint256 amount - ); -} diff --git a/contracts/arbitrum/interfaces/IOutbox.sol b/contracts/arbitrum/interfaces/IOutbox.sol deleted file mode 100644 index 02fe1d64..00000000 --- a/contracts/arbitrum/interfaces/IOutbox.sol +++ /dev/null @@ -1,8 +0,0 @@ -// SPDX-FileCopyrightText: 2022 Lido -// SPDX-License-Identifier: GPL-3.0 - -pragma solidity 0.8.10; - -interface IOutbox { - function l2ToL1Sender() external view returns (address); -} diff --git a/contracts/arbitrum/libraries/L1OutboundDataParser.sol b/contracts/arbitrum/libraries/L1OutboundDataParser.sol deleted file mode 100644 index 03c99b8b..00000000 --- a/contracts/arbitrum/libraries/L1OutboundDataParser.sol +++ /dev/null @@ -1,45 +0,0 @@ -// SPDX-FileCopyrightText: 2022 Lido -// SPDX-License-Identifier: GPL-3.0 - -pragma solidity 0.8.10; - -/// @author psirex -/// @notice A helper library to parse data passed to outboundTransfer() of L1TokensGateway -library L1OutboundDataParser { - /// @dev Decodes value contained in data_ bytes array and returns it - /// @param router_ Address of the Arbitrum’s L1GatewayRouter - /// @param data_ Data encoded for the outboundTransfer() method - /// @return Decoded (from, maxSubmissionCost) values - function decode(address router_, bytes memory data_) - internal - view - returns (address, uint256) - { - if (msg.sender != router_) { - return (msg.sender, _parseSubmissionCostData(data_)); - } - (address from, bytes memory extraData) = abi.decode( - data_, - (address, bytes) - ); - return (from, _parseSubmissionCostData(extraData)); - } - - /// @dev Extracts the maxSubmissionCost value from the outboundTransfer() data - function _parseSubmissionCostData(bytes memory data_) - private - pure - returns (uint256) - { - (uint256 maxSubmissionCost, bytes memory extraData) = abi.decode( - data_, - (uint256, bytes) - ); - if (extraData.length != 0) { - revert ExtraDataNotEmpty(); - } - return maxSubmissionCost; - } - - error ExtraDataNotEmpty(); -} diff --git a/contracts/arbitrum/libraries/L2OutboundDataParser.sol b/contracts/arbitrum/libraries/L2OutboundDataParser.sol deleted file mode 100644 index f10acf90..00000000 --- a/contracts/arbitrum/libraries/L2OutboundDataParser.sol +++ /dev/null @@ -1,30 +0,0 @@ -// SPDX-FileCopyrightText: 2022 Lido -// SPDX-License-Identifier: GPL-3.0 - -pragma solidity 0.8.10; - -/// @author psirex -/// @notice A helper library to parse data passed to outboundTransfer() of L2ERC20TokenGateway -library L2OutboundDataParser { - /// @dev Decodes value contained in data_ bytes array and returns it - /// @param router_ Address of the Arbitrum’s L2GatewayRouter - /// @param data_ Data encoded for the outboundTransfer() method - /// @return from_ address of the sender - function decode(address router_, bytes memory data_) - internal - view - returns (address from_) - { - bytes memory extraData; - if (msg.sender == router_) { - (from_, extraData) = abi.decode(data_, (address, bytes)); - } else { - (from_, extraData) = (msg.sender, data_); - } - if (extraData.length != 0) { - revert ExtraDataNotEmpty(); - } - } - - error ExtraDataNotEmpty(); -} diff --git a/contracts/arbitrum/stubs/ArbSysStub.sol b/contracts/arbitrum/stubs/ArbSysStub.sol deleted file mode 100644 index 5315414b..00000000 --- a/contracts/arbitrum/stubs/ArbSysStub.sol +++ /dev/null @@ -1,24 +0,0 @@ -// SPDX-FileCopyrightText: 2022 Lido -// SPDX-License-Identifier: GPL-3.0 - -pragma solidity 0.8.10; - -contract ArbSysStub { - uint256 public l2ToL1TxId; - - function setl2ToL1TxId(uint256 l2ToL1TxId_) public { - l2ToL1TxId = l2ToL1TxId_; - } - - function sendTxToL1(address recipient, bytes calldata data) - external - payable - returns (uint256) - { - l2ToL1TxId += 1; - emit CreateL2ToL1Tx(recipient, data); - return l2ToL1TxId; - } - - event CreateL2ToL1Tx(address recipient, bytes data); -} diff --git a/contracts/arbitrum/stubs/BridgeStub.sol b/contracts/arbitrum/stubs/BridgeStub.sol deleted file mode 100644 index 9498e68e..00000000 --- a/contracts/arbitrum/stubs/BridgeStub.sol +++ /dev/null @@ -1,18 +0,0 @@ -// SPDX-FileCopyrightText: 2022 Lido -// SPDX-License-Identifier: GPL-3.0 - -pragma solidity 0.8.10; - -import {IBridge} from "../interfaces/IBridge.sol"; - -contract BridgeStub is IBridge { - address public activeOutbox; - - constructor(address activeOutbox_) payable { - activeOutbox = activeOutbox_; - } - - function setOutbox(address outbox_) external { - activeOutbox = outbox_; - } -} diff --git a/contracts/arbitrum/stubs/InboxStub.sol b/contracts/arbitrum/stubs/InboxStub.sol deleted file mode 100644 index 7cd5e884..00000000 --- a/contracts/arbitrum/stubs/InboxStub.sol +++ /dev/null @@ -1,55 +0,0 @@ -// SPDX-FileCopyrightText: 2022 Lido -// SPDX-License-Identifier: GPL-3.0 - -pragma solidity 0.8.10; - -import {IInbox} from "../interfaces/IInbox.sol"; - -contract InboxStub is IInbox { - uint256 public retryableTicketId; - address public immutable bridge; - - constructor(address bridge_) { - bridge = bridge_; - } - - function setRetryableTicketId(uint256 retryableTicketId_) public { - retryableTicketId = retryableTicketId_; - } - - function createRetryableTicket( - address destAddr, - uint256 arbTxCallValue, - uint256 maxSubmissionCost, - address submissionRefundAddress, - address valueRefundAddress, - uint256 maxGas, - uint256 gasPriceBid, - bytes calldata data - ) external payable returns (uint256) { - emit CreateRetryableTicketCalled( - msg.value, - destAddr, - arbTxCallValue, - maxSubmissionCost, - submissionRefundAddress, - valueRefundAddress, - maxGas, - gasPriceBid, - data - ); - return retryableTicketId; - } - - event CreateRetryableTicketCalled( - uint256 value, - address destAddr, - uint256 arbTxCallValue, - uint256 maxSubmissionCost, - address submissionRefundAddress, - address valueRefundAddress, - uint256 maxGas, - uint256 gasPriceBid, - bytes data - ); -} diff --git a/contracts/arbitrum/stubs/OutboxStub.sol b/contracts/arbitrum/stubs/OutboxStub.sol deleted file mode 100644 index 4278af8c..00000000 --- a/contracts/arbitrum/stubs/OutboxStub.sol +++ /dev/null @@ -1,14 +0,0 @@ -// SPDX-FileCopyrightText: 2022 Lido -// SPDX-License-Identifier: GPL-3.0 - -pragma solidity 0.8.10; - -import {IOutbox} from "../interfaces/IOutbox.sol"; - -contract OutboxStub is IOutbox { - address public l2ToL1Sender; - - function setL2ToL1Sender(address l2ToL1Sender_) external { - l2ToL1Sender = l2ToL1Sender_; - } -} diff --git a/contracts/lib/DepositDataCodec.sol b/contracts/lib/DepositDataCodec.sol new file mode 100644 index 00000000..94403871 --- /dev/null +++ b/contracts/lib/DepositDataCodec.sol @@ -0,0 +1,43 @@ +// SPDX-FileCopyrightText: 2024 Lido +// SPDX-License-Identifier: GPL-3.0 + +pragma solidity 0.8.10; + +/// @author kovalgek +/// @notice encodes and decodes DepositData for crosschain transfering. +library DepositDataCodec { + + uint8 internal constant RATE_FIELD_SIZE = 16; + uint8 internal constant TIMESTAMP_FIELD_SIZE = 5; + + struct DepositData { + uint128 rate; + uint40 timestamp; + bytes data; + } + + function encodeDepositData(DepositData memory depositData) internal pure returns (bytes memory) { + bytes memory data = bytes.concat( + abi.encodePacked(depositData.rate), + abi.encodePacked(depositData.timestamp), + abi.encodePacked(depositData.data) + ); + return data; + } + + function decodeDepositData(bytes calldata buffer) internal pure returns (DepositData memory) { + if (buffer.length < RATE_FIELD_SIZE + TIMESTAMP_FIELD_SIZE) { + revert ErrorDepositDataLength(); + } + + DepositData memory depositData = DepositData({ + rate: uint128(bytes16(buffer[0:RATE_FIELD_SIZE])), + timestamp: uint40(bytes5(buffer[RATE_FIELD_SIZE:RATE_FIELD_SIZE + TIMESTAMP_FIELD_SIZE])), + data: buffer[RATE_FIELD_SIZE + TIMESTAMP_FIELD_SIZE:] + }); + + return depositData; + } + + error ErrorDepositDataLength(); +} diff --git a/contracts/lib/UnstructuredRefStorage.sol b/contracts/lib/UnstructuredRefStorage.sol new file mode 100644 index 00000000..28a80c9b --- /dev/null +++ b/contracts/lib/UnstructuredRefStorage.sol @@ -0,0 +1,20 @@ +// SPDX-FileCopyrightText: 2024 Lido +// SPDX-License-Identifier: GPL-3.0 + +pragma solidity 0.8.10; + +/// @dev A copy of UnstructuredRefStorage.sol library from Lido on Ethereum protocol. +/// https://github.com/lidofinance/lido-dao/blob/master/contracts/0.8.9/lib/UnstructuredRefStorage.sol +library UnstructuredRefStorage { + function storageMapAddressMapAddressUint256(bytes32 _position) internal pure returns ( + mapping(address => mapping(address => uint256)) storage result + ) { + assembly { result.slot := _position } + } + + function storageMapAddressAddressUint256(bytes32 _position) internal pure returns ( + mapping(address => uint256) storage result + ) { + assembly { result.slot := _position } + } +} diff --git a/contracts/lib/UnstructuredStorage.sol b/contracts/lib/UnstructuredStorage.sol new file mode 100644 index 00000000..994b4e34 --- /dev/null +++ b/contracts/lib/UnstructuredStorage.sol @@ -0,0 +1,40 @@ +// SPDX-FileCopyrightText: 2024 Lido +// SPDX-License-Identifier: GPL-3.0 + +pragma solidity 0.8.10; + +/// @dev A copy of UnstructuredStorage.sol library from Lido on Ethereum protocol. +/// https://github.com/lidofinance/lido-dao/blob/master/contracts/0.8.9/lib/UnstructuredStorage.sol +library UnstructuredStorage { + function getStorageBool(bytes32 position) internal view returns (bool data) { + assembly { data := sload(position) } + } + + function getStorageAddress(bytes32 position) internal view returns (address data) { + assembly { data := sload(position) } + } + + function getStorageBytes32(bytes32 position) internal view returns (bytes32 data) { + assembly { data := sload(position) } + } + + function getStorageUint256(bytes32 position) internal view returns (uint256 data) { + assembly { data := sload(position) } + } + + function setStorageBool(bytes32 position, bool data) internal { + assembly { sstore(position, data) } + } + + function setStorageAddress(bytes32 position, address data) internal { + assembly { sstore(position, data) } + } + + function setStorageBytes32(bytes32 position, bytes32 data) internal { + assembly { sstore(position, data) } + } + + function setStorageUint256(bytes32 position, uint256 data) internal { + assembly { sstore(position, data) } + } +} diff --git a/contracts/lido/TokenRateNotifier.sol b/contracts/lido/TokenRateNotifier.sol new file mode 100644 index 00000000..96f1c718 --- /dev/null +++ b/contracts/lido/TokenRateNotifier.sol @@ -0,0 +1,158 @@ +// SPDX-FileCopyrightText: 2024 Lido +// SPDX-License-Identifier: GPL-3.0 + +pragma solidity 0.8.10; + +import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol"; +import {ERC165Checker} from "@openzeppelin/contracts/utils/introspection/ERC165Checker.sol"; +import {ITokenRatePusher} from "./interfaces/ITokenRatePusher.sol"; + +/// @notice An interface to subscribe on the `stETH` token rebases (defined in the `Lido` core contract) +interface IPostTokenRebaseReceiver { + + /// @notice Is called in the context of `Lido.handleOracleReport` to notify the subscribers about each token rebase + function handlePostTokenRebase( + uint256 _reportTimestamp, + uint256 _timeElapsed, + uint256 _preTotalShares, + uint256 _preTotalEther, + uint256 _postTotalShares, + uint256 _postTotalEther, + uint256 _sharesMintedAsFees + ) external; +} + +/// @author kovalgek +/// @notice Notifies all `observers` when rebase event occures. +contract TokenRateNotifier is Ownable, IPostTokenRebaseReceiver { + using ERC165Checker for address; + + /// @notice Address of the contract that is allowed to call handlePostTokenRebase. + address public immutable AUTHORIZED_REBASE_CALLER; + + /// @notice Maximum amount of observers to be supported. + uint256 public constant MAX_OBSERVERS_COUNT = 32; + + /// @notice A value that indicates that value was not found. + uint256 public constant INDEX_NOT_FOUND = type(uint256).max; + + /// @notice An interface that each observer should support. + bytes4 public constant REQUIRED_INTERFACE = type(ITokenRatePusher).interfaceId; + + /// @notice All observers. + address[] public observers; + + /// @param initialOwner_ initial owner + /// @param authorizedRebaseCaller_ Address of the contract that is allowed to call handlePostTokenRebase. + constructor(address initialOwner_, address authorizedRebaseCaller_) { + if (initialOwner_ == address(0)) { + revert ErrorZeroAddressOwner(); + } + if (authorizedRebaseCaller_ == address(0)) { + revert ErrorZeroAddressCaller(); + } + _transferOwnership(initialOwner_); + AUTHORIZED_REBASE_CALLER = authorizedRebaseCaller_; + } + + /// @notice Add a `observer_` to the back of array + /// @param observer_ observer address + function addObserver(address observer_) external onlyOwner { + if (observer_ == address(0)) { + revert ErrorZeroAddressObserver(); + } + if (!observer_.supportsInterface(REQUIRED_INTERFACE)) { + revert ErrorBadObserverInterface(); + } + if (observers.length >= MAX_OBSERVERS_COUNT) { + revert ErrorMaxObserversCountExceeded(); + } + if (_observerIndex(observer_) != INDEX_NOT_FOUND) { + revert ErrorAddExistedObserver(); + } + + observers.push(observer_); + emit ObserverAdded(observer_); + } + + /// @notice Remove a observer at the given `observer_` position + /// @param observer_ observer remove position + function removeObserver(address observer_) external onlyOwner { + uint256 observerIndexToRemove = _observerIndex(observer_); + + if (observerIndexToRemove == INDEX_NOT_FOUND) { + revert ErrorNoObserverToRemove(); + } + if (observerIndexToRemove != observers.length - 1) { + observers[observerIndexToRemove] = observers[observers.length - 1]; + } + observers.pop(); + + emit ObserverRemoved(observer_); + } + + /// @inheritdoc IPostTokenRebaseReceiver + /// @dev Parameters aren't used because all required data further components fetch by themselves. + function handlePostTokenRebase( + uint256, /* reportTimestamp */ + uint256, /* timeElapsed */ + uint256, /* preTotalShares */ + uint256, /* preTotalEther */ + uint256, /* postTotalShares */ + uint256, /* postTotalEther */ + uint256 /* sharesMintedAsFees */ + ) external { + if (msg.sender != AUTHORIZED_REBASE_CALLER) { + revert ErrorNotAuthorizedRebaseCaller(); + } + uint256 cachedObserversLength = observers.length; + for (uint256 obIndex = 0; obIndex < cachedObserversLength; obIndex++) { + // solhint-disable-next-line no-empty-blocks + try ITokenRatePusher(observers[obIndex]).pushTokenRate() {} + catch (bytes memory lowLevelRevertData) { + /// @dev This check is required to prevent incorrect gas estimation of the method. + /// Without it, Ethereum nodes that use binary search for gas estimation may + /// return an invalid value when the pushTokenRate() reverts because of the + /// "out of gas" error. Here we assume that the pushTokenRate() method doesn't + /// have reverts with empty error data except "out of gas". + if (lowLevelRevertData.length == 0) revert ErrorTokenRateNotifierRevertedWithNoData(); + emit PushTokenRateFailed( + observers[obIndex], + lowLevelRevertData + ); + } + } + } + + /// @notice Observer length + /// @return Added `observers` count + function observersLength() external view returns (uint256) { + return observers.length; + } + + /// @notice `observer_` index in `observers` array. + /// @return An index of `observer_` or `INDEX_NOT_FOUND` if it wasn't found. + function _observerIndex(address observer_) internal view returns (uint256) { + uint256 cachedObserversLength = observers.length; + for (uint256 obIndex = 0; obIndex < cachedObserversLength; obIndex++) { + if (observers[obIndex] == observer_) { + return obIndex; + } + } + return INDEX_NOT_FOUND; + } + + event PushTokenRateFailed(address indexed observer, bytes lowLevelRevertData); + event ObserverAdded(address indexed observer); + event ObserverRemoved(address indexed observer); + + error ErrorTokenRateNotifierRevertedWithNoData(); + error ErrorZeroAddressObserver(); + error ErrorBadObserverInterface(); + error ErrorMaxObserversCountExceeded(); + error ErrorNoObserverToRemove(); + error ErrorZeroAddressOwner(); + error ErrorZeroAddressCaller(); + error ErrorNotAuthorizedRebaseCaller(); + error ErrorAddExistedObserver(); +} diff --git a/contracts/lido/interfaces/ITokenRatePusher.sol b/contracts/lido/interfaces/ITokenRatePusher.sol new file mode 100644 index 00000000..9d157c3c --- /dev/null +++ b/contracts/lido/interfaces/ITokenRatePusher.sol @@ -0,0 +1,11 @@ +// SPDX-FileCopyrightText: 2024 Lido +// SPDX-License-Identifier: GPL-3.0 + +pragma solidity 0.8.10; + +/// @author kovalgek +/// @notice An interface for entity that pushes token rate. +interface ITokenRatePusher { + /// @notice Pushes token rate to L2 by depositing zero token amount. + function pushTokenRate() external; +} diff --git a/contracts/lido/stubs/AccountingOracleStub.sol b/contracts/lido/stubs/AccountingOracleStub.sol new file mode 100644 index 00000000..11f58942 --- /dev/null +++ b/contracts/lido/stubs/AccountingOracleStub.sol @@ -0,0 +1,32 @@ +// SPDX-FileCopyrightText: 2024 Lido +// SPDX-License-Identifier: GPL-3.0 + +pragma solidity 0.8.10; + +import {IAccountingOracle} from "../../optimism/TokenRateAndUpdateTimestampProvider.sol"; + +/// @dev For testing purposes. +contract AccountingOracleStub is IAccountingOracle { + + uint256 private immutable genesisTime; + uint256 private immutable secondsPerSlot; + uint256 private immutable lastProcessingRefSlot; + + constructor(uint256 genesisTime_, uint256 secondsPerSlot_, uint256 lastProcessingRefSlot_) { + genesisTime = genesisTime_; + secondsPerSlot = secondsPerSlot_; + lastProcessingRefSlot = lastProcessingRefSlot_; + } + + function GENESIS_TIME() external view returns (uint256) { + return genesisTime; + } + + function SECONDS_PER_SLOT() external view returns (uint256) { + return secondsPerSlot; + } + + function getLastProcessingRefSlot() external view returns (uint256) { + return lastProcessingRefSlot; + } +} diff --git a/contracts/lido/stubs/OpStackTokenRatePusherWithOutOfGasErrorStub.sol b/contracts/lido/stubs/OpStackTokenRatePusherWithOutOfGasErrorStub.sol new file mode 100644 index 00000000..0ce7974c --- /dev/null +++ b/contracts/lido/stubs/OpStackTokenRatePusherWithOutOfGasErrorStub.sol @@ -0,0 +1,29 @@ +// SPDX-FileCopyrightText: 2024 Lido +// SPDX-License-Identifier: GPL-3.0 + +pragma solidity 0.8.10; + +import {ITokenRatePusher} from "../interfaces/ITokenRatePusher.sol"; +import {ERC165} from "@openzeppelin/contracts/utils/introspection/ERC165.sol"; + +/// @dev For testing purposes. +contract OpStackTokenRatePusherWithOutOfGasErrorStub is ERC165, ITokenRatePusher { + + uint256 public constant OUT_OF_GAS_INCURRING_MAX = 1000000000000; + + mapping (uint256 => uint256) public data; + + function pushTokenRate() external { + for (uint256 i = 0; i < OUT_OF_GAS_INCURRING_MAX; ++i) { + data[i] = i; + } + } + + /// @inheritdoc ERC165 + function supportsInterface(bytes4 _interfaceId) public view virtual override returns (bool) { + return ( + _interfaceId == type(ITokenRatePusher).interfaceId + || super.supportsInterface(_interfaceId) + ); + } +} diff --git a/contracts/lido/stubs/OpStackTokenRatePusherWithSomeErrorStub.sol b/contracts/lido/stubs/OpStackTokenRatePusherWithSomeErrorStub.sol new file mode 100644 index 00000000..6df0b7fa --- /dev/null +++ b/contracts/lido/stubs/OpStackTokenRatePusherWithSomeErrorStub.sol @@ -0,0 +1,25 @@ +// SPDX-FileCopyrightText: 2024 Lido +// SPDX-License-Identifier: GPL-3.0 + +pragma solidity 0.8.10; + +import {ITokenRatePusher} from "../interfaces/ITokenRatePusher.sol"; +import {ERC165} from "@openzeppelin/contracts/utils/introspection/ERC165.sol"; + +/// @dev For testing purposes. +contract OpStackTokenRatePusherWithSomeErrorStub is ERC165, ITokenRatePusher { + + error SomeError(); + + function pushTokenRate() pure external { + revert SomeError(); + } + + /// @inheritdoc ERC165 + function supportsInterface(bytes4 _interfaceId) public view virtual override returns (bool) { + return ( + _interfaceId == type(ITokenRatePusher).interfaceId + || super.supportsInterface(_interfaceId) + ); + } +} diff --git a/contracts/optimism/CrossDomainEnabled.sol b/contracts/optimism/CrossDomainEnabled.sol index 0fe0e5bb..2103470a 100644 --- a/contracts/optimism/CrossDomainEnabled.sol +++ b/contracts/optimism/CrossDomainEnabled.sol @@ -8,11 +8,14 @@ import {ICrossDomainMessenger} from "./interfaces/ICrossDomainMessenger.sol"; /// @dev Helper contract for contracts performing cross-domain communications contract CrossDomainEnabled { /// @notice Messenger contract used to send and receive messages from the other domain - ICrossDomainMessenger public immutable messenger; + ICrossDomainMessenger public immutable MESSENGER; /// @param messenger_ Address of the CrossDomainMessenger on the current layer constructor(address messenger_) { - messenger = ICrossDomainMessenger(messenger_); + if (messenger_ == address(0)) { + revert ErrorZeroAddressMessenger(); + } + MESSENGER = ICrossDomainMessenger(messenger_); } /// @dev Sends a message to an account on another domain @@ -25,22 +28,23 @@ contract CrossDomainEnabled { uint32 gasLimit_, bytes memory message_ ) internal { - messenger.sendMessage(crossDomainTarget_, message_, gasLimit_); + MESSENGER.sendMessage(crossDomainTarget_, message_, gasLimit_); } /// @dev Enforces that the modified function is only callable by a specific cross-domain account /// @param sourceDomainAccount_ The only account on the originating domain which is /// authenticated to call this function modifier onlyFromCrossDomainAccount(address sourceDomainAccount_) { - if (msg.sender != address(messenger)) { + if (msg.sender != address(MESSENGER)) { revert ErrorUnauthorizedMessenger(); } - if (messenger.xDomainMessageSender() != sourceDomainAccount_) { + if (MESSENGER.xDomainMessageSender() != sourceDomainAccount_) { revert ErrorWrongCrossDomainSender(); } _; } + error ErrorZeroAddressMessenger(); error ErrorUnauthorizedMessenger(); error ErrorWrongCrossDomainSender(); } diff --git a/contracts/optimism/L1ERC20ExtendedTokensBridge.sol b/contracts/optimism/L1ERC20ExtendedTokensBridge.sol new file mode 100644 index 00000000..e4e1a381 --- /dev/null +++ b/contracts/optimism/L1ERC20ExtendedTokensBridge.sol @@ -0,0 +1,188 @@ +// SPDX-FileCopyrightText: 2024 Lido +// SPDX-License-Identifier: GPL-3.0 + +pragma solidity 0.8.10; + +import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; +import {Address} from "@openzeppelin/contracts/utils/Address.sol"; +import {SafeERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; +import {IL1ERC20Bridge} from "./interfaces/IL1ERC20Bridge.sol"; +import {IL2ERC20Bridge} from "./interfaces/IL2ERC20Bridge.sol"; +import {IERC20Wrapper} from "../token/interfaces/IERC20Wrapper.sol"; +import {BridgingManager} from "../BridgingManager.sol"; +import {RebasableAndNonRebasableTokens} from "./RebasableAndNonRebasableTokens.sol"; +import {CrossDomainEnabled} from "./CrossDomainEnabled.sol"; +import {DepositDataCodec} from "../lib//DepositDataCodec.sol"; + +/// @author psirex, kovalgek +/// @notice The L1 ERC20 token bridge locks bridged tokens on the L1 side, sends deposit messages +/// on the L2 side, and finalizes token withdrawals from L2. Additionally, adds the methods for +/// bridging management: enabling and disabling withdrawals/deposits +abstract contract L1ERC20ExtendedTokensBridge is + IL1ERC20Bridge, + BridgingManager, + RebasableAndNonRebasableTokens, + CrossDomainEnabled +{ + using SafeERC20 for IERC20; + + address private immutable L2_TOKEN_BRIDGE; + + /// @param messenger_ L1 messenger address being used for cross-chain communications + /// @param l2TokenBridge_ Address of the corresponding L2 bridge + /// @param l1TokenNonRebasable_ Address of the bridged token in the L1 chain + /// @param l1TokenRebasable_ Address of the bridged token in the L1 chain + /// @param l2TokenNonRebasable_ Address of the token minted on the L2 chain when token bridged + /// @param l2TokenRebasable_ Address of the token minted on the L2 chain when token bridged + constructor( + address messenger_, + address l2TokenBridge_, + address l1TokenNonRebasable_, + address l1TokenRebasable_, + address l2TokenNonRebasable_, + address l2TokenRebasable_ + ) CrossDomainEnabled(messenger_) RebasableAndNonRebasableTokens( + l1TokenNonRebasable_, + l1TokenRebasable_, + l2TokenNonRebasable_, + l2TokenRebasable_ + ) { + if (l2TokenBridge_ == address(0)) { + revert ErrorZeroAddressL2Bridge(); + } + L2_TOKEN_BRIDGE = l2TokenBridge_; + } + + /// @inheritdoc IL1ERC20Bridge + function l2TokenBridge() external view returns (address) { + return L2_TOKEN_BRIDGE; + } + + /// @inheritdoc IL1ERC20Bridge + function depositERC20( + address l1Token_, + address l2Token_, + uint256 amount_, + uint32 l2Gas_, + bytes calldata data_ + ) + external + whenDepositsEnabled + onlySupportedL1L2TokensPair(l1Token_, l2Token_) + { + if (Address.isContract(msg.sender)) { + revert ErrorSenderNotEOA(); + } + bytes memory encodedDepositData = _encodeInputDepositData(data_); + _depositERC20To(l1Token_, l2Token_, msg.sender, msg.sender, amount_, l2Gas_, encodedDepositData); + emit ERC20DepositInitiated(l1Token_, l2Token_, msg.sender, msg.sender, amount_, encodedDepositData); + } + + /// @inheritdoc IL1ERC20Bridge + function depositERC20To( + address l1Token_, + address l2Token_, + address to_, + uint256 amount_, + uint32 l2Gas_, + bytes calldata data_ + ) + external + whenDepositsEnabled + onlyNonZeroAccount(to_) + onlySupportedL1L2TokensPair(l1Token_, l2Token_) + { + bytes memory encodedDepositData = _encodeInputDepositData(data_); + _depositERC20To(l1Token_, l2Token_, msg.sender, to_, amount_, l2Gas_, encodedDepositData); + emit ERC20DepositInitiated(l1Token_, l2Token_, msg.sender, to_, amount_, encodedDepositData); + } + + /// @inheritdoc IL1ERC20Bridge + function finalizeERC20Withdrawal( + address l1Token_, + address l2Token_, + address from_, + address to_, + uint256 amount_, + bytes calldata data_ + ) + external + whenWithdrawalsEnabled + onlyFromCrossDomainAccount(L2_TOKEN_BRIDGE) + onlySupportedL1L2TokensPair(l1Token_, l2Token_) + { + uint256 withdrawnL1TokenAmount = (l1Token_ == L1_TOKEN_REBASABLE && amount_ != 0) ? + IERC20Wrapper(L1_TOKEN_NON_REBASABLE).unwrap(amount_) : + amount_; + IERC20(l1Token_).safeTransfer(to_, withdrawnL1TokenAmount); + emit ERC20WithdrawalFinalized(l1Token_, l2Token_, from_, to_, withdrawnL1TokenAmount, data_); + } + + /// @notice Performs the logic for deposits by informing the L2 token bridge contract + /// of the deposit and calling safeTransferFrom to lock the L1 funds. + /// @param l1Token_ Address of the L1 ERC20 we are depositing + /// @param l2Token_ Address of the L1 respective L2 ERC20 + /// @param from_ Account to pull the deposit from on L1 + /// @param to_ Account to give the deposit to on L2 + /// @param amount_ Amount of the ERC20 to deposit. + /// @param l2Gas_ Gas limit required to complete the deposit on L2. + /// @param encodedDepositData_ a concatenation of packed token rate with L1 time and + /// optional data passed by external contract + function _depositERC20To( + address l1Token_, + address l2Token_, + address from_, + address to_, + uint256 amount_, + uint32 l2Gas_, + bytes memory encodedDepositData_ + ) internal { + uint256 nonRebasableAmountToDeposit = _transferToBridge(l1Token_, from_, amount_); + + bytes memory message = abi.encodeWithSelector( + IL2ERC20Bridge.finalizeDeposit.selector, + l1Token_, l2Token_, from_, to_, nonRebasableAmountToDeposit, encodedDepositData_ + ); + + sendCrossDomainMessage(L2_TOKEN_BRIDGE, l2Gas_, message); + } + + /// @notice Transfers tokens to the bridge and wraps if needed. + /// @param l1Token_ Address of the L1 ERC20 we are depositing. + /// @param from_ Account to pull the deposit from on L1. + /// @param amount_ Amount of the ERC20 to deposit. + /// @return Amount of non-rebasable token. + function _transferToBridge( + address l1Token_, + address from_, + uint256 amount_ + ) internal returns (uint256) { + if (amount_ != 0) { + IERC20(l1Token_).safeTransferFrom(from_, address(this), amount_); + if (l1Token_ == L1_TOKEN_REBASABLE) { + IERC20(l1Token_).safeIncreaseAllowance(L1_TOKEN_NON_REBASABLE, amount_); + return IERC20Wrapper(L1_TOKEN_NON_REBASABLE).wrap(amount_); + } + } + return amount_; + } + + /// @dev Helper that simplifies calling encoding by DepositDataCodec. + /// Encodes token rate, it's L1 timestamp and optional data. + /// @param data_ Optional data to forward to L2. + /// @return encoded data in the 'wired' bytes form. + function _encodeInputDepositData(bytes calldata data_) internal view returns (bytes memory) { + (uint256 rate, uint256 timestamp) = _tokenRate(); + return DepositDataCodec.encodeDepositData(DepositDataCodec.DepositData({ + rate: uint128(rate), + timestamp: uint40(timestamp), + data: data_ + })); + } + + /// @notice required to abstact a way token rate is requested. + function _tokenRate() virtual internal view returns (uint256 rate_, uint256 updateTimestamp_); + + error ErrorSenderNotEOA(); + error ErrorZeroAddressL2Bridge(); +} diff --git a/contracts/optimism/L1ERC20TokenBridge.sol b/contracts/optimism/L1ERC20TokenBridge.sol deleted file mode 100644 index a4438b88..00000000 --- a/contracts/optimism/L1ERC20TokenBridge.sol +++ /dev/null @@ -1,150 +0,0 @@ -// SPDX-FileCopyrightText: 2022 Lido -// SPDX-License-Identifier: GPL-3.0 - -pragma solidity 0.8.10; - -import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; -import {Address} from "@openzeppelin/contracts/utils/Address.sol"; -import {SafeERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; - -import {IL1ERC20Bridge} from "./interfaces/IL1ERC20Bridge.sol"; -import {IL2ERC20Bridge} from "./interfaces/IL2ERC20Bridge.sol"; - -import {BridgingManager} from "../BridgingManager.sol"; -import {BridgeableTokens} from "../BridgeableTokens.sol"; -import {CrossDomainEnabled} from "./CrossDomainEnabled.sol"; - -/// @author psirex -/// @notice The L1 ERC20 token bridge locks bridged tokens on the L1 side, sends deposit messages -/// on the L2 side, and finalizes token withdrawals from L2. Additionally, adds the methods for -/// bridging management: enabling and disabling withdrawals/deposits -contract L1ERC20TokenBridge is - IL1ERC20Bridge, - BridgingManager, - BridgeableTokens, - CrossDomainEnabled -{ - using SafeERC20 for IERC20; - - /// @inheritdoc IL1ERC20Bridge - address public immutable l2TokenBridge; - - /// @param messenger_ L1 messenger address being used for cross-chain communications - /// @param l2TokenBridge_ Address of the corresponding L2 bridge - /// @param l1Token_ Address of the bridged token in the L1 chain - /// @param l2Token_ Address of the token minted on the L2 chain when token bridged - constructor( - address messenger_, - address l2TokenBridge_, - address l1Token_, - address l2Token_ - ) CrossDomainEnabled(messenger_) BridgeableTokens(l1Token_, l2Token_) { - l2TokenBridge = l2TokenBridge_; - } - - /// @inheritdoc IL1ERC20Bridge - function depositERC20( - address l1Token_, - address l2Token_, - uint256 amount_, - uint32 l2Gas_, - bytes calldata data_ - ) - external - whenDepositsEnabled - onlySupportedL1Token(l1Token_) - onlySupportedL2Token(l2Token_) - { - if (Address.isContract(msg.sender)) { - revert ErrorSenderNotEOA(); - } - _initiateERC20Deposit(msg.sender, msg.sender, amount_, l2Gas_, data_); - } - - /// @inheritdoc IL1ERC20Bridge - function depositERC20To( - address l1Token_, - address l2Token_, - address to_, - uint256 amount_, - uint32 l2Gas_, - bytes calldata data_ - ) - external - whenDepositsEnabled - onlyNonZeroAccount(to_) - onlySupportedL1Token(l1Token_) - onlySupportedL2Token(l2Token_) - { - _initiateERC20Deposit(msg.sender, to_, amount_, l2Gas_, data_); - } - - /// @inheritdoc IL1ERC20Bridge - function finalizeERC20Withdrawal( - address l1Token_, - address l2Token_, - address from_, - address to_, - uint256 amount_, - bytes calldata data_ - ) - external - whenWithdrawalsEnabled - onlySupportedL1Token(l1Token_) - onlySupportedL2Token(l2Token_) - onlyFromCrossDomainAccount(l2TokenBridge) - { - IERC20(l1Token_).safeTransfer(to_, amount_); - - emit ERC20WithdrawalFinalized( - l1Token_, - l2Token_, - from_, - to_, - amount_, - data_ - ); - } - - /// @dev Performs the logic for deposits by informing the L2 token bridge contract - /// of the deposit and calling safeTransferFrom to lock the L1 funds. - /// @param from_ Account to pull the deposit from on L1 - /// @param to_ Account to give the deposit to on L2 - /// @param amount_ Amount of the ERC20 to deposit. - /// @param l2Gas_ Gas limit required to complete the deposit on L2. - /// @param data_ Optional data to forward to L2. This data is provided - /// solely as a convenience for external contracts. Aside from enforcing a maximum - /// length, these contracts provide no guarantees about its content. - function _initiateERC20Deposit( - address from_, - address to_, - uint256 amount_, - uint32 l2Gas_, - bytes calldata data_ - ) internal { - IERC20(l1Token).safeTransferFrom(from_, address(this), amount_); - - bytes memory message = abi.encodeWithSelector( - IL2ERC20Bridge.finalizeDeposit.selector, - l1Token, - l2Token, - from_, - to_, - amount_, - data_ - ); - - sendCrossDomainMessage(l2TokenBridge, l2Gas_, message); - - emit ERC20DepositInitiated( - l1Token, - l2Token, - from_, - to_, - amount_, - data_ - ); - } - - error ErrorSenderNotEOA(); -} diff --git a/contracts/optimism/L1LidoTokensBridge.sol b/contracts/optimism/L1LidoTokensBridge.sol new file mode 100644 index 00000000..50fd83aa --- /dev/null +++ b/contracts/optimism/L1LidoTokensBridge.sol @@ -0,0 +1,59 @@ +// SPDX-FileCopyrightText: 2024 Lido +// SPDX-License-Identifier: GPL-3.0 + +pragma solidity 0.8.10; + +import {L1ERC20ExtendedTokensBridge} from "./L1ERC20ExtendedTokensBridge.sol"; +import {Versioned} from "../utils/Versioned.sol"; +import {TokenRateAndUpdateTimestampProvider} from "./TokenRateAndUpdateTimestampProvider.sol"; + +/// @author kovalgek +/// @notice Hides wstETH concept from other contracts to keep `L1ERC20ExtendedTokensBridge` reusable. +contract L1LidoTokensBridge is L1ERC20ExtendedTokensBridge, TokenRateAndUpdateTimestampProvider, Versioned { + + /// @param messenger_ L1 messenger address being used for cross-chain communications + /// @param l2TokenBridge_ Address of the corresponding L2 bridge + /// @param l1TokenNonRebasable_ Address of the bridged token in the L1 chain + /// @param l1TokenRebasable_ Address of the bridged token in the L1 chain + /// @param l2TokenNonRebasable_ Address of the token minted on the L2 chain when token bridged + /// @param l2TokenRebasable_ Address of the token minted on the L2 chain when token bridged + /// @param accountingOracle_ Address of the AccountingOracle instance to retrieve rate update timestamps + constructor( + address messenger_, + address l2TokenBridge_, + address l1TokenNonRebasable_, + address l1TokenRebasable_, + address l2TokenNonRebasable_, + address l2TokenRebasable_, + address accountingOracle_ + ) L1ERC20ExtendedTokensBridge( + messenger_, + l2TokenBridge_, + l1TokenNonRebasable_, + l1TokenRebasable_, + l2TokenNonRebasable_, + l2TokenRebasable_ + ) TokenRateAndUpdateTimestampProvider( + l1TokenNonRebasable_, + accountingOracle_ + ) {} + + /// @notice Initializes the contract from scratch. + /// @param admin_ Address of the account to grant the DEFAULT_ADMIN_ROLE + function initialize(address admin_) external { + _initializeContractVersionTo(2); + _initializeBridgingManager(admin_); + } + + /// @notice A function to finalize upgrade to v2 (from v1). + function finalizeUpgrade_v2() external { + if (!_isBridgingManagerInitialized()) { + revert ErrorBridgingManagerIsNotInitialized(); + } + _initializeContractVersionTo(2); + } + + function _tokenRate() override internal view returns (uint256 rate, uint256 updateTimestamp) { + return _getTokenRateAndUpdateTimestamp(); + } +} diff --git a/contracts/optimism/L2ERC20ExtendedTokensBridge.sol b/contracts/optimism/L2ERC20ExtendedTokensBridge.sol new file mode 100644 index 00000000..e3fed342 --- /dev/null +++ b/contracts/optimism/L2ERC20ExtendedTokensBridge.sol @@ -0,0 +1,226 @@ +// SPDX-FileCopyrightText: 2024 Lido +// SPDX-License-Identifier: GPL-3.0 + +pragma solidity 0.8.10; + +import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; +import {SafeERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; +import {Address} from "@openzeppelin/contracts/utils/Address.sol"; +import {IL1ERC20Bridge} from "./interfaces/IL1ERC20Bridge.sol"; +import {IL2ERC20Bridge} from "./interfaces/IL2ERC20Bridge.sol"; +import {IERC20Bridged} from "../token/ERC20Bridged.sol"; +import {ITokenRateUpdatable} from "../optimism/interfaces/ITokenRateUpdatable.sol"; +import {ERC20RebasableBridged} from "../token/ERC20RebasableBridged.sol"; +import {BridgingManager} from "../BridgingManager.sol"; +import {RebasableAndNonRebasableTokens} from "./RebasableAndNonRebasableTokens.sol"; +import {CrossDomainEnabled} from "./CrossDomainEnabled.sol"; +import {DepositDataCodec} from "../lib/DepositDataCodec.sol"; +import {Versioned} from "../utils/Versioned.sol"; + +/// @author psirex, kovalgek +/// @notice The L2 token bridge works with the L1 token bridge to enable ERC20 token bridging +/// between L1 and L2. It acts as a minter for new tokens when it hears about +/// deposits into the L1 token bridge. It also acts as a burner of the tokens +/// intended for withdrawal, informing the L1 bridge to release L1 funds. Additionally, adds +/// the methods for bridging management: enabling and disabling withdrawals/deposits +contract L2ERC20ExtendedTokensBridge is + IL2ERC20Bridge, + BridgingManager, + RebasableAndNonRebasableTokens, + CrossDomainEnabled, + Versioned +{ + using SafeERC20 for IERC20; + + address private immutable L1_TOKEN_BRIDGE; + + /// @param messenger_ L2 messenger address being used for cross-chain communications + /// @param l1TokenBridge_ Address of the corresponding L1 bridge + /// @param l1TokenNonRebasable_ Address of the bridged token in the L1 chain + /// @param l1TokenRebasable_ Address of the bridged token in the L1 chain + /// @param l2TokenNonRebasable_ Address of the token minted on the L2 chain when token bridged + /// @param l2TokenRebasable_ Address of the token minted on the L2 chain when token bridged + constructor( + address messenger_, + address l1TokenBridge_, + address l1TokenNonRebasable_, + address l1TokenRebasable_, + address l2TokenNonRebasable_, + address l2TokenRebasable_ + ) CrossDomainEnabled(messenger_) RebasableAndNonRebasableTokens ( + l1TokenNonRebasable_, + l1TokenRebasable_, + l2TokenNonRebasable_, + l2TokenRebasable_ + ) { + if (l1TokenBridge_ == address(0)) { + revert ErrorZeroAddressL1Bridge(); + } + L1_TOKEN_BRIDGE = l1TokenBridge_; + } + + /// @notice Initializes the contract from scratch. + /// @param admin_ Address of the account to grant the DEFAULT_ADMIN_ROLE + function initialize(address admin_) external { + _initializeExtendedTokensBridge(); + _initializeBridgingManager(admin_); + } + + /// @notice A function to finalize upgrade to v2 (from v1). + function finalizeUpgrade_v2() external { + if (!_isBridgingManagerInitialized()) { + revert ErrorBridgingManagerIsNotInitialized(); + } + _initializeExtendedTokensBridge(); + } + + /// @inheritdoc IL2ERC20Bridge + function l1TokenBridge() external view returns (address) { + return L1_TOKEN_BRIDGE; + } + + /// @inheritdoc IL2ERC20Bridge + function withdraw( + address l2Token_, + uint256 amount_, + uint32 l1Gas_, + bytes calldata data_ + ) external + whenWithdrawalsEnabled + onlySupportedL2Token(l2Token_) + { + if (Address.isContract(msg.sender)) { + revert ErrorSenderNotEOA(); + } + _withdrawTo(l2Token_, msg.sender, msg.sender, amount_, l1Gas_, data_); + emit WithdrawalInitiated(_getL1Token(l2Token_), l2Token_, msg.sender, msg.sender, amount_, data_); + } + + /// @inheritdoc IL2ERC20Bridge + function withdrawTo( + address l2Token_, + address to_, + uint256 amount_, + uint32 l1Gas_, + bytes calldata data_ + ) external + whenWithdrawalsEnabled + onlyNonZeroAccount(to_) + onlySupportedL2Token(l2Token_) + { + _withdrawTo(l2Token_, msg.sender, to_, amount_, l1Gas_, data_); + emit WithdrawalInitiated(_getL1Token(l2Token_), l2Token_, msg.sender, to_, amount_, data_); + } + + /// @inheritdoc IL2ERC20Bridge + function finalizeDeposit( + address l1Token_, + address l2Token_, + address from_, + address to_, + uint256 amount_, + bytes calldata data_ + ) + external + whenDepositsEnabled + onlyFromCrossDomainAccount(L1_TOKEN_BRIDGE) + onlySupportedL1L2TokensPair(l1Token_, l2Token_) + { + DepositDataCodec.DepositData memory depositData = DepositDataCodec.decodeDepositData(data_); + ITokenRateUpdatable tokenRateOracle = ERC20RebasableBridged(L2_TOKEN_REBASABLE).TOKEN_RATE_ORACLE(); + tokenRateOracle.updateRate(depositData.rate, depositData.timestamp); + + uint256 depositedL2TokenAmount = _mintTokens(l2Token_, to_, amount_); + emit DepositFinalized(l1Token_, l2Token_, from_, to_, depositedL2TokenAmount, depositData.data); + } + + function _initializeExtendedTokensBridge() internal { + _initializeContractVersionTo(2); + // used for `bridgeWrap` call to succeed in the `_mintTokens` method + IERC20(L2_TOKEN_NON_REBASABLE).safeIncreaseAllowance(L2_TOKEN_REBASABLE, type(uint256).max); + } + + /// @notice Performs the logic for withdrawals by burning the token and informing + /// the L1 token Gateway of the withdrawal. This function does not allow sending to token addresses. + /// L1_TOKEN_REBASABLE does not allow transfers to itself. Additionally, sending funds to + /// L1_TOKEN_NON_REBASABLE would lock these funds permanently, as it is non-upgradeable. + /// @param l2Token_ Address of L2 token where withdrawal was initiated. + /// @param from_ Account to pull the withdrawal from on L2 + /// @param to_ Account to give the withdrawal to on L1. + /// @param amount_ Amount of the token to withdraw + /// @param l1Gas_ Minimum gas limit to use for the transaction. + /// @param data_ Optional data to forward to L1. This data is provided + /// solely as a convenience for external contracts. Aside from enforcing a maximum + /// length, these contracts provide no guarantees about its content + function _withdrawTo( + address l2Token_, + address from_, + address to_, + uint256 amount_, + uint32 l1Gas_, + bytes calldata data_ + ) internal { + if (to_ == L1_TOKEN_REBASABLE || to_ == L1_TOKEN_NON_REBASABLE) { + revert ErrorTransferToL1TokenContract(); + } + + uint256 nonRebasableAmountToWithdraw = _burnTokens(l2Token_, from_, amount_); + + bytes memory message = abi.encodeWithSelector( + IL1ERC20Bridge.finalizeERC20Withdrawal.selector, + _getL1Token(l2Token_), l2Token_, from_, to_, nonRebasableAmountToWithdraw, data_ + ); + sendCrossDomainMessage(L1_TOKEN_BRIDGE, l1Gas_, message); + } + + /// @notice Mints tokens, wraps if needed and returns amount of minted tokens. + /// @param l2Token_ Address of L2 token for which deposit is finalizing. + /// @param to_ Account that token mints for. + /// @param nonRebasableTokenAmount_ Amount of non-rebasable token. + /// @return returns amount of minted tokens. + function _mintTokens( + address l2Token_, + address to_, + uint256 nonRebasableTokenAmount_ + ) internal returns (uint256) { + if (nonRebasableTokenAmount_ == 0) { + return 0; + } + if (l2Token_ == L2_TOKEN_REBASABLE) { + IERC20Bridged(L2_TOKEN_NON_REBASABLE).bridgeMint(address(this), nonRebasableTokenAmount_); + return ERC20RebasableBridged(l2Token_).bridgeWrap(to_, nonRebasableTokenAmount_); + } + IERC20Bridged(l2Token_).bridgeMint(to_, nonRebasableTokenAmount_); + return nonRebasableTokenAmount_; + } + + /// @notice Unwraps if needed, burns tokens and returns amount of non-rebasable token to withdraw. + /// @param l2Token_ Address of L2 token where withdrawal was initiated. + /// @param from_ Account which tokens are burns. + /// @param amount_ Amount of token to burn. + /// @return returns amount of non-rebasable token to withdraw. + function _burnTokens( + address l2Token_, + address from_, + uint256 amount_ + ) internal returns (uint256) { + if (amount_ == 0) { + return 0; + } + uint256 nonRebasableTokenAmount = amount_; + if (l2Token_ == L2_TOKEN_REBASABLE) { + nonRebasableTokenAmount = ERC20RebasableBridged(L2_TOKEN_REBASABLE).getSharesByTokens(amount_); + if (nonRebasableTokenAmount != 0) { + ERC20RebasableBridged(L2_TOKEN_REBASABLE).bridgeUnwrap(from_, amount_); + IERC20Bridged(L2_TOKEN_NON_REBASABLE).bridgeBurn(from_, nonRebasableTokenAmount); + } + return nonRebasableTokenAmount; + } + IERC20Bridged(L2_TOKEN_NON_REBASABLE).bridgeBurn(from_, nonRebasableTokenAmount); + return nonRebasableTokenAmount; + } + + error ErrorSenderNotEOA(); + error ErrorZeroAddressL1Bridge(); + error ErrorTransferToL1TokenContract(); +} diff --git a/contracts/optimism/L2ERC20TokenBridge.sol b/contracts/optimism/L2ERC20TokenBridge.sol deleted file mode 100644 index 1b1870e0..00000000 --- a/contracts/optimism/L2ERC20TokenBridge.sol +++ /dev/null @@ -1,114 +0,0 @@ -// SPDX-FileCopyrightText: 2022 Lido -// SPDX-License-Identifier: GPL-3.0 - -pragma solidity 0.8.10; - -import {IL1ERC20Bridge} from "./interfaces/IL1ERC20Bridge.sol"; -import {IL2ERC20Bridge} from "./interfaces/IL2ERC20Bridge.sol"; -import {IERC20Bridged} from "../token/interfaces/IERC20Bridged.sol"; - -import {BridgingManager} from "../BridgingManager.sol"; -import {BridgeableTokens} from "../BridgeableTokens.sol"; -import {CrossDomainEnabled} from "./CrossDomainEnabled.sol"; - -/// @author psirex -/// @notice The L2 token bridge works with the L1 token bridge to enable ERC20 token bridging -/// between L1 and L2. It acts as a minter for new tokens when it hears about -/// deposits into the L1 token bridge. It also acts as a burner of the tokens -/// intended for withdrawal, informing the L1 bridge to release L1 funds. Additionally, adds -/// the methods for bridging management: enabling and disabling withdrawals/deposits -contract L2ERC20TokenBridge is - IL2ERC20Bridge, - BridgingManager, - BridgeableTokens, - CrossDomainEnabled -{ - /// @inheritdoc IL2ERC20Bridge - address public immutable l1TokenBridge; - - /// @param messenger_ L2 messenger address being used for cross-chain communications - /// @param l1TokenBridge_ Address of the corresponding L1 bridge - /// @param l1Token_ Address of the bridged token in the L1 chain - /// @param l2Token_ Address of the token minted on the L2 chain when token bridged - constructor( - address messenger_, - address l1TokenBridge_, - address l1Token_, - address l2Token_ - ) CrossDomainEnabled(messenger_) BridgeableTokens(l1Token_, l2Token_) { - l1TokenBridge = l1TokenBridge_; - } - - /// @inheritdoc IL2ERC20Bridge - function withdraw( - address l2Token_, - uint256 amount_, - uint32 l1Gas_, - bytes calldata data_ - ) external whenWithdrawalsEnabled onlySupportedL2Token(l2Token_) { - _initiateWithdrawal(msg.sender, msg.sender, amount_, l1Gas_, data_); - } - - /// @inheritdoc IL2ERC20Bridge - function withdrawTo( - address l2Token_, - address to_, - uint256 amount_, - uint32 l1Gas_, - bytes calldata data_ - ) external whenWithdrawalsEnabled onlySupportedL2Token(l2Token_) { - _initiateWithdrawal(msg.sender, to_, amount_, l1Gas_, data_); - } - - /// @inheritdoc IL2ERC20Bridge - function finalizeDeposit( - address l1Token_, - address l2Token_, - address from_, - address to_, - uint256 amount_, - bytes calldata data_ - ) - external - whenDepositsEnabled - onlySupportedL1Token(l1Token_) - onlySupportedL2Token(l2Token_) - onlyFromCrossDomainAccount(l1TokenBridge) - { - IERC20Bridged(l2Token_).bridgeMint(to_, amount_); - emit DepositFinalized(l1Token_, l2Token_, from_, to_, amount_, data_); - } - - /// @notice Performs the logic for withdrawals by burning the token and informing - /// the L1 token Gateway of the withdrawal - /// @param from_ Account to pull the withdrawal from on L2 - /// @param to_ Account to give the withdrawal to on L1 - /// @param amount_ Amount of the token to withdraw - /// @param l1Gas_ Unused, but included for potential forward compatibility considerations - /// @param data_ Optional data to forward to L1. This data is provided - /// solely as a convenience for external contracts. Aside from enforcing a maximum - /// length, these contracts provide no guarantees about its content - function _initiateWithdrawal( - address from_, - address to_, - uint256 amount_, - uint32 l1Gas_, - bytes calldata data_ - ) internal { - IERC20Bridged(l2Token).bridgeBurn(from_, amount_); - - bytes memory message = abi.encodeWithSelector( - IL1ERC20Bridge.finalizeERC20Withdrawal.selector, - l1Token, - l2Token, - from_, - to_, - amount_, - data_ - ); - - sendCrossDomainMessage(l1TokenBridge, l1Gas_, message); - - emit WithdrawalInitiated(l1Token, l2Token, from_, to_, amount_, data_); - } -} diff --git a/contracts/optimism/OpStackTokenRatePusher.sol b/contracts/optimism/OpStackTokenRatePusher.sol new file mode 100644 index 00000000..412f61b8 --- /dev/null +++ b/contracts/optimism/OpStackTokenRatePusher.sol @@ -0,0 +1,63 @@ +// SPDX-FileCopyrightText: 2024 Lido +// SPDX-License-Identifier: GPL-3.0 + +pragma solidity 0.8.10; + +import {ERC165} from "@openzeppelin/contracts/utils/introspection/ERC165.sol"; +import {CrossDomainEnabled} from "./CrossDomainEnabled.sol"; +import {ITokenRatePusher} from "../lido/interfaces/ITokenRatePusher.sol"; +import {ITokenRateUpdatable} from "../optimism/interfaces/ITokenRateUpdatable.sol"; +import {TokenRateAndUpdateTimestampProvider} from "./TokenRateAndUpdateTimestampProvider.sol"; + +/// @author kovalgek +/// @notice Pushes token rate to L2 Oracle. +contract OpStackTokenRatePusher is ITokenRatePusher, CrossDomainEnabled, TokenRateAndUpdateTimestampProvider, ERC165 { + + /// @notice Oracle address on L2 for receiving token rate. + address public immutable L2_TOKEN_RATE_ORACLE; + + /// @notice Gas limit for L2 required to finish pushing token rate on L2 side. + /// Client pays for gas on L2 by burning it on L1. + /// Depends linearly on deposit data length and gas used for finalizing deposit on L2. + /// Formula to find value: + /// (gas cost of L2Bridge.finalizeDeposit() + OptimismPortal.minimumGasLimit(depositData.length)) * 1.5 + uint32 public immutable L2_GAS_LIMIT_FOR_PUSHING_TOKEN_RATE; + + /// @param messenger_ L1 messenger address being used for cross-chain communications. + /// @param wstETH_ L1 token bridge address. + /// @param accountingOracle_ Address of the AccountingOracle instance to retrieve rate update timestamps. + /// @param tokenRateOracle_ Oracle address on L2 for receiving token rate. + /// @param l2GasLimitForPushingTokenRate_ Gas limit required to complete pushing token rate on L2. + constructor( + address messenger_, + address wstETH_, + address accountingOracle_, + address tokenRateOracle_, + uint32 l2GasLimitForPushingTokenRate_ + ) CrossDomainEnabled(messenger_) TokenRateAndUpdateTimestampProvider(wstETH_, accountingOracle_) { + if (tokenRateOracle_ == address(0)) { + revert ErrorZeroAddressTokenRateOracle(); + } + L2_TOKEN_RATE_ORACLE = tokenRateOracle_; + L2_GAS_LIMIT_FOR_PUSHING_TOKEN_RATE = l2GasLimitForPushingTokenRate_; + } + + /// @inheritdoc ITokenRatePusher + function pushTokenRate() external { + (uint256 rate, uint256 updateTimestamp) = _getTokenRateAndUpdateTimestamp(); + + bytes memory message = abi.encodeWithSelector(ITokenRateUpdatable.updateRate.selector, rate, updateTimestamp); + + sendCrossDomainMessage(L2_TOKEN_RATE_ORACLE, L2_GAS_LIMIT_FOR_PUSHING_TOKEN_RATE, message); + } + + /// @inheritdoc ERC165 + function supportsInterface(bytes4 _interfaceId) public view virtual override returns (bool) { + return ( + _interfaceId == type(ITokenRatePusher).interfaceId + || super.supportsInterface(_interfaceId) + ); + } + + error ErrorZeroAddressTokenRateOracle(); +} diff --git a/contracts/optimism/README.md b/contracts/optimism/README.md index 598f7b99..ff229220 100644 --- a/contracts/optimism/README.md +++ b/contracts/optimism/README.md @@ -39,10 +39,10 @@ A high-level overview of the proposed solution might be found in the below diagr ![](https://i.imgur.com/yAF9gbl.png) - [**`BridgingManager`**](#BridgingManager) - contains administrative methods to retrieve and control the state of the bridging process. -- [**`BridgeableTokens`**](#BridgeableTokens) - contains the logic for validation of tokens used in the bridging process. +- [**`RebasableAndNonRebasableTokens`**](#RebasableAndNonRebasableTokens) - contains the logic for validation of tokens used in the bridging process. - [**`CrossDomainEnabled`**](#CrossDomainEnabled) - helper contract for contracts performing cross-domain communications -- [**`L1ERC20TokenBridge`**](#L1ERC20TokenBridge) - Ethereum's counterpart of the bridge to bridge registered ERC20 compatible tokens between Ethereum and Optimism chains. -- [**`L2ERC20TokenBridge`**](#L2ERC20TokenBridge) - Optimism's counterpart of the bridge to bridge registered ERC20 compatible tokens between Ethereum and Optimism chains +- [**`L1ERC20ExtendedTokensBridge`**](#L1ERC20ExtendedTokensBridge) - Ethereum's counterpart of the bridge to bridge registered ERC20 compatible tokens between Ethereum and Optimism chains. +- [**`L2ERC20ExtendedTokensBridge`**](#L2ERC20ExtendedTokensBridge) - Optimism's counterpart of the bridge to bridge registered ERC20 compatible tokens between Ethereum and Optimism chains - [**`ERC20Bridged`**](#ERC20Bridged) - an implementation of the `ERC20` token with administrative methods to mint and burn tokens. - [**`OssifiableProxy`**](#OssifiableProxy) - the ERC1967 proxy with extra admin functionality. @@ -165,7 +165,7 @@ Validates that deposits are enabled. Reverts with the error `ErrorDepositsDisabl Validates that withdrawals are enabled. Reverts with the error `ErrorWithdrawalsDisabled()` when called on contract with disabled withdrawals. -## BridgeableTokens +## RebasableAndNonRebasableTokens Contains the logic for validation of tokens used in the bridging process @@ -178,9 +178,9 @@ The contract keeps the addresses of L1/L2 tokens used in the bridging: ### Modifiers -#### `onlySupportedL1Token(address l1Token_)` +#### `onlySupportedL1L2TokensPair(address l1Token_, address l2Token_)` -Validates that passed `l1Token_` is supported by the bridge. Reverts with error `ErrorUnsupportedL1Token()` when addresses mismatch. +Validates that passed `l1Token_` and `l2Token_` are supported by the bridge. Reverts with error `ErrorUnsupportedL1L2TokensPair()` when addresses mismatch. #### `onlySupportedL2Token(address l2Token_)` @@ -216,10 +216,10 @@ Sends a message to an account on another domain. Enforces that the modified function is only callable by a specific cross-domain account. -## `L1ERC20TokenBridge` +## `L1ERC20ExtendedTokensBridge` **Implements:** [`IL1ERC20Bridge`](https://github.com/ethereum-optimism/optimism/blob/develop/packages/contracts/contracts/L1/messaging/IL1ERC20Bridge.sol) -**Inherits:** [`BridgingManager`](#BridgingManager) [`BridgeableTokens`](#BridgeableTokens) [`CrossDomainEnabled`](#CrossDomainEnabled) +**Inherits:** [`BridgingManager`](#BridgingManager) [`RebasableAndNonRebasableTokens`](#RebasableAndNonRebasableTokens) [`CrossDomainEnabled`](#CrossDomainEnabled) The L1 Standard bridge is a contract that locks bridged token on L1 side, send deposit messages on L2 side and finalize token withdrawals from L2. @@ -300,10 +300,10 @@ Complete a withdrawal from L2 to L1, and credit funds to the recipient's balance Performs the logic for deposits by informing the L2 Deposited Token contract of the deposit and calling safeTransferFrom to lock the L1 funds. -## `L2ERC20TokenBridge` +## `L2ERC20ExtendedTokensBridge` **Implements:** [`IL2ERC20Bridge`](https://github.com/ethereum-optimism/optimism/blob/develop/packages/contracts/contracts/L2/messaging/IL2ERC20Bridge.sol) -**Extends** [`BridgingManager`](#BridgingManager) [`BridgeableTokens`](#BridgeableTokens) [`CrossDomainEnabled`](#CrossDomainEnabled) +**Extends** [`BridgingManager`](#BridgingManager) [`RebasableAndNonRebasableTokens`](#RebasableAndNonRebasableTokens) [`CrossDomainEnabled`](#CrossDomainEnabled) The L2 token bridge is a contract that works with the L1 Token bridge to enable ERC20 token bridging between L1 and L2. This contract acts as a minter for new tokens when it hears about deposits into the L1 token bridge. This contract also acts as a burner of the tokens intended for withdrawal, informing the L1 bridge to release L1 funds. @@ -512,39 +512,9 @@ Returns a `bool` value indicating whether the operation succeeded. Transfers `amount` of token from the `from_` account to `to_` using the allowance mechanism. `amount_` is then deducted from the caller's allowance. Returns a `bool` value indicating whether the operation succeed. -#### `increaseAllowance(address,uint256)` - -> **Visibility:**     `external` -> -> **Returns**        `(bool)` -> -> **Arguments:** -> -> - **`spender_`** - an address of the tokens spender -> - **`addedValue_`** - a number to increase allowance -> -> **Emits:** `Approval(address indexed owner, address indexed spender, uint256 value)` - -Atomically increases the allowance granted to `spender` by the caller. Returns a `bool` value indicating whether the operation succeed. - -#### `decreaseAllowance(address,uint256)` - -> **Visibility:**     `external` -> -> **Returns**        `(bool)` -> -> **Arguments:** -> -> - **`spender_`** - an address of the tokens spender -> - **`subtractedValue_`** - a number to decrease allowance -> -> **Emits:** `Approval(address indexed owner, address indexed spender, uint256 value)` - -Atomically decreases the allowance granted to `spender` by the caller. Returns a `bool` value indicating whether the operation succeed. - ## `ERC20Bridged` -**Implements:** [`IERC20Bridged`](https://github.com/lidofinance/lido-l2/blob/main/contracts/token/interfaces/IERC20Bridged.sol) +**Implements:** [`IERC20Bridged`](https://github.com/lidofinance/lido-l2/blob/main/contracts/token/ERC20Bridged.sol) **Inherits:** [`ERC20Metadata`](#ERC20Metadata) [`ERC20Core`](#ERC20CoreLogic) Inherits the `ERC20` default functionality that allows the bridge to mint and burn tokens. @@ -691,7 +661,7 @@ Validates that that proxy is not ossified and that method is called by the admin ## Deployment Process -To reduce the gas costs for users, contracts `L1ERC20TokenBridge`, `L2ERC20TokenBridge`, and `ERC20Bridged` contracts use immutable variables as much as possible. But some of those variables are cross-referred. For example, `L1ERC20TokenBridge` has reference to `L2ERC20TokenBridge` and vice versa. As we use proxies, we can deploy proxies at first and stub the implementation with an empty contract. Then deploy actual implementations with addresses of deployed proxies and then upgrade proxies with new implementations. For stub, the following contract might be used: +To reduce the gas costs for users, contracts `L1ERC20ExtendedTokensBridge`, `L2ERC20ExtendedTokensBridge`, and `ERC20Bridged` contracts use immutable variables as much as possible. But some of those variables are cross-referred. For example, `L1ERC20ExtendedTokensBridge` has reference to `L2ERC20ExtendedTokensBridge` and vice versa. As we use proxies, we can deploy proxies at first and stub the implementation with an empty contract. Then deploy actual implementations with addresses of deployed proxies and then upgrade proxies with new implementations. For stub, the following contract might be used: ``` pragma solidity ^0.8.0; @@ -706,7 +676,7 @@ As an additional link in the tokens flow chain, the Optimism protocol and bridge ## Minting of uncollateralized L2 token -Such an attack might happen if an attacker obtains the right to call `L2ERC20TokenBridge.finalizeDeposit()` directly. In such a scenario, an attacker can mint uncollaterized tokens on L2 and initiate withdrawal later. +Such an attack might happen if an attacker obtains the right to call `L2ERC20ExtendedTokensBridge.finalizeDeposit()` directly. In such a scenario, an attacker can mint uncollaterized tokens on L2 and initiate withdrawal later. The best way to detect such an attack is an offchain monitoring of the minting and depositing/withdrawal events. Based on such events might be tracked following stats: diff --git a/contracts/optimism/RebasableAndNonRebasableTokens.sol b/contracts/optimism/RebasableAndNonRebasableTokens.sol new file mode 100644 index 00000000..bc4cfcc9 --- /dev/null +++ b/contracts/optimism/RebasableAndNonRebasableTokens.sol @@ -0,0 +1,93 @@ +// SPDX-FileCopyrightText: 2024 Lido +// SPDX-License-Identifier: GPL-3.0 + +pragma solidity 0.8.10; + +/// @author psirex, kovalgek +/// @notice Contains the logic for validation of tokens used in the bridging process +contract RebasableAndNonRebasableTokens { + + /// @notice Address of the bridged non rebasable token in the L1 chain + address public immutable L1_TOKEN_NON_REBASABLE; + + /// @notice Address of the bridged rebasable token in the L1 chain + address public immutable L1_TOKEN_REBASABLE; + + /// @notice Address of the non rebasable token minted on the L2 chain when token bridged + address public immutable L2_TOKEN_NON_REBASABLE; + + /// @notice Address of the rebasable token minted on the L2 chain when token bridged + address public immutable L2_TOKEN_REBASABLE; + + /// @param l1TokenNonRebasable_ Address of the bridged non rebasable token in the L1 chain + /// @param l1TokenRebasable_ Address of the bridged rebasable token in the L1 chain + /// @param l2TokenNonRebasable_ Address of the non rebasable token minted on the L2 chain when token bridged + /// @param l2TokenRebasable_ Address of the rebasable token minted on the L2 chain when token bridged + constructor( + address l1TokenNonRebasable_, + address l1TokenRebasable_, + address l2TokenNonRebasable_, + address l2TokenRebasable_ + ) { + if (l1TokenNonRebasable_ == address(0)) { + revert ErrorZeroAddressL1TokenNonRebasable(); + } + if (l1TokenRebasable_ == address(0)) { + revert ErrorZeroAddressL1TokenRebasable(); + } + if (l2TokenNonRebasable_ == address(0)) { + revert ErrorZeroAddressL2TokenNonRebasable(); + } + if (l2TokenRebasable_ == address(0)) { + revert ErrorZeroAddressL2TokenRebasable(); + } + L1_TOKEN_NON_REBASABLE = l1TokenNonRebasable_; + L1_TOKEN_REBASABLE = l1TokenRebasable_; + L2_TOKEN_NON_REBASABLE = l2TokenNonRebasable_; + L2_TOKEN_REBASABLE = l2TokenRebasable_; + } + + function _isSupportedL1L2TokensPair(address l1Token_, address l2Token_) internal view returns (bool) { + bool isNonRebasablePair = l1Token_ == L1_TOKEN_NON_REBASABLE && l2Token_ == L2_TOKEN_NON_REBASABLE; + bool isRebasablePair = l1Token_ == L1_TOKEN_REBASABLE && l2Token_ == L2_TOKEN_REBASABLE; + return isNonRebasablePair || isRebasablePair; + } + + function _getL1Token(address l2Token_) internal view returns (address) { + if (l2Token_ == L2_TOKEN_NON_REBASABLE) { return L1_TOKEN_NON_REBASABLE; } + if (l2Token_ == L2_TOKEN_REBASABLE) { return L1_TOKEN_REBASABLE; } + revert ErrorUnsupportedL2Token(l2Token_); + } + + /// @dev Validates that passed l1Token_ and l2Token_ tokens pair is supported by the bridge. + modifier onlySupportedL1L2TokensPair(address l1Token_, address l2Token_) { + if (!_isSupportedL1L2TokensPair(l1Token_, l2Token_)) { + revert ErrorUnsupportedL1L2TokensPair(l1Token_, l2Token_); + } + _; + } + + /// @dev Validates that passed l2Token_ is supported by the bridge + modifier onlySupportedL2Token(address l2Token_) { + if (l2Token_ != L2_TOKEN_NON_REBASABLE && l2Token_ != L2_TOKEN_REBASABLE) { + revert ErrorUnsupportedL2Token(l2Token_); + } + _; + } + + /// @dev validates that account_ is not zero address + modifier onlyNonZeroAccount(address account_) { + if (account_ == address(0)) { + revert ErrorAccountIsZeroAddress(); + } + _; + } + + error ErrorZeroAddressL1TokenNonRebasable(); + error ErrorZeroAddressL1TokenRebasable(); + error ErrorZeroAddressL2TokenNonRebasable(); + error ErrorZeroAddressL2TokenRebasable(); + error ErrorUnsupportedL2Token(address l2Token); + error ErrorUnsupportedL1L2TokensPair(address l1Token, address l2Token); + error ErrorAccountIsZeroAddress(); +} diff --git a/contracts/optimism/TokenRateAndUpdateTimestampProvider.sol b/contracts/optimism/TokenRateAndUpdateTimestampProvider.sol new file mode 100644 index 00000000..2ffba15c --- /dev/null +++ b/contracts/optimism/TokenRateAndUpdateTimestampProvider.sol @@ -0,0 +1,69 @@ +// SPDX-FileCopyrightText: 2024 Lido +// SPDX-License-Identifier: GPL-3.0 + +pragma solidity 0.8.10; + +/// @author dzhon +/// @notice A subset of AccountingOracle interface of core LIDO protocol. +interface IAccountingOracle { + /// @notice Get timestamp of the Consensus Layer genesis + function GENESIS_TIME() external view returns (uint256); + /// @notice Get seconds per single Consensus Layer slot + function SECONDS_PER_SLOT() external view returns (uint256); + /// @notice Returns the last reference slot for which processing of the report was started + function getLastProcessingRefSlot() external view returns (uint256); +} + +/// @author kovalgek +/// @notice A subset of wstETH token interface of core LIDO protocol. +interface IERC20WstETH { + /// @notice Get amount of stETH for a given amount of wstETH + /// @param wstETHAmount_ amount of wstETH + /// @return Amount of stETH for a given wstETH amount + function getStETHByWstETH(uint256 wstETHAmount_) external view returns (uint256); +} + +/// @author kovalgek +/// @notice Provides token rate and update timestamp. +abstract contract TokenRateAndUpdateTimestampProvider { + + /// @notice Non-rebasable token of Core Lido procotol. + address public immutable WSTETH; + + /// @notice Address of the AccountingOracle instance + address public immutable ACCOUNTING_ORACLE; + + /// @notice Timetamp of the Consensus Layer genesis + uint256 public immutable GENESIS_TIME; + + /// @notice Seconds per single Consensus Layer slot + uint256 public immutable SECONDS_PER_SLOT; + + /// @notice Token rate decimals to push + uint256 public constant TOKEN_RATE_DECIMALS = 27; + + constructor(address wstETH_, address accountingOracle_) { + if (wstETH_ == address(0)) { + revert ErrorZeroAddressWstETH(); + } + if (accountingOracle_ == address(0)) { + revert ErrorZeroAddressAccountingOracle(); + } + WSTETH = wstETH_; + ACCOUNTING_ORACLE = accountingOracle_; + GENESIS_TIME = IAccountingOracle(ACCOUNTING_ORACLE).GENESIS_TIME(); + SECONDS_PER_SLOT = IAccountingOracle(ACCOUNTING_ORACLE).SECONDS_PER_SLOT(); + } + + function _getTokenRateAndUpdateTimestamp() internal view returns (uint256 rate, uint256 updateTimestamp) { + rate = IERC20WstETH(WSTETH).getStETHByWstETH(10 ** TOKEN_RATE_DECIMALS); + + /// @dev github.com/ethereum/consensus-specs/blob/dev/specs/bellatrix/beacon-chain.md#compute_timestamp_at_slot + updateTimestamp = GENESIS_TIME + SECONDS_PER_SLOT * IAccountingOracle( + ACCOUNTING_ORACLE + ).getLastProcessingRefSlot(); + } + + error ErrorZeroAddressWstETH(); + error ErrorZeroAddressAccountingOracle(); +} diff --git a/contracts/optimism/TokenRateOracle.sol b/contracts/optimism/TokenRateOracle.sol new file mode 100644 index 00000000..be73b316 --- /dev/null +++ b/contracts/optimism/TokenRateOracle.sol @@ -0,0 +1,431 @@ +// SPDX-FileCopyrightText: 2024 Lido +// SPDX-License-Identifier: GPL-3.0 + +pragma solidity 0.8.10; + +import {ITokenRateUpdatable} from "./interfaces/ITokenRateUpdatable.sol"; +import {IChainlinkAggregatorInterface} from "./interfaces/IChainlinkAggregatorInterface.sol"; +import {CrossDomainEnabled} from "./CrossDomainEnabled.sol"; +import {Versioned} from "../utils/Versioned.sol"; +import {Math} from "@openzeppelin/contracts/utils/math/Math.sol"; +import {AccessControl} from "@openzeppelin/contracts/access/AccessControl.sol"; +import {UnstructuredStorage} from "../lib/UnstructuredStorage.sol"; + +interface ITokenRateOracle is ITokenRateUpdatable, IChainlinkAggregatorInterface {} + +/// @author kovalgek +/// @notice Oracle for storing and providing token rate. +/// NB: Cross-chain apps and CEXes should fetch the token rate specific to the chain for deposits/withdrawals +/// and compare against the token rate on L1 being an ultimate source of truth; +/// If the L1 rate differs, it can be pushed permissionlessly via OpStackTokenRatePusher. +/// @dev Token rate updates can be delivered from two sources: L1 token rate pusher and L2 bridge. +contract TokenRateOracle is ITokenRateOracle, CrossDomainEnabled, AccessControl, Versioned { + + using UnstructuredStorage for bytes32; + + /// @dev Used to store historical data of rate and times. + struct TokenRateData { + /// @notice wstETH/stETH token rate. + uint128 tokenRate; + /// @notice last time when token rate was updated on L1. + uint64 rateUpdatedL1Timestamp; + /// @notice last time when token rate was received on L2. + uint64 rateReceivedL2Timestamp; + } // occupies a single slot + + /// @notice A bridge which can update oracle. + address public immutable L2_ERC20_TOKEN_BRIDGE; + + /// @notice An address of account on L1 that can update token rate. + address public immutable L1_TOKEN_RATE_PUSHER; + + /// @notice A time period when token rate can be considered outdated. + uint256 public immutable TOKEN_RATE_OUTDATED_DELAY; + + /// @notice A time difference between received l1Timestamp and L2 block.timestamp + /// when token rate can be considered outdated. + uint256 public immutable MAX_ALLOWED_L2_TO_L1_CLOCK_LAG; + + /// @notice Allowed token rate deviation per day in basic points. + uint256 public immutable MAX_ALLOWED_TOKEN_RATE_DEVIATION_PER_DAY_BP; + + /// @notice The maximum allowed time difference between the current time and the last received + /// token rate update that can be set during a pause. This is required to limit the pause role + /// and mitigate potential economic attacks. + /// See the 'pauseTokenRateUpdates()' method + uint256 public immutable OLDEST_RATE_ALLOWED_IN_PAUSE_TIME_SPAN; + + /// @notice The maximum delta time that is allowed between two L1 timestamps of token rate updates. + uint256 public immutable MAX_ALLOWED_TIME_BETWEEN_TOKEN_RATE_UPDATES; + + /// @notice Decimals of the oracle response. + uint8 public constant DECIMALS = 27; + + /// @notice Max sane token rate value. + uint256 public constant MAX_SANE_TOKEN_RATE = 10 ** (DECIMALS + 2); + + /// @notice Min sane token rate value. + uint256 public constant MIN_SANE_TOKEN_RATE = 10 ** (DECIMALS - 2); + + /// @dev Role granting the permission to pause updating rate. + bytes32 public constant RATE_UPDATE_DISABLER_ROLE = keccak256("TokenRateOracle.RATE_UPDATE_DISABLER_ROLE"); + + /// @dev Role granting the permission to resume updating rate. + bytes32 public constant RATE_UPDATE_ENABLER_ROLE = keccak256("TokenRafteOracle.RATE_UPDATE_ENABLER_ROLE"); + + /// @notice Basic point scale. + uint256 private constant BASIS_POINT_SCALE = 1e4; + + /// @notice Number of seconds in one day. + uint256 private constant ONE_DAY_SECONDS = 86400; + + /// @notice Flag to pause token rate updates slot position. + bytes32 private constant PAUSE_TOKEN_RATE_UPDATES_SLOT = keccak256("TokenRateOracle.PAUSE_TOKEN_RATE_UPDATES_SLOT"); + + /// @notice Token rates array slot position. + bytes32 private constant TOKEN_RATES_DATA_SLOT = keccak256("TokenRateOracle.TOKEN_RATES_DATA_SLOT"); + + /// @param messenger_ L2 messenger address being used for cross-chain communications + /// @param l2ERC20TokenBridge_ the bridge address that has a right to updates oracle. + /// @param l1TokenRatePusher_ An address of account on L1 that can update token rate. + /// @param tokenRateOutdatedDelay_ time period when token rate can be considered outdated. + /// @param maxAllowedL2ToL1ClockLag_ A time difference between received l1Timestamp and L2 block.timestamp + /// when token rate can be considered outdated. + /// @param maxAllowedTokenRateDeviationPerDayBp_ Allowed token rate deviation per day in basic points. + /// Can't be bigger than BASIS_POINT_SCALE. + /// @param oldestRateAllowedInPauseTimeSpan_ Maximum allowed time difference between the current time + /// and the last received token rate update that can be set during a pause. + /// @param maxAllowedTimeBetweenTokenRateUpdates_ the maximum delta time that is allowed between two + /// L1 timestamps of token rate updates. + constructor( + address messenger_, + address l2ERC20TokenBridge_, + address l1TokenRatePusher_, + uint256 tokenRateOutdatedDelay_, + uint256 maxAllowedL2ToL1ClockLag_, + uint256 maxAllowedTokenRateDeviationPerDayBp_, + uint256 oldestRateAllowedInPauseTimeSpan_, + uint256 maxAllowedTimeBetweenTokenRateUpdates_ + ) CrossDomainEnabled(messenger_) { + if (l2ERC20TokenBridge_ == address(0)) { + revert ErrorZeroAddressL2ERC20TokenBridge(); + } + if (l1TokenRatePusher_ == address(0)) { + revert ErrorZeroAddressL1TokenRatePusher(); + } + if (maxAllowedTokenRateDeviationPerDayBp_ == 0 || maxAllowedTokenRateDeviationPerDayBp_ > BASIS_POINT_SCALE) { + revert ErrorMaxTokenRateDeviationIsOutOfRange(); + } + L2_ERC20_TOKEN_BRIDGE = l2ERC20TokenBridge_; + L1_TOKEN_RATE_PUSHER = l1TokenRatePusher_; + TOKEN_RATE_OUTDATED_DELAY = tokenRateOutdatedDelay_; + MAX_ALLOWED_L2_TO_L1_CLOCK_LAG = maxAllowedL2ToL1ClockLag_; + MAX_ALLOWED_TOKEN_RATE_DEVIATION_PER_DAY_BP = maxAllowedTokenRateDeviationPerDayBp_; + OLDEST_RATE_ALLOWED_IN_PAUSE_TIME_SPAN = oldestRateAllowedInPauseTimeSpan_; + MAX_ALLOWED_TIME_BETWEEN_TOKEN_RATE_UPDATES = maxAllowedTimeBetweenTokenRateUpdates_; + } + + /// @notice Initializes the contract from scratch. + /// @param admin_ Address of the account to grant the DEFAULT_ADMIN_ROLE + /// @param tokenRate_ wstETH/stETH token rate, uses 10**DECIMALS precision. + /// @param rateUpdatedL1Timestamp_ L1 time when rate was updated on L1 side. + function initialize(address admin_, uint256 tokenRate_, uint256 rateUpdatedL1Timestamp_) external { + _initializeContractVersionTo(1); + if (admin_ == address(0)) { + revert ErrorZeroAddressAdmin(); + } + if (tokenRate_ < MIN_SANE_TOKEN_RATE || tokenRate_ > MAX_SANE_TOKEN_RATE) { + revert ErrorTokenRateIsOutOfSaneRange(tokenRate_); + } + if (rateUpdatedL1Timestamp_ > block.timestamp + MAX_ALLOWED_L2_TO_L1_CLOCK_LAG) { + revert ErrorL1TimestampExceededMaxAllowedClockLag(rateUpdatedL1Timestamp_); + } + _grantRole(DEFAULT_ADMIN_ROLE, admin_); + _addTokenRate(tokenRate_, rateUpdatedL1Timestamp_, block.timestamp); + } + + /// @notice Pauses token rate updates and sets the old rate provided by tokenRateIndex_. + /// Should be called by DAO or emergency brakes only. + /// @param tokenRateIndex_ The index of the token rate that applies after the pause. + /// Token Rate can't be received older then OLDEST_RATE_ALLOWED_IN_PAUSE_TIME_SPAN + /// except only if the passed index is the latest one. + function pauseTokenRateUpdates(uint256 tokenRateIndex_) external onlyRole(RATE_UPDATE_DISABLER_ROLE) { + if (_isPaused()) { + revert ErrorAlreadyPaused(); + } + TokenRateData memory tokenRateData = _getTokenRateByIndex(tokenRateIndex_); + if (tokenRateIndex_ != _getStorageTokenRates().length - 1 && + tokenRateData.rateReceivedL2Timestamp < block.timestamp - OLDEST_RATE_ALLOWED_IN_PAUSE_TIME_SPAN) { + revert ErrorTokenRateUpdateTooOld(); + } + _removeElementsAfterIndex(tokenRateIndex_); + _setPause(true); + emit TokenRateUpdatesPaused(tokenRateData.tokenRate, tokenRateData.rateUpdatedL1Timestamp); + emit RateUpdated(tokenRateData.tokenRate, tokenRateData.rateUpdatedL1Timestamp); + } + + /// @notice Resume token rate updates applying provided token rate. + /// @param tokenRate_ a new token rate that applies after resuming. + /// @param rateUpdatedL1Timestamp_ L1 time when rate was updated on L1 side. + function resumeTokenRateUpdates( + uint256 tokenRate_, + uint256 rateUpdatedL1Timestamp_ + ) external onlyRole(RATE_UPDATE_ENABLER_ROLE) { + if (!_isPaused()) { + revert ErrorAlreadyResumed(); + } + if (tokenRate_ < MIN_SANE_TOKEN_RATE || tokenRate_ > MAX_SANE_TOKEN_RATE) { + revert ErrorTokenRateIsOutOfSaneRange(tokenRate_); + } + if (rateUpdatedL1Timestamp_ > block.timestamp + MAX_ALLOWED_L2_TO_L1_CLOCK_LAG) { + revert ErrorL1TimestampExceededMaxAllowedClockLag(rateUpdatedL1Timestamp_); + } + _addTokenRate(tokenRate_, rateUpdatedL1Timestamp_, block.timestamp); + _setPause(false); + emit TokenRateUpdatesResumed(tokenRate_, rateUpdatedL1Timestamp_); + emit RateUpdated(tokenRate_, rateUpdatedL1Timestamp_); + } + + /// @notice Shows that token rate updates are paused or not. + function isTokenRateUpdatesPaused() external view returns (bool) { + return _isPaused(); + } + + /// @notice Returns token rate data by index. + /// @param tokenRateIndex_ an index of token rate data. + function getTokenRateByIndex(uint256 tokenRateIndex_) external view returns (TokenRateData memory) { + return _getTokenRateByIndex(tokenRateIndex_); + } + + /// @notice Returns token rates data length. + function getTokenRatesLength() external view returns (uint256) { + return _getStorageTokenRates().length; + } + + /// @inheritdoc IChainlinkAggregatorInterface + function latestRoundData() external view returns ( + uint80 roundId_, + int256 answer_, + uint256 startedAt_, + uint256 updatedAt_, + uint80 answeredInRound_ + ) { + TokenRateData memory tokenRateData = _getLastTokenRate(); + return ( + uint80(tokenRateData.rateUpdatedL1Timestamp), + int256(uint256(tokenRateData.tokenRate)), + tokenRateData.rateUpdatedL1Timestamp, + tokenRateData.rateReceivedL2Timestamp, + uint80(tokenRateData.rateUpdatedL1Timestamp) + ); + } + + /// @inheritdoc IChainlinkAggregatorInterface + function latestAnswer() external view returns (int256) { + TokenRateData memory tokenRateData = _getLastTokenRate(); + return int256(uint256(tokenRateData.tokenRate)); + } + + /// @inheritdoc IChainlinkAggregatorInterface + function decimals() external pure returns (uint8) { + return DECIMALS; + } + + /// @inheritdoc ITokenRateUpdatable + function updateRate( + uint256 tokenRate_, + uint256 rateUpdatedL1Timestamp_ + ) external onlyBridgeOrTokenRatePusher { + if (_isPaused()) { + emit TokenRateUpdateAttemptDuringPause(); + return; + } + + TokenRateData storage tokenRateData = _getLastTokenRate(); + + /// @dev checks if the clock lag (i.e, time difference) between L1 and L2 exceeds the configurable threshold + if (rateUpdatedL1Timestamp_ > block.timestamp + MAX_ALLOWED_L2_TO_L1_CLOCK_LAG) { + revert ErrorL1TimestampExceededAllowedClockLag(tokenRate_, rateUpdatedL1Timestamp_); + } + + /// @dev Use only the most up-to-date token rate. Reverting should be avoided as it may occur occasionally. + if (rateUpdatedL1Timestamp_ < tokenRateData.rateUpdatedL1Timestamp) { + emit DormantTokenRateUpdateIgnored(rateUpdatedL1Timestamp_, tokenRateData.rateUpdatedL1Timestamp); + return; + } + + /// @dev Bump L2 receipt time, don't touch the rate othwerwise + /// NB: Here we assume that the rate can only be changed together with the token rebase induced + /// by the AccountingOracle report + if (rateUpdatedL1Timestamp_ == tokenRateData.rateUpdatedL1Timestamp) { + tokenRateData.rateReceivedL2Timestamp = uint64(block.timestamp); + emit RateReceivedTimestampUpdated(block.timestamp); + return; + } + + /// @dev This condition was made under the assumption that the L1 timestamps can be hacked. + if (rateUpdatedL1Timestamp_ < tokenRateData.rateUpdatedL1Timestamp + MAX_ALLOWED_TIME_BETWEEN_TOKEN_RATE_UPDATES) { + emit UpdateRateIsTooOften(rateUpdatedL1Timestamp_, tokenRateData.rateUpdatedL1Timestamp); + return; + } + + /// @dev allow token rate to be within some configurable range that depens on time it wasn't updated. + if (!_isTokenRateWithinAllowedRange( + tokenRateData.tokenRate, + tokenRate_, + tokenRateData.rateUpdatedL1Timestamp, + rateUpdatedL1Timestamp_) + ) { + revert ErrorTokenRateIsOutOfRange(tokenRate_, rateUpdatedL1Timestamp_); + } + + /// @dev notify that there is a differnce L1 and L2 time. + if (rateUpdatedL1Timestamp_ > block.timestamp) { + emit TokenRateL1TimestampIsInFuture(tokenRate_, rateUpdatedL1Timestamp_); + } + + _addTokenRate(tokenRate_, rateUpdatedL1Timestamp_, block.timestamp); + emit RateUpdated(tokenRate_, rateUpdatedL1Timestamp_); + } + + /// @notice Returns flag that shows that token rate can be considered outdated. + function isLikelyOutdated() external view returns (bool) { + return (block.timestamp > _getLastTokenRate().rateReceivedL2Timestamp + TOKEN_RATE_OUTDATED_DELAY) || + _isPaused(); + } + + /// @notice Allow tokenRate deviation from the previous value to be + /// ±`MAX_ALLOWED_TOKEN_RATE_DEVIATION_PER_DAY` BP per day. + function _isTokenRateWithinAllowedRange( + uint256 currentTokenRate_, + uint256 newTokenRate_, + uint256 currentRateL1Timestamp_, + uint256 newRateL1Timestamp_ + ) internal view returns (bool) { + uint256 allowedTokenRateDeviation = _allowedTokenRateDeviation(newRateL1Timestamp_, currentRateL1Timestamp_); + return newTokenRate_ <= _maxTokenRateLimit(currentTokenRate_, allowedTokenRateDeviation) && + newTokenRate_ >= _minTokenRateLimit(currentTokenRate_, allowedTokenRateDeviation); + } + + /// @dev Returns the allowed token deviation depending on the number of days passed since the last update. + function _allowedTokenRateDeviation( + uint256 newRateL1Timestamp_, + uint256 currentRateL1Timestamp_ + ) internal view returns (uint256) { + uint256 rateL1TimestampDiff = newRateL1Timestamp_ - currentRateL1Timestamp_; + uint256 roundedUpNumberOfDays = (rateL1TimestampDiff + ONE_DAY_SECONDS - 1) / ONE_DAY_SECONDS; + return roundedUpNumberOfDays * MAX_ALLOWED_TOKEN_RATE_DEVIATION_PER_DAY_BP; + } + + /// @dev Returns the maximum allowable value for the token rate. + function _maxTokenRateLimit( + uint256 currentTokenRate, + uint256 allowedTokenRateDeviation + ) internal pure returns (uint256) { + uint256 maxTokenRateLimit = currentTokenRate * (BASIS_POINT_SCALE + allowedTokenRateDeviation) / + BASIS_POINT_SCALE; + return Math.min(maxTokenRateLimit, MAX_SANE_TOKEN_RATE); + } + + /// @dev Returns the minimum allowable value for the token rate. + function _minTokenRateLimit( + uint256 currentTokenRate, + uint256 allowedTokenRateDeviation + ) internal pure returns (uint256) { + uint256 minTokenRateLimit = MIN_SANE_TOKEN_RATE; + if (allowedTokenRateDeviation <= BASIS_POINT_SCALE) { + minTokenRateLimit = (currentTokenRate * (BASIS_POINT_SCALE - allowedTokenRateDeviation) / + BASIS_POINT_SCALE); + } + return Math.max(minTokenRateLimit, MIN_SANE_TOKEN_RATE); + } + + function _isCallerBridgeOrMessengerWithTokenRatePusher(address caller_) internal view returns (bool) { + if (caller_ == L2_ERC20_TOKEN_BRIDGE) { + return true; + } + if (caller_ == address(MESSENGER) && MESSENGER.xDomainMessageSender() == L1_TOKEN_RATE_PUSHER) { + return true; + } + return false; + } + + function _addTokenRate( + uint256 tokenRate_, uint256 rateUpdatedL1Timestamp_, uint256 rateReceivedL2Timestamp_ + ) internal { + _getStorageTokenRates().push(TokenRateData({ + tokenRate: uint128(tokenRate_), + rateUpdatedL1Timestamp: uint64(rateUpdatedL1Timestamp_), + rateReceivedL2Timestamp: uint64(rateReceivedL2Timestamp_) + })); + } + + function _getLastTokenRate() internal view returns (TokenRateData storage) { + return _getTokenRateByIndex(_getStorageTokenRates().length - 1); + } + + function _getTokenRateByIndex(uint256 tokenRateIndex_) internal view returns (TokenRateData storage) { + if (tokenRateIndex_ >= _getStorageTokenRates().length) { + revert ErrorWrongTokenRateIndex(); + } + return _getStorageTokenRates()[tokenRateIndex_]; + } + + function _getStorageTokenRates() internal pure returns (TokenRateData [] storage result) { + bytes32 position = TOKEN_RATES_DATA_SLOT; + assembly { + result.slot := position + } + } + + /// @dev tokenRateIndex_ is limited by time in the past and the number of elements also has restrictions. + /// Therefore, this loop can't consume a lot of gas. + function _removeElementsAfterIndex(uint256 tokenRateIndex_) internal { + uint256 tokenRatesLength = _getStorageTokenRates().length; + if (tokenRateIndex_ >= tokenRatesLength) { + return; + } + uint256 numberOfElementsToRemove = tokenRatesLength - tokenRateIndex_ - 1; + for (uint256 i = 0; i < numberOfElementsToRemove; i++) { + _getStorageTokenRates().pop(); + } + } + + function _setPause(bool pause) internal { + PAUSE_TOKEN_RATE_UPDATES_SLOT.setStorageBool(pause); + } + + function _isPaused() internal view returns (bool) { + return PAUSE_TOKEN_RATE_UPDATES_SLOT.getStorageBool(); + } + + modifier onlyBridgeOrTokenRatePusher() { + if (!_isCallerBridgeOrMessengerWithTokenRatePusher(msg.sender)) { + revert ErrorNotBridgeOrTokenRatePusher(); + } + _; + } + + event RateUpdated(uint256 tokenRate_, uint256 indexed rateL1Timestamp_); + event RateReceivedTimestampUpdated(uint256 indexed rateReceivedL2Timestamp); + event DormantTokenRateUpdateIgnored(uint256 indexed newRateL1Timestamp_, uint256 indexed currentRateL1Timestamp_); + event TokenRateL1TimestampIsInFuture(uint256 tokenRate_, uint256 indexed rateL1Timestamp_); + event TokenRateUpdatesPaused(uint256 tokenRate_, uint256 indexed rateL1Timestamp_); + event TokenRateUpdatesResumed(uint256 tokenRate_, uint256 indexed rateL1Timestamp_); + event TokenRateUpdateAttemptDuringPause(); + event UpdateRateIsTooOften(uint256 indexed newRateL1Timestamp_, uint256 indexed currentRateL1Timestamp_); + + error ErrorZeroAddressAdmin(); + error ErrorWrongTokenRateIndex(); + error ErrorTokenRateUpdateTooOld(); + error ErrorAlreadyPaused(); + error ErrorAlreadyResumed(); + error ErrorZeroAddressL2ERC20TokenBridge(); + error ErrorZeroAddressL1TokenRatePusher(); + error ErrorNotBridgeOrTokenRatePusher(); + error ErrorL1TimestampExceededAllowedClockLag(uint256 tokenRate_, uint256 rateL1Timestamp_); + error ErrorTokenRateIsOutOfRange(uint256 tokenRate_, uint256 rateL1Timestamp_); + error ErrorMaxTokenRateDeviationIsOutOfRange(); + error ErrorTokenRateIsOutOfSaneRange(uint256 tokenRate_); + error ErrorL1TimestampExceededMaxAllowedClockLag(uint256 rateL1Timestamp_); +} diff --git a/contracts/optimism/interfaces/IChainlinkAggregatorInterface.sol b/contracts/optimism/interfaces/IChainlinkAggregatorInterface.sol new file mode 100644 index 00000000..03332adf --- /dev/null +++ b/contracts/optimism/interfaces/IChainlinkAggregatorInterface.sol @@ -0,0 +1,33 @@ +// SPDX-FileCopyrightText: 2024 Lido +// SPDX-License-Identifier: GPL-3.0 + +pragma solidity 0.8.10; + +/// @author kovalgek +/// @notice A subset of chainlink data feed interface for token rate oracle. +interface IChainlinkAggregatorInterface { + /// @notice get the latest token rate data. + /// @return roundId_ is a unique id for each answer. The value is based on timestamp. + /// @return answer_ is wstETH/stETH token rate. It is a chainlink convention to return int256. + /// @return startedAt_ is time when rate was pushed on L1 side. + /// @return updatedAt_ is the same as startedAt_. + /// @return answeredInRound_ is the same as roundId_. + function latestRoundData() + external + view + returns ( + uint80 roundId_, + int256 answer_, + uint256 startedAt_, + uint256 updatedAt_, + uint80 answeredInRound_ + ); + + /// @notice get the lastest token rate. + /// @return wstETH/stETH token rate. It is a chainlink convention to return int256. + function latestAnswer() external view returns (int256); + + /// @notice represents the number of decimals the oracle responses represent. + /// @return decimals of the oracle response. + function decimals() external view returns (uint8); +} diff --git a/contracts/optimism/interfaces/IL2ERC20Bridge.sol b/contracts/optimism/interfaces/IL2ERC20Bridge.sol index 448dfb8b..a0907ee1 100644 --- a/contracts/optimism/interfaces/IL2ERC20Bridge.sol +++ b/contracts/optimism/interfaces/IL2ERC20Bridge.sol @@ -26,22 +26,13 @@ interface IL2ERC20Bridge { bytes _data ); - event DepositFailed( - address indexed _l1Token, - address indexed _l2Token, - address indexed _from, - address _to, - uint256 _amount, - bytes _data - ); - /// @notice Returns the address of the corresponding L1 bridge contract function l1TokenBridge() external returns (address); /// @notice Initiates a withdraw of some tokens to the caller's account on L1 /// @param l2Token_ Address of L2 token where withdrawal was initiated. /// @param amount_ Amount of the token to withdraw. - /// @param l1Gas_ Unused, but included for potential forward compatibility considerations. + /// @param l1Gas_ Minimum gas limit to use for the transaction. /// @param data_ Optional data to forward to L1. This data is provided /// solely as a convenience for external contracts. Aside from enforcing a maximum /// length, these contracts provide no guarantees about its content. @@ -56,7 +47,7 @@ interface IL2ERC20Bridge { /// @param l2Token_ Address of L2 token where withdrawal is initiated. /// @param to_ L1 adress to credit the withdrawal to. /// @param amount_ Amount of the token to withdraw. - /// @param l1Gas_ Unused, but included for potential forward compatibility considerations. + /// @param l1Gas_ Minimum gas limit to use for the transaction. /// @param data_ Optional data to forward to L1. This data is provided /// solely as a convenience for external contracts. Aside from enforcing a maximum /// length, these contracts provide no guarantees about its content. diff --git a/contracts/optimism/interfaces/ITokenRateUpdatable.sol b/contracts/optimism/interfaces/ITokenRateUpdatable.sol new file mode 100644 index 00000000..433396de --- /dev/null +++ b/contracts/optimism/interfaces/ITokenRateUpdatable.sol @@ -0,0 +1,13 @@ +// SPDX-FileCopyrightText: 2024 Lido +// SPDX-License-Identifier: GPL-3.0 + +pragma solidity 0.8.10; + +/// @author kovalgek +/// @notice An interface for updating token rate of token rate oracle. +interface ITokenRateUpdatable { + /// @notice Updates token rate. + /// @param tokenRate_ wstETH/stETH token rate. + /// @param rateUpdatedL1Timestamp_ L1 time when rate was updated on L1 side. + function updateRate(uint256 tokenRate_, uint256 rateUpdatedL1Timestamp_) external; +} diff --git a/contracts/optimism/stubs/CrossDomainMessengerStub.sol b/contracts/optimism/stubs/CrossDomainMessengerStub.sol index f2d30805..d552ab3f 100644 --- a/contracts/optimism/stubs/CrossDomainMessengerStub.sol +++ b/contracts/optimism/stubs/CrossDomainMessengerStub.sol @@ -5,6 +5,7 @@ pragma solidity 0.8.10; import {ICrossDomainMessenger} from "../interfaces/ICrossDomainMessenger.sol"; +/// @dev For testing purposes. contract CrossDomainMessengerStub is ICrossDomainMessenger { address public xDomainMessageSender; uint256 public messageNonce; diff --git a/contracts/stubs/BridgingManagerStub.sol b/contracts/stubs/BridgingManagerStub.sol new file mode 100644 index 00000000..4e534317 --- /dev/null +++ b/contracts/stubs/BridgingManagerStub.sol @@ -0,0 +1,13 @@ +// SPDX-FileCopyrightText: 2024 Lido +// SPDX-License-Identifier: GPL-3.0 + +import {BridgingManager} from "../BridgingManager.sol"; + +pragma solidity 0.8.10; + +/// @dev For testing purposes. +contract BridgingManagerStub is BridgingManager { + function initialize(address admin_) external { + _initializeBridgingManager(admin_); + } +} diff --git a/contracts/stubs/ERC1271PermitSignerMock.sol b/contracts/stubs/ERC1271PermitSignerMock.sol new file mode 100644 index 00000000..56e94718 --- /dev/null +++ b/contracts/stubs/ERC1271PermitSignerMock.sol @@ -0,0 +1,21 @@ +// SPDX-FileCopyrightText: 2024 Lido +// SPDX-License-Identifier: GPL-3.0 + +pragma solidity 0.8.10; + +/// @dev For testing purposes. +contract ERC1271PermitSignerMock { + bytes4 public constant ERC1271_MAGIC_VALUE = 0x1626ba7e; + + function sign(bytes32 hash) public view returns (bytes1 v, bytes32 r, bytes32 s) { + v = 0x42; + r = hash; + s = bytes32(bytes20(address(this))); + } + + function isValidSignature(bytes32 hash, bytes memory sig) external view returns (bytes4) { + (bytes1 v, bytes32 r, bytes32 s) = sign(hash); + bytes memory validSig = abi.encodePacked(r, s, v); + return keccak256(sig) == keccak256(validSig) ? ERC1271_MAGIC_VALUE : bytes4(0); + } +} diff --git a/contracts/stubs/ERC20BridgedStub.sol b/contracts/stubs/ERC20BridgedStub.sol index 85e457a9..af5995fd 100644 --- a/contracts/stubs/ERC20BridgedStub.sol +++ b/contracts/stubs/ERC20BridgedStub.sol @@ -1,18 +1,19 @@ -// SPDX-FileCopyrightText: 2022 Lido +// SPDX-FileCopyrightText: 2024 Lido // SPDX-License-Identifier: GPL-3.0 pragma solidity 0.8.10; -import {IERC20Bridged} from "../token/interfaces/IERC20Bridged.sol"; +import {IERC20Bridged} from "../token/ERC20Bridged.sol"; import {ERC20} from "@openzeppelin/contracts/token/ERC20/ERC20.sol"; +/// @dev For testing purposes. contract ERC20BridgedStub is IERC20Bridged, ERC20 { address public bridge; constructor(string memory name_, string memory symbol_) ERC20(name_, symbol_) { - _mint(msg.sender, 1000000 * 10**18); + _mint(msg.sender, 1000000 * 10**40); } function setBridge(address bridge_) external { diff --git a/contracts/stubs/ERC20BridgedWithInitializerStub.sol b/contracts/stubs/ERC20BridgedWithInitializerStub.sol new file mode 100644 index 00000000..c4f79773 --- /dev/null +++ b/contracts/stubs/ERC20BridgedWithInitializerStub.sol @@ -0,0 +1,20 @@ +// SPDX-FileCopyrightText: 2024 Lido +// SPDX-License-Identifier: GPL-3.0 + +pragma solidity 0.8.10; + +import {ERC20Bridged} from "../token/ERC20Bridged.sol"; + +/// @dev For testing purposes. +contract ERC20BridgedWithInitializerStub is ERC20Bridged { + constructor( + string memory name_, + string memory symbol_, + uint8 decimals_, + address bridge_ + ) ERC20Bridged(name_, symbol_, decimals_, bridge_) {} + + function initializeERC20Metadata(string memory name_, string memory symbol_) external { + _initializeERC20Metadata(name_, symbol_); + } +} diff --git a/contracts/stubs/ERC20WrapperStub.sol b/contracts/stubs/ERC20WrapperStub.sol new file mode 100644 index 00000000..df4dd1fb --- /dev/null +++ b/contracts/stubs/ERC20WrapperStub.sol @@ -0,0 +1,76 @@ +// SPDX-FileCopyrightText: 2024 Lido +// SPDX-License-Identifier: GPL-3.0 + +pragma solidity 0.8.10; + +import {IERC20Bridged} from "../token/ERC20Bridged.sol"; +import {ERC20} from "@openzeppelin/contracts/token/ERC20/ERC20.sol"; +import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; +import {IERC20WstETH} from "../optimism/TokenRateAndUpdateTimestampProvider.sol"; +import {IERC20Wrapper} from "../token/interfaces/IERC20Wrapper.sol"; + +/// @dev represents wstETH on L1. For testing purposes. +contract ERC20WrapperStub is IERC20Wrapper, IERC20WstETH, ERC20 { + + IERC20 public stETH; + address public bridge; + uint256 private immutable TOTAL_POOLED_ETHER; + uint256 private immutable TOTAL_SHARES; + uint256 private decimalsShift = 0; + + constructor( + IERC20 stETH_, + string memory name_, + string memory symbol_, + uint256 totalPooledEther_, + uint256 totalShares_ + ) ERC20(name_, symbol_) { + stETH = stETH_; + TOTAL_POOLED_ETHER = totalPooledEther_; + TOTAL_SHARES = totalShares_; + _mint(msg.sender, 1000000 * 10**40); + } + + function wrap(uint256 _stETHAmount) external returns (uint256) { + require(_stETHAmount > 0, "wstETH: can't wrap zero stETH"); + + uint256 wstETHAmount = _getSharesByPooledEth(_stETHAmount); + + _mint(msg.sender, wstETHAmount); + stETH.transferFrom(msg.sender, address(this), _stETHAmount); + + return wstETHAmount; + } + + function unwrap(uint256 _wstETHAmount) external returns (uint256) { + require(_wstETHAmount > 0, "wstETH: zero amount unwrap not allowed"); + + uint256 stETHAmount = _getPooledEthByShares(_wstETHAmount); + + _burn(msg.sender, _wstETHAmount); + stETH.transfer(msg.sender, stETHAmount); + + return stETHAmount; + } + + function getStETHByWstETH(uint256 wstETHAmount_) external view returns (uint256) { + uint256 wstETHAmount = wstETHAmount_ - decimalsShift; + return _getPooledEthByShares(wstETHAmount); + } + + function _getPooledEthByShares(uint256 sharesAmount_) internal view returns (uint256) { + return sharesAmount_ * TOTAL_POOLED_ETHER / TOTAL_SHARES; + } + + function getWstETHByStETH(uint256 stETHAmount_) external view returns (uint256) { + return _getSharesByPooledEth(stETHAmount_); + } + + function _getSharesByPooledEth(uint256 ethAmount_) internal view returns (uint256) { + return ethAmount_ * TOTAL_SHARES / TOTAL_POOLED_ETHER; + } + + function setDecimalsShift(uint256 decimalsShift_) external { + decimalsShift = decimalsShift_; + } +} diff --git a/contracts/stubs/EmptyContractStub.sol b/contracts/stubs/EmptyContractStub.sol index 9a334ca1..96e3995c 100644 --- a/contracts/stubs/EmptyContractStub.sol +++ b/contracts/stubs/EmptyContractStub.sol @@ -1,8 +1,9 @@ -// SPDX-FileCopyrightText: 2022 Lido +// SPDX-FileCopyrightText: 2024 Lido // SPDX-License-Identifier: GPL-3.0 pragma solidity 0.8.10; +/// @dev For testing purposes. contract EmptyContractStub { constructor() payable {} } diff --git a/contracts/token/ERC20Bridged.sol b/contracts/token/ERC20Bridged.sol index 574ddd8b..7ec7e011 100644 --- a/contracts/token/ERC20Bridged.sol +++ b/contracts/token/ERC20Bridged.sol @@ -1,14 +1,30 @@ -// SPDX-FileCopyrightText: 2022 Lido +// SPDX-FileCopyrightText: 2024 Lido // SPDX-License-Identifier: GPL-3.0 pragma solidity 0.8.10; -import {IERC20Bridged} from "./interfaces/IERC20Bridged.sol"; - +import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import {ERC20Core} from "./ERC20Core.sol"; import {ERC20Metadata} from "./ERC20Metadata.sol"; -/// @author psirex +/// @author psirex, kovalgek +/// @notice Extends the ERC20 functionality that allows the bridge to mint/burn tokens +interface IERC20Bridged is IERC20 { + /// @notice Returns bridge which can mint and burn tokens on L2 + function bridge() external view returns (address); + + /// @notice Creates `amount_` tokens and assigns them to `account_`, increasing the total supply + /// @param account_ An address of the account to mint tokens + /// @param amount_ An amount of tokens to mint + function bridgeMint(address account_, uint256 amount_) external; + + /// @notice Destroys `amount_` tokens from `account_`, reducing the total supply + /// @param account_ An address of the account to burn tokens + /// @param amount_ An amount of tokens to burn + function bridgeBurn(address account_, uint256 amount_) external; +} + +/// @author psirex, kovalgek /// @notice Extends the ERC20 functionality that allows the bridge to mint/burn tokens contract ERC20Bridged is IERC20Bridged, ERC20Core, ERC20Metadata { /// @inheritdoc IERC20Bridged @@ -17,24 +33,19 @@ contract ERC20Bridged is IERC20Bridged, ERC20Core, ERC20Metadata { /// @param name_ The name of the token /// @param symbol_ The symbol of the token /// @param decimals_ The decimals places of the token - /// @param bridge_ The bridge address which allowd to mint/burn tokens + /// @param bridge_ The bridge address which allows to mint/burn tokens constructor( string memory name_, string memory symbol_, uint8 decimals_, address bridge_ ) ERC20Metadata(name_, symbol_, decimals_) { + if (bridge_ == address(0)) { + revert ErrorZeroAddressBridge(); + } bridge = bridge_; } - /// @notice Sets the name and the symbol of the tokens if they both are empty - /// @param name_ The name of the token - /// @param symbol_ The symbol of the token - function initialize(string memory name_, string memory symbol_) external { - _setERC20MetadataName(name_); - _setERC20MetadataSymbol(symbol_); - } - /// @inheritdoc IERC20Bridged function bridgeMint(address account_, uint256 amount_) external onlyBridge { _mint(account_, amount_); @@ -45,6 +56,14 @@ contract ERC20Bridged is IERC20Bridged, ERC20Core, ERC20Metadata { _burn(account_, amount_); } + /// @notice Sets the name and the symbol of the tokens if they both are empty + /// @param name_ The name of the token + /// @param symbol_ The symbol of the token + function _initializeERC20Metadata(string memory name_, string memory symbol_) internal { + _setERC20MetadataName(name_); + _setERC20MetadataSymbol(symbol_); + } + /// @dev Validates that sender of the transaction is the bridge modifier onlyBridge() { if (msg.sender != bridge) { @@ -53,5 +72,6 @@ contract ERC20Bridged is IERC20Bridged, ERC20Core, ERC20Metadata { _; } + error ErrorZeroAddressBridge(); error ErrorNotBridge(); } diff --git a/contracts/token/ERC20BridgedPermit.sol b/contracts/token/ERC20BridgedPermit.sol new file mode 100644 index 00000000..87536453 --- /dev/null +++ b/contracts/token/ERC20BridgedPermit.sol @@ -0,0 +1,63 @@ +// SPDX-FileCopyrightText: 2024 OpenZeppelin, Lido +// SPDX-License-Identifier: GPL-3.0 + +pragma solidity 0.8.10; + +import {ERC20Bridged} from "./ERC20Bridged.sol"; +import {PermitExtension} from "./PermitExtension.sol"; +import {Versioned} from "../utils/Versioned.sol"; + +/// @author kovalgek +/// @notice extends ERC20Bridged functionality that allows to use permits and versioning. +contract ERC20BridgedPermit is ERC20Bridged, PermitExtension, Versioned { + + /// @param name_ The name of the token + /// @param symbol_ The symbol of the token + /// @param version_ The current major version of the signing domain (aka token version) + /// @param decimals_ The decimals places of the token + /// @param bridge_ The bridge address which allows to mint/burn tokens + constructor( + string memory name_, + string memory symbol_, + string memory version_, + uint8 decimals_, + address bridge_ + ) + ERC20Bridged(name_, symbol_, decimals_, bridge_) + PermitExtension(name_, version_) + { + } + + /// @notice Initializes the contract from scratch. + /// @param name_ The name of the token + /// @param symbol_ The symbol of the token + /// @param version_ The version of the token + function initialize(string memory name_, string memory symbol_, string memory version_) external { + if (_isMetadataInitialized()) { + revert ErrorMetadataIsAlreadyInitialized(); + } + _initializeERC20Metadata(name_, symbol_); + _initialize_v2(name_, version_); + } + + /// @notice A function to finalize upgrade to v2 (from v1). + function finalizeUpgrade_v2(string memory name_, string memory version_) external { + if (!_isMetadataInitialized()) { + revert ErrorMetadataIsNotInitialized(); + } + _initialize_v2(name_, version_); + } + + function _initialize_v2(string memory name_, string memory version_) internal { + _initializeContractVersionTo(2); + _initializeEIP5267Metadata(name_, version_); + } + + /// @inheritdoc PermitExtension + function _permitAccepted(address owner_, address spender_, uint256 amount_) internal override { + _approve(owner_, spender_, amount_); + } + + error ErrorMetadataIsNotInitialized(); + error ErrorMetadataIsAlreadyInitialized(); +} diff --git a/contracts/token/ERC20Core.sol b/contracts/token/ERC20Core.sol index bf4e67db..db8aafb8 100644 --- a/contracts/token/ERC20Core.sol +++ b/contracts/token/ERC20Core.sol @@ -44,38 +44,6 @@ contract ERC20Core is IERC20 { return true; } - /// @notice Atomically increases the allowance granted to spender by the caller. - /// @param spender_ An address of the tokens spender - /// @param addedValue_ An amount to increase the allowance - function increaseAllowance(address spender_, uint256 addedValue_) - external - returns (bool) - { - _approve( - msg.sender, - spender_, - allowance[msg.sender][spender_] + addedValue_ - ); - return true; - } - - /// @notice Atomically decreases the allowance granted to spender by the caller. - /// @param spender_ An address of the tokens spender - /// @param subtractedValue_ An amount to decrease the allowance - function decreaseAllowance(address spender_, uint256 subtractedValue_) - external - returns (bool) - { - uint256 currentAllowance = allowance[msg.sender][spender_]; - if (currentAllowance < subtractedValue_) { - revert ErrorDecreasedAllowanceBelowZero(); - } - unchecked { - _approve(msg.sender, spender_, currentAllowance - subtractedValue_); - } - return true; - } - /// @dev Moves amount_ of tokens from sender_ to recipient_ /// @param from_ An address of the sender of the tokens /// @param to_ An address of the recipient of the tokens @@ -174,5 +142,4 @@ contract ERC20Core is IERC20 { error ErrorNotEnoughBalance(); error ErrorNotEnoughAllowance(); error ErrorAccountIsZeroAddress(); - error ErrorDecreasedAllowanceBelowZero(); } diff --git a/contracts/token/ERC20Metadata.sol b/contracts/token/ERC20Metadata.sol index 397b4d0d..b86c700f 100644 --- a/contracts/token/ERC20Metadata.sol +++ b/contracts/token/ERC20Metadata.sol @@ -3,7 +3,18 @@ pragma solidity 0.8.10; -import {IERC20Metadata} from "./interfaces/IERC20Metadata.sol"; +/// @author psirex +/// @notice Interface for the optional metadata functions from the ERC20 standard. +interface IERC20Metadata { + /// @dev Returns the name of the token. + function name() external view returns (string memory); + + /// @dev Returns the symbol of the token. + function symbol() external view returns (string memory); + + /// @dev Returns the decimals places of the token. + function decimals() external view returns (uint8); +} /// @author psirex /// @notice Contains the optional metadata functions from the ERC20 standard @@ -18,6 +29,7 @@ contract ERC20Metadata is IERC20Metadata { } /// @dev Location of the slot with DynamicMetdata + /// The slot's index string has a misspelling, but the contract storage will be broken without it. bytes32 private constant DYNAMIC_METADATA_SLOT = keccak256("ERC20Metdata.dynamicMetadata"); @@ -32,6 +44,9 @@ contract ERC20Metadata is IERC20Metadata { string memory symbol_, uint8 decimals_ ) { + if (decimals_ == 0) { + revert ErrorZeroDecimals(); + } decimals = decimals_; _setERC20MetadataName(name_); _setERC20MetadataSymbol(symbol_); @@ -47,23 +62,27 @@ contract ERC20Metadata is IERC20Metadata { return _loadDynamicMetadata().symbol; } - /// @dev Sets the name of the token. Might be called only when the name is empty + /// @dev Sets the name of the token. function _setERC20MetadataName(string memory name_) internal { - if (bytes(name()).length > 0) { - revert ErrorNameAlreadySet(); + if (bytes(name_).length == 0) { + revert ErrorNameIsEmpty(); } _loadDynamicMetadata().name = name_; } - /// @dev Sets the symbol of the token. Might be called only when the symbol is empty + /// @dev Sets the symbol of the token. function _setERC20MetadataSymbol(string memory symbol_) internal { - if (bytes(symbol()).length > 0) { - revert ErrorSymbolAlreadySet(); + if (bytes(symbol_).length == 0) { + revert ErrorSymbolIsEmpty(); } _loadDynamicMetadata().symbol = symbol_; } - /// @dev Returns the reference to the slot with DynamicMetadta struct + function _isMetadataInitialized() internal view returns (bool) { + return bytes(name()).length != 0 && bytes(symbol()).length != 0; + } + + /// @dev Returns the reference to the slot with DynamicMetadata struct function _loadDynamicMetadata() private pure @@ -75,6 +94,7 @@ contract ERC20Metadata is IERC20Metadata { } } - error ErrorNameAlreadySet(); - error ErrorSymbolAlreadySet(); + error ErrorZeroDecimals(); + error ErrorNameIsEmpty(); + error ErrorSymbolIsEmpty(); } diff --git a/contracts/token/ERC20RebasableBridged.sol b/contracts/token/ERC20RebasableBridged.sol new file mode 100644 index 00000000..f2adfe12 --- /dev/null +++ b/contracts/token/ERC20RebasableBridged.sol @@ -0,0 +1,424 @@ +// SPDX-FileCopyrightText: 2024 Lido +// SPDX-License-Identifier: GPL-3.0 + +pragma solidity 0.8.10; + +import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; +import {SafeERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; +import {IERC20Wrapper} from "./interfaces/IERC20Wrapper.sol"; +import {ITokenRateOracle} from "../optimism/TokenRateOracle.sol"; +import {ERC20Metadata} from "./ERC20Metadata.sol"; +import {UnstructuredRefStorage} from "../lib/UnstructuredRefStorage.sol"; +import {UnstructuredStorage} from "../lib/UnstructuredStorage.sol"; + +/// @author kovalgek +/// @notice Extends the ERC20 functionality that allows the bridge to wrap/unwrap token. +interface IBridgeWrapper { + /// @notice Returns bridge which can wrap/unwrap token on L2. + function L2_ERC20_TOKEN_BRIDGE() external view returns (address); + + /// @notice Exchanges non-rebasable token (shares) to rebasable token. Can be called by bridge only. + /// @param account_ an address of the account to exchange shares for. + /// @param sharesAmount_ amount of non-rebasable token (shares). + /// @return Amount of rebasable token. + function bridgeWrap(address account_, uint256 sharesAmount_) external returns (uint256); + + /// @notice Exchanges rebasable token to non-rebasable (shares). Can be called by bridge only. + /// @param account_ an address of the account to exchange token for. + /// @param tokenAmount_ amount of rebasable token to uwrap in exchange for non-rebasable token (shares). + /// @return Amount of non-rebasable token (shares) user receives after unwrap. + function bridgeUnwrap(address account_, uint256 tokenAmount_) external returns (uint256); +} + +/// @author kovalgek +/// @notice Rebasable token that wraps/unwraps non-rebasable token and allow to mint/burn tokens by bridge. +contract ERC20RebasableBridged is IERC20, IERC20Wrapper, IBridgeWrapper, ERC20Metadata { + using SafeERC20 for IERC20; + using UnstructuredRefStorage for bytes32; + using UnstructuredStorage for bytes32; + + /// @inheritdoc IBridgeWrapper + address public immutable L2_ERC20_TOKEN_BRIDGE; + + /// @notice Contract of non-rebasable token to wrap from. + IERC20 public immutable TOKEN_TO_WRAP_FROM; + + /// @notice Oracle contract used to get token rate for wrapping/unwrapping tokens. + ITokenRateOracle public immutable TOKEN_RATE_ORACLE; + + /// @notice Decimals of the oracle response. + uint8 public immutable TOKEN_RATE_ORACLE_DECIMALS; + + /// @dev token allowance slot position. + bytes32 internal constant TOKEN_ALLOWANCE_POSITION = keccak256("ERC20RebasableBridged.TOKEN_ALLOWANCE_POSITION"); + + /// @dev user shares slot position. + bytes32 internal constant SHARES_POSITION = keccak256("ERC20RebasableBridged.SHARES_POSITION"); + + /// @dev token shares slot position. + bytes32 internal constant TOTAL_SHARES_POSITION = keccak256("ERC20RebasableBridged.TOTAL_SHARES_POSITION"); + + /// @param name_ The name of the token + /// @param symbol_ The symbol of the token + /// @param decimals_ The decimals places of the token + /// @param tokenToWrapFrom_ address of the ERC20 token to wrap + /// @param tokenRateOracle_ address of oracle that returns tokens rate + /// @param l2ERC20TokenBridge_ The bridge address which allows to mint/burn tokens + constructor( + string memory name_, + string memory symbol_, + uint8 decimals_, + address tokenToWrapFrom_, + address tokenRateOracle_, + address l2ERC20TokenBridge_ + ) ERC20Metadata(name_, symbol_, decimals_) { + if (tokenToWrapFrom_ == address(0)) { + revert ErrorZeroAddressTokenToWrapFrom(); + } + if (tokenRateOracle_ == address(0)) { + revert ErrorZeroAddressTokenRateOracle(); + } + if (l2ERC20TokenBridge_ == address(0)) { + revert ErrorZeroAddressL2ERC20TokenBridge(); + } + TOKEN_TO_WRAP_FROM = IERC20(tokenToWrapFrom_); + TOKEN_RATE_ORACLE = ITokenRateOracle(tokenRateOracle_); + TOKEN_RATE_ORACLE_DECIMALS = TOKEN_RATE_ORACLE.decimals(); + L2_ERC20_TOKEN_BRIDGE = l2ERC20TokenBridge_; + } + + /// @inheritdoc IERC20Wrapper + function wrap(uint256 sharesAmount_) external returns (uint256) { + return _wrap(msg.sender, msg.sender, sharesAmount_); + } + + /// @inheritdoc IERC20Wrapper + function unwrap(uint256 tokenAmount_) external returns (uint256) { + return _unwrap(msg.sender, tokenAmount_); + } + + /// @notice Exchanges rebasable token to non-rebasable by providing rebasable token shares. + /// @param sharesAmount_ amount of rebasable token shares to unwrap. + /// @return amount of non-rebasable token user receives after unwrap. + function unwrapShares(uint256 sharesAmount_) external returns (uint256) { + uint256 tokenAmount = _getTokensByShares(sharesAmount_); + return _unwrapShares(msg.sender, sharesAmount_, tokenAmount); + } + + /// @inheritdoc IBridgeWrapper + function bridgeWrap(address account_, uint256 sharesAmount_) external onlyBridge returns (uint256) { + return _wrap(L2_ERC20_TOKEN_BRIDGE, account_, sharesAmount_); + } + + /// @inheritdoc IBridgeWrapper + function bridgeUnwrap(address account_, uint256 tokenAmount_) external onlyBridge returns (uint256) { + return _unwrap(account_, tokenAmount_); + } + + /// @inheritdoc IERC20 + function allowance(address owner, address spender) external view returns (uint256) { + return _getTokenAllowance()[owner][spender]; + } + + /// @inheritdoc IERC20 + function totalSupply() external view returns (uint256) { + return _getTokensByShares(_getTotalShares()); + } + + /// @inheritdoc IERC20 + function balanceOf(address account_) external view returns (uint256) { + return _getTokensByShares(_sharesOf(account_)); + } + + /// @notice Get shares amount of the provided account. + /// @param account_ provided account address. + /// @return amount of shares owned by `_account`. + function sharesOf(address account_) external view returns (uint256) { + return _sharesOf(account_); + } + + /// @return total amount of shares. + function getTotalShares() external view returns (uint256) { + return _getTotalShares(); + } + + /// @notice Get amount of tokens for a given amount of shares. + /// @param sharesAmount_ amount of shares. + /// @return amount of tokens for a given shares amount. + function getTokensByShares(uint256 sharesAmount_) external view returns (uint256) { + return _getTokensByShares(sharesAmount_); + } + + /// @notice Get amount of shares for a given amount of tokens. + /// @param tokenAmount_ provided tokens amount. + /// @return amount of shares for a given tokens amount. + function getSharesByTokens(uint256 tokenAmount_) external view returns (uint256) { + return _getSharesByTokens(tokenAmount_); + } + + /// @inheritdoc IERC20 + function approve(address spender_, uint256 amount_) external returns (bool) { + _approve(msg.sender, spender_, amount_); + return true; + } + + /// @inheritdoc IERC20 + function transfer(address to_, uint256 amount_) external returns (bool) { + _transfer(msg.sender, to_, amount_); + return true; + } + + /// @inheritdoc IERC20 + function transferFrom(address from_, address to_, uint256 amount_) external returns (bool) { + _spendAllowance(from_, msg.sender, amount_); + _transfer(from_, to_, amount_); + return true; + } + + /// @notice Moves `sharesAmount_` token shares from the caller's account to the `recipient_` account. + /// + /// @return amount of transferred tokens. + /// Emits a `TransferShares` event. + /// Emits a `Transfer` event. + /// + /// Requirements: + /// + /// - `recipient_` cannot be the zero address. + /// - the caller must have at least `sharesAmount_` shares. + /// + /// @dev The `sharesAmount_` argument is the amount of shares, not tokens. + /// + function transferShares(address recipient_, uint256 sharesAmount_) external returns (uint256) { + _transferShares(msg.sender, recipient_, sharesAmount_); + uint256 tokensAmount = _getTokensByShares(sharesAmount_); + _emitTransferEvents(msg.sender, recipient_, tokensAmount, sharesAmount_); + return tokensAmount; + } + + /// @notice Moves `sharesAmount_` token shares from the `sender_` account to the `_recipient` account. + /// + /// @return amount of transferred tokens. + /// Emits a `TransferShares` event. + /// Emits a `Transfer` event. + /// + /// Requirements: + /// + /// - `sender_` and `_recipient` cannot be the zero addresses. + /// - `sender_` must have at least `sharesAmount_` shares. + /// - the caller must have allowance for `sender_`'s tokens of at least `_getTokensByShares(sharesAmount_)`. + /// + /// @dev The `_sharesAmount` argument is the amount of shares, not tokens. + /// + function transferSharesFrom( + address sender_, address recipient_, uint256 sharesAmount_ + ) external returns (uint256) { + uint256 tokensAmount = _getTokensByShares(sharesAmount_); + _spendAllowance(sender_, msg.sender, tokensAmount); + _transferShares(sender_, recipient_, sharesAmount_); + _emitTransferEvents(sender_, recipient_, tokensAmount, sharesAmount_); + return tokensAmount; + } + + function _getTokenAllowance() internal pure returns (mapping(address => mapping(address => uint256)) storage) { + return TOKEN_ALLOWANCE_POSITION.storageMapAddressMapAddressUint256(); + } + + /// @notice Amount of shares (locked wstETH amount) owned by the holder. + function _getShares() internal pure returns (mapping(address => uint256) storage) { + return SHARES_POSITION.storageMapAddressAddressUint256(); + } + + /// @notice The total amount of shares in existence. + function _getTotalShares() internal view returns (uint256) { + return TOTAL_SHARES_POSITION.getStorageUint256(); + } + + /// @notice Set total amount of shares. + function _setTotalShares(uint256 _newTotalShares) internal { + TOTAL_SHARES_POSITION.setStorageUint256(_newTotalShares); + } + + /// @dev Moves amount_ of tokens from sender_ to recipient_ + /// @param from_ An address of the sender of the tokens + /// @param to_ An address of the recipient of the tokens + /// @param amount_ An amount of tokens to transfer + function _transfer( + address from_, address to_, uint256 amount_ + ) internal onlyNonZeroAccount(from_) onlyNonZeroAccount(to_) { + uint256 sharesToTransfer = _getSharesByTokens(amount_); + _transferShares(from_, to_, sharesToTransfer); + _emitTransferEvents(from_, to_, amount_, sharesToTransfer); + } + + /// @dev Updates owner_'s allowance for spender_ based on spent amount_. Does not update + /// the allowance amount in case of infinite allowance + /// @param owner_ An address of the account to spend allowance + /// @param spender_ An address of the spender of the tokens + /// @param amount_ An amount of allowance spend + function _spendAllowance( + address owner_, + address spender_, + uint256 amount_ + ) internal { + uint256 currentAllowance = _getTokenAllowance()[owner_][spender_]; + if (currentAllowance == type(uint256).max) { + return; + } + if (amount_ > currentAllowance) { + revert ErrorNotEnoughAllowance(); + } + unchecked { + _approve(owner_, spender_, currentAllowance - amount_); + } + } + + /// @dev Sets amount_ as the allowance of spender_ over the owner_'s tokens + /// @param owner_ An address of the account to set allowance + /// @param spender_ An address of the tokens spender + /// @param amount_ An amount of tokens to allow to spend + function _approve( + address owner_, + address spender_, + uint256 amount_ + ) internal virtual onlyNonZeroAccount(owner_) onlyNonZeroAccount(spender_) { + _getTokenAllowance()[owner_][spender_] = amount_; + emit Approval(owner_, spender_, amount_); + } + + function _sharesOf(address account_) internal view returns (uint256) { + return _getShares()[account_]; + } + + function _getTokensByShares(uint256 sharesAmount_) internal view returns (uint256) { + return (sharesAmount_ * _getTokenRate()) / (10 ** TOKEN_RATE_ORACLE_DECIMALS); + } + + function _getSharesByTokens(uint256 tokenAmount_) internal view returns (uint256) { + return (tokenAmount_ * (10 ** TOKEN_RATE_ORACLE_DECIMALS)) / _getTokenRate(); + } + + function _getTokenRate() internal view returns (uint256) { + return uint256(TOKEN_RATE_ORACLE.latestAnswer()); + } + + /// @dev Creates `amount_` shares and assigns them to `account_`, increasing the total shares supply + /// @param recipient_ An address of the account to mint shares + /// @param amount_ An amount of shares to mint + function _mintShares( + address recipient_, + uint256 amount_ + ) internal onlyNonZeroAccount(recipient_) { + _setTotalShares(_getTotalShares() + amount_); + _getShares()[recipient_] = _getShares()[recipient_] + amount_; + } + + /// @dev Destroys `amount_` shares from `account_`, reducing the total shares supply. + /// @param account_ An address of the account to mint shares + /// @param amount_ An amount of shares to mint + function _burnShares( + address account_, + uint256 amount_ + ) internal onlyNonZeroAccount(account_) { + uint256 accountShares = _getShares()[account_]; + if (accountShares < amount_) revert ErrorNotEnoughBalance(); + _setTotalShares(_getTotalShares() - amount_); + _getShares()[account_] = accountShares - amount_; + } + + /// @dev Moves `sharesAmount_` shares from `sender_` to `recipient_`. + /// @param sender_ An address of the account to take shares + /// @param recipient_ An address of the account to transfer shares + /// @param sharesAmount_ An amount of shares to transfer + function _transferShares( + address sender_, + address recipient_, + uint256 sharesAmount_ + ) internal onlyNonZeroAccount(sender_) onlyNonZeroAccount(recipient_) { + if (recipient_ == address(this)) revert ErrorTransferToRebasableContract(); + + uint256 currentSenderShares = _getShares()[sender_]; + if (sharesAmount_ > currentSenderShares) revert ErrorNotEnoughBalance(); + + _getShares()[sender_] = currentSenderShares - sharesAmount_; + _getShares()[recipient_] = _getShares()[recipient_] + sharesAmount_; + } + + /// @dev Emits `Transfer` and `TransferShares` events + function _emitTransferEvents( + address _from, + address _to, + uint256 _tokenAmount, + uint256 _sharesAmount + ) internal { + emit Transfer(_from, _to, _tokenAmount); + emit TransferShares(_from, _to, _sharesAmount); + } + + /// @notice Sets the name and the symbol of the tokens if they both are empty + /// @param name_ The name of the token + /// @param symbol_ The symbol of the token + function _initializeERC20Metadata(string memory name_, string memory symbol_) internal { + _setERC20MetadataName(name_); + _setERC20MetadataSymbol(symbol_); + } + + function _wrap(address from_, address to_, uint256 sharesAmount_) internal returns (uint256) { + if (sharesAmount_ == 0) revert ErrorZeroSharesWrap(); + TOKEN_TO_WRAP_FROM.safeTransferFrom(from_, address(this), sharesAmount_); + _mintShares(to_, sharesAmount_); + uint256 tokensAmount = _getTokensByShares(sharesAmount_); + _emitTransferEvents(address(0), to_, tokensAmount, sharesAmount_); + return tokensAmount; + } + + function _unwrap(address account_, uint256 tokenAmount_) internal returns (uint256) { + if (tokenAmount_ == 0) revert ErrorZeroTokensUnwrap(); + uint256 sharesAmount = _getSharesByTokens(tokenAmount_); + return _unwrapShares(account_, sharesAmount, tokenAmount_); + } + + function _unwrapShares(address account_, uint256 sharesAmount_, uint256 tokenAmount_) internal returns (uint256) { + if (sharesAmount_ == 0) revert ErrorZeroSharesUnwrap(); + _burnShares(account_, sharesAmount_); + _emitTransferEvents(account_, address(0), tokenAmount_, sharesAmount_); + TOKEN_TO_WRAP_FROM.safeTransfer(account_, sharesAmount_); + return sharesAmount_; + } + + /// @dev validates that account_ is not zero address + modifier onlyNonZeroAccount(address account_) { + if (account_ == address(0)) { + revert ErrorAccountIsZeroAddress(); + } + _; + } + + /// @dev Validates that sender of the transaction is the bridge + modifier onlyBridge() { + if (msg.sender != L2_ERC20_TOKEN_BRIDGE) { + revert ErrorNotBridge(); + } + _; + } + + /// @notice An executed shares transfer from `sender` to `recipient`. + /// @dev emitted in pair with an ERC20-defined `Transfer` event. + event TransferShares( + address indexed from, + address indexed to, + uint256 sharesValue + ); + + error ErrorZeroAddressTokenToWrapFrom(); + error ErrorZeroAddressTokenRateOracle(); + error ErrorZeroAddressL2ERC20TokenBridge(); + error ErrorZeroSharesWrap(); + error ErrorZeroTokensUnwrap(); + error ErrorZeroSharesUnwrap(); + error ErrorTokenRateDecimalsIsZero(); + error ErrorTransferToRebasableContract(); + error ErrorNotEnoughBalance(); + error ErrorNotEnoughAllowance(); + error ErrorAccountIsZeroAddress(); + error ErrorNotBridge(); +} diff --git a/contracts/token/ERC20RebasableBridgedPermit.sol b/contracts/token/ERC20RebasableBridgedPermit.sol new file mode 100644 index 00000000..1755fd17 --- /dev/null +++ b/contracts/token/ERC20RebasableBridgedPermit.sol @@ -0,0 +1,56 @@ +// SPDX-FileCopyrightText: 2024 OpenZeppelin, Lido +// SPDX-License-Identifier: GPL-3.0 + +pragma solidity 0.8.10; + +import {ERC20RebasableBridged} from "./ERC20RebasableBridged.sol"; +import {PermitExtension} from "./PermitExtension.sol"; +import {Versioned} from "../utils/Versioned.sol"; + +/// @author kovalgek +/// @notice extends ERC20RebasableBridged functionality that allows to use permits and versioning. +contract ERC20RebasableBridgedPermit is ERC20RebasableBridged, PermitExtension, Versioned { + + /// @param name_ The name of the token + /// @param symbol_ The symbol of the token + /// @param version_ The current major version of the signing domain (aka token version) + /// @param decimals_ The decimals places of the token + /// @param tokenToWrapFrom_ address of the ERC20 token to wrap + /// @param tokenRateOracle_ address of oracle that returns tokens rate + /// @param bridge_ The bridge address which allowd to mint/burn tokens + constructor( + string memory name_, + string memory symbol_, + string memory version_, + uint8 decimals_, + address tokenToWrapFrom_, + address tokenRateOracle_, + address bridge_ + ) + ERC20RebasableBridged( + name_, + symbol_, + decimals_, + tokenToWrapFrom_, + tokenRateOracle_, + bridge_ + ) + PermitExtension(name_, version_) + { + } + + /// @notice Initializes the contract from scratch. + /// @param name_ The name of the token + /// @param symbol_ The symbol of the token + /// @param version_ The version of the token + function initialize(string memory name_, string memory symbol_, string memory version_) external { + _initializeContractVersionTo(1); + _initializeERC20Metadata(name_, symbol_); + _initializeEIP5267Metadata(name_, version_); + } + + /// @inheritdoc PermitExtension + function _permitAccepted(address owner_, address spender_, uint256 amount_) internal override { + _approve(owner_, spender_, amount_); + } +} diff --git a/contracts/token/PermitExtension.sol b/contracts/token/PermitExtension.sol new file mode 100644 index 00000000..2dc6dc58 --- /dev/null +++ b/contracts/token/PermitExtension.sol @@ -0,0 +1,184 @@ +// SPDX-FileCopyrightText: 2024 OpenZeppelin, Lido +// SPDX-License-Identifier: GPL-3.0 + +pragma solidity 0.8.10; + +import {IERC2612} from "@openzeppelin/contracts/interfaces/draft-IERC2612.sol"; +import {EIP712} from "@openzeppelin/contracts/utils/cryptography/draft-EIP712.sol"; +import {SignatureChecker} from "@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol"; +import {UnstructuredRefStorage} from "../lib//UnstructuredRefStorage.sol"; + +/// @author arwer13, kovalgek +abstract contract PermitExtension is IERC2612, EIP712 { + using UnstructuredRefStorage for bytes32; + + /// @dev Stores the dynamic metadata of the PermitExtension. Allows safely use of this + /// contract with upgradable proxies + struct EIP5267Metadata { + string name; + string version; + } + + /// @dev user nonce slot position. + bytes32 internal constant NONCE_BY_ADDRESS_POSITION = keccak256("PermitExtension.NONCE_BY_ADDRESS_POSITION"); + + /// @dev Typehash constant for ERC-2612 (Permit) + /// keccak256("Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)") + bytes32 internal constant PERMIT_TYPEHASH = + 0x6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9; + + /// @dev Location of the slot with EIP5267Metadata + bytes32 private constant EIP5267_METADATA_SLOT = keccak256("PermitExtension.eip5267MetadataSlot"); + + /// @param name_ The name of the token + /// @param version_ The current major version of the signing domain (aka token version) + constructor(string memory name_, string memory version_) EIP712(name_, version_) { + _initializeEIP5267Metadata(name_, version_); + } + + /// @notice Sets `value_` as the allowance of `spender_` over `owner_`'s tokens, given `owner_`'s signed approval. + /// @param owner_ Token owner's address (Authorizer). Cannot be the zero address. + /// @param spender_ An address of the tokens spender. Cannot be the zero address. + /// @param value_ An amount of tokens to allow to spend. + /// @param deadline_ The time at which the signature expires (unix time). Must be a timestamp in the future. + /// @param v_, r_, s_ must be a valid `secp256k1` signature from `owner` + /// over the EIP712-formatted function arguments. + /// The signature must use ``owner``'s current nonce (see {nonces}). + function permit( + address owner_, + address spender_, + uint256 value_, + uint256 deadline_, + uint8 v_, + bytes32 r_, + bytes32 s_ + ) external { + _permit(owner_, spender_, value_, deadline_, abi.encodePacked(r_, s_, v_)); + } + + /// @notice Sets `value_` as the allowance of `spender_` over `owner_`'s tokens, given `owner_`'s signed approval. + /// @param owner_ Token owner's address (Authorizer). Cannot be the zero address. + /// @param spender_ An address of the tokens spender. Cannot be the zero address. + /// @param value_ An amount of tokens to allow to spend. + /// @param deadline_ The time at which the signature expires (unix time). Must be a timestamp in the future. + /// @param signature_ Unstructured bytes signature signed by an EOA wallet or a contract wallet. + function permit( + address owner_, + address spender_, + uint256 value_, + uint256 deadline_, + bytes calldata signature_ + ) external { + _permit(owner_, spender_, value_, deadline_, signature_); + } + + function _permit( + address owner_, + address spender_, + uint256 value_, + uint256 deadline_, + bytes memory signature_ + ) internal { + if (block.timestamp > deadline_) { + revert ErrorDeadlineExpired(); + } + + bytes32 hash = _hashTypedDataV4( + keccak256( + abi.encode(PERMIT_TYPEHASH, owner_, spender_, value_, _useNonce(owner_), deadline_) + ) + ); + + if (!SignatureChecker.isValidSignatureNow(owner_, hash, signature_)) { + revert ErrorInvalidSignature(); + } + + _permitAccepted(owner_, spender_, value_); + } + + /// @dev Returns the current nonce for `owner`. This value must be + /// included whenever a signature is generated for {permit}. + /// + /// Every successful call to {permit} increases ``owner``'s nonce by one. This + /// prevents a signature from being used multiple times. + /// + function nonces(address owner) external view returns (uint256) { + return _getNonceByAddress()[owner]; + } + + /// @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}. + // solhint-disable-next-line func-name-mixedcase + function DOMAIN_SEPARATOR() external view returns (bytes32) { + return _domainSeparatorV4(); + } + + /// @dev EIP-5267. Returns the fields and values that describe the domain separator + /// used by this contract for EIP-712 signature. + function eip712Domain() + external + view + virtual + returns ( + bytes1 fields, + string memory name, + string memory version, + uint256 chainId, + address verifyingContract, + bytes32 salt, + uint256[] memory extensions + ) + { + return ( + hex"0f", // 01111 + _loadEIP5267Metadata().name, + _loadEIP5267Metadata().version, + block.chainid, + address(this), + bytes32(0), + new uint256[](0) + ); + } + + /// @notice Sets the name and the version of the tokens if they both are empty + /// @param name_ The name of the token + /// @param version_ The version of the token + function _initializeEIP5267Metadata(string memory name_, string memory version_) internal { + _setEIP5267MetadataName(name_); + _setEIP5267MetadataVersion(version_); + } + + /// @dev "Consume a nonce": return the current value and increment. + function _useNonce(address _owner) internal returns (uint256 current) { + current = _getNonceByAddress()[_owner]; + _getNonceByAddress()[_owner] = current + 1; + } + + /// @notice Nonces for ERC-2612 (Permit) + function _getNonceByAddress() internal pure returns (mapping(address => uint256) storage) { + return NONCE_BY_ADDRESS_POSITION.storageMapAddressAddressUint256(); + } + + /// @dev Override this function in the inherited contract to invoke the approve() function of ERC20. + function _permitAccepted(address owner_, address spender_, uint256 amount_) internal virtual; + + /// @dev Sets the name of the token. Might be called only when the name is empty + function _setEIP5267MetadataName(string memory name_) internal { + _loadEIP5267Metadata().name = name_; + } + + /// @dev Sets the version of the token. Might be called only when the version is empty + function _setEIP5267MetadataVersion(string memory version_) internal { + _loadEIP5267Metadata().version = version_; + } + + /// @dev Returns the reference to the slot with EIP5267Metadata struct + function _loadEIP5267Metadata() private pure returns (EIP5267Metadata storage r) { + bytes32 slot = EIP5267_METADATA_SLOT; + assembly { + r.slot := slot + } + } + + error ErrorInvalidSignature(); + error ErrorDeadlineExpired(); +} diff --git a/contracts/token/interfaces/IERC20Bridged.sol b/contracts/token/interfaces/IERC20Bridged.sol deleted file mode 100644 index f29633d9..00000000 --- a/contracts/token/interfaces/IERC20Bridged.sol +++ /dev/null @@ -1,23 +0,0 @@ -// SPDX-FileCopyrightText: 2022 Lido -// SPDX-License-Identifier: GPL-3.0 - -pragma solidity 0.8.10; - -import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; - -/// @author psirex -/// @notice Extends the ERC20 functionality that allows the bridge to mint/burn tokens -interface IERC20Bridged is IERC20 { - /// @notice Returns bridge which can mint and burn tokens on L2 - function bridge() external view returns (address); - - /// @notice Creates amount_ tokens and assigns them to account_, increasing the total supply - /// @param account_ An address of the account to mint tokens - /// @param amount_ An amount of tokens to mint - function bridgeMint(address account_, uint256 amount_) external; - - /// @notice Destroys amount_ tokens from account_, reducing the total supply - /// @param account_ An address of the account to burn tokens - /// @param amount_ An amount of tokens to burn - function bridgeBurn(address account_, uint256 amount_) external; -} diff --git a/contracts/token/interfaces/IERC20Metadata.sol b/contracts/token/interfaces/IERC20Metadata.sol deleted file mode 100644 index a7c82d00..00000000 --- a/contracts/token/interfaces/IERC20Metadata.sol +++ /dev/null @@ -1,17 +0,0 @@ -// SPDX-FileCopyrightText: 2022 Lido -// SPDX-License-Identifier: GPL-3.0 - -pragma solidity 0.8.10; - -/// @author psirex -/// @notice Interface for the optional metadata functions from the ERC20 standard. -interface IERC20Metadata { - /// @dev Returns the name of the token. - function name() external view returns (string memory); - - /// @dev Returns the symbol of the token. - function symbol() external view returns (string memory); - - /// @dev Returns the decimals places of the token. - function decimals() external view returns (uint8); -} diff --git a/contracts/token/interfaces/IERC20Wrapper.sol b/contracts/token/interfaces/IERC20Wrapper.sol new file mode 100644 index 00000000..c443f3cd --- /dev/null +++ b/contracts/token/interfaces/IERC20Wrapper.sol @@ -0,0 +1,19 @@ +// SPDX-FileCopyrightText: 2024 Lido +// SPDX-License-Identifier: GPL-3.0 + +pragma solidity 0.8.10; + +/// @author kovalgek +/// @notice Extends the ERC20 functionality that allows to wrap/unwrap token. +interface IERC20Wrapper { + + /// @notice Exchanges wrappable token to wrapper one. + /// @param wrappableTokenAmount_ amount of wrappable token to wrap. + /// @return Amount of wrapper token user receives after wrap. + function wrap(uint256 wrappableTokenAmount_) external returns (uint256); + + /// @notice Exchanges wrapper token to wrappable one. + /// @param wrapperTokenAmount_ amount of wrapper token to uwrap in exchange for wrappable. + /// @return Amount of wrappable token user receives after unwrap. + function unwrap(uint256 wrapperTokenAmount_) external returns (uint256); +} diff --git a/contracts/utils/Versioned.sol b/contracts/utils/Versioned.sol new file mode 100644 index 00000000..48e1b0a1 --- /dev/null +++ b/contracts/utils/Versioned.sol @@ -0,0 +1,62 @@ +// SPDX-FileCopyrightText: 2022 Lido +// SPDX-License-Identifier: GPL-3.0 + +pragma solidity 0.8.10; + +import {UnstructuredStorage} from "../lib/UnstructuredStorage.sol"; + +/// @dev A copy of Versioned.sol contract from Lido on Ethereum protocol +/// https://github.com/lidofinance/lido-dao/blob/master/contracts/0.8.9/utils/Versioned.sol +contract Versioned { + using UnstructuredStorage for bytes32; + + event ContractVersionSet(uint256 version); + + error NonZeroContractVersionOnInit(); + error InvalidContractVersionIncrement(); + error UnexpectedContractVersion(uint256 expected, uint256 received); + + /// @dev Storage slot: uint256 version + /// Version of the initialized contract storage. + /// The version stored in CONTRACT_VERSION_POSITION equals to: + /// - 0 right after the deployment, before an initializer is invoked (and only at that moment); + /// - N after calling initialize(), where N is the initially deployed contract version; + /// - N after upgrading contract by calling finalizeUpgrade_vN(). + bytes32 internal constant CONTRACT_VERSION_POSITION = keccak256("lido.Versioned.contractVersion"); + + uint256 internal constant PETRIFIED_VERSION_MARK = type(uint256).max; + + constructor() { + // lock version in the implementation's storage to prevent initialization + CONTRACT_VERSION_POSITION.setStorageUint256(PETRIFIED_VERSION_MARK); + } + + /// @notice Returns the current contract version. + function getContractVersion() public view returns (uint256) { + return CONTRACT_VERSION_POSITION.getStorageUint256(); + } + + function _checkContractVersion(uint256 version) internal view { + uint256 expectedVersion = getContractVersion(); + if (version != expectedVersion) { + revert UnexpectedContractVersion(expectedVersion, version); + } + } + + /// @dev Sets the contract version to N. Should be called from the initialize() function. + function _initializeContractVersionTo(uint256 version) internal { + if (getContractVersion() != 0) revert NonZeroContractVersionOnInit(); + _setContractVersion(version); + } + + /// @dev Updates the contract version. Should be called from a finalizeUpgrade_vN() function. + function _updateContractVersion(uint256 newVersion) internal { + if (newVersion != getContractVersion() + 1) revert InvalidContractVersionIncrement(); + _setContractVersion(newVersion); + } + + function _setContractVersion(uint256 version) private { + CONTRACT_VERSION_POSITION.setStorageUint256(version); + emit ContractVersionSet(version); + } +} diff --git a/hardhat.config.ts b/hardhat.config.ts index ed47221c..83cac4bd 100644 --- a/hardhat.config.ts +++ b/hardhat.config.ts @@ -15,15 +15,6 @@ dotenv.config(); const config: HardhatUserConfig = { solidity: { compilers: [ - { - version: "0.6.11", - settings: { - optimizer: { - enabled: true, - runs: 100, - }, - }, - }, { version: "0.8.10", settings: { @@ -52,22 +43,6 @@ const config: HardhatUserConfig = { url: "http://localhost:8545", }, - // Arbitrum Public Chains - arb_mainnet: { - url: env.string("RPC_ARB_MAINNET", ""), - }, - arb_sepolia: { - url: env.string("RPC_ARB_SEPOLIA", ""), - }, - - // Arbitrum Fork Chains - arb_mainnet_fork: { - url: "http://localhost:8546", - }, - arb_sepolia_fork: { - url: "http://localhost:8546", - }, - // Optimism Public Chains opt_mainnet: { url: env.string("RPC_OPT_MAINNET", ""), @@ -92,7 +67,6 @@ const config: HardhatUserConfig = { apiKey: { mainnet: env.string("ETHERSCAN_API_KEY_ETH", ""), sepolia: env.string("ETHERSCAN_API_KEY_ETH", ""), - arbitrumOne: env.string("ETHERSCAN_API_KEY_ARB", ""), optimisticEthereum: env.string("ETHERSCAN_API_KEY_OPT", ""), "opt_sepolia": env.string("ETHERSCAN_API_KEY_OPT", ""), }, @@ -120,7 +94,6 @@ const config: HardhatUserConfig = { externalArtifacts: [ "./interfaces/**/*.json", "./utils/optimism/artifacts/*.json", - "./utils/arbitrum/artifacts/*.json", ], }, mocha: { diff --git a/interfaces/arbitrum/Bridge.json b/interfaces/arbitrum/Bridge.json deleted file mode 100644 index fbbbd6f5..00000000 --- a/interfaces/arbitrum/Bridge.json +++ /dev/null @@ -1,265 +0,0 @@ -[ - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "outbox", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "destAddr", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "amount", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "bytes", - "name": "data", - "type": "bytes" - } - ], - "name": "BridgeCallTriggered", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "inbox", - "type": "address" - }, - { - "indexed": false, - "internalType": "bool", - "name": "enabled", - "type": "bool" - } - ], - "name": "InboxToggle", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "uint256", - "name": "messageIndex", - "type": "uint256" - }, - { - "indexed": true, - "internalType": "bytes32", - "name": "beforeInboxAcc", - "type": "bytes32" - }, - { - "indexed": false, - "internalType": "address", - "name": "inbox", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint8", - "name": "kind", - "type": "uint8" - }, - { - "indexed": false, - "internalType": "address", - "name": "sender", - "type": "address" - }, - { - "indexed": false, - "internalType": "bytes32", - "name": "messageDataHash", - "type": "bytes32" - } - ], - "name": "MessageDelivered", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "outbox", - "type": "address" - }, - { - "indexed": false, - "internalType": "bool", - "name": "enabled", - "type": "bool" - } - ], - "name": "OutboxToggle", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "previousOwner", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "newOwner", - "type": "address" - } - ], - "name": "OwnershipTransferred", - "type": "event" - }, - { - "inputs": [], - "name": "activeOutbox", - "outputs": [{ "internalType": "address", "name": "", "type": "address" }], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], - "name": "allowedInboxList", - "outputs": [{ "internalType": "address", "name": "", "type": "address" }], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { "internalType": "address", "name": "inbox", "type": "address" } - ], - "name": "allowedInboxes", - "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], - "name": "allowedOutboxList", - "outputs": [{ "internalType": "address", "name": "", "type": "address" }], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { "internalType": "address", "name": "outbox", "type": "address" } - ], - "name": "allowedOutboxes", - "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { "internalType": "uint8", "name": "kind", "type": "uint8" }, - { "internalType": "address", "name": "sender", "type": "address" }, - { - "internalType": "bytes32", - "name": "messageDataHash", - "type": "bytes32" - } - ], - "name": "deliverMessageToInbox", - "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [ - { "internalType": "address", "name": "destAddr", "type": "address" }, - { "internalType": "uint256", "name": "amount", "type": "uint256" }, - { "internalType": "bytes", "name": "data", "type": "bytes" } - ], - "name": "executeCall", - "outputs": [ - { "internalType": "bool", "name": "success", "type": "bool" }, - { "internalType": "bytes", "name": "returnData", "type": "bytes" } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], - "name": "inboxAccs", - "outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "initialize", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "messageCount", - "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "owner", - "outputs": [{ "internalType": "address", "name": "", "type": "address" }], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "renounceOwnership", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { "internalType": "address", "name": "inbox", "type": "address" }, - { "internalType": "bool", "name": "enabled", "type": "bool" } - ], - "name": "setInbox", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { "internalType": "address", "name": "outbox", "type": "address" }, - { "internalType": "bool", "name": "enabled", "type": "bool" } - ], - "name": "setOutbox", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { "internalType": "address", "name": "newOwner", "type": "address" } - ], - "name": "transferOwnership", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - } -] diff --git a/interfaces/arbitrum/IMessageProvider.json b/interfaces/arbitrum/IMessageProvider.json deleted file mode 100644 index a4ae9c5c..00000000 --- a/interfaces/arbitrum/IMessageProvider.json +++ /dev/null @@ -1,21 +0,0 @@ -[ - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "uint256", - "name": "messageNum", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "bytes", - "name": "data", - "type": "bytes" - } - ], - "name": "InboxMessageDelivered", - "type": "event" - } -] diff --git a/interfaces/arbitrum/Inbox.json b/interfaces/arbitrum/Inbox.json deleted file mode 100644 index 9c224494..00000000 --- a/interfaces/arbitrum/Inbox.json +++ /dev/null @@ -1,328 +0,0 @@ -[ - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "uint256", - "name": "messageNum", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "bytes", - "name": "data", - "type": "bytes" - } - ], - "name": "InboxMessageDelivered", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "uint256", - "name": "messageNum", - "type": "uint256" - } - ], - "name": "InboxMessageDeliveredFromOrigin", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "bool", - "name": "enabled", - "type": "bool" - } - ], - "name": "PauseToggled", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "bool", - "name": "enabled", - "type": "bool" - } - ], - "name": "RewriteToggled", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "address", - "name": "newSource", - "type": "address" - } - ], - "name": "WhitelistSourceUpdated", - "type": "event" - }, - { - "inputs": [], - "name": "bridge", - "outputs": [ - { "internalType": "contract IBridge", "name": "", "type": "address" } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { "internalType": "address", "name": "destAddr", "type": "address" }, - { "internalType": "uint256", "name": "l2CallValue", "type": "uint256" }, - { - "internalType": "uint256", - "name": "maxSubmissionCost", - "type": "uint256" - }, - { - "internalType": "address", - "name": "excessFeeRefundAddress", - "type": "address" - }, - { - "internalType": "address", - "name": "callValueRefundAddress", - "type": "address" - }, - { "internalType": "uint256", "name": "maxGas", "type": "uint256" }, - { "internalType": "uint256", "name": "gasPriceBid", "type": "uint256" }, - { "internalType": "bytes", "name": "data", "type": "bytes" } - ], - "name": "createRetryableTicket", - "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [ - { "internalType": "address", "name": "destAddr", "type": "address" }, - { "internalType": "uint256", "name": "l2CallValue", "type": "uint256" }, - { - "internalType": "uint256", - "name": "maxSubmissionCost", - "type": "uint256" - }, - { - "internalType": "address", - "name": "excessFeeRefundAddress", - "type": "address" - }, - { - "internalType": "address", - "name": "callValueRefundAddress", - "type": "address" - }, - { "internalType": "uint256", "name": "maxGas", "type": "uint256" }, - { "internalType": "uint256", "name": "gasPriceBid", "type": "uint256" }, - { "internalType": "bytes", "name": "data", "type": "bytes" } - ], - "name": "createRetryableTicketNoRefundAliasRewrite", - "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "maxSubmissionCost", - "type": "uint256" - } - ], - "name": "depositEth", - "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "contract IBridge", - "name": "_bridge", - "type": "address" - }, - { "internalType": "address", "name": "_whitelist", "type": "address" } - ], - "name": "initialize", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "isCreateRetryablePaused", - "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "isMaster", - "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "pauseCreateRetryables", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { "internalType": "uint256", "name": "maxGas", "type": "uint256" }, - { "internalType": "uint256", "name": "gasPriceBid", "type": "uint256" }, - { "internalType": "address", "name": "destAddr", "type": "address" }, - { "internalType": "uint256", "name": "amount", "type": "uint256" }, - { "internalType": "bytes", "name": "data", "type": "bytes" } - ], - "name": "sendContractTransaction", - "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { "internalType": "uint256", "name": "maxGas", "type": "uint256" }, - { "internalType": "uint256", "name": "gasPriceBid", "type": "uint256" }, - { "internalType": "address", "name": "destAddr", "type": "address" }, - { "internalType": "bytes", "name": "data", "type": "bytes" } - ], - "name": "sendL1FundedContractTransaction", - "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [ - { "internalType": "uint256", "name": "maxGas", "type": "uint256" }, - { "internalType": "uint256", "name": "gasPriceBid", "type": "uint256" }, - { "internalType": "uint256", "name": "nonce", "type": "uint256" }, - { "internalType": "address", "name": "destAddr", "type": "address" }, - { "internalType": "bytes", "name": "data", "type": "bytes" } - ], - "name": "sendL1FundedUnsignedTransaction", - "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [ - { "internalType": "bytes", "name": "messageData", "type": "bytes" } - ], - "name": "sendL2Message", - "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { "internalType": "bytes", "name": "messageData", "type": "bytes" } - ], - "name": "sendL2MessageFromOrigin", - "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { "internalType": "uint256", "name": "maxGas", "type": "uint256" }, - { "internalType": "uint256", "name": "gasPriceBid", "type": "uint256" }, - { "internalType": "uint256", "name": "nonce", "type": "uint256" }, - { "internalType": "address", "name": "destAddr", "type": "address" }, - { "internalType": "uint256", "name": "amount", "type": "uint256" }, - { "internalType": "bytes", "name": "data", "type": "bytes" } - ], - "name": "sendUnsignedTransaction", - "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "shouldRewriteSender", - "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "startRewriteAddress", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "stopRewriteAddress", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "unpauseCreateRetryables", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { "internalType": "address", "name": "destAddr", "type": "address" }, - { "internalType": "uint256", "name": "l2CallValue", "type": "uint256" }, - { - "internalType": "uint256", - "name": "maxSubmissionCost", - "type": "uint256" - }, - { - "internalType": "address", - "name": "excessFeeRefundAddress", - "type": "address" - }, - { - "internalType": "address", - "name": "callValueRefundAddress", - "type": "address" - }, - { "internalType": "uint256", "name": "maxGas", "type": "uint256" }, - { "internalType": "uint256", "name": "gasPriceBid", "type": "uint256" }, - { "internalType": "bytes", "name": "data", "type": "bytes" } - ], - "name": "unsafeCreateRetryableTicket", - "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [ - { "internalType": "address", "name": "newSource", "type": "address" } - ], - "name": "updateWhitelistSource", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "whitelist", - "outputs": [{ "internalType": "address", "name": "", "type": "address" }], - "stateMutability": "view", - "type": "function" - } -] diff --git a/package-lock.json b/package-lock.json index cfddd6b4..e116e721 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,16 +1,15 @@ { - "name": "lido-l2", - "version": "1.0.0", - "lockfileVersion": 2, + "name": "lido-l2-optimism", + "version": "2.0.0", + "lockfileVersion": 3, "requires": true, "packages": { "": { - "name": "lido-l2", - "version": "1.0.0", + "name": "lido-l2-optimism", + "version": "2.0.0", "license": "ISC", "dependencies": { - "@arbitrum/sdk": "3.1.6", - "@eth-optimism/sdk": "3.2.0", + "@eth-optimism/sdk": "3.2.3", "@ethersproject/providers": "^5.6.8", "@lidofinance/evm-script-decoder": "^0.2.2", "@openzeppelin/contracts": "4.6.0", @@ -37,6 +36,7 @@ "eslint-plugin-prettier": "^3.4.1", "eslint-plugin-promise": "^5.2.0", "ethereum-waffle": "^3.4.4", + "ethereumjs-util": "^7.0.8", "ethers": "^5.6.2", "hardhat": "^2.12.2", "hardhat-gas-reporter": "^1.0.8", @@ -58,22 +58,6 @@ "node": ">=0.10.0" } }, - "node_modules/@arbitrum/sdk": { - "version": "3.1.6", - "resolved": "https://registry.npmjs.org/@arbitrum/sdk/-/sdk-3.1.6.tgz", - "integrity": "sha512-wY7RHmvY26yc/OuwpJY+kjgAmUJZDGDXaQxfSQTp2t6sSFO+8oFFVsKIthBCY2RpDGFUVTGpRjCUEXiuJ6/SFA==", - "dependencies": { - "@ethersproject/address": "^5.0.8", - "@ethersproject/bignumber": "^5.1.1", - "@ethersproject/bytes": "^5.0.8", - "ethers": "^5.1.0" - }, - "engines": { - "node": ">=v11", - "npm": "please-use-yarn", - "yarn": ">= 1.0.0" - } - }, "node_modules/@babel/code-frame": { "version": "7.12.11", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", @@ -84,23 +68,24 @@ } }, "node_modules/@babel/helper-validator-identifier": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.5.tgz", - "integrity": "sha512-aJXu+6lErq8ltp+JhkJUfk1MTGyuA4v7f3pA+BJ5HLfNC6nAQ0Cpi9uOquUj8Hehg0aUiHzWQbOVJGao6ztBAQ==", + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz", + "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==", "dev": true, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/highlight": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.5.tgz", - "integrity": "sha512-BSKlD1hgnedS5XRnGOljZawtag7H1yPfQp0tdNJCHoH6AZ+Pcm9VvkrK59/Yy593Ypg0zMxH2BxD1VPYUQ7UIw==", + "version": "7.24.2", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.2.tgz", + "integrity": "sha512-Yac1ao4flkTxTteCDZLEvdxg2fZfz1v8M4QpaGypq/WPDqg3ijHYbDfs+LG5hvzSoqaSZ9/Z9lKSP3CjZjv+pA==", "dev": true, "dependencies": { - "@babel/helper-validator-identifier": "^7.22.5", - "chalk": "^2.0.0", - "js-tokens": "^4.0.0" + "@babel/helper-validator-identifier": "^7.22.20", + "chalk": "^2.4.2", + "js-tokens": "^4.0.0", + "picocolors": "^1.0.0" }, "engines": { "node": ">=6.9.0" @@ -177,32 +162,6 @@ "node": ">=4" } }, - "node_modules/@chainsafe/as-sha256": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/@chainsafe/as-sha256/-/as-sha256-0.3.1.tgz", - "integrity": "sha512-hldFFYuf49ed7DAakWVXSJODuq3pzJEguD8tQ7h+sGkM18vja+OFoJI9krnGmgzyuZC2ETX0NOIcCTy31v2Mtg==", - "dev": true - }, - "node_modules/@chainsafe/persistent-merkle-tree": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/@chainsafe/persistent-merkle-tree/-/persistent-merkle-tree-0.4.2.tgz", - "integrity": "sha512-lLO3ihKPngXLTus/L7WHKaw9PnNJWizlOF1H9NNzHP6Xvh82vzg9F2bzkXhYIFshMZ2gTCEz8tq6STe7r5NDfQ==", - "dev": true, - "dependencies": { - "@chainsafe/as-sha256": "^0.3.1" - } - }, - "node_modules/@chainsafe/ssz": { - "version": "0.9.4", - "resolved": "https://registry.npmjs.org/@chainsafe/ssz/-/ssz-0.9.4.tgz", - "integrity": "sha512-77Qtg2N1ayqs4Bg/wvnWfg5Bta7iy7IRh8XqXh7oNMeP2HBbBwx8m6yTpA8p0EHItWPEBkgZd5S5/LSlp3GXuQ==", - "dev": true, - "dependencies": { - "@chainsafe/as-sha256": "^0.3.1", - "@chainsafe/persistent-merkle-tree": "^0.4.2", - "case": "^1.6.3" - } - }, "node_modules/@cspotcode/source-map-support": { "version": "0.8.1", "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", @@ -531,10 +490,9 @@ } }, "node_modules/@eth-optimism/sdk": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/@eth-optimism/sdk/-/sdk-3.2.0.tgz", - "integrity": "sha512-+ZEO/mDWz3WLzaPVHvgOAK4iN723HmI6sLLr2tmO1/RUoCHVfWMUDwuiikrA49cAsdsjMxCV9+0XNZ8btD2JUg==", - "hasInstallScript": true, + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/@eth-optimism/sdk/-/sdk-3.2.3.tgz", + "integrity": "sha512-e3XQTbbU+HTzsEv/VIsJpZifK6YZVlzEtF6tj/Vz/VIEDCjZk5JPcnCQOMVcs9ICI4EJyyur+y/+RU7fPa6qtg==", "dependencies": { "@eth-optimism/contracts": "0.6.0", "@eth-optimism/contracts-bedrock": "0.17.1", @@ -542,42 +500,12 @@ "lodash": "^4.17.21", "merkletreejs": "^0.3.11", "rlp": "^2.2.7", - "semver": "^7.5.4" + "semver": "^7.6.0" }, "peerDependencies": { "ethers": "^5" } }, - "node_modules/@eth-optimism/sdk/node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/@eth-optimism/sdk/node_modules/semver": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", - "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/@eth-optimism/sdk/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" - }, "node_modules/@ethereum-waffle/chai": { "version": "3.4.4", "resolved": "https://registry.npmjs.org/@ethereum-waffle/chai/-/chai-3.4.4.tgz", @@ -706,43 +634,15 @@ "ethereumjs-util": "^7.1.5" } }, - "node_modules/@ethereumjs/common/node_modules/ethereum-cryptography": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz", - "integrity": "sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==", - "dev": true, - "dependencies": { - "@types/pbkdf2": "^3.0.0", - "@types/secp256k1": "^4.0.1", - "blakejs": "^1.1.0", - "browserify-aes": "^1.2.0", - "bs58check": "^2.1.2", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "hash.js": "^1.1.7", - "keccak": "^3.0.0", - "pbkdf2": "^3.0.17", - "randombytes": "^2.1.0", - "safe-buffer": "^5.1.2", - "scrypt-js": "^3.0.0", - "secp256k1": "^4.0.1", - "setimmediate": "^1.0.5" - } - }, - "node_modules/@ethereumjs/common/node_modules/ethereumjs-util": { - "version": "7.1.5", - "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-7.1.5.tgz", - "integrity": "sha512-SDl5kKrQAudFBUe5OJM9Ac6WmMyYmXX/6sTmLZ3ffG2eY6ZIGBes3pEDxNN6V72WyOw4CPD5RomKdsa8DAAwLg==", - "dev": true, - "dependencies": { - "@types/bn.js": "^5.1.0", - "bn.js": "^5.1.2", - "create-hash": "^1.1.2", - "ethereum-cryptography": "^0.1.3", - "rlp": "^2.2.4" + "node_modules/@ethereumjs/rlp": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@ethereumjs/rlp/-/rlp-4.0.1.tgz", + "integrity": "sha512-tqsQiBQDQdmPWE1xkkBq4rlSW5QZpLOUJ5RJh2/9fug+q9tnUhuZoVLk7s0scUIKTOzEtR72DFBXI4WiZcMpvw==", + "bin": { + "rlp": "bin/rlp" }, "engines": { - "node": ">=10.0.0" + "node": ">=14" } }, "node_modules/@ethereumjs/tx": { @@ -755,43 +655,39 @@ "ethereumjs-util": "^7.1.5" } }, - "node_modules/@ethereumjs/tx/node_modules/ethereum-cryptography": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz", - "integrity": "sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==", - "dev": true, + "node_modules/@ethereumjs/util": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@ethereumjs/util/-/util-8.1.0.tgz", + "integrity": "sha512-zQ0IqbdX8FZ9aw11vP+dZkKDkS+kgIvQPHnSAXzP9pLu+Rfu3D3XEeLbicvoXJTYnhZiPmsZUxgdzXwNKxRPbA==", "dependencies": { - "@types/pbkdf2": "^3.0.0", - "@types/secp256k1": "^4.0.1", - "blakejs": "^1.1.0", - "browserify-aes": "^1.2.0", - "bs58check": "^2.1.2", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "hash.js": "^1.1.7", - "keccak": "^3.0.0", - "pbkdf2": "^3.0.17", - "randombytes": "^2.1.0", - "safe-buffer": "^5.1.2", - "scrypt-js": "^3.0.0", - "secp256k1": "^4.0.1", - "setimmediate": "^1.0.5" + "@ethereumjs/rlp": "^4.0.1", + "ethereum-cryptography": "^2.0.0", + "micro-ftch": "^0.3.1" + }, + "engines": { + "node": ">=14" } }, - "node_modules/@ethereumjs/tx/node_modules/ethereumjs-util": { - "version": "7.1.5", - "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-7.1.5.tgz", - "integrity": "sha512-SDl5kKrQAudFBUe5OJM9Ac6WmMyYmXX/6sTmLZ3ffG2eY6ZIGBes3pEDxNN6V72WyOw4CPD5RomKdsa8DAAwLg==", - "dev": true, - "dependencies": { - "@types/bn.js": "^5.1.0", - "bn.js": "^5.1.2", - "create-hash": "^1.1.2", - "ethereum-cryptography": "^0.1.3", - "rlp": "^2.2.4" - }, + "node_modules/@ethereumjs/util/node_modules/@noble/hashes": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.3.3.tgz", + "integrity": "sha512-V7/fPHgl+jsVPXqqeOzT8egNj2iBIVt+ECeMMG8TdcnTikP3oaBtUVqpT/gYCR68aEBJSF+XbYUxStjbFMqIIA==", "engines": { - "node": ">=10.0.0" + "node": ">= 16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@ethereumjs/util/node_modules/ethereum-cryptography": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-2.1.3.tgz", + "integrity": "sha512-BlwbIL7/P45W8FGW2r7LGuvoEZ+7PWsniMvQ4p5s2xCyw9tmaDlpfsN9HjAucbF+t/qpVHwZUisgfK24TCW8aA==", + "dependencies": { + "@noble/curves": "1.3.0", + "@noble/hashes": "1.3.3", + "@scure/bip32": "1.3.3", + "@scure/bip39": "1.2.2" } }, "node_modules/@ethersproject/abi": { @@ -1466,9 +1362,9 @@ } }, "node_modules/@fastify/busboy": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@fastify/busboy/-/busboy-2.0.0.tgz", - "integrity": "sha512-JUFJad5lv7jxj926GPgymrWQxxjPYuJNiNjNMzqT+HiuP6Vl3dk5xzG+8sTX96np0ZAluvaMzPsjhHZ5rNuNQQ==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@fastify/busboy/-/busboy-2.1.1.tgz", + "integrity": "sha512-vBZP4NlzfOlerQTnba4aqZoMhE/a9HY7HRqoOPaETQcSQuWEIyZMHGfVu6w9wGtGK5fED5qRs2DteVCjOH60sA==", "dev": true, "engines": { "node": ">=14" @@ -1495,9 +1391,9 @@ "dev": true }, "node_modules/@jridgewell/resolve-uri": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz", - "integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", "dev": true, "engines": { "node": ">=6.0.0" @@ -1544,17 +1440,68 @@ "node": ">=12.0.0" } }, - "node_modules/@noble/hashes": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.2.0.tgz", - "integrity": "sha512-FZfhjEDbT5GRswV3C6uvLPHMiVD6lQBmpoX5+eSiPaMTXte/IKqI5dykDxzZB/WBeK/CDuQRBWarPdi3FNY2zQ==", + "node_modules/@metamask/eth-sig-util/node_modules/@types/bn.js": { + "version": "4.11.6", + "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-4.11.6.tgz", + "integrity": "sha512-pqr857jrp2kPuO9uRjZ3PwnJTjoQy+fcdxvBTvHm6dkmEL9q+hDD/2j/0ELOBPtPnS8LjCX0gI9nbl8lVkadpg==", "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://paulmillr.com/funding/" - } - ] + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@metamask/eth-sig-util/node_modules/bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", + "dev": true + }, + "node_modules/@metamask/eth-sig-util/node_modules/ethereumjs-util": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-6.2.1.tgz", + "integrity": "sha512-W2Ktez4L01Vexijrm5EB6w7dg4n/TgpoYU4avuT5T3Vmnw/eCRtiBrJfQYS/DCSvDIOLn2k57GcHdeBcgVxAqw==", + "dev": true, + "dependencies": { + "@types/bn.js": "^4.11.3", + "bn.js": "^4.11.0", + "create-hash": "^1.1.2", + "elliptic": "^6.5.2", + "ethereum-cryptography": "^0.1.3", + "ethjs-util": "0.1.6", + "rlp": "^2.2.3" + } + }, + "node_modules/@noble/curves": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.3.0.tgz", + "integrity": "sha512-t01iSXPuN+Eqzb4eBX0S5oubSqXbK/xXa1Ne18Hj8f9pStxztHCE2gfboSp/dZRLSqfuLpRK2nDXDK+W9puocA==", + "dependencies": { + "@noble/hashes": "1.3.3" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@noble/curves/node_modules/@noble/hashes": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.3.3.tgz", + "integrity": "sha512-V7/fPHgl+jsVPXqqeOzT8egNj2iBIVt+ECeMMG8TdcnTikP3oaBtUVqpT/gYCR68aEBJSF+XbYUxStjbFMqIIA==", + "engines": { + "node": ">= 16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@noble/hashes": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.4.0.tgz", + "integrity": "sha512-V1JJ1WTRUqHHrOSh597hURcMqVKVGL/ea3kv0gSnEdsEZ0/+VyPghM1lMNGc00z7CIQorSvbKpuJkxvuHbvdbg==", + "engines": { + "node": ">= 16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } }, "node_modules/@noble/secp256k1": { "version": "1.7.1", @@ -1603,415 +1550,199 @@ "node": ">= 8" } }, - "node_modules/@nomicfoundation/ethereumjs-block": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-block/-/ethereumjs-block-5.0.1.tgz", - "integrity": "sha512-u1Yioemi6Ckj3xspygu/SfFvm8vZEO8/Yx5a1QLzi6nVU0jz3Pg2OmHKJ5w+D9Ogk1vhwRiqEBAqcb0GVhCyHw==", + "node_modules/@nomicfoundation/edr": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/@nomicfoundation/edr/-/edr-0.3.5.tgz", + "integrity": "sha512-dPSM9DuI1sr71gqWUMgLo8MjHQWO4+WNDm3iWaT6P4vUFJReZX5qwA5X+3UwIPBry8GvNY084u7yWUvB3/8rqA==", "dev": true, - "dependencies": { - "@nomicfoundation/ethereumjs-common": "4.0.1", - "@nomicfoundation/ethereumjs-rlp": "5.0.1", - "@nomicfoundation/ethereumjs-trie": "6.0.1", - "@nomicfoundation/ethereumjs-tx": "5.0.1", - "@nomicfoundation/ethereumjs-util": "9.0.1", - "ethereum-cryptography": "0.1.3", - "ethers": "^5.7.1" + "engines": { + "node": ">= 18" }, + "optionalDependencies": { + "@nomicfoundation/edr-darwin-arm64": "0.3.5", + "@nomicfoundation/edr-darwin-x64": "0.3.5", + "@nomicfoundation/edr-linux-arm64-gnu": "0.3.5", + "@nomicfoundation/edr-linux-arm64-musl": "0.3.5", + "@nomicfoundation/edr-linux-x64-gnu": "0.3.5", + "@nomicfoundation/edr-linux-x64-musl": "0.3.5", + "@nomicfoundation/edr-win32-x64-msvc": "0.3.5" + } + }, + "node_modules/@nomicfoundation/edr-darwin-arm64": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/@nomicfoundation/edr-darwin-arm64/-/edr-darwin-arm64-0.3.5.tgz", + "integrity": "sha512-gIXUIiPMUy6roLHpNlxf15DumU7/YhffUf7XIB+WUjMecaySfTGyZsTGnCMJZqrDyiYqWPyPKwCV/2u/jqFAUg==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], "engines": { - "node": ">=14" + "node": ">= 18" } }, - "node_modules/@nomicfoundation/ethereumjs-block/node_modules/ethereum-cryptography": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz", - "integrity": "sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==", + "node_modules/@nomicfoundation/edr-darwin-x64": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/@nomicfoundation/edr-darwin-x64/-/edr-darwin-x64-0.3.5.tgz", + "integrity": "sha512-0MrpOCXUK8gmplpYZ2Cy0holHEylvWoNeecFcrP2WJ5DLQzrB23U5JU2MvUzOJ7aL76Za1VXNBWi/UeTWdHM+w==", + "cpu": [ + "x64" + ], "dev": true, - "dependencies": { - "@types/pbkdf2": "^3.0.0", - "@types/secp256k1": "^4.0.1", - "blakejs": "^1.1.0", - "browserify-aes": "^1.2.0", - "bs58check": "^2.1.2", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "hash.js": "^1.1.7", - "keccak": "^3.0.0", - "pbkdf2": "^3.0.17", - "randombytes": "^2.1.0", - "safe-buffer": "^5.1.2", - "scrypt-js": "^3.0.0", - "secp256k1": "^4.0.1", - "setimmediate": "^1.0.5" + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 18" } }, - "node_modules/@nomicfoundation/ethereumjs-blockchain": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-blockchain/-/ethereumjs-blockchain-7.0.1.tgz", - "integrity": "sha512-NhzndlGg829XXbqJEYrF1VeZhAwSPgsK/OB7TVrdzft3y918hW5KNd7gIZ85sn6peDZOdjBsAXIpXZ38oBYE5A==", - "dev": true, - "dependencies": { - "@nomicfoundation/ethereumjs-block": "5.0.1", - "@nomicfoundation/ethereumjs-common": "4.0.1", - "@nomicfoundation/ethereumjs-ethash": "3.0.1", - "@nomicfoundation/ethereumjs-rlp": "5.0.1", - "@nomicfoundation/ethereumjs-trie": "6.0.1", - "@nomicfoundation/ethereumjs-tx": "5.0.1", - "@nomicfoundation/ethereumjs-util": "9.0.1", - "abstract-level": "^1.0.3", - "debug": "^4.3.3", - "ethereum-cryptography": "0.1.3", - "level": "^8.0.0", - "lru-cache": "^5.1.1", - "memory-level": "^1.0.0" - }, + "node_modules/@nomicfoundation/edr-linux-arm64-gnu": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/@nomicfoundation/edr-linux-arm64-gnu/-/edr-linux-arm64-gnu-0.3.5.tgz", + "integrity": "sha512-aw9f7AZMiY1dZFNePJGKho2k+nEgFgzUAyyukiKfSqUIMXoFXMf1U3Ujv848czrSq9c5XGcdDa2xnEf3daU3xg==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=14" + "node": ">= 18" } }, - "node_modules/@nomicfoundation/ethereumjs-blockchain/node_modules/ethereum-cryptography": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz", - "integrity": "sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==", + "node_modules/@nomicfoundation/edr-linux-arm64-musl": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/@nomicfoundation/edr-linux-arm64-musl/-/edr-linux-arm64-musl-0.3.5.tgz", + "integrity": "sha512-cVFRQjyABBlsbDj+XTczYBfrCHprZ6YNzN8gGGSqAh+UGIJkAIRomK6ar27GyJLNx3HkgbuDoi/9kA0zOo/95w==", + "cpu": [ + "arm64" + ], "dev": true, - "dependencies": { - "@types/pbkdf2": "^3.0.0", - "@types/secp256k1": "^4.0.1", - "blakejs": "^1.1.0", - "browserify-aes": "^1.2.0", - "bs58check": "^2.1.2", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "hash.js": "^1.1.7", - "keccak": "^3.0.0", - "pbkdf2": "^3.0.17", - "randombytes": "^2.1.0", - "safe-buffer": "^5.1.2", - "scrypt-js": "^3.0.0", - "secp256k1": "^4.0.1", - "setimmediate": "^1.0.5" - } - }, - "node_modules/@nomicfoundation/ethereumjs-common": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-common/-/ethereumjs-common-4.0.1.tgz", - "integrity": "sha512-OBErlkfp54GpeiE06brBW/TTbtbuBJV5YI5Nz/aB2evTDo+KawyEzPjBlSr84z/8MFfj8wS2wxzQX1o32cev5g==", - "dev": true, - "dependencies": { - "@nomicfoundation/ethereumjs-util": "9.0.1", - "crc-32": "^1.2.0" + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 18" } }, - "node_modules/@nomicfoundation/ethereumjs-ethash": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-ethash/-/ethereumjs-ethash-3.0.1.tgz", - "integrity": "sha512-KDjGIB5igzWOp8Ik5I6QiRH5DH+XgILlplsHR7TEuWANZA759G6krQ6o8bvj+tRUz08YygMQu/sGd9mJ1DYT8w==", + "node_modules/@nomicfoundation/edr-linux-x64-gnu": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/@nomicfoundation/edr-linux-x64-gnu/-/edr-linux-x64-gnu-0.3.5.tgz", + "integrity": "sha512-CjOg85DfR1Vt0fQWn5U0qi26DATK9tVzo3YOZEyI0JBsnqvk43fUTPv3uUAWBrPIRg5O5kOc9xG13hSpCBBxBg==", + "cpu": [ + "x64" + ], "dev": true, - "dependencies": { - "@nomicfoundation/ethereumjs-block": "5.0.1", - "@nomicfoundation/ethereumjs-rlp": "5.0.1", - "@nomicfoundation/ethereumjs-util": "9.0.1", - "abstract-level": "^1.0.3", - "bigint-crypto-utils": "^3.0.23", - "ethereum-cryptography": "0.1.3" - }, + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=14" + "node": ">= 18" } }, - "node_modules/@nomicfoundation/ethereumjs-ethash/node_modules/ethereum-cryptography": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz", - "integrity": "sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==", + "node_modules/@nomicfoundation/edr-linux-x64-musl": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/@nomicfoundation/edr-linux-x64-musl/-/edr-linux-x64-musl-0.3.5.tgz", + "integrity": "sha512-hvX8bBGpBydAVevzK8jsu2FlqVZK1RrCyTX6wGHnltgMuBaoGLHYtNHiFpteOaJw2byYMiORc2bvj+98LhJ0Ew==", + "cpu": [ + "x64" + ], "dev": true, - "dependencies": { - "@types/pbkdf2": "^3.0.0", - "@types/secp256k1": "^4.0.1", - "blakejs": "^1.1.0", - "browserify-aes": "^1.2.0", - "bs58check": "^2.1.2", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "hash.js": "^1.1.7", - "keccak": "^3.0.0", - "pbkdf2": "^3.0.17", - "randombytes": "^2.1.0", - "safe-buffer": "^5.1.2", - "scrypt-js": "^3.0.0", - "secp256k1": "^4.0.1", - "setimmediate": "^1.0.5" + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 18" } }, - "node_modules/@nomicfoundation/ethereumjs-evm": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-evm/-/ethereumjs-evm-2.0.1.tgz", - "integrity": "sha512-oL8vJcnk0Bx/onl+TgQOQ1t/534GKFaEG17fZmwtPFeH8S5soiBYPCLUrvANOl4sCp9elYxIMzIiTtMtNNN8EQ==", + "node_modules/@nomicfoundation/edr-win32-x64-msvc": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/@nomicfoundation/edr-win32-x64-msvc/-/edr-win32-x64-msvc-0.3.5.tgz", + "integrity": "sha512-IJXjW13DY5UPsx/eG5DGfXtJ7Ydwrvw/BTZ2Y93lRLHzszVpSmeVmlxjZP5IW2afTSgMLaAAsqNw4NhppRGN8A==", + "cpu": [ + "x64" + ], "dev": true, - "dependencies": { - "@ethersproject/providers": "^5.7.1", - "@nomicfoundation/ethereumjs-common": "4.0.1", - "@nomicfoundation/ethereumjs-tx": "5.0.1", - "@nomicfoundation/ethereumjs-util": "9.0.1", - "debug": "^4.3.3", - "ethereum-cryptography": "0.1.3", - "mcl-wasm": "^0.7.1", - "rustbn.js": "~0.2.0" - }, + "optional": true, + "os": [ + "win32" + ], "engines": { - "node": ">=14" + "node": ">= 18" } }, - "node_modules/@nomicfoundation/ethereumjs-evm/node_modules/ethereum-cryptography": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz", - "integrity": "sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==", + "node_modules/@nomicfoundation/ethereumjs-common": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-common/-/ethereumjs-common-4.0.4.tgz", + "integrity": "sha512-9Rgb658lcWsjiicr5GzNCjI1llow/7r0k50dLL95OJ+6iZJcVbi15r3Y0xh2cIO+zgX0WIHcbzIu6FeQf9KPrg==", "dev": true, "dependencies": { - "@types/pbkdf2": "^3.0.0", - "@types/secp256k1": "^4.0.1", - "blakejs": "^1.1.0", - "browserify-aes": "^1.2.0", - "bs58check": "^2.1.2", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "hash.js": "^1.1.7", - "keccak": "^3.0.0", - "pbkdf2": "^3.0.17", - "randombytes": "^2.1.0", - "safe-buffer": "^5.1.2", - "scrypt-js": "^3.0.0", - "secp256k1": "^4.0.1", - "setimmediate": "^1.0.5" + "@nomicfoundation/ethereumjs-util": "9.0.4" } }, "node_modules/@nomicfoundation/ethereumjs-rlp": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-rlp/-/ethereumjs-rlp-5.0.1.tgz", - "integrity": "sha512-xtxrMGa8kP4zF5ApBQBtjlSbN5E2HI8m8FYgVSYAnO6ssUoY5pVPGy2H8+xdf/bmMa22Ce8nWMH3aEW8CcqMeQ==", + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-rlp/-/ethereumjs-rlp-5.0.4.tgz", + "integrity": "sha512-8H1S3s8F6QueOc/X92SdrA4RDenpiAEqMg5vJH99kcQaCy/a3Q6fgseo75mgWlbanGJXSlAPtnCeG9jvfTYXlw==", "dev": true, "bin": { - "rlp": "bin/rlp" - }, - "engines": { - "node": ">=14" - } - }, - "node_modules/@nomicfoundation/ethereumjs-statemanager": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-statemanager/-/ethereumjs-statemanager-2.0.1.tgz", - "integrity": "sha512-B5ApMOnlruVOR7gisBaYwFX+L/AP7i/2oAahatssjPIBVDF6wTX1K7Qpa39E/nzsH8iYuL3krkYeUFIdO3EMUQ==", - "dev": true, - "dependencies": { - "@nomicfoundation/ethereumjs-common": "4.0.1", - "@nomicfoundation/ethereumjs-rlp": "5.0.1", - "debug": "^4.3.3", - "ethereum-cryptography": "0.1.3", - "ethers": "^5.7.1", - "js-sdsl": "^4.1.4" - } - }, - "node_modules/@nomicfoundation/ethereumjs-statemanager/node_modules/ethereum-cryptography": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz", - "integrity": "sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==", - "dev": true, - "dependencies": { - "@types/pbkdf2": "^3.0.0", - "@types/secp256k1": "^4.0.1", - "blakejs": "^1.1.0", - "browserify-aes": "^1.2.0", - "bs58check": "^2.1.2", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "hash.js": "^1.1.7", - "keccak": "^3.0.0", - "pbkdf2": "^3.0.17", - "randombytes": "^2.1.0", - "safe-buffer": "^5.1.2", - "scrypt-js": "^3.0.0", - "secp256k1": "^4.0.1", - "setimmediate": "^1.0.5" - } - }, - "node_modules/@nomicfoundation/ethereumjs-trie": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-trie/-/ethereumjs-trie-6.0.1.tgz", - "integrity": "sha512-A64It/IMpDVODzCgxDgAAla8jNjNtsoQZIzZUfIV5AY6Coi4nvn7+VReBn5itlxMiL2yaTlQr9TRWp3CSI6VoA==", - "dev": true, - "dependencies": { - "@nomicfoundation/ethereumjs-rlp": "5.0.1", - "@nomicfoundation/ethereumjs-util": "9.0.1", - "@types/readable-stream": "^2.3.13", - "ethereum-cryptography": "0.1.3", - "readable-stream": "^3.6.0" + "rlp": "bin/rlp.cjs" }, "engines": { - "node": ">=14" - } - }, - "node_modules/@nomicfoundation/ethereumjs-trie/node_modules/ethereum-cryptography": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz", - "integrity": "sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==", - "dev": true, - "dependencies": { - "@types/pbkdf2": "^3.0.0", - "@types/secp256k1": "^4.0.1", - "blakejs": "^1.1.0", - "browserify-aes": "^1.2.0", - "bs58check": "^2.1.2", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "hash.js": "^1.1.7", - "keccak": "^3.0.0", - "pbkdf2": "^3.0.17", - "randombytes": "^2.1.0", - "safe-buffer": "^5.1.2", - "scrypt-js": "^3.0.0", - "secp256k1": "^4.0.1", - "setimmediate": "^1.0.5" + "node": ">=18" } }, "node_modules/@nomicfoundation/ethereumjs-tx": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-tx/-/ethereumjs-tx-5.0.1.tgz", - "integrity": "sha512-0HwxUF2u2hrsIM1fsasjXvlbDOq1ZHFV2dd1yGq8CA+MEYhaxZr8OTScpVkkxqMwBcc5y83FyPl0J9MZn3kY0w==", + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-tx/-/ethereumjs-tx-5.0.4.tgz", + "integrity": "sha512-Xjv8wAKJGMrP1f0n2PeyfFCCojHd7iS3s/Ab7qzF1S64kxZ8Z22LCMynArYsVqiFx6rzYy548HNVEyI+AYN/kw==", "dev": true, "dependencies": { - "@chainsafe/ssz": "^0.9.2", - "@ethersproject/providers": "^5.7.2", - "@nomicfoundation/ethereumjs-common": "4.0.1", - "@nomicfoundation/ethereumjs-rlp": "5.0.1", - "@nomicfoundation/ethereumjs-util": "9.0.1", + "@nomicfoundation/ethereumjs-common": "4.0.4", + "@nomicfoundation/ethereumjs-rlp": "5.0.4", + "@nomicfoundation/ethereumjs-util": "9.0.4", "ethereum-cryptography": "0.1.3" }, "engines": { - "node": ">=14" - } - }, - "node_modules/@nomicfoundation/ethereumjs-tx/node_modules/ethereum-cryptography": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz", - "integrity": "sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==", - "dev": true, - "dependencies": { - "@types/pbkdf2": "^3.0.0", - "@types/secp256k1": "^4.0.1", - "blakejs": "^1.1.0", - "browserify-aes": "^1.2.0", - "bs58check": "^2.1.2", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "hash.js": "^1.1.7", - "keccak": "^3.0.0", - "pbkdf2": "^3.0.17", - "randombytes": "^2.1.0", - "safe-buffer": "^5.1.2", - "scrypt-js": "^3.0.0", - "secp256k1": "^4.0.1", - "setimmediate": "^1.0.5" + "node": ">=18" + }, + "peerDependencies": { + "c-kzg": "^2.1.2" + }, + "peerDependenciesMeta": { + "c-kzg": { + "optional": true + } } }, "node_modules/@nomicfoundation/ethereumjs-util": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-util/-/ethereumjs-util-9.0.1.tgz", - "integrity": "sha512-TwbhOWQ8QoSCFhV/DDfSmyfFIHjPjFBj957219+V3jTZYZ2rf9PmDtNOeZWAE3p3vlp8xb02XGpd0v6nTUPbsA==", + "version": "9.0.4", + "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-util/-/ethereumjs-util-9.0.4.tgz", + "integrity": "sha512-sLOzjnSrlx9Bb9EFNtHzK/FJFsfg2re6bsGqinFinH1gCqVfz9YYlXiMWwDM4C/L4ywuHFCYwfKTVr/QHQcU0Q==", "dev": true, "dependencies": { - "@chainsafe/ssz": "^0.10.0", - "@nomicfoundation/ethereumjs-rlp": "5.0.1", + "@nomicfoundation/ethereumjs-rlp": "5.0.4", "ethereum-cryptography": "0.1.3" }, "engines": { - "node": ">=14" - } - }, - "node_modules/@nomicfoundation/ethereumjs-util/node_modules/@chainsafe/persistent-merkle-tree": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/@chainsafe/persistent-merkle-tree/-/persistent-merkle-tree-0.5.0.tgz", - "integrity": "sha512-l0V1b5clxA3iwQLXP40zYjyZYospQLZXzBVIhhr9kDg/1qHZfzzHw0jj4VPBijfYCArZDlPkRi1wZaV2POKeuw==", - "dev": true, - "dependencies": { - "@chainsafe/as-sha256": "^0.3.1" - } - }, - "node_modules/@nomicfoundation/ethereumjs-util/node_modules/@chainsafe/ssz": { - "version": "0.10.2", - "resolved": "https://registry.npmjs.org/@chainsafe/ssz/-/ssz-0.10.2.tgz", - "integrity": "sha512-/NL3Lh8K+0q7A3LsiFq09YXS9fPE+ead2rr7vM2QK8PLzrNsw3uqrif9bpRX5UxgeRjM+vYi+boCM3+GM4ovXg==", - "dev": true, - "dependencies": { - "@chainsafe/as-sha256": "^0.3.1", - "@chainsafe/persistent-merkle-tree": "^0.5.0" - } - }, - "node_modules/@nomicfoundation/ethereumjs-util/node_modules/ethereum-cryptography": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz", - "integrity": "sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==", - "dev": true, - "dependencies": { - "@types/pbkdf2": "^3.0.0", - "@types/secp256k1": "^4.0.1", - "blakejs": "^1.1.0", - "browserify-aes": "^1.2.0", - "bs58check": "^2.1.2", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "hash.js": "^1.1.7", - "keccak": "^3.0.0", - "pbkdf2": "^3.0.17", - "randombytes": "^2.1.0", - "safe-buffer": "^5.1.2", - "scrypt-js": "^3.0.0", - "secp256k1": "^4.0.1", - "setimmediate": "^1.0.5" - } - }, - "node_modules/@nomicfoundation/ethereumjs-vm": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-vm/-/ethereumjs-vm-7.0.1.tgz", - "integrity": "sha512-rArhyn0jPsS/D+ApFsz3yVJMQ29+pVzNZ0VJgkzAZ+7FqXSRtThl1C1prhmlVr3YNUlfpZ69Ak+RUT4g7VoOuQ==", - "dev": true, - "dependencies": { - "@nomicfoundation/ethereumjs-block": "5.0.1", - "@nomicfoundation/ethereumjs-blockchain": "7.0.1", - "@nomicfoundation/ethereumjs-common": "4.0.1", - "@nomicfoundation/ethereumjs-evm": "2.0.1", - "@nomicfoundation/ethereumjs-rlp": "5.0.1", - "@nomicfoundation/ethereumjs-statemanager": "2.0.1", - "@nomicfoundation/ethereumjs-trie": "6.0.1", - "@nomicfoundation/ethereumjs-tx": "5.0.1", - "@nomicfoundation/ethereumjs-util": "9.0.1", - "debug": "^4.3.3", - "ethereum-cryptography": "0.1.3", - "mcl-wasm": "^0.7.1", - "rustbn.js": "~0.2.0" + "node": ">=18" }, - "engines": { - "node": ">=14" - } - }, - "node_modules/@nomicfoundation/ethereumjs-vm/node_modules/ethereum-cryptography": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz", - "integrity": "sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==", - "dev": true, - "dependencies": { - "@types/pbkdf2": "^3.0.0", - "@types/secp256k1": "^4.0.1", - "blakejs": "^1.1.0", - "browserify-aes": "^1.2.0", - "bs58check": "^2.1.2", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "hash.js": "^1.1.7", - "keccak": "^3.0.0", - "pbkdf2": "^3.0.17", - "randombytes": "^2.1.0", - "safe-buffer": "^5.1.2", - "scrypt-js": "^3.0.0", - "secp256k1": "^4.0.1", - "setimmediate": "^1.0.5" + "peerDependencies": { + "c-kzg": "^2.1.2" + }, + "peerDependenciesMeta": { + "c-kzg": { + "optional": true + } } }, "node_modules/@nomicfoundation/solidity-analyzer": { @@ -2286,6 +2017,15 @@ "node": ">=4" } }, + "node_modules/@nomiclabs/hardhat-etherscan/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, "node_modules/@nomiclabs/hardhat-etherscan/node_modules/supports-color": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", @@ -2398,48 +2138,58 @@ } }, "node_modules/@scure/base": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@scure/base/-/base-1.1.1.tgz", - "integrity": "sha512-ZxOhsSyxYwLJj3pLZCefNitxsj093tb2vq90mp2txoYeBqbcjDjqFhyM8eUjq/uFm6zJ+mUuqxlS2FkuSY1MTA==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://paulmillr.com/funding/" - } - ] + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/@scure/base/-/base-1.1.6.tgz", + "integrity": "sha512-ok9AWwhcgYuGG3Zfhyqg+zwl+Wn5uE+dwC0NV/2qQkx4dABbb/bx96vWu8NSj+BNjjSjno+JRYRjle1jV08k3g==", + "funding": { + "url": "https://paulmillr.com/funding/" + } }, "node_modules/@scure/bip32": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/@scure/bip32/-/bip32-1.1.5.tgz", - "integrity": "sha512-XyNh1rB0SkEqd3tXcXMi+Xe1fvg+kUIcoRIEujP1Jgv7DqW2r9lg3Ah0NkFaCs9sTkQAQA8kw7xiRXzENi9Rtw==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://paulmillr.com/funding/" - } - ], + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/@scure/bip32/-/bip32-1.3.3.tgz", + "integrity": "sha512-LJaN3HwRbfQK0X1xFSi0Q9amqOgzQnnDngIt+ZlsBC3Bm7/nE7K0kwshZHyaru79yIVRv/e1mQAjZyuZG6jOFQ==", "dependencies": { - "@noble/hashes": "~1.2.0", - "@noble/secp256k1": "~1.7.0", - "@scure/base": "~1.1.0" + "@noble/curves": "~1.3.0", + "@noble/hashes": "~1.3.2", + "@scure/base": "~1.1.4" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@scure/bip32/node_modules/@noble/hashes": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.3.3.tgz", + "integrity": "sha512-V7/fPHgl+jsVPXqqeOzT8egNj2iBIVt+ECeMMG8TdcnTikP3oaBtUVqpT/gYCR68aEBJSF+XbYUxStjbFMqIIA==", + "engines": { + "node": ">= 16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" } }, "node_modules/@scure/bip39": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@scure/bip39/-/bip39-1.1.1.tgz", - "integrity": "sha512-t+wDck2rVkh65Hmv280fYdVdY25J9YeEUIgn2LG1WM6gxFkGzcksoDiUkWVpVp3Oex9xGC68JU2dSbUfwZ2jPg==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://paulmillr.com/funding/" - } - ], + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@scure/bip39/-/bip39-1.2.2.tgz", + "integrity": "sha512-HYf9TUXG80beW+hGAt3TRM8wU6pQoYur9iNypTROm42dorCGmLnFe3eWjz3gOq6G62H2WRh0FCzAR1PI+29zIA==", "dependencies": { - "@noble/hashes": "~1.2.0", - "@scure/base": "~1.1.0" + "@noble/hashes": "~1.3.2", + "@scure/base": "~1.1.4" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@scure/bip39/node_modules/@noble/hashes": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.3.3.tgz", + "integrity": "sha512-V7/fPHgl+jsVPXqqeOzT8egNj2iBIVt+ECeMMG8TdcnTikP3oaBtUVqpT/gYCR68aEBJSF+XbYUxStjbFMqIIA==", + "engines": { + "node": ">= 16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" } }, "node_modules/@sentry/core": { @@ -2578,17 +2328,22 @@ "version": "0.1.1", "resolved": "https://registry.npmjs.org/@truffle/error/-/error-0.1.1.tgz", "integrity": "sha512-sE7c9IHIGdbK4YayH4BC8i8qMjoAOeg6nUXUDZZp8wlU21/EMpaG+CLx+KqcIPyR+GSWIW3Dm0PXkr2nlggFDA==", + "deprecated": "Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.", "dev": true }, "node_modules/@truffle/interface-adapter": { - "version": "0.5.35", - "resolved": "https://registry.npmjs.org/@truffle/interface-adapter/-/interface-adapter-0.5.35.tgz", - "integrity": "sha512-B5gtJnvsum5j2do393n0UfCT8MklrlAZxuqvEFBeMM9UKnreYct0/D368FVMlZwWo1N50HgGeZ0hlpSJqR/nvg==", + "version": "0.5.37", + "resolved": "https://registry.npmjs.org/@truffle/interface-adapter/-/interface-adapter-0.5.37.tgz", + "integrity": "sha512-lPH9MDgU+7sNDlJSClwyOwPCfuOimqsCx0HfGkznL3mcFRymc1pukAR1k17zn7ErHqBwJjiKAZ6Ri72KkS+IWw==", + "deprecated": "Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.", "dev": true, "dependencies": { "bn.js": "^5.1.3", "ethers": "^4.0.32", "web3": "1.10.0" + }, + "engines": { + "node": "^16.20 || ^18.16 || >=20" } }, "node_modules/@truffle/interface-adapter/node_modules/@ethereumjs/common": { @@ -2718,67 +2473,6 @@ "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", "dev": true }, - "node_modules/@truffle/interface-adapter/node_modules/ethereum-cryptography": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz", - "integrity": "sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==", - "dev": true, - "dependencies": { - "@types/pbkdf2": "^3.0.0", - "@types/secp256k1": "^4.0.1", - "blakejs": "^1.1.0", - "browserify-aes": "^1.2.0", - "bs58check": "^2.1.2", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "hash.js": "^1.1.7", - "keccak": "^3.0.0", - "pbkdf2": "^3.0.17", - "randombytes": "^2.1.0", - "safe-buffer": "^5.1.2", - "scrypt-js": "^3.0.0", - "secp256k1": "^4.0.1", - "setimmediate": "^1.0.5" - } - }, - "node_modules/@truffle/interface-adapter/node_modules/ethereum-cryptography/node_modules/hash.js": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", - "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", - "dev": true, - "dependencies": { - "inherits": "^2.0.3", - "minimalistic-assert": "^1.0.1" - } - }, - "node_modules/@truffle/interface-adapter/node_modules/ethereum-cryptography/node_modules/scrypt-js": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/scrypt-js/-/scrypt-js-3.0.1.tgz", - "integrity": "sha512-cdwTTnqPu0Hyvf5in5asVdZocVDTNRmR7XEcJuIzMjJeSHybHl7vpB66AzwTaIg6CLSbtjcxc8fqcySfnTkccA==", - "dev": true - }, - "node_modules/@truffle/interface-adapter/node_modules/ethereum-cryptography/node_modules/setimmediate": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", - "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==", - "dev": true - }, - "node_modules/@truffle/interface-adapter/node_modules/ethereumjs-util": { - "version": "7.1.5", - "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-7.1.5.tgz", - "integrity": "sha512-SDl5kKrQAudFBUe5OJM9Ac6WmMyYmXX/6sTmLZ3ffG2eY6ZIGBes3pEDxNN6V72WyOw4CPD5RomKdsa8DAAwLg==", - "dev": true, - "dependencies": { - "@types/bn.js": "^5.1.0", - "bn.js": "^5.1.2", - "create-hash": "^1.1.2", - "ethereum-cryptography": "^0.1.3", - "rlp": "^2.2.4" - }, - "engines": { - "node": ">=10.0.0" - } - }, "node_modules/@truffle/interface-adapter/node_modules/ethers": { "version": "4.0.49", "resolved": "https://registry.npmjs.org/ethers/-/ethers-4.0.49.tgz", @@ -2857,21 +2551,6 @@ "integrity": "sha512-GII20kjaPX0zJ8wzkTbNDYMY7msuZcTWk8S5UOh6806Jq/wz1J8/bnr8uGU0DAUmYDjj2Mr4X1cW8v/GLYnR+g==", "dev": true }, - "node_modules/@truffle/interface-adapter/node_modules/json-buffer": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", - "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", - "dev": true - }, - "node_modules/@truffle/interface-adapter/node_modules/keyv": { - "version": "4.5.3", - "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.3.tgz", - "integrity": "sha512-QCiSav9WaX1PgETJ+SpNnx2PRRapJ/oRSXM4VO5OGYGSjrxbKPVFVhB3l2OCbLCk329N8qyAtsJjSjvVBWzEug==", - "dev": true, - "dependencies": { - "json-buffer": "3.0.1" - } - }, "node_modules/@truffle/interface-adapter/node_modules/lowercase-keys": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-3.0.0.tgz", @@ -3143,10 +2822,14 @@ "dev": true }, "node_modules/@truffle/interface-adapter/node_modules/web3-eth-accounts/node_modules/uuid": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.0.tgz", - "integrity": "sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg==", + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", + "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", "dev": true, + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], "bin": { "uuid": "dist/bin/uuid" } @@ -3291,10 +2974,29 @@ "node": ">=8.0.0" } }, + "node_modules/@truffle/interface-adapter/node_modules/web3-utils": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.10.0.tgz", + "integrity": "sha512-kSaCM0uMcZTNUSmn5vMEhlo02RObGNRRCkdX0V9UTAU0+lrvn0HSaudyCo6CQzuXUsnuY2ERJGCGPfeWmv19Rg==", + "dev": true, + "dependencies": { + "bn.js": "^5.2.1", + "ethereum-bloom-filters": "^1.0.6", + "ethereumjs-util": "^7.1.0", + "ethjs-unit": "0.1.6", + "number-to-bn": "1.7.0", + "randombytes": "^2.1.0", + "utf8": "3.0.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, "node_modules/@truffle/provider": { "version": "0.2.64", "resolved": "https://registry.npmjs.org/@truffle/provider/-/provider-0.2.64.tgz", "integrity": "sha512-ZwPsofw4EsCq/2h0t73SPnnFezu4YQWBmK4FxFaOUX0F+o8NsZuHKyfJzuZwyZbiktYmefM3yD9rM0Dj4BhNbw==", + "deprecated": "Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.", "dev": true, "dependencies": { "@truffle/error": "^0.1.1", @@ -3304,9 +3006,9 @@ } }, "node_modules/@tsconfig/node10": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz", - "integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==", + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.11.tgz", + "integrity": "sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==", "dev": true }, "node_modules/@tsconfig/node12": { @@ -3387,18 +3089,19 @@ } }, "node_modules/@typechain/hardhat/node_modules/universalify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", - "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", "dev": true, "engines": { "node": ">= 10.0.0" } }, "node_modules/@types/bn.js": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-5.1.1.tgz", - "integrity": "sha512-qNrYbZqMx0uJAfKnKclPh+dTwK33KfLHYqtyODwd5HnXOjnkhc4qgn3BrK6RWyGZm5+sIFE7Q7Vz6QQtJB7w7g==", + "version": "5.1.5", + "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-5.1.5.tgz", + "integrity": "sha512-V46N0zwKRF5Q00AZ6hWtN0T8gGmDUaUzLWQvHFo5yThtVwK/VCenFY3wXVbOvNfajEpsTfQM4IN9k/d6gUVX3A==", + "dev": true, "dependencies": { "@types/node": "*" } @@ -3416,9 +3119,9 @@ } }, "node_modules/@types/chai": { - "version": "4.3.5", - "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.5.tgz", - "integrity": "sha512-mEo1sAde+UCE6b2hxn332f1g1E8WfYRu6p5SvTKr2ZKC1f7gFJXk4h5PyGP9Dt6gCaG8y8XhwnXWC6Iy2cmBng==", + "version": "4.3.14", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.14.tgz", + "integrity": "sha512-Wj71sXE4Q4AkGdG9Tvq1u/fquNz9EdG4LIJMwVVII7ashjD/8cf8fyIfJAjRr6YcsXnSE8cOGQPq1gqeR8z+3w==", "dev": true }, "node_modules/@types/concat-stream": { @@ -3450,15 +3153,15 @@ } }, "node_modules/@types/http-cache-semantics": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.1.tgz", - "integrity": "sha512-SZs7ekbP8CN0txVG2xVRH6EgKmEm31BOxA07vkFaETzZz1xh+cbt8BcI0slpymvwhx5dlFnQG2rTlPVQn+iRPQ==", + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.4.tgz", + "integrity": "sha512-1m0bIFVc7eJWyve9S0RnuRgcQqF/Xd5QsUZAZeQFr1Q3/p9JWoQQEqmVy+DPTNpGXwhgIetAoYF8JSc33q29QA==", "dev": true }, "node_modules/@types/json-schema": { - "version": "7.0.12", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.12.tgz", - "integrity": "sha512-Hr5Jfhc9eYOQNPYO5WLDq/n4jqijdHNlDXjuAQkkt+mWdQR+XJToOHrsD4cPaMXpn6KO7y2+wM8AZEs8VpBLVA==", + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", "dev": true }, "node_modules/@types/json5": { @@ -3506,22 +3209,24 @@ "node_modules/@types/node": { "version": "12.20.55", "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.55.tgz", - "integrity": "sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==" + "integrity": "sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==", + "dev": true }, "node_modules/@types/node-fetch": { - "version": "2.6.4", - "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.6.4.tgz", - "integrity": "sha512-1ZX9fcN4Rvkvgv4E6PAY5WXUFWFcRWxZa3EW83UjycOB9ljJCedb2CupIP4RZMEwF/M3eTcCihbBRgwtGbg5Rg==", + "version": "2.6.11", + "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.6.11.tgz", + "integrity": "sha512-24xFj9R5+rfQJLRyM56qh+wnVSYhyXC2tkoBndtY0U+vubqNsYXGjufB2nn8Q6gt0LrARwL6UBtMCSVCwl4B1g==", "dev": true, "dependencies": { "@types/node": "*", - "form-data": "^3.0.0" + "form-data": "^4.0.0" } }, "node_modules/@types/pbkdf2": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@types/pbkdf2/-/pbkdf2-3.1.0.tgz", - "integrity": "sha512-Cf63Rv7jCQ0LaL8tNXmEyqTHuIJxRdlS5vMh1mj5voN4+QFhVZnlZruezqpWYDiJ8UTzhP0VmeLXCmBk66YrMQ==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@types/pbkdf2/-/pbkdf2-3.1.2.tgz", + "integrity": "sha512-uRwJqmiXmh9++aSu1VNEn3iIxWOhd8AHXNSdlaLfdAAdSTY9jYVeGWnzejM3dvrkbqE3/hyQkQQ29IFATEGlew==", + "dev": true, "dependencies": { "@types/node": "*" } @@ -3533,21 +3238,11 @@ "dev": true }, "node_modules/@types/qs": { - "version": "6.9.7", - "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.7.tgz", - "integrity": "sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==", + "version": "6.9.15", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.15.tgz", + "integrity": "sha512-uXHQKES6DQKKCLh441Xv/dwxOq1TVS3JPUMlEqoEglvlhR6Mxnlew/Xq/LRVHpLyk7iK3zODe1qYHIMltO7XGg==", "dev": true }, - "node_modules/@types/readable-stream": { - "version": "2.3.15", - "resolved": "https://registry.npmjs.org/@types/readable-stream/-/readable-stream-2.3.15.tgz", - "integrity": "sha512-oM5JSKQCcICF1wvGgmecmHldZ48OZamtMxcGGVICOJA8o8cahXC1zEVAif8iwoc5j8etxFaRFnf095+CDsuoFQ==", - "dev": true, - "dependencies": { - "@types/node": "*", - "safe-buffer": "~5.1.1" - } - }, "node_modules/@types/resolve": { "version": "0.0.8", "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-0.0.8.tgz", @@ -3558,26 +3253,27 @@ } }, "node_modules/@types/responselike": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@types/responselike/-/responselike-1.0.0.tgz", - "integrity": "sha512-85Y2BjiufFzaMIlvJDvTTB8Fxl2xfLo4HgmHzVBz08w4wDePCTjYw66PdrolO0kzli3yam/YCgRufyo1DdQVTA==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@types/responselike/-/responselike-1.0.3.tgz", + "integrity": "sha512-H/+L+UkTV33uf49PH5pCAUBVPNj2nDBXTN+qS1dOwyyg24l3CcicicCA7ca+HMvJBZcFgl5r8e+RR6elsb4Lyw==", "dev": true, "dependencies": { "@types/node": "*" } }, "node_modules/@types/secp256k1": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/@types/secp256k1/-/secp256k1-4.0.3.tgz", - "integrity": "sha512-Da66lEIFeIz9ltsdMZcpQvmrmmoqrfju8pm1BH8WbYjZSwUgCwXLb9C+9XYogwBITnbsSaMdVPb2ekf7TV+03w==", + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/@types/secp256k1/-/secp256k1-4.0.6.tgz", + "integrity": "sha512-hHxJU6PAEUn0TP4S/ZOzuTUvJWuZ6eIKeNKb5RBpODvSl6hp1Wrw4s7ATY50rklRCScUDpHzVA/DQdSjJ3UoYQ==", + "dev": true, "dependencies": { "@types/node": "*" } }, "node_modules/@types/sinon": { - "version": "10.0.15", - "resolved": "https://registry.npmjs.org/@types/sinon/-/sinon-10.0.15.tgz", - "integrity": "sha512-3lrFNQG0Kr2LDzvjyjB6AMJk4ge+8iYhQfdnSwIwlG88FUOV43kPcQqDZkDa/h3WSZy6i8Fr0BSjfQtB1B3xuQ==", + "version": "17.0.3", + "resolved": "https://registry.npmjs.org/@types/sinon/-/sinon-17.0.3.tgz", + "integrity": "sha512-j3uovdn8ewky9kRBG19bOwaZbexJu/XjtkHyjvUgt4xfPFz18dcORIMqnYh66Fx3Powhcr85NT5+er3+oViapw==", "dev": true, "peer": true, "dependencies": { @@ -3585,9 +3281,9 @@ } }, "node_modules/@types/sinon-chai": { - "version": "3.2.9", - "resolved": "https://registry.npmjs.org/@types/sinon-chai/-/sinon-chai-3.2.9.tgz", - "integrity": "sha512-/19t63pFYU0ikrdbXKBWj9PCdnKyTd0Qkz0X91Ta081cYsq90OxYdcWwK/dwEoDa6dtXgj2HJfmzgq+QZTHdmQ==", + "version": "3.2.12", + "resolved": "https://registry.npmjs.org/@types/sinon-chai/-/sinon-chai-3.2.12.tgz", + "integrity": "sha512-9y0Gflk3b0+NhQZ/oxGtaAJDvRywCa5sIyaVnounqLvmf93yBF4EgIRspePtkMs3Tr844nCclYMlcCNmLCvjuQ==", "dev": true, "peer": true, "dependencies": { @@ -3596,9 +3292,9 @@ } }, "node_modules/@types/sinonjs__fake-timers": { - "version": "8.1.2", - "resolved": "https://registry.npmjs.org/@types/sinonjs__fake-timers/-/sinonjs__fake-timers-8.1.2.tgz", - "integrity": "sha512-9GcLXF0/v3t80caGs5p2rRfkB+a8VBGLJZVih6CNFkx8IZ994wiKKLSRs9nuFwk1HevWs/1mnUmkApGrSGsShA==", + "version": "8.1.5", + "resolved": "https://registry.npmjs.org/@types/sinonjs__fake-timers/-/sinonjs__fake-timers-8.1.5.tgz", + "integrity": "sha512-mQkU2jY8jJEF7YHjHvsQO8+3ughTL1mcnn96igfhONmR+fUPSKIkefQYpSe8bsly2Ep7oQbn/6VG5/9/0qcArQ==", "dev": true, "peer": true }, @@ -3634,39 +3330,6 @@ } } }, - "node_modules/@typescript-eslint/eslint-plugin/node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/@typescript-eslint/eslint-plugin/node_modules/semver": { - "version": "7.5.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", - "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", - "dev": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/@typescript-eslint/eslint-plugin/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - }, "node_modules/@typescript-eslint/experimental-utils": { "version": "4.33.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-4.33.0.tgz", @@ -3775,39 +3438,6 @@ } } }, - "node_modules/@typescript-eslint/typescript-estree/node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/@typescript-eslint/typescript-estree/node_modules/semver": { - "version": "7.5.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", - "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", - "dev": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/@typescript-eslint/typescript-estree/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - }, "node_modules/@typescript-eslint/visitor-keys": { "version": "4.33.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.33.0.tgz", @@ -3837,42 +3467,12 @@ "integrity": "sha512-LEyx4aLEC3x6T0UguF6YILf+ntvmOaWsVfENmIW0E9H09vKlLDGelMjjSm0jkDHALj8A8quZ/HapKNigzwge+Q==", "dev": true }, - "node_modules/abort-controller": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", - "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", - "dev": true, - "dependencies": { - "event-target-shim": "^5.0.0" - }, - "engines": { - "node": ">=6.5" - } - }, "node_modules/abortcontroller-polyfill": { "version": "1.7.5", "resolved": "https://registry.npmjs.org/abortcontroller-polyfill/-/abortcontroller-polyfill-1.7.5.tgz", "integrity": "sha512-JMJ5soJWP18htbbxJjG7bG6yuI6pRhgJ0scHHTfkUjf6wjP912xZWvM+A4sJK3gqd9E8fcPbDnOefbA9Th/FIQ==", "dev": true }, - "node_modules/abstract-level": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/abstract-level/-/abstract-level-1.0.3.tgz", - "integrity": "sha512-t6jv+xHy+VYwc4xqZMn2Pa9DjcdzvzZmQGRjTFc8spIbRGHgBrEKbPq+rYXc7CCo0lxgYvSgKVg9qZAhpVQSjA==", - "dev": true, - "dependencies": { - "buffer": "^6.0.3", - "catering": "^2.1.0", - "is-buffer": "^2.0.5", - "level-supports": "^4.0.0", - "level-transcoder": "^1.0.1", - "module-error": "^1.0.1", - "queue-microtask": "^1.2.3" - }, - "engines": { - "node": ">=12" - } - }, "node_modules/accepts": { "version": "1.3.8", "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", @@ -3908,9 +3508,9 @@ } }, "node_modules/acorn-walk": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", - "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.2.tgz", + "integrity": "sha512-cjkyv4OtNCIeqhHrfS81QWXoCBPExR/J62oyEqepVw8WaQeSqpW2uhuLPh1m9eWhDuOo/jUXVTlifvesOWp/4A==", "dev": true, "engines": { "node": ">=0.4.0" @@ -3990,6 +3590,15 @@ "node": ">=0.4.2" } }, + "node_modules/ansi-align": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.1.tgz", + "integrity": "sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w==", + "dev": true, + "dependencies": { + "string-width": "^4.1.0" + } + }, "node_modules/ansi-colors": { "version": "4.1.3", "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", @@ -4050,9 +3659,9 @@ } }, "node_modules/antlr4": { - "version": "4.13.0", - "resolved": "https://registry.npmjs.org/antlr4/-/antlr4-4.13.0.tgz", - "integrity": "sha512-zooUbt+UscjnWyOrsuY/tVFL4rwrAGwOivpQmvmUDE22hy/lUA467Rc1rcixyRwcRUIXFYBwv7+dClDSHdmmew==", + "version": "4.13.1", + "resolved": "https://registry.npmjs.org/antlr4/-/antlr4-4.13.1.tgz", + "integrity": "sha512-kiXTspaRYvnIArgE97z5YVVf/cDVQABr3abFRR6mE7yesLMkgu4ujuyV/sgxafQ8wgve0DJQUJ38Z8tkgA2izA==", "dev": true, "engines": { "node": ">=16" @@ -4105,13 +3714,16 @@ } }, "node_modules/array-buffer-byte-length": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.0.tgz", - "integrity": "sha512-LPuwb2P+NrQw3XhxGc36+XSvuBPopovXYTR9Ew++Du9Yb/bx5AzBfrIsBoj0EZUifjQU+sHL21sseZ3jerWO/A==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.1.tgz", + "integrity": "sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg==", "dev": true, "dependencies": { - "call-bind": "^1.0.2", - "is-array-buffer": "^3.0.1" + "call-bind": "^1.0.5", + "is-array-buffer": "^3.0.4" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -4124,15 +3736,16 @@ "dev": true }, "node_modules/array-includes": { - "version": "3.1.6", - "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.6.tgz", - "integrity": "sha512-sgTbLvL6cNnw24FnbaDyjmvddQ2ML8arZsgaJhoABMoplz/4QRhtrYS+alr1BUM1Bwp6dhx8vVCBSLG+StwOFw==", + "version": "3.1.8", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.8.tgz", + "integrity": "sha512-itaWrbYbqpGXkGhZPGUulwnhVf5Hpy1xiCFsGqyIGglbBxmG5vSjxQen3/WGOjPpNEv1RtBLKxbmVXm8HpJStQ==", "dev": true, "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4", - "get-intrinsic": "^1.1.3", + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.4", "is-string": "^1.0.7" }, "engines": { @@ -4160,16 +3773,18 @@ "node": ">=0.10.0" } }, - "node_modules/array.prototype.flat": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.1.tgz", - "integrity": "sha512-roTU0KWIOmJ4DRLmwKd19Otg0/mT3qPNt0Qb3GWW8iObuZXxrjB/pzn0R3hqpRSWg4HCwqx+0vwOnWnvlOyeIA==", + "node_modules/array.prototype.findlastindex": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.5.tgz", + "integrity": "sha512-zfETvRFA8o7EiNn++N5f/kaCw221hrpGsDmcpndVupkPzEc1Wuf3VgC0qby1BbHs7f5DVYjgtEU2LLh5bqeGfQ==", "dev": true, "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4", - "es-shim-unscopables": "^1.0.0" + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "es-shim-unscopables": "^1.0.2" }, "engines": { "node": ">= 0.4" @@ -4178,15 +3793,15 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/array.prototype.flatmap": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.1.tgz", - "integrity": "sha512-8UGn9O1FDVvMNB0UlLv4voxRMze7+FpHyF5mSMRjWHUMlpoDViniy05870VlxhfgTnLbpuwTzvD76MTtWxB/mQ==", - "dev": true, + "node_modules/array.prototype.flat": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.2.tgz", + "integrity": "sha512-djYB+Zx2vLewY8RWlNCUdHjDXs2XOgm602S9E7P/UpHgfeHL00cRiIF+IN/G/aUJ7kGPb6yO/ErDI5V2s8iycA==", + "dev": true, "dependencies": { "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", "es-shim-unscopables": "^1.0.0" }, "engines": { @@ -4196,17 +3811,16 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/array.prototype.reduce": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/array.prototype.reduce/-/array.prototype.reduce-1.0.5.tgz", - "integrity": "sha512-kDdugMl7id9COE8R7MHF5jWk7Dqt/fs4Pv+JXoICnYwqpjjjbUurz6w5fT5IG6brLdJhv6/VoHB0H7oyIBXd+Q==", + "node_modules/array.prototype.flatmap": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.2.tgz", + "integrity": "sha512-Ewyx0c9PmpcsByhSW4r+9zDU7sGjFc86qf/kKtuSCRdhfbk0SNLLkaT5qvcHnRGgc5NP/ly/y+qkXkqONX54CQ==", "dev": true, "dependencies": { "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4", - "es-array-method-boxes-properly": "^1.0.0", - "is-string": "^1.0.7" + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "es-shim-unscopables": "^1.0.0" }, "engines": { "node": ">= 0.4" @@ -4216,16 +3830,18 @@ } }, "node_modules/arraybuffer.prototype.slice": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.1.tgz", - "integrity": "sha512-09x0ZWFEjj4WD8PDbykUwo3t9arLn8NIzmmYEJFpYekOAQjpkGSyrQhNoRTcwwcFRu+ycWF78QZ63oWTqSjBcw==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.3.tgz", + "integrity": "sha512-bMxMKAjg13EBSVscxTaYA4mRc5t1UAXa2kXiGTNfZ079HIWXEkKmkgFrh/nJqamaLSrXO5H4WFFkPEaLJWbs3A==", "dev": true, "dependencies": { - "array-buffer-byte-length": "^1.0.0", - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "get-intrinsic": "^1.2.1", - "is-array-buffer": "^3.0.2", + "array-buffer-byte-length": "^1.0.1", + "call-bind": "^1.0.5", + "define-properties": "^1.2.1", + "es-abstract": "^1.22.3", + "es-errors": "^1.2.1", + "get-intrinsic": "^1.2.3", + "is-array-buffer": "^3.0.4", "is-shared-array-buffer": "^1.0.2" }, "engines": { @@ -4251,15 +3867,14 @@ } }, "node_modules/asn1.js": { - "version": "5.4.1", - "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-5.4.1.tgz", - "integrity": "sha512-+I//4cYPccV8LdmBLiX8CYvf9Sp3vQsrqu2QNXRcrbiWvcx/UdlFiqUJJzxRQxgsZmvhXhn4cSKeSmoFjVdupA==", + "version": "4.10.1", + "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.10.1.tgz", + "integrity": "sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw==", "dev": true, "dependencies": { "bn.js": "^4.0.0", "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0", - "safer-buffer": "^2.1.0" + "minimalistic-assert": "^1.0.0" } }, "node_modules/asn1.js/node_modules/bn.js": { @@ -4328,10 +3943,13 @@ } }, "node_modules/available-typed-arrays": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz", - "integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", + "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", "dev": true, + "dependencies": { + "possible-typed-array-names": "^1.0.0" + }, "engines": { "node": ">= 0.4" }, @@ -4354,6 +3972,17 @@ "integrity": "sha512-NmWvPnx0F1SfrQbYwOi7OeaNGokp9XhzNioJ/CSBs8Qa4vxug81mhJEAVZwxXuBmYB5KDRfMq/F3RR0BIU7sWg==", "dev": true }, + "node_modules/axios": { + "version": "1.6.8", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.6.8.tgz", + "integrity": "sha512-v/ZHtJDU39mDpyBoFVkETcd/uNdxrWRrg3bKpOKzXFA6Bvqopts6ALSMU3y6ijYxbw2B+wPrIv46egTzJXCLGQ==", + "dev": true, + "dependencies": { + "follow-redirects": "^1.15.6", + "form-data": "^4.0.0", + "proxy-from-env": "^1.1.0" + } + }, "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", @@ -4364,6 +3993,7 @@ "version": "3.0.9", "resolved": "https://registry.npmjs.org/base-x/-/base-x-3.0.9.tgz", "integrity": "sha512-H7JU6iBHTal1gp56aKoaa//YUxEaAOUiydvrV/pILqIHXTtqxSkATOnDA2u+jZ/61sD+L/412+7kzXRtWukhpQ==", + "dev": true, "dependencies": { "safe-buffer": "^5.0.1" } @@ -4407,36 +4037,31 @@ "resolved": "https://registry.npmjs.org/bech32/-/bech32-1.1.4.tgz", "integrity": "sha512-s0IrSOzLlbvX7yp4WBfPITzpAU8sqQcpsmwXDiKwrG4r491vwCO/XpejasRNl0piBMe/DvP4Tz0mIS/X1DPJBQ==" }, - "node_modules/bigint-crypto-utils": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/bigint-crypto-utils/-/bigint-crypto-utils-3.3.0.tgz", - "integrity": "sha512-jOTSb+drvEDxEq6OuUybOAv/xxoh3cuYRUIPyu8sSHQNKM303UQ2R1DAo45o1AkcIXw6fzbaFI1+xGGdaXs2lg==", - "dev": true, - "engines": { - "node": ">=14.0.0" - } - }, "node_modules/bignumber.js": { - "version": "9.1.1", - "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.1.1.tgz", - "integrity": "sha512-pHm4LsMJ6lzgNGVfZHjMoO8sdoRhOzOH4MLmY65Jg70bpxCKu5iOHNJyfF6OyvYw7t8Fpf35RuzUyqnQsj8Vig==", + "version": "9.1.2", + "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.1.2.tgz", + "integrity": "sha512-2/mKyZH9K85bzOEfhXDBFZTGd1CTs+5IHpeFQo9luiBG7hghdC851Pj2WAhb6E3R6b9tZj/XKhbg4fum+Kepug==", "engines": { "node": "*" } }, "node_modules/binary-extensions": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", - "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", + "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", "dev": true, "engines": { "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/blakejs": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/blakejs/-/blakejs-1.2.1.tgz", - "integrity": "sha512-QXUSXI3QVc/gJME0dBpXrag1kbzOqCjCX8/b54ntNyW6sjtoqxqRk3LTmXzaJoh71zMsDCjM+47jS7XiwN/+fQ==" + "integrity": "sha512-QXUSXI3QVc/gJME0dBpXrag1kbzOqCjCX8/b54ntNyW6sjtoqxqRk3LTmXzaJoh71zMsDCjM+47jS7XiwN/+fQ==", + "dev": true }, "node_modules/bluebird": { "version": "3.7.2", @@ -4503,6 +4128,28 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/boxen": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/boxen/-/boxen-5.1.2.tgz", + "integrity": "sha512-9gYgQKXx+1nP8mP7CzFyaUARhg7D3n1dF/FnErWmu9l6JvGpNUN278h0aSb+QjoiKSWG+iZ3uHrcqk0qrY9RQQ==", + "dev": true, + "dependencies": { + "ansi-align": "^3.0.0", + "camelcase": "^6.2.0", + "chalk": "^4.1.0", + "cli-boxes": "^2.2.1", + "string-width": "^4.2.2", + "type-fest": "^0.20.2", + "widest-line": "^3.1.0", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", @@ -4530,18 +4177,6 @@ "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", "integrity": "sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w==" }, - "node_modules/browser-level": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/browser-level/-/browser-level-1.0.1.tgz", - "integrity": "sha512-XECYKJ+Dbzw0lbydyQuJzwNXtOpbMSq737qxJN11sIRTErOMShvDpbzTlgju7orJKvx4epULolZAuJGLzCmWRQ==", - "dev": true, - "dependencies": { - "abstract-level": "^1.0.2", - "catering": "^2.1.1", - "module-error": "^1.0.2", - "run-parallel-limit": "^1.1.0" - } - }, "node_modules/browser-stdout": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", @@ -4552,6 +4187,7 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", + "dev": true, "dependencies": { "buffer-xor": "^1.0.3", "cipher-base": "^1.0.0", @@ -4595,49 +4231,107 @@ } }, "node_modules/browserify-sign": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.2.2.tgz", - "integrity": "sha512-1rudGyeYY42Dk6texmv7c4VcQ0EsvVbLwZkA+AQB7SxvXxmcD93jcHie8bzecJ+ChDlmAm2Qyu0+Ccg5uhZXCg==", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.2.3.tgz", + "integrity": "sha512-JWCZW6SKhfhjJxO8Tyiiy+XYB7cqd2S5/+WeYHsKdNKFlCBhKbblba1A/HN/90YwtxKc8tCErjffZl++UNmGiw==", "dev": true, "dependencies": { "bn.js": "^5.2.1", "browserify-rsa": "^4.1.0", "create-hash": "^1.2.0", "create-hmac": "^1.1.7", - "elliptic": "^6.5.4", + "elliptic": "^6.5.5", + "hash-base": "~3.0", "inherits": "^2.0.4", - "parse-asn1": "^5.1.6", - "readable-stream": "^3.6.2", + "parse-asn1": "^5.1.7", + "readable-stream": "^2.3.8", "safe-buffer": "^5.2.1" }, "engines": { - "node": ">= 4" + "node": ">= 0.12" } }, - "node_modules/browserify-sign/node_modules/safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "node_modules/browserify-sign/node_modules/elliptic": { + "version": "6.5.5", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.5.tgz", + "integrity": "sha512-7EjbcmUm17NQFu4Pmgmq2olYMj8nwMnpcddByChSUjArp8F5DQWcIcpriwO4ZToLNAJig0yiyjswfyGNje/ixw==", "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] + "dependencies": { + "bn.js": "^4.11.9", + "brorand": "^1.1.0", + "hash.js": "^1.0.0", + "hmac-drbg": "^1.0.1", + "inherits": "^2.0.4", + "minimalistic-assert": "^1.0.1", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "node_modules/browserify-sign/node_modules/elliptic/node_modules/bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", + "dev": true + }, + "node_modules/browserify-sign/node_modules/hash-base": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.0.4.tgz", + "integrity": "sha512-EeeoJKjTyt868liAlVmcv2ZsUfGHlE3Q+BICOXcZiwN3osr5Q/zFGYmTJpoIzuaSTAwndFy+GqhEwlU4L3j4Ow==", + "dev": true, + "dependencies": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/browserify-sign/node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "dev": true + }, + "node_modules/browserify-sign/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "dev": true, + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/browserify-sign/node_modules/readable-stream/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "node_modules/browserify-sign/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/browserify-sign/node_modules/string_decoder/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true }, "node_modules/bs58": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/bs58/-/bs58-4.0.1.tgz", "integrity": "sha512-Ok3Wdf5vOIlBrgCvTq96gBkJw+JUEzdBgyaza5HLtPm7yTHkjRy8+JzNyHF7BHa0bNWOQIp3m5YF0nnFcOIKLw==", + "dev": true, "dependencies": { "base-x": "^3.0.2" } @@ -4646,6 +4340,7 @@ "version": "2.1.2", "resolved": "https://registry.npmjs.org/bs58check/-/bs58check-2.1.2.tgz", "integrity": "sha512-0TS1jicxdU09dwJMNZtVAfzPi6Q6QeN0pM1Fkzrjn+XYHvzMKPU3pHVpva+769iNVSfIYWf7LJ6WR+BuuMf8cA==", + "dev": true, "dependencies": { "bs58": "^4.0.0", "create-hash": "^1.1.0", @@ -4695,12 +4390,13 @@ "node_modules/buffer-xor": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", - "integrity": "sha512-571s0T7nZWK6vB67HI5dyUF7wXiNcfaPPPTl6zYCNApANjIvYJTg7hlud/+cJpdAhS7dVzqMLmfhfHR3rAcOjQ==" + "integrity": "sha512-571s0T7nZWK6vB67HI5dyUF7wXiNcfaPPPTl6zYCNApANjIvYJTg7hlud/+cJpdAhS7dVzqMLmfhfHR3rAcOjQ==", + "dev": true }, "node_modules/bufferutil": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/bufferutil/-/bufferutil-4.0.7.tgz", - "integrity": "sha512-kukuqc39WOHtdxtw4UScxF/WVnMFVSQVKhtx3AjZJzhd0RGZZldcrfSEbVsWWe6KNH253574cq5F+wpv0G9pJw==", + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/bufferutil/-/bufferutil-4.0.8.tgz", + "integrity": "sha512-4T53u4PdgsXqKaIctwF8ifXlRTTmEPJ8iEPWFdGZvcf7sbwYo6FKFEX9eNNAnzFZ7EzJAQ3CJeOtCRA4rDp7Pw==", "devOptional": true, "hasInstallScript": true, "dependencies": { @@ -4711,11 +4407,11 @@ } }, "node_modules/bufio": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/bufio/-/bufio-1.2.0.tgz", - "integrity": "sha512-UlFk8z/PwdhYQTXSQQagwGAdtRI83gib2n4uy4rQnenxUM2yQi8lBDzF230BNk+3wAoZDxYRoBwVVUPgHa9MCA==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/bufio/-/bufio-1.2.1.tgz", + "integrity": "sha512-9oR3zNdupcg/Ge2sSHQF3GX+kmvL/fTPvD0nd5AGLq8SjUYnTz+SlFjK/GXidndbZtIj+pVKXiWeR9w6e9wKCA==", "engines": { - "node": ">=8.0.0" + "node": ">=14.0.0" } }, "node_modules/bytes": { @@ -4769,6 +4465,21 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/cacheable-request/node_modules/json-buffer": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.0.tgz", + "integrity": "sha512-CuUqjv0FUZIdXkHPI8MezCnFCdaTAacej1TZYulLoAg1h/PhwkdXFN4V/gzY4g+fMBCOV2xF+rp7t2XD2ns/NQ==", + "dev": true + }, + "node_modules/cacheable-request/node_modules/keyv": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-3.1.0.tgz", + "integrity": "sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA==", + "dev": true, + "dependencies": { + "json-buffer": "3.0.0" + } + }, "node_modules/cacheable-request/node_modules/lowercase-keys": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", @@ -4779,13 +4490,19 @@ } }, "node_modules/call-bind": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", - "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", + "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", "dev": true, "dependencies": { - "function-bind": "^1.1.1", - "get-intrinsic": "^1.0.2" + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -4812,30 +4529,12 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/case": { - "version": "1.6.3", - "resolved": "https://registry.npmjs.org/case/-/case-1.6.3.tgz", - "integrity": "sha512-mzDSXIPaFwVDvZAHqZ9VlbyF4yyXRuX6IvB06WvPYkqJVO24kX1PPhv9bfpKNFZyxYFmmgo03HUiD8iklmJYRQ==", - "dev": true, - "engines": { - "node": ">= 0.8.0" - } - }, "node_modules/caseless": { "version": "0.12.0", "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", "integrity": "sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==", "dev": true }, - "node_modules/catering": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/catering/-/catering-2.1.1.tgz", - "integrity": "sha512-K7Qy8O9p76sL3/3m7/zLKbRkyOlSZAgzEaLhyj2mXS8PsCud2Eo4hAb8aLtZqHh0QGqLcb9dlJSu6lHRVENm1w==", - "dev": true, - "engines": { - "node": ">=6" - } - }, "node_modules/cbor": { "version": "8.1.0", "resolved": "https://registry.npmjs.org/cbor/-/cbor-8.1.0.tgz", @@ -4901,16 +4600,10 @@ } }, "node_modules/chokidar": { - "version": "3.5.3", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", - "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://paulmillr.com/funding/" - } - ], "dependencies": { "anymatch": "~3.1.2", "braces": "~3.0.2", @@ -4923,6 +4616,9 @@ "engines": { "node": ">= 8.10.0" }, + "funding": { + "url": "https://paulmillr.com/funding/" + }, "optionalDependencies": { "fsevents": "~2.3.2" } @@ -4996,6 +4692,7 @@ "version": "1.0.4", "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", + "dev": true, "dependencies": { "inherits": "^2.0.1", "safe-buffer": "^5.0.1" @@ -5007,23 +4704,6 @@ "integrity": "sha512-rhjH9AG1fvabIDoGRVH587413LPjTZgmDF9fOFCbFJQV4yuocX1mHxxvXI4g3cGwbVY9wAYIoKlg1N79frJKQw==", "dev": true }, - "node_modules/classic-level": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/classic-level/-/classic-level-1.3.0.tgz", - "integrity": "sha512-iwFAJQYtqRTRM0F6L8h4JCt00ZSGdOyqh7yVrhhjrOpFhmBjNlRUey64MCiyo6UmQHMJ+No3c81nujPv+n9yrg==", - "dev": true, - "hasInstallScript": true, - "dependencies": { - "abstract-level": "^1.0.2", - "catering": "^2.1.0", - "module-error": "^1.0.1", - "napi-macros": "^2.2.2", - "node-gyp-build": "^4.3.0" - }, - "engines": { - "node": ">=12" - } - }, "node_modules/clean-stack": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", @@ -5033,6 +4713,18 @@ "node": ">=6" } }, + "node_modules/cli-boxes": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-2.2.1.tgz", + "integrity": "sha512-y4coMcylgSCdVinjiDBuR8PCC2bLjyGTwEmPb9NHR/QaNU6EUOXcTY/s6VjGMD6ENSEaeQYHCY0GNGS5jfMwPw==", + "dev": true, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/cli-table3": { "version": "0.5.1", "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.5.1.tgz", @@ -5049,50 +4741,70 @@ "colors": "^1.1.2" } }, - "node_modules/cliui": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", - "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "node_modules/cli-table3/node_modules/ansi-regex": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.1.tgz", + "integrity": "sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw==", "dev": true, - "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^7.0.0" + "engines": { + "node": ">=4" } }, - "node_modules/cliui/node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "node_modules/cli-table3/node_modules/is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==", "dev": true, "engines": { - "node": ">=8" + "node": ">=4" } }, - "node_modules/cliui/node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "node_modules/cli-table3/node_modules/string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", "dev": true, "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" }, "engines": { - "node": ">=8" + "node": ">=4" } }, - "node_modules/clone-response": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.3.tgz", - "integrity": "sha512-ROoL94jJH2dUVML2Y/5PEDNaSHgeOdSDicUyS7izcF63G6sTc/FTjLub4b8Il9S8S0beOfYt0TaA5qvFK+w0wA==", + "node_modules/cli-table3/node_modules/strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha512-4XaJ2zQdCzROZDivEVIDPkcQn8LMFSa8kj8Gxb/Lnwzv9A8VctNZ+lfivC/sV3ivW8ElJTERXZoPBRrZKkNKow==", "dev": true, "dependencies": { - "mimic-response": "^1.0.0" + "ansi-regex": "^3.0.0" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "engines": { + "node": ">=4" + } + }, + "node_modules/cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "dev": true, + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "node_modules/clone-response": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.3.tgz", + "integrity": "sha512-ROoL94jJH2dUVML2Y/5PEDNaSHgeOdSDicUyS7izcF63G6sTc/FTjLub4b8Il9S8S0beOfYt0TaA5qvFK+w0wA==", + "dev": true, + "dependencies": { + "mimic-response": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/code-point-at": { @@ -5209,6 +4921,12 @@ "util-deprecate": "~1.0.1" } }, + "node_modules/concat-stream/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, "node_modules/concat-stream/node_modules/string_decoder": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", @@ -5230,26 +4948,6 @@ "node": ">= 0.6" } }, - "node_modules/content-disposition/node_modules/safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, "node_modules/content-hash": { "version": "2.5.2", "resolved": "https://registry.npmjs.org/content-hash/-/content-hash-2.5.2.tgz", @@ -5311,14 +5009,14 @@ } }, "node_modules/cosmiconfig": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-8.2.0.tgz", - "integrity": "sha512-3rTMnFJA1tCOPwRxtgF4wd7Ab2qvDbL8jX+3smjIbS4HlZBagTlpERbdN7iAbWlrfxE3M8c27kTwTawQ7st+OQ==", + "version": "8.3.6", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-8.3.6.tgz", + "integrity": "sha512-kcZ6+W5QzcJ3P1Mt+83OUv/oHFqZHIx8DuxG6eZ5RGMERoLqp4BuGjhHLYGK+Kf5XVkQvqBSmAy/nGWN3qDgEA==", "dev": true, "dependencies": { - "import-fresh": "^3.2.1", + "import-fresh": "^3.3.0", "js-yaml": "^4.1.0", - "parse-json": "^5.0.0", + "parse-json": "^5.2.0", "path-type": "^4.0.0" }, "engines": { @@ -5326,6 +5024,14 @@ }, "funding": { "url": "https://github.com/sponsors/d-fischer" + }, + "peerDependencies": { + "typescript": ">=4.9.5" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } } }, "node_modules/cosmiconfig/node_modules/argparse": { @@ -5378,6 +5084,7 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", + "dev": true, "dependencies": { "cipher-base": "^1.0.1", "inherits": "^2.0.1", @@ -5390,6 +5097,7 @@ "version": "1.1.7", "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", + "dev": true, "dependencies": { "cipher-base": "^1.0.3", "create-hash": "^1.1.0", @@ -5465,13 +5173,16 @@ "integrity": "sha512-KALDyEYgpY+Rlob/iriUtjV6d5Eq+Y191A5g4UqLAi8CyGP9N1+FdVbkc1SxKc2r4YAYqG8JzO2KGL+AizD70Q==" }, "node_modules/d": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/d/-/d-1.0.1.tgz", - "integrity": "sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/d/-/d-1.0.2.tgz", + "integrity": "sha512-MOqHvMWF9/9MX6nza0KgvFH4HpMU0EF5uUDXqX/BtxtU8NfB0QzRtJ8Oe/6SuS4kbhyzVJwjd97EA4PKrzJ8bw==", "dev": true, "dependencies": { - "es5-ext": "^0.10.50", - "type": "^1.0.1" + "es5-ext": "^0.10.64", + "type": "^2.7.2" + }, + "engines": { + "node": ">=0.12" } }, "node_modules/dashdash": { @@ -5486,6 +5197,57 @@ "node": ">=0.10" } }, + "node_modules/data-view-buffer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.1.tgz", + "integrity": "sha512-0lht7OugA5x3iJLOWFhWK/5ehONdprk0ISXqVFn/NFrDu+cuc8iADFrGQz5BnRK7LLU3JmkbXSxaqX+/mXYtUA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.6", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/data-view-byte-length": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.1.tgz", + "integrity": "sha512-4J7wRJD3ABAzr8wP+OcIcqq2dlUKp4DVflx++hs5h5ZKydWMI6/D/fAot+yh6g2tHh8fLFTvNOaVN357NvSrOQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/data-view-byte-offset": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.0.tgz", + "integrity": "sha512-t/Ygsytq+R995EJ5PZlD4Cu56sWa8InXySaViRzw9apusqsOO2bQP+SbYzAhR0pFKoB+43lYy8rWban9JSuXnA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.6", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/death": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/death/-/death-1.1.0.tgz", @@ -5565,12 +5327,30 @@ "integrity": "sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ==", "dev": true }, + "node_modules/define-data-property": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "dev": true, + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/define-properties": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.0.tgz", - "integrity": "sha512-xvqAVKGfT1+UAvPwKTVw/njhdQ8ZhXK4lI0bCIuCMrp2up9nPnaDftrLtmpTazqd1o+UY4zgzU+avtMbDP+ldA==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", + "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", "dev": true, "dependencies": { + "define-data-property": "^1.0.1", "has-property-descriptors": "^1.0.0", "object-keys": "^1.1.1" }, @@ -5764,12 +5544,13 @@ } }, "node_modules/enquirer": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", - "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.4.1.tgz", + "integrity": "sha512-rRqJg/6gd538VHvR3PSrdRBb/1Vy2YfzHqzvbhGIQpDRKIa4FgV/54b5Q1xYSxOOwKvjXweS26E0Q+nAMwp2pQ==", "dev": true, "dependencies": { - "ansi-colors": "^4.1.1" + "ansi-colors": "^4.1.1", + "strip-ansi": "^6.0.1" }, "engines": { "node": ">=8.6" @@ -5794,50 +5575,57 @@ } }, "node_modules/es-abstract": { - "version": "1.22.1", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.22.1.tgz", - "integrity": "sha512-ioRRcXMO6OFyRpyzV3kE1IIBd4WG5/kltnzdxSCqoP8CMGs/Li+M1uF5o7lOkZVFjDs+NLesthnF66Pg/0q0Lw==", - "dev": true, - "dependencies": { - "array-buffer-byte-length": "^1.0.0", - "arraybuffer.prototype.slice": "^1.0.1", - "available-typed-arrays": "^1.0.5", - "call-bind": "^1.0.2", - "es-set-tostringtag": "^2.0.1", + "version": "1.23.3", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.23.3.tgz", + "integrity": "sha512-e+HfNH61Bj1X9/jLc5v1owaLYuHdeHHSQlkhCBiTK8rBvKaULl/beGMxwrMXjpYrv4pz22BlY570vVePA2ho4A==", + "dev": true, + "dependencies": { + "array-buffer-byte-length": "^1.0.1", + "arraybuffer.prototype.slice": "^1.0.3", + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.7", + "data-view-buffer": "^1.0.1", + "data-view-byte-length": "^1.0.1", + "data-view-byte-offset": "^1.0.0", + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "es-set-tostringtag": "^2.0.3", "es-to-primitive": "^1.2.1", - "function.prototype.name": "^1.1.5", - "get-intrinsic": "^1.2.1", - "get-symbol-description": "^1.0.0", + "function.prototype.name": "^1.1.6", + "get-intrinsic": "^1.2.4", + "get-symbol-description": "^1.0.2", "globalthis": "^1.0.3", "gopd": "^1.0.1", - "has": "^1.0.3", - "has-property-descriptors": "^1.0.0", - "has-proto": "^1.0.1", + "has-property-descriptors": "^1.0.2", + "has-proto": "^1.0.3", "has-symbols": "^1.0.3", - "internal-slot": "^1.0.5", - "is-array-buffer": "^3.0.2", + "hasown": "^2.0.2", + "internal-slot": "^1.0.7", + "is-array-buffer": "^3.0.4", "is-callable": "^1.2.7", - "is-negative-zero": "^2.0.2", + "is-data-view": "^1.0.1", + "is-negative-zero": "^2.0.3", "is-regex": "^1.1.4", - "is-shared-array-buffer": "^1.0.2", + "is-shared-array-buffer": "^1.0.3", "is-string": "^1.0.7", - "is-typed-array": "^1.1.10", + "is-typed-array": "^1.1.13", "is-weakref": "^1.0.2", - "object-inspect": "^1.12.3", + "object-inspect": "^1.13.1", "object-keys": "^1.1.1", - "object.assign": "^4.1.4", - "regexp.prototype.flags": "^1.5.0", - "safe-array-concat": "^1.0.0", - "safe-regex-test": "^1.0.0", - "string.prototype.trim": "^1.2.7", - "string.prototype.trimend": "^1.0.6", - "string.prototype.trimstart": "^1.0.6", - "typed-array-buffer": "^1.0.0", - "typed-array-byte-length": "^1.0.0", - "typed-array-byte-offset": "^1.0.0", - "typed-array-length": "^1.0.4", + "object.assign": "^4.1.5", + "regexp.prototype.flags": "^1.5.2", + "safe-array-concat": "^1.1.2", + "safe-regex-test": "^1.0.3", + "string.prototype.trim": "^1.2.9", + "string.prototype.trimend": "^1.0.8", + "string.prototype.trimstart": "^1.0.8", + "typed-array-buffer": "^1.0.2", + "typed-array-byte-length": "^1.0.1", + "typed-array-byte-offset": "^1.0.2", + "typed-array-length": "^1.0.6", "unbox-primitive": "^1.0.2", - "which-typed-array": "^1.1.10" + "which-typed-array": "^1.1.15" }, "engines": { "node": ">= 0.4" @@ -5846,33 +5634,60 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/es-array-method-boxes-properly": { + "node_modules/es-define-property": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/es-array-method-boxes-properly/-/es-array-method-boxes-properly-1.0.0.tgz", - "integrity": "sha512-wd6JXUmyHmt8T5a2xreUwKcGPq6f1f+WwIJkijUqiGcJz1qqnZgP6XIK+QyIWU5lT7imeNxUll48bziG+TSYcA==", - "dev": true + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", + "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.2.4" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-object-atoms": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.0.0.tgz", + "integrity": "sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw==", + "dev": true, + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } }, "node_modules/es-set-tostringtag": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.1.tgz", - "integrity": "sha512-g3OMbtlwY3QewlqAiMLI47KywjWZoEytKr8pf6iTC8uJq5bIAH52Z9pnQ8pVL6whrCto53JZDuUIsifGeLorTg==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.3.tgz", + "integrity": "sha512-3T8uNMC3OQTHkFUsFq8r/BwAXLHvU/9O9mE0fBc/MY5iq/8H7ncvO947LmYA6ldWw9Uh8Yhf25zu6n7nML5QWQ==", "dev": true, "dependencies": { - "get-intrinsic": "^1.1.3", - "has": "^1.0.3", - "has-tostringtag": "^1.0.0" + "get-intrinsic": "^1.2.4", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.1" }, "engines": { "node": ">= 0.4" } }, "node_modules/es-shim-unscopables": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.0.tgz", - "integrity": "sha512-Jm6GPcCdC30eMLbZ2x8z2WuRwAws3zTBBKuusffYVUrNj/GVSUAZ+xKMaUpfNDR5IbyNA5LJbaecoUVbmUcB1w==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.2.tgz", + "integrity": "sha512-J3yBRXCzDu4ULnQwxyToo/OjdMx6akgVC7K6few0a7F/0wLtmKKN7I73AH5T2836UuXRqN7Qg+IIUw/+YJksRw==", "dev": true, "dependencies": { - "has": "^1.0.3" + "hasown": "^2.0.0" } }, "node_modules/es-to-primitive": { @@ -5893,14 +5708,15 @@ } }, "node_modules/es5-ext": { - "version": "0.10.62", - "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.62.tgz", - "integrity": "sha512-BHLqn0klhEpnOKSrzn/Xsz2UIW8j+cGmo9JLzr8BiUapV8hPL9+FliFqjwr9ngW7jWdnxv6eO+/LqyhJVqgrjA==", + "version": "0.10.64", + "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.64.tgz", + "integrity": "sha512-p2snDhiLaXe6dahss1LddxqEm+SkuDvV8dnIQG0MWjyHpcMNfXKPE+/Cc0y+PhxJX3A4xGNeFCj5oc0BUh6deg==", "dev": true, "hasInstallScript": true, "dependencies": { "es6-iterator": "^2.0.3", "es6-symbol": "^3.1.3", + "esniff": "^2.0.1", "next-tick": "^1.1.0" }, "engines": { @@ -5925,19 +5741,22 @@ "dev": true }, "node_modules/es6-symbol": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.3.tgz", - "integrity": "sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA==", + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.4.tgz", + "integrity": "sha512-U9bFFjX8tFiATgtkJ1zg25+KviIXpgRvRHS8sau3GfhVzThRQrOeksPeT0BWW2MNZs1OEWJ1DPXOQMn0KKRkvg==", "dev": true, "dependencies": { - "d": "^1.0.1", - "ext": "^1.1.2" + "d": "^1.0.2", + "ext": "^1.7.0" + }, + "engines": { + "node": ">=0.12" } }, "node_modules/escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz", + "integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==", "dev": true, "engines": { "node": ">=6" @@ -6114,9 +5933,9 @@ } }, "node_modules/eslint-config-prettier": { - "version": "8.8.0", - "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-8.8.0.tgz", - "integrity": "sha512-wLbQiFre3tdGgpDv67NQKnJuTlcUVYHas3k+DZCc2U2BadthoEY4B7hLPvAxaqdyOGCzuLfii2fqGph10va7oA==", + "version": "8.10.0", + "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-8.10.0.tgz", + "integrity": "sha512-SM8AMJdeQqRYT9O9zguiruQZaN7+z+E4eAP9oiLNGKMtomwaB1E9dcgUD6ZAn/eQAb52USbvezbiljfZUhbJcg==", "dev": true, "bin": { "eslint-config-prettier": "bin/cli.js" @@ -6152,14 +5971,14 @@ } }, "node_modules/eslint-import-resolver-node": { - "version": "0.3.7", - "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.7.tgz", - "integrity": "sha512-gozW2blMLJCeFpBwugLTGyvVjNoeo1knonXAcatC6bjPBZitotxdWf7Gimr25N4c0AAOo4eOUfaG82IJPDpqCA==", + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz", + "integrity": "sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==", "dev": true, "dependencies": { "debug": "^3.2.7", - "is-core-module": "^2.11.0", - "resolve": "^1.22.1" + "is-core-module": "^2.13.0", + "resolve": "^1.22.4" } }, "node_modules/eslint-import-resolver-node/node_modules/debug": { @@ -6172,9 +5991,9 @@ } }, "node_modules/eslint-module-utils": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.8.0.tgz", - "integrity": "sha512-aWajIYfsqCKRDgUfjEXNN/JlrzauMuSEy5sbd7WXbtW3EH6A6MpwEh42c7qD+MqQo9QMJ6fWLAeIJynx0g6OAw==", + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.8.1.tgz", + "integrity": "sha512-rXDXR3h7cs7dy9RNpUlQf80nX31XWJEyGq1tRMo+6GsO5VmTe4UTwtmonAD4ZkAsrfMVDA2wlGJ3790Ys+D49Q==", "dev": true, "dependencies": { "debug": "^3.2.7" @@ -6241,26 +6060,28 @@ } }, "node_modules/eslint-plugin-import": { - "version": "2.27.5", - "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.27.5.tgz", - "integrity": "sha512-LmEt3GVofgiGuiE+ORpnvP+kAm3h6MLZJ4Q5HCyHADofsb4VzXFsRiWj3c0OFiV+3DWFh0qg3v9gcPlfc3zRow==", + "version": "2.29.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.29.1.tgz", + "integrity": "sha512-BbPC0cuExzhiMo4Ff1BTVwHpjjv28C5R+btTOGaCRC7UEz801up0JadwkeSk5Ued6TG34uaczuVuH6qyy5YUxw==", "dev": true, "dependencies": { - "array-includes": "^3.1.6", - "array.prototype.flat": "^1.3.1", - "array.prototype.flatmap": "^1.3.1", + "array-includes": "^3.1.7", + "array.prototype.findlastindex": "^1.2.3", + "array.prototype.flat": "^1.3.2", + "array.prototype.flatmap": "^1.3.2", "debug": "^3.2.7", "doctrine": "^2.1.0", - "eslint-import-resolver-node": "^0.3.7", - "eslint-module-utils": "^2.7.4", - "has": "^1.0.3", - "is-core-module": "^2.11.0", + "eslint-import-resolver-node": "^0.3.9", + "eslint-module-utils": "^2.8.0", + "hasown": "^2.0.0", + "is-core-module": "^2.13.1", "is-glob": "^4.0.3", "minimatch": "^3.1.2", - "object.values": "^1.1.6", - "resolve": "^1.22.1", - "semver": "^6.3.0", - "tsconfig-paths": "^3.14.1" + "object.fromentries": "^2.0.7", + "object.groupby": "^1.0.1", + "object.values": "^1.1.7", + "semver": "^6.3.1", + "tsconfig-paths": "^3.15.0" }, "engines": { "node": ">=4" @@ -6290,6 +6111,15 @@ "node": ">=0.10.0" } }, + "node_modules/eslint-plugin-import/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, "node_modules/eslint-plugin-node": { "version": "11.1.0", "resolved": "https://registry.npmjs.org/eslint-plugin-node/-/eslint-plugin-node-11.1.0.tgz", @@ -6334,6 +6164,15 @@ "node": ">=4" } }, + "node_modules/eslint-plugin-node/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, "node_modules/eslint-plugin-prettier": { "version": "3.4.1", "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-3.4.1.tgz", @@ -6440,39 +6279,21 @@ "node": ">= 4" } }, - "node_modules/eslint/node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/eslint/node_modules/semver": { - "version": "7.5.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", - "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "node_modules/esniff": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/esniff/-/esniff-2.0.1.tgz", + "integrity": "sha512-kTUIGKQ/mDPFoJ0oVfcmyJn4iBDRptjNVIzwIFR7tqWXdVI9xfA2RMwY/gbSpJG3lkdWNEjLap/NqVHZiJsdfg==", "dev": true, "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" + "d": "^1.0.1", + "es5-ext": "^0.10.62", + "event-emitter": "^0.3.5", + "type": "^2.7.2" }, "engines": { - "node": ">=10" + "node": ">=0.10" } }, - "node_modules/eslint/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - }, "node_modules/espree": { "version": "7.3.1", "resolved": "https://registry.npmjs.org/espree/-/espree-7.3.1.tgz", @@ -6595,24 +6416,22 @@ "dev": true }, "node_modules/eth-gas-reporter": { - "version": "0.2.25", - "resolved": "https://registry.npmjs.org/eth-gas-reporter/-/eth-gas-reporter-0.2.25.tgz", - "integrity": "sha512-1fRgyE4xUB8SoqLgN3eDfpDfwEfRxh2Sz1b7wzFbyQA+9TekMmvSjjoRu9SKcSVyK+vLkLIsVbJDsTWjw195OQ==", + "version": "0.2.27", + "resolved": "https://registry.npmjs.org/eth-gas-reporter/-/eth-gas-reporter-0.2.27.tgz", + "integrity": "sha512-femhvoAM7wL0GcI8ozTdxfuBtBFJ9qsyIAsmKVjlWAHUbdnnXHt+lKzz/kmldM5lA9jLuNHGwuIxorNpLbR1Zw==", "dev": true, "dependencies": { - "@ethersproject/abi": "^5.0.0-beta.146", "@solidity-parser/parser": "^0.14.0", + "axios": "^1.5.1", "cli-table3": "^0.5.0", "colors": "1.4.0", "ethereum-cryptography": "^1.0.3", - "ethers": "^4.0.40", + "ethers": "^5.7.2", "fs-readdir-recursive": "^1.1.0", "lodash": "^4.17.14", "markdown-table": "^1.1.3", - "mocha": "^7.1.1", + "mocha": "^10.2.0", "req-cwd": "^2.0.0", - "request": "^2.88.0", - "request-promise-native": "^1.0.5", "sha1": "^1.1.1", "sync-request": "^6.0.0" }, @@ -6625,734 +6444,838 @@ } } }, - "node_modules/eth-gas-reporter/node_modules/ansi-colors": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.3.tgz", - "integrity": "sha512-LEHHyuhlPY3TmuUYMh2oz89lTShfvgbmzaBcxve9t/9Wuy7Dwf4yoAKcND7KFT1HAQfqZ12qtc+DUrBMeKF9nw==", + "node_modules/eth-gas-reporter/node_modules/@noble/hashes": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.2.0.tgz", + "integrity": "sha512-FZfhjEDbT5GRswV3C6uvLPHMiVD6lQBmpoX5+eSiPaMTXte/IKqI5dykDxzZB/WBeK/CDuQRBWarPdi3FNY2zQ==", "dev": true, - "engines": { - "node": ">=6" - } + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ] }, - "node_modules/eth-gas-reporter/node_modules/ansi-regex": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz", - "integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==", + "node_modules/eth-gas-reporter/node_modules/@scure/bip32": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@scure/bip32/-/bip32-1.1.5.tgz", + "integrity": "sha512-XyNh1rB0SkEqd3tXcXMi+Xe1fvg+kUIcoRIEujP1Jgv7DqW2r9lg3Ah0NkFaCs9sTkQAQA8kw7xiRXzENi9Rtw==", "dev": true, - "engines": { - "node": ">=6" + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ], + "dependencies": { + "@noble/hashes": "~1.2.0", + "@noble/secp256k1": "~1.7.0", + "@scure/base": "~1.1.0" } }, - "node_modules/eth-gas-reporter/node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "node_modules/eth-gas-reporter/node_modules/@scure/bip39": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@scure/bip39/-/bip39-1.1.1.tgz", + "integrity": "sha512-t+wDck2rVkh65Hmv280fYdVdY25J9YeEUIgn2LG1WM6gxFkGzcksoDiUkWVpVp3Oex9xGC68JU2dSbUfwZ2jPg==", "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ], "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" + "@noble/hashes": "~1.2.0", + "@scure/base": "~1.1.0" } }, - "node_modules/eth-gas-reporter/node_modules/bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", - "dev": true - }, - "node_modules/eth-gas-reporter/node_modules/camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "node_modules/eth-gas-reporter/node_modules/ethereum-cryptography": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-1.2.0.tgz", + "integrity": "sha512-6yFQC9b5ug6/17CQpCyE3k9eKBMdhyVjzUy1WkiuY/E4vj/SXDBbCw8QEIaXqf0Mf2SnY6RmpDcwlUmBSS0EJw==", "dev": true, - "engines": { - "node": ">=6" + "dependencies": { + "@noble/hashes": "1.2.0", + "@noble/secp256k1": "1.7.1", + "@scure/bip32": "1.1.5", + "@scure/bip39": "1.1.1" } }, - "node_modules/eth-gas-reporter/node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "node_modules/eth-lib": { + "version": "0.1.29", + "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.1.29.tgz", + "integrity": "sha512-bfttrr3/7gG4E02HoWTDUcDDslN003OlOoBxk9virpAZQ1ja/jDgwkWB8QfJF7ojuEowrqy+lzp9VcJG7/k5bQ==", "dev": true, "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" + "bn.js": "^4.11.6", + "elliptic": "^6.4.0", + "nano-json-stream-parser": "^0.1.2", + "servify": "^0.1.12", + "ws": "^3.0.0", + "xhr-request-promise": "^0.1.2" } }, - "node_modules/eth-gas-reporter/node_modules/chalk/node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "node_modules/eth-lib/node_modules/bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", + "dev": true + }, + "node_modules/eth-lib/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "node_modules/eth-lib/node_modules/ws": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/ws/-/ws-3.3.3.tgz", + "integrity": "sha512-nnWLa/NwZSt4KQJu51MYlCcSQ5g7INpOrOMt4XV8j4dqTXdmlUmSHQ8/oLC069ckre0fRsgfvsKwbTdtKLCDkA==", "dev": true, "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" + "async-limiter": "~1.0.0", + "safe-buffer": "~5.1.0", + "ultron": "~1.1.0" } }, - "node_modules/eth-gas-reporter/node_modules/chokidar": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.3.0.tgz", - "integrity": "sha512-dGmKLDdT3Gdl7fBUe8XK+gAtGmzy5Fn0XkkWQuYxGIgWVPPse2CxFA5mtrlD0TOHaHjEUqkWNyP1XdHoJES/4A==", + "node_modules/ethereum-bloom-filters": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/ethereum-bloom-filters/-/ethereum-bloom-filters-1.1.0.tgz", + "integrity": "sha512-J1gDRkLpuGNvWYzWslBQR9cDV4nd4kfvVTE/Wy4Kkm4yb3EYRSlyi0eB/inTsSTTVyA0+HyzHgbr95Fn/Z1fSw==", + "dependencies": { + "@noble/hashes": "^1.4.0" + } + }, + "node_modules/ethereum-cryptography": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz", + "integrity": "sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==", "dev": true, "dependencies": { - "anymatch": "~3.1.1", - "braces": "~3.0.2", - "glob-parent": "~5.1.0", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.2.0" + "@types/pbkdf2": "^3.0.0", + "@types/secp256k1": "^4.0.1", + "blakejs": "^1.1.0", + "browserify-aes": "^1.2.0", + "bs58check": "^2.1.2", + "create-hash": "^1.2.0", + "create-hmac": "^1.1.7", + "hash.js": "^1.1.7", + "keccak": "^3.0.0", + "pbkdf2": "^3.0.17", + "randombytes": "^2.1.0", + "safe-buffer": "^5.1.2", + "scrypt-js": "^3.0.0", + "secp256k1": "^4.0.1", + "setimmediate": "^1.0.5" + } + }, + "node_modules/ethereum-waffle": { + "version": "3.4.4", + "resolved": "https://registry.npmjs.org/ethereum-waffle/-/ethereum-waffle-3.4.4.tgz", + "integrity": "sha512-PA9+jCjw4WC3Oc5ocSMBj5sXvueWQeAbvCA+hUlb6oFgwwKyq5ka3bWQ7QZcjzIX+TdFkxP4IbFmoY2D8Dkj9Q==", + "dev": true, + "dependencies": { + "@ethereum-waffle/chai": "^3.4.4", + "@ethereum-waffle/compiler": "^3.4.4", + "@ethereum-waffle/mock-contract": "^3.4.4", + "@ethereum-waffle/provider": "^3.4.4", + "ethers": "^5.0.1" }, - "engines": { - "node": ">= 8.10.0" + "bin": { + "waffle": "bin/waffle" }, - "optionalDependencies": { - "fsevents": "~2.1.1" + "engines": { + "node": ">=10.0" } }, - "node_modules/eth-gas-reporter/node_modules/cliui": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", - "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", + "node_modules/ethereumjs-abi": { + "version": "0.6.8", + "resolved": "https://registry.npmjs.org/ethereumjs-abi/-/ethereumjs-abi-0.6.8.tgz", + "integrity": "sha512-Tx0r/iXI6r+lRsdvkFDlut0N08jWMnKRZ6Gkq+Nmw75lZe4e6o3EkSnkaBP5NF6+m5PTGAr9JP43N3LyeoglsA==", "dev": true, "dependencies": { - "string-width": "^3.1.0", - "strip-ansi": "^5.2.0", - "wrap-ansi": "^5.1.0" + "bn.js": "^4.11.8", + "ethereumjs-util": "^6.0.0" } }, - "node_modules/eth-gas-reporter/node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "node_modules/ethereumjs-abi/node_modules/@types/bn.js": { + "version": "4.11.6", + "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-4.11.6.tgz", + "integrity": "sha512-pqr857jrp2kPuO9uRjZ3PwnJTjoQy+fcdxvBTvHm6dkmEL9q+hDD/2j/0ELOBPtPnS8LjCX0gI9nbl8lVkadpg==", "dev": true, "dependencies": { - "color-name": "1.1.3" + "@types/node": "*" } }, - "node_modules/eth-gas-reporter/node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "node_modules/ethereumjs-abi/node_modules/bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", "dev": true }, - "node_modules/eth-gas-reporter/node_modules/debug": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", - "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", - "deprecated": "Debug versions >=3.2.0 <3.2.7 || >=4 <4.3.1 have a low-severity ReDos regression when used in a Node.js environment. It is recommended you upgrade to 3.2.7 or 4.3.1. (https://github.com/visionmedia/debug/issues/797)", + "node_modules/ethereumjs-abi/node_modules/ethereumjs-util": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-6.2.1.tgz", + "integrity": "sha512-W2Ktez4L01Vexijrm5EB6w7dg4n/TgpoYU4avuT5T3Vmnw/eCRtiBrJfQYS/DCSvDIOLn2k57GcHdeBcgVxAqw==", "dev": true, "dependencies": { - "ms": "^2.1.1" + "@types/bn.js": "^4.11.3", + "bn.js": "^4.11.0", + "create-hash": "^1.1.2", + "elliptic": "^6.5.2", + "ethereum-cryptography": "^0.1.3", + "ethjs-util": "0.1.6", + "rlp": "^2.2.3" } }, - "node_modules/eth-gas-reporter/node_modules/decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", + "node_modules/ethereumjs-util": { + "version": "7.1.5", + "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-7.1.5.tgz", + "integrity": "sha512-SDl5kKrQAudFBUe5OJM9Ac6WmMyYmXX/6sTmLZ3ffG2eY6ZIGBes3pEDxNN6V72WyOw4CPD5RomKdsa8DAAwLg==", "dev": true, + "dependencies": { + "@types/bn.js": "^5.1.0", + "bn.js": "^5.1.2", + "create-hash": "^1.1.2", + "ethereum-cryptography": "^0.1.3", + "rlp": "^2.2.4" + }, "engines": { - "node": ">=0.10.0" + "node": ">=10.0.0" } }, - "node_modules/eth-gas-reporter/node_modules/diff": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", - "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", - "dev": true, - "engines": { - "node": ">=0.3.1" + "node_modules/ethers": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/ethers/-/ethers-5.7.2.tgz", + "integrity": "sha512-wswUsmWo1aOK8rR7DIKiWSw9DbLWe6x98Jrn8wcTflTVvaXhAMaB5zGAXy0GYQEQp9iO1iSHWVyARQm11zUtyg==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/abi": "5.7.0", + "@ethersproject/abstract-provider": "5.7.0", + "@ethersproject/abstract-signer": "5.7.0", + "@ethersproject/address": "5.7.0", + "@ethersproject/base64": "5.7.0", + "@ethersproject/basex": "5.7.0", + "@ethersproject/bignumber": "5.7.0", + "@ethersproject/bytes": "5.7.0", + "@ethersproject/constants": "5.7.0", + "@ethersproject/contracts": "5.7.0", + "@ethersproject/hash": "5.7.0", + "@ethersproject/hdnode": "5.7.0", + "@ethersproject/json-wallets": "5.7.0", + "@ethersproject/keccak256": "5.7.0", + "@ethersproject/logger": "5.7.0", + "@ethersproject/networks": "5.7.1", + "@ethersproject/pbkdf2": "5.7.0", + "@ethersproject/properties": "5.7.0", + "@ethersproject/providers": "5.7.2", + "@ethersproject/random": "5.7.0", + "@ethersproject/rlp": "5.7.0", + "@ethersproject/sha2": "5.7.0", + "@ethersproject/signing-key": "5.7.0", + "@ethersproject/solidity": "5.7.0", + "@ethersproject/strings": "5.7.0", + "@ethersproject/transactions": "5.7.0", + "@ethersproject/units": "5.7.0", + "@ethersproject/wallet": "5.7.0", + "@ethersproject/web": "5.7.1", + "@ethersproject/wordlists": "5.7.0" } }, - "node_modules/eth-gas-reporter/node_modules/emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true - }, - "node_modules/eth-gas-reporter/node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true, + "node_modules/ethjs-unit": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/ethjs-unit/-/ethjs-unit-0.1.6.tgz", + "integrity": "sha512-/Sn9Y0oKl0uqQuvgFk/zQgR7aw1g36qX/jzSQ5lSwlO0GigPymk4eGQfeNTD03w1dPOqfz8V77Cy43jH56pagw==", + "dependencies": { + "bn.js": "4.11.6", + "number-to-bn": "1.7.0" + }, "engines": { - "node": ">=0.8.0" + "node": ">=6.5.0", + "npm": ">=3" } }, - "node_modules/eth-gas-reporter/node_modules/ethers": { - "version": "4.0.49", - "resolved": "https://registry.npmjs.org/ethers/-/ethers-4.0.49.tgz", - "integrity": "sha512-kPltTvWiyu+OktYy1IStSO16i2e7cS9D9OxZ81q2UUaiNPVrm/RTcbxamCXF9VUSKzJIdJV68EAIhTEVBalRWg==", - "dev": true, - "dependencies": { - "aes-js": "3.0.0", - "bn.js": "^4.11.9", - "elliptic": "6.5.4", - "hash.js": "1.1.3", - "js-sha3": "0.5.7", - "scrypt-js": "2.0.4", - "setimmediate": "1.0.4", - "uuid": "2.0.1", - "xmlhttprequest": "1.8.0" - } + "node_modules/ethjs-unit/node_modules/bn.js": { + "version": "4.11.6", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.6.tgz", + "integrity": "sha512-XWwnNNFCuuSQ0m3r3C4LE3EiORltHd9M05pq6FOlVeiophzRbMo50Sbz1ehl8K3Z+jw9+vmgnXefY1hz8X+2wA==" }, - "node_modules/eth-gas-reporter/node_modules/find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "node_modules/ethjs-util": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/ethjs-util/-/ethjs-util-0.1.6.tgz", + "integrity": "sha512-CUnVOQq7gSpDHZVVrQW8ExxUETWrnrvXYvYz55wOU8Uj4VCgw56XC2B/fVqQN+f7gmrnRHSLVnFAwsCuNwji8w==", "dev": true, "dependencies": { - "locate-path": "^3.0.0" + "is-hex-prefixed": "1.0.0", + "strip-hex-prefix": "1.0.0" }, "engines": { - "node": ">=6" + "node": ">=6.5.0", + "npm": ">=3" } }, - "node_modules/eth-gas-reporter/node_modules/flat": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/flat/-/flat-4.1.1.tgz", - "integrity": "sha512-FmTtBsHskrU6FJ2VxCnsDb84wu9zhmO3cUX2kGFb5tuwhfXxGciiT0oRY+cck35QmG+NmGh5eLz6lLCpWTqwpA==", + "node_modules/event-emitter": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.5.tgz", + "integrity": "sha512-D9rRn9y7kLPnJ+hMq7S/nhvoKwwvVJahBi2BPmx3bvbsEdK3W9ii8cBSGjP+72/LnM4n6fo3+dkCX5FeTQruXA==", "dev": true, "dependencies": { - "is-buffer": "~2.0.3" - }, - "bin": { - "flat": "cli.js" + "d": "1", + "es5-ext": "~0.10.14" } }, - "node_modules/eth-gas-reporter/node_modules/fsevents": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz", - "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==", - "deprecated": "\"Please update to latest v2.3 or v2.2\"", - "dev": true, - "hasInstallScript": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + "node_modules/eventemitter3": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.4.tgz", + "integrity": "sha512-rlaVLnVxtxvoyLsQQFBx53YmXHDxRIzzTLbdfxqi4yocpSjAxXwkU0cScM5JgSKMqEhrZpnvQ2D9gjylR0AimQ==", + "dev": true + }, + "node_modules/evp_bytestokey": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", + "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", + "dev": true, + "dependencies": { + "md5.js": "^1.3.4", + "safe-buffer": "^5.1.1" } }, - "node_modules/eth-gas-reporter/node_modules/glob": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", - "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", + "node_modules/express": { + "version": "4.19.2", + "resolved": "https://registry.npmjs.org/express/-/express-4.19.2.tgz", + "integrity": "sha512-5T6nhjsT+EOMzuck8JjBHARTHfMht0POzlA60WV2pMD3gyXw2LZnZ+ueGdNxG+0calOJcWKbpFcuzLZ91YWq9Q==", "dev": true, "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" + "accepts": "~1.3.8", + "array-flatten": "1.1.1", + "body-parser": "1.20.2", + "content-disposition": "0.5.4", + "content-type": "~1.0.4", + "cookie": "0.6.0", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "2.0.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "1.2.0", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "merge-descriptors": "1.0.1", + "methods": "~1.1.2", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "path-to-regexp": "0.1.7", + "proxy-addr": "~2.0.7", + "qs": "6.11.0", + "range-parser": "~1.2.1", + "safe-buffer": "5.2.1", + "send": "0.18.0", + "serve-static": "1.15.0", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" }, "engines": { - "node": "*" + "node": ">= 0.10.0" } }, - "node_modules/eth-gas-reporter/node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "node_modules/express/node_modules/cookie": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz", + "integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==", "dev": true, "engines": { - "node": ">=4" + "node": ">= 0.6" } }, - "node_modules/eth-gas-reporter/node_modules/hash.js": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.3.tgz", - "integrity": "sha512-/UETyP0W22QILqS+6HowevwhEFJ3MBJnwTf75Qob9Wz9t0DPuisL8kW8YZMK62dHAKE1c1p+gY1TtOLY+USEHA==", + "node_modules/express/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "dev": true, "dependencies": { - "inherits": "^2.0.3", - "minimalistic-assert": "^1.0.0" + "ms": "2.0.0" } }, - "node_modules/eth-gas-reporter/node_modules/js-sha3": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.5.7.tgz", - "integrity": "sha512-GII20kjaPX0zJ8wzkTbNDYMY7msuZcTWk8S5UOh6806Jq/wz1J8/bnr8uGU0DAUmYDjj2Mr4X1cW8v/GLYnR+g==", + "node_modules/express/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", "dev": true }, - "node_modules/eth-gas-reporter/node_modules/js-yaml": { - "version": "3.13.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", - "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", + "node_modules/express/node_modules/qs": { + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", + "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", "dev": true, "dependencies": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" + "side-channel": "^1.0.4" }, - "bin": { - "js-yaml": "bin/js-yaml.js" + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/eth-gas-reporter/node_modules/locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "node_modules/ext": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/ext/-/ext-1.7.0.tgz", + "integrity": "sha512-6hxeJYaL110a9b5TEJSj0gojyHQAmA2ch5Os+ySCiA1QGdS697XWY1pzsrSjqA9LDEEgdB/KypIlR59RcLuHYw==", "dev": true, "dependencies": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - }, - "engines": { - "node": ">=6" + "type": "^2.7.2" } }, - "node_modules/eth-gas-reporter/node_modules/log-symbols": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-3.0.0.tgz", - "integrity": "sha512-dSkNGuI7iG3mfvDzUuYZyvk5dD9ocYCYzNU6CYDE6+Xqd+gwme6Z00NS3dUh8mq/73HaEtT7m6W+yUPtU6BZnQ==", + "node_modules/extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "dev": true + }, + "node_modules/extsprintf": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", + "integrity": "sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g==", + "dev": true, + "engines": [ + "node >=0.6.0" + ] + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true + }, + "node_modules/fast-diff": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.3.0.tgz", + "integrity": "sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==", + "dev": true + }, + "node_modules/fast-glob": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", + "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", "dev": true, "dependencies": { - "chalk": "^2.4.2" + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" }, "engines": { - "node": ">=8" + "node": ">=8.6.0" } }, - "node_modules/eth-gas-reporter/node_modules/minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "dev": true + }, + "node_modules/fastq": { + "version": "1.17.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", + "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", "dev": true, "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" + "reusify": "^1.0.4" } }, - "node_modules/eth-gas-reporter/node_modules/mkdirp": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", - "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "node_modules/file-entry-cache": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", "dev": true, "dependencies": { - "minimist": "^1.2.5" + "flat-cache": "^3.0.4" }, - "bin": { - "mkdirp": "bin/cmd.js" + "engines": { + "node": "^10.12.0 || >=12.0.0" } }, - "node_modules/eth-gas-reporter/node_modules/mocha": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-7.2.0.tgz", - "integrity": "sha512-O9CIypScywTVpNaRrCAgoUnJgozpIofjKUYmJhiCIJMiuYnLI6otcb1/kpW9/n/tJODHGZ7i8aLQoDVsMtOKQQ==", + "node_modules/fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", "dev": true, "dependencies": { - "ansi-colors": "3.2.3", - "browser-stdout": "1.3.1", - "chokidar": "3.3.0", - "debug": "3.2.6", - "diff": "3.5.0", - "escape-string-regexp": "1.0.5", - "find-up": "3.0.0", - "glob": "7.1.3", - "growl": "1.10.5", - "he": "1.2.0", - "js-yaml": "3.13.1", - "log-symbols": "3.0.0", - "minimatch": "3.0.4", - "mkdirp": "0.5.5", - "ms": "2.1.1", - "node-environment-flags": "1.0.6", - "object.assign": "4.1.0", - "strip-json-comments": "2.0.1", - "supports-color": "6.0.0", - "which": "1.3.1", - "wide-align": "1.1.3", - "yargs": "13.3.2", - "yargs-parser": "13.1.2", - "yargs-unparser": "1.6.0" - }, - "bin": { - "_mocha": "bin/_mocha", - "mocha": "bin/mocha" + "to-regex-range": "^5.0.1" }, "engines": { - "node": ">= 8.10.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/mochajs" + "node": ">=8" } }, - "node_modules/eth-gas-reporter/node_modules/ms": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", - "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", - "dev": true - }, - "node_modules/eth-gas-reporter/node_modules/object.assign": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz", - "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==", + "node_modules/finalhandler": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", + "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", "dev": true, "dependencies": { - "define-properties": "^1.1.2", - "function-bind": "^1.1.1", - "has-symbols": "^1.0.0", - "object-keys": "^1.0.11" + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "statuses": "2.0.1", + "unpipe": "~1.0.0" }, "engines": { - "node": ">= 0.4" + "node": ">= 0.8" } }, - "node_modules/eth-gas-reporter/node_modules/p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "node_modules/finalhandler/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "dev": true, "dependencies": { - "p-try": "^2.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "ms": "2.0.0" } }, - "node_modules/eth-gas-reporter/node_modules/p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "node_modules/finalhandler/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true + }, + "node_modules/find-replace": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/find-replace/-/find-replace-1.0.3.tgz", + "integrity": "sha512-KrUnjzDCD9426YnCP56zGYy/eieTnhtK6Vn++j+JJzmlsWWwEkDnsyVF575spT6HJ6Ow9tlbT3TQTDsa+O4UWA==", "dev": true, "dependencies": { - "p-limit": "^2.0.0" + "array-back": "^1.0.4", + "test-value": "^2.1.0" }, "engines": { - "node": ">=6" + "node": ">=4.0.0" } }, - "node_modules/eth-gas-reporter/node_modules/p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "node_modules/find-replace/node_modules/array-back": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/array-back/-/array-back-1.0.4.tgz", + "integrity": "sha512-1WxbZvrmyhkNoeYcizokbmh5oiOCIfyvGtcqbK3Ls1v1fKcquzxnQSceOx6tzq7jmai2kFLWIpGND2cLhH6TPw==", "dev": true, + "dependencies": { + "typical": "^2.6.0" + }, "engines": { - "node": ">=6" + "node": ">=0.12.0" } }, - "node_modules/eth-gas-reporter/node_modules/readdirp": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.2.0.tgz", - "integrity": "sha512-crk4Qu3pmXwgxdSgGhgA/eXiJAPQiX4GMOZZMXnqKxHX7TaoL+3gQVo/WeuAiogr07DpnfjIMpXXa+PAIvwPGQ==", + "node_modules/find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha512-NWzkk0jSJtTt08+FBFMvXoeZnOJD+jTtsRmBYbAIzJdX6l7dLgR7CTubCM5/eDdPUBvLCeVasP1brfVR/9/EZQ==", "dev": true, "dependencies": { - "picomatch": "^2.0.4" + "locate-path": "^2.0.0" }, "engines": { - "node": ">= 8" + "node": ">=4" } }, - "node_modules/eth-gas-reporter/node_modules/require-main-filename": { + "node_modules/find-yarn-workspace-root": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", - "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", - "dev": true - }, - "node_modules/eth-gas-reporter/node_modules/scrypt-js": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/scrypt-js/-/scrypt-js-2.0.4.tgz", - "integrity": "sha512-4KsaGcPnuhtCZQCxFxN3GVYIhKFPTdLd8PLC552XwbMndtD0cjRFAhDuuydXQ0h08ZfPgzqe6EKHozpuH74iDw==", - "dev": true - }, - "node_modules/eth-gas-reporter/node_modules/setimmediate": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.4.tgz", - "integrity": "sha512-/TjEmXQVEzdod/FFskf3o7oOAsGhHf2j1dZqRFbDzq4F3mvvxflIIi4Hd3bLQE9y/CpwqfSQam5JakI/mi3Pog==", - "dev": true - }, - "node_modules/eth-gas-reporter/node_modules/string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "resolved": "https://registry.npmjs.org/find-yarn-workspace-root/-/find-yarn-workspace-root-2.0.0.tgz", + "integrity": "sha512-1IMnbjt4KzsQfnhnzNd8wUEgXZ44IzZaZmnLYx7D5FZlaHt2gW20Cri8Q+E/t5tIj4+epTBub+2Zxu/vNILzqQ==", "dev": true, "dependencies": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - }, - "engines": { - "node": ">=6" + "micromatch": "^4.0.2" } }, - "node_modules/eth-gas-reporter/node_modules/strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "node_modules/flat": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", + "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", + "dev": true, + "bin": { + "flat": "cli.js" + } + }, + "node_modules/flat-cache": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz", + "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==", "dev": true, "dependencies": { - "ansi-regex": "^4.1.0" + "flatted": "^3.2.9", + "keyv": "^4.5.3", + "rimraf": "^3.0.2" }, "engines": { - "node": ">=6" + "node": "^10.12.0 || >=12.0.0" } }, - "node_modules/eth-gas-reporter/node_modules/strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", + "node_modules/flatted": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz", + "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==", + "dev": true + }, + "node_modules/follow-redirects": { + "version": "1.15.6", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz", + "integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==", "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], "engines": { - "node": ">=0.10.0" + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } } }, - "node_modules/eth-gas-reporter/node_modules/supports-color": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.0.0.tgz", - "integrity": "sha512-on9Kwidc1IUQo+bQdhi8+Tijpo0e1SS6RoGo2guUwn5vdaxw8RXOF9Vb2ws+ihWOmh4JnCJOvaziZWP1VABaLg==", + "node_modules/for-each": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", + "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", "dev": true, "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=6" + "is-callable": "^1.1.3" } }, - "node_modules/eth-gas-reporter/node_modules/uuid": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-2.0.1.tgz", - "integrity": "sha512-nWg9+Oa3qD2CQzHIP4qKUqwNfzKn8P0LtFhotaCTFchsV7ZfDhAybeip/HZVeMIpZi9JgY1E3nUlwaCmZT1sEg==", - "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", - "dev": true - }, - "node_modules/eth-gas-reporter/node_modules/which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "node_modules/forever-agent": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", + "integrity": "sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw==", "dev": true, - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "which": "bin/which" + "engines": { + "node": "*" } }, - "node_modules/eth-gas-reporter/node_modules/which-module": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.1.tgz", - "integrity": "sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ==", - "dev": true - }, - "node_modules/eth-gas-reporter/node_modules/wrap-ansi": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", - "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", + "node_modules/form-data": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", "dev": true, "dependencies": { - "ansi-styles": "^3.2.0", - "string-width": "^3.0.0", - "strip-ansi": "^5.0.0" + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" }, "engines": { - "node": ">=6" + "node": ">= 6" } }, - "node_modules/eth-gas-reporter/node_modules/y18n": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", - "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==", + "node_modules/form-data-encoder": { + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/form-data-encoder/-/form-data-encoder-1.7.1.tgz", + "integrity": "sha512-EFRDrsMm/kyqbTQocNvRXMLjc7Es2Vk+IQFx/YW7hkUH1eBl4J1fqiP34l74Yt0pFLCNpc06fkbVk00008mzjg==", "dev": true }, - "node_modules/eth-gas-reporter/node_modules/yargs": { - "version": "13.3.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", - "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", + "node_modules/forwarded": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", "dev": true, - "dependencies": { - "cliui": "^5.0.0", - "find-up": "^3.0.0", - "get-caller-file": "^2.0.1", - "require-directory": "^2.1.1", - "require-main-filename": "^2.0.0", - "set-blocking": "^2.0.0", - "string-width": "^3.0.0", - "which-module": "^2.0.0", - "y18n": "^4.0.0", - "yargs-parser": "^13.1.2" + "engines": { + "node": ">= 0.6" } }, - "node_modules/eth-gas-reporter/node_modules/yargs-parser": { - "version": "13.1.2", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", - "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", + "node_modules/fp-ts": { + "version": "1.19.3", + "resolved": "https://registry.npmjs.org/fp-ts/-/fp-ts-1.19.3.tgz", + "integrity": "sha512-H5KQDspykdHuztLTg+ajGN0Z2qUjcEf3Ybxc6hLt0k7/zPkn29XnKnxlBPyW2XIddWrGaJBzBl4VLYOtk39yZg==", + "dev": true + }, + "node_modules/fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", "dev": true, - "dependencies": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" + "engines": { + "node": ">= 0.6" } }, - "node_modules/eth-gas-reporter/node_modules/yargs-unparser": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-1.6.0.tgz", - "integrity": "sha512-W9tKgmSn0DpSatfri0nx52Joq5hVXgeLiqR/5G0sZNDoLZFOr/xjBUDcShCOGNsBnEMNo1KAMBkTej1Hm62HTw==", + "node_modules/fs-extra": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", + "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", "dev": true, "dependencies": { - "flat": "^4.1.0", - "lodash": "^4.17.15", - "yargs": "^13.3.0" + "graceful-fs": "^4.1.2", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" }, "engines": { - "node": ">=6" + "node": ">=6 <7 || >=8" } }, - "node_modules/eth-lib": { - "version": "0.1.29", - "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.1.29.tgz", - "integrity": "sha512-bfttrr3/7gG4E02HoWTDUcDDslN003OlOoBxk9virpAZQ1ja/jDgwkWB8QfJF7ojuEowrqy+lzp9VcJG7/k5bQ==", + "node_modules/fs-minipass": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-1.2.7.tgz", + "integrity": "sha512-GWSSJGFy4e9GUeCcbIkED+bgAoFyj7XF1mV8rma3QW4NIqX9Kyx79N/PF61H5udOV3aY1IaMLs6pGbH71nlCTA==", "dev": true, "dependencies": { - "bn.js": "^4.11.6", - "elliptic": "^6.4.0", - "nano-json-stream-parser": "^0.1.2", - "servify": "^0.1.12", - "ws": "^3.0.0", - "xhr-request-promise": "^0.1.2" + "minipass": "^2.6.0" } }, - "node_modules/eth-lib/node_modules/bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", + "node_modules/fs-readdir-recursive": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fs-readdir-recursive/-/fs-readdir-recursive-1.1.0.tgz", + "integrity": "sha512-GNanXlVr2pf02+sPN40XN8HG+ePaNcvM0q5mZBd668Obwb0yD5GiUbZOFgwn8kGMY6I3mdyDJzieUy3PTYyTRA==", "dev": true }, - "node_modules/eth-lib/node_modules/ws": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/ws/-/ws-3.3.3.tgz", - "integrity": "sha512-nnWLa/NwZSt4KQJu51MYlCcSQ5g7INpOrOMt4XV8j4dqTXdmlUmSHQ8/oLC069ckre0fRsgfvsKwbTdtKLCDkA==", - "dev": true, - "dependencies": { - "async-limiter": "~1.0.0", - "safe-buffer": "~5.1.0", - "ultron": "~1.1.0" - } + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true }, - "node_modules/ethereum-bloom-filters": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/ethereum-bloom-filters/-/ethereum-bloom-filters-1.0.10.tgz", - "integrity": "sha512-rxJ5OFN3RwjQxDcFP2Z5+Q9ho4eIdEmSc2ht0fCu8Se9nbXjZ7/031uXoUYJ87KHCOdVeiUuwSnoS7hmYAGVHA==", - "dependencies": { - "js-sha3": "^0.8.0" + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" } }, - "node_modules/ethereum-cryptography": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-1.2.0.tgz", - "integrity": "sha512-6yFQC9b5ug6/17CQpCyE3k9eKBMdhyVjzUy1WkiuY/E4vj/SXDBbCw8QEIaXqf0Mf2SnY6RmpDcwlUmBSS0EJw==", + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", "dev": true, - "dependencies": { - "@noble/hashes": "1.2.0", - "@noble/secp256k1": "1.7.1", - "@scure/bip32": "1.1.5", - "@scure/bip39": "1.1.1" + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/ethereum-waffle": { - "version": "3.4.4", - "resolved": "https://registry.npmjs.org/ethereum-waffle/-/ethereum-waffle-3.4.4.tgz", - "integrity": "sha512-PA9+jCjw4WC3Oc5ocSMBj5sXvueWQeAbvCA+hUlb6oFgwwKyq5ka3bWQ7QZcjzIX+TdFkxP4IbFmoY2D8Dkj9Q==", + "node_modules/function.prototype.name": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.6.tgz", + "integrity": "sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==", "dev": true, "dependencies": { - "@ethereum-waffle/chai": "^3.4.4", - "@ethereum-waffle/compiler": "^3.4.4", - "@ethereum-waffle/mock-contract": "^3.4.4", - "@ethereum-waffle/provider": "^3.4.4", - "ethers": "^5.0.1" - }, - "bin": { - "waffle": "bin/waffle" + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "functions-have-names": "^1.2.3" }, "engines": { - "node": ">=10.0" - } - }, - "node_modules/ethereumjs-abi": { - "version": "0.6.8", - "resolved": "https://registry.npmjs.org/ethereumjs-abi/-/ethereumjs-abi-0.6.8.tgz", - "integrity": "sha512-Tx0r/iXI6r+lRsdvkFDlut0N08jWMnKRZ6Gkq+Nmw75lZe4e6o3EkSnkaBP5NF6+m5PTGAr9JP43N3LyeoglsA==", - "dev": true, - "dependencies": { - "bn.js": "^4.11.8", - "ethereumjs-util": "^6.0.0" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/ethereumjs-abi/node_modules/bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", + "node_modules/functional-red-black-tree": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", + "integrity": "sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g==", "dev": true }, - "node_modules/ethereumjs-util": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-6.2.1.tgz", - "integrity": "sha512-W2Ktez4L01Vexijrm5EB6w7dg4n/TgpoYU4avuT5T3Vmnw/eCRtiBrJfQYS/DCSvDIOLn2k57GcHdeBcgVxAqw==", + "node_modules/functions-have-names": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", + "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", "dev": true, - "dependencies": { - "@types/bn.js": "^4.11.3", - "bn.js": "^4.11.0", - "create-hash": "^1.1.2", - "elliptic": "^6.5.2", - "ethereum-cryptography": "^0.1.3", - "ethjs-util": "0.1.6", - "rlp": "^2.2.3" + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/ethereumjs-util/node_modules/@types/bn.js": { - "version": "4.11.6", - "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-4.11.6.tgz", - "integrity": "sha512-pqr857jrp2kPuO9uRjZ3PwnJTjoQy+fcdxvBTvHm6dkmEL9q+hDD/2j/0ELOBPtPnS8LjCX0gI9nbl8lVkadpg==", + "node_modules/ganache-core": { + "version": "2.13.2", + "resolved": "https://registry.npmjs.org/ganache-core/-/ganache-core-2.13.2.tgz", + "integrity": "sha512-tIF5cR+ANQz0+3pHWxHjIwHqFXcVo0Mb+kcsNhglNFALcYo49aQpnS9dqHartqPfMFjiHh/qFoD3mYK0d/qGgw==", + "bundleDependencies": [ + "keccak" + ], + "deprecated": "ganache-core is now ganache; visit https://trfl.io/g7 for details", "dev": true, + "hasShrinkwrap": true, "dependencies": { - "@types/node": "*" + "abstract-leveldown": "3.0.0", + "async": "2.6.2", + "bip39": "2.5.0", + "cachedown": "1.0.0", + "clone": "2.1.2", + "debug": "3.2.6", + "encoding-down": "5.0.4", + "eth-sig-util": "3.0.0", + "ethereumjs-abi": "0.6.8", + "ethereumjs-account": "3.0.0", + "ethereumjs-block": "2.2.2", + "ethereumjs-common": "1.5.0", + "ethereumjs-tx": "2.1.2", + "ethereumjs-util": "6.2.1", + "ethereumjs-vm": "4.2.0", + "heap": "0.2.6", + "keccak": "3.0.1", + "level-sublevel": "6.6.4", + "levelup": "3.1.1", + "lodash": "4.17.20", + "lru-cache": "5.1.1", + "merkle-patricia-tree": "3.0.0", + "patch-package": "6.2.2", + "seedrandom": "3.0.1", + "source-map-support": "0.5.12", + "tmp": "0.1.0", + "web3-provider-engine": "14.2.1", + "websocket": "1.0.32" + }, + "engines": { + "node": ">=8.9.0" + }, + "optionalDependencies": { + "ethereumjs-wallet": "0.6.5", + "web3": "1.2.11" } }, - "node_modules/ethereumjs-util/node_modules/bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", - "dev": true - }, - "node_modules/ethereumjs-util/node_modules/ethereum-cryptography": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz", - "integrity": "sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==", + "node_modules/ganache-core/node_modules/@ethersproject/abi": { + "version": "5.0.0-beta.153", "dev": true, + "license": "MIT", + "optional": true, "dependencies": { - "@types/pbkdf2": "^3.0.0", - "@types/secp256k1": "^4.0.1", - "blakejs": "^1.1.0", - "browserify-aes": "^1.2.0", - "bs58check": "^2.1.2", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "hash.js": "^1.1.7", - "keccak": "^3.0.0", - "pbkdf2": "^3.0.17", - "randombytes": "^2.1.0", - "safe-buffer": "^5.1.2", - "scrypt-js": "^3.0.0", - "secp256k1": "^4.0.1", - "setimmediate": "^1.0.5" + "@ethersproject/address": ">=5.0.0-beta.128", + "@ethersproject/bignumber": ">=5.0.0-beta.130", + "@ethersproject/bytes": ">=5.0.0-beta.129", + "@ethersproject/constants": ">=5.0.0-beta.128", + "@ethersproject/hash": ">=5.0.0-beta.128", + "@ethersproject/keccak256": ">=5.0.0-beta.127", + "@ethersproject/logger": ">=5.0.0-beta.129", + "@ethersproject/properties": ">=5.0.0-beta.131", + "@ethersproject/strings": ">=5.0.0-beta.130" } }, - "node_modules/ethers": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/ethers/-/ethers-5.7.2.tgz", - "integrity": "sha512-wswUsmWo1aOK8rR7DIKiWSw9DbLWe6x98Jrn8wcTflTVvaXhAMaB5zGAXy0GYQEQp9iO1iSHWVyARQm11zUtyg==", + "node_modules/ganache-core/node_modules/@ethersproject/abstract-provider": { + "version": "5.0.8", + "dev": true, "funding": [ { "type": "individual", @@ -7363,3387 +7286,3074 @@ "url": "https://www.buymeacoffee.com/ricmoo" } ], + "license": "MIT", + "optional": true, "dependencies": { - "@ethersproject/abi": "5.7.0", - "@ethersproject/abstract-provider": "5.7.0", - "@ethersproject/abstract-signer": "5.7.0", - "@ethersproject/address": "5.7.0", - "@ethersproject/base64": "5.7.0", - "@ethersproject/basex": "5.7.0", - "@ethersproject/bignumber": "5.7.0", - "@ethersproject/bytes": "5.7.0", - "@ethersproject/constants": "5.7.0", - "@ethersproject/contracts": "5.7.0", - "@ethersproject/hash": "5.7.0", - "@ethersproject/hdnode": "5.7.0", - "@ethersproject/json-wallets": "5.7.0", - "@ethersproject/keccak256": "5.7.0", - "@ethersproject/logger": "5.7.0", - "@ethersproject/networks": "5.7.1", - "@ethersproject/pbkdf2": "5.7.0", - "@ethersproject/properties": "5.7.0", - "@ethersproject/providers": "5.7.2", - "@ethersproject/random": "5.7.0", - "@ethersproject/rlp": "5.7.0", - "@ethersproject/sha2": "5.7.0", - "@ethersproject/signing-key": "5.7.0", - "@ethersproject/solidity": "5.7.0", - "@ethersproject/strings": "5.7.0", - "@ethersproject/transactions": "5.7.0", - "@ethersproject/units": "5.7.0", - "@ethersproject/wallet": "5.7.0", - "@ethersproject/web": "5.7.1", - "@ethersproject/wordlists": "5.7.0" + "@ethersproject/bignumber": "^5.0.13", + "@ethersproject/bytes": "^5.0.9", + "@ethersproject/logger": "^5.0.8", + "@ethersproject/networks": "^5.0.7", + "@ethersproject/properties": "^5.0.7", + "@ethersproject/transactions": "^5.0.9", + "@ethersproject/web": "^5.0.12" } }, - "node_modules/ethjs-unit": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/ethjs-unit/-/ethjs-unit-0.1.6.tgz", - "integrity": "sha512-/Sn9Y0oKl0uqQuvgFk/zQgR7aw1g36qX/jzSQ5lSwlO0GigPymk4eGQfeNTD03w1dPOqfz8V77Cy43jH56pagw==", + "node_modules/ganache-core/node_modules/@ethersproject/abstract-signer": { + "version": "5.0.10", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "optional": true, "dependencies": { - "bn.js": "4.11.6", - "number-to-bn": "1.7.0" - }, - "engines": { - "node": ">=6.5.0", - "npm": ">=3" + "@ethersproject/abstract-provider": "^5.0.8", + "@ethersproject/bignumber": "^5.0.13", + "@ethersproject/bytes": "^5.0.9", + "@ethersproject/logger": "^5.0.8", + "@ethersproject/properties": "^5.0.7" } }, - "node_modules/ethjs-unit/node_modules/bn.js": { - "version": "4.11.6", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.6.tgz", - "integrity": "sha512-XWwnNNFCuuSQ0m3r3C4LE3EiORltHd9M05pq6FOlVeiophzRbMo50Sbz1ehl8K3Z+jw9+vmgnXefY1hz8X+2wA==" - }, - "node_modules/ethjs-util": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/ethjs-util/-/ethjs-util-0.1.6.tgz", - "integrity": "sha512-CUnVOQq7gSpDHZVVrQW8ExxUETWrnrvXYvYz55wOU8Uj4VCgw56XC2B/fVqQN+f7gmrnRHSLVnFAwsCuNwji8w==", + "node_modules/ganache-core/node_modules/@ethersproject/address": { + "version": "5.0.9", "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "optional": true, "dependencies": { - "is-hex-prefixed": "1.0.0", - "strip-hex-prefix": "1.0.0" - }, - "engines": { - "node": ">=6.5.0", - "npm": ">=3" + "@ethersproject/bignumber": "^5.0.13", + "@ethersproject/bytes": "^5.0.9", + "@ethersproject/keccak256": "^5.0.7", + "@ethersproject/logger": "^5.0.8", + "@ethersproject/rlp": "^5.0.7" } }, - "node_modules/event-target-shim": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", - "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==", + "node_modules/ganache-core/node_modules/@ethersproject/base64": { + "version": "5.0.7", "dev": true, - "engines": { - "node": ">=6" + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "optional": true, + "dependencies": { + "@ethersproject/bytes": "^5.0.9" } }, - "node_modules/eventemitter3": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.4.tgz", - "integrity": "sha512-rlaVLnVxtxvoyLsQQFBx53YmXHDxRIzzTLbdfxqi4yocpSjAxXwkU0cScM5JgSKMqEhrZpnvQ2D9gjylR0AimQ==", - "dev": true - }, - "node_modules/evp_bytestokey": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", - "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", + "node_modules/ganache-core/node_modules/@ethersproject/bignumber": { + "version": "5.0.13", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "optional": true, "dependencies": { - "md5.js": "^1.3.4", - "safe-buffer": "^5.1.1" + "@ethersproject/bytes": "^5.0.9", + "@ethersproject/logger": "^5.0.8", + "bn.js": "^4.4.0" } }, - "node_modules/express": { - "version": "4.18.2", - "resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz", - "integrity": "sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==", + "node_modules/ganache-core/node_modules/@ethersproject/bytes": { + "version": "5.0.9", "dev": true, - "dependencies": { - "accepts": "~1.3.8", - "array-flatten": "1.1.1", - "body-parser": "1.20.1", - "content-disposition": "0.5.4", - "content-type": "~1.0.4", - "cookie": "0.5.0", - "cookie-signature": "1.0.6", - "debug": "2.6.9", - "depd": "2.0.0", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "finalhandler": "1.2.0", - "fresh": "0.5.2", - "http-errors": "2.0.0", - "merge-descriptors": "1.0.1", - "methods": "~1.1.2", - "on-finished": "2.4.1", - "parseurl": "~1.3.3", - "path-to-regexp": "0.1.7", - "proxy-addr": "~2.0.7", - "qs": "6.11.0", - "range-parser": "~1.2.1", - "safe-buffer": "5.2.1", - "send": "0.18.0", - "serve-static": "1.15.0", - "setprototypeof": "1.2.0", - "statuses": "2.0.1", - "type-is": "~1.6.18", - "utils-merge": "1.0.1", - "vary": "~1.1.2" - }, - "engines": { - "node": ">= 0.10.0" + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "optional": true, + "dependencies": { + "@ethersproject/logger": "^5.0.8" } }, - "node_modules/express/node_modules/body-parser": { - "version": "1.20.1", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz", - "integrity": "sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==", + "node_modules/ganache-core/node_modules/@ethersproject/constants": { + "version": "5.0.8", "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "optional": true, "dependencies": { - "bytes": "3.1.2", - "content-type": "~1.0.4", - "debug": "2.6.9", - "depd": "2.0.0", - "destroy": "1.2.0", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "on-finished": "2.4.1", - "qs": "6.11.0", - "raw-body": "2.5.1", - "type-is": "~1.6.18", - "unpipe": "1.0.0" - }, - "engines": { - "node": ">= 0.8", - "npm": "1.2.8000 || >= 1.4.16" + "@ethersproject/bignumber": "^5.0.13" } }, - "node_modules/express/node_modules/cookie": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", - "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==", + "node_modules/ganache-core/node_modules/@ethersproject/hash": { + "version": "5.0.10", "dev": true, - "engines": { - "node": ">= 0.6" + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "optional": true, + "dependencies": { + "@ethersproject/abstract-signer": "^5.0.10", + "@ethersproject/address": "^5.0.9", + "@ethersproject/bignumber": "^5.0.13", + "@ethersproject/bytes": "^5.0.9", + "@ethersproject/keccak256": "^5.0.7", + "@ethersproject/logger": "^5.0.8", + "@ethersproject/properties": "^5.0.7", + "@ethersproject/strings": "^5.0.8" } }, - "node_modules/express/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "node_modules/ganache-core/node_modules/@ethersproject/keccak256": { + "version": "5.0.7", "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "optional": true, "dependencies": { - "ms": "2.0.0" + "@ethersproject/bytes": "^5.0.9", + "js-sha3": "0.5.7" } }, - "node_modules/express/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true + "node_modules/ganache-core/node_modules/@ethersproject/logger": { + "version": "5.0.8", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "optional": true }, - "node_modules/express/node_modules/qs": { - "version": "6.11.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", - "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", + "node_modules/ganache-core/node_modules/@ethersproject/networks": { + "version": "5.0.7", "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "optional": true, "dependencies": { - "side-channel": "^1.0.4" - }, - "engines": { - "node": ">=0.6" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "@ethersproject/logger": "^5.0.8" } }, - "node_modules/express/node_modules/raw-body": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz", - "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==", + "node_modules/ganache-core/node_modules/@ethersproject/properties": { + "version": "5.0.7", "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "optional": true, "dependencies": { - "bytes": "3.1.2", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "unpipe": "1.0.0" - }, - "engines": { - "node": ">= 0.8" + "@ethersproject/logger": "^5.0.8" } }, - "node_modules/express/node_modules/safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "node_modules/ganache-core/node_modules/@ethersproject/rlp": { + "version": "5.0.7", "dev": true, "funding": [ { - "type": "github", - "url": "https://github.com/sponsors/feross" + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" }, { - "type": "patreon", - "url": "https://www.patreon.com/feross" + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "optional": true, + "dependencies": { + "@ethersproject/bytes": "^5.0.9", + "@ethersproject/logger": "^5.0.8" + } + }, + "node_modules/ganache-core/node_modules/@ethersproject/signing-key": { + "version": "5.0.8", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" }, { - "type": "consulting", - "url": "https://feross.org/support" + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" } - ] + ], + "license": "MIT", + "optional": true, + "dependencies": { + "@ethersproject/bytes": "^5.0.9", + "@ethersproject/logger": "^5.0.8", + "@ethersproject/properties": "^5.0.7", + "elliptic": "6.5.3" + } }, - "node_modules/ext": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/ext/-/ext-1.7.0.tgz", - "integrity": "sha512-6hxeJYaL110a9b5TEJSj0gojyHQAmA2ch5Os+ySCiA1QGdS697XWY1pzsrSjqA9LDEEgdB/KypIlR59RcLuHYw==", + "node_modules/ganache-core/node_modules/@ethersproject/strings": { + "version": "5.0.8", "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "optional": true, "dependencies": { - "type": "^2.7.2" + "@ethersproject/bytes": "^5.0.9", + "@ethersproject/constants": "^5.0.8", + "@ethersproject/logger": "^5.0.8" } }, - "node_modules/ext/node_modules/type": { - "version": "2.7.2", - "resolved": "https://registry.npmjs.org/type/-/type-2.7.2.tgz", - "integrity": "sha512-dzlvlNlt6AXU7EBSfpAscydQ7gXB+pPGsPnfJnZpiNJBDj7IaJzQlBZYGdEi4R9HmPdBv2XmWJ6YUtoTa7lmCw==", - "dev": true - }, - "node_modules/extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", - "dev": true - }, - "node_modules/extsprintf": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", - "integrity": "sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g==", - "dev": true, - "engines": [ - "node >=0.6.0" - ] - }, - "node_modules/fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true - }, - "node_modules/fast-diff": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.3.0.tgz", - "integrity": "sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==", - "dev": true - }, - "node_modules/fast-glob": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.0.tgz", - "integrity": "sha512-ChDuvbOypPuNjO8yIDf36x7BlZX1smcUMTTcyoIjycexOxd6DFsKsg21qVBzEmr3G7fUKIRy2/psii+CIUt7FA==", + "node_modules/ganache-core/node_modules/@ethersproject/transactions": { + "version": "5.0.9", "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "optional": true, "dependencies": { - "@nodelib/fs.stat": "^2.0.2", - "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.2", - "merge2": "^1.3.0", - "micromatch": "^4.0.4" - }, - "engines": { - "node": ">=8.6.0" + "@ethersproject/address": "^5.0.9", + "@ethersproject/bignumber": "^5.0.13", + "@ethersproject/bytes": "^5.0.9", + "@ethersproject/constants": "^5.0.8", + "@ethersproject/keccak256": "^5.0.7", + "@ethersproject/logger": "^5.0.8", + "@ethersproject/properties": "^5.0.7", + "@ethersproject/rlp": "^5.0.7", + "@ethersproject/signing-key": "^5.0.8" } }, - "node_modules/fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "dev": true - }, - "node_modules/fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", - "dev": true - }, - "node_modules/fastq": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz", - "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==", + "node_modules/ganache-core/node_modules/@ethersproject/web": { + "version": "5.0.12", "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "optional": true, "dependencies": { - "reusify": "^1.0.4" + "@ethersproject/base64": "^5.0.7", + "@ethersproject/bytes": "^5.0.9", + "@ethersproject/logger": "^5.0.8", + "@ethersproject/properties": "^5.0.7", + "@ethersproject/strings": "^5.0.8" } }, - "node_modules/file-entry-cache": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", - "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "node_modules/ganache-core/node_modules/@sindresorhus/is": { + "version": "0.14.0", "dev": true, - "dependencies": { - "flat-cache": "^3.0.4" - }, + "license": "MIT", + "optional": true, "engines": { - "node": "^10.12.0 || >=12.0.0" + "node": ">=6" } }, - "node_modules/fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "node_modules/ganache-core/node_modules/@szmarczak/http-timer": { + "version": "1.1.2", "dev": true, + "license": "MIT", + "optional": true, "dependencies": { - "to-regex-range": "^5.0.1" + "defer-to-connect": "^1.0.1" }, "engines": { - "node": ">=8" + "node": ">=6" } }, - "node_modules/finalhandler": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", - "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", + "node_modules/ganache-core/node_modules/@types/bn.js": { + "version": "4.11.6", "dev": true, + "license": "MIT", "dependencies": { - "debug": "2.6.9", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "on-finished": "2.4.1", - "parseurl": "~1.3.3", - "statuses": "2.0.1", - "unpipe": "~1.0.0" - }, - "engines": { - "node": ">= 0.8" + "@types/node": "*" } }, - "node_modules/finalhandler/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "node_modules/ganache-core/node_modules/@types/node": { + "version": "14.14.20", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/@types/pbkdf2": { + "version": "3.1.0", "dev": true, + "license": "MIT", "dependencies": { - "ms": "2.0.0" + "@types/node": "*" } }, - "node_modules/finalhandler/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true - }, - "node_modules/find-replace": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/find-replace/-/find-replace-1.0.3.tgz", - "integrity": "sha512-KrUnjzDCD9426YnCP56zGYy/eieTnhtK6Vn++j+JJzmlsWWwEkDnsyVF575spT6HJ6Ow9tlbT3TQTDsa+O4UWA==", + "node_modules/ganache-core/node_modules/@types/secp256k1": { + "version": "4.0.1", "dev": true, + "license": "MIT", "dependencies": { - "array-back": "^1.0.4", - "test-value": "^2.1.0" - }, - "engines": { - "node": ">=4.0.0" + "@types/node": "*" } }, - "node_modules/find-replace/node_modules/array-back": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/array-back/-/array-back-1.0.4.tgz", - "integrity": "sha512-1WxbZvrmyhkNoeYcizokbmh5oiOCIfyvGtcqbK3Ls1v1fKcquzxnQSceOx6tzq7jmai2kFLWIpGND2cLhH6TPw==", + "node_modules/ganache-core/node_modules/@yarnpkg/lockfile": { + "version": "1.1.0", + "dev": true, + "license": "BSD-2-Clause" + }, + "node_modules/ganache-core/node_modules/abstract-leveldown": { + "version": "3.0.0", "dev": true, + "license": "MIT", "dependencies": { - "typical": "^2.6.0" + "xtend": "~4.0.0" }, "engines": { - "node": ">=0.12.0" + "node": ">=4" } }, - "node_modules/find-up": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", - "integrity": "sha512-NWzkk0jSJtTt08+FBFMvXoeZnOJD+jTtsRmBYbAIzJdX6l7dLgR7CTubCM5/eDdPUBvLCeVasP1brfVR/9/EZQ==", + "node_modules/ganache-core/node_modules/accepts": { + "version": "1.3.7", "dev": true, + "license": "MIT", + "optional": true, "dependencies": { - "locate-path": "^2.0.0" + "mime-types": "~2.1.24", + "negotiator": "0.6.2" }, "engines": { - "node": ">=4" + "node": ">= 0.6" } }, - "node_modules/find-yarn-workspace-root": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/find-yarn-workspace-root/-/find-yarn-workspace-root-2.0.0.tgz", - "integrity": "sha512-1IMnbjt4KzsQfnhnzNd8wUEgXZ44IzZaZmnLYx7D5FZlaHt2gW20Cri8Q+E/t5tIj4+epTBub+2Zxu/vNILzqQ==", + "node_modules/ganache-core/node_modules/aes-js": { + "version": "3.1.2", "dev": true, - "dependencies": { - "micromatch": "^4.0.2" - } + "license": "MIT", + "optional": true }, - "node_modules/flat": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", - "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", + "node_modules/ganache-core/node_modules/ajv": { + "version": "6.12.6", "dev": true, - "bin": { - "flat": "cli.js" + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" } }, - "node_modules/flat-cache": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", - "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", + "node_modules/ganache-core/node_modules/ansi-styles": { + "version": "3.2.1", "dev": true, + "license": "MIT", "dependencies": { - "flatted": "^3.1.0", - "rimraf": "^3.0.2" + "color-convert": "^1.9.0" }, "engines": { - "node": "^10.12.0 || >=12.0.0" + "node": ">=4" } }, - "node_modules/flatted": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz", - "integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==", - "dev": true - }, - "node_modules/follow-redirects": { - "version": "1.15.2", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz", - "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==", + "node_modules/ganache-core/node_modules/arr-diff": { + "version": "4.0.0", "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://github.com/sponsors/RubenVerborgh" - } - ], + "license": "MIT", "engines": { - "node": ">=4.0" - }, - "peerDependenciesMeta": { - "debug": { - "optional": true - } + "node": ">=0.10.0" } }, - "node_modules/for-each": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", - "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", + "node_modules/ganache-core/node_modules/arr-flatten": { + "version": "1.1.0", "dev": true, - "dependencies": { - "is-callable": "^1.1.3" + "license": "MIT", + "engines": { + "node": ">=0.10.0" } }, - "node_modules/forever-agent": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", - "integrity": "sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw==", + "node_modules/ganache-core/node_modules/arr-union": { + "version": "3.1.0", "dev": true, + "license": "MIT", "engines": { - "node": "*" + "node": ">=0.10.0" } }, - "node_modules/form-data": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz", - "integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==", + "node_modules/ganache-core/node_modules/array-flatten": { + "version": "1.1.1", "dev": true, - "dependencies": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "mime-types": "^2.1.12" - }, + "license": "MIT", + "optional": true + }, + "node_modules/ganache-core/node_modules/array-unique": { + "version": "0.3.2", + "dev": true, + "license": "MIT", "engines": { - "node": ">= 6" + "node": ">=0.10.0" } }, - "node_modules/form-data-encoder": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/form-data-encoder/-/form-data-encoder-1.7.1.tgz", - "integrity": "sha512-EFRDrsMm/kyqbTQocNvRXMLjc7Es2Vk+IQFx/YW7hkUH1eBl4J1fqiP34l74Yt0pFLCNpc06fkbVk00008mzjg==", - "dev": true + "node_modules/ganache-core/node_modules/asn1": { + "version": "0.2.4", + "dev": true, + "license": "MIT", + "dependencies": { + "safer-buffer": "~2.1.0" + } }, - "node_modules/forwarded": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", - "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", + "node_modules/ganache-core/node_modules/asn1.js": { + "version": "5.4.1", "dev": true, - "engines": { - "node": ">= 0.6" + "license": "MIT", + "optional": true, + "dependencies": { + "bn.js": "^4.0.0", + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0", + "safer-buffer": "^2.1.0" } }, - "node_modules/fp-ts": { - "version": "1.19.3", - "resolved": "https://registry.npmjs.org/fp-ts/-/fp-ts-1.19.3.tgz", - "integrity": "sha512-H5KQDspykdHuztLTg+ajGN0Z2qUjcEf3Ybxc6hLt0k7/zPkn29XnKnxlBPyW2XIddWrGaJBzBl4VLYOtk39yZg==", - "dev": true + "node_modules/ganache-core/node_modules/assert-plus": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8" + } }, - "node_modules/fresh": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", - "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", + "node_modules/ganache-core/node_modules/assign-symbols": { + "version": "1.0.0", "dev": true, + "license": "MIT", "engines": { - "node": ">= 0.6" + "node": ">=0.10.0" } }, - "node_modules/fs-extra": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", - "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", + "node_modules/ganache-core/node_modules/async": { + "version": "2.6.2", "dev": true, + "license": "MIT", "dependencies": { - "graceful-fs": "^4.1.2", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - }, - "engines": { - "node": ">=6 <7 || >=8" + "lodash": "^4.17.11" } }, - "node_modules/fs-minipass": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-1.2.7.tgz", - "integrity": "sha512-GWSSJGFy4e9GUeCcbIkED+bgAoFyj7XF1mV8rma3QW4NIqX9Kyx79N/PF61H5udOV3aY1IaMLs6pGbH71nlCTA==", + "node_modules/ganache-core/node_modules/async-eventemitter": { + "version": "0.2.4", "dev": true, + "license": "MIT", "dependencies": { - "minipass": "^2.6.0" + "async": "^2.4.0" } }, - "node_modules/fs-readdir-recursive": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/fs-readdir-recursive/-/fs-readdir-recursive-1.1.0.tgz", - "integrity": "sha512-GNanXlVr2pf02+sPN40XN8HG+ePaNcvM0q5mZBd668Obwb0yD5GiUbZOFgwn8kGMY6I3mdyDJzieUy3PTYyTRA==", - "dev": true + "node_modules/ganache-core/node_modules/async-limiter": { + "version": "1.0.1", + "dev": true, + "license": "MIT" }, - "node_modules/fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", - "dev": true + "node_modules/ganache-core/node_modules/asynckit": { + "version": "0.4.0", + "dev": true, + "license": "MIT" }, - "node_modules/fsevents": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "node_modules/ganache-core/node_modules/atob": { + "version": "2.1.2", "dev": true, - "hasInstallScript": true, - "optional": true, - "os": [ - "darwin" - ], + "license": "(MIT OR Apache-2.0)", + "bin": { + "atob": "bin/atob.js" + }, "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + "node": ">= 4.5.0" } }, - "node_modules/function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", - "dev": true + "node_modules/ganache-core/node_modules/aws-sign2": { + "version": "0.7.0", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "*" + } }, - "node_modules/function.prototype.name": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.5.tgz", - "integrity": "sha512-uN7m/BzVKQnCUF/iW8jYea67v++2u7m5UgENbHRtdDVclOUP+FMPlCNdmk0h/ysGyo2tavMJEDqJAkJdRa1vMA==", + "node_modules/ganache-core/node_modules/aws4": { + "version": "1.11.0", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/babel-code-frame": { + "version": "6.26.0", "dev": true, + "license": "MIT", "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.0", - "functions-have-names": "^1.2.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "chalk": "^1.1.3", + "esutils": "^2.0.2", + "js-tokens": "^3.0.2" } }, - "node_modules/functional-red-black-tree": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", - "integrity": "sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g==", - "dev": true + "node_modules/ganache-core/node_modules/babel-code-frame/node_modules/ansi-regex": { + "version": "2.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } }, - "node_modules/functions-have-names": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", - "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", + "node_modules/ganache-core/node_modules/babel-code-frame/node_modules/ansi-styles": { + "version": "2.2.1", "dev": true, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "license": "MIT", + "engines": { + "node": ">=0.10.0" } }, - "node_modules/ganache-core": { - "version": "2.13.2", - "resolved": "https://registry.npmjs.org/ganache-core/-/ganache-core-2.13.2.tgz", - "integrity": "sha512-tIF5cR+ANQz0+3pHWxHjIwHqFXcVo0Mb+kcsNhglNFALcYo49aQpnS9dqHartqPfMFjiHh/qFoD3mYK0d/qGgw==", - "bundleDependencies": [ - "keccak" - ], - "deprecated": "ganache-core is now ganache; visit https://trfl.io/g7 for details", + "node_modules/ganache-core/node_modules/babel-code-frame/node_modules/chalk": { + "version": "1.1.3", "dev": true, - "hasShrinkwrap": true, + "license": "MIT", "dependencies": { - "abstract-leveldown": "3.0.0", - "async": "2.6.2", - "bip39": "2.5.0", - "cachedown": "1.0.0", - "clone": "2.1.2", - "debug": "3.2.6", - "encoding-down": "5.0.4", - "eth-sig-util": "3.0.0", - "ethereumjs-abi": "0.6.8", - "ethereumjs-account": "3.0.0", - "ethereumjs-block": "2.2.2", - "ethereumjs-common": "1.5.0", - "ethereumjs-tx": "2.1.2", - "ethereumjs-util": "6.2.1", - "ethereumjs-vm": "4.2.0", - "heap": "0.2.6", - "keccak": "3.0.1", - "level-sublevel": "6.6.4", - "levelup": "3.1.1", - "lodash": "4.17.20", - "lru-cache": "5.1.1", - "merkle-patricia-tree": "3.0.0", - "patch-package": "6.2.2", - "seedrandom": "3.0.1", - "source-map-support": "0.5.12", - "tmp": "0.1.0", - "web3-provider-engine": "14.2.1", - "websocket": "1.0.32" + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" }, "engines": { - "node": ">=8.9.0" - }, - "optionalDependencies": { - "ethereumjs-wallet": "0.6.5", - "web3": "1.2.11" + "node": ">=0.10.0" } }, - "node_modules/ganache-core/node_modules/@ethersproject/abi": { - "version": "5.0.0-beta.153", + "node_modules/ganache-core/node_modules/babel-code-frame/node_modules/js-tokens": { + "version": "3.0.2", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/babel-code-frame/node_modules/strip-ansi": { + "version": "3.0.1", "dev": true, "license": "MIT", - "optional": true, "dependencies": { - "@ethersproject/address": ">=5.0.0-beta.128", - "@ethersproject/bignumber": ">=5.0.0-beta.130", - "@ethersproject/bytes": ">=5.0.0-beta.129", - "@ethersproject/constants": ">=5.0.0-beta.128", - "@ethersproject/hash": ">=5.0.0-beta.128", - "@ethersproject/keccak256": ">=5.0.0-beta.127", - "@ethersproject/logger": ">=5.0.0-beta.129", - "@ethersproject/properties": ">=5.0.0-beta.131", - "@ethersproject/strings": ">=5.0.0-beta.130" + "ansi-regex": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" } }, - "node_modules/ganache-core/node_modules/@ethersproject/abstract-provider": { - "version": "5.0.8", + "node_modules/ganache-core/node_modules/babel-code-frame/node_modules/supports-color": { + "version": "2.0.0", "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], "license": "MIT", - "optional": true, - "dependencies": { - "@ethersproject/bignumber": "^5.0.13", - "@ethersproject/bytes": "^5.0.9", - "@ethersproject/logger": "^5.0.8", - "@ethersproject/networks": "^5.0.7", - "@ethersproject/properties": "^5.0.7", - "@ethersproject/transactions": "^5.0.9", - "@ethersproject/web": "^5.0.12" + "engines": { + "node": ">=0.8.0" } }, - "node_modules/ganache-core/node_modules/@ethersproject/abstract-signer": { - "version": "5.0.10", + "node_modules/ganache-core/node_modules/babel-core": { + "version": "6.26.3", "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], "license": "MIT", - "optional": true, "dependencies": { - "@ethersproject/abstract-provider": "^5.0.8", - "@ethersproject/bignumber": "^5.0.13", - "@ethersproject/bytes": "^5.0.9", - "@ethersproject/logger": "^5.0.8", - "@ethersproject/properties": "^5.0.7" + "babel-code-frame": "^6.26.0", + "babel-generator": "^6.26.0", + "babel-helpers": "^6.24.1", + "babel-messages": "^6.23.0", + "babel-register": "^6.26.0", + "babel-runtime": "^6.26.0", + "babel-template": "^6.26.0", + "babel-traverse": "^6.26.0", + "babel-types": "^6.26.0", + "babylon": "^6.18.0", + "convert-source-map": "^1.5.1", + "debug": "^2.6.9", + "json5": "^0.5.1", + "lodash": "^4.17.4", + "minimatch": "^3.0.4", + "path-is-absolute": "^1.0.1", + "private": "^0.1.8", + "slash": "^1.0.0", + "source-map": "^0.5.7" } }, - "node_modules/ganache-core/node_modules/@ethersproject/address": { - "version": "5.0.9", + "node_modules/ganache-core/node_modules/babel-core/node_modules/debug": { + "version": "2.6.9", "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], "license": "MIT", - "optional": true, "dependencies": { - "@ethersproject/bignumber": "^5.0.13", - "@ethersproject/bytes": "^5.0.9", - "@ethersproject/keccak256": "^5.0.7", - "@ethersproject/logger": "^5.0.8", - "@ethersproject/rlp": "^5.0.7" + "ms": "2.0.0" } }, - "node_modules/ganache-core/node_modules/@ethersproject/base64": { - "version": "5.0.7", + "node_modules/ganache-core/node_modules/babel-core/node_modules/json5": { + "version": "0.5.1", "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], "license": "MIT", - "optional": true, - "dependencies": { - "@ethersproject/bytes": "^5.0.9" + "bin": { + "json5": "lib/cli.js" } }, - "node_modules/ganache-core/node_modules/@ethersproject/bignumber": { - "version": "5.0.13", + "node_modules/ganache-core/node_modules/babel-core/node_modules/ms": { + "version": "2.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/babel-core/node_modules/slash": { + "version": "1.0.0", "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], "license": "MIT", - "optional": true, - "dependencies": { - "@ethersproject/bytes": "^5.0.9", - "@ethersproject/logger": "^5.0.8", - "bn.js": "^4.4.0" + "engines": { + "node": ">=0.10.0" } }, - "node_modules/ganache-core/node_modules/@ethersproject/bytes": { - "version": "5.0.9", + "node_modules/ganache-core/node_modules/babel-generator": { + "version": "6.26.1", "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], "license": "MIT", - "optional": true, "dependencies": { - "@ethersproject/logger": "^5.0.8" + "babel-messages": "^6.23.0", + "babel-runtime": "^6.26.0", + "babel-types": "^6.26.0", + "detect-indent": "^4.0.0", + "jsesc": "^1.3.0", + "lodash": "^4.17.4", + "source-map": "^0.5.7", + "trim-right": "^1.0.1" } }, - "node_modules/ganache-core/node_modules/@ethersproject/constants": { - "version": "5.0.8", + "node_modules/ganache-core/node_modules/babel-generator/node_modules/jsesc": { + "version": "1.3.0", "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], "license": "MIT", - "optional": true, - "dependencies": { - "@ethersproject/bignumber": "^5.0.13" + "bin": { + "jsesc": "bin/jsesc" } }, - "node_modules/ganache-core/node_modules/@ethersproject/hash": { - "version": "5.0.10", + "node_modules/ganache-core/node_modules/babel-helper-builder-binary-assignment-operator-visitor": { + "version": "6.24.1", "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], "license": "MIT", - "optional": true, "dependencies": { - "@ethersproject/abstract-signer": "^5.0.10", - "@ethersproject/address": "^5.0.9", - "@ethersproject/bignumber": "^5.0.13", - "@ethersproject/bytes": "^5.0.9", - "@ethersproject/keccak256": "^5.0.7", - "@ethersproject/logger": "^5.0.8", - "@ethersproject/properties": "^5.0.7", - "@ethersproject/strings": "^5.0.8" + "babel-helper-explode-assignable-expression": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" } }, - "node_modules/ganache-core/node_modules/@ethersproject/keccak256": { - "version": "5.0.7", + "node_modules/ganache-core/node_modules/babel-helper-call-delegate": { + "version": "6.24.1", "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], "license": "MIT", - "optional": true, "dependencies": { - "@ethersproject/bytes": "^5.0.9", - "js-sha3": "0.5.7" + "babel-helper-hoist-variables": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-traverse": "^6.24.1", + "babel-types": "^6.24.1" } }, - "node_modules/ganache-core/node_modules/@ethersproject/logger": { - "version": "5.0.8", + "node_modules/ganache-core/node_modules/babel-helper-define-map": { + "version": "6.26.0", "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], "license": "MIT", - "optional": true + "dependencies": { + "babel-helper-function-name": "^6.24.1", + "babel-runtime": "^6.26.0", + "babel-types": "^6.26.0", + "lodash": "^4.17.4" + } }, - "node_modules/ganache-core/node_modules/@ethersproject/networks": { - "version": "5.0.7", + "node_modules/ganache-core/node_modules/babel-helper-explode-assignable-expression": { + "version": "6.24.1", "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], "license": "MIT", - "optional": true, "dependencies": { - "@ethersproject/logger": "^5.0.8" + "babel-runtime": "^6.22.0", + "babel-traverse": "^6.24.1", + "babel-types": "^6.24.1" } }, - "node_modules/ganache-core/node_modules/@ethersproject/properties": { - "version": "5.0.7", + "node_modules/ganache-core/node_modules/babel-helper-function-name": { + "version": "6.24.1", "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], "license": "MIT", - "optional": true, "dependencies": { - "@ethersproject/logger": "^5.0.8" + "babel-helper-get-function-arity": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1", + "babel-traverse": "^6.24.1", + "babel-types": "^6.24.1" } }, - "node_modules/ganache-core/node_modules/@ethersproject/rlp": { - "version": "5.0.7", + "node_modules/ganache-core/node_modules/babel-helper-get-function-arity": { + "version": "6.24.1", "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], "license": "MIT", - "optional": true, "dependencies": { - "@ethersproject/bytes": "^5.0.9", - "@ethersproject/logger": "^5.0.8" + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" } }, - "node_modules/ganache-core/node_modules/@ethersproject/signing-key": { - "version": "5.0.8", + "node_modules/ganache-core/node_modules/babel-helper-hoist-variables": { + "version": "6.24.1", "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], "license": "MIT", - "optional": true, "dependencies": { - "@ethersproject/bytes": "^5.0.9", - "@ethersproject/logger": "^5.0.8", - "@ethersproject/properties": "^5.0.7", - "elliptic": "6.5.3" + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" } }, - "node_modules/ganache-core/node_modules/@ethersproject/strings": { - "version": "5.0.8", + "node_modules/ganache-core/node_modules/babel-helper-optimise-call-expression": { + "version": "6.24.1", "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], "license": "MIT", - "optional": true, "dependencies": { - "@ethersproject/bytes": "^5.0.9", - "@ethersproject/constants": "^5.0.8", - "@ethersproject/logger": "^5.0.8" + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" } }, - "node_modules/ganache-core/node_modules/@ethersproject/transactions": { - "version": "5.0.9", + "node_modules/ganache-core/node_modules/babel-helper-regex": { + "version": "6.26.0", "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], "license": "MIT", - "optional": true, "dependencies": { - "@ethersproject/address": "^5.0.9", - "@ethersproject/bignumber": "^5.0.13", - "@ethersproject/bytes": "^5.0.9", - "@ethersproject/constants": "^5.0.8", - "@ethersproject/keccak256": "^5.0.7", - "@ethersproject/logger": "^5.0.8", - "@ethersproject/properties": "^5.0.7", - "@ethersproject/rlp": "^5.0.7", - "@ethersproject/signing-key": "^5.0.8" + "babel-runtime": "^6.26.0", + "babel-types": "^6.26.0", + "lodash": "^4.17.4" } }, - "node_modules/ganache-core/node_modules/@ethersproject/web": { - "version": "5.0.12", + "node_modules/ganache-core/node_modules/babel-helper-remap-async-to-generator": { + "version": "6.24.1", "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], "license": "MIT", - "optional": true, "dependencies": { - "@ethersproject/base64": "^5.0.7", - "@ethersproject/bytes": "^5.0.9", - "@ethersproject/logger": "^5.0.8", - "@ethersproject/properties": "^5.0.7", - "@ethersproject/strings": "^5.0.8" + "babel-helper-function-name": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1", + "babel-traverse": "^6.24.1", + "babel-types": "^6.24.1" } }, - "node_modules/ganache-core/node_modules/@sindresorhus/is": { - "version": "0.14.0", + "node_modules/ganache-core/node_modules/babel-helper-replace-supers": { + "version": "6.24.1", "dev": true, "license": "MIT", - "optional": true, - "engines": { - "node": ">=6" + "dependencies": { + "babel-helper-optimise-call-expression": "^6.24.1", + "babel-messages": "^6.23.0", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1", + "babel-traverse": "^6.24.1", + "babel-types": "^6.24.1" } }, - "node_modules/ganache-core/node_modules/@szmarczak/http-timer": { - "version": "1.1.2", + "node_modules/ganache-core/node_modules/babel-helpers": { + "version": "6.24.1", "dev": true, "license": "MIT", - "optional": true, "dependencies": { - "defer-to-connect": "^1.0.1" - }, - "engines": { - "node": ">=6" + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1" } }, - "node_modules/ganache-core/node_modules/@types/bn.js": { - "version": "4.11.6", + "node_modules/ganache-core/node_modules/babel-messages": { + "version": "6.23.0", "dev": true, "license": "MIT", "dependencies": { - "@types/node": "*" + "babel-runtime": "^6.22.0" } }, - "node_modules/ganache-core/node_modules/@types/node": { - "version": "14.14.20", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/@types/pbkdf2": { - "version": "3.1.0", + "node_modules/ganache-core/node_modules/babel-plugin-check-es2015-constants": { + "version": "6.22.0", "dev": true, "license": "MIT", "dependencies": { - "@types/node": "*" + "babel-runtime": "^6.22.0" } }, - "node_modules/ganache-core/node_modules/@types/secp256k1": { - "version": "4.0.1", + "node_modules/ganache-core/node_modules/babel-plugin-syntax-async-functions": { + "version": "6.13.0", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/babel-plugin-syntax-exponentiation-operator": { + "version": "6.13.0", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/babel-plugin-syntax-trailing-function-commas": { + "version": "6.22.0", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/babel-plugin-transform-async-to-generator": { + "version": "6.24.1", "dev": true, "license": "MIT", "dependencies": { - "@types/node": "*" + "babel-helper-remap-async-to-generator": "^6.24.1", + "babel-plugin-syntax-async-functions": "^6.8.0", + "babel-runtime": "^6.22.0" } }, - "node_modules/ganache-core/node_modules/@yarnpkg/lockfile": { - "version": "1.1.0", - "dev": true, - "license": "BSD-2-Clause" - }, - "node_modules/ganache-core/node_modules/abstract-leveldown": { - "version": "3.0.0", + "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-arrow-functions": { + "version": "6.22.0", "dev": true, "license": "MIT", "dependencies": { - "xtend": "~4.0.0" - }, - "engines": { - "node": ">=4" + "babel-runtime": "^6.22.0" } }, - "node_modules/ganache-core/node_modules/accepts": { - "version": "1.3.7", + "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-block-scoped-functions": { + "version": "6.22.0", "dev": true, "license": "MIT", - "optional": true, "dependencies": { - "mime-types": "~2.1.24", - "negotiator": "0.6.2" - }, - "engines": { - "node": ">= 0.6" + "babel-runtime": "^6.22.0" } }, - "node_modules/ganache-core/node_modules/aes-js": { - "version": "3.1.2", + "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-block-scoping": { + "version": "6.26.0", "dev": true, "license": "MIT", - "optional": true + "dependencies": { + "babel-runtime": "^6.26.0", + "babel-template": "^6.26.0", + "babel-traverse": "^6.26.0", + "babel-types": "^6.26.0", + "lodash": "^4.17.4" + } }, - "node_modules/ganache-core/node_modules/ajv": { - "version": "6.12.6", + "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-classes": { + "version": "6.24.1", "dev": true, "license": "MIT", "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" + "babel-helper-define-map": "^6.24.1", + "babel-helper-function-name": "^6.24.1", + "babel-helper-optimise-call-expression": "^6.24.1", + "babel-helper-replace-supers": "^6.24.1", + "babel-messages": "^6.23.0", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1", + "babel-traverse": "^6.24.1", + "babel-types": "^6.24.1" } }, - "node_modules/ganache-core/node_modules/ansi-styles": { - "version": "3.2.1", + "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-computed-properties": { + "version": "6.24.1", "dev": true, "license": "MIT", "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1" } }, - "node_modules/ganache-core/node_modules/arr-diff": { - "version": "4.0.0", + "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-destructuring": { + "version": "6.23.0", "dev": true, "license": "MIT", - "engines": { - "node": ">=0.10.0" + "dependencies": { + "babel-runtime": "^6.22.0" } }, - "node_modules/ganache-core/node_modules/arr-flatten": { - "version": "1.1.0", + "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-duplicate-keys": { + "version": "6.24.1", "dev": true, "license": "MIT", - "engines": { - "node": ">=0.10.0" + "dependencies": { + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" } }, - "node_modules/ganache-core/node_modules/arr-union": { - "version": "3.1.0", + "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-for-of": { + "version": "6.23.0", "dev": true, "license": "MIT", - "engines": { - "node": ">=0.10.0" + "dependencies": { + "babel-runtime": "^6.22.0" } }, - "node_modules/ganache-core/node_modules/array-flatten": { - "version": "1.1.1", + "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-function-name": { + "version": "6.24.1", "dev": true, "license": "MIT", - "optional": true + "dependencies": { + "babel-helper-function-name": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" + } }, - "node_modules/ganache-core/node_modules/array-unique": { - "version": "0.3.2", + "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-literals": { + "version": "6.22.0", "dev": true, "license": "MIT", - "engines": { - "node": ">=0.10.0" + "dependencies": { + "babel-runtime": "^6.22.0" } }, - "node_modules/ganache-core/node_modules/asn1": { - "version": "0.2.4", + "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-modules-amd": { + "version": "6.24.1", "dev": true, "license": "MIT", "dependencies": { - "safer-buffer": "~2.1.0" + "babel-plugin-transform-es2015-modules-commonjs": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1" } }, - "node_modules/ganache-core/node_modules/asn1.js": { - "version": "5.4.1", + "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-modules-commonjs": { + "version": "6.26.2", "dev": true, "license": "MIT", - "optional": true, "dependencies": { - "bn.js": "^4.0.0", - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0", - "safer-buffer": "^2.1.0" + "babel-plugin-transform-strict-mode": "^6.24.1", + "babel-runtime": "^6.26.0", + "babel-template": "^6.26.0", + "babel-types": "^6.26.0" } }, - "node_modules/ganache-core/node_modules/assert-plus": { - "version": "1.0.0", + "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-modules-systemjs": { + "version": "6.24.1", "dev": true, "license": "MIT", - "engines": { - "node": ">=0.8" + "dependencies": { + "babel-helper-hoist-variables": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1" } }, - "node_modules/ganache-core/node_modules/assign-symbols": { - "version": "1.0.0", + "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-modules-umd": { + "version": "6.24.1", "dev": true, "license": "MIT", - "engines": { - "node": ">=0.10.0" + "dependencies": { + "babel-plugin-transform-es2015-modules-amd": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1" } }, - "node_modules/ganache-core/node_modules/async": { - "version": "2.6.2", + "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-object-super": { + "version": "6.24.1", "dev": true, "license": "MIT", "dependencies": { - "lodash": "^4.17.11" + "babel-helper-replace-supers": "^6.24.1", + "babel-runtime": "^6.22.0" } }, - "node_modules/ganache-core/node_modules/async-eventemitter": { - "version": "0.2.4", + "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-parameters": { + "version": "6.24.1", "dev": true, "license": "MIT", "dependencies": { - "async": "^2.4.0" + "babel-helper-call-delegate": "^6.24.1", + "babel-helper-get-function-arity": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1", + "babel-traverse": "^6.24.1", + "babel-types": "^6.24.1" } }, - "node_modules/ganache-core/node_modules/async-limiter": { - "version": "1.0.1", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/asynckit": { - "version": "0.4.0", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/atob": { - "version": "2.1.2", + "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-shorthand-properties": { + "version": "6.24.1", "dev": true, - "license": "(MIT OR Apache-2.0)", - "bin": { - "atob": "bin/atob.js" - }, - "engines": { - "node": ">= 4.5.0" + "license": "MIT", + "dependencies": { + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" } }, - "node_modules/ganache-core/node_modules/aws-sign2": { - "version": "0.7.0", + "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-spread": { + "version": "6.22.0", "dev": true, - "license": "Apache-2.0", - "engines": { - "node": "*" + "license": "MIT", + "dependencies": { + "babel-runtime": "^6.22.0" } }, - "node_modules/ganache-core/node_modules/aws4": { - "version": "1.11.0", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/babel-code-frame": { - "version": "6.26.0", + "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-sticky-regex": { + "version": "6.24.1", "dev": true, "license": "MIT", "dependencies": { - "chalk": "^1.1.3", - "esutils": "^2.0.2", - "js-tokens": "^3.0.2" + "babel-helper-regex": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" } }, - "node_modules/ganache-core/node_modules/babel-code-frame/node_modules/ansi-regex": { - "version": "2.1.1", + "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-template-literals": { + "version": "6.22.0", "dev": true, "license": "MIT", - "engines": { - "node": ">=0.10.0" + "dependencies": { + "babel-runtime": "^6.22.0" } }, - "node_modules/ganache-core/node_modules/babel-code-frame/node_modules/ansi-styles": { - "version": "2.2.1", + "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-typeof-symbol": { + "version": "6.23.0", "dev": true, "license": "MIT", - "engines": { - "node": ">=0.10.0" + "dependencies": { + "babel-runtime": "^6.22.0" } }, - "node_modules/ganache-core/node_modules/babel-code-frame/node_modules/chalk": { - "version": "1.1.3", + "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-unicode-regex": { + "version": "6.24.1", "dev": true, "license": "MIT", "dependencies": { - "ansi-styles": "^2.2.1", - "escape-string-regexp": "^1.0.2", - "has-ansi": "^2.0.0", - "strip-ansi": "^3.0.0", - "supports-color": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" + "babel-helper-regex": "^6.24.1", + "babel-runtime": "^6.22.0", + "regexpu-core": "^2.0.0" } }, - "node_modules/ganache-core/node_modules/babel-code-frame/node_modules/js-tokens": { - "version": "3.0.2", + "node_modules/ganache-core/node_modules/babel-plugin-transform-exponentiation-operator": { + "version": "6.24.1", "dev": true, - "license": "MIT" + "license": "MIT", + "dependencies": { + "babel-helper-builder-binary-assignment-operator-visitor": "^6.24.1", + "babel-plugin-syntax-exponentiation-operator": "^6.8.0", + "babel-runtime": "^6.22.0" + } }, - "node_modules/ganache-core/node_modules/babel-code-frame/node_modules/strip-ansi": { - "version": "3.0.1", + "node_modules/ganache-core/node_modules/babel-plugin-transform-regenerator": { + "version": "6.26.0", "dev": true, "license": "MIT", "dependencies": { - "ansi-regex": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" + "regenerator-transform": "^0.10.0" } }, - "node_modules/ganache-core/node_modules/babel-code-frame/node_modules/supports-color": { - "version": "2.0.0", + "node_modules/ganache-core/node_modules/babel-plugin-transform-strict-mode": { + "version": "6.24.1", "dev": true, "license": "MIT", - "engines": { - "node": ">=0.8.0" + "dependencies": { + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" } }, - "node_modules/ganache-core/node_modules/babel-core": { - "version": "6.26.3", + "node_modules/ganache-core/node_modules/babel-preset-env": { + "version": "1.7.0", "dev": true, "license": "MIT", "dependencies": { - "babel-code-frame": "^6.26.0", - "babel-generator": "^6.26.0", - "babel-helpers": "^6.24.1", - "babel-messages": "^6.23.0", - "babel-register": "^6.26.0", - "babel-runtime": "^6.26.0", - "babel-template": "^6.26.0", - "babel-traverse": "^6.26.0", - "babel-types": "^6.26.0", - "babylon": "^6.18.0", - "convert-source-map": "^1.5.1", - "debug": "^2.6.9", - "json5": "^0.5.1", - "lodash": "^4.17.4", - "minimatch": "^3.0.4", - "path-is-absolute": "^1.0.1", - "private": "^0.1.8", - "slash": "^1.0.0", - "source-map": "^0.5.7" - } - }, - "node_modules/ganache-core/node_modules/babel-core/node_modules/debug": { - "version": "2.6.9", - "dev": true, - "license": "MIT", - "dependencies": { - "ms": "2.0.0" + "babel-plugin-check-es2015-constants": "^6.22.0", + "babel-plugin-syntax-trailing-function-commas": "^6.22.0", + "babel-plugin-transform-async-to-generator": "^6.22.0", + "babel-plugin-transform-es2015-arrow-functions": "^6.22.0", + "babel-plugin-transform-es2015-block-scoped-functions": "^6.22.0", + "babel-plugin-transform-es2015-block-scoping": "^6.23.0", + "babel-plugin-transform-es2015-classes": "^6.23.0", + "babel-plugin-transform-es2015-computed-properties": "^6.22.0", + "babel-plugin-transform-es2015-destructuring": "^6.23.0", + "babel-plugin-transform-es2015-duplicate-keys": "^6.22.0", + "babel-plugin-transform-es2015-for-of": "^6.23.0", + "babel-plugin-transform-es2015-function-name": "^6.22.0", + "babel-plugin-transform-es2015-literals": "^6.22.0", + "babel-plugin-transform-es2015-modules-amd": "^6.22.0", + "babel-plugin-transform-es2015-modules-commonjs": "^6.23.0", + "babel-plugin-transform-es2015-modules-systemjs": "^6.23.0", + "babel-plugin-transform-es2015-modules-umd": "^6.23.0", + "babel-plugin-transform-es2015-object-super": "^6.22.0", + "babel-plugin-transform-es2015-parameters": "^6.23.0", + "babel-plugin-transform-es2015-shorthand-properties": "^6.22.0", + "babel-plugin-transform-es2015-spread": "^6.22.0", + "babel-plugin-transform-es2015-sticky-regex": "^6.22.0", + "babel-plugin-transform-es2015-template-literals": "^6.22.0", + "babel-plugin-transform-es2015-typeof-symbol": "^6.23.0", + "babel-plugin-transform-es2015-unicode-regex": "^6.22.0", + "babel-plugin-transform-exponentiation-operator": "^6.22.0", + "babel-plugin-transform-regenerator": "^6.22.0", + "browserslist": "^3.2.6", + "invariant": "^2.2.2", + "semver": "^5.3.0" } }, - "node_modules/ganache-core/node_modules/babel-core/node_modules/json5": { - "version": "0.5.1", + "node_modules/ganache-core/node_modules/babel-preset-env/node_modules/semver": { + "version": "5.7.1", "dev": true, - "license": "MIT", + "license": "ISC", "bin": { - "json5": "lib/cli.js" - } - }, - "node_modules/ganache-core/node_modules/babel-core/node_modules/ms": { - "version": "2.0.0", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/babel-core/node_modules/slash": { - "version": "1.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" + "semver": "bin/semver" } }, - "node_modules/ganache-core/node_modules/babel-generator": { - "version": "6.26.1", + "node_modules/ganache-core/node_modules/babel-register": { + "version": "6.26.0", "dev": true, "license": "MIT", "dependencies": { - "babel-messages": "^6.23.0", + "babel-core": "^6.26.0", "babel-runtime": "^6.26.0", - "babel-types": "^6.26.0", - "detect-indent": "^4.0.0", - "jsesc": "^1.3.0", + "core-js": "^2.5.0", + "home-or-tmp": "^2.0.0", "lodash": "^4.17.4", - "source-map": "^0.5.7", - "trim-right": "^1.0.1" + "mkdirp": "^0.5.1", + "source-map-support": "^0.4.15" } }, - "node_modules/ganache-core/node_modules/babel-generator/node_modules/jsesc": { - "version": "1.3.0", + "node_modules/ganache-core/node_modules/babel-register/node_modules/source-map-support": { + "version": "0.4.18", "dev": true, "license": "MIT", - "bin": { - "jsesc": "bin/jsesc" + "dependencies": { + "source-map": "^0.5.6" } }, - "node_modules/ganache-core/node_modules/babel-helper-builder-binary-assignment-operator-visitor": { - "version": "6.24.1", + "node_modules/ganache-core/node_modules/babel-runtime": { + "version": "6.26.0", "dev": true, "license": "MIT", "dependencies": { - "babel-helper-explode-assignable-expression": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" + "core-js": "^2.4.0", + "regenerator-runtime": "^0.11.0" } }, - "node_modules/ganache-core/node_modules/babel-helper-call-delegate": { - "version": "6.24.1", + "node_modules/ganache-core/node_modules/babel-template": { + "version": "6.26.0", "dev": true, "license": "MIT", "dependencies": { - "babel-helper-hoist-variables": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-traverse": "^6.24.1", - "babel-types": "^6.24.1" + "babel-runtime": "^6.26.0", + "babel-traverse": "^6.26.0", + "babel-types": "^6.26.0", + "babylon": "^6.18.0", + "lodash": "^4.17.4" } }, - "node_modules/ganache-core/node_modules/babel-helper-define-map": { + "node_modules/ganache-core/node_modules/babel-traverse": { "version": "6.26.0", "dev": true, "license": "MIT", "dependencies": { - "babel-helper-function-name": "^6.24.1", + "babel-code-frame": "^6.26.0", + "babel-messages": "^6.23.0", "babel-runtime": "^6.26.0", "babel-types": "^6.26.0", + "babylon": "^6.18.0", + "debug": "^2.6.8", + "globals": "^9.18.0", + "invariant": "^2.2.2", "lodash": "^4.17.4" } }, - "node_modules/ganache-core/node_modules/babel-helper-explode-assignable-expression": { - "version": "6.24.1", + "node_modules/ganache-core/node_modules/babel-traverse/node_modules/debug": { + "version": "2.6.9", "dev": true, "license": "MIT", "dependencies": { - "babel-runtime": "^6.22.0", - "babel-traverse": "^6.24.1", - "babel-types": "^6.24.1" + "ms": "2.0.0" } }, - "node_modules/ganache-core/node_modules/babel-helper-function-name": { - "version": "6.24.1", + "node_modules/ganache-core/node_modules/babel-traverse/node_modules/globals": { + "version": "9.18.0", "dev": true, "license": "MIT", - "dependencies": { - "babel-helper-get-function-arity": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1", - "babel-traverse": "^6.24.1", - "babel-types": "^6.24.1" + "engines": { + "node": ">=0.10.0" } }, - "node_modules/ganache-core/node_modules/babel-helper-get-function-arity": { - "version": "6.24.1", + "node_modules/ganache-core/node_modules/babel-traverse/node_modules/ms": { + "version": "2.0.0", "dev": true, - "license": "MIT", - "dependencies": { - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" - } + "license": "MIT" }, - "node_modules/ganache-core/node_modules/babel-helper-hoist-variables": { - "version": "6.24.1", + "node_modules/ganache-core/node_modules/babel-types": { + "version": "6.26.0", "dev": true, "license": "MIT", "dependencies": { - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" + "babel-runtime": "^6.26.0", + "esutils": "^2.0.2", + "lodash": "^4.17.4", + "to-fast-properties": "^1.0.3" } }, - "node_modules/ganache-core/node_modules/babel-helper-optimise-call-expression": { - "version": "6.24.1", + "node_modules/ganache-core/node_modules/babel-types/node_modules/to-fast-properties": { + "version": "1.0.3", "dev": true, "license": "MIT", - "dependencies": { - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" + "engines": { + "node": ">=0.10.0" } }, - "node_modules/ganache-core/node_modules/babel-helper-regex": { - "version": "6.26.0", + "node_modules/ganache-core/node_modules/babelify": { + "version": "7.3.0", "dev": true, "license": "MIT", "dependencies": { - "babel-runtime": "^6.26.0", - "babel-types": "^6.26.0", - "lodash": "^4.17.4" + "babel-core": "^6.0.14", + "object-assign": "^4.0.0" } }, - "node_modules/ganache-core/node_modules/babel-helper-remap-async-to-generator": { - "version": "6.24.1", + "node_modules/ganache-core/node_modules/babylon": { + "version": "6.18.0", "dev": true, "license": "MIT", - "dependencies": { - "babel-helper-function-name": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1", - "babel-traverse": "^6.24.1", - "babel-types": "^6.24.1" + "bin": { + "babylon": "bin/babylon.js" } }, - "node_modules/ganache-core/node_modules/babel-helper-replace-supers": { - "version": "6.24.1", + "node_modules/ganache-core/node_modules/backoff": { + "version": "2.5.0", "dev": true, "license": "MIT", "dependencies": { - "babel-helper-optimise-call-expression": "^6.24.1", - "babel-messages": "^6.23.0", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1", - "babel-traverse": "^6.24.1", - "babel-types": "^6.24.1" + "precond": "0.2" + }, + "engines": { + "node": ">= 0.6" } }, - "node_modules/ganache-core/node_modules/babel-helpers": { - "version": "6.24.1", + "node_modules/ganache-core/node_modules/balanced-match": { + "version": "1.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/base": { + "version": "0.11.2", "dev": true, "license": "MIT", "dependencies": { - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1" + "cache-base": "^1.0.1", + "class-utils": "^0.3.5", + "component-emitter": "^1.2.1", + "define-property": "^1.0.0", + "isobject": "^3.0.1", + "mixin-deep": "^1.2.0", + "pascalcase": "^0.1.1" + }, + "engines": { + "node": ">=0.10.0" } }, - "node_modules/ganache-core/node_modules/babel-messages": { - "version": "6.23.0", + "node_modules/ganache-core/node_modules/base-x": { + "version": "3.0.8", "dev": true, "license": "MIT", "dependencies": { - "babel-runtime": "^6.22.0" + "safe-buffer": "^5.0.1" } }, - "node_modules/ganache-core/node_modules/babel-plugin-check-es2015-constants": { - "version": "6.22.0", + "node_modules/ganache-core/node_modules/base/node_modules/define-property": { + "version": "1.0.0", "dev": true, "license": "MIT", "dependencies": { - "babel-runtime": "^6.22.0" + "is-descriptor": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" } }, - "node_modules/ganache-core/node_modules/babel-plugin-syntax-async-functions": { - "version": "6.13.0", + "node_modules/ganache-core/node_modules/base64-js": { + "version": "1.5.1", "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], "license": "MIT" }, - "node_modules/ganache-core/node_modules/babel-plugin-syntax-exponentiation-operator": { - "version": "6.13.0", + "node_modules/ganache-core/node_modules/bcrypt-pbkdf": { + "version": "1.0.2", "dev": true, - "license": "MIT" + "license": "BSD-3-Clause", + "dependencies": { + "tweetnacl": "^0.14.3" + } }, - "node_modules/ganache-core/node_modules/babel-plugin-syntax-trailing-function-commas": { - "version": "6.22.0", + "node_modules/ganache-core/node_modules/bcrypt-pbkdf/node_modules/tweetnacl": { + "version": "0.14.5", "dev": true, - "license": "MIT" + "license": "Unlicense" }, - "node_modules/ganache-core/node_modules/babel-plugin-transform-async-to-generator": { - "version": "6.24.1", + "node_modules/ganache-core/node_modules/bignumber.js": { + "version": "9.0.1", "dev": true, "license": "MIT", - "dependencies": { - "babel-helper-remap-async-to-generator": "^6.24.1", - "babel-plugin-syntax-async-functions": "^6.8.0", - "babel-runtime": "^6.22.0" + "optional": true, + "engines": { + "node": "*" } }, - "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-arrow-functions": { - "version": "6.22.0", + "node_modules/ganache-core/node_modules/bip39": { + "version": "2.5.0", "dev": true, - "license": "MIT", + "license": "ISC", "dependencies": { - "babel-runtime": "^6.22.0" + "create-hash": "^1.1.0", + "pbkdf2": "^3.0.9", + "randombytes": "^2.0.1", + "safe-buffer": "^5.0.1", + "unorm": "^1.3.3" } }, - "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-block-scoped-functions": { - "version": "6.22.0", + "node_modules/ganache-core/node_modules/blakejs": { + "version": "1.1.0", "dev": true, - "license": "MIT", - "dependencies": { - "babel-runtime": "^6.22.0" - } + "license": "CC0-1.0" }, - "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-block-scoping": { - "version": "6.26.0", + "node_modules/ganache-core/node_modules/bluebird": { + "version": "3.7.2", "dev": true, "license": "MIT", - "dependencies": { - "babel-runtime": "^6.26.0", - "babel-template": "^6.26.0", - "babel-traverse": "^6.26.0", - "babel-types": "^6.26.0", - "lodash": "^4.17.4" - } + "optional": true }, - "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-classes": { - "version": "6.24.1", + "node_modules/ganache-core/node_modules/bn.js": { + "version": "4.11.9", "dev": true, - "license": "MIT", - "dependencies": { - "babel-helper-define-map": "^6.24.1", - "babel-helper-function-name": "^6.24.1", - "babel-helper-optimise-call-expression": "^6.24.1", - "babel-helper-replace-supers": "^6.24.1", - "babel-messages": "^6.23.0", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1", - "babel-traverse": "^6.24.1", - "babel-types": "^6.24.1" - } + "license": "MIT" }, - "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-computed-properties": { - "version": "6.24.1", + "node_modules/ganache-core/node_modules/body-parser": { + "version": "1.19.0", "dev": true, "license": "MIT", + "optional": true, "dependencies": { - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1" + "bytes": "3.1.0", + "content-type": "~1.0.4", + "debug": "2.6.9", + "depd": "~1.1.2", + "http-errors": "1.7.2", + "iconv-lite": "0.4.24", + "on-finished": "~2.3.0", + "qs": "6.7.0", + "raw-body": "2.4.0", + "type-is": "~1.6.17" + }, + "engines": { + "node": ">= 0.8" } }, - "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-destructuring": { - "version": "6.23.0", + "node_modules/ganache-core/node_modules/body-parser/node_modules/debug": { + "version": "2.6.9", "dev": true, "license": "MIT", + "optional": true, "dependencies": { - "babel-runtime": "^6.22.0" + "ms": "2.0.0" } }, - "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-duplicate-keys": { - "version": "6.24.1", + "node_modules/ganache-core/node_modules/body-parser/node_modules/ms": { + "version": "2.0.0", "dev": true, "license": "MIT", - "dependencies": { - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" + "optional": true + }, + "node_modules/ganache-core/node_modules/body-parser/node_modules/qs": { + "version": "6.7.0", + "dev": true, + "license": "BSD-3-Clause", + "optional": true, + "engines": { + "node": ">=0.6" } }, - "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-for-of": { - "version": "6.23.0", + "node_modules/ganache-core/node_modules/brace-expansion": { + "version": "1.1.11", "dev": true, "license": "MIT", "dependencies": { - "babel-runtime": "^6.22.0" + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" } }, - "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-function-name": { - "version": "6.24.1", + "node_modules/ganache-core/node_modules/brorand": { + "version": "1.1.0", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/browserify-aes": { + "version": "1.2.0", "dev": true, "license": "MIT", "dependencies": { - "babel-helper-function-name": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" + "buffer-xor": "^1.0.3", + "cipher-base": "^1.0.0", + "create-hash": "^1.1.0", + "evp_bytestokey": "^1.0.3", + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" } }, - "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-literals": { - "version": "6.22.0", + "node_modules/ganache-core/node_modules/browserify-cipher": { + "version": "1.0.1", "dev": true, "license": "MIT", + "optional": true, "dependencies": { - "babel-runtime": "^6.22.0" + "browserify-aes": "^1.0.4", + "browserify-des": "^1.0.0", + "evp_bytestokey": "^1.0.0" } }, - "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-modules-amd": { - "version": "6.24.1", + "node_modules/ganache-core/node_modules/browserify-des": { + "version": "1.0.2", "dev": true, "license": "MIT", + "optional": true, "dependencies": { - "babel-plugin-transform-es2015-modules-commonjs": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1" + "cipher-base": "^1.0.1", + "des.js": "^1.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" } }, - "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-modules-commonjs": { - "version": "6.26.2", + "node_modules/ganache-core/node_modules/browserify-rsa": { + "version": "4.1.0", "dev": true, "license": "MIT", + "optional": true, "dependencies": { - "babel-plugin-transform-strict-mode": "^6.24.1", - "babel-runtime": "^6.26.0", - "babel-template": "^6.26.0", - "babel-types": "^6.26.0" + "bn.js": "^5.0.0", + "randombytes": "^2.0.1" } }, - "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-modules-systemjs": { - "version": "6.24.1", + "node_modules/ganache-core/node_modules/browserify-rsa/node_modules/bn.js": { + "version": "5.1.3", "dev": true, "license": "MIT", + "optional": true + }, + "node_modules/ganache-core/node_modules/browserify-sign": { + "version": "4.2.1", + "dev": true, + "license": "ISC", + "optional": true, "dependencies": { - "babel-helper-hoist-variables": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1" + "bn.js": "^5.1.1", + "browserify-rsa": "^4.0.1", + "create-hash": "^1.2.0", + "create-hmac": "^1.1.7", + "elliptic": "^6.5.3", + "inherits": "^2.0.4", + "parse-asn1": "^5.1.5", + "readable-stream": "^3.6.0", + "safe-buffer": "^5.2.0" } }, - "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-modules-umd": { - "version": "6.24.1", + "node_modules/ganache-core/node_modules/browserify-sign/node_modules/bn.js": { + "version": "5.1.3", "dev": true, "license": "MIT", - "dependencies": { - "babel-plugin-transform-es2015-modules-amd": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1" - } + "optional": true }, - "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-object-super": { - "version": "6.24.1", + "node_modules/ganache-core/node_modules/browserify-sign/node_modules/readable-stream": { + "version": "3.6.0", "dev": true, "license": "MIT", + "optional": true, "dependencies": { - "babel-helper-replace-supers": "^6.24.1", - "babel-runtime": "^6.22.0" + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" } }, - "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-parameters": { - "version": "6.24.1", + "node_modules/ganache-core/node_modules/browserslist": { + "version": "3.2.8", "dev": true, "license": "MIT", "dependencies": { - "babel-helper-call-delegate": "^6.24.1", - "babel-helper-get-function-arity": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1", - "babel-traverse": "^6.24.1", - "babel-types": "^6.24.1" + "caniuse-lite": "^1.0.30000844", + "electron-to-chromium": "^1.3.47" + }, + "bin": { + "browserslist": "cli.js" } }, - "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-shorthand-properties": { - "version": "6.24.1", + "node_modules/ganache-core/node_modules/bs58": { + "version": "4.0.1", "dev": true, "license": "MIT", "dependencies": { - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" + "base-x": "^3.0.2" } }, - "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-spread": { - "version": "6.22.0", + "node_modules/ganache-core/node_modules/bs58check": { + "version": "2.1.2", "dev": true, "license": "MIT", "dependencies": { - "babel-runtime": "^6.22.0" + "bs58": "^4.0.0", + "create-hash": "^1.1.0", + "safe-buffer": "^5.1.2" } }, - "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-sticky-regex": { - "version": "6.24.1", + "node_modules/ganache-core/node_modules/buffer": { + "version": "5.7.1", "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], "license": "MIT", "dependencies": { - "babel-helper-regex": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" } }, - "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-template-literals": { - "version": "6.22.0", + "node_modules/ganache-core/node_modules/buffer-from": { + "version": "1.1.1", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/buffer-to-arraybuffer": { + "version": "0.0.5", "dev": true, "license": "MIT", - "dependencies": { - "babel-runtime": "^6.22.0" - } + "optional": true }, - "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-typeof-symbol": { - "version": "6.23.0", + "node_modules/ganache-core/node_modules/buffer-xor": { + "version": "1.0.3", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/bufferutil": { + "version": "4.0.3", "dev": true, + "hasInstallScript": true, "license": "MIT", "dependencies": { - "babel-runtime": "^6.22.0" + "node-gyp-build": "^4.2.0" } }, - "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-unicode-regex": { - "version": "6.24.1", + "node_modules/ganache-core/node_modules/bytes": { + "version": "3.1.0", "dev": true, "license": "MIT", - "dependencies": { - "babel-helper-regex": "^6.24.1", - "babel-runtime": "^6.22.0", - "regexpu-core": "^2.0.0" + "optional": true, + "engines": { + "node": ">= 0.8" } }, - "node_modules/ganache-core/node_modules/babel-plugin-transform-exponentiation-operator": { - "version": "6.24.1", + "node_modules/ganache-core/node_modules/bytewise": { + "version": "1.1.0", "dev": true, "license": "MIT", "dependencies": { - "babel-helper-builder-binary-assignment-operator-visitor": "^6.24.1", - "babel-plugin-syntax-exponentiation-operator": "^6.8.0", - "babel-runtime": "^6.22.0" + "bytewise-core": "^1.2.2", + "typewise": "^1.0.3" } }, - "node_modules/ganache-core/node_modules/babel-plugin-transform-regenerator": { - "version": "6.26.0", + "node_modules/ganache-core/node_modules/bytewise-core": { + "version": "1.2.3", "dev": true, "license": "MIT", "dependencies": { - "regenerator-transform": "^0.10.0" + "typewise-core": "^1.2" } }, - "node_modules/ganache-core/node_modules/babel-plugin-transform-strict-mode": { - "version": "6.24.1", + "node_modules/ganache-core/node_modules/cache-base": { + "version": "1.0.1", "dev": true, "license": "MIT", "dependencies": { - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" + "collection-visit": "^1.0.0", + "component-emitter": "^1.2.1", + "get-value": "^2.0.6", + "has-value": "^1.0.0", + "isobject": "^3.0.1", + "set-value": "^2.0.0", + "to-object-path": "^0.3.0", + "union-value": "^1.0.0", + "unset-value": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" } }, - "node_modules/ganache-core/node_modules/babel-preset-env": { - "version": "1.7.0", + "node_modules/ganache-core/node_modules/cacheable-request": { + "version": "6.1.0", "dev": true, "license": "MIT", + "optional": true, "dependencies": { - "babel-plugin-check-es2015-constants": "^6.22.0", - "babel-plugin-syntax-trailing-function-commas": "^6.22.0", - "babel-plugin-transform-async-to-generator": "^6.22.0", - "babel-plugin-transform-es2015-arrow-functions": "^6.22.0", - "babel-plugin-transform-es2015-block-scoped-functions": "^6.22.0", - "babel-plugin-transform-es2015-block-scoping": "^6.23.0", - "babel-plugin-transform-es2015-classes": "^6.23.0", - "babel-plugin-transform-es2015-computed-properties": "^6.22.0", - "babel-plugin-transform-es2015-destructuring": "^6.23.0", - "babel-plugin-transform-es2015-duplicate-keys": "^6.22.0", - "babel-plugin-transform-es2015-for-of": "^6.23.0", - "babel-plugin-transform-es2015-function-name": "^6.22.0", - "babel-plugin-transform-es2015-literals": "^6.22.0", - "babel-plugin-transform-es2015-modules-amd": "^6.22.0", - "babel-plugin-transform-es2015-modules-commonjs": "^6.23.0", - "babel-plugin-transform-es2015-modules-systemjs": "^6.23.0", - "babel-plugin-transform-es2015-modules-umd": "^6.23.0", - "babel-plugin-transform-es2015-object-super": "^6.22.0", - "babel-plugin-transform-es2015-parameters": "^6.23.0", - "babel-plugin-transform-es2015-shorthand-properties": "^6.22.0", - "babel-plugin-transform-es2015-spread": "^6.22.0", - "babel-plugin-transform-es2015-sticky-regex": "^6.22.0", - "babel-plugin-transform-es2015-template-literals": "^6.22.0", - "babel-plugin-transform-es2015-typeof-symbol": "^6.23.0", - "babel-plugin-transform-es2015-unicode-regex": "^6.22.0", - "babel-plugin-transform-exponentiation-operator": "^6.22.0", - "babel-plugin-transform-regenerator": "^6.22.0", - "browserslist": "^3.2.6", - "invariant": "^2.2.2", - "semver": "^5.3.0" + "clone-response": "^1.0.2", + "get-stream": "^5.1.0", + "http-cache-semantics": "^4.0.0", + "keyv": "^3.0.0", + "lowercase-keys": "^2.0.0", + "normalize-url": "^4.1.0", + "responselike": "^1.0.2" + }, + "engines": { + "node": ">=8" } }, - "node_modules/ganache-core/node_modules/babel-preset-env/node_modules/semver": { - "version": "5.7.1", + "node_modules/ganache-core/node_modules/cacheable-request/node_modules/lowercase-keys": { + "version": "2.0.0", "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver" + "license": "MIT", + "optional": true, + "engines": { + "node": ">=8" } }, - "node_modules/ganache-core/node_modules/babel-register": { - "version": "6.26.0", + "node_modules/ganache-core/node_modules/cachedown": { + "version": "1.0.0", "dev": true, "license": "MIT", "dependencies": { - "babel-core": "^6.26.0", - "babel-runtime": "^6.26.0", - "core-js": "^2.5.0", - "home-or-tmp": "^2.0.0", - "lodash": "^4.17.4", - "mkdirp": "^0.5.1", - "source-map-support": "^0.4.15" + "abstract-leveldown": "^2.4.1", + "lru-cache": "^3.2.0" } }, - "node_modules/ganache-core/node_modules/babel-register/node_modules/source-map-support": { - "version": "0.4.18", + "node_modules/ganache-core/node_modules/cachedown/node_modules/abstract-leveldown": { + "version": "2.7.2", "dev": true, "license": "MIT", "dependencies": { - "source-map": "^0.5.6" + "xtend": "~4.0.0" } }, - "node_modules/ganache-core/node_modules/babel-runtime": { - "version": "6.26.0", + "node_modules/ganache-core/node_modules/cachedown/node_modules/lru-cache": { + "version": "3.2.0", "dev": true, - "license": "MIT", + "license": "ISC", "dependencies": { - "core-js": "^2.4.0", - "regenerator-runtime": "^0.11.0" + "pseudomap": "^1.0.1" } }, - "node_modules/ganache-core/node_modules/babel-template": { - "version": "6.26.0", + "node_modules/ganache-core/node_modules/call-bind": { + "version": "1.0.2", "dev": true, "license": "MIT", "dependencies": { - "babel-runtime": "^6.26.0", - "babel-traverse": "^6.26.0", - "babel-types": "^6.26.0", - "babylon": "^6.18.0", - "lodash": "^4.17.4" + "function-bind": "^1.1.1", + "get-intrinsic": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/ganache-core/node_modules/babel-traverse": { - "version": "6.26.0", + "node_modules/ganache-core/node_modules/caniuse-lite": { + "version": "1.0.30001174", + "dev": true, + "license": "CC-BY-4.0" + }, + "node_modules/ganache-core/node_modules/caseless": { + "version": "0.12.0", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/ganache-core/node_modules/chalk": { + "version": "2.4.2", "dev": true, "license": "MIT", "dependencies": { - "babel-code-frame": "^6.26.0", - "babel-messages": "^6.23.0", - "babel-runtime": "^6.26.0", - "babel-types": "^6.26.0", - "babylon": "^6.18.0", - "debug": "^2.6.8", - "globals": "^9.18.0", - "invariant": "^2.2.2", - "lodash": "^4.17.4" + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" } }, - "node_modules/ganache-core/node_modules/babel-traverse/node_modules/debug": { - "version": "2.6.9", + "node_modules/ganache-core/node_modules/checkpoint-store": { + "version": "1.1.0", "dev": true, - "license": "MIT", + "license": "ISC", "dependencies": { - "ms": "2.0.0" + "functional-red-black-tree": "^1.0.1" } }, - "node_modules/ganache-core/node_modules/babel-traverse/node_modules/globals": { - "version": "9.18.0", + "node_modules/ganache-core/node_modules/chownr": { + "version": "1.1.4", "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } + "license": "ISC", + "optional": true }, - "node_modules/ganache-core/node_modules/babel-traverse/node_modules/ms": { + "node_modules/ganache-core/node_modules/ci-info": { "version": "2.0.0", "dev": true, "license": "MIT" }, - "node_modules/ganache-core/node_modules/babel-types": { - "version": "6.26.0", + "node_modules/ganache-core/node_modules/cids": { + "version": "0.7.5", "dev": true, "license": "MIT", + "optional": true, "dependencies": { - "babel-runtime": "^6.26.0", - "esutils": "^2.0.2", - "lodash": "^4.17.4", - "to-fast-properties": "^1.0.3" + "buffer": "^5.5.0", + "class-is": "^1.1.0", + "multibase": "~0.6.0", + "multicodec": "^1.0.0", + "multihashes": "~0.4.15" + }, + "engines": { + "node": ">=4.0.0", + "npm": ">=3.0.0" } }, - "node_modules/ganache-core/node_modules/babel-types/node_modules/to-fast-properties": { - "version": "1.0.3", - "dev": true, + "node_modules/ganache-core/node_modules/cids/node_modules/multicodec": { + "version": "1.0.4", + "dev": true, "license": "MIT", - "engines": { - "node": ">=0.10.0" + "optional": true, + "dependencies": { + "buffer": "^5.6.0", + "varint": "^5.0.0" } }, - "node_modules/ganache-core/node_modules/babelify": { - "version": "7.3.0", + "node_modules/ganache-core/node_modules/cipher-base": { + "version": "1.0.4", "dev": true, "license": "MIT", "dependencies": { - "babel-core": "^6.0.14", - "object-assign": "^4.0.0" + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" } }, - "node_modules/ganache-core/node_modules/babylon": { - "version": "6.18.0", + "node_modules/ganache-core/node_modules/class-is": { + "version": "1.1.0", "dev": true, "license": "MIT", - "bin": { - "babylon": "bin/babylon.js" - } + "optional": true }, - "node_modules/ganache-core/node_modules/backoff": { - "version": "2.5.0", + "node_modules/ganache-core/node_modules/class-utils": { + "version": "0.3.6", "dev": true, "license": "MIT", "dependencies": { - "precond": "0.2" + "arr-union": "^3.1.0", + "define-property": "^0.2.5", + "isobject": "^3.0.0", + "static-extend": "^0.1.1" }, "engines": { - "node": ">= 0.6" + "node": ">=0.10.0" } }, - "node_modules/ganache-core/node_modules/balanced-match": { - "version": "1.0.0", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/base": { - "version": "0.11.2", + "node_modules/ganache-core/node_modules/class-utils/node_modules/define-property": { + "version": "0.2.5", "dev": true, "license": "MIT", "dependencies": { - "cache-base": "^1.0.1", - "class-utils": "^0.3.5", - "component-emitter": "^1.2.1", - "define-property": "^1.0.0", - "isobject": "^3.0.1", - "mixin-deep": "^1.2.0", - "pascalcase": "^0.1.1" + "is-descriptor": "^0.1.0" }, "engines": { "node": ">=0.10.0" } }, - "node_modules/ganache-core/node_modules/base-x": { - "version": "3.0.8", + "node_modules/ganache-core/node_modules/class-utils/node_modules/is-accessor-descriptor": { + "version": "0.1.6", "dev": true, "license": "MIT", "dependencies": { - "safe-buffer": "^5.0.1" + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" } }, - "node_modules/ganache-core/node_modules/base/node_modules/define-property": { - "version": "1.0.0", + "node_modules/ganache-core/node_modules/class-utils/node_modules/is-accessor-descriptor/node_modules/kind-of": { + "version": "3.2.2", "dev": true, "license": "MIT", "dependencies": { - "is-descriptor": "^1.0.0" + "is-buffer": "^1.1.5" }, "engines": { "node": ">=0.10.0" } }, - "node_modules/ganache-core/node_modules/base64-js": { - "version": "1.5.1", + "node_modules/ganache-core/node_modules/class-utils/node_modules/is-buffer": { + "version": "1.1.6", "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], "license": "MIT" }, - "node_modules/ganache-core/node_modules/bcrypt-pbkdf": { - "version": "1.0.2", + "node_modules/ganache-core/node_modules/class-utils/node_modules/is-data-descriptor": { + "version": "0.1.4", "dev": true, - "license": "BSD-3-Clause", + "license": "MIT", "dependencies": { - "tweetnacl": "^0.14.3" + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" } }, - "node_modules/ganache-core/node_modules/bcrypt-pbkdf/node_modules/tweetnacl": { - "version": "0.14.5", - "dev": true, - "license": "Unlicense" - }, - "node_modules/ganache-core/node_modules/bignumber.js": { - "version": "9.0.1", + "node_modules/ganache-core/node_modules/class-utils/node_modules/is-data-descriptor/node_modules/kind-of": { + "version": "3.2.2", "dev": true, "license": "MIT", - "optional": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, "engines": { - "node": "*" + "node": ">=0.10.0" } }, - "node_modules/ganache-core/node_modules/bip39": { - "version": "2.5.0", + "node_modules/ganache-core/node_modules/class-utils/node_modules/is-descriptor": { + "version": "0.1.6", "dev": true, - "license": "ISC", + "license": "MIT", "dependencies": { - "create-hash": "^1.1.0", - "pbkdf2": "^3.0.9", - "randombytes": "^2.0.1", - "safe-buffer": "^5.0.1", - "unorm": "^1.3.3" + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + }, + "engines": { + "node": ">=0.10.0" } }, - "node_modules/ganache-core/node_modules/blakejs": { - "version": "1.1.0", - "dev": true, - "license": "CC0-1.0" - }, - "node_modules/ganache-core/node_modules/bluebird": { - "version": "3.7.2", + "node_modules/ganache-core/node_modules/class-utils/node_modules/kind-of": { + "version": "5.1.0", "dev": true, "license": "MIT", - "optional": true - }, - "node_modules/ganache-core/node_modules/bn.js": { - "version": "4.11.9", - "dev": true, - "license": "MIT" + "engines": { + "node": ">=0.10.0" + } }, - "node_modules/ganache-core/node_modules/body-parser": { - "version": "1.19.0", + "node_modules/ganache-core/node_modules/clone": { + "version": "2.1.2", "dev": true, "license": "MIT", - "optional": true, - "dependencies": { - "bytes": "3.1.0", - "content-type": "~1.0.4", - "debug": "2.6.9", - "depd": "~1.1.2", - "http-errors": "1.7.2", - "iconv-lite": "0.4.24", - "on-finished": "~2.3.0", - "qs": "6.7.0", - "raw-body": "2.4.0", - "type-is": "~1.6.17" - }, "engines": { - "node": ">= 0.8" + "node": ">=0.8" } }, - "node_modules/ganache-core/node_modules/body-parser/node_modules/debug": { - "version": "2.6.9", + "node_modules/ganache-core/node_modules/clone-response": { + "version": "1.0.2", "dev": true, "license": "MIT", "optional": true, "dependencies": { - "ms": "2.0.0" + "mimic-response": "^1.0.0" } }, - "node_modules/ganache-core/node_modules/body-parser/node_modules/ms": { - "version": "2.0.0", + "node_modules/ganache-core/node_modules/collection-visit": { + "version": "1.0.0", "dev": true, "license": "MIT", - "optional": true - }, - "node_modules/ganache-core/node_modules/body-parser/node_modules/qs": { - "version": "6.7.0", - "dev": true, - "license": "BSD-3-Clause", - "optional": true, + "dependencies": { + "map-visit": "^1.0.0", + "object-visit": "^1.0.0" + }, "engines": { - "node": ">=0.6" + "node": ">=0.10.0" } }, - "node_modules/ganache-core/node_modules/brace-expansion": { - "version": "1.1.11", + "node_modules/ganache-core/node_modules/color-convert": { + "version": "1.9.3", "dev": true, "license": "MIT", "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" + "color-name": "1.1.3" } }, - "node_modules/ganache-core/node_modules/brorand": { - "version": "1.1.0", + "node_modules/ganache-core/node_modules/color-name": { + "version": "1.1.3", "dev": true, "license": "MIT" }, - "node_modules/ganache-core/node_modules/browserify-aes": { - "version": "1.2.0", + "node_modules/ganache-core/node_modules/combined-stream": { + "version": "1.0.8", "dev": true, "license": "MIT", "dependencies": { - "buffer-xor": "^1.0.3", - "cipher-base": "^1.0.0", - "create-hash": "^1.1.0", - "evp_bytestokey": "^1.0.3", - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" } }, - "node_modules/ganache-core/node_modules/browserify-cipher": { - "version": "1.0.1", + "node_modules/ganache-core/node_modules/component-emitter": { + "version": "1.3.0", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/concat-map": { + "version": "0.0.1", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/concat-stream": { + "version": "1.6.2", "dev": true, + "engines": [ + "node >= 0.8" + ], "license": "MIT", - "optional": true, "dependencies": { - "browserify-aes": "^1.0.4", - "browserify-des": "^1.0.0", - "evp_bytestokey": "^1.0.0" + "buffer-from": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^2.2.2", + "typedarray": "^0.0.6" } }, - "node_modules/ganache-core/node_modules/browserify-des": { - "version": "1.0.2", + "node_modules/ganache-core/node_modules/content-disposition": { + "version": "0.5.3", "dev": true, "license": "MIT", "optional": true, "dependencies": { - "cipher-base": "^1.0.1", - "des.js": "^1.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" + "safe-buffer": "5.1.2" + }, + "engines": { + "node": ">= 0.6" } }, - "node_modules/ganache-core/node_modules/browserify-rsa": { - "version": "4.1.0", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "bn.js": "^5.0.0", - "randombytes": "^2.0.1" - } - }, - "node_modules/ganache-core/node_modules/browserify-rsa/node_modules/bn.js": { - "version": "5.1.3", + "node_modules/ganache-core/node_modules/content-disposition/node_modules/safe-buffer": { + "version": "5.1.2", "dev": true, "license": "MIT", "optional": true }, - "node_modules/ganache-core/node_modules/browserify-sign": { - "version": "4.2.1", + "node_modules/ganache-core/node_modules/content-hash": { + "version": "2.5.2", "dev": true, "license": "ISC", "optional": true, "dependencies": { - "bn.js": "^5.1.1", - "browserify-rsa": "^4.0.1", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "elliptic": "^6.5.3", - "inherits": "^2.0.4", - "parse-asn1": "^5.1.5", - "readable-stream": "^3.6.0", - "safe-buffer": "^5.2.0" + "cids": "^0.7.1", + "multicodec": "^0.5.5", + "multihashes": "^0.4.15" } }, - "node_modules/ganache-core/node_modules/browserify-sign/node_modules/bn.js": { - "version": "5.1.3", - "dev": true, - "license": "MIT", - "optional": true - }, - "node_modules/ganache-core/node_modules/browserify-sign/node_modules/readable-stream": { - "version": "3.6.0", + "node_modules/ganache-core/node_modules/content-type": { + "version": "1.0.4", "dev": true, "license": "MIT", "optional": true, - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, "engines": { - "node": ">= 6" + "node": ">= 0.6" } }, - "node_modules/ganache-core/node_modules/browserslist": { - "version": "3.2.8", + "node_modules/ganache-core/node_modules/convert-source-map": { + "version": "1.7.0", "dev": true, "license": "MIT", "dependencies": { - "caniuse-lite": "^1.0.30000844", - "electron-to-chromium": "^1.3.47" - }, - "bin": { - "browserslist": "cli.js" + "safe-buffer": "~5.1.1" } }, - "node_modules/ganache-core/node_modules/bs58": { - "version": "4.0.1", + "node_modules/ganache-core/node_modules/convert-source-map/node_modules/safe-buffer": { + "version": "5.1.2", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/cookie": { + "version": "0.4.0", "dev": true, "license": "MIT", - "dependencies": { - "base-x": "^3.0.2" + "optional": true, + "engines": { + "node": ">= 0.6" } }, - "node_modules/ganache-core/node_modules/bs58check": { + "node_modules/ganache-core/node_modules/cookie-signature": { + "version": "1.0.6", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/ganache-core/node_modules/cookiejar": { "version": "2.1.2", "dev": true, "license": "MIT", - "dependencies": { - "bs58": "^4.0.0", - "create-hash": "^1.1.0", - "safe-buffer": "^5.1.2" - } + "optional": true }, - "node_modules/ganache-core/node_modules/buffer": { - "version": "5.7.1", + "node_modules/ganache-core/node_modules/copy-descriptor": { + "version": "0.1.1", "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], "license": "MIT", - "dependencies": { - "base64-js": "^1.3.1", - "ieee754": "^1.1.13" + "engines": { + "node": ">=0.10.0" } }, - "node_modules/ganache-core/node_modules/buffer-from": { - "version": "1.1.1", + "node_modules/ganache-core/node_modules/core-js": { + "version": "2.6.12", "dev": true, + "hasInstallScript": true, "license": "MIT" }, - "node_modules/ganache-core/node_modules/buffer-to-arraybuffer": { - "version": "0.0.5", + "node_modules/ganache-core/node_modules/core-js-pure": { + "version": "3.8.2", "dev": true, + "hasInstallScript": true, "license": "MIT", - "optional": true + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/core-js" + } }, - "node_modules/ganache-core/node_modules/buffer-xor": { - "version": "1.0.3", + "node_modules/ganache-core/node_modules/core-util-is": { + "version": "1.0.2", "dev": true, "license": "MIT" }, - "node_modules/ganache-core/node_modules/bufferutil": { - "version": "4.0.3", + "node_modules/ganache-core/node_modules/cors": { + "version": "2.8.5", "dev": true, - "hasInstallScript": true, "license": "MIT", + "optional": true, "dependencies": { - "node-gyp-build": "^4.2.0" + "object-assign": "^4", + "vary": "^1" + }, + "engines": { + "node": ">= 0.10" } }, - "node_modules/ganache-core/node_modules/bytes": { - "version": "3.1.0", + "node_modules/ganache-core/node_modules/create-ecdh": { + "version": "4.0.4", "dev": true, "license": "MIT", "optional": true, - "engines": { - "node": ">= 0.8" + "dependencies": { + "bn.js": "^4.1.0", + "elliptic": "^6.5.3" } }, - "node_modules/ganache-core/node_modules/bytewise": { - "version": "1.1.0", + "node_modules/ganache-core/node_modules/create-hash": { + "version": "1.2.0", "dev": true, "license": "MIT", "dependencies": { - "bytewise-core": "^1.2.2", - "typewise": "^1.0.3" + "cipher-base": "^1.0.1", + "inherits": "^2.0.1", + "md5.js": "^1.3.4", + "ripemd160": "^2.0.1", + "sha.js": "^2.4.0" } }, - "node_modules/ganache-core/node_modules/bytewise-core": { - "version": "1.2.3", + "node_modules/ganache-core/node_modules/create-hmac": { + "version": "1.1.7", "dev": true, "license": "MIT", "dependencies": { - "typewise-core": "^1.2" + "cipher-base": "^1.0.3", + "create-hash": "^1.1.0", + "inherits": "^2.0.1", + "ripemd160": "^2.0.0", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" } }, - "node_modules/ganache-core/node_modules/cache-base": { - "version": "1.0.1", + "node_modules/ganache-core/node_modules/cross-fetch": { + "version": "2.2.3", "dev": true, "license": "MIT", "dependencies": { - "collection-visit": "^1.0.0", - "component-emitter": "^1.2.1", - "get-value": "^2.0.6", - "has-value": "^1.0.0", - "isobject": "^3.0.1", - "set-value": "^2.0.0", - "to-object-path": "^0.3.0", - "union-value": "^1.0.0", - "unset-value": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" + "node-fetch": "2.1.2", + "whatwg-fetch": "2.0.4" } }, - "node_modules/ganache-core/node_modules/cacheable-request": { - "version": "6.1.0", + "node_modules/ganache-core/node_modules/crypto-browserify": { + "version": "3.12.0", "dev": true, "license": "MIT", "optional": true, "dependencies": { - "clone-response": "^1.0.2", - "get-stream": "^5.1.0", - "http-cache-semantics": "^4.0.0", - "keyv": "^3.0.0", - "lowercase-keys": "^2.0.0", - "normalize-url": "^4.1.0", - "responselike": "^1.0.2" + "browserify-cipher": "^1.0.0", + "browserify-sign": "^4.0.0", + "create-ecdh": "^4.0.0", + "create-hash": "^1.1.0", + "create-hmac": "^1.1.0", + "diffie-hellman": "^5.0.0", + "inherits": "^2.0.1", + "pbkdf2": "^3.0.3", + "public-encrypt": "^4.0.0", + "randombytes": "^2.0.0", + "randomfill": "^1.0.3" }, "engines": { - "node": ">=8" + "node": "*" } }, - "node_modules/ganache-core/node_modules/cacheable-request/node_modules/lowercase-keys": { - "version": "2.0.0", + "node_modules/ganache-core/node_modules/d": { + "version": "1.0.1", "dev": true, - "license": "MIT", - "optional": true, - "engines": { - "node": ">=8" + "license": "ISC", + "dependencies": { + "es5-ext": "^0.10.50", + "type": "^1.0.1" } }, - "node_modules/ganache-core/node_modules/cachedown": { - "version": "1.0.0", + "node_modules/ganache-core/node_modules/dashdash": { + "version": "1.14.1", "dev": true, "license": "MIT", "dependencies": { - "abstract-leveldown": "^2.4.1", - "lru-cache": "^3.2.0" + "assert-plus": "^1.0.0" + }, + "engines": { + "node": ">=0.10" } }, - "node_modules/ganache-core/node_modules/cachedown/node_modules/abstract-leveldown": { - "version": "2.7.2", + "node_modules/ganache-core/node_modules/debug": { + "version": "3.2.6", "dev": true, "license": "MIT", "dependencies": { - "xtend": "~4.0.0" + "ms": "^2.1.1" } }, - "node_modules/ganache-core/node_modules/cachedown/node_modules/lru-cache": { - "version": "3.2.0", + "node_modules/ganache-core/node_modules/decode-uri-component": { + "version": "0.2.0", "dev": true, - "license": "ISC", - "dependencies": { - "pseudomap": "^1.0.1" + "license": "MIT", + "engines": { + "node": ">=0.10" } }, - "node_modules/ganache-core/node_modules/call-bind": { - "version": "1.0.2", + "node_modules/ganache-core/node_modules/decompress-response": { + "version": "3.3.0", "dev": true, "license": "MIT", + "optional": true, "dependencies": { - "function-bind": "^1.1.1", - "get-intrinsic": "^1.0.2" + "mimic-response": "^1.0.0" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } + "engines": { + "node": ">=4" + } }, - "node_modules/ganache-core/node_modules/caniuse-lite": { - "version": "1.0.30001174", + "node_modules/ganache-core/node_modules/deep-equal": { + "version": "1.1.1", "dev": true, - "license": "CC-BY-4.0" + "license": "MIT", + "dependencies": { + "is-arguments": "^1.0.4", + "is-date-object": "^1.0.1", + "is-regex": "^1.0.4", + "object-is": "^1.0.1", + "object-keys": "^1.1.1", + "regexp.prototype.flags": "^1.2.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, - "node_modules/ganache-core/node_modules/caseless": { - "version": "0.12.0", + "node_modules/ganache-core/node_modules/defer-to-connect": { + "version": "1.1.3", "dev": true, - "license": "Apache-2.0" + "license": "MIT", + "optional": true }, - "node_modules/ganache-core/node_modules/chalk": { - "version": "2.4.2", + "node_modules/ganache-core/node_modules/deferred-leveldown": { + "version": "4.0.2", "dev": true, "license": "MIT", "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" + "abstract-leveldown": "~5.0.0", + "inherits": "^2.0.3" }, "engines": { - "node": ">=4" + "node": ">=6" } }, - "node_modules/ganache-core/node_modules/checkpoint-store": { - "version": "1.1.0", + "node_modules/ganache-core/node_modules/deferred-leveldown/node_modules/abstract-leveldown": { + "version": "5.0.0", "dev": true, - "license": "ISC", + "license": "MIT", "dependencies": { - "functional-red-black-tree": "^1.0.1" + "xtend": "~4.0.0" + }, + "engines": { + "node": ">=6" } }, - "node_modules/ganache-core/node_modules/chownr": { - "version": "1.1.4", + "node_modules/ganache-core/node_modules/define-properties": { + "version": "1.1.3", "dev": true, - "license": "ISC", - "optional": true + "license": "MIT", + "dependencies": { + "object-keys": "^1.0.12" + }, + "engines": { + "node": ">= 0.4" + } }, - "node_modules/ganache-core/node_modules/ci-info": { - "version": "2.0.0", + "node_modules/ganache-core/node_modules/define-property": { + "version": "2.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "is-descriptor": "^1.0.2", + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/defined": { + "version": "1.0.0", "dev": true, "license": "MIT" }, - "node_modules/ganache-core/node_modules/cids": { - "version": "0.7.5", + "node_modules/ganache-core/node_modules/delayed-stream": { + "version": "1.0.0", "dev": true, "license": "MIT", - "optional": true, - "dependencies": { - "buffer": "^5.5.0", - "class-is": "^1.1.0", - "multibase": "~0.6.0", - "multicodec": "^1.0.0", - "multihashes": "~0.4.15" - }, "engines": { - "node": ">=4.0.0", - "npm": ">=3.0.0" + "node": ">=0.4.0" } }, - "node_modules/ganache-core/node_modules/cids/node_modules/multicodec": { - "version": "1.0.4", + "node_modules/ganache-core/node_modules/depd": { + "version": "1.1.2", "dev": true, "license": "MIT", "optional": true, - "dependencies": { - "buffer": "^5.6.0", - "varint": "^5.0.0" + "engines": { + "node": ">= 0.6" } }, - "node_modules/ganache-core/node_modules/cipher-base": { - "version": "1.0.4", + "node_modules/ganache-core/node_modules/des.js": { + "version": "1.0.1", "dev": true, "license": "MIT", + "optional": true, "dependencies": { "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" + "minimalistic-assert": "^1.0.0" } }, - "node_modules/ganache-core/node_modules/class-is": { - "version": "1.1.0", + "node_modules/ganache-core/node_modules/destroy": { + "version": "1.0.4", "dev": true, "license": "MIT", "optional": true }, - "node_modules/ganache-core/node_modules/class-utils": { - "version": "0.3.6", + "node_modules/ganache-core/node_modules/detect-indent": { + "version": "4.0.0", "dev": true, "license": "MIT", "dependencies": { - "arr-union": "^3.1.0", - "define-property": "^0.2.5", - "isobject": "^3.0.0", - "static-extend": "^0.1.1" + "repeating": "^2.0.0" }, "engines": { "node": ">=0.10.0" } }, - "node_modules/ganache-core/node_modules/class-utils/node_modules/define-property": { - "version": "0.2.5", + "node_modules/ganache-core/node_modules/diffie-hellman": { + "version": "5.0.3", "dev": true, "license": "MIT", + "optional": true, "dependencies": { - "is-descriptor": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" + "bn.js": "^4.1.0", + "miller-rabin": "^4.0.0", + "randombytes": "^2.0.0" } }, - "node_modules/ganache-core/node_modules/class-utils/node_modules/is-accessor-descriptor": { - "version": "0.1.6", + "node_modules/ganache-core/node_modules/dom-walk": { + "version": "0.1.2", + "dev": true + }, + "node_modules/ganache-core/node_modules/dotignore": { + "version": "0.1.2", "dev": true, "license": "MIT", "dependencies": { - "kind-of": "^3.0.2" + "minimatch": "^3.0.4" }, - "engines": { - "node": ">=0.10.0" + "bin": { + "ignored": "bin/ignored" } }, - "node_modules/ganache-core/node_modules/class-utils/node_modules/is-accessor-descriptor/node_modules/kind-of": { - "version": "3.2.2", + "node_modules/ganache-core/node_modules/duplexer3": { + "version": "0.1.4", + "dev": true, + "license": "BSD-3-Clause", + "optional": true + }, + "node_modules/ganache-core/node_modules/ecc-jsbn": { + "version": "0.1.2", "dev": true, "license": "MIT", "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" + "jsbn": "~0.1.0", + "safer-buffer": "^2.1.0" } }, - "node_modules/ganache-core/node_modules/class-utils/node_modules/is-buffer": { - "version": "1.1.6", + "node_modules/ganache-core/node_modules/ee-first": { + "version": "1.1.1", "dev": true, - "license": "MIT" + "license": "MIT", + "optional": true }, - "node_modules/ganache-core/node_modules/class-utils/node_modules/is-data-descriptor": { - "version": "0.1.4", + "node_modules/ganache-core/node_modules/electron-to-chromium": { + "version": "1.3.636", "dev": true, - "license": "MIT", - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } + "license": "ISC" }, - "node_modules/ganache-core/node_modules/class-utils/node_modules/is-data-descriptor/node_modules/kind-of": { - "version": "3.2.2", + "node_modules/ganache-core/node_modules/elliptic": { + "version": "6.5.3", "dev": true, "license": "MIT", "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" + "bn.js": "^4.4.0", + "brorand": "^1.0.1", + "hash.js": "^1.0.0", + "hmac-drbg": "^1.0.0", + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.0" } }, - "node_modules/ganache-core/node_modules/class-utils/node_modules/is-descriptor": { - "version": "0.1.6", + "node_modules/ganache-core/node_modules/encodeurl": { + "version": "1.0.2", "dev": true, "license": "MIT", - "dependencies": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - }, + "optional": true, "engines": { - "node": ">=0.10.0" + "node": ">= 0.8" } }, - "node_modules/ganache-core/node_modules/class-utils/node_modules/kind-of": { - "version": "5.1.0", + "node_modules/ganache-core/node_modules/encoding": { + "version": "0.1.13", "dev": true, "license": "MIT", - "engines": { - "node": ">=0.10.0" + "dependencies": { + "iconv-lite": "^0.6.2" } }, - "node_modules/ganache-core/node_modules/clone": { - "version": "2.1.2", + "node_modules/ganache-core/node_modules/encoding-down": { + "version": "5.0.4", "dev": true, "license": "MIT", + "dependencies": { + "abstract-leveldown": "^5.0.0", + "inherits": "^2.0.3", + "level-codec": "^9.0.0", + "level-errors": "^2.0.0", + "xtend": "^4.0.1" + }, "engines": { - "node": ">=0.8" + "node": ">=6" } }, - "node_modules/ganache-core/node_modules/clone-response": { - "version": "1.0.2", + "node_modules/ganache-core/node_modules/encoding-down/node_modules/abstract-leveldown": { + "version": "5.0.0", "dev": true, "license": "MIT", - "optional": true, "dependencies": { - "mimic-response": "^1.0.0" + "xtend": "~4.0.0" + }, + "engines": { + "node": ">=6" } }, - "node_modules/ganache-core/node_modules/collection-visit": { - "version": "1.0.0", + "node_modules/ganache-core/node_modules/encoding/node_modules/iconv-lite": { + "version": "0.6.2", "dev": true, "license": "MIT", "dependencies": { - "map-visit": "^1.0.0", - "object-visit": "^1.0.0" + "safer-buffer": ">= 2.1.2 < 3.0.0" }, "engines": { "node": ">=0.10.0" } }, - "node_modules/ganache-core/node_modules/color-convert": { - "version": "1.9.3", + "node_modules/ganache-core/node_modules/end-of-stream": { + "version": "1.4.4", "dev": true, "license": "MIT", "dependencies": { - "color-name": "1.1.3" + "once": "^1.4.0" } }, - "node_modules/ganache-core/node_modules/color-name": { - "version": "1.1.3", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/combined-stream": { - "version": "1.0.8", + "node_modules/ganache-core/node_modules/errno": { + "version": "0.1.8", "dev": true, "license": "MIT", "dependencies": { - "delayed-stream": "~1.0.0" + "prr": "~1.0.1" }, - "engines": { - "node": ">= 0.8" + "bin": { + "errno": "cli.js" } }, - "node_modules/ganache-core/node_modules/component-emitter": { - "version": "1.3.0", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/concat-map": { - "version": "0.0.1", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/concat-stream": { - "version": "1.6.2", + "node_modules/ganache-core/node_modules/es-abstract": { + "version": "1.18.0-next.1", "dev": true, - "engines": [ - "node >= 0.8" - ], "license": "MIT", "dependencies": { - "buffer-from": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^2.2.2", - "typedarray": "^0.0.6" + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1", + "is-callable": "^1.2.2", + "is-negative-zero": "^2.0.0", + "is-regex": "^1.1.1", + "object-inspect": "^1.8.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.1", + "string.prototype.trimend": "^1.0.1", + "string.prototype.trimstart": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/ganache-core/node_modules/content-disposition": { - "version": "0.5.3", + "node_modules/ganache-core/node_modules/es-to-primitive": { + "version": "1.2.1", "dev": true, "license": "MIT", - "optional": true, "dependencies": { - "safe-buffer": "5.1.2" + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" }, "engines": { - "node": ">= 0.6" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/ganache-core/node_modules/content-disposition/node_modules/safe-buffer": { - "version": "5.1.2", - "dev": true, - "license": "MIT", - "optional": true - }, - "node_modules/ganache-core/node_modules/content-hash": { - "version": "2.5.2", + "node_modules/ganache-core/node_modules/es5-ext": { + "version": "0.10.53", "dev": true, "license": "ISC", - "optional": true, "dependencies": { - "cids": "^0.7.1", - "multicodec": "^0.5.5", - "multihashes": "^0.4.15" + "es6-iterator": "~2.0.3", + "es6-symbol": "~3.1.3", + "next-tick": "~1.0.0" } }, - "node_modules/ganache-core/node_modules/content-type": { - "version": "1.0.4", + "node_modules/ganache-core/node_modules/es6-iterator": { + "version": "2.0.3", "dev": true, "license": "MIT", - "optional": true, - "engines": { - "node": ">= 0.6" + "dependencies": { + "d": "1", + "es5-ext": "^0.10.35", + "es6-symbol": "^3.1.1" } }, - "node_modules/ganache-core/node_modules/convert-source-map": { - "version": "1.7.0", + "node_modules/ganache-core/node_modules/es6-symbol": { + "version": "3.1.3", "dev": true, - "license": "MIT", + "license": "ISC", "dependencies": { - "safe-buffer": "~5.1.1" + "d": "^1.0.1", + "ext": "^1.1.2" } }, - "node_modules/ganache-core/node_modules/convert-source-map/node_modules/safe-buffer": { - "version": "5.1.2", + "node_modules/ganache-core/node_modules/escape-html": { + "version": "1.0.3", "dev": true, - "license": "MIT" + "license": "MIT", + "optional": true }, - "node_modules/ganache-core/node_modules/cookie": { - "version": "0.4.0", + "node_modules/ganache-core/node_modules/escape-string-regexp": { + "version": "1.0.5", "dev": true, "license": "MIT", - "optional": true, "engines": { - "node": ">= 0.6" + "node": ">=0.8.0" } }, - "node_modules/ganache-core/node_modules/cookie-signature": { - "version": "1.0.6", - "dev": true, - "license": "MIT", - "optional": true - }, - "node_modules/ganache-core/node_modules/cookiejar": { - "version": "2.1.2", + "node_modules/ganache-core/node_modules/esutils": { + "version": "2.0.3", "dev": true, - "license": "MIT", - "optional": true + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.10.0" + } }, - "node_modules/ganache-core/node_modules/copy-descriptor": { - "version": "0.1.1", + "node_modules/ganache-core/node_modules/etag": { + "version": "1.8.1", "dev": true, "license": "MIT", + "optional": true, "engines": { - "node": ">=0.10.0" + "node": ">= 0.6" } }, - "node_modules/ganache-core/node_modules/core-js": { - "version": "2.6.12", + "node_modules/ganache-core/node_modules/eth-block-tracker": { + "version": "3.0.1", "dev": true, - "hasInstallScript": true, - "license": "MIT" + "license": "MIT", + "dependencies": { + "eth-query": "^2.1.0", + "ethereumjs-tx": "^1.3.3", + "ethereumjs-util": "^5.1.3", + "ethjs-util": "^0.1.3", + "json-rpc-engine": "^3.6.0", + "pify": "^2.3.0", + "tape": "^4.6.3" + } }, - "node_modules/ganache-core/node_modules/core-js-pure": { - "version": "3.8.2", + "node_modules/ganache-core/node_modules/eth-block-tracker/node_modules/ethereumjs-tx": { + "version": "1.3.7", "dev": true, - "hasInstallScript": true, - "license": "MIT", - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/core-js" + "license": "MPL-2.0", + "dependencies": { + "ethereum-common": "^0.0.18", + "ethereumjs-util": "^5.0.0" } }, - "node_modules/ganache-core/node_modules/core-util-is": { - "version": "1.0.2", + "node_modules/ganache-core/node_modules/eth-block-tracker/node_modules/ethereumjs-util": { + "version": "5.2.1", "dev": true, - "license": "MIT" + "license": "MPL-2.0", + "dependencies": { + "bn.js": "^4.11.0", + "create-hash": "^1.1.2", + "elliptic": "^6.5.2", + "ethereum-cryptography": "^0.1.3", + "ethjs-util": "^0.1.3", + "rlp": "^2.0.0", + "safe-buffer": "^5.1.1" + } }, - "node_modules/ganache-core/node_modules/cors": { - "version": "2.8.5", + "node_modules/ganache-core/node_modules/eth-block-tracker/node_modules/pify": { + "version": "2.3.0", "dev": true, "license": "MIT", - "optional": true, - "dependencies": { - "object-assign": "^4", - "vary": "^1" - }, "engines": { - "node": ">= 0.10" + "node": ">=0.10.0" } }, - "node_modules/ganache-core/node_modules/create-ecdh": { - "version": "4.0.4", + "node_modules/ganache-core/node_modules/eth-ens-namehash": { + "version": "2.0.8", "dev": true, - "license": "MIT", + "license": "ISC", "optional": true, "dependencies": { - "bn.js": "^4.1.0", - "elliptic": "^6.5.3" + "idna-uts46-hx": "^2.3.1", + "js-sha3": "^0.5.7" } }, - "node_modules/ganache-core/node_modules/create-hash": { - "version": "1.2.0", + "node_modules/ganache-core/node_modules/eth-json-rpc-infura": { + "version": "3.2.1", "dev": true, - "license": "MIT", + "license": "ISC", "dependencies": { - "cipher-base": "^1.0.1", - "inherits": "^2.0.1", - "md5.js": "^1.3.4", - "ripemd160": "^2.0.1", - "sha.js": "^2.4.0" + "cross-fetch": "^2.1.1", + "eth-json-rpc-middleware": "^1.5.0", + "json-rpc-engine": "^3.4.0", + "json-rpc-error": "^2.0.0" } }, - "node_modules/ganache-core/node_modules/create-hmac": { - "version": "1.1.7", + "node_modules/ganache-core/node_modules/eth-json-rpc-middleware": { + "version": "1.6.0", "dev": true, - "license": "MIT", + "license": "ISC", "dependencies": { - "cipher-base": "^1.0.3", - "create-hash": "^1.1.0", - "inherits": "^2.0.1", - "ripemd160": "^2.0.0", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" + "async": "^2.5.0", + "eth-query": "^2.1.2", + "eth-tx-summary": "^3.1.2", + "ethereumjs-block": "^1.6.0", + "ethereumjs-tx": "^1.3.3", + "ethereumjs-util": "^5.1.2", + "ethereumjs-vm": "^2.1.0", + "fetch-ponyfill": "^4.0.0", + "json-rpc-engine": "^3.6.0", + "json-rpc-error": "^2.0.0", + "json-stable-stringify": "^1.0.1", + "promise-to-callback": "^1.0.0", + "tape": "^4.6.3" } }, - "node_modules/ganache-core/node_modules/cross-fetch": { - "version": "2.2.3", + "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/abstract-leveldown": { + "version": "2.6.3", "dev": true, "license": "MIT", "dependencies": { - "node-fetch": "2.1.2", - "whatwg-fetch": "2.0.4" + "xtend": "~4.0.0" } }, - "node_modules/ganache-core/node_modules/crypto-browserify": { - "version": "3.12.0", + "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/deferred-leveldown": { + "version": "1.2.2", "dev": true, "license": "MIT", - "optional": true, - "dependencies": { - "browserify-cipher": "^1.0.0", - "browserify-sign": "^4.0.0", - "create-ecdh": "^4.0.0", - "create-hash": "^1.1.0", - "create-hmac": "^1.1.0", - "diffie-hellman": "^5.0.0", - "inherits": "^2.0.1", - "pbkdf2": "^3.0.3", - "public-encrypt": "^4.0.0", - "randombytes": "^2.0.0", - "randomfill": "^1.0.3" - }, - "engines": { - "node": "*" - } - }, - "node_modules/ganache-core/node_modules/d": { - "version": "1.0.1", - "dev": true, - "license": "ISC", "dependencies": { - "es5-ext": "^0.10.50", - "type": "^1.0.1" + "abstract-leveldown": "~2.6.0" } }, - "node_modules/ganache-core/node_modules/dashdash": { - "version": "1.14.1", + "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/ethereumjs-account": { + "version": "2.0.5", "dev": true, - "license": "MIT", + "license": "MPL-2.0", "dependencies": { - "assert-plus": "^1.0.0" - }, - "engines": { - "node": ">=0.10" + "ethereumjs-util": "^5.0.0", + "rlp": "^2.0.0", + "safe-buffer": "^5.1.1" } }, - "node_modules/ganache-core/node_modules/debug": { - "version": "3.2.6", + "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/ethereumjs-block": { + "version": "1.7.1", "dev": true, - "license": "MIT", + "license": "MPL-2.0", "dependencies": { - "ms": "^2.1.1" + "async": "^2.0.1", + "ethereum-common": "0.2.0", + "ethereumjs-tx": "^1.2.2", + "ethereumjs-util": "^5.0.0", + "merkle-patricia-tree": "^2.1.2" } }, - "node_modules/ganache-core/node_modules/decode-uri-component": { + "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/ethereumjs-block/node_modules/ethereum-common": { "version": "0.2.0", "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10" - } + "license": "MIT" }, - "node_modules/ganache-core/node_modules/decompress-response": { - "version": "3.3.0", + "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/ethereumjs-tx": { + "version": "1.3.7", "dev": true, - "license": "MIT", - "optional": true, + "license": "MPL-2.0", "dependencies": { - "mimic-response": "^1.0.0" - }, - "engines": { - "node": ">=4" + "ethereum-common": "^0.0.18", + "ethereumjs-util": "^5.0.0" } }, - "node_modules/ganache-core/node_modules/deep-equal": { - "version": "1.1.1", + "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/ethereumjs-util": { + "version": "5.2.1", "dev": true, - "license": "MIT", + "license": "MPL-2.0", "dependencies": { - "is-arguments": "^1.0.4", - "is-date-object": "^1.0.1", - "is-regex": "^1.0.4", - "object-is": "^1.0.1", - "object-keys": "^1.1.1", - "regexp.prototype.flags": "^1.2.0" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "bn.js": "^4.11.0", + "create-hash": "^1.1.2", + "elliptic": "^6.5.2", + "ethereum-cryptography": "^0.1.3", + "ethjs-util": "^0.1.3", + "rlp": "^2.0.0", + "safe-buffer": "^5.1.1" } }, - "node_modules/ganache-core/node_modules/defer-to-connect": { - "version": "1.1.3", + "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/ethereumjs-vm": { + "version": "2.6.0", "dev": true, - "license": "MIT", - "optional": true + "license": "MPL-2.0", + "dependencies": { + "async": "^2.1.2", + "async-eventemitter": "^0.2.2", + "ethereumjs-account": "^2.0.3", + "ethereumjs-block": "~2.2.0", + "ethereumjs-common": "^1.1.0", + "ethereumjs-util": "^6.0.0", + "fake-merkle-patricia-tree": "^1.0.1", + "functional-red-black-tree": "^1.0.1", + "merkle-patricia-tree": "^2.3.2", + "rustbn.js": "~0.2.0", + "safe-buffer": "^5.1.1" + } }, - "node_modules/ganache-core/node_modules/deferred-leveldown": { - "version": "4.0.2", + "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/ethereumjs-vm/node_modules/ethereumjs-block": { + "version": "2.2.2", "dev": true, - "license": "MIT", + "license": "MPL-2.0", "dependencies": { - "abstract-leveldown": "~5.0.0", - "inherits": "^2.0.3" - }, - "engines": { - "node": ">=6" + "async": "^2.0.1", + "ethereumjs-common": "^1.5.0", + "ethereumjs-tx": "^2.1.1", + "ethereumjs-util": "^5.0.0", + "merkle-patricia-tree": "^2.1.2" } }, - "node_modules/ganache-core/node_modules/deferred-leveldown/node_modules/abstract-leveldown": { - "version": "5.0.0", + "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/ethereumjs-vm/node_modules/ethereumjs-block/node_modules/ethereumjs-util": { + "version": "5.2.1", "dev": true, - "license": "MIT", + "license": "MPL-2.0", "dependencies": { - "xtend": "~4.0.0" - }, - "engines": { - "node": ">=6" + "bn.js": "^4.11.0", + "create-hash": "^1.1.2", + "elliptic": "^6.5.2", + "ethereum-cryptography": "^0.1.3", + "ethjs-util": "^0.1.3", + "rlp": "^2.0.0", + "safe-buffer": "^5.1.1" } }, - "node_modules/ganache-core/node_modules/define-properties": { - "version": "1.1.3", + "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/ethereumjs-vm/node_modules/ethereumjs-tx": { + "version": "2.1.2", "dev": true, - "license": "MIT", + "license": "MPL-2.0", "dependencies": { - "object-keys": "^1.0.12" - }, - "engines": { - "node": ">= 0.4" + "ethereumjs-common": "^1.5.0", + "ethereumjs-util": "^6.0.0" } }, - "node_modules/ganache-core/node_modules/define-property": { - "version": "2.0.2", + "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/ethereumjs-vm/node_modules/ethereumjs-util": { + "version": "6.2.1", "dev": true, - "license": "MIT", + "license": "MPL-2.0", "dependencies": { - "is-descriptor": "^1.0.2", - "isobject": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" + "@types/bn.js": "^4.11.3", + "bn.js": "^4.11.0", + "create-hash": "^1.1.2", + "elliptic": "^6.5.2", + "ethereum-cryptography": "^0.1.3", + "ethjs-util": "0.1.6", + "rlp": "^2.2.3" } }, - "node_modules/ganache-core/node_modules/defined": { - "version": "1.0.0", + "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/isarray": { + "version": "0.0.1", "dev": true, "license": "MIT" }, - "node_modules/ganache-core/node_modules/delayed-stream": { - "version": "1.0.0", + "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/level-codec": { + "version": "7.0.1", "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.4.0" - } + "license": "MIT" }, - "node_modules/ganache-core/node_modules/depd": { - "version": "1.1.2", + "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/level-errors": { + "version": "1.0.5", "dev": true, "license": "MIT", - "optional": true, - "engines": { - "node": ">= 0.6" + "dependencies": { + "errno": "~0.1.1" } }, - "node_modules/ganache-core/node_modules/des.js": { - "version": "1.0.1", + "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/level-iterator-stream": { + "version": "1.3.1", "dev": true, "license": "MIT", - "optional": true, "dependencies": { "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0" + "level-errors": "^1.0.3", + "readable-stream": "^1.0.33", + "xtend": "^4.0.0" } }, - "node_modules/ganache-core/node_modules/destroy": { - "version": "1.0.4", + "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/level-iterator-stream/node_modules/readable-stream": { + "version": "1.1.14", "dev": true, "license": "MIT", - "optional": true + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } }, - "node_modules/ganache-core/node_modules/detect-indent": { - "version": "4.0.0", + "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/level-ws": { + "version": "0.0.0", "dev": true, "license": "MIT", "dependencies": { - "repeating": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" + "readable-stream": "~1.0.15", + "xtend": "~2.1.1" } }, - "node_modules/ganache-core/node_modules/diffie-hellman": { - "version": "5.0.3", + "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/level-ws/node_modules/readable-stream": { + "version": "1.0.34", "dev": true, "license": "MIT", - "optional": true, "dependencies": { - "bn.js": "^4.1.0", - "miller-rabin": "^4.0.0", - "randombytes": "^2.0.0" + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" } }, - "node_modules/ganache-core/node_modules/dom-walk": { - "version": "0.1.2", - "dev": true - }, - "node_modules/ganache-core/node_modules/dotignore": { - "version": "0.1.2", + "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/level-ws/node_modules/xtend": { + "version": "2.1.2", "dev": true, - "license": "MIT", "dependencies": { - "minimatch": "^3.0.4" + "object-keys": "~0.4.0" }, - "bin": { - "ignored": "bin/ignored" + "engines": { + "node": ">=0.4" } }, - "node_modules/ganache-core/node_modules/duplexer3": { - "version": "0.1.4", - "dev": true, - "license": "BSD-3-Clause", - "optional": true - }, - "node_modules/ganache-core/node_modules/ecc-jsbn": { - "version": "0.1.2", + "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/levelup": { + "version": "1.3.9", "dev": true, "license": "MIT", "dependencies": { - "jsbn": "~0.1.0", - "safer-buffer": "^2.1.0" + "deferred-leveldown": "~1.2.1", + "level-codec": "~7.0.0", + "level-errors": "~1.0.3", + "level-iterator-stream": "~1.3.0", + "prr": "~1.0.1", + "semver": "~5.4.1", + "xtend": "~4.0.0" } }, - "node_modules/ganache-core/node_modules/ee-first": { - "version": "1.1.1", - "dev": true, - "license": "MIT", - "optional": true - }, - "node_modules/ganache-core/node_modules/electron-to-chromium": { - "version": "1.3.636", + "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/ltgt": { + "version": "2.2.1", "dev": true, - "license": "ISC" + "license": "MIT" }, - "node_modules/ganache-core/node_modules/elliptic": { - "version": "6.5.3", + "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/memdown": { + "version": "1.4.1", "dev": true, "license": "MIT", "dependencies": { - "bn.js": "^4.4.0", - "brorand": "^1.0.1", - "hash.js": "^1.0.0", - "hmac-drbg": "^1.0.0", - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0", - "minimalistic-crypto-utils": "^1.0.0" + "abstract-leveldown": "~2.7.1", + "functional-red-black-tree": "^1.0.1", + "immediate": "^3.2.3", + "inherits": "~2.0.1", + "ltgt": "~2.2.0", + "safe-buffer": "~5.1.1" } }, - "node_modules/ganache-core/node_modules/encodeurl": { - "version": "1.0.2", + "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/memdown/node_modules/abstract-leveldown": { + "version": "2.7.2", "dev": true, "license": "MIT", - "optional": true, - "engines": { - "node": ">= 0.8" + "dependencies": { + "xtend": "~4.0.0" } }, - "node_modules/ganache-core/node_modules/encoding": { - "version": "0.1.13", + "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/merkle-patricia-tree": { + "version": "2.3.2", "dev": true, - "license": "MIT", + "license": "MPL-2.0", "dependencies": { - "iconv-lite": "^0.6.2" + "async": "^1.4.2", + "ethereumjs-util": "^5.0.0", + "level-ws": "0.0.0", + "levelup": "^1.2.1", + "memdown": "^1.0.0", + "readable-stream": "^2.0.0", + "rlp": "^2.0.0", + "semaphore": ">=1.0.1" } }, - "node_modules/ganache-core/node_modules/encoding-down": { - "version": "5.0.4", + "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/merkle-patricia-tree/node_modules/async": { + "version": "1.5.2", "dev": true, - "license": "MIT", - "dependencies": { - "abstract-leveldown": "^5.0.0", - "inherits": "^2.0.3", - "level-codec": "^9.0.0", - "level-errors": "^2.0.0", - "xtend": "^4.0.1" - }, - "engines": { - "node": ">=6" - } + "license": "MIT" }, - "node_modules/ganache-core/node_modules/encoding-down/node_modules/abstract-leveldown": { - "version": "5.0.0", + "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/object-keys": { + "version": "0.4.0", "dev": true, - "license": "MIT", - "dependencies": { - "xtend": "~4.0.0" - }, - "engines": { - "node": ">=6" - } + "license": "MIT" }, - "node_modules/ganache-core/node_modules/encoding/node_modules/iconv-lite": { - "version": "0.6.2", + "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/safe-buffer": { + "version": "5.1.2", "dev": true, - "license": "MIT", - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3.0.0" - }, - "engines": { - "node": ">=0.10.0" + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/semver": { + "version": "5.4.1", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver" } }, - "node_modules/ganache-core/node_modules/end-of-stream": { - "version": "1.4.4", + "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/string_decoder": { + "version": "0.10.31", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/eth-lib": { + "version": "0.1.29", "dev": true, "license": "MIT", + "optional": true, "dependencies": { - "once": "^1.4.0" + "bn.js": "^4.11.6", + "elliptic": "^6.4.0", + "nano-json-stream-parser": "^0.1.2", + "servify": "^0.1.12", + "ws": "^3.0.0", + "xhr-request-promise": "^0.1.2" } }, - "node_modules/ganache-core/node_modules/errno": { - "version": "0.1.8", + "node_modules/ganache-core/node_modules/eth-query": { + "version": "2.1.2", "dev": true, - "license": "MIT", + "license": "ISC", "dependencies": { - "prr": "~1.0.1" - }, - "bin": { - "errno": "cli.js" + "json-rpc-random-id": "^1.0.0", + "xtend": "^4.0.1" } }, - "node_modules/ganache-core/node_modules/es-abstract": { - "version": "1.18.0-next.1", + "node_modules/ganache-core/node_modules/eth-sig-util": { + "version": "3.0.0", "dev": true, - "license": "MIT", + "license": "ISC", "dependencies": { - "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1", - "is-callable": "^1.2.2", - "is-negative-zero": "^2.0.0", - "is-regex": "^1.1.1", - "object-inspect": "^1.8.0", - "object-keys": "^1.1.1", - "object.assign": "^4.1.1", - "string.prototype.trimend": "^1.0.1", - "string.prototype.trimstart": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "buffer": "^5.2.1", + "elliptic": "^6.4.0", + "ethereumjs-abi": "0.6.5", + "ethereumjs-util": "^5.1.1", + "tweetnacl": "^1.0.0", + "tweetnacl-util": "^0.15.0" } }, - "node_modules/ganache-core/node_modules/es-to-primitive": { - "version": "1.2.1", + "node_modules/ganache-core/node_modules/eth-sig-util/node_modules/ethereumjs-abi": { + "version": "0.6.5", "dev": true, "license": "MIT", "dependencies": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "bn.js": "^4.10.0", + "ethereumjs-util": "^4.3.0" } }, - "node_modules/ganache-core/node_modules/es5-ext": { - "version": "0.10.53", + "node_modules/ganache-core/node_modules/eth-sig-util/node_modules/ethereumjs-abi/node_modules/ethereumjs-util": { + "version": "4.5.1", "dev": true, - "license": "ISC", + "license": "MPL-2.0", "dependencies": { - "es6-iterator": "~2.0.3", - "es6-symbol": "~3.1.3", - "next-tick": "~1.0.0" + "bn.js": "^4.8.0", + "create-hash": "^1.1.2", + "elliptic": "^6.5.2", + "ethereum-cryptography": "^0.1.3", + "rlp": "^2.0.0" } }, - "node_modules/ganache-core/node_modules/es6-iterator": { - "version": "2.0.3", + "node_modules/ganache-core/node_modules/eth-sig-util/node_modules/ethereumjs-util": { + "version": "5.2.1", "dev": true, - "license": "MIT", + "license": "MPL-2.0", "dependencies": { - "d": "1", - "es5-ext": "^0.10.35", - "es6-symbol": "^3.1.1" + "bn.js": "^4.11.0", + "create-hash": "^1.1.2", + "elliptic": "^6.5.2", + "ethereum-cryptography": "^0.1.3", + "ethjs-util": "^0.1.3", + "rlp": "^2.0.0", + "safe-buffer": "^5.1.1" } }, - "node_modules/ganache-core/node_modules/es6-symbol": { - "version": "3.1.3", + "node_modules/ganache-core/node_modules/eth-tx-summary": { + "version": "3.2.4", "dev": true, "license": "ISC", "dependencies": { - "d": "^1.0.1", - "ext": "^1.1.2" + "async": "^2.1.2", + "clone": "^2.0.0", + "concat-stream": "^1.5.1", + "end-of-stream": "^1.1.0", + "eth-query": "^2.0.2", + "ethereumjs-block": "^1.4.1", + "ethereumjs-tx": "^1.1.1", + "ethereumjs-util": "^5.0.1", + "ethereumjs-vm": "^2.6.0", + "through2": "^2.0.3" } }, - "node_modules/ganache-core/node_modules/escape-html": { - "version": "1.0.3", + "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/abstract-leveldown": { + "version": "2.6.3", "dev": true, "license": "MIT", - "optional": true + "dependencies": { + "xtend": "~4.0.0" + } }, - "node_modules/ganache-core/node_modules/escape-string-regexp": { - "version": "1.0.5", + "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/deferred-leveldown": { + "version": "1.2.2", "dev": true, "license": "MIT", - "engines": { - "node": ">=0.8.0" + "dependencies": { + "abstract-leveldown": "~2.6.0" } }, - "node_modules/ganache-core/node_modules/esutils": { - "version": "2.0.3", - "dev": true, - "license": "BSD-2-Clause", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ganache-core/node_modules/etag": { - "version": "1.8.1", - "dev": true, - "license": "MIT", - "optional": true, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/ganache-core/node_modules/eth-block-tracker": { - "version": "3.0.1", - "dev": true, - "license": "MIT", - "dependencies": { - "eth-query": "^2.1.0", - "ethereumjs-tx": "^1.3.3", - "ethereumjs-util": "^5.1.3", - "ethjs-util": "^0.1.3", - "json-rpc-engine": "^3.6.0", - "pify": "^2.3.0", - "tape": "^4.6.3" - } - }, - "node_modules/ganache-core/node_modules/eth-block-tracker/node_modules/ethereumjs-tx": { - "version": "1.3.7", - "dev": true, - "license": "MPL-2.0", - "dependencies": { - "ethereum-common": "^0.0.18", - "ethereumjs-util": "^5.0.0" - } - }, - "node_modules/ganache-core/node_modules/eth-block-tracker/node_modules/ethereumjs-util": { - "version": "5.2.1", - "dev": true, - "license": "MPL-2.0", - "dependencies": { - "bn.js": "^4.11.0", - "create-hash": "^1.1.2", - "elliptic": "^6.5.2", - "ethereum-cryptography": "^0.1.3", - "ethjs-util": "^0.1.3", - "rlp": "^2.0.0", - "safe-buffer": "^5.1.1" - } - }, - "node_modules/ganache-core/node_modules/eth-block-tracker/node_modules/pify": { - "version": "2.3.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ganache-core/node_modules/eth-ens-namehash": { - "version": "2.0.8", - "dev": true, - "license": "ISC", - "optional": true, - "dependencies": { - "idna-uts46-hx": "^2.3.1", - "js-sha3": "^0.5.7" - } - }, - "node_modules/ganache-core/node_modules/eth-json-rpc-infura": { - "version": "3.2.1", - "dev": true, - "license": "ISC", - "dependencies": { - "cross-fetch": "^2.1.1", - "eth-json-rpc-middleware": "^1.5.0", - "json-rpc-engine": "^3.4.0", - "json-rpc-error": "^2.0.0" - } - }, - "node_modules/ganache-core/node_modules/eth-json-rpc-middleware": { - "version": "1.6.0", - "dev": true, - "license": "ISC", - "dependencies": { - "async": "^2.5.0", - "eth-query": "^2.1.2", - "eth-tx-summary": "^3.1.2", - "ethereumjs-block": "^1.6.0", - "ethereumjs-tx": "^1.3.3", - "ethereumjs-util": "^5.1.2", - "ethereumjs-vm": "^2.1.0", - "fetch-ponyfill": "^4.0.0", - "json-rpc-engine": "^3.6.0", - "json-rpc-error": "^2.0.0", - "json-stable-stringify": "^1.0.1", - "promise-to-callback": "^1.0.0", - "tape": "^4.6.3" - } - }, - "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/abstract-leveldown": { - "version": "2.6.3", - "dev": true, - "license": "MIT", - "dependencies": { - "xtend": "~4.0.0" - } - }, - "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/deferred-leveldown": { - "version": "1.2.2", - "dev": true, - "license": "MIT", - "dependencies": { - "abstract-leveldown": "~2.6.0" - } - }, - "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/ethereumjs-account": { - "version": "2.0.5", + "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/ethereumjs-account": { + "version": "2.0.5", "dev": true, "license": "MPL-2.0", "dependencies": { @@ -10752,7 +10362,7 @@ "safe-buffer": "^5.1.1" } }, - "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/ethereumjs-block": { + "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/ethereumjs-block": { "version": "1.7.1", "dev": true, "license": "MPL-2.0", @@ -10764,12 +10374,12 @@ "merkle-patricia-tree": "^2.1.2" } }, - "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/ethereumjs-block/node_modules/ethereum-common": { + "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/ethereumjs-block/node_modules/ethereum-common": { "version": "0.2.0", "dev": true, "license": "MIT" }, - "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/ethereumjs-tx": { + "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/ethereumjs-tx": { "version": "1.3.7", "dev": true, "license": "MPL-2.0", @@ -10778,7 +10388,7 @@ "ethereumjs-util": "^5.0.0" } }, - "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/ethereumjs-util": { + "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/ethereumjs-util": { "version": "5.2.1", "dev": true, "license": "MPL-2.0", @@ -10792,7 +10402,7 @@ "safe-buffer": "^5.1.1" } }, - "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/ethereumjs-vm": { + "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/ethereumjs-vm": { "version": "2.6.0", "dev": true, "license": "MPL-2.0", @@ -10810,7 +10420,7 @@ "safe-buffer": "^5.1.1" } }, - "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/ethereumjs-vm/node_modules/ethereumjs-block": { + "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/ethereumjs-vm/node_modules/ethereumjs-block": { "version": "2.2.2", "dev": true, "license": "MPL-2.0", @@ -10822,7 +10432,7 @@ "merkle-patricia-tree": "^2.1.2" } }, - "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/ethereumjs-vm/node_modules/ethereumjs-block/node_modules/ethereumjs-util": { + "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/ethereumjs-vm/node_modules/ethereumjs-block/node_modules/ethereumjs-util": { "version": "5.2.1", "dev": true, "license": "MPL-2.0", @@ -10836,7 +10446,7 @@ "safe-buffer": "^5.1.1" } }, - "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/ethereumjs-vm/node_modules/ethereumjs-tx": { + "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/ethereumjs-vm/node_modules/ethereumjs-tx": { "version": "2.1.2", "dev": true, "license": "MPL-2.0", @@ -10845,7 +10455,7 @@ "ethereumjs-util": "^6.0.0" } }, - "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/ethereumjs-vm/node_modules/ethereumjs-util": { + "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/ethereumjs-vm/node_modules/ethereumjs-util": { "version": "6.2.1", "dev": true, "license": "MPL-2.0", @@ -10859,17 +10469,17 @@ "rlp": "^2.2.3" } }, - "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/isarray": { + "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/isarray": { "version": "0.0.1", "dev": true, "license": "MIT" }, - "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/level-codec": { + "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/level-codec": { "version": "7.0.1", "dev": true, "license": "MIT" }, - "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/level-errors": { + "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/level-errors": { "version": "1.0.5", "dev": true, "license": "MIT", @@ -10877,7 +10487,7 @@ "errno": "~0.1.1" } }, - "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/level-iterator-stream": { + "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/level-iterator-stream": { "version": "1.3.1", "dev": true, "license": "MIT", @@ -10888,7 +10498,7 @@ "xtend": "^4.0.0" } }, - "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/level-iterator-stream/node_modules/readable-stream": { + "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/level-iterator-stream/node_modules/readable-stream": { "version": "1.1.14", "dev": true, "license": "MIT", @@ -10899,7 +10509,7 @@ "string_decoder": "~0.10.x" } }, - "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/level-ws": { + "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/level-ws": { "version": "0.0.0", "dev": true, "license": "MIT", @@ -10908,7 +10518,7 @@ "xtend": "~2.1.1" } }, - "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/level-ws/node_modules/readable-stream": { + "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/level-ws/node_modules/readable-stream": { "version": "1.0.34", "dev": true, "license": "MIT", @@ -10919,7 +10529,7 @@ "string_decoder": "~0.10.x" } }, - "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/level-ws/node_modules/xtend": { + "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/level-ws/node_modules/xtend": { "version": "2.1.2", "dev": true, "dependencies": { @@ -10929,7 +10539,7 @@ "node": ">=0.4" } }, - "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/levelup": { + "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/levelup": { "version": "1.3.9", "dev": true, "license": "MIT", @@ -10943,12 +10553,12 @@ "xtend": "~4.0.0" } }, - "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/ltgt": { + "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/ltgt": { "version": "2.2.1", "dev": true, "license": "MIT" }, - "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/memdown": { + "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/memdown": { "version": "1.4.1", "dev": true, "license": "MIT", @@ -10961,7 +10571,7 @@ "safe-buffer": "~5.1.1" } }, - "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/memdown/node_modules/abstract-leveldown": { + "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/memdown/node_modules/abstract-leveldown": { "version": "2.7.2", "dev": true, "license": "MIT", @@ -10969,7 +10579,7 @@ "xtend": "~4.0.0" } }, - "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/merkle-patricia-tree": { + "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/merkle-patricia-tree": { "version": "2.3.2", "dev": true, "license": "MPL-2.0", @@ -10984,22 +10594,22 @@ "semaphore": ">=1.0.1" } }, - "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/merkle-patricia-tree/node_modules/async": { + "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/merkle-patricia-tree/node_modules/async": { "version": "1.5.2", "dev": true, "license": "MIT" }, - "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/object-keys": { + "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/object-keys": { "version": "0.4.0", "dev": true, "license": "MIT" }, - "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/safe-buffer": { + "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/safe-buffer": { "version": "5.1.2", "dev": true, "license": "MIT" }, - "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/semver": { + "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/semver": { "version": "5.4.1", "dev": true, "license": "ISC", @@ -11007,184 +10617,113 @@ "semver": "bin/semver" } }, - "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/string_decoder": { + "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/string_decoder": { "version": "0.10.31", "dev": true, "license": "MIT" }, - "node_modules/ganache-core/node_modules/eth-lib": { - "version": "0.1.29", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "bn.js": "^4.11.6", - "elliptic": "^6.4.0", - "nano-json-stream-parser": "^0.1.2", - "servify": "^0.1.12", - "ws": "^3.0.0", - "xhr-request-promise": "^0.1.2" - } - }, - "node_modules/ganache-core/node_modules/eth-query": { - "version": "2.1.2", + "node_modules/ganache-core/node_modules/ethashjs": { + "version": "0.0.8", "dev": true, - "license": "ISC", + "license": "MPL-2.0", "dependencies": { - "json-rpc-random-id": "^1.0.0", - "xtend": "^4.0.1" + "async": "^2.1.2", + "buffer-xor": "^2.0.1", + "ethereumjs-util": "^7.0.2", + "miller-rabin": "^4.0.0" } }, - "node_modules/ganache-core/node_modules/eth-sig-util": { - "version": "3.0.0", + "node_modules/ganache-core/node_modules/ethashjs/node_modules/bn.js": { + "version": "5.1.3", "dev": true, - "license": "ISC", - "dependencies": { - "buffer": "^5.2.1", - "elliptic": "^6.4.0", - "ethereumjs-abi": "0.6.5", - "ethereumjs-util": "^5.1.1", - "tweetnacl": "^1.0.0", - "tweetnacl-util": "^0.15.0" - } + "license": "MIT" }, - "node_modules/ganache-core/node_modules/eth-sig-util/node_modules/ethereumjs-abi": { - "version": "0.6.5", + "node_modules/ganache-core/node_modules/ethashjs/node_modules/buffer-xor": { + "version": "2.0.2", "dev": true, "license": "MIT", "dependencies": { - "bn.js": "^4.10.0", - "ethereumjs-util": "^4.3.0" + "safe-buffer": "^5.1.1" } }, - "node_modules/ganache-core/node_modules/eth-sig-util/node_modules/ethereumjs-abi/node_modules/ethereumjs-util": { - "version": "4.5.1", + "node_modules/ganache-core/node_modules/ethashjs/node_modules/ethereumjs-util": { + "version": "7.0.7", "dev": true, "license": "MPL-2.0", "dependencies": { - "bn.js": "^4.8.0", + "@types/bn.js": "^4.11.3", + "bn.js": "^5.1.2", "create-hash": "^1.1.2", - "elliptic": "^6.5.2", "ethereum-cryptography": "^0.1.3", - "rlp": "^2.0.0" + "ethjs-util": "0.1.6", + "rlp": "^2.2.4" + }, + "engines": { + "node": ">=10.0.0" } }, - "node_modules/ganache-core/node_modules/eth-sig-util/node_modules/ethereumjs-util": { - "version": "5.2.1", + "node_modules/ganache-core/node_modules/ethereum-bloom-filters": { + "version": "1.0.7", "dev": true, - "license": "MPL-2.0", + "license": "MIT", + "optional": true, "dependencies": { - "bn.js": "^4.11.0", - "create-hash": "^1.1.2", - "elliptic": "^6.5.2", - "ethereum-cryptography": "^0.1.3", - "ethjs-util": "^0.1.3", - "rlp": "^2.0.0", - "safe-buffer": "^5.1.1" + "js-sha3": "^0.8.0" } }, - "node_modules/ganache-core/node_modules/eth-tx-summary": { - "version": "3.2.4", - "dev": true, - "license": "ISC", - "dependencies": { - "async": "^2.1.2", - "clone": "^2.0.0", - "concat-stream": "^1.5.1", - "end-of-stream": "^1.1.0", - "eth-query": "^2.0.2", - "ethereumjs-block": "^1.4.1", - "ethereumjs-tx": "^1.1.1", - "ethereumjs-util": "^5.0.1", - "ethereumjs-vm": "^2.6.0", - "through2": "^2.0.3" - } - }, - "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/abstract-leveldown": { - "version": "2.6.3", - "dev": true, - "license": "MIT", - "dependencies": { - "xtend": "~4.0.0" - } - }, - "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/deferred-leveldown": { - "version": "1.2.2", + "node_modules/ganache-core/node_modules/ethereum-bloom-filters/node_modules/js-sha3": { + "version": "0.8.0", "dev": true, "license": "MIT", - "dependencies": { - "abstract-leveldown": "~2.6.0" - } - }, - "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/ethereumjs-account": { - "version": "2.0.5", - "dev": true, - "license": "MPL-2.0", - "dependencies": { - "ethereumjs-util": "^5.0.0", - "rlp": "^2.0.0", - "safe-buffer": "^5.1.1" - } - }, - "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/ethereumjs-block": { - "version": "1.7.1", - "dev": true, - "license": "MPL-2.0", - "dependencies": { - "async": "^2.0.1", - "ethereum-common": "0.2.0", - "ethereumjs-tx": "^1.2.2", - "ethereumjs-util": "^5.0.0", - "merkle-patricia-tree": "^2.1.2" - } + "optional": true }, - "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/ethereumjs-block/node_modules/ethereum-common": { - "version": "0.2.0", + "node_modules/ganache-core/node_modules/ethereum-common": { + "version": "0.0.18", "dev": true, "license": "MIT" }, - "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/ethereumjs-tx": { - "version": "1.3.7", + "node_modules/ganache-core/node_modules/ethereum-cryptography": { + "version": "0.1.3", "dev": true, - "license": "MPL-2.0", + "license": "MIT", "dependencies": { - "ethereum-common": "^0.0.18", - "ethereumjs-util": "^5.0.0" + "@types/pbkdf2": "^3.0.0", + "@types/secp256k1": "^4.0.1", + "blakejs": "^1.1.0", + "browserify-aes": "^1.2.0", + "bs58check": "^2.1.2", + "create-hash": "^1.2.0", + "create-hmac": "^1.1.7", + "hash.js": "^1.1.7", + "keccak": "^3.0.0", + "pbkdf2": "^3.0.17", + "randombytes": "^2.1.0", + "safe-buffer": "^5.1.2", + "scrypt-js": "^3.0.0", + "secp256k1": "^4.0.1", + "setimmediate": "^1.0.5" } }, - "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/ethereumjs-util": { - "version": "5.2.1", + "node_modules/ganache-core/node_modules/ethereumjs-abi": { + "version": "0.6.8", "dev": true, - "license": "MPL-2.0", + "license": "MIT", "dependencies": { - "bn.js": "^4.11.0", - "create-hash": "^1.1.2", - "elliptic": "^6.5.2", - "ethereum-cryptography": "^0.1.3", - "ethjs-util": "^0.1.3", - "rlp": "^2.0.0", - "safe-buffer": "^5.1.1" + "bn.js": "^4.11.8", + "ethereumjs-util": "^6.0.0" } }, - "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/ethereumjs-vm": { - "version": "2.6.0", + "node_modules/ganache-core/node_modules/ethereumjs-account": { + "version": "3.0.0", "dev": true, "license": "MPL-2.0", "dependencies": { - "async": "^2.1.2", - "async-eventemitter": "^0.2.2", - "ethereumjs-account": "^2.0.3", - "ethereumjs-block": "~2.2.0", - "ethereumjs-common": "^1.1.0", "ethereumjs-util": "^6.0.0", - "fake-merkle-patricia-tree": "^1.0.1", - "functional-red-black-tree": "^1.0.1", - "merkle-patricia-tree": "^2.3.2", - "rustbn.js": "~0.2.0", + "rlp": "^2.2.1", "safe-buffer": "^5.1.1" } }, - "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/ethereumjs-vm/node_modules/ethereumjs-block": { + "node_modules/ganache-core/node_modules/ethereumjs-block": { "version": "2.2.2", "dev": true, "license": "MPL-2.0", @@ -11196,54 +10735,47 @@ "merkle-patricia-tree": "^2.1.2" } }, - "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/ethereumjs-vm/node_modules/ethereumjs-block/node_modules/ethereumjs-util": { - "version": "5.2.1", + "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/abstract-leveldown": { + "version": "2.6.3", "dev": true, - "license": "MPL-2.0", + "license": "MIT", "dependencies": { - "bn.js": "^4.11.0", - "create-hash": "^1.1.2", - "elliptic": "^6.5.2", - "ethereum-cryptography": "^0.1.3", - "ethjs-util": "^0.1.3", - "rlp": "^2.0.0", - "safe-buffer": "^5.1.1" + "xtend": "~4.0.0" } }, - "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/ethereumjs-vm/node_modules/ethereumjs-tx": { - "version": "2.1.2", + "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/deferred-leveldown": { + "version": "1.2.2", "dev": true, - "license": "MPL-2.0", + "license": "MIT", "dependencies": { - "ethereumjs-common": "^1.5.0", - "ethereumjs-util": "^6.0.0" + "abstract-leveldown": "~2.6.0" } }, - "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/ethereumjs-vm/node_modules/ethereumjs-util": { - "version": "6.2.1", + "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/ethereumjs-util": { + "version": "5.2.1", "dev": true, "license": "MPL-2.0", "dependencies": { - "@types/bn.js": "^4.11.3", "bn.js": "^4.11.0", "create-hash": "^1.1.2", "elliptic": "^6.5.2", "ethereum-cryptography": "^0.1.3", - "ethjs-util": "0.1.6", - "rlp": "^2.2.3" + "ethjs-util": "^0.1.3", + "rlp": "^2.0.0", + "safe-buffer": "^5.1.1" } }, - "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/isarray": { + "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/isarray": { "version": "0.0.1", "dev": true, "license": "MIT" }, - "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/level-codec": { + "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/level-codec": { "version": "7.0.1", "dev": true, "license": "MIT" }, - "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/level-errors": { + "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/level-errors": { "version": "1.0.5", "dev": true, "license": "MIT", @@ -11251,7 +10783,7 @@ "errno": "~0.1.1" } }, - "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/level-iterator-stream": { + "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/level-iterator-stream": { "version": "1.3.1", "dev": true, "license": "MIT", @@ -11262,7 +10794,7 @@ "xtend": "^4.0.0" } }, - "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/level-iterator-stream/node_modules/readable-stream": { + "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/level-iterator-stream/node_modules/readable-stream": { "version": "1.1.14", "dev": true, "license": "MIT", @@ -11273,7 +10805,7 @@ "string_decoder": "~0.10.x" } }, - "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/level-ws": { + "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/level-ws": { "version": "0.0.0", "dev": true, "license": "MIT", @@ -11282,7 +10814,7 @@ "xtend": "~2.1.1" } }, - "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/level-ws/node_modules/readable-stream": { + "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/level-ws/node_modules/readable-stream": { "version": "1.0.34", "dev": true, "license": "MIT", @@ -11293,7 +10825,7 @@ "string_decoder": "~0.10.x" } }, - "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/level-ws/node_modules/xtend": { + "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/level-ws/node_modules/xtend": { "version": "2.1.2", "dev": true, "dependencies": { @@ -11303,7 +10835,7 @@ "node": ">=0.4" } }, - "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/levelup": { + "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/levelup": { "version": "1.3.9", "dev": true, "license": "MIT", @@ -11317,12 +10849,12 @@ "xtend": "~4.0.0" } }, - "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/ltgt": { + "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/ltgt": { "version": "2.2.1", "dev": true, "license": "MIT" }, - "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/memdown": { + "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/memdown": { "version": "1.4.1", "dev": true, "license": "MIT", @@ -11335,7 +10867,7 @@ "safe-buffer": "~5.1.1" } }, - "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/memdown/node_modules/abstract-leveldown": { + "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/memdown/node_modules/abstract-leveldown": { "version": "2.7.2", "dev": true, "license": "MIT", @@ -11343,7 +10875,7 @@ "xtend": "~4.0.0" } }, - "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/merkle-patricia-tree": { + "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/merkle-patricia-tree": { "version": "2.3.2", "dev": true, "license": "MPL-2.0", @@ -11358,22 +10890,22 @@ "semaphore": ">=1.0.1" } }, - "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/merkle-patricia-tree/node_modules/async": { + "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/merkle-patricia-tree/node_modules/async": { "version": "1.5.2", "dev": true, "license": "MIT" }, - "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/object-keys": { + "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/object-keys": { "version": "0.4.0", "dev": true, "license": "MIT" }, - "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/safe-buffer": { + "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/safe-buffer": { "version": "5.1.2", "dev": true, "license": "MIT" }, - "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/semver": { + "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/semver": { "version": "5.4.1", "dev": true, "license": "ISC", @@ -11381,165 +10913,105 @@ "semver": "bin/semver" } }, - "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/string_decoder": { + "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/string_decoder": { "version": "0.10.31", "dev": true, "license": "MIT" }, - "node_modules/ganache-core/node_modules/ethashjs": { - "version": "0.0.8", + "node_modules/ganache-core/node_modules/ethereumjs-blockchain": { + "version": "4.0.4", "dev": true, "license": "MPL-2.0", "dependencies": { - "async": "^2.1.2", - "buffer-xor": "^2.0.1", - "ethereumjs-util": "^7.0.2", - "miller-rabin": "^4.0.0" + "async": "^2.6.1", + "ethashjs": "~0.0.7", + "ethereumjs-block": "~2.2.2", + "ethereumjs-common": "^1.5.0", + "ethereumjs-util": "^6.1.0", + "flow-stoplight": "^1.0.0", + "level-mem": "^3.0.1", + "lru-cache": "^5.1.1", + "rlp": "^2.2.2", + "semaphore": "^1.1.0" } }, - "node_modules/ganache-core/node_modules/ethashjs/node_modules/bn.js": { - "version": "5.1.3", + "node_modules/ganache-core/node_modules/ethereumjs-common": { + "version": "1.5.0", "dev": true, "license": "MIT" }, - "node_modules/ganache-core/node_modules/ethashjs/node_modules/buffer-xor": { - "version": "2.0.2", + "node_modules/ganache-core/node_modules/ethereumjs-tx": { + "version": "2.1.2", "dev": true, - "license": "MIT", + "license": "MPL-2.0", "dependencies": { - "safe-buffer": "^5.1.1" + "ethereumjs-common": "^1.5.0", + "ethereumjs-util": "^6.0.0" } }, - "node_modules/ganache-core/node_modules/ethashjs/node_modules/ethereumjs-util": { - "version": "7.0.7", + "node_modules/ganache-core/node_modules/ethereumjs-util": { + "version": "6.2.1", "dev": true, "license": "MPL-2.0", "dependencies": { "@types/bn.js": "^4.11.3", - "bn.js": "^5.1.2", + "bn.js": "^4.11.0", "create-hash": "^1.1.2", + "elliptic": "^6.5.2", "ethereum-cryptography": "^0.1.3", "ethjs-util": "0.1.6", - "rlp": "^2.2.4" - }, - "engines": { - "node": ">=10.0.0" + "rlp": "^2.2.3" } }, - "node_modules/ganache-core/node_modules/ethereum-bloom-filters": { - "version": "1.0.7", + "node_modules/ganache-core/node_modules/ethereumjs-vm": { + "version": "4.2.0", "dev": true, - "license": "MIT", - "optional": true, + "license": "MPL-2.0", "dependencies": { - "js-sha3": "^0.8.0" + "async": "^2.1.2", + "async-eventemitter": "^0.2.2", + "core-js-pure": "^3.0.1", + "ethereumjs-account": "^3.0.0", + "ethereumjs-block": "^2.2.2", + "ethereumjs-blockchain": "^4.0.3", + "ethereumjs-common": "^1.5.0", + "ethereumjs-tx": "^2.1.2", + "ethereumjs-util": "^6.2.0", + "fake-merkle-patricia-tree": "^1.0.1", + "functional-red-black-tree": "^1.0.1", + "merkle-patricia-tree": "^2.3.2", + "rustbn.js": "~0.2.0", + "safe-buffer": "^5.1.1", + "util.promisify": "^1.0.0" } }, - "node_modules/ganache-core/node_modules/ethereum-bloom-filters/node_modules/js-sha3": { - "version": "0.8.0", + "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/abstract-leveldown": { + "version": "2.6.3", "dev": true, "license": "MIT", - "optional": true + "dependencies": { + "xtend": "~4.0.0" + } }, - "node_modules/ganache-core/node_modules/ethereum-common": { - "version": "0.0.18", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/ethereum-cryptography": { - "version": "0.1.3", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/pbkdf2": "^3.0.0", - "@types/secp256k1": "^4.0.1", - "blakejs": "^1.1.0", - "browserify-aes": "^1.2.0", - "bs58check": "^2.1.2", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "hash.js": "^1.1.7", - "keccak": "^3.0.0", - "pbkdf2": "^3.0.17", - "randombytes": "^2.1.0", - "safe-buffer": "^5.1.2", - "scrypt-js": "^3.0.0", - "secp256k1": "^4.0.1", - "setimmediate": "^1.0.5" - } - }, - "node_modules/ganache-core/node_modules/ethereumjs-abi": { - "version": "0.6.8", - "dev": true, - "license": "MIT", - "dependencies": { - "bn.js": "^4.11.8", - "ethereumjs-util": "^6.0.0" - } - }, - "node_modules/ganache-core/node_modules/ethereumjs-account": { - "version": "3.0.0", - "dev": true, - "license": "MPL-2.0", - "dependencies": { - "ethereumjs-util": "^6.0.0", - "rlp": "^2.2.1", - "safe-buffer": "^5.1.1" - } - }, - "node_modules/ganache-core/node_modules/ethereumjs-block": { - "version": "2.2.2", - "dev": true, - "license": "MPL-2.0", - "dependencies": { - "async": "^2.0.1", - "ethereumjs-common": "^1.5.0", - "ethereumjs-tx": "^2.1.1", - "ethereumjs-util": "^5.0.0", - "merkle-patricia-tree": "^2.1.2" - } - }, - "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/abstract-leveldown": { - "version": "2.6.3", - "dev": true, - "license": "MIT", - "dependencies": { - "xtend": "~4.0.0" - } - }, - "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/deferred-leveldown": { - "version": "1.2.2", + "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/deferred-leveldown": { + "version": "1.2.2", "dev": true, "license": "MIT", "dependencies": { "abstract-leveldown": "~2.6.0" } }, - "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/ethereumjs-util": { - "version": "5.2.1", - "dev": true, - "license": "MPL-2.0", - "dependencies": { - "bn.js": "^4.11.0", - "create-hash": "^1.1.2", - "elliptic": "^6.5.2", - "ethereum-cryptography": "^0.1.3", - "ethjs-util": "^0.1.3", - "rlp": "^2.0.0", - "safe-buffer": "^5.1.1" - } - }, - "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/isarray": { + "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/isarray": { "version": "0.0.1", "dev": true, "license": "MIT" }, - "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/level-codec": { + "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/level-codec": { "version": "7.0.1", "dev": true, "license": "MIT" }, - "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/level-errors": { + "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/level-errors": { "version": "1.0.5", "dev": true, "license": "MIT", @@ -11547,7 +11019,7 @@ "errno": "~0.1.1" } }, - "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/level-iterator-stream": { + "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/level-iterator-stream": { "version": "1.3.1", "dev": true, "license": "MIT", @@ -11558,7 +11030,7 @@ "xtend": "^4.0.0" } }, - "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/level-iterator-stream/node_modules/readable-stream": { + "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/level-iterator-stream/node_modules/readable-stream": { "version": "1.1.14", "dev": true, "license": "MIT", @@ -11569,7 +11041,7 @@ "string_decoder": "~0.10.x" } }, - "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/level-ws": { + "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/level-ws": { "version": "0.0.0", "dev": true, "license": "MIT", @@ -11578,7 +11050,7 @@ "xtend": "~2.1.1" } }, - "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/level-ws/node_modules/readable-stream": { + "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/level-ws/node_modules/readable-stream": { "version": "1.0.34", "dev": true, "license": "MIT", @@ -11589,7 +11061,7 @@ "string_decoder": "~0.10.x" } }, - "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/level-ws/node_modules/xtend": { + "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/level-ws/node_modules/xtend": { "version": "2.1.2", "dev": true, "dependencies": { @@ -11599,7 +11071,7 @@ "node": ">=0.4" } }, - "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/levelup": { + "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/levelup": { "version": "1.3.9", "dev": true, "license": "MIT", @@ -11613,12 +11085,12 @@ "xtend": "~4.0.0" } }, - "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/ltgt": { + "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/ltgt": { "version": "2.2.1", "dev": true, "license": "MIT" }, - "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/memdown": { + "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/memdown": { "version": "1.4.1", "dev": true, "license": "MIT", @@ -11631,7 +11103,7 @@ "safe-buffer": "~5.1.1" } }, - "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/memdown/node_modules/abstract-leveldown": { + "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/memdown/node_modules/abstract-leveldown": { "version": "2.7.2", "dev": true, "license": "MIT", @@ -11639,7 +11111,7 @@ "xtend": "~4.0.0" } }, - "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/merkle-patricia-tree": { + "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/merkle-patricia-tree": { "version": "2.3.2", "dev": true, "license": "MPL-2.0", @@ -11654,22 +11126,36 @@ "semaphore": ">=1.0.1" } }, - "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/merkle-patricia-tree/node_modules/async": { + "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/merkle-patricia-tree/node_modules/async": { "version": "1.5.2", "dev": true, "license": "MIT" }, - "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/object-keys": { + "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/merkle-patricia-tree/node_modules/ethereumjs-util": { + "version": "5.2.1", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "bn.js": "^4.11.0", + "create-hash": "^1.1.2", + "elliptic": "^6.5.2", + "ethereum-cryptography": "^0.1.3", + "ethjs-util": "^0.1.3", + "rlp": "^2.0.0", + "safe-buffer": "^5.1.1" + } + }, + "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/object-keys": { "version": "0.4.0", "dev": true, "license": "MIT" }, - "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/safe-buffer": { + "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/safe-buffer": { "version": "5.1.2", "dev": true, "license": "MIT" }, - "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/semver": { + "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/semver": { "version": "5.4.1", "dev": true, "license": "ISC", @@ -11677,336 +11163,86 @@ "semver": "bin/semver" } }, - "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/string_decoder": { + "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/string_decoder": { "version": "0.10.31", "dev": true, "license": "MIT" }, - "node_modules/ganache-core/node_modules/ethereumjs-blockchain": { - "version": "4.0.4", - "dev": true, - "license": "MPL-2.0", - "dependencies": { - "async": "^2.6.1", - "ethashjs": "~0.0.7", - "ethereumjs-block": "~2.2.2", - "ethereumjs-common": "^1.5.0", - "ethereumjs-util": "^6.1.0", - "flow-stoplight": "^1.0.0", - "level-mem": "^3.0.1", - "lru-cache": "^5.1.1", - "rlp": "^2.2.2", - "semaphore": "^1.1.0" - } - }, - "node_modules/ganache-core/node_modules/ethereumjs-common": { - "version": "1.5.0", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/ethereumjs-tx": { - "version": "2.1.2", - "dev": true, - "license": "MPL-2.0", - "dependencies": { - "ethereumjs-common": "^1.5.0", - "ethereumjs-util": "^6.0.0" - } - }, - "node_modules/ganache-core/node_modules/ethereumjs-util": { - "version": "6.2.1", + "node_modules/ganache-core/node_modules/ethereumjs-wallet": { + "version": "0.6.5", "dev": true, - "license": "MPL-2.0", + "license": "MIT", + "optional": true, "dependencies": { - "@types/bn.js": "^4.11.3", - "bn.js": "^4.11.0", - "create-hash": "^1.1.2", - "elliptic": "^6.5.2", + "aes-js": "^3.1.1", + "bs58check": "^2.1.2", "ethereum-cryptography": "^0.1.3", - "ethjs-util": "0.1.6", - "rlp": "^2.2.3" + "ethereumjs-util": "^6.0.0", + "randombytes": "^2.0.6", + "safe-buffer": "^5.1.2", + "scryptsy": "^1.2.1", + "utf8": "^3.0.0", + "uuid": "^3.3.2" } }, - "node_modules/ganache-core/node_modules/ethereumjs-vm": { - "version": "4.2.0", + "node_modules/ganache-core/node_modules/ethjs-unit": { + "version": "0.1.6", "dev": true, - "license": "MPL-2.0", + "license": "MIT", + "optional": true, "dependencies": { - "async": "^2.1.2", - "async-eventemitter": "^0.2.2", - "core-js-pure": "^3.0.1", - "ethereumjs-account": "^3.0.0", - "ethereumjs-block": "^2.2.2", - "ethereumjs-blockchain": "^4.0.3", - "ethereumjs-common": "^1.5.0", - "ethereumjs-tx": "^2.1.2", - "ethereumjs-util": "^6.2.0", - "fake-merkle-patricia-tree": "^1.0.1", - "functional-red-black-tree": "^1.0.1", - "merkle-patricia-tree": "^2.3.2", - "rustbn.js": "~0.2.0", - "safe-buffer": "^5.1.1", - "util.promisify": "^1.0.0" + "bn.js": "4.11.6", + "number-to-bn": "1.7.0" + }, + "engines": { + "node": ">=6.5.0", + "npm": ">=3" } }, - "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/abstract-leveldown": { - "version": "2.6.3", + "node_modules/ganache-core/node_modules/ethjs-unit/node_modules/bn.js": { + "version": "4.11.6", "dev": true, "license": "MIT", - "dependencies": { - "xtend": "~4.0.0" - } + "optional": true }, - "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/deferred-leveldown": { - "version": "1.2.2", + "node_modules/ganache-core/node_modules/ethjs-util": { + "version": "0.1.6", "dev": true, "license": "MIT", "dependencies": { - "abstract-leveldown": "~2.6.0" + "is-hex-prefixed": "1.0.0", + "strip-hex-prefix": "1.0.0" + }, + "engines": { + "node": ">=6.5.0", + "npm": ">=3" } }, - "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/isarray": { - "version": "0.0.1", + "node_modules/ganache-core/node_modules/eventemitter3": { + "version": "4.0.4", "dev": true, - "license": "MIT" + "license": "MIT", + "optional": true }, - "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/level-codec": { - "version": "7.0.1", + "node_modules/ganache-core/node_modules/events": { + "version": "3.2.0", "dev": true, - "license": "MIT" + "license": "MIT", + "engines": { + "node": ">=0.8.x" + } }, - "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/level-errors": { - "version": "1.0.5", + "node_modules/ganache-core/node_modules/evp_bytestokey": { + "version": "1.0.3", "dev": true, "license": "MIT", "dependencies": { - "errno": "~0.1.1" + "md5.js": "^1.3.4", + "safe-buffer": "^5.1.1" } }, - "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/level-iterator-stream": { - "version": "1.3.1", - "dev": true, - "license": "MIT", - "dependencies": { - "inherits": "^2.0.1", - "level-errors": "^1.0.3", - "readable-stream": "^1.0.33", - "xtend": "^4.0.0" - } - }, - "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/level-iterator-stream/node_modules/readable-stream": { - "version": "1.1.14", - "dev": true, - "license": "MIT", - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "0.0.1", - "string_decoder": "~0.10.x" - } - }, - "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/level-ws": { - "version": "0.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "readable-stream": "~1.0.15", - "xtend": "~2.1.1" - } - }, - "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/level-ws/node_modules/readable-stream": { - "version": "1.0.34", - "dev": true, - "license": "MIT", - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "0.0.1", - "string_decoder": "~0.10.x" - } - }, - "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/level-ws/node_modules/xtend": { - "version": "2.1.2", - "dev": true, - "dependencies": { - "object-keys": "~0.4.0" - }, - "engines": { - "node": ">=0.4" - } - }, - "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/levelup": { - "version": "1.3.9", - "dev": true, - "license": "MIT", - "dependencies": { - "deferred-leveldown": "~1.2.1", - "level-codec": "~7.0.0", - "level-errors": "~1.0.3", - "level-iterator-stream": "~1.3.0", - "prr": "~1.0.1", - "semver": "~5.4.1", - "xtend": "~4.0.0" - } - }, - "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/ltgt": { - "version": "2.2.1", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/memdown": { - "version": "1.4.1", - "dev": true, - "license": "MIT", - "dependencies": { - "abstract-leveldown": "~2.7.1", - "functional-red-black-tree": "^1.0.1", - "immediate": "^3.2.3", - "inherits": "~2.0.1", - "ltgt": "~2.2.0", - "safe-buffer": "~5.1.1" - } - }, - "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/memdown/node_modules/abstract-leveldown": { - "version": "2.7.2", - "dev": true, - "license": "MIT", - "dependencies": { - "xtend": "~4.0.0" - } - }, - "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/merkle-patricia-tree": { - "version": "2.3.2", - "dev": true, - "license": "MPL-2.0", - "dependencies": { - "async": "^1.4.2", - "ethereumjs-util": "^5.0.0", - "level-ws": "0.0.0", - "levelup": "^1.2.1", - "memdown": "^1.0.0", - "readable-stream": "^2.0.0", - "rlp": "^2.0.0", - "semaphore": ">=1.0.1" - } - }, - "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/merkle-patricia-tree/node_modules/async": { - "version": "1.5.2", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/merkle-patricia-tree/node_modules/ethereumjs-util": { - "version": "5.2.1", - "dev": true, - "license": "MPL-2.0", - "dependencies": { - "bn.js": "^4.11.0", - "create-hash": "^1.1.2", - "elliptic": "^6.5.2", - "ethereum-cryptography": "^0.1.3", - "ethjs-util": "^0.1.3", - "rlp": "^2.0.0", - "safe-buffer": "^5.1.1" - } - }, - "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/object-keys": { - "version": "0.4.0", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/safe-buffer": { - "version": "5.1.2", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/semver": { - "version": "5.4.1", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver" - } - }, - "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/string_decoder": { - "version": "0.10.31", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/ethereumjs-wallet": { - "version": "0.6.5", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "aes-js": "^3.1.1", - "bs58check": "^2.1.2", - "ethereum-cryptography": "^0.1.3", - "ethereumjs-util": "^6.0.0", - "randombytes": "^2.0.6", - "safe-buffer": "^5.1.2", - "scryptsy": "^1.2.1", - "utf8": "^3.0.0", - "uuid": "^3.3.2" - } - }, - "node_modules/ganache-core/node_modules/ethjs-unit": { - "version": "0.1.6", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "bn.js": "4.11.6", - "number-to-bn": "1.7.0" - }, - "engines": { - "node": ">=6.5.0", - "npm": ">=3" - } - }, - "node_modules/ganache-core/node_modules/ethjs-unit/node_modules/bn.js": { - "version": "4.11.6", - "dev": true, - "license": "MIT", - "optional": true - }, - "node_modules/ganache-core/node_modules/ethjs-util": { - "version": "0.1.6", - "dev": true, - "license": "MIT", - "dependencies": { - "is-hex-prefixed": "1.0.0", - "strip-hex-prefix": "1.0.0" - }, - "engines": { - "node": ">=6.5.0", - "npm": ">=3" - } - }, - "node_modules/ganache-core/node_modules/eventemitter3": { - "version": "4.0.4", - "dev": true, - "license": "MIT", - "optional": true - }, - "node_modules/ganache-core/node_modules/events": { - "version": "3.2.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.8.x" - } - }, - "node_modules/ganache-core/node_modules/evp_bytestokey": { - "version": "1.0.3", - "dev": true, - "license": "MIT", - "dependencies": { - "md5.js": "^1.3.4", - "safe-buffer": "^5.1.1" - } - }, - "node_modules/ganache-core/node_modules/expand-brackets": { - "version": "2.1.4", + "node_modules/ganache-core/node_modules/expand-brackets": { + "version": "2.1.4", "dev": true, "license": "MIT", "dependencies": { @@ -17168,15 +16404,19 @@ } }, "node_modules/get-intrinsic": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.1.tgz", - "integrity": "sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw==", + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", + "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", "dev": true, "dependencies": { - "function-bind": "^1.1.1", - "has": "^1.0.3", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", "has-proto": "^1.0.1", - "has-symbols": "^1.0.3" + "has-symbols": "^1.0.3", + "hasown": "^2.0.0" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -17204,13 +16444,14 @@ } }, "node_modules/get-symbol-description": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz", - "integrity": "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.2.tgz", + "integrity": "sha512-g0QYk1dZBxGwk+Ngc+ltRH2IBp2f7zBkBMBJZCDerh6EhlhSR6+9irMCuT/09zD6qkarHUSn529sK/yL4S27mg==", "dev": true, "dependencies": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.1.1" + "call-bind": "^1.0.5", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.4" }, "engines": { "node": ">= 0.4" @@ -17393,9 +16634,9 @@ } }, "node_modules/globals": { - "version": "13.20.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.20.0.tgz", - "integrity": "sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ==", + "version": "13.24.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", + "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", "dev": true, "dependencies": { "type-fest": "^0.20.2" @@ -17482,23 +16723,14 @@ "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", "dev": true }, - "node_modules/growl": { - "version": "1.10.5", - "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", - "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", - "dev": true, - "engines": { - "node": ">=4.x" - } - }, "node_modules/handlebars": { - "version": "4.7.7", - "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.7.tgz", - "integrity": "sha512-aAcXm5OAfE/8IXkcZvCepKU3VzW1/39Fb5ZuqMtgI/hT8X2YgoMvBY5dLhq/cpOvw7Lk1nK/UF71aLG/ZnVYRA==", + "version": "4.7.8", + "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.8.tgz", + "integrity": "sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ==", "dev": true, "dependencies": { "minimist": "^1.2.5", - "neo-async": "^2.6.0", + "neo-async": "^2.6.2", "source-map": "^0.6.1", "wordwrap": "^1.0.0" }, @@ -17545,31 +16777,25 @@ } }, "node_modules/hardhat": { - "version": "2.17.0", - "resolved": "https://registry.npmjs.org/hardhat/-/hardhat-2.17.0.tgz", - "integrity": "sha512-CaEGa13tkJNe2/rdaBiive4pmdNShwxvdWVhr1zfb6aVpRhQt9VNO0l/UIBt/zzajz38ZFjvhfM2bj8LDXo9gw==", + "version": "2.22.3", + "resolved": "https://registry.npmjs.org/hardhat/-/hardhat-2.22.3.tgz", + "integrity": "sha512-k8JV2ECWNchD6ahkg2BR5wKVxY0OiKot7fuxiIpRK0frRqyOljcR2vKwgWSLw6YIeDcNNA4xybj7Og7NSxr2hA==", "dev": true, "dependencies": { "@ethersproject/abi": "^5.1.2", "@metamask/eth-sig-util": "^4.0.0", - "@nomicfoundation/ethereumjs-block": "5.0.1", - "@nomicfoundation/ethereumjs-blockchain": "7.0.1", - "@nomicfoundation/ethereumjs-common": "4.0.1", - "@nomicfoundation/ethereumjs-evm": "2.0.1", - "@nomicfoundation/ethereumjs-rlp": "5.0.1", - "@nomicfoundation/ethereumjs-statemanager": "2.0.1", - "@nomicfoundation/ethereumjs-trie": "6.0.1", - "@nomicfoundation/ethereumjs-tx": "5.0.1", - "@nomicfoundation/ethereumjs-util": "9.0.1", - "@nomicfoundation/ethereumjs-vm": "7.0.1", + "@nomicfoundation/edr": "^0.3.5", + "@nomicfoundation/ethereumjs-common": "4.0.4", + "@nomicfoundation/ethereumjs-tx": "5.0.4", + "@nomicfoundation/ethereumjs-util": "9.0.4", "@nomicfoundation/solidity-analyzer": "^0.1.0", "@sentry/node": "^5.18.1", "@types/bn.js": "^5.1.0", "@types/lru-cache": "^5.1.0", - "abort-controller": "^3.0.0", "adm-zip": "^0.4.16", "aggregate-error": "^3.0.0", "ansi-escapes": "^4.3.0", + "boxen": "^5.1.2", "chalk": "^2.4.2", "chokidar": "^3.4.0", "ci-info": "^2.0.0", @@ -17603,9 +16829,6 @@ "bin": { "hardhat": "internal/cli/bootstrap.js" }, - "engines": { - "node": ">=16.0.0" - }, "peerDependencies": { "ts-node": "*", "typescript": "*" @@ -17620,9 +16843,9 @@ } }, "node_modules/hardhat-gas-reporter": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/hardhat-gas-reporter/-/hardhat-gas-reporter-1.0.9.tgz", - "integrity": "sha512-INN26G3EW43adGKBNzYWOlI3+rlLnasXTwW79YNnUhXPDa+yHESgt639dJEs37gCjhkbNKcRRJnomXEuMFBXJg==", + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/hardhat-gas-reporter/-/hardhat-gas-reporter-1.0.10.tgz", + "integrity": "sha512-02N4+So/fZrzJ88ci54GqwVA3Zrf0C9duuTyGt0CFRIh/CdNwbnTgkXkRfojOMLBQ+6t+lBIkgbsOtqMvNwikA==", "dev": true, "dependencies": { "array-uniq": "1.0.3", @@ -17633,21 +16856,66 @@ "hardhat": "^2.0.2" } }, - "node_modules/hardhat/node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "node_modules/hardhat/node_modules/@noble/hashes": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.2.0.tgz", + "integrity": "sha512-FZfhjEDbT5GRswV3C6uvLPHMiVD6lQBmpoX5+eSiPaMTXte/IKqI5dykDxzZB/WBeK/CDuQRBWarPdi3FNY2zQ==", "dev": true, - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/hardhat/node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ] + }, + "node_modules/hardhat/node_modules/@scure/bip32": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@scure/bip32/-/bip32-1.1.5.tgz", + "integrity": "sha512-XyNh1rB0SkEqd3tXcXMi+Xe1fvg+kUIcoRIEujP1Jgv7DqW2r9lg3Ah0NkFaCs9sTkQAQA8kw7xiRXzENi9Rtw==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ], + "dependencies": { + "@noble/hashes": "~1.2.0", + "@noble/secp256k1": "~1.7.0", + "@scure/base": "~1.1.0" + } + }, + "node_modules/hardhat/node_modules/@scure/bip39": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@scure/bip39/-/bip39-1.1.1.tgz", + "integrity": "sha512-t+wDck2rVkh65Hmv280fYdVdY25J9YeEUIgn2LG1WM6gxFkGzcksoDiUkWVpVp3Oex9xGC68JU2dSbUfwZ2jPg==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ], + "dependencies": { + "@noble/hashes": "~1.2.0", + "@scure/base": "~1.1.0" + } + }, + "node_modules/hardhat/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/hardhat/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", "dev": true, "dependencies": { @@ -17683,6 +16951,18 @@ "node": ">=0.8.0" } }, + "node_modules/hardhat/node_modules/ethereum-cryptography": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-1.2.0.tgz", + "integrity": "sha512-6yFQC9b5ug6/17CQpCyE3k9eKBMdhyVjzUy1WkiuY/E4vj/SXDBbCw8QEIaXqf0Mf2SnY6RmpDcwlUmBSS0EJw==", + "dev": true, + "dependencies": { + "@noble/hashes": "1.2.0", + "@noble/secp256k1": "1.7.1", + "@scure/bip32": "1.1.5", + "@scure/bip39": "1.1.1" + } + }, "node_modules/hardhat/node_modules/has-flag": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", @@ -17725,6 +17005,15 @@ "rimraf": "bin.js" } }, + "node_modules/hardhat/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, "node_modules/hardhat/node_modules/solc": { "version": "0.7.3", "resolved": "https://registry.npmjs.org/solc/-/solc-0.7.3.tgz", @@ -17782,18 +17071,6 @@ "node": ">=4" } }, - "node_modules/has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "dev": true, - "dependencies": { - "function-bind": "^1.1.1" - }, - "engines": { - "node": ">= 0.4.0" - } - }, "node_modules/has-bigints": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", @@ -17812,21 +17089,21 @@ } }, "node_modules/has-property-descriptors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz", - "integrity": "sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", "dev": true, "dependencies": { - "get-intrinsic": "^1.1.1" + "es-define-property": "^1.0.0" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/has-proto": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz", - "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", + "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", "dev": true, "engines": { "node": ">= 0.4" @@ -17848,12 +17125,12 @@ } }, "node_modules/has-tostringtag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", - "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", "dev": true, "dependencies": { - "has-symbols": "^1.0.2" + "has-symbols": "^1.0.3" }, "engines": { "node": ">= 0.4" @@ -17866,6 +17143,7 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz", "integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==", + "dev": true, "dependencies": { "inherits": "^2.0.4", "readable-stream": "^3.6.0", @@ -17875,25 +17153,6 @@ "node": ">=4" } }, - "node_modules/hash-base/node_modules/safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, "node_modules/hash.js": { "version": "1.1.7", "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", @@ -17903,6 +17162,18 @@ "minimalistic-assert": "^1.0.1" } }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/he": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", @@ -18002,9 +17273,9 @@ } }, "node_modules/http2-wrapper": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-2.2.0.tgz", - "integrity": "sha512-kZB0wxMo0sh1PehyjJUWRFEd99KC5TLjZ2cULC4f9iqJBAmKQQXEICjxl5iPJRwP40dpeHFqqhm7tYCvODpqpQ==", + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-2.2.1.tgz", + "integrity": "sha512-V5nVw1PAOgfI3Lmeaj2Exmeg7fenjhRUgz1lPSezy1CuhPYbgQtbQj4jZfEAEMlaL+vupsvhjqCyjzob0yxsmQ==", "dev": true, "dependencies": { "quick-lru": "^5.1.1", @@ -18071,18 +17342,18 @@ ] }, "node_modules/ignore": { - "version": "5.2.4", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", - "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==", + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz", + "integrity": "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==", "dev": true, "engines": { "node": ">= 4" } }, "node_modules/immutable": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.3.1.tgz", - "integrity": "sha512-lj9cnmB/kVS0QHsJnYKD1uo3o39nrbKxszjnqS9Fr6NB7bZzW45U6WSGBPKXDL/CvDKqDNPA4r3DoDQ8GTxo2A==", + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.3.5.tgz", + "integrity": "sha512-8eabxkth9gZatlwl5TBuJnCsoTADlL6ftEr7A4qgdaTsPyreilDSnUk57SO+jfKcNtxPa22U5KK6DSeAYhpBJw==", "dev": true }, "node_modules/import-fresh": { @@ -18141,13 +17412,13 @@ "dev": true }, "node_modules/internal-slot": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.5.tgz", - "integrity": "sha512-Y+R5hJrzs52QCG2laLn4udYVnxsfny9CpOhNhUvk/SSSVyF6T27FzRbF0sroPidSu3X8oEAkOn2K804mjpt6UQ==", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.7.tgz", + "integrity": "sha512-NGnrKwXzSms2qUUih/ILZ5JBqNTSa1+ZmP6flaIp6KmSElgE9qdndzS3cqjrDovwFdmwsGsLdeFgB6suw+1e9g==", "dev": true, "dependencies": { - "get-intrinsic": "^1.2.0", - "has": "^1.0.3", + "es-errors": "^1.3.0", + "hasown": "^2.0.0", "side-channel": "^1.0.4" }, "engines": { @@ -18207,14 +17478,16 @@ } }, "node_modules/is-array-buffer": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.2.tgz", - "integrity": "sha512-y+FyyR/w8vfIRq4eQcM1EYgSTnmHXPqaF+IgzgraytCFq5Xh8lllDVmAZolPJiZttZLeFSINPYMaEJ7/vWUa1w==", + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.4.tgz", + "integrity": "sha512-wcjaerHw0ydZwfhiKbXJWLDY8A7yV7KhjQOpb83hGgGfId/aQa4TOvwyzn2PuswW2gPCYEL/nEAiSVpdOj1lXw==", "dev": true, "dependencies": { "call-bind": "^1.0.2", - "get-intrinsic": "^1.2.0", - "is-typed-array": "^1.1.10" + "get-intrinsic": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -18266,29 +17539,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-buffer": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.5.tgz", - "integrity": "sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "engines": { - "node": ">=4" - } - }, "node_modules/is-callable": { "version": "1.2.7", "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", @@ -18314,12 +17564,27 @@ } }, "node_modules/is-core-module": { - "version": "2.12.1", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.12.1.tgz", - "integrity": "sha512-Q4ZuBAe2FUsKtyQJoQHlvP8OvBERxO3jEmy1I7hcRXcJBGGHFh/aJBswbXuS9sgrDH2QUO8ilkwNPHvHMd8clg==", + "version": "2.13.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz", + "integrity": "sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==", "dev": true, "dependencies": { - "has": "^1.0.3" + "hasown": "^2.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-data-view": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.1.tgz", + "integrity": "sha512-AHkaJrsUVW6wq6JS8y3JnM/GJF/9cf+k20+iDzlSaJrinEo5+7vRiteOSwBhHRiAyQATN1AmY4hwzxJKPmYf+w==", + "dev": true, + "dependencies": { + "is-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -18365,12 +17630,12 @@ } }, "node_modules/is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", "dev": true, "engines": { - "node": ">=4" + "node": ">=8" } }, "node_modules/is-function": { @@ -18416,9 +17681,9 @@ } }, "node_modules/is-negative-zero": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz", - "integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz", + "integrity": "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==", "dev": true, "engines": { "node": ">= 0.4" @@ -18477,12 +17742,15 @@ } }, "node_modules/is-shared-array-buffer": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz", - "integrity": "sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.3.tgz", + "integrity": "sha512-nA2hv5XIhLR3uVzDDfCIknerhx8XUKnstuOERPNNIinXG7v9u+ohXF67vxm4TPTEPU6lm61ZkwP3c9PCB97rhg==", "dev": true, "dependencies": { - "call-bind": "^1.0.2" + "call-bind": "^1.0.7" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -18519,12 +17787,12 @@ } }, "node_modules/is-typed-array": { - "version": "1.1.12", - "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.12.tgz", - "integrity": "sha512-Z14TF2JNG8Lss5/HMqt0//T9JeHXttXy5pH/DBU4vi98ozO2btxzq9MwYDZYnKwU8nRsz/+GVFVRDq3DkVuSPg==", + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.13.tgz", + "integrity": "sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==", "dev": true, "dependencies": { - "which-typed-array": "^1.1.11" + "which-typed-array": "^1.1.14" }, "engines": { "node": ">= 0.4" @@ -18605,16 +17873,6 @@ "integrity": "sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==", "dev": true }, - "node_modules/js-sdsl": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.4.1.tgz", - "integrity": "sha512-6Gsx8R0RucyePbWqPssR8DyfuXmLBooYN5cZFZKjHGnQuaf7pEzhtpceagJxVu4LqhYY5EYA7nko3FmeHZ1KbA==", - "dev": true, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/js-sdsl" - } - }, "node_modules/js-sha3": { "version": "0.8.0", "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.8.0.tgz", @@ -18646,9 +17904,9 @@ "dev": true }, "node_modules/json-buffer": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.0.tgz", - "integrity": "sha512-CuUqjv0FUZIdXkHPI8MezCnFCdaTAacej1TZYulLoAg1h/PhwkdXFN4V/gzY4g+fMBCOV2xF+rp7t2XD2ns/NQ==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", "dev": true }, "node_modules/json-parse-even-better-errors": { @@ -18727,9 +17985,9 @@ } }, "node_modules/keccak": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/keccak/-/keccak-3.0.3.tgz", - "integrity": "sha512-JZrLIAJWuZxKbCilMpNz5Vj7Vtb4scDG3dMXLOsbzBmQGyjwE61BbW7bJkfKKCShXiQZt3T6sBgALRtmd+nZaQ==", + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/keccak/-/keccak-3.0.4.tgz", + "integrity": "sha512-3vKuW0jV8J3XNTzvfyicFR5qvxrSAGl7KIhvgOu5cmWwM7tZRj3fMbj/pfIf4be7aznbc+prBWGjywox/g2Y6Q==", "hasInstallScript": true, "dependencies": { "node-addon-api": "^2.0.0", @@ -18751,12 +18009,12 @@ } }, "node_modules/keyv": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/keyv/-/keyv-3.1.0.tgz", - "integrity": "sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA==", + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", "dev": true, "dependencies": { - "json-buffer": "3.0.0" + "json-buffer": "3.0.1" } }, "node_modules/kind-of": { @@ -18798,45 +18056,6 @@ "node": ">=0.10.0" } }, - "node_modules/level": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/level/-/level-8.0.0.tgz", - "integrity": "sha512-ypf0jjAk2BWI33yzEaaotpq7fkOPALKAgDBxggO6Q9HGX2MRXn0wbP1Jn/tJv1gtL867+YOjOB49WaUF3UoJNQ==", - "dev": true, - "dependencies": { - "browser-level": "^1.0.1", - "classic-level": "^1.2.0" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/level" - } - }, - "node_modules/level-supports": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/level-supports/-/level-supports-4.0.1.tgz", - "integrity": "sha512-PbXpve8rKeNcZ9C1mUicC9auIYFyGpkV9/i6g76tLgANwWhtG2v7I4xNBUlkn3lE2/dZF3Pi0ygYGtLc4RXXdA==", - "dev": true, - "engines": { - "node": ">=12" - } - }, - "node_modules/level-transcoder": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/level-transcoder/-/level-transcoder-1.0.1.tgz", - "integrity": "sha512-t7bFwFtsQeD8cl8NIoQ2iwxA0CL/9IFw7/9gAjOonH0PWTTiRfY7Hq+Ejbsxh86tXobDQ6IOiddjNYIfOBs06w==", - "dev": true, - "dependencies": { - "buffer": "^6.0.3", - "module-error": "^1.0.1" - }, - "engines": { - "node": ">=12" - } - }, "node_modules/levn": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", @@ -18958,11 +18177,11 @@ } }, "node_modules/loupe": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.6.tgz", - "integrity": "sha512-RaPMZKiMy8/JruncMU5Bt6na1eftNoo++R4Y+N2FrxkDVTrGvcyzFTsaGif4QTeKESheMGegbhw6iUAq+5A8zA==", + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.7.tgz", + "integrity": "sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA==", "dependencies": { - "get-func-name": "^2.0.0" + "get-func-name": "^2.0.1" } }, "node_modules/lowercase-keys": { @@ -18981,12 +18200,14 @@ "dev": true }, "node_modules/lru-cache": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", - "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", - "dev": true, + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", "dependencies": { - "yallist": "^3.0.2" + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" } }, "node_modules/make-error": { @@ -19001,19 +18222,11 @@ "integrity": "sha512-1RUZVgQlpJSPWYbFSpmudq5nHY1doEIv89gBtF0s4gW1GF2XorxcA/70M5vq7rLv0a6mhOUccRsqkwhwLCIQ2Q==", "dev": true }, - "node_modules/mcl-wasm": { - "version": "0.7.9", - "resolved": "https://registry.npmjs.org/mcl-wasm/-/mcl-wasm-0.7.9.tgz", - "integrity": "sha512-iJIUcQWA88IJB/5L15GnJVnSQJmf/YaxxV6zRavv83HILHaJQb6y0iFyDMdDO0gN8X37tdxmAOrH/P8B6RB8sQ==", - "dev": true, - "engines": { - "node": ">=8.9.0" - } - }, "node_modules/md5.js": { "version": "1.3.5", "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", + "dev": true, "dependencies": { "hash-base": "^3.0.0", "inherits": "^2.0.1", @@ -19029,20 +18242,6 @@ "node": ">= 0.6" } }, - "node_modules/memory-level": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/memory-level/-/memory-level-1.0.0.tgz", - "integrity": "sha512-UXzwewuWeHBz5krr7EvehKcmLFNoXxGcvuYhC41tRnkrTbJohtS7kVn9akmgirtRygg+f7Yjsfi8Uu5SGSQ4Og==", - "dev": true, - "dependencies": { - "abstract-level": "^1.0.0", - "functional-red-black-tree": "^1.0.1", - "module-error": "^1.0.1" - }, - "engines": { - "node": ">=12" - } - }, "node_modules/memorystream": { "version": "0.3.1", "resolved": "https://registry.npmjs.org/memorystream/-/memorystream-0.3.1.tgz", @@ -19091,6 +18290,11 @@ "node": ">= 0.6" } }, + "node_modules/micro-ftch": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/micro-ftch/-/micro-ftch-0.3.1.tgz", + "integrity": "sha512-/0LLxhzP0tfiR5hcQebtudP56gUurs2CLkGarnCiB/OqEyUFQ6U3paQi/tgLv0hBJYt2rnr9MNpxz4fiiugstg==" + }, "node_modules/micromatch": { "version": "4.0.5", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", @@ -19215,6 +18419,12 @@ "yallist": "^3.0.0" } }, + "node_modules/minipass/node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true + }, "node_modules/minizlib": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-1.3.3.tgz", @@ -19259,9 +18469,9 @@ } }, "node_modules/mocha": { - "version": "10.2.0", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.2.0.tgz", - "integrity": "sha512-IDY7fl/BecMwFHzoqF2sg/SHHANeBoMMXFlS9r0OXKDssYE1M5O43wUY/9BVPeIvfH2zmEbBfseqN9gBQZzXkg==", + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.4.0.tgz", + "integrity": "sha512-eqhGB8JKapEYcC4ytX/xrzKforgEc3j1pGlAXVy3eRwrtAy5/nIfT1SvgGzfN0XZZxeLq0aQWkOUAmqIJiv+bA==", "dev": true, "dependencies": { "ansi-colors": "4.1.1", @@ -19271,13 +18481,12 @@ "diff": "5.0.0", "escape-string-regexp": "4.0.0", "find-up": "5.0.0", - "glob": "7.2.0", + "glob": "8.1.0", "he": "1.2.0", "js-yaml": "4.1.0", "log-symbols": "4.1.0", "minimatch": "5.0.1", "ms": "2.1.3", - "nanoid": "3.3.3", "serialize-javascript": "6.0.0", "strip-json-comments": "3.1.1", "supports-color": "8.1.1", @@ -19292,10 +18501,6 @@ }, "engines": { "node": ">= 14.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/mochajs" } }, "node_modules/mocha/node_modules/ansi-colors": { @@ -19322,6 +18527,33 @@ "balanced-match": "^1.0.0" } }, + "node_modules/mocha/node_modules/chokidar": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", + "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ], + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, "node_modules/mocha/node_modules/find-up": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", @@ -19338,6 +18570,25 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/mocha/node_modules/glob": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", + "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^5.0.1", + "once": "^1.3.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/mocha/node_modules/js-yaml": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", @@ -19443,15 +18694,6 @@ "integrity": "sha512-qYvlv/exQ4+svI3UOvPUpLDF0OMX5euvUH0Ny4N5QyRyhNdgAgUrVH3iUINSzEPLvx0kbo/Bp28GJKIqvE7URw==", "dev": true }, - "node_modules/module-error": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/module-error/-/module-error-1.0.2.tgz", - "integrity": "sha512-0yuvsqSCv8LbaOKhnsQ/T5JhyFlCYLPXK3U2sgV10zoKQwzs/MyfuQUOZQ1V/6OCOJsK/TRgNVrPuPDqtdMFtA==", - "dev": true, - "engines": { - "node": ">=10" - } - }, "node_modules/ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", @@ -19555,24 +18797,6 @@ "integrity": "sha512-9MqxMH/BSJC7dnLsEMPyfN5Dvoo49IsPFYMcHw3Bcfc2kN0lpHRBSzlMSVx4HGyJ7s9B31CyBTVehWJoQ8Ctew==", "dev": true }, - "node_modules/nanoid": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.3.tgz", - "integrity": "sha512-p1sjXuopFs0xg+fPASzQ28agW1oHD7xDsd9Xkf3T15H3c/cifrFHVwrh74PdoklAPi+i7MdRsE47vm2r6JoB+w==", - "dev": true, - "bin": { - "nanoid": "bin/nanoid.cjs" - }, - "engines": { - "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" - } - }, - "node_modules/napi-macros": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/napi-macros/-/napi-macros-2.2.2.tgz", - "integrity": "sha512-hmEVtAGYzVQpCKdbQea4skABsdXW4RUh5t5mJ2zzqowJS2OyXZTU1KhDVFhx+NlWZ4ap9mqR9TcDO3LTTttd+g==", - "dev": true - }, "node_modules/natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", @@ -19620,29 +18844,10 @@ "lodash": "^4.17.21" } }, - "node_modules/node-environment-flags": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/node-environment-flags/-/node-environment-flags-1.0.6.tgz", - "integrity": "sha512-5Evy2epuL+6TM0lCQGpFIj6KwiEsGh1SrHUhTbNX+sLbBtjidPZFAnVK9y5yU1+h//RitLbRHTIMyxQPtxMdHw==", - "dev": true, - "dependencies": { - "object.getownpropertydescriptors": "^2.0.3", - "semver": "^5.7.0" - } - }, - "node_modules/node-environment-flags/node_modules/semver": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", - "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", - "dev": true, - "bin": { - "semver": "bin/semver" - } - }, "node_modules/node-fetch": { - "version": "2.6.12", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.12.tgz", - "integrity": "sha512-C/fGU2E8ToujUivIO0H+tpQ6HWo4eEmchoPIoXtxCrVghxdKq+QOHqEZW7tuP3KlV3bC8FRMO5nMCC7Zm1VP6g==", + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", + "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", "dependencies": { "whatwg-url": "^5.0.0" }, @@ -19659,9 +18864,9 @@ } }, "node_modules/node-gyp-build": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.6.0.tgz", - "integrity": "sha512-NTZVKn9IylLwUzaKjkas1e4u2DLNcV4rdYagA4PWdPwW87Bi7z+BznyKSRwS/761tV/lzCGXplWsiaMjLqP2zQ==", + "version": "4.8.0", + "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.8.0.tgz", + "integrity": "sha512-u6fs2AEUljNho3EYTJNBfImO5QTo/J/1Etd+NVdCj7qWKUSN/bSLkZwhDv7I+w/MSC6qJ4cknepkAYykDdK8og==", "bin": { "node-gyp-build": "bin.js", "node-gyp-build-optional": "optional.js", @@ -19774,9 +18979,9 @@ } }, "node_modules/object-inspect": { - "version": "1.12.3", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.3.tgz", - "integrity": "sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==", + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", + "integrity": "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==", "dev": true, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -19792,13 +18997,13 @@ } }, "node_modules/object.assign": { - "version": "4.1.4", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.4.tgz", - "integrity": "sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ==", + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.5.tgz", + "integrity": "sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==", "dev": true, "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", + "call-bind": "^1.0.5", + "define-properties": "^1.2.1", "has-symbols": "^1.0.3", "object-keys": "^1.1.1" }, @@ -19809,34 +19014,47 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/object.getownpropertydescriptors": { - "version": "2.1.6", - "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.6.tgz", - "integrity": "sha512-lq+61g26E/BgHv0ZTFgRvi7NMEPuAxLkFU7rukXjc/AlwH4Am5xXVnIXy3un1bg/JPbXHrixRkK1itUzzPiIjQ==", + "node_modules/object.fromentries": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.8.tgz", + "integrity": "sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==", "dev": true, "dependencies": { - "array.prototype.reduce": "^1.0.5", - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.21.2", - "safe-array-concat": "^1.0.0" + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-object-atoms": "^1.0.0" }, "engines": { - "node": ">= 0.8" + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/object.groupby": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/object.groupby/-/object.groupby-1.0.3.tgz", + "integrity": "sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/object.values": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.6.tgz", - "integrity": "sha512-FVVTkD1vENCsAcwNs9k6jea2uHC/X0+JcjG8YA60FN5CMaJmG95wT9jek/xX9nornqGRrBkKtzuAu2wuHpKqvw==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.2.0.tgz", + "integrity": "sha512-yBYjY9QX2hnRmZHAjG/f13MzmBzxzYgQhFrke06TTyKY5zSTEqkOeukBzIdVA3j3ulu8Qa3MbVFShV7T2RmGtQ==", "dev": true, "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4" + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" }, "engines": { "node": ">= 0.4" @@ -20005,16 +19223,33 @@ } }, "node_modules/parse-asn1": { - "version": "5.1.6", - "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.6.tgz", - "integrity": "sha512-RnZRo1EPU6JBnra2vGHj0yhp6ebyjBZpmUCLHWiFhxlzvBCCpAuZ7elsBp1PVAbQN0/04VD/19rfzlBSwLstMw==", + "version": "5.1.7", + "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.7.tgz", + "integrity": "sha512-CTM5kuWR3sx9IFamcl5ErfPl6ea/N8IYwiJ+vpeB2g+1iknv7zBl5uPwbMbRVznRVbrNY6lGuDoE5b30grmbqg==", "dev": true, "dependencies": { - "asn1.js": "^5.2.0", - "browserify-aes": "^1.0.0", - "evp_bytestokey": "^1.0.0", - "pbkdf2": "^3.0.3", - "safe-buffer": "^5.1.1" + "asn1.js": "^4.10.1", + "browserify-aes": "^1.2.0", + "evp_bytestokey": "^1.0.3", + "hash-base": "~3.0", + "pbkdf2": "^3.1.2", + "safe-buffer": "^5.2.1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/parse-asn1/node_modules/hash-base": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.0.4.tgz", + "integrity": "sha512-EeeoJKjTyt868liAlVmcv2ZsUfGHlE3Q+BICOXcZiwN3osr5Q/zFGYmTJpoIzuaSTAwndFy+GqhEwlU4L3j4Ow==", + "dev": true, + "dependencies": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + }, + "engines": { + "node": ">=4" } }, "node_modules/parse-cache-control": { @@ -20189,9 +19424,9 @@ } }, "node_modules/patch-package/node_modules/universalify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", - "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", "dev": true, "engines": { "node": ">= 10.0.0" @@ -20275,6 +19510,7 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.2.tgz", "integrity": "sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA==", + "dev": true, "dependencies": { "create-hash": "^1.1.2", "create-hmac": "^1.1.4", @@ -20292,6 +19528,12 @@ "integrity": "sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==", "dev": true }, + "node_modules/picocolors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", + "dev": true + }, "node_modules/picomatch": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", @@ -20343,6 +19585,15 @@ "node": ">=4" } }, + "node_modules/possible-typed-array-names": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz", + "integrity": "sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/postinstall-postinstall": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/postinstall-postinstall/-/postinstall-postinstall-2.1.0.tgz", @@ -20396,62 +19647,26 @@ } }, "node_modules/prettier-plugin-solidity": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/prettier-plugin-solidity/-/prettier-plugin-solidity-1.1.3.tgz", - "integrity": "sha512-fQ9yucPi2sBbA2U2Xjh6m4isUTJ7S7QLc/XDDsktqqxYfTwdYKJ0EnnywXHwCGAaYbQNK+HIYPL1OemxuMsgeg==", + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/prettier-plugin-solidity/-/prettier-plugin-solidity-1.3.1.tgz", + "integrity": "sha512-MN4OP5I2gHAzHZG1wcuJl0FsLS3c4Cc5494bbg+6oQWBPuEamjwDvmGfFMZ6NFzsh3Efd9UUxeT7ImgjNH4ozA==", "dev": true, "dependencies": { - "@solidity-parser/parser": "^0.16.0", - "semver": "^7.3.8", - "solidity-comments-extractor": "^0.0.7" + "@solidity-parser/parser": "^0.17.0", + "semver": "^7.5.4", + "solidity-comments-extractor": "^0.0.8" }, "engines": { - "node": ">=12" + "node": ">=16" }, "peerDependencies": { - "prettier": ">=2.3.0 || >=3.0.0-alpha.0" + "prettier": ">=2.3.0" } }, "node_modules/prettier-plugin-solidity/node_modules/@solidity-parser/parser": { - "version": "0.16.1", - "resolved": "https://registry.npmjs.org/@solidity-parser/parser/-/parser-0.16.1.tgz", - "integrity": "sha512-PdhRFNhbTtu3x8Axm0uYpqOy/lODYQK+MlYSgqIsq2L8SFYEHJPHNUiOTAJbDGzNjjr1/n9AcIayxafR/fWmYw==", - "dev": true, - "dependencies": { - "antlr4ts": "^0.5.0-alpha.4" - } - }, - "node_modules/prettier-plugin-solidity/node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/prettier-plugin-solidity/node_modules/semver": { - "version": "7.5.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", - "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", - "dev": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/prettier-plugin-solidity/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/@solidity-parser/parser/-/parser-0.17.0.tgz", + "integrity": "sha512-Nko8R0/kUo391jsEHHxrGM07QFdnPGvlmox4rmH0kNiNAashItAilhy4Mv4pK5gQmW5f4sXAF58fwJbmlkGcVw==", "dev": true }, "node_modules/process": { @@ -20500,6 +19715,12 @@ "node": ">= 0.10" } }, + "node_modules/proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", + "dev": true + }, "node_modules/psl": { "version": "1.9.0", "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz", @@ -20767,14 +19988,15 @@ } }, "node_modules/regexp.prototype.flags": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.0.tgz", - "integrity": "sha512-0SutC3pNudRKgquxGoRGIz946MZVHqbNfPjBdxeOhBrdgDKlRoXmYLQN9xRbrR09ZXWeGAdPuif7egofn6v5LA==", + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.2.tgz", + "integrity": "sha512-NcDiDkTLuPR+++OCKB0nWafEmhg/Da8aUPLPMQbK+bxKKCm1/S5he+AqYa4PlMCVBalb4/yxIRub6qkEx5yJbw==", "dev": true, "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "functions-have-names": "^1.2.3" + "call-bind": "^1.0.6", + "define-properties": "^1.2.1", + "es-errors": "^1.3.0", + "set-function-name": "^2.0.1" }, "engines": { "node": ">= 0.4" @@ -20860,39 +20082,6 @@ "node": ">= 6" } }, - "node_modules/request-promise-core": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.4.tgz", - "integrity": "sha512-TTbAfBBRdWD7aNNOoVOBH4pN/KigV6LyapYNNlAPA8JwbovRti1E88m3sYAwsLi5ryhPKsE9APwnjFTgdUjTpw==", - "dev": true, - "dependencies": { - "lodash": "^4.17.19" - }, - "engines": { - "node": ">=0.10.0" - }, - "peerDependencies": { - "request": "^2.34" - } - }, - "node_modules/request-promise-native": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/request-promise-native/-/request-promise-native-1.0.9.tgz", - "integrity": "sha512-wcW+sIUiWnKgNY0dqCpOZkUbF/I+YPi+f09JZIDa39Ec+q82CpSYniDp+ISgTTbKmnpJWASeJBPZmoxH84wt3g==", - "deprecated": "request-promise-native has been deprecated because it extends the now deprecated request package, see https://github.com/request/request/issues/3142", - "dev": true, - "dependencies": { - "request-promise-core": "1.1.4", - "stealthy-require": "^1.1.1", - "tough-cookie": "^2.3.3" - }, - "engines": { - "node": ">=0.12.0" - }, - "peerDependencies": { - "request": "^2.34" - } - }, "node_modules/request/node_modules/form-data": { "version": "2.3.3", "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", @@ -20942,12 +20131,12 @@ "dev": true }, "node_modules/resolve": { - "version": "1.22.2", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.2.tgz", - "integrity": "sha512-Sb+mjNHOULsBv818T40qSPeRiuWLyaGMa5ewydRLFimneixmVy2zdivRl+AF6jaYPC8ERxGDmFSiqui6SfPd+g==", + "version": "1.22.8", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", + "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", "dev": true, "dependencies": { - "is-core-module": "^2.11.0", + "is-core-module": "^2.13.0", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, @@ -21011,6 +20200,7 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", + "dev": true, "dependencies": { "hash-base": "^3.0.0", "inherits": "^2.0.1" @@ -21050,43 +20240,14 @@ "queue-microtask": "^1.2.2" } }, - "node_modules/run-parallel-limit": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/run-parallel-limit/-/run-parallel-limit-1.1.0.tgz", - "integrity": "sha512-jJA7irRNM91jaKc3Hcl1npHsFLOXOoTkPCUL1JEa1R82O2miplXXRaGdjW/KM/98YQWDhJLiSs793CnXfblJUw==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "dependencies": { - "queue-microtask": "^1.2.2" - } - }, - "node_modules/rustbn.js": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/rustbn.js/-/rustbn.js-0.2.0.tgz", - "integrity": "sha512-4VlvkRUuCJvr2J6Y0ImW7NvTCriMi7ErOAqWk1y69vAdoNIzCF3yPmgeNzx+RQTLEDFq5sHfscn1MwHxP9hNfA==", - "dev": true - }, "node_modules/safe-array-concat": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.0.0.tgz", - "integrity": "sha512-9dVEFruWIsnie89yym+xWTAYASdpw3CJV7Li/6zBewGf9z2i1j31rP6jnY0pHEO4QZh6N0K11bFjWmdR8UGdPQ==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.2.tgz", + "integrity": "sha512-vj6RsCsWBCf19jIeHEfkRMw8DPiBb+DMXklQ/1SGDHOMlHdPUkZXFQ2YdplS23zESTijAcurb1aSgJA3AgMu1Q==", "dev": true, "dependencies": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.2.0", + "call-bind": "^1.0.7", + "get-intrinsic": "^1.2.4", "has-symbols": "^1.0.3", "isarray": "^2.0.5" }, @@ -21098,20 +20259,37 @@ } }, "node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] }, "node_modules/safe-regex-test": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.0.tgz", - "integrity": "sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.3.tgz", + "integrity": "sha512-CdASjNJPvRa7roO6Ra/gLYBTzYzzPyyBXxIMdGW3USQLyjWEls2RgW5UBTXaQVp+OrpeCK3bLem8smtmheoRuw==", "dev": true, "dependencies": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.1.3", + "call-bind": "^1.0.6", + "es-errors": "^1.3.0", "is-regex": "^1.1.4" }, + "engines": { + "node": ">= 0.4" + }, "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -21224,6 +20402,7 @@ "version": "4.0.3", "resolved": "https://registry.npmjs.org/secp256k1/-/secp256k1-4.0.3.tgz", "integrity": "sha512-NLZVf+ROMxwtEj3Xa562qgv2BK5e2WNmXPiOdVIPLgs6lyTzMvBq0aWTYMI5XCP9jZMVKOcqZLw/Wc4vDkuxhA==", + "dev": true, "hasInstallScript": true, "dependencies": { "elliptic": "^6.5.4", @@ -21235,12 +20414,17 @@ } }, "node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", + "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", + "dependencies": { + "lru-cache": "^6.0.0" + }, "bin": { "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" } }, "node_modules/send": { @@ -21334,10 +20518,43 @@ "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==", "dev": true }, - "node_modules/setimmediate": { + "node_modules/set-function-length": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", + "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", + "dev": true, + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/set-function-name": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz", + "integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==", + "dev": true, + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "functions-have-names": "^1.2.3", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/setimmediate": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", - "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==" + "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==", + "dev": true }, "node_modules/setprototypeof": { "version": "1.2.0", @@ -21349,6 +20566,7 @@ "version": "2.4.11", "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", + "dev": true, "dependencies": { "inherits": "^2.0.1", "safe-buffer": "^5.0.1" @@ -21409,14 +20627,18 @@ } }, "node_modules/side-channel": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", - "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz", + "integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==", "dev": true, "dependencies": { - "call-bind": "^1.0.0", - "get-intrinsic": "^1.0.2", - "object-inspect": "^1.9.0" + "call-bind": "^1.0.7", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.4", + "object-inspect": "^1.13.1" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -21430,20716 +20652,948 @@ "funding": [ { "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/simple-get": { - "version": "2.8.2", - "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-2.8.2.tgz", - "integrity": "sha512-Ijd/rV5o+mSBBs4F/x9oDPtTx9Zb6X9brmnXvMW4J7IR15ngi9q5xxqWBKU744jTZiaXtxaPL7uHG6vtN8kUkw==", - "dev": true, - "dependencies": { - "decompress-response": "^3.3.0", - "once": "^1.3.1", - "simple-concat": "^1.0.0" - } - }, - "node_modules/slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/slice-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", - "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.0.0", - "astral-regex": "^2.0.0", - "is-fullwidth-code-point": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/slice-ansi?sponsor=1" - } - }, - "node_modules/slice-ansi/node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/solc": { - "version": "0.6.12", - "resolved": "https://registry.npmjs.org/solc/-/solc-0.6.12.tgz", - "integrity": "sha512-Lm0Ql2G9Qc7yPP2Ba+WNmzw2jwsrd3u4PobHYlSOxaut3TtUbj9+5ZrT6f4DUpNPEoBaFUOEg9Op9C0mk7ge9g==", - "dev": true, - "dependencies": { - "command-exists": "^1.2.8", - "commander": "3.0.2", - "fs-extra": "^0.30.0", - "js-sha3": "0.8.0", - "memorystream": "^0.3.1", - "require-from-string": "^2.0.0", - "semver": "^5.5.0", - "tmp": "0.0.33" - }, - "bin": { - "solcjs": "solcjs" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/solc/node_modules/fs-extra": { - "version": "0.30.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-0.30.0.tgz", - "integrity": "sha512-UvSPKyhMn6LEd/WpUaV9C9t3zATuqoqfWc3QdPhPLb58prN9tqYPlPWi8Krxi44loBoUzlobqZ3+8tGpxxSzwA==", - "dev": true, - "dependencies": { - "graceful-fs": "^4.1.2", - "jsonfile": "^2.1.0", - "klaw": "^1.0.0", - "path-is-absolute": "^1.0.0", - "rimraf": "^2.2.8" - } - }, - "node_modules/solc/node_modules/jsonfile": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz", - "integrity": "sha512-PKllAqbgLgxHaj8TElYymKCAgrASebJrWpTnEkOaTowt23VKXXN0sUeriJ+eh7y6ufb/CC5ap11pz71/cM0hUw==", - "dev": true, - "optionalDependencies": { - "graceful-fs": "^4.1.6" - } - }, - "node_modules/solc/node_modules/rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "dev": true, - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - } - }, - "node_modules/solc/node_modules/semver": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", - "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", - "dev": true, - "bin": { - "semver": "bin/semver" - } - }, - "node_modules/solhint": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/solhint/-/solhint-3.4.1.tgz", - "integrity": "sha512-pzZn2RlZhws1XwvLPVSsxfHrwsteFf5eySOhpAytzXwKQYbTCJV6z8EevYDiSVKMpWrvbKpEtJ055CuEmzp4Xg==", - "dev": true, - "dependencies": { - "@solidity-parser/parser": "^0.16.0", - "ajv": "^6.12.6", - "antlr4": "^4.11.0", - "ast-parents": "^0.0.1", - "chalk": "^4.1.2", - "commander": "^10.0.0", - "cosmiconfig": "^8.0.0", - "fast-diff": "^1.2.0", - "glob": "^8.0.3", - "ignore": "^5.2.4", - "js-yaml": "^4.1.0", - "lodash": "^4.17.21", - "pluralize": "^8.0.0", - "semver": "^6.3.0", - "strip-ansi": "^6.0.1", - "table": "^6.8.1", - "text-table": "^0.2.0" - }, - "bin": { - "solhint": "solhint.js" - }, - "optionalDependencies": { - "prettier": "^2.8.3" - } - }, - "node_modules/solhint/node_modules/@solidity-parser/parser": { - "version": "0.16.1", - "resolved": "https://registry.npmjs.org/@solidity-parser/parser/-/parser-0.16.1.tgz", - "integrity": "sha512-PdhRFNhbTtu3x8Axm0uYpqOy/lODYQK+MlYSgqIsq2L8SFYEHJPHNUiOTAJbDGzNjjr1/n9AcIayxafR/fWmYw==", - "dev": true, - "dependencies": { - "antlr4ts": "^0.5.0-alpha.4" - } - }, - "node_modules/solhint/node_modules/argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true - }, - "node_modules/solhint/node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/solhint/node_modules/commander": { - "version": "10.0.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz", - "integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==", - "dev": true, - "engines": { - "node": ">=14" - } - }, - "node_modules/solhint/node_modules/glob": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", - "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==", - "dev": true, - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^5.0.1", - "once": "^1.3.0" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/solhint/node_modules/js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dev": true, - "dependencies": { - "argparse": "^2.0.1" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/solhint/node_modules/minimatch": { - "version": "5.1.6", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", - "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", - "dev": true, - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/solidity-comments-extractor": { - "version": "0.0.7", - "resolved": "https://registry.npmjs.org/solidity-comments-extractor/-/solidity-comments-extractor-0.0.7.tgz", - "integrity": "sha512-wciNMLg/Irp8OKGrh3S2tfvZiZ0NEyILfcRCXCD4mp7SgK/i9gzLfhY2hY7VMCQJ3kH9UB9BzNdibIVMchzyYw==", - "dev": true - }, - "node_modules/solidity-coverage": { - "version": "0.7.22", - "resolved": "https://registry.npmjs.org/solidity-coverage/-/solidity-coverage-0.7.22.tgz", - "integrity": "sha512-I6Zd5tsFY+gmj1FDIp6w7OrUePx6ZpMgKQZg7dWgPaQHePLi3Jk+iJ8lwZxsWEoNy2Lcv91rMxATWHqRaFdQpw==", - "dev": true, - "dependencies": { - "@solidity-parser/parser": "^0.14.0", - "@truffle/provider": "^0.2.24", - "chalk": "^2.4.2", - "death": "^1.1.0", - "detect-port": "^1.3.0", - "fs-extra": "^8.1.0", - "ghost-testrpc": "^0.0.2", - "global-modules": "^2.0.0", - "globby": "^10.0.1", - "jsonschema": "^1.2.4", - "lodash": "^4.17.15", - "node-emoji": "^1.10.0", - "pify": "^4.0.1", - "recursive-readdir": "^2.2.2", - "sc-istanbul": "^0.4.5", - "semver": "^7.3.4", - "shelljs": "^0.8.3", - "web3-utils": "^1.3.0" - }, - "bin": { - "solidity-coverage": "plugins/bin.js" - } - }, - "node_modules/solidity-coverage/node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/solidity-coverage/node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/solidity-coverage/node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/solidity-coverage/node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true - }, - "node_modules/solidity-coverage/node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/solidity-coverage/node_modules/fs-extra": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", - "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", - "dev": true, - "dependencies": { - "graceful-fs": "^4.2.0", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - }, - "engines": { - "node": ">=6 <7 || >=8" - } - }, - "node_modules/solidity-coverage/node_modules/globby": { - "version": "10.0.2", - "resolved": "https://registry.npmjs.org/globby/-/globby-10.0.2.tgz", - "integrity": "sha512-7dUi7RvCoT/xast/o/dLN53oqND4yk0nsHkhRgn9w65C4PofCLOoJ39iSOg+qVDdWQPIEj+eszMHQ+aLVwwQSg==", - "dev": true, - "dependencies": { - "@types/glob": "^7.1.1", - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.0.3", - "glob": "^7.1.3", - "ignore": "^5.1.1", - "merge2": "^1.2.3", - "slash": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/solidity-coverage/node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/solidity-coverage/node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/solidity-coverage/node_modules/semver": { - "version": "7.5.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", - "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", - "dev": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/solidity-coverage/node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/solidity-coverage/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - }, - "node_modules/source-map": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.2.0.tgz", - "integrity": "sha512-CBdZ2oa/BHhS4xj5DlhjWNHcan57/5YuvfdLf17iVmIpd9KRm+DFLmC6nBNj+6Ua7Kt3TmOjDpQT1aTYOQtoUA==", - "dev": true, - "optional": true, - "dependencies": { - "amdefine": ">=0.0.4" - }, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/source-map-support": { - "version": "0.5.21", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", - "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", - "dev": true, - "dependencies": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - }, - "node_modules/source-map-support/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/spdx-correct": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz", - "integrity": "sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==", - "dev": true, - "dependencies": { - "spdx-expression-parse": "^3.0.0", - "spdx-license-ids": "^3.0.0" - } - }, - "node_modules/spdx-exceptions": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz", - "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==", - "dev": true - }, - "node_modules/spdx-expression-parse": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", - "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", - "dev": true, - "dependencies": { - "spdx-exceptions": "^2.1.0", - "spdx-license-ids": "^3.0.0" - } - }, - "node_modules/spdx-license-ids": { - "version": "3.0.13", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.13.tgz", - "integrity": "sha512-XkD+zwiqXHikFZm4AX/7JSCXA98U5Db4AFd5XUg/+9UNtnH75+Z9KxtpYiJZx36mUDVOwH83pl7yvCer6ewM3w==", - "dev": true - }, - "node_modules/sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", - "dev": true - }, - "node_modules/sshpk": { - "version": "1.17.0", - "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.17.0.tgz", - "integrity": "sha512-/9HIEs1ZXGhSPE8X6Ccm7Nam1z8KcoCqPdI7ecm1N33EzAetWahvQWVqLZtaZQ+IDKX4IyA2o0gBzqIMkAagHQ==", - "dev": true, - "dependencies": { - "asn1": "~0.2.3", - "assert-plus": "^1.0.0", - "bcrypt-pbkdf": "^1.0.0", - "dashdash": "^1.12.0", - "ecc-jsbn": "~0.1.1", - "getpass": "^0.1.1", - "jsbn": "~0.1.0", - "safer-buffer": "^2.0.2", - "tweetnacl": "~0.14.0" - }, - "bin": { - "sshpk-conv": "bin/sshpk-conv", - "sshpk-sign": "bin/sshpk-sign", - "sshpk-verify": "bin/sshpk-verify" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/sshpk/node_modules/tweetnacl": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==", - "dev": true - }, - "node_modules/stacktrace-parser": { - "version": "0.1.10", - "resolved": "https://registry.npmjs.org/stacktrace-parser/-/stacktrace-parser-0.1.10.tgz", - "integrity": "sha512-KJP1OCML99+8fhOHxwwzyWrlUuVX5GQ0ZpJTd1DFXhdkrvg1szxfHhawXUZ3g9TkXORQd4/WG68jMlQZ2p8wlg==", - "dev": true, - "dependencies": { - "type-fest": "^0.7.1" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/stacktrace-parser/node_modules/type-fest": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.7.1.tgz", - "integrity": "sha512-Ne2YiiGN8bmrmJJEuTWTLJR32nh/JdL1+PSicowtNb0WFpn59GK8/lfD61bVtzguz7b3PBt74nxpv/Pw5po5Rg==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/statuses": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", - "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", - "dev": true, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/stealthy-require": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/stealthy-require/-/stealthy-require-1.1.1.tgz", - "integrity": "sha512-ZnWpYnYugiOVEY5GkcuJK1io5V8QmNYChG62gSit9pQVGErXtrKuPC55ITaVSukmMta5qpMU7vqLt2Lnni4f/g==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/strict-uri-encode": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz", - "integrity": "sha512-R3f198pcvnB+5IpnBlRkphuE9n46WyVl8I39W/ZUTZLz4nqSP/oLYUrcnJrw462Ds8he4YKMov2efsTIw1BDGQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "dependencies": { - "safe-buffer": "~5.2.0" - } - }, - "node_modules/string_decoder/node_modules/safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "dev": true, - "dependencies": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/string-width/node_modules/ansi-regex": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.1.tgz", - "integrity": "sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/string-width/node_modules/strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha512-4XaJ2zQdCzROZDivEVIDPkcQn8LMFSa8kj8Gxb/Lnwzv9A8VctNZ+lfivC/sV3ivW8ElJTERXZoPBRrZKkNKow==", - "dev": true, - "dependencies": { - "ansi-regex": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/string.prototype.trim": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.7.tgz", - "integrity": "sha512-p6TmeT1T3411M8Cgg9wBTMRtY2q9+PNy9EV1i2lIXUN/btt763oIfxwN3RR8VU6wHX8j/1CFy0L+YuThm6bgOg==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/string.prototype.trimend": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.6.tgz", - "integrity": "sha512-JySq+4mrPf9EsDBEDYMOb/lM7XQLulwg5R/m1r0PXEFqrV0qHvl58sdTilSXtKOflCsK2E8jxf+GKC0T07RWwQ==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/string.prototype.trimstart": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.6.tgz", - "integrity": "sha512-omqjMDaY92pbn5HOX7f9IccLA+U1tA9GvtU4JrodiXFfYB7jPzzHpRzpglLAjtUV6bB557zwClJezTqnAiYnQA==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/strip-hex-prefix": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/strip-hex-prefix/-/strip-hex-prefix-1.0.0.tgz", - "integrity": "sha512-q8d4ue7JGEiVcypji1bALTos+0pWtyGlivAWyPuTkHzuTCJqrK9sWxYQZUq6Nq3cuyv3bm734IhHvHtGGURU6A==", - "dependencies": { - "is-hex-prefixed": "1.0.0" - }, - "engines": { - "node": ">=6.5.0", - "npm": ">=3" - } - }, - "node_modules/strip-json-comments": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", - "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", - "dev": true, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/supports-preserve-symlinks-flag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", - "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", - "dev": true, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/swarm-js": { - "version": "0.1.42", - "resolved": "https://registry.npmjs.org/swarm-js/-/swarm-js-0.1.42.tgz", - "integrity": "sha512-BV7c/dVlA3R6ya1lMlSSNPLYrntt0LUq4YMgy3iwpCIc6rZnS5W2wUoctarZ5pXlpKtxDDf9hNziEkcfrxdhqQ==", - "dev": true, - "dependencies": { - "bluebird": "^3.5.0", - "buffer": "^5.0.5", - "eth-lib": "^0.1.26", - "fs-extra": "^4.0.2", - "got": "^11.8.5", - "mime-types": "^2.1.16", - "mkdirp-promise": "^5.0.1", - "mock-fs": "^4.1.0", - "setimmediate": "^1.0.5", - "tar": "^4.0.2", - "xhr-request": "^1.0.1" - } - }, - "node_modules/swarm-js/node_modules/@sindresorhus/is": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.6.0.tgz", - "integrity": "sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sindresorhus/is?sponsor=1" - } - }, - "node_modules/swarm-js/node_modules/@szmarczak/http-timer": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-4.0.6.tgz", - "integrity": "sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w==", - "dev": true, - "dependencies": { - "defer-to-connect": "^2.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/swarm-js/node_modules/buffer": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", - "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "dependencies": { - "base64-js": "^1.3.1", - "ieee754": "^1.1.13" - } - }, - "node_modules/swarm-js/node_modules/cacheable-lookup": { - "version": "5.0.4", - "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-5.0.4.tgz", - "integrity": "sha512-2/kNscPhpcxrOigMZzbiWF7dz8ilhb/nIHU3EyZiXWXpeq/au8qJ8VhdftMkty3n7Gj6HIGalQG8oiBNB3AJgA==", - "dev": true, - "engines": { - "node": ">=10.6.0" - } - }, - "node_modules/swarm-js/node_modules/cacheable-request": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-7.0.4.tgz", - "integrity": "sha512-v+p6ongsrp0yTGbJXjgxPow2+DL93DASP4kXCDKb8/bwRtt9OEF3whggkkDkGNzgcWy2XaF4a8nZglC7uElscg==", - "dev": true, - "dependencies": { - "clone-response": "^1.0.2", - "get-stream": "^5.1.0", - "http-cache-semantics": "^4.0.0", - "keyv": "^4.0.0", - "lowercase-keys": "^2.0.0", - "normalize-url": "^6.0.1", - "responselike": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/swarm-js/node_modules/decompress-response": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", - "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", - "dev": true, - "dependencies": { - "mimic-response": "^3.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/swarm-js/node_modules/defer-to-connect": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.1.tgz", - "integrity": "sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==", - "dev": true, - "engines": { - "node": ">=10" - } - }, - "node_modules/swarm-js/node_modules/fs-extra": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-4.0.3.tgz", - "integrity": "sha512-q6rbdDd1o2mAnQreO7YADIxf/Whx4AHBiRf6d+/cVT8h44ss+lHgxf1FemcqDnQt9X3ct4McHr+JMGlYSsK7Cg==", - "dev": true, - "dependencies": { - "graceful-fs": "^4.1.2", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - } - }, - "node_modules/swarm-js/node_modules/get-stream": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", - "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", - "dev": true, - "dependencies": { - "pump": "^3.0.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/swarm-js/node_modules/got": { - "version": "11.8.6", - "resolved": "https://registry.npmjs.org/got/-/got-11.8.6.tgz", - "integrity": "sha512-6tfZ91bOr7bOXnK7PRDCGBLa1H4U080YHNaAQ2KsMGlLEzRbk44nsZF2E1IeRc3vtJHPVbKCYgdFbaGO2ljd8g==", - "dev": true, - "dependencies": { - "@sindresorhus/is": "^4.0.0", - "@szmarczak/http-timer": "^4.0.5", - "@types/cacheable-request": "^6.0.1", - "@types/responselike": "^1.0.0", - "cacheable-lookup": "^5.0.3", - "cacheable-request": "^7.0.2", - "decompress-response": "^6.0.0", - "http2-wrapper": "^1.0.0-beta.5.2", - "lowercase-keys": "^2.0.0", - "p-cancelable": "^2.0.0", - "responselike": "^2.0.0" - }, - "engines": { - "node": ">=10.19.0" - }, - "funding": { - "url": "https://github.com/sindresorhus/got?sponsor=1" - } - }, - "node_modules/swarm-js/node_modules/http2-wrapper": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-1.0.3.tgz", - "integrity": "sha512-V+23sDMr12Wnz7iTcDeJr3O6AIxlnvT/bmaAAAP/Xda35C90p9599p0F1eHR/N1KILWSoWVAiOMFjBBXaXSMxg==", - "dev": true, - "dependencies": { - "quick-lru": "^5.1.1", - "resolve-alpn": "^1.0.0" - }, - "engines": { - "node": ">=10.19.0" - } - }, - "node_modules/swarm-js/node_modules/json-buffer": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", - "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", - "dev": true - }, - "node_modules/swarm-js/node_modules/keyv": { - "version": "4.5.3", - "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.3.tgz", - "integrity": "sha512-QCiSav9WaX1PgETJ+SpNnx2PRRapJ/oRSXM4VO5OGYGSjrxbKPVFVhB3l2OCbLCk329N8qyAtsJjSjvVBWzEug==", - "dev": true, - "dependencies": { - "json-buffer": "3.0.1" - } - }, - "node_modules/swarm-js/node_modules/lowercase-keys": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", - "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/swarm-js/node_modules/mimic-response": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", - "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/swarm-js/node_modules/normalize-url": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz", - "integrity": "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/swarm-js/node_modules/p-cancelable": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-2.1.1.tgz", - "integrity": "sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/swarm-js/node_modules/responselike": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/responselike/-/responselike-2.0.1.tgz", - "integrity": "sha512-4gl03wn3hj1HP3yzgdI7d3lCkF95F21Pz4BPGvKHinyQzALR5CapwC8yIi0Rh58DEMQ/SguC03wFj2k0M/mHhw==", - "dev": true, - "dependencies": { - "lowercase-keys": "^2.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/sync-request": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/sync-request/-/sync-request-6.1.0.tgz", - "integrity": "sha512-8fjNkrNlNCrVc/av+Jn+xxqfCjYaBoHqCsDz6mt030UMxJGr+GSfCV1dQt2gRtlL63+VPidwDVLr7V2OcTSdRw==", - "dev": true, - "dependencies": { - "http-response-object": "^3.0.1", - "sync-rpc": "^1.2.1", - "then-request": "^6.0.0" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/sync-rpc": { - "version": "1.3.6", - "resolved": "https://registry.npmjs.org/sync-rpc/-/sync-rpc-1.3.6.tgz", - "integrity": "sha512-J8jTXuZzRlvU7HemDgHi3pGnh/rkoqR/OZSjhTyyZrEkkYQbk7Z33AXp37mkPfPpfdOuj7Ex3H/TJM1z48uPQw==", - "dev": true, - "dependencies": { - "get-port": "^3.1.0" - } - }, - "node_modules/table": { - "version": "6.8.1", - "resolved": "https://registry.npmjs.org/table/-/table-6.8.1.tgz", - "integrity": "sha512-Y4X9zqrCftUhMeH2EptSSERdVKt/nEdijTOacGD/97EKjhQ/Qs8RTlEGABSJNNN8lac9kheH+af7yAkEWlgneA==", - "dev": true, - "dependencies": { - "ajv": "^8.0.1", - "lodash.truncate": "^4.4.2", - "slice-ansi": "^4.0.0", - "string-width": "^4.2.3", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/table/node_modules/ajv": { - "version": "8.12.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", - "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", - "dev": true, - "dependencies": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/table/node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/table/node_modules/json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "dev": true - }, - "node_modules/table/node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/tar": { - "version": "4.4.19", - "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.19.tgz", - "integrity": "sha512-a20gEsvHnWe0ygBY8JbxoM4w3SJdhc7ZAuxkLqh+nvNQN2IOt0B5lLgM490X5Hl8FF0dl0tOf2ewFYAlIFgzVA==", - "dev": true, - "dependencies": { - "chownr": "^1.1.4", - "fs-minipass": "^1.2.7", - "minipass": "^2.9.0", - "minizlib": "^1.3.3", - "mkdirp": "^0.5.5", - "safe-buffer": "^5.2.1", - "yallist": "^3.1.1" - }, - "engines": { - "node": ">=4.5" - } - }, - "node_modules/tar/node_modules/safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/test-value": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/test-value/-/test-value-2.1.0.tgz", - "integrity": "sha512-+1epbAxtKeXttkGFMTX9H42oqzOTufR1ceCF+GYA5aOmvaPq9wd4PUS8329fn2RRLGNeUkgRLnVpycjx8DsO2w==", - "dev": true, - "dependencies": { - "array-back": "^1.0.3", - "typical": "^2.6.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/test-value/node_modules/array-back": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/array-back/-/array-back-1.0.4.tgz", - "integrity": "sha512-1WxbZvrmyhkNoeYcizokbmh5oiOCIfyvGtcqbK3Ls1v1fKcquzxnQSceOx6tzq7jmai2kFLWIpGND2cLhH6TPw==", - "dev": true, - "dependencies": { - "typical": "^2.6.0" - }, - "engines": { - "node": ">=0.12.0" - } - }, - "node_modules/testrpc": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/testrpc/-/testrpc-0.0.1.tgz", - "integrity": "sha512-afH1hO+SQ/VPlmaLUFj2636QMeDvPCeQMc/9RBMW0IfjNe9gFD9Ra3ShqYkB7py0do1ZcCna/9acHyzTJ+GcNA==", - "deprecated": "testrpc has been renamed to ganache-cli, please use this package from now on.", - "dev": true - }, - "node_modules/text-table": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", - "dev": true - }, - "node_modules/then-request": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/then-request/-/then-request-6.0.2.tgz", - "integrity": "sha512-3ZBiG7JvP3wbDzA9iNY5zJQcHL4jn/0BWtXIkagfz7QgOL/LqjCEOBQuJNZfu0XYnv5JhKh+cDxCPM4ILrqruA==", - "dev": true, - "dependencies": { - "@types/concat-stream": "^1.6.0", - "@types/form-data": "0.0.33", - "@types/node": "^8.0.0", - "@types/qs": "^6.2.31", - "caseless": "~0.12.0", - "concat-stream": "^1.6.0", - "form-data": "^2.2.0", - "http-basic": "^8.1.1", - "http-response-object": "^3.0.1", - "promise": "^8.0.0", - "qs": "^6.4.0" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/then-request/node_modules/@types/node": { - "version": "8.10.66", - "resolved": "https://registry.npmjs.org/@types/node/-/node-8.10.66.tgz", - "integrity": "sha512-tktOkFUA4kXx2hhhrB8bIFb5TbwzS4uOhKEmwiD+NoiL0qtP2OQ9mFldbgD4dV1djrlBYP6eBuQZiWjuHUpqFw==", - "dev": true - }, - "node_modules/then-request/node_modules/form-data": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.5.1.tgz", - "integrity": "sha512-m21N3WOmEEURgk6B9GLOE4RuWOFf28Lhh9qGYeNlGq4VDXUlJy2th2slBNU8Gp8EzloYZOibZJ7t5ecIrFSjVA==", - "dev": true, - "dependencies": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.6", - "mime-types": "^2.1.12" - }, - "engines": { - "node": ">= 0.12" - } - }, - "node_modules/timed-out": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/timed-out/-/timed-out-4.0.1.tgz", - "integrity": "sha512-G7r3AhovYtr5YKOWQkta8RKAPb+J9IsO4uVmzjl8AZwfhs8UcUwTiD6gcJYSgOtzyjvQKrKYn41syHbUWMkafA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/tmp": { - "version": "0.0.33", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", - "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", - "dev": true, - "dependencies": { - "os-tmpdir": "~1.0.2" - }, - "engines": { - "node": ">=0.6.0" - } - }, - "node_modules/to-readable-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/to-readable-stream/-/to-readable-stream-1.0.0.tgz", - "integrity": "sha512-Iq25XBt6zD5npPhlLVXGFN3/gyR2/qODcKNNyTMd4vbm39HUaOiAM4PMq0eMVC/Tkxz+Zjdsc55g9yyz+Yq00Q==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, - "dependencies": { - "is-number": "^7.0.0" - }, - "engines": { - "node": ">=8.0" - } - }, - "node_modules/toidentifier": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", - "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", - "dev": true, - "engines": { - "node": ">=0.6" - } - }, - "node_modules/tough-cookie": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", - "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", - "dev": true, - "dependencies": { - "psl": "^1.1.28", - "punycode": "^2.1.1" - }, - "engines": { - "node": ">=0.8" - } - }, - "node_modules/tough-cookie/node_modules/punycode": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz", - "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/tr46": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" - }, - "node_modules/treeify": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/treeify/-/treeify-1.1.0.tgz", - "integrity": "sha512-1m4RA7xVAJrSGrrXGs0L3YTwyvBs2S8PbRHaLZAkFw7JR8oIFwYtysxlBZhYIa7xSyiYJKZ3iGrrk55cGA3i9A==", - "engines": { - "node": ">=0.6" - } - }, - "node_modules/ts-essentials": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/ts-essentials/-/ts-essentials-7.0.3.tgz", - "integrity": "sha512-8+gr5+lqO3G84KdiTSMRLtuyJ+nTBVRKuCrK4lidMPdVeEp0uqC875uE5NMcaA7YYMN7XsNiFQuMvasF8HT/xQ==", - "dev": true, - "peerDependencies": { - "typescript": ">=3.7.0" - } - }, - "node_modules/ts-generator": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/ts-generator/-/ts-generator-0.1.1.tgz", - "integrity": "sha512-N+ahhZxTLYu1HNTQetwWcx3so8hcYbkKBHTr4b4/YgObFTIKkOSSsaa+nal12w8mfrJAyzJfETXawbNjSfP2gQ==", - "dev": true, - "dependencies": { - "@types/mkdirp": "^0.5.2", - "@types/prettier": "^2.1.1", - "@types/resolve": "^0.0.8", - "chalk": "^2.4.1", - "glob": "^7.1.2", - "mkdirp": "^0.5.1", - "prettier": "^2.1.2", - "resolve": "^1.8.1", - "ts-essentials": "^1.0.0" - }, - "bin": { - "ts-generator": "dist/cli/run.js" - } - }, - "node_modules/ts-generator/node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/ts-generator/node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/ts-generator/node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/ts-generator/node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true - }, - "node_modules/ts-generator/node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/ts-generator/node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/ts-generator/node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/ts-generator/node_modules/ts-essentials": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/ts-essentials/-/ts-essentials-1.0.4.tgz", - "integrity": "sha512-q3N1xS4vZpRouhYHDPwO0bDW3EZ6SK9CrrDHxi/D6BPReSjpVgWIOpLS2o0gSBZm+7q/wyKp6RVM1AeeW7uyfQ==", - "dev": true - }, - "node_modules/ts-node": { - "version": "10.9.1", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz", - "integrity": "sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==", - "dev": true, - "dependencies": { - "@cspotcode/source-map-support": "^0.8.0", - "@tsconfig/node10": "^1.0.7", - "@tsconfig/node12": "^1.0.7", - "@tsconfig/node14": "^1.0.0", - "@tsconfig/node16": "^1.0.2", - "acorn": "^8.4.1", - "acorn-walk": "^8.1.1", - "arg": "^4.1.0", - "create-require": "^1.1.0", - "diff": "^4.0.1", - "make-error": "^1.1.1", - "v8-compile-cache-lib": "^3.0.1", - "yn": "3.1.1" - }, - "bin": { - "ts-node": "dist/bin.js", - "ts-node-cwd": "dist/bin-cwd.js", - "ts-node-esm": "dist/bin-esm.js", - "ts-node-script": "dist/bin-script.js", - "ts-node-transpile-only": "dist/bin-transpile.js", - "ts-script": "dist/bin-script-deprecated.js" - }, - "peerDependencies": { - "@swc/core": ">=1.2.50", - "@swc/wasm": ">=1.2.50", - "@types/node": "*", - "typescript": ">=2.7" - }, - "peerDependenciesMeta": { - "@swc/core": { - "optional": true - }, - "@swc/wasm": { - "optional": true - } - } - }, - "node_modules/ts-node/node_modules/acorn": { - "version": "8.10.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.10.0.tgz", - "integrity": "sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==", - "dev": true, - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/ts-node/node_modules/diff": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", - "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", - "dev": true, - "engines": { - "node": ">=0.3.1" - } - }, - "node_modules/tsconfig-paths": { - "version": "3.14.2", - "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.14.2.tgz", - "integrity": "sha512-o/9iXgCYc5L/JxCHPe3Hvh8Q/2xm5Z+p18PESBU6Ff33695QnCHBEjcytY2q19ua7Mbl/DavtBOLq+oG0RCL+g==", - "dev": true, - "dependencies": { - "@types/json5": "^0.0.29", - "json5": "^1.0.2", - "minimist": "^1.2.6", - "strip-bom": "^3.0.0" - } - }, - "node_modules/tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", - "dev": true - }, - "node_modules/tsort": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/tsort/-/tsort-0.0.1.tgz", - "integrity": "sha512-Tyrf5mxF8Ofs1tNoxA13lFeZ2Zrbd6cKbuH3V+MQ5sb6DtBj5FjrXVsRWT8YvNAQTqNoz66dz1WsbigI22aEnw==", - "dev": true - }, - "node_modules/tsutils": { - "version": "3.21.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", - "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", - "dev": true, - "dependencies": { - "tslib": "^1.8.1" - }, - "engines": { - "node": ">= 6" - }, - "peerDependencies": { - "typescript": ">=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta" - } - }, - "node_modules/tunnel-agent": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", - "dev": true, - "dependencies": { - "safe-buffer": "^5.0.1" - }, - "engines": { - "node": "*" - } - }, - "node_modules/tweetnacl": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.3.tgz", - "integrity": "sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==", - "dev": true - }, - "node_modules/tweetnacl-util": { - "version": "0.15.1", - "resolved": "https://registry.npmjs.org/tweetnacl-util/-/tweetnacl-util-0.15.1.tgz", - "integrity": "sha512-RKJBIj8lySrShN4w6i/BonWp2Z/uxwC3h4y7xsRrpP59ZboCd0GpEVsOnMDYLMmKBpYhb5TgHzZXy7wTfYFBRw==", - "dev": true - }, - "node_modules/type": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/type/-/type-1.2.0.tgz", - "integrity": "sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg==", - "dev": true - }, - "node_modules/type-check": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", - "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", - "dev": true, - "dependencies": { - "prelude-ls": "^1.2.1" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/type-detect": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", - "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", - "engines": { - "node": ">=4" - } - }, - "node_modules/type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/type-is": { - "version": "1.6.18", - "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", - "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", - "dev": true, - "dependencies": { - "media-typer": "0.3.0", - "mime-types": "~2.1.24" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/typechain": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/typechain/-/typechain-5.2.0.tgz", - "integrity": "sha512-0INirvQ+P+MwJOeMct+WLkUE4zov06QxC96D+i3uGFEHoiSkZN70MKDQsaj8zkL86wQwByJReI2e7fOUwECFuw==", - "dev": true, - "dependencies": { - "@types/prettier": "^2.1.1", - "command-line-args": "^4.0.7", - "debug": "^4.1.1", - "fs-extra": "^7.0.0", - "glob": "^7.1.6", - "js-sha3": "^0.8.0", - "lodash": "^4.17.15", - "mkdirp": "^1.0.4", - "prettier": "^2.1.2", - "ts-essentials": "^7.0.1" - }, - "bin": { - "typechain": "dist/cli/cli.js" - }, - "peerDependencies": { - "typescript": ">=4.1.0" - } - }, - "node_modules/typechain/node_modules/mkdirp": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", - "dev": true, - "bin": { - "mkdirp": "bin/cmd.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/typed-array-buffer": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.0.tgz", - "integrity": "sha512-Y8KTSIglk9OZEr8zywiIHG/kmQ7KWyjseXs1CbSo8vC42w7hg2HgYTxSWwP0+is7bWDc1H+Fo026CpHFwm8tkw==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.2.1", - "is-typed-array": "^1.1.10" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/typed-array-byte-length": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.0.tgz", - "integrity": "sha512-Or/+kvLxNpeQ9DtSydonMxCx+9ZXOswtwJn17SNLvhptaXYDJvkFFP5zbfU/uLmvnBJlI4yrnXRxpdWH/M5tNA==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "for-each": "^0.3.3", - "has-proto": "^1.0.1", - "is-typed-array": "^1.1.10" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/typed-array-byte-offset": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.0.tgz", - "integrity": "sha512-RD97prjEt9EL8YgAgpOkf3O4IF9lhJFr9g0htQkm0rchFp/Vx7LW5Q8fSXXub7BXAODyUQohRMyOc3faCPd0hg==", - "dev": true, - "dependencies": { - "available-typed-arrays": "^1.0.5", - "call-bind": "^1.0.2", - "for-each": "^0.3.3", - "has-proto": "^1.0.1", - "is-typed-array": "^1.1.10" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/typed-array-length": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.4.tgz", - "integrity": "sha512-KjZypGq+I/H7HI5HlOoGHkWUUGq+Q0TPhQurLbyrVrvnKTBgzLhIJ7j6J/XTQOi0d1RjyZ0wdas8bKs2p0x3Ng==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "for-each": "^0.3.3", - "is-typed-array": "^1.1.9" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/typedarray": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", - "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==", - "dev": true - }, - "node_modules/typedarray-to-buffer": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", - "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", - "dev": true, - "dependencies": { - "is-typedarray": "^1.0.0" - } - }, - "node_modules/typescript": { - "version": "4.9.5", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", - "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", - "dev": true, - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=4.2.0" - } - }, - "node_modules/typical": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/typical/-/typical-2.6.1.tgz", - "integrity": "sha512-ofhi8kjIje6npGozTip9Fr8iecmYfEbS06i0JnIg+rh51KakryWF4+jX8lLKZVhy6N+ID45WYSFCxPOdTWCzNg==", - "dev": true - }, - "node_modules/uglify-js": { - "version": "3.17.4", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.17.4.tgz", - "integrity": "sha512-T9q82TJI9e/C1TAxYvfb16xO120tMVFZrGA3f9/P4424DNu6ypK103y0GPFVa17yotwSyZW5iYXgjYHkGrJW/g==", - "dev": true, - "optional": true, - "bin": { - "uglifyjs": "bin/uglifyjs" - }, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/ultron": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ultron/-/ultron-1.1.1.tgz", - "integrity": "sha512-UIEXBNeYmKptWH6z8ZnqTeS8fV74zG0/eRU9VGkpzz+LIJNs8W/zM/L+7ctCkRrgbNnnR0xxw4bKOr0cW0N0Og==", - "dev": true - }, - "node_modules/unbox-primitive": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", - "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "has-bigints": "^1.0.2", - "has-symbols": "^1.0.3", - "which-boxed-primitive": "^1.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/undici": { - "version": "5.26.3", - "resolved": "https://registry.npmjs.org/undici/-/undici-5.26.3.tgz", - "integrity": "sha512-H7n2zmKEWgOllKkIUkLvFmsJQj062lSm3uA4EYApG8gLuiOM0/go9bIoC3HVaSnfg4xunowDE2i9p8drkXuvDw==", - "dev": true, - "dependencies": { - "@fastify/busboy": "^2.0.0" - }, - "engines": { - "node": ">=14.0" - } - }, - "node_modules/universalify": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", - "dev": true, - "engines": { - "node": ">= 4.0.0" - } - }, - "node_modules/unpipe": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", - "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", - "dev": true, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/uri-js": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", - "dev": true, - "dependencies": { - "punycode": "^2.1.0" - } - }, - "node_modules/url": { - "version": "0.11.1", - "resolved": "https://registry.npmjs.org/url/-/url-0.11.1.tgz", - "integrity": "sha512-rWS3H04/+mzzJkv0eZ7vEDGiQbgquI1fGfOad6zKvgYQi1SzMmhl7c/DdRGxhaWrVH6z0qWITo8rpnxK/RfEhA==", - "dev": true, - "dependencies": { - "punycode": "^1.4.1", - "qs": "^6.11.0" - } - }, - "node_modules/url-parse-lax": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-3.0.0.tgz", - "integrity": "sha512-NjFKA0DidqPa5ciFcSrXnAltTtzz84ogy+NebPvfEgAck0+TNg4UJ4IN+fB7zRZfbgUf0syOo9MDxFkDSMuFaQ==", - "dev": true, - "dependencies": { - "prepend-http": "^2.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/url-set-query": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/url-set-query/-/url-set-query-1.0.0.tgz", - "integrity": "sha512-3AChu4NiXquPfeckE5R5cGdiHCMWJx1dwCWOmWIL4KHAziJNOFIYJlpGFeKDvwLPHovZRCxK3cYlwzqI9Vp+Gg==", - "dev": true - }, - "node_modules/url/node_modules/punycode": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ==", - "dev": true - }, - "node_modules/url/node_modules/qs": { - "version": "6.11.2", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.2.tgz", - "integrity": "sha512-tDNIz22aBzCDxLtVH++VnTfzxlfeK5CbqohpSqpJgj1Wg/cQbStNAz3NuqCs5vV+pjBsK4x4pN9HlVh7rcYRiA==", - "dev": true, - "dependencies": { - "side-channel": "^1.0.4" - }, - "engines": { - "node": ">=0.6" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/utf-8-validate": { - "version": "5.0.10", - "resolved": "https://registry.npmjs.org/utf-8-validate/-/utf-8-validate-5.0.10.tgz", - "integrity": "sha512-Z6czzLq4u8fPOyx7TU6X3dvUZVvoJmxSQ+IcrlmagKhilxlhZgxPK6C5Jqbkw1IDUmFTM+cz9QDnnLTwDz/2gQ==", - "devOptional": true, - "hasInstallScript": true, - "dependencies": { - "node-gyp-build": "^4.3.0" - }, - "engines": { - "node": ">=6.14.2" - } - }, - "node_modules/utf8": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/utf8/-/utf8-3.0.0.tgz", - "integrity": "sha512-E8VjFIQ/TyQgp+TZfS6l8yp/xWppSAHzidGiRrqe4bK4XP9pTRyKFgGJpO3SN7zdX4DeomTrwaseCHovfpFcqQ==" - }, - "node_modules/util": { - "version": "0.12.5", - "resolved": "https://registry.npmjs.org/util/-/util-0.12.5.tgz", - "integrity": "sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA==", - "dev": true, - "dependencies": { - "inherits": "^2.0.3", - "is-arguments": "^1.0.4", - "is-generator-function": "^1.0.7", - "is-typed-array": "^1.1.3", - "which-typed-array": "^1.1.2" - } - }, - "node_modules/util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" - }, - "node_modules/utils-merge": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", - "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", - "dev": true, - "engines": { - "node": ">= 0.4.0" - } - }, - "node_modules/uuid": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", - "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", - "dev": true, - "bin": { - "uuid": "dist/bin/uuid" - } - }, - "node_modules/v8-compile-cache": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", - "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", - "dev": true - }, - "node_modules/v8-compile-cache-lib": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", - "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", - "dev": true - }, - "node_modules/validate-npm-package-license": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", - "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", - "dev": true, - "dependencies": { - "spdx-correct": "^3.0.0", - "spdx-expression-parse": "^3.0.0" - } - }, - "node_modules/varint": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/varint/-/varint-5.0.2.tgz", - "integrity": "sha512-lKxKYG6H03yCZUpAGOPOsMcGxd1RHCu1iKvEHYDPmTyq2HueGhD73ssNBqqQWfvYs04G9iUFRvmAVLW20Jw6ow==", - "dev": true - }, - "node_modules/vary": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", - "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", - "dev": true, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/verror": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", - "integrity": "sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw==", - "dev": true, - "engines": [ - "node >=0.6.0" - ], - "dependencies": { - "assert-plus": "^1.0.0", - "core-util-is": "1.0.2", - "extsprintf": "^1.2.0" - } - }, - "node_modules/web3": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/web3/-/web3-1.7.4.tgz", - "integrity": "sha512-iFGK5jO32vnXM/ASaJBaI0+gVR6uHozvYdxkdhaeOCD6HIQ4iIXadbO2atVpE9oc/H8l2MovJ4LtPhG7lIBN8A==", - "dev": true, - "hasInstallScript": true, - "dependencies": { - "web3-bzz": "1.7.4", - "web3-core": "1.7.4", - "web3-eth": "1.7.4", - "web3-eth-personal": "1.7.4", - "web3-net": "1.7.4", - "web3-shh": "1.7.4", - "web3-utils": "1.7.4" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3-bzz": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/web3-bzz/-/web3-bzz-1.7.4.tgz", - "integrity": "sha512-w9zRhyEqTK/yi0LGRHjZMcPCfP24LBjYXI/9YxFw9VqsIZ9/G0CRCnUt12lUx0A56LRAMpF7iQ8eA73aBcO29Q==", - "dev": true, - "hasInstallScript": true, - "dependencies": { - "@types/node": "^12.12.6", - "got": "9.6.0", - "swarm-js": "^0.1.40" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3-core": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/web3-core/-/web3-core-1.7.4.tgz", - "integrity": "sha512-L0DCPlIh9bgIED37tYbe7bsWrddoXYc897ANGvTJ6MFkSNGiMwDkTLWSgYd9Mf8qu8b4iuPqXZHMwIo4atoh7Q==", - "dev": true, - "dependencies": { - "@types/bn.js": "^5.1.0", - "@types/node": "^12.12.6", - "bignumber.js": "^9.0.0", - "web3-core-helpers": "1.7.4", - "web3-core-method": "1.7.4", - "web3-core-requestmanager": "1.7.4", - "web3-utils": "1.7.4" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3-core-helpers": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/web3-core-helpers/-/web3-core-helpers-1.7.4.tgz", - "integrity": "sha512-F8PH11qIkE/LpK4/h1fF/lGYgt4B6doeMi8rukeV/s4ivseZHHslv1L6aaijLX/g/j4PsFmR42byynBI/MIzFg==", - "dev": true, - "dependencies": { - "web3-eth-iban": "1.7.4", - "web3-utils": "1.7.4" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3-core-helpers/node_modules/ethereum-cryptography": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz", - "integrity": "sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==", - "dev": true, - "dependencies": { - "@types/pbkdf2": "^3.0.0", - "@types/secp256k1": "^4.0.1", - "blakejs": "^1.1.0", - "browserify-aes": "^1.2.0", - "bs58check": "^2.1.2", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "hash.js": "^1.1.7", - "keccak": "^3.0.0", - "pbkdf2": "^3.0.17", - "randombytes": "^2.1.0", - "safe-buffer": "^5.1.2", - "scrypt-js": "^3.0.0", - "secp256k1": "^4.0.1", - "setimmediate": "^1.0.5" - } - }, - "node_modules/web3-core-helpers/node_modules/ethereumjs-util": { - "version": "7.1.5", - "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-7.1.5.tgz", - "integrity": "sha512-SDl5kKrQAudFBUe5OJM9Ac6WmMyYmXX/6sTmLZ3ffG2eY6ZIGBes3pEDxNN6V72WyOw4CPD5RomKdsa8DAAwLg==", - "dev": true, - "dependencies": { - "@types/bn.js": "^5.1.0", - "bn.js": "^5.1.2", - "create-hash": "^1.1.2", - "ethereum-cryptography": "^0.1.3", - "rlp": "^2.2.4" - }, - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/web3-core-helpers/node_modules/web3-utils": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.7.4.tgz", - "integrity": "sha512-acBdm6Evd0TEZRnChM/MCvGsMwYKmSh7OaUfNf5OKG0CIeGWD/6gqLOWIwmwSnre/2WrA1nKGId5uW2e5EfluA==", - "dev": true, - "dependencies": { - "bn.js": "^5.2.1", - "ethereum-bloom-filters": "^1.0.6", - "ethereumjs-util": "^7.1.0", - "ethjs-unit": "0.1.6", - "number-to-bn": "1.7.0", - "randombytes": "^2.1.0", - "utf8": "3.0.0" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3-core-method": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/web3-core-method/-/web3-core-method-1.7.4.tgz", - "integrity": "sha512-56K7pq+8lZRkxJyzf5MHQPI9/VL3IJLoy4L/+q8HRdZJ3CkB1DkXYaXGU2PeylG1GosGiSzgIfu1ljqS7CP9xQ==", - "dev": true, - "dependencies": { - "@ethersproject/transactions": "^5.6.2", - "web3-core-helpers": "1.7.4", - "web3-core-promievent": "1.7.4", - "web3-core-subscriptions": "1.7.4", - "web3-utils": "1.7.4" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3-core-method/node_modules/ethereum-cryptography": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz", - "integrity": "sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==", - "dev": true, - "dependencies": { - "@types/pbkdf2": "^3.0.0", - "@types/secp256k1": "^4.0.1", - "blakejs": "^1.1.0", - "browserify-aes": "^1.2.0", - "bs58check": "^2.1.2", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "hash.js": "^1.1.7", - "keccak": "^3.0.0", - "pbkdf2": "^3.0.17", - "randombytes": "^2.1.0", - "safe-buffer": "^5.1.2", - "scrypt-js": "^3.0.0", - "secp256k1": "^4.0.1", - "setimmediate": "^1.0.5" - } - }, - "node_modules/web3-core-method/node_modules/ethereumjs-util": { - "version": "7.1.5", - "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-7.1.5.tgz", - "integrity": "sha512-SDl5kKrQAudFBUe5OJM9Ac6WmMyYmXX/6sTmLZ3ffG2eY6ZIGBes3pEDxNN6V72WyOw4CPD5RomKdsa8DAAwLg==", - "dev": true, - "dependencies": { - "@types/bn.js": "^5.1.0", - "bn.js": "^5.1.2", - "create-hash": "^1.1.2", - "ethereum-cryptography": "^0.1.3", - "rlp": "^2.2.4" - }, - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/web3-core-method/node_modules/web3-utils": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.7.4.tgz", - "integrity": "sha512-acBdm6Evd0TEZRnChM/MCvGsMwYKmSh7OaUfNf5OKG0CIeGWD/6gqLOWIwmwSnre/2WrA1nKGId5uW2e5EfluA==", - "dev": true, - "dependencies": { - "bn.js": "^5.2.1", - "ethereum-bloom-filters": "^1.0.6", - "ethereumjs-util": "^7.1.0", - "ethjs-unit": "0.1.6", - "number-to-bn": "1.7.0", - "randombytes": "^2.1.0", - "utf8": "3.0.0" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3-core-promievent": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/web3-core-promievent/-/web3-core-promievent-1.7.4.tgz", - "integrity": "sha512-o4uxwXKDldN7ER7VUvDfWsqTx9nQSP1aDssi1XYXeYC2xJbVo0n+z6ryKtmcoWoRdRj7uSpVzal3nEmlr480mA==", - "dev": true, - "dependencies": { - "eventemitter3": "4.0.4" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3-core-requestmanager": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/web3-core-requestmanager/-/web3-core-requestmanager-1.7.4.tgz", - "integrity": "sha512-IuXdAm65BQtPL4aI6LZJJOrKAs0SM5IK2Cqo2/lMNvVMT9Kssq6qOk68Uf7EBDH0rPuINi+ReLP+uH+0g3AnPA==", - "dev": true, - "dependencies": { - "util": "^0.12.0", - "web3-core-helpers": "1.7.4", - "web3-providers-http": "1.7.4", - "web3-providers-ipc": "1.7.4", - "web3-providers-ws": "1.7.4" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3-core-subscriptions": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/web3-core-subscriptions/-/web3-core-subscriptions-1.7.4.tgz", - "integrity": "sha512-VJvKWaXRyxk2nFWumOR94ut9xvjzMrRtS38c4qj8WBIRSsugrZr5lqUwgndtj0qx4F+50JhnU++QEqUEAtKm3g==", - "dev": true, - "dependencies": { - "eventemitter3": "4.0.4", - "web3-core-helpers": "1.7.4" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3-core/node_modules/ethereum-cryptography": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz", - "integrity": "sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==", - "dev": true, - "dependencies": { - "@types/pbkdf2": "^3.0.0", - "@types/secp256k1": "^4.0.1", - "blakejs": "^1.1.0", - "browserify-aes": "^1.2.0", - "bs58check": "^2.1.2", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "hash.js": "^1.1.7", - "keccak": "^3.0.0", - "pbkdf2": "^3.0.17", - "randombytes": "^2.1.0", - "safe-buffer": "^5.1.2", - "scrypt-js": "^3.0.0", - "secp256k1": "^4.0.1", - "setimmediate": "^1.0.5" - } - }, - "node_modules/web3-core/node_modules/ethereumjs-util": { - "version": "7.1.5", - "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-7.1.5.tgz", - "integrity": "sha512-SDl5kKrQAudFBUe5OJM9Ac6WmMyYmXX/6sTmLZ3ffG2eY6ZIGBes3pEDxNN6V72WyOw4CPD5RomKdsa8DAAwLg==", - "dev": true, - "dependencies": { - "@types/bn.js": "^5.1.0", - "bn.js": "^5.1.2", - "create-hash": "^1.1.2", - "ethereum-cryptography": "^0.1.3", - "rlp": "^2.2.4" - }, - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/web3-core/node_modules/web3-utils": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.7.4.tgz", - "integrity": "sha512-acBdm6Evd0TEZRnChM/MCvGsMwYKmSh7OaUfNf5OKG0CIeGWD/6gqLOWIwmwSnre/2WrA1nKGId5uW2e5EfluA==", - "dev": true, - "dependencies": { - "bn.js": "^5.2.1", - "ethereum-bloom-filters": "^1.0.6", - "ethereumjs-util": "^7.1.0", - "ethjs-unit": "0.1.6", - "number-to-bn": "1.7.0", - "randombytes": "^2.1.0", - "utf8": "3.0.0" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3-eth": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/web3-eth/-/web3-eth-1.7.4.tgz", - "integrity": "sha512-JG0tTMv0Ijj039emXNHi07jLb0OiWSA9O24MRSk5vToTQyDNXihdF2oyq85LfHuF690lXZaAXrjhtLNlYqb7Ug==", - "dev": true, - "dependencies": { - "web3-core": "1.7.4", - "web3-core-helpers": "1.7.4", - "web3-core-method": "1.7.4", - "web3-core-subscriptions": "1.7.4", - "web3-eth-abi": "1.7.4", - "web3-eth-accounts": "1.7.4", - "web3-eth-contract": "1.7.4", - "web3-eth-ens": "1.7.4", - "web3-eth-iban": "1.7.4", - "web3-eth-personal": "1.7.4", - "web3-net": "1.7.4", - "web3-utils": "1.7.4" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3-eth-abi": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/web3-eth-abi/-/web3-eth-abi-1.7.4.tgz", - "integrity": "sha512-eMZr8zgTbqyL9MCTCAvb67RbVyN5ZX7DvA0jbLOqRWCiw+KlJKTGnymKO6jPE8n5yjk4w01e165Qb11hTDwHgg==", - "dev": true, - "dependencies": { - "@ethersproject/abi": "^5.6.3", - "web3-utils": "1.7.4" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3-eth-abi/node_modules/ethereum-cryptography": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz", - "integrity": "sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==", - "dev": true, - "dependencies": { - "@types/pbkdf2": "^3.0.0", - "@types/secp256k1": "^4.0.1", - "blakejs": "^1.1.0", - "browserify-aes": "^1.2.0", - "bs58check": "^2.1.2", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "hash.js": "^1.1.7", - "keccak": "^3.0.0", - "pbkdf2": "^3.0.17", - "randombytes": "^2.1.0", - "safe-buffer": "^5.1.2", - "scrypt-js": "^3.0.0", - "secp256k1": "^4.0.1", - "setimmediate": "^1.0.5" - } - }, - "node_modules/web3-eth-abi/node_modules/ethereumjs-util": { - "version": "7.1.5", - "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-7.1.5.tgz", - "integrity": "sha512-SDl5kKrQAudFBUe5OJM9Ac6WmMyYmXX/6sTmLZ3ffG2eY6ZIGBes3pEDxNN6V72WyOw4CPD5RomKdsa8DAAwLg==", - "dev": true, - "dependencies": { - "@types/bn.js": "^5.1.0", - "bn.js": "^5.1.2", - "create-hash": "^1.1.2", - "ethereum-cryptography": "^0.1.3", - "rlp": "^2.2.4" - }, - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/web3-eth-abi/node_modules/web3-utils": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.7.4.tgz", - "integrity": "sha512-acBdm6Evd0TEZRnChM/MCvGsMwYKmSh7OaUfNf5OKG0CIeGWD/6gqLOWIwmwSnre/2WrA1nKGId5uW2e5EfluA==", - "dev": true, - "dependencies": { - "bn.js": "^5.2.1", - "ethereum-bloom-filters": "^1.0.6", - "ethereumjs-util": "^7.1.0", - "ethjs-unit": "0.1.6", - "number-to-bn": "1.7.0", - "randombytes": "^2.1.0", - "utf8": "3.0.0" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3-eth-accounts": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/web3-eth-accounts/-/web3-eth-accounts-1.7.4.tgz", - "integrity": "sha512-Y9vYLRKP7VU7Cgq6wG1jFaG2k3/eIuiTKAG8RAuQnb6Cd9k5BRqTm5uPIiSo0AP/u11jDomZ8j7+WEgkU9+Btw==", - "dev": true, - "dependencies": { - "@ethereumjs/common": "^2.5.0", - "@ethereumjs/tx": "^3.3.2", - "crypto-browserify": "3.12.0", - "eth-lib": "0.2.8", - "ethereumjs-util": "^7.0.10", - "scrypt-js": "^3.0.1", - "uuid": "3.3.2", - "web3-core": "1.7.4", - "web3-core-helpers": "1.7.4", - "web3-core-method": "1.7.4", - "web3-utils": "1.7.4" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3-eth-accounts/node_modules/eth-lib": { - "version": "0.2.8", - "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.2.8.tgz", - "integrity": "sha512-ArJ7x1WcWOlSpzdoTBX8vkwlkSQ85CjjifSZtV4co64vWxSV8geWfPI9x4SVYu3DSxnX4yWFVTtGL+j9DUFLNw==", - "dev": true, - "dependencies": { - "bn.js": "^4.11.6", - "elliptic": "^6.4.0", - "xhr-request-promise": "^0.1.2" - } - }, - "node_modules/web3-eth-accounts/node_modules/eth-lib/node_modules/bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", - "dev": true - }, - "node_modules/web3-eth-accounts/node_modules/ethereum-cryptography": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz", - "integrity": "sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==", - "dev": true, - "dependencies": { - "@types/pbkdf2": "^3.0.0", - "@types/secp256k1": "^4.0.1", - "blakejs": "^1.1.0", - "browserify-aes": "^1.2.0", - "bs58check": "^2.1.2", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "hash.js": "^1.1.7", - "keccak": "^3.0.0", - "pbkdf2": "^3.0.17", - "randombytes": "^2.1.0", - "safe-buffer": "^5.1.2", - "scrypt-js": "^3.0.0", - "secp256k1": "^4.0.1", - "setimmediate": "^1.0.5" - } - }, - "node_modules/web3-eth-accounts/node_modules/ethereumjs-util": { - "version": "7.1.5", - "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-7.1.5.tgz", - "integrity": "sha512-SDl5kKrQAudFBUe5OJM9Ac6WmMyYmXX/6sTmLZ3ffG2eY6ZIGBes3pEDxNN6V72WyOw4CPD5RomKdsa8DAAwLg==", - "dev": true, - "dependencies": { - "@types/bn.js": "^5.1.0", - "bn.js": "^5.1.2", - "create-hash": "^1.1.2", - "ethereum-cryptography": "^0.1.3", - "rlp": "^2.2.4" - }, - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/web3-eth-accounts/node_modules/uuid": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", - "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==", - "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", - "dev": true, - "bin": { - "uuid": "bin/uuid" - } - }, - "node_modules/web3-eth-accounts/node_modules/web3-utils": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.7.4.tgz", - "integrity": "sha512-acBdm6Evd0TEZRnChM/MCvGsMwYKmSh7OaUfNf5OKG0CIeGWD/6gqLOWIwmwSnre/2WrA1nKGId5uW2e5EfluA==", - "dev": true, - "dependencies": { - "bn.js": "^5.2.1", - "ethereum-bloom-filters": "^1.0.6", - "ethereumjs-util": "^7.1.0", - "ethjs-unit": "0.1.6", - "number-to-bn": "1.7.0", - "randombytes": "^2.1.0", - "utf8": "3.0.0" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3-eth-contract": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/web3-eth-contract/-/web3-eth-contract-1.7.4.tgz", - "integrity": "sha512-ZgSZMDVI1pE9uMQpK0T0HDT2oewHcfTCv0osEqf5qyn5KrcQDg1GT96/+S0dfqZ4HKj4lzS5O0rFyQiLPQ8LzQ==", - "dev": true, - "dependencies": { - "@types/bn.js": "^5.1.0", - "web3-core": "1.7.4", - "web3-core-helpers": "1.7.4", - "web3-core-method": "1.7.4", - "web3-core-promievent": "1.7.4", - "web3-core-subscriptions": "1.7.4", - "web3-eth-abi": "1.7.4", - "web3-utils": "1.7.4" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3-eth-contract/node_modules/ethereum-cryptography": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz", - "integrity": "sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==", - "dev": true, - "dependencies": { - "@types/pbkdf2": "^3.0.0", - "@types/secp256k1": "^4.0.1", - "blakejs": "^1.1.0", - "browserify-aes": "^1.2.0", - "bs58check": "^2.1.2", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "hash.js": "^1.1.7", - "keccak": "^3.0.0", - "pbkdf2": "^3.0.17", - "randombytes": "^2.1.0", - "safe-buffer": "^5.1.2", - "scrypt-js": "^3.0.0", - "secp256k1": "^4.0.1", - "setimmediate": "^1.0.5" - } - }, - "node_modules/web3-eth-contract/node_modules/ethereumjs-util": { - "version": "7.1.5", - "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-7.1.5.tgz", - "integrity": "sha512-SDl5kKrQAudFBUe5OJM9Ac6WmMyYmXX/6sTmLZ3ffG2eY6ZIGBes3pEDxNN6V72WyOw4CPD5RomKdsa8DAAwLg==", - "dev": true, - "dependencies": { - "@types/bn.js": "^5.1.0", - "bn.js": "^5.1.2", - "create-hash": "^1.1.2", - "ethereum-cryptography": "^0.1.3", - "rlp": "^2.2.4" - }, - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/web3-eth-contract/node_modules/web3-utils": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.7.4.tgz", - "integrity": "sha512-acBdm6Evd0TEZRnChM/MCvGsMwYKmSh7OaUfNf5OKG0CIeGWD/6gqLOWIwmwSnre/2WrA1nKGId5uW2e5EfluA==", - "dev": true, - "dependencies": { - "bn.js": "^5.2.1", - "ethereum-bloom-filters": "^1.0.6", - "ethereumjs-util": "^7.1.0", - "ethjs-unit": "0.1.6", - "number-to-bn": "1.7.0", - "randombytes": "^2.1.0", - "utf8": "3.0.0" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3-eth-ens": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/web3-eth-ens/-/web3-eth-ens-1.7.4.tgz", - "integrity": "sha512-Gw5CVU1+bFXP5RVXTCqJOmHn71X2ghNk9VcEH+9PchLr0PrKbHTA3hySpsPco1WJAyK4t8SNQVlNr3+bJ6/WZA==", - "dev": true, - "dependencies": { - "content-hash": "^2.5.2", - "eth-ens-namehash": "2.0.8", - "web3-core": "1.7.4", - "web3-core-helpers": "1.7.4", - "web3-core-promievent": "1.7.4", - "web3-eth-abi": "1.7.4", - "web3-eth-contract": "1.7.4", - "web3-utils": "1.7.4" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3-eth-ens/node_modules/ethereum-cryptography": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz", - "integrity": "sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==", - "dev": true, - "dependencies": { - "@types/pbkdf2": "^3.0.0", - "@types/secp256k1": "^4.0.1", - "blakejs": "^1.1.0", - "browserify-aes": "^1.2.0", - "bs58check": "^2.1.2", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "hash.js": "^1.1.7", - "keccak": "^3.0.0", - "pbkdf2": "^3.0.17", - "randombytes": "^2.1.0", - "safe-buffer": "^5.1.2", - "scrypt-js": "^3.0.0", - "secp256k1": "^4.0.1", - "setimmediate": "^1.0.5" - } - }, - "node_modules/web3-eth-ens/node_modules/ethereumjs-util": { - "version": "7.1.5", - "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-7.1.5.tgz", - "integrity": "sha512-SDl5kKrQAudFBUe5OJM9Ac6WmMyYmXX/6sTmLZ3ffG2eY6ZIGBes3pEDxNN6V72WyOw4CPD5RomKdsa8DAAwLg==", - "dev": true, - "dependencies": { - "@types/bn.js": "^5.1.0", - "bn.js": "^5.1.2", - "create-hash": "^1.1.2", - "ethereum-cryptography": "^0.1.3", - "rlp": "^2.2.4" - }, - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/web3-eth-ens/node_modules/web3-utils": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.7.4.tgz", - "integrity": "sha512-acBdm6Evd0TEZRnChM/MCvGsMwYKmSh7OaUfNf5OKG0CIeGWD/6gqLOWIwmwSnre/2WrA1nKGId5uW2e5EfluA==", - "dev": true, - "dependencies": { - "bn.js": "^5.2.1", - "ethereum-bloom-filters": "^1.0.6", - "ethereumjs-util": "^7.1.0", - "ethjs-unit": "0.1.6", - "number-to-bn": "1.7.0", - "randombytes": "^2.1.0", - "utf8": "3.0.0" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3-eth-iban": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/web3-eth-iban/-/web3-eth-iban-1.7.4.tgz", - "integrity": "sha512-XyrsgWlZQMv5gRcjXMsNvAoCRvV5wN7YCfFV5+tHUCqN8g9T/o4XUS20vDWD0k4HNiAcWGFqT1nrls02MGZ08w==", - "dev": true, - "dependencies": { - "bn.js": "^5.2.1", - "web3-utils": "1.7.4" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3-eth-iban/node_modules/ethereum-cryptography": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz", - "integrity": "sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==", - "dev": true, - "dependencies": { - "@types/pbkdf2": "^3.0.0", - "@types/secp256k1": "^4.0.1", - "blakejs": "^1.1.0", - "browserify-aes": "^1.2.0", - "bs58check": "^2.1.2", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "hash.js": "^1.1.7", - "keccak": "^3.0.0", - "pbkdf2": "^3.0.17", - "randombytes": "^2.1.0", - "safe-buffer": "^5.1.2", - "scrypt-js": "^3.0.0", - "secp256k1": "^4.0.1", - "setimmediate": "^1.0.5" - } - }, - "node_modules/web3-eth-iban/node_modules/ethereumjs-util": { - "version": "7.1.5", - "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-7.1.5.tgz", - "integrity": "sha512-SDl5kKrQAudFBUe5OJM9Ac6WmMyYmXX/6sTmLZ3ffG2eY6ZIGBes3pEDxNN6V72WyOw4CPD5RomKdsa8DAAwLg==", - "dev": true, - "dependencies": { - "@types/bn.js": "^5.1.0", - "bn.js": "^5.1.2", - "create-hash": "^1.1.2", - "ethereum-cryptography": "^0.1.3", - "rlp": "^2.2.4" - }, - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/web3-eth-iban/node_modules/web3-utils": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.7.4.tgz", - "integrity": "sha512-acBdm6Evd0TEZRnChM/MCvGsMwYKmSh7OaUfNf5OKG0CIeGWD/6gqLOWIwmwSnre/2WrA1nKGId5uW2e5EfluA==", - "dev": true, - "dependencies": { - "bn.js": "^5.2.1", - "ethereum-bloom-filters": "^1.0.6", - "ethereumjs-util": "^7.1.0", - "ethjs-unit": "0.1.6", - "number-to-bn": "1.7.0", - "randombytes": "^2.1.0", - "utf8": "3.0.0" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3-eth-personal": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/web3-eth-personal/-/web3-eth-personal-1.7.4.tgz", - "integrity": "sha512-O10C1Hln5wvLQsDhlhmV58RhXo+GPZ5+W76frSsyIrkJWLtYQTCr5WxHtRC9sMD1idXLqODKKgI2DL+7xeZ0/g==", - "dev": true, - "dependencies": { - "@types/node": "^12.12.6", - "web3-core": "1.7.4", - "web3-core-helpers": "1.7.4", - "web3-core-method": "1.7.4", - "web3-net": "1.7.4", - "web3-utils": "1.7.4" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3-eth-personal/node_modules/ethereum-cryptography": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz", - "integrity": "sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==", - "dev": true, - "dependencies": { - "@types/pbkdf2": "^3.0.0", - "@types/secp256k1": "^4.0.1", - "blakejs": "^1.1.0", - "browserify-aes": "^1.2.0", - "bs58check": "^2.1.2", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "hash.js": "^1.1.7", - "keccak": "^3.0.0", - "pbkdf2": "^3.0.17", - "randombytes": "^2.1.0", - "safe-buffer": "^5.1.2", - "scrypt-js": "^3.0.0", - "secp256k1": "^4.0.1", - "setimmediate": "^1.0.5" - } - }, - "node_modules/web3-eth-personal/node_modules/ethereumjs-util": { - "version": "7.1.5", - "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-7.1.5.tgz", - "integrity": "sha512-SDl5kKrQAudFBUe5OJM9Ac6WmMyYmXX/6sTmLZ3ffG2eY6ZIGBes3pEDxNN6V72WyOw4CPD5RomKdsa8DAAwLg==", - "dev": true, - "dependencies": { - "@types/bn.js": "^5.1.0", - "bn.js": "^5.1.2", - "create-hash": "^1.1.2", - "ethereum-cryptography": "^0.1.3", - "rlp": "^2.2.4" - }, - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/web3-eth-personal/node_modules/web3-utils": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.7.4.tgz", - "integrity": "sha512-acBdm6Evd0TEZRnChM/MCvGsMwYKmSh7OaUfNf5OKG0CIeGWD/6gqLOWIwmwSnre/2WrA1nKGId5uW2e5EfluA==", - "dev": true, - "dependencies": { - "bn.js": "^5.2.1", - "ethereum-bloom-filters": "^1.0.6", - "ethereumjs-util": "^7.1.0", - "ethjs-unit": "0.1.6", - "number-to-bn": "1.7.0", - "randombytes": "^2.1.0", - "utf8": "3.0.0" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3-eth/node_modules/ethereum-cryptography": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz", - "integrity": "sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==", - "dev": true, - "dependencies": { - "@types/pbkdf2": "^3.0.0", - "@types/secp256k1": "^4.0.1", - "blakejs": "^1.1.0", - "browserify-aes": "^1.2.0", - "bs58check": "^2.1.2", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "hash.js": "^1.1.7", - "keccak": "^3.0.0", - "pbkdf2": "^3.0.17", - "randombytes": "^2.1.0", - "safe-buffer": "^5.1.2", - "scrypt-js": "^3.0.0", - "secp256k1": "^4.0.1", - "setimmediate": "^1.0.5" - } - }, - "node_modules/web3-eth/node_modules/ethereumjs-util": { - "version": "7.1.5", - "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-7.1.5.tgz", - "integrity": "sha512-SDl5kKrQAudFBUe5OJM9Ac6WmMyYmXX/6sTmLZ3ffG2eY6ZIGBes3pEDxNN6V72WyOw4CPD5RomKdsa8DAAwLg==", - "dev": true, - "dependencies": { - "@types/bn.js": "^5.1.0", - "bn.js": "^5.1.2", - "create-hash": "^1.1.2", - "ethereum-cryptography": "^0.1.3", - "rlp": "^2.2.4" - }, - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/web3-eth/node_modules/web3-utils": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.7.4.tgz", - "integrity": "sha512-acBdm6Evd0TEZRnChM/MCvGsMwYKmSh7OaUfNf5OKG0CIeGWD/6gqLOWIwmwSnre/2WrA1nKGId5uW2e5EfluA==", - "dev": true, - "dependencies": { - "bn.js": "^5.2.1", - "ethereum-bloom-filters": "^1.0.6", - "ethereumjs-util": "^7.1.0", - "ethjs-unit": "0.1.6", - "number-to-bn": "1.7.0", - "randombytes": "^2.1.0", - "utf8": "3.0.0" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3-net": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/web3-net/-/web3-net-1.7.4.tgz", - "integrity": "sha512-d2Gj+DIARHvwIdmxFQ4PwAAXZVxYCR2lET0cxz4KXbE5Og3DNjJi+MoPkX+WqoUXqimu/EOd4Cd+7gefqVAFDg==", - "dev": true, - "dependencies": { - "web3-core": "1.7.4", - "web3-core-method": "1.7.4", - "web3-utils": "1.7.4" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3-net/node_modules/ethereum-cryptography": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz", - "integrity": "sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==", - "dev": true, - "dependencies": { - "@types/pbkdf2": "^3.0.0", - "@types/secp256k1": "^4.0.1", - "blakejs": "^1.1.0", - "browserify-aes": "^1.2.0", - "bs58check": "^2.1.2", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "hash.js": "^1.1.7", - "keccak": "^3.0.0", - "pbkdf2": "^3.0.17", - "randombytes": "^2.1.0", - "safe-buffer": "^5.1.2", - "scrypt-js": "^3.0.0", - "secp256k1": "^4.0.1", - "setimmediate": "^1.0.5" - } - }, - "node_modules/web3-net/node_modules/ethereumjs-util": { - "version": "7.1.5", - "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-7.1.5.tgz", - "integrity": "sha512-SDl5kKrQAudFBUe5OJM9Ac6WmMyYmXX/6sTmLZ3ffG2eY6ZIGBes3pEDxNN6V72WyOw4CPD5RomKdsa8DAAwLg==", - "dev": true, - "dependencies": { - "@types/bn.js": "^5.1.0", - "bn.js": "^5.1.2", - "create-hash": "^1.1.2", - "ethereum-cryptography": "^0.1.3", - "rlp": "^2.2.4" - }, - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/web3-net/node_modules/web3-utils": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.7.4.tgz", - "integrity": "sha512-acBdm6Evd0TEZRnChM/MCvGsMwYKmSh7OaUfNf5OKG0CIeGWD/6gqLOWIwmwSnre/2WrA1nKGId5uW2e5EfluA==", - "dev": true, - "dependencies": { - "bn.js": "^5.2.1", - "ethereum-bloom-filters": "^1.0.6", - "ethereumjs-util": "^7.1.0", - "ethjs-unit": "0.1.6", - "number-to-bn": "1.7.0", - "randombytes": "^2.1.0", - "utf8": "3.0.0" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3-providers-http": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/web3-providers-http/-/web3-providers-http-1.7.4.tgz", - "integrity": "sha512-AU+/S+49rcogUER99TlhW+UBMk0N2DxvN54CJ2pK7alc2TQ7+cprNPLHJu4KREe8ndV0fT6JtWUfOMyTvl+FRA==", - "dev": true, - "dependencies": { - "web3-core-helpers": "1.7.4", - "xhr2-cookies": "1.1.0" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3-providers-ipc": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/web3-providers-ipc/-/web3-providers-ipc-1.7.4.tgz", - "integrity": "sha512-jhArOZ235dZy8fS8090t60nTxbd1ap92ibQw5xIrAQ9m7LcZKNfmLAQUVsD+3dTFvadRMi6z1vCO7zRi84gWHw==", - "dev": true, - "dependencies": { - "oboe": "2.1.5", - "web3-core-helpers": "1.7.4" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3-providers-ws": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/web3-providers-ws/-/web3-providers-ws-1.7.4.tgz", - "integrity": "sha512-g72X77nrcHMFU8hRzQJzfgi/072n8dHwRCoTw+WQrGp+XCQ71fsk2qIu3Tp+nlp5BPn8bRudQbPblVm2uT4myQ==", - "dev": true, - "dependencies": { - "eventemitter3": "4.0.4", - "web3-core-helpers": "1.7.4", - "websocket": "^1.0.32" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3-shh": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/web3-shh/-/web3-shh-1.7.4.tgz", - "integrity": "sha512-mlSZxSYcMkuMCxqhTYnZkUdahZ11h+bBv/8TlkXp/IHpEe4/Gg+KAbmfudakq3EzG/04z70XQmPgWcUPrsEJ+A==", - "dev": true, - "hasInstallScript": true, - "dependencies": { - "web3-core": "1.7.4", - "web3-core-method": "1.7.4", - "web3-core-subscriptions": "1.7.4", - "web3-net": "1.7.4" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3-utils": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.10.0.tgz", - "integrity": "sha512-kSaCM0uMcZTNUSmn5vMEhlo02RObGNRRCkdX0V9UTAU0+lrvn0HSaudyCo6CQzuXUsnuY2ERJGCGPfeWmv19Rg==", - "dependencies": { - "bn.js": "^5.2.1", - "ethereum-bloom-filters": "^1.0.6", - "ethereumjs-util": "^7.1.0", - "ethjs-unit": "0.1.6", - "number-to-bn": "1.7.0", - "randombytes": "^2.1.0", - "utf8": "3.0.0" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3-utils/node_modules/ethereum-cryptography": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz", - "integrity": "sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==", - "dependencies": { - "@types/pbkdf2": "^3.0.0", - "@types/secp256k1": "^4.0.1", - "blakejs": "^1.1.0", - "browserify-aes": "^1.2.0", - "bs58check": "^2.1.2", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "hash.js": "^1.1.7", - "keccak": "^3.0.0", - "pbkdf2": "^3.0.17", - "randombytes": "^2.1.0", - "safe-buffer": "^5.1.2", - "scrypt-js": "^3.0.0", - "secp256k1": "^4.0.1", - "setimmediate": "^1.0.5" - } - }, - "node_modules/web3-utils/node_modules/ethereumjs-util": { - "version": "7.1.5", - "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-7.1.5.tgz", - "integrity": "sha512-SDl5kKrQAudFBUe5OJM9Ac6WmMyYmXX/6sTmLZ3ffG2eY6ZIGBes3pEDxNN6V72WyOw4CPD5RomKdsa8DAAwLg==", - "dependencies": { - "@types/bn.js": "^5.1.0", - "bn.js": "^5.1.2", - "create-hash": "^1.1.2", - "ethereum-cryptography": "^0.1.3", - "rlp": "^2.2.4" - }, - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/web3/node_modules/ethereum-cryptography": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz", - "integrity": "sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==", - "dev": true, - "dependencies": { - "@types/pbkdf2": "^3.0.0", - "@types/secp256k1": "^4.0.1", - "blakejs": "^1.1.0", - "browserify-aes": "^1.2.0", - "bs58check": "^2.1.2", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "hash.js": "^1.1.7", - "keccak": "^3.0.0", - "pbkdf2": "^3.0.17", - "randombytes": "^2.1.0", - "safe-buffer": "^5.1.2", - "scrypt-js": "^3.0.0", - "secp256k1": "^4.0.1", - "setimmediate": "^1.0.5" - } - }, - "node_modules/web3/node_modules/ethereumjs-util": { - "version": "7.1.5", - "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-7.1.5.tgz", - "integrity": "sha512-SDl5kKrQAudFBUe5OJM9Ac6WmMyYmXX/6sTmLZ3ffG2eY6ZIGBes3pEDxNN6V72WyOw4CPD5RomKdsa8DAAwLg==", - "dev": true, - "dependencies": { - "@types/bn.js": "^5.1.0", - "bn.js": "^5.1.2", - "create-hash": "^1.1.2", - "ethereum-cryptography": "^0.1.3", - "rlp": "^2.2.4" - }, - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/web3/node_modules/web3-utils": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.7.4.tgz", - "integrity": "sha512-acBdm6Evd0TEZRnChM/MCvGsMwYKmSh7OaUfNf5OKG0CIeGWD/6gqLOWIwmwSnre/2WrA1nKGId5uW2e5EfluA==", - "dev": true, - "dependencies": { - "bn.js": "^5.2.1", - "ethereum-bloom-filters": "^1.0.6", - "ethereumjs-util": "^7.1.0", - "ethjs-unit": "0.1.6", - "number-to-bn": "1.7.0", - "randombytes": "^2.1.0", - "utf8": "3.0.0" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/webidl-conversions": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", - "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" - }, - "node_modules/websocket": { - "version": "1.0.34", - "resolved": "https://registry.npmjs.org/websocket/-/websocket-1.0.34.tgz", - "integrity": "sha512-PRDso2sGwF6kM75QykIesBijKSVceR6jL2G8NGYyq2XrItNC2P5/qL5XeR056GhA+Ly7JMFvJb9I312mJfmqnQ==", - "dev": true, - "dependencies": { - "bufferutil": "^4.0.1", - "debug": "^2.2.0", - "es5-ext": "^0.10.50", - "typedarray-to-buffer": "^3.1.5", - "utf-8-validate": "^5.0.2", - "yaeti": "^0.0.6" - }, - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/websocket/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/websocket/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true - }, - "node_modules/whatwg-url": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", - "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", - "dependencies": { - "tr46": "~0.0.3", - "webidl-conversions": "^3.0.0" - } - }, - "node_modules/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/which-boxed-primitive": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", - "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", - "dev": true, - "dependencies": { - "is-bigint": "^1.0.1", - "is-boolean-object": "^1.1.0", - "is-number-object": "^1.0.4", - "is-string": "^1.0.5", - "is-symbol": "^1.0.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/which-module": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-1.0.0.tgz", - "integrity": "sha512-F6+WgncZi/mJDrammbTuHe1q0R5hOXv/mBaiNA2TCNT/LTHusX0V+CJnj9XT8ki5ln2UZyyddDgHfCzyrOH7MQ==", - "dev": true - }, - "node_modules/which-typed-array": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.11.tgz", - "integrity": "sha512-qe9UWWpkeG5yzZ0tNYxDmd7vo58HDBc39mZ0xWWpolAGADdFOzkfamWLDxkOWcvHQKVmdTyQdLD4NOfjLWTKew==", - "dev": true, - "dependencies": { - "available-typed-arrays": "^1.0.5", - "call-bind": "^1.0.2", - "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/wide-align": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", - "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", - "dev": true, - "dependencies": { - "string-width": "^1.0.2 || 2" - } - }, - "node_modules/window-size": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.2.0.tgz", - "integrity": "sha512-UD7d8HFA2+PZsbKyaOCEy8gMh1oDtHgJh1LfgjQ4zVXmYjAT/kvz3PueITKuqDiIXQe7yzpPnxX3lNc+AhQMyw==", - "dev": true, - "bin": { - "window-size": "cli.js" - }, - "engines": { - "node": ">= 0.10.0" - } - }, - "node_modules/word-wrap": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.4.tgz", - "integrity": "sha512-2V81OA4ugVo5pRo46hAoD2ivUJx8jXmWXfUkY4KFNw0hEptvN0QfH3K4nHiwzGeKl5rFKedV48QVoqYavy4YpA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/wordwrap": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", - "integrity": "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==", - "dev": true - }, - "node_modules/workerpool": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.2.1.tgz", - "integrity": "sha512-ILEIE97kDZvF9Wb9f6h5aXK4swSlKGUcOEGiIYb2OOu/IrDU9iwj0fD//SsA6E5ibwJxpEvhullJY4Sl4GcpAw==", - "dev": true - }, - "node_modules/wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, - "node_modules/wrap-ansi/node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/wrap-ansi/node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", - "dev": true - }, - "node_modules/ws": { - "version": "7.4.6", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.6.tgz", - "integrity": "sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A==", - "engines": { - "node": ">=8.3.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": "^5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } - } - }, - "node_modules/xhr": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/xhr/-/xhr-2.6.0.tgz", - "integrity": "sha512-/eCGLb5rxjx5e3mF1A7s+pLlR6CGyqWN91fv1JgER5mVWg1MZmlhBvy9kjcsOdRk8RrIujotWyJamfyrp+WIcA==", - "dev": true, - "dependencies": { - "global": "~4.4.0", - "is-function": "^1.0.1", - "parse-headers": "^2.0.0", - "xtend": "^4.0.0" - } - }, - "node_modules/xhr-request": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/xhr-request/-/xhr-request-1.1.0.tgz", - "integrity": "sha512-Y7qzEaR3FDtL3fP30k9wO/e+FBnBByZeybKOhASsGP30NIkRAAkKD/sCnLvgEfAIEC1rcmK7YG8f4oEnIrrWzA==", - "dev": true, - "dependencies": { - "buffer-to-arraybuffer": "^0.0.5", - "object-assign": "^4.1.1", - "query-string": "^5.0.1", - "simple-get": "^2.7.0", - "timed-out": "^4.0.1", - "url-set-query": "^1.0.0", - "xhr": "^2.0.4" - } - }, - "node_modules/xhr-request-promise": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/xhr-request-promise/-/xhr-request-promise-0.1.3.tgz", - "integrity": "sha512-YUBytBsuwgitWtdRzXDDkWAXzhdGB8bYm0sSzMPZT7Z2MBjMSTHFsyCT1yCRATY+XC69DUrQraRAEgcoCRaIPg==", - "dev": true, - "dependencies": { - "xhr-request": "^1.1.0" - } - }, - "node_modules/xhr2-cookies": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/xhr2-cookies/-/xhr2-cookies-1.1.0.tgz", - "integrity": "sha512-hjXUA6q+jl/bd8ADHcVfFsSPIf+tyLIjuO9TwJC9WI6JP2zKcS7C+p56I9kCLLsaCiNT035iYvEUUzdEFj/8+g==", - "dev": true, - "dependencies": { - "cookiejar": "^2.1.1" - } - }, - "node_modules/xmlhttprequest": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/xmlhttprequest/-/xmlhttprequest-1.8.0.tgz", - "integrity": "sha512-58Im/U0mlVBLM38NdZjHyhuMtCqa61469k2YP/AaPbvCoV9aQGUpbJBj1QRm2ytRiVQBD/fsw7L2bJGDVQswBA==", - "dev": true, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/xtend": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", - "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", - "dev": true, - "engines": { - "node": ">=0.4" - } - }, - "node_modules/y18n": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", - "dev": true, - "engines": { - "node": ">=10" - } - }, - "node_modules/yaeti": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/yaeti/-/yaeti-0.0.6.tgz", - "integrity": "sha512-MvQa//+KcZCUkBTIC9blM+CU9J2GzuTytsOUwf2lidtvkx/6gnEp1QvJv34t9vdjhFmha/mUiNDbN0D0mJWdug==", - "dev": true, - "engines": { - "node": ">=0.10.32" - } - }, - "node_modules/yallist": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", - "dev": true - }, - "node_modules/yaml": { - "version": "1.10.2", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", - "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", - "dev": true, - "engines": { - "node": ">= 6" - } - }, - "node_modules/yargs": { - "version": "16.2.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", - "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", - "dev": true, - "dependencies": { - "cliui": "^7.0.2", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.0", - "y18n": "^5.0.5", - "yargs-parser": "^20.2.2" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/yargs-parser": { - "version": "20.2.4", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz", - "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==", - "dev": true, - "engines": { - "node": ">=10" - } - }, - "node_modules/yargs-unparser": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz", - "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==", - "dev": true, - "dependencies": { - "camelcase": "^6.0.0", - "decamelize": "^4.0.0", - "flat": "^5.0.2", - "is-plain-obj": "^2.1.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/yargs/node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/yargs/node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/yn": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", - "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/yocto-queue": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", - "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - } - }, - "dependencies": { - "@aashutoshrathi/word-wrap": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz", - "integrity": "sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==", - "dev": true - }, - "@arbitrum/sdk": { - "version": "3.1.6", - "resolved": "https://registry.npmjs.org/@arbitrum/sdk/-/sdk-3.1.6.tgz", - "integrity": "sha512-wY7RHmvY26yc/OuwpJY+kjgAmUJZDGDXaQxfSQTp2t6sSFO+8oFFVsKIthBCY2RpDGFUVTGpRjCUEXiuJ6/SFA==", - "requires": { - "@ethersproject/address": "^5.0.8", - "@ethersproject/bignumber": "^5.1.1", - "@ethersproject/bytes": "^5.0.8", - "ethers": "^5.1.0" - } - }, - "@babel/code-frame": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", - "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", - "dev": true, - "requires": { - "@babel/highlight": "^7.10.4" - } - }, - "@babel/helper-validator-identifier": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.5.tgz", - "integrity": "sha512-aJXu+6lErq8ltp+JhkJUfk1MTGyuA4v7f3pA+BJ5HLfNC6nAQ0Cpi9uOquUj8Hehg0aUiHzWQbOVJGao6ztBAQ==", - "dev": true - }, - "@babel/highlight": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.5.tgz", - "integrity": "sha512-BSKlD1hgnedS5XRnGOljZawtag7H1yPfQp0tdNJCHoH6AZ+Pcm9VvkrK59/Yy593Ypg0zMxH2BxD1VPYUQ7UIw==", - "dev": true, - "requires": { - "@babel/helper-validator-identifier": "^7.22.5", - "chalk": "^2.0.0", - "js-tokens": "^4.0.0" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "@chainsafe/as-sha256": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/@chainsafe/as-sha256/-/as-sha256-0.3.1.tgz", - "integrity": "sha512-hldFFYuf49ed7DAakWVXSJODuq3pzJEguD8tQ7h+sGkM18vja+OFoJI9krnGmgzyuZC2ETX0NOIcCTy31v2Mtg==", - "dev": true - }, - "@chainsafe/persistent-merkle-tree": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/@chainsafe/persistent-merkle-tree/-/persistent-merkle-tree-0.4.2.tgz", - "integrity": "sha512-lLO3ihKPngXLTus/L7WHKaw9PnNJWizlOF1H9NNzHP6Xvh82vzg9F2bzkXhYIFshMZ2gTCEz8tq6STe7r5NDfQ==", - "dev": true, - "requires": { - "@chainsafe/as-sha256": "^0.3.1" - } - }, - "@chainsafe/ssz": { - "version": "0.9.4", - "resolved": "https://registry.npmjs.org/@chainsafe/ssz/-/ssz-0.9.4.tgz", - "integrity": "sha512-77Qtg2N1ayqs4Bg/wvnWfg5Bta7iy7IRh8XqXh7oNMeP2HBbBwx8m6yTpA8p0EHItWPEBkgZd5S5/LSlp3GXuQ==", - "dev": true, - "requires": { - "@chainsafe/as-sha256": "^0.3.1", - "@chainsafe/persistent-merkle-tree": "^0.4.2", - "case": "^1.6.3" - } - }, - "@cspotcode/source-map-support": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", - "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", - "dev": true, - "requires": { - "@jridgewell/trace-mapping": "0.3.9" - } - }, - "@ensdomains/ens": { - "version": "0.4.5", - "resolved": "https://registry.npmjs.org/@ensdomains/ens/-/ens-0.4.5.tgz", - "integrity": "sha512-JSvpj1iNMFjK6K+uVl4unqMoa9rf5jopb8cya5UGBWz23Nw8hSNT7efgUx4BTlAPAgpNlEioUfeTyQ6J9ZvTVw==", - "dev": true, - "requires": { - "bluebird": "^3.5.2", - "eth-ens-namehash": "^2.0.8", - "solc": "^0.4.20", - "testrpc": "0.0.1", - "web3-utils": "^1.0.0-beta.31" - }, - "dependencies": { - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==", - "dev": true - }, - "camelcase": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz", - "integrity": "sha512-4nhGqUkc4BqbBBB4Q6zLuD7lzzrHYrjKGeYaEji/3tFR5VdJu9v+LilhGIVe8wxEJPPOeWo7eg8dwY13TZ1BNg==", - "dev": true - }, - "cliui": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz", - "integrity": "sha512-0yayqDxWQbqk3ojkYqUKqaAQ6AfNKeKWRNA8kR0WXzAsdHpP4BIaOmMAG87JGuO6qcobyW4GjxHd9PmhEd+T9w==", - "dev": true, - "requires": { - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1", - "wrap-ansi": "^2.0.0" - } - }, - "decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", - "dev": true - }, - "fs-extra": { - "version": "0.30.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-0.30.0.tgz", - "integrity": "sha512-UvSPKyhMn6LEd/WpUaV9C9t3zATuqoqfWc3QdPhPLb58prN9tqYPlPWi8Krxi44loBoUzlobqZ3+8tGpxxSzwA==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "jsonfile": "^2.1.0", - "klaw": "^1.0.0", - "path-is-absolute": "^1.0.0", - "rimraf": "^2.2.8" - } - }, - "get-caller-file": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz", - "integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", - "integrity": "sha512-1pqUqRjkhPJ9miNq9SwMfdvi6lBJcd6eFxvfaivQhaH3SgisfiuudvFntdKOmxuee/77l+FPjKrQjWvmPjWrRw==", - "dev": true, - "requires": { - "number-is-nan": "^1.0.0" - } - }, - "jsonfile": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz", - "integrity": "sha512-PKllAqbgLgxHaj8TElYymKCAgrASebJrWpTnEkOaTowt23VKXXN0sUeriJ+eh7y6ufb/CC5ap11pz71/cM0hUw==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.6" - } - }, - "require-from-string": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-1.2.1.tgz", - "integrity": "sha512-H7AkJWMobeskkttHyhTVtS0fxpFLjxhbfMa6Bk3wimP7sdPRGL3EyCg3sAQenFfAe+xQ+oAc85Nmtvq0ROM83Q==", - "dev": true - }, - "rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "dev": true, - "requires": { - "glob": "^7.1.3" - } - }, - "semver": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", - "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", - "dev": true - }, - "solc": { - "version": "0.4.26", - "resolved": "https://registry.npmjs.org/solc/-/solc-0.4.26.tgz", - "integrity": "sha512-o+c6FpkiHd+HPjmjEVpQgH7fqZ14tJpXhho+/bQXlXbliLIS/xjXb42Vxh+qQY1WCSTMQ0+a5vR9vi0MfhU6mA==", - "dev": true, - "requires": { - "fs-extra": "^0.30.0", - "memorystream": "^0.3.1", - "require-from-string": "^1.1.0", - "semver": "^5.3.0", - "yargs": "^4.7.1" - } - }, - "string-width": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha512-0XsVpQLnVCXHJfyEs8tC0zpTVIr5PKKsQtkT29IwupnPTjtPmQ3xT/4yCREF9hYkV/3M3kzcUTSAZT6a6h81tw==", - "dev": true, - "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - } - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "wrap-ansi": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", - "integrity": "sha512-vAaEaDM946gbNpH5pLVNR+vX2ht6n0Bt3GXwVB1AuAqZosOvHNF3P7wDnh8KLkSqgUh0uh77le7Owgoz+Z9XBw==", - "dev": true, - "requires": { - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1" - } - }, - "y18n": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.2.tgz", - "integrity": "sha512-uGZHXkHnhF0XeeAPgnKfPv1bgKAYyVvmNL1xlKsPYZPaIHxGti2hHqvOCQv71XMsLxu1QjergkqogUnms5D3YQ==", - "dev": true - }, - "yargs": { - "version": "4.8.1", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-4.8.1.tgz", - "integrity": "sha512-LqodLrnIDM3IFT+Hf/5sxBnEGECrfdC1uIbgZeJmESCSo4HoCAaKEus8MylXHAkdacGc0ye+Qa+dpkuom8uVYA==", - "dev": true, - "requires": { - "cliui": "^3.2.0", - "decamelize": "^1.1.1", - "get-caller-file": "^1.0.1", - "lodash.assign": "^4.0.3", - "os-locale": "^1.4.0", - "read-pkg-up": "^1.0.1", - "require-directory": "^2.1.1", - "require-main-filename": "^1.0.1", - "set-blocking": "^2.0.0", - "string-width": "^1.0.1", - "which-module": "^1.0.0", - "window-size": "^0.2.0", - "y18n": "^3.2.1", - "yargs-parser": "^2.4.1" - } - }, - "yargs-parser": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-2.4.1.tgz", - "integrity": "sha512-9pIKIJhnI5tonzG6OnCFlz/yln8xHYcGl+pn3xR0Vzff0vzN1PbNRaelgfgRUwZ3s4i3jvxT9WhmUGL4whnasA==", - "dev": true, - "requires": { - "camelcase": "^3.0.0", - "lodash.assign": "^4.0.6" - } - } - } - }, - "@ensdomains/resolver": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/@ensdomains/resolver/-/resolver-0.2.4.tgz", - "integrity": "sha512-bvaTH34PMCbv6anRa9I/0zjLJgY4EuznbEMgbV77JBCQ9KNC46rzi0avuxpOfu+xDjPEtSFGqVEOr5GlUSGudA==", - "dev": true - }, - "@eslint/eslintrc": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.3.tgz", - "integrity": "sha512-J6KFFz5QCYUJq3pf0mjEcCJVERbzv71PUIDczuh9JkwGEzced6CO5ADLHB1rbf/+oPBtoPfMYNOpGDzCANlbXw==", - "dev": true, - "requires": { - "ajv": "^6.12.4", - "debug": "^4.1.1", - "espree": "^7.3.0", - "globals": "^13.9.0", - "ignore": "^4.0.6", - "import-fresh": "^3.2.1", - "js-yaml": "^3.13.1", - "minimatch": "^3.0.4", - "strip-json-comments": "^3.1.1" - }, - "dependencies": { - "ignore": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", - "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", - "dev": true - } - } - }, - "@eth-optimism/contracts": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/@eth-optimism/contracts/-/contracts-0.6.0.tgz", - "integrity": "sha512-vQ04wfG9kMf1Fwy3FEMqH2QZbgS0gldKhcBeBUPfO8zu68L61VI97UDXmsMQXzTsEAxK8HnokW3/gosl4/NW3w==", - "requires": { - "@eth-optimism/core-utils": "0.12.0", - "@ethersproject/abstract-provider": "^5.7.0", - "@ethersproject/abstract-signer": "^5.7.0" - }, - "dependencies": { - "@eth-optimism/core-utils": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/@eth-optimism/core-utils/-/core-utils-0.12.0.tgz", - "integrity": "sha512-qW+7LZYCz7i8dRa7SRlUKIo1VBU8lvN0HeXCxJR+z+xtMzMQpPds20XJNCMclszxYQHkXY00fOT6GvFw9ZL6nw==", - "requires": { - "@ethersproject/abi": "^5.7.0", - "@ethersproject/abstract-provider": "^5.7.0", - "@ethersproject/address": "^5.7.0", - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/constants": "^5.7.0", - "@ethersproject/contracts": "^5.7.0", - "@ethersproject/hash": "^5.7.0", - "@ethersproject/keccak256": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/providers": "^5.7.0", - "@ethersproject/rlp": "^5.7.0", - "@ethersproject/transactions": "^5.7.0", - "@ethersproject/web": "^5.7.0", - "bufio": "^1.0.7", - "chai": "^4.3.4" - } - } - } - }, - "@eth-optimism/contracts-bedrock": { - "version": "0.17.1", - "resolved": "https://registry.npmjs.org/@eth-optimism/contracts-bedrock/-/contracts-bedrock-0.17.1.tgz", - "integrity": "sha512-Hc5peN5PM8kzl9dzqSD5jv6ED3QliO1DF0dXLRJxfrXR7/rmEeyuAYESUwUM0gdJZjkwRYiS5m230BI6bQmnlw==" - }, - "@eth-optimism/core-utils": { - "version": "0.13.1", - "resolved": "https://registry.npmjs.org/@eth-optimism/core-utils/-/core-utils-0.13.1.tgz", - "integrity": "sha512-1FvzbUmCEy9zSKPG1QWg2VfA2Cy90xBA9Wkp11lXXrz91zUPCNCNSRTujXWYIC86ketNsZp7p4njSf6lTycHCw==", - "requires": { - "@ethersproject/abi": "^5.7.0", - "@ethersproject/abstract-provider": "^5.7.0", - "@ethersproject/address": "^5.7.0", - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/constants": "^5.7.0", - "@ethersproject/contracts": "^5.7.0", - "@ethersproject/keccak256": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/rlp": "^5.7.0", - "@ethersproject/web": "^5.7.1", - "chai": "^4.3.9", - "ethers": "^5.7.2", - "node-fetch": "^2.6.7" - } - }, - "@eth-optimism/sdk": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/@eth-optimism/sdk/-/sdk-3.2.0.tgz", - "integrity": "sha512-+ZEO/mDWz3WLzaPVHvgOAK4iN723HmI6sLLr2tmO1/RUoCHVfWMUDwuiikrA49cAsdsjMxCV9+0XNZ8btD2JUg==", - "requires": { - "@eth-optimism/contracts": "0.6.0", - "@eth-optimism/contracts-bedrock": "0.17.1", - "@eth-optimism/core-utils": "0.13.1", - "lodash": "^4.17.21", - "merkletreejs": "^0.3.11", - "rlp": "^2.2.7", - "semver": "^7.5.4" - }, - "dependencies": { - "lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "requires": { - "yallist": "^4.0.0" - } - }, - "semver": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", - "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", - "requires": { - "lru-cache": "^6.0.0" - } - }, - "yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" - } - } - }, - "@ethereum-waffle/chai": { - "version": "3.4.4", - "resolved": "https://registry.npmjs.org/@ethereum-waffle/chai/-/chai-3.4.4.tgz", - "integrity": "sha512-/K8czydBtXXkcM9X6q29EqEkc5dN3oYenyH2a9hF7rGAApAJUpH8QBtojxOY/xQ2up5W332jqgxwp0yPiYug1g==", - "dev": true, - "requires": { - "@ethereum-waffle/provider": "^3.4.4", - "ethers": "^5.5.2" - } - }, - "@ethereum-waffle/compiler": { - "version": "3.4.4", - "resolved": "https://registry.npmjs.org/@ethereum-waffle/compiler/-/compiler-3.4.4.tgz", - "integrity": "sha512-RUK3axJ8IkD5xpWjWoJgyHclOeEzDLQFga6gKpeGxiS/zBu+HB0W2FvsrrLalTFIaPw/CGYACRBSIxqiCqwqTQ==", - "dev": true, - "requires": { - "@resolver-engine/imports": "^0.3.3", - "@resolver-engine/imports-fs": "^0.3.3", - "@typechain/ethers-v5": "^2.0.0", - "@types/mkdirp": "^0.5.2", - "@types/node-fetch": "^2.5.5", - "ethers": "^5.0.1", - "mkdirp": "^0.5.1", - "node-fetch": "^2.6.1", - "solc": "^0.6.3", - "ts-generator": "^0.1.1", - "typechain": "^3.0.0" - }, - "dependencies": { - "@typechain/ethers-v5": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@typechain/ethers-v5/-/ethers-v5-2.0.0.tgz", - "integrity": "sha512-0xdCkyGOzdqh4h5JSf+zoWx85IusEjDcPIwNEHP8mrWSnCae4rvrqB+/gtpdNfX7zjlFlZiMeePn2r63EI3Lrw==", - "dev": true, - "requires": { - "ethers": "^5.0.2" - } - }, - "ts-essentials": { - "version": "6.0.7", - "resolved": "https://registry.npmjs.org/ts-essentials/-/ts-essentials-6.0.7.tgz", - "integrity": "sha512-2E4HIIj4tQJlIHuATRHayv0EfMGK3ris/GRk1E3CFnsZzeNV+hUmelbaTZHLtXaZppM5oLhHRtO04gINC4Jusw==", - "dev": true, - "requires": {} - }, - "typechain": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/typechain/-/typechain-3.0.0.tgz", - "integrity": "sha512-ft4KVmiN3zH4JUFu2WJBrwfHeDf772Tt2d8bssDTo/YcckKW2D+OwFrHXRC6hJvO3mHjFQTihoMV6fJOi0Hngg==", - "dev": true, - "requires": { - "command-line-args": "^4.0.7", - "debug": "^4.1.1", - "fs-extra": "^7.0.0", - "js-sha3": "^0.8.0", - "lodash": "^4.17.15", - "ts-essentials": "^6.0.3", - "ts-generator": "^0.1.1" - } - } - } - }, - "@ethereum-waffle/ens": { - "version": "3.4.4", - "resolved": "https://registry.npmjs.org/@ethereum-waffle/ens/-/ens-3.4.4.tgz", - "integrity": "sha512-0m4NdwWxliy3heBYva1Wr4WbJKLnwXizmy5FfSSr5PMbjI7SIGCdCB59U7/ZzY773/hY3bLnzLwvG5mggVjJWg==", - "dev": true, - "requires": { - "@ensdomains/ens": "^0.4.4", - "@ensdomains/resolver": "^0.2.4", - "ethers": "^5.5.2" - } - }, - "@ethereum-waffle/mock-contract": { - "version": "3.4.4", - "resolved": "https://registry.npmjs.org/@ethereum-waffle/mock-contract/-/mock-contract-3.4.4.tgz", - "integrity": "sha512-Mp0iB2YNWYGUV+VMl5tjPsaXKbKo8MDH9wSJ702l9EBjdxFf/vBvnMBAC1Fub1lLtmD0JHtp1pq+mWzg/xlLnA==", - "dev": true, - "requires": { - "@ethersproject/abi": "^5.5.0", - "ethers": "^5.5.2" - } - }, - "@ethereum-waffle/provider": { - "version": "3.4.4", - "resolved": "https://registry.npmjs.org/@ethereum-waffle/provider/-/provider-3.4.4.tgz", - "integrity": "sha512-GK8oKJAM8+PKy2nK08yDgl4A80mFuI8zBkE0C9GqTRYQqvuxIyXoLmJ5NZU9lIwyWVv5/KsoA11BgAv2jXE82g==", - "dev": true, - "requires": { - "@ethereum-waffle/ens": "^3.4.4", - "ethers": "^5.5.2", - "ganache-core": "^2.13.2", - "patch-package": "^6.2.2", - "postinstall-postinstall": "^2.1.0" - } - }, - "@ethereumjs/common": { - "version": "2.6.5", - "resolved": "https://registry.npmjs.org/@ethereumjs/common/-/common-2.6.5.tgz", - "integrity": "sha512-lRyVQOeCDaIVtgfbowla32pzeDv2Obr8oR8Put5RdUBNRGr1VGPGQNGP6elWIpgK3YdpzqTOh4GyUGOureVeeA==", - "dev": true, - "requires": { - "crc-32": "^1.2.0", - "ethereumjs-util": "^7.1.5" - }, - "dependencies": { - "ethereum-cryptography": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz", - "integrity": "sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==", - "dev": true, - "requires": { - "@types/pbkdf2": "^3.0.0", - "@types/secp256k1": "^4.0.1", - "blakejs": "^1.1.0", - "browserify-aes": "^1.2.0", - "bs58check": "^2.1.2", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "hash.js": "^1.1.7", - "keccak": "^3.0.0", - "pbkdf2": "^3.0.17", - "randombytes": "^2.1.0", - "safe-buffer": "^5.1.2", - "scrypt-js": "^3.0.0", - "secp256k1": "^4.0.1", - "setimmediate": "^1.0.5" - } - }, - "ethereumjs-util": { - "version": "7.1.5", - "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-7.1.5.tgz", - "integrity": "sha512-SDl5kKrQAudFBUe5OJM9Ac6WmMyYmXX/6sTmLZ3ffG2eY6ZIGBes3pEDxNN6V72WyOw4CPD5RomKdsa8DAAwLg==", - "dev": true, - "requires": { - "@types/bn.js": "^5.1.0", - "bn.js": "^5.1.2", - "create-hash": "^1.1.2", - "ethereum-cryptography": "^0.1.3", - "rlp": "^2.2.4" - } - } - } - }, - "@ethereumjs/tx": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/@ethereumjs/tx/-/tx-3.5.2.tgz", - "integrity": "sha512-gQDNJWKrSDGu2w7w0PzVXVBNMzb7wwdDOmOqczmhNjqFxFuIbhVJDwiGEnxFNC2/b8ifcZzY7MLcluizohRzNw==", - "dev": true, - "requires": { - "@ethereumjs/common": "^2.6.4", - "ethereumjs-util": "^7.1.5" - }, - "dependencies": { - "ethereum-cryptography": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz", - "integrity": "sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==", - "dev": true, - "requires": { - "@types/pbkdf2": "^3.0.0", - "@types/secp256k1": "^4.0.1", - "blakejs": "^1.1.0", - "browserify-aes": "^1.2.0", - "bs58check": "^2.1.2", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "hash.js": "^1.1.7", - "keccak": "^3.0.0", - "pbkdf2": "^3.0.17", - "randombytes": "^2.1.0", - "safe-buffer": "^5.1.2", - "scrypt-js": "^3.0.0", - "secp256k1": "^4.0.1", - "setimmediate": "^1.0.5" - } - }, - "ethereumjs-util": { - "version": "7.1.5", - "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-7.1.5.tgz", - "integrity": "sha512-SDl5kKrQAudFBUe5OJM9Ac6WmMyYmXX/6sTmLZ3ffG2eY6ZIGBes3pEDxNN6V72WyOw4CPD5RomKdsa8DAAwLg==", - "dev": true, - "requires": { - "@types/bn.js": "^5.1.0", - "bn.js": "^5.1.2", - "create-hash": "^1.1.2", - "ethereum-cryptography": "^0.1.3", - "rlp": "^2.2.4" - } - } - } - }, - "@ethersproject/abi": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/abi/-/abi-5.7.0.tgz", - "integrity": "sha512-351ktp42TiRcYB3H1OP8yajPeAQstMW/yCFokj/AthP9bLHzQFPlOrxOcwYEDkUAICmOHljvN4K39OMTMUa9RA==", - "requires": { - "@ethersproject/address": "^5.7.0", - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/constants": "^5.7.0", - "@ethersproject/hash": "^5.7.0", - "@ethersproject/keccak256": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/strings": "^5.7.0" - } - }, - "@ethersproject/abstract-provider": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/abstract-provider/-/abstract-provider-5.7.0.tgz", - "integrity": "sha512-R41c9UkchKCpAqStMYUpdunjo3pkEvZC3FAwZn5S5MGbXoMQOHIdHItezTETxAO5bevtMApSyEhn9+CHcDsWBw==", - "requires": { - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/networks": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/transactions": "^5.7.0", - "@ethersproject/web": "^5.7.0" - } - }, - "@ethersproject/abstract-signer": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/abstract-signer/-/abstract-signer-5.7.0.tgz", - "integrity": "sha512-a16V8bq1/Cz+TGCkE2OPMTOUDLS3grCpdjoJCYNnVBbdYEMSgKrU0+B90s8b6H+ByYTBZN7a3g76jdIJi7UfKQ==", - "requires": { - "@ethersproject/abstract-provider": "^5.7.0", - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/properties": "^5.7.0" - } - }, - "@ethersproject/address": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/address/-/address-5.7.0.tgz", - "integrity": "sha512-9wYhYt7aghVGo758POM5nqcOMaE168Q6aRLJZwUmiqSrAungkG74gSSeKEIR7ukixesdRZGPgVqme6vmxs1fkA==", - "requires": { - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/keccak256": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/rlp": "^5.7.0" - } - }, - "@ethersproject/base64": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/base64/-/base64-5.7.0.tgz", - "integrity": "sha512-Dr8tcHt2mEbsZr/mwTPIQAf3Ai0Bks/7gTw9dSqk1mQvhW3XvRlmDJr/4n+wg1JmCl16NZue17CDh8xb/vZ0sQ==", - "requires": { - "@ethersproject/bytes": "^5.7.0" - } - }, - "@ethersproject/basex": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/basex/-/basex-5.7.0.tgz", - "integrity": "sha512-ywlh43GwZLv2Voc2gQVTKBoVQ1mti3d8HK5aMxsfu/nRDnMmNqaSJ3r3n85HBByT8OpoY96SXM1FogC533T4zw==", - "requires": { - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/properties": "^5.7.0" - } - }, - "@ethersproject/bignumber": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/bignumber/-/bignumber-5.7.0.tgz", - "integrity": "sha512-n1CAdIHRWjSucQO3MC1zPSVgV/6dy/fjL9pMrPP9peL+QxEg9wOsVqwD4+818B6LUEtaXzVHQiuivzRoxPxUGw==", - "requires": { - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "bn.js": "^5.2.1" - } - }, - "@ethersproject/bytes": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/bytes/-/bytes-5.7.0.tgz", - "integrity": "sha512-nsbxwgFXWh9NyYWo+U8atvmMsSdKJprTcICAkvbBffT75qDocbuggBU0SJiVK2MuTrp0q+xvLkTnGMPK1+uA9A==", - "requires": { - "@ethersproject/logger": "^5.7.0" - } - }, - "@ethersproject/constants": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/constants/-/constants-5.7.0.tgz", - "integrity": "sha512-DHI+y5dBNvkpYUMiRQyxRBYBefZkJfo70VUkUAsRjcPs47muV9evftfZ0PJVCXYbAiCgght0DtcF9srFQmIgWA==", - "requires": { - "@ethersproject/bignumber": "^5.7.0" - } - }, - "@ethersproject/contracts": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/contracts/-/contracts-5.7.0.tgz", - "integrity": "sha512-5GJbzEU3X+d33CdfPhcyS+z8MzsTrBGk/sc+G+59+tPa9yFkl6HQ9D6L0QMgNTA9q8dT0XKxxkyp883XsQvbbg==", - "requires": { - "@ethersproject/abi": "^5.7.0", - "@ethersproject/abstract-provider": "^5.7.0", - "@ethersproject/abstract-signer": "^5.7.0", - "@ethersproject/address": "^5.7.0", - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/constants": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/transactions": "^5.7.0" - } - }, - "@ethersproject/hash": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/hash/-/hash-5.7.0.tgz", - "integrity": "sha512-qX5WrQfnah1EFnO5zJv1v46a8HW0+E5xuBBDTwMFZLuVTx0tbU2kkx15NqdjxecrLGatQN9FGQKpb1FKdHCt+g==", - "requires": { - "@ethersproject/abstract-signer": "^5.7.0", - "@ethersproject/address": "^5.7.0", - "@ethersproject/base64": "^5.7.0", - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/keccak256": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/strings": "^5.7.0" - } - }, - "@ethersproject/hdnode": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/hdnode/-/hdnode-5.7.0.tgz", - "integrity": "sha512-OmyYo9EENBPPf4ERhR7oj6uAtUAhYGqOnIS+jE5pTXvdKBS99ikzq1E7Iv0ZQZ5V36Lqx1qZLeak0Ra16qpeOg==", - "requires": { - "@ethersproject/abstract-signer": "^5.7.0", - "@ethersproject/basex": "^5.7.0", - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/pbkdf2": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/sha2": "^5.7.0", - "@ethersproject/signing-key": "^5.7.0", - "@ethersproject/strings": "^5.7.0", - "@ethersproject/transactions": "^5.7.0", - "@ethersproject/wordlists": "^5.7.0" - } - }, - "@ethersproject/json-wallets": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/json-wallets/-/json-wallets-5.7.0.tgz", - "integrity": "sha512-8oee5Xgu6+RKgJTkvEMl2wDgSPSAQ9MB/3JYjFV9jlKvcYHUXZC+cQp0njgmxdHkYWn8s6/IqIZYm0YWCjO/0g==", - "requires": { - "@ethersproject/abstract-signer": "^5.7.0", - "@ethersproject/address": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/hdnode": "^5.7.0", - "@ethersproject/keccak256": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/pbkdf2": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/random": "^5.7.0", - "@ethersproject/strings": "^5.7.0", - "@ethersproject/transactions": "^5.7.0", - "aes-js": "3.0.0", - "scrypt-js": "3.0.1" - } - }, - "@ethersproject/keccak256": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/keccak256/-/keccak256-5.7.0.tgz", - "integrity": "sha512-2UcPboeL/iW+pSg6vZ6ydF8tCnv3Iu/8tUmLLzWWGzxWKFFqOBQFLo6uLUv6BDrLgCDfN28RJ/wtByx+jZ4KBg==", - "requires": { - "@ethersproject/bytes": "^5.7.0", - "js-sha3": "0.8.0" - } - }, - "@ethersproject/logger": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/logger/-/logger-5.7.0.tgz", - "integrity": "sha512-0odtFdXu/XHtjQXJYA3u9G0G8btm0ND5Cu8M7i5vhEcE8/HmF4Lbdqanwyv4uQTr2tx6b7fQRmgLrsnpQlmnig==" - }, - "@ethersproject/networks": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/@ethersproject/networks/-/networks-5.7.1.tgz", - "integrity": "sha512-n/MufjFYv3yFcUyfhnXotyDlNdFb7onmkSy8aQERi2PjNcnWQ66xXxa3XlS8nCcA8aJKJjIIMNJTC7tu80GwpQ==", - "requires": { - "@ethersproject/logger": "^5.7.0" - } - }, - "@ethersproject/pbkdf2": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/pbkdf2/-/pbkdf2-5.7.0.tgz", - "integrity": "sha512-oR/dBRZR6GTyaofd86DehG72hY6NpAjhabkhxgr3X2FpJtJuodEl2auADWBZfhDHgVCbu3/H/Ocq2uC6dpNjjw==", - "requires": { - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/sha2": "^5.7.0" - } - }, - "@ethersproject/properties": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/properties/-/properties-5.7.0.tgz", - "integrity": "sha512-J87jy8suntrAkIZtecpxEPxY//szqr1mlBaYlQ0r4RCaiD2hjheqF9s1LVE8vVuJCXisjIP+JgtK/Do54ej4Sw==", - "requires": { - "@ethersproject/logger": "^5.7.0" - } - }, - "@ethersproject/providers": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/@ethersproject/providers/-/providers-5.7.2.tgz", - "integrity": "sha512-g34EWZ1WWAVgr4aptGlVBF8mhl3VWjv+8hoAnzStu8Ah22VHBsuGzP17eb6xDVRzw895G4W7vvx60lFFur/1Rg==", - "requires": { - "@ethersproject/abstract-provider": "^5.7.0", - "@ethersproject/abstract-signer": "^5.7.0", - "@ethersproject/address": "^5.7.0", - "@ethersproject/base64": "^5.7.0", - "@ethersproject/basex": "^5.7.0", - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/constants": "^5.7.0", - "@ethersproject/hash": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/networks": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/random": "^5.7.0", - "@ethersproject/rlp": "^5.7.0", - "@ethersproject/sha2": "^5.7.0", - "@ethersproject/strings": "^5.7.0", - "@ethersproject/transactions": "^5.7.0", - "@ethersproject/web": "^5.7.0", - "bech32": "1.1.4", - "ws": "7.4.6" - } - }, - "@ethersproject/random": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/random/-/random-5.7.0.tgz", - "integrity": "sha512-19WjScqRA8IIeWclFme75VMXSBvi4e6InrUNuaR4s5pTF2qNhcGdCUwdxUVGtDDqC00sDLCO93jPQoDUH4HVmQ==", - "requires": { - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/logger": "^5.7.0" - } - }, - "@ethersproject/rlp": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/rlp/-/rlp-5.7.0.tgz", - "integrity": "sha512-rBxzX2vK8mVF7b0Tol44t5Tb8gomOHkj5guL+HhzQ1yBh/ydjGnpw6at+X6Iw0Kp3OzzzkcKp8N9r0W4kYSs9w==", - "requires": { - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/logger": "^5.7.0" - } - }, - "@ethersproject/sha2": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/sha2/-/sha2-5.7.0.tgz", - "integrity": "sha512-gKlH42riwb3KYp0reLsFTokByAKoJdgFCwI+CCiX/k+Jm2mbNs6oOaCjYQSlI1+XBVejwH2KrmCbMAT/GnRDQw==", - "requires": { - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "hash.js": "1.1.7" - } - }, - "@ethersproject/signing-key": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/signing-key/-/signing-key-5.7.0.tgz", - "integrity": "sha512-MZdy2nL3wO0u7gkB4nA/pEf8lu1TlFswPNmy8AiYkfKTdO6eXBJyUdmHO/ehm/htHw9K/qF8ujnTyUAD+Ry54Q==", - "requires": { - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "bn.js": "^5.2.1", - "elliptic": "6.5.4", - "hash.js": "1.1.7" - } - }, - "@ethersproject/solidity": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/solidity/-/solidity-5.7.0.tgz", - "integrity": "sha512-HmabMd2Dt/raavyaGukF4XxizWKhKQ24DoLtdNbBmNKUOPqwjsKQSdV9GQtj9CBEea9DlzETlVER1gYeXXBGaA==", - "requires": { - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/keccak256": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/sha2": "^5.7.0", - "@ethersproject/strings": "^5.7.0" - } - }, - "@ethersproject/strings": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/strings/-/strings-5.7.0.tgz", - "integrity": "sha512-/9nu+lj0YswRNSH0NXYqrh8775XNyEdUQAuf3f+SmOrnVewcJ5SBNAjF7lpgehKi4abvNNXyf+HX86czCdJ8Mg==", - "requires": { - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/constants": "^5.7.0", - "@ethersproject/logger": "^5.7.0" - } - }, - "@ethersproject/transactions": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/transactions/-/transactions-5.7.0.tgz", - "integrity": "sha512-kmcNicCp1lp8qanMTC3RIikGgoJ80ztTyvtsFvCYpSCfkjhD0jZ2LOrnbcuxuToLIUYYf+4XwD1rP+B/erDIhQ==", - "requires": { - "@ethersproject/address": "^5.7.0", - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/constants": "^5.7.0", - "@ethersproject/keccak256": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/rlp": "^5.7.0", - "@ethersproject/signing-key": "^5.7.0" - } - }, - "@ethersproject/units": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/units/-/units-5.7.0.tgz", - "integrity": "sha512-pD3xLMy3SJu9kG5xDGI7+xhTEmGXlEqXU4OfNapmfnxLVY4EMSSRp7j1k7eezutBPH7RBN/7QPnwR7hzNlEFeg==", - "requires": { - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/constants": "^5.7.0", - "@ethersproject/logger": "^5.7.0" - } - }, - "@ethersproject/wallet": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/wallet/-/wallet-5.7.0.tgz", - "integrity": "sha512-MhmXlJXEJFBFVKrDLB4ZdDzxcBxQ3rLyCkhNqVu3CDYvR97E+8r01UgrI+TI99Le+aYm/in/0vp86guJuM7FCA==", - "requires": { - "@ethersproject/abstract-provider": "^5.7.0", - "@ethersproject/abstract-signer": "^5.7.0", - "@ethersproject/address": "^5.7.0", - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/hash": "^5.7.0", - "@ethersproject/hdnode": "^5.7.0", - "@ethersproject/json-wallets": "^5.7.0", - "@ethersproject/keccak256": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/random": "^5.7.0", - "@ethersproject/signing-key": "^5.7.0", - "@ethersproject/transactions": "^5.7.0", - "@ethersproject/wordlists": "^5.7.0" - } - }, - "@ethersproject/web": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/@ethersproject/web/-/web-5.7.1.tgz", - "integrity": "sha512-Gueu8lSvyjBWL4cYsWsjh6MtMwM0+H4HvqFPZfB6dV8ctbP9zFAO73VG1cMWae0FLPCtz0peKPpZY8/ugJJX2w==", - "requires": { - "@ethersproject/base64": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/strings": "^5.7.0" - } - }, - "@ethersproject/wordlists": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/wordlists/-/wordlists-5.7.0.tgz", - "integrity": "sha512-S2TFNJNfHWVHNE6cNDjbVlZ6MgE17MIxMbMg2zv3wn+3XSJGosL1m9ZVv3GXCf/2ymSsQ+hRI5IzoMJTG6aoVA==", - "requires": { - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/hash": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/strings": "^5.7.0" - } - }, - "@fastify/busboy": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@fastify/busboy/-/busboy-2.0.0.tgz", - "integrity": "sha512-JUFJad5lv7jxj926GPgymrWQxxjPYuJNiNjNMzqT+HiuP6Vl3dk5xzG+8sTX96np0ZAluvaMzPsjhHZ5rNuNQQ==", - "dev": true - }, - "@humanwhocodes/config-array": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.5.0.tgz", - "integrity": "sha512-FagtKFz74XrTl7y6HCzQpwDfXP0yhxe9lHLD1UZxjvZIcbyRz8zTFF/yYNfSfzU414eDwZ1SrO0Qvtyf+wFMQg==", - "dev": true, - "requires": { - "@humanwhocodes/object-schema": "^1.2.0", - "debug": "^4.1.1", - "minimatch": "^3.0.4" - } - }, - "@humanwhocodes/object-schema": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", - "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", - "dev": true - }, - "@jridgewell/resolve-uri": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz", - "integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==", - "dev": true - }, - "@jridgewell/sourcemap-codec": { - "version": "1.4.15", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", - "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", - "dev": true - }, - "@jridgewell/trace-mapping": { - "version": "0.3.9", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", - "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", - "dev": true, - "requires": { - "@jridgewell/resolve-uri": "^3.0.3", - "@jridgewell/sourcemap-codec": "^1.4.10" - } - }, - "@lidofinance/evm-script-decoder": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/@lidofinance/evm-script-decoder/-/evm-script-decoder-0.2.2.tgz", - "integrity": "sha512-Gk7gDus2QvOOCCg8NCSOgv43rNIdMFohfRtyc9PSWViIH0GLqNiOFXR71tfwkemrNpu2A0LlBakoB9vgCY+Yfw==", - "requires": { - "@ethersproject/abi": "^5.0.7", - "keccak256": "^1.0.3" - } - }, - "@metamask/eth-sig-util": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@metamask/eth-sig-util/-/eth-sig-util-4.0.1.tgz", - "integrity": "sha512-tghyZKLHZjcdlDqCA3gNZmLeR0XvOE9U1qoQO9ohyAZT6Pya+H9vkBPcsyXytmYLNgVoin7CKCmweo/R43V+tQ==", - "dev": true, - "requires": { - "ethereumjs-abi": "^0.6.8", - "ethereumjs-util": "^6.2.1", - "ethjs-util": "^0.1.6", - "tweetnacl": "^1.0.3", - "tweetnacl-util": "^0.15.1" - } - }, - "@noble/hashes": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.2.0.tgz", - "integrity": "sha512-FZfhjEDbT5GRswV3C6uvLPHMiVD6lQBmpoX5+eSiPaMTXte/IKqI5dykDxzZB/WBeK/CDuQRBWarPdi3FNY2zQ==", - "dev": true - }, - "@noble/secp256k1": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/@noble/secp256k1/-/secp256k1-1.7.1.tgz", - "integrity": "sha512-hOUk6AyBFmqVrv7k5WAw/LpszxVbj9gGN4JRkIX52fdFAj1UA61KXmZDvqVEm+pOyec3+fIeZB02LYa/pWOArw==", - "dev": true - }, - "@nodelib/fs.scandir": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", - "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", - "dev": true, - "requires": { - "@nodelib/fs.stat": "2.0.5", - "run-parallel": "^1.1.9" - } - }, - "@nodelib/fs.stat": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", - "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", - "dev": true - }, - "@nodelib/fs.walk": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", - "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", - "dev": true, - "requires": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" - } - }, - "@nomicfoundation/ethereumjs-block": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-block/-/ethereumjs-block-5.0.1.tgz", - "integrity": "sha512-u1Yioemi6Ckj3xspygu/SfFvm8vZEO8/Yx5a1QLzi6nVU0jz3Pg2OmHKJ5w+D9Ogk1vhwRiqEBAqcb0GVhCyHw==", - "dev": true, - "requires": { - "@nomicfoundation/ethereumjs-common": "4.0.1", - "@nomicfoundation/ethereumjs-rlp": "5.0.1", - "@nomicfoundation/ethereumjs-trie": "6.0.1", - "@nomicfoundation/ethereumjs-tx": "5.0.1", - "@nomicfoundation/ethereumjs-util": "9.0.1", - "ethereum-cryptography": "0.1.3", - "ethers": "^5.7.1" - }, - "dependencies": { - "ethereum-cryptography": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz", - "integrity": "sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==", - "dev": true, - "requires": { - "@types/pbkdf2": "^3.0.0", - "@types/secp256k1": "^4.0.1", - "blakejs": "^1.1.0", - "browserify-aes": "^1.2.0", - "bs58check": "^2.1.2", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "hash.js": "^1.1.7", - "keccak": "^3.0.0", - "pbkdf2": "^3.0.17", - "randombytes": "^2.1.0", - "safe-buffer": "^5.1.2", - "scrypt-js": "^3.0.0", - "secp256k1": "^4.0.1", - "setimmediate": "^1.0.5" - } - } - } - }, - "@nomicfoundation/ethereumjs-blockchain": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-blockchain/-/ethereumjs-blockchain-7.0.1.tgz", - "integrity": "sha512-NhzndlGg829XXbqJEYrF1VeZhAwSPgsK/OB7TVrdzft3y918hW5KNd7gIZ85sn6peDZOdjBsAXIpXZ38oBYE5A==", - "dev": true, - "requires": { - "@nomicfoundation/ethereumjs-block": "5.0.1", - "@nomicfoundation/ethereumjs-common": "4.0.1", - "@nomicfoundation/ethereumjs-ethash": "3.0.1", - "@nomicfoundation/ethereumjs-rlp": "5.0.1", - "@nomicfoundation/ethereumjs-trie": "6.0.1", - "@nomicfoundation/ethereumjs-tx": "5.0.1", - "@nomicfoundation/ethereumjs-util": "9.0.1", - "abstract-level": "^1.0.3", - "debug": "^4.3.3", - "ethereum-cryptography": "0.1.3", - "level": "^8.0.0", - "lru-cache": "^5.1.1", - "memory-level": "^1.0.0" - }, - "dependencies": { - "ethereum-cryptography": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz", - "integrity": "sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==", - "dev": true, - "requires": { - "@types/pbkdf2": "^3.0.0", - "@types/secp256k1": "^4.0.1", - "blakejs": "^1.1.0", - "browserify-aes": "^1.2.0", - "bs58check": "^2.1.2", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "hash.js": "^1.1.7", - "keccak": "^3.0.0", - "pbkdf2": "^3.0.17", - "randombytes": "^2.1.0", - "safe-buffer": "^5.1.2", - "scrypt-js": "^3.0.0", - "secp256k1": "^4.0.1", - "setimmediate": "^1.0.5" - } - } - } - }, - "@nomicfoundation/ethereumjs-common": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-common/-/ethereumjs-common-4.0.1.tgz", - "integrity": "sha512-OBErlkfp54GpeiE06brBW/TTbtbuBJV5YI5Nz/aB2evTDo+KawyEzPjBlSr84z/8MFfj8wS2wxzQX1o32cev5g==", - "dev": true, - "requires": { - "@nomicfoundation/ethereumjs-util": "9.0.1", - "crc-32": "^1.2.0" - } - }, - "@nomicfoundation/ethereumjs-ethash": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-ethash/-/ethereumjs-ethash-3.0.1.tgz", - "integrity": "sha512-KDjGIB5igzWOp8Ik5I6QiRH5DH+XgILlplsHR7TEuWANZA759G6krQ6o8bvj+tRUz08YygMQu/sGd9mJ1DYT8w==", - "dev": true, - "requires": { - "@nomicfoundation/ethereumjs-block": "5.0.1", - "@nomicfoundation/ethereumjs-rlp": "5.0.1", - "@nomicfoundation/ethereumjs-util": "9.0.1", - "abstract-level": "^1.0.3", - "bigint-crypto-utils": "^3.0.23", - "ethereum-cryptography": "0.1.3" - }, - "dependencies": { - "ethereum-cryptography": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz", - "integrity": "sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==", - "dev": true, - "requires": { - "@types/pbkdf2": "^3.0.0", - "@types/secp256k1": "^4.0.1", - "blakejs": "^1.1.0", - "browserify-aes": "^1.2.0", - "bs58check": "^2.1.2", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "hash.js": "^1.1.7", - "keccak": "^3.0.0", - "pbkdf2": "^3.0.17", - "randombytes": "^2.1.0", - "safe-buffer": "^5.1.2", - "scrypt-js": "^3.0.0", - "secp256k1": "^4.0.1", - "setimmediate": "^1.0.5" - } - } - } - }, - "@nomicfoundation/ethereumjs-evm": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-evm/-/ethereumjs-evm-2.0.1.tgz", - "integrity": "sha512-oL8vJcnk0Bx/onl+TgQOQ1t/534GKFaEG17fZmwtPFeH8S5soiBYPCLUrvANOl4sCp9elYxIMzIiTtMtNNN8EQ==", - "dev": true, - "requires": { - "@ethersproject/providers": "^5.7.1", - "@nomicfoundation/ethereumjs-common": "4.0.1", - "@nomicfoundation/ethereumjs-tx": "5.0.1", - "@nomicfoundation/ethereumjs-util": "9.0.1", - "debug": "^4.3.3", - "ethereum-cryptography": "0.1.3", - "mcl-wasm": "^0.7.1", - "rustbn.js": "~0.2.0" - }, - "dependencies": { - "ethereum-cryptography": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz", - "integrity": "sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==", - "dev": true, - "requires": { - "@types/pbkdf2": "^3.0.0", - "@types/secp256k1": "^4.0.1", - "blakejs": "^1.1.0", - "browserify-aes": "^1.2.0", - "bs58check": "^2.1.2", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "hash.js": "^1.1.7", - "keccak": "^3.0.0", - "pbkdf2": "^3.0.17", - "randombytes": "^2.1.0", - "safe-buffer": "^5.1.2", - "scrypt-js": "^3.0.0", - "secp256k1": "^4.0.1", - "setimmediate": "^1.0.5" - } - } - } - }, - "@nomicfoundation/ethereumjs-rlp": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-rlp/-/ethereumjs-rlp-5.0.1.tgz", - "integrity": "sha512-xtxrMGa8kP4zF5ApBQBtjlSbN5E2HI8m8FYgVSYAnO6ssUoY5pVPGy2H8+xdf/bmMa22Ce8nWMH3aEW8CcqMeQ==", - "dev": true - }, - "@nomicfoundation/ethereumjs-statemanager": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-statemanager/-/ethereumjs-statemanager-2.0.1.tgz", - "integrity": "sha512-B5ApMOnlruVOR7gisBaYwFX+L/AP7i/2oAahatssjPIBVDF6wTX1K7Qpa39E/nzsH8iYuL3krkYeUFIdO3EMUQ==", - "dev": true, - "requires": { - "@nomicfoundation/ethereumjs-common": "4.0.1", - "@nomicfoundation/ethereumjs-rlp": "5.0.1", - "debug": "^4.3.3", - "ethereum-cryptography": "0.1.3", - "ethers": "^5.7.1", - "js-sdsl": "^4.1.4" - }, - "dependencies": { - "ethereum-cryptography": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz", - "integrity": "sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==", - "dev": true, - "requires": { - "@types/pbkdf2": "^3.0.0", - "@types/secp256k1": "^4.0.1", - "blakejs": "^1.1.0", - "browserify-aes": "^1.2.0", - "bs58check": "^2.1.2", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "hash.js": "^1.1.7", - "keccak": "^3.0.0", - "pbkdf2": "^3.0.17", - "randombytes": "^2.1.0", - "safe-buffer": "^5.1.2", - "scrypt-js": "^3.0.0", - "secp256k1": "^4.0.1", - "setimmediate": "^1.0.5" - } - } - } - }, - "@nomicfoundation/ethereumjs-trie": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-trie/-/ethereumjs-trie-6.0.1.tgz", - "integrity": "sha512-A64It/IMpDVODzCgxDgAAla8jNjNtsoQZIzZUfIV5AY6Coi4nvn7+VReBn5itlxMiL2yaTlQr9TRWp3CSI6VoA==", - "dev": true, - "requires": { - "@nomicfoundation/ethereumjs-rlp": "5.0.1", - "@nomicfoundation/ethereumjs-util": "9.0.1", - "@types/readable-stream": "^2.3.13", - "ethereum-cryptography": "0.1.3", - "readable-stream": "^3.6.0" - }, - "dependencies": { - "ethereum-cryptography": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz", - "integrity": "sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==", - "dev": true, - "requires": { - "@types/pbkdf2": "^3.0.0", - "@types/secp256k1": "^4.0.1", - "blakejs": "^1.1.0", - "browserify-aes": "^1.2.0", - "bs58check": "^2.1.2", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "hash.js": "^1.1.7", - "keccak": "^3.0.0", - "pbkdf2": "^3.0.17", - "randombytes": "^2.1.0", - "safe-buffer": "^5.1.2", - "scrypt-js": "^3.0.0", - "secp256k1": "^4.0.1", - "setimmediate": "^1.0.5" - } - } - } - }, - "@nomicfoundation/ethereumjs-tx": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-tx/-/ethereumjs-tx-5.0.1.tgz", - "integrity": "sha512-0HwxUF2u2hrsIM1fsasjXvlbDOq1ZHFV2dd1yGq8CA+MEYhaxZr8OTScpVkkxqMwBcc5y83FyPl0J9MZn3kY0w==", - "dev": true, - "requires": { - "@chainsafe/ssz": "^0.9.2", - "@ethersproject/providers": "^5.7.2", - "@nomicfoundation/ethereumjs-common": "4.0.1", - "@nomicfoundation/ethereumjs-rlp": "5.0.1", - "@nomicfoundation/ethereumjs-util": "9.0.1", - "ethereum-cryptography": "0.1.3" - }, - "dependencies": { - "ethereum-cryptography": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz", - "integrity": "sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==", - "dev": true, - "requires": { - "@types/pbkdf2": "^3.0.0", - "@types/secp256k1": "^4.0.1", - "blakejs": "^1.1.0", - "browserify-aes": "^1.2.0", - "bs58check": "^2.1.2", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "hash.js": "^1.1.7", - "keccak": "^3.0.0", - "pbkdf2": "^3.0.17", - "randombytes": "^2.1.0", - "safe-buffer": "^5.1.2", - "scrypt-js": "^3.0.0", - "secp256k1": "^4.0.1", - "setimmediate": "^1.0.5" - } - } - } - }, - "@nomicfoundation/ethereumjs-util": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-util/-/ethereumjs-util-9.0.1.tgz", - "integrity": "sha512-TwbhOWQ8QoSCFhV/DDfSmyfFIHjPjFBj957219+V3jTZYZ2rf9PmDtNOeZWAE3p3vlp8xb02XGpd0v6nTUPbsA==", - "dev": true, - "requires": { - "@chainsafe/ssz": "^0.10.0", - "@nomicfoundation/ethereumjs-rlp": "5.0.1", - "ethereum-cryptography": "0.1.3" - }, - "dependencies": { - "@chainsafe/persistent-merkle-tree": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/@chainsafe/persistent-merkle-tree/-/persistent-merkle-tree-0.5.0.tgz", - "integrity": "sha512-l0V1b5clxA3iwQLXP40zYjyZYospQLZXzBVIhhr9kDg/1qHZfzzHw0jj4VPBijfYCArZDlPkRi1wZaV2POKeuw==", - "dev": true, - "requires": { - "@chainsafe/as-sha256": "^0.3.1" - } - }, - "@chainsafe/ssz": { - "version": "0.10.2", - "resolved": "https://registry.npmjs.org/@chainsafe/ssz/-/ssz-0.10.2.tgz", - "integrity": "sha512-/NL3Lh8K+0q7A3LsiFq09YXS9fPE+ead2rr7vM2QK8PLzrNsw3uqrif9bpRX5UxgeRjM+vYi+boCM3+GM4ovXg==", - "dev": true, - "requires": { - "@chainsafe/as-sha256": "^0.3.1", - "@chainsafe/persistent-merkle-tree": "^0.5.0" - } - }, - "ethereum-cryptography": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz", - "integrity": "sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==", - "dev": true, - "requires": { - "@types/pbkdf2": "^3.0.0", - "@types/secp256k1": "^4.0.1", - "blakejs": "^1.1.0", - "browserify-aes": "^1.2.0", - "bs58check": "^2.1.2", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "hash.js": "^1.1.7", - "keccak": "^3.0.0", - "pbkdf2": "^3.0.17", - "randombytes": "^2.1.0", - "safe-buffer": "^5.1.2", - "scrypt-js": "^3.0.0", - "secp256k1": "^4.0.1", - "setimmediate": "^1.0.5" - } - } - } - }, - "@nomicfoundation/ethereumjs-vm": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-vm/-/ethereumjs-vm-7.0.1.tgz", - "integrity": "sha512-rArhyn0jPsS/D+ApFsz3yVJMQ29+pVzNZ0VJgkzAZ+7FqXSRtThl1C1prhmlVr3YNUlfpZ69Ak+RUT4g7VoOuQ==", - "dev": true, - "requires": { - "@nomicfoundation/ethereumjs-block": "5.0.1", - "@nomicfoundation/ethereumjs-blockchain": "7.0.1", - "@nomicfoundation/ethereumjs-common": "4.0.1", - "@nomicfoundation/ethereumjs-evm": "2.0.1", - "@nomicfoundation/ethereumjs-rlp": "5.0.1", - "@nomicfoundation/ethereumjs-statemanager": "2.0.1", - "@nomicfoundation/ethereumjs-trie": "6.0.1", - "@nomicfoundation/ethereumjs-tx": "5.0.1", - "@nomicfoundation/ethereumjs-util": "9.0.1", - "debug": "^4.3.3", - "ethereum-cryptography": "0.1.3", - "mcl-wasm": "^0.7.1", - "rustbn.js": "~0.2.0" - }, - "dependencies": { - "ethereum-cryptography": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz", - "integrity": "sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==", - "dev": true, - "requires": { - "@types/pbkdf2": "^3.0.0", - "@types/secp256k1": "^4.0.1", - "blakejs": "^1.1.0", - "browserify-aes": "^1.2.0", - "bs58check": "^2.1.2", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "hash.js": "^1.1.7", - "keccak": "^3.0.0", - "pbkdf2": "^3.0.17", - "randombytes": "^2.1.0", - "safe-buffer": "^5.1.2", - "scrypt-js": "^3.0.0", - "secp256k1": "^4.0.1", - "setimmediate": "^1.0.5" - } - } - } - }, - "@nomicfoundation/solidity-analyzer": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer/-/solidity-analyzer-0.1.1.tgz", - "integrity": "sha512-1LMtXj1puAxyFusBgUIy5pZk3073cNXYnXUpuNKFghHbIit/xZgbk0AokpUADbNm3gyD6bFWl3LRFh3dhVdREg==", - "dev": true, - "requires": { - "@nomicfoundation/solidity-analyzer-darwin-arm64": "0.1.1", - "@nomicfoundation/solidity-analyzer-darwin-x64": "0.1.1", - "@nomicfoundation/solidity-analyzer-freebsd-x64": "0.1.1", - "@nomicfoundation/solidity-analyzer-linux-arm64-gnu": "0.1.1", - "@nomicfoundation/solidity-analyzer-linux-arm64-musl": "0.1.1", - "@nomicfoundation/solidity-analyzer-linux-x64-gnu": "0.1.1", - "@nomicfoundation/solidity-analyzer-linux-x64-musl": "0.1.1", - "@nomicfoundation/solidity-analyzer-win32-arm64-msvc": "0.1.1", - "@nomicfoundation/solidity-analyzer-win32-ia32-msvc": "0.1.1", - "@nomicfoundation/solidity-analyzer-win32-x64-msvc": "0.1.1" - } - }, - "@nomicfoundation/solidity-analyzer-darwin-arm64": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-darwin-arm64/-/solidity-analyzer-darwin-arm64-0.1.1.tgz", - "integrity": "sha512-KcTodaQw8ivDZyF+D76FokN/HdpgGpfjc/gFCImdLUyqB6eSWVaZPazMbeAjmfhx3R0zm/NYVzxwAokFKgrc0w==", - "dev": true, - "optional": true - }, - "@nomicfoundation/solidity-analyzer-darwin-x64": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-darwin-x64/-/solidity-analyzer-darwin-x64-0.1.1.tgz", - "integrity": "sha512-XhQG4BaJE6cIbjAVtzGOGbK3sn1BO9W29uhk9J8y8fZF1DYz0Doj8QDMfpMu+A6TjPDs61lbsmeYodIDnfveSA==", - "dev": true, - "optional": true - }, - "@nomicfoundation/solidity-analyzer-freebsd-x64": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-freebsd-x64/-/solidity-analyzer-freebsd-x64-0.1.1.tgz", - "integrity": "sha512-GHF1VKRdHW3G8CndkwdaeLkVBi5A9u2jwtlS7SLhBc8b5U/GcoL39Q+1CSO3hYqePNP+eV5YI7Zgm0ea6kMHoA==", - "dev": true, - "optional": true - }, - "@nomicfoundation/solidity-analyzer-linux-arm64-gnu": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-linux-arm64-gnu/-/solidity-analyzer-linux-arm64-gnu-0.1.1.tgz", - "integrity": "sha512-g4Cv2fO37ZsUENQ2vwPnZc2zRenHyAxHcyBjKcjaSmmkKrFr64yvzeNO8S3GBFCo90rfochLs99wFVGT/0owpg==", - "dev": true, - "optional": true - }, - "@nomicfoundation/solidity-analyzer-linux-arm64-musl": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-linux-arm64-musl/-/solidity-analyzer-linux-arm64-musl-0.1.1.tgz", - "integrity": "sha512-WJ3CE5Oek25OGE3WwzK7oaopY8xMw9Lhb0mlYuJl/maZVo+WtP36XoQTb7bW/i8aAdHW5Z+BqrHMux23pvxG3w==", - "dev": true, - "optional": true - }, - "@nomicfoundation/solidity-analyzer-linux-x64-gnu": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-linux-x64-gnu/-/solidity-analyzer-linux-x64-gnu-0.1.1.tgz", - "integrity": "sha512-5WN7leSr5fkUBBjE4f3wKENUy9HQStu7HmWqbtknfXkkil+eNWiBV275IOlpXku7v3uLsXTOKpnnGHJYI2qsdA==", - "dev": true, - "optional": true - }, - "@nomicfoundation/solidity-analyzer-linux-x64-musl": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-linux-x64-musl/-/solidity-analyzer-linux-x64-musl-0.1.1.tgz", - "integrity": "sha512-KdYMkJOq0SYPQMmErv/63CwGwMm5XHenEna9X9aB8mQmhDBrYrlAOSsIPgFCUSL0hjxE3xHP65/EPXR/InD2+w==", - "dev": true, - "optional": true - }, - "@nomicfoundation/solidity-analyzer-win32-arm64-msvc": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-win32-arm64-msvc/-/solidity-analyzer-win32-arm64-msvc-0.1.1.tgz", - "integrity": "sha512-VFZASBfl4qiBYwW5xeY20exWhmv6ww9sWu/krWSesv3q5hA0o1JuzmPHR4LPN6SUZj5vcqci0O6JOL8BPw+APg==", - "dev": true, - "optional": true - }, - "@nomicfoundation/solidity-analyzer-win32-ia32-msvc": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-win32-ia32-msvc/-/solidity-analyzer-win32-ia32-msvc-0.1.1.tgz", - "integrity": "sha512-JnFkYuyCSA70j6Si6cS1A9Gh1aHTEb8kOTBApp/c7NRTFGNMH8eaInKlyuuiIbvYFhlXW4LicqyYuWNNq9hkpQ==", - "dev": true, - "optional": true - }, - "@nomicfoundation/solidity-analyzer-win32-x64-msvc": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-win32-x64-msvc/-/solidity-analyzer-win32-x64-msvc-0.1.1.tgz", - "integrity": "sha512-HrVJr6+WjIXGnw3Q9u6KQcbZCtk0caVWhCdFADySvRyUxJ8PnzlaP+MhwNE8oyT8OZ6ejHBRrrgjSqDCFXGirw==", - "dev": true, - "optional": true - }, - "@nomiclabs/hardhat-ethers": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/@nomiclabs/hardhat-ethers/-/hardhat-ethers-2.2.3.tgz", - "integrity": "sha512-YhzPdzb612X591FOe68q+qXVXGG2ANZRvDo0RRUtimev85rCrAlv/TLMEZw5c+kq9AbzocLTVX/h2jVIFPL9Xg==", - "dev": true, - "requires": {} - }, - "@nomiclabs/hardhat-etherscan": { - "version": "3.1.8", - "resolved": "https://registry.npmjs.org/@nomiclabs/hardhat-etherscan/-/hardhat-etherscan-3.1.8.tgz", - "integrity": "sha512-v5F6IzQhrsjHh6kQz4uNrym49brK9K5bYCq2zQZ729RYRaifI9hHbtmK+KkIVevfhut7huQFEQ77JLRMAzWYjQ==", - "dev": true, - "requires": { - "@ethersproject/abi": "^5.1.2", - "@ethersproject/address": "^5.0.2", - "cbor": "^8.1.0", - "chalk": "^2.4.2", - "debug": "^4.1.1", - "fs-extra": "^7.0.1", - "lodash": "^4.17.11", - "semver": "^6.3.0", - "table": "^6.8.0", - "undici": "^5.14.0" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "@nomiclabs/hardhat-waffle": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/@nomiclabs/hardhat-waffle/-/hardhat-waffle-2.0.6.tgz", - "integrity": "sha512-+Wz0hwmJGSI17B+BhU/qFRZ1l6/xMW82QGXE/Gi+WTmwgJrQefuBs1lIf7hzQ1hLk6hpkvb/zwcNkpVKRYTQYg==", - "dev": true, - "requires": {} - }, - "@openzeppelin/contracts": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/@openzeppelin/contracts/-/contracts-4.6.0.tgz", - "integrity": "sha512-8vi4d50NNya/bQqCmaVzvHNmwHvS0OBKb7HNtuNwEE3scXWrP31fKQoGxNMT+KbzmrNZzatE3QK5p2gFONI/hg==" - }, - "@resolver-engine/core": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/@resolver-engine/core/-/core-0.3.3.tgz", - "integrity": "sha512-eB8nEbKDJJBi5p5SrvrvILn4a0h42bKtbCTri3ZxCGt6UvoQyp7HnGOfki944bUjBSHKK3RvgfViHn+kqdXtnQ==", - "dev": true, - "requires": { - "debug": "^3.1.0", - "is-url": "^1.2.4", - "request": "^2.85.0" - }, - "dependencies": { - "debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - } - } - }, - "@resolver-engine/fs": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/@resolver-engine/fs/-/fs-0.3.3.tgz", - "integrity": "sha512-wQ9RhPUcny02Wm0IuJwYMyAG8fXVeKdmhm8xizNByD4ryZlx6PP6kRen+t/haF43cMfmaV7T3Cx6ChOdHEhFUQ==", - "dev": true, - "requires": { - "@resolver-engine/core": "^0.3.3", - "debug": "^3.1.0" - }, - "dependencies": { - "debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - } - } - }, - "@resolver-engine/imports": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/@resolver-engine/imports/-/imports-0.3.3.tgz", - "integrity": "sha512-anHpS4wN4sRMwsAbMXhMfOD/y4a4Oo0Cw/5+rue7hSwGWsDOQaAU1ClK1OxjUC35/peazxEl8JaSRRS+Xb8t3Q==", - "dev": true, - "requires": { - "@resolver-engine/core": "^0.3.3", - "debug": "^3.1.0", - "hosted-git-info": "^2.6.0", - "path-browserify": "^1.0.0", - "url": "^0.11.0" - }, - "dependencies": { - "debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - } - } - }, - "@resolver-engine/imports-fs": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/@resolver-engine/imports-fs/-/imports-fs-0.3.3.tgz", - "integrity": "sha512-7Pjg/ZAZtxpeyCFlZR5zqYkz+Wdo84ugB5LApwriT8XFeQoLwGUj4tZFFvvCuxaNCcqZzCYbonJgmGObYBzyCA==", - "dev": true, - "requires": { - "@resolver-engine/fs": "^0.3.3", - "@resolver-engine/imports": "^0.3.3", - "debug": "^3.1.0" - }, - "dependencies": { - "debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - } - } - }, - "@scure/base": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@scure/base/-/base-1.1.1.tgz", - "integrity": "sha512-ZxOhsSyxYwLJj3pLZCefNitxsj093tb2vq90mp2txoYeBqbcjDjqFhyM8eUjq/uFm6zJ+mUuqxlS2FkuSY1MTA==", - "dev": true - }, - "@scure/bip32": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/@scure/bip32/-/bip32-1.1.5.tgz", - "integrity": "sha512-XyNh1rB0SkEqd3tXcXMi+Xe1fvg+kUIcoRIEujP1Jgv7DqW2r9lg3Ah0NkFaCs9sTkQAQA8kw7xiRXzENi9Rtw==", - "dev": true, - "requires": { - "@noble/hashes": "~1.2.0", - "@noble/secp256k1": "~1.7.0", - "@scure/base": "~1.1.0" - } - }, - "@scure/bip39": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@scure/bip39/-/bip39-1.1.1.tgz", - "integrity": "sha512-t+wDck2rVkh65Hmv280fYdVdY25J9YeEUIgn2LG1WM6gxFkGzcksoDiUkWVpVp3Oex9xGC68JU2dSbUfwZ2jPg==", - "dev": true, - "requires": { - "@noble/hashes": "~1.2.0", - "@scure/base": "~1.1.0" - } - }, - "@sentry/core": { - "version": "5.30.0", - "resolved": "https://registry.npmjs.org/@sentry/core/-/core-5.30.0.tgz", - "integrity": "sha512-TmfrII8w1PQZSZgPpUESqjB+jC6MvZJZdLtE/0hZ+SrnKhW3x5WlYLvTXZpcWePYBku7rl2wn1RZu6uT0qCTeg==", - "dev": true, - "requires": { - "@sentry/hub": "5.30.0", - "@sentry/minimal": "5.30.0", - "@sentry/types": "5.30.0", - "@sentry/utils": "5.30.0", - "tslib": "^1.9.3" - } - }, - "@sentry/hub": { - "version": "5.30.0", - "resolved": "https://registry.npmjs.org/@sentry/hub/-/hub-5.30.0.tgz", - "integrity": "sha512-2tYrGnzb1gKz2EkMDQcfLrDTvmGcQPuWxLnJKXJvYTQDGLlEvi2tWz1VIHjunmOvJrB5aIQLhm+dcMRwFZDCqQ==", - "dev": true, - "requires": { - "@sentry/types": "5.30.0", - "@sentry/utils": "5.30.0", - "tslib": "^1.9.3" - } - }, - "@sentry/minimal": { - "version": "5.30.0", - "resolved": "https://registry.npmjs.org/@sentry/minimal/-/minimal-5.30.0.tgz", - "integrity": "sha512-BwWb/owZKtkDX+Sc4zCSTNcvZUq7YcH3uAVlmh/gtR9rmUvbzAA3ewLuB3myi4wWRAMEtny6+J/FN/x+2wn9Xw==", - "dev": true, - "requires": { - "@sentry/hub": "5.30.0", - "@sentry/types": "5.30.0", - "tslib": "^1.9.3" - } - }, - "@sentry/node": { - "version": "5.30.0", - "resolved": "https://registry.npmjs.org/@sentry/node/-/node-5.30.0.tgz", - "integrity": "sha512-Br5oyVBF0fZo6ZS9bxbJZG4ApAjRqAnqFFurMVJJdunNb80brh7a5Qva2kjhm+U6r9NJAB5OmDyPkA1Qnt+QVg==", - "dev": true, - "requires": { - "@sentry/core": "5.30.0", - "@sentry/hub": "5.30.0", - "@sentry/tracing": "5.30.0", - "@sentry/types": "5.30.0", - "@sentry/utils": "5.30.0", - "cookie": "^0.4.1", - "https-proxy-agent": "^5.0.0", - "lru_map": "^0.3.3", - "tslib": "^1.9.3" - } - }, - "@sentry/tracing": { - "version": "5.30.0", - "resolved": "https://registry.npmjs.org/@sentry/tracing/-/tracing-5.30.0.tgz", - "integrity": "sha512-dUFowCr0AIMwiLD7Fs314Mdzcug+gBVo/+NCMyDw8tFxJkwWAKl7Qa2OZxLQ0ZHjakcj1hNKfCQJ9rhyfOl4Aw==", - "dev": true, - "requires": { - "@sentry/hub": "5.30.0", - "@sentry/minimal": "5.30.0", - "@sentry/types": "5.30.0", - "@sentry/utils": "5.30.0", - "tslib": "^1.9.3" - } - }, - "@sentry/types": { - "version": "5.30.0", - "resolved": "https://registry.npmjs.org/@sentry/types/-/types-5.30.0.tgz", - "integrity": "sha512-R8xOqlSTZ+htqrfteCWU5Nk0CDN5ApUTvrlvBuiH1DyP6czDZ4ktbZB0hAgBlVcK0U+qpD3ag3Tqqpa5Q67rPw==", - "dev": true - }, - "@sentry/utils": { - "version": "5.30.0", - "resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-5.30.0.tgz", - "integrity": "sha512-zaYmoH0NWWtvnJjC9/CBseXMtKHm/tm40sz3YfJRxeQjyzRqNQPgivpd9R/oDJCYj999mzdW382p/qi2ypjLww==", - "dev": true, - "requires": { - "@sentry/types": "5.30.0", - "tslib": "^1.9.3" - } - }, - "@sindresorhus/is": { - "version": "0.14.0", - "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.14.0.tgz", - "integrity": "sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ==", - "dev": true - }, - "@solidity-parser/parser": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/@solidity-parser/parser/-/parser-0.14.5.tgz", - "integrity": "sha512-6dKnHZn7fg/iQATVEzqyUOyEidbn05q7YA2mQ9hC0MMXhhV3/JrsxmFSYZAcr7j1yUP700LLhTruvJ3MiQmjJg==", - "dev": true, - "requires": { - "antlr4ts": "^0.5.0-alpha.4" - } - }, - "@szmarczak/http-timer": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-1.1.2.tgz", - "integrity": "sha512-XIB2XbzHTN6ieIjfIMV9hlVcfPU26s2vafYWQcZHWXHOxiaRZYEDKEwdl129Zyg50+foYV2jCgtrqSA6qNuNSA==", - "dev": true, - "requires": { - "defer-to-connect": "^1.0.1" - } - }, - "@truffle/error": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/@truffle/error/-/error-0.1.1.tgz", - "integrity": "sha512-sE7c9IHIGdbK4YayH4BC8i8qMjoAOeg6nUXUDZZp8wlU21/EMpaG+CLx+KqcIPyR+GSWIW3Dm0PXkr2nlggFDA==", - "dev": true - }, - "@truffle/interface-adapter": { - "version": "0.5.35", - "resolved": "https://registry.npmjs.org/@truffle/interface-adapter/-/interface-adapter-0.5.35.tgz", - "integrity": "sha512-B5gtJnvsum5j2do393n0UfCT8MklrlAZxuqvEFBeMM9UKnreYct0/D368FVMlZwWo1N50HgGeZ0hlpSJqR/nvg==", - "dev": true, - "requires": { - "bn.js": "^5.1.3", - "ethers": "^4.0.32", - "web3": "1.10.0" - }, - "dependencies": { - "@ethereumjs/common": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/@ethereumjs/common/-/common-2.5.0.tgz", - "integrity": "sha512-DEHjW6e38o+JmB/NO3GZBpW4lpaiBpkFgXF6jLcJ6gETBYpEyaA5nTimsWBUJR3Vmtm/didUEbNjajskugZORg==", - "dev": true, - "requires": { - "crc-32": "^1.2.0", - "ethereumjs-util": "^7.1.1" - } - }, - "@ethereumjs/tx": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/@ethereumjs/tx/-/tx-3.3.2.tgz", - "integrity": "sha512-6AaJhwg4ucmwTvw/1qLaZUX5miWrwZ4nLOUsKyb/HtzS3BMw/CasKhdi1ims9mBKeK9sOJCH4qGKOBGyJCeeog==", - "dev": true, - "requires": { - "@ethereumjs/common": "^2.5.0", - "ethereumjs-util": "^7.1.2" - } - }, - "@sindresorhus/is": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.6.0.tgz", - "integrity": "sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==", - "dev": true - }, - "@szmarczak/http-timer": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-5.0.1.tgz", - "integrity": "sha512-+PmQX0PiAYPMeVYe237LJAYvOMYW1j2rH5YROyS3b4CTVJum34HfRvKvAzozHAQG0TnHNdUfY9nCeUyRAs//cw==", - "dev": true, - "requires": { - "defer-to-connect": "^2.0.1" - } - }, - "cacheable-request": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-7.0.4.tgz", - "integrity": "sha512-v+p6ongsrp0yTGbJXjgxPow2+DL93DASP4kXCDKb8/bwRtt9OEF3whggkkDkGNzgcWy2XaF4a8nZglC7uElscg==", - "dev": true, - "requires": { - "clone-response": "^1.0.2", - "get-stream": "^5.1.0", - "http-cache-semantics": "^4.0.0", - "keyv": "^4.0.0", - "lowercase-keys": "^2.0.0", - "normalize-url": "^6.0.1", - "responselike": "^2.0.0" - }, - "dependencies": { - "get-stream": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", - "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", - "dev": true, - "requires": { - "pump": "^3.0.0" - } - }, - "lowercase-keys": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", - "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", - "dev": true - } - } - }, - "decompress-response": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", - "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", - "dev": true, - "requires": { - "mimic-response": "^3.1.0" - } - }, - "defer-to-connect": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.1.tgz", - "integrity": "sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==", - "dev": true - }, - "eth-lib": { - "version": "0.2.8", - "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.2.8.tgz", - "integrity": "sha512-ArJ7x1WcWOlSpzdoTBX8vkwlkSQ85CjjifSZtV4co64vWxSV8geWfPI9x4SVYu3DSxnX4yWFVTtGL+j9DUFLNw==", - "dev": true, - "requires": { - "bn.js": "^4.11.6", - "elliptic": "^6.4.0", - "xhr-request-promise": "^0.1.2" - }, - "dependencies": { - "bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", - "dev": true - } - } - }, - "ethereum-cryptography": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz", - "integrity": "sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==", - "dev": true, - "requires": { - "@types/pbkdf2": "^3.0.0", - "@types/secp256k1": "^4.0.1", - "blakejs": "^1.1.0", - "browserify-aes": "^1.2.0", - "bs58check": "^2.1.2", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "hash.js": "^1.1.7", - "keccak": "^3.0.0", - "pbkdf2": "^3.0.17", - "randombytes": "^2.1.0", - "safe-buffer": "^5.1.2", - "scrypt-js": "^3.0.0", - "secp256k1": "^4.0.1", - "setimmediate": "^1.0.5" - }, - "dependencies": { - "hash.js": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", - "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "minimalistic-assert": "^1.0.1" - } - }, - "scrypt-js": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/scrypt-js/-/scrypt-js-3.0.1.tgz", - "integrity": "sha512-cdwTTnqPu0Hyvf5in5asVdZocVDTNRmR7XEcJuIzMjJeSHybHl7vpB66AzwTaIg6CLSbtjcxc8fqcySfnTkccA==", - "dev": true - }, - "setimmediate": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", - "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==", - "dev": true - } - } - }, - "ethereumjs-util": { - "version": "7.1.5", - "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-7.1.5.tgz", - "integrity": "sha512-SDl5kKrQAudFBUe5OJM9Ac6WmMyYmXX/6sTmLZ3ffG2eY6ZIGBes3pEDxNN6V72WyOw4CPD5RomKdsa8DAAwLg==", - "dev": true, - "requires": { - "@types/bn.js": "^5.1.0", - "bn.js": "^5.1.2", - "create-hash": "^1.1.2", - "ethereum-cryptography": "^0.1.3", - "rlp": "^2.2.4" - } - }, - "ethers": { - "version": "4.0.49", - "resolved": "https://registry.npmjs.org/ethers/-/ethers-4.0.49.tgz", - "integrity": "sha512-kPltTvWiyu+OktYy1IStSO16i2e7cS9D9OxZ81q2UUaiNPVrm/RTcbxamCXF9VUSKzJIdJV68EAIhTEVBalRWg==", - "dev": true, - "requires": { - "aes-js": "3.0.0", - "bn.js": "^4.11.9", - "elliptic": "6.5.4", - "hash.js": "1.1.3", - "js-sha3": "0.5.7", - "scrypt-js": "2.0.4", - "setimmediate": "1.0.4", - "uuid": "2.0.1", - "xmlhttprequest": "1.8.0" - }, - "dependencies": { - "bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", - "dev": true - } - } - }, - "get-stream": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", - "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", - "dev": true - }, - "got": { - "version": "12.1.0", - "resolved": "https://registry.npmjs.org/got/-/got-12.1.0.tgz", - "integrity": "sha512-hBv2ty9QN2RdbJJMK3hesmSkFTjVIHyIDDbssCKnSmq62edGgImJWD10Eb1k77TiV1bxloxqcFAVK8+9pkhOig==", - "dev": true, - "requires": { - "@sindresorhus/is": "^4.6.0", - "@szmarczak/http-timer": "^5.0.1", - "@types/cacheable-request": "^6.0.2", - "@types/responselike": "^1.0.0", - "cacheable-lookup": "^6.0.4", - "cacheable-request": "^7.0.2", - "decompress-response": "^6.0.0", - "form-data-encoder": "1.7.1", - "get-stream": "^6.0.1", - "http2-wrapper": "^2.1.10", - "lowercase-keys": "^3.0.0", - "p-cancelable": "^3.0.0", - "responselike": "^2.0.0" - } - }, - "hash.js": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.3.tgz", - "integrity": "sha512-/UETyP0W22QILqS+6HowevwhEFJ3MBJnwTf75Qob9Wz9t0DPuisL8kW8YZMK62dHAKE1c1p+gY1TtOLY+USEHA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "minimalistic-assert": "^1.0.0" - } - }, - "js-sha3": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.5.7.tgz", - "integrity": "sha512-GII20kjaPX0zJ8wzkTbNDYMY7msuZcTWk8S5UOh6806Jq/wz1J8/bnr8uGU0DAUmYDjj2Mr4X1cW8v/GLYnR+g==", - "dev": true - }, - "json-buffer": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", - "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", - "dev": true - }, - "keyv": { - "version": "4.5.3", - "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.3.tgz", - "integrity": "sha512-QCiSav9WaX1PgETJ+SpNnx2PRRapJ/oRSXM4VO5OGYGSjrxbKPVFVhB3l2OCbLCk329N8qyAtsJjSjvVBWzEug==", - "dev": true, - "requires": { - "json-buffer": "3.0.1" - } - }, - "lowercase-keys": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-3.0.0.tgz", - "integrity": "sha512-ozCC6gdQ+glXOQsveKD0YsDy8DSQFjDTz4zyzEHNV5+JP5D62LmfDZ6o1cycFx9ouG940M5dE8C8CTewdj2YWQ==", - "dev": true - }, - "mimic-response": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", - "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", - "dev": true - }, - "normalize-url": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz", - "integrity": "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==", - "dev": true - }, - "p-cancelable": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-3.0.0.tgz", - "integrity": "sha512-mlVgR3PGuzlo0MmTdk4cXqXWlwQDLnONTAg6sm62XkMJEiRxN3GL3SffkYvqwonbkJBcrI7Uvv5Zh9yjvn2iUw==", - "dev": true - }, - "responselike": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/responselike/-/responselike-2.0.1.tgz", - "integrity": "sha512-4gl03wn3hj1HP3yzgdI7d3lCkF95F21Pz4BPGvKHinyQzALR5CapwC8yIi0Rh58DEMQ/SguC03wFj2k0M/mHhw==", - "dev": true, - "requires": { - "lowercase-keys": "^2.0.0" - }, - "dependencies": { - "lowercase-keys": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", - "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", - "dev": true - } - } - }, - "scrypt-js": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/scrypt-js/-/scrypt-js-2.0.4.tgz", - "integrity": "sha512-4KsaGcPnuhtCZQCxFxN3GVYIhKFPTdLd8PLC552XwbMndtD0cjRFAhDuuydXQ0h08ZfPgzqe6EKHozpuH74iDw==", - "dev": true - }, - "setimmediate": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.4.tgz", - "integrity": "sha512-/TjEmXQVEzdod/FFskf3o7oOAsGhHf2j1dZqRFbDzq4F3mvvxflIIi4Hd3bLQE9y/CpwqfSQam5JakI/mi3Pog==", - "dev": true - }, - "uuid": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-2.0.1.tgz", - "integrity": "sha512-nWg9+Oa3qD2CQzHIP4qKUqwNfzKn8P0LtFhotaCTFchsV7ZfDhAybeip/HZVeMIpZi9JgY1E3nUlwaCmZT1sEg==", - "dev": true - }, - "web3": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/web3/-/web3-1.10.0.tgz", - "integrity": "sha512-YfKY9wSkGcM8seO+daR89oVTcbu18NsVfvOngzqMYGUU0pPSQmE57qQDvQzUeoIOHAnXEBNzrhjQJmm8ER0rng==", - "dev": true, - "requires": { - "web3-bzz": "1.10.0", - "web3-core": "1.10.0", - "web3-eth": "1.10.0", - "web3-eth-personal": "1.10.0", - "web3-net": "1.10.0", - "web3-shh": "1.10.0", - "web3-utils": "1.10.0" - } - }, - "web3-bzz": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/web3-bzz/-/web3-bzz-1.10.0.tgz", - "integrity": "sha512-o9IR59io3pDUsXTsps5pO5hW1D5zBmg46iNc2t4j2DkaYHNdDLwk2IP9ukoM2wg47QILfPEJYzhTfkS/CcX0KA==", - "dev": true, - "requires": { - "@types/node": "^12.12.6", - "got": "12.1.0", - "swarm-js": "^0.1.40" - } - }, - "web3-core": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/web3-core/-/web3-core-1.10.0.tgz", - "integrity": "sha512-fWySwqy2hn3TL89w5TM8wXF1Z2Q6frQTKHWmP0ppRQorEK8NcHJRfeMiv/mQlSKoTS1F6n/nv2uyZsixFycjYQ==", - "dev": true, - "requires": { - "@types/bn.js": "^5.1.1", - "@types/node": "^12.12.6", - "bignumber.js": "^9.0.0", - "web3-core-helpers": "1.10.0", - "web3-core-method": "1.10.0", - "web3-core-requestmanager": "1.10.0", - "web3-utils": "1.10.0" - } - }, - "web3-core-helpers": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/web3-core-helpers/-/web3-core-helpers-1.10.0.tgz", - "integrity": "sha512-pIxAzFDS5vnbXvfvLSpaA1tfRykAe9adw43YCKsEYQwH0gCLL0kMLkaCX3q+Q8EVmAh+e1jWL/nl9U0de1+++g==", - "dev": true, - "requires": { - "web3-eth-iban": "1.10.0", - "web3-utils": "1.10.0" - } - }, - "web3-core-method": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/web3-core-method/-/web3-core-method-1.10.0.tgz", - "integrity": "sha512-4R700jTLAMKDMhQ+nsVfIXvH6IGJlJzGisIfMKWAIswH31h5AZz7uDUW2YctI+HrYd+5uOAlS4OJeeT9bIpvkA==", - "dev": true, - "requires": { - "@ethersproject/transactions": "^5.6.2", - "web3-core-helpers": "1.10.0", - "web3-core-promievent": "1.10.0", - "web3-core-subscriptions": "1.10.0", - "web3-utils": "1.10.0" - } - }, - "web3-core-promievent": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/web3-core-promievent/-/web3-core-promievent-1.10.0.tgz", - "integrity": "sha512-68N7k5LWL5R38xRaKFrTFT2pm2jBNFaM4GioS00YjAKXRQ3KjmhijOMG3TICz6Aa5+6GDWYelDNx21YAeZ4YTg==", - "dev": true, - "requires": { - "eventemitter3": "4.0.4" - } - }, - "web3-core-requestmanager": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/web3-core-requestmanager/-/web3-core-requestmanager-1.10.0.tgz", - "integrity": "sha512-3z/JKE++Os62APml4dvBM+GAuId4h3L9ckUrj7ebEtS2AR0ixyQPbrBodgL91Sv7j7cQ3Y+hllaluqjguxvSaQ==", - "dev": true, - "requires": { - "util": "^0.12.5", - "web3-core-helpers": "1.10.0", - "web3-providers-http": "1.10.0", - "web3-providers-ipc": "1.10.0", - "web3-providers-ws": "1.10.0" - } - }, - "web3-core-subscriptions": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/web3-core-subscriptions/-/web3-core-subscriptions-1.10.0.tgz", - "integrity": "sha512-HGm1PbDqsxejI075gxBc5OSkwymilRWZufIy9zEpnWKNmfbuv5FfHgW1/chtJP6aP3Uq2vHkvTDl3smQBb8l+g==", - "dev": true, - "requires": { - "eventemitter3": "4.0.4", - "web3-core-helpers": "1.10.0" - } - }, - "web3-eth": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/web3-eth/-/web3-eth-1.10.0.tgz", - "integrity": "sha512-Z5vT6slNMLPKuwRyKGbqeGYC87OAy8bOblaqRTgg94CXcn/mmqU7iPIlG4506YdcdK3x6cfEDG7B6w+jRxypKA==", - "dev": true, - "requires": { - "web3-core": "1.10.0", - "web3-core-helpers": "1.10.0", - "web3-core-method": "1.10.0", - "web3-core-subscriptions": "1.10.0", - "web3-eth-abi": "1.10.0", - "web3-eth-accounts": "1.10.0", - "web3-eth-contract": "1.10.0", - "web3-eth-ens": "1.10.0", - "web3-eth-iban": "1.10.0", - "web3-eth-personal": "1.10.0", - "web3-net": "1.10.0", - "web3-utils": "1.10.0" - } - }, - "web3-eth-abi": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/web3-eth-abi/-/web3-eth-abi-1.10.0.tgz", - "integrity": "sha512-cwS+qRBWpJ43aI9L3JS88QYPfFcSJJ3XapxOQ4j40v6mk7ATpA8CVK1vGTzpihNlOfMVRBkR95oAj7oL6aiDOg==", - "dev": true, - "requires": { - "@ethersproject/abi": "^5.6.3", - "web3-utils": "1.10.0" - } - }, - "web3-eth-accounts": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/web3-eth-accounts/-/web3-eth-accounts-1.10.0.tgz", - "integrity": "sha512-wiq39Uc3mOI8rw24wE2n15hboLE0E9BsQLdlmsL4Zua9diDS6B5abXG0XhFcoNsXIGMWXVZz4TOq3u4EdpXF/Q==", - "dev": true, - "requires": { - "@ethereumjs/common": "2.5.0", - "@ethereumjs/tx": "3.3.2", - "eth-lib": "0.2.8", - "ethereumjs-util": "^7.1.5", - "scrypt-js": "^3.0.1", - "uuid": "^9.0.0", - "web3-core": "1.10.0", - "web3-core-helpers": "1.10.0", - "web3-core-method": "1.10.0", - "web3-utils": "1.10.0" - }, - "dependencies": { - "scrypt-js": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/scrypt-js/-/scrypt-js-3.0.1.tgz", - "integrity": "sha512-cdwTTnqPu0Hyvf5in5asVdZocVDTNRmR7XEcJuIzMjJeSHybHl7vpB66AzwTaIg6CLSbtjcxc8fqcySfnTkccA==", - "dev": true - }, - "uuid": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.0.tgz", - "integrity": "sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg==", - "dev": true - } - } - }, - "web3-eth-contract": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/web3-eth-contract/-/web3-eth-contract-1.10.0.tgz", - "integrity": "sha512-MIC5FOzP/+2evDksQQ/dpcXhSqa/2hFNytdl/x61IeWxhh6vlFeSjq0YVTAyIzdjwnL7nEmZpjfI6y6/Ufhy7w==", - "dev": true, - "requires": { - "@types/bn.js": "^5.1.1", - "web3-core": "1.10.0", - "web3-core-helpers": "1.10.0", - "web3-core-method": "1.10.0", - "web3-core-promievent": "1.10.0", - "web3-core-subscriptions": "1.10.0", - "web3-eth-abi": "1.10.0", - "web3-utils": "1.10.0" - } - }, - "web3-eth-ens": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/web3-eth-ens/-/web3-eth-ens-1.10.0.tgz", - "integrity": "sha512-3hpGgzX3qjgxNAmqdrC2YUQMTfnZbs4GeLEmy8aCWziVwogbuqQZ+Gzdfrym45eOZodk+lmXyLuAdqkNlvkc1g==", - "dev": true, - "requires": { - "content-hash": "^2.5.2", - "eth-ens-namehash": "2.0.8", - "web3-core": "1.10.0", - "web3-core-helpers": "1.10.0", - "web3-core-promievent": "1.10.0", - "web3-eth-abi": "1.10.0", - "web3-eth-contract": "1.10.0", - "web3-utils": "1.10.0" - } - }, - "web3-eth-iban": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/web3-eth-iban/-/web3-eth-iban-1.10.0.tgz", - "integrity": "sha512-0l+SP3IGhInw7Q20LY3IVafYEuufo4Dn75jAHT7c2aDJsIolvf2Lc6ugHkBajlwUneGfbRQs/ccYPQ9JeMUbrg==", - "dev": true, - "requires": { - "bn.js": "^5.2.1", - "web3-utils": "1.10.0" - } - }, - "web3-eth-personal": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/web3-eth-personal/-/web3-eth-personal-1.10.0.tgz", - "integrity": "sha512-anseKn98w/d703eWq52uNuZi7GhQeVjTC5/svrBWEKob0WZ5kPdo+EZoFN0sp5a5ubbrk/E0xSl1/M5yORMtpg==", - "dev": true, - "requires": { - "@types/node": "^12.12.6", - "web3-core": "1.10.0", - "web3-core-helpers": "1.10.0", - "web3-core-method": "1.10.0", - "web3-net": "1.10.0", - "web3-utils": "1.10.0" - } - }, - "web3-net": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/web3-net/-/web3-net-1.10.0.tgz", - "integrity": "sha512-NLH/N3IshYWASpxk4/18Ge6n60GEvWBVeM8inx2dmZJVmRI6SJIlUxbL8jySgiTn3MMZlhbdvrGo8fpUW7a1GA==", - "dev": true, - "requires": { - "web3-core": "1.10.0", - "web3-core-method": "1.10.0", - "web3-utils": "1.10.0" - } - }, - "web3-providers-http": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/web3-providers-http/-/web3-providers-http-1.10.0.tgz", - "integrity": "sha512-eNr965YB8a9mLiNrkjAWNAPXgmQWfpBfkkn7tpEFlghfww0u3I0tktMZiaToJVcL2+Xq+81cxbkpeWJ5XQDwOA==", - "dev": true, - "requires": { - "abortcontroller-polyfill": "^1.7.3", - "cross-fetch": "^3.1.4", - "es6-promise": "^4.2.8", - "web3-core-helpers": "1.10.0" - } - }, - "web3-providers-ipc": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/web3-providers-ipc/-/web3-providers-ipc-1.10.0.tgz", - "integrity": "sha512-OfXG1aWN8L1OUqppshzq8YISkWrYHaATW9H8eh0p89TlWMc1KZOL9vttBuaBEi96D/n0eYDn2trzt22bqHWfXA==", - "dev": true, - "requires": { - "oboe": "2.1.5", - "web3-core-helpers": "1.10.0" - } - }, - "web3-providers-ws": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/web3-providers-ws/-/web3-providers-ws-1.10.0.tgz", - "integrity": "sha512-sK0fNcglW36yD5xjnjtSGBnEtf59cbw4vZzJ+CmOWIKGIR96mP5l684g0WD0Eo+f4NQc2anWWXG74lRc9OVMCQ==", - "dev": true, - "requires": { - "eventemitter3": "4.0.4", - "web3-core-helpers": "1.10.0", - "websocket": "^1.0.32" - } - }, - "web3-shh": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/web3-shh/-/web3-shh-1.10.0.tgz", - "integrity": "sha512-uNUUuNsO2AjX41GJARV9zJibs11eq6HtOe6Wr0FtRUcj8SN6nHeYIzwstAvJ4fXA53gRqFMTxdntHEt9aXVjpg==", - "dev": true, - "requires": { - "web3-core": "1.10.0", - "web3-core-method": "1.10.0", - "web3-core-subscriptions": "1.10.0", - "web3-net": "1.10.0" - } - } - } - }, - "@truffle/provider": { - "version": "0.2.64", - "resolved": "https://registry.npmjs.org/@truffle/provider/-/provider-0.2.64.tgz", - "integrity": "sha512-ZwPsofw4EsCq/2h0t73SPnnFezu4YQWBmK4FxFaOUX0F+o8NsZuHKyfJzuZwyZbiktYmefM3yD9rM0Dj4BhNbw==", - "dev": true, - "requires": { - "@truffle/error": "^0.1.1", - "@truffle/interface-adapter": "^0.5.25", - "debug": "^4.3.1", - "web3": "1.7.4" - } - }, - "@tsconfig/node10": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz", - "integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==", - "dev": true - }, - "@tsconfig/node12": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", - "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", - "dev": true - }, - "@tsconfig/node14": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", - "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", - "dev": true - }, - "@tsconfig/node16": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz", - "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==", - "dev": true - }, - "@typechain/ethers-v5": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@typechain/ethers-v5/-/ethers-v5-7.2.0.tgz", - "integrity": "sha512-jfcmlTvaaJjng63QsT49MT6R1HFhtO/TBMWbyzPFSzMmVIqb2tL6prnKBs4ZJrSvmgIXWy+ttSjpaxCTq8D/Tw==", - "dev": true, - "requires": { - "lodash": "^4.17.15", - "ts-essentials": "^7.0.1" - } - }, - "@typechain/hardhat": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/@typechain/hardhat/-/hardhat-2.3.1.tgz", - "integrity": "sha512-BQV8OKQi0KAzLXCdsPO0pZBNQQ6ra8A2ucC26uFX/kquRBtJu1yEyWnVSmtr07b5hyRoJRpzUeINLnyqz4/MAw==", - "dev": true, - "requires": { - "fs-extra": "^9.1.0" - }, - "dependencies": { - "fs-extra": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", - "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", - "dev": true, - "requires": { - "at-least-node": "^1.0.0", - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - } - }, - "jsonfile": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", - "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.6", - "universalify": "^2.0.0" - } - }, - "universalify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", - "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", - "dev": true - } - } - }, - "@types/bn.js": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-5.1.1.tgz", - "integrity": "sha512-qNrYbZqMx0uJAfKnKclPh+dTwK33KfLHYqtyODwd5HnXOjnkhc4qgn3BrK6RWyGZm5+sIFE7Q7Vz6QQtJB7w7g==", - "requires": { - "@types/node": "*" - } - }, - "@types/cacheable-request": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/@types/cacheable-request/-/cacheable-request-6.0.3.tgz", - "integrity": "sha512-IQ3EbTzGxIigb1I3qPZc1rWJnH0BmSKv5QYTalEwweFvyBDLSAe24zP0le/hyi7ecGfZVlIVAg4BZqb8WBwKqw==", - "dev": true, - "requires": { - "@types/http-cache-semantics": "*", - "@types/keyv": "^3.1.4", - "@types/node": "*", - "@types/responselike": "^1.0.0" - } - }, - "@types/chai": { - "version": "4.3.5", - "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.5.tgz", - "integrity": "sha512-mEo1sAde+UCE6b2hxn332f1g1E8WfYRu6p5SvTKr2ZKC1f7gFJXk4h5PyGP9Dt6gCaG8y8XhwnXWC6Iy2cmBng==", - "dev": true - }, - "@types/concat-stream": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/@types/concat-stream/-/concat-stream-1.6.1.tgz", - "integrity": "sha512-eHE4cQPoj6ngxBZMvVf6Hw7Mh4jMW4U9lpGmS5GBPB9RYxlFg+CHaVN7ErNY4W9XfLIEn20b4VDYaIrbq0q4uA==", - "dev": true, - "requires": { - "@types/node": "*" - } - }, - "@types/form-data": { - "version": "0.0.33", - "resolved": "https://registry.npmjs.org/@types/form-data/-/form-data-0.0.33.tgz", - "integrity": "sha512-8BSvG1kGm83cyJITQMZSulnl6QV8jqAGreJsc5tPu1Jq0vTSOiY/k24Wx82JRpWwZSqrala6sd5rWi6aNXvqcw==", - "dev": true, - "requires": { - "@types/node": "*" - } - }, - "@types/glob": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.2.0.tgz", - "integrity": "sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA==", - "dev": true, - "requires": { - "@types/minimatch": "*", - "@types/node": "*" - } - }, - "@types/http-cache-semantics": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.1.tgz", - "integrity": "sha512-SZs7ekbP8CN0txVG2xVRH6EgKmEm31BOxA07vkFaETzZz1xh+cbt8BcI0slpymvwhx5dlFnQG2rTlPVQn+iRPQ==", - "dev": true - }, - "@types/json-schema": { - "version": "7.0.12", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.12.tgz", - "integrity": "sha512-Hr5Jfhc9eYOQNPYO5WLDq/n4jqijdHNlDXjuAQkkt+mWdQR+XJToOHrsD4cPaMXpn6KO7y2+wM8AZEs8VpBLVA==", - "dev": true - }, - "@types/json5": { - "version": "0.0.29", - "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", - "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", - "dev": true - }, - "@types/keyv": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/@types/keyv/-/keyv-3.1.4.tgz", - "integrity": "sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg==", - "dev": true, - "requires": { - "@types/node": "*" - } - }, - "@types/lru-cache": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/@types/lru-cache/-/lru-cache-5.1.1.tgz", - "integrity": "sha512-ssE3Vlrys7sdIzs5LOxCzTVMsU7i9oa/IaW92wF32JFb3CVczqOkru2xspuKczHEbG3nvmPY7IFqVmGGHdNbYw==", - "dev": true - }, - "@types/minimatch": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-5.1.2.tgz", - "integrity": "sha512-K0VQKziLUWkVKiRVrx4a40iPaxTUefQmjtkQofBkYRcoaaL/8rhwDWww9qWbrgicNOgnpIsMxyNIUM4+n6dUIA==", - "dev": true - }, - "@types/mkdirp": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/@types/mkdirp/-/mkdirp-0.5.2.tgz", - "integrity": "sha512-U5icWpv7YnZYGsN4/cmh3WD2onMY0aJIiTE6+51TwJCttdHvtCYmkBNOobHlXwrJRL0nkH9jH4kD+1FAdMN4Tg==", - "dev": true, - "requires": { - "@types/node": "*" - } - }, - "@types/mocha": { - "version": "9.1.1", - "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-9.1.1.tgz", - "integrity": "sha512-Z61JK7DKDtdKTWwLeElSEBcWGRLY8g95ic5FoQqI9CMx0ns/Ghep3B4DfcEimiKMvtamNVULVNKEsiwV3aQmXw==", - "dev": true - }, - "@types/node": { - "version": "12.20.55", - "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.55.tgz", - "integrity": "sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==" - }, - "@types/node-fetch": { - "version": "2.6.4", - "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.6.4.tgz", - "integrity": "sha512-1ZX9fcN4Rvkvgv4E6PAY5WXUFWFcRWxZa3EW83UjycOB9ljJCedb2CupIP4RZMEwF/M3eTcCihbBRgwtGbg5Rg==", - "dev": true, - "requires": { - "@types/node": "*", - "form-data": "^3.0.0" - } - }, - "@types/pbkdf2": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@types/pbkdf2/-/pbkdf2-3.1.0.tgz", - "integrity": "sha512-Cf63Rv7jCQ0LaL8tNXmEyqTHuIJxRdlS5vMh1mj5voN4+QFhVZnlZruezqpWYDiJ8UTzhP0VmeLXCmBk66YrMQ==", - "requires": { - "@types/node": "*" - } - }, - "@types/prettier": { - "version": "2.7.3", - "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.7.3.tgz", - "integrity": "sha512-+68kP9yzs4LMp7VNh8gdzMSPZFL44MLGqiHWvttYJe+6qnuVr4Ek9wSBQoveqY/r+LwjCcU29kNVkidwim+kYA==", - "dev": true - }, - "@types/qs": { - "version": "6.9.7", - "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.7.tgz", - "integrity": "sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==", - "dev": true - }, - "@types/readable-stream": { - "version": "2.3.15", - "resolved": "https://registry.npmjs.org/@types/readable-stream/-/readable-stream-2.3.15.tgz", - "integrity": "sha512-oM5JSKQCcICF1wvGgmecmHldZ48OZamtMxcGGVICOJA8o8cahXC1zEVAif8iwoc5j8etxFaRFnf095+CDsuoFQ==", - "dev": true, - "requires": { - "@types/node": "*", - "safe-buffer": "~5.1.1" - } - }, - "@types/resolve": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-0.0.8.tgz", - "integrity": "sha512-auApPaJf3NPfe18hSoJkp8EbZzer2ISk7o8mCC3M9he/a04+gbMF97NkpD2S8riMGvm4BMRI59/SZQSaLTKpsQ==", - "dev": true, - "requires": { - "@types/node": "*" - } - }, - "@types/responselike": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@types/responselike/-/responselike-1.0.0.tgz", - "integrity": "sha512-85Y2BjiufFzaMIlvJDvTTB8Fxl2xfLo4HgmHzVBz08w4wDePCTjYw66PdrolO0kzli3yam/YCgRufyo1DdQVTA==", - "dev": true, - "requires": { - "@types/node": "*" - } - }, - "@types/secp256k1": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/@types/secp256k1/-/secp256k1-4.0.3.tgz", - "integrity": "sha512-Da66lEIFeIz9ltsdMZcpQvmrmmoqrfju8pm1BH8WbYjZSwUgCwXLb9C+9XYogwBITnbsSaMdVPb2ekf7TV+03w==", - "requires": { - "@types/node": "*" - } - }, - "@types/sinon": { - "version": "10.0.15", - "resolved": "https://registry.npmjs.org/@types/sinon/-/sinon-10.0.15.tgz", - "integrity": "sha512-3lrFNQG0Kr2LDzvjyjB6AMJk4ge+8iYhQfdnSwIwlG88FUOV43kPcQqDZkDa/h3WSZy6i8Fr0BSjfQtB1B3xuQ==", - "dev": true, - "peer": true, - "requires": { - "@types/sinonjs__fake-timers": "*" - } - }, - "@types/sinon-chai": { - "version": "3.2.9", - "resolved": "https://registry.npmjs.org/@types/sinon-chai/-/sinon-chai-3.2.9.tgz", - "integrity": "sha512-/19t63pFYU0ikrdbXKBWj9PCdnKyTd0Qkz0X91Ta081cYsq90OxYdcWwK/dwEoDa6dtXgj2HJfmzgq+QZTHdmQ==", - "dev": true, - "peer": true, - "requires": { - "@types/chai": "*", - "@types/sinon": "*" - } - }, - "@types/sinonjs__fake-timers": { - "version": "8.1.2", - "resolved": "https://registry.npmjs.org/@types/sinonjs__fake-timers/-/sinonjs__fake-timers-8.1.2.tgz", - "integrity": "sha512-9GcLXF0/v3t80caGs5p2rRfkB+a8VBGLJZVih6CNFkx8IZ994wiKKLSRs9nuFwk1HevWs/1mnUmkApGrSGsShA==", - "dev": true, - "peer": true - }, - "@typescript-eslint/eslint-plugin": { - "version": "4.33.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.33.0.tgz", - "integrity": "sha512-aINiAxGVdOl1eJyVjaWn/YcVAq4Gi/Yo35qHGCnqbWVz61g39D0h23veY/MA0rFFGfxK7TySg2uwDeNv+JgVpg==", - "dev": true, - "requires": { - "@typescript-eslint/experimental-utils": "4.33.0", - "@typescript-eslint/scope-manager": "4.33.0", - "debug": "^4.3.1", - "functional-red-black-tree": "^1.0.1", - "ignore": "^5.1.8", - "regexpp": "^3.1.0", - "semver": "^7.3.5", - "tsutils": "^3.21.0" - }, - "dependencies": { - "lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "requires": { - "yallist": "^4.0.0" - } - }, - "semver": { - "version": "7.5.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", - "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", - "dev": true, - "requires": { - "lru-cache": "^6.0.0" - } - }, - "yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - } - } - }, - "@typescript-eslint/experimental-utils": { - "version": "4.33.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-4.33.0.tgz", - "integrity": "sha512-zeQjOoES5JFjTnAhI5QY7ZviczMzDptls15GFsI6jyUOq0kOf9+WonkhtlIhh0RgHRnqj5gdNxW5j1EvAyYg6Q==", - "dev": true, - "requires": { - "@types/json-schema": "^7.0.7", - "@typescript-eslint/scope-manager": "4.33.0", - "@typescript-eslint/types": "4.33.0", - "@typescript-eslint/typescript-estree": "4.33.0", - "eslint-scope": "^5.1.1", - "eslint-utils": "^3.0.0" - } - }, - "@typescript-eslint/parser": { - "version": "4.33.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-4.33.0.tgz", - "integrity": "sha512-ZohdsbXadjGBSK0/r+d87X0SBmKzOq4/S5nzK6SBgJspFo9/CUDJ7hjayuze+JK7CZQLDMroqytp7pOcFKTxZA==", - "dev": true, - "requires": { - "@typescript-eslint/scope-manager": "4.33.0", - "@typescript-eslint/types": "4.33.0", - "@typescript-eslint/typescript-estree": "4.33.0", - "debug": "^4.3.1" - } - }, - "@typescript-eslint/scope-manager": { - "version": "4.33.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.33.0.tgz", - "integrity": "sha512-5IfJHpgTsTZuONKbODctL4kKuQje/bzBRkwHE8UOZ4f89Zeddg+EGZs8PD8NcN4LdM3ygHWYB3ukPAYjvl/qbQ==", - "dev": true, - "requires": { - "@typescript-eslint/types": "4.33.0", - "@typescript-eslint/visitor-keys": "4.33.0" - } - }, - "@typescript-eslint/types": { - "version": "4.33.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.33.0.tgz", - "integrity": "sha512-zKp7CjQzLQImXEpLt2BUw1tvOMPfNoTAfb8l51evhYbOEEzdWyQNmHWWGPR6hwKJDAi+1VXSBmnhL9kyVTTOuQ==", - "dev": true - }, - "@typescript-eslint/typescript-estree": { - "version": "4.33.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.33.0.tgz", - "integrity": "sha512-rkWRY1MPFzjwnEVHsxGemDzqqddw2QbTJlICPD9p9I9LfsO8fdmfQPOX3uKfUaGRDFJbfrtm/sXhVXN4E+bzCA==", - "dev": true, - "requires": { - "@typescript-eslint/types": "4.33.0", - "@typescript-eslint/visitor-keys": "4.33.0", - "debug": "^4.3.1", - "globby": "^11.0.3", - "is-glob": "^4.0.1", - "semver": "^7.3.5", - "tsutils": "^3.21.0" - }, - "dependencies": { - "lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "requires": { - "yallist": "^4.0.0" - } - }, - "semver": { - "version": "7.5.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", - "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", - "dev": true, - "requires": { - "lru-cache": "^6.0.0" - } - }, - "yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - } - } - }, - "@typescript-eslint/visitor-keys": { - "version": "4.33.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.33.0.tgz", - "integrity": "sha512-uqi/2aSz9g2ftcHWf8uLPJA70rUv6yuMW5Bohw+bwcuzaxQIHaKFZCKGoGXIrc9vkTJ3+0txM73K0Hq3d5wgIg==", - "dev": true, - "requires": { - "@typescript-eslint/types": "4.33.0", - "eslint-visitor-keys": "^2.0.0" - } - }, - "@yarnpkg/lockfile": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@yarnpkg/lockfile/-/lockfile-1.1.0.tgz", - "integrity": "sha512-GpSwvyXOcOOlV70vbnzjj4fW5xW/FdUF6nQEt1ENy7m4ZCczi1+/buVUPAqmGfqznsORNFzUMjctTIp8a9tuCQ==", - "dev": true - }, - "abbrev": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.0.9.tgz", - "integrity": "sha512-LEyx4aLEC3x6T0UguF6YILf+ntvmOaWsVfENmIW0E9H09vKlLDGelMjjSm0jkDHALj8A8quZ/HapKNigzwge+Q==", - "dev": true - }, - "abort-controller": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", - "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", - "dev": true, - "requires": { - "event-target-shim": "^5.0.0" - } - }, - "abortcontroller-polyfill": { - "version": "1.7.5", - "resolved": "https://registry.npmjs.org/abortcontroller-polyfill/-/abortcontroller-polyfill-1.7.5.tgz", - "integrity": "sha512-JMJ5soJWP18htbbxJjG7bG6yuI6pRhgJ0scHHTfkUjf6wjP912xZWvM+A4sJK3gqd9E8fcPbDnOefbA9Th/FIQ==", - "dev": true - }, - "abstract-level": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/abstract-level/-/abstract-level-1.0.3.tgz", - "integrity": "sha512-t6jv+xHy+VYwc4xqZMn2Pa9DjcdzvzZmQGRjTFc8spIbRGHgBrEKbPq+rYXc7CCo0lxgYvSgKVg9qZAhpVQSjA==", - "dev": true, - "requires": { - "buffer": "^6.0.3", - "catering": "^2.1.0", - "is-buffer": "^2.0.5", - "level-supports": "^4.0.0", - "level-transcoder": "^1.0.1", - "module-error": "^1.0.1", - "queue-microtask": "^1.2.3" - } - }, - "accepts": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", - "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", - "dev": true, - "requires": { - "mime-types": "~2.1.34", - "negotiator": "0.6.3" - } - }, - "acorn": { - "version": "7.4.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", - "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", - "dev": true - }, - "acorn-jsx": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", - "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", - "dev": true, - "requires": {} - }, - "acorn-walk": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", - "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", - "dev": true - }, - "address": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/address/-/address-1.2.2.tgz", - "integrity": "sha512-4B/qKCfeE/ODUaAUpSwfzazo5x29WD4r3vXiWsB7I2mSDAihwEqKO+g8GELZUQSSAo5e1XTYh3ZVfLyxBc12nA==", - "dev": true - }, - "adm-zip": { - "version": "0.4.16", - "resolved": "https://registry.npmjs.org/adm-zip/-/adm-zip-0.4.16.tgz", - "integrity": "sha512-TFi4HBKSGfIKsK5YCkKaaFG2m4PEDyViZmEwof3MTIgzimHLto6muaHVpbrljdIvIrFZzEq/p4nafOeLcYegrg==", - "dev": true - }, - "aes-js": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/aes-js/-/aes-js-3.0.0.tgz", - "integrity": "sha512-H7wUZRn8WpTq9jocdxQ2c8x2sKo9ZVmzfRE13GiNJXfp7NcKYEdvl3vspKjXox6RIG2VtaRe4JFvxG4rqp2Zuw==" - }, - "agent-base": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", - "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", - "dev": true, - "requires": { - "debug": "4" - } - }, - "aggregate-error": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", - "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", - "dev": true, - "requires": { - "clean-stack": "^2.0.0", - "indent-string": "^4.0.0" - } - }, - "ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dev": true, - "requires": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - }, - "amdefine": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz", - "integrity": "sha512-S2Hw0TtNkMJhIabBwIojKL9YHO5T0n5eNqWJ7Lrlel/zDbftQpxpapi8tZs3X1HWa+u+QeydGmzzNU0m09+Rcg==", - "dev": true, - "optional": true - }, - "ansi-colors": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", - "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==", - "dev": true - }, - "ansi-escapes": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", - "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", - "dev": true, - "requires": { - "type-fest": "^0.21.3" - }, - "dependencies": { - "type-fest": { - "version": "0.21.3", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", - "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", - "dev": true - } - } - }, - "ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true - }, - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "requires": { - "color-convert": "^2.0.1" - } - }, - "antlr4": { - "version": "4.13.0", - "resolved": "https://registry.npmjs.org/antlr4/-/antlr4-4.13.0.tgz", - "integrity": "sha512-zooUbt+UscjnWyOrsuY/tVFL4rwrAGwOivpQmvmUDE22hy/lUA467Rc1rcixyRwcRUIXFYBwv7+dClDSHdmmew==", - "dev": true - }, - "antlr4ts": { - "version": "0.5.0-alpha.4", - "resolved": "https://registry.npmjs.org/antlr4ts/-/antlr4ts-0.5.0-alpha.4.tgz", - "integrity": "sha512-WPQDt1B74OfPv/IMS2ekXAKkTZIHl88uMetg6q3OTqgFxZ/dxDXI0EWLyZid/1Pe6hTftyg5N7gel5wNAGxXyQ==", - "dev": true - }, - "anymatch": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", - "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", - "dev": true, - "requires": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - } - }, - "arg": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", - "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", - "dev": true - }, - "argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dev": true, - "requires": { - "sprintf-js": "~1.0.2" - } - }, - "array-back": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/array-back/-/array-back-2.0.0.tgz", - "integrity": "sha512-eJv4pLLufP3g5kcZry0j6WXpIbzYw9GUB4mVJZno9wfwiBxbizTnHCw3VJb07cBihbFX48Y7oSrW9y+gt4glyw==", - "dev": true, - "requires": { - "typical": "^2.6.1" - } - }, - "array-buffer-byte-length": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.0.tgz", - "integrity": "sha512-LPuwb2P+NrQw3XhxGc36+XSvuBPopovXYTR9Ew++Du9Yb/bx5AzBfrIsBoj0EZUifjQU+sHL21sseZ3jerWO/A==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "is-array-buffer": "^3.0.1" - } - }, - "array-flatten": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", - "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==", - "dev": true - }, - "array-includes": { - "version": "3.1.6", - "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.6.tgz", - "integrity": "sha512-sgTbLvL6cNnw24FnbaDyjmvddQ2ML8arZsgaJhoABMoplz/4QRhtrYS+alr1BUM1Bwp6dhx8vVCBSLG+StwOFw==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4", - "get-intrinsic": "^1.1.3", - "is-string": "^1.0.7" - } - }, - "array-union": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", - "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", - "dev": true - }, - "array-uniq": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", - "integrity": "sha512-MNha4BWQ6JbwhFhj03YK552f7cb3AzoE8SzeljgChvL1dl3IcvggXVz1DilzySZkCja+CXuZbdW7yATchWn8/Q==", - "dev": true - }, - "array.prototype.flat": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.1.tgz", - "integrity": "sha512-roTU0KWIOmJ4DRLmwKd19Otg0/mT3qPNt0Qb3GWW8iObuZXxrjB/pzn0R3hqpRSWg4HCwqx+0vwOnWnvlOyeIA==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4", - "es-shim-unscopables": "^1.0.0" - } - }, - "array.prototype.flatmap": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.1.tgz", - "integrity": "sha512-8UGn9O1FDVvMNB0UlLv4voxRMze7+FpHyF5mSMRjWHUMlpoDViniy05870VlxhfgTnLbpuwTzvD76MTtWxB/mQ==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4", - "es-shim-unscopables": "^1.0.0" - } - }, - "array.prototype.reduce": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/array.prototype.reduce/-/array.prototype.reduce-1.0.5.tgz", - "integrity": "sha512-kDdugMl7id9COE8R7MHF5jWk7Dqt/fs4Pv+JXoICnYwqpjjjbUurz6w5fT5IG6brLdJhv6/VoHB0H7oyIBXd+Q==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4", - "es-array-method-boxes-properly": "^1.0.0", - "is-string": "^1.0.7" - } - }, - "arraybuffer.prototype.slice": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.1.tgz", - "integrity": "sha512-09x0ZWFEjj4WD8PDbykUwo3t9arLn8NIzmmYEJFpYekOAQjpkGSyrQhNoRTcwwcFRu+ycWF78QZ63oWTqSjBcw==", - "dev": true, - "requires": { - "array-buffer-byte-length": "^1.0.0", - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "get-intrinsic": "^1.2.1", - "is-array-buffer": "^3.0.2", - "is-shared-array-buffer": "^1.0.2" - } - }, - "asap": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", - "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==", - "dev": true - }, - "asn1": { - "version": "0.2.6", - "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz", - "integrity": "sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==", - "dev": true, - "requires": { - "safer-buffer": "~2.1.0" - } - }, - "asn1.js": { - "version": "5.4.1", - "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-5.4.1.tgz", - "integrity": "sha512-+I//4cYPccV8LdmBLiX8CYvf9Sp3vQsrqu2QNXRcrbiWvcx/UdlFiqUJJzxRQxgsZmvhXhn4cSKeSmoFjVdupA==", - "dev": true, - "requires": { - "bn.js": "^4.0.0", - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0", - "safer-buffer": "^2.1.0" - }, - "dependencies": { - "bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", - "dev": true - } - } - }, - "assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==", - "dev": true - }, - "assertion-error": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", - "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==" - }, - "ast-parents": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/ast-parents/-/ast-parents-0.0.1.tgz", - "integrity": "sha512-XHusKxKz3zoYk1ic8Un640joHbFMhbqneyoZfoKnEGtf2ey9Uh/IdpcQplODdO/kENaMIWsD0nJm4+wX3UNLHA==", - "dev": true - }, - "astral-regex": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", - "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", - "dev": true - }, - "async": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", - "integrity": "sha512-nSVgobk4rv61R9PUSDtYt7mPVB2olxNR5RWJcAsH676/ef11bUZwvu7+RGYrYauVdDPcO519v68wRhXQtxsV9w==", - "dev": true - }, - "async-limiter": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz", - "integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==", - "dev": true - }, - "asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", - "dev": true - }, - "at-least-node": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", - "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==", - "dev": true - }, - "available-typed-arrays": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz", - "integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==", - "dev": true - }, - "aws-sign2": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", - "integrity": "sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA==", - "dev": true - }, - "aws4": { - "version": "1.12.0", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.12.0.tgz", - "integrity": "sha512-NmWvPnx0F1SfrQbYwOi7OeaNGokp9XhzNioJ/CSBs8Qa4vxug81mhJEAVZwxXuBmYB5KDRfMq/F3RR0BIU7sWg==", - "dev": true - }, - "balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true - }, - "base-x": { - "version": "3.0.9", - "resolved": "https://registry.npmjs.org/base-x/-/base-x-3.0.9.tgz", - "integrity": "sha512-H7JU6iBHTal1gp56aKoaa//YUxEaAOUiydvrV/pILqIHXTtqxSkATOnDA2u+jZ/61sD+L/412+7kzXRtWukhpQ==", - "requires": { - "safe-buffer": "^5.0.1" - } - }, - "base64-js": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", - "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==" - }, - "bcrypt-pbkdf": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", - "integrity": "sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==", - "dev": true, - "requires": { - "tweetnacl": "^0.14.3" - }, - "dependencies": { - "tweetnacl": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==", - "dev": true - } - } - }, - "bech32": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/bech32/-/bech32-1.1.4.tgz", - "integrity": "sha512-s0IrSOzLlbvX7yp4WBfPITzpAU8sqQcpsmwXDiKwrG4r491vwCO/XpejasRNl0piBMe/DvP4Tz0mIS/X1DPJBQ==" - }, - "bigint-crypto-utils": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/bigint-crypto-utils/-/bigint-crypto-utils-3.3.0.tgz", - "integrity": "sha512-jOTSb+drvEDxEq6OuUybOAv/xxoh3cuYRUIPyu8sSHQNKM303UQ2R1DAo45o1AkcIXw6fzbaFI1+xGGdaXs2lg==", - "dev": true - }, - "bignumber.js": { - "version": "9.1.1", - "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.1.1.tgz", - "integrity": "sha512-pHm4LsMJ6lzgNGVfZHjMoO8sdoRhOzOH4MLmY65Jg70bpxCKu5iOHNJyfF6OyvYw7t8Fpf35RuzUyqnQsj8Vig==" - }, - "binary-extensions": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", - "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", - "dev": true - }, - "blakejs": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/blakejs/-/blakejs-1.2.1.tgz", - "integrity": "sha512-QXUSXI3QVc/gJME0dBpXrag1kbzOqCjCX8/b54ntNyW6sjtoqxqRk3LTmXzaJoh71zMsDCjM+47jS7XiwN/+fQ==" - }, - "bluebird": { - "version": "3.7.2", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", - "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", - "dev": true - }, - "bn.js": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz", - "integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==" - }, - "body-parser": { - "version": "1.20.2", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.2.tgz", - "integrity": "sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA==", - "dev": true, - "requires": { - "bytes": "3.1.2", - "content-type": "~1.0.5", - "debug": "2.6.9", - "depd": "2.0.0", - "destroy": "1.2.0", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "on-finished": "2.4.1", - "qs": "6.11.0", - "raw-body": "2.5.2", - "type-is": "~1.6.18", - "unpipe": "1.0.0" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true - }, - "qs": { - "version": "6.11.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", - "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", - "dev": true, - "requires": { - "side-channel": "^1.0.4" - } - } - } - }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dev": true, - "requires": { - "fill-range": "^7.0.1" - } - }, - "brorand": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", - "integrity": "sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w==" - }, - "browser-level": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/browser-level/-/browser-level-1.0.1.tgz", - "integrity": "sha512-XECYKJ+Dbzw0lbydyQuJzwNXtOpbMSq737qxJN11sIRTErOMShvDpbzTlgju7orJKvx4epULolZAuJGLzCmWRQ==", - "dev": true, - "requires": { - "abstract-level": "^1.0.2", - "catering": "^2.1.1", - "module-error": "^1.0.2", - "run-parallel-limit": "^1.1.0" - } - }, - "browser-stdout": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", - "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", - "dev": true - }, - "browserify-aes": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", - "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", - "requires": { - "buffer-xor": "^1.0.3", - "cipher-base": "^1.0.0", - "create-hash": "^1.1.0", - "evp_bytestokey": "^1.0.3", - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "browserify-cipher": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz", - "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==", - "dev": true, - "requires": { - "browserify-aes": "^1.0.4", - "browserify-des": "^1.0.0", - "evp_bytestokey": "^1.0.0" - } - }, - "browserify-des": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz", - "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==", - "dev": true, - "requires": { - "cipher-base": "^1.0.1", - "des.js": "^1.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "browserify-rsa": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.1.0.tgz", - "integrity": "sha512-AdEER0Hkspgno2aR97SAf6vi0y0k8NuOpGnVH3O99rcA5Q6sh8QxcngtHuJ6uXwnfAXNM4Gn1Gb7/MV1+Ymbog==", - "dev": true, - "requires": { - "bn.js": "^5.0.0", - "randombytes": "^2.0.1" - } - }, - "browserify-sign": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.2.2.tgz", - "integrity": "sha512-1rudGyeYY42Dk6texmv7c4VcQ0EsvVbLwZkA+AQB7SxvXxmcD93jcHie8bzecJ+ChDlmAm2Qyu0+Ccg5uhZXCg==", - "dev": true, - "requires": { - "bn.js": "^5.2.1", - "browserify-rsa": "^4.1.0", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "elliptic": "^6.5.4", - "inherits": "^2.0.4", - "parse-asn1": "^5.1.6", - "readable-stream": "^3.6.2", - "safe-buffer": "^5.2.1" - }, - "dependencies": { - "safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "dev": true - } - } - }, - "bs58": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/bs58/-/bs58-4.0.1.tgz", - "integrity": "sha512-Ok3Wdf5vOIlBrgCvTq96gBkJw+JUEzdBgyaza5HLtPm7yTHkjRy8+JzNyHF7BHa0bNWOQIp3m5YF0nnFcOIKLw==", - "requires": { - "base-x": "^3.0.2" - } - }, - "bs58check": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/bs58check/-/bs58check-2.1.2.tgz", - "integrity": "sha512-0TS1jicxdU09dwJMNZtVAfzPi6Q6QeN0pM1Fkzrjn+XYHvzMKPU3pHVpva+769iNVSfIYWf7LJ6WR+BuuMf8cA==", - "requires": { - "bs58": "^4.0.0", - "create-hash": "^1.1.0", - "safe-buffer": "^5.1.2" - } - }, - "buffer": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", - "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", - "requires": { - "base64-js": "^1.3.1", - "ieee754": "^1.2.1" - } - }, - "buffer-from": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", - "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", - "dev": true - }, - "buffer-reverse": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/buffer-reverse/-/buffer-reverse-1.0.1.tgz", - "integrity": "sha512-M87YIUBsZ6N924W57vDwT/aOu8hw7ZgdByz6ijksLjmHJELBASmYTTlNHRgjE+pTsT9oJXGaDSgqqwfdHotDUg==" - }, - "buffer-to-arraybuffer": { - "version": "0.0.5", - "resolved": "https://registry.npmjs.org/buffer-to-arraybuffer/-/buffer-to-arraybuffer-0.0.5.tgz", - "integrity": "sha512-3dthu5CYiVB1DEJp61FtApNnNndTckcqe4pFcLdvHtrpG+kcyekCJKg4MRiDcFW7A6AODnXB9U4dwQiCW5kzJQ==", - "dev": true - }, - "buffer-xor": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", - "integrity": "sha512-571s0T7nZWK6vB67HI5dyUF7wXiNcfaPPPTl6zYCNApANjIvYJTg7hlud/+cJpdAhS7dVzqMLmfhfHR3rAcOjQ==" - }, - "bufferutil": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/bufferutil/-/bufferutil-4.0.7.tgz", - "integrity": "sha512-kukuqc39WOHtdxtw4UScxF/WVnMFVSQVKhtx3AjZJzhd0RGZZldcrfSEbVsWWe6KNH253574cq5F+wpv0G9pJw==", - "devOptional": true, - "requires": { - "node-gyp-build": "^4.3.0" - } - }, - "bufio": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/bufio/-/bufio-1.2.0.tgz", - "integrity": "sha512-UlFk8z/PwdhYQTXSQQagwGAdtRI83gib2n4uy4rQnenxUM2yQi8lBDzF230BNk+3wAoZDxYRoBwVVUPgHa9MCA==" - }, - "bytes": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", - "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", - "dev": true - }, - "cacheable-lookup": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-6.1.0.tgz", - "integrity": "sha512-KJ/Dmo1lDDhmW2XDPMo+9oiy/CeqosPguPCrgcVzKyZrL6pM1gU2GmPY/xo6OQPTUaA/c0kwHuywB4E6nmT9ww==", - "dev": true - }, - "cacheable-request": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-6.1.0.tgz", - "integrity": "sha512-Oj3cAGPCqOZX7Rz64Uny2GYAZNliQSqfbePrgAQ1wKAihYmCUnraBtJtKcGR4xz7wF+LoJC+ssFZvv5BgF9Igg==", - "dev": true, - "requires": { - "clone-response": "^1.0.2", - "get-stream": "^5.1.0", - "http-cache-semantics": "^4.0.0", - "keyv": "^3.0.0", - "lowercase-keys": "^2.0.0", - "normalize-url": "^4.1.0", - "responselike": "^1.0.2" - }, - "dependencies": { - "get-stream": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", - "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", - "dev": true, - "requires": { - "pump": "^3.0.0" - } - }, - "lowercase-keys": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", - "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", - "dev": true - } - } - }, - "call-bind": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", - "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", - "dev": true, - "requires": { - "function-bind": "^1.1.1", - "get-intrinsic": "^1.0.2" - } - }, - "callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "dev": true - }, - "camelcase": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", - "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", - "dev": true - }, - "case": { - "version": "1.6.3", - "resolved": "https://registry.npmjs.org/case/-/case-1.6.3.tgz", - "integrity": "sha512-mzDSXIPaFwVDvZAHqZ9VlbyF4yyXRuX6IvB06WvPYkqJVO24kX1PPhv9bfpKNFZyxYFmmgo03HUiD8iklmJYRQ==", - "dev": true - }, - "caseless": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==", - "dev": true - }, - "catering": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/catering/-/catering-2.1.1.tgz", - "integrity": "sha512-K7Qy8O9p76sL3/3m7/zLKbRkyOlSZAgzEaLhyj2mXS8PsCud2Eo4hAb8aLtZqHh0QGqLcb9dlJSu6lHRVENm1w==", - "dev": true - }, - "cbor": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/cbor/-/cbor-8.1.0.tgz", - "integrity": "sha512-DwGjNW9omn6EwP70aXsn7FQJx5kO12tX0bZkaTjzdVFM6/7nhA4t0EENocKGx6D2Bch9PE2KzCUf5SceBdeijg==", - "dev": true, - "requires": { - "nofilter": "^3.1.0" - } - }, - "chai": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/chai/-/chai-4.4.1.tgz", - "integrity": "sha512-13sOfMv2+DWduEU+/xbun3LScLoqN17nBeTLUsmDfKdoiC1fr0n9PU4guu4AhRcOVFk/sW8LyZWHuhWtQZiF+g==", - "requires": { - "assertion-error": "^1.1.0", - "check-error": "^1.0.3", - "deep-eql": "^4.1.3", - "get-func-name": "^2.0.2", - "loupe": "^2.3.6", - "pathval": "^1.1.1", - "type-detect": "^4.0.8" - } - }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "charenc": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/charenc/-/charenc-0.0.2.tgz", - "integrity": "sha512-yrLQ/yVUFXkzg7EDQsPieE/53+0RlaWTs+wBrvW36cyilJ2SaDWfl4Yj7MtLTXleV9uEKefbAGUPv2/iWSooRA==", - "dev": true - }, - "check-error": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.3.tgz", - "integrity": "sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg==", - "requires": { - "get-func-name": "^2.0.2" - } - }, - "chokidar": { - "version": "3.5.3", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", - "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", - "dev": true, - "requires": { - "anymatch": "~3.1.2", - "braces": "~3.0.2", - "fsevents": "~2.3.2", - "glob-parent": "~5.1.2", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.6.0" - } - }, - "chownr": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", - "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", - "dev": true - }, - "ci-info": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", - "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==", - "dev": true - }, - "cids": { - "version": "0.7.5", - "resolved": "https://registry.npmjs.org/cids/-/cids-0.7.5.tgz", - "integrity": "sha512-zT7mPeghoWAu+ppn8+BS1tQ5qGmbMfB4AregnQjA/qHY3GC1m1ptI9GkWNlgeu38r7CuRdXB47uY2XgAYt6QVA==", - "dev": true, - "requires": { - "buffer": "^5.5.0", - "class-is": "^1.1.0", - "multibase": "~0.6.0", - "multicodec": "^1.0.0", - "multihashes": "~0.4.15" - }, - "dependencies": { - "buffer": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", - "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", - "dev": true, - "requires": { - "base64-js": "^1.3.1", - "ieee754": "^1.1.13" - } - }, - "multicodec": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/multicodec/-/multicodec-1.0.4.tgz", - "integrity": "sha512-NDd7FeS3QamVtbgfvu5h7fd1IlbaC4EQ0/pgU4zqE2vdHCmBGsUa0TiM8/TdSeG6BMPC92OOCf8F1ocE/Wkrrg==", - "dev": true, - "requires": { - "buffer": "^5.6.0", - "varint": "^5.0.0" - } - } - } - }, - "cipher-base": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", - "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", - "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "class-is": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/class-is/-/class-is-1.1.0.tgz", - "integrity": "sha512-rhjH9AG1fvabIDoGRVH587413LPjTZgmDF9fOFCbFJQV4yuocX1mHxxvXI4g3cGwbVY9wAYIoKlg1N79frJKQw==", - "dev": true - }, - "classic-level": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/classic-level/-/classic-level-1.3.0.tgz", - "integrity": "sha512-iwFAJQYtqRTRM0F6L8h4JCt00ZSGdOyqh7yVrhhjrOpFhmBjNlRUey64MCiyo6UmQHMJ+No3c81nujPv+n9yrg==", - "dev": true, - "requires": { - "abstract-level": "^1.0.2", - "catering": "^2.1.0", - "module-error": "^1.0.1", - "napi-macros": "^2.2.2", - "node-gyp-build": "^4.3.0" - } - }, - "clean-stack": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", - "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", - "dev": true - }, - "cli-table3": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.5.1.tgz", - "integrity": "sha512-7Qg2Jrep1S/+Q3EceiZtQcDPWxhAvBw+ERf1162v4sikJrvojMHFqXt8QIVha8UlH9rgU0BeWPytZ9/TzYqlUw==", - "dev": true, - "requires": { - "colors": "^1.1.2", - "object-assign": "^4.1.0", - "string-width": "^2.1.1" - } - }, - "cliui": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", - "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", - "dev": true, - "requires": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^7.0.0" - }, - "dependencies": { - "is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true - }, - "string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - } - } - } - }, - "clone-response": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.3.tgz", - "integrity": "sha512-ROoL94jJH2dUVML2Y/5PEDNaSHgeOdSDicUyS7izcF63G6sTc/FTjLub4b8Il9S8S0beOfYt0TaA5qvFK+w0wA==", - "dev": true, - "requires": { - "mimic-response": "^1.0.0" - } - }, - "code-point-at": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", - "integrity": "sha512-RpAVKQA5T63xEj6/giIbUEtZwJ4UFIc3ZtvEkiaUERylqe8xb5IvqcgOurZLahv93CLKfxcw5YI+DZcUBRyLXA==", - "dev": true - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "colors": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz", - "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==", - "dev": true - }, - "combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "dev": true, - "requires": { - "delayed-stream": "~1.0.0" - } - }, - "command-exists": { - "version": "1.2.9", - "resolved": "https://registry.npmjs.org/command-exists/-/command-exists-1.2.9.tgz", - "integrity": "sha512-LTQ/SGc+s0Xc0Fu5WaKnR0YiygZkm9eKFvyS+fRsU7/ZWFF8ykFM6Pc9aCVf1+xasOOZpO3BAVgVrKvsqKHV7w==", - "dev": true - }, - "command-line-args": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/command-line-args/-/command-line-args-4.0.7.tgz", - "integrity": "sha512-aUdPvQRAyBvQd2n7jXcsMDz68ckBJELXNzBybCHOibUWEg0mWTnaYCSRU8h9R+aNRSvDihJtssSRCiDRpLaezA==", - "dev": true, - "requires": { - "array-back": "^2.0.0", - "find-replace": "^1.0.3", - "typical": "^2.6.1" - } - }, - "commander": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/commander/-/commander-3.0.2.tgz", - "integrity": "sha512-Gar0ASD4BDyKC4hl4DwHqDrmvjoxWKZigVnAbn5H1owvm4CxCPdb0HQDehwNYMJpla5+M2tPmPARzhtYuwpHow==", - "dev": true - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "dev": true - }, - "concat-stream": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", - "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", - "dev": true, - "requires": { - "buffer-from": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^2.2.2", - "typedarray": "^0.0.6" - }, - "dependencies": { - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", - "dev": true - }, - "readable-stream": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", - "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "content-disposition": { - "version": "0.5.4", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", - "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", - "dev": true, - "requires": { - "safe-buffer": "5.2.1" - }, - "dependencies": { - "safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "dev": true - } - } - }, - "content-hash": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/content-hash/-/content-hash-2.5.2.tgz", - "integrity": "sha512-FvIQKy0S1JaWV10sMsA7TRx8bpU+pqPkhbsfvOJAdjRXvYxEckAwQWGwtRjiaJfh+E0DvcWUGqcdjwMGFjsSdw==", - "dev": true, - "requires": { - "cids": "^0.7.1", - "multicodec": "^0.5.5", - "multihashes": "^0.4.15" - } - }, - "content-type": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", - "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", - "dev": true - }, - "cookie": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz", - "integrity": "sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==", - "dev": true - }, - "cookie-signature": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", - "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==", - "dev": true - }, - "cookiejar": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/cookiejar/-/cookiejar-2.1.4.tgz", - "integrity": "sha512-LDx6oHrK+PhzLKJU9j5S7/Y3jM/mUHvD/DeI1WQmJn652iPC5Y4TBzC9l+5OMOXlyTTA+SmVUPm0HQUwpD5Jqw==", - "dev": true - }, - "core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==", - "dev": true - }, - "cors": { - "version": "2.8.5", - "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", - "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", - "dev": true, - "requires": { - "object-assign": "^4", - "vary": "^1" - } - }, - "cosmiconfig": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-8.2.0.tgz", - "integrity": "sha512-3rTMnFJA1tCOPwRxtgF4wd7Ab2qvDbL8jX+3smjIbS4HlZBagTlpERbdN7iAbWlrfxE3M8c27kTwTawQ7st+OQ==", - "dev": true, - "requires": { - "import-fresh": "^3.2.1", - "js-yaml": "^4.1.0", - "parse-json": "^5.0.0", - "path-type": "^4.0.0" - }, - "dependencies": { - "argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true - }, - "js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dev": true, - "requires": { - "argparse": "^2.0.1" - } - } - } - }, - "crc-32": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/crc-32/-/crc-32-1.2.2.tgz", - "integrity": "sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==", - "dev": true - }, - "create-ecdh": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.4.tgz", - "integrity": "sha512-mf+TCx8wWc9VpuxfP2ht0iSISLZnt0JgWlrOKZiNqyUZWnjIaCIVNQArMHnCZKfEYRg6IM7A+NeJoN8gf/Ws0A==", - "dev": true, - "requires": { - "bn.js": "^4.1.0", - "elliptic": "^6.5.3" - }, - "dependencies": { - "bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", - "dev": true - } - } - }, - "create-hash": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", - "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", - "requires": { - "cipher-base": "^1.0.1", - "inherits": "^2.0.1", - "md5.js": "^1.3.4", - "ripemd160": "^2.0.1", - "sha.js": "^2.4.0" - } - }, - "create-hmac": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", - "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", - "requires": { - "cipher-base": "^1.0.3", - "create-hash": "^1.1.0", - "inherits": "^2.0.1", - "ripemd160": "^2.0.0", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - } - }, - "create-require": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", - "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", - "dev": true - }, - "cross-fetch": { - "version": "3.1.8", - "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.8.tgz", - "integrity": "sha512-cvA+JwZoU0Xq+h6WkMvAUqPEYy92Obet6UdKLfW60qn99ftItKjB5T+BkyWOFWe2pUyfQ+IJHmpOTznqk1M6Kg==", - "dev": true, - "requires": { - "node-fetch": "^2.6.12" - } - }, - "cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "dev": true, - "requires": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - } - }, - "crypt": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/crypt/-/crypt-0.0.2.tgz", - "integrity": "sha512-mCxBlsHFYh9C+HVpiEacem8FEBnMXgU9gy4zmNC+SXAZNB/1idgp/aulFJ4FgCi7GPEVbfyng092GqL2k2rmow==", - "dev": true - }, - "crypto-browserify": { - "version": "3.12.0", - "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz", - "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==", - "dev": true, - "requires": { - "browserify-cipher": "^1.0.0", - "browserify-sign": "^4.0.0", - "create-ecdh": "^4.0.0", - "create-hash": "^1.1.0", - "create-hmac": "^1.1.0", - "diffie-hellman": "^5.0.0", - "inherits": "^2.0.1", - "pbkdf2": "^3.0.3", - "public-encrypt": "^4.0.0", - "randombytes": "^2.0.0", - "randomfill": "^1.0.3" - } - }, - "crypto-js": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-4.2.0.tgz", - "integrity": "sha512-KALDyEYgpY+Rlob/iriUtjV6d5Eq+Y191A5g4UqLAi8CyGP9N1+FdVbkc1SxKc2r4YAYqG8JzO2KGL+AizD70Q==" - }, - "d": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/d/-/d-1.0.1.tgz", - "integrity": "sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==", - "dev": true, - "requires": { - "es5-ext": "^0.10.50", - "type": "^1.0.1" - } - }, - "dashdash": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", - "integrity": "sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==", - "dev": true, - "requires": { - "assert-plus": "^1.0.0" - } - }, - "death": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/death/-/death-1.1.0.tgz", - "integrity": "sha512-vsV6S4KVHvTGxbEcij7hkWRv0It+sGGWVOM67dQde/o5Xjnr+KmLjxWJii2uEObIrt1CcM9w0Yaovx+iOlIL+w==", - "dev": true - }, - "debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dev": true, - "requires": { - "ms": "2.1.2" - } - }, - "decamelize": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", - "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", - "dev": true - }, - "decode-uri-component": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.2.tgz", - "integrity": "sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ==", - "dev": true - }, - "decompress-response": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz", - "integrity": "sha512-BzRPQuY1ip+qDonAOz42gRm/pg9F768C+npV/4JOsxRC2sq+Rlk+Q4ZCAsOhnIaMrgarILY+RMUIvMmmX1qAEA==", - "dev": true, - "requires": { - "mimic-response": "^1.0.0" - } - }, - "deep-eql": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-4.1.3.tgz", - "integrity": "sha512-WaEtAOpRA1MQ0eohqZjpGD8zdI0Ovsm8mmFhaDN8dvDZzyoUMcYDnf5Y6iu7HTXxf8JDS23qWa4a+hKCDyOPzw==", - "requires": { - "type-detect": "^4.0.0" - } - }, - "deep-is": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", - "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", - "dev": true - }, - "defer-to-connect": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-1.1.3.tgz", - "integrity": "sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ==", - "dev": true - }, - "define-properties": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.0.tgz", - "integrity": "sha512-xvqAVKGfT1+UAvPwKTVw/njhdQ8ZhXK4lI0bCIuCMrp2up9nPnaDftrLtmpTazqd1o+UY4zgzU+avtMbDP+ldA==", - "dev": true, - "requires": { - "has-property-descriptors": "^1.0.0", - "object-keys": "^1.1.1" - } - }, - "delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", - "dev": true - }, - "depd": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", - "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", - "dev": true - }, - "des.js": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.1.0.tgz", - "integrity": "sha512-r17GxjhUCjSRy8aiJpr8/UadFIzMzJGexI3Nmz4ADi9LYSFx4gTBp80+NaX/YsXWWLhpZ7v/v/ubEc/bCNfKwg==", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0" - } - }, - "destroy": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", - "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", - "dev": true - }, - "detect-port": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/detect-port/-/detect-port-1.5.1.tgz", - "integrity": "sha512-aBzdj76lueB6uUst5iAs7+0H/oOjqI5D16XUWxlWMIMROhcM0rfsNVk93zTngq1dDNpoXRr++Sus7ETAExppAQ==", - "dev": true, - "requires": { - "address": "^1.0.1", - "debug": "4" - } - }, - "diff": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz", - "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==", - "dev": true - }, - "diffie-hellman": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", - "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==", - "dev": true, - "requires": { - "bn.js": "^4.1.0", - "miller-rabin": "^4.0.0", - "randombytes": "^2.0.0" - }, - "dependencies": { - "bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", - "dev": true - } - } - }, - "dir-glob": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", - "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", - "dev": true, - "requires": { - "path-type": "^4.0.0" - } - }, - "doctrine": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", - "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", - "dev": true, - "requires": { - "esutils": "^2.0.2" - } - }, - "dom-walk": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/dom-walk/-/dom-walk-0.1.2.tgz", - "integrity": "sha512-6QvTW9mrGeIegrFXdtQi9pk7O/nSK6lSdXW2eqUspN5LWD7UTji2Fqw5V2YLjBpHEoU9Xl/eUWNpDeZvoyOv2w==", - "dev": true - }, - "dotenv": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-10.0.0.tgz", - "integrity": "sha512-rlBi9d8jpv9Sf1klPjNfFAuWDjKLwTIJJ/VxtoTwIR6hnZxcEOQCZg2oIL3MWBYw5GpUDKOEnND7LXTbIpQ03Q==", - "dev": true - }, - "duplexer3": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.5.tgz", - "integrity": "sha512-1A8za6ws41LQgv9HrE/66jyC5yuSjQ3L/KOpFtoBilsAK2iA2wuS5rTt1OCzIvtS2V7nVmedsUU+DGRcjBmOYA==", - "dev": true - }, - "ecc-jsbn": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", - "integrity": "sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw==", - "dev": true, - "requires": { - "jsbn": "~0.1.0", - "safer-buffer": "^2.1.0" - } - }, - "ee-first": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", - "dev": true - }, - "elliptic": { - "version": "6.5.4", - "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz", - "integrity": "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==", - "requires": { - "bn.js": "^4.11.9", - "brorand": "^1.1.0", - "hash.js": "^1.0.0", - "hmac-drbg": "^1.0.1", - "inherits": "^2.0.4", - "minimalistic-assert": "^1.0.1", - "minimalistic-crypto-utils": "^1.0.1" - }, - "dependencies": { - "bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" - } - } - }, - "emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - }, - "encodeurl": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", - "dev": true - }, - "end-of-stream": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", - "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", - "dev": true, - "requires": { - "once": "^1.4.0" - } - }, - "enquirer": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", - "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", - "dev": true, - "requires": { - "ansi-colors": "^4.1.1" - } - }, - "env-paths": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", - "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", - "dev": true - }, - "error-ex": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", - "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", - "dev": true, - "requires": { - "is-arrayish": "^0.2.1" - } - }, - "es-abstract": { - "version": "1.22.1", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.22.1.tgz", - "integrity": "sha512-ioRRcXMO6OFyRpyzV3kE1IIBd4WG5/kltnzdxSCqoP8CMGs/Li+M1uF5o7lOkZVFjDs+NLesthnF66Pg/0q0Lw==", - "dev": true, - "requires": { - "array-buffer-byte-length": "^1.0.0", - "arraybuffer.prototype.slice": "^1.0.1", - "available-typed-arrays": "^1.0.5", - "call-bind": "^1.0.2", - "es-set-tostringtag": "^2.0.1", - "es-to-primitive": "^1.2.1", - "function.prototype.name": "^1.1.5", - "get-intrinsic": "^1.2.1", - "get-symbol-description": "^1.0.0", - "globalthis": "^1.0.3", - "gopd": "^1.0.1", - "has": "^1.0.3", - "has-property-descriptors": "^1.0.0", - "has-proto": "^1.0.1", - "has-symbols": "^1.0.3", - "internal-slot": "^1.0.5", - "is-array-buffer": "^3.0.2", - "is-callable": "^1.2.7", - "is-negative-zero": "^2.0.2", - "is-regex": "^1.1.4", - "is-shared-array-buffer": "^1.0.2", - "is-string": "^1.0.7", - "is-typed-array": "^1.1.10", - "is-weakref": "^1.0.2", - "object-inspect": "^1.12.3", - "object-keys": "^1.1.1", - "object.assign": "^4.1.4", - "regexp.prototype.flags": "^1.5.0", - "safe-array-concat": "^1.0.0", - "safe-regex-test": "^1.0.0", - "string.prototype.trim": "^1.2.7", - "string.prototype.trimend": "^1.0.6", - "string.prototype.trimstart": "^1.0.6", - "typed-array-buffer": "^1.0.0", - "typed-array-byte-length": "^1.0.0", - "typed-array-byte-offset": "^1.0.0", - "typed-array-length": "^1.0.4", - "unbox-primitive": "^1.0.2", - "which-typed-array": "^1.1.10" - } - }, - "es-array-method-boxes-properly": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/es-array-method-boxes-properly/-/es-array-method-boxes-properly-1.0.0.tgz", - "integrity": "sha512-wd6JXUmyHmt8T5a2xreUwKcGPq6f1f+WwIJkijUqiGcJz1qqnZgP6XIK+QyIWU5lT7imeNxUll48bziG+TSYcA==", - "dev": true - }, - "es-set-tostringtag": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.1.tgz", - "integrity": "sha512-g3OMbtlwY3QewlqAiMLI47KywjWZoEytKr8pf6iTC8uJq5bIAH52Z9pnQ8pVL6whrCto53JZDuUIsifGeLorTg==", - "dev": true, - "requires": { - "get-intrinsic": "^1.1.3", - "has": "^1.0.3", - "has-tostringtag": "^1.0.0" - } - }, - "es-shim-unscopables": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.0.tgz", - "integrity": "sha512-Jm6GPcCdC30eMLbZ2x8z2WuRwAws3zTBBKuusffYVUrNj/GVSUAZ+xKMaUpfNDR5IbyNA5LJbaecoUVbmUcB1w==", - "dev": true, - "requires": { - "has": "^1.0.3" - } - }, - "es-to-primitive": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", - "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", - "dev": true, - "requires": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" - } - }, - "es5-ext": { - "version": "0.10.62", - "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.62.tgz", - "integrity": "sha512-BHLqn0klhEpnOKSrzn/Xsz2UIW8j+cGmo9JLzr8BiUapV8hPL9+FliFqjwr9ngW7jWdnxv6eO+/LqyhJVqgrjA==", - "dev": true, - "requires": { - "es6-iterator": "^2.0.3", - "es6-symbol": "^3.1.3", - "next-tick": "^1.1.0" - } - }, - "es6-iterator": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz", - "integrity": "sha512-zw4SRzoUkd+cl+ZoE15A9o1oQd920Bb0iOJMQkQhl3jNc03YqVjAhG7scf9C5KWRU/R13Orf588uCC6525o02g==", - "dev": true, - "requires": { - "d": "1", - "es5-ext": "^0.10.35", - "es6-symbol": "^3.1.1" - } - }, - "es6-promise": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", - "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==", - "dev": true - }, - "es6-symbol": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.3.tgz", - "integrity": "sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA==", - "dev": true, - "requires": { - "d": "^1.0.1", - "ext": "^1.1.2" - } - }, - "escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", - "dev": true - }, - "escape-html": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", - "dev": true - }, - "escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "dev": true - }, - "escodegen": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.8.1.tgz", - "integrity": "sha512-yhi5S+mNTOuRvyW4gWlg5W1byMaQGWWSYHXsuFZ7GBo7tpyOwi2EdzMP/QWxh9hwkD2m+wDVHJsxhRIj+v/b/A==", - "dev": true, - "requires": { - "esprima": "^2.7.1", - "estraverse": "^1.9.1", - "esutils": "^2.0.2", - "optionator": "^0.8.1", - "source-map": "~0.2.0" - }, - "dependencies": { - "esprima": { - "version": "2.7.3", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-2.7.3.tgz", - "integrity": "sha512-OarPfz0lFCiW4/AV2Oy1Rp9qu0iusTKqykwTspGCZtPxmF81JR4MmIebvF1F9+UOKth2ZubLQ4XGGaU+hSn99A==", - "dev": true - }, - "estraverse": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-1.9.3.tgz", - "integrity": "sha512-25w1fMXQrGdoquWnScXZGckOv+Wes+JDnuN/+7ex3SauFRS72r2lFDec0EKPt2YD1wUJ/IrfEex+9yp4hfSOJA==", - "dev": true - }, - "levn": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", - "integrity": "sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA==", - "dev": true, - "requires": { - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2" - } - }, - "optionator": { - "version": "0.8.3", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", - "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", - "dev": true, - "requires": { - "deep-is": "~0.1.3", - "fast-levenshtein": "~2.0.6", - "levn": "~0.3.0", - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2", - "word-wrap": "~1.2.3" - } - }, - "prelude-ls": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", - "integrity": "sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w==", - "dev": true - }, - "type-check": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", - "integrity": "sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg==", - "dev": true, - "requires": { - "prelude-ls": "~1.1.2" - } - } - } - }, - "eslint": { - "version": "7.32.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.32.0.tgz", - "integrity": "sha512-VHZ8gX+EDfz+97jGcgyGCyRia/dPOd6Xh9yPv8Bl1+SoaIwD+a/vlrOmGRUyOYu7MwUhc7CxqeaDZU13S4+EpA==", - "dev": true, - "requires": { - "@babel/code-frame": "7.12.11", - "@eslint/eslintrc": "^0.4.3", - "@humanwhocodes/config-array": "^0.5.0", - "ajv": "^6.10.0", - "chalk": "^4.0.0", - "cross-spawn": "^7.0.2", - "debug": "^4.0.1", - "doctrine": "^3.0.0", - "enquirer": "^2.3.5", - "escape-string-regexp": "^4.0.0", - "eslint-scope": "^5.1.1", - "eslint-utils": "^2.1.0", - "eslint-visitor-keys": "^2.0.0", - "espree": "^7.3.1", - "esquery": "^1.4.0", - "esutils": "^2.0.2", - "fast-deep-equal": "^3.1.3", - "file-entry-cache": "^6.0.1", - "functional-red-black-tree": "^1.0.1", - "glob-parent": "^5.1.2", - "globals": "^13.6.0", - "ignore": "^4.0.6", - "import-fresh": "^3.0.0", - "imurmurhash": "^0.1.4", - "is-glob": "^4.0.0", - "js-yaml": "^3.13.1", - "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.4.1", - "lodash.merge": "^4.6.2", - "minimatch": "^3.0.4", - "natural-compare": "^1.4.0", - "optionator": "^0.9.1", - "progress": "^2.0.0", - "regexpp": "^3.1.0", - "semver": "^7.2.1", - "strip-ansi": "^6.0.0", - "strip-json-comments": "^3.1.0", - "table": "^6.0.9", - "text-table": "^0.2.0", - "v8-compile-cache": "^2.0.3" - }, - "dependencies": { - "eslint-utils": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", - "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", - "dev": true, - "requires": { - "eslint-visitor-keys": "^1.1.0" - }, - "dependencies": { - "eslint-visitor-keys": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", - "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", - "dev": true - } - } - }, - "ignore": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", - "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", - "dev": true - }, - "lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "requires": { - "yallist": "^4.0.0" - } - }, - "semver": { - "version": "7.5.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", - "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", - "dev": true, - "requires": { - "lru-cache": "^6.0.0" - } - }, - "yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - } - } - }, - "eslint-config-prettier": { - "version": "8.8.0", - "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-8.8.0.tgz", - "integrity": "sha512-wLbQiFre3tdGgpDv67NQKnJuTlcUVYHas3k+DZCc2U2BadthoEY4B7hLPvAxaqdyOGCzuLfii2fqGph10va7oA==", - "dev": true, - "requires": {} - }, - "eslint-config-standard": { - "version": "16.0.3", - "resolved": "https://registry.npmjs.org/eslint-config-standard/-/eslint-config-standard-16.0.3.tgz", - "integrity": "sha512-x4fmJL5hGqNJKGHSjnLdgA6U6h1YW/G2dW9fA+cyVur4SK6lyue8+UgNKWlZtUDTXvgKDD/Oa3GQjmB5kjtVvg==", - "dev": true, - "requires": {} - }, - "eslint-import-resolver-node": { - "version": "0.3.7", - "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.7.tgz", - "integrity": "sha512-gozW2blMLJCeFpBwugLTGyvVjNoeo1knonXAcatC6bjPBZitotxdWf7Gimr25N4c0AAOo4eOUfaG82IJPDpqCA==", - "dev": true, - "requires": { - "debug": "^3.2.7", - "is-core-module": "^2.11.0", - "resolve": "^1.22.1" - }, - "dependencies": { - "debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - } - } - }, - "eslint-module-utils": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.8.0.tgz", - "integrity": "sha512-aWajIYfsqCKRDgUfjEXNN/JlrzauMuSEy5sbd7WXbtW3EH6A6MpwEh42c7qD+MqQo9QMJ6fWLAeIJynx0g6OAw==", - "dev": true, - "requires": { - "debug": "^3.2.7" - }, - "dependencies": { - "debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - } - } - }, - "eslint-plugin-es": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-es/-/eslint-plugin-es-3.0.1.tgz", - "integrity": "sha512-GUmAsJaN4Fc7Gbtl8uOBlayo2DqhwWvEzykMHSCZHU3XdJ+NSzzZcVhXh3VxX5icqQ+oQdIEawXX8xkR3mIFmQ==", - "dev": true, - "requires": { - "eslint-utils": "^2.0.0", - "regexpp": "^3.0.0" - }, - "dependencies": { - "eslint-utils": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", - "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", - "dev": true, - "requires": { - "eslint-visitor-keys": "^1.1.0" - } - }, - "eslint-visitor-keys": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", - "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", - "dev": true - } - } - }, - "eslint-plugin-import": { - "version": "2.27.5", - "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.27.5.tgz", - "integrity": "sha512-LmEt3GVofgiGuiE+ORpnvP+kAm3h6MLZJ4Q5HCyHADofsb4VzXFsRiWj3c0OFiV+3DWFh0qg3v9gcPlfc3zRow==", - "dev": true, - "requires": { - "array-includes": "^3.1.6", - "array.prototype.flat": "^1.3.1", - "array.prototype.flatmap": "^1.3.1", - "debug": "^3.2.7", - "doctrine": "^2.1.0", - "eslint-import-resolver-node": "^0.3.7", - "eslint-module-utils": "^2.7.4", - "has": "^1.0.3", - "is-core-module": "^2.11.0", - "is-glob": "^4.0.3", - "minimatch": "^3.1.2", - "object.values": "^1.1.6", - "resolve": "^1.22.1", - "semver": "^6.3.0", - "tsconfig-paths": "^3.14.1" - }, - "dependencies": { - "debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "doctrine": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", - "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", - "dev": true, - "requires": { - "esutils": "^2.0.2" - } - } - } - }, - "eslint-plugin-node": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-node/-/eslint-plugin-node-11.1.0.tgz", - "integrity": "sha512-oUwtPJ1W0SKD0Tr+wqu92c5xuCeQqB3hSCHasn/ZgjFdA9iDGNkNf2Zi9ztY7X+hNuMib23LNGRm6+uN+KLE3g==", - "dev": true, - "requires": { - "eslint-plugin-es": "^3.0.0", - "eslint-utils": "^2.0.0", - "ignore": "^5.1.1", - "minimatch": "^3.0.4", - "resolve": "^1.10.1", - "semver": "^6.1.0" - }, - "dependencies": { - "eslint-utils": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", - "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", - "dev": true, - "requires": { - "eslint-visitor-keys": "^1.1.0" - } - }, - "eslint-visitor-keys": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", - "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", - "dev": true - } - } - }, - "eslint-plugin-prettier": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-3.4.1.tgz", - "integrity": "sha512-htg25EUYUeIhKHXjOinK4BgCcDwtLHjqaxCDsMy5nbnUMkKFvIhMVCp+5GFUXQ4Nr8lBsPqtGAqBenbpFqAA2g==", - "dev": true, - "requires": { - "prettier-linter-helpers": "^1.0.0" - } - }, - "eslint-plugin-promise": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-5.2.0.tgz", - "integrity": "sha512-SftLb1pUG01QYq2A/hGAWfDRXqYD82zE7j7TopDOyNdU+7SvvoXREls/+PRTY17vUXzXnZA/zfnyKgRH6x4JJw==", - "dev": true, - "requires": {} - }, - "eslint-scope": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", - "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", - "dev": true, - "requires": { - "esrecurse": "^4.3.0", - "estraverse": "^4.1.1" - } - }, - "eslint-utils": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", - "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", - "dev": true, - "requires": { - "eslint-visitor-keys": "^2.0.0" - } - }, - "eslint-visitor-keys": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", - "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", - "dev": true - }, - "espree": { - "version": "7.3.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-7.3.1.tgz", - "integrity": "sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g==", - "dev": true, - "requires": { - "acorn": "^7.4.0", - "acorn-jsx": "^5.3.1", - "eslint-visitor-keys": "^1.3.0" - }, - "dependencies": { - "eslint-visitor-keys": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", - "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", - "dev": true - } - } - }, - "esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "dev": true - }, - "esquery": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", - "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", - "dev": true, - "requires": { - "estraverse": "^5.1.0" - }, - "dependencies": { - "estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true - } - } - }, - "esrecurse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", - "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", - "dev": true, - "requires": { - "estraverse": "^5.2.0" - }, - "dependencies": { - "estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true - } - } - }, - "estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", - "dev": true - }, - "esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "dev": true - }, - "etag": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", - "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", - "dev": true - }, - "eth-ens-namehash": { - "version": "2.0.8", - "resolved": "https://registry.npmjs.org/eth-ens-namehash/-/eth-ens-namehash-2.0.8.tgz", - "integrity": "sha512-VWEI1+KJfz4Km//dadyvBBoBeSQ0MHTXPvr8UIXiLW6IanxvAV+DmlZAijZwAyggqGUfwQBeHf7tc9wzc1piSw==", - "dev": true, - "requires": { - "idna-uts46-hx": "^2.3.1", - "js-sha3": "^0.5.7" - }, - "dependencies": { - "js-sha3": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.5.7.tgz", - "integrity": "sha512-GII20kjaPX0zJ8wzkTbNDYMY7msuZcTWk8S5UOh6806Jq/wz1J8/bnr8uGU0DAUmYDjj2Mr4X1cW8v/GLYnR+g==", - "dev": true - } - } - }, - "eth-gas-reporter": { - "version": "0.2.25", - "resolved": "https://registry.npmjs.org/eth-gas-reporter/-/eth-gas-reporter-0.2.25.tgz", - "integrity": "sha512-1fRgyE4xUB8SoqLgN3eDfpDfwEfRxh2Sz1b7wzFbyQA+9TekMmvSjjoRu9SKcSVyK+vLkLIsVbJDsTWjw195OQ==", - "dev": true, - "requires": { - "@ethersproject/abi": "^5.0.0-beta.146", - "@solidity-parser/parser": "^0.14.0", - "cli-table3": "^0.5.0", - "colors": "1.4.0", - "ethereum-cryptography": "^1.0.3", - "ethers": "^4.0.40", - "fs-readdir-recursive": "^1.1.0", - "lodash": "^4.17.14", - "markdown-table": "^1.1.3", - "mocha": "^7.1.1", - "req-cwd": "^2.0.0", - "request": "^2.88.0", - "request-promise-native": "^1.0.5", - "sha1": "^1.1.1", - "sync-request": "^6.0.0" - }, - "dependencies": { - "ansi-colors": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.3.tgz", - "integrity": "sha512-LEHHyuhlPY3TmuUYMh2oz89lTShfvgbmzaBcxve9t/9Wuy7Dwf4yoAKcND7KFT1HAQfqZ12qtc+DUrBMeKF9nw==", - "dev": true - }, - "ansi-regex": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz", - "integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==", - "dev": true - }, - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", - "dev": true - }, - "camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "dependencies": { - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "chokidar": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.3.0.tgz", - "integrity": "sha512-dGmKLDdT3Gdl7fBUe8XK+gAtGmzy5Fn0XkkWQuYxGIgWVPPse2CxFA5mtrlD0TOHaHjEUqkWNyP1XdHoJES/4A==", - "dev": true, - "requires": { - "anymatch": "~3.1.1", - "braces": "~3.0.2", - "fsevents": "~2.1.1", - "glob-parent": "~5.1.0", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.2.0" - } - }, - "cliui": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", - "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", - "dev": true, - "requires": { - "string-width": "^3.1.0", - "strip-ansi": "^5.2.0", - "wrap-ansi": "^5.1.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true - }, - "debug": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", - "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", - "dev": true - }, - "diff": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", - "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", - "dev": true - }, - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true - }, - "ethers": { - "version": "4.0.49", - "resolved": "https://registry.npmjs.org/ethers/-/ethers-4.0.49.tgz", - "integrity": "sha512-kPltTvWiyu+OktYy1IStSO16i2e7cS9D9OxZ81q2UUaiNPVrm/RTcbxamCXF9VUSKzJIdJV68EAIhTEVBalRWg==", - "dev": true, - "requires": { - "aes-js": "3.0.0", - "bn.js": "^4.11.9", - "elliptic": "6.5.4", - "hash.js": "1.1.3", - "js-sha3": "0.5.7", - "scrypt-js": "2.0.4", - "setimmediate": "1.0.4", - "uuid": "2.0.1", - "xmlhttprequest": "1.8.0" - } - }, - "find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "dev": true, - "requires": { - "locate-path": "^3.0.0" - } - }, - "flat": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/flat/-/flat-4.1.1.tgz", - "integrity": "sha512-FmTtBsHskrU6FJ2VxCnsDb84wu9zhmO3cUX2kGFb5tuwhfXxGciiT0oRY+cck35QmG+NmGh5eLz6lLCpWTqwpA==", - "dev": true, - "requires": { - "is-buffer": "~2.0.3" - } - }, - "fsevents": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz", - "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==", - "dev": true, - "optional": true - }, - "glob": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", - "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true - }, - "hash.js": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.3.tgz", - "integrity": "sha512-/UETyP0W22QILqS+6HowevwhEFJ3MBJnwTf75Qob9Wz9t0DPuisL8kW8YZMK62dHAKE1c1p+gY1TtOLY+USEHA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "minimalistic-assert": "^1.0.0" - } - }, - "js-sha3": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.5.7.tgz", - "integrity": "sha512-GII20kjaPX0zJ8wzkTbNDYMY7msuZcTWk8S5UOh6806Jq/wz1J8/bnr8uGU0DAUmYDjj2Mr4X1cW8v/GLYnR+g==", - "dev": true - }, - "js-yaml": { - "version": "3.13.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", - "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", - "dev": true, - "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - } - }, - "locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "dev": true, - "requires": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - } - }, - "log-symbols": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-3.0.0.tgz", - "integrity": "sha512-dSkNGuI7iG3mfvDzUuYZyvk5dD9ocYCYzNU6CYDE6+Xqd+gwme6Z00NS3dUh8mq/73HaEtT7m6W+yUPtU6BZnQ==", - "dev": true, - "requires": { - "chalk": "^2.4.2" - } - }, - "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "mkdirp": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", - "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", - "dev": true, - "requires": { - "minimist": "^1.2.5" - } - }, - "mocha": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-7.2.0.tgz", - "integrity": "sha512-O9CIypScywTVpNaRrCAgoUnJgozpIofjKUYmJhiCIJMiuYnLI6otcb1/kpW9/n/tJODHGZ7i8aLQoDVsMtOKQQ==", - "dev": true, - "requires": { - "ansi-colors": "3.2.3", - "browser-stdout": "1.3.1", - "chokidar": "3.3.0", - "debug": "3.2.6", - "diff": "3.5.0", - "escape-string-regexp": "1.0.5", - "find-up": "3.0.0", - "glob": "7.1.3", - "growl": "1.10.5", - "he": "1.2.0", - "js-yaml": "3.13.1", - "log-symbols": "3.0.0", - "minimatch": "3.0.4", - "mkdirp": "0.5.5", - "ms": "2.1.1", - "node-environment-flags": "1.0.6", - "object.assign": "4.1.0", - "strip-json-comments": "2.0.1", - "supports-color": "6.0.0", - "which": "1.3.1", - "wide-align": "1.1.3", - "yargs": "13.3.2", - "yargs-parser": "13.1.2", - "yargs-unparser": "1.6.0" - } - }, - "ms": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", - "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", - "dev": true - }, - "object.assign": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz", - "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==", - "dev": true, - "requires": { - "define-properties": "^1.1.2", - "function-bind": "^1.1.1", - "has-symbols": "^1.0.0", - "object-keys": "^1.0.11" - } - }, - "p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "dev": true, - "requires": { - "p-limit": "^2.0.0" - } - }, - "p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true - }, - "readdirp": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.2.0.tgz", - "integrity": "sha512-crk4Qu3pmXwgxdSgGhgA/eXiJAPQiX4GMOZZMXnqKxHX7TaoL+3gQVo/WeuAiogr07DpnfjIMpXXa+PAIvwPGQ==", - "dev": true, - "requires": { - "picomatch": "^2.0.4" - } - }, - "require-main-filename": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", - "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", - "dev": true - }, - "scrypt-js": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/scrypt-js/-/scrypt-js-2.0.4.tgz", - "integrity": "sha512-4KsaGcPnuhtCZQCxFxN3GVYIhKFPTdLd8PLC552XwbMndtD0cjRFAhDuuydXQ0h08ZfPgzqe6EKHozpuH74iDw==", - "dev": true - }, - "setimmediate": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.4.tgz", - "integrity": "sha512-/TjEmXQVEzdod/FFskf3o7oOAsGhHf2j1dZqRFbDzq4F3mvvxflIIi4Hd3bLQE9y/CpwqfSQam5JakI/mi3Pog==", - "dev": true - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - } - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - } - }, - "strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", - "dev": true - }, - "supports-color": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.0.0.tgz", - "integrity": "sha512-on9Kwidc1IUQo+bQdhi8+Tijpo0e1SS6RoGo2guUwn5vdaxw8RXOF9Vb2ws+ihWOmh4JnCJOvaziZWP1VABaLg==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - }, - "uuid": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-2.0.1.tgz", - "integrity": "sha512-nWg9+Oa3qD2CQzHIP4qKUqwNfzKn8P0LtFhotaCTFchsV7ZfDhAybeip/HZVeMIpZi9JgY1E3nUlwaCmZT1sEg==", - "dev": true - }, - "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - }, - "which-module": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.1.tgz", - "integrity": "sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ==", - "dev": true - }, - "wrap-ansi": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", - "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.0", - "string-width": "^3.0.0", - "strip-ansi": "^5.0.0" - } - }, - "y18n": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", - "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==", - "dev": true - }, - "yargs": { - "version": "13.3.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", - "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", - "dev": true, - "requires": { - "cliui": "^5.0.0", - "find-up": "^3.0.0", - "get-caller-file": "^2.0.1", - "require-directory": "^2.1.1", - "require-main-filename": "^2.0.0", - "set-blocking": "^2.0.0", - "string-width": "^3.0.0", - "which-module": "^2.0.0", - "y18n": "^4.0.0", - "yargs-parser": "^13.1.2" - } - }, - "yargs-parser": { - "version": "13.1.2", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", - "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", - "dev": true, - "requires": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - } - }, - "yargs-unparser": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-1.6.0.tgz", - "integrity": "sha512-W9tKgmSn0DpSatfri0nx52Joq5hVXgeLiqR/5G0sZNDoLZFOr/xjBUDcShCOGNsBnEMNo1KAMBkTej1Hm62HTw==", - "dev": true, - "requires": { - "flat": "^4.1.0", - "lodash": "^4.17.15", - "yargs": "^13.3.0" - } - } - } - }, - "eth-lib": { - "version": "0.1.29", - "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.1.29.tgz", - "integrity": "sha512-bfttrr3/7gG4E02HoWTDUcDDslN003OlOoBxk9virpAZQ1ja/jDgwkWB8QfJF7ojuEowrqy+lzp9VcJG7/k5bQ==", - "dev": true, - "requires": { - "bn.js": "^4.11.6", - "elliptic": "^6.4.0", - "nano-json-stream-parser": "^0.1.2", - "servify": "^0.1.12", - "ws": "^3.0.0", - "xhr-request-promise": "^0.1.2" - }, - "dependencies": { - "bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", - "dev": true - }, - "ws": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/ws/-/ws-3.3.3.tgz", - "integrity": "sha512-nnWLa/NwZSt4KQJu51MYlCcSQ5g7INpOrOMt4XV8j4dqTXdmlUmSHQ8/oLC069ckre0fRsgfvsKwbTdtKLCDkA==", - "dev": true, - "requires": { - "async-limiter": "~1.0.0", - "safe-buffer": "~5.1.0", - "ultron": "~1.1.0" - } - } - } - }, - "ethereum-bloom-filters": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/ethereum-bloom-filters/-/ethereum-bloom-filters-1.0.10.tgz", - "integrity": "sha512-rxJ5OFN3RwjQxDcFP2Z5+Q9ho4eIdEmSc2ht0fCu8Se9nbXjZ7/031uXoUYJ87KHCOdVeiUuwSnoS7hmYAGVHA==", - "requires": { - "js-sha3": "^0.8.0" - } - }, - "ethereum-cryptography": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-1.2.0.tgz", - "integrity": "sha512-6yFQC9b5ug6/17CQpCyE3k9eKBMdhyVjzUy1WkiuY/E4vj/SXDBbCw8QEIaXqf0Mf2SnY6RmpDcwlUmBSS0EJw==", - "dev": true, - "requires": { - "@noble/hashes": "1.2.0", - "@noble/secp256k1": "1.7.1", - "@scure/bip32": "1.1.5", - "@scure/bip39": "1.1.1" - } - }, - "ethereum-waffle": { - "version": "3.4.4", - "resolved": "https://registry.npmjs.org/ethereum-waffle/-/ethereum-waffle-3.4.4.tgz", - "integrity": "sha512-PA9+jCjw4WC3Oc5ocSMBj5sXvueWQeAbvCA+hUlb6oFgwwKyq5ka3bWQ7QZcjzIX+TdFkxP4IbFmoY2D8Dkj9Q==", - "dev": true, - "requires": { - "@ethereum-waffle/chai": "^3.4.4", - "@ethereum-waffle/compiler": "^3.4.4", - "@ethereum-waffle/mock-contract": "^3.4.4", - "@ethereum-waffle/provider": "^3.4.4", - "ethers": "^5.0.1" - } - }, - "ethereumjs-abi": { - "version": "0.6.8", - "resolved": "https://registry.npmjs.org/ethereumjs-abi/-/ethereumjs-abi-0.6.8.tgz", - "integrity": "sha512-Tx0r/iXI6r+lRsdvkFDlut0N08jWMnKRZ6Gkq+Nmw75lZe4e6o3EkSnkaBP5NF6+m5PTGAr9JP43N3LyeoglsA==", - "dev": true, - "requires": { - "bn.js": "^4.11.8", - "ethereumjs-util": "^6.0.0" - }, - "dependencies": { - "bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", - "dev": true - } - } - }, - "ethereumjs-util": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-6.2.1.tgz", - "integrity": "sha512-W2Ktez4L01Vexijrm5EB6w7dg4n/TgpoYU4avuT5T3Vmnw/eCRtiBrJfQYS/DCSvDIOLn2k57GcHdeBcgVxAqw==", - "dev": true, - "requires": { - "@types/bn.js": "^4.11.3", - "bn.js": "^4.11.0", - "create-hash": "^1.1.2", - "elliptic": "^6.5.2", - "ethereum-cryptography": "^0.1.3", - "ethjs-util": "0.1.6", - "rlp": "^2.2.3" - }, - "dependencies": { - "@types/bn.js": { - "version": "4.11.6", - "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-4.11.6.tgz", - "integrity": "sha512-pqr857jrp2kPuO9uRjZ3PwnJTjoQy+fcdxvBTvHm6dkmEL9q+hDD/2j/0ELOBPtPnS8LjCX0gI9nbl8lVkadpg==", - "dev": true, - "requires": { - "@types/node": "*" - } - }, - "bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", - "dev": true - }, - "ethereum-cryptography": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz", - "integrity": "sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==", - "dev": true, - "requires": { - "@types/pbkdf2": "^3.0.0", - "@types/secp256k1": "^4.0.1", - "blakejs": "^1.1.0", - "browserify-aes": "^1.2.0", - "bs58check": "^2.1.2", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "hash.js": "^1.1.7", - "keccak": "^3.0.0", - "pbkdf2": "^3.0.17", - "randombytes": "^2.1.0", - "safe-buffer": "^5.1.2", - "scrypt-js": "^3.0.0", - "secp256k1": "^4.0.1", - "setimmediate": "^1.0.5" - } - } - } - }, - "ethers": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/ethers/-/ethers-5.7.2.tgz", - "integrity": "sha512-wswUsmWo1aOK8rR7DIKiWSw9DbLWe6x98Jrn8wcTflTVvaXhAMaB5zGAXy0GYQEQp9iO1iSHWVyARQm11zUtyg==", - "requires": { - "@ethersproject/abi": "5.7.0", - "@ethersproject/abstract-provider": "5.7.0", - "@ethersproject/abstract-signer": "5.7.0", - "@ethersproject/address": "5.7.0", - "@ethersproject/base64": "5.7.0", - "@ethersproject/basex": "5.7.0", - "@ethersproject/bignumber": "5.7.0", - "@ethersproject/bytes": "5.7.0", - "@ethersproject/constants": "5.7.0", - "@ethersproject/contracts": "5.7.0", - "@ethersproject/hash": "5.7.0", - "@ethersproject/hdnode": "5.7.0", - "@ethersproject/json-wallets": "5.7.0", - "@ethersproject/keccak256": "5.7.0", - "@ethersproject/logger": "5.7.0", - "@ethersproject/networks": "5.7.1", - "@ethersproject/pbkdf2": "5.7.0", - "@ethersproject/properties": "5.7.0", - "@ethersproject/providers": "5.7.2", - "@ethersproject/random": "5.7.0", - "@ethersproject/rlp": "5.7.0", - "@ethersproject/sha2": "5.7.0", - "@ethersproject/signing-key": "5.7.0", - "@ethersproject/solidity": "5.7.0", - "@ethersproject/strings": "5.7.0", - "@ethersproject/transactions": "5.7.0", - "@ethersproject/units": "5.7.0", - "@ethersproject/wallet": "5.7.0", - "@ethersproject/web": "5.7.1", - "@ethersproject/wordlists": "5.7.0" - } - }, - "ethjs-unit": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/ethjs-unit/-/ethjs-unit-0.1.6.tgz", - "integrity": "sha512-/Sn9Y0oKl0uqQuvgFk/zQgR7aw1g36qX/jzSQ5lSwlO0GigPymk4eGQfeNTD03w1dPOqfz8V77Cy43jH56pagw==", - "requires": { - "bn.js": "4.11.6", - "number-to-bn": "1.7.0" - }, - "dependencies": { - "bn.js": { - "version": "4.11.6", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.6.tgz", - "integrity": "sha512-XWwnNNFCuuSQ0m3r3C4LE3EiORltHd9M05pq6FOlVeiophzRbMo50Sbz1ehl8K3Z+jw9+vmgnXefY1hz8X+2wA==" - } - } - }, - "ethjs-util": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/ethjs-util/-/ethjs-util-0.1.6.tgz", - "integrity": "sha512-CUnVOQq7gSpDHZVVrQW8ExxUETWrnrvXYvYz55wOU8Uj4VCgw56XC2B/fVqQN+f7gmrnRHSLVnFAwsCuNwji8w==", - "dev": true, - "requires": { - "is-hex-prefixed": "1.0.0", - "strip-hex-prefix": "1.0.0" - } - }, - "event-target-shim": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", - "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==", - "dev": true - }, - "eventemitter3": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.4.tgz", - "integrity": "sha512-rlaVLnVxtxvoyLsQQFBx53YmXHDxRIzzTLbdfxqi4yocpSjAxXwkU0cScM5JgSKMqEhrZpnvQ2D9gjylR0AimQ==", - "dev": true - }, - "evp_bytestokey": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", - "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", - "requires": { - "md5.js": "^1.3.4", - "safe-buffer": "^5.1.1" - } - }, - "express": { - "version": "4.18.2", - "resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz", - "integrity": "sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==", - "dev": true, - "requires": { - "accepts": "~1.3.8", - "array-flatten": "1.1.1", - "body-parser": "1.20.1", - "content-disposition": "0.5.4", - "content-type": "~1.0.4", - "cookie": "0.5.0", - "cookie-signature": "1.0.6", - "debug": "2.6.9", - "depd": "2.0.0", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "finalhandler": "1.2.0", - "fresh": "0.5.2", - "http-errors": "2.0.0", - "merge-descriptors": "1.0.1", - "methods": "~1.1.2", - "on-finished": "2.4.1", - "parseurl": "~1.3.3", - "path-to-regexp": "0.1.7", - "proxy-addr": "~2.0.7", - "qs": "6.11.0", - "range-parser": "~1.2.1", - "safe-buffer": "5.2.1", - "send": "0.18.0", - "serve-static": "1.15.0", - "setprototypeof": "1.2.0", - "statuses": "2.0.1", - "type-is": "~1.6.18", - "utils-merge": "1.0.1", - "vary": "~1.1.2" - }, - "dependencies": { - "body-parser": { - "version": "1.20.1", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz", - "integrity": "sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==", - "dev": true, - "requires": { - "bytes": "3.1.2", - "content-type": "~1.0.4", - "debug": "2.6.9", - "depd": "2.0.0", - "destroy": "1.2.0", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "on-finished": "2.4.1", - "qs": "6.11.0", - "raw-body": "2.5.1", - "type-is": "~1.6.18", - "unpipe": "1.0.0" - } - }, - "cookie": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", - "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==", - "dev": true - }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true - }, - "qs": { - "version": "6.11.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", - "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", - "dev": true, - "requires": { - "side-channel": "^1.0.4" - } - }, - "raw-body": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz", - "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==", - "dev": true, - "requires": { - "bytes": "3.1.2", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "unpipe": "1.0.0" - } - }, - "safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "dev": true - } - } - }, - "ext": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/ext/-/ext-1.7.0.tgz", - "integrity": "sha512-6hxeJYaL110a9b5TEJSj0gojyHQAmA2ch5Os+ySCiA1QGdS697XWY1pzsrSjqA9LDEEgdB/KypIlR59RcLuHYw==", - "dev": true, - "requires": { - "type": "^2.7.2" - }, - "dependencies": { - "type": { - "version": "2.7.2", - "resolved": "https://registry.npmjs.org/type/-/type-2.7.2.tgz", - "integrity": "sha512-dzlvlNlt6AXU7EBSfpAscydQ7gXB+pPGsPnfJnZpiNJBDj7IaJzQlBZYGdEi4R9HmPdBv2XmWJ6YUtoTa7lmCw==", - "dev": true - } - } - }, - "extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", - "dev": true - }, - "extsprintf": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", - "integrity": "sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g==", - "dev": true - }, - "fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true - }, - "fast-diff": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.3.0.tgz", - "integrity": "sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==", - "dev": true - }, - "fast-glob": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.0.tgz", - "integrity": "sha512-ChDuvbOypPuNjO8yIDf36x7BlZX1smcUMTTcyoIjycexOxd6DFsKsg21qVBzEmr3G7fUKIRy2/psii+CIUt7FA==", - "dev": true, - "requires": { - "@nodelib/fs.stat": "^2.0.2", - "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.2", - "merge2": "^1.3.0", - "micromatch": "^4.0.4" - } - }, - "fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "dev": true - }, - "fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", - "dev": true - }, - "fastq": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz", - "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==", - "dev": true, - "requires": { - "reusify": "^1.0.4" - } - }, - "file-entry-cache": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", - "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", - "dev": true, - "requires": { - "flat-cache": "^3.0.4" - } - }, - "fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "dev": true, - "requires": { - "to-regex-range": "^5.0.1" - } - }, - "finalhandler": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", - "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", - "dev": true, - "requires": { - "debug": "2.6.9", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "on-finished": "2.4.1", - "parseurl": "~1.3.3", - "statuses": "2.0.1", - "unpipe": "~1.0.0" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true - } - } - }, - "find-replace": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/find-replace/-/find-replace-1.0.3.tgz", - "integrity": "sha512-KrUnjzDCD9426YnCP56zGYy/eieTnhtK6Vn++j+JJzmlsWWwEkDnsyVF575spT6HJ6Ow9tlbT3TQTDsa+O4UWA==", - "dev": true, - "requires": { - "array-back": "^1.0.4", - "test-value": "^2.1.0" - }, - "dependencies": { - "array-back": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/array-back/-/array-back-1.0.4.tgz", - "integrity": "sha512-1WxbZvrmyhkNoeYcizokbmh5oiOCIfyvGtcqbK3Ls1v1fKcquzxnQSceOx6tzq7jmai2kFLWIpGND2cLhH6TPw==", - "dev": true, - "requires": { - "typical": "^2.6.0" - } - } - } - }, - "find-up": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", - "integrity": "sha512-NWzkk0jSJtTt08+FBFMvXoeZnOJD+jTtsRmBYbAIzJdX6l7dLgR7CTubCM5/eDdPUBvLCeVasP1brfVR/9/EZQ==", - "dev": true, - "requires": { - "locate-path": "^2.0.0" - } - }, - "find-yarn-workspace-root": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/find-yarn-workspace-root/-/find-yarn-workspace-root-2.0.0.tgz", - "integrity": "sha512-1IMnbjt4KzsQfnhnzNd8wUEgXZ44IzZaZmnLYx7D5FZlaHt2gW20Cri8Q+E/t5tIj4+epTBub+2Zxu/vNILzqQ==", - "dev": true, - "requires": { - "micromatch": "^4.0.2" - } - }, - "flat": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", - "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", - "dev": true - }, - "flat-cache": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", - "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", - "dev": true, - "requires": { - "flatted": "^3.1.0", - "rimraf": "^3.0.2" - } - }, - "flatted": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz", - "integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==", - "dev": true - }, - "follow-redirects": { - "version": "1.15.2", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz", - "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==", - "dev": true - }, - "for-each": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", - "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", - "dev": true, - "requires": { - "is-callable": "^1.1.3" - } - }, - "forever-agent": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", - "integrity": "sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw==", - "dev": true - }, - "form-data": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz", - "integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==", - "dev": true, - "requires": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "mime-types": "^2.1.12" - } - }, - "form-data-encoder": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/form-data-encoder/-/form-data-encoder-1.7.1.tgz", - "integrity": "sha512-EFRDrsMm/kyqbTQocNvRXMLjc7Es2Vk+IQFx/YW7hkUH1eBl4J1fqiP34l74Yt0pFLCNpc06fkbVk00008mzjg==", - "dev": true - }, - "forwarded": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", - "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", - "dev": true - }, - "fp-ts": { - "version": "1.19.3", - "resolved": "https://registry.npmjs.org/fp-ts/-/fp-ts-1.19.3.tgz", - "integrity": "sha512-H5KQDspykdHuztLTg+ajGN0Z2qUjcEf3Ybxc6hLt0k7/zPkn29XnKnxlBPyW2XIddWrGaJBzBl4VLYOtk39yZg==", - "dev": true - }, - "fresh": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", - "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", - "dev": true - }, - "fs-extra": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", - "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - } - }, - "fs-minipass": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-1.2.7.tgz", - "integrity": "sha512-GWSSJGFy4e9GUeCcbIkED+bgAoFyj7XF1mV8rma3QW4NIqX9Kyx79N/PF61H5udOV3aY1IaMLs6pGbH71nlCTA==", - "dev": true, - "requires": { - "minipass": "^2.6.0" - } - }, - "fs-readdir-recursive": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/fs-readdir-recursive/-/fs-readdir-recursive-1.1.0.tgz", - "integrity": "sha512-GNanXlVr2pf02+sPN40XN8HG+ePaNcvM0q5mZBd668Obwb0yD5GiUbZOFgwn8kGMY6I3mdyDJzieUy3PTYyTRA==", - "dev": true - }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", - "dev": true - }, - "fsevents": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", - "dev": true, - "optional": true - }, - "function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", - "dev": true - }, - "function.prototype.name": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.5.tgz", - "integrity": "sha512-uN7m/BzVKQnCUF/iW8jYea67v++2u7m5UgENbHRtdDVclOUP+FMPlCNdmk0h/ysGyo2tavMJEDqJAkJdRa1vMA==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.0", - "functions-have-names": "^1.2.2" - } - }, - "functional-red-black-tree": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", - "integrity": "sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g==", - "dev": true - }, - "functions-have-names": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", - "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", - "dev": true - }, - "ganache-core": { - "version": "2.13.2", - "resolved": "https://registry.npmjs.org/ganache-core/-/ganache-core-2.13.2.tgz", - "integrity": "sha512-tIF5cR+ANQz0+3pHWxHjIwHqFXcVo0Mb+kcsNhglNFALcYo49aQpnS9dqHartqPfMFjiHh/qFoD3mYK0d/qGgw==", - "dev": true, - "requires": { - "abstract-leveldown": "3.0.0", - "async": "2.6.2", - "bip39": "2.5.0", - "cachedown": "1.0.0", - "clone": "2.1.2", - "debug": "3.2.6", - "encoding-down": "5.0.4", - "eth-sig-util": "3.0.0", - "ethereumjs-abi": "0.6.8", - "ethereumjs-account": "3.0.0", - "ethereumjs-block": "2.2.2", - "ethereumjs-common": "1.5.0", - "ethereumjs-tx": "2.1.2", - "ethereumjs-util": "6.2.1", - "ethereumjs-vm": "4.2.0", - "ethereumjs-wallet": "0.6.5", - "heap": "0.2.6", - "keccak": "3.0.1", - "level-sublevel": "6.6.4", - "levelup": "3.1.1", - "lodash": "4.17.20", - "lru-cache": "5.1.1", - "merkle-patricia-tree": "3.0.0", - "patch-package": "6.2.2", - "seedrandom": "3.0.1", - "source-map-support": "0.5.12", - "tmp": "0.1.0", - "web3": "1.2.11", - "web3-provider-engine": "14.2.1", - "websocket": "1.0.32" - }, - "dependencies": { - "@ethersproject/abi": { - "version": "5.0.0-beta.153", - "dev": true, - "optional": true, - "requires": { - "@ethersproject/address": ">=5.0.0-beta.128", - "@ethersproject/bignumber": ">=5.0.0-beta.130", - "@ethersproject/bytes": ">=5.0.0-beta.129", - "@ethersproject/constants": ">=5.0.0-beta.128", - "@ethersproject/hash": ">=5.0.0-beta.128", - "@ethersproject/keccak256": ">=5.0.0-beta.127", - "@ethersproject/logger": ">=5.0.0-beta.129", - "@ethersproject/properties": ">=5.0.0-beta.131", - "@ethersproject/strings": ">=5.0.0-beta.130" - } - }, - "@ethersproject/abstract-provider": { - "version": "5.0.8", - "dev": true, - "optional": true, - "requires": { - "@ethersproject/bignumber": "^5.0.13", - "@ethersproject/bytes": "^5.0.9", - "@ethersproject/logger": "^5.0.8", - "@ethersproject/networks": "^5.0.7", - "@ethersproject/properties": "^5.0.7", - "@ethersproject/transactions": "^5.0.9", - "@ethersproject/web": "^5.0.12" - } - }, - "@ethersproject/abstract-signer": { - "version": "5.0.10", - "dev": true, - "optional": true, - "requires": { - "@ethersproject/abstract-provider": "^5.0.8", - "@ethersproject/bignumber": "^5.0.13", - "@ethersproject/bytes": "^5.0.9", - "@ethersproject/logger": "^5.0.8", - "@ethersproject/properties": "^5.0.7" - } - }, - "@ethersproject/address": { - "version": "5.0.9", - "dev": true, - "optional": true, - "requires": { - "@ethersproject/bignumber": "^5.0.13", - "@ethersproject/bytes": "^5.0.9", - "@ethersproject/keccak256": "^5.0.7", - "@ethersproject/logger": "^5.0.8", - "@ethersproject/rlp": "^5.0.7" - } - }, - "@ethersproject/base64": { - "version": "5.0.7", - "dev": true, - "optional": true, - "requires": { - "@ethersproject/bytes": "^5.0.9" - } - }, - "@ethersproject/bignumber": { - "version": "5.0.13", - "dev": true, - "optional": true, - "requires": { - "@ethersproject/bytes": "^5.0.9", - "@ethersproject/logger": "^5.0.8", - "bn.js": "^4.4.0" - } - }, - "@ethersproject/bytes": { - "version": "5.0.9", - "dev": true, - "optional": true, - "requires": { - "@ethersproject/logger": "^5.0.8" - } - }, - "@ethersproject/constants": { - "version": "5.0.8", - "dev": true, - "optional": true, - "requires": { - "@ethersproject/bignumber": "^5.0.13" - } - }, - "@ethersproject/hash": { - "version": "5.0.10", - "dev": true, - "optional": true, - "requires": { - "@ethersproject/abstract-signer": "^5.0.10", - "@ethersproject/address": "^5.0.9", - "@ethersproject/bignumber": "^5.0.13", - "@ethersproject/bytes": "^5.0.9", - "@ethersproject/keccak256": "^5.0.7", - "@ethersproject/logger": "^5.0.8", - "@ethersproject/properties": "^5.0.7", - "@ethersproject/strings": "^5.0.8" - } - }, - "@ethersproject/keccak256": { - "version": "5.0.7", - "dev": true, - "optional": true, - "requires": { - "@ethersproject/bytes": "^5.0.9", - "js-sha3": "0.5.7" - } - }, - "@ethersproject/logger": { - "version": "5.0.8", - "dev": true, - "optional": true - }, - "@ethersproject/networks": { - "version": "5.0.7", - "dev": true, - "optional": true, - "requires": { - "@ethersproject/logger": "^5.0.8" - } - }, - "@ethersproject/properties": { - "version": "5.0.7", - "dev": true, - "optional": true, - "requires": { - "@ethersproject/logger": "^5.0.8" - } - }, - "@ethersproject/rlp": { - "version": "5.0.7", - "dev": true, - "optional": true, - "requires": { - "@ethersproject/bytes": "^5.0.9", - "@ethersproject/logger": "^5.0.8" - } - }, - "@ethersproject/signing-key": { - "version": "5.0.8", - "dev": true, - "optional": true, - "requires": { - "@ethersproject/bytes": "^5.0.9", - "@ethersproject/logger": "^5.0.8", - "@ethersproject/properties": "^5.0.7", - "elliptic": "6.5.3" - } - }, - "@ethersproject/strings": { - "version": "5.0.8", - "dev": true, - "optional": true, - "requires": { - "@ethersproject/bytes": "^5.0.9", - "@ethersproject/constants": "^5.0.8", - "@ethersproject/logger": "^5.0.8" - } - }, - "@ethersproject/transactions": { - "version": "5.0.9", - "dev": true, - "optional": true, - "requires": { - "@ethersproject/address": "^5.0.9", - "@ethersproject/bignumber": "^5.0.13", - "@ethersproject/bytes": "^5.0.9", - "@ethersproject/constants": "^5.0.8", - "@ethersproject/keccak256": "^5.0.7", - "@ethersproject/logger": "^5.0.8", - "@ethersproject/properties": "^5.0.7", - "@ethersproject/rlp": "^5.0.7", - "@ethersproject/signing-key": "^5.0.8" - } - }, - "@ethersproject/web": { - "version": "5.0.12", - "dev": true, - "optional": true, - "requires": { - "@ethersproject/base64": "^5.0.7", - "@ethersproject/bytes": "^5.0.9", - "@ethersproject/logger": "^5.0.8", - "@ethersproject/properties": "^5.0.7", - "@ethersproject/strings": "^5.0.8" - } - }, - "@sindresorhus/is": { - "version": "0.14.0", - "dev": true, - "optional": true - }, - "@szmarczak/http-timer": { - "version": "1.1.2", - "dev": true, - "optional": true, - "requires": { - "defer-to-connect": "^1.0.1" - } - }, - "@types/bn.js": { - "version": "4.11.6", - "dev": true, - "requires": { - "@types/node": "*" - } - }, - "@types/node": { - "version": "14.14.20", - "dev": true - }, - "@types/pbkdf2": { - "version": "3.1.0", - "dev": true, - "requires": { - "@types/node": "*" - } - }, - "@types/secp256k1": { - "version": "4.0.1", - "dev": true, - "requires": { - "@types/node": "*" - } - }, - "@yarnpkg/lockfile": { - "version": "1.1.0", - "dev": true - }, - "abstract-leveldown": { - "version": "3.0.0", - "dev": true, - "requires": { - "xtend": "~4.0.0" - } - }, - "accepts": { - "version": "1.3.7", - "dev": true, - "optional": true, - "requires": { - "mime-types": "~2.1.24", - "negotiator": "0.6.2" - } - }, - "aes-js": { - "version": "3.1.2", - "dev": true, - "optional": true - }, - "ajv": { - "version": "6.12.6", - "dev": true, - "requires": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - }, - "ansi-styles": { - "version": "3.2.1", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "arr-diff": { - "version": "4.0.0", - "dev": true - }, - "arr-flatten": { - "version": "1.1.0", - "dev": true - }, - "arr-union": { - "version": "3.1.0", - "dev": true - }, - "array-flatten": { - "version": "1.1.1", - "dev": true, - "optional": true - }, - "array-unique": { - "version": "0.3.2", - "dev": true - }, - "asn1": { - "version": "0.2.4", - "dev": true, - "requires": { - "safer-buffer": "~2.1.0" - } - }, - "asn1.js": { - "version": "5.4.1", - "dev": true, - "optional": true, - "requires": { - "bn.js": "^4.0.0", - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0", - "safer-buffer": "^2.1.0" - } - }, - "assert-plus": { - "version": "1.0.0", - "dev": true - }, - "assign-symbols": { - "version": "1.0.0", - "dev": true - }, - "async": { - "version": "2.6.2", - "dev": true, - "requires": { - "lodash": "^4.17.11" - } - }, - "async-eventemitter": { - "version": "0.2.4", - "dev": true, - "requires": { - "async": "^2.4.0" - } - }, - "async-limiter": { - "version": "1.0.1", - "dev": true - }, - "asynckit": { - "version": "0.4.0", - "dev": true - }, - "atob": { - "version": "2.1.2", - "dev": true - }, - "aws-sign2": { - "version": "0.7.0", - "dev": true - }, - "aws4": { - "version": "1.11.0", - "dev": true - }, - "babel-code-frame": { - "version": "6.26.0", - "dev": true, - "requires": { - "chalk": "^1.1.3", - "esutils": "^2.0.2", - "js-tokens": "^3.0.2" - }, - "dependencies": { - "ansi-regex": { - "version": "2.1.1", - "dev": true - }, - "ansi-styles": { - "version": "2.2.1", - "dev": true - }, - "chalk": { - "version": "1.1.3", - "dev": true, - "requires": { - "ansi-styles": "^2.2.1", - "escape-string-regexp": "^1.0.2", - "has-ansi": "^2.0.0", - "strip-ansi": "^3.0.0", - "supports-color": "^2.0.0" - } - }, - "js-tokens": { - "version": "3.0.2", - "dev": true - }, - "strip-ansi": { - "version": "3.0.1", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "supports-color": { - "version": "2.0.0", - "dev": true - } - } - }, - "babel-core": { - "version": "6.26.3", - "dev": true, - "requires": { - "babel-code-frame": "^6.26.0", - "babel-generator": "^6.26.0", - "babel-helpers": "^6.24.1", - "babel-messages": "^6.23.0", - "babel-register": "^6.26.0", - "babel-runtime": "^6.26.0", - "babel-template": "^6.26.0", - "babel-traverse": "^6.26.0", - "babel-types": "^6.26.0", - "babylon": "^6.18.0", - "convert-source-map": "^1.5.1", - "debug": "^2.6.9", - "json5": "^0.5.1", - "lodash": "^4.17.4", - "minimatch": "^3.0.4", - "path-is-absolute": "^1.0.1", - "private": "^0.1.8", - "slash": "^1.0.0", - "source-map": "^0.5.7" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "json5": { - "version": "0.5.1", - "dev": true - }, - "ms": { - "version": "2.0.0", - "dev": true - }, - "slash": { - "version": "1.0.0", - "dev": true - } - } - }, - "babel-generator": { - "version": "6.26.1", - "dev": true, - "requires": { - "babel-messages": "^6.23.0", - "babel-runtime": "^6.26.0", - "babel-types": "^6.26.0", - "detect-indent": "^4.0.0", - "jsesc": "^1.3.0", - "lodash": "^4.17.4", - "source-map": "^0.5.7", - "trim-right": "^1.0.1" - }, - "dependencies": { - "jsesc": { - "version": "1.3.0", - "dev": true - } - } - }, - "babel-helper-builder-binary-assignment-operator-visitor": { - "version": "6.24.1", - "dev": true, - "requires": { - "babel-helper-explode-assignable-expression": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" - } - }, - "babel-helper-call-delegate": { - "version": "6.24.1", - "dev": true, - "requires": { - "babel-helper-hoist-variables": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-traverse": "^6.24.1", - "babel-types": "^6.24.1" - } - }, - "babel-helper-define-map": { - "version": "6.26.0", - "dev": true, - "requires": { - "babel-helper-function-name": "^6.24.1", - "babel-runtime": "^6.26.0", - "babel-types": "^6.26.0", - "lodash": "^4.17.4" - } - }, - "babel-helper-explode-assignable-expression": { - "version": "6.24.1", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0", - "babel-traverse": "^6.24.1", - "babel-types": "^6.24.1" - } - }, - "babel-helper-function-name": { - "version": "6.24.1", - "dev": true, - "requires": { - "babel-helper-get-function-arity": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1", - "babel-traverse": "^6.24.1", - "babel-types": "^6.24.1" - } - }, - "babel-helper-get-function-arity": { - "version": "6.24.1", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" - } - }, - "babel-helper-hoist-variables": { - "version": "6.24.1", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" - } - }, - "babel-helper-optimise-call-expression": { - "version": "6.24.1", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" - } - }, - "babel-helper-regex": { - "version": "6.26.0", - "dev": true, - "requires": { - "babel-runtime": "^6.26.0", - "babel-types": "^6.26.0", - "lodash": "^4.17.4" - } - }, - "babel-helper-remap-async-to-generator": { - "version": "6.24.1", - "dev": true, - "requires": { - "babel-helper-function-name": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1", - "babel-traverse": "^6.24.1", - "babel-types": "^6.24.1" - } - }, - "babel-helper-replace-supers": { - "version": "6.24.1", - "dev": true, - "requires": { - "babel-helper-optimise-call-expression": "^6.24.1", - "babel-messages": "^6.23.0", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1", - "babel-traverse": "^6.24.1", - "babel-types": "^6.24.1" - } - }, - "babel-helpers": { - "version": "6.24.1", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1" - } - }, - "babel-messages": { - "version": "6.23.0", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-check-es2015-constants": { - "version": "6.22.0", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-syntax-async-functions": { - "version": "6.13.0", - "dev": true - }, - "babel-plugin-syntax-exponentiation-operator": { - "version": "6.13.0", - "dev": true - }, - "babel-plugin-syntax-trailing-function-commas": { - "version": "6.22.0", - "dev": true - }, - "babel-plugin-transform-async-to-generator": { - "version": "6.24.1", - "dev": true, - "requires": { - "babel-helper-remap-async-to-generator": "^6.24.1", - "babel-plugin-syntax-async-functions": "^6.8.0", - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-transform-es2015-arrow-functions": { - "version": "6.22.0", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-transform-es2015-block-scoped-functions": { - "version": "6.22.0", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-transform-es2015-block-scoping": { - "version": "6.26.0", - "dev": true, - "requires": { - "babel-runtime": "^6.26.0", - "babel-template": "^6.26.0", - "babel-traverse": "^6.26.0", - "babel-types": "^6.26.0", - "lodash": "^4.17.4" - } - }, - "babel-plugin-transform-es2015-classes": { - "version": "6.24.1", - "dev": true, - "requires": { - "babel-helper-define-map": "^6.24.1", - "babel-helper-function-name": "^6.24.1", - "babel-helper-optimise-call-expression": "^6.24.1", - "babel-helper-replace-supers": "^6.24.1", - "babel-messages": "^6.23.0", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1", - "babel-traverse": "^6.24.1", - "babel-types": "^6.24.1" - } - }, - "babel-plugin-transform-es2015-computed-properties": { - "version": "6.24.1", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1" - } - }, - "babel-plugin-transform-es2015-destructuring": { - "version": "6.23.0", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-transform-es2015-duplicate-keys": { - "version": "6.24.1", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" - } - }, - "babel-plugin-transform-es2015-for-of": { - "version": "6.23.0", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-transform-es2015-function-name": { - "version": "6.24.1", - "dev": true, - "requires": { - "babel-helper-function-name": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" - } - }, - "babel-plugin-transform-es2015-literals": { - "version": "6.22.0", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-transform-es2015-modules-amd": { - "version": "6.24.1", - "dev": true, - "requires": { - "babel-plugin-transform-es2015-modules-commonjs": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1" - } - }, - "babel-plugin-transform-es2015-modules-commonjs": { - "version": "6.26.2", - "dev": true, - "requires": { - "babel-plugin-transform-strict-mode": "^6.24.1", - "babel-runtime": "^6.26.0", - "babel-template": "^6.26.0", - "babel-types": "^6.26.0" - } - }, - "babel-plugin-transform-es2015-modules-systemjs": { - "version": "6.24.1", - "dev": true, - "requires": { - "babel-helper-hoist-variables": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1" - } - }, - "babel-plugin-transform-es2015-modules-umd": { - "version": "6.24.1", - "dev": true, - "requires": { - "babel-plugin-transform-es2015-modules-amd": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1" - } - }, - "babel-plugin-transform-es2015-object-super": { - "version": "6.24.1", - "dev": true, - "requires": { - "babel-helper-replace-supers": "^6.24.1", - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-transform-es2015-parameters": { - "version": "6.24.1", - "dev": true, - "requires": { - "babel-helper-call-delegate": "^6.24.1", - "babel-helper-get-function-arity": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1", - "babel-traverse": "^6.24.1", - "babel-types": "^6.24.1" - } - }, - "babel-plugin-transform-es2015-shorthand-properties": { - "version": "6.24.1", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" - } - }, - "babel-plugin-transform-es2015-spread": { - "version": "6.22.0", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-transform-es2015-sticky-regex": { - "version": "6.24.1", - "dev": true, - "requires": { - "babel-helper-regex": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" - } - }, - "babel-plugin-transform-es2015-template-literals": { - "version": "6.22.0", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-transform-es2015-typeof-symbol": { - "version": "6.23.0", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-transform-es2015-unicode-regex": { - "version": "6.24.1", - "dev": true, - "requires": { - "babel-helper-regex": "^6.24.1", - "babel-runtime": "^6.22.0", - "regexpu-core": "^2.0.0" - } - }, - "babel-plugin-transform-exponentiation-operator": { - "version": "6.24.1", - "dev": true, - "requires": { - "babel-helper-builder-binary-assignment-operator-visitor": "^6.24.1", - "babel-plugin-syntax-exponentiation-operator": "^6.8.0", - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-transform-regenerator": { - "version": "6.26.0", - "dev": true, - "requires": { - "regenerator-transform": "^0.10.0" - } - }, - "babel-plugin-transform-strict-mode": { - "version": "6.24.1", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" - } - }, - "babel-preset-env": { - "version": "1.7.0", - "dev": true, - "requires": { - "babel-plugin-check-es2015-constants": "^6.22.0", - "babel-plugin-syntax-trailing-function-commas": "^6.22.0", - "babel-plugin-transform-async-to-generator": "^6.22.0", - "babel-plugin-transform-es2015-arrow-functions": "^6.22.0", - "babel-plugin-transform-es2015-block-scoped-functions": "^6.22.0", - "babel-plugin-transform-es2015-block-scoping": "^6.23.0", - "babel-plugin-transform-es2015-classes": "^6.23.0", - "babel-plugin-transform-es2015-computed-properties": "^6.22.0", - "babel-plugin-transform-es2015-destructuring": "^6.23.0", - "babel-plugin-transform-es2015-duplicate-keys": "^6.22.0", - "babel-plugin-transform-es2015-for-of": "^6.23.0", - "babel-plugin-transform-es2015-function-name": "^6.22.0", - "babel-plugin-transform-es2015-literals": "^6.22.0", - "babel-plugin-transform-es2015-modules-amd": "^6.22.0", - "babel-plugin-transform-es2015-modules-commonjs": "^6.23.0", - "babel-plugin-transform-es2015-modules-systemjs": "^6.23.0", - "babel-plugin-transform-es2015-modules-umd": "^6.23.0", - "babel-plugin-transform-es2015-object-super": "^6.22.0", - "babel-plugin-transform-es2015-parameters": "^6.23.0", - "babel-plugin-transform-es2015-shorthand-properties": "^6.22.0", - "babel-plugin-transform-es2015-spread": "^6.22.0", - "babel-plugin-transform-es2015-sticky-regex": "^6.22.0", - "babel-plugin-transform-es2015-template-literals": "^6.22.0", - "babel-plugin-transform-es2015-typeof-symbol": "^6.23.0", - "babel-plugin-transform-es2015-unicode-regex": "^6.22.0", - "babel-plugin-transform-exponentiation-operator": "^6.22.0", - "babel-plugin-transform-regenerator": "^6.22.0", - "browserslist": "^3.2.6", - "invariant": "^2.2.2", - "semver": "^5.3.0" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "dev": true - } - } - }, - "babel-register": { - "version": "6.26.0", - "dev": true, - "requires": { - "babel-core": "^6.26.0", - "babel-runtime": "^6.26.0", - "core-js": "^2.5.0", - "home-or-tmp": "^2.0.0", - "lodash": "^4.17.4", - "mkdirp": "^0.5.1", - "source-map-support": "^0.4.15" - }, - "dependencies": { - "source-map-support": { - "version": "0.4.18", - "dev": true, - "requires": { - "source-map": "^0.5.6" - } - } - } - }, - "babel-runtime": { - "version": "6.26.0", - "dev": true, - "requires": { - "core-js": "^2.4.0", - "regenerator-runtime": "^0.11.0" - } - }, - "babel-template": { - "version": "6.26.0", - "dev": true, - "requires": { - "babel-runtime": "^6.26.0", - "babel-traverse": "^6.26.0", - "babel-types": "^6.26.0", - "babylon": "^6.18.0", - "lodash": "^4.17.4" - } - }, - "babel-traverse": { - "version": "6.26.0", - "dev": true, - "requires": { - "babel-code-frame": "^6.26.0", - "babel-messages": "^6.23.0", - "babel-runtime": "^6.26.0", - "babel-types": "^6.26.0", - "babylon": "^6.18.0", - "debug": "^2.6.8", - "globals": "^9.18.0", - "invariant": "^2.2.2", - "lodash": "^4.17.4" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "globals": { - "version": "9.18.0", - "dev": true - }, - "ms": { - "version": "2.0.0", - "dev": true - } - } - }, - "babel-types": { - "version": "6.26.0", - "dev": true, - "requires": { - "babel-runtime": "^6.26.0", - "esutils": "^2.0.2", - "lodash": "^4.17.4", - "to-fast-properties": "^1.0.3" - }, - "dependencies": { - "to-fast-properties": { - "version": "1.0.3", - "dev": true - } - } - }, - "babelify": { - "version": "7.3.0", - "dev": true, - "requires": { - "babel-core": "^6.0.14", - "object-assign": "^4.0.0" - } - }, - "babylon": { - "version": "6.18.0", - "dev": true - }, - "backoff": { - "version": "2.5.0", - "dev": true, - "requires": { - "precond": "0.2" - } - }, - "balanced-match": { - "version": "1.0.0", - "dev": true - }, - "base": { - "version": "0.11.2", - "dev": true, - "requires": { - "cache-base": "^1.0.1", - "class-utils": "^0.3.5", - "component-emitter": "^1.2.1", - "define-property": "^1.0.0", - "isobject": "^3.0.1", - "mixin-deep": "^1.2.0", - "pascalcase": "^0.1.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - } - } - }, - "base-x": { - "version": "3.0.8", - "dev": true, - "requires": { - "safe-buffer": "^5.0.1" - } - }, - "base64-js": { - "version": "1.5.1", - "dev": true - }, - "bcrypt-pbkdf": { - "version": "1.0.2", - "dev": true, - "requires": { - "tweetnacl": "^0.14.3" - }, - "dependencies": { - "tweetnacl": { - "version": "0.14.5", - "dev": true - } - } - }, - "bignumber.js": { - "version": "9.0.1", - "dev": true, - "optional": true - }, - "bip39": { - "version": "2.5.0", - "dev": true, - "requires": { - "create-hash": "^1.1.0", - "pbkdf2": "^3.0.9", - "randombytes": "^2.0.1", - "safe-buffer": "^5.0.1", - "unorm": "^1.3.3" - } - }, - "blakejs": { - "version": "1.1.0", - "dev": true - }, - "bluebird": { - "version": "3.7.2", - "dev": true, - "optional": true - }, - "bn.js": { - "version": "4.11.9", - "dev": true - }, - "body-parser": { - "version": "1.19.0", - "dev": true, - "optional": true, - "requires": { - "bytes": "3.1.0", - "content-type": "~1.0.4", - "debug": "2.6.9", - "depd": "~1.1.2", - "http-errors": "1.7.2", - "iconv-lite": "0.4.24", - "on-finished": "~2.3.0", - "qs": "6.7.0", - "raw-body": "2.4.0", - "type-is": "~1.6.17" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "dev": true, - "optional": true, - "requires": { - "ms": "2.0.0" - } - }, - "ms": { - "version": "2.0.0", - "dev": true, - "optional": true - }, - "qs": { - "version": "6.7.0", - "dev": true, - "optional": true - } - } - }, - "brace-expansion": { - "version": "1.1.11", - "dev": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "brorand": { - "version": "1.1.0", - "dev": true - }, - "browserify-aes": { - "version": "1.2.0", - "dev": true, - "requires": { - "buffer-xor": "^1.0.3", - "cipher-base": "^1.0.0", - "create-hash": "^1.1.0", - "evp_bytestokey": "^1.0.3", - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "browserify-cipher": { - "version": "1.0.1", - "dev": true, - "optional": true, - "requires": { - "browserify-aes": "^1.0.4", - "browserify-des": "^1.0.0", - "evp_bytestokey": "^1.0.0" - } - }, - "browserify-des": { - "version": "1.0.2", - "dev": true, - "optional": true, - "requires": { - "cipher-base": "^1.0.1", - "des.js": "^1.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "browserify-rsa": { - "version": "4.1.0", - "dev": true, - "optional": true, - "requires": { - "bn.js": "^5.0.0", - "randombytes": "^2.0.1" - }, - "dependencies": { - "bn.js": { - "version": "5.1.3", - "dev": true, - "optional": true - } - } - }, - "browserify-sign": { - "version": "4.2.1", - "dev": true, - "optional": true, - "requires": { - "bn.js": "^5.1.1", - "browserify-rsa": "^4.0.1", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "elliptic": "^6.5.3", - "inherits": "^2.0.4", - "parse-asn1": "^5.1.5", - "readable-stream": "^3.6.0", - "safe-buffer": "^5.2.0" - }, - "dependencies": { - "bn.js": { - "version": "5.1.3", - "dev": true, - "optional": true - }, - "readable-stream": { - "version": "3.6.0", - "dev": true, - "optional": true, - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - } - } - }, - "browserslist": { - "version": "3.2.8", - "dev": true, - "requires": { - "caniuse-lite": "^1.0.30000844", - "electron-to-chromium": "^1.3.47" - } - }, - "bs58": { - "version": "4.0.1", - "dev": true, - "requires": { - "base-x": "^3.0.2" - } - }, - "bs58check": { - "version": "2.1.2", - "dev": true, - "requires": { - "bs58": "^4.0.0", - "create-hash": "^1.1.0", - "safe-buffer": "^5.1.2" - } - }, - "buffer": { - "version": "5.7.1", - "dev": true, - "requires": { - "base64-js": "^1.3.1", - "ieee754": "^1.1.13" - } - }, - "buffer-from": { - "version": "1.1.1", - "dev": true - }, - "buffer-to-arraybuffer": { - "version": "0.0.5", - "dev": true, - "optional": true - }, - "buffer-xor": { - "version": "1.0.3", - "dev": true - }, - "bufferutil": { - "version": "4.0.3", - "dev": true, - "requires": { - "node-gyp-build": "^4.2.0" - } - }, - "bytes": { - "version": "3.1.0", - "dev": true, - "optional": true - }, - "bytewise": { - "version": "1.1.0", - "dev": true, - "requires": { - "bytewise-core": "^1.2.2", - "typewise": "^1.0.3" - } - }, - "bytewise-core": { - "version": "1.2.3", - "dev": true, - "requires": { - "typewise-core": "^1.2" - } - }, - "cache-base": { - "version": "1.0.1", - "dev": true, - "requires": { - "collection-visit": "^1.0.0", - "component-emitter": "^1.2.1", - "get-value": "^2.0.6", - "has-value": "^1.0.0", - "isobject": "^3.0.1", - "set-value": "^2.0.0", - "to-object-path": "^0.3.0", - "union-value": "^1.0.0", - "unset-value": "^1.0.0" - } - }, - "cacheable-request": { - "version": "6.1.0", - "dev": true, - "optional": true, - "requires": { - "clone-response": "^1.0.2", - "get-stream": "^5.1.0", - "http-cache-semantics": "^4.0.0", - "keyv": "^3.0.0", - "lowercase-keys": "^2.0.0", - "normalize-url": "^4.1.0", - "responselike": "^1.0.2" - }, - "dependencies": { - "lowercase-keys": { - "version": "2.0.0", - "dev": true, - "optional": true - } - } - }, - "cachedown": { - "version": "1.0.0", - "dev": true, - "requires": { - "abstract-leveldown": "^2.4.1", - "lru-cache": "^3.2.0" - }, - "dependencies": { - "abstract-leveldown": { - "version": "2.7.2", - "dev": true, - "requires": { - "xtend": "~4.0.0" - } - }, - "lru-cache": { - "version": "3.2.0", - "dev": true, - "requires": { - "pseudomap": "^1.0.1" - } - } - } - }, - "call-bind": { - "version": "1.0.2", - "dev": true, - "requires": { - "function-bind": "^1.1.1", - "get-intrinsic": "^1.0.2" - } - }, - "caniuse-lite": { - "version": "1.0.30001174", - "dev": true - }, - "caseless": { - "version": "0.12.0", - "dev": true - }, - "chalk": { - "version": "2.4.2", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "checkpoint-store": { - "version": "1.1.0", - "dev": true, - "requires": { - "functional-red-black-tree": "^1.0.1" - } - }, - "chownr": { - "version": "1.1.4", - "dev": true, - "optional": true - }, - "ci-info": { - "version": "2.0.0", - "dev": true - }, - "cids": { - "version": "0.7.5", - "dev": true, - "optional": true, - "requires": { - "buffer": "^5.5.0", - "class-is": "^1.1.0", - "multibase": "~0.6.0", - "multicodec": "^1.0.0", - "multihashes": "~0.4.15" - }, - "dependencies": { - "multicodec": { - "version": "1.0.4", - "dev": true, - "optional": true, - "requires": { - "buffer": "^5.6.0", - "varint": "^5.0.0" - } - } - } - }, - "cipher-base": { - "version": "1.0.4", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "class-is": { - "version": "1.1.0", - "dev": true, - "optional": true - }, - "class-utils": { - "version": "0.3.6", - "dev": true, - "requires": { - "arr-union": "^3.1.0", - "define-property": "^0.2.5", - "isobject": "^3.0.0", - "static-extend": "^0.1.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-buffer": { - "version": "1.1.6", - "dev": true - }, - "is-data-descriptor": { - "version": "0.1.4", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - } - }, - "kind-of": { - "version": "5.1.0", - "dev": true - } - } - }, - "clone": { - "version": "2.1.2", - "dev": true - }, - "clone-response": { - "version": "1.0.2", - "dev": true, - "optional": true, - "requires": { - "mimic-response": "^1.0.0" - } - }, - "collection-visit": { - "version": "1.0.0", - "dev": true, - "requires": { - "map-visit": "^1.0.0", - "object-visit": "^1.0.0" - } - }, - "color-convert": { - "version": "1.9.3", - "dev": true, - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "dev": true - }, - "combined-stream": { - "version": "1.0.8", - "dev": true, - "requires": { - "delayed-stream": "~1.0.0" - } - }, - "component-emitter": { - "version": "1.3.0", - "dev": true - }, - "concat-map": { - "version": "0.0.1", - "dev": true - }, - "concat-stream": { - "version": "1.6.2", - "dev": true, - "requires": { - "buffer-from": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^2.2.2", - "typedarray": "^0.0.6" - } - }, - "content-disposition": { - "version": "0.5.3", - "dev": true, - "optional": true, - "requires": { - "safe-buffer": "5.1.2" - }, - "dependencies": { - "safe-buffer": { - "version": "5.1.2", - "dev": true, - "optional": true - } - } - }, - "content-hash": { - "version": "2.5.2", - "dev": true, - "optional": true, - "requires": { - "cids": "^0.7.1", - "multicodec": "^0.5.5", - "multihashes": "^0.4.15" - } - }, - "content-type": { - "version": "1.0.4", - "dev": true, - "optional": true - }, - "convert-source-map": { - "version": "1.7.0", - "dev": true, - "requires": { - "safe-buffer": "~5.1.1" - }, - "dependencies": { - "safe-buffer": { - "version": "5.1.2", - "dev": true - } - } - }, - "cookie": { - "version": "0.4.0", - "dev": true, - "optional": true - }, - "cookie-signature": { - "version": "1.0.6", - "dev": true, - "optional": true - }, - "cookiejar": { - "version": "2.1.2", - "dev": true, - "optional": true - }, - "copy-descriptor": { - "version": "0.1.1", - "dev": true - }, - "core-js": { - "version": "2.6.12", - "dev": true - }, - "core-js-pure": { - "version": "3.8.2", - "dev": true - }, - "core-util-is": { - "version": "1.0.2", - "dev": true - }, - "cors": { - "version": "2.8.5", - "dev": true, - "optional": true, - "requires": { - "object-assign": "^4", - "vary": "^1" - } - }, - "create-ecdh": { - "version": "4.0.4", - "dev": true, - "optional": true, - "requires": { - "bn.js": "^4.1.0", - "elliptic": "^6.5.3" - } - }, - "create-hash": { - "version": "1.2.0", - "dev": true, - "requires": { - "cipher-base": "^1.0.1", - "inherits": "^2.0.1", - "md5.js": "^1.3.4", - "ripemd160": "^2.0.1", - "sha.js": "^2.4.0" - } - }, - "create-hmac": { - "version": "1.1.7", - "dev": true, - "requires": { - "cipher-base": "^1.0.3", - "create-hash": "^1.1.0", - "inherits": "^2.0.1", - "ripemd160": "^2.0.0", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - } - }, - "cross-fetch": { - "version": "2.2.3", - "dev": true, - "requires": { - "node-fetch": "2.1.2", - "whatwg-fetch": "2.0.4" - } - }, - "crypto-browserify": { - "version": "3.12.0", - "dev": true, - "optional": true, - "requires": { - "browserify-cipher": "^1.0.0", - "browserify-sign": "^4.0.0", - "create-ecdh": "^4.0.0", - "create-hash": "^1.1.0", - "create-hmac": "^1.1.0", - "diffie-hellman": "^5.0.0", - "inherits": "^2.0.1", - "pbkdf2": "^3.0.3", - "public-encrypt": "^4.0.0", - "randombytes": "^2.0.0", - "randomfill": "^1.0.3" - } - }, - "d": { - "version": "1.0.1", - "dev": true, - "requires": { - "es5-ext": "^0.10.50", - "type": "^1.0.1" - } - }, - "dashdash": { - "version": "1.14.1", - "dev": true, - "requires": { - "assert-plus": "^1.0.0" - } - }, - "debug": { - "version": "3.2.6", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "decode-uri-component": { - "version": "0.2.0", - "dev": true - }, - "decompress-response": { - "version": "3.3.0", - "dev": true, - "optional": true, - "requires": { - "mimic-response": "^1.0.0" - } - }, - "deep-equal": { - "version": "1.1.1", - "dev": true, - "requires": { - "is-arguments": "^1.0.4", - "is-date-object": "^1.0.1", - "is-regex": "^1.0.4", - "object-is": "^1.0.1", - "object-keys": "^1.1.1", - "regexp.prototype.flags": "^1.2.0" - } - }, - "defer-to-connect": { - "version": "1.1.3", - "dev": true, - "optional": true - }, - "deferred-leveldown": { - "version": "4.0.2", - "dev": true, - "requires": { - "abstract-leveldown": "~5.0.0", - "inherits": "^2.0.3" - }, - "dependencies": { - "abstract-leveldown": { - "version": "5.0.0", - "dev": true, - "requires": { - "xtend": "~4.0.0" - } - } - } - }, - "define-properties": { - "version": "1.1.3", - "dev": true, - "requires": { - "object-keys": "^1.0.12" - } - }, - "define-property": { - "version": "2.0.2", - "dev": true, - "requires": { - "is-descriptor": "^1.0.2", - "isobject": "^3.0.1" - } - }, - "defined": { - "version": "1.0.0", - "dev": true - }, - "delayed-stream": { - "version": "1.0.0", - "dev": true - }, - "depd": { - "version": "1.1.2", - "dev": true, - "optional": true - }, - "des.js": { - "version": "1.0.1", - "dev": true, - "optional": true, - "requires": { - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0" - } - }, - "destroy": { - "version": "1.0.4", - "dev": true, - "optional": true - }, - "detect-indent": { - "version": "4.0.0", - "dev": true, - "requires": { - "repeating": "^2.0.0" - } - }, - "diffie-hellman": { - "version": "5.0.3", - "dev": true, - "optional": true, - "requires": { - "bn.js": "^4.1.0", - "miller-rabin": "^4.0.0", - "randombytes": "^2.0.0" - } - }, - "dom-walk": { - "version": "0.1.2", - "dev": true - }, - "dotignore": { - "version": "0.1.2", - "dev": true, - "requires": { - "minimatch": "^3.0.4" - } - }, - "duplexer3": { - "version": "0.1.4", - "dev": true, - "optional": true - }, - "ecc-jsbn": { - "version": "0.1.2", - "dev": true, - "requires": { - "jsbn": "~0.1.0", - "safer-buffer": "^2.1.0" - } - }, - "ee-first": { - "version": "1.1.1", - "dev": true, - "optional": true - }, - "electron-to-chromium": { - "version": "1.3.636", - "dev": true - }, - "elliptic": { - "version": "6.5.3", - "dev": true, - "requires": { - "bn.js": "^4.4.0", - "brorand": "^1.0.1", - "hash.js": "^1.0.0", - "hmac-drbg": "^1.0.0", - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0", - "minimalistic-crypto-utils": "^1.0.0" - } - }, - "encodeurl": { - "version": "1.0.2", - "dev": true, - "optional": true - }, - "encoding": { - "version": "0.1.13", - "dev": true, - "requires": { - "iconv-lite": "^0.6.2" - }, - "dependencies": { - "iconv-lite": { - "version": "0.6.2", - "dev": true, - "requires": { - "safer-buffer": ">= 2.1.2 < 3.0.0" - } - } - } - }, - "encoding-down": { - "version": "5.0.4", - "dev": true, - "requires": { - "abstract-leveldown": "^5.0.0", - "inherits": "^2.0.3", - "level-codec": "^9.0.0", - "level-errors": "^2.0.0", - "xtend": "^4.0.1" - }, - "dependencies": { - "abstract-leveldown": { - "version": "5.0.0", - "dev": true, - "requires": { - "xtend": "~4.0.0" - } - } - } - }, - "end-of-stream": { - "version": "1.4.4", - "dev": true, - "requires": { - "once": "^1.4.0" - } - }, - "errno": { - "version": "0.1.8", - "dev": true, - "requires": { - "prr": "~1.0.1" - } - }, - "es-abstract": { - "version": "1.18.0-next.1", - "dev": true, - "requires": { - "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1", - "is-callable": "^1.2.2", - "is-negative-zero": "^2.0.0", - "is-regex": "^1.1.1", - "object-inspect": "^1.8.0", - "object-keys": "^1.1.1", - "object.assign": "^4.1.1", - "string.prototype.trimend": "^1.0.1", - "string.prototype.trimstart": "^1.0.1" - } - }, - "es-to-primitive": { - "version": "1.2.1", - "dev": true, - "requires": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" - } - }, - "es5-ext": { - "version": "0.10.53", - "dev": true, - "requires": { - "es6-iterator": "~2.0.3", - "es6-symbol": "~3.1.3", - "next-tick": "~1.0.0" - } - }, - "es6-iterator": { - "version": "2.0.3", - "dev": true, - "requires": { - "d": "1", - "es5-ext": "^0.10.35", - "es6-symbol": "^3.1.1" - } - }, - "es6-symbol": { - "version": "3.1.3", - "dev": true, - "requires": { - "d": "^1.0.1", - "ext": "^1.1.2" - } - }, - "escape-html": { - "version": "1.0.3", - "dev": true, - "optional": true - }, - "escape-string-regexp": { - "version": "1.0.5", - "dev": true - }, - "esutils": { - "version": "2.0.3", - "dev": true - }, - "etag": { - "version": "1.8.1", - "dev": true, - "optional": true - }, - "eth-block-tracker": { - "version": "3.0.1", - "dev": true, - "requires": { - "eth-query": "^2.1.0", - "ethereumjs-tx": "^1.3.3", - "ethereumjs-util": "^5.1.3", - "ethjs-util": "^0.1.3", - "json-rpc-engine": "^3.6.0", - "pify": "^2.3.0", - "tape": "^4.6.3" - }, - "dependencies": { - "ethereumjs-tx": { - "version": "1.3.7", - "dev": true, - "requires": { - "ethereum-common": "^0.0.18", - "ethereumjs-util": "^5.0.0" - } - }, - "ethereumjs-util": { - "version": "5.2.1", - "dev": true, - "requires": { - "bn.js": "^4.11.0", - "create-hash": "^1.1.2", - "elliptic": "^6.5.2", - "ethereum-cryptography": "^0.1.3", - "ethjs-util": "^0.1.3", - "rlp": "^2.0.0", - "safe-buffer": "^5.1.1" - } - }, - "pify": { - "version": "2.3.0", - "dev": true - } - } - }, - "eth-ens-namehash": { - "version": "2.0.8", - "dev": true, - "optional": true, - "requires": { - "idna-uts46-hx": "^2.3.1", - "js-sha3": "^0.5.7" - } - }, - "eth-json-rpc-infura": { - "version": "3.2.1", - "dev": true, - "requires": { - "cross-fetch": "^2.1.1", - "eth-json-rpc-middleware": "^1.5.0", - "json-rpc-engine": "^3.4.0", - "json-rpc-error": "^2.0.0" - } - }, - "eth-json-rpc-middleware": { - "version": "1.6.0", - "dev": true, - "requires": { - "async": "^2.5.0", - "eth-query": "^2.1.2", - "eth-tx-summary": "^3.1.2", - "ethereumjs-block": "^1.6.0", - "ethereumjs-tx": "^1.3.3", - "ethereumjs-util": "^5.1.2", - "ethereumjs-vm": "^2.1.0", - "fetch-ponyfill": "^4.0.0", - "json-rpc-engine": "^3.6.0", - "json-rpc-error": "^2.0.0", - "json-stable-stringify": "^1.0.1", - "promise-to-callback": "^1.0.0", - "tape": "^4.6.3" - }, - "dependencies": { - "abstract-leveldown": { - "version": "2.6.3", - "dev": true, - "requires": { - "xtend": "~4.0.0" - } - }, - "deferred-leveldown": { - "version": "1.2.2", - "dev": true, - "requires": { - "abstract-leveldown": "~2.6.0" - } - }, - "ethereumjs-account": { - "version": "2.0.5", - "dev": true, - "requires": { - "ethereumjs-util": "^5.0.0", - "rlp": "^2.0.0", - "safe-buffer": "^5.1.1" - } - }, - "ethereumjs-block": { - "version": "1.7.1", - "dev": true, - "requires": { - "async": "^2.0.1", - "ethereum-common": "0.2.0", - "ethereumjs-tx": "^1.2.2", - "ethereumjs-util": "^5.0.0", - "merkle-patricia-tree": "^2.1.2" - }, - "dependencies": { - "ethereum-common": { - "version": "0.2.0", - "dev": true - } - } - }, - "ethereumjs-tx": { - "version": "1.3.7", - "dev": true, - "requires": { - "ethereum-common": "^0.0.18", - "ethereumjs-util": "^5.0.0" - } - }, - "ethereumjs-util": { - "version": "5.2.1", - "dev": true, - "requires": { - "bn.js": "^4.11.0", - "create-hash": "^1.1.2", - "elliptic": "^6.5.2", - "ethereum-cryptography": "^0.1.3", - "ethjs-util": "^0.1.3", - "rlp": "^2.0.0", - "safe-buffer": "^5.1.1" - } - }, - "ethereumjs-vm": { - "version": "2.6.0", - "dev": true, - "requires": { - "async": "^2.1.2", - "async-eventemitter": "^0.2.2", - "ethereumjs-account": "^2.0.3", - "ethereumjs-block": "~2.2.0", - "ethereumjs-common": "^1.1.0", - "ethereumjs-util": "^6.0.0", - "fake-merkle-patricia-tree": "^1.0.1", - "functional-red-black-tree": "^1.0.1", - "merkle-patricia-tree": "^2.3.2", - "rustbn.js": "~0.2.0", - "safe-buffer": "^5.1.1" - }, - "dependencies": { - "ethereumjs-block": { - "version": "2.2.2", - "dev": true, - "requires": { - "async": "^2.0.1", - "ethereumjs-common": "^1.5.0", - "ethereumjs-tx": "^2.1.1", - "ethereumjs-util": "^5.0.0", - "merkle-patricia-tree": "^2.1.2" - }, - "dependencies": { - "ethereumjs-util": { - "version": "5.2.1", - "dev": true, - "requires": { - "bn.js": "^4.11.0", - "create-hash": "^1.1.2", - "elliptic": "^6.5.2", - "ethereum-cryptography": "^0.1.3", - "ethjs-util": "^0.1.3", - "rlp": "^2.0.0", - "safe-buffer": "^5.1.1" - } - } - } - }, - "ethereumjs-tx": { - "version": "2.1.2", - "dev": true, - "requires": { - "ethereumjs-common": "^1.5.0", - "ethereumjs-util": "^6.0.0" - } - }, - "ethereumjs-util": { - "version": "6.2.1", - "dev": true, - "requires": { - "@types/bn.js": "^4.11.3", - "bn.js": "^4.11.0", - "create-hash": "^1.1.2", - "elliptic": "^6.5.2", - "ethereum-cryptography": "^0.1.3", - "ethjs-util": "0.1.6", - "rlp": "^2.2.3" - } - } - } - }, - "isarray": { - "version": "0.0.1", - "dev": true - }, - "level-codec": { - "version": "7.0.1", - "dev": true - }, - "level-errors": { - "version": "1.0.5", - "dev": true, - "requires": { - "errno": "~0.1.1" - } - }, - "level-iterator-stream": { - "version": "1.3.1", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "level-errors": "^1.0.3", - "readable-stream": "^1.0.33", - "xtend": "^4.0.0" - }, - "dependencies": { - "readable-stream": { - "version": "1.1.14", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "0.0.1", - "string_decoder": "~0.10.x" - } - } - } - }, - "level-ws": { - "version": "0.0.0", - "dev": true, - "requires": { - "readable-stream": "~1.0.15", - "xtend": "~2.1.1" - }, - "dependencies": { - "readable-stream": { - "version": "1.0.34", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "0.0.1", - "string_decoder": "~0.10.x" - } - }, - "xtend": { - "version": "2.1.2", - "dev": true, - "requires": { - "object-keys": "~0.4.0" - } - } - } - }, - "levelup": { - "version": "1.3.9", - "dev": true, - "requires": { - "deferred-leveldown": "~1.2.1", - "level-codec": "~7.0.0", - "level-errors": "~1.0.3", - "level-iterator-stream": "~1.3.0", - "prr": "~1.0.1", - "semver": "~5.4.1", - "xtend": "~4.0.0" - } - }, - "ltgt": { - "version": "2.2.1", - "dev": true - }, - "memdown": { - "version": "1.4.1", - "dev": true, - "requires": { - "abstract-leveldown": "~2.7.1", - "functional-red-black-tree": "^1.0.1", - "immediate": "^3.2.3", - "inherits": "~2.0.1", - "ltgt": "~2.2.0", - "safe-buffer": "~5.1.1" - }, - "dependencies": { - "abstract-leveldown": { - "version": "2.7.2", - "dev": true, - "requires": { - "xtend": "~4.0.0" - } - } - } - }, - "merkle-patricia-tree": { - "version": "2.3.2", - "dev": true, - "requires": { - "async": "^1.4.2", - "ethereumjs-util": "^5.0.0", - "level-ws": "0.0.0", - "levelup": "^1.2.1", - "memdown": "^1.0.0", - "readable-stream": "^2.0.0", - "rlp": "^2.0.0", - "semaphore": ">=1.0.1" - }, - "dependencies": { - "async": { - "version": "1.5.2", - "dev": true - } - } - }, - "object-keys": { - "version": "0.4.0", - "dev": true - }, - "safe-buffer": { - "version": "5.1.2", - "dev": true - }, - "semver": { - "version": "5.4.1", - "dev": true - }, - "string_decoder": { - "version": "0.10.31", - "dev": true - } - } - }, - "eth-lib": { - "version": "0.1.29", - "dev": true, - "optional": true, - "requires": { - "bn.js": "^4.11.6", - "elliptic": "^6.4.0", - "nano-json-stream-parser": "^0.1.2", - "servify": "^0.1.12", - "ws": "^3.0.0", - "xhr-request-promise": "^0.1.2" - } - }, - "eth-query": { - "version": "2.1.2", - "dev": true, - "requires": { - "json-rpc-random-id": "^1.0.0", - "xtend": "^4.0.1" - } - }, - "eth-sig-util": { - "version": "3.0.0", - "dev": true, - "requires": { - "buffer": "^5.2.1", - "elliptic": "^6.4.0", - "ethereumjs-abi": "0.6.5", - "ethereumjs-util": "^5.1.1", - "tweetnacl": "^1.0.0", - "tweetnacl-util": "^0.15.0" - }, - "dependencies": { - "ethereumjs-abi": { - "version": "0.6.5", - "dev": true, - "requires": { - "bn.js": "^4.10.0", - "ethereumjs-util": "^4.3.0" - }, - "dependencies": { - "ethereumjs-util": { - "version": "4.5.1", - "dev": true, - "requires": { - "bn.js": "^4.8.0", - "create-hash": "^1.1.2", - "elliptic": "^6.5.2", - "ethereum-cryptography": "^0.1.3", - "rlp": "^2.0.0" - } - } - } - }, - "ethereumjs-util": { - "version": "5.2.1", - "dev": true, - "requires": { - "bn.js": "^4.11.0", - "create-hash": "^1.1.2", - "elliptic": "^6.5.2", - "ethereum-cryptography": "^0.1.3", - "ethjs-util": "^0.1.3", - "rlp": "^2.0.0", - "safe-buffer": "^5.1.1" - } - } - } - }, - "eth-tx-summary": { - "version": "3.2.4", - "dev": true, - "requires": { - "async": "^2.1.2", - "clone": "^2.0.0", - "concat-stream": "^1.5.1", - "end-of-stream": "^1.1.0", - "eth-query": "^2.0.2", - "ethereumjs-block": "^1.4.1", - "ethereumjs-tx": "^1.1.1", - "ethereumjs-util": "^5.0.1", - "ethereumjs-vm": "^2.6.0", - "through2": "^2.0.3" - }, - "dependencies": { - "abstract-leveldown": { - "version": "2.6.3", - "dev": true, - "requires": { - "xtend": "~4.0.0" - } - }, - "deferred-leveldown": { - "version": "1.2.2", - "dev": true, - "requires": { - "abstract-leveldown": "~2.6.0" - } - }, - "ethereumjs-account": { - "version": "2.0.5", - "dev": true, - "requires": { - "ethereumjs-util": "^5.0.0", - "rlp": "^2.0.0", - "safe-buffer": "^5.1.1" - } - }, - "ethereumjs-block": { - "version": "1.7.1", - "dev": true, - "requires": { - "async": "^2.0.1", - "ethereum-common": "0.2.0", - "ethereumjs-tx": "^1.2.2", - "ethereumjs-util": "^5.0.0", - "merkle-patricia-tree": "^2.1.2" - }, - "dependencies": { - "ethereum-common": { - "version": "0.2.0", - "dev": true - } - } - }, - "ethereumjs-tx": { - "version": "1.3.7", - "dev": true, - "requires": { - "ethereum-common": "^0.0.18", - "ethereumjs-util": "^5.0.0" - } - }, - "ethereumjs-util": { - "version": "5.2.1", - "dev": true, - "requires": { - "bn.js": "^4.11.0", - "create-hash": "^1.1.2", - "elliptic": "^6.5.2", - "ethereum-cryptography": "^0.1.3", - "ethjs-util": "^0.1.3", - "rlp": "^2.0.0", - "safe-buffer": "^5.1.1" - } - }, - "ethereumjs-vm": { - "version": "2.6.0", - "dev": true, - "requires": { - "async": "^2.1.2", - "async-eventemitter": "^0.2.2", - "ethereumjs-account": "^2.0.3", - "ethereumjs-block": "~2.2.0", - "ethereumjs-common": "^1.1.0", - "ethereumjs-util": "^6.0.0", - "fake-merkle-patricia-tree": "^1.0.1", - "functional-red-black-tree": "^1.0.1", - "merkle-patricia-tree": "^2.3.2", - "rustbn.js": "~0.2.0", - "safe-buffer": "^5.1.1" - }, - "dependencies": { - "ethereumjs-block": { - "version": "2.2.2", - "dev": true, - "requires": { - "async": "^2.0.1", - "ethereumjs-common": "^1.5.0", - "ethereumjs-tx": "^2.1.1", - "ethereumjs-util": "^5.0.0", - "merkle-patricia-tree": "^2.1.2" - }, - "dependencies": { - "ethereumjs-util": { - "version": "5.2.1", - "dev": true, - "requires": { - "bn.js": "^4.11.0", - "create-hash": "^1.1.2", - "elliptic": "^6.5.2", - "ethereum-cryptography": "^0.1.3", - "ethjs-util": "^0.1.3", - "rlp": "^2.0.0", - "safe-buffer": "^5.1.1" - } - } - } - }, - "ethereumjs-tx": { - "version": "2.1.2", - "dev": true, - "requires": { - "ethereumjs-common": "^1.5.0", - "ethereumjs-util": "^6.0.0" - } - }, - "ethereumjs-util": { - "version": "6.2.1", - "dev": true, - "requires": { - "@types/bn.js": "^4.11.3", - "bn.js": "^4.11.0", - "create-hash": "^1.1.2", - "elliptic": "^6.5.2", - "ethereum-cryptography": "^0.1.3", - "ethjs-util": "0.1.6", - "rlp": "^2.2.3" - } - } - } - }, - "isarray": { - "version": "0.0.1", - "dev": true - }, - "level-codec": { - "version": "7.0.1", - "dev": true - }, - "level-errors": { - "version": "1.0.5", - "dev": true, - "requires": { - "errno": "~0.1.1" - } - }, - "level-iterator-stream": { - "version": "1.3.1", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "level-errors": "^1.0.3", - "readable-stream": "^1.0.33", - "xtend": "^4.0.0" - }, - "dependencies": { - "readable-stream": { - "version": "1.1.14", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "0.0.1", - "string_decoder": "~0.10.x" - } - } - } - }, - "level-ws": { - "version": "0.0.0", - "dev": true, - "requires": { - "readable-stream": "~1.0.15", - "xtend": "~2.1.1" - }, - "dependencies": { - "readable-stream": { - "version": "1.0.34", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "0.0.1", - "string_decoder": "~0.10.x" - } - }, - "xtend": { - "version": "2.1.2", - "dev": true, - "requires": { - "object-keys": "~0.4.0" - } - } - } - }, - "levelup": { - "version": "1.3.9", - "dev": true, - "requires": { - "deferred-leveldown": "~1.2.1", - "level-codec": "~7.0.0", - "level-errors": "~1.0.3", - "level-iterator-stream": "~1.3.0", - "prr": "~1.0.1", - "semver": "~5.4.1", - "xtend": "~4.0.0" - } - }, - "ltgt": { - "version": "2.2.1", - "dev": true - }, - "memdown": { - "version": "1.4.1", - "dev": true, - "requires": { - "abstract-leveldown": "~2.7.1", - "functional-red-black-tree": "^1.0.1", - "immediate": "^3.2.3", - "inherits": "~2.0.1", - "ltgt": "~2.2.0", - "safe-buffer": "~5.1.1" - }, - "dependencies": { - "abstract-leveldown": { - "version": "2.7.2", - "dev": true, - "requires": { - "xtend": "~4.0.0" - } - } - } - }, - "merkle-patricia-tree": { - "version": "2.3.2", - "dev": true, - "requires": { - "async": "^1.4.2", - "ethereumjs-util": "^5.0.0", - "level-ws": "0.0.0", - "levelup": "^1.2.1", - "memdown": "^1.0.0", - "readable-stream": "^2.0.0", - "rlp": "^2.0.0", - "semaphore": ">=1.0.1" - }, - "dependencies": { - "async": { - "version": "1.5.2", - "dev": true - } - } - }, - "object-keys": { - "version": "0.4.0", - "dev": true - }, - "safe-buffer": { - "version": "5.1.2", - "dev": true - }, - "semver": { - "version": "5.4.1", - "dev": true - }, - "string_decoder": { - "version": "0.10.31", - "dev": true - } - } - }, - "ethashjs": { - "version": "0.0.8", - "dev": true, - "requires": { - "async": "^2.1.2", - "buffer-xor": "^2.0.1", - "ethereumjs-util": "^7.0.2", - "miller-rabin": "^4.0.0" - }, - "dependencies": { - "bn.js": { - "version": "5.1.3", - "dev": true - }, - "buffer-xor": { - "version": "2.0.2", - "dev": true, - "requires": { - "safe-buffer": "^5.1.1" - } - }, - "ethereumjs-util": { - "version": "7.0.7", - "dev": true, - "requires": { - "@types/bn.js": "^4.11.3", - "bn.js": "^5.1.2", - "create-hash": "^1.1.2", - "ethereum-cryptography": "^0.1.3", - "ethjs-util": "0.1.6", - "rlp": "^2.2.4" - } - } - } - }, - "ethereum-bloom-filters": { - "version": "1.0.7", - "dev": true, - "optional": true, - "requires": { - "js-sha3": "^0.8.0" - }, - "dependencies": { - "js-sha3": { - "version": "0.8.0", - "dev": true, - "optional": true - } - } - }, - "ethereum-common": { - "version": "0.0.18", - "dev": true - }, - "ethereum-cryptography": { - "version": "0.1.3", - "dev": true, - "requires": { - "@types/pbkdf2": "^3.0.0", - "@types/secp256k1": "^4.0.1", - "blakejs": "^1.1.0", - "browserify-aes": "^1.2.0", - "bs58check": "^2.1.2", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "hash.js": "^1.1.7", - "keccak": "^3.0.0", - "pbkdf2": "^3.0.17", - "randombytes": "^2.1.0", - "safe-buffer": "^5.1.2", - "scrypt-js": "^3.0.0", - "secp256k1": "^4.0.1", - "setimmediate": "^1.0.5" - } - }, - "ethereumjs-abi": { - "version": "0.6.8", - "dev": true, - "requires": { - "bn.js": "^4.11.8", - "ethereumjs-util": "^6.0.0" - } - }, - "ethereumjs-account": { - "version": "3.0.0", - "dev": true, - "requires": { - "ethereumjs-util": "^6.0.0", - "rlp": "^2.2.1", - "safe-buffer": "^5.1.1" - } - }, - "ethereumjs-block": { - "version": "2.2.2", - "dev": true, - "requires": { - "async": "^2.0.1", - "ethereumjs-common": "^1.5.0", - "ethereumjs-tx": "^2.1.1", - "ethereumjs-util": "^5.0.0", - "merkle-patricia-tree": "^2.1.2" - }, - "dependencies": { - "abstract-leveldown": { - "version": "2.6.3", - "dev": true, - "requires": { - "xtend": "~4.0.0" - } - }, - "deferred-leveldown": { - "version": "1.2.2", - "dev": true, - "requires": { - "abstract-leveldown": "~2.6.0" - } - }, - "ethereumjs-util": { - "version": "5.2.1", - "dev": true, - "requires": { - "bn.js": "^4.11.0", - "create-hash": "^1.1.2", - "elliptic": "^6.5.2", - "ethereum-cryptography": "^0.1.3", - "ethjs-util": "^0.1.3", - "rlp": "^2.0.0", - "safe-buffer": "^5.1.1" - } - }, - "isarray": { - "version": "0.0.1", - "dev": true - }, - "level-codec": { - "version": "7.0.1", - "dev": true - }, - "level-errors": { - "version": "1.0.5", - "dev": true, - "requires": { - "errno": "~0.1.1" - } - }, - "level-iterator-stream": { - "version": "1.3.1", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "level-errors": "^1.0.3", - "readable-stream": "^1.0.33", - "xtend": "^4.0.0" - }, - "dependencies": { - "readable-stream": { - "version": "1.1.14", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "0.0.1", - "string_decoder": "~0.10.x" - } - } - } - }, - "level-ws": { - "version": "0.0.0", - "dev": true, - "requires": { - "readable-stream": "~1.0.15", - "xtend": "~2.1.1" - }, - "dependencies": { - "readable-stream": { - "version": "1.0.34", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "0.0.1", - "string_decoder": "~0.10.x" - } - }, - "xtend": { - "version": "2.1.2", - "dev": true, - "requires": { - "object-keys": "~0.4.0" - } - } - } - }, - "levelup": { - "version": "1.3.9", - "dev": true, - "requires": { - "deferred-leveldown": "~1.2.1", - "level-codec": "~7.0.0", - "level-errors": "~1.0.3", - "level-iterator-stream": "~1.3.0", - "prr": "~1.0.1", - "semver": "~5.4.1", - "xtend": "~4.0.0" - } - }, - "ltgt": { - "version": "2.2.1", - "dev": true - }, - "memdown": { - "version": "1.4.1", - "dev": true, - "requires": { - "abstract-leveldown": "~2.7.1", - "functional-red-black-tree": "^1.0.1", - "immediate": "^3.2.3", - "inherits": "~2.0.1", - "ltgt": "~2.2.0", - "safe-buffer": "~5.1.1" - }, - "dependencies": { - "abstract-leveldown": { - "version": "2.7.2", - "dev": true, - "requires": { - "xtend": "~4.0.0" - } - } - } - }, - "merkle-patricia-tree": { - "version": "2.3.2", - "dev": true, - "requires": { - "async": "^1.4.2", - "ethereumjs-util": "^5.0.0", - "level-ws": "0.0.0", - "levelup": "^1.2.1", - "memdown": "^1.0.0", - "readable-stream": "^2.0.0", - "rlp": "^2.0.0", - "semaphore": ">=1.0.1" - }, - "dependencies": { - "async": { - "version": "1.5.2", - "dev": true - } - } - }, - "object-keys": { - "version": "0.4.0", - "dev": true - }, - "safe-buffer": { - "version": "5.1.2", - "dev": true - }, - "semver": { - "version": "5.4.1", - "dev": true - }, - "string_decoder": { - "version": "0.10.31", - "dev": true - } - } - }, - "ethereumjs-blockchain": { - "version": "4.0.4", - "dev": true, - "requires": { - "async": "^2.6.1", - "ethashjs": "~0.0.7", - "ethereumjs-block": "~2.2.2", - "ethereumjs-common": "^1.5.0", - "ethereumjs-util": "^6.1.0", - "flow-stoplight": "^1.0.0", - "level-mem": "^3.0.1", - "lru-cache": "^5.1.1", - "rlp": "^2.2.2", - "semaphore": "^1.1.0" - } - }, - "ethereumjs-common": { - "version": "1.5.0", - "dev": true - }, - "ethereumjs-tx": { - "version": "2.1.2", - "dev": true, - "requires": { - "ethereumjs-common": "^1.5.0", - "ethereumjs-util": "^6.0.0" - } - }, - "ethereumjs-util": { - "version": "6.2.1", - "dev": true, - "requires": { - "@types/bn.js": "^4.11.3", - "bn.js": "^4.11.0", - "create-hash": "^1.1.2", - "elliptic": "^6.5.2", - "ethereum-cryptography": "^0.1.3", - "ethjs-util": "0.1.6", - "rlp": "^2.2.3" - } - }, - "ethereumjs-vm": { - "version": "4.2.0", - "dev": true, - "requires": { - "async": "^2.1.2", - "async-eventemitter": "^0.2.2", - "core-js-pure": "^3.0.1", - "ethereumjs-account": "^3.0.0", - "ethereumjs-block": "^2.2.2", - "ethereumjs-blockchain": "^4.0.3", - "ethereumjs-common": "^1.5.0", - "ethereumjs-tx": "^2.1.2", - "ethereumjs-util": "^6.2.0", - "fake-merkle-patricia-tree": "^1.0.1", - "functional-red-black-tree": "^1.0.1", - "merkle-patricia-tree": "^2.3.2", - "rustbn.js": "~0.2.0", - "safe-buffer": "^5.1.1", - "util.promisify": "^1.0.0" - }, - "dependencies": { - "abstract-leveldown": { - "version": "2.6.3", - "dev": true, - "requires": { - "xtend": "~4.0.0" - } - }, - "deferred-leveldown": { - "version": "1.2.2", - "dev": true, - "requires": { - "abstract-leveldown": "~2.6.0" - } - }, - "isarray": { - "version": "0.0.1", - "dev": true - }, - "level-codec": { - "version": "7.0.1", - "dev": true - }, - "level-errors": { - "version": "1.0.5", - "dev": true, - "requires": { - "errno": "~0.1.1" - } - }, - "level-iterator-stream": { - "version": "1.3.1", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "level-errors": "^1.0.3", - "readable-stream": "^1.0.33", - "xtend": "^4.0.0" - }, - "dependencies": { - "readable-stream": { - "version": "1.1.14", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "0.0.1", - "string_decoder": "~0.10.x" - } - } - } - }, - "level-ws": { - "version": "0.0.0", - "dev": true, - "requires": { - "readable-stream": "~1.0.15", - "xtend": "~2.1.1" - }, - "dependencies": { - "readable-stream": { - "version": "1.0.34", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "0.0.1", - "string_decoder": "~0.10.x" - } - }, - "xtend": { - "version": "2.1.2", - "dev": true, - "requires": { - "object-keys": "~0.4.0" - } - } - } - }, - "levelup": { - "version": "1.3.9", - "dev": true, - "requires": { - "deferred-leveldown": "~1.2.1", - "level-codec": "~7.0.0", - "level-errors": "~1.0.3", - "level-iterator-stream": "~1.3.0", - "prr": "~1.0.1", - "semver": "~5.4.1", - "xtend": "~4.0.0" - } - }, - "ltgt": { - "version": "2.2.1", - "dev": true - }, - "memdown": { - "version": "1.4.1", - "dev": true, - "requires": { - "abstract-leveldown": "~2.7.1", - "functional-red-black-tree": "^1.0.1", - "immediate": "^3.2.3", - "inherits": "~2.0.1", - "ltgt": "~2.2.0", - "safe-buffer": "~5.1.1" - }, - "dependencies": { - "abstract-leveldown": { - "version": "2.7.2", - "dev": true, - "requires": { - "xtend": "~4.0.0" - } - } - } - }, - "merkle-patricia-tree": { - "version": "2.3.2", - "dev": true, - "requires": { - "async": "^1.4.2", - "ethereumjs-util": "^5.0.0", - "level-ws": "0.0.0", - "levelup": "^1.2.1", - "memdown": "^1.0.0", - "readable-stream": "^2.0.0", - "rlp": "^2.0.0", - "semaphore": ">=1.0.1" - }, - "dependencies": { - "async": { - "version": "1.5.2", - "dev": true - }, - "ethereumjs-util": { - "version": "5.2.1", - "dev": true, - "requires": { - "bn.js": "^4.11.0", - "create-hash": "^1.1.2", - "elliptic": "^6.5.2", - "ethereum-cryptography": "^0.1.3", - "ethjs-util": "^0.1.3", - "rlp": "^2.0.0", - "safe-buffer": "^5.1.1" - } - } - } - }, - "object-keys": { - "version": "0.4.0", - "dev": true - }, - "safe-buffer": { - "version": "5.1.2", - "dev": true - }, - "semver": { - "version": "5.4.1", - "dev": true - }, - "string_decoder": { - "version": "0.10.31", - "dev": true - } - } - }, - "ethereumjs-wallet": { - "version": "0.6.5", - "dev": true, - "optional": true, - "requires": { - "aes-js": "^3.1.1", - "bs58check": "^2.1.2", - "ethereum-cryptography": "^0.1.3", - "ethereumjs-util": "^6.0.0", - "randombytes": "^2.0.6", - "safe-buffer": "^5.1.2", - "scryptsy": "^1.2.1", - "utf8": "^3.0.0", - "uuid": "^3.3.2" - } - }, - "ethjs-unit": { - "version": "0.1.6", - "dev": true, - "optional": true, - "requires": { - "bn.js": "4.11.6", - "number-to-bn": "1.7.0" - }, - "dependencies": { - "bn.js": { - "version": "4.11.6", - "dev": true, - "optional": true - } - } - }, - "ethjs-util": { - "version": "0.1.6", - "dev": true, - "requires": { - "is-hex-prefixed": "1.0.0", - "strip-hex-prefix": "1.0.0" - } - }, - "eventemitter3": { - "version": "4.0.4", - "dev": true, - "optional": true - }, - "events": { - "version": "3.2.0", - "dev": true - }, - "evp_bytestokey": { - "version": "1.0.3", - "dev": true, - "requires": { - "md5.js": "^1.3.4", - "safe-buffer": "^5.1.1" - } - }, - "expand-brackets": { - "version": "2.1.4", - "dev": true, - "requires": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "define-property": { - "version": "0.2.5", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-buffer": { - "version": "1.1.6", - "dev": true - }, - "is-data-descriptor": { - "version": "0.1.4", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - } - }, - "is-extendable": { - "version": "0.1.1", - "dev": true - }, - "kind-of": { - "version": "5.1.0", - "dev": true - }, - "ms": { - "version": "2.0.0", - "dev": true - } - } - }, - "express": { - "version": "4.17.1", - "dev": true, - "optional": true, - "requires": { - "accepts": "~1.3.7", - "array-flatten": "1.1.1", - "body-parser": "1.19.0", - "content-disposition": "0.5.3", - "content-type": "~1.0.4", - "cookie": "0.4.0", - "cookie-signature": "1.0.6", - "debug": "2.6.9", - "depd": "~1.1.2", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "finalhandler": "~1.1.2", - "fresh": "0.5.2", - "merge-descriptors": "1.0.1", - "methods": "~1.1.2", - "on-finished": "~2.3.0", - "parseurl": "~1.3.3", - "path-to-regexp": "0.1.7", - "proxy-addr": "~2.0.5", - "qs": "6.7.0", - "range-parser": "~1.2.1", - "safe-buffer": "5.1.2", - "send": "0.17.1", - "serve-static": "1.14.1", - "setprototypeof": "1.1.1", - "statuses": "~1.5.0", - "type-is": "~1.6.18", - "utils-merge": "1.0.1", - "vary": "~1.1.2" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "dev": true, - "optional": true, - "requires": { - "ms": "2.0.0" - } - }, - "ms": { - "version": "2.0.0", - "dev": true, - "optional": true - }, - "qs": { - "version": "6.7.0", - "dev": true, - "optional": true - }, - "safe-buffer": { - "version": "5.1.2", - "dev": true, - "optional": true - } - } - }, - "ext": { - "version": "1.4.0", - "dev": true, - "requires": { - "type": "^2.0.0" - }, - "dependencies": { - "type": { - "version": "2.1.0", - "dev": true - } - } - }, - "extend": { - "version": "3.0.2", - "dev": true - }, - "extend-shallow": { - "version": "3.0.2", - "dev": true, - "requires": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - } - }, - "extglob": { - "version": "2.0.4", - "dev": true, - "requires": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "is-extendable": { - "version": "0.1.1", - "dev": true - } - } - }, - "extsprintf": { - "version": "1.3.0", - "dev": true - }, - "fake-merkle-patricia-tree": { - "version": "1.0.1", - "dev": true, - "requires": { - "checkpoint-store": "^1.1.0" - } - }, - "fast-deep-equal": { - "version": "3.1.3", - "dev": true - }, - "fast-json-stable-stringify": { - "version": "2.1.0", - "dev": true - }, - "fetch-ponyfill": { - "version": "4.1.0", - "dev": true, - "requires": { - "node-fetch": "~1.7.1" - }, - "dependencies": { - "is-stream": { - "version": "1.1.0", - "dev": true - }, - "node-fetch": { - "version": "1.7.3", - "dev": true, - "requires": { - "encoding": "^0.1.11", - "is-stream": "^1.0.1" - } - } - } - }, - "finalhandler": { - "version": "1.1.2", - "dev": true, - "optional": true, - "requires": { - "debug": "2.6.9", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "on-finished": "~2.3.0", - "parseurl": "~1.3.3", - "statuses": "~1.5.0", - "unpipe": "~1.0.0" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "dev": true, - "optional": true, - "requires": { - "ms": "2.0.0" - } - }, - "ms": { - "version": "2.0.0", - "dev": true, - "optional": true - } - } - }, - "find-yarn-workspace-root": { - "version": "1.2.1", - "dev": true, - "requires": { - "fs-extra": "^4.0.3", - "micromatch": "^3.1.4" - }, - "dependencies": { - "braces": { - "version": "2.3.2", - "dev": true, - "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "fill-range": { - "version": "4.0.0", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "fs-extra": { - "version": "4.0.3", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - } - }, - "is-buffer": { - "version": "1.1.6", - "dev": true - }, - "is-extendable": { - "version": "0.1.1", - "dev": true - }, - "is-number": { - "version": "3.0.0", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "micromatch": { - "version": "3.1.10", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - } - }, - "to-regex-range": { - "version": "2.1.1", - "dev": true, - "requires": { - "is-number": "^3.0.0", - "repeat-string": "^1.6.1" - } - } - } - }, - "flow-stoplight": { - "version": "1.0.0", - "dev": true - }, - "for-each": { - "version": "0.3.3", - "dev": true, - "requires": { - "is-callable": "^1.1.3" - } - }, - "for-in": { - "version": "1.0.2", - "dev": true - }, - "forever-agent": { - "version": "0.6.1", - "dev": true - }, - "form-data": { - "version": "2.3.3", - "dev": true, - "requires": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.6", - "mime-types": "^2.1.12" - } - }, - "forwarded": { - "version": "0.1.2", - "dev": true, - "optional": true - }, - "fragment-cache": { - "version": "0.2.1", - "dev": true, - "requires": { - "map-cache": "^0.2.2" - } - }, - "fresh": { - "version": "0.5.2", - "dev": true, - "optional": true - }, - "fs-extra": { - "version": "7.0.1", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - } - }, - "fs.realpath": { - "version": "1.0.0", - "dev": true - }, - "function-bind": { - "version": "1.1.1", - "dev": true - }, - "functional-red-black-tree": { - "version": "1.0.1", - "dev": true - }, - "get-intrinsic": { - "version": "1.0.2", - "dev": true, - "requires": { - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1" - } - }, - "get-stream": { - "version": "5.2.0", - "dev": true, - "optional": true, - "requires": { - "pump": "^3.0.0" - } - }, - "get-value": { - "version": "2.0.6", - "dev": true - }, - "getpass": { - "version": "0.1.7", - "dev": true, - "requires": { - "assert-plus": "^1.0.0" - } - }, - "glob": { - "version": "7.1.3", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "global": { - "version": "4.4.0", - "dev": true, - "requires": { - "min-document": "^2.19.0", - "process": "^0.11.10" - } - }, - "got": { - "version": "9.6.0", - "dev": true, - "optional": true, - "requires": { - "@sindresorhus/is": "^0.14.0", - "@szmarczak/http-timer": "^1.1.2", - "cacheable-request": "^6.0.0", - "decompress-response": "^3.3.0", - "duplexer3": "^0.1.4", - "get-stream": "^4.1.0", - "lowercase-keys": "^1.0.1", - "mimic-response": "^1.0.1", - "p-cancelable": "^1.0.0", - "to-readable-stream": "^1.0.0", - "url-parse-lax": "^3.0.0" - }, - "dependencies": { - "get-stream": { - "version": "4.1.0", - "dev": true, - "optional": true, - "requires": { - "pump": "^3.0.0" - } - } - } - }, - "graceful-fs": { - "version": "4.2.4", - "dev": true - }, - "har-schema": { - "version": "2.0.0", - "dev": true - }, - "har-validator": { - "version": "5.1.5", - "dev": true, - "requires": { - "ajv": "^6.12.3", - "har-schema": "^2.0.0" - } - }, - "has": { - "version": "1.0.3", - "dev": true, - "requires": { - "function-bind": "^1.1.1" - } - }, - "has-ansi": { - "version": "2.0.0", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "2.1.1", - "dev": true - } - } - }, - "has-flag": { - "version": "3.0.0", - "dev": true - }, - "has-symbol-support-x": { - "version": "1.4.2", - "dev": true, - "optional": true - }, - "has-symbols": { - "version": "1.0.1", - "dev": true - }, - "has-to-string-tag-x": { - "version": "1.4.1", - "dev": true, - "optional": true, - "requires": { - "has-symbol-support-x": "^1.4.1" - } - }, - "has-value": { - "version": "1.0.0", - "dev": true, - "requires": { - "get-value": "^2.0.6", - "has-values": "^1.0.0", - "isobject": "^3.0.0" - } - }, - "has-values": { - "version": "1.0.0", - "dev": true, - "requires": { - "is-number": "^3.0.0", - "kind-of": "^4.0.0" - }, - "dependencies": { - "is-buffer": { - "version": "1.1.6", - "dev": true - }, - "is-number": { - "version": "3.0.0", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "kind-of": { - "version": "4.0.0", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "hash-base": { - "version": "3.1.0", - "dev": true, - "requires": { - "inherits": "^2.0.4", - "readable-stream": "^3.6.0", - "safe-buffer": "^5.2.0" - }, - "dependencies": { - "readable-stream": { - "version": "3.6.0", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - } - } - }, - "hash.js": { - "version": "1.1.7", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "minimalistic-assert": "^1.0.1" - } - }, - "heap": { - "version": "0.2.6", - "dev": true - }, - "hmac-drbg": { - "version": "1.0.1", - "dev": true, - "requires": { - "hash.js": "^1.0.3", - "minimalistic-assert": "^1.0.0", - "minimalistic-crypto-utils": "^1.0.1" - } - }, - "home-or-tmp": { - "version": "2.0.0", - "dev": true, - "requires": { - "os-homedir": "^1.0.0", - "os-tmpdir": "^1.0.1" - } - }, - "http-cache-semantics": { - "version": "4.1.0", - "dev": true, - "optional": true - }, - "http-errors": { - "version": "1.7.2", - "dev": true, - "optional": true, - "requires": { - "depd": "~1.1.2", - "inherits": "2.0.3", - "setprototypeof": "1.1.1", - "statuses": ">= 1.5.0 < 2", - "toidentifier": "1.0.0" - }, - "dependencies": { - "inherits": { - "version": "2.0.3", - "dev": true, - "optional": true - } - } - }, - "http-https": { - "version": "1.0.0", - "dev": true, - "optional": true - }, - "http-signature": { - "version": "1.2.0", - "dev": true, - "requires": { - "assert-plus": "^1.0.0", - "jsprim": "^1.2.2", - "sshpk": "^1.7.0" - } - }, - "iconv-lite": { - "version": "0.4.24", - "dev": true, - "optional": true, - "requires": { - "safer-buffer": ">= 2.1.2 < 3" - } - }, - "idna-uts46-hx": { - "version": "2.3.1", - "dev": true, - "optional": true, - "requires": { - "punycode": "2.1.0" - }, - "dependencies": { - "punycode": { - "version": "2.1.0", - "dev": true, - "optional": true - } - } - }, - "ieee754": { - "version": "1.2.1", - "dev": true - }, - "immediate": { - "version": "3.2.3", - "dev": true - }, - "inflight": { - "version": "1.0.6", - "dev": true, - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.4", - "dev": true - }, - "invariant": { - "version": "2.2.4", - "dev": true, - "requires": { - "loose-envify": "^1.0.0" - } - }, - "ipaddr.js": { - "version": "1.9.1", - "dev": true, - "optional": true - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-arguments": { - "version": "1.1.0", - "dev": true, - "requires": { - "call-bind": "^1.0.0" - } - }, - "is-callable": { - "version": "1.2.2", - "dev": true - }, - "is-ci": { - "version": "2.0.0", - "dev": true, - "requires": { - "ci-info": "^2.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-date-object": { - "version": "1.0.2", - "dev": true - }, - "is-descriptor": { - "version": "1.0.2", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "is-extendable": { - "version": "1.0.1", - "dev": true, - "requires": { - "is-plain-object": "^2.0.4" - } - }, - "is-finite": { - "version": "1.1.0", - "dev": true - }, - "is-fn": { - "version": "1.0.0", - "dev": true - }, - "is-function": { - "version": "1.0.2", - "dev": true - }, - "is-hex-prefixed": { - "version": "1.0.0", - "dev": true - }, - "is-negative-zero": { - "version": "2.0.1", - "dev": true - }, - "is-object": { - "version": "1.0.2", - "dev": true, - "optional": true - }, - "is-plain-obj": { - "version": "1.1.0", - "dev": true, - "optional": true - }, - "is-plain-object": { - "version": "2.0.4", - "dev": true, - "requires": { - "isobject": "^3.0.1" - } - }, - "is-regex": { - "version": "1.1.1", - "dev": true, - "requires": { - "has-symbols": "^1.0.1" - } - }, - "is-retry-allowed": { - "version": "1.2.0", - "dev": true, - "optional": true - }, - "is-symbol": { - "version": "1.0.3", - "dev": true, - "requires": { - "has-symbols": "^1.0.1" - } - }, - "is-typedarray": { - "version": "1.0.0", - "dev": true - }, - "is-windows": { - "version": "1.0.2", - "dev": true - }, - "isarray": { - "version": "1.0.0", - "dev": true - }, - "isexe": { - "version": "2.0.0", - "dev": true - }, - "isobject": { - "version": "3.0.1", - "dev": true - }, - "isstream": { - "version": "0.1.2", - "dev": true - }, - "isurl": { - "version": "1.0.0", - "dev": true, - "optional": true, - "requires": { - "has-to-string-tag-x": "^1.2.0", - "is-object": "^1.0.1" - } - }, - "js-sha3": { - "version": "0.5.7", - "dev": true, - "optional": true - }, - "js-tokens": { - "version": "4.0.0", - "dev": true - }, - "jsbn": { - "version": "0.1.1", - "dev": true - }, - "json-buffer": { - "version": "3.0.0", - "dev": true, - "optional": true - }, - "json-rpc-engine": { - "version": "3.8.0", - "dev": true, - "requires": { - "async": "^2.0.1", - "babel-preset-env": "^1.7.0", - "babelify": "^7.3.0", - "json-rpc-error": "^2.0.0", - "promise-to-callback": "^1.0.0", - "safe-event-emitter": "^1.0.1" - } - }, - "json-rpc-error": { - "version": "2.0.0", - "dev": true, - "requires": { - "inherits": "^2.0.1" - } - }, - "json-rpc-random-id": { - "version": "1.0.1", - "dev": true - }, - "json-schema": { - "version": "0.2.3", - "dev": true - }, - "json-schema-traverse": { - "version": "0.4.1", - "dev": true - }, - "json-stable-stringify": { - "version": "1.0.1", - "dev": true, - "requires": { - "jsonify": "~0.0.0" - } - }, - "json-stringify-safe": { - "version": "5.0.1", - "dev": true - }, - "jsonfile": { - "version": "4.0.0", - "dev": true, - "requires": { - "graceful-fs": "^4.1.6" - } - }, - "jsonify": { - "version": "0.0.0", - "dev": true - }, - "jsprim": { - "version": "1.4.1", - "dev": true, - "requires": { - "assert-plus": "1.0.0", - "extsprintf": "1.3.0", - "json-schema": "0.2.3", - "verror": "1.10.0" - } - }, - "keccak": { - "version": "3.0.1", - "bundled": true, - "dev": true, - "requires": { - "node-addon-api": "^2.0.0", - "node-gyp-build": "^4.2.0" - } - }, - "keyv": { - "version": "3.1.0", - "dev": true, - "optional": true, - "requires": { - "json-buffer": "3.0.0" - } - }, - "kind-of": { - "version": "6.0.3", - "dev": true - }, - "klaw-sync": { - "version": "6.0.0", - "dev": true, - "requires": { - "graceful-fs": "^4.1.11" - } - }, - "level-codec": { - "version": "9.0.2", - "dev": true, - "requires": { - "buffer": "^5.6.0" - } - }, - "level-errors": { - "version": "2.0.1", - "dev": true, - "requires": { - "errno": "~0.1.1" - } - }, - "level-iterator-stream": { - "version": "2.0.3", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "readable-stream": "^2.0.5", - "xtend": "^4.0.0" - } - }, - "level-mem": { - "version": "3.0.1", - "dev": true, - "requires": { - "level-packager": "~4.0.0", - "memdown": "~3.0.0" - }, - "dependencies": { - "abstract-leveldown": { - "version": "5.0.0", - "dev": true, - "requires": { - "xtend": "~4.0.0" - } - }, - "ltgt": { - "version": "2.2.1", - "dev": true - }, - "memdown": { - "version": "3.0.0", - "dev": true, - "requires": { - "abstract-leveldown": "~5.0.0", - "functional-red-black-tree": "~1.0.1", - "immediate": "~3.2.3", - "inherits": "~2.0.1", - "ltgt": "~2.2.0", - "safe-buffer": "~5.1.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "dev": true - } - } - }, - "level-packager": { - "version": "4.0.1", - "dev": true, - "requires": { - "encoding-down": "~5.0.0", - "levelup": "^3.0.0" - } - }, - "level-post": { - "version": "1.0.7", - "dev": true, - "requires": { - "ltgt": "^2.1.2" - } - }, - "level-sublevel": { - "version": "6.6.4", - "dev": true, - "requires": { - "bytewise": "~1.1.0", - "level-codec": "^9.0.0", - "level-errors": "^2.0.0", - "level-iterator-stream": "^2.0.3", - "ltgt": "~2.1.1", - "pull-defer": "^0.2.2", - "pull-level": "^2.0.3", - "pull-stream": "^3.6.8", - "typewiselite": "~1.0.0", - "xtend": "~4.0.0" - } - }, - "level-ws": { - "version": "1.0.0", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "readable-stream": "^2.2.8", - "xtend": "^4.0.1" - } - }, - "levelup": { - "version": "3.1.1", - "dev": true, - "requires": { - "deferred-leveldown": "~4.0.0", - "level-errors": "~2.0.0", - "level-iterator-stream": "~3.0.0", - "xtend": "~4.0.0" - }, - "dependencies": { - "level-iterator-stream": { - "version": "3.0.1", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "readable-stream": "^2.3.6", - "xtend": "^4.0.0" - } - } - } - }, - "lodash": { - "version": "4.17.20", - "dev": true - }, - "looper": { - "version": "2.0.0", - "dev": true - }, - "loose-envify": { - "version": "1.4.0", - "dev": true, - "requires": { - "js-tokens": "^3.0.0 || ^4.0.0" - } - }, - "lowercase-keys": { - "version": "1.0.1", - "dev": true, - "optional": true - }, - "lru-cache": { - "version": "5.1.1", - "dev": true, - "requires": { - "yallist": "^3.0.2" - } - }, - "ltgt": { - "version": "2.1.3", - "dev": true - }, - "map-cache": { - "version": "0.2.2", - "dev": true - }, - "map-visit": { - "version": "1.0.0", - "dev": true, - "requires": { - "object-visit": "^1.0.0" - } - }, - "md5.js": { - "version": "1.3.5", - "dev": true, - "requires": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "media-typer": { - "version": "0.3.0", - "dev": true, - "optional": true - }, - "merge-descriptors": { - "version": "1.0.1", - "dev": true, - "optional": true - }, - "merkle-patricia-tree": { - "version": "3.0.0", - "dev": true, - "requires": { - "async": "^2.6.1", - "ethereumjs-util": "^5.2.0", - "level-mem": "^3.0.1", - "level-ws": "^1.0.0", - "readable-stream": "^3.0.6", - "rlp": "^2.0.0", - "semaphore": ">=1.0.1" - }, - "dependencies": { - "ethereumjs-util": { - "version": "5.2.1", - "dev": true, - "requires": { - "bn.js": "^4.11.0", - "create-hash": "^1.1.2", - "elliptic": "^6.5.2", - "ethereum-cryptography": "^0.1.3", - "ethjs-util": "^0.1.3", - "rlp": "^2.0.0", - "safe-buffer": "^5.1.1" - } - }, - "readable-stream": { - "version": "3.6.0", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - } - } - }, - "methods": { - "version": "1.1.2", - "dev": true, - "optional": true - }, - "miller-rabin": { - "version": "4.0.1", - "dev": true, - "requires": { - "bn.js": "^4.0.0", - "brorand": "^1.0.1" - } - }, - "mime": { - "version": "1.6.0", - "dev": true, - "optional": true - }, - "mime-db": { - "version": "1.45.0", - "dev": true - }, - "mime-types": { - "version": "2.1.28", - "dev": true, - "requires": { - "mime-db": "1.45.0" - } - }, - "mimic-response": { - "version": "1.0.1", - "dev": true, - "optional": true - }, - "min-document": { - "version": "2.19.0", - "dev": true, - "requires": { - "dom-walk": "^0.1.0" - } - }, - "minimalistic-assert": { - "version": "1.0.1", - "dev": true - }, - "minimalistic-crypto-utils": { - "version": "1.0.1", - "dev": true - }, - "minimatch": { - "version": "3.0.4", - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "minimist": { - "version": "1.2.5", - "dev": true - }, - "minizlib": { - "version": "1.3.3", - "dev": true, - "optional": true, - "requires": { - "minipass": "^2.9.0" - }, - "dependencies": { - "minipass": { - "version": "2.9.0", - "dev": true, - "optional": true, - "requires": { - "safe-buffer": "^5.1.2", - "yallist": "^3.0.0" - } - } - } - }, - "mixin-deep": { - "version": "1.3.2", - "dev": true, - "requires": { - "for-in": "^1.0.2", - "is-extendable": "^1.0.1" - } - }, - "mkdirp": { - "version": "0.5.5", - "dev": true, - "requires": { - "minimist": "^1.2.5" - } - }, - "mkdirp-promise": { - "version": "5.0.1", - "dev": true, - "optional": true, - "requires": { - "mkdirp": "*" - } - }, - "mock-fs": { - "version": "4.13.0", - "dev": true, - "optional": true - }, - "ms": { - "version": "2.1.3", - "dev": true - }, - "multibase": { - "version": "0.6.1", - "dev": true, - "optional": true, - "requires": { - "base-x": "^3.0.8", - "buffer": "^5.5.0" - } - }, - "multicodec": { - "version": "0.5.7", - "dev": true, - "optional": true, - "requires": { - "varint": "^5.0.0" - } - }, - "multihashes": { - "version": "0.4.21", - "dev": true, - "optional": true, - "requires": { - "buffer": "^5.5.0", - "multibase": "^0.7.0", - "varint": "^5.0.0" - }, - "dependencies": { - "multibase": { - "version": "0.7.0", - "dev": true, - "optional": true, - "requires": { - "base-x": "^3.0.8", - "buffer": "^5.5.0" - } - } - } - }, - "nano-json-stream-parser": { - "version": "0.1.2", - "dev": true, - "optional": true - }, - "nanomatch": { - "version": "1.2.13", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "fragment-cache": "^0.2.1", - "is-windows": "^1.0.2", - "kind-of": "^6.0.2", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - } - }, - "negotiator": { - "version": "0.6.2", - "dev": true, - "optional": true - }, - "next-tick": { - "version": "1.0.0", - "dev": true - }, - "nice-try": { - "version": "1.0.5", - "dev": true - }, - "node-addon-api": { - "version": "2.0.2", - "bundled": true, - "dev": true - }, - "node-fetch": { - "version": "2.1.2", - "dev": true - }, - "node-gyp-build": { - "version": "4.2.3", - "bundled": true, - "dev": true - }, - "normalize-url": { - "version": "4.5.0", - "dev": true, - "optional": true - }, - "number-to-bn": { - "version": "1.7.0", - "dev": true, - "optional": true, - "requires": { - "bn.js": "4.11.6", - "strip-hex-prefix": "1.0.0" - }, - "dependencies": { - "bn.js": { - "version": "4.11.6", - "dev": true, - "optional": true - } - } - }, - "oauth-sign": { - "version": "0.9.0", - "dev": true - }, - "object-assign": { - "version": "4.1.1", - "dev": true - }, - "object-copy": { - "version": "0.1.0", - "dev": true, - "requires": { - "copy-descriptor": "^0.1.0", - "define-property": "^0.2.5", - "kind-of": "^3.0.3" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - } - }, - "is-buffer": { - "version": "1.1.6", - "dev": true - }, - "is-data-descriptor": { - "version": "0.1.4", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - } - }, - "is-descriptor": { - "version": "0.1.6", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - }, - "dependencies": { - "kind-of": { - "version": "5.1.0", - "dev": true - } - } - }, - "kind-of": { - "version": "3.2.2", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "object-inspect": { - "version": "1.9.0", - "dev": true - }, - "object-is": { - "version": "1.1.4", - "dev": true, - "requires": { - "call-bind": "^1.0.0", - "define-properties": "^1.1.3" - } - }, - "object-keys": { - "version": "1.1.1", - "dev": true - }, - "object-visit": { - "version": "1.0.1", - "dev": true, - "requires": { - "isobject": "^3.0.0" - } - }, - "object.assign": { - "version": "4.1.2", - "dev": true, - "requires": { - "call-bind": "^1.0.0", - "define-properties": "^1.1.3", - "has-symbols": "^1.0.1", - "object-keys": "^1.1.1" - } - }, - "object.getownpropertydescriptors": { - "version": "2.1.1", - "dev": true, - "requires": { - "call-bind": "^1.0.0", - "define-properties": "^1.1.3", - "es-abstract": "^1.18.0-next.1" - } - }, - "object.pick": { - "version": "1.3.0", - "dev": true, - "requires": { - "isobject": "^3.0.1" - } - }, - "oboe": { - "version": "2.1.4", - "dev": true, - "optional": true, - "requires": { - "http-https": "^1.0.0" - } - }, - "on-finished": { - "version": "2.3.0", - "dev": true, - "optional": true, - "requires": { - "ee-first": "1.1.1" - } - }, - "once": { - "version": "1.4.0", - "dev": true, - "requires": { - "wrappy": "1" - } - }, - "os-homedir": { - "version": "1.0.2", - "dev": true - }, - "os-tmpdir": { - "version": "1.0.2", - "dev": true - }, - "p-cancelable": { - "version": "1.1.0", - "dev": true, - "optional": true - }, - "p-timeout": { - "version": "1.2.1", - "dev": true, - "optional": true, - "requires": { - "p-finally": "^1.0.0" - }, - "dependencies": { - "p-finally": { - "version": "1.0.0", - "dev": true, - "optional": true - } - } - }, - "parse-asn1": { - "version": "5.1.6", - "dev": true, - "optional": true, - "requires": { - "asn1.js": "^5.2.0", - "browserify-aes": "^1.0.0", - "evp_bytestokey": "^1.0.0", - "pbkdf2": "^3.0.3", - "safe-buffer": "^5.1.1" - } - }, - "parse-headers": { - "version": "2.0.3", - "dev": true - }, - "parseurl": { - "version": "1.3.3", - "dev": true, - "optional": true - }, - "pascalcase": { - "version": "0.1.1", - "dev": true - }, - "patch-package": { - "version": "6.2.2", - "dev": true, - "requires": { - "@yarnpkg/lockfile": "^1.1.0", - "chalk": "^2.4.2", - "cross-spawn": "^6.0.5", - "find-yarn-workspace-root": "^1.2.1", - "fs-extra": "^7.0.1", - "is-ci": "^2.0.0", - "klaw-sync": "^6.0.0", - "minimist": "^1.2.0", - "rimraf": "^2.6.3", - "semver": "^5.6.0", - "slash": "^2.0.0", - "tmp": "^0.0.33" - }, - "dependencies": { - "cross-spawn": { - "version": "6.0.5", - "dev": true, - "requires": { - "nice-try": "^1.0.4", - "path-key": "^2.0.1", - "semver": "^5.5.0", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - } - }, - "path-key": { - "version": "2.0.1", - "dev": true - }, - "semver": { - "version": "5.7.1", - "dev": true - }, - "shebang-command": { - "version": "1.2.0", - "dev": true, - "requires": { - "shebang-regex": "^1.0.0" - } - }, - "shebang-regex": { - "version": "1.0.0", - "dev": true - }, - "slash": { - "version": "2.0.0", - "dev": true - }, - "tmp": { - "version": "0.0.33", - "dev": true, - "requires": { - "os-tmpdir": "~1.0.2" - } - }, - "which": { - "version": "1.3.1", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - } - } - }, - "path-is-absolute": { - "version": "1.0.1", - "dev": true - }, - "path-parse": { - "version": "1.0.6", - "dev": true - }, - "path-to-regexp": { - "version": "0.1.7", - "dev": true, - "optional": true - }, - "pbkdf2": { - "version": "3.1.1", - "dev": true, - "requires": { - "create-hash": "^1.1.2", - "create-hmac": "^1.1.4", - "ripemd160": "^2.0.1", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - } - }, - "performance-now": { - "version": "2.1.0", - "dev": true - }, - "posix-character-classes": { - "version": "0.1.1", - "dev": true - }, - "precond": { - "version": "0.2.3", - "dev": true - }, - "prepend-http": { - "version": "2.0.0", - "dev": true, - "optional": true - }, - "private": { - "version": "0.1.8", - "dev": true - }, - "process": { - "version": "0.11.10", - "dev": true - }, - "process-nextick-args": { - "version": "2.0.1", - "dev": true - }, - "promise-to-callback": { - "version": "1.0.0", - "dev": true, - "requires": { - "is-fn": "^1.0.0", - "set-immediate-shim": "^1.0.1" - } - }, - "proxy-addr": { - "version": "2.0.6", - "dev": true, - "optional": true, - "requires": { - "forwarded": "~0.1.2", - "ipaddr.js": "1.9.1" - } - }, - "prr": { - "version": "1.0.1", - "dev": true - }, - "pseudomap": { - "version": "1.0.2", - "dev": true - }, - "psl": { - "version": "1.8.0", - "dev": true - }, - "public-encrypt": { - "version": "4.0.3", - "dev": true, - "optional": true, - "requires": { - "bn.js": "^4.1.0", - "browserify-rsa": "^4.0.0", - "create-hash": "^1.1.0", - "parse-asn1": "^5.0.0", - "randombytes": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "pull-cat": { - "version": "1.1.11", - "dev": true - }, - "pull-defer": { - "version": "0.2.3", - "dev": true - }, - "pull-level": { - "version": "2.0.4", - "dev": true, - "requires": { - "level-post": "^1.0.7", - "pull-cat": "^1.1.9", - "pull-live": "^1.0.1", - "pull-pushable": "^2.0.0", - "pull-stream": "^3.4.0", - "pull-window": "^2.1.4", - "stream-to-pull-stream": "^1.7.1" - } - }, - "pull-live": { - "version": "1.0.1", - "dev": true, - "requires": { - "pull-cat": "^1.1.9", - "pull-stream": "^3.4.0" - } - }, - "pull-pushable": { - "version": "2.2.0", - "dev": true - }, - "pull-stream": { - "version": "3.6.14", - "dev": true - }, - "pull-window": { - "version": "2.1.4", - "dev": true, - "requires": { - "looper": "^2.0.0" - } - }, - "pump": { - "version": "3.0.0", - "dev": true, - "optional": true, - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "punycode": { - "version": "2.1.1", - "dev": true - }, - "qs": { - "version": "6.5.2", - "dev": true - }, - "query-string": { - "version": "5.1.1", - "dev": true, - "optional": true, - "requires": { - "decode-uri-component": "^0.2.0", - "object-assign": "^4.1.0", - "strict-uri-encode": "^1.0.0" - } - }, - "randombytes": { - "version": "2.1.0", - "dev": true, - "requires": { - "safe-buffer": "^5.1.0" - } - }, - "randomfill": { - "version": "1.0.4", - "dev": true, - "optional": true, - "requires": { - "randombytes": "^2.0.5", - "safe-buffer": "^5.1.0" - } - }, - "range-parser": { - "version": "1.2.1", - "dev": true, - "optional": true - }, - "raw-body": { - "version": "2.4.0", - "dev": true, - "optional": true, - "requires": { - "bytes": "3.1.0", - "http-errors": "1.7.2", - "iconv-lite": "0.4.24", - "unpipe": "1.0.0" - } - }, - "readable-stream": { - "version": "2.3.7", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - }, - "dependencies": { - "safe-buffer": { - "version": "5.1.2", - "dev": true - } - } - }, - "regenerate": { - "version": "1.4.2", - "dev": true - }, - "regenerator-runtime": { - "version": "0.11.1", - "dev": true - }, - "regenerator-transform": { - "version": "0.10.1", - "dev": true, - "requires": { - "babel-runtime": "^6.18.0", - "babel-types": "^6.19.0", - "private": "^0.1.6" - } - }, - "regex-not": { - "version": "1.0.2", - "dev": true, - "requires": { - "extend-shallow": "^3.0.2", - "safe-regex": "^1.1.0" - } - }, - "regexp.prototype.flags": { - "version": "1.3.0", - "dev": true, - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.0-next.1" - }, - "dependencies": { - "es-abstract": { - "version": "1.17.7", - "dev": true, - "requires": { - "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1", - "is-callable": "^1.2.2", - "is-regex": "^1.1.1", - "object-inspect": "^1.8.0", - "object-keys": "^1.1.1", - "object.assign": "^4.1.1", - "string.prototype.trimend": "^1.0.1", - "string.prototype.trimstart": "^1.0.1" - } - } - } - }, - "regexpu-core": { - "version": "2.0.0", - "dev": true, - "requires": { - "regenerate": "^1.2.1", - "regjsgen": "^0.2.0", - "regjsparser": "^0.1.4" - } - }, - "regjsgen": { - "version": "0.2.0", - "dev": true - }, - "regjsparser": { - "version": "0.1.5", - "dev": true, - "requires": { - "jsesc": "~0.5.0" - }, - "dependencies": { - "jsesc": { - "version": "0.5.0", - "dev": true - } - } - }, - "repeat-element": { - "version": "1.1.3", - "dev": true - }, - "repeat-string": { - "version": "1.6.1", - "dev": true - }, - "repeating": { - "version": "2.0.1", - "dev": true, - "requires": { - "is-finite": "^1.0.0" - } - }, - "request": { - "version": "2.88.2", - "dev": true, - "requires": { - "aws-sign2": "~0.7.0", - "aws4": "^1.8.0", - "caseless": "~0.12.0", - "combined-stream": "~1.0.6", - "extend": "~3.0.2", - "forever-agent": "~0.6.1", - "form-data": "~2.3.2", - "har-validator": "~5.1.3", - "http-signature": "~1.2.0", - "is-typedarray": "~1.0.0", - "isstream": "~0.1.2", - "json-stringify-safe": "~5.0.1", - "mime-types": "~2.1.19", - "oauth-sign": "~0.9.0", - "performance-now": "^2.1.0", - "qs": "~6.5.2", - "safe-buffer": "^5.1.2", - "tough-cookie": "~2.5.0", - "tunnel-agent": "^0.6.0", - "uuid": "^3.3.2" - } - }, - "resolve-url": { - "version": "0.2.1", - "dev": true - }, - "responselike": { - "version": "1.0.2", - "dev": true, - "optional": true, - "requires": { - "lowercase-keys": "^1.0.0" - } - }, - "resumer": { - "version": "0.0.0", - "dev": true, - "requires": { - "through": "~2.3.4" - } - }, - "ret": { - "version": "0.1.15", - "dev": true - }, - "rimraf": { - "version": "2.6.3", - "dev": true, - "requires": { - "glob": "^7.1.3" - } - }, - "ripemd160": { - "version": "2.0.2", - "dev": true, - "requires": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1" - } - }, - "rlp": { - "version": "2.2.6", - "dev": true, - "requires": { - "bn.js": "^4.11.1" - } - }, - "rustbn.js": { - "version": "0.2.0", - "dev": true - }, - "safe-buffer": { - "version": "5.2.1", - "dev": true - }, - "safe-event-emitter": { - "version": "1.0.1", - "dev": true, - "requires": { - "events": "^3.0.0" - } - }, - "safe-regex": { - "version": "1.1.0", - "dev": true, - "requires": { - "ret": "~0.1.10" - } - }, - "safer-buffer": { - "version": "2.1.2", - "dev": true - }, - "scrypt-js": { - "version": "3.0.1", - "dev": true - }, - "scryptsy": { - "version": "1.2.1", - "dev": true, - "optional": true, - "requires": { - "pbkdf2": "^3.0.3" - } - }, - "secp256k1": { - "version": "4.0.2", - "dev": true, - "requires": { - "elliptic": "^6.5.2", - "node-addon-api": "^2.0.0", - "node-gyp-build": "^4.2.0" - } - }, - "seedrandom": { - "version": "3.0.1", - "dev": true - }, - "semaphore": { - "version": "1.1.0", - "dev": true - }, - "send": { - "version": "0.17.1", - "dev": true, - "optional": true, - "requires": { - "debug": "2.6.9", - "depd": "~1.1.2", - "destroy": "~1.0.4", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "fresh": "0.5.2", - "http-errors": "~1.7.2", - "mime": "1.6.0", - "ms": "2.1.1", - "on-finished": "~2.3.0", - "range-parser": "~1.2.1", - "statuses": "~1.5.0" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "dev": true, - "optional": true, - "requires": { - "ms": "2.0.0" - }, - "dependencies": { - "ms": { - "version": "2.0.0", - "dev": true, - "optional": true - } - } - }, - "ms": { - "version": "2.1.1", - "dev": true, - "optional": true - } - } - }, - "serve-static": { - "version": "1.14.1", - "dev": true, - "optional": true, - "requires": { - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "parseurl": "~1.3.3", - "send": "0.17.1" - } - }, - "servify": { - "version": "0.1.12", - "dev": true, - "optional": true, - "requires": { - "body-parser": "^1.16.0", - "cors": "^2.8.1", - "express": "^4.14.0", - "request": "^2.79.0", - "xhr": "^2.3.3" - } - }, - "set-immediate-shim": { - "version": "1.0.1", - "dev": true - }, - "set-value": { - "version": "2.0.1", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-extendable": "^0.1.1", - "is-plain-object": "^2.0.3", - "split-string": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "is-extendable": { - "version": "0.1.1", - "dev": true - } - } - }, - "setimmediate": { - "version": "1.0.5", - "dev": true - }, - "setprototypeof": { - "version": "1.1.1", - "dev": true, - "optional": true - }, - "sha.js": { - "version": "2.4.11", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "simple-concat": { - "version": "1.0.1", - "dev": true, - "optional": true - }, - "simple-get": { - "version": "2.8.1", - "dev": true, - "optional": true, - "requires": { - "decompress-response": "^3.3.0", - "once": "^1.3.1", - "simple-concat": "^1.0.0" - } - }, - "snapdragon": { - "version": "0.8.2", - "dev": true, - "requires": { - "base": "^0.11.1", - "debug": "^2.2.0", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "map-cache": "^0.2.2", - "source-map": "^0.5.6", - "source-map-resolve": "^0.5.0", - "use": "^3.1.0" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "define-property": { - "version": "0.2.5", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-buffer": { - "version": "1.1.6", - "dev": true - }, - "is-data-descriptor": { - "version": "0.1.4", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - } - }, - "is-extendable": { - "version": "0.1.1", - "dev": true - }, - "kind-of": { - "version": "5.1.0", - "dev": true - }, - "ms": { - "version": "2.0.0", - "dev": true - } - } - }, - "snapdragon-node": { - "version": "2.1.1", - "dev": true, - "requires": { - "define-property": "^1.0.0", - "isobject": "^3.0.0", - "snapdragon-util": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - } - } - }, - "snapdragon-util": { - "version": "3.0.1", - "dev": true, - "requires": { - "kind-of": "^3.2.0" - }, - "dependencies": { - "is-buffer": { - "version": "1.1.6", - "dev": true - }, - "kind-of": { - "version": "3.2.2", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "source-map": { - "version": "0.5.7", - "dev": true - }, - "source-map-resolve": { - "version": "0.5.3", - "dev": true, - "requires": { - "atob": "^2.1.2", - "decode-uri-component": "^0.2.0", - "resolve-url": "^0.2.1", - "source-map-url": "^0.4.0", - "urix": "^0.1.0" - } - }, - "source-map-support": { - "version": "0.5.12", - "dev": true, - "requires": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "dev": true - } - } - }, - "source-map-url": { - "version": "0.4.0", - "dev": true - }, - "split-string": { - "version": "3.1.0", - "dev": true, - "requires": { - "extend-shallow": "^3.0.0" - } - }, - "sshpk": { - "version": "1.16.1", - "dev": true, - "requires": { - "asn1": "~0.2.3", - "assert-plus": "^1.0.0", - "bcrypt-pbkdf": "^1.0.0", - "dashdash": "^1.12.0", - "ecc-jsbn": "~0.1.1", - "getpass": "^0.1.1", - "jsbn": "~0.1.0", - "safer-buffer": "^2.0.2", - "tweetnacl": "~0.14.0" - }, - "dependencies": { - "tweetnacl": { - "version": "0.14.5", - "dev": true - } - } - }, - "static-extend": { - "version": "0.1.2", - "dev": true, - "requires": { - "define-property": "^0.2.5", - "object-copy": "^0.1.0" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-buffer": { - "version": "1.1.6", - "dev": true - }, - "is-data-descriptor": { - "version": "0.1.4", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - } - }, - "kind-of": { - "version": "5.1.0", - "dev": true - } - } - }, - "statuses": { - "version": "1.5.0", - "dev": true, - "optional": true - }, - "stream-to-pull-stream": { - "version": "1.7.3", - "dev": true, - "requires": { - "looper": "^3.0.0", - "pull-stream": "^3.2.3" - }, - "dependencies": { - "looper": { - "version": "3.0.0", - "dev": true - } - } - }, - "strict-uri-encode": { - "version": "1.1.0", - "dev": true, - "optional": true - }, - "string_decoder": { - "version": "1.1.1", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - }, - "dependencies": { - "safe-buffer": { - "version": "5.1.2", - "dev": true - } - } - }, - "string.prototype.trim": { - "version": "1.2.3", - "dev": true, - "requires": { - "call-bind": "^1.0.0", - "define-properties": "^1.1.3", - "es-abstract": "^1.18.0-next.1" - } - }, - "string.prototype.trimend": { - "version": "1.0.3", - "dev": true, - "requires": { - "call-bind": "^1.0.0", - "define-properties": "^1.1.3" - } - }, - "string.prototype.trimstart": { - "version": "1.0.3", - "dev": true, - "requires": { - "call-bind": "^1.0.0", - "define-properties": "^1.1.3" - } - }, - "strip-hex-prefix": { - "version": "1.0.0", - "dev": true, - "requires": { - "is-hex-prefixed": "1.0.0" - } - }, - "supports-color": { - "version": "5.5.0", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - }, - "swarm-js": { - "version": "0.1.40", - "dev": true, - "optional": true, - "requires": { - "bluebird": "^3.5.0", - "buffer": "^5.0.5", - "eth-lib": "^0.1.26", - "fs-extra": "^4.0.2", - "got": "^7.1.0", - "mime-types": "^2.1.16", - "mkdirp-promise": "^5.0.1", - "mock-fs": "^4.1.0", - "setimmediate": "^1.0.5", - "tar": "^4.0.2", - "xhr-request": "^1.0.1" - }, - "dependencies": { - "fs-extra": { - "version": "4.0.3", - "dev": true, - "optional": true, - "requires": { - "graceful-fs": "^4.1.2", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - } - }, - "get-stream": { - "version": "3.0.0", - "dev": true, - "optional": true - }, - "got": { - "version": "7.1.0", - "dev": true, - "optional": true, - "requires": { - "decompress-response": "^3.2.0", - "duplexer3": "^0.1.4", - "get-stream": "^3.0.0", - "is-plain-obj": "^1.1.0", - "is-retry-allowed": "^1.0.0", - "is-stream": "^1.0.0", - "isurl": "^1.0.0-alpha5", - "lowercase-keys": "^1.0.0", - "p-cancelable": "^0.3.0", - "p-timeout": "^1.1.1", - "safe-buffer": "^5.0.1", - "timed-out": "^4.0.0", - "url-parse-lax": "^1.0.0", - "url-to-options": "^1.0.1" - } - }, - "is-stream": { - "version": "1.1.0", - "dev": true, - "optional": true - }, - "p-cancelable": { - "version": "0.3.0", - "dev": true, - "optional": true - }, - "prepend-http": { - "version": "1.0.4", - "dev": true, - "optional": true - }, - "url-parse-lax": { - "version": "1.0.0", - "dev": true, - "optional": true, - "requires": { - "prepend-http": "^1.0.1" - } - } - } - }, - "tape": { - "version": "4.13.3", - "dev": true, - "requires": { - "deep-equal": "~1.1.1", - "defined": "~1.0.0", - "dotignore": "~0.1.2", - "for-each": "~0.3.3", - "function-bind": "~1.1.1", - "glob": "~7.1.6", - "has": "~1.0.3", - "inherits": "~2.0.4", - "is-regex": "~1.0.5", - "minimist": "~1.2.5", - "object-inspect": "~1.7.0", - "resolve": "~1.17.0", - "resumer": "~0.0.0", - "string.prototype.trim": "~1.2.1", - "through": "~2.3.8" - }, - "dependencies": { - "glob": { - "version": "7.1.6", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "is-regex": { - "version": "1.0.5", - "dev": true, - "requires": { - "has": "^1.0.3" - } - }, - "object-inspect": { - "version": "1.7.0", - "dev": true - }, - "resolve": { - "version": "1.17.0", - "dev": true, - "requires": { - "path-parse": "^1.0.6" - } - } - } - }, - "tar": { - "version": "4.4.13", - "dev": true, - "optional": true, - "requires": { - "chownr": "^1.1.1", - "fs-minipass": "^1.2.5", - "minipass": "^2.8.6", - "minizlib": "^1.2.1", - "mkdirp": "^0.5.0", - "safe-buffer": "^5.1.2", - "yallist": "^3.0.3" - }, - "dependencies": { - "fs-minipass": { - "version": "1.2.7", - "dev": true, - "optional": true, - "requires": { - "minipass": "^2.6.0" - } - }, - "minipass": { - "version": "2.9.0", - "dev": true, - "optional": true, - "requires": { - "safe-buffer": "^5.1.2", - "yallist": "^3.0.0" - } - } - } - }, - "through": { - "version": "2.3.8", - "dev": true - }, - "through2": { - "version": "2.0.5", - "dev": true, - "requires": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - } - }, - "timed-out": { - "version": "4.0.1", - "dev": true, - "optional": true - }, - "tmp": { - "version": "0.1.0", - "dev": true, - "requires": { - "rimraf": "^2.6.3" - } - }, - "to-object-path": { - "version": "0.3.0", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "is-buffer": { - "version": "1.1.6", - "dev": true - }, - "kind-of": { - "version": "3.2.2", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "to-readable-stream": { - "version": "1.0.0", - "dev": true, - "optional": true - }, - "to-regex": { - "version": "3.0.2", - "dev": true, - "requires": { - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "regex-not": "^1.0.2", - "safe-regex": "^1.1.0" - } - }, - "toidentifier": { - "version": "1.0.0", - "dev": true, - "optional": true - }, - "tough-cookie": { - "version": "2.5.0", - "dev": true, - "requires": { - "psl": "^1.1.28", - "punycode": "^2.1.1" - } - }, - "trim-right": { - "version": "1.0.1", - "dev": true - }, - "tunnel-agent": { - "version": "0.6.0", - "dev": true, - "requires": { - "safe-buffer": "^5.0.1" - } - }, - "tweetnacl": { - "version": "1.0.3", - "dev": true - }, - "tweetnacl-util": { - "version": "0.15.1", - "dev": true - }, - "type": { - "version": "1.2.0", - "dev": true - }, - "type-is": { - "version": "1.6.18", - "dev": true, - "optional": true, - "requires": { - "media-typer": "0.3.0", - "mime-types": "~2.1.24" - } - }, - "typedarray": { - "version": "0.0.6", - "dev": true - }, - "typedarray-to-buffer": { - "version": "3.1.5", - "dev": true, - "requires": { - "is-typedarray": "^1.0.0" - } - }, - "typewise": { - "version": "1.0.3", - "dev": true, - "requires": { - "typewise-core": "^1.2.0" - } - }, - "typewise-core": { - "version": "1.2.0", - "dev": true - }, - "typewiselite": { - "version": "1.0.0", - "dev": true - }, - "ultron": { - "version": "1.1.1", - "dev": true, - "optional": true - }, - "underscore": { - "version": "1.9.1", - "dev": true, - "optional": true - }, - "union-value": { - "version": "1.0.1", - "dev": true, - "requires": { - "arr-union": "^3.1.0", - "get-value": "^2.0.6", - "is-extendable": "^0.1.1", - "set-value": "^2.0.1" - }, - "dependencies": { - "is-extendable": { - "version": "0.1.1", - "dev": true - } - } - }, - "universalify": { - "version": "0.1.2", - "dev": true - }, - "unorm": { - "version": "1.6.0", - "dev": true - }, - "unpipe": { - "version": "1.0.0", - "dev": true, - "optional": true - }, - "unset-value": { - "version": "1.0.0", - "dev": true, - "requires": { - "has-value": "^0.3.1", - "isobject": "^3.0.0" - }, - "dependencies": { - "has-value": { - "version": "0.3.1", - "dev": true, - "requires": { - "get-value": "^2.0.3", - "has-values": "^0.1.4", - "isobject": "^2.0.0" - }, - "dependencies": { - "isobject": { - "version": "2.1.0", - "dev": true, - "requires": { - "isarray": "1.0.0" - } - } - } - }, - "has-values": { - "version": "0.1.4", - "dev": true - } - } - }, - "uri-js": { - "version": "4.4.1", - "dev": true, - "requires": { - "punycode": "^2.1.0" - } - }, - "urix": { - "version": "0.1.0", - "dev": true - }, - "url-parse-lax": { - "version": "3.0.0", - "dev": true, - "optional": true, - "requires": { - "prepend-http": "^2.0.0" - } - }, - "url-set-query": { - "version": "1.0.0", - "dev": true, - "optional": true - }, - "url-to-options": { - "version": "1.0.1", - "dev": true, - "optional": true - }, - "use": { - "version": "3.1.1", - "dev": true - }, - "utf-8-validate": { - "version": "5.0.4", - "dev": true, - "requires": { - "node-gyp-build": "^4.2.0" - } - }, - "utf8": { - "version": "3.0.0", - "dev": true, - "optional": true - }, - "util-deprecate": { - "version": "1.0.2", - "dev": true - }, - "util.promisify": { - "version": "1.1.1", - "dev": true, - "requires": { - "call-bind": "^1.0.0", - "define-properties": "^1.1.3", - "for-each": "^0.3.3", - "has-symbols": "^1.0.1", - "object.getownpropertydescriptors": "^2.1.1" - } - }, - "utils-merge": { - "version": "1.0.1", - "dev": true, - "optional": true - }, - "uuid": { - "version": "3.4.0", - "dev": true - }, - "varint": { - "version": "5.0.2", - "dev": true, - "optional": true - }, - "vary": { - "version": "1.1.2", - "dev": true, - "optional": true - }, - "verror": { - "version": "1.10.0", - "dev": true, - "requires": { - "assert-plus": "^1.0.0", - "core-util-is": "1.0.2", - "extsprintf": "^1.2.0" - } - }, - "web3": { - "version": "1.2.11", - "dev": true, - "optional": true, - "requires": { - "web3-bzz": "1.2.11", - "web3-core": "1.2.11", - "web3-eth": "1.2.11", - "web3-eth-personal": "1.2.11", - "web3-net": "1.2.11", - "web3-shh": "1.2.11", - "web3-utils": "1.2.11" - } - }, - "web3-bzz": { - "version": "1.2.11", - "dev": true, - "optional": true, - "requires": { - "@types/node": "^12.12.6", - "got": "9.6.0", - "swarm-js": "^0.1.40", - "underscore": "1.9.1" - }, - "dependencies": { - "@types/node": { - "version": "12.19.12", - "dev": true, - "optional": true - } - } - }, - "web3-core": { - "version": "1.2.11", - "dev": true, - "optional": true, - "requires": { - "@types/bn.js": "^4.11.5", - "@types/node": "^12.12.6", - "bignumber.js": "^9.0.0", - "web3-core-helpers": "1.2.11", - "web3-core-method": "1.2.11", - "web3-core-requestmanager": "1.2.11", - "web3-utils": "1.2.11" - }, - "dependencies": { - "@types/node": { - "version": "12.19.12", - "dev": true, - "optional": true - } - } - }, - "web3-core-helpers": { - "version": "1.2.11", - "dev": true, - "optional": true, - "requires": { - "underscore": "1.9.1", - "web3-eth-iban": "1.2.11", - "web3-utils": "1.2.11" - } - }, - "web3-core-method": { - "version": "1.2.11", - "dev": true, - "optional": true, - "requires": { - "@ethersproject/transactions": "^5.0.0-beta.135", - "underscore": "1.9.1", - "web3-core-helpers": "1.2.11", - "web3-core-promievent": "1.2.11", - "web3-core-subscriptions": "1.2.11", - "web3-utils": "1.2.11" - } - }, - "web3-core-promievent": { - "version": "1.2.11", - "dev": true, - "optional": true, - "requires": { - "eventemitter3": "4.0.4" - } - }, - "web3-core-requestmanager": { - "version": "1.2.11", - "dev": true, - "optional": true, - "requires": { - "underscore": "1.9.1", - "web3-core-helpers": "1.2.11", - "web3-providers-http": "1.2.11", - "web3-providers-ipc": "1.2.11", - "web3-providers-ws": "1.2.11" - } - }, - "web3-core-subscriptions": { - "version": "1.2.11", - "dev": true, - "optional": true, - "requires": { - "eventemitter3": "4.0.4", - "underscore": "1.9.1", - "web3-core-helpers": "1.2.11" - } - }, - "web3-eth": { - "version": "1.2.11", - "dev": true, - "optional": true, - "requires": { - "underscore": "1.9.1", - "web3-core": "1.2.11", - "web3-core-helpers": "1.2.11", - "web3-core-method": "1.2.11", - "web3-core-subscriptions": "1.2.11", - "web3-eth-abi": "1.2.11", - "web3-eth-accounts": "1.2.11", - "web3-eth-contract": "1.2.11", - "web3-eth-ens": "1.2.11", - "web3-eth-iban": "1.2.11", - "web3-eth-personal": "1.2.11", - "web3-net": "1.2.11", - "web3-utils": "1.2.11" - } - }, - "web3-eth-abi": { - "version": "1.2.11", - "dev": true, - "optional": true, - "requires": { - "@ethersproject/abi": "5.0.0-beta.153", - "underscore": "1.9.1", - "web3-utils": "1.2.11" - } - }, - "web3-eth-accounts": { - "version": "1.2.11", - "dev": true, - "optional": true, - "requires": { - "crypto-browserify": "3.12.0", - "eth-lib": "0.2.8", - "ethereumjs-common": "^1.3.2", - "ethereumjs-tx": "^2.1.1", - "scrypt-js": "^3.0.1", - "underscore": "1.9.1", - "uuid": "3.3.2", - "web3-core": "1.2.11", - "web3-core-helpers": "1.2.11", - "web3-core-method": "1.2.11", - "web3-utils": "1.2.11" - }, - "dependencies": { - "eth-lib": { - "version": "0.2.8", - "dev": true, - "optional": true, - "requires": { - "bn.js": "^4.11.6", - "elliptic": "^6.4.0", - "xhr-request-promise": "^0.1.2" - } - }, - "uuid": { - "version": "3.3.2", - "dev": true, - "optional": true - } - } - }, - "web3-eth-contract": { - "version": "1.2.11", - "dev": true, - "optional": true, - "requires": { - "@types/bn.js": "^4.11.5", - "underscore": "1.9.1", - "web3-core": "1.2.11", - "web3-core-helpers": "1.2.11", - "web3-core-method": "1.2.11", - "web3-core-promievent": "1.2.11", - "web3-core-subscriptions": "1.2.11", - "web3-eth-abi": "1.2.11", - "web3-utils": "1.2.11" - } - }, - "web3-eth-ens": { - "version": "1.2.11", - "dev": true, - "optional": true, - "requires": { - "content-hash": "^2.5.2", - "eth-ens-namehash": "2.0.8", - "underscore": "1.9.1", - "web3-core": "1.2.11", - "web3-core-helpers": "1.2.11", - "web3-core-promievent": "1.2.11", - "web3-eth-abi": "1.2.11", - "web3-eth-contract": "1.2.11", - "web3-utils": "1.2.11" - } - }, - "web3-eth-iban": { - "version": "1.2.11", - "dev": true, - "optional": true, - "requires": { - "bn.js": "^4.11.9", - "web3-utils": "1.2.11" - } - }, - "web3-eth-personal": { - "version": "1.2.11", - "dev": true, - "optional": true, - "requires": { - "@types/node": "^12.12.6", - "web3-core": "1.2.11", - "web3-core-helpers": "1.2.11", - "web3-core-method": "1.2.11", - "web3-net": "1.2.11", - "web3-utils": "1.2.11" - }, - "dependencies": { - "@types/node": { - "version": "12.19.12", - "dev": true, - "optional": true - } - } - }, - "web3-net": { - "version": "1.2.11", - "dev": true, - "optional": true, - "requires": { - "web3-core": "1.2.11", - "web3-core-method": "1.2.11", - "web3-utils": "1.2.11" - } - }, - "web3-provider-engine": { - "version": "14.2.1", - "dev": true, - "requires": { - "async": "^2.5.0", - "backoff": "^2.5.0", - "clone": "^2.0.0", - "cross-fetch": "^2.1.0", - "eth-block-tracker": "^3.0.0", - "eth-json-rpc-infura": "^3.1.0", - "eth-sig-util": "3.0.0", - "ethereumjs-block": "^1.2.2", - "ethereumjs-tx": "^1.2.0", - "ethereumjs-util": "^5.1.5", - "ethereumjs-vm": "^2.3.4", - "json-rpc-error": "^2.0.0", - "json-stable-stringify": "^1.0.1", - "promise-to-callback": "^1.0.0", - "readable-stream": "^2.2.9", - "request": "^2.85.0", - "semaphore": "^1.0.3", - "ws": "^5.1.1", - "xhr": "^2.2.0", - "xtend": "^4.0.1" - }, - "dependencies": { - "abstract-leveldown": { - "version": "2.6.3", - "dev": true, - "requires": { - "xtend": "~4.0.0" - } - }, - "deferred-leveldown": { - "version": "1.2.2", - "dev": true, - "requires": { - "abstract-leveldown": "~2.6.0" - } - }, - "eth-sig-util": { - "version": "1.4.2", - "dev": true, - "requires": { - "ethereumjs-abi": "git+https://github.com/ethereumjs/ethereumjs-abi.git", - "ethereumjs-util": "^5.1.1" - } - }, - "ethereumjs-account": { - "version": "2.0.5", - "dev": true, - "requires": { - "ethereumjs-util": "^5.0.0", - "rlp": "^2.0.0", - "safe-buffer": "^5.1.1" - } - }, - "ethereumjs-block": { - "version": "1.7.1", - "dev": true, - "requires": { - "async": "^2.0.1", - "ethereum-common": "0.2.0", - "ethereumjs-tx": "^1.2.2", - "ethereumjs-util": "^5.0.0", - "merkle-patricia-tree": "^2.1.2" - }, - "dependencies": { - "ethereum-common": { - "version": "0.2.0", - "dev": true - } - } - }, - "ethereumjs-tx": { - "version": "1.3.7", - "dev": true, - "requires": { - "ethereum-common": "^0.0.18", - "ethereumjs-util": "^5.0.0" - } - }, - "ethereumjs-util": { - "version": "5.2.1", - "dev": true, - "requires": { - "bn.js": "^4.11.0", - "create-hash": "^1.1.2", - "elliptic": "^6.5.2", - "ethereum-cryptography": "^0.1.3", - "ethjs-util": "^0.1.3", - "rlp": "^2.0.0", - "safe-buffer": "^5.1.1" - } - }, - "ethereumjs-vm": { - "version": "2.6.0", - "dev": true, - "requires": { - "async": "^2.1.2", - "async-eventemitter": "^0.2.2", - "ethereumjs-account": "^2.0.3", - "ethereumjs-block": "~2.2.0", - "ethereumjs-common": "^1.1.0", - "ethereumjs-util": "^6.0.0", - "fake-merkle-patricia-tree": "^1.0.1", - "functional-red-black-tree": "^1.0.1", - "merkle-patricia-tree": "^2.3.2", - "rustbn.js": "~0.2.0", - "safe-buffer": "^5.1.1" - }, - "dependencies": { - "ethereumjs-block": { - "version": "2.2.2", - "dev": true, - "requires": { - "async": "^2.0.1", - "ethereumjs-common": "^1.5.0", - "ethereumjs-tx": "^2.1.1", - "ethereumjs-util": "^5.0.0", - "merkle-patricia-tree": "^2.1.2" - }, - "dependencies": { - "ethereumjs-util": { - "version": "5.2.1", - "dev": true, - "requires": { - "bn.js": "^4.11.0", - "create-hash": "^1.1.2", - "elliptic": "^6.5.2", - "ethereum-cryptography": "^0.1.3", - "ethjs-util": "^0.1.3", - "rlp": "^2.0.0", - "safe-buffer": "^5.1.1" - } - } - } - }, - "ethereumjs-tx": { - "version": "2.1.2", - "dev": true, - "requires": { - "ethereumjs-common": "^1.5.0", - "ethereumjs-util": "^6.0.0" - } - }, - "ethereumjs-util": { - "version": "6.2.1", - "dev": true, - "requires": { - "@types/bn.js": "^4.11.3", - "bn.js": "^4.11.0", - "create-hash": "^1.1.2", - "elliptic": "^6.5.2", - "ethereum-cryptography": "^0.1.3", - "ethjs-util": "0.1.6", - "rlp": "^2.2.3" - } - } - } - }, - "isarray": { - "version": "0.0.1", - "dev": true - }, - "level-codec": { - "version": "7.0.1", - "dev": true - }, - "level-errors": { - "version": "1.0.5", - "dev": true, - "requires": { - "errno": "~0.1.1" - } - }, - "level-iterator-stream": { - "version": "1.3.1", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "level-errors": "^1.0.3", - "readable-stream": "^1.0.33", - "xtend": "^4.0.0" - }, - "dependencies": { - "readable-stream": { - "version": "1.1.14", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "0.0.1", - "string_decoder": "~0.10.x" - } - } - } - }, - "level-ws": { - "version": "0.0.0", - "dev": true, - "requires": { - "readable-stream": "~1.0.15", - "xtend": "~2.1.1" - }, - "dependencies": { - "readable-stream": { - "version": "1.0.34", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "0.0.1", - "string_decoder": "~0.10.x" - } - }, - "xtend": { - "version": "2.1.2", - "dev": true, - "requires": { - "object-keys": "~0.4.0" - } - } - } - }, - "levelup": { - "version": "1.3.9", - "dev": true, - "requires": { - "deferred-leveldown": "~1.2.1", - "level-codec": "~7.0.0", - "level-errors": "~1.0.3", - "level-iterator-stream": "~1.3.0", - "prr": "~1.0.1", - "semver": "~5.4.1", - "xtend": "~4.0.0" - } - }, - "ltgt": { - "version": "2.2.1", - "dev": true - }, - "memdown": { - "version": "1.4.1", - "dev": true, - "requires": { - "abstract-leveldown": "~2.7.1", - "functional-red-black-tree": "^1.0.1", - "immediate": "^3.2.3", - "inherits": "~2.0.1", - "ltgt": "~2.2.0", - "safe-buffer": "~5.1.1" - }, - "dependencies": { - "abstract-leveldown": { - "version": "2.7.2", - "dev": true, - "requires": { - "xtend": "~4.0.0" - } - } - } - }, - "merkle-patricia-tree": { - "version": "2.3.2", - "dev": true, - "requires": { - "async": "^1.4.2", - "ethereumjs-util": "^5.0.0", - "level-ws": "0.0.0", - "levelup": "^1.2.1", - "memdown": "^1.0.0", - "readable-stream": "^2.0.0", - "rlp": "^2.0.0", - "semaphore": ">=1.0.1" - }, - "dependencies": { - "async": { - "version": "1.5.2", - "dev": true - } - } - }, - "object-keys": { - "version": "0.4.0", - "dev": true - }, - "safe-buffer": { - "version": "5.1.2", - "dev": true - }, - "semver": { - "version": "5.4.1", - "dev": true - }, - "string_decoder": { - "version": "0.10.31", - "dev": true - }, - "ws": { - "version": "5.2.2", - "dev": true, - "requires": { - "async-limiter": "~1.0.0" - } - } - } - }, - "web3-providers-http": { - "version": "1.2.11", - "dev": true, - "optional": true, - "requires": { - "web3-core-helpers": "1.2.11", - "xhr2-cookies": "1.1.0" - } - }, - "web3-providers-ipc": { - "version": "1.2.11", - "dev": true, - "optional": true, - "requires": { - "oboe": "2.1.4", - "underscore": "1.9.1", - "web3-core-helpers": "1.2.11" - } - }, - "web3-providers-ws": { - "version": "1.2.11", - "dev": true, - "optional": true, - "requires": { - "eventemitter3": "4.0.4", - "underscore": "1.9.1", - "web3-core-helpers": "1.2.11", - "websocket": "^1.0.31" - } - }, - "web3-shh": { - "version": "1.2.11", - "dev": true, - "optional": true, - "requires": { - "web3-core": "1.2.11", - "web3-core-method": "1.2.11", - "web3-core-subscriptions": "1.2.11", - "web3-net": "1.2.11" - } - }, - "web3-utils": { - "version": "1.2.11", - "dev": true, - "optional": true, - "requires": { - "bn.js": "^4.11.9", - "eth-lib": "0.2.8", - "ethereum-bloom-filters": "^1.0.6", - "ethjs-unit": "0.1.6", - "number-to-bn": "1.7.0", - "randombytes": "^2.1.0", - "underscore": "1.9.1", - "utf8": "3.0.0" - }, - "dependencies": { - "eth-lib": { - "version": "0.2.8", - "dev": true, - "optional": true, - "requires": { - "bn.js": "^4.11.6", - "elliptic": "^6.4.0", - "xhr-request-promise": "^0.1.2" - } - } - } - }, - "websocket": { - "version": "1.0.32", - "dev": true, - "requires": { - "bufferutil": "^4.0.1", - "debug": "^2.2.0", - "es5-ext": "^0.10.50", - "typedarray-to-buffer": "^3.1.5", - "utf-8-validate": "^5.0.2", - "yaeti": "^0.0.6" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "ms": { - "version": "2.0.0", - "dev": true - } - } - }, - "whatwg-fetch": { - "version": "2.0.4", - "dev": true - }, - "wrappy": { - "version": "1.0.2", - "dev": true - }, - "ws": { - "version": "3.3.3", - "dev": true, - "optional": true, - "requires": { - "async-limiter": "~1.0.0", - "safe-buffer": "~5.1.0", - "ultron": "~1.1.0" - }, - "dependencies": { - "safe-buffer": { - "version": "5.1.2", - "dev": true, - "optional": true - } - } - }, - "xhr": { - "version": "2.6.0", - "dev": true, - "requires": { - "global": "~4.4.0", - "is-function": "^1.0.1", - "parse-headers": "^2.0.0", - "xtend": "^4.0.0" - } - }, - "xhr-request": { - "version": "1.1.0", - "dev": true, - "optional": true, - "requires": { - "buffer-to-arraybuffer": "^0.0.5", - "object-assign": "^4.1.1", - "query-string": "^5.0.1", - "simple-get": "^2.7.0", - "timed-out": "^4.0.1", - "url-set-query": "^1.0.0", - "xhr": "^2.0.4" - } - }, - "xhr-request-promise": { - "version": "0.1.3", - "dev": true, - "optional": true, - "requires": { - "xhr-request": "^1.1.0" - } - }, - "xhr2-cookies": { - "version": "1.1.0", - "dev": true, - "optional": true, - "requires": { - "cookiejar": "^2.1.1" - } - }, - "xtend": { - "version": "4.0.2", - "dev": true - }, - "yaeti": { - "version": "0.0.6", - "dev": true - }, - "yallist": { - "version": "3.1.1", - "dev": true - } - } - }, - "get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "dev": true - }, - "get-func-name": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.2.tgz", - "integrity": "sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==" - }, - "get-intrinsic": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.1.tgz", - "integrity": "sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw==", - "dev": true, - "requires": { - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-proto": "^1.0.1", - "has-symbols": "^1.0.3" - } - }, - "get-port": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/get-port/-/get-port-3.2.0.tgz", - "integrity": "sha512-x5UJKlgeUiNT8nyo/AcnwLnZuZNcSjSw0kogRB+Whd1fjjFq4B1hySFxSFWWSn4mIBzg3sRNUDFYc4g5gjPoLg==", - "dev": true - }, - "get-stream": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", - "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", - "dev": true, - "requires": { - "pump": "^3.0.0" - } - }, - "get-symbol-description": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz", - "integrity": "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.1.1" - } - }, - "getpass": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", - "integrity": "sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng==", - "dev": true, - "requires": { - "assert-plus": "^1.0.0" - } - }, - "ghost-testrpc": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/ghost-testrpc/-/ghost-testrpc-0.0.2.tgz", - "integrity": "sha512-i08dAEgJ2g8z5buJIrCTduwPIhih3DP+hOCTyyryikfV8T0bNvHnGXO67i0DD1H4GBDETTclPy9njZbfluQYrQ==", - "dev": true, - "requires": { - "chalk": "^2.4.2", - "node-emoji": "^1.10.0" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "glob": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", - "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "requires": { - "is-glob": "^4.0.1" - } - }, - "global": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/global/-/global-4.4.0.tgz", - "integrity": "sha512-wv/LAoHdRE3BeTGz53FAamhGlPLhlssK45usmGFThIi4XqnBmjKQ16u+RNbP7WvigRZDxUsM0J3gcQ5yicaL0w==", - "dev": true, - "requires": { - "min-document": "^2.19.0", - "process": "^0.11.10" - } - }, - "global-modules": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-2.0.0.tgz", - "integrity": "sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A==", - "dev": true, - "requires": { - "global-prefix": "^3.0.0" - } - }, - "global-prefix": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-3.0.0.tgz", - "integrity": "sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg==", - "dev": true, - "requires": { - "ini": "^1.3.5", - "kind-of": "^6.0.2", - "which": "^1.3.1" - }, - "dependencies": { - "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - } - } - }, - "globals": { - "version": "13.20.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.20.0.tgz", - "integrity": "sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ==", - "dev": true, - "requires": { - "type-fest": "^0.20.2" - } - }, - "globalthis": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.3.tgz", - "integrity": "sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==", - "dev": true, - "requires": { - "define-properties": "^1.1.3" - } - }, - "globby": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", - "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", - "dev": true, - "requires": { - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.2.9", - "ignore": "^5.2.0", - "merge2": "^1.4.1", - "slash": "^3.0.0" - } - }, - "gopd": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", - "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", - "dev": true, - "requires": { - "get-intrinsic": "^1.1.3" - } - }, - "got": { - "version": "9.6.0", - "resolved": "https://registry.npmjs.org/got/-/got-9.6.0.tgz", - "integrity": "sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q==", - "dev": true, - "requires": { - "@sindresorhus/is": "^0.14.0", - "@szmarczak/http-timer": "^1.1.2", - "cacheable-request": "^6.0.0", - "decompress-response": "^3.3.0", - "duplexer3": "^0.1.4", - "get-stream": "^4.1.0", - "lowercase-keys": "^1.0.1", - "mimic-response": "^1.0.1", - "p-cancelable": "^1.0.0", - "to-readable-stream": "^1.0.0", - "url-parse-lax": "^3.0.0" - } - }, - "graceful-fs": { - "version": "4.2.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", - "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", - "dev": true - }, - "growl": { - "version": "1.10.5", - "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", - "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", - "dev": true - }, - "handlebars": { - "version": "4.7.7", - "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.7.tgz", - "integrity": "sha512-aAcXm5OAfE/8IXkcZvCepKU3VzW1/39Fb5ZuqMtgI/hT8X2YgoMvBY5dLhq/cpOvw7Lk1nK/UF71aLG/ZnVYRA==", - "dev": true, - "requires": { - "minimist": "^1.2.5", - "neo-async": "^2.6.0", - "source-map": "^0.6.1", - "uglify-js": "^3.1.4", - "wordwrap": "^1.0.0" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - } - } - }, - "har-schema": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", - "integrity": "sha512-Oqluz6zhGX8cyRaTQlFMPw80bSJVG2x/cFb8ZPhUILGgHka9SsokCCOQgpveePerqidZOrT14ipqfJb7ILcW5Q==", - "dev": true - }, - "har-validator": { - "version": "5.1.5", - "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz", - "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==", - "dev": true, - "requires": { - "ajv": "^6.12.3", - "har-schema": "^2.0.0" - } - }, - "hardhat": { - "version": "2.17.0", - "resolved": "https://registry.npmjs.org/hardhat/-/hardhat-2.17.0.tgz", - "integrity": "sha512-CaEGa13tkJNe2/rdaBiive4pmdNShwxvdWVhr1zfb6aVpRhQt9VNO0l/UIBt/zzajz38ZFjvhfM2bj8LDXo9gw==", - "dev": true, - "requires": { - "@ethersproject/abi": "^5.1.2", - "@metamask/eth-sig-util": "^4.0.0", - "@nomicfoundation/ethereumjs-block": "5.0.1", - "@nomicfoundation/ethereumjs-blockchain": "7.0.1", - "@nomicfoundation/ethereumjs-common": "4.0.1", - "@nomicfoundation/ethereumjs-evm": "2.0.1", - "@nomicfoundation/ethereumjs-rlp": "5.0.1", - "@nomicfoundation/ethereumjs-statemanager": "2.0.1", - "@nomicfoundation/ethereumjs-trie": "6.0.1", - "@nomicfoundation/ethereumjs-tx": "5.0.1", - "@nomicfoundation/ethereumjs-util": "9.0.1", - "@nomicfoundation/ethereumjs-vm": "7.0.1", - "@nomicfoundation/solidity-analyzer": "^0.1.0", - "@sentry/node": "^5.18.1", - "@types/bn.js": "^5.1.0", - "@types/lru-cache": "^5.1.0", - "abort-controller": "^3.0.0", - "adm-zip": "^0.4.16", - "aggregate-error": "^3.0.0", - "ansi-escapes": "^4.3.0", - "chalk": "^2.4.2", - "chokidar": "^3.4.0", - "ci-info": "^2.0.0", - "debug": "^4.1.1", - "enquirer": "^2.3.0", - "env-paths": "^2.2.0", - "ethereum-cryptography": "^1.0.3", - "ethereumjs-abi": "^0.6.8", - "find-up": "^2.1.0", - "fp-ts": "1.19.3", - "fs-extra": "^7.0.1", - "glob": "7.2.0", - "immutable": "^4.0.0-rc.12", - "io-ts": "1.10.4", - "keccak": "^3.0.2", - "lodash": "^4.17.11", - "mnemonist": "^0.38.0", - "mocha": "^10.0.0", - "p-map": "^4.0.0", - "raw-body": "^2.4.1", - "resolve": "1.17.0", - "semver": "^6.3.0", - "solc": "0.7.3", - "source-map-support": "^0.5.13", - "stacktrace-parser": "^0.1.10", - "tsort": "0.0.1", - "undici": "^5.14.0", - "uuid": "^8.3.2", - "ws": "^7.4.6" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true - }, - "jsonfile": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz", - "integrity": "sha512-PKllAqbgLgxHaj8TElYymKCAgrASebJrWpTnEkOaTowt23VKXXN0sUeriJ+eh7y6ufb/CC5ap11pz71/cM0hUw==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.6" - } - }, - "resolve": { - "version": "1.17.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", - "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", - "dev": true, - "requires": { - "path-parse": "^1.0.6" - } - }, - "rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "dev": true, - "requires": { - "glob": "^7.1.3" - } - }, - "solc": { - "version": "0.7.3", - "resolved": "https://registry.npmjs.org/solc/-/solc-0.7.3.tgz", - "integrity": "sha512-GAsWNAjGzIDg7VxzP6mPjdurby3IkGCjQcM8GFYZT6RyaoUZKmMU6Y7YwG+tFGhv7dwZ8rmR4iwFDrrD99JwqA==", - "dev": true, - "requires": { - "command-exists": "^1.2.8", - "commander": "3.0.2", - "follow-redirects": "^1.12.1", - "fs-extra": "^0.30.0", - "js-sha3": "0.8.0", - "memorystream": "^0.3.1", - "require-from-string": "^2.0.0", - "semver": "^5.5.0", - "tmp": "0.0.33" - }, - "dependencies": { - "fs-extra": { - "version": "0.30.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-0.30.0.tgz", - "integrity": "sha512-UvSPKyhMn6LEd/WpUaV9C9t3zATuqoqfWc3QdPhPLb58prN9tqYPlPWi8Krxi44loBoUzlobqZ3+8tGpxxSzwA==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "jsonfile": "^2.1.0", - "klaw": "^1.0.0", - "path-is-absolute": "^1.0.0", - "rimraf": "^2.2.8" - } - }, - "semver": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", - "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", - "dev": true - } - } - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "hardhat-gas-reporter": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/hardhat-gas-reporter/-/hardhat-gas-reporter-1.0.9.tgz", - "integrity": "sha512-INN26G3EW43adGKBNzYWOlI3+rlLnasXTwW79YNnUhXPDa+yHESgt639dJEs37gCjhkbNKcRRJnomXEuMFBXJg==", - "dev": true, - "requires": { - "array-uniq": "1.0.3", - "eth-gas-reporter": "^0.2.25", - "sha1": "^1.1.1" - } - }, - "has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "dev": true, - "requires": { - "function-bind": "^1.1.1" - } - }, - "has-bigints": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", - "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==", - "dev": true - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" - }, - "has-property-descriptors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz", - "integrity": "sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==", - "dev": true, - "requires": { - "get-intrinsic": "^1.1.1" - } - }, - "has-proto": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz", - "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==", - "dev": true - }, - "has-symbols": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", - "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", - "dev": true - }, - "has-tostringtag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", - "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", - "dev": true, - "requires": { - "has-symbols": "^1.0.2" - } - }, - "hash-base": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz", - "integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==", - "requires": { - "inherits": "^2.0.4", - "readable-stream": "^3.6.0", - "safe-buffer": "^5.2.0" - }, - "dependencies": { - "safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" - } - } - }, - "hash.js": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", - "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", - "requires": { - "inherits": "^2.0.3", - "minimalistic-assert": "^1.0.1" - } - }, - "he": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", - "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", - "dev": true - }, - "hmac-drbg": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", - "integrity": "sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg==", - "requires": { - "hash.js": "^1.0.3", - "minimalistic-assert": "^1.0.0", - "minimalistic-crypto-utils": "^1.0.1" - } - }, - "hosted-git-info": { - "version": "2.8.9", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", - "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", - "dev": true - }, - "http-basic": { - "version": "8.1.3", - "resolved": "https://registry.npmjs.org/http-basic/-/http-basic-8.1.3.tgz", - "integrity": "sha512-/EcDMwJZh3mABI2NhGfHOGOeOZITqfkEO4p/xK+l3NpyncIHUQBoMvCSF/b5GqvKtySC2srL/GGG3+EtlqlmCw==", - "dev": true, - "requires": { - "caseless": "^0.12.0", - "concat-stream": "^1.6.2", - "http-response-object": "^3.0.1", - "parse-cache-control": "^1.0.1" - } - }, - "http-cache-semantics": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz", - "integrity": "sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==", - "dev": true - }, - "http-errors": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", - "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", - "dev": true, - "requires": { - "depd": "2.0.0", - "inherits": "2.0.4", - "setprototypeof": "1.2.0", - "statuses": "2.0.1", - "toidentifier": "1.0.1" - } - }, - "http-https": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/http-https/-/http-https-1.0.0.tgz", - "integrity": "sha512-o0PWwVCSp3O0wS6FvNr6xfBCHgt0m1tvPLFOCc2iFDKTRAXhB7m8klDf7ErowFH8POa6dVdGatKU5I1YYwzUyg==", - "dev": true - }, - "http-response-object": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/http-response-object/-/http-response-object-3.0.2.tgz", - "integrity": "sha512-bqX0XTF6fnXSQcEJ2Iuyr75yVakyjIDCqroJQ/aHfSdlM743Cwqoi2nDYMzLGWUcuTWGWy8AAvOKXTfiv6q9RA==", - "dev": true, - "requires": { - "@types/node": "^10.0.3" - }, - "dependencies": { - "@types/node": { - "version": "10.17.60", - "resolved": "https://registry.npmjs.org/@types/node/-/node-10.17.60.tgz", - "integrity": "sha512-F0KIgDJfy2nA3zMLmWGKxcH2ZVEtCZXHHdOQs2gSaQ27+lNeEfGxzkIw90aXswATX7AZ33tahPbzy6KAfUreVw==", - "dev": true - } - } - }, - "http-signature": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", - "integrity": "sha512-CAbnr6Rz4CYQkLYUtSNXxQPUH2gK8f3iWexVlsnMeD+GjlsQ0Xsy1cOX+mN3dtxYomRy21CiOzU8Uhw6OwncEQ==", - "dev": true, - "requires": { - "assert-plus": "^1.0.0", - "jsprim": "^1.2.2", - "sshpk": "^1.7.0" - } - }, - "http2-wrapper": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-2.2.0.tgz", - "integrity": "sha512-kZB0wxMo0sh1PehyjJUWRFEd99KC5TLjZ2cULC4f9iqJBAmKQQXEICjxl5iPJRwP40dpeHFqqhm7tYCvODpqpQ==", - "dev": true, - "requires": { - "quick-lru": "^5.1.1", - "resolve-alpn": "^1.2.0" - } - }, - "https-proxy-agent": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", - "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", - "dev": true, - "requires": { - "agent-base": "6", - "debug": "4" - } - }, - "iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "dev": true, - "requires": { - "safer-buffer": ">= 2.1.2 < 3" - } - }, - "idna-uts46-hx": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/idna-uts46-hx/-/idna-uts46-hx-2.3.1.tgz", - "integrity": "sha512-PWoF9Keq6laYdIRwwCdhTPl60xRqAloYNMQLiyUnG42VjT53oW07BXIRM+NK7eQjzXjAk2gUvX9caRxlnF9TAA==", - "dev": true, - "requires": { - "punycode": "2.1.0" - } - }, - "ieee754": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", - "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==" - }, - "ignore": { - "version": "5.2.4", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", - "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==", - "dev": true - }, - "immutable": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.3.1.tgz", - "integrity": "sha512-lj9cnmB/kVS0QHsJnYKD1uo3o39nrbKxszjnqS9Fr6NB7bZzW45U6WSGBPKXDL/CvDKqDNPA4r3DoDQ8GTxo2A==", - "dev": true - }, - "import-fresh": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", - "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", - "dev": true, - "requires": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" - } - }, - "imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", - "dev": true - }, - "indent-string": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", - "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", - "dev": true - }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", - "dev": true, - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, - "ini": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", - "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", - "dev": true - }, - "internal-slot": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.5.tgz", - "integrity": "sha512-Y+R5hJrzs52QCG2laLn4udYVnxsfny9CpOhNhUvk/SSSVyF6T27FzRbF0sroPidSu3X8oEAkOn2K804mjpt6UQ==", - "dev": true, - "requires": { - "get-intrinsic": "^1.2.0", - "has": "^1.0.3", - "side-channel": "^1.0.4" - } - }, - "interpret": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz", - "integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==", - "dev": true - }, - "invert-kv": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz", - "integrity": "sha512-xgs2NH9AE66ucSq4cNG1nhSFghr5l6tdL15Pk+jl46bmmBapgoaY/AacXyaDznAqmGL99TiLSQgO/XazFSKYeQ==", - "dev": true - }, - "io-ts": { - "version": "1.10.4", - "resolved": "https://registry.npmjs.org/io-ts/-/io-ts-1.10.4.tgz", - "integrity": "sha512-b23PteSnYXSONJ6JQXRAlvJhuw8KOtkqa87W4wDtvMrud/DTJd5X+NpOOI+O/zZwVq6v0VLAaJ+1EDViKEuN9g==", - "dev": true, - "requires": { - "fp-ts": "^1.0.0" - } - }, - "ipaddr.js": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", - "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", - "dev": true - }, - "is-arguments": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz", - "integrity": "sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - } - }, - "is-array-buffer": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.2.tgz", - "integrity": "sha512-y+FyyR/w8vfIRq4eQcM1EYgSTnmHXPqaF+IgzgraytCFq5Xh8lllDVmAZolPJiZttZLeFSINPYMaEJ7/vWUa1w==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.2.0", - "is-typed-array": "^1.1.10" - } - }, - "is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", - "dev": true - }, - "is-bigint": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", - "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", - "dev": true, - "requires": { - "has-bigints": "^1.0.1" - } - }, - "is-binary-path": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "dev": true, - "requires": { - "binary-extensions": "^2.0.0" - } - }, - "is-boolean-object": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", - "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - } - }, - "is-buffer": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.5.tgz", - "integrity": "sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==", - "dev": true - }, - "is-callable": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", - "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", - "dev": true - }, - "is-ci": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz", - "integrity": "sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==", - "dev": true, - "requires": { - "ci-info": "^2.0.0" - } - }, - "is-core-module": { - "version": "2.12.1", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.12.1.tgz", - "integrity": "sha512-Q4ZuBAe2FUsKtyQJoQHlvP8OvBERxO3jEmy1I7hcRXcJBGGHFh/aJBswbXuS9sgrDH2QUO8ilkwNPHvHMd8clg==", - "dev": true, - "requires": { - "has": "^1.0.3" - } - }, - "is-date-object": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", - "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", - "dev": true, - "requires": { - "has-tostringtag": "^1.0.0" - } - }, - "is-docker": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", - "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", - "dev": true - }, - "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==", - "dev": true - }, - "is-function": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-function/-/is-function-1.0.2.tgz", - "integrity": "sha512-lw7DUp0aWXYg+CBCN+JKkcE0Q2RayZnSvnZBlwgxHBQhqt5pZNVy4Ri7H9GmmXkdu7LUthszM+Tor1u/2iBcpQ==", - "dev": true - }, - "is-generator-function": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz", - "integrity": "sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==", - "dev": true, - "requires": { - "has-tostringtag": "^1.0.0" - } - }, - "is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "dev": true, - "requires": { - "is-extglob": "^2.1.1" - } - }, - "is-hex-prefixed": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-hex-prefixed/-/is-hex-prefixed-1.0.0.tgz", - "integrity": "sha512-WvtOiug1VFrE9v1Cydwm+FnXd3+w9GaeVUss5W4v/SLy3UW00vP+6iNF2SdnfiBoLy4bTqVdkftNGTUeOFVsbA==" - }, - "is-negative-zero": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz", - "integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==", - "dev": true - }, - "is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true - }, - "is-number-object": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", - "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==", - "dev": true, - "requires": { - "has-tostringtag": "^1.0.0" - } - }, - "is-plain-obj": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", - "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", - "dev": true - }, - "is-regex": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", - "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - } - }, - "is-shared-array-buffer": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz", - "integrity": "sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==", - "dev": true, - "requires": { - "call-bind": "^1.0.2" - } - }, - "is-string": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", - "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", - "dev": true, - "requires": { - "has-tostringtag": "^1.0.0" - } - }, - "is-symbol": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", - "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", - "dev": true, - "requires": { - "has-symbols": "^1.0.2" - } - }, - "is-typed-array": { - "version": "1.1.12", - "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.12.tgz", - "integrity": "sha512-Z14TF2JNG8Lss5/HMqt0//T9JeHXttXy5pH/DBU4vi98ozO2btxzq9MwYDZYnKwU8nRsz/+GVFVRDq3DkVuSPg==", - "dev": true, - "requires": { - "which-typed-array": "^1.1.11" - } - }, - "is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==", - "dev": true - }, - "is-unicode-supported": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", - "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", - "dev": true - }, - "is-url": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/is-url/-/is-url-1.2.4.tgz", - "integrity": "sha512-ITvGim8FhRiYe4IQ5uHSkj7pVaPDrCTkNd3yq3cV7iZAcJdHTUMPMEHcqSOy9xZ9qFenQCvi+2wjH9a1nXqHww==", - "dev": true - }, - "is-utf8": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", - "integrity": "sha512-rMYPYvCzsXywIsldgLaSoPlw5PfoB/ssr7hY4pLfcodrA5M/eArza1a9VmTiNIBNMjOGr1Ow9mTyU2o69U6U9Q==", - "dev": true - }, - "is-weakref": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", - "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", - "dev": true, - "requires": { - "call-bind": "^1.0.2" - } - }, - "is-wsl": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", - "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", - "dev": true, - "requires": { - "is-docker": "^2.0.0" - } - }, - "isarray": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", - "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", - "dev": true - }, - "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "dev": true - }, - "isstream": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", - "integrity": "sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==", - "dev": true - }, - "js-sdsl": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.4.1.tgz", - "integrity": "sha512-6Gsx8R0RucyePbWqPssR8DyfuXmLBooYN5cZFZKjHGnQuaf7pEzhtpceagJxVu4LqhYY5EYA7nko3FmeHZ1KbA==", - "dev": true - }, - "js-sha3": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.8.0.tgz", - "integrity": "sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q==" - }, - "js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true - }, - "js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", - "dev": true, - "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - } - }, - "jsbn": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==", - "dev": true - }, - "json-buffer": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.0.tgz", - "integrity": "sha512-CuUqjv0FUZIdXkHPI8MezCnFCdaTAacej1TZYulLoAg1h/PhwkdXFN4V/gzY4g+fMBCOV2xF+rp7t2XD2ns/NQ==", - "dev": true - }, - "json-parse-even-better-errors": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", - "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", - "dev": true - }, - "json-schema": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz", - "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==", - "dev": true - }, - "json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true - }, - "json-stable-stringify-without-jsonify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", - "dev": true - }, - "json-stringify-safe": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==", - "dev": true - }, - "json5": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", - "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", - "dev": true, - "requires": { - "minimist": "^1.2.0" - } - }, - "jsonfile": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.6" - } - }, - "jsonschema": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/jsonschema/-/jsonschema-1.4.1.tgz", - "integrity": "sha512-S6cATIPVv1z0IlxdN+zUk5EPjkGCdnhN4wVSBlvoUO1tOLJootbo9CquNJmbIh4yikWHiUedhRYrNPn1arpEmQ==", - "dev": true - }, - "jsprim": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.2.tgz", - "integrity": "sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw==", - "dev": true, - "requires": { - "assert-plus": "1.0.0", - "extsprintf": "1.3.0", - "json-schema": "0.4.0", - "verror": "1.10.0" - } - }, - "keccak": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/keccak/-/keccak-3.0.3.tgz", - "integrity": "sha512-JZrLIAJWuZxKbCilMpNz5Vj7Vtb4scDG3dMXLOsbzBmQGyjwE61BbW7bJkfKKCShXiQZt3T6sBgALRtmd+nZaQ==", - "requires": { - "node-addon-api": "^2.0.0", - "node-gyp-build": "^4.2.0", - "readable-stream": "^3.6.0" - } - }, - "keccak256": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/keccak256/-/keccak256-1.0.6.tgz", - "integrity": "sha512-8GLiM01PkdJVGUhR1e6M/AvWnSqYS0HaERI+K/QtStGDGlSTx2B1zTqZk4Zlqu5TxHJNTxWAdP9Y+WI50OApUw==", - "requires": { - "bn.js": "^5.2.0", - "buffer": "^6.0.3", - "keccak": "^3.0.2" - } - }, - "keyv": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/keyv/-/keyv-3.1.0.tgz", - "integrity": "sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA==", - "dev": true, - "requires": { - "json-buffer": "3.0.0" - } - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - }, - "klaw": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/klaw/-/klaw-1.3.1.tgz", - "integrity": "sha512-TED5xi9gGQjGpNnvRWknrwAB1eL5GciPfVFOt3Vk1OJCVDQbzuSfrF3hkUQKlsgKrG1F+0t5W0m+Fje1jIt8rw==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.9" - } - }, - "klaw-sync": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/klaw-sync/-/klaw-sync-6.0.0.tgz", - "integrity": "sha512-nIeuVSzdCCs6TDPTqI8w1Yre34sSq7AkZ4B3sfOBbI2CgVSB4Du4aLQijFU2+lhAFCwt9+42Hel6lQNIv6AntQ==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.11" - } - }, - "lcid": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz", - "integrity": "sha512-YiGkH6EnGrDGqLMITnGjXtGmNtjoXw9SVUzcaos8RBi7Ps0VBylkq+vOcY9QE5poLasPCR849ucFUkl0UzUyOw==", - "dev": true, - "requires": { - "invert-kv": "^1.0.0" - } - }, - "level": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/level/-/level-8.0.0.tgz", - "integrity": "sha512-ypf0jjAk2BWI33yzEaaotpq7fkOPALKAgDBxggO6Q9HGX2MRXn0wbP1Jn/tJv1gtL867+YOjOB49WaUF3UoJNQ==", - "dev": true, - "requires": { - "browser-level": "^1.0.1", - "classic-level": "^1.2.0" - } - }, - "level-supports": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/level-supports/-/level-supports-4.0.1.tgz", - "integrity": "sha512-PbXpve8rKeNcZ9C1mUicC9auIYFyGpkV9/i6g76tLgANwWhtG2v7I4xNBUlkn3lE2/dZF3Pi0ygYGtLc4RXXdA==", - "dev": true - }, - "level-transcoder": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/level-transcoder/-/level-transcoder-1.0.1.tgz", - "integrity": "sha512-t7bFwFtsQeD8cl8NIoQ2iwxA0CL/9IFw7/9gAjOonH0PWTTiRfY7Hq+Ejbsxh86tXobDQ6IOiddjNYIfOBs06w==", - "dev": true, - "requires": { - "buffer": "^6.0.3", - "module-error": "^1.0.1" - } - }, - "levn": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", - "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", - "dev": true, - "requires": { - "prelude-ls": "^1.2.1", - "type-check": "~0.4.0" - } - }, - "lines-and-columns": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", - "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", - "dev": true - }, - "load-json-file": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", - "integrity": "sha512-cy7ZdNRXdablkXYNI049pthVeXFurRyb9+hA/dZzerZ0pGTx42z+y+ssxBaVV2l70t1muq5IdKhn4UtcoGUY9A==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "parse-json": "^2.2.0", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0", - "strip-bom": "^2.0.0" - }, - "dependencies": { - "parse-json": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", - "integrity": "sha512-QR/GGaKCkhwk1ePQNYDRKYZ3mwU9ypsKhB0XyFnLQdomyEqk3e8wpW3V5Jp88zbxK4n5ST1nqo+g9juTpownhQ==", - "dev": true, - "requires": { - "error-ex": "^1.2.0" - } - }, - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", - "dev": true - }, - "strip-bom": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", - "integrity": "sha512-kwrX1y7czp1E69n2ajbG65mIo9dqvJ+8aBQXOGVxqwvNbsXdFM6Lq37dLAY3mknUwru8CfcCbfOLL/gMo+fi3g==", - "dev": true, - "requires": { - "is-utf8": "^0.2.0" - } - } - } - }, - "locate-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", - "integrity": "sha512-NCI2kiDkyR7VeEKm27Kda/iQHyKJe1Bu0FlTbYp3CqJu+9IFe9bLyAjMxf5ZDDbEg+iMPzB5zYyUTSm8wVTKmA==", - "dev": true, - "requires": { - "p-locate": "^2.0.0", - "path-exists": "^3.0.0" - } - }, - "lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" - }, - "lodash.assign": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/lodash.assign/-/lodash.assign-4.2.0.tgz", - "integrity": "sha512-hFuH8TY+Yji7Eja3mGiuAxBqLagejScbG8GbG0j6o9vzn0YL14My+ktnqtZgFTosKymC9/44wP6s7xyuLfnClw==", - "dev": true - }, - "lodash.merge": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", - "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", - "dev": true - }, - "lodash.truncate": { - "version": "4.4.2", - "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz", - "integrity": "sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw==", - "dev": true - }, - "log-symbols": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", - "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", - "dev": true, - "requires": { - "chalk": "^4.1.0", - "is-unicode-supported": "^0.1.0" - } - }, - "loupe": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.6.tgz", - "integrity": "sha512-RaPMZKiMy8/JruncMU5Bt6na1eftNoo++R4Y+N2FrxkDVTrGvcyzFTsaGif4QTeKESheMGegbhw6iUAq+5A8zA==", - "requires": { - "get-func-name": "^2.0.0" - } - }, - "lowercase-keys": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz", - "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==", - "dev": true - }, - "lru_map": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/lru_map/-/lru_map-0.3.3.tgz", - "integrity": "sha512-Pn9cox5CsMYngeDbmChANltQl+5pi6XmTrraMSzhPmMBbmgcxmqWry0U3PGapCU1yB4/LqCcom7qhHZiF/jGfQ==", - "dev": true - }, - "lru-cache": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", - "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", - "dev": true, - "requires": { - "yallist": "^3.0.2" - } - }, - "make-error": { - "version": "1.3.6", - "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", - "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", - "dev": true - }, - "markdown-table": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-1.1.3.tgz", - "integrity": "sha512-1RUZVgQlpJSPWYbFSpmudq5nHY1doEIv89gBtF0s4gW1GF2XorxcA/70M5vq7rLv0a6mhOUccRsqkwhwLCIQ2Q==", - "dev": true - }, - "mcl-wasm": { - "version": "0.7.9", - "resolved": "https://registry.npmjs.org/mcl-wasm/-/mcl-wasm-0.7.9.tgz", - "integrity": "sha512-iJIUcQWA88IJB/5L15GnJVnSQJmf/YaxxV6zRavv83HILHaJQb6y0iFyDMdDO0gN8X37tdxmAOrH/P8B6RB8sQ==", - "dev": true - }, - "md5.js": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", - "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", - "requires": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "media-typer": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", - "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", - "dev": true - }, - "memory-level": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/memory-level/-/memory-level-1.0.0.tgz", - "integrity": "sha512-UXzwewuWeHBz5krr7EvehKcmLFNoXxGcvuYhC41tRnkrTbJohtS7kVn9akmgirtRygg+f7Yjsfi8Uu5SGSQ4Og==", - "dev": true, - "requires": { - "abstract-level": "^1.0.0", - "functional-red-black-tree": "^1.0.1", - "module-error": "^1.0.1" - } - }, - "memorystream": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/memorystream/-/memorystream-0.3.1.tgz", - "integrity": "sha512-S3UwM3yj5mtUSEfP41UZmt/0SCoVYUcU1rkXv+BQ5Ig8ndL4sPoJNBUJERafdPb5jjHJGuMgytgKvKIf58XNBw==", - "dev": true - }, - "merge-descriptors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", - "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==", - "dev": true - }, - "merge2": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", - "dev": true - }, - "merkletreejs": { - "version": "0.3.11", - "resolved": "https://registry.npmjs.org/merkletreejs/-/merkletreejs-0.3.11.tgz", - "integrity": "sha512-LJKTl4iVNTndhL+3Uz/tfkjD0klIWsHlUzgtuNnNrsf7bAlXR30m+xYB7lHr5Z/l6e/yAIsr26Dabx6Buo4VGQ==", - "requires": { - "bignumber.js": "^9.0.1", - "buffer-reverse": "^1.0.1", - "crypto-js": "^4.2.0", - "treeify": "^1.1.0", - "web3-utils": "^1.3.4" - } - }, - "methods": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", - "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", - "dev": true - }, - "micromatch": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", - "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", - "dev": true, - "requires": { - "braces": "^3.0.2", - "picomatch": "^2.3.1" - } - }, - "miller-rabin": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", - "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==", - "dev": true, - "requires": { - "bn.js": "^4.0.0", - "brorand": "^1.0.1" - }, - "dependencies": { - "bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", - "dev": true - } - } - }, - "mime": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", - "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", - "dev": true - }, - "mime-db": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", - "dev": true - }, - "mime-types": { - "version": "2.1.35", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", - "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", - "dev": true, - "requires": { - "mime-db": "1.52.0" - } - }, - "mimic-response": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", - "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==", - "dev": true - }, - "min-document": { - "version": "2.19.0", - "resolved": "https://registry.npmjs.org/min-document/-/min-document-2.19.0.tgz", - "integrity": "sha512-9Wy1B3m3f66bPPmU5hdA4DR4PB2OfDU/+GS3yAB7IQozE3tqXaVv2zOjgla7MEGSRv95+ILmOuvhLkOK6wJtCQ==", - "dev": true, - "requires": { - "dom-walk": "^0.1.0" - } - }, - "minimalistic-assert": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", - "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==" - }, - "minimalistic-crypto-utils": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", - "integrity": "sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg==" - }, - "minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "minimist": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", - "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", - "dev": true - }, - "minipass": { - "version": "2.9.0", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.9.0.tgz", - "integrity": "sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg==", - "dev": true, - "requires": { - "safe-buffer": "^5.1.2", - "yallist": "^3.0.0" - } - }, - "minizlib": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-1.3.3.tgz", - "integrity": "sha512-6ZYMOEnmVsdCeTJVE0W9ZD+pVnE8h9Hma/iOwwRDsdQoePpoX56/8B6z3P9VNwppJuBKNRuFDRNRqRWexT9G9Q==", - "dev": true, - "requires": { - "minipass": "^2.9.0" - } - }, - "mkdirp": { - "version": "0.5.6", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", - "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", - "dev": true, - "requires": { - "minimist": "^1.2.6" - } - }, - "mkdirp-promise": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/mkdirp-promise/-/mkdirp-promise-5.0.1.tgz", - "integrity": "sha512-Hepn5kb1lJPtVW84RFT40YG1OddBNTOVUZR2bzQUHc+Z03en8/3uX0+060JDhcEzyO08HmipsN9DcnFMxhIL9w==", - "dev": true, - "requires": { - "mkdirp": "*" - } - }, - "mnemonist": { - "version": "0.38.5", - "resolved": "https://registry.npmjs.org/mnemonist/-/mnemonist-0.38.5.tgz", - "integrity": "sha512-bZTFT5rrPKtPJxj8KSV0WkPyNxl72vQepqqVUAW2ARUpUSF2qXMB6jZj7hW5/k7C1rtpzqbD/IIbJwLXUjCHeg==", - "dev": true, - "requires": { - "obliterator": "^2.0.0" - } - }, - "mocha": { - "version": "10.2.0", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.2.0.tgz", - "integrity": "sha512-IDY7fl/BecMwFHzoqF2sg/SHHANeBoMMXFlS9r0OXKDssYE1M5O43wUY/9BVPeIvfH2zmEbBfseqN9gBQZzXkg==", - "dev": true, - "requires": { - "ansi-colors": "4.1.1", - "browser-stdout": "1.3.1", - "chokidar": "3.5.3", - "debug": "4.3.4", - "diff": "5.0.0", - "escape-string-regexp": "4.0.0", - "find-up": "5.0.0", - "glob": "7.2.0", - "he": "1.2.0", - "js-yaml": "4.1.0", - "log-symbols": "4.1.0", - "minimatch": "5.0.1", - "ms": "2.1.3", - "nanoid": "3.3.3", - "serialize-javascript": "6.0.0", - "strip-json-comments": "3.1.1", - "supports-color": "8.1.1", - "workerpool": "6.2.1", - "yargs": "16.2.0", - "yargs-parser": "20.2.4", - "yargs-unparser": "2.0.0" - }, - "dependencies": { - "ansi-colors": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", - "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", - "dev": true - }, - "argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true - }, - "brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "requires": { - "balanced-match": "^1.0.0" - } - }, - "find-up": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", - "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", - "dev": true, - "requires": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" - } - }, - "js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dev": true, - "requires": { - "argparse": "^2.0.1" - } - }, - "locate-path": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", - "dev": true, - "requires": { - "p-locate": "^5.0.0" - } - }, - "minimatch": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.0.1.tgz", - "integrity": "sha512-nLDxIFRyhDblz3qMuq+SoRZED4+miJ/G+tdDrjkkkRnjAsBexeGpgjLEQ0blJy7rHhR2b93rhQY4SvyWu9v03g==", - "dev": true, - "requires": { - "brace-expansion": "^2.0.1" - } - }, - "ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true - }, - "p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "dev": true, - "requires": { - "yocto-queue": "^0.1.0" - } - }, - "p-locate": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", - "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", - "dev": true, - "requires": { - "p-limit": "^3.0.2" - } - }, - "path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true - }, - "supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - } - } - }, - "mock-fs": { - "version": "4.14.0", - "resolved": "https://registry.npmjs.org/mock-fs/-/mock-fs-4.14.0.tgz", - "integrity": "sha512-qYvlv/exQ4+svI3UOvPUpLDF0OMX5euvUH0Ny4N5QyRyhNdgAgUrVH3iUINSzEPLvx0kbo/Bp28GJKIqvE7URw==", - "dev": true - }, - "module-error": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/module-error/-/module-error-1.0.2.tgz", - "integrity": "sha512-0yuvsqSCv8LbaOKhnsQ/T5JhyFlCYLPXK3U2sgV10zoKQwzs/MyfuQUOZQ1V/6OCOJsK/TRgNVrPuPDqtdMFtA==", - "dev": true - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, - "multibase": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/multibase/-/multibase-0.6.1.tgz", - "integrity": "sha512-pFfAwyTjbbQgNc3G7D48JkJxWtoJoBMaR4xQUOuB8RnCgRqaYmWNFeJTTvrJ2w51bjLq2zTby6Rqj9TQ9elSUw==", - "dev": true, - "requires": { - "base-x": "^3.0.8", - "buffer": "^5.5.0" - }, - "dependencies": { - "buffer": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", - "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", - "dev": true, - "requires": { - "base64-js": "^1.3.1", - "ieee754": "^1.1.13" - } - } - } - }, - "multicodec": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/multicodec/-/multicodec-0.5.7.tgz", - "integrity": "sha512-PscoRxm3f+88fAtELwUnZxGDkduE2HD9Q6GHUOywQLjOGT/HAdhjLDYNZ1e7VR0s0TP0EwZ16LNUTFpoBGivOA==", - "dev": true, - "requires": { - "varint": "^5.0.0" - } - }, - "multihashes": { - "version": "0.4.21", - "resolved": "https://registry.npmjs.org/multihashes/-/multihashes-0.4.21.tgz", - "integrity": "sha512-uVSvmeCWf36pU2nB4/1kzYZjsXD9vofZKpgudqkceYY5g2aZZXJ5r9lxuzoRLl1OAp28XljXsEJ/X/85ZsKmKw==", - "dev": true, - "requires": { - "buffer": "^5.5.0", - "multibase": "^0.7.0", - "varint": "^5.0.0" - }, - "dependencies": { - "buffer": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", - "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", - "dev": true, - "requires": { - "base64-js": "^1.3.1", - "ieee754": "^1.1.13" - } - }, - "multibase": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/multibase/-/multibase-0.7.0.tgz", - "integrity": "sha512-TW8q03O0f6PNFTQDvh3xxH03c8CjGaaYrjkl9UQPG6rz53TQzzxJVCIWVjzcbN/Q5Y53Zd0IBQBMVktVgNx4Fg==", - "dev": true, - "requires": { - "base-x": "^3.0.8", - "buffer": "^5.5.0" - } - } - } - }, - "nano-json-stream-parser": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/nano-json-stream-parser/-/nano-json-stream-parser-0.1.2.tgz", - "integrity": "sha512-9MqxMH/BSJC7dnLsEMPyfN5Dvoo49IsPFYMcHw3Bcfc2kN0lpHRBSzlMSVx4HGyJ7s9B31CyBTVehWJoQ8Ctew==", - "dev": true - }, - "nanoid": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.3.tgz", - "integrity": "sha512-p1sjXuopFs0xg+fPASzQ28agW1oHD7xDsd9Xkf3T15H3c/cifrFHVwrh74PdoklAPi+i7MdRsE47vm2r6JoB+w==", - "dev": true - }, - "napi-macros": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/napi-macros/-/napi-macros-2.2.2.tgz", - "integrity": "sha512-hmEVtAGYzVQpCKdbQea4skABsdXW4RUh5t5mJ2zzqowJS2OyXZTU1KhDVFhx+NlWZ4ap9mqR9TcDO3LTTttd+g==", - "dev": true - }, - "natural-compare": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", - "dev": true - }, - "negotiator": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", - "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", - "dev": true - }, - "neo-async": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", - "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", - "dev": true - }, - "next-tick": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.1.0.tgz", - "integrity": "sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ==", - "dev": true - }, - "nice-try": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", - "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", - "dev": true - }, - "node-addon-api": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-2.0.2.tgz", - "integrity": "sha512-Ntyt4AIXyaLIuMHF6IOoTakB3K+RWxwtsHNRxllEoA6vPwP9o4866g6YWDLUdnucilZhmkxiHwHr11gAENw+QA==" - }, - "node-emoji": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/node-emoji/-/node-emoji-1.11.0.tgz", - "integrity": "sha512-wo2DpQkQp7Sjm2A0cq+sN7EHKO6Sl0ctXeBdFZrL9T9+UywORbufTcTZxom8YqpLQt/FqNMUkOpkZrJVYSKD3A==", - "dev": true, - "requires": { - "lodash": "^4.17.21" - } - }, - "node-environment-flags": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/node-environment-flags/-/node-environment-flags-1.0.6.tgz", - "integrity": "sha512-5Evy2epuL+6TM0lCQGpFIj6KwiEsGh1SrHUhTbNX+sLbBtjidPZFAnVK9y5yU1+h//RitLbRHTIMyxQPtxMdHw==", - "dev": true, - "requires": { - "object.getownpropertydescriptors": "^2.0.3", - "semver": "^5.7.0" - }, - "dependencies": { - "semver": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", - "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", - "dev": true - } - } - }, - "node-fetch": { - "version": "2.6.12", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.12.tgz", - "integrity": "sha512-C/fGU2E8ToujUivIO0H+tpQ6HWo4eEmchoPIoXtxCrVghxdKq+QOHqEZW7tuP3KlV3bC8FRMO5nMCC7Zm1VP6g==", - "requires": { - "whatwg-url": "^5.0.0" - } - }, - "node-gyp-build": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.6.0.tgz", - "integrity": "sha512-NTZVKn9IylLwUzaKjkas1e4u2DLNcV4rdYagA4PWdPwW87Bi7z+BznyKSRwS/761tV/lzCGXplWsiaMjLqP2zQ==" - }, - "nofilter": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/nofilter/-/nofilter-3.1.0.tgz", - "integrity": "sha512-l2NNj07e9afPnhAhvgVrCD/oy2Ai1yfLpuo3EpiO1jFTsB4sFz6oIfAfSZyQzVpkZQ9xS8ZS5g1jCBgq4Hwo0g==", - "dev": true - }, - "nopt": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz", - "integrity": "sha512-4GUt3kSEYmk4ITxzB/b9vaIDfUVWN/Ml1Fwl11IlnIG2iaJ9O6WXZ9SrYM9NLI8OCBieN2Y8SWC2oJV0RQ7qYg==", - "dev": true, - "requires": { - "abbrev": "1" - } - }, - "normalize-package-data": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", - "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", - "dev": true, - "requires": { - "hosted-git-info": "^2.1.4", - "resolve": "^1.10.0", - "semver": "2 || 3 || 4 || 5", - "validate-npm-package-license": "^3.0.1" - }, - "dependencies": { - "semver": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", - "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", - "dev": true - } - } - }, - "normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true - }, - "normalize-url": { - "version": "4.5.1", - "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.1.tgz", - "integrity": "sha512-9UZCFRHQdNrfTpGg8+1INIg93B6zE0aXMVFkw1WFwvO4SlZywU6aLg5Of0Ap/PgcbSw4LNxvMWXMeugwMCX0AA==", - "dev": true - }, - "number-is-nan": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", - "integrity": "sha512-4jbtZXNAsfZbAHiiqjLPBiCl16dES1zI4Hpzzxw61Tk+loF+sBDBKx1ICKKKwIqQ7M0mFn1TmkN7euSncWgHiQ==", - "dev": true - }, - "number-to-bn": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/number-to-bn/-/number-to-bn-1.7.0.tgz", - "integrity": "sha512-wsJ9gfSz1/s4ZsJN01lyonwuxA1tml6X1yBDnfpMglypcBRFZZkus26EdPSlqS5GJfYddVZa22p3VNb3z5m5Ig==", - "requires": { - "bn.js": "4.11.6", - "strip-hex-prefix": "1.0.0" - }, - "dependencies": { - "bn.js": { - "version": "4.11.6", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.6.tgz", - "integrity": "sha512-XWwnNNFCuuSQ0m3r3C4LE3EiORltHd9M05pq6FOlVeiophzRbMo50Sbz1ehl8K3Z+jw9+vmgnXefY1hz8X+2wA==" - } - } - }, - "oauth-sign": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", - "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", - "dev": true - }, - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", - "dev": true - }, - "object-inspect": { - "version": "1.12.3", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.3.tgz", - "integrity": "sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==", - "dev": true - }, - "object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", - "dev": true - }, - "object.assign": { - "version": "4.1.4", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.4.tgz", - "integrity": "sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "has-symbols": "^1.0.3", - "object-keys": "^1.1.1" - } - }, - "object.getownpropertydescriptors": { - "version": "2.1.6", - "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.6.tgz", - "integrity": "sha512-lq+61g26E/BgHv0ZTFgRvi7NMEPuAxLkFU7rukXjc/AlwH4Am5xXVnIXy3un1bg/JPbXHrixRkK1itUzzPiIjQ==", - "dev": true, - "requires": { - "array.prototype.reduce": "^1.0.5", - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.21.2", - "safe-array-concat": "^1.0.0" - } - }, - "object.values": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.6.tgz", - "integrity": "sha512-FVVTkD1vENCsAcwNs9k6jea2uHC/X0+JcjG8YA60FN5CMaJmG95wT9jek/xX9nornqGRrBkKtzuAu2wuHpKqvw==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4" - } - }, - "obliterator": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/obliterator/-/obliterator-2.0.4.tgz", - "integrity": "sha512-lgHwxlxV1qIg1Eap7LgIeoBWIMFibOjbrYPIPJZcI1mmGAI2m3lNYpK12Y+GBdPQ0U1hRwSord7GIaawz962qQ==", - "dev": true - }, - "oboe": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/oboe/-/oboe-2.1.5.tgz", - "integrity": "sha512-zRFWiF+FoicxEs3jNI/WYUrVEgA7DeET/InK0XQuudGHRg8iIob3cNPrJTKaz4004uaA9Pbe+Dwa8iluhjLZWA==", - "dev": true, - "requires": { - "http-https": "^1.0.0" - } - }, - "on-finished": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", - "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", - "dev": true, - "requires": { - "ee-first": "1.1.1" - } - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "dev": true, - "requires": { - "wrappy": "1" - } - }, - "open": { - "version": "7.4.2", - "resolved": "https://registry.npmjs.org/open/-/open-7.4.2.tgz", - "integrity": "sha512-MVHddDVweXZF3awtlAS+6pgKLlm/JgxZ90+/NBurBoQctVOOB/zDdVjcyPzQ+0laDGbsWgrRkflI65sQeOgT9Q==", - "dev": true, - "requires": { - "is-docker": "^2.0.0", - "is-wsl": "^2.1.1" - } - }, - "optionator": { - "version": "0.9.3", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", - "integrity": "sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==", - "dev": true, - "requires": { - "@aashutoshrathi/word-wrap": "^1.2.3", - "deep-is": "^0.1.3", - "fast-levenshtein": "^2.0.6", - "levn": "^0.4.1", - "prelude-ls": "^1.2.1", - "type-check": "^0.4.0" - } - }, - "os-locale": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz", - "integrity": "sha512-PRT7ZORmwu2MEFt4/fv3Q+mEfN4zetKxufQrkShY2oGvUms9r8otu5HfdyIFHkYXjO7laNsoVGmM2MANfuTA8g==", - "dev": true, - "requires": { - "lcid": "^1.0.0" - } - }, - "os-tmpdir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", - "integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==", - "dev": true - }, - "p-cancelable": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-1.1.0.tgz", - "integrity": "sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw==", - "dev": true - }, - "p-limit": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", - "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", - "dev": true, - "requires": { - "p-try": "^1.0.0" - } - }, - "p-locate": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", - "integrity": "sha512-nQja7m7gSKuewoVRen45CtVfODR3crN3goVQ0DDZ9N3yHxgpkuBhZqsaiotSQRrADUrne346peY7kT3TSACykg==", - "dev": true, - "requires": { - "p-limit": "^1.1.0" - } - }, - "p-map": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", - "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", - "dev": true, - "requires": { - "aggregate-error": "^3.0.0" - } - }, - "p-try": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", - "integrity": "sha512-U1etNYuMJoIz3ZXSrrySFjsXQTWOx2/jdi86L+2pRvph/qMKL6sbcCYdH23fqsbm8TH2Gn0OybpT4eSFlCVHww==", - "dev": true - }, - "parent-module": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", - "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", - "dev": true, - "requires": { - "callsites": "^3.0.0" - } - }, - "parse-asn1": { - "version": "5.1.6", - "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.6.tgz", - "integrity": "sha512-RnZRo1EPU6JBnra2vGHj0yhp6ebyjBZpmUCLHWiFhxlzvBCCpAuZ7elsBp1PVAbQN0/04VD/19rfzlBSwLstMw==", - "dev": true, - "requires": { - "asn1.js": "^5.2.0", - "browserify-aes": "^1.0.0", - "evp_bytestokey": "^1.0.0", - "pbkdf2": "^3.0.3", - "safe-buffer": "^5.1.1" - } - }, - "parse-cache-control": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parse-cache-control/-/parse-cache-control-1.0.1.tgz", - "integrity": "sha512-60zvsJReQPX5/QP0Kzfd/VrpjScIQ7SHBW6bFCYfEP+fp0Eppr1SHhIO5nd1PjZtvclzSzES9D/p5nFJurwfWg==", - "dev": true - }, - "parse-headers": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/parse-headers/-/parse-headers-2.0.5.tgz", - "integrity": "sha512-ft3iAoLOB/MlwbNXgzy43SWGP6sQki2jQvAyBg/zDFAgr9bfNWZIUj42Kw2eJIl8kEi4PbgE6U1Zau/HwI75HA==", - "dev": true - }, - "parse-json": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", - "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.0.0", - "error-ex": "^1.3.1", - "json-parse-even-better-errors": "^2.3.0", - "lines-and-columns": "^1.1.6" - } - }, - "parseurl": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", - "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", - "dev": true - }, - "patch-package": { - "version": "6.5.1", - "resolved": "https://registry.npmjs.org/patch-package/-/patch-package-6.5.1.tgz", - "integrity": "sha512-I/4Zsalfhc6bphmJTlrLoOcAF87jcxko4q0qsv4bGcurbr8IskEOtdnt9iCmsQVGL1B+iUhSQqweyTLJfCF9rA==", - "dev": true, - "requires": { - "@yarnpkg/lockfile": "^1.1.0", - "chalk": "^4.1.2", - "cross-spawn": "^6.0.5", - "find-yarn-workspace-root": "^2.0.0", - "fs-extra": "^9.0.0", - "is-ci": "^2.0.0", - "klaw-sync": "^6.0.0", - "minimist": "^1.2.6", - "open": "^7.4.2", - "rimraf": "^2.6.3", - "semver": "^5.6.0", - "slash": "^2.0.0", - "tmp": "^0.0.33", - "yaml": "^1.10.2" - }, - "dependencies": { - "cross-spawn": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", - "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", - "dev": true, - "requires": { - "nice-try": "^1.0.4", - "path-key": "^2.0.1", - "semver": "^5.5.0", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - } - }, - "fs-extra": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", - "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", - "dev": true, - "requires": { - "at-least-node": "^1.0.0", - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - } - }, - "jsonfile": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", - "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.6", - "universalify": "^2.0.0" - } - }, - "path-key": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==", - "dev": true - }, - "rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "dev": true, - "requires": { - "glob": "^7.1.3" - } - }, - "semver": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", - "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", - "dev": true - }, - "shebang-command": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", - "integrity": "sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==", - "dev": true, - "requires": { - "shebang-regex": "^1.0.0" - } - }, - "shebang-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==", - "dev": true - }, - "slash": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz", - "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==", - "dev": true - }, - "universalify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", - "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", - "dev": true - }, - "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - } - } - }, - "path-browserify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-1.0.1.tgz", - "integrity": "sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==", - "dev": true - }, - "path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", - "dev": true - }, - "path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", - "dev": true - }, - "path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true - }, - "path-parse": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", - "dev": true - }, - "path-to-regexp": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", - "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==", - "dev": true - }, - "path-type": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", - "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", - "dev": true - }, - "pathval": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz", - "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==" - }, - "pbkdf2": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.2.tgz", - "integrity": "sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA==", - "requires": { - "create-hash": "^1.1.2", - "create-hmac": "^1.1.4", - "ripemd160": "^2.0.1", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - } - }, - "performance-now": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==", - "dev": true - }, - "picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "dev": true - }, - "pify": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", - "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", - "dev": true - }, - "pinkie": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", - "integrity": "sha512-MnUuEycAemtSaeFSjXKW/aroV7akBbY+Sv+RkyqFjgAe73F+MR0TBWKBRDkmfWq/HiFmdavfZ1G7h4SPZXaCSg==", - "dev": true - }, - "pinkie-promise": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", - "integrity": "sha512-0Gni6D4UcLTbv9c57DfxDGdr41XfgUjqWZu492f0cIGr16zDU06BWP/RAEvOuo7CQ0CNjHaLlM59YJJFm3NWlw==", - "dev": true, - "requires": { - "pinkie": "^2.0.0" - } - }, - "pluralize": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-8.0.0.tgz", - "integrity": "sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==", - "dev": true - }, - "postinstall-postinstall": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/postinstall-postinstall/-/postinstall-postinstall-2.1.0.tgz", - "integrity": "sha512-7hQX6ZlZXIoRiWNrbMQaLzUUfH+sSx39u8EJ9HYuDc1kLo9IXKWjM5RSquZN1ad5GnH8CGFM78fsAAQi3OKEEQ==", - "dev": true - }, - "prelude-ls": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", - "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", - "dev": true - }, - "prepend-http": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-2.0.0.tgz", - "integrity": "sha512-ravE6m9Atw9Z/jjttRUZ+clIXogdghyZAuWJ3qEzjT+jI/dL1ifAqhZeC5VHzQp1MSt1+jxKkFNemj/iO7tVUA==", - "dev": true - }, - "prettier": { - "version": "2.8.8", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz", - "integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==", - "dev": true - }, - "prettier-linter-helpers": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz", - "integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==", - "dev": true, - "requires": { - "fast-diff": "^1.1.2" - } - }, - "prettier-plugin-solidity": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/prettier-plugin-solidity/-/prettier-plugin-solidity-1.1.3.tgz", - "integrity": "sha512-fQ9yucPi2sBbA2U2Xjh6m4isUTJ7S7QLc/XDDsktqqxYfTwdYKJ0EnnywXHwCGAaYbQNK+HIYPL1OemxuMsgeg==", - "dev": true, - "requires": { - "@solidity-parser/parser": "^0.16.0", - "semver": "^7.3.8", - "solidity-comments-extractor": "^0.0.7" - }, - "dependencies": { - "@solidity-parser/parser": { - "version": "0.16.1", - "resolved": "https://registry.npmjs.org/@solidity-parser/parser/-/parser-0.16.1.tgz", - "integrity": "sha512-PdhRFNhbTtu3x8Axm0uYpqOy/lODYQK+MlYSgqIsq2L8SFYEHJPHNUiOTAJbDGzNjjr1/n9AcIayxafR/fWmYw==", - "dev": true, - "requires": { - "antlr4ts": "^0.5.0-alpha.4" - } - }, - "lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "requires": { - "yallist": "^4.0.0" - } - }, - "semver": { - "version": "7.5.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", - "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", - "dev": true, - "requires": { - "lru-cache": "^6.0.0" - } - }, - "yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - } - } - }, - "process": { - "version": "0.11.10", - "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", - "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==", - "dev": true - }, - "process-nextick-args": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", - "dev": true - }, - "progress": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", - "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", - "dev": true + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] }, - "promise": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/promise/-/promise-8.3.0.tgz", - "integrity": "sha512-rZPNPKTOYVNEEKFaq1HqTgOwZD+4/YHS5ukLzQCypkj+OkYx7iv0mA91lJlpPPZ8vMau3IIGj5Qlwrx+8iiSmg==", + "node_modules/simple-get": { + "version": "2.8.2", + "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-2.8.2.tgz", + "integrity": "sha512-Ijd/rV5o+mSBBs4F/x9oDPtTx9Zb6X9brmnXvMW4J7IR15ngi9q5xxqWBKU744jTZiaXtxaPL7uHG6vtN8kUkw==", "dev": true, - "requires": { - "asap": "~2.0.6" + "dependencies": { + "decompress-response": "^3.3.0", + "once": "^1.3.1", + "simple-concat": "^1.0.0" } }, - "proxy-addr": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", - "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", + "node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", "dev": true, - "requires": { - "forwarded": "0.2.0", - "ipaddr.js": "1.9.1" + "engines": { + "node": ">=8" } }, - "psl": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz", - "integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==", - "dev": true - }, - "public-encrypt": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz", - "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==", + "node_modules/slice-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", + "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", "dev": true, - "requires": { - "bn.js": "^4.1.0", - "browserify-rsa": "^4.0.0", - "create-hash": "^1.1.0", - "parse-asn1": "^5.0.0", - "randombytes": "^2.0.1", - "safe-buffer": "^5.1.2" - }, "dependencies": { - "bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", - "dev": true - } + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/slice-ansi?sponsor=1" } }, - "pump": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "node_modules/solc": { + "version": "0.6.12", + "resolved": "https://registry.npmjs.org/solc/-/solc-0.6.12.tgz", + "integrity": "sha512-Lm0Ql2G9Qc7yPP2Ba+WNmzw2jwsrd3u4PobHYlSOxaut3TtUbj9+5ZrT6f4DUpNPEoBaFUOEg9Op9C0mk7ge9g==", "dev": true, - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" + "dependencies": { + "command-exists": "^1.2.8", + "commander": "3.0.2", + "fs-extra": "^0.30.0", + "js-sha3": "0.8.0", + "memorystream": "^0.3.1", + "require-from-string": "^2.0.0", + "semver": "^5.5.0", + "tmp": "0.0.33" + }, + "bin": { + "solcjs": "solcjs" + }, + "engines": { + "node": ">=8.0.0" } }, - "punycode": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.0.tgz", - "integrity": "sha512-Yxz2kRwT90aPiWEMHVYnEf4+rhwF1tBmmZ4KepCP+Wkium9JxtWnUm1nqGwpiAHr/tnTSeHqr3wb++jgSkXjhA==", - "dev": true - }, - "qs": { - "version": "6.5.3", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.3.tgz", - "integrity": "sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==", - "dev": true - }, - "query-string": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/query-string/-/query-string-5.1.1.tgz", - "integrity": "sha512-gjWOsm2SoGlgLEdAGt7a6slVOk9mGiXmPFMqrEhLQ68rhQuBnpfs3+EmlvqKyxnCo9/PPlF+9MtY02S1aFg+Jw==", + "node_modules/solc/node_modules/fs-extra": { + "version": "0.30.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-0.30.0.tgz", + "integrity": "sha512-UvSPKyhMn6LEd/WpUaV9C9t3zATuqoqfWc3QdPhPLb58prN9tqYPlPWi8Krxi44loBoUzlobqZ3+8tGpxxSzwA==", "dev": true, - "requires": { - "decode-uri-component": "^0.2.0", - "object-assign": "^4.1.0", - "strict-uri-encode": "^1.0.0" + "dependencies": { + "graceful-fs": "^4.1.2", + "jsonfile": "^2.1.0", + "klaw": "^1.0.0", + "path-is-absolute": "^1.0.0", + "rimraf": "^2.2.8" } }, - "queue-microtask": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", - "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", - "dev": true - }, - "quick-lru": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz", - "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==", - "dev": true - }, - "randombytes": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", - "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", - "requires": { - "safe-buffer": "^5.1.0" + "node_modules/solc/node_modules/jsonfile": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz", + "integrity": "sha512-PKllAqbgLgxHaj8TElYymKCAgrASebJrWpTnEkOaTowt23VKXXN0sUeriJ+eh7y6ufb/CC5ap11pz71/cM0hUw==", + "dev": true, + "optionalDependencies": { + "graceful-fs": "^4.1.6" } }, - "randomfill": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz", - "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==", + "node_modules/solc/node_modules/rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", "dev": true, - "requires": { - "randombytes": "^2.0.5", - "safe-buffer": "^5.1.0" + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" } }, - "range-parser": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", - "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", - "dev": true - }, - "raw-body": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", - "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", + "node_modules/solc/node_modules/semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", "dev": true, - "requires": { - "bytes": "3.1.2", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "unpipe": "1.0.0" + "bin": { + "semver": "bin/semver" } }, - "read-pkg": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz", - "integrity": "sha512-7BGwRHqt4s/uVbuyoeejRn4YmFnYZiFl4AuaeXHlgZf3sONF0SOGlxs2Pw8g6hCKupo08RafIO5YXFNOKTfwsQ==", + "node_modules/solhint": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/solhint/-/solhint-3.6.2.tgz", + "integrity": "sha512-85EeLbmkcPwD+3JR7aEMKsVC9YrRSxd4qkXuMzrlf7+z2Eqdfm1wHWq1ffTuo5aDhoZxp2I9yF3QkxZOxOL7aQ==", "dev": true, - "requires": { - "load-json-file": "^1.0.0", - "normalize-package-data": "^2.3.2", - "path-type": "^1.0.0" - }, "dependencies": { - "path-type": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz", - "integrity": "sha512-S4eENJz1pkiQn9Znv33Q+deTOKmbl+jj1Fl+qiP/vYezj+S8x+J3Uo0ISrx/QoEvIlOaDWJhPaRd1flJ9HXZqg==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0" - } - }, - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", - "dev": true - } + "@solidity-parser/parser": "^0.16.0", + "ajv": "^6.12.6", + "antlr4": "^4.11.0", + "ast-parents": "^0.0.1", + "chalk": "^4.1.2", + "commander": "^10.0.0", + "cosmiconfig": "^8.0.0", + "fast-diff": "^1.2.0", + "glob": "^8.0.3", + "ignore": "^5.2.4", + "js-yaml": "^4.1.0", + "lodash": "^4.17.21", + "pluralize": "^8.0.0", + "semver": "^7.5.2", + "strip-ansi": "^6.0.1", + "table": "^6.8.1", + "text-table": "^0.2.0" + }, + "bin": { + "solhint": "solhint.js" + }, + "optionalDependencies": { + "prettier": "^2.8.3" } }, - "read-pkg-up": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz", - "integrity": "sha512-WD9MTlNtI55IwYUS27iHh9tK3YoIVhxis8yKhLpTqWtml739uXc9NWTpxoHkfZf3+DkCCsXox94/VWZniuZm6A==", + "node_modules/solhint/node_modules/@solidity-parser/parser": { + "version": "0.16.2", + "resolved": "https://registry.npmjs.org/@solidity-parser/parser/-/parser-0.16.2.tgz", + "integrity": "sha512-PI9NfoA3P8XK2VBkK5oIfRgKDsicwDZfkVq9ZTBCQYGOP1N2owgY2dyLGyU5/J/hQs8KRk55kdmvTLjy3Mu3vg==", "dev": true, - "requires": { - "find-up": "^1.0.0", - "read-pkg": "^1.0.0" - }, "dependencies": { - "find-up": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", - "integrity": "sha512-jvElSjyuo4EMQGoTwo1uJU5pQMwTW5lS1x05zzfJuTIyLR3zwO27LYrxNg+dlvKpGOuGy/MzBdXh80g0ve5+HA==", - "dev": true, - "requires": { - "path-exists": "^2.0.0", - "pinkie-promise": "^2.0.0" - } - }, - "path-exists": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", - "integrity": "sha512-yTltuKuhtNeFJKa1PiRzfLAU5182q1y4Eb4XCJ3PBqyzEDkAZRzBrKKBct682ls9reBVHf9udYLN5Nd+K1B9BQ==", - "dev": true, - "requires": { - "pinkie-promise": "^2.0.0" - } - } + "antlr4ts": "^0.5.0-alpha.4" } }, - "readable-stream": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" + "node_modules/solhint/node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "node_modules/solhint/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" } }, - "readdirp": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", - "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "node_modules/solhint/node_modules/commander": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz", + "integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==", "dev": true, - "requires": { - "picomatch": "^2.2.1" + "engines": { + "node": ">=14" } }, - "rechoir": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", - "integrity": "sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw==", + "node_modules/solhint/node_modules/glob": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", + "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==", "dev": true, - "requires": { - "resolve": "^1.1.6" + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^5.0.1", + "once": "^1.3.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "recursive-readdir": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/recursive-readdir/-/recursive-readdir-2.2.3.tgz", - "integrity": "sha512-8HrF5ZsXk5FAH9dgsx3BlUer73nIhuj+9OrQwEbLTPOBzGkL1lsFCR01am+v+0m2Cmbs1nP12hLDl5FA7EszKA==", + "node_modules/solhint/node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", "dev": true, - "requires": { - "minimatch": "^3.0.5" + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" } }, - "regexp.prototype.flags": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.0.tgz", - "integrity": "sha512-0SutC3pNudRKgquxGoRGIz946MZVHqbNfPjBdxeOhBrdgDKlRoXmYLQN9xRbrR09ZXWeGAdPuif7egofn6v5LA==", + "node_modules/solhint/node_modules/minimatch": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", + "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "functions-have-names": "^1.2.3" + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" } }, - "regexpp": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", - "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", + "node_modules/solidity-comments-extractor": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/solidity-comments-extractor/-/solidity-comments-extractor-0.0.8.tgz", + "integrity": "sha512-htM7Vn6LhHreR+EglVMd2s+sZhcXAirB1Zlyrv5zBuTxieCvjfnRpd7iZk75m/u6NOlEyQ94C6TWbBn2cY7w8g==", "dev": true }, - "req-cwd": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/req-cwd/-/req-cwd-2.0.0.tgz", - "integrity": "sha512-ueoIoLo1OfB6b05COxAA9UpeoscNpYyM+BqYlA7H6LVF4hKGPXQQSSaD2YmvDVJMkk4UDpAHIeU1zG53IqjvlQ==", - "dev": true, - "requires": { - "req-from": "^2.0.0" - } - }, - "req-from": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/req-from/-/req-from-2.0.0.tgz", - "integrity": "sha512-LzTfEVDVQHBRfjOUMgNBA+V6DWsSnoeKzf42J7l0xa/B4jyPOuuF5MlNSmomLNGemWTnV2TIdjSSLnEn95fOQA==", + "node_modules/solidity-coverage": { + "version": "0.7.22", + "resolved": "https://registry.npmjs.org/solidity-coverage/-/solidity-coverage-0.7.22.tgz", + "integrity": "sha512-I6Zd5tsFY+gmj1FDIp6w7OrUePx6ZpMgKQZg7dWgPaQHePLi3Jk+iJ8lwZxsWEoNy2Lcv91rMxATWHqRaFdQpw==", "dev": true, - "requires": { - "resolve-from": "^3.0.0" - }, "dependencies": { - "resolve-from": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", - "integrity": "sha512-GnlH6vxLymXJNMBo7XP1fJIzBFbdYt49CuTwmB/6N53t+kMPRMFKz783LlQ4tv28XoQfMWinAJX6WCGf2IlaIw==", - "dev": true - } + "@solidity-parser/parser": "^0.14.0", + "@truffle/provider": "^0.2.24", + "chalk": "^2.4.2", + "death": "^1.1.0", + "detect-port": "^1.3.0", + "fs-extra": "^8.1.0", + "ghost-testrpc": "^0.0.2", + "global-modules": "^2.0.0", + "globby": "^10.0.1", + "jsonschema": "^1.2.4", + "lodash": "^4.17.15", + "node-emoji": "^1.10.0", + "pify": "^4.0.1", + "recursive-readdir": "^2.2.2", + "sc-istanbul": "^0.4.5", + "semver": "^7.3.4", + "shelljs": "^0.8.3", + "web3-utils": "^1.3.0" + }, + "bin": { + "solidity-coverage": "plugins/bin.js" } }, - "request": { - "version": "2.88.2", - "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", - "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", + "node_modules/solidity-coverage/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", "dev": true, - "requires": { - "aws-sign2": "~0.7.0", - "aws4": "^1.8.0", - "caseless": "~0.12.0", - "combined-stream": "~1.0.6", - "extend": "~3.0.2", - "forever-agent": "~0.6.1", - "form-data": "~2.3.2", - "har-validator": "~5.1.3", - "http-signature": "~1.2.0", - "is-typedarray": "~1.0.0", - "isstream": "~0.1.2", - "json-stringify-safe": "~5.0.1", - "mime-types": "~2.1.19", - "oauth-sign": "~0.9.0", - "performance-now": "^2.1.0", - "qs": "~6.5.2", - "safe-buffer": "^5.1.2", - "tough-cookie": "~2.5.0", - "tunnel-agent": "^0.6.0", - "uuid": "^3.3.2" - }, "dependencies": { - "form-data": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", - "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", - "dev": true, - "requires": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.6", - "mime-types": "^2.1.12" - } - }, - "uuid": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", - "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", - "dev": true - } + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" } }, - "request-promise-core": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.4.tgz", - "integrity": "sha512-TTbAfBBRdWD7aNNOoVOBH4pN/KigV6LyapYNNlAPA8JwbovRti1E88m3sYAwsLi5ryhPKsE9APwnjFTgdUjTpw==", + "node_modules/solidity-coverage/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", "dev": true, - "requires": { - "lodash": "^4.17.19" + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" } }, - "request-promise-native": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/request-promise-native/-/request-promise-native-1.0.9.tgz", - "integrity": "sha512-wcW+sIUiWnKgNY0dqCpOZkUbF/I+YPi+f09JZIDa39Ec+q82CpSYniDp+ISgTTbKmnpJWASeJBPZmoxH84wt3g==", + "node_modules/solidity-coverage/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", "dev": true, - "requires": { - "request-promise-core": "1.1.4", - "stealthy-require": "^1.1.1", - "tough-cookie": "^2.3.3" + "dependencies": { + "color-name": "1.1.3" } }, - "require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", - "dev": true - }, - "require-from-string": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", - "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", - "dev": true - }, - "require-main-filename": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz", - "integrity": "sha512-IqSUtOVP4ksd1C/ej5zeEh/BIP2ajqpn8c5x+q99gvcIG/Qf0cud5raVnE/Dwd0ua9TXYDoDc0RE5hBSdz22Ug==", + "node_modules/solidity-coverage/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", "dev": true }, - "resolve": { - "version": "1.22.2", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.2.tgz", - "integrity": "sha512-Sb+mjNHOULsBv818T40qSPeRiuWLyaGMa5ewydRLFimneixmVy2zdivRl+AF6jaYPC8ERxGDmFSiqui6SfPd+g==", + "node_modules/solidity-coverage/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", "dev": true, - "requires": { - "is-core-module": "^2.11.0", - "path-parse": "^1.0.7", - "supports-preserve-symlinks-flag": "^1.0.0" + "engines": { + "node": ">=0.8.0" } }, - "resolve-alpn": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/resolve-alpn/-/resolve-alpn-1.2.1.tgz", - "integrity": "sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==", - "dev": true - }, - "resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "dev": true - }, - "responselike": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/responselike/-/responselike-1.0.2.tgz", - "integrity": "sha512-/Fpe5guzJk1gPqdJLJR5u7eG/gNY4nImjbRDaVWVMRhne55TCmj2i9Q+54PBRfatRC8v/rIiv9BN0pMd9OV5EQ==", + "node_modules/solidity-coverage/node_modules/fs-extra": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", + "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", "dev": true, - "requires": { - "lowercase-keys": "^1.0.0" + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + }, + "engines": { + "node": ">=6 <7 || >=8" } }, - "reusify": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", - "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", - "dev": true - }, - "rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "node_modules/solidity-coverage/node_modules/globby": { + "version": "10.0.2", + "resolved": "https://registry.npmjs.org/globby/-/globby-10.0.2.tgz", + "integrity": "sha512-7dUi7RvCoT/xast/o/dLN53oqND4yk0nsHkhRgn9w65C4PofCLOoJ39iSOg+qVDdWQPIEj+eszMHQ+aLVwwQSg==", "dev": true, - "requires": { - "glob": "^7.1.3" - } - }, - "ripemd160": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", - "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", - "requires": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1" - } - }, - "rlp": { - "version": "2.2.7", - "resolved": "https://registry.npmjs.org/rlp/-/rlp-2.2.7.tgz", - "integrity": "sha512-d5gdPmgQ0Z+AklL2NVXr/IoSjNZFfTVvQWzL/AM2AOcSzYP2xjlb0AC8YyCLc41MSNf6P6QVtjgPdmVtzb+4lQ==", - "requires": { - "bn.js": "^5.2.0" + "dependencies": { + "@types/glob": "^7.1.1", + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.0.3", + "glob": "^7.1.3", + "ignore": "^5.1.1", + "merge2": "^1.2.3", + "slash": "^3.0.0" + }, + "engines": { + "node": ">=8" } }, - "run-parallel": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", - "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "node_modules/solidity-coverage/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", "dev": true, - "requires": { - "queue-microtask": "^1.2.2" + "engines": { + "node": ">=4" } }, - "run-parallel-limit": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/run-parallel-limit/-/run-parallel-limit-1.1.0.tgz", - "integrity": "sha512-jJA7irRNM91jaKc3Hcl1npHsFLOXOoTkPCUL1JEa1R82O2miplXXRaGdjW/KM/98YQWDhJLiSs793CnXfblJUw==", + "node_modules/solidity-coverage/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", "dev": true, - "requires": { - "queue-microtask": "^1.2.2" + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" } }, - "rustbn.js": { + "node_modules/source-map": { "version": "0.2.0", - "resolved": "https://registry.npmjs.org/rustbn.js/-/rustbn.js-0.2.0.tgz", - "integrity": "sha512-4VlvkRUuCJvr2J6Y0ImW7NvTCriMi7ErOAqWk1y69vAdoNIzCF3yPmgeNzx+RQTLEDFq5sHfscn1MwHxP9hNfA==", - "dev": true + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.2.0.tgz", + "integrity": "sha512-CBdZ2oa/BHhS4xj5DlhjWNHcan57/5YuvfdLf17iVmIpd9KRm+DFLmC6nBNj+6Ua7Kt3TmOjDpQT1aTYOQtoUA==", + "dev": true, + "optional": true, + "dependencies": { + "amdefine": ">=0.0.4" + }, + "engines": { + "node": ">=0.8.0" + } }, - "safe-array-concat": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.0.0.tgz", - "integrity": "sha512-9dVEFruWIsnie89yym+xWTAYASdpw3CJV7Li/6zBewGf9z2i1j31rP6jnY0pHEO4QZh6N0K11bFjWmdR8UGdPQ==", + "node_modules/source-map-support": { + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", "dev": true, - "requires": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.2.0", - "has-symbols": "^1.0.3", - "isarray": "^2.0.5" + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" } }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + "node_modules/source-map-support/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } }, - "safe-regex-test": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.0.tgz", - "integrity": "sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA==", + "node_modules/spdx-correct": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz", + "integrity": "sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==", "dev": true, - "requires": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.1.3", - "is-regex": "^1.1.4" + "dependencies": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" } }, - "safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "node_modules/spdx-exceptions": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.5.0.tgz", + "integrity": "sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==", "dev": true }, - "sc-istanbul": { - "version": "0.4.6", - "resolved": "https://registry.npmjs.org/sc-istanbul/-/sc-istanbul-0.4.6.tgz", - "integrity": "sha512-qJFF/8tW/zJsbyfh/iT/ZM5QNHE3CXxtLJbZsL+CzdJLBsPD7SedJZoUA4d8iAcN2IoMp/Dx80shOOd2x96X/g==", + "node_modules/spdx-expression-parse": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", + "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", "dev": true, - "requires": { - "abbrev": "1.0.x", - "async": "1.x", - "escodegen": "1.8.x", - "esprima": "2.7.x", - "glob": "^5.0.15", - "handlebars": "^4.0.1", - "js-yaml": "3.x", - "mkdirp": "0.5.x", - "nopt": "3.x", - "once": "1.x", - "resolve": "1.1.x", - "supports-color": "^3.1.0", - "which": "^1.1.1", - "wordwrap": "^1.0.0" - }, "dependencies": { - "esprima": { - "version": "2.7.3", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-2.7.3.tgz", - "integrity": "sha512-OarPfz0lFCiW4/AV2Oy1Rp9qu0iusTKqykwTspGCZtPxmF81JR4MmIebvF1F9+UOKth2ZubLQ4XGGaU+hSn99A==", - "dev": true - }, - "glob": { - "version": "5.0.15", - "resolved": "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz", - "integrity": "sha512-c9IPMazfRITpmAAKi22dK1VKxGDX9ehhqfABDriL/lzO92xcUKEJPQHrVA/2YHSNFB4iFlykVmWvwo48nr3OxA==", - "dev": true, - "requires": { - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "2 || 3", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "has-flag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", - "integrity": "sha512-DyYHfIYwAJmjAjSSPKANxI8bFY9YtFrgkAfinBojQ8YJTOuOuav64tMUJv584SES4xl74PmuaevIyaLESHdTAA==", - "dev": true - }, - "resolve": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz", - "integrity": "sha512-9znBF0vBcaSN3W2j7wKvdERPwqTxSpCq+if5C0WoTCyV9n24rua28jeuQ2pL/HOf+yUe/Mef+H/5p60K0Id3bg==", - "dev": true - }, - "supports-color": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", - "integrity": "sha512-Jds2VIYDrlp5ui7t8abHN2bjAu4LV/q4N2KivFPpGH0lrka0BMq/33AmECUXlKPcHigkNaqfXRENFju+rlcy+A==", - "dev": true, - "requires": { - "has-flag": "^1.0.0" - } - }, - "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - } + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" } }, - "scrypt-js": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/scrypt-js/-/scrypt-js-3.0.1.tgz", - "integrity": "sha512-cdwTTnqPu0Hyvf5in5asVdZocVDTNRmR7XEcJuIzMjJeSHybHl7vpB66AzwTaIg6CLSbtjcxc8fqcySfnTkccA==" + "node_modules/spdx-license-ids": { + "version": "3.0.17", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.17.tgz", + "integrity": "sha512-sh8PWc/ftMqAAdFiBu6Fy6JUOYjqDJBJvIhpfDMyHrr0Rbp5liZqd4TjtQ/RgfLjKFZb+LMx5hpml5qOWy0qvg==", + "dev": true }, - "secp256k1": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/secp256k1/-/secp256k1-4.0.3.tgz", - "integrity": "sha512-NLZVf+ROMxwtEj3Xa562qgv2BK5e2WNmXPiOdVIPLgs6lyTzMvBq0aWTYMI5XCP9jZMVKOcqZLw/Wc4vDkuxhA==", - "requires": { - "elliptic": "^6.5.4", - "node-addon-api": "^2.0.0", - "node-gyp-build": "^4.2.0" + "node_modules/sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", + "dev": true + }, + "node_modules/sshpk": { + "version": "1.18.0", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.18.0.tgz", + "integrity": "sha512-2p2KJZTSqQ/I3+HX42EpYOa2l3f8Erv8MWKsy2I9uf4wA7yFIkXRffYdsx86y6z4vHtV8u7g+pPlr8/4ouAxsQ==", + "dev": true, + "dependencies": { + "asn1": "~0.2.3", + "assert-plus": "^1.0.0", + "bcrypt-pbkdf": "^1.0.0", + "dashdash": "^1.12.0", + "ecc-jsbn": "~0.1.1", + "getpass": "^0.1.1", + "jsbn": "~0.1.0", + "safer-buffer": "^2.0.2", + "tweetnacl": "~0.14.0" + }, + "bin": { + "sshpk-conv": "bin/sshpk-conv", + "sshpk-sign": "bin/sshpk-sign", + "sshpk-verify": "bin/sshpk-verify" + }, + "engines": { + "node": ">=0.10.0" } }, - "semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "node_modules/sshpk/node_modules/tweetnacl": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", + "integrity": "sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==", "dev": true }, - "send": { - "version": "0.18.0", - "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", - "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", + "node_modules/stacktrace-parser": { + "version": "0.1.10", + "resolved": "https://registry.npmjs.org/stacktrace-parser/-/stacktrace-parser-0.1.10.tgz", + "integrity": "sha512-KJP1OCML99+8fhOHxwwzyWrlUuVX5GQ0ZpJTd1DFXhdkrvg1szxfHhawXUZ3g9TkXORQd4/WG68jMlQZ2p8wlg==", "dev": true, - "requires": { - "debug": "2.6.9", - "depd": "2.0.0", - "destroy": "1.2.0", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "fresh": "0.5.2", - "http-errors": "2.0.0", - "mime": "1.6.0", - "ms": "2.1.3", - "on-finished": "2.4.1", - "range-parser": "~1.2.1", - "statuses": "2.0.1" - }, "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - }, - "dependencies": { - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true - } - } - }, - "ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true - } + "type-fest": "^0.7.1" + }, + "engines": { + "node": ">=6" } }, - "serialize-javascript": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz", - "integrity": "sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==", + "node_modules/stacktrace-parser/node_modules/type-fest": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.7.1.tgz", + "integrity": "sha512-Ne2YiiGN8bmrmJJEuTWTLJR32nh/JdL1+PSicowtNb0WFpn59GK8/lfD61bVtzguz7b3PBt74nxpv/Pw5po5Rg==", "dev": true, - "requires": { - "randombytes": "^2.1.0" + "engines": { + "node": ">=8" } }, - "serve-static": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", - "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==", + "node_modules/statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", "dev": true, - "requires": { - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "parseurl": "~1.3.3", - "send": "0.18.0" + "engines": { + "node": ">= 0.8" } }, - "servify": { - "version": "0.1.12", - "resolved": "https://registry.npmjs.org/servify/-/servify-0.1.12.tgz", - "integrity": "sha512-/xE6GvsKKqyo1BAY+KxOWXcLpPsUUyji7Qg3bVD7hh1eRze5bR1uYiuDA/k3Gof1s9BTzQZEJK8sNcNGFIzeWw==", + "node_modules/strict-uri-encode": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz", + "integrity": "sha512-R3f198pcvnB+5IpnBlRkphuE9n46WyVl8I39W/ZUTZLz4nqSP/oLYUrcnJrw462Ds8he4YKMov2efsTIw1BDGQ==", "dev": true, - "requires": { - "body-parser": "^1.16.0", - "cors": "^2.8.1", - "express": "^4.14.0", - "request": "^2.79.0", - "xhr": "^2.3.3" + "engines": { + "node": ">=0.10.0" } }, - "set-blocking": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==", - "dev": true - }, - "setimmediate": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", - "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==" - }, - "setprototypeof": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", - "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", - "dev": true - }, - "sha.js": { - "version": "2.4.11", - "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", - "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", - "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" + "node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dependencies": { + "safe-buffer": "~5.2.0" } }, - "sha1": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/sha1/-/sha1-1.1.1.tgz", - "integrity": "sha512-dZBS6OrMjtgVkopB1Gmo4RQCDKiZsqcpAQpkV/aaj+FCrCg8r4I4qMkDPQjBgLIxlmu9k4nUbWq6ohXahOneYA==", + "node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "dev": true, - "requires": { - "charenc": ">= 0.0.1", - "crypt": ">= 0.0.1" + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" } }, - "shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "node_modules/string.prototype.trim": { + "version": "1.2.9", + "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.9.tgz", + "integrity": "sha512-klHuCNxiMZ8MlsOihJhJEBJAiMVqU3Z2nEXWfWnIqjN0gEFS9J9+IxKozWWtQGcgoa1WUZzLjKPTr4ZHNFTFxw==", "dev": true, - "requires": { - "shebang-regex": "^3.0.0" + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.0", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true - }, - "shelljs": { - "version": "0.8.5", - "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.8.5.tgz", - "integrity": "sha512-TiwcRcrkhHvbrZbnRcFYMLl30Dfov3HKqzp5tO5b4pt6G/SezKcYhmDg15zXVBswHmctSAQKznqNW2LO5tTDow==", + "node_modules/string.prototype.trimend": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.8.tgz", + "integrity": "sha512-p73uL5VCHCO2BZZ6krwwQE3kCzM7NKmis8S//xEC6fQonchbum4eP6kR4DLEjQFO3Wnj3Fuo8NM0kOSjVdHjZQ==", "dev": true, - "requires": { - "glob": "^7.0.0", - "interpret": "^1.0.0", - "rechoir": "^0.6.2" + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "side-channel": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", - "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", + "node_modules/string.prototype.trimstart": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz", + "integrity": "sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==", "dev": true, - "requires": { - "call-bind": "^1.0.0", - "get-intrinsic": "^1.0.2", - "object-inspect": "^1.9.0" + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "simple-concat": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz", - "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==", - "dev": true - }, - "simple-get": { - "version": "2.8.2", - "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-2.8.2.tgz", - "integrity": "sha512-Ijd/rV5o+mSBBs4F/x9oDPtTx9Zb6X9brmnXvMW4J7IR15ngi9q5xxqWBKU744jTZiaXtxaPL7uHG6vtN8kUkw==", + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dev": true, - "requires": { - "decompress-response": "^3.3.0", - "once": "^1.3.1", - "simple-concat": "^1.0.0" + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" } }, - "slash": { + "node_modules/strip-bom": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "dev": true - }, - "slice-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", - "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", "dev": true, - "requires": { - "ansi-styles": "^4.0.0", - "astral-regex": "^2.0.0", - "is-fullwidth-code-point": "^3.0.0" - }, + "engines": { + "node": ">=4" + } + }, + "node_modules/strip-hex-prefix": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/strip-hex-prefix/-/strip-hex-prefix-1.0.0.tgz", + "integrity": "sha512-q8d4ue7JGEiVcypji1bALTos+0pWtyGlivAWyPuTkHzuTCJqrK9sWxYQZUq6Nq3cuyv3bm734IhHvHtGGURU6A==", "dependencies": { - "is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true - } + "is-hex-prefixed": "1.0.0" + }, + "engines": { + "node": ">=6.5.0", + "npm": ">=3" } }, - "solc": { - "version": "0.6.12", - "resolved": "https://registry.npmjs.org/solc/-/solc-0.6.12.tgz", - "integrity": "sha512-Lm0Ql2G9Qc7yPP2Ba+WNmzw2jwsrd3u4PobHYlSOxaut3TtUbj9+5ZrT6f4DUpNPEoBaFUOEg9Op9C0mk7ge9g==", + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", "dev": true, - "requires": { - "command-exists": "^1.2.8", - "commander": "3.0.2", - "fs-extra": "^0.30.0", - "js-sha3": "0.8.0", - "memorystream": "^0.3.1", - "require-from-string": "^2.0.0", - "semver": "^5.5.0", - "tmp": "0.0.33" + "engines": { + "node": ">=8" }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dependencies": { - "fs-extra": { - "version": "0.30.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-0.30.0.tgz", - "integrity": "sha512-UvSPKyhMn6LEd/WpUaV9C9t3zATuqoqfWc3QdPhPLb58prN9tqYPlPWi8Krxi44loBoUzlobqZ3+8tGpxxSzwA==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "jsonfile": "^2.1.0", - "klaw": "^1.0.0", - "path-is-absolute": "^1.0.0", - "rimraf": "^2.2.8" - } - }, - "jsonfile": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz", - "integrity": "sha512-PKllAqbgLgxHaj8TElYymKCAgrASebJrWpTnEkOaTowt23VKXXN0sUeriJ+eh7y6ufb/CC5ap11pz71/cM0hUw==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.6" - } - }, - "rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "dev": true, - "requires": { - "glob": "^7.1.3" - } - }, - "semver": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", - "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", - "dev": true - } + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" } }, - "solhint": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/solhint/-/solhint-3.4.1.tgz", - "integrity": "sha512-pzZn2RlZhws1XwvLPVSsxfHrwsteFf5eySOhpAytzXwKQYbTCJV6z8EevYDiSVKMpWrvbKpEtJ055CuEmzp4Xg==", + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", "dev": true, - "requires": { - "@solidity-parser/parser": "^0.16.0", - "ajv": "^6.12.6", - "antlr4": "^4.11.0", - "ast-parents": "^0.0.1", - "chalk": "^4.1.2", - "commander": "^10.0.0", - "cosmiconfig": "^8.0.0", - "fast-diff": "^1.2.0", - "glob": "^8.0.3", - "ignore": "^5.2.4", - "js-yaml": "^4.1.0", - "lodash": "^4.17.21", - "pluralize": "^8.0.0", - "prettier": "^2.8.3", - "semver": "^6.3.0", - "strip-ansi": "^6.0.1", - "table": "^6.8.1", - "text-table": "^0.2.0" + "engines": { + "node": ">= 0.4" }, - "dependencies": { - "@solidity-parser/parser": { - "version": "0.16.1", - "resolved": "https://registry.npmjs.org/@solidity-parser/parser/-/parser-0.16.1.tgz", - "integrity": "sha512-PdhRFNhbTtu3x8Axm0uYpqOy/lODYQK+MlYSgqIsq2L8SFYEHJPHNUiOTAJbDGzNjjr1/n9AcIayxafR/fWmYw==", - "dev": true, - "requires": { - "antlr4ts": "^0.5.0-alpha.4" - } - }, - "argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true - }, - "brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "requires": { - "balanced-match": "^1.0.0" - } - }, - "commander": { - "version": "10.0.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz", - "integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==", - "dev": true - }, - "glob": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", - "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^5.0.1", - "once": "^1.3.0" - } - }, - "js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dev": true, - "requires": { - "argparse": "^2.0.1" - } - }, - "minimatch": { - "version": "5.1.6", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", - "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", - "dev": true, - "requires": { - "brace-expansion": "^2.0.1" - } - } + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "solidity-comments-extractor": { - "version": "0.0.7", - "resolved": "https://registry.npmjs.org/solidity-comments-extractor/-/solidity-comments-extractor-0.0.7.tgz", - "integrity": "sha512-wciNMLg/Irp8OKGrh3S2tfvZiZ0NEyILfcRCXCD4mp7SgK/i9gzLfhY2hY7VMCQJ3kH9UB9BzNdibIVMchzyYw==", - "dev": true - }, - "solidity-coverage": { - "version": "0.7.22", - "resolved": "https://registry.npmjs.org/solidity-coverage/-/solidity-coverage-0.7.22.tgz", - "integrity": "sha512-I6Zd5tsFY+gmj1FDIp6w7OrUePx6ZpMgKQZg7dWgPaQHePLi3Jk+iJ8lwZxsWEoNy2Lcv91rMxATWHqRaFdQpw==", + "node_modules/swarm-js": { + "version": "0.1.42", + "resolved": "https://registry.npmjs.org/swarm-js/-/swarm-js-0.1.42.tgz", + "integrity": "sha512-BV7c/dVlA3R6ya1lMlSSNPLYrntt0LUq4YMgy3iwpCIc6rZnS5W2wUoctarZ5pXlpKtxDDf9hNziEkcfrxdhqQ==", "dev": true, - "requires": { - "@solidity-parser/parser": "^0.14.0", - "@truffle/provider": "^0.2.24", - "chalk": "^2.4.2", - "death": "^1.1.0", - "detect-port": "^1.3.0", - "fs-extra": "^8.1.0", - "ghost-testrpc": "^0.0.2", - "global-modules": "^2.0.0", - "globby": "^10.0.1", - "jsonschema": "^1.2.4", - "lodash": "^4.17.15", - "node-emoji": "^1.10.0", - "pify": "^4.0.1", - "recursive-readdir": "^2.2.2", - "sc-istanbul": "^0.4.5", - "semver": "^7.3.4", - "shelljs": "^0.8.3", - "web3-utils": "^1.3.0" - }, "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true - }, - "fs-extra": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", - "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", - "dev": true, - "requires": { - "graceful-fs": "^4.2.0", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - } - }, - "globby": { - "version": "10.0.2", - "resolved": "https://registry.npmjs.org/globby/-/globby-10.0.2.tgz", - "integrity": "sha512-7dUi7RvCoT/xast/o/dLN53oqND4yk0nsHkhRgn9w65C4PofCLOoJ39iSOg+qVDdWQPIEj+eszMHQ+aLVwwQSg==", - "dev": true, - "requires": { - "@types/glob": "^7.1.1", - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.0.3", - "glob": "^7.1.3", - "ignore": "^5.1.1", - "merge2": "^1.2.3", - "slash": "^3.0.0" - } - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true - }, - "lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "requires": { - "yallist": "^4.0.0" - } - }, - "semver": { - "version": "7.5.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", - "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", - "dev": true, - "requires": { - "lru-cache": "^6.0.0" - } - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - }, - "yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - } + "bluebird": "^3.5.0", + "buffer": "^5.0.5", + "eth-lib": "^0.1.26", + "fs-extra": "^4.0.2", + "got": "^11.8.5", + "mime-types": "^2.1.16", + "mkdirp-promise": "^5.0.1", + "mock-fs": "^4.1.0", + "setimmediate": "^1.0.5", + "tar": "^4.0.2", + "xhr-request": "^1.0.1" } }, - "source-map": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.2.0.tgz", - "integrity": "sha512-CBdZ2oa/BHhS4xj5DlhjWNHcan57/5YuvfdLf17iVmIpd9KRm+DFLmC6nBNj+6Ua7Kt3TmOjDpQT1aTYOQtoUA==", + "node_modules/swarm-js/node_modules/@sindresorhus/is": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.6.0.tgz", + "integrity": "sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==", "dev": true, - "optional": true, - "requires": { - "amdefine": ">=0.0.4" + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/is?sponsor=1" } }, - "source-map-support": { - "version": "0.5.21", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", - "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", + "node_modules/swarm-js/node_modules/@szmarczak/http-timer": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-4.0.6.tgz", + "integrity": "sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w==", "dev": true, - "requires": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - }, "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - } + "defer-to-connect": "^2.0.0" + }, + "engines": { + "node": ">=10" } }, - "spdx-correct": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz", - "integrity": "sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==", + "node_modules/swarm-js/node_modules/buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", "dev": true, - "requires": { - "spdx-expression-parse": "^3.0.0", - "spdx-license-ids": "^3.0.0" + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" } }, - "spdx-exceptions": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz", - "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==", - "dev": true - }, - "spdx-expression-parse": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", - "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", + "node_modules/swarm-js/node_modules/cacheable-lookup": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-5.0.4.tgz", + "integrity": "sha512-2/kNscPhpcxrOigMZzbiWF7dz8ilhb/nIHU3EyZiXWXpeq/au8qJ8VhdftMkty3n7Gj6HIGalQG8oiBNB3AJgA==", "dev": true, - "requires": { - "spdx-exceptions": "^2.1.0", - "spdx-license-ids": "^3.0.0" + "engines": { + "node": ">=10.6.0" } }, - "spdx-license-ids": { - "version": "3.0.13", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.13.tgz", - "integrity": "sha512-XkD+zwiqXHikFZm4AX/7JSCXA98U5Db4AFd5XUg/+9UNtnH75+Z9KxtpYiJZx36mUDVOwH83pl7yvCer6ewM3w==", - "dev": true - }, - "sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", - "dev": true - }, - "sshpk": { - "version": "1.17.0", - "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.17.0.tgz", - "integrity": "sha512-/9HIEs1ZXGhSPE8X6Ccm7Nam1z8KcoCqPdI7ecm1N33EzAetWahvQWVqLZtaZQ+IDKX4IyA2o0gBzqIMkAagHQ==", + "node_modules/swarm-js/node_modules/cacheable-request": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-7.0.4.tgz", + "integrity": "sha512-v+p6ongsrp0yTGbJXjgxPow2+DL93DASP4kXCDKb8/bwRtt9OEF3whggkkDkGNzgcWy2XaF4a8nZglC7uElscg==", "dev": true, - "requires": { - "asn1": "~0.2.3", - "assert-plus": "^1.0.0", - "bcrypt-pbkdf": "^1.0.0", - "dashdash": "^1.12.0", - "ecc-jsbn": "~0.1.1", - "getpass": "^0.1.1", - "jsbn": "~0.1.0", - "safer-buffer": "^2.0.2", - "tweetnacl": "~0.14.0" - }, "dependencies": { - "tweetnacl": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==", - "dev": true - } + "clone-response": "^1.0.2", + "get-stream": "^5.1.0", + "http-cache-semantics": "^4.0.0", + "keyv": "^4.0.0", + "lowercase-keys": "^2.0.0", + "normalize-url": "^6.0.1", + "responselike": "^2.0.0" + }, + "engines": { + "node": ">=8" } }, - "stacktrace-parser": { - "version": "0.1.10", - "resolved": "https://registry.npmjs.org/stacktrace-parser/-/stacktrace-parser-0.1.10.tgz", - "integrity": "sha512-KJP1OCML99+8fhOHxwwzyWrlUuVX5GQ0ZpJTd1DFXhdkrvg1szxfHhawXUZ3g9TkXORQd4/WG68jMlQZ2p8wlg==", + "node_modules/swarm-js/node_modules/decompress-response": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", + "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", "dev": true, - "requires": { - "type-fest": "^0.7.1" - }, "dependencies": { - "type-fest": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.7.1.tgz", - "integrity": "sha512-Ne2YiiGN8bmrmJJEuTWTLJR32nh/JdL1+PSicowtNb0WFpn59GK8/lfD61bVtzguz7b3PBt74nxpv/Pw5po5Rg==", - "dev": true - } + "mimic-response": "^3.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "statuses": { + "node_modules/swarm-js/node_modules/defer-to-connect": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", - "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", - "dev": true - }, - "stealthy-require": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/stealthy-require/-/stealthy-require-1.1.1.tgz", - "integrity": "sha512-ZnWpYnYugiOVEY5GkcuJK1io5V8QmNYChG62gSit9pQVGErXtrKuPC55ITaVSukmMta5qpMU7vqLt2Lnni4f/g==", - "dev": true - }, - "strict-uri-encode": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz", - "integrity": "sha512-R3f198pcvnB+5IpnBlRkphuE9n46WyVl8I39W/ZUTZLz4nqSP/oLYUrcnJrw462Ds8he4YKMov2efsTIw1BDGQ==", - "dev": true + "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.1.tgz", + "integrity": "sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==", + "dev": true, + "engines": { + "node": ">=10" + } }, - "string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "requires": { - "safe-buffer": "~5.2.0" - }, + "node_modules/swarm-js/node_modules/fs-extra": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-4.0.3.tgz", + "integrity": "sha512-q6rbdDd1o2mAnQreO7YADIxf/Whx4AHBiRf6d+/cVT8h44ss+lHgxf1FemcqDnQt9X3ct4McHr+JMGlYSsK7Cg==", + "dev": true, "dependencies": { - "safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" - } + "graceful-fs": "^4.1.2", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" } }, - "string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "node_modules/swarm-js/node_modules/get-stream": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", "dev": true, - "requires": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" - }, "dependencies": { - "ansi-regex": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.1.tgz", - "integrity": "sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw==", - "dev": true - }, - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha512-4XaJ2zQdCzROZDivEVIDPkcQn8LMFSa8kj8Gxb/Lnwzv9A8VctNZ+lfivC/sV3ivW8ElJTERXZoPBRrZKkNKow==", - "dev": true, - "requires": { - "ansi-regex": "^3.0.0" - } - } + "pump": "^3.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "string.prototype.trim": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.7.tgz", - "integrity": "sha512-p6TmeT1T3411M8Cgg9wBTMRtY2q9+PNy9EV1i2lIXUN/btt763oIfxwN3RR8VU6wHX8j/1CFy0L+YuThm6bgOg==", + "node_modules/swarm-js/node_modules/got": { + "version": "11.8.6", + "resolved": "https://registry.npmjs.org/got/-/got-11.8.6.tgz", + "integrity": "sha512-6tfZ91bOr7bOXnK7PRDCGBLa1H4U080YHNaAQ2KsMGlLEzRbk44nsZF2E1IeRc3vtJHPVbKCYgdFbaGO2ljd8g==", "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4" + "dependencies": { + "@sindresorhus/is": "^4.0.0", + "@szmarczak/http-timer": "^4.0.5", + "@types/cacheable-request": "^6.0.1", + "@types/responselike": "^1.0.0", + "cacheable-lookup": "^5.0.3", + "cacheable-request": "^7.0.2", + "decompress-response": "^6.0.0", + "http2-wrapper": "^1.0.0-beta.5.2", + "lowercase-keys": "^2.0.0", + "p-cancelable": "^2.0.0", + "responselike": "^2.0.0" + }, + "engines": { + "node": ">=10.19.0" + }, + "funding": { + "url": "https://github.com/sindresorhus/got?sponsor=1" } }, - "string.prototype.trimend": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.6.tgz", - "integrity": "sha512-JySq+4mrPf9EsDBEDYMOb/lM7XQLulwg5R/m1r0PXEFqrV0qHvl58sdTilSXtKOflCsK2E8jxf+GKC0T07RWwQ==", + "node_modules/swarm-js/node_modules/http2-wrapper": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-1.0.3.tgz", + "integrity": "sha512-V+23sDMr12Wnz7iTcDeJr3O6AIxlnvT/bmaAAAP/Xda35C90p9599p0F1eHR/N1KILWSoWVAiOMFjBBXaXSMxg==", "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4" + "dependencies": { + "quick-lru": "^5.1.1", + "resolve-alpn": "^1.0.0" + }, + "engines": { + "node": ">=10.19.0" } }, - "string.prototype.trimstart": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.6.tgz", - "integrity": "sha512-omqjMDaY92pbn5HOX7f9IccLA+U1tA9GvtU4JrodiXFfYB7jPzzHpRzpglLAjtUV6bB557zwClJezTqnAiYnQA==", + "node_modules/swarm-js/node_modules/lowercase-keys": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", + "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4" + "engines": { + "node": ">=8" } }, - "strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "node_modules/swarm-js/node_modules/mimic-response": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", + "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", "dev": true, - "requires": { - "ansi-regex": "^5.0.1" + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", - "dev": true - }, - "strip-hex-prefix": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/strip-hex-prefix/-/strip-hex-prefix-1.0.0.tgz", - "integrity": "sha512-q8d4ue7JGEiVcypji1bALTos+0pWtyGlivAWyPuTkHzuTCJqrK9sWxYQZUq6Nq3cuyv3bm734IhHvHtGGURU6A==", - "requires": { - "is-hex-prefixed": "1.0.0" + "node_modules/swarm-js/node_modules/normalize-url": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz", + "integrity": "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "strip-json-comments": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", - "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", - "dev": true - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "requires": { - "has-flag": "^4.0.0" + "node_modules/swarm-js/node_modules/p-cancelable": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-2.1.1.tgz", + "integrity": "sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg==", + "dev": true, + "engines": { + "node": ">=8" } }, - "supports-preserve-symlinks-flag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", - "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", - "dev": true - }, - "swarm-js": { - "version": "0.1.42", - "resolved": "https://registry.npmjs.org/swarm-js/-/swarm-js-0.1.42.tgz", - "integrity": "sha512-BV7c/dVlA3R6ya1lMlSSNPLYrntt0LUq4YMgy3iwpCIc6rZnS5W2wUoctarZ5pXlpKtxDDf9hNziEkcfrxdhqQ==", + "node_modules/swarm-js/node_modules/responselike": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/responselike/-/responselike-2.0.1.tgz", + "integrity": "sha512-4gl03wn3hj1HP3yzgdI7d3lCkF95F21Pz4BPGvKHinyQzALR5CapwC8yIi0Rh58DEMQ/SguC03wFj2k0M/mHhw==", "dev": true, - "requires": { - "bluebird": "^3.5.0", - "buffer": "^5.0.5", - "eth-lib": "^0.1.26", - "fs-extra": "^4.0.2", - "got": "^11.8.5", - "mime-types": "^2.1.16", - "mkdirp-promise": "^5.0.1", - "mock-fs": "^4.1.0", - "setimmediate": "^1.0.5", - "tar": "^4.0.2", - "xhr-request": "^1.0.1" - }, "dependencies": { - "@sindresorhus/is": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.6.0.tgz", - "integrity": "sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==", - "dev": true - }, - "@szmarczak/http-timer": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-4.0.6.tgz", - "integrity": "sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w==", - "dev": true, - "requires": { - "defer-to-connect": "^2.0.0" - } - }, - "buffer": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", - "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", - "dev": true, - "requires": { - "base64-js": "^1.3.1", - "ieee754": "^1.1.13" - } - }, - "cacheable-lookup": { - "version": "5.0.4", - "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-5.0.4.tgz", - "integrity": "sha512-2/kNscPhpcxrOigMZzbiWF7dz8ilhb/nIHU3EyZiXWXpeq/au8qJ8VhdftMkty3n7Gj6HIGalQG8oiBNB3AJgA==", - "dev": true - }, - "cacheable-request": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-7.0.4.tgz", - "integrity": "sha512-v+p6ongsrp0yTGbJXjgxPow2+DL93DASP4kXCDKb8/bwRtt9OEF3whggkkDkGNzgcWy2XaF4a8nZglC7uElscg==", - "dev": true, - "requires": { - "clone-response": "^1.0.2", - "get-stream": "^5.1.0", - "http-cache-semantics": "^4.0.0", - "keyv": "^4.0.0", - "lowercase-keys": "^2.0.0", - "normalize-url": "^6.0.1", - "responselike": "^2.0.0" - } - }, - "decompress-response": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", - "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", - "dev": true, - "requires": { - "mimic-response": "^3.1.0" - } - }, - "defer-to-connect": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.1.tgz", - "integrity": "sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==", - "dev": true - }, - "fs-extra": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-4.0.3.tgz", - "integrity": "sha512-q6rbdDd1o2mAnQreO7YADIxf/Whx4AHBiRf6d+/cVT8h44ss+lHgxf1FemcqDnQt9X3ct4McHr+JMGlYSsK7Cg==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - } - }, - "get-stream": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", - "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", - "dev": true, - "requires": { - "pump": "^3.0.0" - } - }, - "got": { - "version": "11.8.6", - "resolved": "https://registry.npmjs.org/got/-/got-11.8.6.tgz", - "integrity": "sha512-6tfZ91bOr7bOXnK7PRDCGBLa1H4U080YHNaAQ2KsMGlLEzRbk44nsZF2E1IeRc3vtJHPVbKCYgdFbaGO2ljd8g==", - "dev": true, - "requires": { - "@sindresorhus/is": "^4.0.0", - "@szmarczak/http-timer": "^4.0.5", - "@types/cacheable-request": "^6.0.1", - "@types/responselike": "^1.0.0", - "cacheable-lookup": "^5.0.3", - "cacheable-request": "^7.0.2", - "decompress-response": "^6.0.0", - "http2-wrapper": "^1.0.0-beta.5.2", - "lowercase-keys": "^2.0.0", - "p-cancelable": "^2.0.0", - "responselike": "^2.0.0" - } - }, - "http2-wrapper": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-1.0.3.tgz", - "integrity": "sha512-V+23sDMr12Wnz7iTcDeJr3O6AIxlnvT/bmaAAAP/Xda35C90p9599p0F1eHR/N1KILWSoWVAiOMFjBBXaXSMxg==", - "dev": true, - "requires": { - "quick-lru": "^5.1.1", - "resolve-alpn": "^1.0.0" - } - }, - "json-buffer": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", - "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", - "dev": true - }, - "keyv": { - "version": "4.5.3", - "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.3.tgz", - "integrity": "sha512-QCiSav9WaX1PgETJ+SpNnx2PRRapJ/oRSXM4VO5OGYGSjrxbKPVFVhB3l2OCbLCk329N8qyAtsJjSjvVBWzEug==", - "dev": true, - "requires": { - "json-buffer": "3.0.1" - } - }, - "lowercase-keys": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", - "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", - "dev": true - }, - "mimic-response": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", - "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", - "dev": true - }, - "normalize-url": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz", - "integrity": "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==", - "dev": true - }, - "p-cancelable": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-2.1.1.tgz", - "integrity": "sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg==", - "dev": true - }, - "responselike": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/responselike/-/responselike-2.0.1.tgz", - "integrity": "sha512-4gl03wn3hj1HP3yzgdI7d3lCkF95F21Pz4BPGvKHinyQzALR5CapwC8yIi0Rh58DEMQ/SguC03wFj2k0M/mHhw==", - "dev": true, - "requires": { - "lowercase-keys": "^2.0.0" - } - } + "lowercase-keys": "^2.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "sync-request": { + "node_modules/sync-request": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/sync-request/-/sync-request-6.1.0.tgz", "integrity": "sha512-8fjNkrNlNCrVc/av+Jn+xxqfCjYaBoHqCsDz6mt030UMxJGr+GSfCV1dQt2gRtlL63+VPidwDVLr7V2OcTSdRw==", "dev": true, - "requires": { + "dependencies": { "http-response-object": "^3.0.1", "sync-rpc": "^1.2.1", "then-request": "^6.0.0" + }, + "engines": { + "node": ">=8.0.0" } }, - "sync-rpc": { + "node_modules/sync-rpc": { "version": "1.3.6", "resolved": "https://registry.npmjs.org/sync-rpc/-/sync-rpc-1.3.6.tgz", "integrity": "sha512-J8jTXuZzRlvU7HemDgHi3pGnh/rkoqR/OZSjhTyyZrEkkYQbk7Z33AXp37mkPfPpfdOuj7Ex3H/TJM1z48uPQw==", "dev": true, - "requires": { + "dependencies": { "get-port": "^3.1.0" } }, - "table": { - "version": "6.8.1", - "resolved": "https://registry.npmjs.org/table/-/table-6.8.1.tgz", - "integrity": "sha512-Y4X9zqrCftUhMeH2EptSSERdVKt/nEdijTOacGD/97EKjhQ/Qs8RTlEGABSJNNN8lac9kheH+af7yAkEWlgneA==", + "node_modules/table": { + "version": "6.8.2", + "resolved": "https://registry.npmjs.org/table/-/table-6.8.2.tgz", + "integrity": "sha512-w2sfv80nrAh2VCbqR5AK27wswXhqcck2AhfnNW76beQXskGZ1V12GwS//yYVa3d3fcvAip2OUnbDAjW2k3v9fA==", "dev": true, - "requires": { + "dependencies": { "ajv": "^8.0.1", "lodash.truncate": "^4.4.2", "slice-ansi": "^4.0.0", "string-width": "^4.2.3", "strip-ansi": "^6.0.1" }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/table/node_modules/ajv": { + "version": "8.12.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", + "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", + "dev": true, "dependencies": { - "ajv": { - "version": "8.12.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", - "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", - "dev": true, - "requires": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - } - }, - "is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true - }, - "json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "dev": true - }, - "string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - } - } + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" } }, - "tar": { + "node_modules/table/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true + }, + "node_modules/tar": { "version": "4.4.19", "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.19.tgz", "integrity": "sha512-a20gEsvHnWe0ygBY8JbxoM4w3SJdhc7ZAuxkLqh+nvNQN2IOt0B5lLgM490X5Hl8FF0dl0tOf2ewFYAlIFgzVA==", "dev": true, - "requires": { + "dependencies": { "chownr": "^1.1.4", "fs-minipass": "^1.2.7", "minipass": "^2.9.0", @@ -42148,54 +21602,60 @@ "safe-buffer": "^5.2.1", "yallist": "^3.1.1" }, - "dependencies": { - "safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "dev": true - } + "engines": { + "node": ">=4.5" } }, - "test-value": { + "node_modules/tar/node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true + }, + "node_modules/test-value": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/test-value/-/test-value-2.1.0.tgz", "integrity": "sha512-+1epbAxtKeXttkGFMTX9H42oqzOTufR1ceCF+GYA5aOmvaPq9wd4PUS8329fn2RRLGNeUkgRLnVpycjx8DsO2w==", "dev": true, - "requires": { + "dependencies": { "array-back": "^1.0.3", "typical": "^2.6.0" }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/test-value/node_modules/array-back": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/array-back/-/array-back-1.0.4.tgz", + "integrity": "sha512-1WxbZvrmyhkNoeYcizokbmh5oiOCIfyvGtcqbK3Ls1v1fKcquzxnQSceOx6tzq7jmai2kFLWIpGND2cLhH6TPw==", + "dev": true, "dependencies": { - "array-back": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/array-back/-/array-back-1.0.4.tgz", - "integrity": "sha512-1WxbZvrmyhkNoeYcizokbmh5oiOCIfyvGtcqbK3Ls1v1fKcquzxnQSceOx6tzq7jmai2kFLWIpGND2cLhH6TPw==", - "dev": true, - "requires": { - "typical": "^2.6.0" - } - } + "typical": "^2.6.0" + }, + "engines": { + "node": ">=0.12.0" } }, - "testrpc": { + "node_modules/testrpc": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/testrpc/-/testrpc-0.0.1.tgz", "integrity": "sha512-afH1hO+SQ/VPlmaLUFj2636QMeDvPCeQMc/9RBMW0IfjNe9gFD9Ra3ShqYkB7py0do1ZcCna/9acHyzTJ+GcNA==", + "deprecated": "testrpc has been renamed to ganache-cli, please use this package from now on.", "dev": true }, - "text-table": { + "node_modules/text-table": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", "dev": true }, - "then-request": { + "node_modules/then-request": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/then-request/-/then-request-6.0.2.tgz", "integrity": "sha512-3ZBiG7JvP3wbDzA9iNY5zJQcHL4jn/0BWtXIkagfz7QgOL/LqjCEOBQuJNZfu0XYnv5JhKh+cDxCPM4ILrqruA==", "dev": true, - "requires": { + "dependencies": { "@types/concat-stream": "^1.6.0", "@types/form-data": "0.0.33", "@types/node": "^8.0.0", @@ -42208,103 +21668,131 @@ "promise": "^8.0.0", "qs": "^6.4.0" }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/then-request/node_modules/@types/node": { + "version": "8.10.66", + "resolved": "https://registry.npmjs.org/@types/node/-/node-8.10.66.tgz", + "integrity": "sha512-tktOkFUA4kXx2hhhrB8bIFb5TbwzS4uOhKEmwiD+NoiL0qtP2OQ9mFldbgD4dV1djrlBYP6eBuQZiWjuHUpqFw==", + "dev": true + }, + "node_modules/then-request/node_modules/form-data": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.5.1.tgz", + "integrity": "sha512-m21N3WOmEEURgk6B9GLOE4RuWOFf28Lhh9qGYeNlGq4VDXUlJy2th2slBNU8Gp8EzloYZOibZJ7t5ecIrFSjVA==", + "dev": true, "dependencies": { - "@types/node": { - "version": "8.10.66", - "resolved": "https://registry.npmjs.org/@types/node/-/node-8.10.66.tgz", - "integrity": "sha512-tktOkFUA4kXx2hhhrB8bIFb5TbwzS4uOhKEmwiD+NoiL0qtP2OQ9mFldbgD4dV1djrlBYP6eBuQZiWjuHUpqFw==", - "dev": true - }, - "form-data": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.5.1.tgz", - "integrity": "sha512-m21N3WOmEEURgk6B9GLOE4RuWOFf28Lhh9qGYeNlGq4VDXUlJy2th2slBNU8Gp8EzloYZOibZJ7t5ecIrFSjVA==", - "dev": true, - "requires": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.6", - "mime-types": "^2.1.12" - } - } + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 0.12" } }, - "timed-out": { + "node_modules/timed-out": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/timed-out/-/timed-out-4.0.1.tgz", "integrity": "sha512-G7r3AhovYtr5YKOWQkta8RKAPb+J9IsO4uVmzjl8AZwfhs8UcUwTiD6gcJYSgOtzyjvQKrKYn41syHbUWMkafA==", - "dev": true + "dev": true, + "engines": { + "node": ">=0.10.0" + } }, - "tmp": { + "node_modules/tmp": { "version": "0.0.33", "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", "dev": true, - "requires": { + "dependencies": { "os-tmpdir": "~1.0.2" + }, + "engines": { + "node": ">=0.6.0" } }, - "to-readable-stream": { + "node_modules/to-readable-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/to-readable-stream/-/to-readable-stream-1.0.0.tgz", "integrity": "sha512-Iq25XBt6zD5npPhlLVXGFN3/gyR2/qODcKNNyTMd4vbm39HUaOiAM4PMq0eMVC/Tkxz+Zjdsc55g9yyz+Yq00Q==", - "dev": true + "dev": true, + "engines": { + "node": ">=6" + } }, - "to-regex-range": { + "node_modules/to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", "dev": true, - "requires": { + "dependencies": { "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" } }, - "toidentifier": { + "node_modules/toidentifier": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", - "dev": true + "dev": true, + "engines": { + "node": ">=0.6" + } }, - "tough-cookie": { + "node_modules/tough-cookie": { "version": "2.5.0", "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", "dev": true, - "requires": { + "dependencies": { "psl": "^1.1.28", "punycode": "^2.1.1" }, - "dependencies": { - "punycode": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz", - "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==", - "dev": true - } + "engines": { + "node": ">=0.8" + } + }, + "node_modules/tough-cookie/node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "dev": true, + "engines": { + "node": ">=6" } }, - "tr46": { + "node_modules/tr46": { "version": "0.0.3", "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" }, - "treeify": { + "node_modules/treeify": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/treeify/-/treeify-1.1.0.tgz", - "integrity": "sha512-1m4RA7xVAJrSGrrXGs0L3YTwyvBs2S8PbRHaLZAkFw7JR8oIFwYtysxlBZhYIa7xSyiYJKZ3iGrrk55cGA3i9A==" + "integrity": "sha512-1m4RA7xVAJrSGrrXGs0L3YTwyvBs2S8PbRHaLZAkFw7JR8oIFwYtysxlBZhYIa7xSyiYJKZ3iGrrk55cGA3i9A==", + "engines": { + "node": ">=0.6" + } }, - "ts-essentials": { + "node_modules/ts-essentials": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/ts-essentials/-/ts-essentials-7.0.3.tgz", "integrity": "sha512-8+gr5+lqO3G84KdiTSMRLtuyJ+nTBVRKuCrK4lidMPdVeEp0uqC875uE5NMcaA7YYMN7XsNiFQuMvasF8HT/xQ==", "dev": true, - "requires": {} + "peerDependencies": { + "typescript": ">=3.7.0" + } }, - "ts-generator": { + "node_modules/ts-generator": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/ts-generator/-/ts-generator-0.1.1.tgz", "integrity": "sha512-N+ahhZxTLYu1HNTQetwWcx3so8hcYbkKBHTr4b4/YgObFTIKkOSSsaa+nal12w8mfrJAyzJfETXawbNjSfP2gQ==", "dev": true, - "requires": { + "dependencies": { "@types/mkdirp": "^0.5.2", "@types/prettier": "^2.1.1", "@types/resolve": "^0.0.8", @@ -42315,77 +21803,93 @@ "resolve": "^1.8.1", "ts-essentials": "^1.0.0" }, + "bin": { + "ts-generator": "dist/cli/run.js" + } + }, + "node_modules/ts-generator/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - }, - "ts-essentials": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/ts-essentials/-/ts-essentials-1.0.4.tgz", - "integrity": "sha512-q3N1xS4vZpRouhYHDPwO0bDW3EZ6SK9CrrDHxi/D6BPReSjpVgWIOpLS2o0gSBZm+7q/wyKp6RVM1AeeW7uyfQ==", - "dev": true - } + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/ts-generator/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/ts-generator/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/ts-generator/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true + }, + "node_modules/ts-generator/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/ts-generator/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/ts-generator/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" } }, - "ts-node": { - "version": "10.9.1", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz", - "integrity": "sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==", + "node_modules/ts-generator/node_modules/ts-essentials": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/ts-essentials/-/ts-essentials-1.0.4.tgz", + "integrity": "sha512-q3N1xS4vZpRouhYHDPwO0bDW3EZ6SK9CrrDHxi/D6BPReSjpVgWIOpLS2o0gSBZm+7q/wyKp6RVM1AeeW7uyfQ==", + "dev": true + }, + "node_modules/ts-node": { + "version": "10.9.2", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz", + "integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==", "dev": true, - "requires": { + "dependencies": { "@cspotcode/source-map-support": "^0.8.0", "@tsconfig/node10": "^1.0.7", "@tsconfig/node12": "^1.0.7", @@ -42400,117 +21904,170 @@ "v8-compile-cache-lib": "^3.0.1", "yn": "3.1.1" }, - "dependencies": { - "acorn": { - "version": "8.10.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.10.0.tgz", - "integrity": "sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==", - "dev": true + "bin": { + "ts-node": "dist/bin.js", + "ts-node-cwd": "dist/bin-cwd.js", + "ts-node-esm": "dist/bin-esm.js", + "ts-node-script": "dist/bin-script.js", + "ts-node-transpile-only": "dist/bin-transpile.js", + "ts-script": "dist/bin-script-deprecated.js" + }, + "peerDependencies": { + "@swc/core": ">=1.2.50", + "@swc/wasm": ">=1.2.50", + "@types/node": "*", + "typescript": ">=2.7" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true }, - "diff": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", - "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", - "dev": true + "@swc/wasm": { + "optional": true } } }, - "tsconfig-paths": { - "version": "3.14.2", - "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.14.2.tgz", - "integrity": "sha512-o/9iXgCYc5L/JxCHPe3Hvh8Q/2xm5Z+p18PESBU6Ff33695QnCHBEjcytY2q19ua7Mbl/DavtBOLq+oG0RCL+g==", + "node_modules/ts-node/node_modules/acorn": { + "version": "8.11.3", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", + "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/ts-node/node_modules/diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "dev": true, + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/tsconfig-paths": { + "version": "3.15.0", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz", + "integrity": "sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==", "dev": true, - "requires": { + "dependencies": { "@types/json5": "^0.0.29", "json5": "^1.0.2", "minimist": "^1.2.6", "strip-bom": "^3.0.0" } }, - "tslib": { + "node_modules/tslib": { "version": "1.14.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", "dev": true }, - "tsort": { + "node_modules/tsort": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/tsort/-/tsort-0.0.1.tgz", "integrity": "sha512-Tyrf5mxF8Ofs1tNoxA13lFeZ2Zrbd6cKbuH3V+MQ5sb6DtBj5FjrXVsRWT8YvNAQTqNoz66dz1WsbigI22aEnw==", "dev": true }, - "tsutils": { + "node_modules/tsutils": { "version": "3.21.0", "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", "dev": true, - "requires": { + "dependencies": { "tslib": "^1.8.1" + }, + "engines": { + "node": ">= 6" + }, + "peerDependencies": { + "typescript": ">=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta" } }, - "tunnel-agent": { + "node_modules/tunnel-agent": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", "dev": true, - "requires": { + "dependencies": { "safe-buffer": "^5.0.1" + }, + "engines": { + "node": "*" } }, - "tweetnacl": { + "node_modules/tweetnacl": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.3.tgz", "integrity": "sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==", "dev": true }, - "tweetnacl-util": { + "node_modules/tweetnacl-util": { "version": "0.15.1", "resolved": "https://registry.npmjs.org/tweetnacl-util/-/tweetnacl-util-0.15.1.tgz", "integrity": "sha512-RKJBIj8lySrShN4w6i/BonWp2Z/uxwC3h4y7xsRrpP59ZboCd0GpEVsOnMDYLMmKBpYhb5TgHzZXy7wTfYFBRw==", "dev": true }, - "type": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/type/-/type-1.2.0.tgz", - "integrity": "sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg==", + "node_modules/type": { + "version": "2.7.2", + "resolved": "https://registry.npmjs.org/type/-/type-2.7.2.tgz", + "integrity": "sha512-dzlvlNlt6AXU7EBSfpAscydQ7gXB+pPGsPnfJnZpiNJBDj7IaJzQlBZYGdEi4R9HmPdBv2XmWJ6YUtoTa7lmCw==", "dev": true }, - "type-check": { + "node_modules/type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", "dev": true, - "requires": { + "dependencies": { "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" } }, - "type-detect": { + "node_modules/type-detect": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", - "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==" + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "engines": { + "node": ">=4" + } }, - "type-fest": { + "node_modules/type-fest": { "version": "0.20.2", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", - "dev": true + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } }, - "type-is": { + "node_modules/type-is": { "version": "1.6.18", "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", "dev": true, - "requires": { + "dependencies": { "media-typer": "0.3.0", "mime-types": "~2.1.24" + }, + "engines": { + "node": ">= 0.6" } }, - "typechain": { + "node_modules/typechain": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/typechain/-/typechain-5.2.0.tgz", "integrity": "sha512-0INirvQ+P+MwJOeMct+WLkUE4zov06QxC96D+i3uGFEHoiSkZN70MKDQsaj8zkL86wQwByJReI2e7fOUwECFuw==", "dev": true, - "requires": { + "dependencies": { "@types/prettier": "^2.1.1", "command-line-args": "^4.0.7", "debug": "^4.1.1", @@ -42522,206 +22079,278 @@ "prettier": "^2.1.2", "ts-essentials": "^7.0.1" }, - "dependencies": { - "mkdirp": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", - "dev": true - } + "bin": { + "typechain": "dist/cli/cli.js" + }, + "peerDependencies": { + "typescript": ">=4.1.0" } }, - "typed-array-buffer": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.0.tgz", - "integrity": "sha512-Y8KTSIglk9OZEr8zywiIHG/kmQ7KWyjseXs1CbSo8vC42w7hg2HgYTxSWwP0+is7bWDc1H+Fo026CpHFwm8tkw==", + "node_modules/typechain/node_modules/mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", "dev": true, - "requires": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.2.1", - "is-typed-array": "^1.1.10" + "bin": { + "mkdirp": "bin/cmd.js" + }, + "engines": { + "node": ">=10" } }, - "typed-array-byte-length": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.0.tgz", - "integrity": "sha512-Or/+kvLxNpeQ9DtSydonMxCx+9ZXOswtwJn17SNLvhptaXYDJvkFFP5zbfU/uLmvnBJlI4yrnXRxpdWH/M5tNA==", + "node_modules/typed-array-buffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.2.tgz", + "integrity": "sha512-gEymJYKZtKXzzBzM4jqa9w6Q1Jjm7x2d+sh19AdsD4wqnMPDYyvwpsIc2Q/835kHuo3BEQ7CjelGhfTsoBb2MQ==", "dev": true, - "requires": { - "call-bind": "^1.0.2", + "dependencies": { + "call-bind": "^1.0.7", + "es-errors": "^1.3.0", + "is-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/typed-array-byte-length": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.1.tgz", + "integrity": "sha512-3iMJ9q0ao7WE9tWcaYKIptkNBuOIcZCCT0d4MRvuuH88fEoEH62IuQe0OtraD3ebQEoTRk8XCBoknUNc1Y67pw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", "for-each": "^0.3.3", - "has-proto": "^1.0.1", - "is-typed-array": "^1.1.10" + "gopd": "^1.0.1", + "has-proto": "^1.0.3", + "is-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "typed-array-byte-offset": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.0.tgz", - "integrity": "sha512-RD97prjEt9EL8YgAgpOkf3O4IF9lhJFr9g0htQkm0rchFp/Vx7LW5Q8fSXXub7BXAODyUQohRMyOc3faCPd0hg==", + "node_modules/typed-array-byte-offset": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.2.tgz", + "integrity": "sha512-Ous0vodHa56FviZucS2E63zkgtgrACj7omjwd/8lTEMEPFFyjfixMZ1ZXenpgCFBBt4EC1J2XsyVS2gkG0eTFA==", "dev": true, - "requires": { - "available-typed-arrays": "^1.0.5", - "call-bind": "^1.0.2", + "dependencies": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.7", "for-each": "^0.3.3", - "has-proto": "^1.0.1", - "is-typed-array": "^1.1.10" + "gopd": "^1.0.1", + "has-proto": "^1.0.3", + "is-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "typed-array-length": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.4.tgz", - "integrity": "sha512-KjZypGq+I/H7HI5HlOoGHkWUUGq+Q0TPhQurLbyrVrvnKTBgzLhIJ7j6J/XTQOi0d1RjyZ0wdas8bKs2p0x3Ng==", + "node_modules/typed-array-length": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.6.tgz", + "integrity": "sha512-/OxDN6OtAk5KBpGb28T+HZc2M+ADtvRxXrKKbUwtsLgdoxgX13hyy7ek6bFRl5+aBs2yZzB0c4CnQfAtVypW/g==", "dev": true, - "requires": { - "call-bind": "^1.0.2", + "dependencies": { + "call-bind": "^1.0.7", "for-each": "^0.3.3", - "is-typed-array": "^1.1.9" + "gopd": "^1.0.1", + "has-proto": "^1.0.3", + "is-typed-array": "^1.1.13", + "possible-typed-array-names": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "typedarray": { + "node_modules/typedarray": { "version": "0.0.6", "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==", "dev": true }, - "typedarray-to-buffer": { + "node_modules/typedarray-to-buffer": { "version": "3.1.5", "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", "dev": true, - "requires": { + "dependencies": { "is-typedarray": "^1.0.0" } }, - "typescript": { + "node_modules/typescript": { "version": "4.9.5", "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", - "dev": true + "dev": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=4.2.0" + } }, - "typical": { + "node_modules/typical": { "version": "2.6.1", "resolved": "https://registry.npmjs.org/typical/-/typical-2.6.1.tgz", "integrity": "sha512-ofhi8kjIje6npGozTip9Fr8iecmYfEbS06i0JnIg+rh51KakryWF4+jX8lLKZVhy6N+ID45WYSFCxPOdTWCzNg==", "dev": true }, - "uglify-js": { + "node_modules/uglify-js": { "version": "3.17.4", "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.17.4.tgz", "integrity": "sha512-T9q82TJI9e/C1TAxYvfb16xO120tMVFZrGA3f9/P4424DNu6ypK103y0GPFVa17yotwSyZW5iYXgjYHkGrJW/g==", "dev": true, - "optional": true + "optional": true, + "bin": { + "uglifyjs": "bin/uglifyjs" + }, + "engines": { + "node": ">=0.8.0" + } }, - "ultron": { + "node_modules/ultron": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/ultron/-/ultron-1.1.1.tgz", "integrity": "sha512-UIEXBNeYmKptWH6z8ZnqTeS8fV74zG0/eRU9VGkpzz+LIJNs8W/zM/L+7ctCkRrgbNnnR0xxw4bKOr0cW0N0Og==", "dev": true }, - "unbox-primitive": { + "node_modules/unbox-primitive": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", "dev": true, - "requires": { + "dependencies": { "call-bind": "^1.0.2", "has-bigints": "^1.0.2", "has-symbols": "^1.0.3", "which-boxed-primitive": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "undici": { - "version": "5.26.3", - "resolved": "https://registry.npmjs.org/undici/-/undici-5.26.3.tgz", - "integrity": "sha512-H7n2zmKEWgOllKkIUkLvFmsJQj062lSm3uA4EYApG8gLuiOM0/go9bIoC3HVaSnfg4xunowDE2i9p8drkXuvDw==", + "node_modules/undici": { + "version": "5.28.4", + "resolved": "https://registry.npmjs.org/undici/-/undici-5.28.4.tgz", + "integrity": "sha512-72RFADWFqKmUb2hmmvNODKL3p9hcB6Gt2DOQMis1SEBaV6a4MH8soBvzg+95CYhCKPFedut2JY9bMfrDl9D23g==", "dev": true, - "requires": { + "dependencies": { "@fastify/busboy": "^2.0.0" + }, + "engines": { + "node": ">=14.0" } }, - "universalify": { + "node_modules/universalify": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", - "dev": true + "dev": true, + "engines": { + "node": ">= 4.0.0" + } }, - "unpipe": { + "node_modules/unpipe": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", - "dev": true + "dev": true, + "engines": { + "node": ">= 0.8" + } }, - "uri-js": { + "node_modules/uri-js": { "version": "4.4.1", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", "dev": true, - "requires": { + "dependencies": { "punycode": "^2.1.0" } }, - "url": { - "version": "0.11.1", - "resolved": "https://registry.npmjs.org/url/-/url-0.11.1.tgz", - "integrity": "sha512-rWS3H04/+mzzJkv0eZ7vEDGiQbgquI1fGfOad6zKvgYQi1SzMmhl7c/DdRGxhaWrVH6z0qWITo8rpnxK/RfEhA==", + "node_modules/url": { + "version": "0.11.3", + "resolved": "https://registry.npmjs.org/url/-/url-0.11.3.tgz", + "integrity": "sha512-6hxOLGfZASQK/cijlZnZJTq8OXAkt/3YGfQX45vvMYXpZoo8NdWZcY73K108Jf759lS1Bv/8wXnHDTSz17dSRw==", "dev": true, - "requires": { - "punycode": "^1.4.1", - "qs": "^6.11.0" - }, "dependencies": { - "punycode": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ==", - "dev": true - }, - "qs": { - "version": "6.11.2", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.2.tgz", - "integrity": "sha512-tDNIz22aBzCDxLtVH++VnTfzxlfeK5CbqohpSqpJgj1Wg/cQbStNAz3NuqCs5vV+pjBsK4x4pN9HlVh7rcYRiA==", - "dev": true, - "requires": { - "side-channel": "^1.0.4" - } - } + "punycode": "^1.4.1", + "qs": "^6.11.2" } }, - "url-parse-lax": { + "node_modules/url-parse-lax": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-3.0.0.tgz", "integrity": "sha512-NjFKA0DidqPa5ciFcSrXnAltTtzz84ogy+NebPvfEgAck0+TNg4UJ4IN+fB7zRZfbgUf0syOo9MDxFkDSMuFaQ==", "dev": true, - "requires": { + "dependencies": { "prepend-http": "^2.0.0" + }, + "engines": { + "node": ">=4" } }, - "url-set-query": { + "node_modules/url-set-query": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/url-set-query/-/url-set-query-1.0.0.tgz", "integrity": "sha512-3AChu4NiXquPfeckE5R5cGdiHCMWJx1dwCWOmWIL4KHAziJNOFIYJlpGFeKDvwLPHovZRCxK3cYlwzqI9Vp+Gg==", "dev": true }, - "utf-8-validate": { + "node_modules/url/node_modules/punycode": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", + "integrity": "sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ==", + "dev": true + }, + "node_modules/url/node_modules/qs": { + "version": "6.12.1", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.12.1.tgz", + "integrity": "sha512-zWmv4RSuB9r2mYQw3zxQuHWeU+42aKi1wWig/j4ele4ygELZ7PEO6MM7rim9oAQH2A5MWfsAVf/jPvTPgCbvUQ==", + "dev": true, + "dependencies": { + "side-channel": "^1.0.6" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/utf-8-validate": { "version": "5.0.10", "resolved": "https://registry.npmjs.org/utf-8-validate/-/utf-8-validate-5.0.10.tgz", "integrity": "sha512-Z6czzLq4u8fPOyx7TU6X3dvUZVvoJmxSQ+IcrlmagKhilxlhZgxPK6C5Jqbkw1IDUmFTM+cz9QDnnLTwDz/2gQ==", "devOptional": true, - "requires": { + "hasInstallScript": true, + "dependencies": { "node-gyp-build": "^4.3.0" + }, + "engines": { + "node": ">=6.14.2" } }, - "utf8": { + "node_modules/utf8": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/utf8/-/utf8-3.0.0.tgz", "integrity": "sha512-E8VjFIQ/TyQgp+TZfS6l8yp/xWppSAHzidGiRrqe4bK4XP9pTRyKFgGJpO3SN7zdX4DeomTrwaseCHovfpFcqQ==" }, - "util": { + "node_modules/util": { "version": "0.12.5", "resolved": "https://registry.npmjs.org/util/-/util-0.12.5.tgz", "integrity": "sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA==", "dev": true, - "requires": { + "dependencies": { "inherits": "^2.0.3", "is-arguments": "^1.0.4", "is-generator-function": "^1.0.7", @@ -42729,74 +22358,87 @@ "which-typed-array": "^1.1.2" } }, - "util-deprecate": { + "node_modules/util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" }, - "utils-merge": { + "node_modules/utils-merge": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", - "dev": true + "dev": true, + "engines": { + "node": ">= 0.4.0" + } }, - "uuid": { + "node_modules/uuid": { "version": "8.3.2", "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", - "dev": true + "dev": true, + "bin": { + "uuid": "dist/bin/uuid" + } }, - "v8-compile-cache": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", - "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", + "node_modules/v8-compile-cache": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.4.0.tgz", + "integrity": "sha512-ocyWc3bAHBB/guyqJQVI5o4BZkPhznPYUG2ea80Gond/BgNWpap8TOmLSeeQG7bnh2KMISxskdADG59j7zruhw==", "dev": true }, - "v8-compile-cache-lib": { + "node_modules/v8-compile-cache-lib": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", "dev": true }, - "validate-npm-package-license": { + "node_modules/validate-npm-package-license": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", "dev": true, - "requires": { + "dependencies": { "spdx-correct": "^3.0.0", "spdx-expression-parse": "^3.0.0" } }, - "varint": { + "node_modules/varint": { "version": "5.0.2", "resolved": "https://registry.npmjs.org/varint/-/varint-5.0.2.tgz", "integrity": "sha512-lKxKYG6H03yCZUpAGOPOsMcGxd1RHCu1iKvEHYDPmTyq2HueGhD73ssNBqqQWfvYs04G9iUFRvmAVLW20Jw6ow==", "dev": true }, - "vary": { + "node_modules/vary": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", - "dev": true + "dev": true, + "engines": { + "node": ">= 0.8" + } }, - "verror": { + "node_modules/verror": { "version": "1.10.0", "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", "integrity": "sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw==", "dev": true, - "requires": { + "engines": [ + "node >=0.6.0" + ], + "dependencies": { "assert-plus": "^1.0.0", "core-util-is": "1.0.2", "extsprintf": "^1.2.0" } }, - "web3": { + "node_modules/web3": { "version": "1.7.4", "resolved": "https://registry.npmjs.org/web3/-/web3-1.7.4.tgz", "integrity": "sha512-iFGK5jO32vnXM/ASaJBaI0+gVR6uHozvYdxkdhaeOCD6HIQ4iIXadbO2atVpE9oc/H8l2MovJ4LtPhG7lIBN8A==", "dev": true, - "requires": { + "hasInstallScript": true, + "dependencies": { "web3-bzz": "1.7.4", "web3-core": "1.7.4", "web3-eth": "1.7.4", @@ -42805,77 +22447,31 @@ "web3-shh": "1.7.4", "web3-utils": "1.7.4" }, - "dependencies": { - "ethereum-cryptography": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz", - "integrity": "sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==", - "dev": true, - "requires": { - "@types/pbkdf2": "^3.0.0", - "@types/secp256k1": "^4.0.1", - "blakejs": "^1.1.0", - "browserify-aes": "^1.2.0", - "bs58check": "^2.1.2", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "hash.js": "^1.1.7", - "keccak": "^3.0.0", - "pbkdf2": "^3.0.17", - "randombytes": "^2.1.0", - "safe-buffer": "^5.1.2", - "scrypt-js": "^3.0.0", - "secp256k1": "^4.0.1", - "setimmediate": "^1.0.5" - } - }, - "ethereumjs-util": { - "version": "7.1.5", - "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-7.1.5.tgz", - "integrity": "sha512-SDl5kKrQAudFBUe5OJM9Ac6WmMyYmXX/6sTmLZ3ffG2eY6ZIGBes3pEDxNN6V72WyOw4CPD5RomKdsa8DAAwLg==", - "dev": true, - "requires": { - "@types/bn.js": "^5.1.0", - "bn.js": "^5.1.2", - "create-hash": "^1.1.2", - "ethereum-cryptography": "^0.1.3", - "rlp": "^2.2.4" - } - }, - "web3-utils": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.7.4.tgz", - "integrity": "sha512-acBdm6Evd0TEZRnChM/MCvGsMwYKmSh7OaUfNf5OKG0CIeGWD/6gqLOWIwmwSnre/2WrA1nKGId5uW2e5EfluA==", - "dev": true, - "requires": { - "bn.js": "^5.2.1", - "ethereum-bloom-filters": "^1.0.6", - "ethereumjs-util": "^7.1.0", - "ethjs-unit": "0.1.6", - "number-to-bn": "1.7.0", - "randombytes": "^2.1.0", - "utf8": "3.0.0" - } - } + "engines": { + "node": ">=8.0.0" } }, - "web3-bzz": { + "node_modules/web3-bzz": { "version": "1.7.4", "resolved": "https://registry.npmjs.org/web3-bzz/-/web3-bzz-1.7.4.tgz", "integrity": "sha512-w9zRhyEqTK/yi0LGRHjZMcPCfP24LBjYXI/9YxFw9VqsIZ9/G0CRCnUt12lUx0A56LRAMpF7iQ8eA73aBcO29Q==", "dev": true, - "requires": { + "hasInstallScript": true, + "dependencies": { "@types/node": "^12.12.6", "got": "9.6.0", "swarm-js": "^0.1.40" + }, + "engines": { + "node": ">=8.0.0" } }, - "web3-core": { + "node_modules/web3-core": { "version": "1.7.4", "resolved": "https://registry.npmjs.org/web3-core/-/web3-core-1.7.4.tgz", "integrity": "sha512-L0DCPlIh9bgIED37tYbe7bsWrddoXYc897ANGvTJ6MFkSNGiMwDkTLWSgYd9Mf8qu8b4iuPqXZHMwIo4atoh7Q==", "dev": true, - "requires": { + "dependencies": { "@types/bn.js": "^5.1.0", "@types/node": "^12.12.6", "bignumber.js": "^9.0.0", @@ -42884,227 +22480,140 @@ "web3-core-requestmanager": "1.7.4", "web3-utils": "1.7.4" }, - "dependencies": { - "ethereum-cryptography": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz", - "integrity": "sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==", - "dev": true, - "requires": { - "@types/pbkdf2": "^3.0.0", - "@types/secp256k1": "^4.0.1", - "blakejs": "^1.1.0", - "browserify-aes": "^1.2.0", - "bs58check": "^2.1.2", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "hash.js": "^1.1.7", - "keccak": "^3.0.0", - "pbkdf2": "^3.0.17", - "randombytes": "^2.1.0", - "safe-buffer": "^5.1.2", - "scrypt-js": "^3.0.0", - "secp256k1": "^4.0.1", - "setimmediate": "^1.0.5" - } - }, - "ethereumjs-util": { - "version": "7.1.5", - "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-7.1.5.tgz", - "integrity": "sha512-SDl5kKrQAudFBUe5OJM9Ac6WmMyYmXX/6sTmLZ3ffG2eY6ZIGBes3pEDxNN6V72WyOw4CPD5RomKdsa8DAAwLg==", - "dev": true, - "requires": { - "@types/bn.js": "^5.1.0", - "bn.js": "^5.1.2", - "create-hash": "^1.1.2", - "ethereum-cryptography": "^0.1.3", - "rlp": "^2.2.4" - } - }, - "web3-utils": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.7.4.tgz", - "integrity": "sha512-acBdm6Evd0TEZRnChM/MCvGsMwYKmSh7OaUfNf5OKG0CIeGWD/6gqLOWIwmwSnre/2WrA1nKGId5uW2e5EfluA==", - "dev": true, - "requires": { - "bn.js": "^5.2.1", - "ethereum-bloom-filters": "^1.0.6", - "ethereumjs-util": "^7.1.0", - "ethjs-unit": "0.1.6", - "number-to-bn": "1.7.0", - "randombytes": "^2.1.0", - "utf8": "3.0.0" - } - } + "engines": { + "node": ">=8.0.0" } }, - "web3-core-helpers": { + "node_modules/web3-core-helpers": { "version": "1.7.4", "resolved": "https://registry.npmjs.org/web3-core-helpers/-/web3-core-helpers-1.7.4.tgz", "integrity": "sha512-F8PH11qIkE/LpK4/h1fF/lGYgt4B6doeMi8rukeV/s4ivseZHHslv1L6aaijLX/g/j4PsFmR42byynBI/MIzFg==", "dev": true, - "requires": { + "dependencies": { "web3-eth-iban": "1.7.4", "web3-utils": "1.7.4" }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-core-helpers/node_modules/web3-utils": { + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.7.4.tgz", + "integrity": "sha512-acBdm6Evd0TEZRnChM/MCvGsMwYKmSh7OaUfNf5OKG0CIeGWD/6gqLOWIwmwSnre/2WrA1nKGId5uW2e5EfluA==", + "dev": true, "dependencies": { - "ethereum-cryptography": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz", - "integrity": "sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==", - "dev": true, - "requires": { - "@types/pbkdf2": "^3.0.0", - "@types/secp256k1": "^4.0.1", - "blakejs": "^1.1.0", - "browserify-aes": "^1.2.0", - "bs58check": "^2.1.2", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "hash.js": "^1.1.7", - "keccak": "^3.0.0", - "pbkdf2": "^3.0.17", - "randombytes": "^2.1.0", - "safe-buffer": "^5.1.2", - "scrypt-js": "^3.0.0", - "secp256k1": "^4.0.1", - "setimmediate": "^1.0.5" - } - }, - "ethereumjs-util": { - "version": "7.1.5", - "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-7.1.5.tgz", - "integrity": "sha512-SDl5kKrQAudFBUe5OJM9Ac6WmMyYmXX/6sTmLZ3ffG2eY6ZIGBes3pEDxNN6V72WyOw4CPD5RomKdsa8DAAwLg==", - "dev": true, - "requires": { - "@types/bn.js": "^5.1.0", - "bn.js": "^5.1.2", - "create-hash": "^1.1.2", - "ethereum-cryptography": "^0.1.3", - "rlp": "^2.2.4" - } - }, - "web3-utils": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.7.4.tgz", - "integrity": "sha512-acBdm6Evd0TEZRnChM/MCvGsMwYKmSh7OaUfNf5OKG0CIeGWD/6gqLOWIwmwSnre/2WrA1nKGId5uW2e5EfluA==", - "dev": true, - "requires": { - "bn.js": "^5.2.1", - "ethereum-bloom-filters": "^1.0.6", - "ethereumjs-util": "^7.1.0", - "ethjs-unit": "0.1.6", - "number-to-bn": "1.7.0", - "randombytes": "^2.1.0", - "utf8": "3.0.0" - } - } + "bn.js": "^5.2.1", + "ethereum-bloom-filters": "^1.0.6", + "ethereumjs-util": "^7.1.0", + "ethjs-unit": "0.1.6", + "number-to-bn": "1.7.0", + "randombytes": "^2.1.0", + "utf8": "3.0.0" + }, + "engines": { + "node": ">=8.0.0" } }, - "web3-core-method": { + "node_modules/web3-core-method": { "version": "1.7.4", "resolved": "https://registry.npmjs.org/web3-core-method/-/web3-core-method-1.7.4.tgz", "integrity": "sha512-56K7pq+8lZRkxJyzf5MHQPI9/VL3IJLoy4L/+q8HRdZJ3CkB1DkXYaXGU2PeylG1GosGiSzgIfu1ljqS7CP9xQ==", "dev": true, - "requires": { + "dependencies": { "@ethersproject/transactions": "^5.6.2", "web3-core-helpers": "1.7.4", "web3-core-promievent": "1.7.4", "web3-core-subscriptions": "1.7.4", "web3-utils": "1.7.4" }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-core-method/node_modules/web3-utils": { + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.7.4.tgz", + "integrity": "sha512-acBdm6Evd0TEZRnChM/MCvGsMwYKmSh7OaUfNf5OKG0CIeGWD/6gqLOWIwmwSnre/2WrA1nKGId5uW2e5EfluA==", + "dev": true, "dependencies": { - "ethereum-cryptography": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz", - "integrity": "sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==", - "dev": true, - "requires": { - "@types/pbkdf2": "^3.0.0", - "@types/secp256k1": "^4.0.1", - "blakejs": "^1.1.0", - "browserify-aes": "^1.2.0", - "bs58check": "^2.1.2", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "hash.js": "^1.1.7", - "keccak": "^3.0.0", - "pbkdf2": "^3.0.17", - "randombytes": "^2.1.0", - "safe-buffer": "^5.1.2", - "scrypt-js": "^3.0.0", - "secp256k1": "^4.0.1", - "setimmediate": "^1.0.5" - } - }, - "ethereumjs-util": { - "version": "7.1.5", - "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-7.1.5.tgz", - "integrity": "sha512-SDl5kKrQAudFBUe5OJM9Ac6WmMyYmXX/6sTmLZ3ffG2eY6ZIGBes3pEDxNN6V72WyOw4CPD5RomKdsa8DAAwLg==", - "dev": true, - "requires": { - "@types/bn.js": "^5.1.0", - "bn.js": "^5.1.2", - "create-hash": "^1.1.2", - "ethereum-cryptography": "^0.1.3", - "rlp": "^2.2.4" - } - }, - "web3-utils": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.7.4.tgz", - "integrity": "sha512-acBdm6Evd0TEZRnChM/MCvGsMwYKmSh7OaUfNf5OKG0CIeGWD/6gqLOWIwmwSnre/2WrA1nKGId5uW2e5EfluA==", - "dev": true, - "requires": { - "bn.js": "^5.2.1", - "ethereum-bloom-filters": "^1.0.6", - "ethereumjs-util": "^7.1.0", - "ethjs-unit": "0.1.6", - "number-to-bn": "1.7.0", - "randombytes": "^2.1.0", - "utf8": "3.0.0" - } - } + "bn.js": "^5.2.1", + "ethereum-bloom-filters": "^1.0.6", + "ethereumjs-util": "^7.1.0", + "ethjs-unit": "0.1.6", + "number-to-bn": "1.7.0", + "randombytes": "^2.1.0", + "utf8": "3.0.0" + }, + "engines": { + "node": ">=8.0.0" } }, - "web3-core-promievent": { + "node_modules/web3-core-promievent": { "version": "1.7.4", "resolved": "https://registry.npmjs.org/web3-core-promievent/-/web3-core-promievent-1.7.4.tgz", "integrity": "sha512-o4uxwXKDldN7ER7VUvDfWsqTx9nQSP1aDssi1XYXeYC2xJbVo0n+z6ryKtmcoWoRdRj7uSpVzal3nEmlr480mA==", "dev": true, - "requires": { + "dependencies": { "eventemitter3": "4.0.4" + }, + "engines": { + "node": ">=8.0.0" } }, - "web3-core-requestmanager": { + "node_modules/web3-core-requestmanager": { "version": "1.7.4", "resolved": "https://registry.npmjs.org/web3-core-requestmanager/-/web3-core-requestmanager-1.7.4.tgz", "integrity": "sha512-IuXdAm65BQtPL4aI6LZJJOrKAs0SM5IK2Cqo2/lMNvVMT9Kssq6qOk68Uf7EBDH0rPuINi+ReLP+uH+0g3AnPA==", "dev": true, - "requires": { + "dependencies": { "util": "^0.12.0", "web3-core-helpers": "1.7.4", "web3-providers-http": "1.7.4", "web3-providers-ipc": "1.7.4", "web3-providers-ws": "1.7.4" + }, + "engines": { + "node": ">=8.0.0" } }, - "web3-core-subscriptions": { + "node_modules/web3-core-subscriptions": { "version": "1.7.4", "resolved": "https://registry.npmjs.org/web3-core-subscriptions/-/web3-core-subscriptions-1.7.4.tgz", "integrity": "sha512-VJvKWaXRyxk2nFWumOR94ut9xvjzMrRtS38c4qj8WBIRSsugrZr5lqUwgndtj0qx4F+50JhnU++QEqUEAtKm3g==", "dev": true, - "requires": { + "dependencies": { "eventemitter3": "4.0.4", "web3-core-helpers": "1.7.4" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-core/node_modules/web3-utils": { + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.7.4.tgz", + "integrity": "sha512-acBdm6Evd0TEZRnChM/MCvGsMwYKmSh7OaUfNf5OKG0CIeGWD/6gqLOWIwmwSnre/2WrA1nKGId5uW2e5EfluA==", + "dev": true, + "dependencies": { + "bn.js": "^5.2.1", + "ethereum-bloom-filters": "^1.0.6", + "ethereumjs-util": "^7.1.0", + "ethjs-unit": "0.1.6", + "number-to-bn": "1.7.0", + "randombytes": "^2.1.0", + "utf8": "3.0.0" + }, + "engines": { + "node": ">=8.0.0" } }, - "web3-eth": { + "node_modules/web3-eth": { "version": "1.7.4", "resolved": "https://registry.npmjs.org/web3-eth/-/web3-eth-1.7.4.tgz", "integrity": "sha512-JG0tTMv0Ijj039emXNHi07jLb0OiWSA9O24MRSk5vToTQyDNXihdF2oyq85LfHuF690lXZaAXrjhtLNlYqb7Ug==", "dev": true, - "requires": { + "dependencies": { "web3-core": "1.7.4", "web3-core-helpers": "1.7.4", "web3-core-method": "1.7.4", @@ -43118,129 +22627,47 @@ "web3-net": "1.7.4", "web3-utils": "1.7.4" }, - "dependencies": { - "ethereum-cryptography": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz", - "integrity": "sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==", - "dev": true, - "requires": { - "@types/pbkdf2": "^3.0.0", - "@types/secp256k1": "^4.0.1", - "blakejs": "^1.1.0", - "browserify-aes": "^1.2.0", - "bs58check": "^2.1.2", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "hash.js": "^1.1.7", - "keccak": "^3.0.0", - "pbkdf2": "^3.0.17", - "randombytes": "^2.1.0", - "safe-buffer": "^5.1.2", - "scrypt-js": "^3.0.0", - "secp256k1": "^4.0.1", - "setimmediate": "^1.0.5" - } - }, - "ethereumjs-util": { - "version": "7.1.5", - "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-7.1.5.tgz", - "integrity": "sha512-SDl5kKrQAudFBUe5OJM9Ac6WmMyYmXX/6sTmLZ3ffG2eY6ZIGBes3pEDxNN6V72WyOw4CPD5RomKdsa8DAAwLg==", - "dev": true, - "requires": { - "@types/bn.js": "^5.1.0", - "bn.js": "^5.1.2", - "create-hash": "^1.1.2", - "ethereum-cryptography": "^0.1.3", - "rlp": "^2.2.4" - } - }, - "web3-utils": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.7.4.tgz", - "integrity": "sha512-acBdm6Evd0TEZRnChM/MCvGsMwYKmSh7OaUfNf5OKG0CIeGWD/6gqLOWIwmwSnre/2WrA1nKGId5uW2e5EfluA==", - "dev": true, - "requires": { - "bn.js": "^5.2.1", - "ethereum-bloom-filters": "^1.0.6", - "ethereumjs-util": "^7.1.0", - "ethjs-unit": "0.1.6", - "number-to-bn": "1.7.0", - "randombytes": "^2.1.0", - "utf8": "3.0.0" - } - } + "engines": { + "node": ">=8.0.0" } }, - "web3-eth-abi": { + "node_modules/web3-eth-abi": { "version": "1.7.4", "resolved": "https://registry.npmjs.org/web3-eth-abi/-/web3-eth-abi-1.7.4.tgz", "integrity": "sha512-eMZr8zgTbqyL9MCTCAvb67RbVyN5ZX7DvA0jbLOqRWCiw+KlJKTGnymKO6jPE8n5yjk4w01e165Qb11hTDwHgg==", "dev": true, - "requires": { + "dependencies": { "@ethersproject/abi": "^5.6.3", "web3-utils": "1.7.4" }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-eth-abi/node_modules/web3-utils": { + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.7.4.tgz", + "integrity": "sha512-acBdm6Evd0TEZRnChM/MCvGsMwYKmSh7OaUfNf5OKG0CIeGWD/6gqLOWIwmwSnre/2WrA1nKGId5uW2e5EfluA==", + "dev": true, "dependencies": { - "ethereum-cryptography": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz", - "integrity": "sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==", - "dev": true, - "requires": { - "@types/pbkdf2": "^3.0.0", - "@types/secp256k1": "^4.0.1", - "blakejs": "^1.1.0", - "browserify-aes": "^1.2.0", - "bs58check": "^2.1.2", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "hash.js": "^1.1.7", - "keccak": "^3.0.0", - "pbkdf2": "^3.0.17", - "randombytes": "^2.1.0", - "safe-buffer": "^5.1.2", - "scrypt-js": "^3.0.0", - "secp256k1": "^4.0.1", - "setimmediate": "^1.0.5" - } - }, - "ethereumjs-util": { - "version": "7.1.5", - "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-7.1.5.tgz", - "integrity": "sha512-SDl5kKrQAudFBUe5OJM9Ac6WmMyYmXX/6sTmLZ3ffG2eY6ZIGBes3pEDxNN6V72WyOw4CPD5RomKdsa8DAAwLg==", - "dev": true, - "requires": { - "@types/bn.js": "^5.1.0", - "bn.js": "^5.1.2", - "create-hash": "^1.1.2", - "ethereum-cryptography": "^0.1.3", - "rlp": "^2.2.4" - } - }, - "web3-utils": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.7.4.tgz", - "integrity": "sha512-acBdm6Evd0TEZRnChM/MCvGsMwYKmSh7OaUfNf5OKG0CIeGWD/6gqLOWIwmwSnre/2WrA1nKGId5uW2e5EfluA==", - "dev": true, - "requires": { - "bn.js": "^5.2.1", - "ethereum-bloom-filters": "^1.0.6", - "ethereumjs-util": "^7.1.0", - "ethjs-unit": "0.1.6", - "number-to-bn": "1.7.0", - "randombytes": "^2.1.0", - "utf8": "3.0.0" - } - } + "bn.js": "^5.2.1", + "ethereum-bloom-filters": "^1.0.6", + "ethereumjs-util": "^7.1.0", + "ethjs-unit": "0.1.6", + "number-to-bn": "1.7.0", + "randombytes": "^2.1.0", + "utf8": "3.0.0" + }, + "engines": { + "node": ">=8.0.0" } }, - "web3-eth-accounts": { + "node_modules/web3-eth-accounts": { "version": "1.7.4", "resolved": "https://registry.npmjs.org/web3-eth-accounts/-/web3-eth-accounts-1.7.4.tgz", "integrity": "sha512-Y9vYLRKP7VU7Cgq6wG1jFaG2k3/eIuiTKAG8RAuQnb6Cd9k5BRqTm5uPIiSo0AP/u11jDomZ8j7+WEgkU9+Btw==", "dev": true, - "requires": { + "dependencies": { "@ethereumjs/common": "^2.5.0", "@ethereumjs/tx": "^3.3.2", "crypto-browserify": "3.12.0", @@ -43253,91 +22680,61 @@ "web3-core-method": "1.7.4", "web3-utils": "1.7.4" }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-eth-accounts/node_modules/eth-lib": { + "version": "0.2.8", + "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.2.8.tgz", + "integrity": "sha512-ArJ7x1WcWOlSpzdoTBX8vkwlkSQ85CjjifSZtV4co64vWxSV8geWfPI9x4SVYu3DSxnX4yWFVTtGL+j9DUFLNw==", + "dev": true, "dependencies": { - "eth-lib": { - "version": "0.2.8", - "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.2.8.tgz", - "integrity": "sha512-ArJ7x1WcWOlSpzdoTBX8vkwlkSQ85CjjifSZtV4co64vWxSV8geWfPI9x4SVYu3DSxnX4yWFVTtGL+j9DUFLNw==", - "dev": true, - "requires": { - "bn.js": "^4.11.6", - "elliptic": "^6.4.0", - "xhr-request-promise": "^0.1.2" - }, - "dependencies": { - "bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", - "dev": true - } - } - }, - "ethereum-cryptography": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz", - "integrity": "sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==", - "dev": true, - "requires": { - "@types/pbkdf2": "^3.0.0", - "@types/secp256k1": "^4.0.1", - "blakejs": "^1.1.0", - "browserify-aes": "^1.2.0", - "bs58check": "^2.1.2", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "hash.js": "^1.1.7", - "keccak": "^3.0.0", - "pbkdf2": "^3.0.17", - "randombytes": "^2.1.0", - "safe-buffer": "^5.1.2", - "scrypt-js": "^3.0.0", - "secp256k1": "^4.0.1", - "setimmediate": "^1.0.5" - } - }, - "ethereumjs-util": { - "version": "7.1.5", - "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-7.1.5.tgz", - "integrity": "sha512-SDl5kKrQAudFBUe5OJM9Ac6WmMyYmXX/6sTmLZ3ffG2eY6ZIGBes3pEDxNN6V72WyOw4CPD5RomKdsa8DAAwLg==", - "dev": true, - "requires": { - "@types/bn.js": "^5.1.0", - "bn.js": "^5.1.2", - "create-hash": "^1.1.2", - "ethereum-cryptography": "^0.1.3", - "rlp": "^2.2.4" - } - }, - "uuid": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", - "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==", - "dev": true - }, - "web3-utils": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.7.4.tgz", - "integrity": "sha512-acBdm6Evd0TEZRnChM/MCvGsMwYKmSh7OaUfNf5OKG0CIeGWD/6gqLOWIwmwSnre/2WrA1nKGId5uW2e5EfluA==", - "dev": true, - "requires": { - "bn.js": "^5.2.1", - "ethereum-bloom-filters": "^1.0.6", - "ethereumjs-util": "^7.1.0", - "ethjs-unit": "0.1.6", - "number-to-bn": "1.7.0", - "randombytes": "^2.1.0", - "utf8": "3.0.0" - } - } + "bn.js": "^4.11.6", + "elliptic": "^6.4.0", + "xhr-request-promise": "^0.1.2" + } + }, + "node_modules/web3-eth-accounts/node_modules/eth-lib/node_modules/bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", + "dev": true + }, + "node_modules/web3-eth-accounts/node_modules/uuid": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", + "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==", + "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", + "dev": true, + "bin": { + "uuid": "bin/uuid" + } + }, + "node_modules/web3-eth-accounts/node_modules/web3-utils": { + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.7.4.tgz", + "integrity": "sha512-acBdm6Evd0TEZRnChM/MCvGsMwYKmSh7OaUfNf5OKG0CIeGWD/6gqLOWIwmwSnre/2WrA1nKGId5uW2e5EfluA==", + "dev": true, + "dependencies": { + "bn.js": "^5.2.1", + "ethereum-bloom-filters": "^1.0.6", + "ethereumjs-util": "^7.1.0", + "ethjs-unit": "0.1.6", + "number-to-bn": "1.7.0", + "randombytes": "^2.1.0", + "utf8": "3.0.0" + }, + "engines": { + "node": ">=8.0.0" } }, - "web3-eth-contract": { + "node_modules/web3-eth-contract": { "version": "1.7.4", "resolved": "https://registry.npmjs.org/web3-eth-contract/-/web3-eth-contract-1.7.4.tgz", "integrity": "sha512-ZgSZMDVI1pE9uMQpK0T0HDT2oewHcfTCv0osEqf5qyn5KrcQDg1GT96/+S0dfqZ4HKj4lzS5O0rFyQiLPQ8LzQ==", "dev": true, - "requires": { + "dependencies": { "@types/bn.js": "^5.1.0", "web3-core": "1.7.4", "web3-core-helpers": "1.7.4", @@ -43347,66 +22744,34 @@ "web3-eth-abi": "1.7.4", "web3-utils": "1.7.4" }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-eth-contract/node_modules/web3-utils": { + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.7.4.tgz", + "integrity": "sha512-acBdm6Evd0TEZRnChM/MCvGsMwYKmSh7OaUfNf5OKG0CIeGWD/6gqLOWIwmwSnre/2WrA1nKGId5uW2e5EfluA==", + "dev": true, "dependencies": { - "ethereum-cryptography": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz", - "integrity": "sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==", - "dev": true, - "requires": { - "@types/pbkdf2": "^3.0.0", - "@types/secp256k1": "^4.0.1", - "blakejs": "^1.1.0", - "browserify-aes": "^1.2.0", - "bs58check": "^2.1.2", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "hash.js": "^1.1.7", - "keccak": "^3.0.0", - "pbkdf2": "^3.0.17", - "randombytes": "^2.1.0", - "safe-buffer": "^5.1.2", - "scrypt-js": "^3.0.0", - "secp256k1": "^4.0.1", - "setimmediate": "^1.0.5" - } - }, - "ethereumjs-util": { - "version": "7.1.5", - "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-7.1.5.tgz", - "integrity": "sha512-SDl5kKrQAudFBUe5OJM9Ac6WmMyYmXX/6sTmLZ3ffG2eY6ZIGBes3pEDxNN6V72WyOw4CPD5RomKdsa8DAAwLg==", - "dev": true, - "requires": { - "@types/bn.js": "^5.1.0", - "bn.js": "^5.1.2", - "create-hash": "^1.1.2", - "ethereum-cryptography": "^0.1.3", - "rlp": "^2.2.4" - } - }, - "web3-utils": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.7.4.tgz", - "integrity": "sha512-acBdm6Evd0TEZRnChM/MCvGsMwYKmSh7OaUfNf5OKG0CIeGWD/6gqLOWIwmwSnre/2WrA1nKGId5uW2e5EfluA==", - "dev": true, - "requires": { - "bn.js": "^5.2.1", - "ethereum-bloom-filters": "^1.0.6", - "ethereumjs-util": "^7.1.0", - "ethjs-unit": "0.1.6", - "number-to-bn": "1.7.0", - "randombytes": "^2.1.0", - "utf8": "3.0.0" - } - } + "bn.js": "^5.2.1", + "ethereum-bloom-filters": "^1.0.6", + "ethereumjs-util": "^7.1.0", + "ethjs-unit": "0.1.6", + "number-to-bn": "1.7.0", + "randombytes": "^2.1.0", + "utf8": "3.0.0" + }, + "engines": { + "node": ">=8.0.0" } }, - "web3-eth-ens": { + "node_modules/web3-eth-ens": { "version": "1.7.4", "resolved": "https://registry.npmjs.org/web3-eth-ens/-/web3-eth-ens-1.7.4.tgz", "integrity": "sha512-Gw5CVU1+bFXP5RVXTCqJOmHn71X2ghNk9VcEH+9PchLr0PrKbHTA3hySpsPco1WJAyK4t8SNQVlNr3+bJ6/WZA==", "dev": true, - "requires": { + "dependencies": { "content-hash": "^2.5.2", "eth-ens-namehash": "2.0.8", "web3-core": "1.7.4", @@ -43416,129 +22781,65 @@ "web3-eth-contract": "1.7.4", "web3-utils": "1.7.4" }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-eth-ens/node_modules/web3-utils": { + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.7.4.tgz", + "integrity": "sha512-acBdm6Evd0TEZRnChM/MCvGsMwYKmSh7OaUfNf5OKG0CIeGWD/6gqLOWIwmwSnre/2WrA1nKGId5uW2e5EfluA==", + "dev": true, "dependencies": { - "ethereum-cryptography": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz", - "integrity": "sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==", - "dev": true, - "requires": { - "@types/pbkdf2": "^3.0.0", - "@types/secp256k1": "^4.0.1", - "blakejs": "^1.1.0", - "browserify-aes": "^1.2.0", - "bs58check": "^2.1.2", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "hash.js": "^1.1.7", - "keccak": "^3.0.0", - "pbkdf2": "^3.0.17", - "randombytes": "^2.1.0", - "safe-buffer": "^5.1.2", - "scrypt-js": "^3.0.0", - "secp256k1": "^4.0.1", - "setimmediate": "^1.0.5" - } - }, - "ethereumjs-util": { - "version": "7.1.5", - "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-7.1.5.tgz", - "integrity": "sha512-SDl5kKrQAudFBUe5OJM9Ac6WmMyYmXX/6sTmLZ3ffG2eY6ZIGBes3pEDxNN6V72WyOw4CPD5RomKdsa8DAAwLg==", - "dev": true, - "requires": { - "@types/bn.js": "^5.1.0", - "bn.js": "^5.1.2", - "create-hash": "^1.1.2", - "ethereum-cryptography": "^0.1.3", - "rlp": "^2.2.4" - } - }, - "web3-utils": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.7.4.tgz", - "integrity": "sha512-acBdm6Evd0TEZRnChM/MCvGsMwYKmSh7OaUfNf5OKG0CIeGWD/6gqLOWIwmwSnre/2WrA1nKGId5uW2e5EfluA==", - "dev": true, - "requires": { - "bn.js": "^5.2.1", - "ethereum-bloom-filters": "^1.0.6", - "ethereumjs-util": "^7.1.0", - "ethjs-unit": "0.1.6", - "number-to-bn": "1.7.0", - "randombytes": "^2.1.0", - "utf8": "3.0.0" - } - } + "bn.js": "^5.2.1", + "ethereum-bloom-filters": "^1.0.6", + "ethereumjs-util": "^7.1.0", + "ethjs-unit": "0.1.6", + "number-to-bn": "1.7.0", + "randombytes": "^2.1.0", + "utf8": "3.0.0" + }, + "engines": { + "node": ">=8.0.0" } }, - "web3-eth-iban": { + "node_modules/web3-eth-iban": { "version": "1.7.4", "resolved": "https://registry.npmjs.org/web3-eth-iban/-/web3-eth-iban-1.7.4.tgz", "integrity": "sha512-XyrsgWlZQMv5gRcjXMsNvAoCRvV5wN7YCfFV5+tHUCqN8g9T/o4XUS20vDWD0k4HNiAcWGFqT1nrls02MGZ08w==", "dev": true, - "requires": { + "dependencies": { "bn.js": "^5.2.1", "web3-utils": "1.7.4" }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-eth-iban/node_modules/web3-utils": { + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.7.4.tgz", + "integrity": "sha512-acBdm6Evd0TEZRnChM/MCvGsMwYKmSh7OaUfNf5OKG0CIeGWD/6gqLOWIwmwSnre/2WrA1nKGId5uW2e5EfluA==", + "dev": true, "dependencies": { - "ethereum-cryptography": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz", - "integrity": "sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==", - "dev": true, - "requires": { - "@types/pbkdf2": "^3.0.0", - "@types/secp256k1": "^4.0.1", - "blakejs": "^1.1.0", - "browserify-aes": "^1.2.0", - "bs58check": "^2.1.2", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "hash.js": "^1.1.7", - "keccak": "^3.0.0", - "pbkdf2": "^3.0.17", - "randombytes": "^2.1.0", - "safe-buffer": "^5.1.2", - "scrypt-js": "^3.0.0", - "secp256k1": "^4.0.1", - "setimmediate": "^1.0.5" - } - }, - "ethereumjs-util": { - "version": "7.1.5", - "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-7.1.5.tgz", - "integrity": "sha512-SDl5kKrQAudFBUe5OJM9Ac6WmMyYmXX/6sTmLZ3ffG2eY6ZIGBes3pEDxNN6V72WyOw4CPD5RomKdsa8DAAwLg==", - "dev": true, - "requires": { - "@types/bn.js": "^5.1.0", - "bn.js": "^5.1.2", - "create-hash": "^1.1.2", - "ethereum-cryptography": "^0.1.3", - "rlp": "^2.2.4" - } - }, - "web3-utils": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.7.4.tgz", - "integrity": "sha512-acBdm6Evd0TEZRnChM/MCvGsMwYKmSh7OaUfNf5OKG0CIeGWD/6gqLOWIwmwSnre/2WrA1nKGId5uW2e5EfluA==", - "dev": true, - "requires": { - "bn.js": "^5.2.1", - "ethereum-bloom-filters": "^1.0.6", - "ethereumjs-util": "^7.1.0", - "ethjs-unit": "0.1.6", - "number-to-bn": "1.7.0", - "randombytes": "^2.1.0", - "utf8": "3.0.0" - } - } + "bn.js": "^5.2.1", + "ethereum-bloom-filters": "^1.0.6", + "ethereumjs-util": "^7.1.0", + "ethjs-unit": "0.1.6", + "number-to-bn": "1.7.0", + "randombytes": "^2.1.0", + "utf8": "3.0.0" + }, + "engines": { + "node": ">=8.0.0" } }, - "web3-eth-personal": { + "node_modules/web3-eth-personal": { "version": "1.7.4", "resolved": "https://registry.npmjs.org/web3-eth-personal/-/web3-eth-personal-1.7.4.tgz", "integrity": "sha512-O10C1Hln5wvLQsDhlhmV58RhXo+GPZ5+W76frSsyIrkJWLtYQTCr5WxHtRC9sMD1idXLqODKKgI2DL+7xeZ0/g==", "dev": true, - "requires": { + "dependencies": { "@types/node": "^12.12.6", "web3-core": "1.7.4", "web3-core-helpers": "1.7.4", @@ -43546,228 +22847,203 @@ "web3-net": "1.7.4", "web3-utils": "1.7.4" }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-eth-personal/node_modules/web3-utils": { + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.7.4.tgz", + "integrity": "sha512-acBdm6Evd0TEZRnChM/MCvGsMwYKmSh7OaUfNf5OKG0CIeGWD/6gqLOWIwmwSnre/2WrA1nKGId5uW2e5EfluA==", + "dev": true, "dependencies": { - "ethereum-cryptography": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz", - "integrity": "sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==", - "dev": true, - "requires": { - "@types/pbkdf2": "^3.0.0", - "@types/secp256k1": "^4.0.1", - "blakejs": "^1.1.0", - "browserify-aes": "^1.2.0", - "bs58check": "^2.1.2", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "hash.js": "^1.1.7", - "keccak": "^3.0.0", - "pbkdf2": "^3.0.17", - "randombytes": "^2.1.0", - "safe-buffer": "^5.1.2", - "scrypt-js": "^3.0.0", - "secp256k1": "^4.0.1", - "setimmediate": "^1.0.5" - } - }, - "ethereumjs-util": { - "version": "7.1.5", - "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-7.1.5.tgz", - "integrity": "sha512-SDl5kKrQAudFBUe5OJM9Ac6WmMyYmXX/6sTmLZ3ffG2eY6ZIGBes3pEDxNN6V72WyOw4CPD5RomKdsa8DAAwLg==", - "dev": true, - "requires": { - "@types/bn.js": "^5.1.0", - "bn.js": "^5.1.2", - "create-hash": "^1.1.2", - "ethereum-cryptography": "^0.1.3", - "rlp": "^2.2.4" - } - }, - "web3-utils": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.7.4.tgz", - "integrity": "sha512-acBdm6Evd0TEZRnChM/MCvGsMwYKmSh7OaUfNf5OKG0CIeGWD/6gqLOWIwmwSnre/2WrA1nKGId5uW2e5EfluA==", - "dev": true, - "requires": { - "bn.js": "^5.2.1", - "ethereum-bloom-filters": "^1.0.6", - "ethereumjs-util": "^7.1.0", - "ethjs-unit": "0.1.6", - "number-to-bn": "1.7.0", - "randombytes": "^2.1.0", - "utf8": "3.0.0" - } - } + "bn.js": "^5.2.1", + "ethereum-bloom-filters": "^1.0.6", + "ethereumjs-util": "^7.1.0", + "ethjs-unit": "0.1.6", + "number-to-bn": "1.7.0", + "randombytes": "^2.1.0", + "utf8": "3.0.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-eth/node_modules/web3-utils": { + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.7.4.tgz", + "integrity": "sha512-acBdm6Evd0TEZRnChM/MCvGsMwYKmSh7OaUfNf5OKG0CIeGWD/6gqLOWIwmwSnre/2WrA1nKGId5uW2e5EfluA==", + "dev": true, + "dependencies": { + "bn.js": "^5.2.1", + "ethereum-bloom-filters": "^1.0.6", + "ethereumjs-util": "^7.1.0", + "ethjs-unit": "0.1.6", + "number-to-bn": "1.7.0", + "randombytes": "^2.1.0", + "utf8": "3.0.0" + }, + "engines": { + "node": ">=8.0.0" } }, - "web3-net": { + "node_modules/web3-net": { "version": "1.7.4", "resolved": "https://registry.npmjs.org/web3-net/-/web3-net-1.7.4.tgz", "integrity": "sha512-d2Gj+DIARHvwIdmxFQ4PwAAXZVxYCR2lET0cxz4KXbE5Og3DNjJi+MoPkX+WqoUXqimu/EOd4Cd+7gefqVAFDg==", "dev": true, - "requires": { + "dependencies": { "web3-core": "1.7.4", "web3-core-method": "1.7.4", "web3-utils": "1.7.4" }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-net/node_modules/web3-utils": { + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.7.4.tgz", + "integrity": "sha512-acBdm6Evd0TEZRnChM/MCvGsMwYKmSh7OaUfNf5OKG0CIeGWD/6gqLOWIwmwSnre/2WrA1nKGId5uW2e5EfluA==", + "dev": true, "dependencies": { - "ethereum-cryptography": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz", - "integrity": "sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==", - "dev": true, - "requires": { - "@types/pbkdf2": "^3.0.0", - "@types/secp256k1": "^4.0.1", - "blakejs": "^1.1.0", - "browserify-aes": "^1.2.0", - "bs58check": "^2.1.2", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "hash.js": "^1.1.7", - "keccak": "^3.0.0", - "pbkdf2": "^3.0.17", - "randombytes": "^2.1.0", - "safe-buffer": "^5.1.2", - "scrypt-js": "^3.0.0", - "secp256k1": "^4.0.1", - "setimmediate": "^1.0.5" - } - }, - "ethereumjs-util": { - "version": "7.1.5", - "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-7.1.5.tgz", - "integrity": "sha512-SDl5kKrQAudFBUe5OJM9Ac6WmMyYmXX/6sTmLZ3ffG2eY6ZIGBes3pEDxNN6V72WyOw4CPD5RomKdsa8DAAwLg==", - "dev": true, - "requires": { - "@types/bn.js": "^5.1.0", - "bn.js": "^5.1.2", - "create-hash": "^1.1.2", - "ethereum-cryptography": "^0.1.3", - "rlp": "^2.2.4" - } - }, - "web3-utils": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.7.4.tgz", - "integrity": "sha512-acBdm6Evd0TEZRnChM/MCvGsMwYKmSh7OaUfNf5OKG0CIeGWD/6gqLOWIwmwSnre/2WrA1nKGId5uW2e5EfluA==", - "dev": true, - "requires": { - "bn.js": "^5.2.1", - "ethereum-bloom-filters": "^1.0.6", - "ethereumjs-util": "^7.1.0", - "ethjs-unit": "0.1.6", - "number-to-bn": "1.7.0", - "randombytes": "^2.1.0", - "utf8": "3.0.0" - } - } + "bn.js": "^5.2.1", + "ethereum-bloom-filters": "^1.0.6", + "ethereumjs-util": "^7.1.0", + "ethjs-unit": "0.1.6", + "number-to-bn": "1.7.0", + "randombytes": "^2.1.0", + "utf8": "3.0.0" + }, + "engines": { + "node": ">=8.0.0" } }, - "web3-providers-http": { + "node_modules/web3-providers-http": { "version": "1.7.4", "resolved": "https://registry.npmjs.org/web3-providers-http/-/web3-providers-http-1.7.4.tgz", "integrity": "sha512-AU+/S+49rcogUER99TlhW+UBMk0N2DxvN54CJ2pK7alc2TQ7+cprNPLHJu4KREe8ndV0fT6JtWUfOMyTvl+FRA==", "dev": true, - "requires": { + "dependencies": { "web3-core-helpers": "1.7.4", "xhr2-cookies": "1.1.0" + }, + "engines": { + "node": ">=8.0.0" } }, - "web3-providers-ipc": { + "node_modules/web3-providers-ipc": { "version": "1.7.4", "resolved": "https://registry.npmjs.org/web3-providers-ipc/-/web3-providers-ipc-1.7.4.tgz", "integrity": "sha512-jhArOZ235dZy8fS8090t60nTxbd1ap92ibQw5xIrAQ9m7LcZKNfmLAQUVsD+3dTFvadRMi6z1vCO7zRi84gWHw==", "dev": true, - "requires": { + "dependencies": { "oboe": "2.1.5", "web3-core-helpers": "1.7.4" + }, + "engines": { + "node": ">=8.0.0" } }, - "web3-providers-ws": { + "node_modules/web3-providers-ws": { "version": "1.7.4", "resolved": "https://registry.npmjs.org/web3-providers-ws/-/web3-providers-ws-1.7.4.tgz", "integrity": "sha512-g72X77nrcHMFU8hRzQJzfgi/072n8dHwRCoTw+WQrGp+XCQ71fsk2qIu3Tp+nlp5BPn8bRudQbPblVm2uT4myQ==", "dev": true, - "requires": { + "dependencies": { "eventemitter3": "4.0.4", "web3-core-helpers": "1.7.4", "websocket": "^1.0.32" + }, + "engines": { + "node": ">=8.0.0" } }, - "web3-shh": { + "node_modules/web3-shh": { "version": "1.7.4", "resolved": "https://registry.npmjs.org/web3-shh/-/web3-shh-1.7.4.tgz", "integrity": "sha512-mlSZxSYcMkuMCxqhTYnZkUdahZ11h+bBv/8TlkXp/IHpEe4/Gg+KAbmfudakq3EzG/04z70XQmPgWcUPrsEJ+A==", "dev": true, - "requires": { + "hasInstallScript": true, + "dependencies": { "web3-core": "1.7.4", "web3-core-method": "1.7.4", "web3-core-subscriptions": "1.7.4", "web3-net": "1.7.4" + }, + "engines": { + "node": ">=8.0.0" } }, - "web3-utils": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.10.0.tgz", - "integrity": "sha512-kSaCM0uMcZTNUSmn5vMEhlo02RObGNRRCkdX0V9UTAU0+lrvn0HSaudyCo6CQzuXUsnuY2ERJGCGPfeWmv19Rg==", - "requires": { + "node_modules/web3-utils": { + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.10.4.tgz", + "integrity": "sha512-tsu8FiKJLk2PzhDl9fXbGUWTkkVXYhtTA+SmEFkKft+9BgwLxfCRpU96sWv7ICC8zixBNd3JURVoiR3dUXgP8A==", + "dependencies": { + "@ethereumjs/util": "^8.1.0", "bn.js": "^5.2.1", "ethereum-bloom-filters": "^1.0.6", - "ethereumjs-util": "^7.1.0", + "ethereum-cryptography": "^2.1.2", "ethjs-unit": "0.1.6", "number-to-bn": "1.7.0", "randombytes": "^2.1.0", "utf8": "3.0.0" }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-utils/node_modules/@noble/hashes": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.3.3.tgz", + "integrity": "sha512-V7/fPHgl+jsVPXqqeOzT8egNj2iBIVt+ECeMMG8TdcnTikP3oaBtUVqpT/gYCR68aEBJSF+XbYUxStjbFMqIIA==", + "engines": { + "node": ">= 16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/web3-utils/node_modules/ethereum-cryptography": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-2.1.3.tgz", + "integrity": "sha512-BlwbIL7/P45W8FGW2r7LGuvoEZ+7PWsniMvQ4p5s2xCyw9tmaDlpfsN9HjAucbF+t/qpVHwZUisgfK24TCW8aA==", "dependencies": { - "ethereum-cryptography": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz", - "integrity": "sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==", - "requires": { - "@types/pbkdf2": "^3.0.0", - "@types/secp256k1": "^4.0.1", - "blakejs": "^1.1.0", - "browserify-aes": "^1.2.0", - "bs58check": "^2.1.2", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "hash.js": "^1.1.7", - "keccak": "^3.0.0", - "pbkdf2": "^3.0.17", - "randombytes": "^2.1.0", - "safe-buffer": "^5.1.2", - "scrypt-js": "^3.0.0", - "secp256k1": "^4.0.1", - "setimmediate": "^1.0.5" - } - }, - "ethereumjs-util": { - "version": "7.1.5", - "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-7.1.5.tgz", - "integrity": "sha512-SDl5kKrQAudFBUe5OJM9Ac6WmMyYmXX/6sTmLZ3ffG2eY6ZIGBes3pEDxNN6V72WyOw4CPD5RomKdsa8DAAwLg==", - "requires": { - "@types/bn.js": "^5.1.0", - "bn.js": "^5.1.2", - "create-hash": "^1.1.2", - "ethereum-cryptography": "^0.1.3", - "rlp": "^2.2.4" - } - } + "@noble/curves": "1.3.0", + "@noble/hashes": "1.3.3", + "@scure/bip32": "1.3.3", + "@scure/bip39": "1.2.2" + } + }, + "node_modules/web3/node_modules/web3-utils": { + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.7.4.tgz", + "integrity": "sha512-acBdm6Evd0TEZRnChM/MCvGsMwYKmSh7OaUfNf5OKG0CIeGWD/6gqLOWIwmwSnre/2WrA1nKGId5uW2e5EfluA==", + "dev": true, + "dependencies": { + "bn.js": "^5.2.1", + "ethereum-bloom-filters": "^1.0.6", + "ethereumjs-util": "^7.1.0", + "ethjs-unit": "0.1.6", + "number-to-bn": "1.7.0", + "randombytes": "^2.1.0", + "utf8": "3.0.0" + }, + "engines": { + "node": ">=8.0.0" } }, - "webidl-conversions": { + "node_modules/webidl-conversions": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" }, - "websocket": { + "node_modules/websocket": { "version": "1.0.34", "resolved": "https://registry.npmjs.org/websocket/-/websocket-1.0.34.tgz", "integrity": "sha512-PRDso2sGwF6kM75QykIesBijKSVceR6jL2G8NGYyq2XrItNC2P5/qL5XeR056GhA+Ly7JMFvJb9I312mJfmqnQ==", "dev": true, - "requires": { + "dependencies": { "bufferutil": "^4.0.1", "debug": "^2.2.0", "es5-ext": "^0.10.50", @@ -43775,167 +23051,196 @@ "utf-8-validate": "^5.0.2", "yaeti": "^0.0.6" }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/websocket/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true - } + "ms": "2.0.0" } }, - "whatwg-url": { + "node_modules/websocket/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true + }, + "node_modules/whatwg-url": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", - "requires": { + "dependencies": { "tr46": "~0.0.3", "webidl-conversions": "^3.0.0" } }, - "which": { + "node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", "dev": true, - "requires": { + "dependencies": { "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" } }, - "which-boxed-primitive": { + "node_modules/which-boxed-primitive": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", "dev": true, - "requires": { + "dependencies": { "is-bigint": "^1.0.1", "is-boolean-object": "^1.1.0", "is-number-object": "^1.0.4", "is-string": "^1.0.5", "is-symbol": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "which-module": { + "node_modules/which-module": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/which-module/-/which-module-1.0.0.tgz", "integrity": "sha512-F6+WgncZi/mJDrammbTuHe1q0R5hOXv/mBaiNA2TCNT/LTHusX0V+CJnj9XT8ki5ln2UZyyddDgHfCzyrOH7MQ==", "dev": true }, - "which-typed-array": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.11.tgz", - "integrity": "sha512-qe9UWWpkeG5yzZ0tNYxDmd7vo58HDBc39mZ0xWWpolAGADdFOzkfamWLDxkOWcvHQKVmdTyQdLD4NOfjLWTKew==", + "node_modules/which-typed-array": { + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.15.tgz", + "integrity": "sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA==", "dev": true, - "requires": { - "available-typed-arrays": "^1.0.5", - "call-bind": "^1.0.2", + "dependencies": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.7", "for-each": "^0.3.3", "gopd": "^1.0.1", - "has-tostringtag": "^1.0.0" + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "wide-align": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", - "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", + "node_modules/widest-line": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-3.1.0.tgz", + "integrity": "sha512-NsmoXalsWVDMGupxZ5R08ka9flZjjiLvHVAWYOKtiKM8ujtZWr9cRffak+uSE48+Ob8ObalXpwyeUiyDD6QFgg==", "dev": true, - "requires": { - "string-width": "^1.0.2 || 2" + "dependencies": { + "string-width": "^4.0.0" + }, + "engines": { + "node": ">=8" } }, - "window-size": { + "node_modules/window-size": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.2.0.tgz", "integrity": "sha512-UD7d8HFA2+PZsbKyaOCEy8gMh1oDtHgJh1LfgjQ4zVXmYjAT/kvz3PueITKuqDiIXQe7yzpPnxX3lNc+AhQMyw==", - "dev": true + "dev": true, + "bin": { + "window-size": "cli.js" + }, + "engines": { + "node": ">= 0.10.0" + } }, - "word-wrap": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.4.tgz", - "integrity": "sha512-2V81OA4ugVo5pRo46hAoD2ivUJx8jXmWXfUkY4KFNw0hEptvN0QfH3K4nHiwzGeKl5rFKedV48QVoqYavy4YpA==", - "dev": true + "node_modules/word-wrap": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } }, - "wordwrap": { + "node_modules/wordwrap": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", "integrity": "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==", "dev": true }, - "workerpool": { + "node_modules/workerpool": { "version": "6.2.1", "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.2.1.tgz", "integrity": "sha512-ILEIE97kDZvF9Wb9f6h5aXK4swSlKGUcOEGiIYb2OOu/IrDU9iwj0fD//SsA6E5ibwJxpEvhullJY4Sl4GcpAw==", "dev": true }, - "wrap-ansi": { + "node_modules/wrap-ansi": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", "dev": true, - "requires": { + "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", "strip-ansi": "^6.0.0" }, - "dependencies": { - "is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true - }, - "string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - } - } + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, - "wrappy": { + "node_modules/wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", "dev": true }, - "ws": { + "node_modules/ws": { "version": "7.4.6", "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.6.tgz", "integrity": "sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A==", - "requires": {} + "engines": { + "node": ">=8.3.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } }, - "xhr": { + "node_modules/xhr": { "version": "2.6.0", "resolved": "https://registry.npmjs.org/xhr/-/xhr-2.6.0.tgz", "integrity": "sha512-/eCGLb5rxjx5e3mF1A7s+pLlR6CGyqWN91fv1JgER5mVWg1MZmlhBvy9kjcsOdRk8RrIujotWyJamfyrp+WIcA==", "dev": true, - "requires": { + "dependencies": { "global": "~4.4.0", "is-function": "^1.0.1", "parse-headers": "^2.0.0", "xtend": "^4.0.0" } }, - "xhr-request": { + "node_modules/xhr-request": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/xhr-request/-/xhr-request-1.1.0.tgz", "integrity": "sha512-Y7qzEaR3FDtL3fP30k9wO/e+FBnBByZeybKOhASsGP30NIkRAAkKD/sCnLvgEfAIEC1rcmK7YG8f4oEnIrrWzA==", "dev": true, - "requires": { + "dependencies": { "buffer-to-arraybuffer": "^0.0.5", "object-assign": "^4.1.1", "query-string": "^5.0.1", @@ -43945,66 +23250,80 @@ "xhr": "^2.0.4" } }, - "xhr-request-promise": { + "node_modules/xhr-request-promise": { "version": "0.1.3", "resolved": "https://registry.npmjs.org/xhr-request-promise/-/xhr-request-promise-0.1.3.tgz", "integrity": "sha512-YUBytBsuwgitWtdRzXDDkWAXzhdGB8bYm0sSzMPZT7Z2MBjMSTHFsyCT1yCRATY+XC69DUrQraRAEgcoCRaIPg==", "dev": true, - "requires": { + "dependencies": { "xhr-request": "^1.1.0" } }, - "xhr2-cookies": { + "node_modules/xhr2-cookies": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/xhr2-cookies/-/xhr2-cookies-1.1.0.tgz", "integrity": "sha512-hjXUA6q+jl/bd8ADHcVfFsSPIf+tyLIjuO9TwJC9WI6JP2zKcS7C+p56I9kCLLsaCiNT035iYvEUUzdEFj/8+g==", "dev": true, - "requires": { + "dependencies": { "cookiejar": "^2.1.1" } }, - "xmlhttprequest": { + "node_modules/xmlhttprequest": { "version": "1.8.0", "resolved": "https://registry.npmjs.org/xmlhttprequest/-/xmlhttprequest-1.8.0.tgz", "integrity": "sha512-58Im/U0mlVBLM38NdZjHyhuMtCqa61469k2YP/AaPbvCoV9aQGUpbJBj1QRm2ytRiVQBD/fsw7L2bJGDVQswBA==", - "dev": true + "dev": true, + "engines": { + "node": ">=0.4.0" + } }, - "xtend": { + "node_modules/xtend": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", - "dev": true + "dev": true, + "engines": { + "node": ">=0.4" + } }, - "y18n": { + "node_modules/y18n": { "version": "5.0.8", "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", - "dev": true + "dev": true, + "engines": { + "node": ">=10" + } }, - "yaeti": { + "node_modules/yaeti": { "version": "0.0.6", "resolved": "https://registry.npmjs.org/yaeti/-/yaeti-0.0.6.tgz", "integrity": "sha512-MvQa//+KcZCUkBTIC9blM+CU9J2GzuTytsOUwf2lidtvkx/6gnEp1QvJv34t9vdjhFmha/mUiNDbN0D0mJWdug==", - "dev": true + "dev": true, + "engines": { + "node": ">=0.10.32" + } }, - "yallist": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", - "dev": true + "node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" }, - "yaml": { + "node_modules/yaml": { "version": "1.10.2", "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", - "dev": true + "dev": true, + "engines": { + "node": ">= 6" + } }, - "yargs": { + "node_modules/yargs": { "version": "16.2.0", "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", "dev": true, - "requires": { + "dependencies": { "cliui": "^7.0.2", "escalade": "^3.1.1", "get-caller-file": "^2.0.5", @@ -44013,55 +23332,54 @@ "y18n": "^5.0.5", "yargs-parser": "^20.2.2" }, - "dependencies": { - "is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true - }, - "string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - } - } + "engines": { + "node": ">=10" } }, - "yargs-parser": { + "node_modules/yargs-parser": { "version": "20.2.4", "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz", "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==", - "dev": true + "dev": true, + "engines": { + "node": ">=10" + } }, - "yargs-unparser": { + "node_modules/yargs-unparser": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz", "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==", "dev": true, - "requires": { + "dependencies": { "camelcase": "^6.0.0", "decamelize": "^4.0.0", "flat": "^5.0.2", "is-plain-obj": "^2.1.0" + }, + "engines": { + "node": ">=10" } }, - "yn": { + "node_modules/yn": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", - "dev": true + "dev": true, + "engines": { + "node": ">=6" + } }, - "yocto-queue": { + "node_modules/yocto-queue": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", - "dev": true + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } } } } diff --git a/package.json b/package.json index 820a38ee..a4560476 100644 --- a/package.json +++ b/package.json @@ -1,37 +1,25 @@ { - "name": "lido-l2", - "version": "1.0.0", + "name": "lido-l2-optimism", + "version": "2.0.0", "description": "", "main": "index.js", "scripts": { "compile": "hardhat compile", "compile:force": "hardhat compile --force", "coverage": "hardhat coverage --testfiles './test/**/*.unit.test.ts'", - "test:e2e": "hardhat test ./test/**/*.e2e.test.ts", - "test:unit": "hardhat test ./test/**/*.unit.test.ts", - "test:integration": "hardhat test ./test/**/*.integration.test.ts", "fork:eth:mainnet": "hardhat node:fork eth_mainnet 8545", "fork:eth:sepolia": "hardhat node:fork eth_sepolia 8545", - "fork:arb:sepolia": "hardhat node:fork arb_sepolia 8546", - "fork:arb:mainnet": "hardhat node:fork arb_mainnet 8546", "fork:opt:sepolia": "hardhat node:fork opt_sepolia 9545", "fork:opt:mainnet": "hardhat node:fork opt_mainnet 9545", - "arbitrum:deploy": "ts-node --files ./scripts/arbitrum/deploy-gateway.ts", - "arbitrum:finalize-message": "ts-node --files ./scripts/arbitrum/finalize-message.ts", - "arbitrum:test:e2e": "hardhat test ./test/arbitrum/*.e2e.test.ts", - "arbitrum:test:unit": "hardhat test ./test/arbitrum/*.unit.test.ts", - "arbitrum:test:integration": "hardhat test ./test/arbitrum/*.integration.test.ts", - "arbitrum:test:acceptance": "hardhat test ./test/arbitrum/*.acceptance.test.ts", - "arbitrum:test:executor": "hardhat test ./test/bridge-executor/arbitrum.integration.test.ts", - "arbitrum:test:launch": "REVERT=false hardhat test ./test/arbitrum/{_launch.test.ts,bridging.integration.test.ts}", - "optimism:deploy": "ts-node --files ./scripts/optimism/deploy-bridge.ts", - "optimism:finalize-message": "ts-node --files ./scripts/optimism/finalize-message.ts", - "optimism:test:e2e": "hardhat test ./test/optimism/*.e2e.test.ts", - "optimism:test:unit": "hardhat test ./test/optimism/*.unit.test.ts", - "optimism:test:integration": "hardhat test ./test/optimism/*.integration.test.ts", - "optimism:test:acceptance": "hardhat test ./test/optimism/*.acceptance.test.ts", - "optimism:test:executor": "hardhat test ./test/bridge-executor/optimism.integration.test.ts", - "optimism:test:launch": "REVERT=false hardhat test ./test/optimism/{_launch.test.ts,bridging.integration.test.ts}" + "deploy": "ts-node --files ./scripts/optimism/deploy-scratch.ts", + "upgrade": "ts-node --files ./scripts/optimism/upgrade.ts", + "finalize-message": "ts-node --files ./scripts/optimism/finalize-message.ts", + "test:e2e": "hardhat test ./test/optimism/*.e2e.test.ts", + "test:unit": "hardhat test ./test/optimism/*.unit.test.ts", + "test:integration": "hardhat test ./test/optimism/*.integration.test.ts", + "test:acceptance": "hardhat test ./test/optimism/*.acceptance.test.ts", + "test:executor": "hardhat test ./test/bridge-executor/optimism.integration.test.ts", + "test:launch": "REVERT=false hardhat test ./test/optimism/{_launch.test.ts,bridging.integration.test.ts}" }, "keywords": [], "author": "", @@ -57,6 +45,7 @@ "eslint-plugin-prettier": "^3.4.1", "eslint-plugin-promise": "^5.2.0", "ethereum-waffle": "^3.4.4", + "ethereumjs-util": "^7.0.8", "ethers": "^5.6.2", "hardhat": "^2.12.2", "hardhat-gas-reporter": "^1.0.8", @@ -69,8 +58,7 @@ "typescript": "^4.6.3" }, "dependencies": { - "@arbitrum/sdk": "3.1.6", - "@eth-optimism/sdk": "3.2.0", + "@eth-optimism/sdk": "3.2.3", "@ethersproject/providers": "^5.6.8", "@lidofinance/evm-script-decoder": "^0.2.2", "@openzeppelin/contracts": "4.6.0", diff --git a/scripts/arbitrum/deploy-gateway-routers.ts b/scripts/arbitrum/deploy-gateway-routers.ts deleted file mode 100644 index ef48beea..00000000 --- a/scripts/arbitrum/deploy-gateway-routers.ts +++ /dev/null @@ -1,28 +0,0 @@ -import arbitrum from "../../utils/arbitrum"; -import env from "../../utils/env"; -import network from "../../utils/network"; -import prompt from "../../utils/prompt"; - -async function main() { - const networkName = env.network(); - - const [ethDeployer, arbDeployer] = network - .multichain(["eth", "arb"], networkName) - .getSigners(env.privateKey(), { forking: env.forking() }); - - const [l1DeployScript, l2DeployScript] = await arbitrum - .deployment(networkName, { logger: console }) - .gatewayRouterDeployScript(ethDeployer, arbDeployer); - - l1DeployScript.print(); - l2DeployScript.print(); - await prompt.proceed(); - - await l1DeployScript.run(); - await l2DeployScript.run(); -} - -main().catch((error) => { - console.error(error); - process.exitCode = 1; -}); diff --git a/scripts/arbitrum/deploy-gateway.ts b/scripts/arbitrum/deploy-gateway.ts deleted file mode 100644 index cebe3dbd..00000000 --- a/scripts/arbitrum/deploy-gateway.ts +++ /dev/null @@ -1,77 +0,0 @@ -import env from "../../utils/env"; -import prompt from "../../utils/prompt"; -import network from "../../utils/network"; -import arbitrum from "../../utils/arbitrum"; -import deployment from "../../utils/deployment"; -import { BridgingManagement } from "../../utils/bridging-management"; - -async function main() { - const networkName = env.network(); - const [ethDeployer] = network - .multichain(["eth", "arb"], networkName) - .getSigners(env.privateKey(), { forking: env.forking() }); - - const [, arbDeployer] = network - .multichain(["eth", "arb"], networkName) - .getSigners(env.string("ARB_DEPLOYER_PRIVATE_KEY"), { - forking: env.forking(), - }); - - const deploymentConfig = deployment.loadMultiChainDeploymentConfig(); - - const [l1DeployScript, l2DeployScript] = await arbitrum - .deployment(networkName, { logger: console }) - .erc20TokenGatewayDeployScript( - deploymentConfig.token, - { - deployer: ethDeployer, - admins: { - proxy: deploymentConfig.l1.proxyAdmin, - bridge: ethDeployer.address, - }, - }, - { - deployer: arbDeployer, - admins: { - proxy: deploymentConfig.l2.proxyAdmin, - bridge: arbDeployer.address, - }, - } - ); - - await deployment.printMultiChainDeploymentConfig( - "Deploy Arbitrum Gateway", - ethDeployer, - arbDeployer, - deploymentConfig, - l1DeployScript, - l2DeployScript - ); - - await prompt.proceed(); - - await l1DeployScript.run(); - await l2DeployScript.run(); - - const l1ERC20TokenGatewayProxyDeployStepIndex = 1; - const l1BridgingManagement = new BridgingManagement( - l1DeployScript.getContractAddress(l1ERC20TokenGatewayProxyDeployStepIndex), - ethDeployer, - { logger: console } - ); - - const l2ERC20TokenGatewayProxyDeployStepIndex = 3; - const l2BridgingManagement = new BridgingManagement( - l2DeployScript.getContractAddress(l2ERC20TokenGatewayProxyDeployStepIndex), - arbDeployer, - { logger: console } - ); - - await l1BridgingManagement.setup(deploymentConfig.l1); - await l2BridgingManagement.setup(deploymentConfig.l2); -} - -main().catch((error) => { - console.error(error); - process.exitCode = 1; -}); diff --git a/scripts/arbitrum/finalize-message.ts b/scripts/arbitrum/finalize-message.ts deleted file mode 100644 index 5eb83975..00000000 --- a/scripts/arbitrum/finalize-message.ts +++ /dev/null @@ -1,66 +0,0 @@ -import { L2ToL1MessageStatus, L2TransactionReceipt } from "@arbitrum/sdk"; -import env from "../../utils/env"; -import network from "../../utils/network"; - -async function main() { - const networkName = env.network(); - const ethArbNetwork = network.multichain(["eth", "arb"], networkName); - - const [ethProvider, arbProvider] = ethArbNetwork.getProviders({ - forking: false, - }); - const [ethSigner] = ethArbNetwork.getSigners(env.privateKey(), { - forking: false, - }); - - const l2TxHash = env.string("TX_HASH"); - - console.log("Tx hash:", l2TxHash); - - const receipt = await arbProvider.getTransactionReceipt(l2TxHash); - - if (!receipt) { - throw new Error( - `Receipt for tx ${l2TxHash} not found on "${networkName}" network` - ); - } - console.log(`Receipt for tx found!`); - - const l2Receipt = new L2TransactionReceipt(receipt); - - const messages = await l2Receipt.getL2ToL1Messages(ethSigner, arbProvider); - - const l2ToL1Msg = messages[0]; - - const status = await l2ToL1Msg.status(arbProvider); - if (status === L2ToL1MessageStatus.EXECUTED) { - console.log(`Message already executed! Nothing else to do here`); - return; - } - - const timeToWaitMs = 1000 * 60; - const [estimatedConfirmationBlock, currentBlock] = await Promise.all([ - l2ToL1Msg.getFirstExecutableBlock(arbProvider), - ethProvider.getBlockNumber(), - ]); - - if (estimatedConfirmationBlock) { - console.log( - `Estimated block number tx will be confirmed: ${estimatedConfirmationBlock.toString()}` - ); - console.log(`Current block number is ${currentBlock}`); - } - console.log("Waiting for the outbox entry to be created..."); - - await l2ToL1Msg.waitUntilReadyToExecute(arbProvider, timeToWaitMs); - console.log("Outbox entry exists! Trying to execute now"); - - const res = await l2ToL1Msg.execute(arbProvider); - const rec = await res.wait(); - console.log("Done! Your transaction is executed", rec); -} - -main().catch((error) => { - console.error(error); - process.exitCode = 1; -}); diff --git a/scripts/arbitrum/update-ethereum-executor.ts b/scripts/arbitrum/update-ethereum-executor.ts deleted file mode 100644 index e4407706..00000000 --- a/scripts/arbitrum/update-ethereum-executor.ts +++ /dev/null @@ -1,161 +0,0 @@ -import env from "../../utils/env"; -import network from "../../utils/network"; -import lido from "../../utils/lido"; -import arbitrum from "../../utils/arbitrum"; -import { GovBridgeExecutor__factory } from "../../typechain"; -import { assert } from "chai"; -import { L1ToL2MessageStatus } from "@arbitrum/sdk"; -import prompt from "../../utils/prompt"; -import { ethers } from "hardhat"; - -// Set address of the bridge executor to run the script -const GOV_BRIDGE_EXECUTOR = ""; - -async function main() { - const isForking = env.forking(); - const networkName = env.network(); - const ethArbNetwork = network.multichain(["eth", "arb"], networkName); - - const [l1LDOHolder] = ethArbNetwork.getSigners( - env.string("TESTING_ARB_LDO_HOLDER_PRIVATE_KEY"), - { forking: isForking } - ); - const [, arbRunner] = ethArbNetwork.getSigners(env.privateKey(), { - forking: isForking, - }); - - const govBridgeExecutor = GovBridgeExecutor__factory.connect( - GOV_BRIDGE_EXECUTOR, - arbRunner - ); - - const newEthExecutorLidoDAO = lido(networkName, l1LDOHolder); - const oldEthExecutorLidoDAO = lido( - networkName === "mainnet" ? "mainnet_test" : networkName, - l1LDOHolder - ); - const prevEthGovExecutorAddress = - await govBridgeExecutor.getEthereumGovernanceExecutor(); - - assert.equal( - oldEthExecutorLidoDAO.agent.address.toLocaleLowerCase(), - prevEthGovExecutorAddress.toLowerCase(), - `${oldEthExecutorLidoDAO.agent.address} is not current ethereumGovernanceExecutor` - ); - - console.log(` · Is forking: ${isForking}`); - console.log(` · Network Name: ${networkName}`); - console.log( - ` · Prev Ethereum Governance Executor: ${prevEthGovExecutorAddress}` - ); - console.log( - ` · New Ethereum Governance Executor: ${newEthExecutorLidoDAO.agent.address}` - ); - console.log(` · LDO Holder: ${l1LDOHolder.address}`); - console.log(` · LDO Holder ETH balance: ${await l1LDOHolder.getBalance()}`); - console.log(` · L2 tx runner: ${arbRunner.address}`); - console.log(` · L2 tx runner ETH balance: ${await arbRunner.getBalance()}`); - - await prompt.proceed(); - - console.log(`Preparing the voting tx...`); - - const arbAddresses = arbitrum.addresses(networkName); - - // Prepare data for Governance Bridge Executor - const executorCalldata = await govBridgeExecutor.interface.encodeFunctionData( - "queue", - [ - [GOV_BRIDGE_EXECUTOR], - [0], - ["updateEthereumGovernanceExecutor(address)"], - [ - ethers.utils.defaultAbiCoder.encode( - ["address"], - [newEthExecutorLidoDAO.agent.address] - ), - ], - [false], - ] - ); - - const { callvalue, calldata } = await arbitrum - .messaging(networkName, { forking: isForking }) - .prepareRetryableTicketTx({ - calldata: executorCalldata, - recipient: GOV_BRIDGE_EXECUTOR, - refundAddress: l1LDOHolder.address, - sender: oldEthExecutorLidoDAO.agent.address, - }); - - const txTransfer = await l1LDOHolder.sendTransaction({ - to: oldEthExecutorLidoDAO.agent.address, - value: callvalue, - }); - - await txTransfer.wait(); - - const createVoteTx = await oldEthExecutorLidoDAO.createVote( - l1LDOHolder, - "Update ethereumGovernanceExecutor on Arbitrum Governance Bridge Executor", - { - address: oldEthExecutorLidoDAO.agent.address, - signature: "execute(address,uint256,bytes)", - decodedCallData: [arbAddresses.Inbox, callvalue, calldata], - } - ); - - console.log("Creating voting to update ethereumGovernanceExecutor..."); - await createVoteTx.wait(); - console.log(`Vote was created!`); - - const votesCount = await oldEthExecutorLidoDAO.voting.votesLength(); - const voteId = votesCount.sub(1); - - console.log(`New vote id ${voteId.toString()}`); - console.log(`Voting for and executing the vote...`); - - const voteAndExecuteTx = await oldEthExecutorLidoDAO.voteAndExecute( - l1LDOHolder, - voteId, - true - ); - const executeTxReceipt = await voteAndExecuteTx.wait(); - - console.log(`Vote ${voteId.toString()} was executed!`); - - console.log("Waiting for L2 transaction..."); - const { status } = await arbitrum - .messaging(networkName, { forking: isForking }) - .waitForL2Message(executeTxReceipt.transactionHash); - - console.log(`Message delivered to L2`); - - assert.equal( - status, - L1ToL2MessageStatus.REDEEMED, - `L2 retryable txn failed with status ${L1ToL2MessageStatus[status]}` - ); - console.log("Task was queued on L2!"); - - console.log("Executing the queued task..."); - // execute task on L2 - const tasksCount = await govBridgeExecutor.getActionsSetCount(); - const targetTaskId = tasksCount.toNumber() - 1; - - const tx = await govBridgeExecutor.execute(targetTaskId); - await tx.wait(); - console.log("Task executed on L2!"); - - const ethereumGovernanceExecutor = - await govBridgeExecutor.getEthereumGovernanceExecutor(); - - console.log( - `New ethereum governance executor is: ${ethereumGovernanceExecutor}` - ); -} - -main().catch((error) => { - console.error(error); - process.exitCode = 1; -}); diff --git a/scripts/optimism/deploy-bridge.ts b/scripts/optimism/deploy-bridge.ts deleted file mode 100644 index 77d3ecb7..00000000 --- a/scripts/optimism/deploy-bridge.ts +++ /dev/null @@ -1,79 +0,0 @@ -import env from "../../utils/env"; -import prompt from "../../utils/prompt"; -import network from "../../utils/network"; -import optimism from "../../utils/optimism"; -import deployment from "../../utils/deployment"; -import { BridgingManagement } from "../../utils/bridging-management"; - -async function main() { - const networkName = env.network(); - const ethOptNetwork = network.multichain(["eth", "opt"], networkName); - - const [ethDeployer] = ethOptNetwork.getSigners(env.privateKey(), { - forking: env.forking(), - }); - const [, optDeployer] = ethOptNetwork.getSigners( - env.string("OPT_DEPLOYER_PRIVATE_KEY"), - { - forking: env.forking(), - } - ); - - const deploymentConfig = deployment.loadMultiChainDeploymentConfig(); - - const [l1DeployScript, l2DeployScript] = await optimism - .deployment(networkName, { logger: console }) - .erc20TokenBridgeDeployScript( - deploymentConfig.token, - { - deployer: ethDeployer, - admins: { - proxy: deploymentConfig.l1.proxyAdmin, - bridge: ethDeployer.address, - }, - }, - { - deployer: optDeployer, - admins: { - proxy: deploymentConfig.l2.proxyAdmin, - bridge: optDeployer.address, - }, - } - ); - - await deployment.printMultiChainDeploymentConfig( - "Deploy Optimism Bridge", - ethDeployer, - optDeployer, - deploymentConfig, - l1DeployScript, - l2DeployScript - ); - - await prompt.proceed(); - - await l1DeployScript.run(); - await l2DeployScript.run(); - - const l1ERC20TokenBridgeProxyDeployStepIndex = 1; - const l1BridgingManagement = new BridgingManagement( - l1DeployScript.getContractAddress(l1ERC20TokenBridgeProxyDeployStepIndex), - ethDeployer, - { logger: console } - ); - - const l2ERC20TokenBridgeProxyDeployStepIndex = 3; - const l2BridgingManagement = new BridgingManagement( - l2DeployScript.getContractAddress(l2ERC20TokenBridgeProxyDeployStepIndex), - optDeployer, - { logger: console } - ); - - await l1BridgingManagement.setup(deploymentConfig.l1); - await l2BridgingManagement.setup(deploymentConfig.l2); -} - -main().catch((error) => { - console.error(error); - process.exitCode = 1; -}); diff --git a/scripts/optimism/deploy-scratch.ts b/scripts/optimism/deploy-scratch.ts new file mode 100644 index 00000000..3583379f --- /dev/null +++ b/scripts/optimism/deploy-scratch.ts @@ -0,0 +1,99 @@ +import env from "../../utils/env"; +import prompt from "../../utils/prompt"; +import network from "../../utils/network"; +import deployment from "../../utils/deployment"; +import { BridgingManagement } from "../../utils/bridging-management"; +import deploymentAll from "../../utils/optimism/deployment"; + +async function main() { + const networkName = env.network(); + const ethOptNetwork = network.multichain(["eth", "opt"], networkName); + + const [ethDeployer] = ethOptNetwork.getSigners(env.privateKey(), { + forking: env.forking(), + }); + const [, optDeployer] = ethOptNetwork.getSigners( + env.string("OPT_DEPLOYER_PRIVATE_KEY"), + { + forking: env.forking(), + } + ); + + const deploymentConfig = deployment.loadMultiChainDeploymentConfig(); + + const [l1DeployScript, l2DeployScript] = await deploymentAll (networkName, { logger: console }) + .deployAllScript( + { + l1TokenNonRebasable: deploymentConfig.l1TokenNonRebasable, + l1TokenRebasable: deploymentConfig.l1RebasableToken, + accountingOracle: deploymentConfig.accountingOracle, + l2GasLimitForPushingTokenRate: deploymentConfig.l2GasLimitForPushingTokenRate, + l1AuthorizedRebaseCaller: deploymentConfig.l1AuthorizedRebaseCaller, + + deployer: ethDeployer, + admins: { + proxy: deploymentConfig.l1.proxyAdmin, + bridge: ethDeployer.address + }, + contractsShift: 0, + }, + { + tokenRateOracle: { + tokenRateOutdatedDelay: deploymentConfig.tokenRateOutdatedDelay, + maxAllowedL2ToL1ClockLag: deploymentConfig.maxAllowedL2ToL1ClockLag, + maxAllowedTokenRateDeviationPerDayBp: deploymentConfig.maxAllowedTokenRateDeviationPerDayBp, + oldestRateAllowedInPauseTimeSpan: deploymentConfig.oldestRateAllowedInPauseTimeSpan, + maxAllowedTimeBetweenTokenRateUpdates: deploymentConfig.maxAllowedTimeBetweenTokenRateUpdates, + tokenRate: deploymentConfig.tokenRateValue, + l1Timestamp: deploymentConfig.tokenRateL1Timestamp + }, + l2TokenNonRebasable: { + version: "1" + }, + l2TokenRebasable: { + version: "1" + }, + + deployer: optDeployer, + admins: { + proxy: deploymentConfig.l2.proxyAdmin, + bridge: optDeployer.address, + }, + contractsShift: 0, + } + ); + + await deployment.printMultiChainDeploymentConfig( + "Deploy Optimism Bridge", + ethDeployer, + optDeployer, + deploymentConfig, + l1DeployScript, + l2DeployScript + ); + + await prompt.proceed(); + + await l1DeployScript.run(); + await l2DeployScript.run(); + + const l1BridgingManagement = new BridgingManagement( + l1DeployScript.bridgeProxyAddress, + ethDeployer, + { logger: console } + ); + + const l2BridgingManagement = new BridgingManagement( + l2DeployScript.tokenBridgeProxyAddress, + optDeployer, + { logger: console } + ); + + await l1BridgingManagement.setup(deploymentConfig.l1); + await l2BridgingManagement.setup(deploymentConfig.l2); +} + +main().catch((error) => { + console.error(error); + process.exitCode = 1; +}); diff --git a/scripts/optimism/upgrade.ts b/scripts/optimism/upgrade.ts new file mode 100644 index 00000000..c4d969b7 --- /dev/null +++ b/scripts/optimism/upgrade.ts @@ -0,0 +1,109 @@ +import env from "../../utils/env"; +import prompt from "../../utils/prompt"; +import network from "../../utils/network"; +import deployment from "../../utils/deployment"; +import { BridgingManagement } from "../../utils/bridging-management"; +import upgrade from "../../utils/optimism/upgrade"; + +async function main() { + const networkName = env.network(); + const ethOptNetwork = network.multichain(["eth", "opt"], networkName); + + const [ethDeployer] = ethOptNetwork.getSigners(env.privateKey(), { + forking: env.forking(), + }); + const [, optDeployer] = ethOptNetwork.getSigners( + env.string("OPT_DEPLOYER_PRIVATE_KEY"), + { + forking: env.forking(), + } + ); + + const deploymentConfig = deployment.loadMultiChainDeploymentConfig(); + + const [l1DeployScript, l2DeployScript] = await upgrade (networkName, { logger: console }) + .upgradeScript( + { + l1TokenNonRebasable: deploymentConfig.l1TokenNonRebasable, + l1TokenRebasable: deploymentConfig.l1RebasableToken, + accountingOracle: deploymentConfig.accountingOracle, + l2GasLimitForPushingTokenRate: deploymentConfig.l2GasLimitForPushingTokenRate, + + l1TokenBridge: deploymentConfig.l1TokenBridge, + + deployer: ethDeployer, + admins: { + proxy: deploymentConfig.l1.proxyAdmin, + bridge: ethDeployer.address + }, + contractsShift: 0, + }, + { + tokenRateOracle: { + constructor: { + tokenRateOutdatedDelay: deploymentConfig.tokenRateOutdatedDelay, + maxAllowedL2ToL1ClockLag: deploymentConfig.maxAllowedL2ToL1ClockLag, + maxAllowedTokenRateDeviationPerDayBp: deploymentConfig.maxAllowedTokenRateDeviationPerDayBp, + oldestRateAllowedInPauseTimeSpan: deploymentConfig.oldestRateAllowedInPauseTimeSpan, + maxAllowedTimeBetweenTokenRateUpdates: deploymentConfig.maxAllowedTimeBetweenTokenRateUpdates + }, + initialize: { + tokenRate: deploymentConfig.tokenRateValue, + l1Timestamp: deploymentConfig.tokenRateL1Timestamp + } + }, + + l2TokenBridge: deploymentConfig.l2TokenBridge, + + l2TokenNonRebasable: { + address: deploymentConfig.l2TokenNonRebasable, + version: "1" + }, + + l2TokenRebasable: { + version: "1" + }, + + deployer: optDeployer, + admins: { + proxy: deploymentConfig.l2.proxyAdmin, + bridge: optDeployer.address, + }, + contractsShift: 0, + } + ); + + await deployment.printMultiChainDeploymentConfig( + "Upgrade Optimism Bridge", + ethDeployer, + optDeployer, + deploymentConfig, + l1DeployScript, + l2DeployScript + ); + + await prompt.proceed(); + + await l1DeployScript.run(); + await l2DeployScript.run(); + + const l1BridgingManagement = new BridgingManagement( + l1DeployScript.bridgeProxyAddress, + ethDeployer, + { logger: console } + ); + + const l2BridgingManagement = new BridgingManagement( + l2DeployScript.tokenBridgeProxyAddress, + optDeployer, + { logger: console } + ); + + await l1BridgingManagement.setup(deploymentConfig.l1); + await l2BridgingManagement.setup(deploymentConfig.l2); +} + +main().catch((error) => { + console.error(error); + process.exitCode = 1; +}); diff --git a/test/arbitrum/L1ERC20TokensGateway.unit.test.ts b/test/arbitrum/L1ERC20TokensGateway.unit.test.ts deleted file mode 100644 index fa997e5d..00000000 --- a/test/arbitrum/L1ERC20TokensGateway.unit.test.ts +++ /dev/null @@ -1,940 +0,0 @@ -import hre, { ethers } from "hardhat"; -import { wei } from "../../utils/wei"; -import { - BridgeStub__factory, - ERC20BridgedStub__factory, - InboxStub__factory, - L1ERC20TokenGateway__factory, - L2ERC20TokenGateway__factory, - OssifiableProxy__factory, - OutboxStub__factory, - EmptyContractStub__factory, -} from "../../typechain"; -import { assert } from "chai"; -import { unit } from "../../utils/testing"; - -unit("Arbitrum :: L1ERC20TokensGateway", ctxFactory) - .test("l1Token() ", async (ctx) => { - assert.equal( - await ctx.l1TokensGateway.l1Token(), - ctx.stubs.l1Token.address - ); - }) - - .test("l2Token()", async (ctx) => { - assert.equal( - await ctx.l1TokensGateway.l2Token(), - ctx.stubs.l2Token.address - ); - }) - - .test("counterpartGateway()", async (ctx) => { - assert.equal( - await ctx.l1TokensGateway.counterpartGateway(), - ctx.stubs.l2TokensGateway.address - ); - }) - - .test("router()", async (ctx) => { - assert.equal( - await ctx.l1TokensGateway.router(), - ctx.stubs.l1Router.address - ); - }) - - .test("calculateL2TokenAddress() :: correct l1Token", async (ctx) => { - const actualL2TokenAddress = - await ctx.l1TokensGateway.calculateL2TokenAddress( - ctx.stubs.l1Token.address - ); - assert.equal(actualL2TokenAddress, ctx.stubs.l2Token.address); - }) - - .test("calculateL2TokenAddress() :: incorrect l1Token", async (ctx) => { - const wrongAddress = ctx.accounts.stranger.address; - const actualL2TokenAddress = - await ctx.l1TokensGateway.calculateL2TokenAddress(wrongAddress); - assert.equal(actualL2TokenAddress, hre.ethers.constants.AddressZero); - }) - - .test("getOutboundCalldata()", async (ctx) => { - const [sender, recipient] = await hre.ethers.getSigners(); - const amount = wei`1.5 ether`; - const actualCalldata = await ctx.l1TokensGateway.getOutboundCalldata( - ctx.stubs.l1Token.address, - sender.address, - recipient.address, - amount, - "0x" - ); - - const expectedCalldata = - ctx.stubs.l2TokensGateway.interface.encodeFunctionData( - "finalizeInboundTransfer", - [ - ctx.stubs.l1Token.address, - sender.address, - recipient.address, - amount, - "0x", - ] - ); - - assert.equal(actualCalldata, expectedCalldata); - }) - - .test("outboundTransfer() :: deposits are disabled", async (ctx) => { - // validate deposits are disabled - assert.isFalse(await ctx.l1TokensGateway.isDepositsEnabled()); - - const [sender, recipient] = await hre.ethers.getSigners(); - const amount = wei`1.2 ether`; - const maxGas = wei`1000 gwei`; - const gasPriceBid = wei`2000 gwei`; - const maxSubmissionCost = wei`11_000 gwei`; - const data = encodeSenderOutboundTransferData(maxSubmissionCost); - - // validate deposit reverts with error ErrorDepositsDisabled() - await assert.revertsWith( - ctx.l1TokensGateway - .connect(sender) - .outboundTransfer( - ctx.stubs.l1Token.address, - recipient.address, - amount, - maxGas, - gasPriceBid, - data - ), - "ErrorDepositsDisabled()" - ); - }) - - .test("outboundTransfer() :: wrong l1Token address", async (ctx) => { - const [sender, recipient, wrongAddress] = await hre.ethers.getSigners(); - const amount = wei`1.2 ether`; - const maxGas = wei`1000 gwei`; - const gasPriceBid = wei`2000 gwei`; - const maxSubmissionCost = wei`11_000 gwei`; - const data = encodeSenderOutboundTransferData(maxSubmissionCost); - - const { - l1TokensGateway, - accounts: { deployer }, - } = ctx; - - // initialize gateway - await l1TokensGateway.initialize(deployer.address); - - // validate gateway was initialized - assert.isTrue(await l1TokensGateway.isInitialized()); - - // grant DEPOSITS_ENABLER_ROLE to the l1Deployer to enable deposits - await l1TokensGateway.grantRole( - await l1TokensGateway.DEPOSITS_ENABLER_ROLE(), - deployer.address - ); - - // enable deposits - await l1TokensGateway.enableDeposits(); - - // validate deposits was enabled - assert.isTrue(await l1TokensGateway.isDepositsEnabled()); - - await assert.revertsWith( - l1TokensGateway - .connect(sender) - .outboundTransfer( - wrongAddress.address, - recipient.address, - amount, - maxGas, - gasPriceBid, - data - ), - "ErrorUnsupportedL1Token()" - ); - }) - - .test("outboundTransfer() :: max submission cost is zero", async (ctx) => { - const { - l1TokensGateway, - stubs: { l1Token, inbox }, - accounts: { deployer }, - } = ctx; - - // initialize gateway - await l1TokensGateway.initialize(deployer.address); - - // validate gateway was initialized - assert.isTrue(await l1TokensGateway.isInitialized()); - - // grant DEPOSITS_ENABLER_ROLE to the l1Deployer to enable deposits - await l1TokensGateway.grantRole( - await l1TokensGateway.DEPOSITS_ENABLER_ROLE(), - deployer.address - ); - - // enable deposits - await l1TokensGateway.enableDeposits(); - - // validate deposits was enabled - assert.isTrue(await l1TokensGateway.isDepositsEnabled()); - - const [sender, recipient] = await hre.ethers.getSigners(); - const amount = wei`1.2 ether`; - const maxGas = wei`1000 gwei`; - const gasPriceBid = wei`2000 gwei`; - const maxSubmissionCost = wei`0 wei`; - const value = wei`3000 gwei`; - const data = encodeSenderOutboundTransferData(maxSubmissionCost); - - // set allowance for l1TokensGateway before transfer - await l1Token.connect(sender).approve(l1TokensGateway.address, amount); - - const retryableTicketId = 13; - await inbox.setRetryableTicketId(retryableTicketId); - - assert.equalBN(await inbox.retryableTicketId(), retryableTicketId); - - // initiate outbound transfer - await assert.revertsWith( - l1TokensGateway - .connect(sender) - .outboundTransfer( - l1Token.address, - recipient.address, - amount, - maxGas, - gasPriceBid, - data, - { value } - ), - "ErrorNoMaxSubmissionCost()" - ); - }) - - .test("outboundTransfer() :: ETH value too low", async (ctx) => { - const { - l1TokensGateway, - stubs: { l1Token, inbox }, - accounts: { deployer }, - } = ctx; - - // initialize gateway - await l1TokensGateway.initialize(deployer.address); - - // validate gateway was initialized - assert.isTrue(await l1TokensGateway.isInitialized()); - - // grant DEPOSITS_ENABLER_ROLE to the l1Deployer to enable deposits - await l1TokensGateway.grantRole( - await l1TokensGateway.DEPOSITS_ENABLER_ROLE(), - deployer.address - ); - - // enable deposits - await l1TokensGateway.enableDeposits(); - - // validate deposits was enabled - assert.isTrue(await l1TokensGateway.isDepositsEnabled()); - - const [sender, recipient] = await hre.ethers.getSigners(); - const amount = wei`1.2 ether`; - const maxGas = wei`100_000`; - const gasPriceBid = wei`2 gwei`; - const maxSubmissionCost = wei`50_000 gwei`; - const value = wei`200_000 gwei`; - const data = encodeSenderOutboundTransferData(maxSubmissionCost); - - // set allowance for l1TokensGateway before transfer - await l1Token.connect(sender).approve(l1TokensGateway.address, amount); - - const retryableTicketId = 13; - await inbox.setRetryableTicketId(retryableTicketId); - - assert.equalBN(await inbox.retryableTicketId(), retryableTicketId); - - // initiate outbound transfer - await assert.revertsWith( - l1TokensGateway - .connect(sender) - .outboundTransfer( - l1Token.address, - recipient.address, - amount, - maxGas, - gasPriceBid, - data, - { value } - ), - "ErrorETHValueTooLow()" - ); - }) - - .test("outboundTransfer() :: extra data not empty", async (ctx) => { - const { - l1TokensGateway, - stubs: { l1Token }, - accounts: { deployer, l1RouterAsEOA }, - } = ctx; - - // initialize gateway - await l1TokensGateway.initialize(deployer.address); - - // validate gateway was initialized - assert.isTrue(await l1TokensGateway.isInitialized()); - - // grant DEPOSITS_ENABLER_ROLE to the l1Deployer to enable deposits - await l1TokensGateway.grantRole( - await l1TokensGateway.DEPOSITS_ENABLER_ROLE(), - deployer.address - ); - - // enable deposits - await l1TokensGateway.enableDeposits(); - - // validate deposits was enabled - assert.isTrue(await l1TokensGateway.isDepositsEnabled()); - - const [sender, recipient] = await hre.ethers.getSigners(); - const amount = wei`1.2 ether`; - const maxGas = wei`1000 gwei`; - const gasPriceBid = wei`2000 gwei`; - const maxSubmissionCost = wei`11_000 gwei`; - const value = wei`3000 gwei`; - const data = encodeRouterOutboundTransferData( - sender.address, - maxSubmissionCost, - "0xdeadbeef" - ); - - // initiate outbound transfer - await assert.revertsWith( - l1TokensGateway - .connect(l1RouterAsEOA) - .outboundTransfer( - l1Token.address, - recipient.address, - amount, - maxGas, - gasPriceBid, - data, - { value } - ), - "ExtraDataNotEmpty()" - ); - }) - - .test("outboundTransfer() :: ETH value too low", async (ctx) => { - const { - l1TokensGateway, - stubs: { l1Token, inbox }, - accounts: { deployer }, - } = ctx; - - // initialize gateway - await l1TokensGateway.initialize(deployer.address); - - // validate gateway was initialized - assert.isTrue(await l1TokensGateway.isInitialized()); - - // grant DEPOSITS_ENABLER_ROLE to the l1Deployer to enable deposits - await l1TokensGateway.grantRole( - await l1TokensGateway.DEPOSITS_ENABLER_ROLE(), - deployer.address - ); - - // enable deposits - await l1TokensGateway.enableDeposits(); - - // validate deposits was enabled - assert.isTrue(await l1TokensGateway.isDepositsEnabled()); - - const [sender, recipient] = await hre.ethers.getSigners(); - const amount = wei`1.2 ether`; - const maxGas = wei`100_000`; - const gasPriceBid = wei`2 gwei`; - const maxSubmissionCost = wei`50_000 gwei`; - const value = wei`200_000 gwei`; - const data = encodeSenderOutboundTransferData(maxSubmissionCost); - - // set allowance for l1TokensGateway before transfer - await l1Token.connect(sender).approve(l1TokensGateway.address, amount); - - const retryableTicketId = 13; - await inbox.setRetryableTicketId(retryableTicketId); - - assert.equalBN(await inbox.retryableTicketId(), retryableTicketId); - - // initiate outbound transfer - await assert.revertsWith( - l1TokensGateway - .connect(sender) - .outboundTransfer( - l1Token.address, - recipient.address, - amount, - maxGas, - gasPriceBid, - data, - { value } - ), - "ErrorETHValueTooLow()" - ); - }) - - .test("outboundTransfer() :: called by router", async (ctx) => { - const { - l1TokensGateway, - stubs: { l1Token, inbox, l2TokensGateway }, - accounts: { deployer, sender, recipient, l1RouterAsEOA }, - } = ctx; - - // initialize gateway - await l1TokensGateway.initialize(deployer.address); - - // validate gateway was initialized - assert.isTrue(await l1TokensGateway.isInitialized()); - - // grant DEPOSITS_ENABLER_ROLE to the l1Deployer to enable deposits - await l1TokensGateway.grantRole( - await l1TokensGateway.DEPOSITS_ENABLER_ROLE(), - deployer.address - ); - - // enable deposits - await l1TokensGateway.enableDeposits(); - - // validate deposits was enabled - assert.isTrue(await l1TokensGateway.isDepositsEnabled()); - - const amount = wei`1.2 ether`; - const maxGas = wei`100_000`; - const gasPriceBid = wei`2 gwei`; - const maxSubmissionCost = wei`50_000 gwei`; - const value = wei`250_000 gwei`; - const data = encodeRouterOutboundTransferData( - sender.address, - maxSubmissionCost - ); - - const retryableTicketId = 7; - await inbox.setRetryableTicketId(retryableTicketId); - - assert.equalBN(await inbox.retryableTicketId(), retryableTicketId); - - const senderBalanceBefore = await l1Token.balanceOf(sender.address); - - // set allowance for l1TokensGateway before transfer - await l1Token.connect(sender).approve(l1TokensGateway.address, amount); - - // call tx locally to check return value - assert.equal( - await l1TokensGateway - .connect(l1RouterAsEOA) - .callStatic.outboundTransfer( - l1Token.address, - recipient.address, - amount, - maxGas, - gasPriceBid, - data, - { value } - ), - hre.ethers.utils.defaultAbiCoder.encode(["uint256"], [retryableTicketId]) - ); - - // initiate outbound transfer - const tx = await l1TokensGateway - .connect(l1RouterAsEOA) - .outboundTransfer( - l1Token.address, - recipient.address, - amount, - maxGas, - gasPriceBid, - data, - { value } - ); - - // validate DepositInitiated event was emitted - await assert.emits(l1TokensGateway, tx, "DepositInitiated", [ - l1Token.address, - sender.address, - recipient.address, - retryableTicketId, - amount, - ]); - - const expectedCalldata = l2TokensGateway.interface.encodeFunctionData( - "finalizeInboundTransfer", - [l1Token.address, sender.address, recipient.address, amount, "0x"] - ); - - // validate TxToL2 was emitted - await assert.emits(l1TokensGateway, tx, "TxToL2", [ - sender.address, - l2TokensGateway.address, - retryableTicketId, - expectedCalldata, - ]); - - // validate CreateRetryableTicketCalled event was emitted - await assert.emits(inbox, tx, "CreateRetryableTicketCalled", [ - value, - l2TokensGateway.address, - 0, - maxSubmissionCost, - sender.address, - sender.address, - maxGas, - gasPriceBid, - expectedCalldata, - ]); - - // validate balance of the sender decreased - assert.equalBN( - await l1Token.balanceOf(sender.address), - senderBalanceBefore.sub(amount) - ); - - // validate balance of the gateway increased - assert.equalBN(await l1Token.balanceOf(l1TokensGateway.address), amount); - }) - - .test("outboundTransfer() :: called by sender", async (ctx) => { - const { - l1TokensGateway, - stubs: { l1Token, inbox, l2TokensGateway }, - accounts: { deployer }, - } = ctx; - - // initialize gateway - await l1TokensGateway.initialize(deployer.address); - - // validate gateway was initialized - assert.isTrue(await l1TokensGateway.isInitialized()); - - // grant DEPOSITS_ENABLER_ROLE to the l1Deployer to enable deposits - await l1TokensGateway.grantRole( - await l1TokensGateway.DEPOSITS_ENABLER_ROLE(), - deployer.address - ); - - // enable deposits - await l1TokensGateway.enableDeposits(); - - // validate deposits was enabled - assert.isTrue(await l1TokensGateway.isDepositsEnabled()); - - const [sender, recipient] = await hre.ethers.getSigners(); - const amount = wei`1.2 ether`; - const maxGas = wei`100_000`; - const gasPriceBid = wei`2 gwei`; - const maxSubmissionCost = wei`50_000 gwei`; - const value = wei`250_000 gwei`; - const data = encodeSenderOutboundTransferData(maxSubmissionCost); - - const senderBalanceBefore = await l1Token.balanceOf(sender.address); - - // set allowance for l1TokensGateway before transfer - await l1Token.connect(sender).approve(l1TokensGateway.address, amount); - - const retryableTicketId = 13; - await inbox.setRetryableTicketId(retryableTicketId); - - assert.equalBN(await inbox.retryableTicketId(), retryableTicketId); - - // initiate outbound transfer - const tx = await l1TokensGateway - .connect(sender) - .outboundTransfer( - l1Token.address, - recipient.address, - amount, - maxGas, - gasPriceBid, - data, - { value } - ); - - // validate DepositInitiated event was emitted - await assert.emits(l1TokensGateway, tx, "DepositInitiated", [ - l1Token.address, - sender.address, - recipient.address, - retryableTicketId, - amount, - ]); - - const expectedCalldata = l2TokensGateway.interface.encodeFunctionData( - "finalizeInboundTransfer", - [l1Token.address, sender.address, recipient.address, amount, "0x"] - ); - - // validate TxToL2 was emitted - await assert.emits(l1TokensGateway, tx, "TxToL2", [ - sender.address, - l2TokensGateway.address, - retryableTicketId, - expectedCalldata, - ]); - - // validate CreateRetryableTicketCalled event was emitted - await assert.emits(inbox, tx, "CreateRetryableTicketCalled", [ - value, - l2TokensGateway.address, - 0, - maxSubmissionCost, - sender.address, - sender.address, - maxGas, - gasPriceBid, - expectedCalldata, - ]); - - // validate balance of the sender decreased - assert.equalBN( - await l1Token.balanceOf(sender.address), - senderBalanceBefore.sub(amount) - ); - - // validate balance of the gateway increased - assert.equalBN(await l1Token.balanceOf(l1TokensGateway.address), amount); - }) - - .test("finalizeInboundTransfer() :: withdrawals disabled", async (ctx) => { - const { - l1TokensGateway, - accounts: { deployer, bridgeAsEOA, sender, recipient }, - stubs: { l1Token }, - } = ctx; - - // initialize gateway - await l1TokensGateway.initialize(deployer.address); - - // validate gateway was initialized - assert.isTrue(await l1TokensGateway.isInitialized()); - - // validate withdrawals disabled - assert.isFalse(await l1TokensGateway.isWithdrawalsEnabled()); - - await assert.revertsWith( - l1TokensGateway - .connect(bridgeAsEOA) - .finalizeInboundTransfer( - l1Token.address, - sender.address, - recipient.address, - wei`10 ether`, - "0x" - ), - "ErrorWithdrawalsDisabled()" - ); - }) - .test("finalizeInboundTransfer() :: unauthorized bridge", async (ctx) => { - const { - l1TokensGateway, - accounts: { deployer, stranger, sender, recipient }, - stubs: { l1Token }, - } = ctx; - - // initialize gateway - await l1TokensGateway.initialize(deployer.address); - - // validate gateway was initialized - assert.isTrue(await l1TokensGateway.isInitialized()); - - // grant WITHDRAWALS_ENABLER_ROLE to the l1Deployer to enable withdrawals - await l1TokensGateway.grantRole( - await l1TokensGateway.WITHDRAWALS_ENABLER_ROLE(), - deployer.address - ); - - // enable withdrawals - await l1TokensGateway.enableWithdrawals(); - - // validate withdrawals were enabled - assert.isTrue(await l1TokensGateway.isWithdrawalsEnabled()); - - // validate that stranger address is not counterpartGateway - assert.notEqual( - await l1TokensGateway.counterpartGateway(), - stranger.address - ); - - // validate gateway reverts with ErrorUnauthorizedBridge() - await assert.revertsWith( - l1TokensGateway - .connect(stranger) - .finalizeInboundTransfer( - l1Token.address, - sender.address, - recipient.address, - wei`10 ether`, - "0x" - ), - "ErrorUnauthorizedBridge()" - ); - }) - - .test( - "finalizeInboundTransfer() :: wrong cross domain sender", - async (ctx) => { - const { - l1TokensGateway, - accounts: { deployer, stranger, sender, recipient, bridgeAsEOA }, - stubs: { l1Token, outbox }, - } = ctx; - - // initialize gateway - await l1TokensGateway.initialize(deployer.address); - - // validate gateway was initialized - assert.isTrue(await l1TokensGateway.isInitialized()); - - // grant WITHDRAWALS_ENABLER_ROLE to the l1Deployer to enable withdrawals - await l1TokensGateway.grantRole( - await l1TokensGateway.WITHDRAWALS_ENABLER_ROLE(), - deployer.address - ); - - // enable withdrawals - await l1TokensGateway.enableWithdrawals(); - - // validate withdrawals were enabled - assert.isTrue(await l1TokensGateway.isWithdrawalsEnabled()); - - // validate that stranger address is not counterpartGateway - assert.notEqual( - await l1TokensGateway.counterpartGateway(), - stranger.address - ); - - // prepare OutboxStub to return wrong gateway address - await outbox.setL2ToL1Sender(stranger.address); - - // validate gateway reverts with ErrorWrongCrossDomainSender() - await assert.revertsWith( - l1TokensGateway - .connect(bridgeAsEOA) - .finalizeInboundTransfer( - l1Token.address, - sender.address, - recipient.address, - wei`10 ether`, - "0x" - ), - "ErrorWrongCrossDomainSender()" - ); - } - ) - - .test("finalizeInboundTransfer() :: wrong token", async (ctx) => { - const { - l1TokensGateway, - accounts: { stranger, sender, recipient, deployer, bridgeAsEOA }, - } = ctx; - const wrongTokenAddress = stranger.address; - - // initialize gateway - await l1TokensGateway.initialize(deployer.address); - - // validate gateway was initialized - assert.isTrue(await l1TokensGateway.isInitialized()); - - // grant WITHDRAWALS_ENABLER_ROLE to the l1Deployer to enable withdrawals - await l1TokensGateway.grantRole( - await l1TokensGateway.WITHDRAWALS_ENABLER_ROLE(), - deployer.address - ); - - // enable withdrawals - await l1TokensGateway.enableWithdrawals(); - - // validate withdrawals were enabled - assert.isTrue(await l1TokensGateway.isWithdrawalsEnabled()); - - // validate gateway reverts with ErrorUnsupportedL1Token() - await assert.revertsWith( - l1TokensGateway - .connect(bridgeAsEOA) - .finalizeInboundTransfer( - wrongTokenAddress, - sender.address, - recipient.address, - wei`10 ether`, - "0x" - ), - "ErrorUnsupportedL1Token()" - ); - }) - - .test("finalizeInboundTransfer() :: works as expected", async (ctx) => { - const { - l1TokensGateway, - accounts: { sender, recipient, deployer, bridgeAsEOA }, - stubs: { l1Token }, - } = ctx; - - // initialize gateway - await l1TokensGateway.initialize(deployer.address); - - // validate gateway was initialized - assert.isTrue(await l1TokensGateway.isInitialized()); - - // grant WITHDRAWALS_ENABLER_ROLE to the l1Deployer to enable withdrawals - await l1TokensGateway.grantRole( - await l1TokensGateway.WITHDRAWALS_ENABLER_ROLE(), - deployer.address - ); - - // enable withdrawals - await l1TokensGateway.enableWithdrawals(); - - // validate withdrawals were enabled - assert.isTrue(await l1TokensGateway.isWithdrawalsEnabled()); - - // transfer l1Tokens to l1TokensGateway - const initialL1GatewayBalance = wei`10_000 ether`; - await l1Token.transfer(l1TokensGateway.address, initialL1GatewayBalance); - - // validate l1TokensGateway has enough amount of tokens - assert.equal( - await l1Token.balanceOf(l1TokensGateway.address).then(wei.fromBigNumber), - initialL1GatewayBalance - ); - - const amount = wei`10 ether`; - - const tx = await l1TokensGateway - .connect(bridgeAsEOA) - .finalizeInboundTransfer( - l1Token.address, - sender.address, - recipient.address, - amount, - "0x" - ); - - // validate WithdrawalFinalized was emitted - assert.emits(l1TokensGateway, tx, "WithdrawalFinalized", [ - l1Token.address, - sender.address, - recipient.address, - 0, - amount, - ]); - - // validate tokens were transferred to recipient - assert.equalBN(await l1Token.balanceOf(recipient.address), amount); - - // validate balance of the l1TokensGateway was decreased - assert.equalBN( - await l1Token.balanceOf(l1TokensGateway.address), - wei.toBigNumber(initialL1GatewayBalance).sub(amount) - ); - }) - - .run(); - -async function ctxFactory() { - const [deployer, stranger, sender, recipient] = await hre.ethers.getSigners(); - const outboxStub = await new OutboxStub__factory(deployer).deploy(); - const bridgeStub = await new BridgeStub__factory(deployer).deploy( - outboxStub.address, - { value: wei.toBigNumber(wei`1 ether`) } - ); - const inboxStub = await new InboxStub__factory(deployer).deploy( - bridgeStub.address - ); - const l1RouterStub = await new EmptyContractStub__factory(deployer).deploy({ - value: wei.toBigNumber(wei`1 ether`), - }); - const l2TokensGatewayStub = await new EmptyContractStub__factory( - deployer - ).deploy(); - - await outboxStub.setL2ToL1Sender(l2TokensGatewayStub.address); - await hre.network.provider.request({ - method: "hardhat_impersonateAccount", - params: [bridgeStub.address], - }); - const l2TokenStub = await new EmptyContractStub__factory(deployer).deploy(); - const l1TokenStub = await new ERC20BridgedStub__factory(deployer).deploy( - "ERC20 Mock", - "ERC20" - ); - await l1TokenStub.transfer(sender.address, wei`100 ether`); - - const l1TokensGatewayImpl = await new L1ERC20TokenGateway__factory( - deployer - ).deploy( - inboxStub.address, - l1RouterStub.address, - l2TokensGatewayStub.address, - l1TokenStub.address, - l2TokenStub.address - ); - const l1TokensGatewayProxy = await new OssifiableProxy__factory( - deployer - ).deploy(l1TokensGatewayImpl.address, deployer.address, "0x"); - - await hre.network.provider.request({ - method: "hardhat_impersonateAccount", - params: [l1RouterStub.address], - }); - const l1RouterAsEOA = await hre.ethers.getSigner(l1RouterStub.address); - - return { - accounts: { - deployer, - stranger, - sender, - recipient, - bridgeAsEOA: await ethers.getSigner(bridgeStub.address), - l1RouterAsEOA, - }, - stubs: { - inbox: inboxStub, - outbox: outboxStub, - bridge: bridgeStub, - l1Token: l1TokenStub, - l2Token: l2TokenStub, - l1Router: l1RouterStub, - l2TokensGateway: L2ERC20TokenGateway__factory.connect( - l2TokensGatewayStub.address, - deployer - ), - }, - l1TokensGateway: L1ERC20TokenGateway__factory.connect( - l1TokensGatewayProxy.address, - deployer - ), - }; -} - -function encodeSenderOutboundTransferData(maxSubmissionCost: string) { - return hre.ethers.utils.defaultAbiCoder.encode( - ["uint256", "bytes"], - [maxSubmissionCost, "0x"] - ); -} - -function encodeRouterOutboundTransferData( - sender: string, - maxSubmissionCost: string, - extraData = "0x" -) { - return hre.ethers.utils.defaultAbiCoder.encode( - ["address", "bytes"], - [ - sender, - hre.ethers.utils.defaultAbiCoder.encode( - ["uint256", "bytes"], - [maxSubmissionCost, extraData] - ), - ] - ); -} diff --git a/test/arbitrum/L2ERC20TokensGateway.unit.test.ts b/test/arbitrum/L2ERC20TokensGateway.unit.test.ts deleted file mode 100644 index 81fb6068..00000000 --- a/test/arbitrum/L2ERC20TokensGateway.unit.test.ts +++ /dev/null @@ -1,663 +0,0 @@ -import hre, { ethers } from "hardhat"; -import { wei } from "../../utils/wei"; -import { - ERC20BridgedStub__factory, - L1ERC20TokenGateway__factory, - L2ERC20TokenGateway__factory, - OssifiableProxy__factory, - EmptyContractStub__factory, -} from "../../typechain"; -import { assert } from "chai"; -import testing, { unit } from "../../utils/testing"; -import { ArbSysStub__factory } from "../../typechain/factories/ArbSysStub__factory"; - -unit("Arbitrum :: L2ERC20TokensGateway", ctxFactory) - .test("l1Token()", async (ctx) => { - assert.equal( - await ctx.l2TokensGateway.l1Token(), - ctx.stubs.l1Token.address - ); - }) - - .test("l2Token()", async (ctx) => { - assert.equal( - await ctx.l2TokensGateway.l2Token(), - ctx.stubs.l2Token.address - ); - }) - - .test("counterpartGateway()", async (ctx) => { - assert.equal( - await ctx.l2TokensGateway.counterpartGateway(), - ctx.stubs.l1TokensGateway.address - ); - }) - - .test("router() ", async (ctx) => { - assert.equal( - await ctx.l2TokensGateway.router(), - ctx.stubs.l2Router.address - ); - }) - - .test("calculateL2TokenAddress() :: correct l1Token address", async (ctx) => { - const actualL2TokenAddress = - await ctx.l2TokensGateway.calculateL2TokenAddress( - ctx.stubs.l1Token.address - ); - assert.equal(actualL2TokenAddress, ctx.stubs.l2Token.address); - }) - - .test( - "calculateL2TokenAddress() :: incorrect l1Token address", - async (ctx) => { - const wrongAddress = ctx.accounts.stranger.address; - const actualL2TokenAddress = - await ctx.l2TokensGateway.calculateL2TokenAddress(wrongAddress); - assert.equal(actualL2TokenAddress, hre.ethers.constants.AddressZero); - } - ) - - .test("getOutboundCalldata()", async (ctx) => { - const { - l2TokensGateway, - stubs: { l1Token, l1TokensGateway }, - accounts: { sender, recipient }, - } = ctx; - const amount = wei`1.5 ether`; - const actualCalldata = await l2TokensGateway.getOutboundCalldata( - l1Token.address, - sender.address, - recipient.address, - amount, - "0x" - ); - - const expectedCalldata = l1TokensGateway.interface.encodeFunctionData( - "finalizeInboundTransfer", - [l1Token.address, sender.address, recipient.address, amount, "0x"] - ); - - assert.equal(actualCalldata, expectedCalldata); - }) - - .test("outboundTransfer() :: withdrawals are disabled", async (ctx) => { - const { - l2TokensGateway, - accounts: { sender, recipient }, - } = ctx; - // validate deposits are disabled - assert.isFalse(await l2TokensGateway.isDepositsEnabled()); - - const amount = wei`1.2 ether`; - const maxGas = wei`1000 gwei`; - const gasPriceBid = wei`2000 gwei`; - const maxSubmissionCost = wei`11_000 gwei`; - const data = encodeOutboundTransferData(maxSubmissionCost); - - // validate deposit reverts with error ErrorWithdrawalsDisabled() - await assert.revertsWith( - l2TokensGateway - .connect(sender) - .outboundTransfer( - ctx.stubs.l1Token.address, - recipient.address, - amount, - maxGas, - gasPriceBid, - data - ), - "ErrorWithdrawalsDisabled()" - ); - }) - - .test("outboundTransfer() :: wrong l1Token address", async (ctx) => { - const amount = wei`1.2 ether`; - const maxGas = wei`1000 gwei`; - const gasPriceBid = wei`2000 gwei`; - const maxSubmissionCost = wei`11_000 gwei`; - const data = encodeOutboundTransferData(maxSubmissionCost); - - const { - l2TokensGateway, - accounts: { deployer, sender, recipient }, - stubs: { l2Token: wrongAddress }, - } = ctx; - - // initialize gateway - await l2TokensGateway.initialize(deployer.address); - - // validate gateway was initialized - assert.isTrue(await l2TokensGateway.isInitialized()); - - // grant WITHDRAWALS_ENABLER_ROLE to the l1Deployer to enable deposits - await l2TokensGateway.grantRole( - await l2TokensGateway.WITHDRAWALS_ENABLER_ROLE(), - deployer.address - ); - - // enable deposits - await l2TokensGateway.enableWithdrawals(); - - // validate deposits was enabled - assert.isTrue(await l2TokensGateway.isWithdrawalsEnabled()); - - await assert.revertsWith( - l2TokensGateway - .connect(sender) - .outboundTransfer( - wrongAddress.address, - recipient.address, - amount, - maxGas, - gasPriceBid, - data - ), - "ErrorUnsupportedL1Token()" - ); - }) - - .test("outboundTransfer() :: extra data not empty", async (ctx) => { - const { - l2TokensGateway, - stubs: { l1Token }, - accounts: { deployer }, - } = ctx; - - // initialize gateway - await l2TokensGateway.initialize(deployer.address); - - // validate gateway was initialized - assert.isTrue(await l2TokensGateway.isInitialized()); - - // grant WITHDRAWALS_ENABLER_ROLE to the l1Deployer to enable deposits - await l2TokensGateway.grantRole( - await l2TokensGateway.WITHDRAWALS_ENABLER_ROLE(), - deployer.address - ); - - // enable deposits - await l2TokensGateway.enableWithdrawals(); - - // validate deposits was enabled - assert.isTrue(await l2TokensGateway.isWithdrawalsEnabled()); - - const [sender, recipient] = await hre.ethers.getSigners(); - const amount = wei`1.2 ether`; - const maxGas = wei`1000 gwei`; - const gasPriceBid = wei`2000 gwei`; - const data = "0xdeadbeaf"; - - // initiate outbound transfer - await assert.revertsWith( - l2TokensGateway - .connect(sender) - .outboundTransfer( - l1Token.address, - recipient.address, - amount, - maxGas, - gasPriceBid, - data - ), - "ExtraDataNotEmpty()" - ); - }) - - .test("outboundTransfer() :: called by router", async (ctx) => { - const { - l2TokensGateway, - stubs: { l1Token, arbSys, l1TokensGateway }, - accounts: { deployer, l2RouterAsEOA }, - } = ctx; - - // initialize gateway - await l2TokensGateway.initialize(deployer.address); - - // validate gateway was initialized - assert.isTrue(await l2TokensGateway.isInitialized()); - - // grant WITHDRAWALS_ENABLER_ROLE to the l1Deployer to enable deposits - await l2TokensGateway.grantRole( - await l2TokensGateway.WITHDRAWALS_ENABLER_ROLE(), - deployer.address - ); - - // enable deposits - await l2TokensGateway.enableWithdrawals(); - - // validate deposits was enabled - assert.isTrue(await l2TokensGateway.isWithdrawalsEnabled()); - - const l2ToL1Id = 10; - - // set l2ToL1Id value in ArbSysStub - await arbSys.setl2ToL1TxId(l2ToL1Id); - - // validate value was set - assert.equalBN(await arbSys.l2ToL1TxId(), l2ToL1Id); - - const [sender, recipient] = await hre.ethers.getSigners(); - const amount = wei`1.2 ether`; - const maxGas = wei`1000 gwei`; - const gasPriceBid = wei`2000 gwei`; - const data = hre.ethers.utils.defaultAbiCoder.encode( - ["address", "bytes"], - [sender.address, "0x"] - ); - - // initiate outbound transfer - const tx = await l2TokensGateway - .connect(l2RouterAsEOA) - .outboundTransfer( - l1Token.address, - recipient.address, - amount, - maxGas, - gasPriceBid, - data - ); - - const expectedCalldata = - ctx.stubs.l1TokensGateway.interface.encodeFunctionData( - "finalizeInboundTransfer", - [l1Token.address, sender.address, recipient.address, amount, "0x"] - ); - - // validate TxToL1 event was emitted - await assert.emits(l2TokensGateway, tx, "TxToL1", [ - sender.address, - l1TokensGateway.address, - l2ToL1Id + 1, - expectedCalldata, - ]); - - // validate DepositInitiated event was emitted - await assert.emits(l2TokensGateway, tx, "WithdrawalInitiated", [ - l1Token.address, - sender.address, - recipient.address, - l2ToL1Id + 1, - 0, - amount, - ]); - - // validate CreateL2ToL1Tx event was emitted - await assert.emits(arbSys, tx, "CreateL2ToL1Tx", [ - l1TokensGateway.address, - expectedCalldata, - ]); - }) - - .test("outboundTransfer() :: called by sender", async (ctx) => { - const { - l2TokensGateway, - stubs: { l1Token, arbSys, l1TokensGateway }, - accounts: { deployer }, - } = ctx; - - // initialize gateway - await l2TokensGateway.initialize(deployer.address); - - // validate gateway was initialized - assert.isTrue(await l2TokensGateway.isInitialized()); - - // grant WITHDRAWALS_ENABLER_ROLE to the l1Deployer to enable deposits - await l2TokensGateway.grantRole( - await l2TokensGateway.WITHDRAWALS_ENABLER_ROLE(), - deployer.address - ); - - // enable deposits - await l2TokensGateway.enableWithdrawals(); - - // validate deposits was enabled - assert.isTrue(await l2TokensGateway.isWithdrawalsEnabled()); - - const l2ToL1Id = 10; - - // set l2ToL1Id value in ArbSysStub - await arbSys.setl2ToL1TxId(l2ToL1Id); - - // validate value was set - assert.equalBN(await arbSys.l2ToL1TxId(), l2ToL1Id); - - const [sender, recipient] = await hre.ethers.getSigners(); - const amount = wei`1.2 ether`; - const maxGas = wei`1000 gwei`; - const gasPriceBid = wei`2000 gwei`; - const data = "0x"; - - // call tx locally to check return value - assert.equal( - await l2TokensGateway - .connect(sender) - .callStatic.outboundTransfer( - l1Token.address, - recipient.address, - amount, - maxGas, - gasPriceBid, - data - ), - hre.ethers.utils.defaultAbiCoder.encode(["uint256"], [l2ToL1Id + 1]) - ); - - // initiate outbound transfer - const tx = await l2TokensGateway - .connect(sender) - .outboundTransfer( - l1Token.address, - recipient.address, - amount, - maxGas, - gasPriceBid, - data - ); - - const expectedCalldata = - ctx.stubs.l1TokensGateway.interface.encodeFunctionData( - "finalizeInboundTransfer", - [l1Token.address, sender.address, recipient.address, amount, "0x"] - ); - - // validate TxToL1 event was emitted - await assert.emits(l2TokensGateway, tx, "TxToL1", [ - sender.address, - l1TokensGateway.address, - l2ToL1Id + 1, - expectedCalldata, - ]); - - // validate DepositInitiated event was emitted - await assert.emits(l2TokensGateway, tx, "WithdrawalInitiated", [ - l1Token.address, - sender.address, - recipient.address, - l2ToL1Id + 1, - 0, - amount, - ]); - - // validate CreateL2ToL1Tx event was emitted - await assert.emits(arbSys, tx, "CreateL2ToL1Tx", [ - l1TokensGateway.address, - expectedCalldata, - ]); - }) - - .test("finalizeInboundTransfer() :: deposits disabled", async (ctx) => { - const { - l2TokensGateway, - accounts: { deployer, l1TokensGatewayAliasedEOA, sender, recipient }, - stubs: { l1Token }, - } = ctx; - - // initialize gateway - await l2TokensGateway.initialize(deployer.address); - - // validate gateway was initialized - assert.isTrue(await l2TokensGateway.isInitialized()); - - // validate withdrawals disabled - assert.isFalse(await l2TokensGateway.isWithdrawalsEnabled()); - - await assert.revertsWith( - l2TokensGateway - .connect(l1TokensGatewayAliasedEOA) - .finalizeInboundTransfer( - l1Token.address, - sender.address, - recipient.address, - wei`10 ether`, - "0x" - ), - "ErrorDepositsDisabled()" - ); - }) - - .test("finalizeInboundTransfer() :: wrong token", async (ctx) => { - const { - l2TokensGateway, - accounts: { - stranger, - sender, - recipient, - deployer, - l1TokensGatewayAliasedEOA, - }, - } = ctx; - const wrongTokenAddress = stranger.address; - - // initialize gateway - await l2TokensGateway.initialize(deployer.address); - - // validate gateway was initialized - assert.isTrue(await l2TokensGateway.isInitialized()); - - // grant DEPOSITS_ENABLER_ROLE to the l1Deployer to enable withdrawals - await l2TokensGateway.grantRole( - await l2TokensGateway.DEPOSITS_ENABLER_ROLE(), - deployer.address - ); - - // enable withdrawals - await l2TokensGateway.enableDeposits(); - - // validate withdrawals were enabled - assert.isTrue(await l2TokensGateway.isDepositsEnabled()); - - // validate gateway reverts with error ErrorUnsupportedL1Token() - await assert.revertsWith( - l2TokensGateway - .connect(l1TokensGatewayAliasedEOA) - .finalizeInboundTransfer( - wrongTokenAddress, - sender.address, - recipient.address, - wei`10 ether`, - "0x" - ), - "ErrorUnsupportedL1Token()" - ); - }) - - .test("finalizeInboundTransfer() :: not counterpart gateway", async (ctx) => { - const { - l2TokensGateway, - accounts: { deployer, stranger, sender, recipient }, - stubs: { l1Token }, - } = ctx; - - // initialize gateway - await l2TokensGateway.initialize(deployer.address); - - // validate gateway was initialized - assert.isTrue(await l2TokensGateway.isInitialized()); - - // grant DEPOSITS_ENABLER_ROLE to the l1Deployer to enable withdrawals - await l2TokensGateway.grantRole( - await l2TokensGateway.DEPOSITS_ENABLER_ROLE(), - deployer.address - ); - - // enable withdrawals - await l2TokensGateway.enableDeposits(); - - // validate withdrawals were enabled - assert.isTrue(await l2TokensGateway.isDepositsEnabled()); - - // validate that stranger address is not counterpartGateway - assert.notEqual( - await l2TokensGateway.counterpartGateway(), - stranger.address - ); - - // validate gateway reverts with error ErrorWrongCrossDomainSender() - await assert.revertsWith( - l2TokensGateway - .connect(stranger) - .finalizeInboundTransfer( - l1Token.address, - sender.address, - recipient.address, - wei`10 ether`, - "0x" - ), - "ErrorWrongCrossDomainSender()" - ); - }) - - .test("finalizeInboundTransfer() :: works as expected", async (ctx) => { - const { - l2TokensGateway, - accounts: { sender, recipient, deployer, l1TokensGatewayAliasedEOA }, - stubs: { l1Token, l2Token }, - } = ctx; - - // initialize gateway - await l2TokensGateway.initialize(deployer.address); - - // validate gateway was initialized - assert.isTrue(await l2TokensGateway.isInitialized()); - - // grant WITHDRAWALS_ENABLER_ROLE to the l1Deployer to enable withdrawals - await l2TokensGateway.grantRole( - await l2TokensGateway.DEPOSITS_ENABLER_ROLE(), - deployer.address - ); - - // enable withdrawals - await l2TokensGateway.enableDeposits(); - - // validate withdrawals were enabled - assert.isTrue(await l2TokensGateway.isDepositsEnabled()); - - // transfer l2Tokens to l2TokensGateway - const initialL2GatewayBalance = wei`10_000 ether`; - await l2Token.transfer(l2TokensGateway.address, initialL2GatewayBalance); - - // validate l1TokensGateway has enough amount of tokens - assert.equal( - await l2Token.balanceOf(l2TokensGateway.address).then(wei.fromBigNumber), - initialL2GatewayBalance - ); - - const amount = wei`10 ether`; - - const tx = await l2TokensGateway - .connect(l1TokensGatewayAliasedEOA) - .finalizeInboundTransfer( - l1Token.address, - sender.address, - recipient.address, - wei`10 ether`, - "0x" - ); - - // validate DepositFinalized was emitted - await assert.emits(l2TokensGateway, tx, "DepositFinalized", [ - l1Token.address, - sender.address, - recipient.address, - amount, - ]); - - // validate tokens were minted to recipient - assert.equalBN(await l2Token.balanceOf(recipient.address), amount); - }) - - .run(); - -async function ctxFactory() { - const [deployer, stranger, sender, recipient] = await hre.ethers.getSigners(); - const l2RouterStub = await new EmptyContractStub__factory(deployer).deploy({ - value: wei.toBigNumber(wei`1 ether`), - }); - const l1TokensGatewayStub = await new EmptyContractStub__factory( - deployer - ).deploy({ value: wei.toBigNumber(wei`1 ether`) }); - await hre.network.provider.request({ - method: "hardhat_impersonateAccount", - params: [l1TokensGatewayStub.address], - }); - const l2TokenStub = await new ERC20BridgedStub__factory(deployer).deploy( - "L2Token stub", - "L2ERC20" - ); - const l1TokenStub = await new ERC20BridgedStub__factory(deployer).deploy( - "ERC20 Mock", - "ERC20" - ); - - const arbSysStub = await new ArbSysStub__factory(deployer).deploy(); - const l2TokensGatewayImpl = await new L2ERC20TokenGateway__factory( - deployer - ).deploy( - arbSysStub.address, // the default address of the - l2RouterStub.address, - l1TokensGatewayStub.address, - l1TokenStub.address, - l2TokenStub.address - ); - const l2TokensGatewayProxy = await new OssifiableProxy__factory( - deployer - ).deploy(l2TokensGatewayImpl.address, deployer.address, "0x"); - - const l1TokensGatewayAliasedEOAAddress = testing.accounts.applyL1ToL2Alias( - l1TokensGatewayStub.address - ); - - await hre.network.provider.request({ - method: "hardhat_impersonateAccount", - params: [l1TokensGatewayAliasedEOAAddress], - }); - - const l1TokensGatewayAliasedEOA = await hre.ethers.getSigner( - l1TokensGatewayAliasedEOAAddress - ); - - await testing.setBalance( - l1TokensGatewayAliasedEOA.address, - wei.toBigNumber(wei`1 ether`) - ); - - await hre.network.provider.request({ - method: "hardhat_impersonateAccount", - params: [l2RouterStub.address], - }); - const l2RouterAsEOA = await hre.ethers.getSigner(l2RouterStub.address); - - return { - accounts: { - deployer, - stranger, - sender, - recipient, - l2RouterAsEOA, - l1TokensGatewayEOA: await ethers.getSigner(l1TokensGatewayStub.address), - l1TokensGatewayAliasedEOA, - }, - stubs: { - arbSys: arbSysStub, - l1Token: l1TokenStub, - l2Token: l2TokenStub, - l2Router: l2RouterStub, - l1TokensGateway: L1ERC20TokenGateway__factory.connect( - l1TokensGatewayStub.address, - deployer - ), - }, - l2TokensGateway: L2ERC20TokenGateway__factory.connect( - l2TokensGatewayProxy.address, - deployer - ), - }; -} - -function encodeOutboundTransferData(maxSubmissionCost: string) { - return hre.ethers.utils.defaultAbiCoder.encode( - ["uint256", "bytes"], - [maxSubmissionCost, "0x"] - ); -} diff --git a/test/arbitrum/_launch.test.ts b/test/arbitrum/_launch.test.ts deleted file mode 100644 index e5711360..00000000 --- a/test/arbitrum/_launch.test.ts +++ /dev/null @@ -1,89 +0,0 @@ -import { assert } from "chai"; - -import env from "../../utils/env"; -import arbitrum from "../../utils/arbitrum"; -import { L1ERC20TokenBridge__factory } from "../../typechain"; -import { wei } from "../../utils/wei"; -import testing, { scenario } from "../../utils/testing"; -import { BridgingManagerRole } from "../../utils/bridging-management"; - -const REVERT = env.bool("REVERT", true); - -scenario("Arbitrum :: Launch integration test", ctx) - .after(async (ctx) => { - if (REVERT) { - await ctx.l1Provider.send("evm_revert", [ctx.snapshot.l1]); - await ctx.l2Provider.send("evm_revert", [ctx.snapshot.l2]); - } else { - console.warn( - "Revert is skipped! Forked node restart might be required for repeated launches!" - ); - } - }) - - .step("Enable deposits", async (ctx) => { - const { l1ERC20TokenGateway } = ctx; - assert.isFalse(await l1ERC20TokenGateway.isDepositsEnabled()); - - await l1ERC20TokenGateway.enableDeposits(); - assert.isTrue(await l1ERC20TokenGateway.isDepositsEnabled()); - }) - - .step("Renounce role", async (ctx) => { - const { l1ERC20TokenGateway, l1DevMultisig } = ctx; - assert.isTrue( - await l1ERC20TokenGateway.hasRole( - BridgingManagerRole.DEPOSITS_ENABLER_ROLE.hash, - await l1DevMultisig.getAddress() - ) - ); - - await l1ERC20TokenGateway.renounceRole( - BridgingManagerRole.DEPOSITS_ENABLER_ROLE.hash, - await l1DevMultisig.getAddress() - ); - assert.isFalse( - await l1ERC20TokenGateway.hasRole( - BridgingManagerRole.DEPOSITS_ENABLER_ROLE.hash, - await l1DevMultisig.getAddress() - ) - ); - }) - - .run(); - -async function ctx() { - const networkName = env.network("TESTING_ARB_NETWORK", "mainnet"); - const { l1Provider, l2Provider, l1ERC20TokenGateway } = await arbitrum - .testing(networkName) - .getIntegrationTestSetup(); - - const hasDeployedContracts = testing.env.USE_DEPLOYED_CONTRACTS(false); - const l1DevMultisig = hasDeployedContracts - ? await testing.impersonate(testing.env.L1_DEV_MULTISIG(), l1Provider) - : testing.accounts.deployer(l1Provider); - - const l1Snapshot = await l1Provider.send("evm_snapshot", []); - const l2Snapshot = await l2Provider.send("evm_snapshot", []); - - await testing.setBalance( - await l1DevMultisig.getAddress(), - wei.toBigNumber(wei`1 ether`) - ); - - const l1ERC20TokenGatewayImpl = L1ERC20TokenBridge__factory.connect( - l1ERC20TokenGateway.address, - l1DevMultisig - ); - - return { - l1Provider, - l2Provider, - l1DevMultisig, - l1ERC20TokenGateway: l1ERC20TokenGatewayImpl, - snapshot: { - l1: l1Snapshot, - l2: l2Snapshot, - }, - }; -} diff --git a/test/arbitrum/bridging-native.e2e.test.ts b/test/arbitrum/bridging-native.e2e.test.ts deleted file mode 100644 index 6e56499b..00000000 --- a/test/arbitrum/bridging-native.e2e.test.ts +++ /dev/null @@ -1,205 +0,0 @@ -import { assert } from "chai"; -import { ERC20Mintable } from "../../typechain"; -import env from "../../utils/env"; -import { wei } from "../../utils/wei"; -import { - getL2Network, - L1ToL2MessageStatus, - L1TransactionReceipt, -} from "@arbitrum/sdk"; -import { scenario } from "../../utils/testing"; -import arbitrum from "../../utils/arbitrum"; -import { ethers } from "hardhat"; - -async function ctxFactory() { - const networkName = env.network("TESTING_ARB_NETWORK", "sepolia"); - const testingSetup = await arbitrum.testing(networkName).getE2ETestSetup(); - - const l2Network = await getL2Network(testingSetup.l2Provider); - - // replace gateway router addresses with test - l2Network.tokenBridge.l1GatewayRouter = testingSetup.l1GatewayRouter.address; - l2Network.tokenBridge.l2GatewayRouter = testingSetup.l2GatewayRouter.address; - - return { - ...testingSetup, - messaging: arbitrum.messaging(networkName, { - forking: false, - customAddresses: { - L1GatewayRouter: testingSetup.l1GatewayRouter.address, - L2GatewayRouter: testingSetup.l2GatewayRouter.address, - }, - }), - l2Network, - depositAmount: wei`0.025 ether`, - withdrawalAmount: wei`0.025 ether`, - }; -} - -scenario("Arbitrum :: Bridging E2E test natively", ctxFactory) - .step("Validate tester has required amount of L1 token", async (ctx) => { - const { l1Token, l1Tester, depositAmount } = ctx; - const balanceBefore = await l1Token.balanceOf(l1Tester.address); - if (balanceBefore.lt(depositAmount)) { - try { - await (l1Token as ERC20Mintable).mint(l1Tester.address, depositAmount); - } catch {} - } - const balanceAfter = await l1Token.balanceOf(l1Tester.address); - assert.isTrue( - balanceAfter.gte(depositAmount), - "Tester has not enough L1 token" - ); - }) - - .step("Set allowance for L1ERC20TokenGateway to deposit", async (ctx) => { - const { l1Tester, l1Token, depositAmount, l1ERC20TokenGateway } = ctx; - - const allowanceTxResponse = await l1Token - .connect(l1Tester) - .approve(l1ERC20TokenGateway.address, wei.toBigNumber(depositAmount)); - - await allowanceTxResponse.wait(); - - assert.equalBN( - await l1Token.allowance(l1Tester.address, l1ERC20TokenGateway.address), - depositAmount - ); - }) - - .step("Deposit tokens to L2 via L1ERC20Gateway", async (ctx) => { - const { - l1Tester, - l1Token, - l2Tester, - l2Token, - depositAmount, - l1ERC20TokenGateway, - l2ERC20TokenGateway, - } = ctx; - const l1ERC20TokenGatewayBalanceBefore = await l1Token.balanceOf( - ctx.l1ERC20TokenGateway.address - ); - const testerL1TokenBalanceBefore = await l1Token.balanceOf( - l1Tester.address - ); - const testerL2TokenBalanceBefore = await l2Token.balanceOf( - l2Tester.address - ); - - // To estimate params required for L1 -> L2 retryable ticket creation - // we need to know which message will be send on L2 - const finalizeInboundTransferCalldata = - await l1ERC20TokenGateway.getOutboundCalldata( - l1Token.address, - l1Tester.address, - l1Tester.address, - wei.toBigNumber(depositAmount), - "0x" - ); - - const { callvalue, gasPriceBid, maxGas, maxSubmissionCost } = - await ctx.messaging.getRetryableTicketSendParams({ - callvalue: 0, - sender: l1ERC20TokenGateway.address, - recipient: l2ERC20TokenGateway.address, - calldata: finalizeInboundTransferCalldata, - refundAddress: l2Tester.address, - }); - - const maxSubmissionCostEncoded = ethers.utils.defaultAbiCoder.encode( - ["uint256", "bytes"], - [maxSubmissionCost, "0x"] - ); - - const depositTxResponse = await l1ERC20TokenGateway - .connect(l1Tester) - .outboundTransfer( - l1Token.address, - l1Tester.address, - depositAmount, - maxGas, - gasPriceBid, - maxSubmissionCostEncoded, - { value: callvalue } - ); - - const depositL1Receipt = await depositTxResponse.wait(); - - assert.equalBN( - await l1Token.balanceOf(l1Tester.address), - testerL1TokenBalanceBefore.sub(depositAmount) - ); - - assert.equalBN( - await l1Token.balanceOf(ctx.l1ERC20TokenGateway.address), - l1ERC20TokenGatewayBalanceBefore.add(depositAmount) - ); - - const l1TxReceipt = new L1TransactionReceipt(depositL1Receipt); - - const [message] = await l1TxReceipt.getL1ToL2Messages(l2Tester); - - const { status } = await message.waitForStatus(); - - if (status === L1ToL2MessageStatus.FUNDS_DEPOSITED_ON_L2) { - console.warn( - `Auto redeem for tx ${l1TxReceipt.transactionHash} failed. Redeeming it manually...` - ); - const redeemResponse = await message.redeem({ gasLimit: 300_000 }); - await redeemResponse.wait(); - console.log("Tx was redeemed"); - } else if (status === L1ToL2MessageStatus.REDEEMED) { - console.log("Tx was auto redeemed"); - } else { - assert.isTrue( - false, - `L2 retryable txn failed with status ${L1ToL2MessageStatus[status]}` - ); - } - - assert.equalBN( - await l2Token.balanceOf(l2Tester.address), - testerL2TokenBalanceBefore.add(depositAmount) - ); - }) - - .step("Withdraw tokens from L2 via L2ERC20Gateway", async (ctx) => { - const { - l2Token, - l1Tester, - l2Tester, - l1Token, - withdrawalAmount, - l2ERC20TokenGateway, - } = ctx; - - const testerL2TokenBalanceBefore = await l2Token.balanceOf( - l2Tester.address - ); - - const withdrawTxResponse = await l2ERC20TokenGateway.outboundTransfer( - l1Token.address, - l1Tester.address, - withdrawalAmount, - wei`0`, - wei`0`, - "0x" - ); - - const withdrawRec = await withdrawTxResponse.wait(); - - console.log(`Token withdrawal initiated: ${withdrawRec.transactionHash}`); - - assert.equalBN( - await l2Token.balanceOf(l2Tester.address), - testerL2TokenBalanceBefore.sub(withdrawalAmount) - ); - }) - - .step( - "L2 -> L1 transactions takes much time and must be redeemed manually", - async () => {} - ) - - .run(); diff --git a/test/arbitrum/bridging-router.e2e.test.ts b/test/arbitrum/bridging-router.e2e.test.ts deleted file mode 100644 index fc7fcc76..00000000 --- a/test/arbitrum/bridging-router.e2e.test.ts +++ /dev/null @@ -1,145 +0,0 @@ -import { assert } from "chai"; -import { ERC20Mintable } from "../../typechain"; -import env from "../../utils/env"; -import { wei } from "../../utils/wei"; -import { Erc20Bridger, getL2Network, L1ToL2MessageStatus } from "@arbitrum/sdk"; -import { scenario } from "../../utils/testing"; -import arbitrum from "../../utils/arbitrum"; - -async function ctxFactory() { - const networkName = env.network("TESTING_ARB_NETWORK", "sepolia"); - const testingSetup = await arbitrum.testing(networkName).getE2ETestSetup(); - - const l2Network = await getL2Network(testingSetup.l2Provider); - - // replace gateway router addresses with test - l2Network.tokenBridge.l1GatewayRouter = testingSetup.l1GatewayRouter.address; - l2Network.tokenBridge.l2GatewayRouter = testingSetup.l2GatewayRouter.address; - - return { - ...testingSetup, - l2Network, - erc20Bridge: new Erc20Bridger(l2Network), - depositAmount: wei`0.025 ether`, - withdrawalAmount: wei`0.025 ether`, - }; -} - -scenario("Arbitrum :: Bridging E2E test via router", ctxFactory) - .step( - "Check test environment is set correctly", - async ({ erc20Bridge, l1Token, ...ctx }) => { - assert.equal( - await erc20Bridge.getL1GatewayAddress(l1Token.address, ctx.l1Provider), - ctx.l1ERC20TokenGateway.address - ); - assert.equal( - await erc20Bridge.getL2GatewayAddress(l1Token.address, ctx.l2Provider), - ctx.l2ERC20TokenGateway.address - ); - } - ) - - .step("Validate tester has required amount of L1 token", async (ctx) => { - const { l1Token, l1Tester, depositAmount } = ctx; - const balanceBefore = await l1Token.balanceOf(l1Tester.address); - if (balanceBefore.lt(depositAmount)) { - try { - await (l1Token as ERC20Mintable).mint(l1Tester.address, depositAmount); - } catch {} - } - const balanceAfter = await l1Token.balanceOf(l1Tester.address); - assert.isTrue( - balanceAfter.gte(depositAmount), - "Tester has not enough L1 token" - ); - }) - - .step("Set allowance for L1ERC20TokenGateway to deposit", async (ctx) => { - const { l1Tester, l1Token, depositAmount, l1ERC20TokenGateway } = ctx; - - const allowanceTxResponse = await ctx.erc20Bridge.approveToken({ - l1Signer: l1Tester, - erc20L1Address: l1Token.address, - amount: wei.toBigNumber(depositAmount), - }); - - await allowanceTxResponse.wait(); - - assert.equalBN( - await l1Token.allowance(l1Tester.address, l1ERC20TokenGateway.address), - depositAmount - ); - }) - - .step("Deposit tokens to L2 via L1GatewayRouter", async (ctx) => { - const { l1Tester, l1Token, l2Tester, l2Token, depositAmount } = ctx; - const l1ERC20TokenGatewayBalanceBefore = await l1Token.balanceOf( - ctx.l1ERC20TokenGateway.address - ); - const testerL1TokenBalanceBefore = await l1Token.balanceOf( - l1Tester.address - ); - const testerL2TokenBalanceBefore = await l2Token.balanceOf( - l2Tester.address - ); - - const depositTxResponse = await ctx.erc20Bridge.deposit({ - amount: wei.toBigNumber(depositAmount), - erc20L1Address: l1Token.address, - l1Signer: l1Tester, - l2Provider: ctx.l2Provider, - }); - - const depositL1Receipt = await depositTxResponse.wait(); - - assert.equalBN( - await l1Token.balanceOf(l1Tester.address), - testerL1TokenBalanceBefore.sub(depositAmount) - ); - - assert.equalBN( - await l1Token.balanceOf(ctx.l1ERC20TokenGateway.address), - l1ERC20TokenGatewayBalanceBefore.add(depositAmount) - ); - - const l2Result = await depositL1Receipt.waitForL2(l2Tester.provider); - - assert.isTrue( - l2Result.complete, - `L2 message failed: status ${L1ToL2MessageStatus[l2Result.status]}` - ); - - assert.equalBN( - await l2Token.balanceOf(l2Tester.address), - testerL2TokenBalanceBefore.add(depositAmount) - ); - }) - - .step("Withdraw tokens from L2 via L2GatewayRouter", async (ctx) => { - const { l2Token, l2Tester, l1Token, erc20Bridge, withdrawalAmount } = ctx; - const testerL2TokenBalanceBefore = await l2Token.balanceOf( - l2Tester.address - ); - - const withdrawTxResponse = await erc20Bridge.withdraw({ - l2Signer: l2Tester, - erc20l1Address: l1Token.address, - destinationAddress: l2Tester.address, - amount: wei.toBigNumber(withdrawalAmount), - }); - const withdrawRec = await withdrawTxResponse.wait(); - console.log(`Token withdrawal initiated: ${withdrawRec.transactionHash}`); - - assert.equalBN( - await l2Token.balanceOf(l2Tester.address), - testerL2TokenBalanceBefore.sub(withdrawalAmount) - ); - }) - - .step( - "L2 -> L1 transactions takes much time and must be redeemed manually", - async () => {} - ) - - .run(); diff --git a/test/arbitrum/bridging.integration.test.ts b/test/arbitrum/bridging.integration.test.ts deleted file mode 100644 index 00dab003..00000000 --- a/test/arbitrum/bridging.integration.test.ts +++ /dev/null @@ -1,504 +0,0 @@ -import { assert } from "chai"; -import { ethers } from "hardhat"; - -import env from "../../utils/env"; -import { wei } from "../../utils/wei"; -import arbitrum from "../../utils/arbitrum"; -import arbitrumAddresses from "../../utils/arbitrum/addresses"; -import testing, { scenario } from "../../utils/testing"; -import { - OutboxStub__factory, - BridgeStub__factory, - IMessageProvider__factory, -} from "../../typechain"; - -scenario("Arbitrum :: Bridging integration test", ctx) - .after(async (ctx) => { - await ctx.l1Provider.send("evm_revert", [ctx.snapshot.l1]); - await ctx.l2Provider.send("evm_revert", [ctx.snapshot.l2]); - }) - - .step("Activate Bridging on L1", async (ctx) => { - const { l1ERC20TokenGateway } = ctx; - const { l1BridgeAdmin } = ctx.accounts; - - const isDepositsEnabled = await l1ERC20TokenGateway.isDepositsEnabled(); - - if (!isDepositsEnabled) { - await l1ERC20TokenGateway.connect(l1BridgeAdmin).enableDeposits(); - } else { - console.log("L1 deposits already enabled"); - } - - const isWithdrawalsEnabled = - await l1ERC20TokenGateway.isWithdrawalsEnabled(); - - if (!isWithdrawalsEnabled) { - await l1ERC20TokenGateway.connect(l1BridgeAdmin).enableWithdrawals(); - } else { - console.log("L1 withdrawals already enabled"); - } - - assert.isTrue(await l1ERC20TokenGateway.isDepositsEnabled()); - assert.isTrue(await l1ERC20TokenGateway.isWithdrawalsEnabled()); - }) - - .step("Activate Bridging on L2", async (ctx) => { - const { l2ERC20TokenGateway } = ctx; - const { l2BridgeAdmin } = ctx.accounts; - - const isDepositsEnabled = await l2ERC20TokenGateway.isDepositsEnabled(); - - if (!isDepositsEnabled) { - await l2ERC20TokenGateway.connect(l2BridgeAdmin).enableDeposits(); - } else { - console.log("L2 deposits already enabled"); - } - - const isWithdrawalsEnabled = - await l2ERC20TokenGateway.isWithdrawalsEnabled(); - - if (!isWithdrawalsEnabled) { - await l2ERC20TokenGateway.connect(l2BridgeAdmin).enableWithdrawals(); - } else { - console.log("L2 withdrawals already enabled"); - } - - assert.isTrue(await l2ERC20TokenGateway.isDepositsEnabled()); - assert.isTrue(await l2ERC20TokenGateway.isWithdrawalsEnabled()); - }) - - .step( - "Set L1ERC20TokenGateway for new token in L1GatewayRouter", - async (ctx) => { - const { l1ERC20TokenGateway, l1Token, l1GatewayRouter } = ctx; - const { l1GatewayRouterAdmin } = ctx.accounts; - const { maxGas, gasPriceBid, maxSubmissionCost, callValue } = - ctx.constants; - - await l1GatewayRouter - .connect(l1GatewayRouterAdmin) - .setGateways( - [l1Token.address], - [l1ERC20TokenGateway.address], - maxGas, - gasPriceBid, - maxSubmissionCost, - { value: callValue } - ); - - assert.equal( - await l1GatewayRouter.getGateway(l1Token.address), - l1ERC20TokenGateway.address - ); - } - ) - - .step( - "Set L2ERC20TokenGateway for new token in L2GatewayRouter", - async (ctx) => { - const { l1Token, l2GatewayRouter, l2ERC20TokenGateway } = ctx; - const { l1GatewayRouterAliased } = ctx.accounts; - - await l2GatewayRouter - .connect(l1GatewayRouterAliased) - .setGateway([l1Token.address], [l2ERC20TokenGateway.address]); - - assert.equal( - await l2GatewayRouter.getGateway(l1Token.address), - l2ERC20TokenGateway.address - ); - } - ) - - .step("L1 -> L2 deposit via L1GatewayRouter", async (ctx) => { - const { accountA, accountB } = ctx.accounts; - const { l1Token, l1ERC20TokenGateway } = ctx; - const { - depositAmount, - outbdoundTransferData, - maxGas, - gasPriceBid, - callValue, - } = ctx.constants; - - await l1Token - .connect(accountA.l1Signer) - .approve(l1ERC20TokenGateway.address, depositAmount); - - const accountABalanceBefore = await l1Token.balanceOf(accountA.address); - const l1ERC20TokenGatewayBalanceBefore = await l1Token.balanceOf( - l1ERC20TokenGateway.address - ); - - const tx = await ctx.l1GatewayRouter - .connect(accountA.l1Signer) - .outboundTransfer( - l1Token.address, - accountB.address, - depositAmount, - maxGas, - gasPriceBid, - outbdoundTransferData, - { value: callValue } - ); - - const receipt = await tx.wait(); - - const messageProviderInterface = - IMessageProvider__factory.createInterface(); - const inboxMessageDeliveredTopic = messageProviderInterface.getEventTopic( - "InboxMessageDelivered" - ); - const messageDeliveredLog = receipt.logs.find( - (l) => l.topics[0] === inboxMessageDeliveredTopic - ); - if (!messageDeliveredLog) { - throw new Error("InboxMessageDelivered message wasn't fired"); - } - const messageDeliveredEvent = - messageProviderInterface.parseLog(messageDeliveredLog); - - // Validate that message data were passed correctly. - // Inbox contract uses the abi.encodePackedValue(), so it's an overhead - // to parse all data of the event when we only need the last one - assert.isTrue( - messageDeliveredEvent.args.data.endsWith( - ctx.constants.finalizeInboundTransferCalldata.deposit.slice(2) - ) - ); - - assert.equalBN( - await l1Token.balanceOf(accountA.address), - accountABalanceBefore.sub(depositAmount) - ); - - assert.equalBN( - await l1Token.balanceOf(l1ERC20TokenGateway.address), - l1ERC20TokenGatewayBalanceBefore.add(depositAmount) - ); - }) - - .step("Finalize deposit on L2", async (ctx) => { - const { depositAmount } = ctx.constants; - const { l1Token, l2Token, l2ERC20TokenGateway } = ctx; - const { accountA, accountB, l1ERC20TokenGatewayAliased } = ctx.accounts; - - const l2TokenSupplyBefore = await l2Token.totalSupply(); - const accountBBalanceBefore = await l2Token.balanceOf(accountB.address); - - const tx = await l1ERC20TokenGatewayAliased.sendTransaction({ - to: l2ERC20TokenGateway.address, - data: ctx.constants.finalizeInboundTransferCalldata.deposit, - }); - - await assert.emits(l2Token, tx, "Transfer", [ - ethers.constants.AddressZero, - accountB.address, - depositAmount, - ]); - - await assert.emits(l2ERC20TokenGateway, tx, "DepositFinalized", [ - l1Token.address, - accountA.address, - accountB.address, - depositAmount, - ]); - - assert.equalBN( - await l2Token.totalSupply(), - l2TokenSupplyBefore.add(depositAmount) - ); - assert.equalBN( - await l2Token.balanceOf(accountB.address), - accountBBalanceBefore.add(depositAmount) - ); - }) - - .step("L2 -> L1 withdrawal via L2GatewayRouter", async (ctx) => { - const { accountA, accountB } = ctx.accounts; - const { l1Token, arbSys, l2ERC20TokenGateway, l2Token } = ctx; - const { withdrawalAmount } = ctx.constants; - - const l2TokenSupplyBefore = await l2Token.totalSupply(); - const accountBBalanceBefore = await l2Token.balanceOf(accountB.address); - - const prevL2ToL1TxId = await arbSys.l2ToL1TxId(); - const tx = await ctx.l2GatewayRouter - .connect(accountB.l2Signer) - ["outboundTransfer(address,address,uint256,bytes)"]( - l1Token.address, - accountA.address, - withdrawalAmount, - "0x" - ); - - await assert.emits(ctx.l2Token, tx, "Transfer", [ - accountB.address, - ethers.constants.AddressZero, - withdrawalAmount, - ]); - - await assert.emits(arbSys, tx, "CreateL2ToL1Tx", [ - ctx.l1ERC20TokenGateway.address, - ctx.constants.finalizeInboundTransferCalldata.withdraw, - ]); - - await assert.emits(l2ERC20TokenGateway, tx, "WithdrawalInitiated", [ - l1Token.address, - accountB.address, - accountA.address, - prevL2ToL1TxId.add(1), - 0, - withdrawalAmount, - ]); - - assert.equalBN( - await l2Token.totalSupply(), - l2TokenSupplyBefore.sub(withdrawalAmount) - ); - assert.equalBN( - await l2Token.balanceOf(accountB.address), - accountBBalanceBefore.sub(withdrawalAmount) - ); - }) - - .step("Finalize withdrawal on L1", async (ctx) => { - const { accountA, accountB } = ctx.accounts; - const { withdrawalAmount } = ctx.constants; - const { - l1OutboxStub, - l1Provider, - l1Token, - l1ERC20TokenGateway, - l1Bridge, - l1BridgeStub, - } = ctx; - - const accountABalanceBefore = await l1Token.balanceOf(accountA.address); - const l1ERC20TokenGatewayBalanceBefore = await l1Token.balanceOf( - l1ERC20TokenGateway.address - ); - - const [bridgeCodeBefore, bridgeStubCode] = await Promise.all([ - l1Provider.send("eth_getCode", [l1Bridge.address]), - l1Provider.send("eth_getCode", [l1BridgeStub.address]), - ]); - - await l1Provider.send("hardhat_setCode", [ - l1Bridge.address, - bridgeStubCode, - ]); - const bridgeCodeAfter = await l1Provider.send("eth_getCode", [ - l1Bridge.address, - ]); - - const l1BridgeEOA = await testing.impersonate(l1Bridge.address, l1Provider); - - await l1Bridge.setOutbox(l1OutboxStub.address); - - assert.equal(bridgeStubCode, bridgeCodeAfter); - assert.notEqual(bridgeCodeBefore, bridgeCodeAfter); - - const tx = await l1BridgeEOA.sendTransaction({ - to: l1ERC20TokenGateway.address, - data: ctx.constants.finalizeInboundTransferCalldata.withdraw, - }); - - await tx.wait(); - - await assert.emits(l1ERC20TokenGateway, tx, "WithdrawalFinalized", [ - l1Token.address, - accountB.address, - accountA.address, - 0, - withdrawalAmount, - ]); - - assert.equalBN( - accountABalanceBefore.add(withdrawalAmount), - await l1Token.balanceOf(accountA.address) - ); - - assert.equalBN( - l1ERC20TokenGatewayBalanceBefore.sub(withdrawalAmount), - await l1Token.balanceOf(l1ERC20TokenGateway.address) - ); - }) - - .run(); - -async function ctx() { - const networkName = env.network("TESTING_ARB_NETWORK", "mainnet"); - const { - l1Provider, - l2Provider, - l1ERC20TokenGatewayAdmin, - l2ERC20TokenGatewayAdmin, - ...contracts - } = await arbitrum.testing(networkName).getIntegrationTestSetup(); - - const l1Snapshot = await l1Provider.send("evm_snapshot", []); - const l2Snapshot = await l2Provider.send("evm_snapshot", []); - - // by default arbSys contract doesn't exist on the hardhat fork - // so we have to deploy there a stub contract - await arbitrum.testing(networkName).stubArbSysContract(); - - const accountA = testing.accounts.accountA(l1Provider, l2Provider); - const accountB = testing.accounts.accountB(l1Provider, l2Provider); - - const l1TokensHolderAddress = await contracts.l1TokensHolder.getAddress(); - - await testing.setBalance( - l1TokensHolderAddress, - wei.toBigNumber(wei`1 ether`), - l1Provider - ); - - const depositAmount = wei`0.15 ether`; - const withdrawalAmount = wei`0.05 ether`; - - await contracts.l1Token - .connect(contracts.l1TokensHolder) - .transfer(accountA.address, depositAmount); - - const l1ERC20TokenGatewayAliased = await testing.impersonate( - testing.accounts.applyL1ToL2Alias(contracts.l1ERC20TokenGateway.address), - l2Provider - ); - - const l1GatewayRouterAliased = await testing.impersonate( - testing.accounts.applyL1ToL2Alias(contracts.l1GatewayRouter.address), - l2Provider - ); - - await testing.setBalance( - await contracts.l1TokensHolder.getAddress(), - wei.toBigNumber(wei`1 ether`), - l1Provider - ); - - await testing.setBalance( - await l1ERC20TokenGatewayAdmin.getAddress(), - wei.toBigNumber(wei`1 ether`), - l1Provider - ); - - await testing.setBalance( - await l2ERC20TokenGatewayAdmin.getAddress(), - wei.toBigNumber(wei`1 ether`), - l2Provider - ); - - // send ether to l1GatewayRouterAliased to run transactions from it - // as from EOA - await testing.setBalance( - await l1GatewayRouterAliased.getAddress(), - wei.toBigNumber(wei`1 ether`), - l2Provider - ); - - // send ether to l1ERC20TokenGatewayAliased to run transactions from it - // as from EOA - - await testing.setBalance( - await l1ERC20TokenGatewayAliased.getAddress(), - wei.toBigNumber(wei`1 ether`), - l2Provider - ); - - const maxSubmissionCost = wei`200_000 gwei`; - - const l1GatewayRouterAdminAddress = await contracts.l1GatewayRouter.owner(); - - const l1GatewayRouterAdmin = await testing.impersonate( - l1GatewayRouterAdminAddress, - l1Provider - ); - - await testing.setBalance( - l1GatewayRouterAdminAddress, - wei.toBigNumber(wei`1 ether`), - l1Provider - ); - - const l1OutboxStub = await new OutboxStub__factory( - accountA.l1Signer - ).deploy(); - - await l1OutboxStub.setL2ToL1Sender(contracts.l2ERC20TokenGateway.address); - - const l1BridgeStub = await new BridgeStub__factory(accountA.l1Signer).deploy( - l1OutboxStub.address - ); - - const { Bridge: l1BridgeAddress } = arbitrumAddresses(networkName); - const l1Bridge = BridgeStub__factory.connect( - l1BridgeAddress, - accountA.l1Signer - ); - - return { - l1Provider, - l2Provider, - l1Bridge, - l1BridgeStub, - l1OutboxStub, - l1Token: contracts.l1Token, - l2Token: contracts.l2Token, - l2GatewayRouter: contracts.l2GatewayRouter, - l2ERC20TokenGateway: contracts.l2ERC20TokenGateway, - arbSys: contracts.arbSysStub, - l1GatewayRouter: contracts.l1GatewayRouter, - l1ERC20TokenGateway: contracts.l1ERC20TokenGateway, - accounts: { - accountA, - accountB, - l1BridgeAdmin: l1ERC20TokenGatewayAdmin, - l1GatewayRouterAdmin, - l2BridgeAdmin: l2ERC20TokenGatewayAdmin, - l1GatewayRouterAliased, - l1ERC20TokenGatewayAliased, - }, - constants: { - depositAmount, - withdrawalAmount, - maxGas: wei`300_000`, - gasPriceBid: wei`1 gwei`, - callValue: wei`500_000 gwei`, - maxSubmissionCost, - // data for outboundTransfer must contain encoded tuple with (maxSubmissionCost, emptyData) - outbdoundTransferData: ethers.utils.defaultAbiCoder.encode( - ["uint256", "bytes"], - [maxSubmissionCost, "0x"] - ), - finalizeInboundTransferCalldata: { - deposit: contracts.l2ERC20TokenGateway.interface.encodeFunctionData( - "finalizeInboundTransfer", - [ - contracts.l1Token.address, - accountA.address, - accountB.address, - depositAmount, - "0x", - ] - ), - withdraw: contracts.l2ERC20TokenGateway.interface.encodeFunctionData( - "finalizeInboundTransfer", - [ - contracts.l1Token.address, - accountB.address, - accountA.address, - withdrawalAmount, - "0x", - ] - ), - }, - }, - snapshot: { - l1: l1Snapshot, - l2: l2Snapshot, - }, - }; -} diff --git a/test/arbitrum/deployment.acceptance.test.ts b/test/arbitrum/deployment.acceptance.test.ts deleted file mode 100644 index 6ce0c0e0..00000000 --- a/test/arbitrum/deployment.acceptance.test.ts +++ /dev/null @@ -1,313 +0,0 @@ -import { assert } from "chai"; -import { - IERC20Metadata__factory, - OssifiableProxy__factory, -} from "../../typechain"; -import arbitrum from "../../utils/arbitrum"; -import { BridgingManagerRole } from "../../utils/bridging-management"; -import deployment from "../../utils/deployment"; -import env from "../../utils/env"; -import { getRoleHolders, scenario } from "../../utils/testing"; -import { wei } from "../../utils/wei"; - -scenario("Arbitrum Gateway :: deployment acceptance test", ctxFactory) - .step("L1 Bridge :: proxy admin", async (ctx) => { - assert.equal( - await ctx.l1ERC20TokenGatewayProxy.proxy__getAdmin(), - ctx.deployment.l1.proxyAdmin - ); - }) - - .step("L1 Bridge :: bridge admin", async (ctx) => { - const currentAdmins = await getRoleHolders( - ctx.l1ERC20TokenGateway, - BridgingManagerRole.DEFAULT_ADMIN_ROLE.hash - ); - assert.equal(currentAdmins.size, 1); - assert.isTrue(currentAdmins.has(ctx.deployment.l1.bridgeAdmin)); - - assert.isTrue( - await ctx.l1ERC20TokenGateway.hasRole( - BridgingManagerRole.DEFAULT_ADMIN_ROLE.hash, - ctx.deployment.l1.bridgeAdmin - ) - ); - }) - - .step("L1 bridge :: router", async (ctx) => { - assert.equal(await ctx.l1ERC20TokenGateway.router(), ctx.l1Router.address); - }) - - .step("L1 bridge :: L1 token", async (ctx) => { - assert.equal(await ctx.l1ERC20TokenGateway.l1Token(), ctx.deployment.token); - }) - - .step("L1 bridge :: L2 token", async (ctx) => { - assert.equal( - await ctx.l1ERC20TokenGateway.l2Token(), - ctx.erc20Bridged.address - ); - }) - .step("L1 bridge :: counterpart gateway", async (ctx) => { - assert.equal( - await ctx.l1ERC20TokenGateway.counterpartGateway(), - ctx.l2ERC20TokenGateway.address - ); - }) - .step("L1 Bridge :: is deposits enabled", async (ctx) => { - assert.equal( - await ctx.l1ERC20TokenGateway.isDepositsEnabled(), - ctx.deployment.l1.depositsEnabled - ); - }) - .step("L1 Bridge :: is withdrawals enabled", async (ctx) => { - assert.equal( - await ctx.l1ERC20TokenGateway.isWithdrawalsEnabled(), - ctx.deployment.l1.withdrawalsEnabled - ); - }) - .step("L1 Bridge :: deposits enablers", async (ctx) => { - const actualDepositsEnablers = await getRoleHolders( - ctx.l1ERC20TokenGateway, - BridgingManagerRole.DEPOSITS_ENABLER_ROLE.hash - ); - const expectedDepositsEnablers = ctx.deployment.l1.depositsEnablers || []; - - assert.equal(actualDepositsEnablers.size, expectedDepositsEnablers.length); - for (const expectedDepositsEnabler of expectedDepositsEnablers) { - assert.isTrue(actualDepositsEnablers.has(expectedDepositsEnabler)); - } - }) - .step("L1 Bridge :: deposits disablers", async (ctx) => { - const actualDepositsDisablers = await getRoleHolders( - ctx.l1ERC20TokenGateway, - BridgingManagerRole.DEPOSITS_DISABLER_ROLE.hash - ); - const expectedDepositsDisablers = ctx.deployment.l1.depositsDisablers || []; - - assert.equal( - actualDepositsDisablers.size, - expectedDepositsDisablers.length - ); - for (const expectedDepositsDisabler of expectedDepositsDisablers) { - assert.isTrue(actualDepositsDisablers.has(expectedDepositsDisabler)); - } - }) - .step("L1 Bridge :: withdrawals enablers", async (ctx) => { - const actualWithdrawalsEnablers = await getRoleHolders( - ctx.l1ERC20TokenGateway, - BridgingManagerRole.WITHDRAWALS_ENABLER_ROLE.hash - ); - const expectedWithdrawalsEnablers = - ctx.deployment.l1.withdrawalsEnablers || []; - - assert.equal( - actualWithdrawalsEnablers.size, - expectedWithdrawalsEnablers.length - ); - for (const expectedWithdrawalsEnabler of expectedWithdrawalsEnablers) { - assert.isTrue(actualWithdrawalsEnablers.has(expectedWithdrawalsEnabler)); - } - }) - .step("L1 Bridge :: withdrawals disablers", async (ctx) => { - const actualWithdrawalsDisablers = await getRoleHolders( - ctx.l1ERC20TokenGateway, - BridgingManagerRole.WITHDRAWALS_DISABLER_ROLE.hash - ); - const expectedWithdrawalsDisablers = - ctx.deployment.l1.withdrawalsDisablers || []; - - assert.equal( - actualWithdrawalsDisablers.size, - expectedWithdrawalsDisablers.length - ); - for (const expectedWithdrawalsDisabler of expectedWithdrawalsDisablers) { - assert.isTrue( - actualWithdrawalsDisablers.has(expectedWithdrawalsDisabler) - ); - } - }) - - .step("L2 Bridge :: proxy admin", async (ctx) => { - assert.equal( - await ctx.l2ERC20TokenGatewayProxy.proxy__getAdmin(), - ctx.deployment.l2.proxyAdmin - ); - }) - .step("L2 Bridge :: bridge admin", async (ctx) => { - const currentAdmins = await getRoleHolders( - ctx.l2ERC20TokenGateway, - BridgingManagerRole.DEFAULT_ADMIN_ROLE.hash - ); - assert.equal(currentAdmins.size, 1); - assert.isTrue(currentAdmins.has(ctx.deployment.l2.bridgeAdmin)); - - await assert.isTrue( - await ctx.l2ERC20TokenGateway.hasRole( - BridgingManagerRole.DEFAULT_ADMIN_ROLE.hash, - ctx.deployment.l2.bridgeAdmin - ) - ); - }) - .step("L2 bridge :: router", async (ctx) => { - assert.equal(await ctx.l2ERC20TokenGateway.router(), ctx.l2Router.address); - }) - .step("L2 bridge :: L1 token", async (ctx) => { - assert.equal(await ctx.l2ERC20TokenGateway.l1Token(), ctx.deployment.token); - }) - .step("L2 bridge :: L2 token", async (ctx) => { - assert.equal( - await ctx.l2ERC20TokenGateway.l2Token(), - ctx.erc20Bridged.address - ); - }) - .step("L2 bridge :: counterpart gateway", async (ctx) => { - assert.equal( - await ctx.l2ERC20TokenGateway.counterpartGateway(), - ctx.l1ERC20TokenGateway.address - ); - }) - .step("L2 Bridge :: is deposits enabled", async (ctx) => { - assert.equal( - await ctx.l2ERC20TokenGateway.isDepositsEnabled(), - ctx.deployment.l2.depositsEnabled - ); - }) - .step("L2 Bridge :: is withdrawals enabled", async (ctx) => { - assert.equal( - await ctx.l2ERC20TokenGateway.isWithdrawalsEnabled(), - ctx.deployment.l2.withdrawalsEnabled - ); - }) - .step("L2 Bridge :: deposits enablers", async (ctx) => { - const actualDepositsEnablers = await getRoleHolders( - ctx.l2ERC20TokenGateway, - BridgingManagerRole.DEPOSITS_ENABLER_ROLE.hash - ); - const expectedDepositsEnablers = ctx.deployment.l2.depositsEnablers || []; - - assert.equal(actualDepositsEnablers.size, expectedDepositsEnablers.length); - for (const expectedDepositsEnabler of expectedDepositsEnablers) { - assert.isTrue(actualDepositsEnablers.has(expectedDepositsEnabler)); - } - }) - .step("L2 Bridge :: deposits disablers", async (ctx) => { - const actualDepositsDisablers = await getRoleHolders( - ctx.l2ERC20TokenGateway, - BridgingManagerRole.DEPOSITS_DISABLER_ROLE.hash - ); - const expectedDepositsDisablers = ctx.deployment.l2.depositsDisablers || []; - - assert.equal( - actualDepositsDisablers.size, - expectedDepositsDisablers.length - ); - for (const expectedDepositsDisabler of expectedDepositsDisablers) { - assert.isTrue(actualDepositsDisablers.has(expectedDepositsDisabler)); - } - }) - .step("L2 Bridge :: withdrawals enablers", async (ctx) => { - const actualWithdrawalsEnablers = await getRoleHolders( - ctx.l2ERC20TokenGateway, - BridgingManagerRole.WITHDRAWALS_ENABLER_ROLE.hash - ); - const expectedWithdrawalsEnablers = - ctx.deployment.l2.withdrawalsEnablers || []; - - assert.equal( - actualWithdrawalsEnablers.size, - expectedWithdrawalsEnablers.length - ); - for (const expectedWithdrawalsEnabler of expectedWithdrawalsEnablers) { - assert.isTrue(actualWithdrawalsEnablers.has(expectedWithdrawalsEnabler)); - } - }) - .step("L2 Bridge :: withdrawals disablers", async (ctx) => { - const actualWithdrawalsDisablers = await getRoleHolders( - ctx.l2ERC20TokenGateway, - BridgingManagerRole.WITHDRAWALS_DISABLER_ROLE.hash - ); - const expectedWithdrawalsDisablers = - ctx.deployment.l2.withdrawalsDisablers || []; - - assert.equal( - actualWithdrawalsDisablers.size, - expectedWithdrawalsDisablers.length - ); - for (const expectedWithdrawalsDisabler of expectedWithdrawalsDisablers) { - assert.isTrue( - actualWithdrawalsDisablers.has(expectedWithdrawalsDisabler) - ); - } - }) - - .step("L2 Token :: proxy admin", async (ctx) => { - assert.equal( - await ctx.erc20BridgedProxy.proxy__getAdmin(), - ctx.deployment.l2.proxyAdmin - ); - }) - .step("L2 Token :: name", async (ctx) => { - assert.equal(await ctx.erc20Bridged.name(), ctx.l2TokenInfo.name); - }) - .step("L2 Token :: symbol", async (ctx) => { - assert.equal(await ctx.erc20Bridged.symbol(), ctx.l2TokenInfo.symbol); - }) - .step("L2 Token :: decimals", async (ctx) => { - assert.equal(await ctx.erc20Bridged.decimals(), ctx.l2TokenInfo.decimals); - }) - .step("L2 Token :: total supply", async (ctx) => { - assert.equalBN(await ctx.erc20Bridged.totalSupply(), wei`0`); - }) - .step("L2 token :: bridge", async (ctx) => { - assert.equalBN( - await ctx.erc20Bridged.bridge(), - ctx.l2ERC20TokenGateway.address - ); - }) - - .run(); - -async function ctxFactory() { - const networkName = env.network(); - const deploymentConfig = deployment.loadMultiChainDeploymentConfig(); - const testingSetup = await arbitrum - .testing(networkName) - .getAcceptanceTestSetup(); - - const l1TokenMeta = IERC20Metadata__factory.connect( - deploymentConfig.token, - testingSetup.l1Provider - ); - const [name, symbol, decimals] = await Promise.all([ - l1TokenMeta.name(), - l1TokenMeta.symbol(), - l1TokenMeta.decimals(), - ]); - - return { - deployment: deploymentConfig, - l1Router: testingSetup.l1GatewayRouter, - l2Router: testingSetup.l2GatewayRouter, - l2TokenInfo: { - name, - symbol, - decimals, - }, - l1ERC20TokenGateway: testingSetup.l1ERC20TokenGateway, - l1ERC20TokenGatewayProxy: OssifiableProxy__factory.connect( - testingSetup.l1ERC20TokenGateway.address, - testingSetup.l1Provider - ), - l2ERC20TokenGateway: testingSetup.l2ERC20TokenGateway, - l2ERC20TokenGatewayProxy: OssifiableProxy__factory.connect( - testingSetup.l2ERC20TokenGateway.address, - testingSetup.l2Provider - ), - erc20Bridged: testingSetup.l2Token, - erc20BridgedProxy: OssifiableProxy__factory.connect( - testingSetup.l2Token.address, - testingSetup.l2Provider - ), - }; -} diff --git a/test/arbitrum/managing-deposits.e2e.test.ts b/test/arbitrum/managing-deposits.e2e.test.ts deleted file mode 100644 index 1154cbca..00000000 --- a/test/arbitrum/managing-deposits.e2e.test.ts +++ /dev/null @@ -1,194 +0,0 @@ -import { L1ToL2MessageStatus } from "@arbitrum/sdk"; -import { assert } from "chai"; -import { ContractReceipt } from "ethers"; - -import { - L2ERC20TokenGateway__factory, - GovBridgeExecutor__factory, -} from "../../typechain"; -import { - E2E_TEST_CONTRACTS_ARBITRUM as E2E_TEST_CONTRACTS, - sleep, -} from "../../utils/testing/e2e"; -import { wei } from "../../utils/wei"; -import network from "../../utils/network"; -import env from "../../utils/env"; -import { scenario } from "../../utils/testing"; -import arbitrum from "../../utils/arbitrum"; -import lido from "../../utils/lido"; - -const DEPOSIT_ENABLER_ROLE = - "0x4b43b36766bde12c5e9cbbc37d15f8d1f769f08f54720ab370faeb4ce893753a"; -const DEPOSIT_DISABLER_ROLE = - "0x63f736f21cb2943826cd50b191eb054ebbea670e4e962d0527611f830cd399d6"; - -let l2DepositsInitialState: boolean; -let ticketTx: ContractReceipt; - -const scenarioTest = scenario( - "Arbitrum :: AAVE governance crosschain bridge: token bridge management", - ctxFactory -) - .step("LDO Holder has enought ETH", async ({ l1LDOHolder, gasAmount }) => { - assert.gte(await l1LDOHolder.getBalance(), gasAmount); - }) - - .step("L2 Tester has enought ETH", async ({ l2Tester, gasAmount }) => { - assert.gte(await l2Tester.getBalance(), gasAmount); - }) - - .step( - "L2 Agent has enought ETH", - async ({ l1Provider, lidoAragonDAO, gasAmount }) => { - assert.gte( - await l1Provider.getBalance(lidoAragonDAO.agent.address), - gasAmount - ); - } - ) - - .step("Checking deposits status", async ({ l2ERC20TokenGateway }) => { - l2DepositsInitialState = await l2ERC20TokenGateway.isDepositsEnabled(); - }) - - .step(`Starting DAO vote`, async (ctx) => { - const grantRoleCalldata = - ctx.l2ERC20TokenGateway.interface.encodeFunctionData("grantRole", [ - l2DepositsInitialState ? DEPOSIT_DISABLER_ROLE : DEPOSIT_ENABLER_ROLE, - ctx.govBridgeExecutor.address, - ]); - const grantRoleData = "0x" + grantRoleCalldata.substring(10); - - const actionCalldata = l2DepositsInitialState - ? ctx.l2ERC20TokenGateway.interface.encodeFunctionData("disableDeposits") - : ctx.l2ERC20TokenGateway.interface.encodeFunctionData("enableDeposits"); - - const actionData = "0x" + actionCalldata.substring(10); - - const executorCalldata = - await ctx.govBridgeExecutor.interface.encodeFunctionData("queue", [ - [ctx.l2ERC20TokenGateway.address, ctx.l2ERC20TokenGateway.address], - [0, 0], - [ - "grantRole(bytes32,address)", - l2DepositsInitialState ? "disableDeposits()" : "enableDeposits()", - ], - [grantRoleData, actionData], - [false, false], - ]); - - const arbAddresses = arbitrum.addresses("sepolia"); - - const { calldata, callvalue } = - await ctx.messaging.prepareRetryableTicketTx({ - sender: ctx.lidoAragonDAO.agent.address, - recipient: ctx.govBridgeExecutor.address, - calldata: executorCalldata, - refundAddress: ctx.l2Tester.address, - }); - - const tx = await ctx.lidoAragonDAO.createVote( - ctx.l1LDOHolder, - "E2E Test Voting", - { - address: ctx.lidoAragonDAO.agent.address, - signature: "execute(address,uint256,bytes)", - decodedCallData: [arbAddresses.Inbox, callvalue, calldata], - } - ); - - await tx.wait(); - }) - - .step("Enacting Vote", async ({ l1LDOHolder, lidoAragonDAO }) => { - const votesLength = await lidoAragonDAO.voting.votesLength(); - - const tx = await lidoAragonDAO.voteAndExecute( - l1LDOHolder, - votesLength.toNumber() - 1 - ); - - ticketTx = await tx.wait(); - }) - - .step("Waiting for L2 tx", async ({ messaging }) => { - const { status } = await messaging.waitForL2Message( - ticketTx.transactionHash - ); - - assert.equal( - status, - L1ToL2MessageStatus.REDEEMED, - `L2 retryable txn failed with status ${L1ToL2MessageStatus[status]}` - ); - }) - - .step("Execute queued task", async ({ govBridgeExecutor, l2Tester }) => { - const tasksCount = await govBridgeExecutor.getActionsSetCount(); - - const targetTask = tasksCount.toNumber() - 1; - - const executionTime = ( - await govBridgeExecutor.getActionsSetById(targetTask) - ).executionTime.toNumber(); - let chainTime; - - do { - await sleep(5000); - const currentBlockNumber = await l2Tester.provider.getBlockNumber(); - const currentBlock = await l2Tester.provider.getBlock(currentBlockNumber); - chainTime = currentBlock.timestamp; - } while (chainTime <= executionTime); - - const tx = await govBridgeExecutor.execute(targetTask, { - gasLimit: 1000000, - }); - await tx.wait(); - }) - - .step("Checking deposits state", async ({ l2ERC20TokenGateway }) => { - assert.equal( - await l2ERC20TokenGateway.isDepositsEnabled(), - !l2DepositsInitialState - ); - }); - -// make first run to change state from enabled/disabled -> disabled/enabled -scenarioTest.run(); - -// make another run to return the state to the initial and test vice versa actions -scenarioTest.run(); - -async function ctxFactory() { - const ethArbNetwork = network.multichain(["eth", "arb"], "sepolia"); - - const [l1Provider] = ethArbNetwork.getProviders({ - forking: false, - }); - const [, l2Tester] = ethArbNetwork.getSigners( - env.string("TESTING_PRIVATE_KEY"), - { forking: false } - ); - - const [l1LDOHolder] = ethArbNetwork.getSigners( - env.string("TESTING_ARB_LDO_HOLDER_PRIVATE_KEY"), - { forking: false } - ); - - return { - lidoAragonDAO: lido("sepolia", l1Provider), - messaging: arbitrum.messaging("sepolia", { forking: false }), - gasAmount: wei`0.1 ether`, - l2Tester, - l1Provider, - l1LDOHolder, - l2ERC20TokenGateway: L2ERC20TokenGateway__factory.connect( - E2E_TEST_CONTRACTS.l2.l2ERC20TokenGateway, - l2Tester - ), - govBridgeExecutor: GovBridgeExecutor__factory.connect( - E2E_TEST_CONTRACTS.l2.govBridgeExecutor, - l2Tester - ), - }; -} diff --git a/test/arbitrum/managing-executor.e2e.test.ts b/test/arbitrum/managing-executor.e2e.test.ts deleted file mode 100644 index 0dc6a15b..00000000 --- a/test/arbitrum/managing-executor.e2e.test.ts +++ /dev/null @@ -1,164 +0,0 @@ -import { assert } from "chai"; -import { ContractReceipt } from "ethers"; -import { L1ToL2MessageStatus } from "@arbitrum/sdk"; - -import { GovBridgeExecutor__factory } from "../../typechain"; -import { - E2E_TEST_CONTRACTS_ARBITRUM as E2E_TEST_CONTRACTS, - sleep, -} from "../../utils/testing/e2e"; -import env from "../../utils/env"; -import network from "../../utils/network"; -import { wei } from "../../utils/wei"; -import { scenario } from "../../utils/testing"; -import arbitrum from "../../utils/arbitrum"; -import lido from "../../utils/lido"; - -let oldGuardian: string; -let newGuardian: string; -let ticketTx: ContractReceipt; - -scenario("Arbitrum :: Update guardian", ctxFactory) - .step("LDO Holder has enought ETH", async ({ l1LDOHolder, gasAmount }) => { - assert.gte(await l1LDOHolder.getBalance(), gasAmount); - }) - - .step("L2 Tester has enought ETH", async ({ l2Tester, gasAmount }) => { - assert.gte(await l2Tester.getBalance(), gasAmount); - }) - - .step( - "L2 Agent has enought ETH", - async ({ l1Provider, lidoAragonDAO, gasAmount }) => { - assert.gte( - await l1Provider.getBalance(lidoAragonDAO.agent.address), - gasAmount - ); - } - ) - - .step(`Starting DAO vote: Update guardian`, async (ctx) => { - oldGuardian = await ctx.govBridgeExecutor.getGuardian(); - newGuardian = - oldGuardian === "0x4e8CC9024Ea3FE886623025fF2aD0CA4bb3D1F42" - ? "0xD06491e4C8B3107B83dC134894C4c96ED8ddbfa2" - : "0x4e8CC9024Ea3FE886623025fF2aD0CA4bb3D1F42"; - - const updateGuardianCalldata = - ctx.govBridgeExecutor.interface.encodeFunctionData("updateGuardian", [ - newGuardian, - ]); - const updateGuardianData = "0x" + updateGuardianCalldata.substring(10); - - const executorCalldata = - await ctx.govBridgeExecutor.interface.encodeFunctionData("queue", [ - [ctx.govBridgeExecutor.address], - [0], - ["updateGuardian(address)"], - [updateGuardianData], - [false], - ]); - - const arbAddresses = arbitrum.addresses("sepolia"); - - const { calldata, callvalue } = - await ctx.messaging.prepareRetryableTicketTx({ - sender: ctx.lidoAragonDAO.agent.address, - recipient: ctx.govBridgeExecutor.address, - calldata: executorCalldata, - refundAddress: ctx.l2Tester.address, - }); - - const tx = await ctx.lidoAragonDAO.createVote( - ctx.l1LDOHolder, - "E2E Test Voting", - { - address: ctx.lidoAragonDAO.agent.address, - signature: "execute(address,uint256,bytes)", - decodedCallData: [arbAddresses.Inbox, callvalue, calldata], - } - ); - - await tx.wait(); - }) - - .step("Enacting Vote", async ({ l1LDOHolder, lidoAragonDAO }) => { - const votesLength = await lidoAragonDAO.voting.votesLength(); - - const tx = await lidoAragonDAO.voteAndExecute( - l1LDOHolder, - votesLength.toNumber() - 1 - ); - - ticketTx = await tx.wait(); - }) - - .step("Waiting for L2 tx", async ({ messaging }) => { - const { status } = await messaging.waitForL2Message( - ticketTx.transactionHash - ); - - assert.equal( - status, - L1ToL2MessageStatus.REDEEMED, - `L2 retryable txn failed with status ${L1ToL2MessageStatus[status]}` - ); - }) - - .step("Execute queued task", async ({ govBridgeExecutor, l2Tester }) => { - const tasksCount = await govBridgeExecutor.getActionsSetCount(); - - const targetTask = tasksCount.toNumber() - 1; - - const executionTime = ( - await govBridgeExecutor.getActionsSetById(targetTask) - ).executionTime.toNumber(); - let chainTime; - - do { - await sleep(5000); - const currentBlockNumber = await l2Tester.provider.getBlockNumber(); - const currentBlock = await l2Tester.provider.getBlock(currentBlockNumber); - chainTime = currentBlock.timestamp; - } while (chainTime <= executionTime); - - const tx = await govBridgeExecutor.execute(targetTask, { - gasLimit: 1000000, - }); - await tx.wait(); - }) - - .step("Checking guardian", async ({ govBridgeExecutor }) => { - assert.equal(await govBridgeExecutor.getGuardian(), newGuardian); - }) - .run(); - -async function ctxFactory() { - const ethArbNetwork = network.multichain(["eth", "arb"], "sepolia"); - - const [l1Provider] = ethArbNetwork.getProviders({ - forking: false, - }); - const [, l2Tester] = ethArbNetwork.getSigners( - env.string("TESTING_PRIVATE_KEY"), - { forking: false } - ); - - const [l1LDOHolder] = ethArbNetwork.getSigners( - env.string("TESTING_ARB_LDO_HOLDER_PRIVATE_KEY"), - { forking: false } - ); - - return { - lidoAragonDAO: lido("sepolia", l1Provider), - messaging: arbitrum.messaging("sepolia", { forking: false }), - gasAmount: wei`0.1 ether`, - l2Tester, - l1Provider, - l1LDOHolder, - govBridgeExecutor: GovBridgeExecutor__factory.connect( - E2E_TEST_CONTRACTS.l2.govBridgeExecutor, - l2Tester - ), - }; -} diff --git a/test/arbitrum/managing-proxy.e2e.test.ts b/test/arbitrum/managing-proxy.e2e.test.ts deleted file mode 100644 index e8342cfa..00000000 --- a/test/arbitrum/managing-proxy.e2e.test.ts +++ /dev/null @@ -1,284 +0,0 @@ -import { L1ToL2MessageStatus, L1TransactionReceipt } from "@arbitrum/sdk"; -import { assert } from "chai"; -import { ContractReceipt } from "ethers"; - -import { - ERC20Bridged__factory, - L2ERC20TokenGateway__factory, - GovBridgeExecutor__factory, - OssifiableProxy__factory, -} from "../../typechain"; -import { - E2E_TEST_CONTRACTS_ARBITRUM as E2E_TEST_CONTRACTS, - sleep, -} from "../../utils/testing/e2e"; -import env from "../../utils/env"; -import { wei } from "../../utils/wei"; -import network from "../../utils/network"; -import { scenario } from "../../utils/testing"; -import arbitrum from "../../utils/arbitrum"; -import lido from "../../utils/lido"; - -let upgradeMessageResponse: ContractReceipt; -let ossifyMessageResponse: ContractReceipt; - -scenario("Arbitrum :: AAVE governance crosschain bridge", ctxFactory) - .step("LDO Holder has enought ETH", async ({ l1LDOHolder, gasAmount }) => { - assert.gte(await l1LDOHolder.getBalance(), gasAmount); - }) - - .step("L2 Tester has enought ETH", async ({ l2Tester, gasAmount }) => { - assert.gte(await l2Tester.getBalance(), gasAmount); - }) - - .step( - "L2 Agent has enought ETH", - async ({ l1Provider, lidoAragonDAO, gasAmount }) => { - assert.gte( - await l1Provider.getBalance(lidoAragonDAO.agent.address), - gasAmount - ); - } - ) - .step("Check OssifiableProxy deployed correct", async (ctx) => { - const { proxyToOssify } = ctx; - const admin = await proxyToOssify.proxy__getAdmin(); - - assert.equal(admin, E2E_TEST_CONTRACTS.l2.govBridgeExecutor); - }) - - .step("Proxy upgrade: send crosschain message", async (ctx) => { - const implBefore = await await ctx.proxyToOssify.proxy__getImplementation(); - - assert.equal(implBefore, ctx.l2ERC20TokenGateway.address); - - const executorCalldata = - await ctx.govBridgeExecutor.interface.encodeFunctionData("queue", [ - [ctx.proxyToOssify.address], - [0], - ["proxy__upgradeTo(address)"], - [ - "0x" + - ctx.proxyToOssify.interface - .encodeFunctionData("proxy__upgradeTo", [ctx.l2Token.address]) - .substring(10), - ], - [false], - ]); - - const arbAddresses = arbitrum.addresses("sepolia"); - - const { calldata, callvalue } = - await ctx.messaging.prepareRetryableTicketTx({ - sender: ctx.lidoAragonDAO.agent.address, - recipient: ctx.govBridgeExecutor.address, - calldata: executorCalldata, - refundAddress: ctx.l2Tester.address, - }); - - const tx = await ctx.lidoAragonDAO.createVote( - ctx.l1LDOHolder, - "E2E Test Voting", - { - address: ctx.lidoAragonDAO.agent.address, - signature: "execute(address,uint256,bytes)", - decodedCallData: [arbAddresses.Inbox, callvalue, calldata], - } - ); - - await tx.wait(); - }) - - .step( - "Proxy upgrade: Enacting Voting", - async ({ l1LDOHolder, lidoAragonDAO }) => { - const votesLength = await lidoAragonDAO.voting.votesLength(); - - const tx = await lidoAragonDAO.voteAndExecute( - l1LDOHolder, - votesLength.toNumber() - 1 - ); - - upgradeMessageResponse = await tx.wait(); - } - ) - - .step("Proxy upgrade: Waiting for L2 tx", async ({ messaging, l2Tester }) => { - const { status } = await messaging.waitForL2Message( - upgradeMessageResponse.transactionHash - ); - - if (status === L1ToL2MessageStatus.FUNDS_DEPOSITED_ON_L2) { - console.warn( - `Auto redeem for tx ${upgradeMessageResponse.transactionHash} failed. Redeeming it manually...` - ); - const l1TxReceipt = new L1TransactionReceipt(upgradeMessageResponse); - const [message] = await l1TxReceipt.getL1ToL2Messages(l2Tester); - const redeemResponse = await message.redeem({ gasLimit: 300_000 }); - await redeemResponse.wait(); - console.log("Tx was redeemed"); - } else if (status === L1ToL2MessageStatus.REDEEMED) { - console.log("Tx was auto redeemed"); - } else { - assert.isTrue( - false, - `L2 retryable txn failed with status ${L1ToL2MessageStatus[status]}` - ); - } - }) - - .step( - "Proxy upgrade: Execute queued task", - async ({ govBridgeExecutor, l2Tester }) => { - const tasksCount = await govBridgeExecutor.getActionsSetCount(); - - const targetTask = tasksCount.toNumber() - 1; - - const executionTime = ( - await govBridgeExecutor.getActionsSetById(targetTask) - ).executionTime.toNumber(); - let chainTime; - - do { - await sleep(5000); - const currentBlockNumber = await l2Tester.provider.getBlockNumber(); - const currentBlock = await l2Tester.provider.getBlock( - currentBlockNumber - ); - chainTime = currentBlock.timestamp; - } while (chainTime <= executionTime); - - const tx = await govBridgeExecutor.execute(targetTask, { - gasLimit: 1000000, - }); - await tx.wait(); - } - ) - - .step("Proxy upgrade: check state", async ({ proxyToOssify, l2Token }) => { - const implAfter = await await proxyToOssify.proxy__getImplementation(); - assert.equal(implAfter, l2Token.address); - }) - - .step("Proxy ossify: send crosschain message", async (ctx) => { - const isOssifiedBefore = await ctx.proxyToOssify.proxy__getIsOssified(); - assert.isFalse(isOssifiedBefore); - - const executorCalldata = - await ctx.govBridgeExecutor.interface.encodeFunctionData("queue", [ - [ctx.proxyToOssify.address], - [0], - ["proxy__ossify()"], - ["0x00"], - [false], - ]); - - const arbAddresses = arbitrum.addresses("sepolia"); - - const { calldata, callvalue } = - await ctx.messaging.prepareRetryableTicketTx({ - sender: ctx.lidoAragonDAO.agent.address, - recipient: ctx.govBridgeExecutor.address, - calldata: executorCalldata, - refundAddress: ctx.l2Tester.address, - }); - - const tx = await ctx.lidoAragonDAO.createVote( - ctx.l1LDOHolder, - "E2E Test Voting", - { - address: ctx.lidoAragonDAO.agent.address, - signature: "execute(address,uint256,bytes)", - decodedCallData: [arbAddresses.Inbox, callvalue, calldata], - } - ); - - await tx.wait(); - }) - - .step( - "Proxy ossify: Enacting Voting", - async ({ lidoAragonDAO, l1LDOHolder }) => { - const votesLength = await lidoAragonDAO.voting.votesLength(); - - const tx = await lidoAragonDAO.voteAndExecute( - l1LDOHolder, - votesLength.toNumber() - 1 - ); - - ossifyMessageResponse = await tx.wait(); - } - ) - - .step("Proxy ossify: Waiting for L2 tx", async ({ messaging }) => { - const { status } = await messaging.waitForL2Message( - ossifyMessageResponse.transactionHash - ); - - assert.equal( - status, - L1ToL2MessageStatus.REDEEMED, - `L2 retryable txn failed with status ${L1ToL2MessageStatus[status]}` - ); - }) - - .step("Proxy ossify: execute", async ({ govBridgeExecutor }) => { - const taskId = - (await govBridgeExecutor.getActionsSetCount()).toNumber() - 1; - const executeTx = await govBridgeExecutor.execute(taskId, { - gasLimit: 2000000, - }); - await executeTx.wait(); - }) - - .step("Proxy upgrade: check state", async ({ proxyToOssify }) => { - const isOssifiedAfter = await proxyToOssify.proxy__getIsOssified(); - - assert.isTrue(isOssifiedAfter); - }) - - .run(); - -async function ctxFactory() { - const ethArbNetwork = network.multichain(["eth", "arb"], "sepolia"); - - const [l1Provider] = ethArbNetwork.getProviders({ - forking: false, - }); - const [, l2Tester] = ethArbNetwork.getSigners( - env.string("TESTING_PRIVATE_KEY"), - { forking: false } - ); - - const [l1LDOHolder] = ethArbNetwork.getSigners( - env.string("TESTING_ARB_LDO_HOLDER_PRIVATE_KEY"), - { forking: false } - ); - - return { - lidoAragonDAO: lido("sepolia", l1Provider), - messaging: arbitrum.messaging("sepolia", { forking: false }), - gasAmount: wei`0.1 ether`, - l2Tester, - l1LDOHolder, - l1Provider, - - l2Token: ERC20Bridged__factory.connect( - E2E_TEST_CONTRACTS.l2.l2Token, - l2Tester - ), - l2ERC20TokenGateway: L2ERC20TokenGateway__factory.connect( - E2E_TEST_CONTRACTS.l2.l2ERC20TokenGateway, - l2Tester - ), - govBridgeExecutor: GovBridgeExecutor__factory.connect( - E2E_TEST_CONTRACTS.l2.govBridgeExecutor, - l2Tester - ), - proxyToOssify: await new OssifiableProxy__factory(l2Tester).deploy( - E2E_TEST_CONTRACTS.l2.l2ERC20TokenGateway, - E2E_TEST_CONTRACTS.l2.govBridgeExecutor, - "0x" - ), - }; -} diff --git a/test/bridge-executor/arbitrum.integration.test.ts b/test/bridge-executor/arbitrum.integration.test.ts deleted file mode 100644 index 3bfcce5a..00000000 --- a/test/bridge-executor/arbitrum.integration.test.ts +++ /dev/null @@ -1,273 +0,0 @@ -import { assert } from "chai"; -import testing, { scenario } from "../../utils/testing"; -import { - ERC20BridgedStub__factory, - L2ERC20TokenGateway__factory, - ArbitrumBridgeExecutor__factory, - ERC20Bridged__factory, - OssifiableProxy__factory, -} from "../../typechain"; -import { wei } from "../../utils/wei"; -import { getBridgeExecutorParams } from "../../utils/bridge-executor"; -import { BridgingManagerRole } from "../../utils/bridging-management"; - -import arbitrum from "../../utils/arbitrum"; -import network from "../../utils/network"; -import env from "../../utils/env"; - -scenario("Arbitrum :: Bridge Executor integration test", ctx) - .before(async (ctx) => { - ctx.snapshot.l2 = await ctx.l2.provider.send("evm_snapshot", []); - }) - - .after(async (ctx) => { - await ctx.l2.provider.send("evm_revert", [ctx.snapshot.l2]); - }) - - .step("Activate Bridging", async (ctx) => { - const { - l2: { bridgeExecutor, l2ERC20TokenGateway }, - } = ctx; - - assert.isFalse( - await l2ERC20TokenGateway.hasRole( - BridgingManagerRole.DEPOSITS_ENABLER_ROLE.hash, - bridgeExecutor.address - ) - ); - assert.isFalse( - await l2ERC20TokenGateway.hasRole( - BridgingManagerRole.WITHDRAWALS_ENABLER_ROLE.hash, - bridgeExecutor.address - ) - ); - assert.isFalse(await l2ERC20TokenGateway.isDepositsEnabled()); - assert.isFalse(await l2ERC20TokenGateway.isWithdrawalsEnabled()); - - const actionsSetCountBefore = await bridgeExecutor.getActionsSetCount(); - await bridgeExecutor.queue( - new Array(4).fill(l2ERC20TokenGateway.address), - new Array(4).fill(0), - [ - "grantRole(bytes32,address)", - "grantRole(bytes32,address)", - "enableDeposits()", - "enableWithdrawals()", - ], - [ - "0x" + - l2ERC20TokenGateway.interface - .encodeFunctionData("grantRole", [ - BridgingManagerRole.DEPOSITS_ENABLER_ROLE.hash, - bridgeExecutor.address, - ]) - .substring(10), - "0x" + - l2ERC20TokenGateway.interface - .encodeFunctionData("grantRole", [ - BridgingManagerRole.WITHDRAWALS_ENABLER_ROLE.hash, - bridgeExecutor.address, - ]) - .substring(10), - "0x" + - l2ERC20TokenGateway.interface - .encodeFunctionData("enableDeposits") - .substring(10), - "0x" + - l2ERC20TokenGateway.interface - .encodeFunctionData("enableWithdrawals") - .substring(10), - ], - new Array(4).fill(false) - ); - - const actionsSetCountAfter = await bridgeExecutor.getActionsSetCount(); - - assert.equalBN(actionsSetCountBefore.add(1), actionsSetCountAfter); - // execute the last added actions set - await bridgeExecutor.execute(actionsSetCountAfter.sub(1), { value: 0 }); - - assert.isTrue( - await l2ERC20TokenGateway.hasRole( - BridgingManagerRole.DEPOSITS_ENABLER_ROLE.hash, - bridgeExecutor.address - ) - ); - assert.isTrue( - await l2ERC20TokenGateway.hasRole( - BridgingManagerRole.WITHDRAWALS_ENABLER_ROLE.hash, - bridgeExecutor.address - ) - ); - assert.isTrue(await l2ERC20TokenGateway.isDepositsEnabled()); - assert.isTrue(await l2ERC20TokenGateway.isWithdrawalsEnabled()); - }) - - .step("Change Proxy implementation", async (ctx) => { - const { - l2: { l2Token, bridgeExecutor, l2ERC20TokenGatewayProxy }, - } = ctx; - - const actionsSetCountBefore = await bridgeExecutor.getActionsSetCount(); - - const proxyImplBefore = - await l2ERC20TokenGatewayProxy.proxy__getImplementation(); - - await bridgeExecutor.queue( - [l2ERC20TokenGatewayProxy.address], - [0], - ["proxy__upgradeTo(address)"], - [ - "0x" + - l2ERC20TokenGatewayProxy.interface - .encodeFunctionData("proxy__upgradeTo", [l2Token.address]) - .substring(10), - ], - [false] - ); - - const actionSetCount = await bridgeExecutor.getActionsSetCount(); - - assert.equalBN(actionsSetCountBefore.add(1), actionSetCount); - - await bridgeExecutor.execute(actionsSetCountBefore, { value: 0 }); - const proxyImplAfter = - await l2ERC20TokenGatewayProxy.proxy__getImplementation(); - - assert.notEqual(proxyImplBefore, proxyImplAfter); - assert.equal(proxyImplAfter, l2Token.address); - }) - - .step("Change proxy Admin", async (ctx) => { - const { - l2: { - l2ERC20TokenGatewayProxy, - bridgeExecutor, - accounts: { deployer }, - }, - } = ctx; - const proxyAdminBefore = await l2ERC20TokenGatewayProxy.proxy__getAdmin(); - - const actionsSetCountBefore = await bridgeExecutor.getActionsSetCount(); - - await bridgeExecutor.queue( - [l2ERC20TokenGatewayProxy.address], - [0], - ["proxy__changeAdmin(address)"], - [ - "0x" + - l2ERC20TokenGatewayProxy.interface - .encodeFunctionData("proxy__changeAdmin", [deployer.address]) - .substring(10), - ], - [false] - ); - - const actionSetCount = await bridgeExecutor.getActionsSetCount(); - assert.equalBN(actionsSetCountBefore.add(1), actionSetCount); - - await bridgeExecutor.execute(actionsSetCountBefore, { value: 0 }); - const proxyAdminAfter = await l2ERC20TokenGatewayProxy.proxy__getAdmin(); - - assert.notEqual(proxyAdminBefore, proxyAdminAfter); - assert.equal(proxyAdminAfter, deployer.address); - }) - - .run(); - -async function ctx() { - const networkName = env.network("TESTING_ARB_NETWORK", "mainnet"); - const [l1Provider, l2Provider] = network - .multichain(["eth", "arb"], networkName) - .getProviders({ forking: true }); - - const testingOnDeployedContracts = testing.env.USE_DEPLOYED_CONTRACTS(false); - - const l1Deployer = testing.accounts.deployer(l1Provider); - const l2Deployer = testing.accounts.deployer(l2Provider); - - await arbitrum.testing(networkName).stubArbSysContract(); - - const l1Token = await new ERC20BridgedStub__factory(l1Deployer).deploy( - "Test Token", - "TT" - ); - const govBridgeExecutor = testingOnDeployedContracts - ? ArbitrumBridgeExecutor__factory.connect( - testing.env.ARB_GOV_BRIDGE_EXECUTOR(), - l2Provider - ) - : await new ArbitrumBridgeExecutor__factory(l2Deployer).deploy( - l1Deployer.address, - ...getBridgeExecutorParams(), - l2Deployer.address - ); - - const l1EthGovExecutorAddress = - await govBridgeExecutor.getEthereumGovernanceExecutor(); - - const [, l2DeployScript] = await arbitrum - .deployment(networkName) - .erc20TokenGatewayDeployScript( - l1Token.address, - { - deployer: l1Deployer, - admins: { proxy: l1Deployer.address, bridge: l1Deployer.address }, - }, - { - deployer: l2Deployer, - admins: { - proxy: govBridgeExecutor.address, - bridge: govBridgeExecutor.address, - }, - } - ); - - await l2DeployScript.run(); - - const l2Token = ERC20Bridged__factory.connect( - l2DeployScript.getContractAddress(1), - l2Deployer - ); - const l2ERC20TokenGateway = L2ERC20TokenGateway__factory.connect( - l2DeployScript.getContractAddress(3), - l2Deployer - ); - const l2ERC20TokenGatewayProxy = OssifiableProxy__factory.connect( - l2DeployScript.getContractAddress(3), - l2Deployer - ); - const l1ExecutorAliased = await testing.impersonate( - testing.accounts.applyL1ToL2Alias(l1EthGovExecutorAddress), - l2Provider - ); - - await testing.setBalance( - await l1ExecutorAliased.getAddress(), - wei.toBigNumber(wei`1 ether`), - l2Provider - ); - - if (testingOnDeployedContracts) { - console.log("Testing on deployed contracts"); - console.log(` Network name: ${networkName}`); - console.log(` Gov Bridge Executor Address: ${govBridgeExecutor.address}`); - } - - return { - l2: { - l2Token, - bridgeExecutor: govBridgeExecutor.connect(l1ExecutorAliased), - l2ERC20TokenGateway, - l2ERC20TokenGatewayProxy, - accounts: { - deployer: l2Deployer, - }, - provider: l2Provider, - }, - snapshot: { - l1: "", - l2: "", - }, - }; -} diff --git a/test/bridge-executor/optimism.integration.test.ts b/test/bridge-executor/optimism.integration.test.ts index 7c33be93..7159ce59 100644 --- a/test/bridge-executor/optimism.integration.test.ts +++ b/test/bridge-executor/optimism.integration.test.ts @@ -1,39 +1,44 @@ import { assert } from "chai"; +import { BigNumber } from 'ethers' import { ERC20BridgedStub__factory, - L2ERC20TokenBridge__factory, + L2ERC20ExtendedTokensBridge__factory, OssifiableProxy__factory, OptimismBridgeExecutor__factory, - ERC20Bridged__factory, + ERC20BridgedPermit__factory, + ERC20WrapperStub__factory, + AccountingOracleStub__factory } from "../../typechain"; import { wei } from "../../utils/wei"; import optimism from "../../utils/optimism"; import testing, { scenario } from "../../utils/testing"; import { BridgingManagerRole } from "../../utils/bridging-management"; +import { getExchangeRate } from "../../utils/testing/helpers"; import env from "../../utils/env"; import network from "../../utils/network"; import { getBridgeExecutorParams } from "../../utils/bridge-executor"; +import deploymentAll from "../../utils/optimism/deployment"; scenario("Optimism :: Bridge Executor integration test", ctxFactory) .step("Activate L2 bridge", async (ctx) => { - const { l2ERC20TokenBridge, bridgeExecutor, l2CrossDomainMessenger } = + const { l2ERC20ExtendedTokensBridge, bridgeExecutor, l2CrossDomainMessenger } = ctx.l2; assert.isFalse( - await l2ERC20TokenBridge.hasRole( + await l2ERC20ExtendedTokensBridge.hasRole( BridgingManagerRole.DEPOSITS_ENABLER_ROLE.hash, bridgeExecutor.address ) ); assert.isFalse( - await l2ERC20TokenBridge.hasRole( + await l2ERC20ExtendedTokensBridge.hasRole( BridgingManagerRole.WITHDRAWALS_ENABLER_ROLE.hash, bridgeExecutor.address ) ); - assert.isFalse(await l2ERC20TokenBridge.isDepositsEnabled()); - assert.isFalse(await l2ERC20TokenBridge.isWithdrawalsEnabled()); + assert.isFalse(await l2ERC20ExtendedTokensBridge.isDepositsEnabled()); + assert.isFalse(await l2ERC20ExtendedTokensBridge.isWithdrawalsEnabled()); const actionsSetCountBefore = await bridgeExecutor.getActionsSetCount(); @@ -44,7 +49,7 @@ scenario("Optimism :: Bridge Executor integration test", ctxFactory) 0, 300_000, bridgeExecutor.interface.encodeFunctionData("queue", [ - new Array(4).fill(l2ERC20TokenBridge.address), + new Array(4).fill(l2ERC20ExtendedTokensBridge.address), new Array(4).fill(0), [ "grantRole(bytes32,address)", @@ -54,25 +59,25 @@ scenario("Optimism :: Bridge Executor integration test", ctxFactory) ], [ "0x" + - l2ERC20TokenBridge.interface + l2ERC20ExtendedTokensBridge.interface .encodeFunctionData("grantRole", [ BridgingManagerRole.DEPOSITS_ENABLER_ROLE.hash, bridgeExecutor.address, ]) .substring(10), "0x" + - l2ERC20TokenBridge.interface + l2ERC20ExtendedTokensBridge.interface .encodeFunctionData("grantRole", [ BridgingManagerRole.WITHDRAWALS_ENABLER_ROLE.hash, bridgeExecutor.address, ]) .substring(10), "0x" + - l2ERC20TokenBridge.interface + l2ERC20ExtendedTokensBridge.interface .encodeFunctionData("enableDeposits") .substring(10), "0x" + - l2ERC20TokenBridge.interface + l2ERC20ExtendedTokensBridge.interface .encodeFunctionData("enableWithdrawals") .substring(10), ], @@ -89,33 +94,33 @@ scenario("Optimism :: Bridge Executor integration test", ctxFactory) await bridgeExecutor.execute(actionsSetCountAfter.sub(1), { value: 0 }); assert.isTrue( - await l2ERC20TokenBridge.hasRole( + await l2ERC20ExtendedTokensBridge.hasRole( BridgingManagerRole.DEPOSITS_ENABLER_ROLE.hash, bridgeExecutor.address ) ); assert.isTrue( - await l2ERC20TokenBridge.hasRole( + await l2ERC20ExtendedTokensBridge.hasRole( BridgingManagerRole.WITHDRAWALS_ENABLER_ROLE.hash, bridgeExecutor.address ) ); - assert.isTrue(await l2ERC20TokenBridge.isDepositsEnabled()); - assert.isTrue(await l2ERC20TokenBridge.isWithdrawalsEnabled()); + assert.isTrue(await l2ERC20ExtendedTokensBridge.isDepositsEnabled()); + assert.isTrue(await l2ERC20ExtendedTokensBridge.isWithdrawalsEnabled()); }) .step("Change Proxy implementation", async (ctx) => { const { l2Token, l2CrossDomainMessenger, - l2ERC20TokenBridgeProxy, + l2ERC20ExtendedTokensBridgeProxy, bridgeExecutor, } = ctx.l2; const actionsSetCountBefore = await bridgeExecutor.getActionsSetCount(); const proxyImplBefore = - await l2ERC20TokenBridgeProxy.proxy__getImplementation(); + await l2ERC20ExtendedTokensBridgeProxy.proxy__getImplementation(); await l2CrossDomainMessenger.relayMessage( 0, @@ -124,12 +129,12 @@ scenario("Optimism :: Bridge Executor integration test", ctxFactory) 0, 300_000, bridgeExecutor.interface.encodeFunctionData("queue", [ - [l2ERC20TokenBridgeProxy.address], + [l2ERC20ExtendedTokensBridgeProxy.address], [0], ["proxy__upgradeTo(address)"], [ "0x" + - l2ERC20TokenBridgeProxy.interface + l2ERC20ExtendedTokensBridgeProxy.interface .encodeFunctionData("proxy__upgradeTo", [l2Token.address]) .substring(10), ], @@ -143,7 +148,7 @@ scenario("Optimism :: Bridge Executor integration test", ctxFactory) await bridgeExecutor.execute(actionsSetCountBefore, { value: 0 }); const proxyImplAfter = - await l2ERC20TokenBridgeProxy.proxy__getImplementation(); + await l2ERC20ExtendedTokensBridgeProxy.proxy__getImplementation(); assert.notEqual(proxyImplBefore, proxyImplAfter); assert.equal(proxyImplAfter, l2Token.address); @@ -152,14 +157,14 @@ scenario("Optimism :: Bridge Executor integration test", ctxFactory) .step("Change proxy Admin", async (ctx) => { const { l2CrossDomainMessenger, - l2ERC20TokenBridgeProxy, + l2ERC20ExtendedTokensBridgeProxy, bridgeExecutor, accounts: { sender }, } = ctx.l2; const actionsSetCountBefore = await bridgeExecutor.getActionsSetCount(); - const proxyAdminBefore = await l2ERC20TokenBridgeProxy.proxy__getAdmin(); + const proxyAdminBefore = await l2ERC20ExtendedTokensBridgeProxy.proxy__getAdmin(); await l2CrossDomainMessenger.relayMessage( 0, @@ -168,12 +173,12 @@ scenario("Optimism :: Bridge Executor integration test", ctxFactory) 0, 300_000, bridgeExecutor.interface.encodeFunctionData("queue", [ - [l2ERC20TokenBridgeProxy.address], + [l2ERC20ExtendedTokensBridgeProxy.address], [0], ["proxy__changeAdmin(address)"], [ "0x" + - l2ERC20TokenBridgeProxy.interface + l2ERC20ExtendedTokensBridgeProxy.interface .encodeFunctionData("proxy__changeAdmin", [sender.address]) .substring(10), ], @@ -186,7 +191,7 @@ scenario("Optimism :: Bridge Executor integration test", ctxFactory) assert.equalBN(actionsSetCountBefore.add(1), actionSetCount); await bridgeExecutor.execute(actionsSetCountBefore, { value: 0 }); - const proxyAdminAfter = await l2ERC20TokenBridgeProxy.proxy__getAdmin(); + const proxyAdminAfter = await l2ERC20ExtendedTokensBridgeProxy.proxy__getAdmin(); assert.notEqual(proxyAdminBefore, proxyAdminAfter); assert.equal(proxyAdminAfter, sender.address); @@ -200,7 +205,14 @@ async function ctxFactory() { .multichain(["eth", "opt"], networkName) .getProviders({ forking: true }); - const testingOnDeployedContracts = testing.env.USE_DEPLOYED_CONTRACTS(false); + const tokenRateDecimals = BigNumber.from(27); + const totalPooledEther = BigNumber.from('9309904612343950493629678'); + const totalShares = BigNumber.from('7975822843597609202337218'); + const maxAllowedL2ToL1ClockLag = BigNumber.from(86400); + const maxAllowedTokenRateDeviationPerDay = BigNumber.from(500); + const oldestRateAllowedInPauseTimeSpan = BigNumber.from(86400*3); + const maxAllowedTimeBetweenTokenRateUpdates = BigNumber.from(3600); + const exchangeRate = getExchangeRate(tokenRateDecimals, totalPooledEther, totalShares); const l1Deployer = testing.accounts.deployer(l1Provider); const l2Deployer = testing.accounts.deployer(l2Provider); @@ -212,7 +224,18 @@ async function ctxFactory() { "TT" ); + const l1TokenRebasable = await new ERC20WrapperStub__factory(l1Deployer).deploy( + l1Token.address, + "Test Token", + "TT", + totalPooledEther, + totalShares + ); + + const accountingOracle = await new AccountingOracleStub__factory(l1Deployer).deploy(1,2,3); + const optAddresses = optimism.addresses(networkName); + const testingOnDeployedContracts = testing.env.USE_DEPLOYED_CONTRACTS(false); const govBridgeExecutor = testingOnDeployedContracts ? OptimismBridgeExecutor__factory.connect( @@ -229,35 +252,64 @@ async function ctxFactory() { const l1EthGovExecutorAddress = await govBridgeExecutor.getEthereumGovernanceExecutor(); - const [, l2DeployScript] = await optimism - .deployment(networkName) - .erc20TokenBridgeDeployScript( - l1Token.address, - { - deployer: l1Deployer, - admins: { proxy: l1Deployer.address, bridge: l1Deployer.address }, + const [, optDeployScript] = await deploymentAll( + networkName + ).deployAllScript( + { + l1TokenNonRebasable: l1Token.address, + l1TokenRebasable: l1TokenRebasable.address, + accountingOracle: accountingOracle.address, + l2GasLimitForPushingTokenRate: BigNumber.from(300_000), + deployer: l1Deployer, + admins: { + proxy: l1Deployer.address, + bridge: l1Deployer.address }, - { - deployer: l2Deployer, - admins: { - proxy: govBridgeExecutor.address, - bridge: govBridgeExecutor.address, - }, - } - ); + contractsShift: 0, + }, + { + tokenRateOracle: { + tokenRateOutdatedDelay: BigNumber.from(1000), + maxAllowedL2ToL1ClockLag: maxAllowedL2ToL1ClockLag, + maxAllowedTokenRateDeviationPerDayBp: maxAllowedTokenRateDeviationPerDay, + oldestRateAllowedInPauseTimeSpan: oldestRateAllowedInPauseTimeSpan, + maxAllowedTimeBetweenTokenRateUpdates: maxAllowedTimeBetweenTokenRateUpdates, + tokenRate: exchangeRate, + l1Timestamp: BigNumber.from('1000') + }, + l2TokenNonRebasable: { + name: "wstETH", + symbol: "WST", + version: "1", + decimals: 18 + }, + l2TokenRebasable: { + name: "stETH", + symbol: "ST", + version: "1", + decimals: 18 + }, + deployer: l2Deployer, + admins: { + proxy: govBridgeExecutor.address, + bridge: govBridgeExecutor.address, + }, + contractsShift: 0, + } + ); - await l2DeployScript.run(); + await optDeployScript.run(); - const l2Token = ERC20Bridged__factory.connect( - l2DeployScript.getContractAddress(1), + const l2Token = ERC20BridgedPermit__factory.connect( + optDeployScript.tokenProxyAddress, l2Deployer ); - const l2ERC20TokenBridge = L2ERC20TokenBridge__factory.connect( - l2DeployScript.getContractAddress(3), + const l2ERC20ExtendedTokensBridge = L2ERC20ExtendedTokensBridge__factory.connect( + optDeployScript.tokenBridgeProxyAddress, l2Deployer ); - const l2ERC20TokenBridgeProxy = OssifiableProxy__factory.connect( - l2DeployScript.getContractAddress(3), + const l2ERC20ExtendedTokensBridgeProxy = OssifiableProxy__factory.connect( + optDeployScript.tokenBridgeProxyAddress, l2Deployer ); @@ -291,9 +343,9 @@ async function ctxFactory() { l2: { l2Token, bridgeExecutor: govBridgeExecutor.connect(l2Deployer), - l2ERC20TokenBridge, + l2ERC20ExtendedTokensBridge, l2CrossDomainMessenger, - l2ERC20TokenBridgeProxy, + l2ERC20ExtendedTokensBridgeProxy, accounts: { sender: testing.accounts.sender(l2Provider), admin: l2Deployer, diff --git a/test/bridging-manager/BridgingManager.unit.test.ts b/test/bridging-manager/BridgingManager.unit.test.ts index a74566bb..5584b50f 100644 --- a/test/bridging-manager/BridgingManager.unit.test.ts +++ b/test/bridging-manager/BridgingManager.unit.test.ts @@ -1,6 +1,6 @@ import hre from "hardhat"; import { - BridgingManager__factory, + BridgingManagerStub__factory, OssifiableProxy__factory, } from "../../typechain"; import { assert } from "chai"; @@ -301,12 +301,13 @@ async function ctxFactory() { depositsEnabler, depositsDisabler, withdrawalsEnabler, - withdrawalsDisabler, + withdrawalsDisabler ] = await hre.ethers.getSigners(); - const bridgingManagerImpl = await new BridgingManager__factory( + const bridgingManagerImpl = await new BridgingManagerStub__factory( deployer ).deploy(); + const pureOssifiableProxy = await new OssifiableProxy__factory( deployer ).deploy(bridgingManagerImpl.address, deployer.address, "0x"); @@ -314,7 +315,7 @@ async function ctxFactory() { deployer ).deploy(bridgingManagerImpl.address, deployer.address, "0x"); - const bridgingManager = BridgingManager__factory.connect( + const bridgingManager = BridgingManagerStub__factory.connect( initializedOssifiableProxy.address, deployer ); @@ -367,7 +368,7 @@ async function ctxFactory() { withdrawalsDisabler, }, bridgingManager, - bridgingManagerRaw: BridgingManager__factory.connect( + bridgingManagerRaw: BridgingManagerStub__factory.connect( pureOssifiableProxy.address, deployer ), diff --git a/test/optimism/L1ERC20TokenBridge.unit.test.ts b/test/optimism/L1ERC20TokenBridge.unit.test.ts deleted file mode 100644 index 09aeefa2..00000000 --- a/test/optimism/L1ERC20TokenBridge.unit.test.ts +++ /dev/null @@ -1,541 +0,0 @@ -import { assert } from "chai"; -import hre, { ethers } from "hardhat"; -import { - ERC20BridgedStub__factory, - L1ERC20TokenBridge__factory, - L2ERC20TokenBridge__factory, - OssifiableProxy__factory, - EmptyContractStub__factory, -} from "../../typechain"; -import { CrossDomainMessengerStub__factory } from "../../typechain/factories/CrossDomainMessengerStub__factory"; -import testing, { unit } from "../../utils/testing"; -import { wei } from "../../utils/wei"; - -unit("Optimism :: L1ERC20TokenBridge", ctxFactory) - .test("l2TokenBridge()", async (ctx) => { - assert.equal( - await ctx.l1TokenBridge.l2TokenBridge(), - ctx.accounts.l2TokenBridgeEOA.address - ); - }) - - .test("depositERC20() :: deposits disabled", async (ctx) => { - await ctx.l1TokenBridge.disableDeposits(); - - assert.isFalse(await ctx.l1TokenBridge.isDepositsEnabled()); - - await assert.revertsWith( - ctx.l1TokenBridge.depositERC20( - ctx.stubs.l1Token.address, - ctx.stubs.l2Token.address, - wei`1 ether`, - wei`1 gwei`, - "0x" - ), - "ErrorDepositsDisabled()" - ); - }) - - .test("depositsERC20() :: wrong l1Token address", async (ctx) => { - await assert.revertsWith( - ctx.l1TokenBridge.depositERC20( - ctx.accounts.stranger.address, - ctx.stubs.l2Token.address, - wei`1 ether`, - wei`1 gwei`, - "0x" - ), - "ErrorUnsupportedL1Token()" - ); - }) - - .test("depositsERC20() :: wrong l2Token address", async (ctx) => { - await assert.revertsWith( - ctx.l1TokenBridge.depositERC20( - ctx.stubs.l1Token.address, - ctx.accounts.stranger.address, - wei`1 ether`, - wei`1 gwei`, - "0x" - ), - "ErrorUnsupportedL2Token()" - ); - }) - - .test("depositERC20() :: not from EOA", async (ctx) => { - await assert.revertsWith( - ctx.l1TokenBridge - .connect(ctx.accounts.emptyContractAsEOA) - .depositERC20( - ctx.stubs.l1Token.address, - ctx.stubs.l2Token.address, - wei`1 ether`, - wei`1 gwei`, - "0x" - ), - "ErrorSenderNotEOA()" - ); - }) - - .test("depositERC20()", async (ctx) => { - const { - l1TokenBridge, - accounts: { deployer, l2TokenBridgeEOA }, - stubs: { l1Token, l2Token, l1Messenger }, - } = ctx; - - const l2Gas = wei`0.99 wei`; - const amount = wei`1 ether`; - const data = "0xdeadbeaf"; - - await l1Token.approve(l1TokenBridge.address, amount); - - const deployerBalanceBefore = await l1Token.balanceOf(deployer.address); - const bridgeBalanceBefore = await l1Token.balanceOf(l1TokenBridge.address); - - const tx = await l1TokenBridge.depositERC20( - l1Token.address, - l2Token.address, - amount, - l2Gas, - data - ); - - await assert.emits(l1TokenBridge, tx, "ERC20DepositInitiated", [ - l1Token.address, - l2Token.address, - deployer.address, - deployer.address, - amount, - data, - ]); - - await assert.emits(l1Messenger, tx, "SentMessage", [ - l2TokenBridgeEOA.address, - l1TokenBridge.address, - L2ERC20TokenBridge__factory.createInterface().encodeFunctionData( - "finalizeDeposit", - [ - l1Token.address, - l2Token.address, - deployer.address, - deployer.address, - amount, - data, - ] - ), - 1, // message nonce - l2Gas, - ]); - - assert.equalBN( - await l1Token.balanceOf(deployer.address), - deployerBalanceBefore.sub(amount) - ); - - assert.equalBN( - await l1Token.balanceOf(l1TokenBridge.address), - bridgeBalanceBefore.add(amount) - ); - }) - - .test("depositERC20To() :: deposits disabled", async (ctx) => { - const { - l1TokenBridge, - stubs: { l1Token, l2Token }, - accounts: { recipient }, - } = ctx; - await l1TokenBridge.disableDeposits(); - - assert.isFalse(await l1TokenBridge.isDepositsEnabled()); - - await assert.revertsWith( - l1TokenBridge.depositERC20To( - l1Token.address, - l2Token.address, - recipient.address, - wei`1 ether`, - wei`1 gwei`, - "0x" - ), - "ErrorDepositsDisabled()" - ); - }) - - .test("depositsERC20To() :: wrong l1Token address", async (ctx) => { - const { - l1TokenBridge, - stubs: { l2Token }, - accounts: { recipient, stranger }, - } = ctx; - await l1TokenBridge.disableDeposits(); - - assert.isFalse(await l1TokenBridge.isDepositsEnabled()); - - await assert.revertsWith( - l1TokenBridge.depositERC20To( - stranger.address, - l2Token.address, - recipient.address, - wei`1 ether`, - wei`1 gwei`, - "0x" - ), - "ErrorDepositsDisabled()" - ); - }) - - .test("depositsERC20To() :: wrong l2Token address", async (ctx) => { - const { - l1TokenBridge, - stubs: { l1Token }, - accounts: { recipient, stranger }, - } = ctx; - await l1TokenBridge.disableDeposits(); - - assert.isFalse(await l1TokenBridge.isDepositsEnabled()); - - await assert.revertsWith( - l1TokenBridge.depositERC20To( - l1Token.address, - stranger.address, - recipient.address, - wei`1 ether`, - wei`1 gwei`, - "0x" - ), - "ErrorDepositsDisabled()" - ); - }) - - .test("depositsERC20To() :: recipient is zero address", async (ctx) => { - const { - l1TokenBridge, - stubs: { l1Token }, - accounts: { stranger }, - } = ctx; - - await assert.revertsWith( - l1TokenBridge.depositERC20To( - l1Token.address, - stranger.address, - ethers.constants.AddressZero, - wei`1 ether`, - wei`1 gwei`, - "0x" - ), - "ErrorAccountIsZeroAddress()" - ); - }) - - .test("depositERC20To()", async (ctx) => { - const { - l1TokenBridge, - accounts: { deployer, l2TokenBridgeEOA, recipient }, - stubs: { l1Token, l2Token, l1Messenger }, - } = ctx; - - const l2Gas = wei`0.99 wei`; - const amount = wei`1 ether`; - const data = "0x"; - - await l1Token.approve(l1TokenBridge.address, amount); - - const deployerBalanceBefore = await l1Token.balanceOf(deployer.address); - const bridgeBalanceBefore = await l1Token.balanceOf(l1TokenBridge.address); - - const tx = await l1TokenBridge.depositERC20To( - l1Token.address, - l2Token.address, - recipient.address, - amount, - l2Gas, - data - ); - - await assert.emits(l1TokenBridge, tx, "ERC20DepositInitiated", [ - l1Token.address, - l2Token.address, - deployer.address, - recipient.address, - amount, - data, - ]); - - await assert.emits(l1Messenger, tx, "SentMessage", [ - l2TokenBridgeEOA.address, - l1TokenBridge.address, - L2ERC20TokenBridge__factory.createInterface().encodeFunctionData( - "finalizeDeposit", - [ - l1Token.address, - l2Token.address, - deployer.address, - recipient.address, - amount, - data, - ] - ), - 1, // message nonce - l2Gas, - ]); - - assert.equalBN( - await l1Token.balanceOf(deployer.address), - deployerBalanceBefore.sub(amount) - ); - - assert.equalBN( - await l1Token.balanceOf(l1TokenBridge.address), - bridgeBalanceBefore.add(amount) - ); - }) - - .test( - "finalizeERC20Withdrawal() :: withdrawals are disabled", - async (ctx) => { - const { - l1TokenBridge, - stubs: { l1Token, l2Token }, - accounts: { deployer, recipient, l2TokenBridgeEOA }, - } = ctx; - await l1TokenBridge.disableWithdrawals(); - - assert.isFalse(await l1TokenBridge.isWithdrawalsEnabled()); - - await assert.revertsWith( - l1TokenBridge - .connect(l2TokenBridgeEOA) - .finalizeERC20Withdrawal( - l1Token.address, - l2Token.address, - deployer.address, - recipient.address, - wei`1 ether`, - "0x" - ), - "ErrorWithdrawalsDisabled()" - ); - } - ) - - .test("finalizeERC20Withdrawal() :: wrong l1Token", async (ctx) => { - const { - l1TokenBridge, - stubs: { l2Token }, - accounts: { deployer, recipient, l2TokenBridgeEOA, stranger }, - } = ctx; - - await assert.revertsWith( - l1TokenBridge - .connect(l2TokenBridgeEOA) - .finalizeERC20Withdrawal( - stranger.address, - l2Token.address, - deployer.address, - recipient.address, - wei`1 ether`, - "0x" - ), - "ErrorUnsupportedL1Token()" - ); - }) - - .test("finalizeERC20Withdrawal() :: wrong l2Token", async (ctx) => { - const { - l1TokenBridge, - stubs: { l1Token }, - accounts: { deployer, recipient, l2TokenBridgeEOA, stranger }, - } = ctx; - - await assert.revertsWith( - l1TokenBridge - .connect(l2TokenBridgeEOA) - .finalizeERC20Withdrawal( - l1Token.address, - stranger.address, - deployer.address, - recipient.address, - wei`1 ether`, - "0x" - ), - "ErrorUnsupportedL2Token()" - ); - }) - - .test("finalizeERC20Withdrawal() :: unauthorized messenger", async (ctx) => { - const { - l1TokenBridge, - stubs: { l1Token, l2Token }, - accounts: { deployer, recipient, stranger }, - } = ctx; - - await assert.revertsWith( - l1TokenBridge - .connect(stranger) - .finalizeERC20Withdrawal( - l1Token.address, - l2Token.address, - deployer.address, - recipient.address, - wei`1 ether`, - "0x" - ), - "ErrorUnauthorizedMessenger()" - ); - }) - - .test( - "finalizeERC20Withdrawal() :: wrong cross domain sender", - async (ctx) => { - const { - l1TokenBridge, - stubs: { l1Token, l2Token, l1Messenger }, - accounts: { deployer, recipient, stranger, l1MessengerStubAsEOA }, - } = ctx; - - await l1Messenger.setXDomainMessageSender(stranger.address); - - await assert.revertsWith( - l1TokenBridge - .connect(l1MessengerStubAsEOA) - .finalizeERC20Withdrawal( - l1Token.address, - l2Token.address, - deployer.address, - recipient.address, - wei`1 ether`, - "0x" - ), - "ErrorWrongCrossDomainSender()" - ); - } - ) - - .test("finalizeERC20Withdrawal()", async (ctx) => { - const { - l1TokenBridge, - stubs: { l1Token, l2Token, l1Messenger }, - accounts: { deployer, recipient, l1MessengerStubAsEOA, l2TokenBridgeEOA }, - } = ctx; - - await l1Messenger.setXDomainMessageSender(l2TokenBridgeEOA.address); - - const bridgeBalanceBefore = await l1Token.balanceOf(l1TokenBridge.address); - - const amount = wei`1 ether`; - const data = "0xdeadbeaf"; - - const tx = await l1TokenBridge - .connect(l1MessengerStubAsEOA) - .finalizeERC20Withdrawal( - l1Token.address, - l2Token.address, - deployer.address, - recipient.address, - amount, - data - ); - - await assert.emits(l1TokenBridge, tx, "ERC20WithdrawalFinalized", [ - l1Token.address, - l2Token.address, - deployer.address, - recipient.address, - amount, - data, - ]); - - assert.equalBN(await l1Token.balanceOf(recipient.address), amount); - assert.equalBN( - await l1Token.balanceOf(l1TokenBridge.address), - bridgeBalanceBefore.sub(amount) - ); - }) - - .run(); - -async function ctxFactory() { - const [deployer, l2TokenBridgeEOA, stranger, recipient] = - await hre.ethers.getSigners(); - - const l1MessengerStub = await new CrossDomainMessengerStub__factory( - deployer - ).deploy({ value: wei.toBigNumber(wei`1 ether`) }); - - const l1TokenStub = await new ERC20BridgedStub__factory(deployer).deploy( - "L1 Token", - "L1" - ); - - const l2TokenStub = await new ERC20BridgedStub__factory(deployer).deploy( - "L2 Token", - "L2" - ); - - const emptyContract = await new EmptyContractStub__factory(deployer).deploy({ - value: wei.toBigNumber(wei`1 ether`), - }); - const emptyContractAsEOA = await testing.impersonate(emptyContract.address); - - const l1MessengerStubAsEOA = await testing.impersonate( - l1MessengerStub.address - ); - - const l1TokenBridgeImpl = await new L1ERC20TokenBridge__factory( - deployer - ).deploy( - l1MessengerStub.address, - l2TokenBridgeEOA.address, - l1TokenStub.address, - l2TokenStub.address - ); - - const l1TokenBridgeProxy = await new OssifiableProxy__factory( - deployer - ).deploy( - l1TokenBridgeImpl.address, - deployer.address, - l1TokenBridgeImpl.interface.encodeFunctionData("initialize", [ - deployer.address, - ]) - ); - - const l1TokenBridge = L1ERC20TokenBridge__factory.connect( - l1TokenBridgeProxy.address, - deployer - ); - - await l1TokenStub.transfer(l1TokenBridge.address, wei`100 ether`); - - const roles = await Promise.all([ - l1TokenBridge.DEPOSITS_ENABLER_ROLE(), - l1TokenBridge.DEPOSITS_DISABLER_ROLE(), - l1TokenBridge.WITHDRAWALS_ENABLER_ROLE(), - l1TokenBridge.WITHDRAWALS_DISABLER_ROLE(), - ]); - - for (const role of roles) { - await l1TokenBridge.grantRole(role, deployer.address); - } - - await l1TokenBridge.enableDeposits(); - await l1TokenBridge.enableWithdrawals(); - - return { - accounts: { - deployer, - stranger, - l2TokenBridgeEOA, - emptyContractAsEOA, - recipient, - l1MessengerStubAsEOA, - }, - stubs: { - l1Token: l1TokenStub, - l2Token: l2TokenStub, - l1Messenger: l1MessengerStub, - }, - l1TokenBridge, - }; -} diff --git a/test/optimism/L1LidoTokensBridge.unit.test.ts b/test/optimism/L1LidoTokensBridge.unit.test.ts new file mode 100644 index 00000000..4ddf4304 --- /dev/null +++ b/test/optimism/L1LidoTokensBridge.unit.test.ts @@ -0,0 +1,1427 @@ +import { assert } from "chai"; +import hre, { ethers } from "hardhat"; +import { BigNumber } from "ethers"; +import { + ERC20BridgedStub__factory, + ERC20WrapperStub__factory, + L1LidoTokensBridge__factory, + BridgingManagerStub__factory, + L2ERC20ExtendedTokensBridge__factory, + OssifiableProxy__factory, + EmptyContractStub__factory, + AccountingOracleStub__factory, + L1LidoTokensBridge +} from "../../typechain"; +import { CrossDomainMessengerStub__factory } from "../../typechain/factories/CrossDomainMessengerStub__factory"; +import testing, { unit } from "../../utils/testing"; +import { wei } from "../../utils/wei"; +import { SignerWithAddress } from "@nomiclabs/hardhat-ethers/signers"; +import { tokenRateAndTimestampPacked, refSlotTimestamp, getExchangeRate } from "../../utils/testing/helpers"; + +unit("Optimism :: L1LidoTokensBridge", ctxFactory) + + .test("initial state", async (ctx) => { + assert.equal(await ctx.l1TokenBridge.l2TokenBridge(), ctx.accounts.l2TokenBridgeEOA.address); + assert.equal(await ctx.l1TokenBridge.MESSENGER(), ctx.accounts.l1MessengerStubAsEOA._address); + assert.equal(await ctx.l1TokenBridge.L1_TOKEN_NON_REBASABLE(), ctx.stubs.l1TokenNonRebasable.address); + assert.equal(await ctx.l1TokenBridge.L1_TOKEN_REBASABLE(), ctx.stubs.l1TokenRebasable.address); + assert.equal(await ctx.l1TokenBridge.L2_TOKEN_NON_REBASABLE(), ctx.stubs.l2TokenNonRebasable.address); + assert.equal(await ctx.l1TokenBridge.L2_TOKEN_REBASABLE(), ctx.stubs.l2TokenRebasable.address); + }) + + .test("constructor() :: zero params", async (ctx) => { + + const { deployer, stranger, zero } = ctx.accounts; + + await assert.revertsWith(new L1LidoTokensBridge__factory( + deployer + ).deploy( + zero.address, + stranger.address, + stranger.address, + stranger.address, + stranger.address, + stranger.address, + stranger.address + ), "ErrorZeroAddressMessenger()"); + + await assert.revertsWith(new L1LidoTokensBridge__factory( + deployer + ).deploy( + stranger.address, + zero.address, + stranger.address, + stranger.address, + stranger.address, + stranger.address, + stranger.address + ), "ErrorZeroAddressL2Bridge()"); + + await assert.revertsWith(new L1LidoTokensBridge__factory( + deployer + ).deploy( + stranger.address, + stranger.address, + zero.address, + stranger.address, + stranger.address, + stranger.address, + stranger.address + ), "ErrorZeroAddressL1TokenNonRebasable()"); + + await assert.revertsWith(new L1LidoTokensBridge__factory( + deployer + ).deploy( + stranger.address, + stranger.address, + stranger.address, + zero.address, + stranger.address, + stranger.address, + stranger.address + ), "ErrorZeroAddressL1TokenRebasable()"); + + await assert.revertsWith(new L1LidoTokensBridge__factory( + deployer + ).deploy( + stranger.address, + stranger.address, + stranger.address, + stranger.address, + zero.address, + stranger.address, + stranger.address + ), "ErrorZeroAddressL2TokenNonRebasable()"); + + await assert.revertsWith(new L1LidoTokensBridge__factory( + deployer + ).deploy( + stranger.address, + stranger.address, + stranger.address, + stranger.address, + stranger.address, + zero.address, + stranger.address + ), "ErrorZeroAddressL2TokenRebasable()"); + + await assert.revertsWith(new L1LidoTokensBridge__factory( + deployer + ).deploy( + stranger.address, + stranger.address, + stranger.address, + stranger.address, + stranger.address, + stranger.address, + zero.address, + ), "ErrorZeroAddressAccountingOracle()"); + }) + + .test("initialize() :: petrified", async (ctx) => { + const { deployer, l2TokenBridgeEOA } = ctx.accounts; + const { + totalPooledEther, + totalShares, + genesisTime, + secondsPerSlot, + lastProcessingRefSlot + } = ctx.constants; + + const { l1TokenBridgeImpl } = await getL1LidoTokensBridgeImpl( + totalPooledEther, + totalShares, + genesisTime, + secondsPerSlot, + lastProcessingRefSlot, + deployer, + l2TokenBridgeEOA.address + ); + + const petrifiedVersionMark = hre.ethers.constants.MaxUint256; + assert.equalBN(await l1TokenBridgeImpl.getContractVersion(), petrifiedVersionMark); + + await assert.revertsWith( + l1TokenBridgeImpl.initialize(deployer.address), + "NonZeroContractVersionOnInit()" + ); + }) + + .test("initialize() :: zero address L2 bridge", async (ctx) => { + const { deployer } = ctx.accounts; + const { + totalPooledEther, + totalShares, + genesisTime, + secondsPerSlot, + lastProcessingRefSlot + } = ctx.constants; + + await assert.revertsWith( + getL1LidoTokensBridgeImpl( + totalPooledEther, + totalShares, + genesisTime, + secondsPerSlot, + lastProcessingRefSlot, + deployer, + hre.ethers.constants.AddressZero + ), + "ErrorZeroAddressL2Bridge()" + ); + }) + + .test("initialize() :: revert when admin is zero", async (ctx) => { + const { deployer, l2TokenBridgeEOA, zero } = ctx.accounts; + const { + totalPooledEther, + totalShares, + genesisTime, + secondsPerSlot, + lastProcessingRefSlot + } = ctx.constants; + + const { l1TokenBridgeImpl } = await getL1LidoTokensBridgeImpl( + totalPooledEther, + totalShares, + genesisTime, + secondsPerSlot, + lastProcessingRefSlot, + deployer, + l2TokenBridgeEOA.address + ); + + await assert.revertsWith(new OssifiableProxy__factory( + deployer + ).deploy( + l1TokenBridgeImpl.address, + deployer.address, + l1TokenBridgeImpl.interface.encodeFunctionData("initialize", [ + zero.address + ]) + ), "ErrorZeroAddressAdmin()"); + }) + + .test("initialize() :: don't allow to initialize twice", async (ctx) => { + const { deployer, l2TokenBridgeEOA } = ctx.accounts; + const { + totalPooledEther, + totalShares, + genesisTime, + secondsPerSlot, + lastProcessingRefSlot + } = ctx.constants; + + const { l1TokenBridgeImpl } = await getL1LidoTokensBridgeImpl( + totalPooledEther, + totalShares, + genesisTime, + secondsPerSlot, + lastProcessingRefSlot, + deployer, + l2TokenBridgeEOA.address + ); + + const l1TokenBridgeProxy = await new OssifiableProxy__factory( + deployer + ).deploy( + l1TokenBridgeImpl.address, + deployer.address, + l1TokenBridgeImpl.interface.encodeFunctionData("initialize", [ + deployer.address + ]) + ); + + const l1TokenBridge = L1LidoTokensBridge__factory.connect( + l1TokenBridgeProxy.address, + deployer + ); + + assert.equalBN(await l1TokenBridge.getContractVersion(), 2); + + await assert.revertsWith( + l1TokenBridge.initialize(deployer.address), + "NonZeroContractVersionOnInit()" + ); + }) + + .test("finalizeUpgrade_v2() :: bridging manager uninitialized", async (ctx) => { + const { deployer, l2TokenBridgeEOA } = ctx.accounts; + const { + totalPooledEther, + totalShares, + genesisTime, + secondsPerSlot, + lastProcessingRefSlot + } = ctx.constants; + + const { l1TokenBridgeImpl } = await getL1LidoTokensBridgeImpl( + totalPooledEther, + totalShares, + genesisTime, + secondsPerSlot, + lastProcessingRefSlot, + deployer, + l2TokenBridgeEOA.address + ); + + await assert.revertsWith(new OssifiableProxy__factory(deployer).deploy( + l1TokenBridgeImpl.address, + deployer.address, + L1LidoTokensBridge__factory.createInterface().encodeFunctionData("finalizeUpgrade_v2") + ), "ErrorBridgingManagerIsNotInitialized()"); + }) + + .test("finalizeUpgrade_v2() :: bridging manager initialized", async (ctx) => { + const { deployer, l2TokenBridgeEOA } = ctx.accounts; + const { + totalPooledEther, + totalShares, + genesisTime, + secondsPerSlot, + lastProcessingRefSlot + } = ctx.constants; + + const bridgingManagerImpl = await new BridgingManagerStub__factory(deployer).deploy(); + const proxy = await new OssifiableProxy__factory(deployer).deploy( + bridgingManagerImpl.address, + deployer.address, + BridgingManagerStub__factory.createInterface().encodeFunctionData("initialize", [ + deployer.address + ]) + ); + + const { l1TokenBridgeImpl } = await getL1LidoTokensBridgeImpl( + totalPooledEther, + totalShares, + genesisTime, + secondsPerSlot, + lastProcessingRefSlot, + deployer, + l2TokenBridgeEOA.address + ); + + await proxy.proxy__upgradeToAndCall( + l1TokenBridgeImpl.address, + L1LidoTokensBridge__factory.createInterface().encodeFunctionData("finalizeUpgrade_v2"), + false + ); + + const l1LidoTokensBridgeProxied = L1LidoTokensBridge__factory.connect( + proxy.address, + deployer + ); + + assert.equalBN(await l1LidoTokensBridgeProxied.getContractVersion(), 2); + }) + + .test("depositERC20() :: deposits disabled", async (ctx) => { + await ctx.l1TokenBridge.disableDeposits(); + + assert.isFalse(await ctx.l1TokenBridge.isDepositsEnabled()); + + await assert.revertsWith( + ctx.l1TokenBridge.depositERC20( + ctx.stubs.l1TokenNonRebasable.address, + ctx.stubs.l2TokenNonRebasable.address, + wei`1 ether`, + wei`1 gwei`, + "0x" + ), + "ErrorDepositsDisabled()" + ); + + await assert.revertsWith( + ctx.l1TokenBridge.depositERC20( + ctx.stubs.l1TokenRebasable.address, + ctx.stubs.l2TokenRebasable.address, + wei`1 ether`, + wei`1 gwei`, + "0x" + ), + "ErrorDepositsDisabled()" + ); + }) + + .test("depositERC20() :: wrong l1Token address", async (ctx) => { + await assert.revertsWith( + ctx.l1TokenBridge.depositERC20( + ctx.accounts.stranger.address, + ctx.stubs.l2TokenNonRebasable.address, + wei`1 ether`, + wei`1 gwei`, + "0x" + ), + "ErrorUnsupportedL1L2TokensPair(\"" + ctx.accounts.stranger.address + "\", \"" + ctx.stubs.l2TokenNonRebasable.address + "\")" + ); + await assert.revertsWith( + ctx.l1TokenBridge.depositERC20( + ctx.accounts.stranger.address, + ctx.stubs.l2TokenRebasable.address, + wei`1 ether`, + wei`1 gwei`, + "0x" + ), + "ErrorUnsupportedL1L2TokensPair(\"" + ctx.accounts.stranger.address + "\", \"" + ctx.stubs.l2TokenRebasable.address + "\")" + ); + }) + + .test("depositERC20() :: wrong l2Token address", async (ctx) => { + await assert.revertsWith( + ctx.l1TokenBridge.depositERC20( + ctx.stubs.l1TokenNonRebasable.address, + ctx.accounts.stranger.address, + wei`1 ether`, + wei`1 gwei`, + "0x" + ), + "ErrorUnsupportedL1L2TokensPair(\"" + ctx.stubs.l1TokenNonRebasable.address + "\", \"" + ctx.accounts.stranger.address + "\")" + ); + await assert.revertsWith( + ctx.l1TokenBridge.depositERC20( + ctx.stubs.l1TokenRebasable.address, + ctx.accounts.stranger.address, + wei`1 ether`, + wei`1 gwei`, + "0x" + ), + "ErrorUnsupportedL1L2TokensPair(\"" + ctx.stubs.l1TokenRebasable.address + "\", \"" + ctx.accounts.stranger.address + "\")" + ); + }) + + .test("depositERC20() :: wrong tokens combination", async (ctx) => { + await assert.revertsWith( + ctx.l1TokenBridge.depositERC20( + ctx.stubs.l1TokenRebasable.address, + ctx.stubs.l2TokenNonRebasable.address, + wei`1 ether`, + wei`1 gwei`, + "0x" + ), + "ErrorUnsupportedL1L2TokensPair(\"" + ctx.stubs.l1TokenRebasable.address + "\", \"" + ctx.stubs.l2TokenNonRebasable.address + "\")" + ); + await assert.revertsWith( + ctx.l1TokenBridge.depositERC20( + ctx.stubs.l1TokenNonRebasable.address, + ctx.stubs.l2TokenRebasable.address, + wei`1 ether`, + wei`1 gwei`, + "0x" + ), + "ErrorUnsupportedL1L2TokensPair(\"" + ctx.stubs.l1TokenNonRebasable.address + "\", \"" + ctx.stubs.l2TokenRebasable.address + "\")" + ); + }) + + .test("depositERC20() :: not from EOA", async (ctx) => { + await assert.revertsWith( + ctx.l1TokenBridge + .connect(ctx.accounts.emptyContractAsEOA) + .depositERC20( + ctx.stubs.l1TokenNonRebasable.address, + ctx.stubs.l2TokenNonRebasable.address, + wei`1 ether`, + wei`1 gwei`, + "0x" + ), + "ErrorSenderNotEOA()" + ); + await assert.revertsWith( + ctx.l1TokenBridge + .connect(ctx.accounts.emptyContractAsEOA) + .depositERC20( + ctx.stubs.l1TokenRebasable.address, + ctx.stubs.l2TokenRebasable.address, + wei`1 ether`, + wei`1 gwei`, + "0x" + ), + "ErrorSenderNotEOA()" + ); + }) + + .test("depositERC20() :: non-rebasable token flow", async (ctx) => { + const { + l1TokenBridge, + accounts: { deployer, l2TokenBridgeEOA }, + stubs: { l1TokenNonRebasable, l2TokenNonRebasable, l1Messenger, accountingOracle }, + constants: { tokenRate } + } = ctx; + + const l2Gas = wei`0.99 wei`; + const amount = wei`1 ether`; + const data = "0xdeadbeaf"; + + await l1TokenNonRebasable.approve(l1TokenBridge.address, amount); + + const deployerBalanceBefore = await l1TokenNonRebasable.balanceOf(deployer.address); + const bridgeBalanceBefore = await l1TokenNonRebasable.balanceOf(l1TokenBridge.address); + + const tx = await l1TokenBridge.depositERC20( + l1TokenNonRebasable.address, + l2TokenNonRebasable.address, + amount, + l2Gas, + data + ); + + const refSlotTime = await refSlotTimestamp(accountingOracle); + const dataToReceive = await tokenRateAndTimestampPacked(tokenRate, refSlotTime, data); + + await assert.emits(l1TokenBridge, tx, "ERC20DepositInitiated", [ + l1TokenNonRebasable.address, + l2TokenNonRebasable.address, + deployer.address, + deployer.address, + amount, + dataToReceive, + ]); + + await assert.emits(l1Messenger, tx, "SentMessage", [ + l2TokenBridgeEOA.address, + l1TokenBridge.address, + L2ERC20ExtendedTokensBridge__factory.createInterface().encodeFunctionData( + "finalizeDeposit", + [ + l1TokenNonRebasable.address, + l2TokenNonRebasable.address, + deployer.address, + deployer.address, + amount, + dataToReceive, + ] + ), + 1, // message nonce + l2Gas, + ]); + + assert.equalBN( + await l1TokenNonRebasable.balanceOf(deployer.address), + deployerBalanceBefore.sub(amount) + ); + + assert.equalBN( + await l1TokenNonRebasable.balanceOf(l1TokenBridge.address), + bridgeBalanceBefore.add(amount) + ); + }) + + .test("depositERC20() :: rebasable token flow", async (ctx) => { + const { + l1TokenBridge, + constants: { tenPowerDecimals, tokenRate }, + accounts: { deployer, l2TokenBridgeEOA }, + stubs: { l1TokenRebasable, l2TokenRebasable, l1TokenNonRebasable, l1Messenger, accountingOracle }, + } = ctx; + + const l2Gas = wei`0.99 wei`; + const amount = wei`1 ether`; + const data = "0xdeadbeaf"; + const amountWrapped = (wei.toBigNumber(amount)).mul(tenPowerDecimals).div(tokenRate); + const deployerBalanceBefore = await l1TokenRebasable.balanceOf(deployer.address); + const bridgeBalanceBefore = await l1TokenNonRebasable.balanceOf(l1TokenBridge.address); + + await l1TokenRebasable.approve(l1TokenBridge.address, amount); + + const tx = await l1TokenBridge.depositERC20( + l1TokenRebasable.address, + l2TokenRebasable.address, + amount, + l2Gas, + data + ); + + const refSlotTime = await refSlotTimestamp(accountingOracle); + const dataToReceive = await tokenRateAndTimestampPacked(tokenRate, refSlotTime, data); + + await assert.emits(l1TokenBridge, tx, "ERC20DepositInitiated", [ + l1TokenRebasable.address, + l2TokenRebasable.address, + deployer.address, + deployer.address, + amount, + dataToReceive, + ]); + + await assert.emits(l1Messenger, tx, "SentMessage", [ + l2TokenBridgeEOA.address, + l1TokenBridge.address, + L2ERC20ExtendedTokensBridge__factory.createInterface().encodeFunctionData( + "finalizeDeposit", + [ + l1TokenRebasable.address, + l2TokenRebasable.address, + deployer.address, + deployer.address, + amountWrapped, + dataToReceive, + ] + ), + 1, // message nonce + l2Gas, + ]); + + assert.equalBN( + await l1TokenRebasable.balanceOf(deployer.address), + deployerBalanceBefore.sub(amount) + ); + + assert.equalBN( + await l1TokenNonRebasable.balanceOf(l1TokenBridge.address), + bridgeBalanceBefore.add(amountWrapped) + ); + }) + + .test("depositERC20To() :: deposits disabled", async (ctx) => { + const { + l1TokenBridge, + stubs: { l1TokenNonRebasable, l2TokenNonRebasable, l1TokenRebasable, l2TokenRebasable }, + accounts: { recipient }, + } = ctx; + await l1TokenBridge.disableDeposits(); + + assert.isFalse(await l1TokenBridge.isDepositsEnabled()); + + await assert.revertsWith( + l1TokenBridge.depositERC20To( + l1TokenNonRebasable.address, + l2TokenNonRebasable.address, + recipient.address, + wei`1 ether`, + wei`1 gwei`, + "0x" + ), + "ErrorDepositsDisabled()" + ); + + await assert.revertsWith( + l1TokenBridge.depositERC20To( + l1TokenRebasable.address, + l2TokenRebasable.address, + recipient.address, + wei`1 ether`, + wei`1 gwei`, + "0x" + ), + "ErrorDepositsDisabled()" + ); + }) + + .test("depositERC20To() :: wrong l1Token address", async (ctx) => { + const { + l1TokenBridge, + stubs: { l2TokenNonRebasable, l2TokenRebasable }, + accounts: { recipient, stranger }, + } = ctx; + + await assert.revertsWith( + l1TokenBridge.depositERC20To( + stranger.address, + l2TokenNonRebasable.address, + recipient.address, + wei`1 ether`, + wei`1 gwei`, + "0x" + ), + "ErrorUnsupportedL1L2TokensPair(\"" + stranger.address + "\", \"" + l2TokenNonRebasable.address + "\")" + ); + await assert.revertsWith( + l1TokenBridge.depositERC20To( + stranger.address, + l2TokenRebasable.address, + recipient.address, + wei`1 ether`, + wei`1 gwei`, + "0x" + ), + "ErrorUnsupportedL1L2TokensPair(\"" + stranger.address + "\", \"" + l2TokenRebasable.address + "\")" + ); + }) + + .test("depositERC20To() :: wrong l2Token address", async (ctx) => { + const { + l1TokenBridge, + stubs: { l1TokenNonRebasable, l1TokenRebasable }, + accounts: { recipient, stranger }, + } = ctx; + + await assert.revertsWith( + l1TokenBridge.depositERC20To( + l1TokenNonRebasable.address, + stranger.address, + recipient.address, + wei`1 ether`, + wei`1 gwei`, + "0x" + ), + "ErrorUnsupportedL1L2TokensPair(\"" + l1TokenNonRebasable.address + "\", \"" + stranger.address + "\")" + ); + await assert.revertsWith( + l1TokenBridge.depositERC20To( + l1TokenRebasable.address, + stranger.address, + recipient.address, + wei`1 ether`, + wei`1 gwei`, + "0x" + ), + "ErrorUnsupportedL1L2TokensPair(\"" + l1TokenRebasable.address + "\", \"" + stranger.address + "\")" + ); + }) + + .test("depositERC20To() :: wrong tokens combination", async (ctx) => { + const { + l1TokenBridge, + stubs: { l1TokenNonRebasable, l1TokenRebasable, l2TokenNonRebasable, l2TokenRebasable }, + accounts: { recipient }, + } = ctx; + + await assert.revertsWith( + l1TokenBridge.depositERC20To( + l1TokenNonRebasable.address, + l2TokenRebasable.address, + recipient.address, + wei`1 ether`, + wei`1 gwei`, + "0x" + ), + "ErrorUnsupportedL1L2TokensPair(\"" + l1TokenNonRebasable.address + "\", \"" + l2TokenRebasable.address + "\")" + ); + await assert.revertsWith( + l1TokenBridge.depositERC20To( + l1TokenRebasable.address, + l2TokenNonRebasable.address, + recipient.address, + wei`1 ether`, + wei`1 gwei`, + "0x" + ), + "ErrorUnsupportedL1L2TokensPair(\"" + l1TokenRebasable.address + "\", \"" + l2TokenNonRebasable.address + "\")" + ); + }) + + .test("depositERC20To() :: recipient is zero address", async (ctx) => { + const { + l1TokenBridge, + stubs: { l1TokenNonRebasable, l2TokenNonRebasable, l1TokenRebasable, l2TokenRebasable } + } = ctx; + + await assert.revertsWith( + l1TokenBridge.depositERC20To( + l1TokenNonRebasable.address, + l2TokenNonRebasable.address, + ethers.constants.AddressZero, + wei`1 ether`, + wei`1 gwei`, + "0x" + ), + "ErrorAccountIsZeroAddress()" + ); + await assert.revertsWith( + l1TokenBridge.depositERC20To( + l1TokenRebasable.address, + l2TokenRebasable.address, + ethers.constants.AddressZero, + wei`1 ether`, + wei`1 gwei`, + "0x" + ), + "ErrorAccountIsZeroAddress()" + ); + }) + + .test("depositERC20To() :: non-rebasable token flow", async (ctx) => { + const { + l1TokenBridge, + accounts: { deployer, l2TokenBridgeEOA, recipient }, + stubs: { l1TokenNonRebasable, l2TokenNonRebasable, l1Messenger, accountingOracle }, + constants: { tokenRate } + } = ctx; + + const l2Gas = wei`0.99 wei`; + const amount = wei`1 ether`; + const data = "0x"; + + await l1TokenNonRebasable.approve(l1TokenBridge.address, amount); + + const deployerBalanceBefore = await l1TokenNonRebasable.balanceOf(deployer.address); + const bridgeBalanceBefore = await l1TokenNonRebasable.balanceOf(l1TokenBridge.address); + + const tx = await l1TokenBridge.depositERC20To( + l1TokenNonRebasable.address, + l2TokenNonRebasable.address, + recipient.address, + amount, + l2Gas, + data + ); + + const refSlotTime = await refSlotTimestamp(accountingOracle); + const dataToReceive = await tokenRateAndTimestampPacked(tokenRate, refSlotTime, data); + + await assert.emits(l1TokenBridge, tx, "ERC20DepositInitiated", [ + l1TokenNonRebasable.address, + l2TokenNonRebasable.address, + deployer.address, + recipient.address, + amount, + dataToReceive, + ]); + + await assert.emits(l1Messenger, tx, "SentMessage", [ + l2TokenBridgeEOA.address, + l1TokenBridge.address, + L2ERC20ExtendedTokensBridge__factory.createInterface().encodeFunctionData( + "finalizeDeposit", + [ + l1TokenNonRebasable.address, + l2TokenNonRebasable.address, + deployer.address, + recipient.address, + amount, + dataToReceive, + ] + ), + 1, // message nonce + l2Gas, + ]); + + assert.equalBN( + await l1TokenNonRebasable.balanceOf(deployer.address), + deployerBalanceBefore.sub(amount) + ); + + assert.equalBN( + await l1TokenNonRebasable.balanceOf(l1TokenBridge.address), + bridgeBalanceBefore.add(amount) + ); + }) + + .test("depositERC20To() :: rebasable token flow", async (ctx) => { + const { + l1TokenBridge, + constants: { tenPowerDecimals, tokenRate }, + accounts: { deployer, l2TokenBridgeEOA, recipient }, + stubs: { l1TokenNonRebasable, l1TokenRebasable, l2TokenRebasable, l1Messenger, accountingOracle }, + } = ctx; + + const l2Gas = wei`0.99 wei`; + const amount = wei`1 ether`; + const data = "0x"; + + const amountWrapped = (wei.toBigNumber(amount)).mul(tenPowerDecimals).div(tokenRate); + + await l1TokenRebasable.approve(l1TokenBridge.address, amount); + + const deployerBalanceBefore = await l1TokenRebasable.balanceOf(deployer.address); + const bridgeBalanceBefore = await l1TokenNonRebasable.balanceOf(l1TokenBridge.address); + + const tx = await l1TokenBridge.depositERC20To( + l1TokenRebasable.address, + l2TokenRebasable.address, + recipient.address, + amount, + l2Gas, + data + ); + + const refSlotTime = await refSlotTimestamp(accountingOracle); + const dataToReceive = await tokenRateAndTimestampPacked(tokenRate, refSlotTime, data); + + await assert.emits(l1TokenBridge, tx, "ERC20DepositInitiated", [ + l1TokenRebasable.address, + l2TokenRebasable.address, + deployer.address, + recipient.address, + amount, + dataToReceive, + ]); + + await assert.emits(l1Messenger, tx, "SentMessage", [ + l2TokenBridgeEOA.address, + l1TokenBridge.address, + L2ERC20ExtendedTokensBridge__factory.createInterface().encodeFunctionData( + "finalizeDeposit", + [ + l1TokenRebasable.address, + l2TokenRebasable.address, + deployer.address, + recipient.address, + amountWrapped, + dataToReceive, + ] + ), + 1, // message nonce + l2Gas, + ]); + + assert.equalBN( + await l1TokenRebasable.balanceOf(deployer.address), + deployerBalanceBefore.sub(amount) + ); + + assert.equalBN( + await l1TokenNonRebasable.balanceOf(l1TokenBridge.address), + bridgeBalanceBefore.add(amountWrapped) + ); + }) + + .test( + "finalizeERC20Withdrawal() :: withdrawals are disabled", + async (ctx) => { + const { + l1TokenBridge, + stubs: { l1TokenNonRebasable, l2TokenNonRebasable, l1TokenRebasable, l2TokenRebasable }, + accounts: { deployer, recipient, l2TokenBridgeEOA }, + } = ctx; + await l1TokenBridge.disableWithdrawals(); + + assert.isFalse(await l1TokenBridge.isWithdrawalsEnabled()); + + await assert.revertsWith( + l1TokenBridge + .connect(l2TokenBridgeEOA) + .finalizeERC20Withdrawal( + l1TokenNonRebasable.address, + l2TokenNonRebasable.address, + deployer.address, + recipient.address, + wei`1 ether`, + "0x" + ), + "ErrorWithdrawalsDisabled()" + ); + await assert.revertsWith( + l1TokenBridge + .connect(l2TokenBridgeEOA) + .finalizeERC20Withdrawal( + l1TokenRebasable.address, + l2TokenRebasable.address, + deployer.address, + recipient.address, + wei`1 ether`, + "0x" + ), + "ErrorWithdrawalsDisabled()" + ); + } + ) + + .test("finalizeERC20Withdrawal() :: wrong l1Token", async (ctx) => { + const { + l1TokenBridge, + stubs: { l2TokenNonRebasable, l2TokenRebasable, l1Messenger }, + accounts: { deployer, recipient, l1MessengerStubAsEOA, stranger, l2TokenBridgeEOA }, + } = ctx; + + await l1Messenger.setXDomainMessageSender(l2TokenBridgeEOA.address); + + await assert.revertsWith( + l1TokenBridge + .connect(l1MessengerStubAsEOA) + .finalizeERC20Withdrawal( + stranger.address, + l2TokenNonRebasable.address, + deployer.address, + recipient.address, + wei`1 ether`, + "0x" + ), + "ErrorUnsupportedL1L2TokensPair(\"" + stranger.address + "\", \"" + l2TokenNonRebasable.address + "\")" + ); + + await assert.revertsWith( + l1TokenBridge + .connect(l1MessengerStubAsEOA) + .finalizeERC20Withdrawal( + stranger.address, + l2TokenRebasable.address, + deployer.address, + recipient.address, + wei`1 ether`, + "0x" + ), + "ErrorUnsupportedL1L2TokensPair(\"" + stranger.address + "\", \"" + l2TokenRebasable.address + "\")" + ); + }) + + .test("finalizeERC20Withdrawal() :: wrong l2Token", async (ctx) => { + const { + l1TokenBridge, + stubs: { l1TokenNonRebasable, l1TokenRebasable, l1Messenger }, + accounts: { deployer, recipient, l2TokenBridgeEOA, l1MessengerStubAsEOA, stranger }, + } = ctx; + + await l1Messenger.setXDomainMessageSender(l2TokenBridgeEOA.address); + + await assert.revertsWith( + l1TokenBridge + .connect(l1MessengerStubAsEOA) + .finalizeERC20Withdrawal( + l1TokenNonRebasable.address, + stranger.address, + deployer.address, + recipient.address, + wei`1 ether`, + "0x" + ), + "ErrorUnsupportedL1L2TokensPair(\"" + l1TokenNonRebasable.address + "\", \"" + stranger.address + "\")" + ); + + await assert.revertsWith( + l1TokenBridge + .connect(l1MessengerStubAsEOA) + .finalizeERC20Withdrawal( + l1TokenRebasable.address, + stranger.address, + deployer.address, + recipient.address, + wei`1 ether`, + "0x" + ), + "ErrorUnsupportedL1L2TokensPair(\"" + l1TokenRebasable.address + "\", \"" + stranger.address + "\")" + ); + }) + + .test("finalizeERC20Withdrawal() :: wrong token combination", async (ctx) => { + const { + l1TokenBridge, + stubs: { l1TokenNonRebasable, l1TokenRebasable, l2TokenNonRebasable, l2TokenRebasable, l1Messenger }, + accounts: { deployer, recipient, l2TokenBridgeEOA, l1MessengerStubAsEOA }, + } = ctx; + await l1Messenger.setXDomainMessageSender(l2TokenBridgeEOA.address); + + await assert.revertsWith( + l1TokenBridge + .connect(l1MessengerStubAsEOA) + .finalizeERC20Withdrawal( + l1TokenNonRebasable.address, + l2TokenRebasable.address, + deployer.address, + recipient.address, + wei`1 ether`, + "0x" + ), + "ErrorUnsupportedL1L2TokensPair(\"" + l1TokenNonRebasable.address + "\", \"" + l2TokenRebasable.address + "\")" + ); + + await assert.revertsWith( + l1TokenBridge + .connect(l1MessengerStubAsEOA) + .finalizeERC20Withdrawal( + l1TokenRebasable.address, + l2TokenNonRebasable.address, + deployer.address, + recipient.address, + wei`1 ether`, + "0x" + ), + "ErrorUnsupportedL1L2TokensPair(\"" + l1TokenRebasable.address + "\", \"" + l2TokenNonRebasable.address + "\")" + ); + }) + + .test("finalizeERC20Withdrawal() :: unauthorized messenger", async (ctx) => { + const { + l1TokenBridge, + stubs: { l1TokenNonRebasable, l2TokenNonRebasable, l1TokenRebasable, l2TokenRebasable }, + accounts: { deployer, recipient, stranger }, + } = ctx; + + await assert.revertsWith( + l1TokenBridge + .connect(stranger) + .finalizeERC20Withdrawal( + l1TokenNonRebasable.address, + l2TokenNonRebasable.address, + deployer.address, + recipient.address, + wei`1 ether`, + "0x" + ), + "ErrorUnauthorizedMessenger()" + ); + await assert.revertsWith( + l1TokenBridge + .connect(stranger) + .finalizeERC20Withdrawal( + l1TokenRebasable.address, + l2TokenRebasable.address, + deployer.address, + recipient.address, + wei`1 ether`, + "0x" + ), + "ErrorUnauthorizedMessenger()" + ); + }) + + .test("finalizeERC20Withdrawal() :: wrong cross domain sender", async (ctx) => { + const { + l1TokenBridge, + stubs: { l1TokenNonRebasable, l2TokenNonRebasable, l1TokenRebasable, l2TokenRebasable, l1Messenger }, + accounts: { deployer, recipient, stranger, l1MessengerStubAsEOA }, + } = ctx; + + await l1Messenger.setXDomainMessageSender(stranger.address); + + await assert.revertsWith( + l1TokenBridge + .connect(l1MessengerStubAsEOA) + .finalizeERC20Withdrawal( + l1TokenNonRebasable.address, + l2TokenNonRebasable.address, + deployer.address, + recipient.address, + wei`1 ether`, + "0x" + ), + "ErrorWrongCrossDomainSender()" + ); + await assert.revertsWith( + l1TokenBridge + .connect(l1MessengerStubAsEOA) + .finalizeERC20Withdrawal( + l1TokenRebasable.address, + l2TokenRebasable.address, + deployer.address, + recipient.address, + wei`1 ether`, + "0x" + ), + "ErrorWrongCrossDomainSender()" + ); + }) + + .test("finalizeERC20Withdrawal() :: non-rebasable token flow", async (ctx) => { + const { + l1TokenBridge, + stubs: { l1TokenNonRebasable, l2TokenNonRebasable, l1Messenger }, + accounts: { deployer, recipient, l1MessengerStubAsEOA, l2TokenBridgeEOA }, + } = ctx; + + await l1Messenger.setXDomainMessageSender(l2TokenBridgeEOA.address); + + const amount = wei`1 ether`; + const data = "0xdeadbeaf"; + const bridgeBalanceBefore = await l1TokenNonRebasable.balanceOf(l1TokenBridge.address); + + const tx = await l1TokenBridge + .connect(l1MessengerStubAsEOA) + .finalizeERC20Withdrawal( + l1TokenNonRebasable.address, + l2TokenNonRebasable.address, + deployer.address, + recipient.address, + amount, + data + ); + + await assert.emits(l1TokenBridge, tx, "ERC20WithdrawalFinalized", [ + l1TokenNonRebasable.address, + l2TokenNonRebasable.address, + deployer.address, + recipient.address, + amount, + data, + ]); + + assert.equalBN(await l1TokenNonRebasable.balanceOf(recipient.address), amount); + assert.equalBN( + await l1TokenNonRebasable.balanceOf(l1TokenBridge.address), + bridgeBalanceBefore.sub(amount) + ); + }) + + .test("finalizeERC20Withdrawal() :: rebasable token flow", async (ctx) => { + const { + l1TokenBridge, + stubs: { l1TokenRebasable, l2TokenRebasable, l1TokenNonRebasable, l1Messenger }, + accounts: { deployer, recipient, l1MessengerStubAsEOA, l2TokenBridgeEOA }, + } = ctx; + + await l1Messenger.setXDomainMessageSender(l2TokenBridgeEOA.address); + await l1TokenRebasable.transfer(l1TokenNonRebasable.address, wei`100 ether`); + + const amount = wei`1 ether`; + const data = "0xdeadbeaf"; + const rate = await l1TokenNonRebasable.getStETHByWstETH(BigNumber.from(10).pow(27)); + const decimals = BigNumber.from(10).pow(27); + const amountUnwrapped = (wei.toBigNumber(amount)).mul(rate).div(decimals); + const bridgeBalanceBefore = await l1TokenRebasable.balanceOf(l1TokenBridge.address); + + const tx = await l1TokenBridge + .connect(l1MessengerStubAsEOA) + .finalizeERC20Withdrawal( + l1TokenRebasable.address, + l2TokenRebasable.address, + deployer.address, + recipient.address, + amount, + data + ); + + await assert.emits(l1TokenBridge, tx, "ERC20WithdrawalFinalized", [ + l1TokenRebasable.address, + l2TokenRebasable.address, + deployer.address, + recipient.address, + amountUnwrapped, + data, + ]); + + assert.equalBN(await l1TokenRebasable.balanceOf(recipient.address), amountUnwrapped); + assert.equalBN( + await l1TokenNonRebasable.balanceOf(l1TokenBridge.address), + bridgeBalanceBefore.sub(amount) + ); + }) + + .test("finalizeERC20Withdrawal() :: zero amount of rebasable token", async (ctx) => { + const { + l1TokenBridge, + stubs: { l1TokenRebasable, l2TokenRebasable, l1Messenger }, + accounts: { deployer, recipient, l1MessengerStubAsEOA, l2TokenBridgeEOA }, + } = ctx; + + await l1Messenger.setXDomainMessageSender(l2TokenBridgeEOA.address); + + const data = "0xdeadbeaf"; + const recipientBalanceBefore = await l1TokenRebasable.balanceOf(recipient.address); + const bridgeBalanceBefore = await l1TokenRebasable.balanceOf(l1TokenBridge.address); + + const tx = await l1TokenBridge + .connect(l1MessengerStubAsEOA) + .finalizeERC20Withdrawal( + l1TokenRebasable.address, + l2TokenRebasable.address, + deployer.address, + recipient.address, + 0, + data + ); + + await assert.emits(l1TokenBridge, tx, "ERC20WithdrawalFinalized", [ + l1TokenRebasable.address, + l2TokenRebasable.address, + deployer.address, + recipient.address, + 0, + data, + ]); + + assert.equalBN(await l1TokenRebasable.balanceOf(recipient.address), recipientBalanceBefore); + assert.equalBN(await l1TokenRebasable.balanceOf(l1TokenBridge.address), bridgeBalanceBefore); + }) + + .test("finalizeERC20Withdrawal() :: zero amount of non-rebasable token", async (ctx) => { + const { + l1TokenBridge, + stubs: { l1TokenNonRebasable, l2TokenNonRebasable, l1Messenger }, + accounts: { deployer, recipient, l1MessengerStubAsEOA, l2TokenBridgeEOA }, + } = ctx; + + await l1Messenger.setXDomainMessageSender(l2TokenBridgeEOA.address); + + const data = "0xdeadbeaf"; + const recipientBalanceBefore = await l1TokenNonRebasable.balanceOf(recipient.address); + const bridgeBalanceBefore = await l1TokenNonRebasable.balanceOf(l1TokenBridge.address); + + const tx = await l1TokenBridge + .connect(l1MessengerStubAsEOA) + .finalizeERC20Withdrawal( + l1TokenNonRebasable.address, + l2TokenNonRebasable.address, + deployer.address, + recipient.address, + 0, + data + ); + + await assert.emits(l1TokenBridge, tx, "ERC20WithdrawalFinalized", [ + l1TokenNonRebasable.address, + l2TokenNonRebasable.address, + deployer.address, + recipient.address, + 0, + data, + ]); + + assert.equalBN(await l1TokenNonRebasable.balanceOf(recipient.address), recipientBalanceBefore); + assert.equalBN(await l1TokenNonRebasable.balanceOf(l1TokenBridge.address), bridgeBalanceBefore); + }) + + .run(); + +async function ctxFactory() { + const [deployer, l2TokenBridgeEOA, stranger, recipient] = await hre.ethers.getSigners(); + const zero = await hre.ethers.getSigner(hre.ethers.constants.AddressZero); + + const provider = await hre.ethers.provider; + const decimals = BigNumber.from(27); + const totalPooledEther = BigNumber.from('9309904612343950493629678'); + const totalShares = BigNumber.from('7975822843597609202337218'); + const tokenRate = getExchangeRate(decimals, totalPooledEther, totalShares); + const tenPowerDecimals = BigNumber.from(10).pow(decimals); + const genesisTime = BigNumber.from(1); + const secondsPerSlot = BigNumber.from(2); + const lastProcessingRefSlot = BigNumber.from(3); + + const { + l1MessengerStub, + l1TokenBridgeImpl, + l1TokenNonRebasableStub, + l1TokenRebasableStub, + l2TokenNonRebasableStub, + l2TokenRebasableStub, + accountingOracle + } = await getL1LidoTokensBridgeImpl( + totalPooledEther, + totalShares, + genesisTime, + secondsPerSlot, + lastProcessingRefSlot, + deployer, + l2TokenBridgeEOA.address + ); + + const l1TokenBridge = await getL1LidoTokensBridgeProxy(deployer, l1TokenBridgeImpl); + + const emptyContract = await new EmptyContractStub__factory(deployer).deploy({ value: wei.toBigNumber(wei`1 ether`) }); + const emptyContractAsEOA = await testing.impersonate(emptyContract.address); + + const l1MessengerStubAsEOA = await testing.impersonate(l1MessengerStub.address); + + await l1TokenNonRebasableStub.transfer(l1TokenBridge.address, wei`100 ether`); + await l1TokenRebasableStub.transfer(l1TokenBridge.address, wei`100 ether`); + + await setupL1TokenBridge(deployer, l1TokenBridge); + + return { + provider: provider, + accounts: { + deployer, + stranger, + l2TokenBridgeEOA, + emptyContractAsEOA, + recipient, + l1MessengerStubAsEOA, + zero + }, + stubs: { + l1TokenNonRebasable: l1TokenNonRebasableStub, + l1TokenRebasable: l1TokenRebasableStub, + l2TokenNonRebasable: l2TokenNonRebasableStub, + l2TokenRebasable: l2TokenRebasableStub, + l1Messenger: l1MessengerStub, + accountingOracle: accountingOracle + }, + constants: { + decimals, + tenPowerDecimals, + totalPooledEther, + tokenRate, + totalShares, + genesisTime, + secondsPerSlot, + lastProcessingRefSlot + }, + l1TokenBridge, + }; +} + +async function getL1LidoTokensBridgeImpl( + totalPooledEther: BigNumber, + totalShares: BigNumber, + genesisTime: BigNumber, + secondsPerSlot: BigNumber, + lastProcessingRefSlot: BigNumber, + deployer: SignerWithAddress, + l2TokenBridge: string +) { + const l1MessengerStub = await new CrossDomainMessengerStub__factory(deployer) + .deploy({ value: wei.toBigNumber(wei`1 ether`) }); + + const l1TokenRebasableStub = await new ERC20BridgedStub__factory(deployer).deploy( + "L1 Token Rebasable", + "L1R" + ); + + const l1TokenNonRebasableStub = await new ERC20WrapperStub__factory(deployer).deploy( + l1TokenRebasableStub.address, + "L1 Token Non Rebasable", + "L1NR", + totalPooledEther, totalShares + ); + + const l2TokenNonRebasableStub = await new ERC20BridgedStub__factory(deployer).deploy( + "L2 Token Non Rebasable", + "L2NR" + ); + + const l2TokenRebasableStub = await new ERC20WrapperStub__factory(deployer).deploy( + l2TokenNonRebasableStub.address, + "L2 Token Rebasable", + "L2R", + totalPooledEther, totalShares + ); + + const accountingOracle = await new AccountingOracleStub__factory(deployer).deploy( + genesisTime, + secondsPerSlot, + lastProcessingRefSlot + ); + const l1TokenBridgeImpl = await new L1LidoTokensBridge__factory( + deployer + ).deploy( + l1MessengerStub.address, + l2TokenBridge, + l1TokenNonRebasableStub.address, + l1TokenRebasableStub.address, + l2TokenNonRebasableStub.address, + l2TokenRebasableStub.address, + accountingOracle.address + ); + + return { + l1MessengerStub, + l1TokenBridgeImpl, + l1TokenNonRebasableStub, + l1TokenRebasableStub, + l2TokenNonRebasableStub, + l2TokenRebasableStub, + accountingOracle + }; +} + +async function getL1LidoTokensBridgeProxy(deployer: SignerWithAddress, l1TokenBridgeImpl: L1LidoTokensBridge) { + + const l1TokenBridgeProxy = await new OssifiableProxy__factory( + deployer + ).deploy( + l1TokenBridgeImpl.address, + deployer.address, + l1TokenBridgeImpl.interface.encodeFunctionData("initialize", [ + deployer.address + ]) + ); + + return L1LidoTokensBridge__factory.connect( + l1TokenBridgeProxy.address, + deployer + ); +} + +async function setupL1TokenBridge(deployer: SignerWithAddress, l1TokenBridge: L1LidoTokensBridge) { + const roles = await Promise.all([ + l1TokenBridge.DEPOSITS_ENABLER_ROLE(), + l1TokenBridge.DEPOSITS_DISABLER_ROLE(), + l1TokenBridge.WITHDRAWALS_ENABLER_ROLE(), + l1TokenBridge.WITHDRAWALS_DISABLER_ROLE(), + ]); + + for (const role of roles) { + await l1TokenBridge.grantRole(role, deployer.address); + } + + await l1TokenBridge.enableDeposits(); + await l1TokenBridge.enableWithdrawals(); +} diff --git a/test/optimism/L2ERC20ExtendedTokensBridge.unit.test.ts b/test/optimism/L2ERC20ExtendedTokensBridge.unit.test.ts new file mode 100644 index 00000000..c857a22e --- /dev/null +++ b/test/optimism/L2ERC20ExtendedTokensBridge.unit.test.ts @@ -0,0 +1,1511 @@ +import hre from "hardhat"; +import { BigNumber } from "ethers"; +import { assert } from "chai"; +import { SignerWithAddress } from "@nomiclabs/hardhat-ethers/signers"; +import { + tokenRateAndTimestampPacked, + getBlockTimestamp, + predictAddresses, + getExchangeRate, + nonRebasableFromRebasableL1, + nonRebasableFromRebasableL2, + rebasableFromNonRebasableL1, + rebasableFromNonRebasableL2 +} from "../../utils/testing/helpers"; +import testing, { unit } from "../../utils/testing"; +import { wei } from "../../utils/wei"; +import { + ERC20BridgedStub__factory, + ERC20WrapperStub__factory, + TokenRateOracle__factory, + ERC20RebasableBridgedPermit__factory, + L1LidoTokensBridge__factory, + L2ERC20ExtendedTokensBridge__factory, + OssifiableProxy__factory, + EmptyContractStub__factory, + CrossDomainMessengerStub__factory, + BridgingManagerStub__factory +} from "../../typechain"; + +unit("Optimism:: L2ERC20ExtendedTokensBridge", ctxFactory) + +.test("constructor() :: zero params", async (ctx) => { + + const { deployer, stranger, zero } = ctx.accounts; + + await assert.revertsWith(new L2ERC20ExtendedTokensBridge__factory( + deployer + ).deploy( + zero.address, + stranger.address, + stranger.address, + stranger.address, + stranger.address, + stranger.address + ), "ErrorZeroAddressMessenger()"); + + await assert.revertsWith(new L2ERC20ExtendedTokensBridge__factory( + deployer + ).deploy( + stranger.address, + zero.address, + stranger.address, + stranger.address, + stranger.address, + stranger.address + ), "ErrorZeroAddressL1Bridge()"); + + await assert.revertsWith(new L2ERC20ExtendedTokensBridge__factory( + deployer + ).deploy( + stranger.address, + stranger.address, + zero.address, + stranger.address, + stranger.address, + stranger.address + ), "ErrorZeroAddressL1TokenNonRebasable()"); + + await assert.revertsWith(new L2ERC20ExtendedTokensBridge__factory( + deployer + ).deploy( + stranger.address, + stranger.address, + stranger.address, + zero.address, + stranger.address, + stranger.address + ), "ErrorZeroAddressL1TokenRebasable()"); + + await assert.revertsWith(new L2ERC20ExtendedTokensBridge__factory( + deployer + ).deploy( + stranger.address, + stranger.address, + stranger.address, + stranger.address, + zero.address, + stranger.address, + ), "ErrorZeroAddressL2TokenNonRebasable()"); + + await assert.revertsWith(new L2ERC20ExtendedTokensBridge__factory( + deployer + ).deploy( + stranger.address, + stranger.address, + stranger.address, + stranger.address, + stranger.address, + zero.address, + ), "ErrorZeroAddressL2TokenRebasable()"); +}) + + .test("initial state", async (ctx) => { + const { + accounts: { l1TokenBridgeEOA, l2MessengerStubEOA }, + contracts: { l2TokenBridge, l1TokenNonRebasable, l2TokenNonRebasable, l1TokenRebasable, l2TokenRebasable }, + } = ctx; + + assert.equal(await l2TokenBridge.l1TokenBridge(), l1TokenBridgeEOA.address); + assert.equal(await l2TokenBridge.MESSENGER(), l2MessengerStubEOA._address); + assert.equal(await l2TokenBridge.L1_TOKEN_NON_REBASABLE(), l1TokenNonRebasable.address); + assert.equal(await l2TokenBridge.L1_TOKEN_REBASABLE(), l1TokenRebasable.address); + assert.equal(await l2TokenBridge.L2_TOKEN_NON_REBASABLE(), l2TokenNonRebasable.address); + assert.equal(await l2TokenBridge.L2_TOKEN_REBASABLE(), l2TokenRebasable.address); + + assert.equalBN( + await l2TokenNonRebasable.allowance(l2TokenBridge.address, l2TokenRebasable.address), + hre.ethers.constants.MaxUint256 + ); + }) + + .test("initialize() :: petrified", async (ctx) => { + const { deployer, l1TokenBridgeEOA } = ctx.accounts; + + const l2TokenBridgeImpl = await getL2TokenBridgeImpl(deployer, l1TokenBridgeEOA.address); + + const petrifiedVersionMark = hre.ethers.constants.MaxUint256; + assert.equalBN(await l2TokenBridgeImpl.getContractVersion(), petrifiedVersionMark); + + await assert.revertsWith( + l2TokenBridgeImpl.initialize(deployer.address), + "NonZeroContractVersionOnInit()" + ); + }) + + .test("initialize() :: don't allow to initialize twice", async (ctx) => { + const { deployer, l1TokenBridgeEOA } = ctx.accounts; + + const l1LidoTokensBridgeImpl = await getL2TokenBridgeImpl(deployer, l1TokenBridgeEOA.address); + + const l1TokenBridgeProxy = await new OssifiableProxy__factory( + deployer + ).deploy( + l1LidoTokensBridgeImpl.address, + deployer.address, + l1LidoTokensBridgeImpl.interface.encodeFunctionData("initialize", [ + deployer.address + ]) + ); + + const l1TokenBridge = L1LidoTokensBridge__factory.connect( + l1TokenBridgeProxy.address, + deployer + ); + + assert.equalBN(await l1TokenBridge.getContractVersion(), 2); + + await assert.revertsWith( + l1TokenBridge.initialize(deployer.address), + "NonZeroContractVersionOnInit()" + ); + }) + + .test("initialize() :: revert when admin is zero", async (ctx) => { + const { deployer, l1TokenBridgeEOA, zero } = ctx.accounts; + const l2TokenBridgeImpl = await getL2TokenBridgeImpl(deployer, l1TokenBridgeEOA.address); + + await assert.revertsWith(new OssifiableProxy__factory( + deployer + ).deploy( + l2TokenBridgeImpl.address, + deployer.address, + l2TokenBridgeImpl.interface.encodeFunctionData("initialize", [ + zero.address + ]) + ), "ErrorZeroAddressAdmin()"); + }) + + .test("finalizeUpgrade_v2() :: bridging manager uninitialized", async (ctx) => { + const { deployer, l1TokenBridgeEOA } = ctx.accounts; + + const l1LidoTokensBridgeImpl = await getL2TokenBridgeImpl(deployer, l1TokenBridgeEOA.address); + + await assert.revertsWith(new OssifiableProxy__factory(deployer).deploy( + l1LidoTokensBridgeImpl.address, + deployer.address, + L1LidoTokensBridge__factory.createInterface().encodeFunctionData("finalizeUpgrade_v2") + ), "ErrorBridgingManagerIsNotInitialized()"); + }) + + .test("finalizeUpgrade_v2() :: bridging manager initialized", async (ctx) => { + const { deployer, l1TokenBridgeEOA } = ctx.accounts; + + const bridgingManagerImpl = await new BridgingManagerStub__factory(deployer).deploy(); + const proxy = await new OssifiableProxy__factory(deployer).deploy( + bridgingManagerImpl.address, + deployer.address, + BridgingManagerStub__factory.createInterface().encodeFunctionData("initialize", [ + deployer.address + ]) + ); + + const l1LidoTokensBridgeImpl = await getL2TokenBridgeImpl(deployer, l1TokenBridgeEOA.address); + await proxy.proxy__upgradeToAndCall( + l1LidoTokensBridgeImpl.address, + L1LidoTokensBridge__factory.createInterface().encodeFunctionData("finalizeUpgrade_v2"), + false + ); + + const l1LidoTokensBridgeProxied = L1LidoTokensBridge__factory.connect( + proxy.address, + deployer + ); + + assert.equalBN(await l1LidoTokensBridgeProxied.getContractVersion(), 2); + }) + + .test("withdraw() :: withdrawals disabled", async (ctx) => { + const { + contracts: { l2TokenBridge, l2TokenNonRebasable, l2TokenRebasable }, + } = ctx; + + await l2TokenBridge.disableWithdrawals(); + + assert.isFalse(await l2TokenBridge.isWithdrawalsEnabled()); + + await assert.revertsWith( + l2TokenBridge.withdraw( + l2TokenNonRebasable.address, + wei`1 ether`, + wei`1 gwei`, + "0x" + ), + "ErrorWithdrawalsDisabled()" + ); + + await assert.revertsWith( + l2TokenBridge.withdraw( + l2TokenRebasable.address, + wei`1 ether`, + wei`1 gwei`, + "0x" + ), + "ErrorWithdrawalsDisabled()" + ); + }) + + .test("withdraw() :: unsupported l2Token", async (ctx) => { + const { + contracts: { l2TokenBridge }, + accounts: { stranger }, + } = ctx; + await assert.revertsWith( + l2TokenBridge.withdraw(stranger.address, wei`1 ether`, wei`1 gwei`, "0x"), + "ErrorUnsupportedL2Token(\"" + stranger.address + "\")" + ); + }) + + .test("withdraw() :: not from EOA", async (ctx) => { + const { + accounts: { emptyContractEOA }, + contracts: { l2TokenBridge, l2TokenRebasable, l2TokenNonRebasable }, + } = ctx; + + await assert.revertsWith( + l2TokenBridge + .connect(emptyContractEOA) + .withdraw( + l2TokenNonRebasable.address, + wei`1 ether`, + wei`1 gwei`, + "0x" + ), + "ErrorSenderNotEOA()" + ); + await assert.revertsWith( + l2TokenBridge + .connect(emptyContractEOA) + .withdraw( + l2TokenRebasable.address, + wei`1 ether`, + wei`1 gwei`, + "0x" + ), + "ErrorSenderNotEOA()" + ); + }) + + .test("withdraw() :: non-rebasable token flow", async (ctx) => { + const { + accounts: { deployer, l1TokenBridgeEOA }, + contracts: { + l2TokenBridge, + l2Messenger, + l1TokenNonRebasable, + l2TokenNonRebasable, + }, + } = ctx; + + const deployerBalanceBefore = await l2TokenNonRebasable.balanceOf(deployer.address); + const totalSupplyBefore = await l2TokenNonRebasable.totalSupply(); + + const amount = wei`1 ether`; + const l1Gas = wei`1 wei`; + const data = "0xdeadbeaf"; + + const tx = await l2TokenBridge.withdraw( + l2TokenNonRebasable.address, + amount, + l1Gas, + data + ); + + await assert.emits(l2TokenBridge, tx, "WithdrawalInitiated", [ + l1TokenNonRebasable.address, + l2TokenNonRebasable.address, + deployer.address, + deployer.address, + amount, + data, + ]); + + await assert.emits(l2Messenger, tx, "SentMessage", [ + l1TokenBridgeEOA.address, + l2TokenBridge.address, + L1LidoTokensBridge__factory.createInterface().encodeFunctionData( + "finalizeERC20Withdrawal", + [ + l1TokenNonRebasable.address, + l2TokenNonRebasable.address, + deployer.address, + deployer.address, + amount, + data, + ] + ), + 1, // message nonce + l1Gas, + ]); + + assert.equalBN( + await l2TokenNonRebasable.balanceOf(deployer.address), + deployerBalanceBefore.sub(amount) + ); + + assert.equalBN( + await l2TokenNonRebasable.totalSupply(), + totalSupplyBefore.sub(amount) + ); + }) + + .test("withdraw() :: rebasable token flow", async (ctx) => { + const { + accounts: { deployer, l1TokenBridgeEOA, l2MessengerStubEOA, recipient }, + contracts: { + l2TokenBridge, + l2Messenger, + l1TokenRebasable, + l2TokenRebasable + }, + constants: { exchangeRate, tokenRateDecimals } + } = ctx; + + const amountToDepositNonRebasable = wei`1 ether`; + + // wrap on L2 + const amountToWithdrawRebasable = rebasableFromNonRebasableL2( + wei.toBigNumber(amountToDepositNonRebasable), + tokenRateDecimals, + exchangeRate + ); + + // unwrap on L2 + const amountReceivedWithdrawNonRebasable = nonRebasableFromRebasableL2( + amountToWithdrawRebasable, + tokenRateDecimals, + exchangeRate + ); + + console.log("input: amountToDepositNonRebasable=",amountToDepositNonRebasable); + console.log("wrap on L2: amountToWithdrawRebasable=",amountToWithdrawRebasable); + console.log("unwrap on L2: amountReceivedWithdrawNonRebasable=",amountReceivedWithdrawNonRebasable); + + + const l1Gas = wei`1 wei`; + const data = "0xdeadbeaf"; + const currentBlockTimestamp = await getBlockTimestamp(ctx.provider, 0); + const packedTokenRateAndTimestampData = await tokenRateAndTimestampPacked( + exchangeRate, + currentBlockTimestamp, + data + ); + + await l2TokenBridge + .connect(l2MessengerStubEOA) + .finalizeDeposit( + l1TokenRebasable.address, + l2TokenRebasable.address, + deployer.address, + recipient.address, + amountToDepositNonRebasable, + packedTokenRateAndTimestampData + ); + + const recipientBalanceBefore = await l2TokenRebasable.balanceOf(recipient.address); + const totalSupplyBefore = await l2TokenRebasable.totalSupply(); + + const tx = await l2TokenBridge.connect(recipient).withdraw( + l2TokenRebasable.address, + amountToWithdrawRebasable, + l1Gas, + data + ); + + await assert.emits(l2TokenBridge, tx, "WithdrawalInitiated", [ + l1TokenRebasable.address, + l2TokenRebasable.address, + recipient.address, + recipient.address, + amountToWithdrawRebasable, + data, + ]); + + await assert.emits(l2Messenger, tx, "SentMessage", [ + l1TokenBridgeEOA.address, + l2TokenBridge.address, + L1LidoTokensBridge__factory.createInterface().encodeFunctionData( + "finalizeERC20Withdrawal", + [ + l1TokenRebasable.address, + l2TokenRebasable.address, + recipient.address, + recipient.address, + amountReceivedWithdrawNonRebasable, + data, + ] + ), + 1, // message nonce + l1Gas, + ]); + + console.log("rebasable on L2 recipientBalanceBefore=",recipientBalanceBefore); + console.log("rebasable on L2 recipientBalanceAfter=",await l2TokenRebasable.balanceOf(recipient.address)); + + assert.equalBN( + await l2TokenRebasable.balanceOf(deployer.address), + recipientBalanceBefore.sub(amountToWithdrawRebasable) + ); + + assert.isTrue(almostEqual( + await l2TokenRebasable.totalSupply(), + totalSupplyBefore.sub(amountToWithdrawRebasable) + )); + }) + + .test("withdraw() :: zero rebasable tokens", async (ctx) => { + const { + accounts: { deployer, l1TokenBridgeEOA, recipient }, + contracts: { + l2TokenBridge, + l2Messenger, + l1TokenRebasable, + l2TokenRebasable + }, + } = ctx; + + await pushTokenRate(ctx); + + const l1Gas = wei`1 wei`; + const data = "0xdeadbeaf"; + const recipientBalanceBefore = await l2TokenRebasable.balanceOf(recipient.address); + const totalSupplyBefore = await l2TokenRebasable.totalSupply(); + + const tx = await l2TokenBridge + .connect(recipient) + .withdraw( + l2TokenRebasable.address, + 0, + l1Gas, + data); + + await assert.emits(l2TokenBridge, tx, "WithdrawalInitiated", [ + l1TokenRebasable.address, + l2TokenRebasable.address, + recipient.address, + recipient.address, + 0, + data, + ]); + + await assert.emits(l2Messenger, tx, "SentMessage", [ + l1TokenBridgeEOA.address, + l2TokenBridge.address, + L1LidoTokensBridge__factory.createInterface().encodeFunctionData( + "finalizeERC20Withdrawal", + [ + l1TokenRebasable.address, + l2TokenRebasable.address, + recipient.address, + recipient.address, + 0, + data, + ] + ), + 1, // message nonce + l1Gas, + ]); + + assert.equalBN(await l2TokenRebasable.balanceOf(deployer.address), recipientBalanceBefore); + assert.equalBN(await l2TokenRebasable.totalSupply(), totalSupplyBefore); + }) + + .test("withdraw() :: zero non-rebasable tokens", async (ctx) => { + const { + accounts: { l1TokenBridgeEOA, recipient }, + contracts: { + l2TokenBridge, + l2Messenger, + l1TokenNonRebasable, + l2TokenNonRebasable + }, + } = ctx; + + await pushTokenRate(ctx); + + const l1Gas = wei`1 wei`; + const data = "0xdeadbeaf"; + const recipientBalanceBefore = await l2TokenNonRebasable.balanceOf(recipient.address); + const totalSupplyBefore = await l2TokenNonRebasable.totalSupply(); + + const tx = await l2TokenBridge + .connect(recipient) + .withdraw( + l2TokenNonRebasable.address, + 0, + l1Gas, + data); + + await assert.emits(l2TokenBridge, tx, "WithdrawalInitiated", [ + l1TokenNonRebasable.address, + l2TokenNonRebasable.address, + recipient.address, + recipient.address, + 0, + data, + ]); + + await assert.emits(l2Messenger, tx, "SentMessage", [ + l1TokenBridgeEOA.address, + l2TokenBridge.address, + L1LidoTokensBridge__factory.createInterface().encodeFunctionData( + "finalizeERC20Withdrawal", + [ + l1TokenNonRebasable.address, + l2TokenNonRebasable.address, + recipient.address, + recipient.address, + 0, + data, + ] + ), + 1, // message nonce + l1Gas, + ]); + + assert.equalBN(await l2TokenNonRebasable.balanceOf(recipient.address), recipientBalanceBefore); + assert.equalBN(await l2TokenNonRebasable.totalSupply(), totalSupplyBefore); + }) + + .test("withdrawTo() :: withdrawals disabled", async (ctx) => { + const { + contracts: { l2TokenBridge, l2TokenNonRebasable, l2TokenRebasable }, + accounts: { recipient }, + } = ctx; + + await l2TokenBridge.disableWithdrawals(); + + assert.isFalse(await l2TokenBridge.isWithdrawalsEnabled()); + + await assert.revertsWith( + l2TokenBridge.withdrawTo( + l2TokenNonRebasable.address, + recipient.address, + wei`1 ether`, + wei`1 gwei`, + "0x" + ), + "ErrorWithdrawalsDisabled()" + ); + await assert.revertsWith( + l2TokenBridge.withdrawTo( + l2TokenRebasable.address, + recipient.address, + wei`1 ether`, + wei`1 gwei`, + "0x" + ), + "ErrorWithdrawalsDisabled()" + ); + }) + + .test("withdrawTo() :: unsupported l2Token", async (ctx) => { + const { + contracts: { l2TokenBridge }, + accounts: { stranger, recipient }, + } = ctx; + await assert.revertsWith( + l2TokenBridge.withdrawTo( + stranger.address, + recipient.address, + wei`1 ether`, + wei`1 gwei`, + "0x" + ), + "ErrorUnsupportedL2Token(\"" + stranger.address + "\")" + ); + }) + + .test("withdrawTo() :: non rebasable token flow", async (ctx) => { + const { + accounts: { deployer, recipient, l1TokenBridgeEOA }, + contracts: { + l2TokenBridge, + l2Messenger: l2MessengerStub, + l1TokenNonRebasable, + l2TokenNonRebasable + }, + } = ctx; + + const deployerBalanceBefore = await l2TokenNonRebasable.balanceOf(deployer.address); + const totalSupplyBefore = await l2TokenNonRebasable.totalSupply(); + + const amount = wei`1 ether`; + const l1Gas = wei`1 wei`; + const data = "0xdeadbeaf"; + + const tx = await l2TokenBridge.withdrawTo( + l2TokenNonRebasable.address, + recipient.address, + amount, + l1Gas, + data + ); + + await assert.emits(l2TokenBridge, tx, "WithdrawalInitiated", [ + l1TokenNonRebasable.address, + l2TokenNonRebasable.address, + deployer.address, + recipient.address, + amount, + data, + ]); + + await assert.emits(l2MessengerStub, tx, "SentMessage", [ + l1TokenBridgeEOA.address, + l2TokenBridge.address, + L1LidoTokensBridge__factory.createInterface().encodeFunctionData( + "finalizeERC20Withdrawal", + [ + l1TokenNonRebasable.address, + l2TokenNonRebasable.address, + deployer.address, + recipient.address, + amount, + data, + ] + ), + 1, // message nonce + l1Gas, + ]); + + assert.equalBN( + await l2TokenNonRebasable.balanceOf(deployer.address), + deployerBalanceBefore.sub(amount) + ); + + assert.equalBN( + await l2TokenNonRebasable.totalSupply(), + totalSupplyBefore.sub(amount) + ); + }) + + .test("withdrawTo() :: rebasable token flow", async (ctx) => { + + const { + accounts: { deployer, l1TokenBridgeEOA, l2MessengerStubEOA, recipient }, + contracts: { + l2TokenBridge, + l2Messenger, + l1TokenRebasable, + l2TokenRebasable + }, + constants: { exchangeRate, tokenRateDecimals } + } = ctx; + + const amountToDepositNonRebasable = wei`1 ether`; // shares + const amountToWithdraw = rebasableFromNonRebasableL2( + wei.toBigNumber(amountToDepositNonRebasable), + tokenRateDecimals, + exchangeRate + ); + const amountReceivedWithdrawNonRebasable = nonRebasableFromRebasableL2( + amountToWithdraw, + tokenRateDecimals, + exchangeRate + ); + + const l1Gas = wei`1 wei`; + const data = "0xdeadbeaf"; + const currentBlockTimestamp = await getBlockTimestamp(ctx.provider, 0); + const packedTokenRateAndTimestampData = await tokenRateAndTimestampPacked( + exchangeRate, + currentBlockTimestamp, + data + ); + + await l2TokenBridge + .connect(l2MessengerStubEOA) + .finalizeDeposit( + l1TokenRebasable.address, + l2TokenRebasable.address, + deployer.address, + deployer.address, + amountToDepositNonRebasable, + packedTokenRateAndTimestampData + ); + + const deployerBalanceBefore = await l2TokenRebasable.balanceOf(deployer.address); + const totalSupplyBefore = await l2TokenRebasable.totalSupply(); + + const tx = await l2TokenBridge.connect(deployer).withdrawTo( + l2TokenRebasable.address, + recipient.address, + amountToWithdraw, + l1Gas, + data + ); + + await assert.emits(l2TokenBridge, tx, "WithdrawalInitiated", [ + l1TokenRebasable.address, + l2TokenRebasable.address, + deployer.address, + recipient.address, + amountToWithdraw, + data, + ]); + + await assert.emits(l2Messenger, tx, "SentMessage", [ + l1TokenBridgeEOA.address, + l2TokenBridge.address, + L1LidoTokensBridge__factory.createInterface().encodeFunctionData( + "finalizeERC20Withdrawal", + [ + l1TokenRebasable.address, + l2TokenRebasable.address, + deployer.address, + recipient.address, + amountReceivedWithdrawNonRebasable, + data, + ] + ), + 1, // message nonce + l1Gas, + ]); + + assert.equalBN( + await l2TokenRebasable.balanceOf(recipient.address), + deployerBalanceBefore.sub(amountToWithdraw) + ); + + assert.isTrue(almostEqual( + await l2TokenRebasable.totalSupply(), + totalSupplyBefore.sub(amountToWithdraw)) + ); + }) + + .test("withdrawTo() :: zero rebasable tokens", async (ctx) => { + const { + accounts: { deployer, l1TokenBridgeEOA, recipient }, + contracts: { + l2TokenBridge, + l2Messenger, + l1TokenRebasable, + l2TokenRebasable + }, + } = ctx; + + await pushTokenRate(ctx); + + const l1Gas = wei`1 wei`; + const data = "0xdeadbeaf"; + const recipientBalanceBefore = await l2TokenRebasable.balanceOf(recipient.address); + const totalSupplyBefore = await l2TokenRebasable.totalSupply(); + + const tx = await l2TokenBridge + .connect(recipient) + .withdrawTo( + l2TokenRebasable.address, + recipient.address, + 0, + l1Gas, + data); + + await assert.emits(l2TokenBridge, tx, "WithdrawalInitiated", [ + l1TokenRebasable.address, + l2TokenRebasable.address, + recipient.address, + recipient.address, + 0, + data, + ]); + + await assert.emits(l2Messenger, tx, "SentMessage", [ + l1TokenBridgeEOA.address, + l2TokenBridge.address, + L1LidoTokensBridge__factory.createInterface().encodeFunctionData( + "finalizeERC20Withdrawal", + [ + l1TokenRebasable.address, + l2TokenRebasable.address, + recipient.address, + recipient.address, + 0, + data, + ] + ), + 1, // message nonce + l1Gas, + ]); + + assert.equalBN(await l2TokenRebasable.balanceOf(deployer.address), recipientBalanceBefore); + assert.equalBN(await l2TokenRebasable.totalSupply(), totalSupplyBefore); + }) + + .test("withdrawTo() :: zero non-rebasable tokens", async (ctx) => { + const { + accounts: { l1TokenBridgeEOA, recipient }, + contracts: { + l2TokenBridge, + l2Messenger, + l1TokenNonRebasable, + l2TokenNonRebasable + }, + } = ctx; + + await pushTokenRate(ctx); + + const l1Gas = wei`1 wei`; + const data = "0xdeadbeaf"; + const recipientBalanceBefore = await l2TokenNonRebasable.balanceOf(recipient.address); + const totalSupplyBefore = await l2TokenNonRebasable.totalSupply(); + + const tx = await l2TokenBridge + .connect(recipient) + .withdrawTo( + l2TokenNonRebasable.address, + recipient.address, + 0, + l1Gas, + data); + + await assert.emits(l2TokenBridge, tx, "WithdrawalInitiated", [ + l1TokenNonRebasable.address, + l2TokenNonRebasable.address, + recipient.address, + recipient.address, + 0, + data, + ]); + + await assert.emits(l2Messenger, tx, "SentMessage", [ + l1TokenBridgeEOA.address, + l2TokenBridge.address, + L1LidoTokensBridge__factory.createInterface().encodeFunctionData( + "finalizeERC20Withdrawal", + [ + l1TokenNonRebasable.address, + l2TokenNonRebasable.address, + recipient.address, + recipient.address, + 0, + data, + ] + ), + 1, // message nonce + l1Gas, + ]); + + assert.equalBN(await l2TokenNonRebasable.balanceOf(recipient.address), recipientBalanceBefore); + assert.equalBN(await l2TokenNonRebasable.totalSupply(), totalSupplyBefore); + }) + + .test("withdrawTo() :: sending to L1 stETH address", async (ctx) => { + const { + accounts: { recipient }, + contracts: { + l2TokenBridge, + l1TokenRebasable, + l2TokenRebasable + }, + } = ctx; + + const l1Gas = wei`1 wei`; + const data = "0xdeadbeaf"; + + await assert.revertsWith( + l2TokenBridge + .connect(recipient) + .withdrawTo( + l2TokenRebasable.address, + l1TokenRebasable.address, + 0, + l1Gas, + data), + "ErrorTransferToL1TokenContract()" + ); + }) + + .test("finalizeDeposit() :: deposits disabled", async (ctx) => { + const { + accounts: { l2MessengerStubEOA, deployer, recipient }, + contracts: { l2TokenBridge, l1TokenNonRebasable, l2TokenNonRebasable, l1TokenRebasable, l2TokenRebasable }, + } = ctx; + + await l2TokenBridge.disableDeposits(); + + assert.isFalse(await l2TokenBridge.isDepositsEnabled()); + + await assert.revertsWith( + l2TokenBridge + .connect(l2MessengerStubEOA) + .finalizeDeposit( + l1TokenNonRebasable.address, + l2TokenNonRebasable.address, + deployer.address, + recipient.address, + wei`1 ether`, + "0x" + ), + "ErrorDepositsDisabled()" + ); + await assert.revertsWith( + l2TokenBridge + .connect(l2MessengerStubEOA) + .finalizeDeposit( + l1TokenRebasable.address, + l2TokenRebasable.address, + deployer.address, + recipient.address, + wei`1 ether`, + "0x" + ), + "ErrorDepositsDisabled()" + ); + }) + + .test("finalizeDeposit() :: unsupported l1Token", async (ctx) => { + const { + accounts: { l2MessengerStubEOA, deployer, recipient, stranger }, + contracts: { l2TokenBridge, l2TokenNonRebasable, l2TokenRebasable }, + } = ctx; + + await assert.revertsWith( + l2TokenBridge + .connect(l2MessengerStubEOA) + .finalizeDeposit( + stranger.address, + l2TokenNonRebasable.address, + deployer.address, + recipient.address, + wei`1 ether`, + "0x" + ), + "ErrorUnsupportedL1L2TokensPair(\"" + stranger.address + "\", \"" + l2TokenNonRebasable.address + "\")" + ); + await assert.revertsWith( + l2TokenBridge + .connect(l2MessengerStubEOA) + .finalizeDeposit( + stranger.address, + l2TokenRebasable.address, + deployer.address, + recipient.address, + wei`1 ether`, + "0x" + ), + "ErrorUnsupportedL1L2TokensPair(\"" + stranger.address + "\", \"" + l2TokenRebasable.address + "\")" + ); + }) + + .test("finalizeDeposit() :: unsupported l2Token", async (ctx) => { + const { + accounts: { l2MessengerStubEOA, deployer, recipient, stranger }, + contracts: { l2TokenBridge, l1TokenNonRebasable, l1TokenRebasable }, + } = ctx; + + await assert.revertsWith( + l2TokenBridge + .connect(l2MessengerStubEOA) + .finalizeDeposit( + l1TokenNonRebasable.address, + stranger.address, + deployer.address, + recipient.address, + wei`1 ether`, + "0x" + ), + "ErrorUnsupportedL1L2TokensPair(\"" + l1TokenNonRebasable.address + "\", \"" + stranger.address + "\")" + ); + await assert.revertsWith( + l2TokenBridge + .connect(l2MessengerStubEOA) + .finalizeDeposit( + l1TokenRebasable.address, + stranger.address, + deployer.address, + recipient.address, + wei`1 ether`, + "0x" + ), + "ErrorUnsupportedL1L2TokensPair(\"" + l1TokenRebasable.address + "\", \"" + stranger.address + "\")" + ); + }) + + .test("finalizeDeposit() :: unsupported tokens combination", async (ctx) => { + const { + accounts: { l2MessengerStubEOA, deployer, recipient }, + contracts: { l2TokenBridge, l1TokenNonRebasable, l1TokenRebasable, l2TokenNonRebasable, l2TokenRebasable }, + } = ctx; + + await assert.revertsWith( + l2TokenBridge + .connect(l2MessengerStubEOA) + .finalizeDeposit( + l1TokenNonRebasable.address, + l2TokenRebasable.address, + deployer.address, + recipient.address, + wei`1 ether`, + "0x" + ), + "ErrorUnsupportedL1L2TokensPair(\"" + l1TokenNonRebasable.address + "\", \"" + l2TokenRebasable.address + "\")" + ); + await assert.revertsWith( + l2TokenBridge + .connect(l2MessengerStubEOA) + .finalizeDeposit( + l1TokenRebasable.address, + l2TokenNonRebasable.address, + deployer.address, + recipient.address, + wei`1 ether`, + "0x" + ), + "ErrorUnsupportedL1L2TokensPair(\"" + l1TokenRebasable.address + "\", \"" + l2TokenNonRebasable.address + "\")" + ); + }) + + .test("finalizeDeposit() :: unauthorized messenger", async (ctx) => { + const { + contracts: { l2TokenBridge, l1TokenNonRebasable, l2TokenNonRebasable, l1TokenRebasable, l2TokenRebasable }, + accounts: { deployer, recipient, stranger }, + } = ctx; + + await assert.revertsWith( + l2TokenBridge + .connect(stranger) + .finalizeDeposit( + l1TokenNonRebasable.address, + l2TokenNonRebasable.address, + deployer.address, + recipient.address, + wei`1 ether`, + "0x" + ), + "ErrorUnauthorizedMessenger()" + ); + await assert.revertsWith( + l2TokenBridge + .connect(stranger) + .finalizeDeposit( + l1TokenRebasable.address, + l2TokenRebasable.address, + deployer.address, + recipient.address, + wei`1 ether`, + "0x" + ), + "ErrorUnauthorizedMessenger()" + ); + }) + + .test("finalizeDeposit() :: wrong cross domain sender", async (ctx) => { + const { + contracts: { l2TokenBridge, l1TokenNonRebasable, l2TokenNonRebasable, l1TokenRebasable, l2TokenRebasable, l2Messenger }, + accounts: { deployer, recipient, stranger, l2MessengerStubEOA }, + } = ctx; + + await l2Messenger.setXDomainMessageSender(stranger.address); + + await assert.revertsWith( + l2TokenBridge + .connect(l2MessengerStubEOA) + .finalizeDeposit( + l1TokenNonRebasable.address, + l2TokenNonRebasable.address, + deployer.address, + recipient.address, + wei`1 ether`, + "0x" + ), + "ErrorWrongCrossDomainSender()" + ); + + await assert.revertsWith( + l2TokenBridge + .connect(l2MessengerStubEOA) + .finalizeDeposit( + l1TokenRebasable.address, + l2TokenRebasable.address, + deployer.address, + recipient.address, + wei`1 ether`, + "0x" + ), + "ErrorWrongCrossDomainSender()" + ); + }) + + .test("finalizeDeposit() :: non-rebasable token flow", async (ctx) => { + const { + contracts: { l2TokenBridge, l1TokenNonRebasable, l2TokenNonRebasable, l2Messenger }, + accounts: { deployer, recipient, l2MessengerStubEOA, l1TokenBridgeEOA }, + constants: { exchangeRate } + } = ctx; + + await l2Messenger.setXDomainMessageSender(l1TokenBridgeEOA.address); + + const totalSupplyBefore = await l2TokenNonRebasable.totalSupply(); + + const amount = wei`1 ether`; + const data = "0xdeadbeaf"; + const currentBlockTimestamp = await getBlockTimestamp(ctx.provider, 0); + const dataToReceive = await tokenRateAndTimestampPacked( + exchangeRate, + currentBlockTimestamp, + data + ); + + + const tx = await l2TokenBridge + .connect(l2MessengerStubEOA) + .finalizeDeposit( + l1TokenNonRebasable.address, + l2TokenNonRebasable.address, + deployer.address, + recipient.address, + amount, + dataToReceive + ); + + await assert.emits(l2TokenBridge, tx, "DepositFinalized", [ + l1TokenNonRebasable.address, + l2TokenNonRebasable.address, + deployer.address, + recipient.address, + amount, + data, + ]); + + assert.equalBN(await l2TokenNonRebasable.balanceOf(recipient.address), amount); + assert.equalBN(await l2TokenNonRebasable.totalSupply(), totalSupplyBefore.add(amount)); + }) + + .test("finalizeDeposit() :: rebasable token flow", async (ctx) => { + const { + contracts: { l2TokenBridge, l1TokenRebasable, l2TokenRebasable, l2Messenger }, + accounts: { deployer, recipient, l2MessengerStubEOA, l1TokenBridgeEOA }, + constants: { exchangeRate, tokenRateDecimals } + } = ctx; + + await l2Messenger.setXDomainMessageSender(l1TokenBridgeEOA.address); + + const amountOfSharesToDeposit = wei`1 ether`; + const amountOfRebasableToken = rebasableFromNonRebasableL2( + wei.toBigNumber(amountOfSharesToDeposit), + tokenRateDecimals, + exchangeRate + ); + + const data = "0xdeadbeaf"; + const currentBlockTimestamp = await getBlockTimestamp(ctx.provider, 0); + const dataToReceive = await tokenRateAndTimestampPacked( + exchangeRate, + currentBlockTimestamp, + data + ); + + const tx = await l2TokenBridge + .connect(l2MessengerStubEOA) + .finalizeDeposit( + l1TokenRebasable.address, + l2TokenRebasable.address, + deployer.address, + recipient.address, + amountOfSharesToDeposit, + dataToReceive + ); + + await assert.emits(l2TokenBridge, tx, "DepositFinalized", [ + l1TokenRebasable.address, + l2TokenRebasable.address, + deployer.address, + recipient.address, + amountOfRebasableToken, + data, + ]); + + assert.equalBN(await l2TokenRebasable.balanceOf(recipient.address), amountOfRebasableToken); + }) + + .run(); + +async function ctxFactory() { + const [deployer, stranger, recipient, l1TokenBridgeEOA] = await hre.ethers.getSigners(); + const zero = await hre.ethers.getSigner(hre.ethers.constants.AddressZero); + + const tokenDecimals = 18; + const tokenRateDecimals = BigNumber.from(27); + const totalPooledEther = BigNumber.from('9309904612343950493629678'); + const totalShares = BigNumber.from('7975822843597609202337218'); + const exchangeRate = getExchangeRate(tokenRateDecimals, totalPooledEther, totalShares); + const tokenRateOutdatedDelay = 86400; + const maxAllowedL2ToL1ClockLag = BigNumber.from(86400); + const maxAllowedTokenRateDeviationPerDay = BigNumber.from(500); + const oldestRateAllowedInPauseTimeSpan = BigNumber.from(86400*3); + const maxAllowedTimeBetweenTokenRateUpdates = BigNumber.from(3600); + + const l2MessengerStub = await new CrossDomainMessengerStub__factory( + deployer + ).deploy({ value: wei.toBigNumber(wei`1 ether`) }); + const l2MessengerStubEOA = await testing.impersonate(l2MessengerStub.address); + await l2MessengerStub.setXDomainMessageSender(l1TokenBridgeEOA.address); + + const emptyContract = await new EmptyContractStub__factory(deployer).deploy({ + value: wei.toBigNumber(wei`1 ether`), + }); + const emptyContractEOA = await testing.impersonate(emptyContract.address); + + const [ + , + , + , + , + , + , + , + l2TokenBridgeProxyAddress + ] = await predictAddresses(deployer, 8); + + const l1TokenRebasableStub = await new ERC20BridgedStub__factory(deployer).deploy( + "L1 Token Rebasable", + "L1R" + ); + + const l1TokenNonRebasableStub = await new ERC20WrapperStub__factory(deployer).deploy( + l1TokenRebasableStub.address, + "L1 Token Non Rebasable", + "L1NR", + totalPooledEther, + totalShares + ); + + const l2TokenNonRebasableStub = await new ERC20BridgedStub__factory(deployer).deploy( + "L2 Token Non Rebasable", + "L2NR" + ); + + const tokenRateOracleImpl = await new TokenRateOracle__factory(deployer).deploy( + l2MessengerStub.address, + l2TokenBridgeProxyAddress, + l1TokenBridgeEOA.address, + tokenRateOutdatedDelay, + maxAllowedL2ToL1ClockLag, + maxAllowedTokenRateDeviationPerDay, + oldestRateAllowedInPauseTimeSpan, + maxAllowedTimeBetweenTokenRateUpdates + ); + + const provider = await hre.ethers.provider; + const blockNumber = await provider.getBlockNumber(); + const blockTimestamp = (await provider.getBlock(blockNumber)).timestamp; + const tokenRateOracleProxy = await new OssifiableProxy__factory( + deployer + ).deploy( + tokenRateOracleImpl.address, + deployer.address, + tokenRateOracleImpl.interface.encodeFunctionData("initialize", [ + deployer.address, + exchangeRate, + blockTimestamp + ]) + ); + + const tokenRateOracle = TokenRateOracle__factory.connect( + tokenRateOracleProxy.address, + deployer + ); + + const l2TokenRebasableStub = await new ERC20RebasableBridgedPermit__factory(deployer).deploy( + "L2 Token Rebasable", + "L2R", + "1", + tokenDecimals, + l2TokenNonRebasableStub.address, + tokenRateOracle.address, + l2TokenBridgeProxyAddress + ); + + const l2TokenBridgeImpl = await new L2ERC20ExtendedTokensBridge__factory( + deployer + ).deploy( + l2MessengerStub.address, + l1TokenBridgeEOA.address, + l1TokenNonRebasableStub.address, + l1TokenRebasableStub.address, + l2TokenNonRebasableStub.address, + l2TokenRebasableStub.address + ); + + const l2TokenBridgeProxy = await new OssifiableProxy__factory( + deployer + ).deploy( + l2TokenBridgeImpl.address, + deployer.address, + l2TokenBridgeImpl.interface.encodeFunctionData("initialize", [ + deployer.address, + ]) + ); + + const l2TokenBridge = L2ERC20ExtendedTokensBridge__factory.connect( + l2TokenBridgeProxy.address, + deployer + ); + + const roles = await Promise.all([ + l2TokenBridge.DEPOSITS_ENABLER_ROLE(), + l2TokenBridge.DEPOSITS_DISABLER_ROLE(), + l2TokenBridge.WITHDRAWALS_ENABLER_ROLE(), + l2TokenBridge.WITHDRAWALS_DISABLER_ROLE(), + ]); + + for (const role of roles) { + await l2TokenBridge.grantRole(role, deployer.address); + } + + await l2TokenBridge.enableDeposits(); + await l2TokenBridge.enableWithdrawals(); + + return { + constants: { + exchangeRate, + tokenRateDecimals + }, + accounts: { + deployer, + stranger, + zero, + recipient, + l2MessengerStubEOA, + emptyContractEOA, + l1TokenBridgeEOA, + }, + contracts: { + l1TokenNonRebasable: l1TokenNonRebasableStub, + l1TokenRebasable: l1TokenRebasableStub, + l2TokenNonRebasable: l2TokenNonRebasableStub, + l2TokenRebasable: l2TokenRebasableStub, + l2Messenger: l2MessengerStub, + l2TokenBridge: l2TokenBridge + }, + provider + }; +} + +type ContextType = Awaited> + +async function pushTokenRate(ctx: ContextType) { + + const currentBlockTimestamp = await getBlockTimestamp(ctx.provider, 0); + const packedTokenRateAndTimestampData = await tokenRateAndTimestampPacked( + ctx.constants.exchangeRate, + currentBlockTimestamp, + "0x" + ); + + await ctx.contracts.l2TokenBridge + .connect(ctx.accounts.l2MessengerStubEOA) + .finalizeDeposit( + ctx.contracts.l1TokenRebasable.address, + ctx.contracts.l2TokenRebasable.address, + ctx.accounts.deployer.address, + ctx.accounts.deployer.address, + 0, + packedTokenRateAndTimestampData + ); +} + +async function getL2TokenBridgeImpl(deployer: SignerWithAddress, l1TokenBridge: string) { + const decimals = 18; + const tokenRateDecimals = BigNumber.from(27); + const totalPooledEther = BigNumber.from('9309904612343950493629678'); + const totalShares = BigNumber.from('7975822843597609202337218'); + const exchangeRate = getExchangeRate(tokenRateDecimals, totalPooledEther, totalShares); + const tokenRateOutdatedDelay = 86400; + const maxAllowedL2ToL1ClockLag = BigNumber.from(86400); + const maxAllowedTokenRateDeviationPerDay = BigNumber.from(500); + const oldestRateAllowedInPauseTimeSpan = BigNumber.from(86400*3); + const maxAllowedTimeBetweenTokenRateUpdates = BigNumber.from(3600); + + const l2MessengerStub = await new CrossDomainMessengerStub__factory( + deployer + ).deploy({ value: wei.toBigNumber(wei`1 ether`) }); + await l2MessengerStub.setXDomainMessageSender(l1TokenBridge); + + const [ + , + , + , + , + , + , + , + l2TokenBridgeProxyAddress + ] = await predictAddresses(deployer, 8); + + const l1TokenRebasableStub = await new ERC20BridgedStub__factory(deployer).deploy( + "L1 Token Rebasable", + "L1R" + ); + + const l1TokenNonRebasableStub = await new ERC20WrapperStub__factory(deployer).deploy( + l1TokenRebasableStub.address, + "L1 Token Non Rebasable", + "L1NR", + totalPooledEther, totalShares + ); + + const l2TokenNonRebasableStub = await new ERC20BridgedStub__factory(deployer).deploy( + "L2 Token Non Rebasable", + "L2NR" + ); + + const tokenRateOracleImpl = await new TokenRateOracle__factory(deployer).deploy( + l2MessengerStub.address, + l2TokenBridgeProxyAddress, + l1TokenBridge, + tokenRateOutdatedDelay, + maxAllowedL2ToL1ClockLag, + maxAllowedTokenRateDeviationPerDay, + oldestRateAllowedInPauseTimeSpan, + maxAllowedTimeBetweenTokenRateUpdates + ); + + const provider = await hre.ethers.provider; + const blockNumber = await provider.getBlockNumber(); + const blockTimestamp = (await provider.getBlock(blockNumber)).timestamp; + const tokenRateOracleProxy = await new OssifiableProxy__factory( + deployer + ).deploy( + tokenRateOracleImpl.address, + deployer.address, + tokenRateOracleImpl.interface.encodeFunctionData("initialize", [ + deployer.address, + exchangeRate, + blockTimestamp + ]) + ); + + const tokenRateOracle = TokenRateOracle__factory.connect( + tokenRateOracleProxy.address, + deployer + ); + + const l2TokenRebasableStub = await new ERC20RebasableBridgedPermit__factory(deployer).deploy( + "L2 Token Rebasable", + "L2R", + "1", + decimals, + l2TokenNonRebasableStub.address, + tokenRateOracle.address, + l2TokenBridgeProxyAddress + ); + + const l2TokenBridgeImpl = await new L2ERC20ExtendedTokensBridge__factory( + deployer + ).deploy( + l2MessengerStub.address, + l1TokenBridge, + l1TokenNonRebasableStub.address, + l1TokenRebasableStub.address, + l2TokenNonRebasableStub.address, + l2TokenRebasableStub.address + ); + return l2TokenBridgeImpl; +} + +function almostEqual(num1: BigNumber, num2: BigNumber) { + const delta = (num1.sub(num2)).abs(); + return delta.lte(BigNumber.from('2')); +} diff --git a/test/optimism/L2ERC20TokenBridge.unit.test.ts b/test/optimism/L2ERC20TokenBridge.unit.test.ts deleted file mode 100644 index 97e40afa..00000000 --- a/test/optimism/L2ERC20TokenBridge.unit.test.ts +++ /dev/null @@ -1,454 +0,0 @@ -import hre from "hardhat"; -import { - ERC20BridgedStub__factory, - L1ERC20TokenBridge__factory, - L2ERC20TokenBridge__factory, - OssifiableProxy__factory, - EmptyContractStub__factory, - CrossDomainMessengerStub__factory, -} from "../../typechain"; -import testing, { unit } from "../../utils/testing"; -import { wei } from "../../utils/wei"; -import { assert } from "chai"; - -unit("Optimism:: L2ERC20TokenBridge", ctxFactory) - .test("l1TokenBridge()", async (ctx) => { - assert.equal( - await ctx.l2TokenBridge.l1TokenBridge(), - ctx.accounts.l1TokenBridgeEOA.address - ); - }) - - .test("withdraw() :: withdrawals disabled", async (ctx) => { - const { - l2TokenBridge, - stubs: { l2Token: l2TokenStub }, - } = ctx; - - await ctx.l2TokenBridge.disableWithdrawals(); - - assert.isFalse(await ctx.l2TokenBridge.isWithdrawalsEnabled()); - - await assert.revertsWith( - l2TokenBridge.withdraw( - l2TokenStub.address, - wei`1 ether`, - wei`1 gwei`, - "0x" - ), - "ErrorWithdrawalsDisabled()" - ); - }) - - .test("withdraw() :: unsupported l2Token", async (ctx) => { - const { - l2TokenBridge, - accounts: { stranger }, - } = ctx; - await assert.revertsWith( - l2TokenBridge.withdraw(stranger.address, wei`1 ether`, wei`1 gwei`, "0x"), - "ErrorUnsupportedL2Token()" - ); - }) - - .test("withdraw()", async (ctx) => { - const { - l2TokenBridge, - accounts: { deployer, l1TokenBridgeEOA }, - stubs: { - l2Messenger: l2MessengerStub, - l1Token: l1TokenStub, - l2Token: l2TokenStub, - }, - } = ctx; - - const deployerBalanceBefore = await l2TokenStub.balanceOf(deployer.address); - const totalSupplyBefore = await l2TokenStub.totalSupply(); - - const amount = wei`1 ether`; - const l1Gas = wei`1 wei`; - const data = "0xdeadbeaf"; - - const tx = await l2TokenBridge.withdraw( - l2TokenStub.address, - amount, - l1Gas, - data - ); - - await assert.emits(l2TokenBridge, tx, "WithdrawalInitiated", [ - l1TokenStub.address, - l2TokenStub.address, - deployer.address, - deployer.address, - amount, - data, - ]); - - await assert.emits(l2MessengerStub, tx, "SentMessage", [ - l1TokenBridgeEOA.address, - l2TokenBridge.address, - L1ERC20TokenBridge__factory.createInterface().encodeFunctionData( - "finalizeERC20Withdrawal", - [ - l1TokenStub.address, - l2TokenStub.address, - deployer.address, - deployer.address, - amount, - data, - ] - ), - 1, // message nonce - l1Gas, - ]); - - assert.equalBN( - await l2TokenStub.balanceOf(deployer.address), - deployerBalanceBefore.sub(amount) - ); - - assert.equalBN( - await l2TokenStub.totalSupply(), - totalSupplyBefore.sub(amount) - ); - }) - - .test("withdrawTo() :: withdrawals disabled", async (ctx) => { - const { - l2TokenBridge, - stubs: { l2Token: l2TokenStub }, - accounts: { recipient }, - } = ctx; - - await ctx.l2TokenBridge.disableWithdrawals(); - - assert.isFalse(await ctx.l2TokenBridge.isWithdrawalsEnabled()); - - await assert.revertsWith( - l2TokenBridge.withdrawTo( - l2TokenStub.address, - recipient.address, - wei`1 ether`, - wei`1 gwei`, - "0x" - ), - "ErrorWithdrawalsDisabled()" - ); - }) - - .test("withdrawTo() :: unsupported l2Token", async (ctx) => { - const { - l2TokenBridge, - accounts: { stranger, recipient }, - } = ctx; - await assert.revertsWith( - l2TokenBridge.withdrawTo( - stranger.address, - recipient.address, - wei`1 ether`, - wei`1 gwei`, - "0x" - ), - "ErrorUnsupportedL2Token()" - ); - }) - - .test("withdrawTo()", async (ctx) => { - const { - l2TokenBridge, - accounts: { deployer, recipient, l1TokenBridgeEOA }, - stubs: { - l2Messenger: l2MessengerStub, - l1Token: l1TokenStub, - l2Token: l2TokenStub, - }, - } = ctx; - - const deployerBalanceBefore = await l2TokenStub.balanceOf(deployer.address); - const totalSupplyBefore = await l2TokenStub.totalSupply(); - - const amount = wei`1 ether`; - const l1Gas = wei`1 wei`; - const data = "0xdeadbeaf"; - - const tx = await l2TokenBridge.withdrawTo( - l2TokenStub.address, - recipient.address, - amount, - l1Gas, - data - ); - - await assert.emits(l2TokenBridge, tx, "WithdrawalInitiated", [ - l1TokenStub.address, - l2TokenStub.address, - deployer.address, - recipient.address, - amount, - data, - ]); - - await assert.emits(l2MessengerStub, tx, "SentMessage", [ - l1TokenBridgeEOA.address, - l2TokenBridge.address, - L1ERC20TokenBridge__factory.createInterface().encodeFunctionData( - "finalizeERC20Withdrawal", - [ - l1TokenStub.address, - l2TokenStub.address, - deployer.address, - recipient.address, - amount, - data, - ] - ), - 1, // message nonce - l1Gas, - ]); - - assert.equalBN( - await l2TokenStub.balanceOf(deployer.address), - deployerBalanceBefore.sub(amount) - ); - - assert.equalBN( - await l2TokenStub.totalSupply(), - totalSupplyBefore.sub(amount) - ); - }) - - .test("finalizeDeposit() :: deposits disabled", async (ctx) => { - const { - l2TokenBridge, - accounts: { l2MessengerStubEOA, deployer, recipient }, - stubs: { l1Token: l1TokenStub, l2Token: l2TokenStub }, - } = ctx; - - await l2TokenBridge.disableDeposits(); - - assert.isFalse(await l2TokenBridge.isDepositsEnabled()); - - await assert.revertsWith( - l2TokenBridge - .connect(l2MessengerStubEOA) - .finalizeDeposit( - l1TokenStub.address, - l2TokenStub.address, - deployer.address, - recipient.address, - wei`1 ether`, - "0x" - ), - "ErrorDepositsDisabled()" - ); - }) - - .test("finalizeDeposit() :: unsupported l1Token", async (ctx) => { - const { - l2TokenBridge, - accounts: { l2MessengerStubEOA, deployer, recipient, stranger }, - stubs: { l2Token: l2TokenStub }, - } = ctx; - - await assert.revertsWith( - l2TokenBridge - .connect(l2MessengerStubEOA) - .finalizeDeposit( - stranger.address, - l2TokenStub.address, - deployer.address, - recipient.address, - wei`1 ether`, - "0x" - ), - "ErrorUnsupportedL1Token()" - ); - }) - - .test("finalizeDeposit() :: unsupported l2Token", async (ctx) => { - const { - l2TokenBridge, - accounts: { l2MessengerStubEOA, deployer, recipient, stranger }, - stubs: { l1Token: l1TokenStub }, - } = ctx; - - await assert.revertsWith( - l2TokenBridge - .connect(l2MessengerStubEOA) - .finalizeDeposit( - l1TokenStub.address, - stranger.address, - deployer.address, - recipient.address, - wei`1 ether`, - "0x" - ), - "ErrorUnsupportedL2Token()" - ); - }) - - .test("finalizeDeposit() :: unauthorized messenger", async (ctx) => { - const { - l2TokenBridge, - stubs: { l1Token, l2Token }, - accounts: { deployer, recipient, stranger }, - } = ctx; - - await assert.revertsWith( - l2TokenBridge - .connect(stranger) - .finalizeDeposit( - l1Token.address, - l2Token.address, - deployer.address, - recipient.address, - wei`1 ether`, - "0x" - ), - "ErrorUnauthorizedMessenger()" - ); - }) - - .test("finalizeDeposit() :: wrong cross domain sender", async (ctx) => { - const { - l2TokenBridge, - stubs: { l1Token, l2Token, l2Messenger }, - accounts: { deployer, recipient, stranger, l2MessengerStubEOA }, - } = ctx; - - await l2Messenger.setXDomainMessageSender(stranger.address); - - await assert.revertsWith( - l2TokenBridge - .connect(l2MessengerStubEOA) - .finalizeDeposit( - l1Token.address, - l2Token.address, - deployer.address, - recipient.address, - wei`1 ether`, - "0x" - ), - "ErrorWrongCrossDomainSender()" - ); - }) - - .test("finalizeDeposit()", async (ctx) => { - const { - l2TokenBridge, - stubs: { l1Token, l2Token, l2Messenger }, - accounts: { deployer, recipient, l2MessengerStubEOA, l1TokenBridgeEOA }, - } = ctx; - - await l2Messenger.setXDomainMessageSender(l1TokenBridgeEOA.address); - - const totalSupplyBefore = await l2Token.totalSupply(); - - const amount = wei`1 ether`; - const data = "0xdeadbeaf"; - - const tx = await l2TokenBridge - .connect(l2MessengerStubEOA) - .finalizeDeposit( - l1Token.address, - l2Token.address, - deployer.address, - recipient.address, - amount, - data - ); - - await assert.emits(l2TokenBridge, tx, "DepositFinalized", [ - l1Token.address, - l2Token.address, - deployer.address, - recipient.address, - amount, - data, - ]); - - assert.equalBN(await l2Token.balanceOf(recipient.address), amount); - assert.equalBN(await l2Token.totalSupply(), totalSupplyBefore.add(amount)); - }) - - .run(); - -async function ctxFactory() { - const [deployer, stranger, recipient, l1TokenBridgeEOA] = - await hre.ethers.getSigners(); - - const l2Messenger = await new CrossDomainMessengerStub__factory( - deployer - ).deploy({ value: wei.toBigNumber(wei`1 ether`) }); - - const l2MessengerStubEOA = await testing.impersonate(l2Messenger.address); - - const l1Token = await new ERC20BridgedStub__factory(deployer).deploy( - "L1 Token", - "L1" - ); - - const l2Token = await new ERC20BridgedStub__factory(deployer).deploy( - "L2 Token", - "L2" - ); - - const emptyContract = await new EmptyContractStub__factory(deployer).deploy({ - value: wei.toBigNumber(wei`1 ether`), - }); - const emptyContractEOA = await testing.impersonate(emptyContract.address); - - const l2TokenBridgeImpl = await new L2ERC20TokenBridge__factory( - deployer - ).deploy( - l2Messenger.address, - l1TokenBridgeEOA.address, - l1Token.address, - l2Token.address - ); - - const l2TokenBridgeProxy = await new OssifiableProxy__factory( - deployer - ).deploy( - l2TokenBridgeImpl.address, - deployer.address, - l2TokenBridgeImpl.interface.encodeFunctionData("initialize", [ - deployer.address, - ]) - ); - - const l2TokenBridge = L2ERC20TokenBridge__factory.connect( - l2TokenBridgeProxy.address, - deployer - ); - - await l2Token.transfer(l2TokenBridge.address, wei`100 ether`); - - const roles = await Promise.all([ - l2TokenBridge.DEPOSITS_ENABLER_ROLE(), - l2TokenBridge.DEPOSITS_DISABLER_ROLE(), - l2TokenBridge.WITHDRAWALS_ENABLER_ROLE(), - l2TokenBridge.WITHDRAWALS_DISABLER_ROLE(), - ]); - - for (const role of roles) { - await l2TokenBridge.grantRole(role, deployer.address); - } - - await l2TokenBridge.enableDeposits(); - await l2TokenBridge.enableWithdrawals(); - - return { - stubs: { l1Token, l2Token, l2Messenger: l2Messenger }, - accounts: { - deployer, - stranger, - recipient, - l2MessengerStubEOA, - emptyContractEOA, - l1TokenBridgeEOA, - }, - l2TokenBridge, - }; -} diff --git a/test/optimism/OpStackTokenRatePusher.unit.test.ts b/test/optimism/OpStackTokenRatePusher.unit.test.ts new file mode 100644 index 00000000..76fec554 --- /dev/null +++ b/test/optimism/OpStackTokenRatePusher.unit.test.ts @@ -0,0 +1,163 @@ +import hre, { ethers } from "hardhat"; +import { assert } from "chai"; +import { BigNumber } from 'ethers' +import { unit } from "../../utils/testing"; +import { wei } from "../../utils/wei"; +import { getInterfaceID, getExchangeRate } from "../../utils/testing/helpers"; +import { + OpStackTokenRatePusher__factory, + CrossDomainMessengerStub__factory, + ITokenRateOracle__factory, + ITokenRatePusher__factory, + ERC20BridgedStub__factory, + ERC20WrapperStub__factory, + AccountingOracleStub__factory + +} from "../../typechain"; + +unit("OpStackTokenRatePusher", ctxFactory) + + .test("constructor() :: zero params", async (ctx) => { + + const { deployer, stranger, zero } = ctx.accounts; + + const accountingOracle = await new AccountingOracleStub__factory(deployer).deploy(1,2,3); + + await assert.revertsWith(new OpStackTokenRatePusher__factory( + deployer + ).deploy( + zero.address, + stranger.address, + accountingOracle.address, + stranger.address, + 10 + ), "ErrorZeroAddressMessenger()"); + + await assert.revertsWith(new OpStackTokenRatePusher__factory( + deployer + ).deploy( + stranger.address, + zero.address, + accountingOracle.address, + stranger.address, + 10 + ), "ErrorZeroAddressWstETH()"); + + await assert.revertsWith(new OpStackTokenRatePusher__factory( + deployer + ).deploy( + stranger.address, + stranger.address, + zero.address, + stranger.address, + 10 + ), "ErrorZeroAddressAccountingOracle()"); + + await assert.revertsWith(new OpStackTokenRatePusher__factory( + deployer + ).deploy( + stranger.address, + stranger.address, + accountingOracle.address, + zero.address, + 10 + ), "ErrorZeroAddressTokenRateOracle()"); + }) + + .test("initial state", async (ctx) => { + const { tokenRateOracle } = ctx.accounts; + const { opStackTokenRatePusher, l1MessengerStub, accountingOracle } = ctx.contracts; + const { genesisTime, secondsPerSlot } = ctx.constants; + + assert.equal(await opStackTokenRatePusher.MESSENGER(), l1MessengerStub.address); + assert.equalBN(await opStackTokenRatePusher.GENESIS_TIME(), genesisTime); + assert.equalBN(await opStackTokenRatePusher.SECONDS_PER_SLOT(), secondsPerSlot); + assert.equal(await opStackTokenRatePusher.ACCOUNTING_ORACLE(), accountingOracle.address); + assert.equal(await opStackTokenRatePusher.L2_TOKEN_RATE_ORACLE(), tokenRateOracle.address); + assert.equalBN(await opStackTokenRatePusher.L2_GAS_LIMIT_FOR_PUSHING_TOKEN_RATE(), 123); + const iTokenRatePusher = getInterfaceID(ITokenRatePusher__factory.createInterface()); + assert.isTrue(await opStackTokenRatePusher.supportsInterface(iTokenRatePusher._hex)); + }) + + .test("pushTokenRate() :: success", async (ctx) => { + const { tokenRateOracle } = ctx.accounts; + const { l2GasLimitForPushingTokenRate, tokenRate, updateRateTime } = ctx.constants; + const { opStackTokenRatePusher, l1MessengerStub } = ctx.contracts; + + let tx = await opStackTokenRatePusher.pushTokenRate(); + + await assert.emits(l1MessengerStub, tx, "SentMessage", [ + tokenRateOracle.address, + opStackTokenRatePusher.address, + ITokenRateOracle__factory.createInterface().encodeFunctionData( + "updateRate", + [ + tokenRate, + updateRateTime + ] + ), + 1, + l2GasLimitForPushingTokenRate, + ]); + }) + + .run(); + +async function ctxFactory() { + /// --------------------------- + /// constants + /// --------------------------- + const [deployer, bridge, stranger, tokenRateOracle, l1TokenBridgeEOA] = await ethers.getSigners(); + const zero = await hre.ethers.getSigner(hre.ethers.constants.AddressZero); + + const totalPooledEther = BigNumber.from('9309904612343950493629678'); + const totalShares = BigNumber.from('7975822843597609202337218'); + const tokenRateDecimals = BigNumber.from(27); + const tokenRate = getExchangeRate(tokenRateDecimals, totalPooledEther, totalShares); + + const genesisTime = BigNumber.from(1); + const secondsPerSlot = BigNumber.from(2); + const lastProcessingRefSlot = BigNumber.from(3); + const updateRateTime = genesisTime.add(secondsPerSlot.mul(lastProcessingRefSlot)); + const l2GasLimitForPushingTokenRate = 123; + + const l1MessengerStub = await new CrossDomainMessengerStub__factory(deployer) + .deploy({ value: wei.toBigNumber(wei`1 ether`) }); + await l1MessengerStub.setXDomainMessageSender(l1TokenBridgeEOA.address); + + /// --------------------------- + /// contracts + /// --------------------------- + const l1TokenRebasableStub = await new ERC20BridgedStub__factory(deployer).deploy( + "L1 Token Rebasable", + "L1R" + ); + + const l1TokenNonRebasableStub = await new ERC20WrapperStub__factory(deployer).deploy( + l1TokenRebasableStub.address, + "L1 Token Non Rebasable", + "L1NR", + totalPooledEther, + totalShares + ); + + const accountingOracle = await new AccountingOracleStub__factory(deployer).deploy( + genesisTime, + secondsPerSlot, + lastProcessingRefSlot + ); + + const opStackTokenRatePusher = await new OpStackTokenRatePusher__factory(deployer).deploy( + l1MessengerStub.address, + l1TokenNonRebasableStub.address, + accountingOracle.address, + tokenRateOracle.address, + l2GasLimitForPushingTokenRate + ); + + return { + accounts: { deployer, bridge, stranger, zero, tokenRateOracle }, + contracts: { opStackTokenRatePusher, l1MessengerStub, l1TokenNonRebasableStub, accountingOracle }, + constants: { l2GasLimitForPushingTokenRate, tokenRate, updateRateTime, genesisTime, secondsPerSlot, lastProcessingRefSlot } + }; +} diff --git a/test/optimism/TokenRateNotifier.unit.test.ts b/test/optimism/TokenRateNotifier.unit.test.ts new file mode 100644 index 00000000..e0d7b38b --- /dev/null +++ b/test/optimism/TokenRateNotifier.unit.test.ts @@ -0,0 +1,381 @@ +import { ethers } from "hardhat"; +import { assert } from "chai"; +import { BigNumber } from 'ethers' +import { unit } from "../../utils/testing"; +import { wei } from "../../utils/wei"; +import { getInterfaceID, getExchangeRate } from "../../utils/testing/helpers"; +import { SignerWithAddress } from "@nomiclabs/hardhat-ethers/signers"; +import { + TokenRateNotifier__factory, + ITokenRatePusher__factory, + OpStackTokenRatePusher__factory, + ITokenRateOracle__factory, + CrossDomainMessengerStub__factory, + OpStackTokenRatePusherWithSomeErrorStub__factory, + OpStackTokenRatePusherWithOutOfGasErrorStub__factory, + ERC20BridgedStub__factory, + ERC20WrapperStub__factory, + AccountingOracleStub__factory +} from "../../typechain"; + +unit("TokenRateNotifier", ctxFactory) + + .test("deploy with zero address owner", async (ctx) => { + const { deployer, l1AuthorizedRebaseCaller } = ctx.accounts; + + await assert.revertsWith( + new TokenRateNotifier__factory(deployer).deploy(ethers.constants.AddressZero, l1AuthorizedRebaseCaller.address), + "ErrorZeroAddressOwner()" + ); + }) + + .test("deploy with zero address rebase caller", async (ctx) => { + const { deployer } = ctx.accounts; + + await assert.revertsWith( + new TokenRateNotifier__factory(deployer).deploy(deployer.address, ethers.constants.AddressZero), + "ErrorZeroAddressCaller()" + ); + }) + + .test("initial state", async (ctx) => { + const { tokenRateNotifier } = ctx.contracts; + + assert.equalBN(await tokenRateNotifier.MAX_OBSERVERS_COUNT(), 32); + const iTokenRateObserver = getInterfaceID(ITokenRatePusher__factory.createInterface()); + assert.equal(await tokenRateNotifier.REQUIRED_INTERFACE(), iTokenRateObserver._hex); + assert.equalBN(await tokenRateNotifier.observersLength(), 0); + }) + + .test("addObserver() :: not the owner", async (ctx) => { + const { tokenRateNotifier } = ctx.contracts; + const { stranger } = ctx.accounts; + + await assert.revertsWith( + tokenRateNotifier + .connect(stranger) + .addObserver(ethers.constants.AddressZero), + "Ownable: caller is not the owner" + ); + }) + + .test("addObserver() :: revert on adding zero address observer", async (ctx) => { + const { tokenRateNotifier } = ctx.contracts; + + await assert.revertsWith( + tokenRateNotifier + .connect(ctx.accounts.owner) + .addObserver(ethers.constants.AddressZero), + "ErrorZeroAddressObserver()" + ); + }) + + .test("addObserver() :: revert on adding observer with bad interface", async (ctx) => { + const { tokenRateNotifier } = ctx.contracts; + const { deployer, l1AuthorizedRebaseCaller } = ctx.accounts; + + const observer = await new TokenRateNotifier__factory(deployer).deploy(deployer.address, l1AuthorizedRebaseCaller.address); + await assert.revertsWith( + tokenRateNotifier + .connect(ctx.accounts.owner) + .addObserver(observer.address), + "ErrorBadObserverInterface()" + ); + }) + + .test("addObserver() :: revert on adding too many observers", async (ctx) => { + const { tokenRateNotifier, opStackTokenRatePusher } = ctx.contracts; + const { deployer, owner, tokenRateOracle, l1AuthorizedRebaseCaller } = ctx.accounts; + const { l2GasLimitForPushingTokenRate, tokenRate, totalPooledEther, totalShares, genesisTime, secondsPerSlot, lastProcessingRefSlot } = ctx.constants; + + assert.equalBN(await tokenRateNotifier.observersLength(), 0); + const maxObservers = await tokenRateNotifier.MAX_OBSERVERS_COUNT(); + for (let i = 0; i < maxObservers.toNumber(); i++) { + + const { + opStackTokenRatePusher + } = await createContracts( + totalPooledEther, + totalShares, + tokenRate, + genesisTime, + secondsPerSlot, + lastProcessingRefSlot, + deployer, + owner, + tokenRateOracle, + l2GasLimitForPushingTokenRate, + l1AuthorizedRebaseCaller + ); + + await tokenRateNotifier + .connect(ctx.accounts.owner) + .addObserver(opStackTokenRatePusher.address); + } + assert.equalBN(await tokenRateNotifier.observersLength(), maxObservers); + + await assert.revertsWith( + tokenRateNotifier + .connect(ctx.accounts.owner) + .addObserver(opStackTokenRatePusher.address), + "ErrorMaxObserversCountExceeded()" + ); + }) + + .test("addObserver() :: revert on adding the same observer twice", async (ctx) => { + const { tokenRateNotifier, opStackTokenRatePusher } = ctx.contracts; + + await tokenRateNotifier + .connect(ctx.accounts.owner) + .addObserver(opStackTokenRatePusher.address); + + await assert.revertsWith( + tokenRateNotifier + .connect(ctx.accounts.owner) + .addObserver(opStackTokenRatePusher.address), + "ErrorAddExistedObserver()" + ); + }) + + .test("addObserver() :: happy path of adding observer", async (ctx) => { + const { tokenRateNotifier, opStackTokenRatePusher } = ctx.contracts; + + assert.equalBN(await tokenRateNotifier.observersLength(), 0); + const tx = await tokenRateNotifier + .connect(ctx.accounts.owner) + .addObserver(opStackTokenRatePusher.address); + assert.equalBN(await tokenRateNotifier.observersLength(), 1); + + await assert.emits(tokenRateNotifier, tx, "ObserverAdded", [opStackTokenRatePusher.address]); + }) + + .test("removeObserver() :: revert on calling by not the owner", async (ctx) => { + const { tokenRateNotifier } = ctx.contracts; + const { stranger } = ctx.accounts; + + await assert.revertsWith( + tokenRateNotifier + .connect(stranger) + .removeObserver(ethers.constants.AddressZero), + "Ownable: caller is not the owner" + ); + }) + + .test("removeObserver() :: revert on removing non-added observer", async (ctx) => { + const { tokenRateNotifier, opStackTokenRatePusher } = ctx.contracts; + + assert.equalBN(await tokenRateNotifier.observersLength(), 0); + + await assert.revertsWith( + tokenRateNotifier + .connect(ctx.accounts.owner) + .removeObserver(opStackTokenRatePusher.address), + "ErrorNoObserverToRemove()" + ); + }) + + .test("removeObserver() :: happy path of removing observer", async (ctx) => { + const { tokenRateNotifier, opStackTokenRatePusher } = ctx.contracts; + + assert.equalBN(await tokenRateNotifier.observersLength(), 0); + + await tokenRateNotifier + .connect(ctx.accounts.owner) + .addObserver(opStackTokenRatePusher.address); + + assert.equalBN(await tokenRateNotifier.observersLength(), 1); + + const tx = await tokenRateNotifier + .connect(ctx.accounts.owner) + .removeObserver(opStackTokenRatePusher.address); + await assert.emits(tokenRateNotifier, tx, "ObserverRemoved", [opStackTokenRatePusher.address]); + + assert.equalBN(await tokenRateNotifier.observersLength(), 0); + }) + + .test("handlePostTokenRebase() :: unauthorized caller", async (ctx) => { + const { tokenRateNotifier } = ctx.contracts; + const { stranger } = ctx.accounts; + + await assert.revertsWith( + tokenRateNotifier.connect(stranger).handlePostTokenRebase(1, 2, 3, 4, 5, 6, 7), + "ErrorNotAuthorizedRebaseCaller()" + ); + }) + + .test("handlePostTokenRebase() :: failed with some error", async (ctx) => { + const { tokenRateNotifier } = ctx.contracts; + const { deployer, l1AuthorizedRebaseCaller } = ctx.accounts; + + const observer = await new OpStackTokenRatePusherWithSomeErrorStub__factory(deployer).deploy(); + await tokenRateNotifier + .connect(ctx.accounts.owner) + .addObserver(observer.address); + + const tx = await tokenRateNotifier.connect(l1AuthorizedRebaseCaller).handlePostTokenRebase(1, 2, 3, 4, 5, 6, 7); + + await assert.emits(tokenRateNotifier, tx, "PushTokenRateFailed", [observer.address, "0x332e27d2"]); + }) + + .test("handlePostTokenRebase() :: revert when observer has out of gas error", async (ctx) => { + const { tokenRateNotifier } = ctx.contracts; + const { deployer, l1AuthorizedRebaseCaller } = ctx.accounts; + + const observer = await new OpStackTokenRatePusherWithOutOfGasErrorStub__factory(deployer).deploy(); + await tokenRateNotifier + .connect(ctx.accounts.owner) + .addObserver(observer.address); + + await assert.revertsWith( + tokenRateNotifier.connect(l1AuthorizedRebaseCaller).handlePostTokenRebase(1, 2, 3, 4, 5, 6, 7), + "ErrorTokenRateNotifierRevertedWithNoData()" + ); + }) + + .test("handlePostTokenRebase() :: happy path of handling token rebase", async (ctx) => { + const { + tokenRateNotifier, + l1MessengerStub, + opStackTokenRatePusher + } = ctx.contracts; + const { tokenRateOracle, l1AuthorizedRebaseCaller } = ctx.accounts; + const { l2GasLimitForPushingTokenRate, tokenRate, genesisTime, secondsPerSlot, lastProcessingRefSlot } = ctx.constants; + + const updateRateTime = genesisTime.add(secondsPerSlot.mul(lastProcessingRefSlot)); + + await tokenRateNotifier + .connect(ctx.accounts.owner) + .addObserver(opStackTokenRatePusher.address); + let tx = await tokenRateNotifier.connect(l1AuthorizedRebaseCaller).handlePostTokenRebase(1, 2, 3, 4, 5, 6, 7); + + await assert.emits(l1MessengerStub, tx, "SentMessage", [ + tokenRateOracle.address, + opStackTokenRatePusher.address, + ITokenRateOracle__factory.createInterface().encodeFunctionData( + "updateRate", + [ + tokenRate, + updateRateTime + ] + ), + 1, + l2GasLimitForPushingTokenRate, + ]); + }) + + .run(); + +async function ctxFactory() { + const [deployer, owner, stranger, tokenRateOracle, l1AuthorizedRebaseCaller] = await ethers.getSigners(); + const totalPooledEther = BigNumber.from('9309904612343950493629678'); + const totalShares = BigNumber.from('7975822843597609202337218'); + const tokenRateDecimals = BigNumber.from(27); + const tokenRate = getExchangeRate(tokenRateDecimals, totalPooledEther, totalShares); + const l2GasLimitForPushingTokenRate = 300_000; + const genesisTime = BigNumber.from(1); + const secondsPerSlot = BigNumber.from(2); + const lastProcessingRefSlot = BigNumber.from(3); + + const { + tokenRateNotifier, + opStackTokenRatePusher, + l1MessengerStub + } = await createContracts( + totalPooledEther, + totalShares, + tokenRate, + genesisTime, + secondsPerSlot, + lastProcessingRefSlot, + deployer, + owner, + tokenRateOracle, + l2GasLimitForPushingTokenRate, + l1AuthorizedRebaseCaller + ); + + return { + accounts: { + deployer, + owner, + stranger, + tokenRateOracle, + l1AuthorizedRebaseCaller + }, + contracts: { + tokenRateNotifier, + opStackTokenRatePusher, + l1MessengerStub + }, + constants: { + l2GasLimitForPushingTokenRate, + tokenRate, + totalPooledEther, + totalShares, + genesisTime, + secondsPerSlot, + lastProcessingRefSlot + } + }; +} + +async function createContracts( + totalPooledEther: BigNumber, + totalShares: BigNumber, + tokenRate: BigNumber, + genesisTime: BigNumber, + secondsPerSlot: BigNumber, + lastProcessingRefSlot: BigNumber, + deployer: SignerWithAddress, + owner: SignerWithAddress, + tokenRateOracle: SignerWithAddress, + l2GasLimitForPushingTokenRate: number, + l1AuthorizedRebaseCaller: SignerWithAddress) { + + const tokenRateNotifier = await new TokenRateNotifier__factory(deployer).deploy( + owner.address, + l1AuthorizedRebaseCaller.address + ); + + const l1MessengerStub = await new CrossDomainMessengerStub__factory(deployer) + .deploy({ value: wei.toBigNumber(wei`1 ether`) }); + + + const l1TokenRebasableStub = await new ERC20BridgedStub__factory(deployer).deploy( + "L1 Token Rebasable", + "L1R" + ); + + const l1TokenNonRebasableStub = await new ERC20WrapperStub__factory(deployer).deploy( + l1TokenRebasableStub.address, + "L1 Token Non Rebasable", + "L1NR", + totalPooledEther, + totalShares + ); + + const accountingOracle = await new AccountingOracleStub__factory(deployer).deploy( + genesisTime, + secondsPerSlot, + lastProcessingRefSlot + ); + + const opStackTokenRatePusher = await new OpStackTokenRatePusher__factory(deployer).deploy( + l1MessengerStub.address, + l1TokenNonRebasableStub.address, + accountingOracle.address, + tokenRateOracle.address, + l2GasLimitForPushingTokenRate + ); + + return { + tokenRateNotifier, + l1TokenNonRebasableStub, + opStackTokenRatePusher, + accountingOracle, + l1MessengerStub, + totalPooledEther, + totalShares, + tokenRate + }; +} diff --git a/test/optimism/TokenRateOracle.unit.test.ts b/test/optimism/TokenRateOracle.unit.test.ts new file mode 100644 index 00000000..c54fc3cc --- /dev/null +++ b/test/optimism/TokenRateOracle.unit.test.ts @@ -0,0 +1,787 @@ +import hre from "hardhat"; +import { assert } from "chai"; +import { BigNumber } from "ethers"; +import { wei } from "../../utils/wei"; +import testing, { unit } from "../../utils/testing"; +import { tokenRateOracleUnderProxy } from "../../utils/testing/contractsFactory"; +import { getContractTransactionTimestamp, getBlockTimestamp } from "../../utils/testing/helpers"; +import { TokenRateOracle__factory, CrossDomainMessengerStub__factory } from "../../typechain"; + +unit("TokenRateOracle", ctxFactory) + + .test("constructor() :: zero params", async (ctx) => { + + const { deployer, stranger, zero } = ctx.accounts; + + await assert.revertsWith(new TokenRateOracle__factory( + deployer + ).deploy( + zero.address, + stranger.address, + stranger.address, + 0, + 0, + 0, + 0, + 0 + ), "ErrorZeroAddressMessenger()"); + + await assert.revertsWith(new TokenRateOracle__factory( + deployer + ).deploy( + stranger.address, + zero.address, + stranger.address, + 0, + 0, + 0, + 0, + 0 + ), "ErrorZeroAddressL2ERC20TokenBridge()"); + + await assert.revertsWith(new TokenRateOracle__factory( + deployer + ).deploy( + stranger.address, + stranger.address, + zero.address, + 0, + 0, + 0, + 0, + 0 + ), "ErrorZeroAddressL1TokenRatePusher()"); + }) + + .test("state after init", async (ctx) => { + const { tokenRateOracle, l2MessengerStub } = ctx.contracts; + const { bridge, l1TokenBridgeEOA } = ctx.accounts; + const { + tokenRate, + decimals, + rateL1Timestamp, + blockTimestampOfDeployment, + tokenRateOutdatedDelay, + maxAllowedL2ToL1ClockLag, + maxAllowedTokenRateDeviationPerDay + } = ctx.constants; + + assert.equal(await tokenRateOracle.MESSENGER(), l2MessengerStub.address); + assert.equal(await tokenRateOracle.L2_ERC20_TOKEN_BRIDGE(), bridge.address); + assert.equal(await tokenRateOracle.L1_TOKEN_RATE_PUSHER(), l1TokenBridgeEOA.address); + assert.equalBN(await tokenRateOracle.TOKEN_RATE_OUTDATED_DELAY(), tokenRateOutdatedDelay); + assert.equalBN(await tokenRateOracle.MAX_ALLOWED_L2_TO_L1_CLOCK_LAG(), maxAllowedL2ToL1ClockLag); + assert.equalBN(await tokenRateOracle.MAX_ALLOWED_TOKEN_RATE_DEVIATION_PER_DAY_BP(), maxAllowedTokenRateDeviationPerDay); + assert.equalBN(await tokenRateOracle.latestAnswer(), tokenRate); + + const { + roundId_, + answer_, + startedAt_, + updatedAt_, + answeredInRound_ + } = await tokenRateOracle.latestRoundData(); + + assert.equalBN(roundId_, rateL1Timestamp); + assert.equalBN(answer_, tokenRate); + assert.equalBN(startedAt_, rateL1Timestamp); + assert.equalBN(updatedAt_, blockTimestampOfDeployment); + assert.equalBN(answeredInRound_, rateL1Timestamp); + + assert.equalBN(await tokenRateOracle.decimals(), decimals); + }) + + .test("initialize() :: petrified version", async (ctx) => { + const { deployer, bridge, l1TokenBridgeEOA } = ctx.accounts; + const { l2MessengerStub } = ctx.contracts; + const { tokenRate, blockTimestampOfDeployment } = ctx.constants; + + const tokenRateOracleImpl = await new TokenRateOracle__factory(deployer).deploy( + l2MessengerStub.address, + bridge.address, + l1TokenBridgeEOA.address, + 86400, + 86400, + 500, + 86400*3, + 3600 + ); + + const petrifiedVersionMark = hre.ethers.constants.MaxUint256; + assert.equalBN(await tokenRateOracleImpl.getContractVersion(), petrifiedVersionMark); + + await assert.revertsWith( + tokenRateOracleImpl.initialize(deployer.address, tokenRate, blockTimestampOfDeployment), + "NonZeroContractVersionOnInit()" + ); + }) + + .test("initialize() :: don't allow to initialize twice", async (ctx) => { + const { deployer } = ctx.accounts; + const { tokenRateOracle } = ctx.contracts; + const { tokenRate, blockTimestampOfDeployment } = ctx.constants; + + assert.equalBN(await tokenRateOracle.getContractVersion(), 1); + + await assert.revertsWith( + tokenRateOracle.initialize(deployer.address, tokenRate, blockTimestampOfDeployment), + "NonZeroContractVersionOnInit()" + ); + }) + + .test("initialize() :: token rate is out of range", async (ctx) => { + const { deployer, bridge, l1TokenBridgeEOA } = ctx.accounts; + const { l2MessengerStub } = ctx.contracts; + const { + blockTimestampOfDeployment, + tokenRateOutdatedDelay, + maxAllowedL2ToL1ClockLag, + maxAllowedTokenRateDeviationPerDay, + oldestRateAllowedInPauseTimeSpan, + maxAllowedTimeBetweenTokenRateUpdates + } = ctx.constants; + + const tokenRateMin = BigNumber.from(10).pow(27-2); + const tokenRateMax = BigNumber.from(10).pow(27+2); + + await assert.revertsWith( + tokenRateOracleUnderProxy( + deployer, + l2MessengerStub.address, + bridge.address, + l1TokenBridgeEOA.address, + tokenRateOutdatedDelay, + maxAllowedL2ToL1ClockLag, + maxAllowedTokenRateDeviationPerDay, + oldestRateAllowedInPauseTimeSpan, + maxAllowedTimeBetweenTokenRateUpdates, + tokenRateMin.sub(1), + blockTimestampOfDeployment + ), + "ErrorTokenRateIsOutOfSaneRange(" + tokenRateMin.sub(1) + ")" + ); + + await assert.revertsWith( + tokenRateOracleUnderProxy( + deployer, + l2MessengerStub.address, + bridge.address, + l1TokenBridgeEOA.address, + tokenRateOutdatedDelay, + maxAllowedL2ToL1ClockLag, + maxAllowedTokenRateDeviationPerDay, + oldestRateAllowedInPauseTimeSpan, + maxAllowedTimeBetweenTokenRateUpdates, + tokenRateMax.add(1), + blockTimestampOfDeployment + ), + "ErrorTokenRateIsOutOfSaneRange(" + tokenRateMax.add(1) + ")" + ); + }) + + .test("initialize() :: time is out of init range", async (ctx) => { + const { deployer, bridge, l1TokenBridgeEOA } = ctx.accounts; + const { l2MessengerStub } = ctx.contracts; + const { + tokenRate, + blockTimestampOfDeployment, + tokenRateOutdatedDelay, + maxAllowedL2ToL1ClockLag, + maxAllowedTokenRateDeviationPerDay, + oldestRateAllowedInPauseTimeSpan, + maxAllowedTimeBetweenTokenRateUpdates + } = ctx.constants; + + const wrongTimeMax = blockTimestampOfDeployment.add(maxAllowedL2ToL1ClockLag).add(20); + + await assert.revertsWith( + tokenRateOracleUnderProxy( + deployer, + l2MessengerStub.address, + bridge.address, + l1TokenBridgeEOA.address, + tokenRateOutdatedDelay, + maxAllowedL2ToL1ClockLag, + maxAllowedTokenRateDeviationPerDay, + oldestRateAllowedInPauseTimeSpan, + maxAllowedTimeBetweenTokenRateUpdates, + tokenRate, + wrongTimeMax + ), + "ErrorL1TimestampExceededMaxAllowedClockLag(" + wrongTimeMax + ")" + ); + }) + + .test("initialize() :: wrong maxAllowedTokenRateDeviationPerDay", async (ctx) => { + const { deployer, bridge, l1TokenBridgeEOA } = ctx.accounts; + const { l2MessengerStub } = ctx.contracts; + + const maxAllowedTokenRateDeviationPerDay = 10001; + + await assert.revertsWith( + new TokenRateOracle__factory(deployer).deploy( + l2MessengerStub.address, + bridge.address, + l1TokenBridgeEOA.address, + 86400, + 86400, + maxAllowedTokenRateDeviationPerDay, + 86400*3, + 3600 + ), + "ErrorMaxTokenRateDeviationIsOutOfRange()" + ); + }) + + .test("updateRate() :: called by non-bridge account", async (ctx) => { + const { tokenRateOracle } = ctx.contracts; + const { stranger } = ctx.accounts; + await assert.revertsWith( + tokenRateOracle.connect(stranger).updateRate(10, 40), + "ErrorNotBridgeOrTokenRatePusher()" + ); + }) + + .test("updateRate() :: called by messenger with incorrect cross-domain sender", async (ctx) => { + const { tokenRateOracle, l2MessengerStub } = ctx.contracts; + const { stranger, l2MessengerStubEOA } = ctx.accounts; + await l2MessengerStub.setXDomainMessageSender(stranger.address); + await assert.revertsWith( + tokenRateOracle.connect(l2MessengerStubEOA).updateRate(10, 40), + "ErrorNotBridgeOrTokenRatePusher()" + ); + }) + + .test("updateRate() :: L1 time exceeded allowed L2 clock lag", async (ctx) => { + const { tokenRateOracle } = ctx.contracts; + const { bridge } = ctx.accounts; + const { tokenRate, blockTimestampOfDeployment, maxAllowedL2ToL1ClockLag } = ctx.constants; + + const exceededTime = blockTimestampOfDeployment.add(maxAllowedL2ToL1ClockLag).add(40); // more than maxAllowedL2ToL1ClockLag + await assert.revertsWith( + tokenRateOracle.connect(bridge).updateRate(tokenRate, exceededTime), + "ErrorL1TimestampExceededAllowedClockLag(" + tokenRate + ", " + exceededTime + ")" + ) + }) + + .test("updateRate() :: received token rate has l1 time in the past", async (ctx) => { + const { tokenRateOracle } = ctx.contracts; + const { bridge } = ctx.accounts; + const { tokenRate, rateL1Timestamp } = ctx.constants; + + const rateL1TimestampInPast = rateL1Timestamp.sub(100); + + const tx0 = await tokenRateOracle + .connect(bridge) + .updateRate(tokenRate, rateL1TimestampInPast); + + await assert.emits(tokenRateOracle, tx0, "DormantTokenRateUpdateIgnored", [ + rateL1TimestampInPast, + rateL1Timestamp, + ]); + await assert.notEmits(tokenRateOracle, tx0, "RateUpdated"); + }) + + .test("updateRate() :: received token rate has the same l1 time", async (ctx) => { + const { tokenRateOracle } = ctx.contracts; + const { bridge } = ctx.accounts; + const { tokenRate, rateL1Timestamp } = ctx.constants; + + const tx = await tokenRateOracle + .connect(bridge) + .updateRate(tokenRate, rateL1Timestamp); + + const updatedAt = await getContractTransactionTimestamp(ctx.provider, tx); + + await assert.emits(tokenRateOracle, tx, "RateReceivedTimestampUpdated", [updatedAt]); + + const { + roundId_, + answer_, + startedAt_, + updatedAt_, + answeredInRound_ + } = await tokenRateOracle.latestRoundData(); + + assert.equalBN(updatedAt_, updatedAt); + }) + + .test("updateRate() :: token rate updates too often", async (ctx) => { + const { tokenRateOracle } = ctx.contracts; + const { bridge } = ctx.accounts; + const { tokenRate, rateL1Timestamp, maxAllowedTimeBetweenTokenRateUpdates } = ctx.constants; + + const rateL1TimestampWithinTooOften = rateL1Timestamp.add(maxAllowedTimeBetweenTokenRateUpdates).sub(1); + + const tx0 = await tokenRateOracle + .connect(bridge) + .updateRate(tokenRate, rateL1TimestampWithinTooOften); + + await assert.emits(tokenRateOracle, tx0, "UpdateRateIsTooOften", [rateL1TimestampWithinTooOften, rateL1Timestamp]); + await assert.notEmits(tokenRateOracle, tx0, "RateUpdated"); + }) + + .test("updateRate() :: token rate is out of range 1 day", async (ctx) => { + const { tokenRateOracle } = ctx.contracts; + const { bridge } = ctx.accounts; + const { + tokenRate, + blockTimestampOfDeployment, + maxAllowedTokenRateDeviationPerDay, + maxAllowedTimeBetweenTokenRateUpdates + } = ctx.constants; + + const blockTimestampForNextUpdate = blockTimestampOfDeployment.add(maxAllowedTimeBetweenTokenRateUpdates).add(1); + const tokenRateTooBig = tokenRate.mul( + BigNumber.from('10000') + .add(maxAllowedTokenRateDeviationPerDay) + .add(100) + ) + .div(BigNumber.from('10000')); // 1% more than allowed + const tokenRateTooSmall = tokenRate.mul( + BigNumber.from('10000') + .sub(maxAllowedTokenRateDeviationPerDay) + .sub(100) + ) + .div(BigNumber.from('10000')); // 1% less than allowed + + const tokenRateAllowed = tokenRate.mul( + BigNumber.from('10000') + .add(maxAllowedTokenRateDeviationPerDay) + .sub(100) + ) + .div(BigNumber.from('10000')); // allowed within one day + + await tokenRateOracle.connect(bridge).updateRate(tokenRate, blockTimestampOfDeployment); + + await assert.revertsWith( + tokenRateOracle.connect(bridge).updateRate(tokenRateTooBig, blockTimestampForNextUpdate), + "ErrorTokenRateIsOutOfRange(" + tokenRateTooBig + ", " + blockTimestampForNextUpdate + ")" + ); + + await assert.revertsWith( + tokenRateOracle.connect(bridge).updateRate(tokenRateTooSmall, blockTimestampForNextUpdate), + "ErrorTokenRateIsOutOfRange(" + tokenRateTooSmall + ", " + blockTimestampForNextUpdate + ")" + ); + + await tokenRateOracle.connect(bridge).updateRate(tokenRateAllowed, blockTimestampForNextUpdate); + }) + + .test("updateRate() :: token rate is out of range 2 days", async (ctx) => { + const { tokenRateOracle } = ctx.contracts; + const { bridge } = ctx.accounts; + const { tokenRate, blockTimestampOfDeployment, maxAllowedTokenRateDeviationPerDay } = ctx.constants; + + const tokenRateFirstUpdate = tokenRate.add(10); + + const tokenRateTooBig = tokenRate.mul( + BigNumber.from('10000') + .add(maxAllowedTokenRateDeviationPerDay.mul(2)) + .add(100) + ) + .div(BigNumber.from('10000')); // 1% more than allowed in 2 days + + const tokenRateTooSmall = tokenRate.mul( + BigNumber.from('10000') + .sub(maxAllowedTokenRateDeviationPerDay.mul(2)) + .sub(100) + ) + .div(BigNumber.from('10000')); // 1% less than allowed in 2 days + + const tokenRateSizeDoesMatterAfterAll = tokenRate.mul( + BigNumber.from('10000') + .add(maxAllowedTokenRateDeviationPerDay.mul(2)) + .sub(100) + ) + .div(BigNumber.from('10000')); // allowed within 2 days + + + await tokenRateOracle.connect(bridge).updateRate(tokenRateFirstUpdate, blockTimestampOfDeployment.add(1000)); + + const blockTimestampMoreThanOneDays = blockTimestampOfDeployment.add(86400 + 2000); + await assert.revertsWith( + tokenRateOracle.connect(bridge).updateRate(tokenRateTooBig, blockTimestampMoreThanOneDays), + "ErrorTokenRateIsOutOfRange(" + tokenRateTooBig + ", " + blockTimestampMoreThanOneDays + ")" + ); + + await assert.revertsWith( + tokenRateOracle.connect(bridge).updateRate(tokenRateTooSmall, blockTimestampMoreThanOneDays), + "ErrorTokenRateIsOutOfRange(" + tokenRateTooSmall + ", " + blockTimestampMoreThanOneDays + ")" + ); + + await tokenRateOracle.connect(bridge).updateRate(tokenRateSizeDoesMatterAfterAll, blockTimestampMoreThanOneDays); + }) + + .test("updateRate() :: token rate limits", async (ctx) => { + const { deployer, bridge, l1TokenBridgeEOA } = ctx.accounts; + const { tokenRate, maxAllowedTimeBetweenTokenRateUpdates } = ctx.constants; + + const tokenRateOutdatedDelay = BigNumber.from(86400); // 1 day + const maxAllowedL2ToL1ClockLag = BigNumber.from(86400 * 2); // 2 days + const maxAllowedTokenRateDeviationPerDay = BigNumber.from(10000); // 100% + + const l2MessengerStub = await new CrossDomainMessengerStub__factory( + deployer + ).deploy({ value: wei.toBigNumber(wei`1 ether`) }); + + const { tokenRateOracle, blockTimestampOfDeployment } = await tokenRateOracleUnderProxy( + deployer, + l2MessengerStub.address, + bridge.address, + l1TokenBridgeEOA.address, + tokenRateOutdatedDelay, + maxAllowedL2ToL1ClockLag, + maxAllowedTokenRateDeviationPerDay, + BigNumber.from(86400*3), + BigNumber.from(3600), + tokenRate, + BigNumber.from(0) + ); + + const maxAllowedTokenRate = await tokenRateOracle.MAX_SANE_TOKEN_RATE(); + await tokenRateOracle.connect(bridge).updateRate(maxAllowedTokenRate, blockTimestampOfDeployment.add(maxAllowedTimeBetweenTokenRateUpdates).add(1)); + assert.equalBN(await tokenRateOracle.latestAnswer(), maxAllowedTokenRate); + + const minAllowedTokenRate = await tokenRateOracle.MIN_SANE_TOKEN_RATE(); + await tokenRateOracle.connect(bridge).updateRate(minAllowedTokenRate, blockTimestampOfDeployment.add(maxAllowedTimeBetweenTokenRateUpdates.mul(2)).add(1)); + assert.equalBN(await tokenRateOracle.latestAnswer(), minAllowedTokenRate); + }) + + .test("updateRate() :: happy path called by bridge", async (ctx) => { + const { tokenRateOracle } = ctx.contracts; + const { bridge } = ctx.accounts; + const { tokenRate, blockTimestampOfDeployment, maxAllowedTimeBetweenTokenRateUpdates } = ctx.constants; + + const newTokenRate = tokenRate.mul(BigNumber.from('104')).div(BigNumber.from('100')); // 104% + + const blockTimestampInFuture = blockTimestampOfDeployment.add(maxAllowedTimeBetweenTokenRateUpdates).add(1); + const tx = await tokenRateOracle.connect(bridge).updateRate(newTokenRate, blockTimestampInFuture); + + await assert.emits(tokenRateOracle, tx, "TokenRateL1TimestampIsInFuture", [ + newTokenRate, + blockTimestampInFuture + ]); + + await assert.emits(tokenRateOracle, tx, "RateUpdated", [ + newTokenRate, + blockTimestampInFuture + ]); + + assert.equalBN(await tokenRateOracle.latestAnswer(), newTokenRate); + + const { + roundId_, + answer_, + startedAt_, + updatedAt_, + answeredInRound_ + } = await tokenRateOracle.latestRoundData(); + + const updatedAt = await getContractTransactionTimestamp(ctx.provider, tx); + + assert.equalBN(roundId_, blockTimestampInFuture); + assert.equalBN(answer_, newTokenRate); + assert.equalBN(startedAt_, blockTimestampInFuture); + assert.equalBN(updatedAt_, updatedAt); + assert.equalBN(answeredInRound_, blockTimestampInFuture); + }) + + .test("updateRate() :: happy path called by messenger with correct cross-domain sender", async (ctx) => { + const { tokenRateOracle, l2MessengerStub } = ctx.contracts; + const { l2MessengerStubEOA, l1TokenBridgeEOA } = ctx.accounts; + const { tokenRate, blockTimestampOfDeployment, maxAllowedTimeBetweenTokenRateUpdates } = ctx.constants; + + await l2MessengerStub.setXDomainMessageSender(l1TokenBridgeEOA.address); + + const newTokenRate = tokenRate.mul(BigNumber.from('104')).div(BigNumber.from('100')); // 104% + + const blockTimestampInFuture = blockTimestampOfDeployment.add(maxAllowedTimeBetweenTokenRateUpdates).add(1); + const tx = await tokenRateOracle.connect(l2MessengerStubEOA).updateRate(newTokenRate, blockTimestampInFuture); + + await assert.emits(tokenRateOracle, tx, "TokenRateL1TimestampIsInFuture", [ + newTokenRate, + blockTimestampInFuture + ]); + + await assert.emits(tokenRateOracle, tx, "RateUpdated", [ + newTokenRate, + blockTimestampInFuture + ]); + + assert.equalBN(await tokenRateOracle.latestAnswer(), newTokenRate); + + const { + roundId_, + answer_, + startedAt_, + updatedAt_, + answeredInRound_ + } = await tokenRateOracle.latestRoundData(); + + const updatedAt = await getContractTransactionTimestamp(ctx.provider, tx); + + assert.equalBN(roundId_, blockTimestampInFuture); + assert.equalBN(answer_, newTokenRate); + assert.equalBN(startedAt_, blockTimestampInFuture); + assert.equalBN(updatedAt_, updatedAt); + assert.equalBN(answeredInRound_, blockTimestampInFuture); + }) + + .test("pauseTokenRateUpdates() :: wrong role", async (ctx) => { + const { tokenRateOracle } = ctx.contracts; + const { deployer } = ctx.accounts; + + const disablerRole = await tokenRateOracle.RATE_UPDATE_DISABLER_ROLE(); + const account = deployer.address.toLowerCase(); + + await assert.revertsWith( + tokenRateOracle.pauseTokenRateUpdates(1), + "AccessControl: account " + account + " is missing role " + disablerRole + ); + }) + + .test("pauseTokenRateUpdates() :: double pause", async (ctx) => { + const { tokenRateOracle } = ctx.contracts; + const { multisig } = ctx.accounts; + + const disablerRole = await tokenRateOracle.RATE_UPDATE_DISABLER_ROLE(); + await tokenRateOracle.grantRole(disablerRole, multisig.address); + + await tokenRateOracle.connect(multisig).pauseTokenRateUpdates(0); + + await assert.revertsWith( + tokenRateOracle.connect(multisig).pauseTokenRateUpdates(1), + "ErrorAlreadyPaused()" + ); + }) + + .test("pauseTokenRateUpdates() :: wrong index", async (ctx) => { + const { tokenRateOracle } = ctx.contracts; + const { multisig } = ctx.accounts; + + const disablerRole = await tokenRateOracle.RATE_UPDATE_DISABLER_ROLE(); + await tokenRateOracle.grantRole(disablerRole, multisig.address); + + await assert.revertsWith( + tokenRateOracle.connect(multisig).pauseTokenRateUpdates(1), + "ErrorWrongTokenRateIndex()" + ); + }) + + .test("pauseTokenRateUpdates() :: old rate", async (ctx) => { + + const { multisig, bridge, deployer, l1TokenBridgeEOA } = ctx.accounts; + const { tokenRate, tokenRateOutdatedDelay, maxAllowedL2ToL1ClockLag, maxAllowedTokenRateDeviationPerDay } = ctx.constants; + const { l2MessengerStub } = ctx.contracts; + + /// create new Oracle with 0 maxDeltaTimeToPauseTokenRateUpdates + const maxDeltaTimeToPauseTokenRateUpdates = BigNumber.from(0); + const { tokenRateOracle, blockTimestampOfDeployment } = await tokenRateOracleUnderProxy( + deployer, + l2MessengerStub.address, + bridge.address, + l1TokenBridgeEOA.address, + tokenRateOutdatedDelay, + maxAllowedL2ToL1ClockLag, + maxAllowedTokenRateDeviationPerDay, + maxDeltaTimeToPauseTokenRateUpdates, + BigNumber.from(3600), + tokenRate, + BigNumber.from(0), + ); + + const disablerRole = await tokenRateOracle.RATE_UPDATE_DISABLER_ROLE(); + await tokenRateOracle.grantRole(disablerRole, multisig.address); + + await tokenRateOracle.connect(bridge).updateRate(tokenRate, blockTimestampOfDeployment.add(1000)); + + await assert.revertsWith( + tokenRateOracle.connect(multisig).pauseTokenRateUpdates(0), + "ErrorTokenRateUpdateTooOld()" + ); + }) + + .test("pauseTokenRateUpdates() :: success", async (ctx) => { + const { tokenRateOracle } = ctx.contracts; + const { multisig, bridge } = ctx.accounts; + const { tokenRate, blockTimestampOfDeployment, maxAllowedTimeBetweenTokenRateUpdates } = ctx.constants; + + const disablerRole = await tokenRateOracle.RATE_UPDATE_DISABLER_ROLE(); + await tokenRateOracle.grantRole(disablerRole, multisig.address); + + const tokenRate0 = tokenRate.add(100); + const tokenRate1 = tokenRate.add(200); + const tokenRate2 = tokenRate.add(300); + const tokenRate3 = tokenRate.add(300); + + const blockTimestampOfDeployment0 = blockTimestampOfDeployment.add(maxAllowedTimeBetweenTokenRateUpdates).add(1); + const blockTimestampOfDeployment1 = blockTimestampOfDeployment.add(maxAllowedTimeBetweenTokenRateUpdates.mul(2)).add(1); + const blockTimestampOfDeployment2 = blockTimestampOfDeployment.add(maxAllowedTimeBetweenTokenRateUpdates.mul(3)).add(1); + const blockTimestampOfDeployment3 = blockTimestampOfDeployment.add(maxAllowedTimeBetweenTokenRateUpdates.mul(4)).add(1); + + const tx0 = await tokenRateOracle.connect(bridge).updateRate(tokenRate0, blockTimestampOfDeployment0); + await assert.emits(tokenRateOracle, tx0, "RateUpdated", [tokenRate0, blockTimestampOfDeployment0]); + + const tx1 = await tokenRateOracle.connect(bridge).updateRate(tokenRate1, blockTimestampOfDeployment1); + await assert.emits(tokenRateOracle, tx1, "RateUpdated", [tokenRate1, blockTimestampOfDeployment1]); + + const tx2 = await tokenRateOracle.connect(bridge).updateRate(tokenRate2, blockTimestampOfDeployment2); + await assert.emits(tokenRateOracle, tx2, "RateUpdated", [tokenRate2, blockTimestampOfDeployment2]); + + assert.equalBN(await tokenRateOracle.getTokenRatesLength(), 4); + assert.isFalse(await tokenRateOracle.isTokenRateUpdatesPaused()); + + const pauseTx = await tokenRateOracle.connect(multisig).pauseTokenRateUpdates(1); + + await assert.emits(tokenRateOracle, pauseTx, "TokenRateUpdatesPaused", [ + tokenRate0, + blockTimestampOfDeployment0 + ]); + + assert.equalBN(await tokenRateOracle.getTokenRatesLength(), 2); + assert.isTrue(await tokenRateOracle.isTokenRateUpdatesPaused()); + + const tx3 = await tokenRateOracle.connect(bridge).updateRate(tokenRate3, blockTimestampOfDeployment3); + await assert.emits( + tokenRateOracle, + tx3, + "TokenRateUpdateAttemptDuringPause" + ); + }) + + .test("resumeTokenRateUpdates() :: wrong role", async (ctx) => { + const { tokenRateOracle } = ctx.contracts; + const { deployer } = ctx.accounts; + const { tokenRate, blockTimestampOfDeployment } = ctx.constants; + + const enablerRole = await tokenRateOracle.RATE_UPDATE_ENABLER_ROLE(); + const account = deployer.address.toLowerCase(); + + await assert.revertsWith( + tokenRateOracle.resumeTokenRateUpdates(tokenRate, blockTimestampOfDeployment.add(1000)), + "AccessControl: account " + account + " is missing role " + enablerRole + ); + }) + + .test("resumeTokenRateUpdates() :: unpause when unpaused", async (ctx) => { + const { tokenRateOracle } = ctx.contracts; + const { multisig } = ctx.accounts; + const { tokenRate, blockTimestampOfDeployment } = ctx.constants; + + const enablerRole = await tokenRateOracle.RATE_UPDATE_ENABLER_ROLE(); + await tokenRateOracle.grantRole(enablerRole, multisig.address); + + await assert.revertsWith( + tokenRateOracle.connect(multisig).resumeTokenRateUpdates(tokenRate, blockTimestampOfDeployment), + "ErrorAlreadyResumed()" + ); + }) + + .test("resumeTokenRateUpdates() :: success", async (ctx) => { + const { tokenRateOracle } = ctx.contracts; + const { multisig, bridge } = ctx.accounts; + const { tokenRate, blockTimestampOfDeployment, maxAllowedTimeBetweenTokenRateUpdates } = ctx.constants; + + const disablerRole = await tokenRateOracle.RATE_UPDATE_DISABLER_ROLE(); + await tokenRateOracle.grantRole(disablerRole, multisig.address); + + const enablerRole = await tokenRateOracle.RATE_UPDATE_ENABLER_ROLE(); + await tokenRateOracle.grantRole(enablerRole, multisig.address); + + await tokenRateOracle.connect(bridge).updateRate(tokenRate, blockTimestampOfDeployment.add(maxAllowedTimeBetweenTokenRateUpdates).add(1)); + assert.isFalse(await tokenRateOracle.isTokenRateUpdatesPaused()); + await tokenRateOracle.connect(multisig).pauseTokenRateUpdates(0); + assert.isTrue(await tokenRateOracle.isTokenRateUpdatesPaused()); + const unpauseTx = await tokenRateOracle.connect(multisig).resumeTokenRateUpdates(tokenRate, blockTimestampOfDeployment); + assert.isFalse(await tokenRateOracle.isTokenRateUpdatesPaused()); + + await assert.emits( + tokenRateOracle, + unpauseTx, + "TokenRateUpdatesResumed", + [tokenRate, blockTimestampOfDeployment] + ); + await assert.emits(tokenRateOracle, + unpauseTx, + "RateUpdated", + [tokenRate, blockTimestampOfDeployment] + ); + + const newTime = blockTimestampOfDeployment.add(maxAllowedTimeBetweenTokenRateUpdates.mul(2)).add(1); + const tx = await tokenRateOracle.connect(bridge).updateRate(tokenRate.add(100), newTime); + await assert.emits(tokenRateOracle, + tx, + "RateUpdated", + [tokenRate.add(100), newTime] + ); + }) + + .run(); + +async function ctxFactory() { + /// --------------------------- + /// constants + /// --------------------------- + const decimals = 27; + const provider = await hre.ethers.provider; + const tokenRate = BigNumber.from('1164454276599657236000000000'); // value taken from real contact on 23.04.24 + const tokenRateOutdatedDelay = BigNumber.from(86400); // 1 day + const maxAllowedL2ToL1ClockLag = BigNumber.from(86400 * 2); // 2 days + const maxAllowedTokenRateDeviationPerDay = BigNumber.from(500); // 5% + const oldestRateAllowedInPauseTimeSpan = BigNumber.from(86400*3); // 3 days + const maxAllowedTimeBetweenTokenRateUpdates = BigNumber.from(3600); // 1 hour + + const [deployer, bridge, stranger, l1TokenBridgeEOA, multisig] = await hre.ethers.getSigners(); + const zero = await hre.ethers.getSigner(hre.ethers.constants.AddressZero); + + const l2MessengerStub = await new CrossDomainMessengerStub__factory(deployer) + .deploy({ value: wei.toBigNumber(wei`1 ether`) }); + const l2MessengerStubEOA = await testing.impersonate(l2MessengerStub.address); + + const rateL1Timestamp = await getBlockTimestamp(provider, 0); + + /// --------------------------- + /// contracts + /// --------------------------- + const { tokenRateOracle, blockTimestampOfDeployment } = await tokenRateOracleUnderProxy( + deployer, + l2MessengerStub.address, + bridge.address, + l1TokenBridgeEOA.address, + tokenRateOutdatedDelay, + maxAllowedL2ToL1ClockLag, + maxAllowedTokenRateDeviationPerDay, + oldestRateAllowedInPauseTimeSpan, + maxAllowedTimeBetweenTokenRateUpdates, + tokenRate, + rateL1Timestamp + ); + + return { + accounts: { + deployer, + bridge, + zero, + stranger, + l1TokenBridgeEOA, + l2MessengerStubEOA, + multisig + }, + contracts: { + tokenRateOracle, + l2MessengerStub + }, + constants: { + tokenRate, + decimals, + rateL1Timestamp, + blockTimestampOfDeployment, + tokenRateOutdatedDelay, + maxAllowedL2ToL1ClockLag, + maxAllowedTokenRateDeviationPerDay, + oldestRateAllowedInPauseTimeSpan, + maxAllowedTimeBetweenTokenRateUpdates + }, + provider + }; +} diff --git a/test/optimism/_launch.test.ts b/test/optimism/_launch.test.ts index 4d192be3..e64f0d33 100644 --- a/test/optimism/_launch.test.ts +++ b/test/optimism/_launch.test.ts @@ -5,7 +5,8 @@ import { wei } from "../../utils/wei"; import optimism from "../../utils/optimism"; import testing, { scenario } from "../../utils/testing"; import { BridgingManagerRole } from "../../utils/bridging-management"; -import { L1ERC20TokenBridge__factory } from "../../typechain"; +import { L1LidoTokensBridge__factory } from "../../typechain"; +import { BigNumber } from 'ethers' const REVERT = env.bool("REVERT", true); @@ -22,28 +23,28 @@ scenario("Optimism :: Launch integration test", ctxFactory) }) .step("Enable deposits", async (ctx) => { - const { l1ERC20TokenBridge } = ctx; - assert.isFalse(await l1ERC20TokenBridge.isDepositsEnabled()); + const { l1LidoTokensBridge } = ctx; + assert.isFalse(await l1LidoTokensBridge.isDepositsEnabled()); - await l1ERC20TokenBridge.enableDeposits(); - assert.isTrue(await l1ERC20TokenBridge.isDepositsEnabled()); + await l1LidoTokensBridge.enableDeposits(); + assert.isTrue(await l1LidoTokensBridge.isDepositsEnabled()); }) .step("Renounce role", async (ctx) => { - const { l1ERC20TokenBridge, l1DevMultisig } = ctx; + const { l1LidoTokensBridge, l1DevMultisig } = ctx; assert.isTrue( - await l1ERC20TokenBridge.hasRole( + await l1LidoTokensBridge.hasRole( BridgingManagerRole.DEPOSITS_ENABLER_ROLE.hash, await l1DevMultisig.getAddress() ) ); - await l1ERC20TokenBridge.renounceRole( + await l1LidoTokensBridge.renounceRole( BridgingManagerRole.DEPOSITS_ENABLER_ROLE.hash, await l1DevMultisig.getAddress() ); assert.isFalse( - await l1ERC20TokenBridge.hasRole( + await l1LidoTokensBridge.hasRole( BridgingManagerRole.DEPOSITS_ENABLER_ROLE.hash, await l1DevMultisig.getAddress() ) @@ -55,9 +56,9 @@ scenario("Optimism :: Launch integration test", ctxFactory) async function ctxFactory() { const networkName = env.network("TESTING_OPT_NETWORK", "mainnet"); - const { l1Provider, l2Provider, l1ERC20TokenBridge } = await optimism + const { l1Provider, l2Provider, l1LidoTokensBridge } = await optimism .testing(networkName) - .getIntegrationTestSetup(); + .getIntegrationTestSetup(BigNumber.from('1164454276599657236000000000')); const hasDeployedContracts = testing.env.USE_DEPLOYED_CONTRACTS(false); const l1DevMultisig = hasDeployedContracts @@ -73,8 +74,8 @@ async function ctxFactory() { l1Provider ); - const l1ERC20TokenBridgeImpl = L1ERC20TokenBridge__factory.connect( - l1ERC20TokenBridge.address, + const l1LidoTokensBridgeImpl = L1LidoTokensBridge__factory.connect( + l1LidoTokensBridge.address, l1DevMultisig ); @@ -82,7 +83,7 @@ async function ctxFactory() { l1Provider, l2Provider, l1DevMultisig, - l1ERC20TokenBridge: l1ERC20TokenBridgeImpl, + l1LidoTokensBridge: l1LidoTokensBridgeImpl, snapshot: { l1: l1Snapshot, l2: l2Snapshot, diff --git a/test/optimism/bridging-non-rebasable.integration.test.ts b/test/optimism/bridging-non-rebasable.integration.test.ts new file mode 100644 index 00000000..2026f7a4 --- /dev/null +++ b/test/optimism/bridging-non-rebasable.integration.test.ts @@ -0,0 +1,698 @@ +import { assert } from "chai"; +import { BigNumber } from 'ethers' +import env from "../../utils/env"; +import { wei } from "../../utils/wei"; +import optimism from "../../utils/optimism"; +import testing, { scenario } from "../../utils/testing"; +import { ScenarioTest } from "../../utils/testing"; +import { tokenRateAndTimestampPacked, refSlotTimestamp, getExchangeRate } from "../../utils/testing/helpers"; + +type ContextType = Awaited>> + +function bridgingTestsSuit(scenarioInstance: ScenarioTest) { + scenarioInstance + .after(async (ctx) => { + await ctx.l1Provider.send("evm_revert", [ctx.snapshot.l1]); + await ctx.l2Provider.send("evm_revert", [ctx.snapshot.l2]); + }) + + .step("Activate bridging on L1", async (ctx) => { + const { l1LidoTokensBridge } = ctx; + const { l1ERC20ExtendedTokensBridgeAdmin } = ctx.accounts; + + const isDepositsEnabled = await l1LidoTokensBridge.isDepositsEnabled(); + + if (!isDepositsEnabled) { + await l1LidoTokensBridge + .connect(l1ERC20ExtendedTokensBridgeAdmin) + .enableDeposits(); + } else { + console.log("L1 deposits already enabled"); + } + + const isWithdrawalsEnabled = + await l1LidoTokensBridge.isWithdrawalsEnabled(); + + if (!isWithdrawalsEnabled) { + await l1LidoTokensBridge + .connect(l1ERC20ExtendedTokensBridgeAdmin) + .enableWithdrawals(); + } else { + console.log("L1 withdrawals already enabled"); + } + + assert.isTrue(await l1LidoTokensBridge.isDepositsEnabled()); + assert.isTrue(await l1LidoTokensBridge.isWithdrawalsEnabled()); + }) + + .step("Activate bridging on L2", async (ctx) => { + const { l2ERC20ExtendedTokensBridge } = ctx; + const { l2ERC20ExtendedTokensBridgeAdmin } = ctx.accounts; + + const isDepositsEnabled = await l2ERC20ExtendedTokensBridge.isDepositsEnabled(); + + if (!isDepositsEnabled) { + await l2ERC20ExtendedTokensBridge + .connect(l2ERC20ExtendedTokensBridgeAdmin) + .enableDeposits(); + } else { + console.log("L2 deposits already enabled"); + } + + const isWithdrawalsEnabled = + await l2ERC20ExtendedTokensBridge.isWithdrawalsEnabled(); + + if (!isWithdrawalsEnabled) { + await l2ERC20ExtendedTokensBridge + .connect(l2ERC20ExtendedTokensBridgeAdmin) + .enableWithdrawals(); + } else { + console.log("L2 withdrawals already enabled"); + } + + assert.isTrue(await l2ERC20ExtendedTokensBridge.isDepositsEnabled()); + assert.isTrue(await l2ERC20ExtendedTokensBridge.isWithdrawalsEnabled()); + }) + + .step("L1 -> L2 deposit via depositERC20() method", async (ctx) => { + const { + l1Token, + l1LidoTokensBridge, + l2Token, + l1CrossDomainMessenger, + l2ERC20ExtendedTokensBridge, + accountingOracle + } = ctx; + const { accountA: tokenHolderA } = ctx.accounts; + const { depositAmount, tokenRate } = ctx.constants; + + await l1Token + .connect(tokenHolderA.l1Signer) + .approve(l1LidoTokensBridge.address, depositAmount); + + const tokenHolderABalanceBefore = await l1Token.balanceOf(tokenHolderA.address); + const l1ERC20ExtendedTokensBridgeBalanceBefore = await l1Token.balanceOf(l1LidoTokensBridge.address); + + ctx.balances.accountABalanceBeforeDeposit = tokenHolderABalanceBefore; + + const tx = await l1LidoTokensBridge + .connect(tokenHolderA.l1Signer) + .depositERC20( + l1Token.address, + l2Token.address, + depositAmount, + 200_000, + "0x" + ); + + const refSlotTime = await refSlotTimestamp(accountingOracle); + const dataToSend = await tokenRateAndTimestampPacked(tokenRate, refSlotTime, "0x"); + + await assert.emits(l1LidoTokensBridge, tx, "ERC20DepositInitiated", [ + l1Token.address, + l2Token.address, + tokenHolderA.address, + tokenHolderA.address, + depositAmount, + dataToSend, + ]); + + const l2DepositCalldata = l2ERC20ExtendedTokensBridge.interface.encodeFunctionData( + "finalizeDeposit", + [ + l1Token.address, + l2Token.address, + tokenHolderA.address, + tokenHolderA.address, + depositAmount, + dataToSend, + ] + ); + + const messageNonce = await l1CrossDomainMessenger.messageNonce(); + + await assert.emits(l1CrossDomainMessenger, tx, "SentMessage", [ + l2ERC20ExtendedTokensBridge.address, + l1LidoTokensBridge.address, + l2DepositCalldata, + messageNonce, + 200_000, + ]); + + assert.equalBN( + await l1Token.balanceOf(l1LidoTokensBridge.address), + l1ERC20ExtendedTokensBridgeBalanceBefore.add(depositAmount) + ); + + assert.equalBN( + await l1Token.balanceOf(tokenHolderA.address), + tokenHolderABalanceBefore.sub(depositAmount) + ); + }) + + .step("Finalize deposit on L2", async (ctx) => { + const { + l1Token, + l2Token, + l1LidoTokensBridge, + l2CrossDomainMessenger, + l2ERC20ExtendedTokensBridge, + accountingOracle + } = ctx; + const { depositAmount, tokenRate } = ctx.constants; + + const { accountA: tokenHolderA, l1CrossDomainMessengerAliased } = + ctx.accounts; + + const tokenHolderABalanceBefore = await l2Token.balanceOf(tokenHolderA.address); + const l2TokenTotalSupplyBefore = await l2Token.totalSupply(); + + const refSlotTime = await refSlotTimestamp(accountingOracle); + const dataToReceive = await tokenRateAndTimestampPacked(tokenRate, refSlotTime, "0x"); + + const tx = await l2CrossDomainMessenger + .connect(l1CrossDomainMessengerAliased) + .relayMessage( + 1, + l1LidoTokensBridge.address, + l2ERC20ExtendedTokensBridge.address, + 0, + 300_000, + l2ERC20ExtendedTokensBridge.interface.encodeFunctionData("finalizeDeposit", [ + l1Token.address, + l2Token.address, + tokenHolderA.address, + tokenHolderA.address, + depositAmount, + dataToReceive, + ]), + { gasLimit: 5_000_000 } + ); + + await assert.emits(l2ERC20ExtendedTokensBridge, tx, "DepositFinalized", [ + l1Token.address, + l2Token.address, + tokenHolderA.address, + tokenHolderA.address, + depositAmount, + "0x", + ]); + assert.equalBN( + await l2Token.balanceOf(tokenHolderA.address), + tokenHolderABalanceBefore.add(depositAmount) + ); + assert.equalBN( + await l2Token.totalSupply(), + l2TokenTotalSupplyBefore.add(depositAmount) + ); + }) + + .step("L2 -> L1 withdrawal via withdraw()", async (ctx) => { + const { accountA: tokenHolderA } = ctx.accounts; + const { withdrawalAmount } = ctx.constants; + const { l1Token, l2Token, l2ERC20ExtendedTokensBridge } = ctx; + + const tokenHolderABalanceBefore = await l2Token.balanceOf(tokenHolderA.address); + const l2TotalSupplyBefore = await l2Token.totalSupply(); + + const tx = await l2ERC20ExtendedTokensBridge + .connect(tokenHolderA.l2Signer) + .withdraw(l2Token.address, withdrawalAmount, 0, "0x"); + + await assert.emits(l2ERC20ExtendedTokensBridge, tx, "WithdrawalInitiated", [ + l1Token.address, + l2Token.address, + tokenHolderA.address, + tokenHolderA.address, + withdrawalAmount, + "0x", + ]); + + const tokenHolderABalanceAfter = await l2Token.balanceOf(tokenHolderA.address); + const l2TotalSupplyAfter = await l2Token.totalSupply(); + + assert.equalBN( + tokenHolderABalanceAfter, + tokenHolderABalanceBefore.sub(withdrawalAmount) + ); + assert.equalBN( + l2TotalSupplyAfter, + l2TotalSupplyBefore.sub(withdrawalAmount) + ); + }) + + .step("Finalize withdrawal on L1", async (ctx) => { + const { + l1Token, + l1CrossDomainMessenger, + l1LidoTokensBridge, + l2CrossDomainMessenger, + l2Token, + l2ERC20ExtendedTokensBridge, + } = ctx; + const { accountA: tokenHolderA, l1Stranger } = ctx.accounts; + const { depositAmount, withdrawalAmount } = ctx.constants; + + const tokenHolderABalanceBefore = await l1Token.balanceOf( + tokenHolderA.address + ); + const l1ERC20ExtendedTokensBridgeBalanceBefore = await l1Token.balanceOf( + l1LidoTokensBridge.address + ); + + await l1CrossDomainMessenger + .connect(l1Stranger) + .setXDomainMessageSender(l2ERC20ExtendedTokensBridge.address); + + const tx = await l1CrossDomainMessenger + .connect(l1Stranger) + .relayMessage( + l1LidoTokensBridge.address, + l2CrossDomainMessenger.address, + l1LidoTokensBridge.interface.encodeFunctionData( + "finalizeERC20Withdrawal", + [ + l1Token.address, + l2Token.address, + tokenHolderA.address, + tokenHolderA.address, + withdrawalAmount, + "0x", + ] + ), + 0 + ); + + await assert.emits(l1LidoTokensBridge, tx, "ERC20WithdrawalFinalized", [ + l1Token.address, + l2Token.address, + tokenHolderA.address, + tokenHolderA.address, + withdrawalAmount, + "0x", + ]); + + const l1LidoTokensBridgeBalanceAfter = await l1Token.balanceOf(l1LidoTokensBridge.address); + const tokenHolderABalanceAfter = await l1Token.balanceOf(tokenHolderA.address); + + assert.equalBN( + l1LidoTokensBridgeBalanceAfter, + l1ERC20ExtendedTokensBridgeBalanceBefore.sub(withdrawalAmount) + ); + + assert.equalBN( + tokenHolderABalanceAfter, + tokenHolderABalanceBefore.add(withdrawalAmount) + ); + + /// check that user balance is correct after depositing and withdrawal. + const deltaDepositWithdrawal = depositAmount.sub(withdrawalAmount); + assert.equalBN( + ctx.balances.accountABalanceBeforeDeposit, + tokenHolderABalanceAfter.add(deltaDepositWithdrawal) + ); + }) + + .step("L1 -> L2 deposit via depositERC20To()", async (ctx) => { + const { + l1Token, + l2Token, + l1LidoTokensBridge, + l2ERC20ExtendedTokensBridge, + l1CrossDomainMessenger, + accountingOracle + } = ctx; + const { accountA: tokenHolderA, accountB: tokenHolderB } = ctx.accounts; + const { depositAmount, tokenRate } = ctx.constants; + + assert.notEqual(tokenHolderA.address, tokenHolderB.address); + + const tokenHolderABalanceBefore = await l1Token.balanceOf(tokenHolderA.address); + const l1ERC20ExtendedTokensBridgeBalanceBefore = await l1Token.balanceOf(l1LidoTokensBridge.address); + + ctx.balances.accountABalanceBeforeDeposit = tokenHolderABalanceBefore; + ctx.balances.accountBBalanceBeforeDeposit = await l2Token.balanceOf(tokenHolderB.address); + + await l1Token + .connect(tokenHolderA.l1Signer) + .approve(l1LidoTokensBridge.address, depositAmount); + + const tx = await l1LidoTokensBridge + .connect(tokenHolderA.l1Signer) + .depositERC20To( + l1Token.address, + l2Token.address, + tokenHolderB.address, + depositAmount, + 200_000, + "0x" + ); + + const refSlotTime = await refSlotTimestamp(accountingOracle); + const dataToSend = await tokenRateAndTimestampPacked(tokenRate, refSlotTime, "0x"); + + await assert.emits(l1LidoTokensBridge, tx, "ERC20DepositInitiated", [ + l1Token.address, + l2Token.address, + tokenHolderA.address, + tokenHolderB.address, + depositAmount, + dataToSend, + ]); + + const l2DepositCalldata = l2ERC20ExtendedTokensBridge.interface.encodeFunctionData( + "finalizeDeposit", + [ + l1Token.address, + l2Token.address, + tokenHolderA.address, + tokenHolderB.address, + depositAmount, + dataToSend, + ] + ); + + const messageNonce = await l1CrossDomainMessenger.messageNonce(); + + await assert.emits(l1CrossDomainMessenger, tx, "SentMessage", [ + l2ERC20ExtendedTokensBridge.address, + l1LidoTokensBridge.address, + l2DepositCalldata, + messageNonce, + 200_000, + ]); + + assert.equalBN( + await l1Token.balanceOf(l1LidoTokensBridge.address), + l1ERC20ExtendedTokensBridgeBalanceBefore.add(depositAmount) + ); + + assert.equalBN( + await l1Token.balanceOf(tokenHolderA.address), + tokenHolderABalanceBefore.sub(depositAmount) + ); + }) + + .step("Finalize deposit on L2", async (ctx) => { + const { + l1Token, + l1LidoTokensBridge, + l2Token, + l2CrossDomainMessenger, + l2ERC20ExtendedTokensBridge, + accountingOracle + } = ctx; + const { + accountA: tokenHolderA, + accountB: tokenHolderB, + l1CrossDomainMessengerAliased, + } = ctx.accounts; + const { depositAmount, tokenRate } = ctx.constants; + + const l2TokenTotalSupplyBefore = await l2Token.totalSupply(); + const tokenHolderBBalanceBefore = await l2Token.balanceOf(tokenHolderB.address); + + const refSlotTime = await refSlotTimestamp(accountingOracle); + const dataToReceive = await tokenRateAndTimestampPacked(tokenRate, refSlotTime, "0x"); + + const tx = await l2CrossDomainMessenger + .connect(l1CrossDomainMessengerAliased) + .relayMessage( + 1, + l1LidoTokensBridge.address, + l2ERC20ExtendedTokensBridge.address, + 0, + 300_000, + l2ERC20ExtendedTokensBridge.interface.encodeFunctionData("finalizeDeposit", [ + l1Token.address, + l2Token.address, + tokenHolderA.address, + tokenHolderB.address, + depositAmount, + dataToReceive, + ]), + { gasLimit: 5_000_000 } + ); + + await assert.emits(l2ERC20ExtendedTokensBridge, tx, "DepositFinalized", [ + l1Token.address, + l2Token.address, + tokenHolderA.address, + tokenHolderB.address, + depositAmount, + "0x", + ]); + + assert.equalBN( + await l2Token.totalSupply(), + l2TokenTotalSupplyBefore.add(depositAmount) + ); + assert.equalBN( + await l2Token.balanceOf(tokenHolderB.address), + tokenHolderBBalanceBefore.add(depositAmount) + ); + }) + + .step("L2 -> L1 withdrawal via withdrawTo()", async (ctx) => { + const { l1Token, l2Token, l2ERC20ExtendedTokensBridge } = ctx; + const { accountA: tokenHolderA, accountB: tokenHolderB } = ctx.accounts; + const { withdrawalAmount } = ctx.constants; + + const tokenHolderBBalanceBefore = await l2Token.balanceOf( + tokenHolderB.address + ); + const l2TotalSupplyBefore = await l2Token.totalSupply(); + + const tx = await l2ERC20ExtendedTokensBridge + .connect(tokenHolderB.l2Signer) + .withdrawTo( + l2Token.address, + tokenHolderA.address, + withdrawalAmount, + 0, + "0x" + ); + + await assert.emits(l2ERC20ExtendedTokensBridge, tx, "WithdrawalInitiated", [ + l1Token.address, + l2Token.address, + tokenHolderB.address, + tokenHolderA.address, + withdrawalAmount, + "0x", + ]); + + assert.equalBN( + await l2Token.balanceOf(tokenHolderB.address), + tokenHolderBBalanceBefore.sub(withdrawalAmount) + ); + + assert.equalBN( + await l2Token.totalSupply(), + l2TotalSupplyBefore.sub(withdrawalAmount) + ); + }) + + .step("Finalize withdrawal on L1", async (ctx) => { + const { + l1Token, + l1CrossDomainMessenger, + l1LidoTokensBridge, + l2CrossDomainMessenger, + l2Token, + l2ERC20ExtendedTokensBridge, + } = ctx; + const { + accountA: tokenHolderA, + accountB: tokenHolderB, + l1Stranger, + } = ctx.accounts; + const { depositAmount, withdrawalAmount } = ctx.constants; + + const tokenHolderABalanceBefore = await l1Token.balanceOf( + tokenHolderA.address + ); + const l1ERC20ExtendedTokensBridgeBalanceBefore = await l1Token.balanceOf( + l1LidoTokensBridge.address + ); + + await l1CrossDomainMessenger + .connect(l1Stranger) + .setXDomainMessageSender(l2ERC20ExtendedTokensBridge.address); + + const tx = await l1CrossDomainMessenger + .connect(l1Stranger) + .relayMessage( + l1LidoTokensBridge.address, + l2CrossDomainMessenger.address, + l1LidoTokensBridge.interface.encodeFunctionData( + "finalizeERC20Withdrawal", + [ + l1Token.address, + l2Token.address, + tokenHolderB.address, + tokenHolderA.address, + withdrawalAmount, + "0x", + ] + ), + 0 + ); + + await assert.emits(l1LidoTokensBridge, tx, "ERC20WithdrawalFinalized", [ + l1Token.address, + l2Token.address, + tokenHolderB.address, + tokenHolderA.address, + withdrawalAmount, + "0x", + ]); + + const l1LidoTokensBridgeBalanceAfter = await l1Token.balanceOf(l1LidoTokensBridge.address); + const tokenHolderABalanceAfter = await l1Token.balanceOf(tokenHolderA.address); + const tokenHolderBBalanceAfter = await l2Token.balanceOf(tokenHolderB.address); + + assert.equalBN( + l1LidoTokensBridgeBalanceAfter, + l1ERC20ExtendedTokensBridgeBalanceBefore.sub(withdrawalAmount) + ); + + assert.equalBN( + tokenHolderABalanceAfter, + tokenHolderABalanceBefore.add(withdrawalAmount) + ); + + /// check that user balance is correct after depositing and withdrawal. + const deltaDepositWithdrawal = depositAmount.sub(withdrawalAmount); + assert.equalBN( + ctx.balances.accountABalanceBeforeDeposit, + tokenHolderABalanceAfter.add(deltaDepositWithdrawal) + ); + assert.equalBN( + ctx.balances.accountBBalanceBeforeDeposit, + tokenHolderBBalanceAfter.sub(deltaDepositWithdrawal) + ); + }) + + .run(); +} + +function ctxFactory(depositAmount: BigNumber, withdrawalAmount: BigNumber) { + return async () => { + const networkName = env.network("TESTING_OPT_NETWORK", "mainnet"); + const tokenRateDecimals = BigNumber.from(27); + const totalPooledEther = BigNumber.from('9309904612343950493629678'); + const totalShares = BigNumber.from('7975822843597609202337218'); + + const { + l1Provider, + l2Provider, + l1ERC20ExtendedTokensBridgeAdmin, + l2ERC20ExtendedTokensBridgeAdmin, + ...contracts + } = await optimism.testing(networkName).getIntegrationTestSetup(totalPooledEther, totalShares); + + const l1Snapshot = await l1Provider.send("evm_snapshot", []); + const l2Snapshot = await l2Provider.send("evm_snapshot", []); + + const tokenRate = await contracts.l1Token.getStETHByWstETH(BigNumber.from(10).pow(tokenRateDecimals)); + + await optimism.testing(networkName).stubL1CrossChainMessengerContract(); + + const accountA = testing.accounts.accountA(l1Provider, l2Provider); + const accountB = testing.accounts.accountB(l1Provider, l2Provider); + + await testing.setBalance( + await contracts.l1TokensHolder.getAddress(), + wei.toBigNumber(wei`1 ether`), + l1Provider + ); + + await testing.setBalance( + await l1ERC20ExtendedTokensBridgeAdmin.getAddress(), + wei.toBigNumber(wei`1 ether`), + l1Provider + ); + + await testing.setBalance( + await l2ERC20ExtendedTokensBridgeAdmin.getAddress(), + wei.toBigNumber(wei`1 ether`), + l2Provider + ); + + const l1CrossDomainMessengerAliased = await testing.impersonate( + testing.accounts.applyL1ToL2Alias(contracts.l1CrossDomainMessenger.address), + l2Provider + ); + + await testing.setBalance( + await l1CrossDomainMessengerAliased.getAddress(), + wei.toBigNumber(wei`1 ether`), + l2Provider + ); + + await contracts.l1Token + .connect(contracts.l1TokensHolder) + .transfer(accountA.l1Signer.address, depositAmount.mul(2)); + + var accountABalanceBeforeDeposit = BigNumber.from(0); + var accountBBalanceBeforeDeposit = BigNumber.from(0); + + return { + l1Provider, + l2Provider, + ...contracts, + accounts: { + accountA, + accountB, + l1Stranger: testing.accounts.stranger(l1Provider), + l1ERC20ExtendedTokensBridgeAdmin, + l2ERC20ExtendedTokensBridgeAdmin, + l1CrossDomainMessengerAliased, + }, + constants: { + depositAmount, + withdrawalAmount, + tokenRate + }, + balances: { + accountABalanceBeforeDeposit, + accountBBalanceBeforeDeposit + }, + snapshot: { + l1: l1Snapshot, + l2: l2Snapshot, + }, + }; + } +} + +bridgingTestsSuit( + scenario( + "Optimism :: Bridging X non-rebasable token integration test", + ctxFactory( + wei.toBigNumber(wei`0.001 ether`), + wei.toBigNumber(wei`0.001 ether`) + ) + ) +); + +bridgingTestsSuit( + scenario( + "Optimism :: Bridging 1 wei non-rebasable token integration test", + ctxFactory( + wei.toBigNumber(wei`1 wei`), + wei.toBigNumber(wei`1 wei`) + ) + ) +); + +bridgingTestsSuit( + scenario( + "Optimism :: Bridging zero non-rebasable token integration test", + ctxFactory( + BigNumber.from('0'), + BigNumber.from('0') + ) + ) +); diff --git a/test/optimism/bridging-rebasable-to.e2e.test.ts b/test/optimism/bridging-rebasable-to.e2e.test.ts new file mode 100644 index 00000000..6dc3d5ac --- /dev/null +++ b/test/optimism/bridging-rebasable-to.e2e.test.ts @@ -0,0 +1,165 @@ +import { + CrossChainMessenger, + DAIBridgeAdapter, + MessageStatus, + } from "@eth-optimism/sdk"; + import { assert } from "chai"; + import { TransactionResponse } from "@ethersproject/providers"; + + import env from "../../utils/env"; + import { wei } from "../../utils/wei"; + import network from "../../utils/network"; + import optimism from "../../utils/optimism"; + import { ERC20Mintable } from "../../typechain"; + import { scenario } from "../../utils/testing"; + import { sleep } from "../../utils/testing/e2e"; + import { LidoBridgeAdapter } from "../../utils/optimism/LidoBridgeAdapter"; + + let depositTokensTxResponse: TransactionResponse; + let withdrawTokensTxResponse: TransactionResponse; + + scenario("Optimism :: Bridging via depositTo/withdrawTo E2E test", ctxFactory) + .step( + "Validate tester has required amount of L1 token", + async ({ l1TokenRebasable, l1Tester, depositAmount }) => { + const balanceBefore = await l1TokenRebasable.balanceOf(l1Tester.address); + if (balanceBefore.lt(depositAmount)) { + try { + await (l1TokenRebasable as ERC20Mintable).mint( + l1Tester.address, + depositAmount + ); + } catch {} + const balanceAfter = await l1TokenRebasable.balanceOf(l1Tester.address); + assert.isTrue( + balanceAfter.gte(depositAmount), + "Tester has not enough L1 token" + ); + } + } + ) + + .step("Set allowance for L1LidoTokensBridge to deposit", async (ctx) => { + const allowanceTxResponse = await ctx.crossChainMessenger.approveERC20( + ctx.l1TokenRebasable.address, + ctx.l2TokenRebasable.address, + ctx.depositAmount + ); + + await allowanceTxResponse.wait(); + + assert.equalBN( + await ctx.l1TokenRebasable.allowance( + ctx.l1Tester.address, + ctx.l1LidoTokensBridge.address + ), + ctx.depositAmount + ); + }) + + .step("Bridge tokens to L2 via depositERC20To()", async (ctx) => { + depositTokensTxResponse = await ctx.l1LidoTokensBridge + .connect(ctx.l1Tester) + .depositERC20To( + ctx.l1TokenRebasable.address, + ctx.l2TokenRebasable.address, + ctx.l1Tester.address, + ctx.depositAmount, + 2_000_000, + "0x" + ); + + await depositTokensTxResponse.wait(); + }) + + .step("Waiting for status to change to RELAYED", async (ctx) => { + await ctx.crossChainMessenger.waitForMessageStatus( + depositTokensTxResponse.hash, + MessageStatus.RELAYED + ); + }) + + .step("Withdraw tokens from L2 via withdrawERC20To()", async (ctx) => { + withdrawTokensTxResponse = await ctx.l2ERC20ExtendedTokensBridge + .connect(ctx.l2Tester) + .withdrawTo( + ctx.l2TokenRebasable.address, + ctx.l1Tester.address, + ctx.withdrawalAmount, + 0, + "0x" + ); + await withdrawTokensTxResponse.wait(); + }) + + .step("Waiting for status to change to READY_TO_PROVE", async (ctx) => { + await ctx.crossChainMessenger.waitForMessageStatus( + withdrawTokensTxResponse.hash, + MessageStatus.READY_TO_PROVE + ); + }) + + .step("Proving the L2 -> L1 message", async (ctx) => { + const tx = await ctx.crossChainMessenger.proveMessage( + withdrawTokensTxResponse.hash + ); + await tx.wait(); + }) + + .step("Waiting for status to change to IN_CHALLENGE_PERIOD", async (ctx) => { + await ctx.crossChainMessenger.waitForMessageStatus( + withdrawTokensTxResponse.hash, + MessageStatus.IN_CHALLENGE_PERIOD + ); + }) + + .step("Waiting for status to change to READY_FOR_RELAY", async (ctx) => { + await ctx.crossChainMessenger.waitForMessageStatus( + withdrawTokensTxResponse.hash, + MessageStatus.READY_FOR_RELAY + ); + }) + + .step("Finalizing L2 -> L1 message", async (ctx) => { + const finalizationPeriod = await ctx.crossChainMessenger.contracts.l1.L2OutputOracle.FINALIZATION_PERIOD_SECONDS(); + await sleep(finalizationPeriod * 1000); + await ctx.crossChainMessenger.finalizeMessage(withdrawTokensTxResponse); + }) + + .step("Waiting for status to change to RELAYED", async (ctx) => { + await ctx.crossChainMessenger.waitForMessageStatus( + withdrawTokensTxResponse, + MessageStatus.RELAYED + ); + }) + + .run(); + + async function ctxFactory() { + const networkName = env.network("TESTING_OPT_NETWORK", "sepolia"); + const testingSetup = await optimism.testing(networkName).getE2ETestSetup(); + + return { + depositAmount: wei`0.0025 ether`, + withdrawalAmount: wei`0.0025 ether`, + l1Tester: testingSetup.l1Tester, + l2Tester: testingSetup.l2Tester, + l1TokenRebasable: testingSetup.l1TokenRebasable, + l2TokenRebasable: testingSetup.l2TokenRebasable, + l1LidoTokensBridge: testingSetup.l1LidoTokensBridge, + l2ERC20ExtendedTokensBridge: testingSetup.l2ERC20ExtendedTokensBridge, + crossChainMessenger: new CrossChainMessenger({ + l2ChainId: network.chainId("opt", networkName), + l1ChainId: network.chainId("eth", networkName), + l1SignerOrProvider: testingSetup.l1Tester, + l2SignerOrProvider: testingSetup.l2Tester, + bridges: { + LidoBridge: { + Adapter: LidoBridgeAdapter, + l1Bridge: testingSetup.l1LidoTokensBridge.address, + l2Bridge: testingSetup.l2ERC20ExtendedTokensBridge.address, + }, + }, + }), + }; + } diff --git a/test/optimism/bridging-rebasable.e2e.test.ts b/test/optimism/bridging-rebasable.e2e.test.ts new file mode 100644 index 00000000..27aaa65d --- /dev/null +++ b/test/optimism/bridging-rebasable.e2e.test.ts @@ -0,0 +1,152 @@ +import { + CrossChainMessenger, + MessageStatus, + } from "@eth-optimism/sdk"; + import { assert } from "chai"; + import { TransactionResponse } from "@ethersproject/providers"; + + import env from "../../utils/env"; + import { wei } from "../../utils/wei"; + import network from "../../utils/network"; + import optimism from "../../utils/optimism"; + import { ERC20Mintable } from "../../typechain"; + import { scenario } from "../../utils/testing"; + import { sleep } from "../../utils/testing/e2e"; + import { LidoBridgeAdapter } from "../../utils/optimism/LidoBridgeAdapter"; + + let depositTokensTxResponse: TransactionResponse; + let withdrawTokensTxResponse: TransactionResponse; + + scenario("Optimism :: Bridging via deposit/withdraw E2E test", ctxFactory) + .step( + "Validate tester has required amount of L1 token", + async ({ l1TokenRebasable, l1Tester, depositAmount }) => { + const balanceBefore = await l1TokenRebasable.balanceOf(l1Tester.address); + if (balanceBefore.lt(depositAmount)) { + try { + await (l1TokenRebasable as ERC20Mintable).mint( + l1Tester.address, + depositAmount + ); + } catch {} + const balanceAfter = await l1TokenRebasable.balanceOf(l1Tester.address); + assert.isTrue( + balanceAfter.gte(depositAmount), + "Tester has not enough L1 token" + ); + } + } + ) + + .step("Set allowance for L1LidoTokensBridge to deposit", async (ctx) => { + const allowanceTxResponse = await ctx.crossChainMessenger.approveERC20( + ctx.l1TokenRebasable.address, + ctx.l2TokenRebasable.address, + ctx.depositAmount + ); + + await allowanceTxResponse.wait(); + + assert.equalBN( + await ctx.l1TokenRebasable.allowance( + ctx.l1Tester.address, + ctx.l1LidoTokensBridge.address + ), + ctx.depositAmount + ); + }) + + .step("Bridge tokens to L2 via depositERC20()", async (ctx) => { + depositTokensTxResponse = await ctx.crossChainMessenger.depositERC20( + ctx.l1TokenRebasable.address, + ctx.l2TokenRebasable.address, + ctx.depositAmount + ); + await depositTokensTxResponse.wait(); + }) + + .step("Waiting for status to change to RELAYED", async (ctx) => { + await ctx.crossChainMessenger.waitForMessageStatus( + depositTokensTxResponse.hash, + MessageStatus.RELAYED + ); + }) + + .step("Withdraw tokens from L2 via withdrawERC20()", async (ctx) => { + withdrawTokensTxResponse = await ctx.crossChainMessenger.withdrawERC20( + ctx.l1TokenRebasable.address, + ctx.l2TokenRebasable.address, + ctx.withdrawalAmount + ); + await withdrawTokensTxResponse.wait(); + }) + + .step("Waiting for status to change to READY_TO_PROVE", async (ctx) => { + await ctx.crossChainMessenger.waitForMessageStatus( + withdrawTokensTxResponse.hash, + MessageStatus.READY_TO_PROVE + ); + }) + + .step("Proving the L2 -> L1 message", async (ctx) => { + const tx = await ctx.crossChainMessenger.proveMessage( + withdrawTokensTxResponse.hash + ); + await tx.wait(); + }) + + .step("Waiting for status to change to IN_CHALLENGE_PERIOD", async (ctx) => { + await ctx.crossChainMessenger.waitForMessageStatus( + withdrawTokensTxResponse.hash, + MessageStatus.IN_CHALLENGE_PERIOD + ); + }) + + .step("Waiting for status to change to READY_FOR_RELAY", async (ctx) => { + await ctx.crossChainMessenger.waitForMessageStatus( + withdrawTokensTxResponse.hash, + MessageStatus.READY_FOR_RELAY + ); + }) + + .step("Finalizing L2 -> L1 message", async (ctx) => { + const finalizationPeriod = await ctx.crossChainMessenger.contracts.l1.L2OutputOracle.FINALIZATION_PERIOD_SECONDS(); + await sleep(finalizationPeriod * 1000); + await ctx.crossChainMessenger.finalizeMessage(withdrawTokensTxResponse); + }) + + .step("Waiting for status to change to RELAYED", async (ctx) => { + await ctx.crossChainMessenger.waitForMessageStatus( + withdrawTokensTxResponse, + MessageStatus.RELAYED + ); + }) + + .run(); + + async function ctxFactory() { + const networkName = env.network("TESTING_OPT_NETWORK", "sepolia"); + const testingSetup = await optimism.testing(networkName).getE2ETestSetup(); + + return { + depositAmount: wei`0.0025 ether`, + withdrawalAmount: wei`0.0025 ether`, + l1Tester: testingSetup.l1Tester, + l1TokenRebasable: testingSetup.l1TokenRebasable, + l2TokenRebasable: testingSetup.l2TokenRebasable, + l1LidoTokensBridge: testingSetup.l1LidoTokensBridge, + crossChainMessenger: new CrossChainMessenger({ + l2ChainId: network.chainId("opt", networkName), + l1ChainId: network.chainId("eth", networkName), + l1SignerOrProvider: testingSetup.l1Tester, + l2SignerOrProvider: testingSetup.l2Tester, + bridges: { + LidoBridge: { + Adapter: LidoBridgeAdapter, + l1Bridge: testingSetup.l1LidoTokensBridge.address, + l2Bridge: testingSetup.l2ERC20ExtendedTokensBridge.address, + }, + }, + }), + }; + } diff --git a/test/optimism/bridging-rebasable.integration.test.ts b/test/optimism/bridging-rebasable.integration.test.ts new file mode 100644 index 00000000..dab782f9 --- /dev/null +++ b/test/optimism/bridging-rebasable.integration.test.ts @@ -0,0 +1,854 @@ +import { assert } from "chai"; +import { BigNumber } from 'ethers' +import env from "../../utils/env"; +import { wei } from "../../utils/wei"; +import optimism from "../../utils/optimism"; +import testing, { scenario } from "../../utils/testing"; +import { ScenarioTest } from "../../utils/testing"; +import { + tokenRateAndTimestampPacked, + refSlotTimestamp, + nonRebasableFromRebasableL1, + nonRebasableFromRebasableL2, + rebasableFromNonRebasableL1, + rebasableFromNonRebasableL2 +} from "../../utils/testing/helpers"; + +type ContextType = Awaited>> + +function bridgingTestsSuit(scenarioInstance: ScenarioTest) { + scenarioInstance + .after(async (ctx) => { + await ctx.l1Provider.send("evm_revert", [ctx.snapshot.l1]); + await ctx.l2Provider.send("evm_revert", [ctx.snapshot.l2]); + }) + + .step("Activate bridging on L1", async (ctx) => { + const { l1LidoTokensBridge } = ctx; + const { l1ERC20ExtendedTokensBridgeAdmin } = ctx.accounts; + + const isDepositsEnabled = await l1LidoTokensBridge.isDepositsEnabled(); + + if (!isDepositsEnabled) { + await l1LidoTokensBridge + .connect(l1ERC20ExtendedTokensBridgeAdmin) + .enableDeposits(); + } else { + console.log("L1 deposits already enabled"); + } + + const isWithdrawalsEnabled = + await l1LidoTokensBridge.isWithdrawalsEnabled(); + + if (!isWithdrawalsEnabled) { + await l1LidoTokensBridge + .connect(l1ERC20ExtendedTokensBridgeAdmin) + .enableWithdrawals(); + } else { + console.log("L1 withdrawals already enabled"); + } + + assert.isTrue(await l1LidoTokensBridge.isDepositsEnabled()); + assert.isTrue(await l1LidoTokensBridge.isWithdrawalsEnabled()); + }) + + .step("Activate bridging on L2", async (ctx) => { + const { l2ERC20ExtendedTokensBridge } = ctx; + const { l2ERC20ExtendedTokensBridgeAdmin } = ctx.accounts; + + const isDepositsEnabled = await l2ERC20ExtendedTokensBridge.isDepositsEnabled(); + + if (!isDepositsEnabled) { + await l2ERC20ExtendedTokensBridge + .connect(l2ERC20ExtendedTokensBridgeAdmin) + .enableDeposits(); + } else { + console.log("L2 deposits already enabled"); + } + + const isWithdrawalsEnabled = + await l2ERC20ExtendedTokensBridge.isWithdrawalsEnabled(); + + if (!isWithdrawalsEnabled) { + await l2ERC20ExtendedTokensBridge + .connect(l2ERC20ExtendedTokensBridgeAdmin) + .enableWithdrawals(); + } else { + console.log("L2 withdrawals already enabled"); + } + + assert.isTrue(await l2ERC20ExtendedTokensBridge.isDepositsEnabled()); + assert.isTrue(await l2ERC20ExtendedTokensBridge.isWithdrawalsEnabled()); + }) + + .step("L1 -> L2 deposit via depositERC20() method", async (ctx) => { + const { + l1Token, + l1TokenRebasable, + l2TokenRebasable, + l1LidoTokensBridge, + l1CrossDomainMessenger, + l2ERC20ExtendedTokensBridge, + accountingOracle + } = ctx; + const { accountA: tokenHolderA } = ctx.accounts; + const { depositAmountOfRebasableToken, tokenRate } = ctx.constants; + + /// wrap L1 + const depositAmountNonRebasable = nonRebasableFromRebasableL1( + depositAmountOfRebasableToken, + ctx.constants.totalPooledEther, + ctx.constants.totalShares + ); + + console.log("depositAmountOfRebasableToken=",depositAmountOfRebasableToken); + console.log("wrap L1: depositAmountNonRebasable=",depositAmountNonRebasable); + + await l1TokenRebasable + .connect(tokenHolderA.l1Signer) + .approve(l1LidoTokensBridge.address, depositAmountOfRebasableToken); + + const rebasableTokenHolderBalanceBefore = await l1TokenRebasable.balanceOf(tokenHolderA.address); + const nonRebasableTokenBridgeBalanceBefore = await l1Token.balanceOf(l1LidoTokensBridge.address); + const warappedRebasableTokenBalanceBefore = await l1TokenRebasable.balanceOf(l1Token.address); + + ctx.balances.accountABalanceBeforeDeposit = rebasableTokenHolderBalanceBefore; + + const tx = await l1LidoTokensBridge + .connect(tokenHolderA.l1Signer) + .depositERC20( + l1TokenRebasable.address, + l2TokenRebasable.address, + depositAmountOfRebasableToken, + 200_000, + "0x" + ); + + const refSlotTime = await refSlotTimestamp(accountingOracle); + const dataToSend = await tokenRateAndTimestampPacked(tokenRate, refSlotTime, "0x"); + + await assert.emits(l1LidoTokensBridge, tx, "ERC20DepositInitiated", [ + l1TokenRebasable.address, + l2TokenRebasable.address, + tokenHolderA.address, + tokenHolderA.address, + depositAmountOfRebasableToken, + dataToSend, + ]); + + const l2DepositCalldata = l2ERC20ExtendedTokensBridge.interface.encodeFunctionData( + "finalizeDeposit", + [ + l1TokenRebasable.address, + l2TokenRebasable.address, + tokenHolderA.address, + tokenHolderA.address, + depositAmountNonRebasable, + dataToSend, + ] + ); + + const messageNonce = await l1CrossDomainMessenger.messageNonce(); + + await assert.emits(l1CrossDomainMessenger, tx, "SentMessage", [ + l2ERC20ExtendedTokensBridge.address, + l1LidoTokensBridge.address, + l2DepositCalldata, + messageNonce, + 200_000, + ]); + + const rebasableTokenHolderBalanceAfter = await l1TokenRebasable.balanceOf(tokenHolderA.address); + const nonRebasableTokenBridgeBalanceAfter = await l1Token.balanceOf(l1LidoTokensBridge.address); + const wrappedRebasableTokenBalanceAfter = await l1TokenRebasable.balanceOf(l1Token.address); + + assert.equalBN( + rebasableTokenHolderBalanceAfter, + rebasableTokenHolderBalanceBefore.sub(depositAmountOfRebasableToken) + ); + + // during wrapping 1-2 wei can be lost + assert.isTrue(almostEqual( + depositAmountNonRebasable, + nonRebasableTokenBridgeBalanceAfter.sub(nonRebasableTokenBridgeBalanceBefore)) + ); + + assert.equalBN( + wrappedRebasableTokenBalanceAfter, + warappedRebasableTokenBalanceBefore.add(depositAmountOfRebasableToken) + ); + }) + + .step("Finalize deposit on L2", async (ctx) => { + const { + l1TokenRebasable, + accountingOracle, + l2TokenRebasable, + l1LidoTokensBridge, + l2CrossDomainMessenger, + l2ERC20ExtendedTokensBridge + } = ctx; + + const { depositAmountOfRebasableToken, tokenRate } = ctx.constants; + + // first wrap on L1 + const depositAmountNonRebasable = nonRebasableFromRebasableL1( + depositAmountOfRebasableToken, + ctx.constants.totalPooledEther, + ctx.constants.totalShares + ); + // second wrap on L2 + const depositAmountRebasable = rebasableFromNonRebasableL2( + depositAmountNonRebasable, + ctx.constants.tokenRateDecimals, + ctx.constants.tokenRate + ); + + console.log("input: depositAmountOfRebasableToken=",depositAmountOfRebasableToken); + console.log("wrap on L1: depositAmountNonRebasable=",depositAmountNonRebasable); + console.log("wrap on L2: depositAmountRebasable=",depositAmountRebasable); + + const { accountA: tokenHolderA, l1CrossDomainMessengerAliased } = ctx.accounts; + + const tokenHolderABalanceBefore = await l2TokenRebasable.balanceOf(tokenHolderA.address); + const l2TokenRebasableTotalSupplyBefore = await l2TokenRebasable.totalSupply(); + + const refSlotTime = await refSlotTimestamp(accountingOracle); + const dataToReceive = await tokenRateAndTimestampPacked(tokenRate, refSlotTime, "0x"); + + const tx = await l2CrossDomainMessenger + .connect(l1CrossDomainMessengerAliased) + .relayMessage( + 1, + l1LidoTokensBridge.address, + l2ERC20ExtendedTokensBridge.address, + 0, + 300_000, + l2ERC20ExtendedTokensBridge.interface.encodeFunctionData("finalizeDeposit", [ + l1TokenRebasable.address, + l2TokenRebasable.address, + tokenHolderA.address, + tokenHolderA.address, + depositAmountNonRebasable, + dataToReceive, + ]), + { gasLimit: 5_000_000 } + ); + + await assert.emits(l2ERC20ExtendedTokensBridge, tx, "DepositFinalized", [ + l1TokenRebasable.address, + l2TokenRebasable.address, + tokenHolderA.address, + tokenHolderA.address, + depositAmountRebasable, + "0x", + ]); + + const tokenHolderABalanceAfter = await l2TokenRebasable.balanceOf(tokenHolderA.address); + const l2TokenRebasableTotalSupplyAfter = await l2TokenRebasable.totalSupply(); + + console.log("rebasable on L2 tokenHolderABalanceBefore=",tokenHolderABalanceBefore); + console.log("rebasable on L2 tokenHolderABalanceAfter=",tokenHolderABalanceAfter); + console.log("diff on L2 tokenHolderABalance=",tokenHolderABalanceBefore.add(depositAmountRebasable).sub(tokenHolderABalanceAfter)); + + assert.equalBN( + tokenHolderABalanceBefore.add(depositAmountRebasable), + tokenHolderABalanceAfter + ); + assert.equalBN( + l2TokenRebasableTotalSupplyBefore.add(depositAmountRebasable), + l2TokenRebasableTotalSupplyAfter + ); + }) + + .step("L2 -> L1 withdrawal via withdraw()", async (ctx) => { + const { accountA: tokenHolderA } = ctx.accounts; + const { + l1TokenRebasable, + l2TokenRebasable, + l2ERC20ExtendedTokensBridge + } = ctx; + const { withdrawalAmountOfRebasableToken } = ctx.constants; + + const tokenHolderABalanceBefore = await l2TokenRebasable.balanceOf(tokenHolderA.address); + const l2TotalSupplyBefore = await l2TokenRebasable.totalSupply(); + + console.log("input: withdrawalAmountOfRebasableToken=",withdrawalAmountOfRebasableToken); + + const tx = await l2ERC20ExtendedTokensBridge + .connect(tokenHolderA.l2Signer) + .withdraw( + l2TokenRebasable.address, + withdrawalAmountOfRebasableToken, + 0, + "0x" + ); + + await assert.emits(l2ERC20ExtendedTokensBridge, tx, "WithdrawalInitiated", [ + l1TokenRebasable.address, + l2TokenRebasable.address, + tokenHolderA.address, + tokenHolderA.address, + withdrawalAmountOfRebasableToken, + "0x", + ]); + + const tokenHolderABalanceAfter = await l2TokenRebasable.balanceOf(tokenHolderA.address); + const l2TotalSupplyAfter = await l2TokenRebasable.totalSupply() + + // during unwrapping 1-2 wei can be lost + assert.isTrue(almostEqual(tokenHolderABalanceAfter, tokenHolderABalanceBefore.sub(withdrawalAmountOfRebasableToken))); + assert.isTrue(almostEqual(l2TotalSupplyAfter, l2TotalSupplyBefore.sub(withdrawalAmountOfRebasableToken))); + }) + + .step("Finalize withdrawal on L1", async (ctx) => { + const { + l1Token, + l1TokenRebasable, + l1CrossDomainMessenger, + l1LidoTokensBridge, + l2CrossDomainMessenger, + l2TokenRebasable, + l2ERC20ExtendedTokensBridge, + } = ctx; + const { accountA: tokenHolderA, l1Stranger } = ctx.accounts; + const { depositAmountOfRebasableToken, withdrawalAmountOfRebasableToken, tokenRate } = ctx.constants; + + // unwrap on L2 + const withdrawalAmountNonRebasable = nonRebasableFromRebasableL2( + withdrawalAmountOfRebasableToken, + ctx.constants.tokenRateDecimals, + tokenRate); + + // unwrap on L1: loosing 1-2 wei + const withdrawalAmountRebasable = rebasableFromNonRebasableL1( + withdrawalAmountNonRebasable, + ctx.constants.totalPooledEther, + ctx.constants.totalShares + ); + + console.log("input: withdrawalAmountOfRebasableToken=",withdrawalAmountOfRebasableToken); + console.log("unwrap on L2: withdrawalAmountNonRebasable=",withdrawalAmountNonRebasable); + console.log("unwrap on L1: withdrawalAmountRebasable=",withdrawalAmountRebasable); + + const tokenHolderABalanceBefore = await l1TokenRebasable.balanceOf(tokenHolderA.address); + const l1LidoTokensBridgeBalanceBefore = await l1Token.balanceOf(l1LidoTokensBridge.address); + + await l1CrossDomainMessenger + .connect(l1Stranger) + .setXDomainMessageSender(l2ERC20ExtendedTokensBridge.address); + + const tx = await l1CrossDomainMessenger + .connect(l1Stranger) + .relayMessage( + l1LidoTokensBridge.address, + l2CrossDomainMessenger.address, + l1LidoTokensBridge.interface.encodeFunctionData( + "finalizeERC20Withdrawal", + [ + l1TokenRebasable.address, + l2TokenRebasable.address, + tokenHolderA.address, + tokenHolderA.address, + withdrawalAmountNonRebasable, + "0x", + ] + ), + 0 + ); + + await assert.emits(l1LidoTokensBridge, tx, "ERC20WithdrawalFinalized", [ + l1TokenRebasable.address, + l2TokenRebasable.address, + tokenHolderA.address, + tokenHolderA.address, + withdrawalAmountRebasable, + "0x", + ]); + + const l1LidoTokensBridgeBalanceAfter = await l1Token.balanceOf(l1LidoTokensBridge.address); + const tokenHolderABalanceAfter = await l1TokenRebasable.balanceOf(tokenHolderA.address); + + console.log("rebasable on L1 tokenHolderABalanceBefore=",tokenHolderABalanceBefore); + console.log("rebasable on L1 tokenHolderABalanceAfter=",tokenHolderABalanceAfter); + console.log("diff on L1 tokenHolderA=",tokenHolderABalanceAfter.sub(tokenHolderABalanceBefore.add(withdrawalAmountRebasable))); + + assert.equalBN( + l1LidoTokensBridgeBalanceAfter, + l1LidoTokensBridgeBalanceBefore.sub(withdrawalAmountNonRebasable) + ); + + assert.equalBN( + tokenHolderABalanceAfter, + tokenHolderABalanceBefore.add(withdrawalAmountRebasable) + ); + + /// check that user balance is correct after depositing and withdrawal. + const deltaDepositWithdrawal = depositAmountOfRebasableToken.sub(withdrawalAmountOfRebasableToken); + assert.isTrue(almostEqual( + ctx.balances.accountABalanceBeforeDeposit, + tokenHolderABalanceAfter.add(deltaDepositWithdrawal)) + ); + }) + + .step("L1 -> L2 deposit via depositERC20To()", async (ctx) => { + + const { + l1Token, + l1TokenRebasable, + accountingOracle, + l1LidoTokensBridge, + l2TokenRebasable, + l1CrossDomainMessenger, + l2ERC20ExtendedTokensBridge, + } = ctx; + const { accountA: tokenHolderA, accountB: tokenHolderB } = ctx.accounts; + assert.notEqual(tokenHolderA.address, tokenHolderB.address); + + const { depositAmountOfRebasableToken, tokenRate } = ctx.constants; + + // wrap on L1 + const depositAmountNonRebasable = nonRebasableFromRebasableL1( + depositAmountOfRebasableToken, + ctx.constants.totalPooledEther, + ctx.constants.totalShares + ); + + const rebasableTokenHolderABalanceBefore = await l1TokenRebasable.balanceOf(tokenHolderA.address); + const nonRebasableTokenBridgeBalanceBefore = await l1Token.balanceOf(l1LidoTokensBridge.address); + const warappedRebasableTokenBalanceBefore = await l1TokenRebasable.balanceOf(l1Token.address); + + // save to check balance later + ctx.balances.accountABalanceBeforeDeposit = rebasableTokenHolderABalanceBefore; + ctx.balances.accountBBalanceBeforeDeposit = await l2TokenRebasable.balanceOf(tokenHolderB.address); + + await l1TokenRebasable + .connect(tokenHolderA.l1Signer) + .approve(l1LidoTokensBridge.address, depositAmountOfRebasableToken); + + const tx = await l1LidoTokensBridge + .connect(tokenHolderA.l1Signer) + .depositERC20To( + l1TokenRebasable.address, + l2TokenRebasable.address, + tokenHolderB.address, + depositAmountOfRebasableToken, + 200_000, + "0x" + ); + + const refSlotTime = await refSlotTimestamp(accountingOracle); + const dataToSend = await tokenRateAndTimestampPacked(tokenRate, refSlotTime, "0x"); + + await assert.emits(l1LidoTokensBridge, tx, "ERC20DepositInitiated", [ + l1TokenRebasable.address, + l2TokenRebasable.address, + tokenHolderA.address, + tokenHolderB.address, + depositAmountOfRebasableToken, + dataToSend, + ]); + + const l2DepositCalldata = l2ERC20ExtendedTokensBridge.interface.encodeFunctionData( + "finalizeDeposit", + [ + l1TokenRebasable.address, + l2TokenRebasable.address, + tokenHolderA.address, + tokenHolderB.address, + depositAmountNonRebasable, + dataToSend, + ] + ); + + const messageNonce = await l1CrossDomainMessenger.messageNonce(); + + await assert.emits(l1CrossDomainMessenger, tx, "SentMessage", [ + l2ERC20ExtendedTokensBridge.address, + l1LidoTokensBridge.address, + l2DepositCalldata, + messageNonce, + 200_000, + ]); + + const rebasableTokenHolderABalanceAfter = await l1TokenRebasable.balanceOf(tokenHolderA.address); + const nonRebasableTokenBridgeBalanceAfter = await l1Token.balanceOf(l1LidoTokensBridge.address); + const warappedRebasableTokenBalanceAfter = await l1TokenRebasable.balanceOf(l1Token.address); + + assert.equalBN( + rebasableTokenHolderABalanceAfter, + rebasableTokenHolderABalanceBefore.sub(depositAmountOfRebasableToken) + ); + + // during wrapping 1-2 wei can be lost + assert.isTrue(almostEqual( + depositAmountNonRebasable, + nonRebasableTokenBridgeBalanceAfter.sub(nonRebasableTokenBridgeBalanceBefore)) + ); + + assert.equalBN( + warappedRebasableTokenBalanceAfter, + warappedRebasableTokenBalanceBefore.add(depositAmountOfRebasableToken) + ); + }) + + .step("Finalize deposit on L2", async (ctx) => { + const { + l1TokenRebasable, + accountingOracle, + l1LidoTokensBridge, + l2TokenRebasable, + l2CrossDomainMessenger, + l2ERC20ExtendedTokensBridge + } = ctx; + + const { + accountA: tokenHolderA, + accountB: tokenHolderB, + l1CrossDomainMessengerAliased, + } = ctx.accounts; + + const { depositAmountOfRebasableToken, tokenRate } = ctx.constants; + + // wrap on L1 + const depositAmountNonRebasable = nonRebasableFromRebasableL1( + depositAmountOfRebasableToken, + ctx.constants.totalPooledEther, + ctx.constants.totalShares + ); + // wrap on L2: loosing 1-2 wei for big numbers + const depositAmountRebasable = rebasableFromNonRebasableL2( + depositAmountNonRebasable, + ctx.constants.tokenRateDecimals, + ctx.constants.tokenRate + ); + + const refSlotTime = await refSlotTimestamp(accountingOracle); + const dataToReceive = await tokenRateAndTimestampPacked(tokenRate, refSlotTime, "0x"); + + const l2TokenRebasableTotalSupplyBefore = await l2TokenRebasable.totalSupply(); + const tokenHolderBBalanceBefore = await l2TokenRebasable.balanceOf(tokenHolderB.address); + + const tx = await l2CrossDomainMessenger + .connect(l1CrossDomainMessengerAliased) + .relayMessage( + 1, + l1LidoTokensBridge.address, + l2ERC20ExtendedTokensBridge.address, + 0, + 300_000, + l2ERC20ExtendedTokensBridge.interface.encodeFunctionData("finalizeDeposit", [ + l1TokenRebasable.address, + l2TokenRebasable.address, + tokenHolderA.address, + tokenHolderB.address, + depositAmountNonRebasable, + dataToReceive, + ]), + { gasLimit: 5_000_000 } + ); + + await assert.emits(l2ERC20ExtendedTokensBridge, tx, "DepositFinalized", [ + l1TokenRebasable.address, + l2TokenRebasable.address, + tokenHolderA.address, + tokenHolderB.address, + depositAmountRebasable, + "0x", + ]); + + assert.equalBN( + await l2TokenRebasable.balanceOf(tokenHolderB.address), + tokenHolderBBalanceBefore.add(depositAmountRebasable) + ); + + assert.equalBN( + await l2TokenRebasable.totalSupply(), + l2TokenRebasableTotalSupplyBefore.add(depositAmountRebasable) + ); + }) + + .step("L2 -> L1 withdrawal via withdrawTo()", async (ctx) => { + const { l1TokenRebasable, l2TokenRebasable, l2ERC20ExtendedTokensBridge } = ctx; + const { accountA: tokenHolderA, accountB: tokenHolderB } = ctx.accounts; + + const { withdrawalAmountOfRebasableToken } = ctx.constants; + + const tokenHolderBBalanceBefore = await l2TokenRebasable.balanceOf(tokenHolderB.address); + const l2TotalSupplyBefore = await l2TokenRebasable.totalSupply(); + + const tx = await l2ERC20ExtendedTokensBridge + .connect(tokenHolderB.l2Signer) + .withdrawTo( + l2TokenRebasable.address, + tokenHolderA.address, + withdrawalAmountOfRebasableToken, + 0, + "0x" + ); + + await assert.emits(l2ERC20ExtendedTokensBridge, tx, "WithdrawalInitiated", [ + l1TokenRebasable.address, + l2TokenRebasable.address, + tokenHolderB.address, + tokenHolderA.address, + withdrawalAmountOfRebasableToken, + "0x", + ]); + + const tokenHolderABalanceAfter = await l2TokenRebasable.balanceOf(tokenHolderB.address); + const l2TotalSupplyAfter = await l2TokenRebasable.totalSupply() + + assert.isTrue(almostEqual(tokenHolderABalanceAfter, tokenHolderBBalanceBefore.sub(withdrawalAmountOfRebasableToken))); + assert.isTrue(almostEqual(l2TotalSupplyAfter, l2TotalSupplyBefore.sub(withdrawalAmountOfRebasableToken))); + }) + + .step("Finalize withdrawal on L1", async (ctx) => { + const { + l1Token, + l1TokenRebasable, + l1CrossDomainMessenger, + l1LidoTokensBridge, + l2CrossDomainMessenger, + l2TokenRebasable, + l2ERC20ExtendedTokensBridge, + } = ctx; + const { + accountA: tokenHolderA, + accountB: tokenHolderB, + l1Stranger, + } = ctx.accounts; + + const { depositAmountOfRebasableToken, withdrawalAmountOfRebasableToken, tokenRate } = ctx.constants; + + // unwrap on L2 + const withdrawalAmountNonRebasable = nonRebasableFromRebasableL2( + withdrawalAmountOfRebasableToken, + ctx.constants.tokenRateDecimals, + tokenRate); + + // unwrap on L1: loosing 1-2 wei + const withdrawalAmountRebasable = rebasableFromNonRebasableL1( + withdrawalAmountNonRebasable, + ctx.constants.totalPooledEther, + ctx.constants.totalShares + ); + + const tokenHolderABalanceBefore = await l1TokenRebasable.balanceOf(tokenHolderA.address); + const l1LidoTokensBridgeBalanceBefore = await l1Token.balanceOf(l1LidoTokensBridge.address); + + await l1CrossDomainMessenger + .connect(l1Stranger) + .setXDomainMessageSender(l2ERC20ExtendedTokensBridge.address); + + const tx = await l1CrossDomainMessenger + .connect(l1Stranger) + .relayMessage( + l1LidoTokensBridge.address, + l2CrossDomainMessenger.address, + l1LidoTokensBridge.interface.encodeFunctionData( + "finalizeERC20Withdrawal", + [ + l1TokenRebasable.address, + l2TokenRebasable.address, + tokenHolderB.address, + tokenHolderA.address, + withdrawalAmountNonRebasable, + "0x", + ] + ), + 0 + ); + + await assert.emits(l1LidoTokensBridge, tx, "ERC20WithdrawalFinalized", [ + l1TokenRebasable.address, + l2TokenRebasable.address, + tokenHolderB.address, + tokenHolderA.address, + withdrawalAmountRebasable, + "0x", + ]); + + const l1LidoTokensBridgeBalanceAfter = await l1Token.balanceOf(l1LidoTokensBridge.address); + const tokenHolderABalanceAfter = await l1TokenRebasable.balanceOf(tokenHolderA.address); + const tokenHolderBBalanceAfter = await l2TokenRebasable.balanceOf(tokenHolderB.address); + + assert.equalBN( + l1LidoTokensBridgeBalanceAfter, + l1LidoTokensBridgeBalanceBefore.sub(withdrawalAmountNonRebasable) + ); + + assert.equalBN( + tokenHolderABalanceAfter, + tokenHolderABalanceBefore.add(withdrawalAmountRebasable) + ); + + /// check that user balance is correct after depositing and withdrawal. + const deltaDepositWithdrawal = depositAmountOfRebasableToken.sub(withdrawalAmountOfRebasableToken); + assert.isTrue(almostEqual( + ctx.balances.accountABalanceBeforeDeposit, + tokenHolderABalanceAfter.add(deltaDepositWithdrawal)) + ); + assert.isTrue(almostEqual( + ctx.balances.accountBBalanceBeforeDeposit, + tokenHolderBBalanceAfter.sub(deltaDepositWithdrawal)) + ); + }) + + .run(); +} + +function ctxFactory( + totalPooledEther: BigNumber, + totalShares: BigNumber, + tokenRateDecimals: BigNumber, + depositAmountOfRebasableToken: BigNumber, + withdrawalAmountOfRebasableToken: BigNumber +) { + return async () => { + const networkName = env.network("TESTING_OPT_NETWORK", "mainnet"); + + const { + l1Provider, + l2Provider, + l1ERC20ExtendedTokensBridgeAdmin, + l2ERC20ExtendedTokensBridgeAdmin, + ...contracts + } = await optimism.testing(networkName).getIntegrationTestSetup(totalPooledEther, totalShares); + + const l1Snapshot = await l1Provider.send("evm_snapshot", []); + const l2Snapshot = await l2Provider.send("evm_snapshot", []); + + const exchangeRate = await contracts.l1Token.getStETHByWstETH(BigNumber.from(10).pow(tokenRateDecimals)); + + await optimism.testing(networkName).stubL1CrossChainMessengerContract(); + + const accountA = testing.accounts.accountA(l1Provider, l2Provider); + const accountB = testing.accounts.accountB(l1Provider, l2Provider); + + await testing.setBalance( + await contracts.l1TokensHolder.getAddress(), + wei.toBigNumber(wei`1 ether`), + l1Provider + ); + + await testing.setBalance( + await l1ERC20ExtendedTokensBridgeAdmin.getAddress(), + wei.toBigNumber(wei`1 ether`), + l1Provider + ); + + await testing.setBalance( + await l2ERC20ExtendedTokensBridgeAdmin.getAddress(), + wei.toBigNumber(wei`1 ether`), + l2Provider + ); + + const l1CrossDomainMessengerAliased = await testing.impersonate( + testing.accounts.applyL1ToL2Alias(contracts.l1CrossDomainMessenger.address), + l2Provider + ); + + await testing.setBalance( + await l1CrossDomainMessengerAliased.getAddress(), + wei.toBigNumber(wei`1 ether`), + l2Provider + ); + + await contracts.l1TokenRebasable + .connect(contracts.l1TokensHolder) + .transfer(accountA.l1Signer.address, depositAmountOfRebasableToken.mul(2)); + + var accountABalanceBeforeDeposit = BigNumber.from(0); + var accountBBalanceBeforeDeposit = BigNumber.from(0); + + return { + l1Provider, + l2Provider, + ...contracts, + accounts: { + accountA, + accountB, + l1Stranger: testing.accounts.stranger(l1Provider), + l1ERC20ExtendedTokensBridgeAdmin, + l2ERC20ExtendedTokensBridgeAdmin, + l1CrossDomainMessengerAliased, + }, + constants: { + depositAmountOfRebasableToken, + withdrawalAmountOfRebasableToken, + tokenRate: exchangeRate, + totalPooledEther, + totalShares, + tokenRateDecimals, + }, + balances: { + accountABalanceBeforeDeposit, + accountBBalanceBeforeDeposit + }, + snapshot: { + l1: l1Snapshot, + l2: l2Snapshot, + }, + }; + } +} + +function almostEqual(num1: BigNumber, num2: BigNumber) { + const delta = (num1.sub(num2)).abs(); + return delta.lte(BigNumber.from('2')); +} + +bridgingTestsSuit( + scenario( + "Optimism :: Bridging X rebasable token integration test ", + ctxFactory( + BigNumber.from('9309904612343950493629678'), + BigNumber.from('7975822843597609202337218'), + BigNumber.from(27), + wei.toBigNumber(wei`0.001 ether`), + wei.toBigNumber(wei`0.001 ether`) + ) + ) +); + +bridgingTestsSuit( + scenario( + "Optimism :: Bridging 1 wei rebasable token integration test", + ctxFactory( + BigNumber.from('9309904612343950493629678'), + BigNumber.from('7975822843597609202337218'), + BigNumber.from(27), + wei.toBigNumber(wei`1 wei`), + wei.toBigNumber(wei`1 wei`) + ) + ) +); + +bridgingTestsSuit( + scenario( + "Optimism :: Bridging Zero rebasable token integration test", + ctxFactory( + BigNumber.from('9309904612343950493629678'), + BigNumber.from('7975822843597609202337218'), + BigNumber.from(27), + BigNumber.from('0'), + BigNumber.from('0') + ) + ) +); + +bridgingTestsSuit( + scenario( + "Optimism :: Bridging Big rebasable token integration test", + ctxFactory( + BigNumber.from('9309904612343950493629678'), + BigNumber.from('7975822843597609202337218'), + BigNumber.from(27), + BigNumber.from(10).pow(27), + BigNumber.from(10).pow(27).sub(2) // correct big number because during rounding looses 1-2 wei + /// Thus, user can't withdraw the same amount + ) + ) +); + diff --git a/test/optimism/bridging-to.e2e.test.ts b/test/optimism/bridging-to.e2e.test.ts index a7a0dbc6..13d9833f 100644 --- a/test/optimism/bridging-to.e2e.test.ts +++ b/test/optimism/bridging-to.e2e.test.ts @@ -38,7 +38,7 @@ scenario("Optimism :: Bridging via depositTo/withdrawTo E2E test", ctxFactory) } ) - .step("Set allowance for L1ERC20TokenBridge to deposit", async (ctx) => { + .step("Set allowance for L1LidoTokensBridge to deposit", async (ctx) => { const allowanceTxResponse = await ctx.crossChainMessenger.approveERC20( ctx.l1Token.address, ctx.l2Token.address, @@ -50,14 +50,14 @@ scenario("Optimism :: Bridging via depositTo/withdrawTo E2E test", ctxFactory) assert.equalBN( await ctx.l1Token.allowance( ctx.l1Tester.address, - ctx.l1ERC20TokenBridge.address + ctx.l1LidoTokensBridge.address ), ctx.depositAmount ); }) .step("Bridge tokens to L2 via depositERC20To()", async (ctx) => { - depositTokensTxResponse = await ctx.l1ERC20TokenBridge + depositTokensTxResponse = await ctx.l1LidoTokensBridge .connect(ctx.l1Tester) .depositERC20To( ctx.l1Token.address, @@ -79,7 +79,7 @@ scenario("Optimism :: Bridging via depositTo/withdrawTo E2E test", ctxFactory) }) .step("Withdraw tokens from L2 via withdrawERC20To()", async (ctx) => { - withdrawTokensTxResponse = await ctx.l2ERC20TokenBridge + withdrawTokensTxResponse = await ctx.l2ERC20ExtendedTokensBridge .connect(ctx.l2Tester) .withdrawTo( ctx.l2Token.address, @@ -145,8 +145,8 @@ async function ctxFactory() { l2Tester: testingSetup.l2Tester, l1Token: testingSetup.l1Token, l2Token: testingSetup.l2Token, - l1ERC20TokenBridge: testingSetup.l1ERC20TokenBridge, - l2ERC20TokenBridge: testingSetup.l2ERC20TokenBridge, + l1LidoTokensBridge: testingSetup.l1LidoTokensBridge, + l2ERC20ExtendedTokensBridge: testingSetup.l2ERC20ExtendedTokensBridge, crossChainMessenger: new CrossChainMessenger({ l2ChainId: network.chainId("opt", networkName), l1ChainId: network.chainId("eth", networkName), @@ -155,8 +155,8 @@ async function ctxFactory() { bridges: { LidoBridge: { Adapter: DAIBridgeAdapter, - l1Bridge: testingSetup.l1ERC20TokenBridge.address, - l2Bridge: testingSetup.l2ERC20TokenBridge.address, + l1Bridge: testingSetup.l1LidoTokensBridge.address, + l2Bridge: testingSetup.l2ERC20ExtendedTokensBridge.address, }, }, }), diff --git a/test/optimism/bridging.e2e.test.ts b/test/optimism/bridging.e2e.test.ts index d578e860..c045267e 100644 --- a/test/optimism/bridging.e2e.test.ts +++ b/test/optimism/bridging.e2e.test.ts @@ -1,6 +1,5 @@ import { CrossChainMessenger, - DAIBridgeAdapter, MessageStatus, } from "@eth-optimism/sdk"; import { assert } from "chai"; @@ -13,6 +12,7 @@ import optimism from "../../utils/optimism"; import { ERC20Mintable } from "../../typechain"; import { scenario } from "../../utils/testing"; import { sleep } from "../../utils/testing/e2e"; +import { LidoBridgeAdapter } from "../../utils/optimism/LidoBridgeAdapter"; let depositTokensTxResponse: TransactionResponse; let withdrawTokensTxResponse: TransactionResponse; @@ -38,7 +38,7 @@ scenario("Optimism :: Bridging via deposit/withdraw E2E test", ctxFactory) } ) - .step("Set allowance for L1ERC20TokenBridge to deposit", async (ctx) => { + .step("Set allowance for L1LidoTokensBridge to deposit", async (ctx) => { const allowanceTxResponse = await ctx.crossChainMessenger.approveERC20( ctx.l1Token.address, ctx.l2Token.address, @@ -50,7 +50,7 @@ scenario("Optimism :: Bridging via deposit/withdraw E2E test", ctxFactory) assert.equalBN( await ctx.l1Token.allowance( ctx.l1Tester.address, - ctx.l1ERC20TokenBridge.address + ctx.l1LidoTokensBridge.address ), ctx.depositAmount ); @@ -134,7 +134,7 @@ async function ctxFactory() { l1Tester: testingSetup.l1Tester, l1Token: testingSetup.l1Token, l2Token: testingSetup.l2Token, - l1ERC20TokenBridge: testingSetup.l1ERC20TokenBridge, + l1LidoTokensBridge: testingSetup.l1LidoTokensBridge, crossChainMessenger: new CrossChainMessenger({ l2ChainId: network.chainId("opt", networkName), l1ChainId: network.chainId("eth", networkName), @@ -142,9 +142,9 @@ async function ctxFactory() { l2SignerOrProvider: testingSetup.l2Tester, bridges: { LidoBridge: { - Adapter: DAIBridgeAdapter, - l1Bridge: testingSetup.l1ERC20TokenBridge.address, - l2Bridge: testingSetup.l2ERC20TokenBridge.address, + Adapter: LidoBridgeAdapter, + l1Bridge: testingSetup.l1LidoTokensBridge.address, + l2Bridge: testingSetup.l2ERC20ExtendedTokensBridge.address, }, }, }), diff --git a/test/optimism/bridging.integration.test.ts b/test/optimism/bridging.integration.test.ts deleted file mode 100644 index 23eb66f6..00000000 --- a/test/optimism/bridging.integration.test.ts +++ /dev/null @@ -1,613 +0,0 @@ -import { assert } from "chai"; - -import env from "../../utils/env"; -import { wei } from "../../utils/wei"; -import optimism from "../../utils/optimism"; -import testing, { scenario } from "../../utils/testing"; - -scenario("Optimism :: Bridging integration test", ctxFactory) - .after(async (ctx) => { - await ctx.l1Provider.send("evm_revert", [ctx.snapshot.l1]); - await ctx.l2Provider.send("evm_revert", [ctx.snapshot.l2]); - }) - - .step("Activate bridging on L1", async (ctx) => { - const { l1ERC20TokenBridge } = ctx; - const { l1ERC20TokenBridgeAdmin } = ctx.accounts; - - const isDepositsEnabled = await l1ERC20TokenBridge.isDepositsEnabled(); - - if (!isDepositsEnabled) { - await l1ERC20TokenBridge - .connect(l1ERC20TokenBridgeAdmin) - .enableDeposits(); - } else { - console.log("L1 deposits already enabled"); - } - - const isWithdrawalsEnabled = - await l1ERC20TokenBridge.isWithdrawalsEnabled(); - - if (!isWithdrawalsEnabled) { - await l1ERC20TokenBridge - .connect(l1ERC20TokenBridgeAdmin) - .enableWithdrawals(); - } else { - console.log("L1 withdrawals already enabled"); - } - - assert.isTrue(await l1ERC20TokenBridge.isDepositsEnabled()); - assert.isTrue(await l1ERC20TokenBridge.isWithdrawalsEnabled()); - }) - - .step("Activate bridging on L2", async (ctx) => { - const { l2ERC20TokenBridge } = ctx; - const { l2ERC20TokenBridgeAdmin } = ctx.accounts; - - const isDepositsEnabled = await l2ERC20TokenBridge.isDepositsEnabled(); - - if (!isDepositsEnabled) { - await l2ERC20TokenBridge - .connect(l2ERC20TokenBridgeAdmin) - .enableDeposits(); - } else { - console.log("L2 deposits already enabled"); - } - - const isWithdrawalsEnabled = - await l2ERC20TokenBridge.isWithdrawalsEnabled(); - - if (!isWithdrawalsEnabled) { - await l2ERC20TokenBridge - .connect(l2ERC20TokenBridgeAdmin) - .enableWithdrawals(); - } else { - console.log("L2 withdrawals already enabled"); - } - - assert.isTrue(await l2ERC20TokenBridge.isDepositsEnabled()); - assert.isTrue(await l2ERC20TokenBridge.isWithdrawalsEnabled()); - }) - - .step("L1 -> L2 deposit via depositERC20() method", async (ctx) => { - const { - l1Token, - l1ERC20TokenBridge, - l2Token, - l1CrossDomainMessenger, - l2ERC20TokenBridge, - } = ctx; - const { accountA: tokenHolderA } = ctx.accounts; - const { depositAmount } = ctx.common; - - await l1Token - .connect(tokenHolderA.l1Signer) - .approve(l1ERC20TokenBridge.address, depositAmount); - - const tokenHolderABalanceBefore = await l1Token.balanceOf( - tokenHolderA.address - ); - const l1ERC20TokenBridgeBalanceBefore = await l1Token.balanceOf( - l1ERC20TokenBridge.address - ); - - const tx = await l1ERC20TokenBridge - .connect(tokenHolderA.l1Signer) - .depositERC20( - l1Token.address, - l2Token.address, - depositAmount, - 200_000, - "0x" - ); - - await assert.emits(l1ERC20TokenBridge, tx, "ERC20DepositInitiated", [ - l1Token.address, - l2Token.address, - tokenHolderA.address, - tokenHolderA.address, - depositAmount, - "0x", - ]); - - const l2DepositCalldata = l2ERC20TokenBridge.interface.encodeFunctionData( - "finalizeDeposit", - [ - l1Token.address, - l2Token.address, - tokenHolderA.address, - tokenHolderA.address, - depositAmount, - "0x", - ] - ); - - const messageNonce = await l1CrossDomainMessenger.messageNonce(); - - await assert.emits(l1CrossDomainMessenger, tx, "SentMessage", [ - l2ERC20TokenBridge.address, - l1ERC20TokenBridge.address, - l2DepositCalldata, - messageNonce, - 200_000, - ]); - - assert.equalBN( - await l1Token.balanceOf(l1ERC20TokenBridge.address), - l1ERC20TokenBridgeBalanceBefore.add(depositAmount) - ); - - assert.equalBN( - await l1Token.balanceOf(tokenHolderA.address), - tokenHolderABalanceBefore.sub(depositAmount) - ); - }) - - .step("Finalize deposit on L2", async (ctx) => { - const { - l1Token, - l2Token, - l1ERC20TokenBridge, - l2CrossDomainMessenger, - l2ERC20TokenBridge, - } = ctx; - const { depositAmount } = ctx.common; - const { accountA: tokenHolderA, l1CrossDomainMessengerAliased } = - ctx.accounts; - - const tokenHolderABalanceBefore = await l2Token.balanceOf( - tokenHolderA.address - ); - const l2TokenTotalSupplyBefore = await l2Token.totalSupply(); - - const tx = await l2CrossDomainMessenger - .connect(l1CrossDomainMessengerAliased) - .relayMessage( - 1, - l1ERC20TokenBridge.address, - l2ERC20TokenBridge.address, - 0, - 300_000, - l2ERC20TokenBridge.interface.encodeFunctionData("finalizeDeposit", [ - l1Token.address, - l2Token.address, - tokenHolderA.address, - tokenHolderA.address, - depositAmount, - "0x", - ]), - { gasLimit: 5_000_000 } - ); - - await assert.emits(l2ERC20TokenBridge, tx, "DepositFinalized", [ - l1Token.address, - l2Token.address, - tokenHolderA.address, - tokenHolderA.address, - depositAmount, - "0x", - ]); - assert.equalBN( - await l2Token.balanceOf(tokenHolderA.address), - tokenHolderABalanceBefore.add(depositAmount) - ); - assert.equalBN( - await l2Token.totalSupply(), - l2TokenTotalSupplyBefore.add(depositAmount) - ); - }) - - .step("L2 -> L1 withdrawal via withdraw()", async (ctx) => { - const { accountA: tokenHolderA } = ctx.accounts; - const { withdrawalAmount } = ctx.common; - const { l1Token, l2Token, l2ERC20TokenBridge } = ctx; - - const tokenHolderABalanceBefore = await l2Token.balanceOf( - tokenHolderA.address - ); - const l2TotalSupplyBefore = await l2Token.totalSupply(); - - const tx = await l2ERC20TokenBridge - .connect(tokenHolderA.l2Signer) - .withdraw(l2Token.address, withdrawalAmount, 0, "0x"); - - await assert.emits(l2ERC20TokenBridge, tx, "WithdrawalInitiated", [ - l1Token.address, - l2Token.address, - tokenHolderA.address, - tokenHolderA.address, - withdrawalAmount, - "0x", - ]); - assert.equalBN( - await l2Token.balanceOf(tokenHolderA.address), - tokenHolderABalanceBefore.sub(withdrawalAmount) - ); - assert.equalBN( - await l2Token.totalSupply(), - l2TotalSupplyBefore.sub(withdrawalAmount) - ); - }) - - .step("Finalize withdrawal on L1", async (ctx) => { - const { - l1Token, - l1CrossDomainMessenger, - l1ERC20TokenBridge, - l2CrossDomainMessenger, - l2Token, - l2ERC20TokenBridge, - } = ctx; - const { accountA: tokenHolderA, l1Stranger } = ctx.accounts; - const { withdrawalAmount } = ctx.common; - - const tokenHolderABalanceBefore = await l1Token.balanceOf( - tokenHolderA.address - ); - const l1ERC20TokenBridgeBalanceBefore = await l1Token.balanceOf( - l1ERC20TokenBridge.address - ); - - await l1CrossDomainMessenger - .connect(l1Stranger) - .setXDomainMessageSender(l2ERC20TokenBridge.address); - - const tx = await l1CrossDomainMessenger - .connect(l1Stranger) - .relayMessage( - l1ERC20TokenBridge.address, - l2CrossDomainMessenger.address, - l1ERC20TokenBridge.interface.encodeFunctionData( - "finalizeERC20Withdrawal", - [ - l1Token.address, - l2Token.address, - tokenHolderA.address, - tokenHolderA.address, - withdrawalAmount, - "0x", - ] - ), - 0 - ); - - await assert.emits(l1ERC20TokenBridge, tx, "ERC20WithdrawalFinalized", [ - l1Token.address, - l2Token.address, - tokenHolderA.address, - tokenHolderA.address, - withdrawalAmount, - "0x", - ]); - - assert.equalBN( - await l1Token.balanceOf(l1ERC20TokenBridge.address), - l1ERC20TokenBridgeBalanceBefore.sub(withdrawalAmount) - ); - - assert.equalBN( - await l1Token.balanceOf(tokenHolderA.address), - tokenHolderABalanceBefore.add(withdrawalAmount) - ); - }) - - .step("L1 -> L2 deposit via depositERC20To()", async (ctx) => { - const { - l1Token, - l2Token, - l1ERC20TokenBridge, - l2ERC20TokenBridge, - l1CrossDomainMessenger, - } = ctx; - const { accountA: tokenHolderA, accountB: tokenHolderB } = ctx.accounts; - const { depositAmount } = ctx.common; - - assert.notEqual(tokenHolderA.address, tokenHolderB.address); - - await l1Token - .connect(tokenHolderA.l1Signer) - .approve(l1ERC20TokenBridge.address, depositAmount); - - const tokenHolderABalanceBefore = await l1Token.balanceOf( - tokenHolderA.address - ); - const l1ERC20TokenBridgeBalanceBefore = await l1Token.balanceOf( - l1ERC20TokenBridge.address - ); - - const tx = await l1ERC20TokenBridge - .connect(tokenHolderA.l1Signer) - .depositERC20To( - l1Token.address, - l2Token.address, - tokenHolderB.address, - depositAmount, - 200_000, - "0x" - ); - - await assert.emits(l1ERC20TokenBridge, tx, "ERC20DepositInitiated", [ - l1Token.address, - l2Token.address, - tokenHolderA.address, - tokenHolderB.address, - depositAmount, - "0x", - ]); - - const l2DepositCalldata = l2ERC20TokenBridge.interface.encodeFunctionData( - "finalizeDeposit", - [ - l1Token.address, - l2Token.address, - tokenHolderA.address, - tokenHolderB.address, - depositAmount, - "0x", - ] - ); - - const messageNonce = await l1CrossDomainMessenger.messageNonce(); - - await assert.emits(l1CrossDomainMessenger, tx, "SentMessage", [ - l2ERC20TokenBridge.address, - l1ERC20TokenBridge.address, - l2DepositCalldata, - messageNonce, - 200_000, - ]); - - assert.equalBN( - await l1Token.balanceOf(l1ERC20TokenBridge.address), - l1ERC20TokenBridgeBalanceBefore.add(depositAmount) - ); - - assert.equalBN( - await l1Token.balanceOf(tokenHolderA.address), - tokenHolderABalanceBefore.sub(depositAmount) - ); - }) - - .step("Finalize deposit on L2", async (ctx) => { - const { - l1Token, - l1ERC20TokenBridge, - l2Token, - l2CrossDomainMessenger, - l2ERC20TokenBridge, - } = ctx; - const { - accountA: tokenHolderA, - accountB: tokenHolderB, - l1CrossDomainMessengerAliased, - } = ctx.accounts; - const { depositAmount } = ctx.common; - - const l2TokenTotalSupplyBefore = await l2Token.totalSupply(); - const tokenHolderBBalanceBefore = await l2Token.balanceOf( - tokenHolderB.address - ); - - const tx = await l2CrossDomainMessenger - .connect(l1CrossDomainMessengerAliased) - .relayMessage( - 1, - l1ERC20TokenBridge.address, - l2ERC20TokenBridge.address, - 0, - 300_000, - l2ERC20TokenBridge.interface.encodeFunctionData("finalizeDeposit", [ - l1Token.address, - l2Token.address, - tokenHolderA.address, - tokenHolderB.address, - depositAmount, - "0x", - ]), - { gasLimit: 5_000_000 } - ); - - await assert.emits(l2ERC20TokenBridge, tx, "DepositFinalized", [ - l1Token.address, - l2Token.address, - tokenHolderA.address, - tokenHolderB.address, - depositAmount, - "0x", - ]); - - assert.equalBN( - await l2Token.totalSupply(), - l2TokenTotalSupplyBefore.add(depositAmount) - ); - assert.equalBN( - await l2Token.balanceOf(tokenHolderB.address), - tokenHolderBBalanceBefore.add(depositAmount) - ); - }) - - .step("L2 -> L1 withdrawal via withdrawTo()", async (ctx) => { - const { l1Token, l2Token, l2ERC20TokenBridge } = ctx; - const { accountA: tokenHolderA, accountB: tokenHolderB } = ctx.accounts; - const { withdrawalAmount } = ctx.common; - - const tokenHolderBBalanceBefore = await l2Token.balanceOf( - tokenHolderB.address - ); - const l2TotalSupplyBefore = await l2Token.totalSupply(); - - const tx = await l2ERC20TokenBridge - .connect(tokenHolderB.l2Signer) - .withdrawTo( - l2Token.address, - tokenHolderA.address, - withdrawalAmount, - 0, - "0x" - ); - - await assert.emits(l2ERC20TokenBridge, tx, "WithdrawalInitiated", [ - l1Token.address, - l2Token.address, - tokenHolderB.address, - tokenHolderA.address, - withdrawalAmount, - "0x", - ]); - - assert.equalBN( - await l2Token.balanceOf(tokenHolderB.address), - tokenHolderBBalanceBefore.sub(withdrawalAmount) - ); - - assert.equalBN( - await l2Token.totalSupply(), - l2TotalSupplyBefore.sub(withdrawalAmount) - ); - }) - - .step("Finalize withdrawal on L1", async (ctx) => { - const { - l1Token, - l1CrossDomainMessenger, - l1ERC20TokenBridge, - l2CrossDomainMessenger, - l2Token, - l2ERC20TokenBridge, - } = ctx; - const { - accountA: tokenHolderA, - accountB: tokenHolderB, - l1Stranger, - } = ctx.accounts; - const { withdrawalAmount } = ctx.common; - - const tokenHolderABalanceBefore = await l1Token.balanceOf( - tokenHolderA.address - ); - const l1ERC20TokenBridgeBalanceBefore = await l1Token.balanceOf( - l1ERC20TokenBridge.address - ); - - await l1CrossDomainMessenger - .connect(l1Stranger) - .setXDomainMessageSender(l2ERC20TokenBridge.address); - - const tx = await l1CrossDomainMessenger - .connect(l1Stranger) - .relayMessage( - l1ERC20TokenBridge.address, - l2CrossDomainMessenger.address, - l1ERC20TokenBridge.interface.encodeFunctionData( - "finalizeERC20Withdrawal", - [ - l1Token.address, - l2Token.address, - tokenHolderB.address, - tokenHolderA.address, - withdrawalAmount, - "0x", - ] - ), - 0 - ); - - await assert.emits(l1ERC20TokenBridge, tx, "ERC20WithdrawalFinalized", [ - l1Token.address, - l2Token.address, - tokenHolderB.address, - tokenHolderA.address, - withdrawalAmount, - "0x", - ]); - - assert.equalBN( - await l1Token.balanceOf(l1ERC20TokenBridge.address), - l1ERC20TokenBridgeBalanceBefore.sub(withdrawalAmount) - ); - - assert.equalBN( - await l1Token.balanceOf(tokenHolderA.address), - tokenHolderABalanceBefore.add(withdrawalAmount) - ); - }) - - .run(); - -async function ctxFactory() { - const networkName = env.network("TESTING_OPT_NETWORK", "mainnet"); - - const { - l1Provider, - l2Provider, - l1ERC20TokenBridgeAdmin, - l2ERC20TokenBridgeAdmin, - ...contracts - } = await optimism.testing(networkName).getIntegrationTestSetup(); - - const l1Snapshot = await l1Provider.send("evm_snapshot", []); - const l2Snapshot = await l2Provider.send("evm_snapshot", []); - - await optimism.testing(networkName).stubL1CrossChainMessengerContract(); - - const accountA = testing.accounts.accountA(l1Provider, l2Provider); - const accountB = testing.accounts.accountB(l1Provider, l2Provider); - - const depositAmount = wei`0.15 ether`; - const withdrawalAmount = wei`0.05 ether`; - - await testing.setBalance( - await contracts.l1TokensHolder.getAddress(), - wei.toBigNumber(wei`1 ether`), - l1Provider - ); - - await testing.setBalance( - await l1ERC20TokenBridgeAdmin.getAddress(), - wei.toBigNumber(wei`1 ether`), - l1Provider - ); - - await testing.setBalance( - await l2ERC20TokenBridgeAdmin.getAddress(), - wei.toBigNumber(wei`1 ether`), - l2Provider - ); - - await contracts.l1Token - .connect(contracts.l1TokensHolder) - .transfer(accountA.l1Signer.address, wei.toBigNumber(depositAmount).mul(2)); - - const l1CrossDomainMessengerAliased = await testing.impersonate( - testing.accounts.applyL1ToL2Alias(contracts.l1CrossDomainMessenger.address), - l2Provider - ); - - await testing.setBalance( - await l1CrossDomainMessengerAliased.getAddress(), - wei.toBigNumber(wei`1 ether`), - l2Provider - ); - - return { - l1Provider, - l2Provider, - ...contracts, - accounts: { - accountA, - accountB, - l1Stranger: testing.accounts.stranger(l1Provider), - l1ERC20TokenBridgeAdmin, - l2ERC20TokenBridgeAdmin, - l1CrossDomainMessengerAliased, - }, - common: { - depositAmount, - withdrawalAmount, - }, - snapshot: { - l1: l1Snapshot, - l2: l2Snapshot, - }, - }; -} diff --git a/test/optimism/deployment.acceptance.test.ts b/test/optimism/deployment.acceptance.test.ts index be49d3c5..ec30d93f 100644 --- a/test/optimism/deployment.acceptance.test.ts +++ b/test/optimism/deployment.acceptance.test.ts @@ -13,55 +13,55 @@ import { wei } from "../../utils/wei"; scenario("Optimism Bridge :: deployment acceptance test", ctxFactory) .step("L1 Bridge :: proxy admin", async (ctx) => { assert.equal( - await ctx.l1ERC20TokenBridgeProxy.proxy__getAdmin(), + await ctx.l1LidoTokensBridgeProxy.proxy__getAdmin(), ctx.deployment.l1.proxyAdmin ); }) .step("L1 Bridge :: bridge admin", async (ctx) => { const currentAdmins = await getRoleHolders( - ctx.l1ERC20TokenBridge, + ctx.l1LidoTokensBridge, BridgingManagerRole.DEFAULT_ADMIN_ROLE.hash ); assert.equal(currentAdmins.size, 1); assert.isTrue(currentAdmins.has(ctx.deployment.l1.bridgeAdmin)); await assert.isTrue( - await ctx.l1ERC20TokenBridge.hasRole( + await ctx.l1LidoTokensBridge.hasRole( BridgingManagerRole.DEFAULT_ADMIN_ROLE.hash, ctx.deployment.l1.bridgeAdmin ) ); }) .step("L1 bridge :: L1 token", async (ctx) => { - assert.equal(await ctx.l1ERC20TokenBridge.l1Token(), ctx.deployment.token); + assert.equal(await ctx.l1LidoTokensBridge.L1_TOKEN_NON_REBASABLE(), ctx.deployment.token); }) .step("L1 bridge :: L2 token", async (ctx) => { assert.equal( - await ctx.l1ERC20TokenBridge.l2Token(), + await ctx.l1LidoTokensBridge.L2_TOKEN_NON_REBASABLE(), ctx.erc20Bridged.address ); }) .step("L1 bridge :: L2 token bridge", async (ctx) => { assert.equal( - await ctx.l1ERC20TokenBridge.l2TokenBridge(), - ctx.l2ERC20TokenBridge.address + await ctx.l1LidoTokensBridge.l2TokenBridge(), + ctx.l2ERC20ExtendedTokensBridge.address ); }) .step("L1 Bridge :: is deposits enabled", async (ctx) => { assert.equal( - await ctx.l1ERC20TokenBridge.isDepositsEnabled(), + await ctx.l1LidoTokensBridge.isDepositsEnabled(), ctx.deployment.l1.depositsEnabled ); }) .step("L1 Bridge :: is withdrawals enabled", async (ctx) => { assert.equal( - await ctx.l1ERC20TokenBridge.isWithdrawalsEnabled(), + await ctx.l1LidoTokensBridge.isWithdrawalsEnabled(), ctx.deployment.l1.withdrawalsEnabled ); }) .step("L1 Bridge :: deposits enablers", async (ctx) => { const actualDepositsEnablers = await getRoleHolders( - ctx.l1ERC20TokenBridge, + ctx.l1LidoTokensBridge, BridgingManagerRole.DEPOSITS_ENABLER_ROLE.hash ); const expectedDepositsEnablers = ctx.deployment.l1.depositsEnablers || []; @@ -73,7 +73,7 @@ scenario("Optimism Bridge :: deployment acceptance test", ctxFactory) }) .step("L1 Bridge :: deposits disablers", async (ctx) => { const actualDepositsDisablers = await getRoleHolders( - ctx.l1ERC20TokenBridge, + ctx.l1LidoTokensBridge, BridgingManagerRole.DEPOSITS_DISABLER_ROLE.hash ); const expectedDepositsDisablers = ctx.deployment.l1.depositsDisablers || []; @@ -87,7 +87,7 @@ scenario("Optimism Bridge :: deployment acceptance test", ctxFactory) }) .step("L1 Bridge :: withdrawals enablers", async (ctx) => { const actualWithdrawalsEnablers = await getRoleHolders( - ctx.l1ERC20TokenBridge, + ctx.l1LidoTokensBridge, BridgingManagerRole.WITHDRAWALS_ENABLER_ROLE.hash ); const expectedWithdrawalsEnablers = @@ -103,7 +103,7 @@ scenario("Optimism Bridge :: deployment acceptance test", ctxFactory) }) .step("L1 Bridge :: withdrawals disablers", async (ctx) => { const actualWithdrawalsDisablers = await getRoleHolders( - ctx.l1ERC20TokenBridge, + ctx.l1LidoTokensBridge, BridgingManagerRole.WITHDRAWALS_DISABLER_ROLE.hash ); const expectedWithdrawalsDisablers = @@ -122,55 +122,55 @@ scenario("Optimism Bridge :: deployment acceptance test", ctxFactory) .step("L2 Bridge :: proxy admin", async (ctx) => { assert.equal( - await ctx.l2ERC20TokenBridgeProxy.proxy__getAdmin(), + await ctx.l2ERC20ExtendedTokensBridgeProxy.proxy__getAdmin(), ctx.deployment.l2.proxyAdmin ); }) .step("L2 Bridge :: bridge admin", async (ctx) => { const currentAdmins = await getRoleHolders( - ctx.l2ERC20TokenBridge, + ctx.l2ERC20ExtendedTokensBridge, BridgingManagerRole.DEFAULT_ADMIN_ROLE.hash ); assert.equal(currentAdmins.size, 1); assert.isTrue(currentAdmins.has(ctx.deployment.l2.bridgeAdmin)); await assert.isTrue( - await ctx.l2ERC20TokenBridge.hasRole( + await ctx.l2ERC20ExtendedTokensBridge.hasRole( BridgingManagerRole.DEFAULT_ADMIN_ROLE.hash, ctx.deployment.l2.bridgeAdmin ) ); }) .step("L2 bridge :: L1 token", async (ctx) => { - assert.equal(await ctx.l2ERC20TokenBridge.l1Token(), ctx.deployment.token); + assert.equal(await ctx.l2ERC20ExtendedTokensBridge.L1_TOKEN_NON_REBASABLE(), ctx.deployment.token); }) .step("L2 bridge :: L2 token", async (ctx) => { assert.equal( - await ctx.l2ERC20TokenBridge.l2Token(), + await ctx.l2ERC20ExtendedTokensBridge.L2_TOKEN_NON_REBASABLE(), ctx.erc20Bridged.address ); }) .step("L2 bridge :: L1 token bridge", async (ctx) => { assert.equal( - await ctx.l2ERC20TokenBridge.l1TokenBridge(), - ctx.l1ERC20TokenBridge.address + await ctx.l2ERC20ExtendedTokensBridge.l1TokenBridge(), + ctx.l1LidoTokensBridge.address ); }) .step("L2 Bridge :: is deposits enabled", async (ctx) => { assert.equal( - await ctx.l2ERC20TokenBridge.isDepositsEnabled(), + await ctx.l2ERC20ExtendedTokensBridge.isDepositsEnabled(), ctx.deployment.l2.depositsEnabled ); }) .step("L2 Bridge :: is withdrawals enabled", async (ctx) => { assert.equal( - await ctx.l2ERC20TokenBridge.isWithdrawalsEnabled(), + await ctx.l2ERC20ExtendedTokensBridge.isWithdrawalsEnabled(), ctx.deployment.l2.withdrawalsEnabled ); }) .step("L2 Bridge :: deposits enablers", async (ctx) => { const actualDepositsEnablers = await getRoleHolders( - ctx.l2ERC20TokenBridge, + ctx.l2ERC20ExtendedTokensBridge, BridgingManagerRole.DEPOSITS_ENABLER_ROLE.hash ); const expectedDepositsEnablers = ctx.deployment.l2.depositsEnablers || []; @@ -182,7 +182,7 @@ scenario("Optimism Bridge :: deployment acceptance test", ctxFactory) }) .step("L2 Bridge :: deposits disablers", async (ctx) => { const actualDepositsDisablers = await getRoleHolders( - ctx.l2ERC20TokenBridge, + ctx.l2ERC20ExtendedTokensBridge, BridgingManagerRole.DEPOSITS_DISABLER_ROLE.hash ); const expectedDepositsDisablers = ctx.deployment.l2.depositsDisablers || []; @@ -197,7 +197,7 @@ scenario("Optimism Bridge :: deployment acceptance test", ctxFactory) }) .step("L2 Bridge :: withdrawals enablers", async (ctx) => { const actualWithdrawalsEnablers = await getRoleHolders( - ctx.l2ERC20TokenBridge, + ctx.l2ERC20ExtendedTokensBridge, BridgingManagerRole.WITHDRAWALS_ENABLER_ROLE.hash ); const expectedWithdrawalsEnablers = @@ -213,7 +213,7 @@ scenario("Optimism Bridge :: deployment acceptance test", ctxFactory) }) .step("L2 Bridge :: withdrawals disablers", async (ctx) => { const actualWithdrawalsDisablers = await getRoleHolders( - ctx.l2ERC20TokenBridge, + ctx.l2ERC20ExtendedTokensBridge, BridgingManagerRole.WITHDRAWALS_DISABLER_ROLE.hash ); const expectedWithdrawalsDisablers = @@ -251,7 +251,7 @@ scenario("Optimism Bridge :: deployment acceptance test", ctxFactory) .step("L2 token :: bridge", async (ctx) => { assert.equalBN( await ctx.erc20Bridged.bridge(), - ctx.l2ERC20TokenBridge.address + ctx.l2ERC20ExtendedTokensBridge.address ); }) @@ -282,14 +282,14 @@ async function ctxFactory() { symbol, decimals, }, - l1ERC20TokenBridge: testingSetup.l1ERC20TokenBridge, - l1ERC20TokenBridgeProxy: OssifiableProxy__factory.connect( - testingSetup.l1ERC20TokenBridge.address, + l1LidoTokensBridge: testingSetup.l1LidoTokensBridge, + l1LidoTokensBridgeProxy: OssifiableProxy__factory.connect( + testingSetup.l1LidoTokensBridge.address, testingSetup.l1Provider ), - l2ERC20TokenBridge: testingSetup.l2ERC20TokenBridge, - l2ERC20TokenBridgeProxy: OssifiableProxy__factory.connect( - testingSetup.l2ERC20TokenBridge.address, + l2ERC20ExtendedTokensBridge: testingSetup.l2ERC20ExtendedTokensBridge, + l2ERC20ExtendedTokensBridgeProxy: OssifiableProxy__factory.connect( + testingSetup.l2ERC20ExtendedTokensBridge.address, testingSetup.l2Provider ), erc20Bridged: testingSetup.l2Token, diff --git a/test/optimism/deposit-gas-estimation.test.ts b/test/optimism/deposit-gas-estimation.test.ts new file mode 100644 index 00000000..8994aa95 --- /dev/null +++ b/test/optimism/deposit-gas-estimation.test.ts @@ -0,0 +1,219 @@ +import { assert } from "chai"; + +import env from "../../utils/env"; +import { wei } from "../../utils/wei"; +import optimism from "../../utils/optimism"; +import testing, { scenario } from "../../utils/testing"; +import { BigNumber } from 'ethers' + +scenario("Optimism :: Bridging integration test", ctxFactory) + .after(async (ctx) => { + await ctx.l1Provider.send("evm_revert", [ctx.snapshot.l1]); + await ctx.l2Provider.send("evm_revert", [ctx.snapshot.l2]); + }) + + .step("Activate bridging on L1", async (ctx) => { + const { l1LidoTokensBridge } = ctx; + const { l1ERC20ExtendedTokensBridgeAdmin } = ctx.accounts; + + const isDepositsEnabled = await l1LidoTokensBridge.isDepositsEnabled(); + + if (!isDepositsEnabled) { + await l1LidoTokensBridge + .connect(l1ERC20ExtendedTokensBridgeAdmin) + .enableDeposits(); + } else { + console.log("L1 deposits already enabled"); + } + + const isWithdrawalsEnabled = + await l1LidoTokensBridge.isWithdrawalsEnabled(); + + if (!isWithdrawalsEnabled) { + await l1LidoTokensBridge + .connect(l1ERC20ExtendedTokensBridgeAdmin) + .enableWithdrawals(); + } else { + console.log("L1 withdrawals already enabled"); + } + + assert.isTrue(await l1LidoTokensBridge.isDepositsEnabled()); + assert.isTrue(await l1LidoTokensBridge.isWithdrawalsEnabled()); + }) + + .step("Activate bridging on L2", async (ctx) => { + const { l2ERC20ExtendedTokensBridge } = ctx; + const { l2ERC20ExtendedTokensBridgeAdmin } = ctx.accounts; + + const isDepositsEnabled = await l2ERC20ExtendedTokensBridge.isDepositsEnabled(); + + if (!isDepositsEnabled) { + await l2ERC20ExtendedTokensBridge + .connect(l2ERC20ExtendedTokensBridgeAdmin) + .enableDeposits(); + } else { + console.log("L2 deposits already enabled"); + } + + const isWithdrawalsEnabled = + await l2ERC20ExtendedTokensBridge.isWithdrawalsEnabled(); + + if (!isWithdrawalsEnabled) { + await l2ERC20ExtendedTokensBridge + .connect(l2ERC20ExtendedTokensBridgeAdmin) + .enableWithdrawals(); + } else { + console.log("L2 withdrawals already enabled"); + } + + assert.isTrue(await l2ERC20ExtendedTokensBridge.isDepositsEnabled()); + assert.isTrue(await l2ERC20ExtendedTokensBridge.isWithdrawalsEnabled()); + }) + + .step("L1 -> L2 deposit zero tokens via depositERC20() method", async (ctx) => { + const { + l1Token, + l2Token, + l1TokenRebasable, + l1LidoTokensBridge, + l2TokenRebasable + } = ctx; + + const { accountA: tokenHolderA } = ctx.accounts; + const stEthPerToken = await l1Token.getStETHByWstETH(BigNumber.from(10).pow(27)); + + await l1TokenRebasable + .connect(tokenHolderA.l1Signer) + .approve(l1LidoTokensBridge.address, 10); + + await l1Token + .connect(tokenHolderA.l1Signer) + .approve(l1LidoTokensBridge.address, 10); + + const tokenHolderABalanceBefore = await l1Token.balanceOf( + tokenHolderA.address + ); + console.log("tokenHolderABalanceBefore=", tokenHolderABalanceBefore); + + const l1ERC20ExtendedTokensBridgeBalanceBefore = await l1TokenRebasable.balanceOf( + l1LidoTokensBridge.address + ); + + const tx0 = await l1LidoTokensBridge + .connect(tokenHolderA.l1Signer) + .depositERC20( + l1Token.address, + l2Token.address, + 10, + 200_000, + "0x" + ); + + const receipt0 = await tx0.wait(); + console.log("l1Token gasUsed=", receipt0.gasUsed); + + const tx1 = await l1LidoTokensBridge + .connect(tokenHolderA.l1Signer) + .depositERC20( + l1TokenRebasable.address, + l2TokenRebasable.address, + 10, + 200_000, + "0x" + ); + + const receipt1 = await tx1.wait(); + console.log("l1TokenRebasable gasUsed=", receipt1.gasUsed); + + const gasDifference = receipt1.gasUsed.sub(receipt0.gasUsed); + console.log("gasUsed difference=", gasDifference); + }) + + + + .run(); + +async function ctxFactory() { + const networkName = env.network("TESTING_OPT_NETWORK", "mainnet"); + console.log("networkName=", networkName); + const exchangeRate = BigNumber.from('1164454276599657236000000000'); + + const { + l1Provider, + l2Provider, + l1ERC20ExtendedTokensBridgeAdmin, + l2ERC20ExtendedTokensBridgeAdmin, + ...contracts + } = await optimism.testing(networkName).getIntegrationTestSetup(exchangeRate); + + const l1Snapshot = await l1Provider.send("evm_snapshot", []); + const l2Snapshot = await l2Provider.send("evm_snapshot", []); + + const accountA = testing.accounts.accountA(l1Provider, l2Provider); + const accountB = testing.accounts.accountB(l1Provider, l2Provider); + + const depositAmount = wei`0.15 ether`; + const withdrawalAmount = wei`0.05 ether`; + + await testing.setBalance( + await contracts.l1TokensHolder.getAddress(), + wei.toBigNumber(wei`1 ether`), + l1Provider + ); + + await testing.setBalance( + await l1ERC20ExtendedTokensBridgeAdmin.getAddress(), + wei.toBigNumber(wei`1 ether`), + l1Provider + ); + + await testing.setBalance( + await l2ERC20ExtendedTokensBridgeAdmin.getAddress(), + wei.toBigNumber(wei`1 ether`), + l2Provider + ); + + await contracts.l1Token + .connect(contracts.l1TokensHolder) + .transfer(accountA.l1Signer.address, depositAmount); + + await contracts.l1TokenRebasable + .connect(contracts.l1TokensHolder) + .transfer(accountA.l1Signer.address, wei.toBigNumber(depositAmount).mul(2)); + + const l1CrossDomainMessengerAliased = await testing.impersonate( + testing.accounts.applyL1ToL2Alias(contracts.l1CrossDomainMessenger.address), + l2Provider + ); + + console.log("l1CrossDomainMessengerAliased=", l1CrossDomainMessengerAliased); + console.log("contracts.l1CrossDomainMessenger.address=", contracts.l1CrossDomainMessenger.address); + + await testing.setBalance( + await l1CrossDomainMessengerAliased.getAddress(), + wei.toBigNumber(wei`1 ether`), + l2Provider + ); + + return { + l1Provider, + l2Provider, + ...contracts, + accounts: { + accountA, + accountB, + l1Stranger: testing.accounts.stranger(l1Provider), + l1ERC20ExtendedTokensBridgeAdmin, + l2ERC20ExtendedTokensBridgeAdmin, + l1CrossDomainMessengerAliased, + }, + common: { + depositAmount, + withdrawalAmount, + }, + snapshot: { + l1: l1Snapshot, + l2: l2Snapshot, + }, + }; +} diff --git a/test/optimism/managing-deposits.e2e.test.ts b/test/optimism/managing-deposits.e2e.test.ts index 1566d551..36712d50 100644 --- a/test/optimism/managing-deposits.e2e.test.ts +++ b/test/optimism/managing-deposits.e2e.test.ts @@ -2,7 +2,7 @@ import { assert } from "chai"; import { TransactionResponse } from "@ethersproject/providers"; import { - L2ERC20TokenBridge__factory, + L2ERC20ExtendedTokensBridge__factory, GovBridgeExecutor__factory, } from "../../typechain"; import { @@ -33,27 +33,27 @@ const scenarioTest = scenario( assert.gte(await l1LDOHolder.getBalance(), gasAmount); }) - .step("Checking deposits status", async ({ l2ERC20TokenBridge }) => { - l2DepositsInitialState = await l2ERC20TokenBridge.isDepositsEnabled(); + .step("Checking deposits status", async ({ l2ERC20ExtendedTokensBridge }) => { + l2DepositsInitialState = await l2ERC20ExtendedTokensBridge.isDepositsEnabled(); }) .step(`Starting DAO vote`, async (ctx) => { const grantRoleCalldata = - ctx.l2ERC20TokenBridge.interface.encodeFunctionData("grantRole", [ + ctx.l2ERC20ExtendedTokensBridge.interface.encodeFunctionData("grantRole", [ l2DepositsInitialState ? DEPOSIT_DISABLER_ROLE : DEPOSIT_ENABLER_ROLE, ctx.govBridgeExecutor.address, ]); const grantRoleData = "0x" + grantRoleCalldata.substring(10); const actionCalldata = l2DepositsInitialState - ? ctx.l2ERC20TokenBridge.interface.encodeFunctionData("disableDeposits") - : ctx.l2ERC20TokenBridge.interface.encodeFunctionData("enableDeposits"); + ? ctx.l2ERC20ExtendedTokensBridge.interface.encodeFunctionData("disableDeposits") + : ctx.l2ERC20ExtendedTokensBridge.interface.encodeFunctionData("enableDeposits"); const actionData = "0x" + actionCalldata.substring(10); const executorCalldata = await ctx.govBridgeExecutor.interface.encodeFunctionData("queue", [ - [ctx.l2ERC20TokenBridge.address, ctx.l2ERC20TokenBridge.address], + [ctx.l2ERC20ExtendedTokensBridge.address, ctx.l2ERC20ExtendedTokensBridge.address], [0, 0], [ "grantRole(bytes32,address)", @@ -124,9 +124,9 @@ const scenarioTest = scenario( await tx.wait(); }) - .step("Checking deposits state", async ({ l2ERC20TokenBridge }) => { + .step("Checking deposits state", async ({ l2ERC20ExtendedTokensBridge }) => { assert.equal( - await l2ERC20TokenBridge.isDepositsEnabled(), + await l2ERC20ExtendedTokensBridge.isDepositsEnabled(), !l2DepositsInitialState ); }); @@ -158,8 +158,8 @@ async function ctxFactory() { l1Tester, l2Tester, l1LDOHolder, - l2ERC20TokenBridge: L2ERC20TokenBridge__factory.connect( - E2E_TEST_CONTRACTS.l2.l2ERC20TokenBridge, + l2ERC20ExtendedTokensBridge: L2ERC20ExtendedTokensBridge__factory.connect( + E2E_TEST_CONTRACTS.l2.l2ERC20ExtendedTokensBridge, l2Tester ), govBridgeExecutor: GovBridgeExecutor__factory.connect( diff --git a/test/optimism/managing-executor.e2e.test.ts b/test/optimism/managing-executor.e2e.test.ts index 340a050e..f48112e9 100644 --- a/test/optimism/managing-executor.e2e.test.ts +++ b/test/optimism/managing-executor.e2e.test.ts @@ -2,7 +2,7 @@ import { assert } from "chai"; import { TransactionResponse } from "@ethersproject/providers"; import { - L2ERC20TokenBridge__factory, + L2ERC20ExtendedTokensBridge__factory, GovBridgeExecutor__factory, } from "../../typechain"; import { @@ -134,8 +134,8 @@ async function ctxFactory() { gasAmount: wei`0.1 ether`, l2Tester, l1LDOHolder, - l2ERC20TokenBridge: L2ERC20TokenBridge__factory.connect( - E2E_TEST_CONTRACTS.l2.l2ERC20TokenBridge, + l2ERC20ExtendedTokensBridge: L2ERC20ExtendedTokensBridge__factory.connect( + E2E_TEST_CONTRACTS.l2.l2ERC20ExtendedTokensBridge, l2Tester ), govBridgeExecutor: GovBridgeExecutor__factory.connect( diff --git a/test/optimism/managing-proxy.e2e.test.ts b/test/optimism/managing-proxy.e2e.test.ts index 632de88c..8c5ddcc2 100644 --- a/test/optimism/managing-proxy.e2e.test.ts +++ b/test/optimism/managing-proxy.e2e.test.ts @@ -2,10 +2,10 @@ import { assert } from "chai"; import { TransactionResponse } from "@ethersproject/providers"; import { - ERC20Bridged__factory, + ERC20BridgedPermit__factory, GovBridgeExecutor__factory, OssifiableProxy__factory, - L2ERC20TokenBridge__factory, + L2ERC20ExtendedTokensBridge__factory, } from "../../typechain"; import { E2E_TEST_CONTRACTS_OPTIMISM as E2E_TEST_CONTRACTS } from "../../utils/testing/e2e"; import env from "../../utils/env"; @@ -32,7 +32,7 @@ scenario( .step("Proxy upgrade: send crosschain message", async (ctx) => { const implBefore = await await ctx.proxyToOssify.proxy__getImplementation(); - assert.equal(implBefore, ctx.l2ERC20TokenBridge.address); + assert.equal(implBefore, ctx.l2ERC20ExtendedTokensBridge.address); const executorCalldata = await ctx.govBridgeExecutor.interface.encodeFunctionData("queue", [ [ctx.proxyToOssify.address], @@ -40,9 +40,9 @@ scenario( ["proxy__upgradeTo(address)"], [ "0x" + - ctx.proxyToOssify.interface - .encodeFunctionData("proxy__upgradeTo", [ctx.l2Token.address]) - .substring(10), + ctx.proxyToOssify.interface + .encodeFunctionData("proxy__upgradeTo", [ctx.l2Token.address]) + .substring(10), ], [false], ]); @@ -200,12 +200,12 @@ async function ctxFactory() { l1Tester, l2Tester, l1LDOHolder, - l2Token: ERC20Bridged__factory.connect( + l2Token: ERC20BridgedPermit__factory.connect( E2E_TEST_CONTRACTS.l2.l2Token, l2Tester ), - l2ERC20TokenBridge: L2ERC20TokenBridge__factory.connect( - E2E_TEST_CONTRACTS.l2.l2ERC20TokenBridge, + l2ERC20ExtendedTokensBridge: L2ERC20ExtendedTokensBridge__factory.connect( + E2E_TEST_CONTRACTS.l2.l2ERC20ExtendedTokensBridge, l2Tester ), govBridgeExecutor: GovBridgeExecutor__factory.connect( @@ -213,7 +213,7 @@ async function ctxFactory() { l2Tester ), proxyToOssify: await new OssifiableProxy__factory(l2Tester).deploy( - E2E_TEST_CONTRACTS.l2.l2ERC20TokenBridge, + E2E_TEST_CONTRACTS.l2.l2ERC20ExtendedTokensBridge, E2E_TEST_CONTRACTS.l2.govBridgeExecutor, "0x" ), diff --git a/test/optimism/pushingTokenRate.e2e.test.ts b/test/optimism/pushingTokenRate.e2e.test.ts new file mode 100644 index 00000000..9fa24bcc --- /dev/null +++ b/test/optimism/pushingTokenRate.e2e.test.ts @@ -0,0 +1,96 @@ +import { assert } from "chai"; +import env from "../../utils/env"; +import network, { SignerOrProvider } from "../../utils/network"; +import testingUtils, { scenario } from "../../utils/testing"; +import { + ERC20WrapperStub__factory, + TokenRateNotifier__factory, + TokenRateOracle__factory +} from "../../typechain"; + +scenario("Optimism :: Push token rate to Oracle E2E test", ctxFactory) + + .step("Push Token Rate", async (ctx) => { + await ctx.tokenRateNotifier + .connect(ctx.l1Tester) + .handlePostTokenRebase(1, 2, 3, 4, 5, 6, 7); + }) + + .step("Receive token rate", async (ctx) => { + const tokenRate = await ctx.l1Token.getStETHByWstETH(BigNumber.from(10).pow(27)); + + const answer = await ctx.tokenRateOracle.latestAnswer(); + assert.equalBN(answer, tokenRate); + + const [ + , + latestRoundDataAnswer, + , + , + ] = await ctx.tokenRateOracle.latestRoundData(); + assert.equalBN(latestRoundDataAnswer, tokenRate); + }) + + .run(); + +async function ctxFactory() { + const testingSetup = await getE2ETestSetup(); + + return { + l1Tester: testingSetup.l1Tester, + l2Tester: testingSetup.l2Tester, + l1Provider: testingSetup.l1Provider, + l2Provider: testingSetup.l2Provider, + l1Token: testingSetup.l1Token, + tokenRateNotifier: testingSetup.tokenRateNotifier, + tokenRateOracle: testingSetup.tokenRateOracle + }; +} + +async function getE2ETestSetup() { + const testerPrivateKey = testingUtils.env.TESTING_PRIVATE_KEY(); + const networkName = env.network("TESTING_OPT_NETWORK", "sepolia"); + + const ethOptNetworks = network.multichain(["eth", "opt"], networkName); + + const [ethProvider, optProvider] = ethOptNetworks.getProviders({ + forking: false, + }); + const [l1Tester, l2Tester] = ethOptNetworks.getSigners(testerPrivateKey, { + forking: false, + }); + + const contracts = await loadDeployedContracts(l1Tester, l2Tester); + + // await printLoadedTestConfig(networkName, bridgeContracts, l1Tester); + + return { + l1Tester, + l2Tester, + l1Provider: ethProvider, + l2Provider: optProvider, + ...contracts, + }; +} + +async function loadDeployedContracts( + l1SignerOrProvider: SignerOrProvider, + l2SignerOrProvider: SignerOrProvider +) { + return { + l1Token: ERC20WrapperStub__factory.connect( + testingUtils.env.OPT_L1_NON_REBASABLE_TOKEN(), + l1SignerOrProvider + ), + tokenRateNotifier: TokenRateNotifier__factory.connect( + testingUtils.env.OPT_L1_TOKEN_RATE_NOTIFIER(), + l1SignerOrProvider + ), + tokenRateOracle: TokenRateOracle__factory.connect( + testingUtils.env.OPT_L2_TOKEN_RATE_ORACLE(), + l2SignerOrProvider + ), + l1SignerOrProvider, + l2SignerOrProvider + }; +} diff --git a/test/optimism/pushingTokenRate.integration.test.ts b/test/optimism/pushingTokenRate.integration.test.ts new file mode 100644 index 00000000..cf6fc902 --- /dev/null +++ b/test/optimism/pushingTokenRate.integration.test.ts @@ -0,0 +1,259 @@ +import hre from "hardhat"; +import { assert } from "chai"; +import env from "../../utils/env"; +import { wei } from "../../utils/wei"; +import optimism from "../../utils/optimism"; +import network from "../../utils/network"; +import testing, { scenario } from "../../utils/testing"; +import deploymentOracle from "../../utils/optimism/deploymentOracle"; +import { getBridgeExecutorParams } from "../../utils/bridge-executor"; +import { getExchangeRate } from "../../utils/testing/helpers"; +import { BigNumber } from "ethers"; +import { getBlockTimestamp } from "../../utils/testing/helpers"; +import { + ERC20BridgedStub__factory, + ERC20WrapperStub__factory, + OptimismBridgeExecutor__factory, + TokenRateNotifier__factory, + TokenRateOracle__factory, + AccountingOracleStub__factory, + EmptyContractStub__factory +} from "../../typechain"; + +scenario("Optimism :: Token Rate Oracle integration test", ctxFactory) + + .step("Push Token Rate", async (ctx) => { + const { + tokenRateNotifier, + tokenRateOracle, + opTokenRatePusher, + l1CrossDomainMessenger, + genesisTime, + secondsPerSlot, + lastProcessingRefSlot, + tokenRate, + l1AuthorizedRebaseCaller + } = ctx; + + const tx = await tokenRateNotifier + .connect(l1AuthorizedRebaseCaller) + .handlePostTokenRebase(1, 2, 3, 4, 5, 6, 7); + + const messageNonce = await l1CrossDomainMessenger.messageNonce(); + + const updateRateTime = genesisTime.add(secondsPerSlot.mul(lastProcessingRefSlot)); + + const l2Calldata = tokenRateOracle.interface.encodeFunctionData( + "updateRate", + [ + tokenRate, + updateRateTime + ] + ); + + await assert.emits(l1CrossDomainMessenger, tx, "SentMessage", [ + tokenRateOracle.address, + opTokenRatePusher, + l2Calldata, + messageNonce, + 1000, + ]); + }) + + .step("Finalize pushing rate", async (ctx) => { + const { + opTokenRatePusher, + tokenRateOracle, + l1CrossDomainMessenger, + genesisTime, secondsPerSlot, lastProcessingRefSlot, tokenRate + } = ctx; + + const account = ctx.accounts.accountA; + await l1CrossDomainMessenger + .connect(account.l1Signer) + .setXDomainMessageSender(opTokenRatePusher); + + const updateRateTime = genesisTime.add(secondsPerSlot.mul(lastProcessingRefSlot)); + + await ctx.l2CrossDomainMessenger + .connect(ctx.accounts.l1CrossDomainMessengerAliased) + .relayMessage( + 1, + opTokenRatePusher, + tokenRateOracle.address, + 0, + 300_000, + tokenRateOracle.interface.encodeFunctionData("updateRate", [ + tokenRate, + updateRateTime + ]), + { gasLimit: 5_000_000 } + ); + + const answer = await tokenRateOracle.latestAnswer(); + assert.equalBN(answer, tokenRate); + + const [ + , + tokenRateAnswer, + startedAt_, + , + ] = await tokenRateOracle.latestRoundData(); + + assert.equalBN(tokenRateAnswer, tokenRate); + assert.equalBN(startedAt_, updateRateTime); + }) + + .run(); + +async function ctxFactory() { + const l2GasLimitForPushingTokenRate = 1000; + const tokenRateOutdatedDelay = 86400; + const maxAllowedL2ToL1ClockLag = BigNumber.from(86400); + const maxAllowedTokenRateDeviationPerDay = BigNumber.from(500); + const oldestRateAllowedInPauseTimeSpan = BigNumber.from(86400*3); + const maxAllowedTimeBetweenTokenRateUpdates = BigNumber.from(3600); + const totalPooledEther = BigNumber.from('9309904612343950493629678'); + const totalShares = BigNumber.from('7975822843597609202337218'); + const tokenRateDecimals = BigNumber.from(27); + const tokenRate = getExchangeRate(tokenRateDecimals, totalPooledEther, totalShares); + + const networkName = env.network("TESTING_OPT_NETWORK", "mainnet"); + const [l1Provider, l2Provider] = network + .multichain(["eth", "opt"], networkName) + .getProviders({ forking: true }); + const l1Deployer = testing.accounts.deployer(l1Provider); + const l2Deployer = testing.accounts.deployer(l2Provider); + + const blockTimestamp = await getBlockTimestamp(l1Provider, 0); + const blockTimestampInPast = await getBlockTimestamp(l1Provider, -86400); + + const genesisTime = blockTimestamp; + const secondsPerSlot = BigNumber.from(10); + const lastProcessingRefSlot = BigNumber.from(20); + + const optContracts = optimism.contracts(networkName, { forking: true }); + const l2CrossDomainMessenger = optContracts.L2CrossDomainMessenger; + const testingOnDeployedContracts = testing.env.USE_DEPLOYED_CONTRACTS(false); + const optAddresses = optimism.addresses(networkName); + + const govBridgeExecutor = testingOnDeployedContracts + ? OptimismBridgeExecutor__factory.connect( + testing.env.OPT_GOV_BRIDGE_EXECUTOR(), + l2Provider + ) + : await new OptimismBridgeExecutor__factory(l2Deployer).deploy( + optAddresses.L2CrossDomainMessenger, + l1Deployer.address, + ...getBridgeExecutorParams(), + l2Deployer.address + ); + + const l1TokenRebasable = await new ERC20BridgedStub__factory(l1Deployer).deploy( + "Test Token Rebasable", + "TTR" + ); + const l1Token = await new ERC20WrapperStub__factory(l1Deployer).deploy( + l1TokenRebasable.address, + "Test Token", + "TT", + totalPooledEther, + totalShares + ); + + const accountingOracle = await new AccountingOracleStub__factory(l1Deployer).deploy( + genesisTime, + secondsPerSlot, + lastProcessingRefSlot + ); + + const [l2ERC20TokenBridge] = await hre.ethers.getSigners(); + + const l1AuthorizedRebaseCaller = await new EmptyContractStub__factory(l1Deployer).deploy({ value: 10000000 }); + const l1AuthorizedRebaseCallerAsEOA = await testing.impersonate(l1AuthorizedRebaseCaller.address); + await testing.setBalance(l1AuthorizedRebaseCaller.address, wei.toBigNumber(wei`1 ether`)); + + const [ethDeployScript, optDeployScript] = await deploymentOracle( + networkName + ).oracleDeployScript( + l1Token.address, + l2ERC20TokenBridge.address, + accountingOracle.address, + l2GasLimitForPushingTokenRate, + tokenRateOutdatedDelay, + { + l1AuthorizedRebaseCaller: l1AuthorizedRebaseCaller.address, + deployer: l1Deployer, + admins: { + proxy: l1Deployer.address, + bridge: l1Deployer.address + }, + contractsShift: 0 + }, + { + deployer: l2Deployer, + admins: { + proxy: govBridgeExecutor.address, + bridge: govBridgeExecutor.address, + }, + contractsShift: 0, + tokenRateOracle: { + maxAllowedL2ToL1ClockLag: maxAllowedL2ToL1ClockLag, + maxAllowedTokenRateDeviationPerDayBp: maxAllowedTokenRateDeviationPerDay, + oldestRateAllowedInPauseTimeSpan: oldestRateAllowedInPauseTimeSpan, + maxAllowedTimeBetweenTokenRateUpdates: maxAllowedTimeBetweenTokenRateUpdates, + tokenRate: tokenRate, + l1Timestamp: BigNumber.from(blockTimestampInPast) + } + } + ); + + await ethDeployScript.run(); + await optDeployScript.run(); + + await optimism.testing(networkName).stubL1CrossChainMessengerContract(); + + const l1CrossDomainMessengerAliased = await testing.impersonate( + testing.accounts.applyL1ToL2Alias(optContracts.L1CrossDomainMessengerStub.address), + l2Provider + ); + await testing.setBalance( + await l1CrossDomainMessengerAliased.getAddress(), + wei.toBigNumber(wei`1 ether`), + l2Provider + ); + + const tokenRateNotifier = TokenRateNotifier__factory.connect( + ethDeployScript.tokenRateNotifierImplAddress, + l1Provider + ); + await tokenRateNotifier + .connect(l1Deployer) + .addObserver(ethDeployScript.opStackTokenRatePusherImplAddress); + const tokenRateOracle = TokenRateOracle__factory.connect( + optDeployScript.tokenRateOracleProxyAddress, + l2Provider + ); + + const accountA = testing.accounts.accountA(l1Provider, l2Provider); + const l1CrossDomainMessenger = optContracts.L1CrossDomainMessengerStub; + + return { + tokenRateNotifier, + tokenRateOracle, + opTokenRatePusher: ethDeployScript.opStackTokenRatePusherImplAddress, + l1CrossDomainMessenger, + l2CrossDomainMessenger, + l1Token, + accountingOracle, + l1Provider, + blockTimestamp, + tokenRate, + genesisTime, secondsPerSlot, lastProcessingRefSlot, + l1AuthorizedRebaseCaller: l1AuthorizedRebaseCallerAsEOA, + accounts: { + accountA, + l1CrossDomainMessengerAliased + } + }; +} diff --git a/test/token/ERC20Bridged.unit.test.ts b/test/token/ERC20BridgedPermit.unit.test.ts similarity index 62% rename from test/token/ERC20Bridged.unit.test.ts rename to test/token/ERC20BridgedPermit.unit.test.ts index 2ec65bfa..2062600a 100644 --- a/test/token/ERC20Bridged.unit.test.ts +++ b/test/token/ERC20BridgedPermit.unit.test.ts @@ -1,53 +1,265 @@ import { assert } from "chai"; import hre from "hardhat"; +import { BigNumber } from "ethers"; +import { unit } from "../../utils/testing"; +import { wei } from "../../utils/wei"; +import { erc20BridgedPermitUnderProxy } from "../../utils/testing/contractsFactory"; import { - ERC20Bridged__factory, + ERC20BridgedPermit__factory, + ERC20BridgedWithInitializerStub__factory, OssifiableProxy__factory, } from "../../typechain"; -import { unit } from "../../utils/testing"; -import { wei } from "../../utils/wei"; -unit("ERC20Bridged", ctxFactory) - .test("bridge()", async (ctx) => { - assert.equal(await ctx.erc20Bridged.bridge(), ctx.accounts.owner.address); +unit("ERC20BridgedPermit", ctxFactory) + + .test("constructor() :: zero params", async (ctx) => { + const { deployer, stranger, zero } = ctx.accounts; + + await assert.revertsWith(new ERC20BridgedPermit__factory( + deployer + ).deploy( + "name", + "symbol", + "version", + 0, + stranger.address + ), "ErrorZeroDecimals()"); + + await assert.revertsWith(new ERC20BridgedPermit__factory( + deployer + ).deploy( + "name", + "symbol", + "version", + 18, + zero.address + ), "ErrorZeroAddressBridge()"); }) - .test("totalSupply()", async (ctx) => { - assert.equalBN(await ctx.erc20Bridged.totalSupply(), ctx.constants.premint); + .test("initial state", async (ctx) => { + const { erc20Bridged } = ctx; + const { decimals, name, symbol, version, premint } = ctx.constants; + const { owner } = ctx.accounts; + const [, eip712Name, eip712Version, , , ,] = await erc20Bridged.eip712Domain(); + + assert.equal(eip712Name, name); + assert.equal(eip712Version, version); + assert.equal(await erc20Bridged.name(), name); + assert.equal(await erc20Bridged.symbol(), symbol); + assert.equalBN(await erc20Bridged.decimals(), decimals); + assert.equal(await erc20Bridged.bridge(), owner.address); + assert.equalBN(await erc20Bridged.totalSupply(), premint); }) - .test("initialize() :: name already set", async (ctx) => { + .test("initialize() :: petrified", async (ctx) => { const { deployer, owner } = ctx.accounts; // deploy new implementation - const erc20BridgedImpl = await new ERC20Bridged__factory(deployer).deploy( - "Name", - "", + const erc20BridgedImpl = await new ERC20BridgedPermit__factory(deployer).deploy( + "name", + "symbol", + "version", + 9, + owner.address + ); + + const petrifiedVersionMark = hre.ethers.constants.MaxUint256; + assert.equalBN(await erc20BridgedImpl.getContractVersion(), petrifiedVersionMark); + + // an early check of metadata won't allow to see NonZeroContractVersionOnInit() error + await assert.revertsWith( + erc20BridgedImpl.initialize("name", "symbol", "version"), + "ErrorMetadataIsAlreadyInitialized()" + ); + }) + + .test("initialize() :: don't allow to initialize with empty metadata", async (ctx) => { + const { deployer, owner } = ctx.accounts; + const { name, symbol, version } = ctx.constants; + + const l2TokenImpl = await new ERC20BridgedPermit__factory(deployer).deploy( + "wstETH", + "wst", + "1", + 9, + owner.address + ); + + await assert.revertsWith( + new OssifiableProxy__factory(deployer).deploy( + l2TokenImpl.address, + deployer.address, + ERC20BridgedPermit__factory.createInterface().encodeFunctionData("initialize", [ + "", + symbol, + version + ]) + ), + "ErrorNameIsEmpty()" + ); + await assert.revertsWith( + new OssifiableProxy__factory(deployer).deploy( + l2TokenImpl.address, + deployer.address, + ERC20BridgedPermit__factory.createInterface().encodeFunctionData("initialize", [ + name, + "", + version + ]) + ), + "ErrorSymbolIsEmpty()" + ); + }) + + .test("initialize() :: don't allow to initialize twice", async (ctx) => { + const { deployer, owner, holder } = ctx.accounts; + const { name, symbol, version } = ctx.constants; + + // deploy new implementation + const l2TokenImpl = await new ERC20BridgedPermit__factory(deployer).deploy( + "wstETH", + "wst", + "1", 9, owner.address ); + + const l2TokensProxy = await new OssifiableProxy__factory(deployer).deploy( + l2TokenImpl.address, + deployer.address, + ERC20BridgedPermit__factory.createInterface().encodeFunctionData("initialize", [ + name, + symbol, + version + ]) + ); + + const erc20BridgedProxied = ERC20BridgedPermit__factory.connect( + l2TokensProxy.address, + holder + ); + + assert.equalBN(await erc20BridgedProxied.getContractVersion(), 2); + await assert.revertsWith( - erc20BridgedImpl.initialize("New Name", ""), - "ErrorNameAlreadySet()" + erc20BridgedProxied.initialize(name, symbol, version), + "ErrorMetadataIsAlreadyInitialized()" ); }) - .test("initialize() :: symbol already set", async (ctx) => { + .test("finalizeUpgrade_v2() :: metadata uninitialized", async (ctx) => { const { deployer, owner } = ctx.accounts; + const { name, version } = ctx.constants; // deploy new implementation - const erc20BridgedImpl = await new ERC20Bridged__factory(deployer).deploy( - "", + const l2TokenImpl = await new ERC20BridgedPermit__factory(deployer).deploy( + "name", "Symbol", + "1", 9, owner.address ); + + await assert.revertsWith(new OssifiableProxy__factory(deployer).deploy( + l2TokenImpl.address, + deployer.address, + ERC20BridgedPermit__factory.createInterface().encodeFunctionData("finalizeUpgrade_v2", [ + name, + version + ]) + ), "ErrorMetadataIsNotInitialized()"); + }) + + .test("finalizeUpgrade_v2() :: metadata initialized", async (ctx) => { + const { deployer, owner } = ctx.accounts; + const { name, version } = ctx.constants; + + const l2TokenOldImpl = await new ERC20BridgedWithInitializerStub__factory(deployer).deploy( + "name", + "symbol", + 18, + owner.address + ); + + const l2TokenProxy = await new OssifiableProxy__factory(deployer).deploy( + l2TokenOldImpl.address, + deployer.address, + ERC20BridgedWithInitializerStub__factory.createInterface().encodeFunctionData("initializeERC20Metadata", [ + "name", + "symbol" + ]) + ); + + const erc20BridgedProxied = ERC20BridgedPermit__factory.connect( + l2TokenProxy.address, + owner + ); + + const l2TokenImpl = await new ERC20BridgedPermit__factory(deployer).deploy( + "name", + "symbol", + "1", + 18, + owner.address + ); + + await l2TokenProxy.proxy__upgradeToAndCall( + l2TokenImpl.address, + ERC20BridgedPermit__factory.createInterface().encodeFunctionData("finalizeUpgrade_v2", [ + name, + version + ]), + false + ); + + assert.equalBN(await erc20BridgedProxied.getContractVersion(), 2); + + // can't initialize after finalizeUpgrade_v2 await assert.revertsWith( - erc20BridgedImpl.initialize("", "New Symbol"), - "ErrorSymbolAlreadySet()" + erc20BridgedProxied.initialize("name", "symbol", "version"), + "ErrorMetadataIsAlreadyInitialized()" ); }) + .test("initialize() :: ins't allowed to call instead of finalizeUpgrade_v2()", async (ctx) => { + const { deployer, owner } = ctx.accounts; + const { name, symbol, version } = ctx.constants; + + const l2TokenOldImpl = await new ERC20BridgedWithInitializerStub__factory(deployer).deploy( + "name", + "symbol", + 18, + owner.address + ); + + const l2TokenProxy = await new OssifiableProxy__factory(deployer).deploy( + l2TokenOldImpl.address, + deployer.address, + ERC20BridgedWithInitializerStub__factory.createInterface().encodeFunctionData("initializeERC20Metadata", [ + "name", + "symbol" + ]) + ); + + const l2TokenImpl = await new ERC20BridgedPermit__factory(deployer).deploy( + "name", + "symbol", + "1", + 18, + owner.address + ); + + await assert.revertsWith(l2TokenProxy.proxy__upgradeToAndCall( + l2TokenImpl.address, + ERC20BridgedPermit__factory.createInterface().encodeFunctionData("initialize", [ + name, + symbol, + version + ]), + false + ), "ErrorMetadataIsAlreadyInitialized()"); + }) + .test("approve()", async (ctx) => { const { erc20Bridged } = ctx; const { holder, spender } = ctx.accounts; @@ -306,175 +518,6 @@ unit("ERC20Bridged", ctxFactory) ); }) - .test("increaseAllowance() :: initial allowance is zero", async (ctx) => { - const { erc20Bridged } = ctx; - const { holder, spender } = ctx.accounts; - - // validate allowance before increasing - assert.equalBN( - await erc20Bridged.allowance(holder.address, spender.address), - "0" - ); - - const allowanceIncrease = wei`1 ether`; - - // increase allowance - const tx = await erc20Bridged.increaseAllowance( - spender.address, - allowanceIncrease - ); - - // validate Approval event was emitted - await assert.emits(erc20Bridged, tx, "Approval", [ - holder.address, - spender.address, - allowanceIncrease, - ]); - - // validate allowance was updated correctly - assert.equalBN( - await erc20Bridged.allowance(holder.address, spender.address), - allowanceIncrease - ); - }) - - .test("increaseAllowance() :: initial allowance is not zero", async (ctx) => { - const { erc20Bridged } = ctx; - const { holder, spender } = ctx.accounts; - - const initialAllowance = wei`2 ether`; - - // set initial allowance - await erc20Bridged.approve(spender.address, initialAllowance); - - // validate allowance before increasing - assert.equalBN( - await erc20Bridged.allowance(holder.address, spender.address), - initialAllowance - ); - - const allowanceIncrease = wei`1 ether`; - - // increase allowance - const tx = await erc20Bridged.increaseAllowance( - spender.address, - allowanceIncrease - ); - - const expectedAllowance = wei - .toBigNumber(initialAllowance) - .add(allowanceIncrease); - - // validate Approval event was emitted - await assert.emits(erc20Bridged, tx, "Approval", [ - holder.address, - spender.address, - expectedAllowance, - ]); - - // validate allowance was updated correctly - assert.equalBN( - await erc20Bridged.allowance(holder.address, spender.address), - expectedAllowance - ); - }) - - .test("increaseAllowance() :: the increase is not zero", async (ctx) => { - const { erc20Bridged } = ctx; - const { holder, spender } = ctx.accounts; - - const initialAllowance = wei`2 ether`; - - // set initial allowance - await erc20Bridged.approve(spender.address, initialAllowance); - - // validate allowance before increasing - assert.equalBN( - await erc20Bridged.allowance(holder.address, spender.address), - initialAllowance - ); - - // increase allowance - const tx = await erc20Bridged.increaseAllowance(spender.address, "0"); - - // validate Approval event was emitted - await assert.emits(erc20Bridged, tx, "Approval", [ - holder.address, - spender.address, - initialAllowance, - ]); - - // validate allowance was updated correctly - assert.equalBN( - await erc20Bridged.allowance(holder.address, spender.address), - initialAllowance - ); - }) - - .test( - "decreaseAllowance() :: decrease is greater than current allowance", - async (ctx) => { - const { erc20Bridged } = ctx; - const { holder, spender } = ctx.accounts; - - // validate allowance before increasing - assert.equalBN( - await erc20Bridged.allowance(holder.address, spender.address), - "0" - ); - - const allowanceDecrease = wei`1 ether`; - - // decrease allowance - await assert.revertsWith( - erc20Bridged.decreaseAllowance(spender.address, allowanceDecrease), - "ErrorDecreasedAllowanceBelowZero()" - ); - } - ) - - .group([wei`1 ether`, "0"], (allowanceDecrease) => [ - `decreaseAllowance() :: the decrease is ${allowanceDecrease} wei`, - async (ctx) => { - const { erc20Bridged } = ctx; - const { holder, spender } = ctx.accounts; - - const initialAllowance = wei`2 ether`; - - // set initial allowance - await erc20Bridged.approve(spender.address, initialAllowance); - - // validate allowance before increasing - assert.equalBN( - await erc20Bridged.allowance(holder.address, spender.address), - initialAllowance - ); - - // decrease allowance - const tx = await erc20Bridged.decreaseAllowance( - spender.address, - allowanceDecrease - ); - - const expectedAllowance = wei - .toBigNumber(initialAllowance) - .sub(allowanceDecrease); - - // validate Approval event was emitted - await assert.emits(erc20Bridged, tx, "Approval", [ - holder.address, - spender.address, - expectedAllowance, - ]); - - // validate allowance was updated correctly - assert.equalBN( - await erc20Bridged.allowance(holder.address, spender.address), - expectedAllowance - ); - }, - ]) - .test("bridgeMint() :: not owner", async (ctx) => { const { erc20Bridged } = ctx; const { stranger } = ctx.accounts; @@ -595,45 +638,44 @@ unit("ERC20Bridged", ctxFactory) .run(); async function ctxFactory() { + /// --------------------------- + /// constants + /// --------------------------- const name = "ERC20 Test Token"; const symbol = "ERC20"; - const decimals = 18; + const version = "1"; + const decimals = BigNumber.from(18); const premint = wei`100 ether`; - const [deployer, owner, recipient, spender, holder, stranger] = - await hre.ethers.getSigners(); - const l2TokenImpl = await new ERC20Bridged__factory(deployer).deploy( + + const [deployer, owner, recipient, spender, holder, stranger] = await hre.ethers.getSigners(); + const zero = await hre.ethers.getSigner(hre.ethers.constants.AddressZero); + + /// --------------------------- + /// contracts + /// --------------------------- + const erc20BridgedProxied = await erc20BridgedPermitUnderProxy( + deployer, + holder, name, symbol, + version, decimals, owner.address - ); + ) + + /// --------------------------- + /// setup + /// --------------------------- + await erc20BridgedProxied.connect(owner).bridgeMint(holder.address, premint); await hre.network.provider.request({ method: "hardhat_impersonateAccount", params: [hre.ethers.constants.AddressZero], }); - const zero = await hre.ethers.getSigner(hre.ethers.constants.AddressZero); - - const l2TokensProxy = await new OssifiableProxy__factory(deployer).deploy( - l2TokenImpl.address, - deployer.address, - ERC20Bridged__factory.createInterface().encodeFunctionData("initialize", [ - name, - symbol, - ]) - ); - - const erc20BridgedProxied = ERC20Bridged__factory.connect( - l2TokensProxy.address, - holder - ); - - await erc20BridgedProxied.connect(owner).bridgeMint(holder.address, premint); - return { accounts: { deployer, owner, recipient, spender, holder, zero, stranger }, - constants: { name, symbol, decimals, premint }, + constants: { name, symbol, version, decimals, premint }, erc20Bridged: erc20BridgedProxied, }; } diff --git a/test/token/ERC20Permit.unit.test.ts b/test/token/ERC20Permit.unit.test.ts new file mode 100644 index 00000000..9ce167a6 --- /dev/null +++ b/test/token/ERC20Permit.unit.test.ts @@ -0,0 +1,627 @@ +import hre, { ethers } from "hardhat"; +import { assert } from "chai"; +import { BigNumber } from "ethers"; +import { unit, UnitTest } from "../../utils/testing"; +import { wei } from "../../utils/wei"; +import { makeDomainSeparator, signPermit, calculateTransferAuthorizationDigest, signEOAorEIP1271 } from "../../utils/testing/permit-helpers"; +import testing from "../../utils/testing"; +import { SignerWithAddress } from "@nomiclabs/hardhat-ethers/signers"; +import { BaseContract, Overrides } from "@ethersproject/contracts"; + +import { + TokenRateOracle__factory, + OssifiableProxy__factory, + ERC20RebasableBridgedPermit__factory, + ERC1271PermitSignerMock__factory, + ERC20BridgedPermit__factory, + +} from "../../typechain"; + + +type ContextType = Awaited>> + +const SIGNING_DOMAIN_VERSION = '2' // aka token version, used in signing permit +const MAX_UINT256 = '0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff' + +// derived from mnemonic: want believe mosquito cat design route voice cause gold benefit gospel bulk often attitude rural +const ACCOUNTS_AND_KEYS = [ + { + address: '0xF4C028683CAd61ff284d265bC0F77EDd67B4e65A', + privateKey: '0x5f7edf5892efb4a5cd75dedd496598f48e579b562a70eb1360474cc83a982987', + }, + { + address: '0x7F94c1F9e4BfFccc8Cd79195554E0d83a0a5c5f2', + privateKey: '0x3fe2f6bd9dbc7d507a6cb95ec36a36787706617e34385292b66c74cd39874605', + }, +] + +function getChainId() { + return hre.network.config.chainId as number; +} + +const getAccountsEOA = async () => { + return { + alice: ACCOUNTS_AND_KEYS[0], + bob: ACCOUNTS_AND_KEYS[1], + } +} + +const getAccountsEIP1271 = async () => { + const deployer = (await hre.ethers.getSigners())[0] + const alice = await new ERC1271PermitSignerMock__factory(deployer).deploy() + const bob = await new ERC1271PermitSignerMock__factory(deployer).deploy() + return { alice, bob } +} + +function permitTestsSuit(unitInstance: UnitTest) { + unitInstance + .test('eip712Domain() is correct', async (ctx) => { + const token = ctx.contracts.rebasableProxied + const [, name, version, chainId, verifyingContract, ,] = await token.eip712Domain() + + assert.equal(name, ctx.constants.name) + assert.equal(version, SIGNING_DOMAIN_VERSION) + assert.isDefined(hre.network.config.chainId) + assert.equal(chainId.toNumber(), getChainId()) + assert.equal(verifyingContract, token.address) + }) + + .test('DOMAIN_SEPARATOR() is correct', async (ctx) => { + const token = ctx.contracts.rebasableProxied + const domainSeparator = makeDomainSeparator(ctx.constants.name, SIGNING_DOMAIN_VERSION, getChainId(), token.address) + assert.equal(await ctx.contracts.rebasableProxied.DOMAIN_SEPARATOR(), domainSeparator) + }) + + .test('grants allowance when a valid permit is given', async (ctx) => { + const token = ctx.contracts.rebasableProxied + + const { owner, spender, deadline } = ctx.permitParams + let { value } = ctx.permitParams + // create a signed permit to grant Bob permission to spend Alice's funds + // on behalf, and sign with Alice's key + let nonce = 0 + const charlie = ctx.accounts.user2 + + let { v, r, s } = await signPermit(owner.address, owner, spender.address, value, deadline, nonce, ctx.domainSeparator) + + // check that the allowance is initially zero + assert.equalBN(await token.allowance(owner.address, spender.address), BigNumber.from(0)) + // check that the next nonce expected is zero + assert.equalBN(await token.nonces(owner.address), BigNumber.from(0)) + // check domain separator + assert.equal(await token.DOMAIN_SEPARATOR(), ctx.domainSeparator) + + // a third-party, Charlie (not Alice) submits the permit + // TODO: handle unpredictable gas limit somehow better than setting it to a random constant + const tx = await permit( + token, + charlie, + owner.address, + spender.address, + value, + deadline, + v, r, s, + ctx.constants.usePermitMethodWithSignature, + { gasLimit: '0xffffff' } + ); + + // check that allowance is updated + assert.equalBN(await token.allowance(owner.address, spender.address), BigNumber.from(value)) + await assert.emits(token, tx, 'Approval', [owner.address, spender.address, value]) + assert.equalBN(await token.nonces(owner.address), BigNumber.from(1)) + + + // increment nonce + nonce = 1 + value = 4e5 + ; ({ v, r, s } = await signPermit(owner.address, owner, spender.address, value, deadline, nonce, ctx.domainSeparator)) + + // submit the permit + const tx2 = await permit( + token, + charlie, + owner.address, + spender.address, + value, + deadline, + v, r, s, + ctx.constants.usePermitMethodWithSignature + ); + + // check that allowance is updated + assert.equalBN(await token.allowance(owner.address, spender.address), BigNumber.from(value)) + assert.emits(token, tx2, 'Approval', [owner.address, spender.address, BigNumber.from(value)]) + assert.equalBN(await token.nonces(owner.address), BigNumber.from(2)) + }) + + + .test('reverts if the signature does not match given parameters', async (ctx) => { + const { owner, spender, value, nonce, deadline } = ctx.permitParams + const token = ctx.contracts.rebasableProxied + const charlie = ctx.accounts.user2 + + // create a signed permit + const { v, r, s } = await signPermit(owner.address, owner, spender.address, value, deadline, nonce, ctx.domainSeparator) + + // try to cheat by claiming the approved amount + 1 + await assert.revertsWith( + permit(token, + charlie, + owner.address, + spender.address, + value + 1, // pass more than signed value + deadline, + v, + r, + s, + ctx.constants.usePermitMethodWithSignature + ), + 'ErrorInvalidSignature()' + ) + + // check that msg is incorrect even if claim the approved amount - 1 + await assert.revertsWith( + permit( + token, + charlie, + owner.address, + spender.address, + value - 1, // pass less than signed + deadline, + v, + r, + s, + ctx.constants.usePermitMethodWithSignature + ), + 'ErrorInvalidSignature()' + ) + }) + + .test('reverts if the signature is not signed with the right key', async (ctx) => { + const { owner, spender, value, nonce, deadline } = ctx.permitParams + const token = ctx.contracts.rebasableProxied + const spenderSigner = await hre.ethers.getSigner(spender.address) + const charlie = ctx.accounts.user2 + + // create a signed permit to grant Bob permission to spend + // Alice's funds on behalf, but sign with Bob's key instead of Alice's + const { v, r, s } = await signPermit(owner.address, spender, spender.address, value, deadline, nonce, ctx.domainSeparator) + + // try to cheat by submitting the permit that is signed by a + // wrong person + await assert.revertsWith( + permit(token, charlie, owner.address, spender.address, value, deadline, v, r, s, ctx.constants.usePermitMethodWithSignature), + 'ErrorInvalidSignature()' + ) + + await testing.impersonate(spender.address) + await testing.setBalance(spender.address, wei.toBigNumber(wei`10 ether`)) + + // even Bob himself can't call permit with the invalid sig + await assert.revertsWith( + permit(token, spenderSigner, owner.address, spender.address, value, deadline, v, r, s, ctx.constants.usePermitMethodWithSignature), + 'ErrorInvalidSignature()' + ) + }) + + .test('reverts if the permit is expired', async (ctx) => { + const token = ctx.contracts.rebasableProxied + const { owner, spender, value, nonce } = ctx.permitParams + const charlie = ctx.accounts.user2 + + // create a signed permit that already invalid + const deadline = ((await hre.ethers.provider.getBlock('latest')).timestamp - 1).toString() + const { v, r, s } = await signPermit(owner.address, owner, spender.address, value, deadline, nonce, ctx.domainSeparator) + + // try to submit the permit that is expired + await assert.revertsWith( + permit(token, charlie, owner.address, spender.address, value, deadline, v, r, s, ctx.constants.usePermitMethodWithSignature, { gasLimit: '0xffffff' }), + 'ErrorDeadlineExpired()' + ) + + { + // create a signed permit that valid for 1 minute (approximately) + const deadline1min = ((await hre.ethers.provider.getBlock('latest')).timestamp + 60).toString() + const { v, r, s } = await signPermit(owner.address, owner, spender.address, value, deadline1min, nonce, ctx.domainSeparator) + const tx = await permit(token, charlie, owner.address, spender.address, value, deadline1min, v, r, s, ctx.constants.usePermitMethodWithSignature) + + assert.equalBN(await token.nonces(owner.address), BigNumber.from(1)) + assert.emits(token, tx, 'Approval', [owner, spender, BigNumber.from(value)]) + } + }) + + .test('reverts if the nonce given does not match the next nonce expected', async (ctx) => { + const token = ctx.contracts.rebasableProxied + const { owner, spender, value, deadline } = ctx.permitParams + const charlie = ctx.accounts.user2 + const nonce = 1 + // create a signed permit + const { v, r, s } = await signPermit(owner.address, owner, spender.address, value, deadline, nonce, ctx.domainSeparator) + // check that the next nonce expected is 0, not 1 + assert.equalBN(await token.nonces(owner.address), BigNumber.from(0)) + + // try to submit the permit + await assert.revertsWith( + permit(token, charlie, owner.address, spender.address, value, deadline, v, r, s, ctx.constants.usePermitMethodWithSignature), + 'ErrorInvalidSignature()' + ) + }) + + .test('reverts if the permit has already been used', async (ctx) => { + const token = ctx.contracts.rebasableProxied + const { owner, spender, value, nonce, deadline } = ctx.permitParams + const charlie = ctx.accounts.user2 + // create a signed permit + const { v, r, s } = await signPermit(owner.address, owner, spender.address, value, deadline, nonce, ctx.domainSeparator) + + // submit the permit + await permit(token, charlie, owner.address, spender.address, value, deadline, v, r, s, ctx.constants.usePermitMethodWithSignature) + + // try to submit the permit again + await assert.revertsWith( + permit(token, charlie, owner.address, spender.address, value, deadline, v, r, s, ctx.constants.usePermitMethodWithSignature), + 'ErrorInvalidSignature()' + ) + + await testing.impersonate(owner.address) + await testing.setBalance(owner.address, wei.toBigNumber(wei`10 ether`)) + + // try to submit the permit again from Alice herself + await assert.revertsWith( + permit(token, await hre.ethers.getSigner(owner.address), owner.address, spender.address, value, deadline, v, r, s, ctx.constants.usePermitMethodWithSignature), + 'ErrorInvalidSignature()' + ) + }) + + .test('reverts if the permit has a nonce that has already been used by the signer', async (ctx) => { + const token = ctx.contracts.rebasableProxied + const { owner, spender, value, nonce, deadline } = ctx.permitParams + const charlie = ctx.accounts.user2 + // create a signed permit + const permit0 = await signPermit(owner.address, owner, spender.address, value, deadline, nonce, ctx.domainSeparator) + + // submit the permit + await permit(token, charlie, owner.address, spender.address, value, deadline, permit0.v, permit0.r, permit0.s, ctx.constants.usePermitMethodWithSignature) + + // create another signed permit with the same nonce, but + // with different parameters + const permit2 = await signPermit(owner.address, owner, spender.address, 1e6, deadline, nonce, ctx.domainSeparator) + + // try to submit the permit again + await assert.revertsWith( + permit(token, charlie, owner.address, spender.address, 1e6, deadline, permit2.v, permit2.r, permit2.s, ctx.constants.usePermitMethodWithSignature), + 'ErrorInvalidSignature()' + ) + }) + + .test('reverts if the permit includes invalid approval parameters', async (ctx) => { + const token = ctx.contracts.rebasableProxied + const { owner, value, nonce, deadline } = ctx.permitParams + const charlie = ctx.accounts.user2 + // create a signed permit that attempts to grant allowance to the + // zero address + const spender = hre.ethers.constants.AddressZero + const { v, r, s } = await signPermit(owner.address, owner, spender, value, deadline, nonce, ctx.domainSeparator) + + // try to submit the permit with invalid approval parameters + await assert.revertsWith( + permit(token, charlie, owner.address, spender, value, deadline, v, r, s, ctx.constants.usePermitMethodWithSignature), + 'ErrorAccountIsZeroAddress()' + ) + }) + + .test('reverts if the permit is not for an approval', async (ctx) => { + const token = ctx.contracts.rebasableProxied + const charlie = ctx.accounts.user2 + const { owner: from, spender: to, value, deadline: validBefore } = ctx.permitParams + // create a signed permit for a transfer + const validAfter = '0' + const nonce = '0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef' + const digest = calculateTransferAuthorizationDigest( + from.address, + to.address, + value, + validAfter, + validBefore, + nonce, + ctx.domainSeparator + ) + const { v, r, s } = await signEOAorEIP1271(digest, from) + + // try to submit the transfer permit + await assert.revertsWith( + permit(token, charlie, from.address, to.address, value, validBefore, v, r, s, ctx.constants.usePermitMethodWithSignature), + 'ErrorInvalidSignature()' + ) + }) + + .run(); +} + +function ctxFactoryFactory( + name: string, + symbol: string, + isRebasable: boolean, + usePermitMethodWithSignature: boolean, + signingAccountsFuncFactory: typeof getAccountsEIP1271 | typeof getAccountsEOA +) { + return async () => { + const decimalsToSet = 18; + const decimals = BigNumber.from(10).pow(decimalsToSet); + const tokenRate = BigNumber.from('1164454276599657236000000000'); + const premintShares = wei.toBigNumber(wei`100 ether`); + const premintTokens = tokenRate.mul(premintShares).div(decimals); + + const [ + deployer, + owner, + recipient, + spender, + holder, + stranger, + user1, + user2, + messenger, + l1TokenRatePusher + ] = await hre.ethers.getSigners(); + + await hre.network.provider.request({ + method: "hardhat_impersonateAccount", + params: [hre.ethers.constants.AddressZero], + }); + + const zero = await hre.ethers.getSigner(hre.ethers.constants.AddressZero); + + const rebasableProxied = await tokenProxied( + name, + symbol, + decimalsToSet, + tokenRate, + isRebasable, + messenger.address, + l1TokenRatePusher.address, + owner, + deployer, + holder + ); + + const { alice, bob } = await signingAccountsFuncFactory(); + + return { + accounts: { deployer, owner, recipient, spender, holder, stranger, zero, user1, user2 }, + constants: { name, symbol, decimalsToSet, decimals, premintShares, premintTokens, tokenRate, usePermitMethodWithSignature }, + contracts: { rebasableProxied }, + permitParams: { + owner: alice, + spender: bob, + value: 6e6, + nonce: 0, + deadline: MAX_UINT256, + }, + domainSeparator: makeDomainSeparator(name, SIGNING_DOMAIN_VERSION, getChainId(), rebasableProxied.address), + }; + } +} + +async function tokenProxied( + name: string, + symbol: string, + decimalsToSet: number, + tokenRate: BigNumber, + isRebasable: boolean, + messenger: string, + l1TokenRatePusher: string, + owner: SignerWithAddress, + deployer: SignerWithAddress, + holder: SignerWithAddress) { + + if (isRebasable) { + const wrappedToken = await new ERC20BridgedPermit__factory(deployer).deploy( + "WstETH Test Token", + "WstETH", + SIGNING_DOMAIN_VERSION, + decimalsToSet, + owner.address + ); + const tokenRateOracleImpl = await new TokenRateOracle__factory(deployer).deploy( + messenger, + owner.address, + l1TokenRatePusher, + 86400, + 86400, + 500, + 86400*3, + 3600 + ); + const provider = await hre.ethers.provider; + const blockNumber = await provider.getBlockNumber(); + const blockTimestamp = (await provider.getBlock(blockNumber)).timestamp; + + const tokenRateOracleProxy = await new OssifiableProxy__factory( + deployer + ).deploy( + tokenRateOracleImpl.address, + deployer.address, + tokenRateOracleImpl.interface.encodeFunctionData("initialize", [ + deployer.address, + tokenRate, + blockTimestamp + ]) + ); + + const tokenRateOracle = TokenRateOracle__factory.connect( + tokenRateOracleProxy.address, + deployer + ); + + const rebasableTokenImpl = await new ERC20RebasableBridgedPermit__factory(deployer).deploy( + name, + symbol, + SIGNING_DOMAIN_VERSION, + decimalsToSet, + wrappedToken.address, + tokenRateOracle.address, + owner.address + ); + + const l2TokensProxy = await new OssifiableProxy__factory(deployer).deploy( + rebasableTokenImpl.address, + deployer.address, + ERC20RebasableBridgedPermit__factory.createInterface().encodeFunctionData("initialize", [ + name, + symbol, + SIGNING_DOMAIN_VERSION + ]) + ); + + const rebasableProxied = ERC20RebasableBridgedPermit__factory.connect( + l2TokensProxy.address, + holder + ); + + return rebasableProxied; + } + + const wrappedToken = await new ERC20BridgedPermit__factory(deployer).deploy( + name, + symbol, + SIGNING_DOMAIN_VERSION, + decimalsToSet, + owner.address + ); + + const l2TokensProxy = await new OssifiableProxy__factory(deployer).deploy( + wrappedToken.address, + deployer.address, + ERC20BridgedPermit__factory.createInterface().encodeFunctionData("initialize", [ + name, + symbol, + SIGNING_DOMAIN_VERSION + ]) + ); + + const nonRebasableProxied = ERC20BridgedPermit__factory.connect( + l2TokensProxy.address, + holder + ); + + return nonRebasableProxied; +} + +/// permit with signature parameter +permitTestsSuit( + unit("ERC20RebasableBridgedPermit with EIP1271 (contract) signing. Uses permit function with signature parameter.", + ctxFactoryFactory( + "Liquid staked Ether 2.0", + "stETH", + true, + true, + getAccountsEIP1271 + ) + ) +); + +permitTestsSuit( + unit("ERC20RebasableBridgedPermit with ECDSA (EOA) signing. Uses permit function with signature parameter.", + ctxFactoryFactory( + "Liquid staked Ether 2.0", + "stETH", + true, + true, + getAccountsEOA + ) + ) +); + +permitTestsSuit( + unit("ERC20BridgedPermit with EIP1271 (contract) signing. Uses permit function with signature parameter.", + ctxFactoryFactory( + "Wrapped liquid staked Ether 2.0", + "wstETH", + false, + true, + getAccountsEIP1271 + ) + ) +); + +permitTestsSuit( + unit("ERC20BridgedPermit with ECDSA (EOA) signing. Uses permit function with signature parameter.", + ctxFactoryFactory( + "Wrapped liquid staked Ether 2.0", + "WstETH", + false, + true, + getAccountsEOA + ) + ) +); + +/// permit with v,r,s params +permitTestsSuit( + unit("ERC20RebasableBridgedPermit with EIP1271 (contract) signing. Uses permit function with v,r,s params", + ctxFactoryFactory( + "Liquid staked Ether 2.0", + "stETH", + true, + false, + getAccountsEIP1271 + ) + ) +); + +permitTestsSuit( + unit("ERC20RebasableBridgedPermit with ECDSA (EOA) signing. Uses permit function with v,r,s params", + ctxFactoryFactory( + "Liquid staked Ether 2.0", + "stETH", + true, + false, + getAccountsEOA + ) + ) +); + +permitTestsSuit( + unit("ERC20BridgedPermit with EIP1271 (contract) signing. Uses permit function with v,r,s params", + ctxFactoryFactory( + "Wrapped liquid staked Ether 2.0", + "wstETH", + false, + false, + getAccountsEIP1271 + ) + ) +); + +permitTestsSuit( + unit("ERC20BridgedPermit with ECDSA (EOA) signing. Uses permit function with v,r,s params", + ctxFactoryFactory( + "Wrapped liquid staked Ether 2.0", + "WstETH", + false, + false, + getAccountsEOA + ) + ) +); + +async function permit( + token: BaseContract, + signer: SignerWithAddress, + owner: string, + spender: string, + value: number, + deadline: string, + v: string | number, + r: string, + s: string, + functionWithSignature: boolean, + overrides: Overrides & { from?: string | Promise} = {}) { + if(functionWithSignature) { + const signature = ethers.utils.solidityPack(["bytes32", "bytes32", "uint8"], [r, s, v]) + return await token.connect(signer)["permit(address,address,uint256,uint256,bytes)"](owner, spender, value, deadline, signature, overrides); + } else { + return await token.connect(signer)["permit(address,address,uint256,uint256,uint8,bytes32,bytes32)"](owner, spender, value, deadline, v, r, s, overrides); + } +} diff --git a/test/token/ERC20RebasableBridgedPermit.unit.test.ts b/test/token/ERC20RebasableBridgedPermit.unit.test.ts new file mode 100644 index 00000000..75e3fdea --- /dev/null +++ b/test/token/ERC20RebasableBridgedPermit.unit.test.ts @@ -0,0 +1,1328 @@ +import hre from "hardhat"; +import { assert } from "chai"; +import { BigNumber } from "ethers"; +import { unit } from "../../utils/testing"; +import { wei } from "../../utils/wei"; +import { getBlockTimestamp } from "../../utils/testing/helpers"; +import { + erc20RebasableBridgedPermitUnderProxy, + tokenRateOracleUnderProxy +} from "../../utils/testing/contractsFactory"; +import { + OssifiableProxy__factory, + ERC20BridgedPermit__factory, + ERC20RebasableBridgedPermit__factory, + TokenRateOracle__factory +} from "../../typechain"; + +unit("ERC20RebasableBridgedPermit", ctxFactory) + .test("constructor() :: zero params", async (ctx) => { + const { + deployer, + stranger, + zero, + owner, + messenger, + l1TokenRatePusher + } = ctx.accounts; + + const { + tokenRateOutdatedDelay, + maxAllowedL2ToL1ClockLag, + maxAllowedTokenRateDeviationPerDay + } = ctx.constants; + + const tokenRateOracle = await new TokenRateOracle__factory(deployer).deploy( + messenger.address, + owner.address, + l1TokenRatePusher.address, + tokenRateOutdatedDelay, + maxAllowedL2ToL1ClockLag, + maxAllowedTokenRateDeviationPerDay, + BigNumber.from(86400*3), + BigNumber.from(3600) + ); + + await assert.revertsWith(new ERC20RebasableBridgedPermit__factory( + deployer + ).deploy( + "name", + "symbol", + "version", + 0, + stranger.address, + tokenRateOracle.address, + stranger.address + ), "ErrorZeroDecimals()"); + + await assert.revertsWith(new ERC20RebasableBridgedPermit__factory( + deployer + ).deploy( + "name", + "symbol", + "version", + 18, + zero.address, + tokenRateOracle.address, + stranger.address, + ), "ErrorZeroAddressTokenToWrapFrom()"); + + await assert.revertsWith(new ERC20RebasableBridgedPermit__factory( + deployer + ).deploy( + "name", + "symbol", + "version", + 18, + stranger.address, + zero.address, + stranger.address, + ), "ErrorZeroAddressTokenRateOracle()"); + + await assert.revertsWith(new ERC20RebasableBridgedPermit__factory( + deployer + ).deploy( + "name", + "symbol", + "version", + 18, + stranger.address, + tokenRateOracle.address, + zero.address, + ), "ErrorZeroAddressL2ERC20TokenBridge()"); + }) + + .test("initial state", async (ctx) => { + const { rebasableProxied, wrappedToken, tokenRateOracle } = ctx.contracts; + const { name, symbol, version, decimals } = ctx.constants; + const { owner } = ctx.accounts; + const [, eip712Name, eip712Version, , , ,] = await rebasableProxied.eip712Domain(); + assert.equal(eip712Name, name); + assert.equal(eip712Version, version); + assert.equal(await rebasableProxied.name(), name); + assert.equal(await rebasableProxied.symbol(), symbol) + assert.equalBN(await rebasableProxied.decimals(), decimals) + assert.equal(await rebasableProxied.TOKEN_TO_WRAP_FROM(), wrappedToken.address); + assert.equal(await rebasableProxied.TOKEN_RATE_ORACLE(), tokenRateOracle.address); + assert.equal(await rebasableProxied.L2_ERC20_TOKEN_BRIDGE(), owner.address); + }) + + .test("initialize() :: petrified version", async (ctx) => { + const { deployer, owner, zero, messenger, l1TokenRatePusher } = ctx.accounts; + const { decimals } = ctx.constants; + + // deploy new implementation + const wrappedToken = await new ERC20BridgedPermit__factory(deployer).deploy( + "WsETH Test Token", + "WsETH", + "1", + decimals, + owner.address + ); + const tokenRateOracle = await new TokenRateOracle__factory(deployer).deploy( + messenger.address, + owner.address, + l1TokenRatePusher.address, + 86400, + 86400, + 500, + 86400*3, + 3600 + ); + const rebasableTokenImpl = await new ERC20RebasableBridgedPermit__factory(deployer).deploy( + "stETH Test Token", + "stETH", + "1", + 10, + wrappedToken.address, + tokenRateOracle.address, + owner.address + ); + + const petrifiedVersionMark = hre.ethers.constants.MaxUint256; + assert.equalBN(await rebasableTokenImpl.getContractVersion(), petrifiedVersionMark); + + await assert.revertsWith( + rebasableTokenImpl.initialize("name", "symbol", "version"), + "NonZeroContractVersionOnInit()" + ); + }) + + .test("initialize() :: don't allow to initialize with empty metadata", async (ctx) => { + const { deployer, owner, zero, messenger, l1TokenRatePusher } = ctx.accounts; + const { decimals, name, symbol, version } = ctx.constants; + + // deploy new implementation + const wrappedToken = await new ERC20BridgedPermit__factory(deployer).deploy( + "WsETH Test Token", + "WsETH", + "1", + decimals, + owner.address + ); + const tokenRateOracle = await new TokenRateOracle__factory(deployer).deploy( + messenger.address, + owner.address, + l1TokenRatePusher.address, + 86400, + 86400, + 500, + 86400*3, + 3600 + ); + const rebasableTokenImpl = await new ERC20RebasableBridgedPermit__factory(deployer).deploy( + "name", + "symbol", + "1", + 10, + wrappedToken.address, + tokenRateOracle.address, + owner.address + ); + + await assert.revertsWith( + new OssifiableProxy__factory(deployer).deploy( + rebasableTokenImpl.address, + deployer.address, + ERC20RebasableBridgedPermit__factory.createInterface().encodeFunctionData("initialize", [ + "", + symbol, + version + ]) + ), + "ErrorNameIsEmpty()" + ); + await assert.revertsWith( + new OssifiableProxy__factory(deployer).deploy( + rebasableTokenImpl.address, + deployer.address, + ERC20RebasableBridgedPermit__factory.createInterface().encodeFunctionData("initialize", [ + name, + "", + version + ]) + ), + "ErrorSymbolIsEmpty()" + ); + }) + + .test("initialize() :: don't allow to initialize twice", async (ctx) => { + const { deployer, owner, zero, holder, messenger, l1TokenRatePusher } = ctx.accounts; + const { decimals, name, symbol, version } = ctx.constants; + + // deploy new implementation + const wrappedToken = await new ERC20BridgedPermit__factory(deployer).deploy( + "WsETH Test Token", + "WsETH", + "1", + decimals, + owner.address + ); + const tokenRateOracle = await new TokenRateOracle__factory(deployer).deploy( + messenger.address, + owner.address, + l1TokenRatePusher.address, + 86400, + 86400, + 500, + 86400*3, + 3600 + ); + const rebasableTokenImpl = await new ERC20RebasableBridgedPermit__factory(deployer).deploy( + "name", + "symbol", + "1", + 10, + wrappedToken.address, + tokenRateOracle.address, + owner.address + ); + + const l2TokensProxy = await new OssifiableProxy__factory(deployer).deploy( + rebasableTokenImpl.address, + deployer.address, + ERC20RebasableBridgedPermit__factory.createInterface().encodeFunctionData("initialize", [ + name, + symbol, + version + ]) + ); + + const rebasableProxied = ERC20RebasableBridgedPermit__factory.connect( + l2TokensProxy.address, + holder + ); + + assert.equalBN(await rebasableProxied.getContractVersion(), 1); + + await assert.revertsWith( + rebasableProxied.initialize(name, symbol, version), + "NonZeroContractVersionOnInit()" + ); + }) + + .test("decimals() :: has the same value as is in constructor", async (ctx) => + assert.equalBN(await ctx.contracts.rebasableProxied.decimals(), ctx.constants.decimals) + ) + + .test("getTotalShares() :: returns preminted amount", async (ctx) => { + const { premintShares } = ctx.constants; + assert.equalBN(await ctx.contracts.rebasableProxied.getTotalShares(), premintShares); + }) + + .test("wrap() :: revert if wrap 0 wstETH", async (ctx) => { + const { rebasableProxied } = ctx.contracts; + const { user1 } = ctx.accounts; + await assert.revertsWith(rebasableProxied.connect(user1).wrap(0), "ErrorZeroSharesWrap()"); + }) + + .test("wrap() :: when no balance", async (ctx) => { + const { rebasableProxied, wrappedToken } = ctx.contracts; + const { user1 } = ctx.accounts; + + await wrappedToken.connect(user1).approve(rebasableProxied.address, 1000); + await assert.revertsWith(rebasableProxied.connect(user1).wrap(2), "ErrorNotEnoughBalance()"); + }) + + .test("wrap() :: happy path", async (ctx) => { + + const { rebasableProxied, wrappedToken, tokenRateOracle } = ctx.contracts; + const { user1, user2, owner, zero } = ctx.accounts; + const { tokenRate, tenPowDecimals, premintShares } = ctx.constants; + + await tokenRateOracle.connect(owner).updateRate(tokenRate, 1000); + + const totalSupply = tokenRate.mul(premintShares).div(tenPowDecimals); + + assert.equalBN(await rebasableProxied.getTotalShares(), premintShares); + assert.equalBN(await rebasableProxied.totalSupply(), totalSupply); + + // user1 + const user1Shares = wei`100 ether`; + const user1Tokens = tokenRate.mul(user1Shares).div(tenPowDecimals); + + assert.equalBN(await rebasableProxied.sharesOf(user1.address), 0); + assert.equalBN(await rebasableProxied.balanceOf(user1.address), 0); + + await wrappedToken.connect(owner).bridgeMint(user1.address, user1Tokens); + await wrappedToken.connect(user1).approve(rebasableProxied.address, user1Shares); + + assert.equalBN(await rebasableProxied.connect(user1).callStatic.wrap(user1Shares), user1Tokens); + const tx = await rebasableProxied.connect(user1).wrap(user1Shares); + + await assert.emits(rebasableProxied, tx, "Transfer", [zero.address, user1.address, user1Tokens]); + await assert.emits(rebasableProxied, tx, "TransferShares", [zero.address, user1.address, user1Shares]); + + assert.equalBN(await rebasableProxied.sharesOf(user1.address), user1Shares); + assert.equalBN(await rebasableProxied.balanceOf(user1.address), user1Tokens); + assert.equalBN(await wrappedToken.balanceOf(rebasableProxied.address), premintShares.add(user1Shares)); + + // common state changes + assert.equalBN(await rebasableProxied.getTotalShares(), BigNumber.from(premintShares).add(user1Shares)); + assert.equalBN(await rebasableProxied.totalSupply(), totalSupply.add(user1Tokens)); + + // user2 + assert.equalBN(await rebasableProxied.sharesOf(user2.address), 0); + assert.equalBN(await rebasableProxied.balanceOf(user2.address), 0); + + const user2Shares = wei`50 ether`; + const user2Tokens = tokenRate.mul(user2Shares).div(tenPowDecimals); + + await wrappedToken.connect(owner).bridgeMint(user2.address, user2Tokens); + await wrappedToken.connect(user2).approve(rebasableProxied.address, user2Shares); + + assert.equalBN(await rebasableProxied.connect(user2).callStatic.wrap(user2Shares), user2Tokens); + const tx2 = await rebasableProxied.connect(user2).wrap(user2Shares); + + await assert.emits(rebasableProxied, tx2, "Transfer", [zero.address, user2.address, user2Tokens]); + await assert.emits(rebasableProxied, tx2, "TransferShares", [zero.address, user2.address, user2Shares]); + + assert.equalBN(await rebasableProxied.sharesOf(user2.address), user2Shares); + assert.equalBN(await rebasableProxied.balanceOf(user2.address), user2Tokens); + assert.equalBN(await wrappedToken.balanceOf(rebasableProxied.address), premintShares.add(BigNumber.from(user1Shares).add(user2Shares))); + + // common state changes + assert.equalBN(await rebasableProxied.getTotalShares(), BigNumber.from(premintShares).add(user1Shares).add(user2Shares)); + assert.equalBN(await rebasableProxied.totalSupply(), totalSupply.add(user1Tokens).add(user2Tokens)); + }) + + .test("unwrap() :: revert if unwrap 0 wstETH", async (ctx) => { + const { rebasableProxied } = ctx.contracts; + const { user1 } = ctx.accounts; + await assert.revertsWith(rebasableProxied.connect(user1).unwrap(0), "ErrorZeroTokensUnwrap()"); + }) + + .test("unwrap() :: when no balance", async (ctx) => { + const { rebasableProxied } = ctx.contracts; + const { user1 } = ctx.accounts; + + await assert.revertsWith(rebasableProxied.connect(user1).unwrap(wei`4 ether`), "ErrorNotEnoughBalance()"); + }) + + .test("unwrap() :: events", async (ctx) => { + const { rebasableProxied, wrappedToken } = ctx.contracts; + const { user1, owner, zero } = ctx.accounts; + const { tokenRate, tenPowDecimals } = ctx.constants; + + const user1SharesToWrap = BigNumber.from(10).pow(30); + const user1TokensToUnwrap = BigNumber.from('764035550674393190'); + const user1SharesToUnwrap = (user1TokensToUnwrap).mul(tenPowDecimals).div(BigNumber.from(tokenRate)); + + await wrappedToken.connect(owner).bridgeMint(user1.address, user1SharesToWrap); + await wrappedToken.connect(user1).approve(rebasableProxied.address, user1SharesToWrap); + await rebasableProxied.connect(user1).wrap(user1SharesToWrap); + + const tx = await rebasableProxied.connect(user1).unwrap(user1TokensToUnwrap); + + await assert.emits(rebasableProxied, tx, "Transfer", [user1.address, zero.address, user1TokensToUnwrap]); + await assert.emits(rebasableProxied, tx, "TransferShares", [user1.address, zero.address, user1SharesToUnwrap]); + }) + + .test("unwrap() :: happy path", async (ctx) => { + + const { rebasableProxied, wrappedToken } = ctx.contracts; + const { user1, user2, owner } = ctx.accounts; + const { tokenRate, tenPowDecimals, premintShares } = ctx.constants; + + const totalSupply = BigNumber.from(tokenRate).mul(premintShares).div(tenPowDecimals); + + assert.equalBN(await rebasableProxied.getTotalShares(), premintShares); + assert.equalBN(await rebasableProxied.totalSupply(), totalSupply); + + // user1 + + assert.equalBN(await rebasableProxied.sharesOf(user1.address), 0); + assert.equalBN(await rebasableProxied.balanceOf(user1.address), 0); + + const user1SharesToWrap = wei`100 ether`; + const user1SharesToUnwrap = wei`59 ether`; + const user1TokensToUnwrap = tokenRate.mul(user1SharesToUnwrap).div(tenPowDecimals); + + const user1Shares = BigNumber.from(user1SharesToWrap).sub(user1SharesToUnwrap); + const user1Tokens = BigNumber.from(tokenRate).mul(user1Shares).div(tenPowDecimals); + + await wrappedToken.connect(owner).bridgeMint(user1.address, user1SharesToWrap); + await wrappedToken.connect(user1).approve(rebasableProxied.address, user1SharesToWrap); + + const tx0 = await rebasableProxied.connect(user1).wrap(user1SharesToWrap); + assert.equalBN(await rebasableProxied.connect(user1).callStatic.unwrap(user1TokensToUnwrap), user1SharesToUnwrap); + const tx = await rebasableProxied.connect(user1).unwrap(user1TokensToUnwrap); + + assert.equalBN(await rebasableProxied.sharesOf(user1.address), user1Shares); + assert.equalBN(await rebasableProxied.balanceOf(user1.address), user1Tokens); + assert.equalBN(await wrappedToken.balanceOf(rebasableProxied.address), premintShares.add(user1Shares)); + + // common state changes + assert.equalBN(await rebasableProxied.getTotalShares(), premintShares.add(user1Shares)); + assert.equalBN(await rebasableProxied.totalSupply(), totalSupply.add(user1Tokens)); + + // user2 + const user2SharesToWrap = wei`145 ether`; + const user2SharesToUnwrap = wei`14 ether`; + const user2TokensToUnwrap = tokenRate.mul(user2SharesToUnwrap).div(tenPowDecimals); + + const user2Shares = BigNumber.from(user2SharesToWrap).sub(user2SharesToUnwrap); + const user2Tokens = BigNumber.from(tokenRate).mul(user2Shares).div(tenPowDecimals); + + assert.equalBN(await rebasableProxied.sharesOf(user2.address), 0); + assert.equalBN(await rebasableProxied.balanceOf(user2.address), 0); + + await wrappedToken.connect(owner).bridgeMint(user2.address, user2SharesToWrap); + await wrappedToken.connect(user2).approve(rebasableProxied.address, user2SharesToWrap); + + await rebasableProxied.connect(user2).wrap(user2SharesToWrap); + assert.equalBN(await rebasableProxied.connect(user2).callStatic.unwrap(user2TokensToUnwrap), user2SharesToUnwrap); + const tx2 = await rebasableProxied.connect(user2).unwrap(user2TokensToUnwrap); + + assert.equalBN(await rebasableProxied.sharesOf(user2.address), user2Shares); + assert.equalBN(await rebasableProxied.balanceOf(user2.address), user2Tokens); + assert.equalBN(await wrappedToken.balanceOf(rebasableProxied.address), premintShares.add(BigNumber.from(user1Shares).add(user2Shares))); + + // common state changes + assert.equalBN(await rebasableProxied.getTotalShares(), premintShares.add(user1Shares).add(user2Shares)); + assert.equalBN(await rebasableProxied.totalSupply(), totalSupply.add(user1Tokens).add(user2Tokens)); + }) + + .test("unwrapShares() :: revert if unwrap 0 shares", async (ctx) => { + const { rebasableProxied } = ctx.contracts; + const { user1 } = ctx.accounts; + await assert.revertsWith(rebasableProxied.connect(user1).unwrapShares(0), "ErrorZeroSharesUnwrap()"); + }) + + .test("unwrapShares() :: not enough balance", async (ctx) => { + const { rebasableProxied } = ctx.contracts; + const { user1 } = ctx.accounts; + await assert.revertsWith(rebasableProxied.connect(user1).unwrapShares(wei`4 ether`), "ErrorNotEnoughBalance()"); + }) + + .test("unwrapShares() :: happy path", async (ctx) => { + + const { rebasableProxied, wrappedToken } = ctx.contracts; + const { user1, owner } = ctx.accounts; + const { tokenRate, tenPowDecimals, premintShares } = ctx.constants; + + const totalSupply = BigNumber.from(tokenRate).mul(premintShares).div(tenPowDecimals); + + // user1 + const user1SharesToWrap = 10; + const user1SharesToUnwrap = user1SharesToWrap; + + assert.equalBN(await rebasableProxied.getTotalShares(), premintShares); + assert.equalBN(await rebasableProxied.totalSupply(), totalSupply); + + assert.equalBN(await rebasableProxied.sharesOf(user1.address), 0); + assert.equalBN(await rebasableProxied.balanceOf(user1.address), 0); + + await wrappedToken.connect(owner).bridgeMint(user1.address, user1SharesToWrap); + await wrappedToken.connect(user1).approve(rebasableProxied.address, user1SharesToWrap); + await rebasableProxied.connect(user1).wrap(user1SharesToWrap); + + assert.equalBN(await rebasableProxied.sharesOf(user1.address), user1SharesToWrap); + assert.equalBN(await wrappedToken.balanceOf(rebasableProxied.address), premintShares.add(user1SharesToWrap)); + + await rebasableProxied.connect(user1).unwrapShares(user1SharesToUnwrap); + + assert.equalBN(await rebasableProxied.sharesOf(user1.address), 0); + assert.equalBN(await rebasableProxied.balanceOf(user1.address), 0); + assert.equalBN(await wrappedToken.balanceOf(rebasableProxied.address), premintShares); + }) + + .test("bridgeWrap() :: revert if not bridge", async (ctx) => { + const { rebasableProxied } = ctx.contracts; + const { user1, user2 } = ctx.accounts; + await assert.revertsWith(rebasableProxied.connect(user1).bridgeWrap(user2.address, 10), "ErrorNotBridge()"); + }) + + .test("bridgeWrap() :: revert if wrap 0 wstETH", async (ctx) => { + const { rebasableProxied } = ctx.contracts; + const { user1, owner } = ctx.accounts; + await assert.revertsWith(rebasableProxied.connect(owner).bridgeWrap(user1.address, 0), "ErrorZeroSharesWrap()"); + }) + + .test("bridgeWrap() :: when no balance", async (ctx) => { + const { rebasableProxied, wrappedToken } = ctx.contracts; + const { owner, user1 } = ctx.accounts; + + await wrappedToken.connect(owner).approve(rebasableProxied.address, 1000); + await assert.revertsWith(rebasableProxied.connect(owner).bridgeWrap(user1.address, 2), "ErrorNotEnoughBalance()"); + }) + + .test("bridgeWrap() :: happy path", async (ctx) => { + + const { rebasableProxied, wrappedToken, tokenRateOracle } = ctx.contracts; + const { user1, user2, owner, zero } = ctx.accounts; + const { tokenRate, tenPowDecimals, premintShares } = ctx.constants; + + await wrappedToken.connect(owner).bridgeMint(owner.address, wei`1000 ether`); + await tokenRateOracle.connect(owner).updateRate(tokenRate, 1000); + + const totalSupply = tokenRate.mul(premintShares).div(tenPowDecimals); + + assert.equalBN(await rebasableProxied.getTotalShares(), premintShares); + assert.equalBN(await rebasableProxied.totalSupply(), totalSupply); + + // user1 + const user1Shares = wei`100 ether`; + const user1Tokens = tokenRate.mul(user1Shares).div(tenPowDecimals); + + assert.equalBN(await rebasableProxied.sharesOf(user1.address), 0); + assert.equalBN(await rebasableProxied.balanceOf(user1.address), 0); + + await wrappedToken.connect(owner).bridgeMint(user1.address, user1Tokens); + await wrappedToken.connect(owner).approve(rebasableProxied.address, user1Shares); + + assert.equalBN(await rebasableProxied.connect(owner).callStatic.bridgeWrap(user1.address, user1Shares), user1Tokens); + const tx = await rebasableProxied.connect(owner).bridgeWrap(user1.address, user1Shares); + + await assert.emits(rebasableProxied, tx, "Transfer", [zero.address, user1.address, user1Tokens]); + await assert.emits(rebasableProxied, tx, "TransferShares", [zero.address, user1.address, user1Shares]); + + assert.equalBN(await rebasableProxied.sharesOf(user1.address), user1Shares); + assert.equalBN(await rebasableProxied.balanceOf(user1.address), user1Tokens); + assert.equalBN(await wrappedToken.balanceOf(rebasableProxied.address), premintShares.add(user1Shares)); + + // common state changes + assert.equalBN(await rebasableProxied.getTotalShares(), BigNumber.from(premintShares).add(user1Shares)); + assert.equalBN(await rebasableProxied.totalSupply(), totalSupply.add(user1Tokens)); + + // user2 + assert.equalBN(await rebasableProxied.sharesOf(user2.address), 0); + assert.equalBN(await rebasableProxied.balanceOf(user2.address), 0); + + const user2Shares = wei`50 ether`; + const user2Tokens = tokenRate.mul(user2Shares).div(tenPowDecimals); + + await wrappedToken.connect(owner).bridgeMint(user2.address, user2Tokens); + await wrappedToken.connect(owner).approve(rebasableProxied.address, user2Shares); + + assert.equalBN(await rebasableProxied.connect(owner).callStatic.bridgeWrap(user2.address, user2Shares), user2Tokens); + const tx2 = await rebasableProxied.connect(owner).bridgeWrap(user2.address, user2Shares); + + await assert.emits(rebasableProxied, tx2, "Transfer", [zero.address, user2.address, user2Tokens]); + await assert.emits(rebasableProxied, tx2, "TransferShares", [zero.address, user2.address, user2Shares]); + + assert.equalBN(await rebasableProxied.sharesOf(user2.address), user2Shares); + assert.equalBN(await rebasableProxied.balanceOf(user2.address), user2Tokens); + assert.equalBN(await wrappedToken.balanceOf(rebasableProxied.address), premintShares.add(BigNumber.from(user1Shares).add(user2Shares))); + + // common state changes + assert.equalBN(await rebasableProxied.getTotalShares(), BigNumber.from(premintShares).add(user1Shares).add(user2Shares)); + assert.equalBN(await rebasableProxied.totalSupply(), totalSupply.add(user1Tokens).add(user2Tokens)); + }) + + .test("bridgeUnwrap() :: revert if not bridge", async (ctx) => { + const { rebasableProxied } = ctx.contracts; + const { user1, user2 } = ctx.accounts; + await assert.revertsWith(rebasableProxied.connect(user1).bridgeUnwrap(user2.address, 10), "ErrorNotBridge()"); + }) + + .test("bridgeUnwrap() :: revert if unwrap 0 wstETH", async (ctx) => { + const { rebasableProxied } = ctx.contracts; + const { user1, owner } = ctx.accounts; + await assert.revertsWith(rebasableProxied.connect(owner).bridgeUnwrap(user1.address, 0), "ErrorZeroTokensUnwrap()"); + }) + + .test("bridgeUnwrap() :: when no balance", async (ctx) => { + const { rebasableProxied } = ctx.contracts; + const { user1, owner } = ctx.accounts; + + await assert.revertsWith(rebasableProxied.connect(owner).bridgeUnwrap(user1.address, wei`4 ether`), "ErrorNotEnoughBalance()"); + }) + + .test("bridgeUnwrap() :: happy path", async (ctx) => { + + const { rebasableProxied, wrappedToken } = ctx.contracts; + const { user1, user2, owner } = ctx.accounts; + const { tokenRate, tenPowDecimals, premintShares } = ctx.constants; + + const totalSupply = BigNumber.from(tokenRate).mul(premintShares).div(tenPowDecimals); + + assert.equalBN(await rebasableProxied.getTotalShares(), premintShares); + assert.equalBN(await rebasableProxied.totalSupply(), totalSupply); + + // user1 + + assert.equalBN(await rebasableProxied.sharesOf(user1.address), 0); + assert.equalBN(await rebasableProxied.balanceOf(user1.address), 0); + + const user1SharesToWrap = wei`100 ether`; + const user1SharesToUnwrap = wei`59 ether`; + const user1TokensToUnwrap = tokenRate.mul(user1SharesToUnwrap).div(tenPowDecimals); + + const user1Shares = BigNumber.from(user1SharesToWrap).sub(user1SharesToUnwrap); + const user1Tokens = BigNumber.from(tokenRate).mul(user1Shares).div(tenPowDecimals); + + await wrappedToken.connect(owner).bridgeMint(user1.address, user1SharesToWrap); + await wrappedToken.connect(user1).approve(rebasableProxied.address, user1SharesToWrap); + + const tx0 = await rebasableProxied.connect(user1).wrap(user1SharesToWrap); + assert.equalBN(await rebasableProxied.connect(owner).callStatic.bridgeUnwrap(user1.address, user1TokensToUnwrap), user1SharesToUnwrap); + const tx = await rebasableProxied.connect(owner).bridgeUnwrap(user1.address, user1TokensToUnwrap); + + assert.equalBN(await rebasableProxied.sharesOf(user1.address), user1Shares); + assert.equalBN(await rebasableProxied.balanceOf(user1.address), user1Tokens); + assert.equalBN(await wrappedToken.balanceOf(rebasableProxied.address), premintShares.add(user1Shares)); + + // common state changes + assert.equalBN(await rebasableProxied.getTotalShares(), premintShares.add(user1Shares)); + assert.equalBN(await rebasableProxied.totalSupply(), totalSupply.add(user1Tokens)); + + // user2 + const user2SharesToWrap = wei`145 ether`; + const user2SharesToUnwrap = wei`14 ether`; + const user2TokensToUnwrap = tokenRate.mul(user2SharesToUnwrap).div(tenPowDecimals); + + const user2Shares = BigNumber.from(user2SharesToWrap).sub(user2SharesToUnwrap); + const user2Tokens = BigNumber.from(tokenRate).mul(user2Shares).div(tenPowDecimals); + + assert.equalBN(await rebasableProxied.sharesOf(user2.address), 0); + assert.equalBN(await rebasableProxied.balanceOf(user2.address), 0); + + await wrappedToken.connect(owner).bridgeMint(user2.address, user2SharesToWrap); + await wrappedToken.connect(user2).approve(rebasableProxied.address, user2SharesToWrap); + + await rebasableProxied.connect(user2).wrap(user2SharesToWrap); + assert.equalBN(await rebasableProxied.connect(owner).callStatic.bridgeUnwrap(user2.address, user2TokensToUnwrap), user2SharesToUnwrap); + const tx2 = await rebasableProxied.connect(owner).bridgeUnwrap(user2.address, user2TokensToUnwrap); + + assert.equalBN(await rebasableProxied.sharesOf(user2.address), user2Shares); + assert.equalBN(await rebasableProxied.balanceOf(user2.address), user2Tokens); + assert.equalBN(await wrappedToken.balanceOf(rebasableProxied.address), premintShares.add(BigNumber.from(user1Shares).add(user2Shares))); + + // common state changes + assert.equalBN(await rebasableProxied.getTotalShares(), premintShares.add(user1Shares).add(user2Shares)); + assert.equalBN(await rebasableProxied.totalSupply(), totalSupply.add(user1Tokens).add(user2Tokens)); + }) + + .test("approve() :: events", async (ctx) => { + const { rebasableProxied } = ctx.contracts; + const { holder, spender } = ctx.accounts; + const amount = wei`1 ether`; + + const tx = await rebasableProxied.approve(spender.address, amount); + await assert.emits(rebasableProxied, tx, "Approval", [ + holder.address, + spender.address, + amount, + ]); + }) + + .test("approve() :: happy path", async (ctx) => { + const { rebasableProxied } = ctx.contracts; + const { holder, spender } = ctx.accounts; + + // validate initially allowance is zero + assert.equalBN( + await rebasableProxied.allowance(holder.address, spender.address), + "0" + ); + + const amount = wei`1 ether`; + + // validate return value of the method + assert.isTrue( + await rebasableProxied.callStatic.approve(spender.address, amount) + ); + + // approve tokens + const tx = await rebasableProxied.approve(spender.address, amount); + + // validate Approval event was emitted + await assert.emits(rebasableProxied, tx, "Approval", [ + holder.address, + spender.address, + amount, + ]); + + // validate allowance was set + assert.equalBN( + await rebasableProxied.allowance(holder.address, spender.address), + amount + ); + }) + + .test("transfer() :: sender is zero address", async (ctx) => { + const { rebasableProxied } = ctx.contracts; + + const { + accounts: { zero, recipient }, + } = ctx; + await assert.revertsWith( + rebasableProxied.connect(zero).transfer(recipient.address, wei`1 ether`), + "ErrorAccountIsZeroAddress()" + ); + }) + + .test("transfer() :: recipient is zero address", async (ctx) => { + const { zero, holder } = ctx.accounts; + await assert.revertsWith( + ctx.contracts.rebasableProxied.connect(holder).transfer(zero.address, wei`1 ether`), + "ErrorAccountIsZeroAddress()" + ); + }) + + .test("transfer() :: zero balance", async (ctx) => { + const { rebasableProxied } = ctx.contracts; + const { premintTokens } = ctx.constants; + const { recipient, holder } = ctx.accounts; + + // validate balance before transfer + assert.equalBN(await rebasableProxied.balanceOf(holder.address), premintTokens); + + // transfer tokens + await rebasableProxied.connect(holder).transfer(recipient.address, "0"); + + // validate balance stays same + assert.equalBN(await rebasableProxied.balanceOf(holder.address), premintTokens); + }) + + .test("transfer() :: not enough balance", async (ctx) => { + const { rebasableProxied } = ctx.contracts; + const { premintTokens } = ctx.constants; + const { recipient, holder } = ctx.accounts; + + // validate balance before transfer + assert.equalBN(await rebasableProxied.balanceOf(holder.address), premintTokens); + + const amount = premintTokens.add(wei`1 ether`); + + // transfer tokens + await assert.revertsWith( + rebasableProxied.connect(holder).transfer(recipient.address, amount), + "ErrorNotEnoughBalance()" + ); + }) + + .test("transfer() :: happy path", async (ctx) => { + const { rebasableProxied } = ctx.contracts; + const { premintTokens } = ctx.constants; + const { recipient, holder } = ctx.accounts; + + // validate balance before transfer + assert.equalBN(await rebasableProxied.balanceOf(holder.address), premintTokens); + + const amount = wei`1 ether`; + const sharesToTransfer = await rebasableProxied.getSharesByTokens(amount); + + // transfer tokens + const tx = await rebasableProxied + .connect(holder) + .transfer(recipient.address, amount); + + // validate Transfer event was emitted + await assert.emits(rebasableProxied, tx, "Transfer", [ + holder.address, + recipient.address, + amount, + ]); + + await assert.emits(rebasableProxied, tx, "TransferShares", [ + holder.address, + recipient.address, + sharesToTransfer, + ]); + + // validate balance was updated + assert.equalBN( + await rebasableProxied.balanceOf(holder.address), + premintTokens.sub(amount) + ); + + // validate total supply stays same + assert.equalBN(await rebasableProxied.totalSupply(), premintTokens); + }) + + + .test("transferShares() :: sender is zero address", async (ctx) => { + const { rebasableProxied } = ctx.contracts; + + const { + accounts: { zero, recipient }, + } = ctx; + await assert.revertsWith( + rebasableProxied.connect(zero).transferShares(recipient.address, wei`1 ether`), + "ErrorAccountIsZeroAddress()" + ); + }) + + .test("transferShares() :: recipient is zero address", async (ctx) => { + const { zero, holder } = ctx.accounts; + await assert.revertsWith( + ctx.contracts.rebasableProxied.connect(holder).transferShares(zero.address, wei`1 ether`), + "ErrorAccountIsZeroAddress()" + ); + }) + + .test("transferShares() :: zero balance", async (ctx) => { + const { rebasableProxied } = ctx.contracts; + const { premintTokens } = ctx.constants; + const { recipient, holder } = ctx.accounts; + + // validate balance before transfer + assert.equalBN(await rebasableProxied.balanceOf(holder.address), premintTokens); + + // transfer tokens + await rebasableProxied.connect(holder).transferShares(recipient.address, "0"); + + // validate balance stays same + assert.equalBN(await rebasableProxied.balanceOf(holder.address), premintTokens); + }) + + .test("transferShares() :: not enough balance", async (ctx) => { + const { rebasableProxied } = ctx.contracts; + const { premintTokens } = ctx.constants; + const { recipient, holder } = ctx.accounts; + + // validate balance before transfer + assert.equalBN(await rebasableProxied.balanceOf(holder.address), premintTokens); + + const amount = premintTokens.add(wei`1 ether`); + + // transfer tokens + await assert.revertsWith( + rebasableProxied.connect(holder).transferShares(recipient.address, amount), + "ErrorNotEnoughBalance()" + ); + }) + + .test("transferShares() :: happy path", async (ctx) => { + const { rebasableProxied } = ctx.contracts; + const { premintTokens } = ctx.constants; + const { recipient, holder } = ctx.accounts; + + // validate balance before transfer + assert.equalBN(await rebasableProxied.balanceOf(holder.address), premintTokens); + + // + const sharesToTransfer = wei`1 ether`; + const tokensToTransfer = await rebasableProxied.getTokensByShares(sharesToTransfer); + + // transfer tokens + const tx = await rebasableProxied + .connect(holder) + .transferShares(recipient.address, sharesToTransfer); + + // validate Transfer event was emitted + await assert.emits(rebasableProxied, tx, "Transfer", [ + holder.address, + recipient.address, + tokensToTransfer, + ]); + + await assert.emits(rebasableProxied, tx, "TransferShares", [ + holder.address, + recipient.address, + sharesToTransfer, + ]); + + // validate balance was updated + assert.equalBN( + await rebasableProxied.balanceOf(holder.address), + premintTokens.sub(tokensToTransfer) + ); + + // validate total supply stays same + assert.equalBN(await rebasableProxied.totalSupply(), premintTokens); + }) + + .test("transferFrom() :: not enough allowance", async (ctx) => { + const { rebasableProxied } = ctx.contracts; + const { premintTokens } = ctx.constants; + const { recipient, holder, spender } = ctx.accounts; + + const initialAllowance = wei`0.9 ether`; + + // set allowance + await rebasableProxied.approve(recipient.address, initialAllowance); + + // validate allowance is set + assert.equalBN( + await rebasableProxied.allowance(holder.address, recipient.address), + initialAllowance + ); + + // validate balance before transfer + assert.equalBN(await rebasableProxied.balanceOf(holder.address), premintTokens); + + const amount = wei`1 ether`; + + // transfer tokens + await assert.revertsWith( + rebasableProxied + .connect(spender) + .transferFrom(holder.address, recipient.address, amount), + "ErrorNotEnoughAllowance()" + ); + }) + + .test("transferFrom() :: max allowance", async (ctx) => { + const { rebasableProxied } = ctx.contracts; + const { premintTokens } = ctx.constants; + const { recipient, holder, spender } = ctx.accounts; + + const initialAllowance = hre.ethers.constants.MaxUint256; + + // set allowance + await rebasableProxied.approve(spender.address, initialAllowance); + + // validate allowance is set + assert.equalBN( + await rebasableProxied.allowance(holder.address, spender.address), + initialAllowance + ); + + // validate balance before transfer + assert.equalBN(await rebasableProxied.balanceOf(holder.address), premintTokens); + + const tokensAmount = wei`1 ether`; + const sharesAmount = await rebasableProxied.getSharesByTokens(tokensAmount); + + const holderBalanceBefore = await rebasableProxied.balanceOf(holder.address); + const recepientBalanceBefore = await rebasableProxied.balanceOf(recipient.address); + + // transfer tokens + const tx = await rebasableProxied + .connect(spender) + .transferFrom(holder.address, recipient.address, tokensAmount); + + // validate Approval event was not emitted + await assert.notEmits(rebasableProxied, tx, "Approval"); + + // validate Transfer event was emitted + await assert.emits(rebasableProxied, tx, "Transfer", [ + holder.address, + recipient.address, + tokensAmount, + ]); + + await assert.emits(rebasableProxied, tx, "TransferShares", [ + holder.address, + recipient.address, + sharesAmount, + ]); + + // validate allowance wasn't changed + assert.equalBN( + await rebasableProxied.allowance(holder.address, spender.address), + initialAllowance + ); + + // validate holder balance updated + assert.equalBN( + await rebasableProxied.balanceOf(holder.address), + holderBalanceBefore.sub(tokensAmount) + ); + + // validate recipient balance updated + const recipientBalanceAfter = await rebasableProxied.balanceOf(recipient.address); + const balanceDelta = recipientBalanceAfter.sub(recepientBalanceBefore); + const oneTwoWei = wei.toBigNumber(tokensAmount).sub(balanceDelta); + assert.isTrue(oneTwoWei.gte(0) && oneTwoWei.lte(2)); + }) + + .test("transferFrom() :: happy path", async (ctx) => { + const { rebasableProxied } = ctx.contracts; + const { premintTokens } = ctx.constants; + const { recipient, holder, spender } = ctx.accounts; + + const tokensAmountToApprove = wei`2 ether`; + const tokensAmountToTransfer = wei`1 ether`; + const sharesAmountToTransfer = await rebasableProxied.getSharesByTokens(tokensAmountToTransfer); + + // holder sets allowance for spender + await rebasableProxied.approve(spender.address, tokensAmountToApprove); + + // validate allowance is set + assert.equalBN( + await rebasableProxied.allowance(holder.address, spender.address), + tokensAmountToApprove + ); + + // validate balance before transfer + assert.equalBN(await rebasableProxied.balanceOf(holder.address), premintTokens); + + const recepientBalanceBefore = await rebasableProxied.balanceOf(recipient.address); + const holderBalanceBefore = await rebasableProxied.balanceOf(holder.address); + + // transfer tokens + const tx = await rebasableProxied + .connect(spender) + .transferFrom(holder.address, recipient.address, tokensAmountToTransfer); + + // validate Approval event was emitted + await assert.emits(rebasableProxied, tx, "Approval", [ + holder.address, + spender.address, + wei.toBigNumber(tokensAmountToApprove).sub(tokensAmountToTransfer), + ]); + + // validate Transfer event was emitted + await assert.emits(rebasableProxied, tx, "Transfer", [ + holder.address, + recipient.address, + tokensAmountToTransfer, + ]); + + await assert.emits(rebasableProxied, tx, "TransferShares", [ + holder.address, + recipient.address, + sharesAmountToTransfer, + ]); + + // validate allowance updated + assert.equalBN( + await rebasableProxied.allowance(holder.address, spender.address), + wei.toBigNumber(tokensAmountToApprove).sub(tokensAmountToTransfer) + ); + + // validate holder balance updated + assert.equalBN( + await rebasableProxied.balanceOf(holder.address), + holderBalanceBefore.sub(tokensAmountToTransfer) + ); + + // validate recipient balance updated + const recipientBalanceAfter = await rebasableProxied.balanceOf(recipient.address); + const balanceDelta = recipientBalanceAfter.sub(recepientBalanceBefore); + const oneTwoWei = wei.toBigNumber(tokensAmountToTransfer).sub(balanceDelta); + assert.isTrue(oneTwoWei.gte(0) && oneTwoWei.lte(2)); + }) + + .test("transferSharesFrom() :: not enough allowance", async (ctx) => { + const { rebasableProxied } = ctx.contracts; + const { recipient, holder, spender } = ctx.accounts; + + const sharesAmount = wei`1 ether`; + const tokenAllowance = await rebasableProxied.getTokensByShares(wei.toBigNumber(sharesAmount).sub(1000)); + + // set allowance + await rebasableProxied.approve(recipient.address, tokenAllowance); + + // validate allowance is set + assert.equalBN( + await rebasableProxied.allowance(holder.address, recipient.address), + tokenAllowance + ); + + // transfer tokens + await assert.revertsWith( + rebasableProxied + .connect(spender) + .transferSharesFrom(holder.address, recipient.address, sharesAmount), + "ErrorNotEnoughAllowance()" + ); + }) + + .test("transferSharesFrom() :: max allowance", async (ctx) => { + const { rebasableProxied } = ctx.contracts; + const { premintTokens } = ctx.constants; + const { recipient, holder, spender } = ctx.accounts; + + const tokenAllowance = hre.ethers.constants.MaxUint256; + + // set allowance + await rebasableProxied.approve(spender.address, tokenAllowance); + + // validate allowance is set + assert.equalBN( + await rebasableProxied.allowance(holder.address, spender.address), + tokenAllowance + ); + + // validate balance before transfer + assert.equalBN(await rebasableProxied.balanceOf(holder.address), premintTokens); + + const sharesAmount = wei`1 ether`; + const tokensAmount = await rebasableProxied.getTokensByShares(sharesAmount); + + const holderBalanceBefore = await rebasableProxied.balanceOf(holder.address); + + // transfer tokens + const tx = await rebasableProxied + .connect(spender) + .transferSharesFrom(holder.address, recipient.address, sharesAmount); + + // validate Approval event was not emitted + await assert.notEmits(rebasableProxied, tx, "Approval"); + + // validate Transfer event was emitted + await assert.emits(rebasableProxied, tx, "Transfer", [ + holder.address, + recipient.address, + tokensAmount, + ]); + + await assert.emits(rebasableProxied, tx, "TransferShares", [ + holder.address, + recipient.address, + sharesAmount, + ]); + + // validate allowance wasn't changed + assert.equalBN( + await rebasableProxied.allowance(holder.address, spender.address), + tokenAllowance + ); + + // validate holder balance updated + assert.equalBN( + await rebasableProxied.balanceOf(holder.address), + holderBalanceBefore.sub(tokensAmount) + ); + + // validate recipient balance updated + assert.equalBN( + await rebasableProxied.balanceOf(recipient.address), + tokensAmount + ); + }) + + .test("transferSharesFrom() :: happy path", async (ctx) => { + const { rebasableProxied } = ctx.contracts; + const { premintTokens } = ctx.constants; + const { recipient, holder, spender } = ctx.accounts; + + const sharesAmountToApprove = wei`2 ether`; + const sharesAmountToTransfer = wei`1 ether`; + + const tokensAmountToApprove = await rebasableProxied.getTokensByShares(sharesAmountToApprove); + const tokensAmountToTransfer = await rebasableProxied.getTokensByShares(sharesAmountToTransfer); + + + // holder sets allowance for spender + await rebasableProxied.approve(spender.address, tokensAmountToApprove); + + // validate allowance is set + assert.equalBN( + await rebasableProxied.allowance(holder.address, spender.address), + tokensAmountToApprove + ); + + // validate balance before transfer + assert.equalBN(await rebasableProxied.balanceOf(holder.address), premintTokens); + + + const holderBalanceBefore = await rebasableProxied.balanceOf(holder.address); + + // transfer tokens + const tx = await rebasableProxied + .connect(spender) + .transferSharesFrom(holder.address, recipient.address, sharesAmountToTransfer); + + // validate Approval event was emitted + await assert.emits(rebasableProxied, tx, "Approval", [ + holder.address, + spender.address, + tokensAmountToApprove.sub(tokensAmountToTransfer), + ]); + + // validate Transfer event was emitted + await assert.emits(rebasableProxied, tx, "Transfer", [ + holder.address, + recipient.address, + tokensAmountToTransfer, + ]); + + await assert.emits(rebasableProxied, tx, "TransferShares", [ + holder.address, + recipient.address, + sharesAmountToTransfer, + ]); + + // validate allowance updated + assert.equalBN( + await rebasableProxied.allowance(holder.address, spender.address), + tokensAmountToApprove.sub(tokensAmountToTransfer) + ); + + // validate holder balance updated + assert.equalBN( + await rebasableProxied.balanceOf(holder.address), + holderBalanceBefore.sub(tokensAmountToTransfer) + ); + + // validate recipient balance updated + assert.equalBN( + await rebasableProxied.balanceOf(recipient.address), + tokensAmountToTransfer + ); + }) + .run(); + +async function ctxFactory() { + /// --------------------------- + /// constants + /// --------------------------- + const name = "StETH Test Token"; + const symbol = "StETH"; + const version = "1"; + const decimals = BigNumber.from(27); + const tenPowDecimals = BigNumber.from(10).pow(decimals); + const tokenRate = BigNumber.from('1164454276599657236000000000'); // value taken from real contact on 23.04.24 + const tokenRateOutdatedDelay = BigNumber.from(86400); // 1 day + const maxAllowedL2ToL1ClockLag = BigNumber.from(86400); // 1 day + const maxAllowedTokenRateDeviationPerDay = BigNumber.from(500); // 5% + const premintShares = wei.toBigNumber(wei`100 ether`); + const premintTokens = tokenRate.mul(premintShares).div(tenPowDecimals); + const provider = await hre.ethers.provider; + const blockTimestamp = await getBlockTimestamp(provider, 0); + + const [ + deployer, + owner, + recipient, + spender, + holder, + stranger, + user1, + user2, + messenger, + l1TokenRatePusher + ] = await hre.ethers.getSigners(); + + const zero = await hre.ethers.getSigner(hre.ethers.constants.AddressZero); + + /// --------------------------- + /// contracts + /// --------------------------- + const wrappedToken = await new ERC20BridgedPermit__factory(deployer).deploy( + "WsETH Test Token", + "WsETH", + version, + decimals, + owner.address + ); + + const { tokenRateOracle } = await tokenRateOracleUnderProxy( + deployer, + messenger.address, + owner.address, + l1TokenRatePusher.address, + tokenRateOutdatedDelay, + maxAllowedL2ToL1ClockLag, + maxAllowedTokenRateDeviationPerDay, + BigNumber.from(86400*3), + BigNumber.from(3600), + tokenRate, + blockTimestamp + ) + + const rebasableProxied = await erc20RebasableBridgedPermitUnderProxy( + deployer, + holder, + name, + symbol, + version, + decimals, + tokenRateOracle, + wrappedToken, + owner.address, + ); + + /// --------------------------- + /// setup + /// --------------------------- + await wrappedToken.connect(owner).bridgeMint(holder.address, premintTokens); + await wrappedToken.connect(holder).approve(rebasableProxied.address, premintShares); + await rebasableProxied.connect(holder).wrap(premintShares); + + await hre.network.provider.request({ + method: "hardhat_impersonateAccount", + params: [hre.ethers.constants.AddressZero], + }); + + return { + accounts: { + deployer, + owner, + recipient, + spender, + holder, + stranger, + zero, + user1, + user2, + messenger, + l1TokenRatePusher + }, + constants: { + name, + symbol, + version, + decimals, + tenPowDecimals, + premintShares, + premintTokens, + tokenRate, + blockTimestamp, + tokenRateOutdatedDelay, + maxAllowedL2ToL1ClockLag, + maxAllowedTokenRateDeviationPerDay + }, + contracts: { + rebasableProxied, + wrappedToken, + tokenRateOracle + } + }; +} diff --git a/utils/arbitrum/addresses.ts b/utils/arbitrum/addresses.ts deleted file mode 100644 index d06b22ed..00000000 --- a/utils/arbitrum/addresses.ts +++ /dev/null @@ -1,34 +0,0 @@ -import { NetworkName } from "../network"; -import { ArbContractAddresses, CommonOptions } from "./types"; - -const ArbitrumMainnetAddresses: ArbContractAddresses = { - Inbox: "0x4Dbd4fc535Ac27206064B68FfCf827b0A60BAB3f", - ArbSys: "0x0000000000000000000000000000000000000064", - Bridge: "0x8315177ab297ba92a06054ce80a67ed4dbd7ed3a", - Outbox: "0x760723CD2e632826c38Fef8CD438A4CC7E7E1A40", - L1GatewayRouter: "0x72Ce9c846789fdB6fC1f34aC4AD25Dd9ef7031ef", - L2GatewayRouter: "0x5288c571Fd7aD117beA99bF60FE0846C4E84F933", -}; - -const ArbitrumGoerliAddresses: ArbContractAddresses = { - Inbox: "0x6BEbC4925716945D46F0Ec336D5C2564F419682C", - ArbSys: "0x0000000000000000000000000000000000000064", - Bridge: "0xaf4159A80B6Cc41ED517DB1c453d1Ef5C2e4dB72", - Outbox: "0x45Af9Ed1D03703e480CE7d328fB684bb67DA5049", - L1GatewayRouter: "0x4c7708168395aEa569453Fc36862D2ffcDaC588c", - L2GatewayRouter: "0xE5B9d8d42d656d1DcB8065A6c012FE3780246041", -}; - -export default function addresses( - networkName: NetworkName, - options: CommonOptions = {} -) { - switch (networkName) { - case "mainnet": - return { ...ArbitrumMainnetAddresses, ...options.customAddresses }; - case "sepolia": - return { ...ArbitrumGoerliAddresses, ...options.customAddresses }; - default: - throw new Error(`Network "${networkName}" is not supported`); - } -} diff --git a/utils/arbitrum/artifacts/ArbitrumBridgeExecutor.json b/utils/arbitrum/artifacts/ArbitrumBridgeExecutor.json deleted file mode 100644 index 73fa1fbb..00000000 --- a/utils/arbitrum/artifacts/ArbitrumBridgeExecutor.json +++ /dev/null @@ -1,696 +0,0 @@ -{ - "_format": "hh-sol-artifact-1", - "contractName": "ArbitrumBridgeExecutor", - "sourceName": "contracts/bridges/ArbitrumBridgeExecutor.sol", - "abi": [ - { - "inputs": [ - { - "internalType": "address", - "name": "ethereumGovernanceExecutor", - "type": "address" - }, - { - "internalType": "uint256", - "name": "delay", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "gracePeriod", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "minimumDelay", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "maximumDelay", - "type": "uint256" - }, - { - "internalType": "address", - "name": "guardian", - "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "constructor" - }, - { - "inputs": [], - "name": "DelayLongerThanMax", - "type": "error" - }, - { - "inputs": [], - "name": "DelayShorterThanMin", - "type": "error" - }, - { - "inputs": [], - "name": "DuplicateAction", - "type": "error" - }, - { - "inputs": [], - "name": "EmptyTargets", - "type": "error" - }, - { - "inputs": [], - "name": "FailedActionExecution", - "type": "error" - }, - { - "inputs": [], - "name": "GracePeriodTooShort", - "type": "error" - }, - { - "inputs": [], - "name": "InconsistentParamsLength", - "type": "error" - }, - { - "inputs": [], - "name": "InsufficientBalance", - "type": "error" - }, - { - "inputs": [], - "name": "InvalidActionsSetId", - "type": "error" - }, - { - "inputs": [], - "name": "InvalidInitParams", - "type": "error" - }, - { - "inputs": [], - "name": "MaximumDelayTooShort", - "type": "error" - }, - { - "inputs": [], - "name": "MinimumDelayTooLong", - "type": "error" - }, - { - "inputs": [], - "name": "NotGuardian", - "type": "error" - }, - { - "inputs": [], - "name": "OnlyCallableByThis", - "type": "error" - }, - { - "inputs": [], - "name": "OnlyQueuedActions", - "type": "error" - }, - { - "inputs": [], - "name": "TimelockNotFinished", - "type": "error" - }, - { - "inputs": [], - "name": "UnauthorizedEthereumExecutor", - "type": "error" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "uint256", - "name": "id", - "type": "uint256" - } - ], - "name": "ActionsSetCanceled", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "uint256", - "name": "id", - "type": "uint256" - }, - { - "indexed": true, - "internalType": "address", - "name": "initiatorExecution", - "type": "address" - }, - { - "indexed": false, - "internalType": "bytes[]", - "name": "returnedData", - "type": "bytes[]" - } - ], - "name": "ActionsSetExecuted", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "uint256", - "name": "id", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "address[]", - "name": "targets", - "type": "address[]" - }, - { - "indexed": false, - "internalType": "uint256[]", - "name": "values", - "type": "uint256[]" - }, - { - "indexed": false, - "internalType": "string[]", - "name": "signatures", - "type": "string[]" - }, - { - "indexed": false, - "internalType": "bytes[]", - "name": "calldatas", - "type": "bytes[]" - }, - { - "indexed": false, - "internalType": "bool[]", - "name": "withDelegatecalls", - "type": "bool[]" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "executionTime", - "type": "uint256" - } - ], - "name": "ActionsSetQueued", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "uint256", - "name": "oldDelay", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "newDelay", - "type": "uint256" - } - ], - "name": "DelayUpdate", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "address", - "name": "oldEthereumGovernanceExecutor", - "type": "address" - }, - { - "indexed": false, - "internalType": "address", - "name": "newEthereumGovernanceExecutor", - "type": "address" - } - ], - "name": "EthereumGovernanceExecutorUpdate", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "uint256", - "name": "oldGracePeriod", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "newGracePeriod", - "type": "uint256" - } - ], - "name": "GracePeriodUpdate", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "address", - "name": "oldGuardian", - "type": "address" - }, - { - "indexed": false, - "internalType": "address", - "name": "newGuardian", - "type": "address" - } - ], - "name": "GuardianUpdate", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "uint256", - "name": "oldMaximumDelay", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "newMaximumDelay", - "type": "uint256" - } - ], - "name": "MaximumDelayUpdate", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "uint256", - "name": "oldMinimumDelay", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "newMinimumDelay", - "type": "uint256" - } - ], - "name": "MinimumDelayUpdate", - "type": "event" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "actionsSetId", - "type": "uint256" - } - ], - "name": "cancel", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "actionsSetId", - "type": "uint256" - } - ], - "name": "execute", - "outputs": [], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "target", - "type": "address" - }, - { - "internalType": "bytes", - "name": "data", - "type": "bytes" - } - ], - "name": "executeDelegateCall", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - }, - { - "internalType": "bytes", - "name": "", - "type": "bytes" - } - ], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "actionsSetId", - "type": "uint256" - } - ], - "name": "getActionsSetById", - "outputs": [ - { - "components": [ - { - "internalType": "address[]", - "name": "targets", - "type": "address[]" - }, - { - "internalType": "uint256[]", - "name": "values", - "type": "uint256[]" - }, - { - "internalType": "string[]", - "name": "signatures", - "type": "string[]" - }, - { - "internalType": "bytes[]", - "name": "calldatas", - "type": "bytes[]" - }, - { - "internalType": "bool[]", - "name": "withDelegatecalls", - "type": "bool[]" - }, - { - "internalType": "uint256", - "name": "executionTime", - "type": "uint256" - }, - { - "internalType": "bool", - "name": "executed", - "type": "bool" - }, - { - "internalType": "bool", - "name": "canceled", - "type": "bool" - } - ], - "internalType": "struct IExecutorBase.ActionsSet", - "name": "", - "type": "tuple" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "getActionsSetCount", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "actionsSetId", - "type": "uint256" - } - ], - "name": "getCurrentState", - "outputs": [ - { - "internalType": "enum IExecutorBase.ActionsSetState", - "name": "", - "type": "uint8" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "getDelay", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "getEthereumGovernanceExecutor", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "getGracePeriod", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "getGuardian", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "getMaximumDelay", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "getMinimumDelay", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "actionHash", - "type": "bytes32" - } - ], - "name": "isActionQueued", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address[]", - "name": "targets", - "type": "address[]" - }, - { - "internalType": "uint256[]", - "name": "values", - "type": "uint256[]" - }, - { - "internalType": "string[]", - "name": "signatures", - "type": "string[]" - }, - { - "internalType": "bytes[]", - "name": "calldatas", - "type": "bytes[]" - }, - { - "internalType": "bool[]", - "name": "withDelegatecalls", - "type": "bool[]" - } - ], - "name": "queue", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "receiveFunds", - "outputs": [], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "delay", - "type": "uint256" - } - ], - "name": "updateDelay", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "ethereumGovernanceExecutor", - "type": "address" - } - ], - "name": "updateEthereumGovernanceExecutor", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "gracePeriod", - "type": "uint256" - } - ], - "name": "updateGracePeriod", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "guardian", - "type": "address" - } - ], - "name": "updateGuardian", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "maximumDelay", - "type": "uint256" - } - ], - "name": "updateMaximumDelay", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "minimumDelay", - "type": "uint256" - } - ], - "name": "updateMinimumDelay", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - } - ], - "bytecode": "0x60806040523480156200001157600080fd5b50604051620026bb380380620026bb83398101604081905262000034916200027e565b8585858585858484848484610258841080620000505750818310155b806200005b57508285105b806200006657508185115b156200008557604051630a5addd160e21b815260040160405180910390fd5b6200009085620000f4565b6200009b8462000135565b620000a68362000176565b620000b182620001b7565b620000bc81620001f8565b5050600880546001600160a01b0319166001600160a01b039a909a169990991790985550620002db9c50505050505050505050505050565b60005460408051918252602082018390527f43de56b886294fc29767e51a88b5c67fd24aefebc5ddf813b1d9b91b1df38444910160405180910390a1600055565b60015460408051918252602082018390527f9953f3a71052edcd4ae7a0f97302839d1dda32ab93c1039207c91c866b094f72910160405180910390a1600155565b60025460408051918252602082018390527fc534cdcbe9b52100810d787afd57e4174322776fcb58872ea706f23e9319fa8d910160405180910390a1600255565b60035460408051918252602082018390527faf46013422363beb5e6f00ab923cffe3574670494c864de2828b9d7c201fdde5910160405180910390a1600355565b600454604080516001600160a01b03928316815291831660208301527f85bd8788d3c4a160f0f6254229589f137d5633a870dcb46f99ffe07b4da1894b910160405180910390a1600480546001600160a01b0319166001600160a01b0392909216919091179055565b80516001600160a01b03811681146200027957600080fd5b919050565b60008060008060008060c087890312156200029857600080fd5b620002a38762000261565b955060208701519450604087015193506060870151925060808701519150620002cf60a0880162000261565b90509295509295509295565b6123d080620002eb6000396000f3fe6080604052600436106101295760003560e01c8063b3c82e92116100ab578063d9a4cbdf1161006f578063d9a4cbdf1461031e578063dbd183881461033e578063e471b02614610353578063e68a5c3d14610373578063fc52539514610393578063fe0d94c1146103b357600080fd5b8063b3c82e9214610288578063b68df16d146102b5578063c3a76886146102d6578063cebc9a82146102f4578063d89aac391461030957600080fd5b80635ab98d5a116100f25780635ab98d5a146101c157806364d62353146101e15780638533f33714610201578063a75b87d214610216578063b1fc87961461024857600080fd5b80625c33e11461012e57806303c2762114610130578063083a73a21461015457806340e58ee5146101745780635748c13014610194575b600080fd5b005b34801561013c57600080fd5b506002545b6040519081526020015b60405180910390f35b34801561016057600080fd5b5061012e61016f3660046119a8565b6103c6565b34801561018057600080fd5b5061012e61018f3660046119a8565b61041f565b3480156101a057600080fd5b506101b46101af3660046119a8565b6106ca565b60405161014b91906119d7565b3480156101cd57600080fd5b5061012e6101dc3660046119a8565b610760565b3480156101ed57600080fd5b5061012e6101fc3660046119a8565b6107ac565b34801561020d57600080fd5b50600554610141565b34801561022257600080fd5b506004546001600160a01b03165b6040516001600160a01b03909116815260200161014b565b34801561025457600080fd5b506102786102633660046119a8565b60009081526007602052604090205460ff1690565b604051901515815260200161014b565b34801561029457600080fd5b506102a86102a33660046119a8565b6107de565b60405161014b9190611b56565b6102c86102c3366004611c3e565b610b51565b60405161014b929190611cc1565b3480156102e257600080fd5b506008546001600160a01b0316610230565b34801561030057600080fd5b50600054610141565b34801561031557600080fd5b50600354610141565b34801561032a57600080fd5b5061012e610339366004612019565b610be2565b34801561034a57600080fd5b50600154610141565b34801561035f57600080fd5b5061012e61036e3660046119a8565b610c41565b34801561037f57600080fd5b5061012e61038e3660046120eb565b610c8c565b34801561039f57600080fd5b5061012e6103ae3660046120eb565b610d15565b61012e6103c13660046119a8565b610d3e565b3330146103e657604051631dbf5f2360e01b815260040160405180910390fd5b60025481116104085760405163cb2f2b2360e01b815260040160405180910390fd5b61041181611066565b61041c6000546110a7565b50565b6004546001600160a01b0316331461044a576040516377b6878160e11b815260040160405180910390fd5b6000610455826106ca565b6003811115610466576104666119c1565b146104845760405163050ac78b60e11b815260040160405180910390fd5b60008181526006602081905260408220908101805461ff001916610100179055805490915b81811015610699576106918360000182815481106104c9576104c961210d565b6000918252602090912001546001850180546001600160a01b0390921691849081106104f7576104f761210d565b90600052602060002001548560020184815481106105175761051761210d565b90600052602060002001805461052c90612123565b80601f016020809104026020016040519081016040528092919081815260200182805461055890612123565b80156105a55780601f1061057a576101008083540402835291602001916105a5565b820191906000526020600020905b81548152906001019060200180831161058857829003601f168201915b50505050508660030185815481106105bf576105bf61210d565b9060005260206000200180546105d490612123565b80601f016020809104026020016040519081016040528092919081815260200182805461060090612123565b801561064d5780601f106106225761010080835404028352916020019161064d565b820191906000526020600020905b81548152906001019060200180831161063057829003601f168201915b5050505050876005015488600401878154811061066c5761066c61210d565b90600052602060002090602091828204019190069054906101000a900460ff166110ed565b6001016104a9565b5060405183907f0743c673685efcbf3db8591d9e1d98336bc844fe4f4599e6f7efb6d71c02563490600090a2505050565b600081600554116106ee5760405163e5bc0e7b60e01b815260040160405180910390fd5b600082815260066020819052604090912090810154610100900460ff16156107195750600292915050565b600681015460ff161561072f5750600192915050565b60015481600501546107419190612158565b4211156107515750600392915050565b50600092915050565b50919050565b33301461078057604051631dbf5f2360e01b815260040160405180910390fd5b6102588110156107a3576040516301f6f9e560e71b815260040160405180910390fd5b61041c8161113f565b3330146107cc57604051631dbf5f2360e01b815260040160405180910390fd5b6107d5816110a7565b61041c81611180565b61082a6040518061010001604052806060815260200160608152602001606081526020016060815260200160608152602001600081526020016000151581526020016000151581525090565b60008281526006602090815260409182902082518154610120938102820184019094526101008101848152909391928492849184018282801561089657602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610878575b50505050508152602001600182018054806020026020016040519081016040528092919081815260200182805480156108ee57602002820191906000526020600020905b8154815260200190600101908083116108da575b5050505050815260200160028201805480602002602001604051908101604052809291908181526020016000905b828210156109c857838290600052602060002001805461093b90612123565b80601f016020809104026020016040519081016040528092919081815260200182805461096790612123565b80156109b45780601f10610989576101008083540402835291602001916109b4565b820191906000526020600020905b81548152906001019060200180831161099757829003601f168201915b50505050508152602001906001019061091c565b50505050815260200160038201805480602002602001604051908101604052809291908181526020016000905b82821015610aa1578382906000526020600020018054610a1490612123565b80601f0160208091040260200160405190810160405280929190818152602001828054610a4090612123565b8015610a8d5780601f10610a6257610100808354040283529160200191610a8d565b820191906000526020600020905b815481529060010190602001808311610a7057829003601f168201915b5050505050815260200190600101906109f5565b50505050815260200160048201805480602002602001604051908101604052809291908181526020018280548015610b1857602002820191906000526020600020906000905b825461010083900a900460ff161515815260206001928301818104948501949093039092029101808411610ae75790505b50505091835250506005820154602082015260069091015460ff8082161515604084015261010090910416151560609091015292915050565b60006060333014610b7557604051631dbf5f2360e01b815260040160405180910390fd5b60006060866001600160a01b03168686604051610b9392919061217e565b600060405180830381855af49150503d8060008114610bce576040519150601f19603f3d011682016040523d82523d6000602084013e610bd3565b606091505b50909890975095505050505050565b6008546001600160a01b03167311110000000000000000000000000000000011101933016001600160a01b031614610c2d576040516359e8359960e01b815260040160405180910390fd5b610c3a85858585856111c1565b5050505050565b333014610c6157604051631dbf5f2360e01b815260040160405180910390fd5b6003548110610c83576040516301b1029b60e61b815260040160405180910390fd5b6104118161142e565b333014610cac57604051631dbf5f2360e01b815260040160405180910390fd5b600854604080516001600160a01b03928316815291831660208301527f01dd0ca50426f21c1b37ce7f3e95eef45b4a55bc5da80a7b67b2c65a7463caf0910160405180910390a1600880546001600160a01b0319166001600160a01b0392909216919091179055565b333014610d3557604051631dbf5f2360e01b815260040160405180910390fd5b61041c8161146f565b6000610d49826106ca565b6003811115610d5a57610d5a6119c1565b14610d785760405163050ac78b60e11b815260040160405180910390fd5b60008181526006602052604090206005810154421015610dab57604051635192dd5560e01b815260040160405180910390fd5b60068101805460ff19166001179055805460008167ffffffffffffffff811115610dd757610dd7611ce4565b604051908082528060200260200182016040528015610e0a57816020015b6060815260200190600190039081610df55790505b50905060005b8281101561101d57610ff8846000018281548110610e3057610e3061210d565b6000918252602090912001546001860180546001600160a01b039092169184908110610e5e57610e5e61210d565b9060005260206000200154866002018481548110610e7e57610e7e61210d565b906000526020600020018054610e9390612123565b80601f0160208091040260200160405190810160405280929190818152602001828054610ebf90612123565b8015610f0c5780601f10610ee157610100808354040283529160200191610f0c565b820191906000526020600020905b815481529060010190602001808311610eef57829003601f168201915b5050505050876003018581548110610f2657610f2661210d565b906000526020600020018054610f3b90612123565b80601f0160208091040260200160405190810160405280929190818152602001828054610f6790612123565b8015610fb45780601f10610f8957610100808354040283529160200191610fb4565b820191906000526020600020905b815481529060010190602001808311610f9757829003601f168201915b50505050508860050154896004018781548110610fd357610fd361210d565b90600052602060002090602091828204019190069054906101000a900460ff166114d8565b82828151811061100a5761100a61210d565b6020908102919091010152600101610e10565b50336001600160a01b0316847ff5efc4bb09a12b6c9561a7e7ab02938a72a4351316b473d574fdaaa89c43eb9a83604051611058919061218e565b60405180910390a350505050565b60035460408051918252602082018390527faf46013422363beb5e6f00ab923cffe3574670494c864de2828b9d7c201fdde5910160405180910390a1600355565b6002548110156110ca576040516361759e6560e01b815260040160405180910390fd5b60035481111561041c576040516386dac63560e01b815260040160405180910390fd5b600086868686868660405160200161110a969594939291906121a1565b60408051601f198184030181529181528151602092830120600090815260079092529020805460ff1916905550505050505050565b60015460408051918252602082018390527f9953f3a71052edcd4ae7a0f97302839d1dda32ab93c1039207c91c866b094f72910160405180910390a1600155565b60005460408051918252602082018390527f43de56b886294fc29767e51a88b5c67fd24aefebc5ddf813b1d9b91b1df38444910160405180910390a1600055565b84516111e057604051636a8e3e9360e11b815260040160405180910390fd5b84518451811415806111f3575083518114155b806111ff575082518114155b8061120b575081518114155b1561122957604051630d10f63b60e01b815260040160405180910390fd5b6005546000805461123a9042612158565b600580546001019055905060005b8381101561135b5760008982815181106112645761126461210d565b602002602001015189838151811061127e5761127e61210d565b60200260200101518984815181106112985761129861210d565b60200260200101518985815181106112b2576112b261210d565b6020026020010151868a87815181106112cd576112cd61210d565b60200260200101516040516020016112ea969594939291906121a1565b60405160208183030381529060405280519060200120905061131b8160009081526007602052604090205460ff1690565b1561133957604051633b2f04e360e21b815260040160405180910390fd5b6000908152600760205260409020805460ff1916600190811790915501611248565b5060008281526006602090815260409091208951909161137f9183918c01906116be565b50875161139590600183019060208b0190611723565b5086516113ab90600283019060208a019061175e565b5085516113c190600383019060208901906117b7565b5084516113d79060048301906020880190611810565b50818160050181905550827f0325966a4aa089b42f4766ec96f599405102bb309e065f24874aff59082dbc8b8a8a8a8a8a8860405161141b969594939291906121f5565b60405180910390a2505050505050505050565b60025460408051918252602082018390527fc534cdcbe9b52100810d787afd57e4174322776fcb58872ea706f23e9319fa8d910160405180910390a1600255565b600454604080516001600160a01b03928316815291831660208301527f85bd8788d3c4a160f0f6254229589f137d5633a870dcb46f99ffe07b4da1894b910160405180910390a1600480546001600160a01b0319166001600160a01b0392909216919091179055565b6060854710156114fb57604051631e9acf1760e31b815260040160405180910390fd5b6000878787878787604051602001611518969594939291906121a1565b60408051601f198184030181529181528151602092830120600081815260079093529120805460ff191690558651909150606090611557575084611583565b86805190602001208660405160200161157192919061229c565b60405160208183030381529060405290505b6000606085156116055760405163b68df16d60e01b8152309063b68df16d908c906115b4908f9088906004016122cd565b60006040518083038185885af11580156115d2573d6000803e3d6000fd5b50505050506040513d6000823e601f3d908101601f191682016040526115fb91908101906122f1565b9092509050611667565b8a6001600160a01b03168a8460405161161e919061237e565b60006040518083038185875af1925050503d806000811461165b576040519150601f19603f3d011682016040523d82523d6000602084013e611660565b606091505b5090925090505b6116718282611680565b9b9a5050505050505050505050565b6060821561168f5750806116b8565b81511561169f5781518083602001fd5b6040516332f63ed360e21b815260040160405180910390fd5b92915050565b828054828255906000526020600020908101928215611713579160200282015b8281111561171357825182546001600160a01b0319166001600160a01b039091161782556020909201916001909101906116de565b5061171f9291506118ac565b5090565b828054828255906000526020600020908101928215611713579160200282015b82811115611713578251825591602001919060010190611743565b8280548282559060005260206000209081019282156117ab579160200282015b828111156117ab578251805161179b9184916020909101906118c1565b509160200191906001019061177e565b5061171f929150611934565b828054828255906000526020600020908101928215611804579160200282015b8281111561180457825180516117f49184916020909101906118c1565b50916020019190600101906117d7565b5061171f929150611951565b82805482825590600052602060002090601f016020900481019282156117135791602002820160005b8382111561187657835183826101000a81548160ff0219169083151502179055509260200192600101602081600001049283019260010302611839565b80156118a35782816101000a81549060ff0219169055600101602081600001049283019260010302611876565b505061171f9291505b5b8082111561171f57600081556001016118ad565b8280546118cd90612123565b90600052602060002090601f0160209004810192826118ef5760008555611713565b82601f1061190857805160ff1916838001178555611713565b828001600101855582156117135791820182811115611713578251825591602001919060010190611743565b8082111561171f576000611948828261196e565b50600101611934565b8082111561171f576000611965828261196e565b50600101611951565b50805461197a90612123565b6000825580601f1061198a575050565b601f01602090049060005260206000209081019061041c91906118ac565b6000602082840312156119ba57600080fd5b5035919050565b634e487b7160e01b600052602160045260246000fd5b60208101600483106119f957634e487b7160e01b600052602160045260246000fd5b91905290565b600081518084526020808501945080840160005b83811015611a385781516001600160a01b031687529582019590820190600101611a13565b509495945050505050565b600081518084526020808501945080840160005b83811015611a3857815187529582019590820190600101611a57565b60005b83811015611a8e578181015183820152602001611a76565b83811115611a9d576000848401525b50505050565b60008151808452611abb816020860160208601611a73565b601f01601f19169290920160200192915050565b600081518084526020808501808196508360051b8101915082860160005b85811015611b17578284038952611b05848351611aa3565b98850198935090840190600101611aed565b5091979650505050505050565b600081518084526020808501945080840160005b83811015611a38578151151587529582019590820190600101611b38565b6020815260008251610100806020850152611b756101208501836119ff565b91506020850151601f1980868503016040870152611b938483611a43565b93506040870151915080868503016060870152611bb08483611acf565b93506060870151915080868503016080870152611bcd8483611acf565b935060808701519150808685030160a087015250611beb8382611b24565b92505060a085015160c085015260c0850151611c0b60e086018215159052565b5060e0850151801515858301525090949350505050565b80356001600160a01b0381168114611c3957600080fd5b919050565b600080600060408486031215611c5357600080fd5b611c5c84611c22565b9250602084013567ffffffffffffffff80821115611c7957600080fd5b818601915086601f830112611c8d57600080fd5b813581811115611c9c57600080fd5b876020828501011115611cae57600080fd5b6020830194508093505050509250925092565b8215158152604060208201526000611cdc6040830184611aa3565b949350505050565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff81118282101715611d2357611d23611ce4565b604052919050565b600067ffffffffffffffff821115611d4557611d45611ce4565b5060051b60200190565b600082601f830112611d6057600080fd5b81356020611d75611d7083611d2b565b611cfa565b82815260059290921b84018101918181019086841115611d9457600080fd5b8286015b84811015611db657611da981611c22565b8352918301918301611d98565b509695505050505050565b600082601f830112611dd257600080fd5b81356020611de2611d7083611d2b565b82815260059290921b84018101918181019086841115611e0157600080fd5b8286015b84811015611db65780358352918301918301611e05565b600067ffffffffffffffff821115611e3657611e36611ce4565b50601f01601f191660200190565b6000611e52611d7084611e1c565b9050828152838383011115611e6657600080fd5b828260208301376000602084830101529392505050565b600082601f830112611e8e57600080fd5b81356020611e9e611d7083611d2b565b82815260059290921b84018101918181019086841115611ebd57600080fd5b8286015b84811015611db657803567ffffffffffffffff811115611ee15760008081fd5b8701603f81018913611ef35760008081fd5b611f04898683013560408401611e44565b845250918301918301611ec1565b600082601f830112611f2357600080fd5b81356020611f33611d7083611d2b565b82815260059290921b84018101918181019086841115611f5257600080fd5b8286015b84811015611db657803567ffffffffffffffff811115611f765760008081fd5b8701603f81018913611f885760008081fd5b611f99898683013560408401611e44565b845250918301918301611f56565b801515811461041c57600080fd5b600082601f830112611fc657600080fd5b81356020611fd6611d7083611d2b565b82815260059290921b84018101918181019086841115611ff557600080fd5b8286015b84811015611db657803561200c81611fa7565b8352918301918301611ff9565b600080600080600060a0868803121561203157600080fd5b853567ffffffffffffffff8082111561204957600080fd5b61205589838a01611d4f565b9650602088013591508082111561206b57600080fd5b61207789838a01611dc1565b9550604088013591508082111561208d57600080fd5b61209989838a01611e7d565b945060608801359150808211156120af57600080fd5b6120bb89838a01611f12565b935060808801359150808211156120d157600080fd5b506120de88828901611fb5565b9150509295509295909350565b6000602082840312156120fd57600080fd5b61210682611c22565b9392505050565b634e487b7160e01b600052603260045260246000fd5b600181811c9082168061213757607f821691505b6020821081141561075a57634e487b7160e01b600052602260045260246000fd5b6000821982111561217957634e487b7160e01b600052601160045260246000fd5b500190565b8183823760009101908152919050565b6020815260006121066020830184611acf565b60018060a01b038716815285602082015260c0604082015260006121c860c0830187611aa3565b82810360608401526121da8187611aa3565b6080840195909552505090151560a090910152949350505050565b60c0808252875190820181905260009060209060e0840190828b01845b828110156122375781516001600160a01b031684529284019290840190600101612212565b5050508381038285015261224b818a611a43565b91505082810360408401526122608188611acf565b905082810360608401526122748187611acf565b905082810360808401526122888186611b24565b9150508260a0830152979650505050505050565b6001600160e01b03198316815281516000906122bf816004850160208701611a73565b919091016004019392505050565b6001600160a01b0383168152604060208201819052600090611cdc90830184611aa3565b6000806040838503121561230457600080fd5b825161230f81611fa7565b602084015190925067ffffffffffffffff81111561232c57600080fd5b8301601f8101851361233d57600080fd5b805161234b611d7082611e1c565b81815286602083850101111561236057600080fd5b612371826020830160208601611a73565b8093505050509250929050565b60008251612390818460208701611a73565b919091019291505056fea26469706673582212204d15d998b970c88abcf61ca388d9d45b990eea314f3479db111535845712274d64736f6c634300080a0033", - "deployedBytecode": "0x6080604052600436106101295760003560e01c8063b3c82e92116100ab578063d9a4cbdf1161006f578063d9a4cbdf1461031e578063dbd183881461033e578063e471b02614610353578063e68a5c3d14610373578063fc52539514610393578063fe0d94c1146103b357600080fd5b8063b3c82e9214610288578063b68df16d146102b5578063c3a76886146102d6578063cebc9a82146102f4578063d89aac391461030957600080fd5b80635ab98d5a116100f25780635ab98d5a146101c157806364d62353146101e15780638533f33714610201578063a75b87d214610216578063b1fc87961461024857600080fd5b80625c33e11461012e57806303c2762114610130578063083a73a21461015457806340e58ee5146101745780635748c13014610194575b600080fd5b005b34801561013c57600080fd5b506002545b6040519081526020015b60405180910390f35b34801561016057600080fd5b5061012e61016f3660046119a8565b6103c6565b34801561018057600080fd5b5061012e61018f3660046119a8565b61041f565b3480156101a057600080fd5b506101b46101af3660046119a8565b6106ca565b60405161014b91906119d7565b3480156101cd57600080fd5b5061012e6101dc3660046119a8565b610760565b3480156101ed57600080fd5b5061012e6101fc3660046119a8565b6107ac565b34801561020d57600080fd5b50600554610141565b34801561022257600080fd5b506004546001600160a01b03165b6040516001600160a01b03909116815260200161014b565b34801561025457600080fd5b506102786102633660046119a8565b60009081526007602052604090205460ff1690565b604051901515815260200161014b565b34801561029457600080fd5b506102a86102a33660046119a8565b6107de565b60405161014b9190611b56565b6102c86102c3366004611c3e565b610b51565b60405161014b929190611cc1565b3480156102e257600080fd5b506008546001600160a01b0316610230565b34801561030057600080fd5b50600054610141565b34801561031557600080fd5b50600354610141565b34801561032a57600080fd5b5061012e610339366004612019565b610be2565b34801561034a57600080fd5b50600154610141565b34801561035f57600080fd5b5061012e61036e3660046119a8565b610c41565b34801561037f57600080fd5b5061012e61038e3660046120eb565b610c8c565b34801561039f57600080fd5b5061012e6103ae3660046120eb565b610d15565b61012e6103c13660046119a8565b610d3e565b3330146103e657604051631dbf5f2360e01b815260040160405180910390fd5b60025481116104085760405163cb2f2b2360e01b815260040160405180910390fd5b61041181611066565b61041c6000546110a7565b50565b6004546001600160a01b0316331461044a576040516377b6878160e11b815260040160405180910390fd5b6000610455826106ca565b6003811115610466576104666119c1565b146104845760405163050ac78b60e11b815260040160405180910390fd5b60008181526006602081905260408220908101805461ff001916610100179055805490915b81811015610699576106918360000182815481106104c9576104c961210d565b6000918252602090912001546001850180546001600160a01b0390921691849081106104f7576104f761210d565b90600052602060002001548560020184815481106105175761051761210d565b90600052602060002001805461052c90612123565b80601f016020809104026020016040519081016040528092919081815260200182805461055890612123565b80156105a55780601f1061057a576101008083540402835291602001916105a5565b820191906000526020600020905b81548152906001019060200180831161058857829003601f168201915b50505050508660030185815481106105bf576105bf61210d565b9060005260206000200180546105d490612123565b80601f016020809104026020016040519081016040528092919081815260200182805461060090612123565b801561064d5780601f106106225761010080835404028352916020019161064d565b820191906000526020600020905b81548152906001019060200180831161063057829003601f168201915b5050505050876005015488600401878154811061066c5761066c61210d565b90600052602060002090602091828204019190069054906101000a900460ff166110ed565b6001016104a9565b5060405183907f0743c673685efcbf3db8591d9e1d98336bc844fe4f4599e6f7efb6d71c02563490600090a2505050565b600081600554116106ee5760405163e5bc0e7b60e01b815260040160405180910390fd5b600082815260066020819052604090912090810154610100900460ff16156107195750600292915050565b600681015460ff161561072f5750600192915050565b60015481600501546107419190612158565b4211156107515750600392915050565b50600092915050565b50919050565b33301461078057604051631dbf5f2360e01b815260040160405180910390fd5b6102588110156107a3576040516301f6f9e560e71b815260040160405180910390fd5b61041c8161113f565b3330146107cc57604051631dbf5f2360e01b815260040160405180910390fd5b6107d5816110a7565b61041c81611180565b61082a6040518061010001604052806060815260200160608152602001606081526020016060815260200160608152602001600081526020016000151581526020016000151581525090565b60008281526006602090815260409182902082518154610120938102820184019094526101008101848152909391928492849184018282801561089657602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610878575b50505050508152602001600182018054806020026020016040519081016040528092919081815260200182805480156108ee57602002820191906000526020600020905b8154815260200190600101908083116108da575b5050505050815260200160028201805480602002602001604051908101604052809291908181526020016000905b828210156109c857838290600052602060002001805461093b90612123565b80601f016020809104026020016040519081016040528092919081815260200182805461096790612123565b80156109b45780601f10610989576101008083540402835291602001916109b4565b820191906000526020600020905b81548152906001019060200180831161099757829003601f168201915b50505050508152602001906001019061091c565b50505050815260200160038201805480602002602001604051908101604052809291908181526020016000905b82821015610aa1578382906000526020600020018054610a1490612123565b80601f0160208091040260200160405190810160405280929190818152602001828054610a4090612123565b8015610a8d5780601f10610a6257610100808354040283529160200191610a8d565b820191906000526020600020905b815481529060010190602001808311610a7057829003601f168201915b5050505050815260200190600101906109f5565b50505050815260200160048201805480602002602001604051908101604052809291908181526020018280548015610b1857602002820191906000526020600020906000905b825461010083900a900460ff161515815260206001928301818104948501949093039092029101808411610ae75790505b50505091835250506005820154602082015260069091015460ff8082161515604084015261010090910416151560609091015292915050565b60006060333014610b7557604051631dbf5f2360e01b815260040160405180910390fd5b60006060866001600160a01b03168686604051610b9392919061217e565b600060405180830381855af49150503d8060008114610bce576040519150601f19603f3d011682016040523d82523d6000602084013e610bd3565b606091505b50909890975095505050505050565b6008546001600160a01b03167311110000000000000000000000000000000011101933016001600160a01b031614610c2d576040516359e8359960e01b815260040160405180910390fd5b610c3a85858585856111c1565b5050505050565b333014610c6157604051631dbf5f2360e01b815260040160405180910390fd5b6003548110610c83576040516301b1029b60e61b815260040160405180910390fd5b6104118161142e565b333014610cac57604051631dbf5f2360e01b815260040160405180910390fd5b600854604080516001600160a01b03928316815291831660208301527f01dd0ca50426f21c1b37ce7f3e95eef45b4a55bc5da80a7b67b2c65a7463caf0910160405180910390a1600880546001600160a01b0319166001600160a01b0392909216919091179055565b333014610d3557604051631dbf5f2360e01b815260040160405180910390fd5b61041c8161146f565b6000610d49826106ca565b6003811115610d5a57610d5a6119c1565b14610d785760405163050ac78b60e11b815260040160405180910390fd5b60008181526006602052604090206005810154421015610dab57604051635192dd5560e01b815260040160405180910390fd5b60068101805460ff19166001179055805460008167ffffffffffffffff811115610dd757610dd7611ce4565b604051908082528060200260200182016040528015610e0a57816020015b6060815260200190600190039081610df55790505b50905060005b8281101561101d57610ff8846000018281548110610e3057610e3061210d565b6000918252602090912001546001860180546001600160a01b039092169184908110610e5e57610e5e61210d565b9060005260206000200154866002018481548110610e7e57610e7e61210d565b906000526020600020018054610e9390612123565b80601f0160208091040260200160405190810160405280929190818152602001828054610ebf90612123565b8015610f0c5780601f10610ee157610100808354040283529160200191610f0c565b820191906000526020600020905b815481529060010190602001808311610eef57829003601f168201915b5050505050876003018581548110610f2657610f2661210d565b906000526020600020018054610f3b90612123565b80601f0160208091040260200160405190810160405280929190818152602001828054610f6790612123565b8015610fb45780601f10610f8957610100808354040283529160200191610fb4565b820191906000526020600020905b815481529060010190602001808311610f9757829003601f168201915b50505050508860050154896004018781548110610fd357610fd361210d565b90600052602060002090602091828204019190069054906101000a900460ff166114d8565b82828151811061100a5761100a61210d565b6020908102919091010152600101610e10565b50336001600160a01b0316847ff5efc4bb09a12b6c9561a7e7ab02938a72a4351316b473d574fdaaa89c43eb9a83604051611058919061218e565b60405180910390a350505050565b60035460408051918252602082018390527faf46013422363beb5e6f00ab923cffe3574670494c864de2828b9d7c201fdde5910160405180910390a1600355565b6002548110156110ca576040516361759e6560e01b815260040160405180910390fd5b60035481111561041c576040516386dac63560e01b815260040160405180910390fd5b600086868686868660405160200161110a969594939291906121a1565b60408051601f198184030181529181528151602092830120600090815260079092529020805460ff1916905550505050505050565b60015460408051918252602082018390527f9953f3a71052edcd4ae7a0f97302839d1dda32ab93c1039207c91c866b094f72910160405180910390a1600155565b60005460408051918252602082018390527f43de56b886294fc29767e51a88b5c67fd24aefebc5ddf813b1d9b91b1df38444910160405180910390a1600055565b84516111e057604051636a8e3e9360e11b815260040160405180910390fd5b84518451811415806111f3575083518114155b806111ff575082518114155b8061120b575081518114155b1561122957604051630d10f63b60e01b815260040160405180910390fd5b6005546000805461123a9042612158565b600580546001019055905060005b8381101561135b5760008982815181106112645761126461210d565b602002602001015189838151811061127e5761127e61210d565b60200260200101518984815181106112985761129861210d565b60200260200101518985815181106112b2576112b261210d565b6020026020010151868a87815181106112cd576112cd61210d565b60200260200101516040516020016112ea969594939291906121a1565b60405160208183030381529060405280519060200120905061131b8160009081526007602052604090205460ff1690565b1561133957604051633b2f04e360e21b815260040160405180910390fd5b6000908152600760205260409020805460ff1916600190811790915501611248565b5060008281526006602090815260409091208951909161137f9183918c01906116be565b50875161139590600183019060208b0190611723565b5086516113ab90600283019060208a019061175e565b5085516113c190600383019060208901906117b7565b5084516113d79060048301906020880190611810565b50818160050181905550827f0325966a4aa089b42f4766ec96f599405102bb309e065f24874aff59082dbc8b8a8a8a8a8a8860405161141b969594939291906121f5565b60405180910390a2505050505050505050565b60025460408051918252602082018390527fc534cdcbe9b52100810d787afd57e4174322776fcb58872ea706f23e9319fa8d910160405180910390a1600255565b600454604080516001600160a01b03928316815291831660208301527f85bd8788d3c4a160f0f6254229589f137d5633a870dcb46f99ffe07b4da1894b910160405180910390a1600480546001600160a01b0319166001600160a01b0392909216919091179055565b6060854710156114fb57604051631e9acf1760e31b815260040160405180910390fd5b6000878787878787604051602001611518969594939291906121a1565b60408051601f198184030181529181528151602092830120600081815260079093529120805460ff191690558651909150606090611557575084611583565b86805190602001208660405160200161157192919061229c565b60405160208183030381529060405290505b6000606085156116055760405163b68df16d60e01b8152309063b68df16d908c906115b4908f9088906004016122cd565b60006040518083038185885af11580156115d2573d6000803e3d6000fd5b50505050506040513d6000823e601f3d908101601f191682016040526115fb91908101906122f1565b9092509050611667565b8a6001600160a01b03168a8460405161161e919061237e565b60006040518083038185875af1925050503d806000811461165b576040519150601f19603f3d011682016040523d82523d6000602084013e611660565b606091505b5090925090505b6116718282611680565b9b9a5050505050505050505050565b6060821561168f5750806116b8565b81511561169f5781518083602001fd5b6040516332f63ed360e21b815260040160405180910390fd5b92915050565b828054828255906000526020600020908101928215611713579160200282015b8281111561171357825182546001600160a01b0319166001600160a01b039091161782556020909201916001909101906116de565b5061171f9291506118ac565b5090565b828054828255906000526020600020908101928215611713579160200282015b82811115611713578251825591602001919060010190611743565b8280548282559060005260206000209081019282156117ab579160200282015b828111156117ab578251805161179b9184916020909101906118c1565b509160200191906001019061177e565b5061171f929150611934565b828054828255906000526020600020908101928215611804579160200282015b8281111561180457825180516117f49184916020909101906118c1565b50916020019190600101906117d7565b5061171f929150611951565b82805482825590600052602060002090601f016020900481019282156117135791602002820160005b8382111561187657835183826101000a81548160ff0219169083151502179055509260200192600101602081600001049283019260010302611839565b80156118a35782816101000a81549060ff0219169055600101602081600001049283019260010302611876565b505061171f9291505b5b8082111561171f57600081556001016118ad565b8280546118cd90612123565b90600052602060002090601f0160209004810192826118ef5760008555611713565b82601f1061190857805160ff1916838001178555611713565b828001600101855582156117135791820182811115611713578251825591602001919060010190611743565b8082111561171f576000611948828261196e565b50600101611934565b8082111561171f576000611965828261196e565b50600101611951565b50805461197a90612123565b6000825580601f1061198a575050565b601f01602090049060005260206000209081019061041c91906118ac565b6000602082840312156119ba57600080fd5b5035919050565b634e487b7160e01b600052602160045260246000fd5b60208101600483106119f957634e487b7160e01b600052602160045260246000fd5b91905290565b600081518084526020808501945080840160005b83811015611a385781516001600160a01b031687529582019590820190600101611a13565b509495945050505050565b600081518084526020808501945080840160005b83811015611a3857815187529582019590820190600101611a57565b60005b83811015611a8e578181015183820152602001611a76565b83811115611a9d576000848401525b50505050565b60008151808452611abb816020860160208601611a73565b601f01601f19169290920160200192915050565b600081518084526020808501808196508360051b8101915082860160005b85811015611b17578284038952611b05848351611aa3565b98850198935090840190600101611aed565b5091979650505050505050565b600081518084526020808501945080840160005b83811015611a38578151151587529582019590820190600101611b38565b6020815260008251610100806020850152611b756101208501836119ff565b91506020850151601f1980868503016040870152611b938483611a43565b93506040870151915080868503016060870152611bb08483611acf565b93506060870151915080868503016080870152611bcd8483611acf565b935060808701519150808685030160a087015250611beb8382611b24565b92505060a085015160c085015260c0850151611c0b60e086018215159052565b5060e0850151801515858301525090949350505050565b80356001600160a01b0381168114611c3957600080fd5b919050565b600080600060408486031215611c5357600080fd5b611c5c84611c22565b9250602084013567ffffffffffffffff80821115611c7957600080fd5b818601915086601f830112611c8d57600080fd5b813581811115611c9c57600080fd5b876020828501011115611cae57600080fd5b6020830194508093505050509250925092565b8215158152604060208201526000611cdc6040830184611aa3565b949350505050565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff81118282101715611d2357611d23611ce4565b604052919050565b600067ffffffffffffffff821115611d4557611d45611ce4565b5060051b60200190565b600082601f830112611d6057600080fd5b81356020611d75611d7083611d2b565b611cfa565b82815260059290921b84018101918181019086841115611d9457600080fd5b8286015b84811015611db657611da981611c22565b8352918301918301611d98565b509695505050505050565b600082601f830112611dd257600080fd5b81356020611de2611d7083611d2b565b82815260059290921b84018101918181019086841115611e0157600080fd5b8286015b84811015611db65780358352918301918301611e05565b600067ffffffffffffffff821115611e3657611e36611ce4565b50601f01601f191660200190565b6000611e52611d7084611e1c565b9050828152838383011115611e6657600080fd5b828260208301376000602084830101529392505050565b600082601f830112611e8e57600080fd5b81356020611e9e611d7083611d2b565b82815260059290921b84018101918181019086841115611ebd57600080fd5b8286015b84811015611db657803567ffffffffffffffff811115611ee15760008081fd5b8701603f81018913611ef35760008081fd5b611f04898683013560408401611e44565b845250918301918301611ec1565b600082601f830112611f2357600080fd5b81356020611f33611d7083611d2b565b82815260059290921b84018101918181019086841115611f5257600080fd5b8286015b84811015611db657803567ffffffffffffffff811115611f765760008081fd5b8701603f81018913611f885760008081fd5b611f99898683013560408401611e44565b845250918301918301611f56565b801515811461041c57600080fd5b600082601f830112611fc657600080fd5b81356020611fd6611d7083611d2b565b82815260059290921b84018101918181019086841115611ff557600080fd5b8286015b84811015611db657803561200c81611fa7565b8352918301918301611ff9565b600080600080600060a0868803121561203157600080fd5b853567ffffffffffffffff8082111561204957600080fd5b61205589838a01611d4f565b9650602088013591508082111561206b57600080fd5b61207789838a01611dc1565b9550604088013591508082111561208d57600080fd5b61209989838a01611e7d565b945060608801359150808211156120af57600080fd5b6120bb89838a01611f12565b935060808801359150808211156120d157600080fd5b506120de88828901611fb5565b9150509295509295909350565b6000602082840312156120fd57600080fd5b61210682611c22565b9392505050565b634e487b7160e01b600052603260045260246000fd5b600181811c9082168061213757607f821691505b6020821081141561075a57634e487b7160e01b600052602260045260246000fd5b6000821982111561217957634e487b7160e01b600052601160045260246000fd5b500190565b8183823760009101908152919050565b6020815260006121066020830184611acf565b60018060a01b038716815285602082015260c0604082015260006121c860c0830187611aa3565b82810360608401526121da8187611aa3565b6080840195909552505090151560a090910152949350505050565b60c0808252875190820181905260009060209060e0840190828b01845b828110156122375781516001600160a01b031684529284019290840190600101612212565b5050508381038285015261224b818a611a43565b91505082810360408401526122608188611acf565b905082810360608401526122748187611acf565b905082810360808401526122888186611b24565b9150508260a0830152979650505050505050565b6001600160e01b03198316815281516000906122bf816004850160208701611a73565b919091016004019392505050565b6001600160a01b0383168152604060208201819052600090611cdc90830184611aa3565b6000806040838503121561230457600080fd5b825161230f81611fa7565b602084015190925067ffffffffffffffff81111561232c57600080fd5b8301601f8101851361233d57600080fd5b805161234b611d7082611e1c565b81815286602083850101111561236057600080fd5b612371826020830160208601611a73565b8093505050509250929050565b60008251612390818460208701611a73565b919091019291505056fea26469706673582212204d15d998b970c88abcf61ca388d9d45b990eea314f3479db111535845712274d64736f6c634300080a0033", - "linkReferences": {}, - "deployedLinkReferences": {} -} diff --git a/utils/arbitrum/artifacts/L1GatewayRouter.json b/utils/arbitrum/artifacts/L1GatewayRouter.json deleted file mode 100644 index 45af03c2..00000000 --- a/utils/arbitrum/artifacts/L1GatewayRouter.json +++ /dev/null @@ -1,582 +0,0 @@ -{ - "_format": "hh-sol-artifact-1", - "contractName": "L1GatewayRouter", - "sourceName": "contracts/tokenbridge/ethereum/gateway/L1GatewayRouter.sol", - "abi": [ - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "address", - "name": "newDefaultGateway", - "type": "address" - } - ], - "name": "DefaultGatewayUpdated", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "l1Token", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "gateway", - "type": "address" - } - ], - "name": "GatewaySet", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "token", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "_userFrom", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "_userTo", - "type": "address" - }, - { - "indexed": false, - "internalType": "address", - "name": "gateway", - "type": "address" - } - ], - "name": "TransferRouted", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "_from", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "_to", - "type": "address" - }, - { - "indexed": true, - "internalType": "uint256", - "name": "_seqNum", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "bytes", - "name": "_data", - "type": "bytes" - } - ], - "name": "TxToL2", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "address", - "name": "newSource", - "type": "address" - } - ], - "name": "WhitelistSourceUpdated", - "type": "event" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "l1ERC20", - "type": "address" - } - ], - "name": "calculateL2TokenAddress", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "counterpartGateway", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "defaultGateway", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - }, - { - "internalType": "address", - "name": "", - "type": "address" - }, - { - "internalType": "address", - "name": "", - "type": "address" - }, - { - "internalType": "uint256", - "name": "", - "type": "uint256" - }, - { - "internalType": "bytes", - "name": "", - "type": "bytes" - } - ], - "name": "finalizeInboundTransfer", - "outputs": [], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_token", - "type": "address" - } - ], - "name": "getGateway", - "outputs": [ - { - "internalType": "address", - "name": "gateway", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_token", - "type": "address" - }, - { - "internalType": "address", - "name": "_from", - "type": "address" - }, - { - "internalType": "address", - "name": "_to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "_amount", - "type": "uint256" - }, - { - "internalType": "bytes", - "name": "_data", - "type": "bytes" - } - ], - "name": "getOutboundCalldata", - "outputs": [ - { - "internalType": "bytes", - "name": "", - "type": "bytes" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "inbox", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_owner", - "type": "address" - }, - { - "internalType": "address", - "name": "_defaultGateway", - "type": "address" - }, - { - "internalType": "address", - "name": "_whitelist", - "type": "address" - }, - { - "internalType": "address", - "name": "_counterpartGateway", - "type": "address" - }, - { - "internalType": "address", - "name": "_inbox", - "type": "address" - } - ], - "name": "initialize", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "name": "l1TokenToGateway", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_token", - "type": "address" - }, - { - "internalType": "address", - "name": "_to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "_amount", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "_maxGas", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "_gasPriceBid", - "type": "uint256" - }, - { - "internalType": "bytes", - "name": "_data", - "type": "bytes" - } - ], - "name": "outboundTransfer", - "outputs": [ - { - "internalType": "bytes", - "name": "", - "type": "bytes" - } - ], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [], - "name": "owner", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "postUpgradeInit", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "router", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "newL1DefaultGateway", - "type": "address" - }, - { - "internalType": "uint256", - "name": "_maxGas", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "_gasPriceBid", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "_maxSubmissionCost", - "type": "uint256" - } - ], - "name": "setDefaultGateway", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_gateway", - "type": "address" - }, - { - "internalType": "uint256", - "name": "_maxGas", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "_gasPriceBid", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "_maxSubmissionCost", - "type": "uint256" - }, - { - "internalType": "address", - "name": "_creditBackAddress", - "type": "address" - } - ], - "name": "setGateway", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_gateway", - "type": "address" - }, - { - "internalType": "uint256", - "name": "_maxGas", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "_gasPriceBid", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "_maxSubmissionCost", - "type": "uint256" - } - ], - "name": "setGateway", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address[]", - "name": "_token", - "type": "address[]" - }, - { - "internalType": "address[]", - "name": "_gateway", - "type": "address[]" - }, - { - "internalType": "uint256", - "name": "_maxGas", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "_gasPriceBid", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "_maxSubmissionCost", - "type": "uint256" - } - ], - "name": "setGateways", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "newOwner", - "type": "address" - } - ], - "name": "setOwner", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "newSource", - "type": "address" - } - ], - "name": "updateWhitelistSource", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "whitelist", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - } - ], - "bytecode": "0x608060405234801561001057600080fd5b50611f1d806100206000396000f3fe60806040526004361061011f5760003560e01c806393e59dc1116100a0578063d2ce7d6511610064578063d2ce7d651461066a578063dd61456914610704578063ed08fdc61461073c578063f887ea401461076f578063fb0e722b146107845761011f565b806393e59dc11461048c57806395fcea78146104a1578063a0c76a96146104b6578063a7e28d4814610604578063bda009fe146106375761011f565b80632e567b36116100e75780632e567b361461024857806347466f98146102de5780635625a95214610311578063658b53f4146103495780638da5cb5b146104775761011f565b8063032958021461012457806313af4035146101555780631459457a1461018a5780632d67b72d146101df5780632db09c1c14610233575b600080fd5b34801561013057600080fd5b50610139610799565b604080516001600160a01b039092168252519081900360200190f35b34801561016157600080fd5b506101886004803603602081101561017857600080fd5b50356001600160a01b03166107a8565b005b34801561019657600080fd5b50610188600480360360a08110156101ad57600080fd5b506001600160a01b03813581169160208101358216916040820135811691606081013582169160809091013516610861565b610221600480360360a08110156101f557600080fd5b506001600160a01b038135811691602081013591604082013591606081013591608090910135166108af565b60408051918252519081900360200190f35b34801561023f57600080fd5b50610139610b0c565b610188600480360360a081101561025e57600080fd5b6001600160a01b03823581169260208101358216926040820135909216916060820135919081019060a081016080820135600160201b8111156102a057600080fd5b8201836020820111156102b257600080fd5b803590602001918460018302840111600160201b831117156102d357600080fd5b509092509050610b1b565b3480156102ea57600080fd5b506101886004803603602081101561030157600080fd5b50356001600160a01b0316610b5f565b6102216004803603608081101561032757600080fd5b506001600160a01b038135169060208101359060408101359060600135610c02565b610221600480360360a081101561035f57600080fd5b810190602081018135600160201b81111561037957600080fd5b82018360208201111561038b57600080fd5b803590602001918460208302840111600160201b831117156103ac57600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295949360208101935035915050600160201b8111156103fb57600080fd5b82018360208201111561040d57600080fd5b803590602001918460208302840111600160201b8311171561042e57600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295505082359350505060208101359060400135610d9f565b34801561048357600080fd5b50610139610e06565b34801561049857600080fd5b50610139610e15565b3480156104ad57600080fd5b50610188610e24565b3480156104c257600080fd5b5061058f600480360360a08110156104d957600080fd5b6001600160a01b03823581169260208101358216926040820135909216916060820135919081019060a081016080820135600160201b81111561051b57600080fd5b82018360208201111561052d57600080fd5b803590602001918460018302840111600160201b8311171561054e57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550610e81945050505050565b6040805160208082528351818301528351919283929083019185019080838360005b838110156105c95781810151838201526020016105b1565b50505050905090810190601f1680156105f65780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561061057600080fd5b506101396004803603602081101561062757600080fd5b50356001600160a01b0316611083565b34801561064357600080fd5b506101396004803603602081101561065a57600080fd5b50356001600160a01b0316611134565b61058f600480360360c081101561068057600080fd5b6001600160a01b0382358116926020810135909116916040820135916060810135916080820135919081019060c0810160a0820135600160201b8111156106c657600080fd5b8201836020820111156106d857600080fd5b803590602001918460018302840111600160201b831117156106f957600080fd5b509092509050611196565b6102216004803603608081101561071a57600080fd5b506001600160a01b0381351690602081013590604081013590606001356113ba565b34801561074857600080fd5b506101396004803603602081101561075f57600080fd5b50356001600160a01b03166113d2565b34801561077b57600080fd5b506101396113ed565b34801561079057600080fd5b506101396113fc565b6004546001600160a01b031681565b6005546001600160a01b031633146107f4576040805162461bcd60e51b815260206004820152600a60248201526927a7262cafa7aba722a960b11b604482015290519081900360640190fd5b6001600160a01b03811661083f576040805162461bcd60e51b815260206004820152600d60248201526c24a72b20a624a22fa7aba722a960991b604482015290519081900360640190fd5b600580546001600160a01b0319166001600160a01b0392909216919091179055565b61086d8260008661140b565b600580546001600160a01b03199081166001600160a01b0397881617909155600080548216948716949094179093556006805490931694169390931790555050565b600061a4b160ff16336001600160a01b0316638e5f5ad16040518163ffffffff1660e01b815260040160206040518083038186803b1580156108f057600080fd5b505afa158015610904573d6000803e3d6000fd5b505050506040513d602081101561091a57600080fd5b505160ff1614610963576040805162461bcd60e51b815260206004820152600f60248201526e1393d517d0549097d1539050931151608a1b604482015290519081900360640190fd5b610975866001600160a01b0316611482565b6109b8576040805162461bcd60e51b815260206004820152600f60248201526e1393d517d513d7d0d3d395149050d5608a1b604482015290519081900360640190fd5b60006109c333611134565b90506001600160a01b038116158015906109eb57506004546001600160a01b03828116911614155b15610a5657866001600160a01b0316816001600160a01b031614610a56576040805162461bcd60e51b815260206004820152601b60248201527f4e4f5f5550444154455f544f5f444946464552454e545f414444520000000000604482015290519081900360640190fd5b604080516001808252818301909252606091602080830190803683370190505090503381600081518110610a8657fe5b6001600160a01b0392909216602092830291909101909101526040805160018082528183019092526060918160200160208202803683370190505090508881600081518110610ad157fe5b60200260200101906001600160a01b031690816001600160a01b031681525050610aff82828a8a8a8a611488565b9998505050505050505050565b6001546001600160a01b031681565b6040805162461bcd60e51b815260206004820152601460248201527327a7262cafa7aaaa2127aaa7222fa927aaaa22a960611b604482015290519081900360640190fd5b6000546001600160a01b03163314610bae576040805162461bcd60e51b815260206004820152600d60248201526c1393d517d19493d357d31254d5609a1b604482015290519081900360640190fd5b600080546001600160a01b0383166001600160a01b0319909116811790915560408051918252517f37389c47920d5cc3229678a0205d0455002c07541a4139ebdce91ac2274657779181900360200190a150565b6005546000906001600160a01b03163314610c51576040805162461bcd60e51b815260206004820152600a60248201526927a7262cafa7aba722a960b11b604482015290519081900360640190fd5b600480546001600160a01b0387166001600160a01b0319909116811790915560408051918252517f3a8f8eb961383a94d41d193e16a3af73eaddfd5764a4c640257323a1603ac3319181900360200190a160006001600160a01b03861615610d1b57856001600160a01b0316632db09c1c6040518163ffffffff1660e01b815260040160206040518083038186803b158015610cec57600080fd5b505afa158015610d00573d6000803e3d6000fd5b505050506040513d6020811015610d1657600080fd5b505190505b604080516001600160a01b038084166024808401919091528351808403909101815260449092018352602082810180516001600160e01b031663f7c9362f60e01b17905260065460015485516060810187528981529283018b90529482018990529293610d949383169216903390349060009087611905565b979650505050505050565b6005546000906001600160a01b03163314610dee576040805162461bcd60e51b815260206004820152600a60248201526927a7262cafa7aba722a960b11b604482015290519081900360640190fd5b610dfc868686868633611488565b9695505050505050565b6005546001600160a01b031681565b6000546001600160a01b031681565b6000610e2e611924565b9050336001600160a01b03821614610e7e576040805162461bcd60e51b815260206004820152600e60248201526d2727aa2fa32927a6afa0a226a4a760911b604482015290519081900360640190fd5b50565b60606000610e8e87611134565b9050806001600160a01b031663a0c76a9688888888886040518663ffffffff1660e01b815260040180866001600160a01b03166001600160a01b03168152602001856001600160a01b03166001600160a01b03168152602001846001600160a01b03166001600160a01b0316815260200183815260200180602001828103825283818151815260200191508051906020019080838360005b83811015610f3e578181015183820152602001610f26565b50505050905090810190601f168015610f6b5780820380516001836020036101000a031916815260200191505b50965050505050505060006040518083038186803b158015610f8c57600080fd5b505afa158015610fa0573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526020811015610fc957600080fd5b8101908080516040519392919084600160201b821115610fe857600080fd5b908301906020820185811115610ffd57600080fd5b8251600160201b81118282018810171561101657600080fd5b82525081516020918201929091019080838360005b8381101561104357818101518382015260200161102b565b50505050905090810190601f1680156110705780820380516001836020036101000a031916815260200191505b5060405250505091505095945050505050565b60008061108f83611134565b90506001600160a01b0381166110a957600091505061112f565b806001600160a01b031663a7e28d48846040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b1580156110ff57600080fd5b505afa158015611113573d6000803e3d6000fd5b505050506040513d602081101561112957600080fd5b50519150505b919050565b6001600160a01b03808216600090815260036020526040902054168061116257506004546001600160a01b03165b6001600160a01b038116600114806111895750611187816001600160a01b0316611482565b155b1561112f5750600061112f565b6000546060906001600160a01b031615611264576000546040805163babcc53960e01b815233600482015290516001600160a01b039092169163babcc53991602480820192602092909190829003018186803b1580156111f557600080fd5b505afa158015611209573d6000803e3d6000fd5b505050506040513d602081101561121f57600080fd5b5051611264576040805162461bcd60e51b815260206004820152600f60248201526e1393d517d5d2125511531254d51151608a1b604482015290519081900360640190fd5b60008383604081101561127657600080fd5b81359190810190604081016020820135600160201b81111561129757600080fd5b8201836020820111156112a957600080fd5b803590602001918460018302840111600160201b831117156112ca57600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509697505050508989028501935050508215159050611357576040805162461bcd60e51b81526020600482015260126024820152711393d7d4d550935254d4d253d397d0d3d4d560721b604482015290519081900360640190fd5b80341461139d576040805162461bcd60e51b815260206004820152600f60248201526e57524f4e475f4554485f56414c554560881b604482015290519081900360640190fd5b6113ac8a8a8a8a8a8a8a611949565b9a9950505050505050505050565b60006113c985858585336108af565b95945050505050565b6003602052600090815260409020546001600160a01b031681565b6002546001600160a01b031681565b6006546001600160a01b031681565b6001600160a01b03821615611454576040805162461bcd60e51b815260206004820152600a6024820152692120a22fa927aaaa22a960b11b604482015290519081900360640190fd5b61145e8383611b9e565b600480546001600160a01b0319166001600160a01b03929092169190911790555050565b3b151590565b600085518751146114cf576040805162461bcd60e51b815260206004820152600c60248201526b0aea49e9c8ebe988a9c8ea8960a31b604482015290519081900360640190fd5b60005b87518110156117d0578681815181106114e757fe5b6020026020010151600360008a84815181106114ff57fe5b60200260200101516001600160a01b03166001600160a01b0316815260200190815260200160002060006101000a8154816001600160a01b0302191690836001600160a01b0316021790555086818151811061155757fe5b60200260200101516001600160a01b031688828151811061157457fe5b60200260200101516001600160a01b03167f812ca95fe4492a9e2d1f2723c2c40c03a60a27b059581ae20ac4e4d73bfba35460405160405180910390a360006001600160a01b03168782815181106115c857fe5b60200260200101516001600160a01b03161415801561160d575060016001600160a01b03168782815181106115f957fe5b60200260200101516001600160a01b031614155b156117c85760006001600160a01b031687828151811061162957fe5b60200260200101516001600160a01b031663a7e28d488a848151811061164b57fe5b60200260200101516040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b15801561169957600080fd5b505afa1580156116ad573d6000803e3d6000fd5b505050506040513d60208110156116c357600080fd5b50516001600160a01b03161415611721576040805162461bcd60e51b815260206004820152601c60248201527f544f4b454e5f4e4f545f48414e444c45445f42595f4741544557415900000000604482015290519081900360640190fd5b86818151811061172d57fe5b60200260200101516001600160a01b0316632db09c1c6040518163ffffffff1660e01b815260040160206040518083038186803b15801561176d57600080fd5b505afa158015611781573d6000803e3d6000fd5b505050506040513d602081101561179757600080fd5b505187518890839081106117a757fe5b60200260200101906001600160a01b031690816001600160a01b0316815250505b6001016114d2565b506060634201f98560e01b8888604051602401808060200180602001838103835285818151815260200191508051906020019060200280838360005b8381101561182457818101518382015260200161180c565b50505050905001838103825284818151815260200191508051906020019060200280838360005b8381101561186357818101518382015260200161184b565b50505050905001945050505050604051602081830303815290604052906001600160e01b0319166020820180516001600160e01b03838183161783525050505090506118f9600660009054906101000a90046001600160a01b0316600160009054906101000a90046001600160a01b03168534600060405180606001604052808b81526020018d81526020018c81525087611905565b98975050505050505050565b60006118f98888888888886000015189602001518a604001518a611c6a565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b6060600061195689611134565b90506060611965338686611e7d565b604080516001600160a01b0385811682529151929350818c169233928e16917f85291dff2161a93c2f12c819d31889c96c63042116f5bc5a205aa701c2c429f5919081900360200190a4816001600160a01b031663d2ce7d65348c8c8c8c8c886040518863ffffffff1660e01b815260040180876001600160a01b03166001600160a01b03168152602001866001600160a01b03166001600160a01b0316815260200185815260200184815260200183815260200180602001828103825283818151815260200191508051906020019080838360005b83811015611a53578181015183820152602001611a3b565b50505050905090810190601f168015611a805780820380516001836020036101000a031916815260200191505b509750505050505050506000604051808303818588803b158015611aa357600080fd5b505af1158015611ab7573d6000803e3d6000fd5b50505050506040513d6000823e601f3d908101601f191682016040526020811015611ae157600080fd5b8101908080516040519392919084600160201b821115611b0057600080fd5b908301906020820185811115611b1557600080fd5b8251600160201b811182820188101715611b2e57600080fd5b82525081516020918201929091019080838360005b83811015611b5b578181015183820152602001611b43565b50505050905090810190601f168015611b885780820380516001836020036101000a031916815260200191505b5060405250505092505050979650505050505050565b6001600160a01b038216611bef576040805162461bcd60e51b81526020600482015260136024820152721253959053125117d0d3d55395115494105495606a1b604482015290519081900360640190fd5b6001546001600160a01b031615611c3c576040805162461bcd60e51b815260206004820152600c60248201526b1053149150511657d253925560a21b604482015290519081900360640190fd5b600180546001600160a01b039384166001600160a01b03199182161790915560028054929093169116179055565b6000808a6001600160a01b031663679b6ded898c8a8a8e8f8c8c8c6040518a63ffffffff1660e01b815260040180896001600160a01b03166001600160a01b03168152602001888152602001878152602001866001600160a01b03166001600160a01b03168152602001856001600160a01b03166001600160a01b0316815260200184815260200183815260200180602001828103825283818151815260200191508051906020019080838360005b83811015611d31578181015183820152602001611d19565b50505050905090810190601f168015611d5e5780820380516001836020036101000a031916815260200191505b5099505050505050505050506020604051808303818588803b158015611d8357600080fd5b505af1158015611d97573d6000803e3d6000fd5b50505050506040513d6020811015611dae57600080fd5b81019080805190602001909291905050509050808a6001600160a01b03168a6001600160a01b03167fc1d1490cf25c3b40d600dfb27c7680340ed1ab901b7e8f3551280968a3b372b0866040518080602001828103825283818151815260200191508051906020019080838360005b83811015611e35578181015183820152602001611e1d565b50505050905090810190601f168015611e625780820380516001836020036101000a031916815260200191505b509250505060405180910390a49a9950505050505050505050565b606083838360405160200180846001600160a01b03166001600160a01b0316815260200180602001828103825284848281815260200192508082843760008184015260408051601f19601f909301831690940184810390920184525250999850505050505050505056fea2646970667358221220d7743bc55082d15fef9972e04a86235c42530952c92b25d83792f50a8a6830f564736f6c634300060b0033", - "deployedBytecode": "0x60806040526004361061011f5760003560e01c806393e59dc1116100a0578063d2ce7d6511610064578063d2ce7d651461066a578063dd61456914610704578063ed08fdc61461073c578063f887ea401461076f578063fb0e722b146107845761011f565b806393e59dc11461048c57806395fcea78146104a1578063a0c76a96146104b6578063a7e28d4814610604578063bda009fe146106375761011f565b80632e567b36116100e75780632e567b361461024857806347466f98146102de5780635625a95214610311578063658b53f4146103495780638da5cb5b146104775761011f565b8063032958021461012457806313af4035146101555780631459457a1461018a5780632d67b72d146101df5780632db09c1c14610233575b600080fd5b34801561013057600080fd5b50610139610799565b604080516001600160a01b039092168252519081900360200190f35b34801561016157600080fd5b506101886004803603602081101561017857600080fd5b50356001600160a01b03166107a8565b005b34801561019657600080fd5b50610188600480360360a08110156101ad57600080fd5b506001600160a01b03813581169160208101358216916040820135811691606081013582169160809091013516610861565b610221600480360360a08110156101f557600080fd5b506001600160a01b038135811691602081013591604082013591606081013591608090910135166108af565b60408051918252519081900360200190f35b34801561023f57600080fd5b50610139610b0c565b610188600480360360a081101561025e57600080fd5b6001600160a01b03823581169260208101358216926040820135909216916060820135919081019060a081016080820135600160201b8111156102a057600080fd5b8201836020820111156102b257600080fd5b803590602001918460018302840111600160201b831117156102d357600080fd5b509092509050610b1b565b3480156102ea57600080fd5b506101886004803603602081101561030157600080fd5b50356001600160a01b0316610b5f565b6102216004803603608081101561032757600080fd5b506001600160a01b038135169060208101359060408101359060600135610c02565b610221600480360360a081101561035f57600080fd5b810190602081018135600160201b81111561037957600080fd5b82018360208201111561038b57600080fd5b803590602001918460208302840111600160201b831117156103ac57600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295949360208101935035915050600160201b8111156103fb57600080fd5b82018360208201111561040d57600080fd5b803590602001918460208302840111600160201b8311171561042e57600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295505082359350505060208101359060400135610d9f565b34801561048357600080fd5b50610139610e06565b34801561049857600080fd5b50610139610e15565b3480156104ad57600080fd5b50610188610e24565b3480156104c257600080fd5b5061058f600480360360a08110156104d957600080fd5b6001600160a01b03823581169260208101358216926040820135909216916060820135919081019060a081016080820135600160201b81111561051b57600080fd5b82018360208201111561052d57600080fd5b803590602001918460018302840111600160201b8311171561054e57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550610e81945050505050565b6040805160208082528351818301528351919283929083019185019080838360005b838110156105c95781810151838201526020016105b1565b50505050905090810190601f1680156105f65780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561061057600080fd5b506101396004803603602081101561062757600080fd5b50356001600160a01b0316611083565b34801561064357600080fd5b506101396004803603602081101561065a57600080fd5b50356001600160a01b0316611134565b61058f600480360360c081101561068057600080fd5b6001600160a01b0382358116926020810135909116916040820135916060810135916080820135919081019060c0810160a0820135600160201b8111156106c657600080fd5b8201836020820111156106d857600080fd5b803590602001918460018302840111600160201b831117156106f957600080fd5b509092509050611196565b6102216004803603608081101561071a57600080fd5b506001600160a01b0381351690602081013590604081013590606001356113ba565b34801561074857600080fd5b506101396004803603602081101561075f57600080fd5b50356001600160a01b03166113d2565b34801561077b57600080fd5b506101396113ed565b34801561079057600080fd5b506101396113fc565b6004546001600160a01b031681565b6005546001600160a01b031633146107f4576040805162461bcd60e51b815260206004820152600a60248201526927a7262cafa7aba722a960b11b604482015290519081900360640190fd5b6001600160a01b03811661083f576040805162461bcd60e51b815260206004820152600d60248201526c24a72b20a624a22fa7aba722a960991b604482015290519081900360640190fd5b600580546001600160a01b0319166001600160a01b0392909216919091179055565b61086d8260008661140b565b600580546001600160a01b03199081166001600160a01b0397881617909155600080548216948716949094179093556006805490931694169390931790555050565b600061a4b160ff16336001600160a01b0316638e5f5ad16040518163ffffffff1660e01b815260040160206040518083038186803b1580156108f057600080fd5b505afa158015610904573d6000803e3d6000fd5b505050506040513d602081101561091a57600080fd5b505160ff1614610963576040805162461bcd60e51b815260206004820152600f60248201526e1393d517d0549097d1539050931151608a1b604482015290519081900360640190fd5b610975866001600160a01b0316611482565b6109b8576040805162461bcd60e51b815260206004820152600f60248201526e1393d517d513d7d0d3d395149050d5608a1b604482015290519081900360640190fd5b60006109c333611134565b90506001600160a01b038116158015906109eb57506004546001600160a01b03828116911614155b15610a5657866001600160a01b0316816001600160a01b031614610a56576040805162461bcd60e51b815260206004820152601b60248201527f4e4f5f5550444154455f544f5f444946464552454e545f414444520000000000604482015290519081900360640190fd5b604080516001808252818301909252606091602080830190803683370190505090503381600081518110610a8657fe5b6001600160a01b0392909216602092830291909101909101526040805160018082528183019092526060918160200160208202803683370190505090508881600081518110610ad157fe5b60200260200101906001600160a01b031690816001600160a01b031681525050610aff82828a8a8a8a611488565b9998505050505050505050565b6001546001600160a01b031681565b6040805162461bcd60e51b815260206004820152601460248201527327a7262cafa7aaaa2127aaa7222fa927aaaa22a960611b604482015290519081900360640190fd5b6000546001600160a01b03163314610bae576040805162461bcd60e51b815260206004820152600d60248201526c1393d517d19493d357d31254d5609a1b604482015290519081900360640190fd5b600080546001600160a01b0383166001600160a01b0319909116811790915560408051918252517f37389c47920d5cc3229678a0205d0455002c07541a4139ebdce91ac2274657779181900360200190a150565b6005546000906001600160a01b03163314610c51576040805162461bcd60e51b815260206004820152600a60248201526927a7262cafa7aba722a960b11b604482015290519081900360640190fd5b600480546001600160a01b0387166001600160a01b0319909116811790915560408051918252517f3a8f8eb961383a94d41d193e16a3af73eaddfd5764a4c640257323a1603ac3319181900360200190a160006001600160a01b03861615610d1b57856001600160a01b0316632db09c1c6040518163ffffffff1660e01b815260040160206040518083038186803b158015610cec57600080fd5b505afa158015610d00573d6000803e3d6000fd5b505050506040513d6020811015610d1657600080fd5b505190505b604080516001600160a01b038084166024808401919091528351808403909101815260449092018352602082810180516001600160e01b031663f7c9362f60e01b17905260065460015485516060810187528981529283018b90529482018990529293610d949383169216903390349060009087611905565b979650505050505050565b6005546000906001600160a01b03163314610dee576040805162461bcd60e51b815260206004820152600a60248201526927a7262cafa7aba722a960b11b604482015290519081900360640190fd5b610dfc868686868633611488565b9695505050505050565b6005546001600160a01b031681565b6000546001600160a01b031681565b6000610e2e611924565b9050336001600160a01b03821614610e7e576040805162461bcd60e51b815260206004820152600e60248201526d2727aa2fa32927a6afa0a226a4a760911b604482015290519081900360640190fd5b50565b60606000610e8e87611134565b9050806001600160a01b031663a0c76a9688888888886040518663ffffffff1660e01b815260040180866001600160a01b03166001600160a01b03168152602001856001600160a01b03166001600160a01b03168152602001846001600160a01b03166001600160a01b0316815260200183815260200180602001828103825283818151815260200191508051906020019080838360005b83811015610f3e578181015183820152602001610f26565b50505050905090810190601f168015610f6b5780820380516001836020036101000a031916815260200191505b50965050505050505060006040518083038186803b158015610f8c57600080fd5b505afa158015610fa0573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526020811015610fc957600080fd5b8101908080516040519392919084600160201b821115610fe857600080fd5b908301906020820185811115610ffd57600080fd5b8251600160201b81118282018810171561101657600080fd5b82525081516020918201929091019080838360005b8381101561104357818101518382015260200161102b565b50505050905090810190601f1680156110705780820380516001836020036101000a031916815260200191505b5060405250505091505095945050505050565b60008061108f83611134565b90506001600160a01b0381166110a957600091505061112f565b806001600160a01b031663a7e28d48846040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b1580156110ff57600080fd5b505afa158015611113573d6000803e3d6000fd5b505050506040513d602081101561112957600080fd5b50519150505b919050565b6001600160a01b03808216600090815260036020526040902054168061116257506004546001600160a01b03165b6001600160a01b038116600114806111895750611187816001600160a01b0316611482565b155b1561112f5750600061112f565b6000546060906001600160a01b031615611264576000546040805163babcc53960e01b815233600482015290516001600160a01b039092169163babcc53991602480820192602092909190829003018186803b1580156111f557600080fd5b505afa158015611209573d6000803e3d6000fd5b505050506040513d602081101561121f57600080fd5b5051611264576040805162461bcd60e51b815260206004820152600f60248201526e1393d517d5d2125511531254d51151608a1b604482015290519081900360640190fd5b60008383604081101561127657600080fd5b81359190810190604081016020820135600160201b81111561129757600080fd5b8201836020820111156112a957600080fd5b803590602001918460018302840111600160201b831117156112ca57600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509697505050508989028501935050508215159050611357576040805162461bcd60e51b81526020600482015260126024820152711393d7d4d550935254d4d253d397d0d3d4d560721b604482015290519081900360640190fd5b80341461139d576040805162461bcd60e51b815260206004820152600f60248201526e57524f4e475f4554485f56414c554560881b604482015290519081900360640190fd5b6113ac8a8a8a8a8a8a8a611949565b9a9950505050505050505050565b60006113c985858585336108af565b95945050505050565b6003602052600090815260409020546001600160a01b031681565b6002546001600160a01b031681565b6006546001600160a01b031681565b6001600160a01b03821615611454576040805162461bcd60e51b815260206004820152600a6024820152692120a22fa927aaaa22a960b11b604482015290519081900360640190fd5b61145e8383611b9e565b600480546001600160a01b0319166001600160a01b03929092169190911790555050565b3b151590565b600085518751146114cf576040805162461bcd60e51b815260206004820152600c60248201526b0aea49e9c8ebe988a9c8ea8960a31b604482015290519081900360640190fd5b60005b87518110156117d0578681815181106114e757fe5b6020026020010151600360008a84815181106114ff57fe5b60200260200101516001600160a01b03166001600160a01b0316815260200190815260200160002060006101000a8154816001600160a01b0302191690836001600160a01b0316021790555086818151811061155757fe5b60200260200101516001600160a01b031688828151811061157457fe5b60200260200101516001600160a01b03167f812ca95fe4492a9e2d1f2723c2c40c03a60a27b059581ae20ac4e4d73bfba35460405160405180910390a360006001600160a01b03168782815181106115c857fe5b60200260200101516001600160a01b03161415801561160d575060016001600160a01b03168782815181106115f957fe5b60200260200101516001600160a01b031614155b156117c85760006001600160a01b031687828151811061162957fe5b60200260200101516001600160a01b031663a7e28d488a848151811061164b57fe5b60200260200101516040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b15801561169957600080fd5b505afa1580156116ad573d6000803e3d6000fd5b505050506040513d60208110156116c357600080fd5b50516001600160a01b03161415611721576040805162461bcd60e51b815260206004820152601c60248201527f544f4b454e5f4e4f545f48414e444c45445f42595f4741544557415900000000604482015290519081900360640190fd5b86818151811061172d57fe5b60200260200101516001600160a01b0316632db09c1c6040518163ffffffff1660e01b815260040160206040518083038186803b15801561176d57600080fd5b505afa158015611781573d6000803e3d6000fd5b505050506040513d602081101561179757600080fd5b505187518890839081106117a757fe5b60200260200101906001600160a01b031690816001600160a01b0316815250505b6001016114d2565b506060634201f98560e01b8888604051602401808060200180602001838103835285818151815260200191508051906020019060200280838360005b8381101561182457818101518382015260200161180c565b50505050905001838103825284818151815260200191508051906020019060200280838360005b8381101561186357818101518382015260200161184b565b50505050905001945050505050604051602081830303815290604052906001600160e01b0319166020820180516001600160e01b03838183161783525050505090506118f9600660009054906101000a90046001600160a01b0316600160009054906101000a90046001600160a01b03168534600060405180606001604052808b81526020018d81526020018c81525087611905565b98975050505050505050565b60006118f98888888888886000015189602001518a604001518a611c6a565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b6060600061195689611134565b90506060611965338686611e7d565b604080516001600160a01b0385811682529151929350818c169233928e16917f85291dff2161a93c2f12c819d31889c96c63042116f5bc5a205aa701c2c429f5919081900360200190a4816001600160a01b031663d2ce7d65348c8c8c8c8c886040518863ffffffff1660e01b815260040180876001600160a01b03166001600160a01b03168152602001866001600160a01b03166001600160a01b0316815260200185815260200184815260200183815260200180602001828103825283818151815260200191508051906020019080838360005b83811015611a53578181015183820152602001611a3b565b50505050905090810190601f168015611a805780820380516001836020036101000a031916815260200191505b509750505050505050506000604051808303818588803b158015611aa357600080fd5b505af1158015611ab7573d6000803e3d6000fd5b50505050506040513d6000823e601f3d908101601f191682016040526020811015611ae157600080fd5b8101908080516040519392919084600160201b821115611b0057600080fd5b908301906020820185811115611b1557600080fd5b8251600160201b811182820188101715611b2e57600080fd5b82525081516020918201929091019080838360005b83811015611b5b578181015183820152602001611b43565b50505050905090810190601f168015611b885780820380516001836020036101000a031916815260200191505b5060405250505092505050979650505050505050565b6001600160a01b038216611bef576040805162461bcd60e51b81526020600482015260136024820152721253959053125117d0d3d55395115494105495606a1b604482015290519081900360640190fd5b6001546001600160a01b031615611c3c576040805162461bcd60e51b815260206004820152600c60248201526b1053149150511657d253925560a21b604482015290519081900360640190fd5b600180546001600160a01b039384166001600160a01b03199182161790915560028054929093169116179055565b6000808a6001600160a01b031663679b6ded898c8a8a8e8f8c8c8c6040518a63ffffffff1660e01b815260040180896001600160a01b03166001600160a01b03168152602001888152602001878152602001866001600160a01b03166001600160a01b03168152602001856001600160a01b03166001600160a01b0316815260200184815260200183815260200180602001828103825283818151815260200191508051906020019080838360005b83811015611d31578181015183820152602001611d19565b50505050905090810190601f168015611d5e5780820380516001836020036101000a031916815260200191505b5099505050505050505050506020604051808303818588803b158015611d8357600080fd5b505af1158015611d97573d6000803e3d6000fd5b50505050506040513d6020811015611dae57600080fd5b81019080805190602001909291905050509050808a6001600160a01b03168a6001600160a01b03167fc1d1490cf25c3b40d600dfb27c7680340ed1ab901b7e8f3551280968a3b372b0866040518080602001828103825283818151815260200191508051906020019080838360005b83811015611e35578181015183820152602001611e1d565b50505050905090810190601f168015611e625780820380516001836020036101000a031916815260200191505b509250505060405180910390a49a9950505050505050505050565b606083838360405160200180846001600160a01b03166001600160a01b0316815260200180602001828103825284848281815260200192508082843760008184015260408051601f19601f909301831690940184810390920184525250999850505050505050505056fea2646970667358221220d7743bc55082d15fef9972e04a86235c42530952c92b25d83792f50a8a6830f564736f6c634300060b0033", - "linkReferences": {}, - "deployedLinkReferences": {} - } - \ No newline at end of file diff --git a/utils/arbitrum/artifacts/L2GatewayRouter.json b/utils/arbitrum/artifacts/L2GatewayRouter.json deleted file mode 100644 index 8fd5cce8..00000000 --- a/utils/arbitrum/artifacts/L2GatewayRouter.json +++ /dev/null @@ -1,408 +0,0 @@ -{ - "_format": "hh-sol-artifact-1", - "contractName": "L2GatewayRouter", - "sourceName": "contracts/tokenbridge/arbitrum/gateway/L2GatewayRouter.sol", - "abi": [ - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "address", - "name": "newDefaultGateway", - "type": "address" - } - ], - "name": "DefaultGatewayUpdated", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "l1Token", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "gateway", - "type": "address" - } - ], - "name": "GatewaySet", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "token", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "_userFrom", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "_userTo", - "type": "address" - }, - { - "indexed": false, - "internalType": "address", - "name": "gateway", - "type": "address" - } - ], - "name": "TransferRouted", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "_from", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "_to", - "type": "address" - }, - { - "indexed": true, - "internalType": "uint256", - "name": "_id", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "bytes", - "name": "_data", - "type": "bytes" - } - ], - "name": "TxToL1", - "type": "event" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "l1ERC20", - "type": "address" - } - ], - "name": "calculateL2TokenAddress", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "counterpartGateway", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "defaultGateway", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - }, - { - "internalType": "address", - "name": "", - "type": "address" - }, - { - "internalType": "address", - "name": "", - "type": "address" - }, - { - "internalType": "uint256", - "name": "", - "type": "uint256" - }, - { - "internalType": "bytes", - "name": "", - "type": "bytes" - } - ], - "name": "finalizeInboundTransfer", - "outputs": [], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_token", - "type": "address" - } - ], - "name": "getGateway", - "outputs": [ - { - "internalType": "address", - "name": "gateway", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_token", - "type": "address" - }, - { - "internalType": "address", - "name": "_from", - "type": "address" - }, - { - "internalType": "address", - "name": "_to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "_amount", - "type": "uint256" - }, - { - "internalType": "bytes", - "name": "_data", - "type": "bytes" - } - ], - "name": "getOutboundCalldata", - "outputs": [ - { - "internalType": "bytes", - "name": "", - "type": "bytes" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_counterpartGateway", - "type": "address" - }, - { - "internalType": "address", - "name": "_defaultGateway", - "type": "address" - } - ], - "name": "initialize", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "name": "l1TokenToGateway", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_l1Token", - "type": "address" - }, - { - "internalType": "address", - "name": "_to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "_amount", - "type": "uint256" - }, - { - "internalType": "bytes", - "name": "_data", - "type": "bytes" - } - ], - "name": "outboundTransfer", - "outputs": [ - { - "internalType": "bytes", - "name": "", - "type": "bytes" - } - ], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_token", - "type": "address" - }, - { - "internalType": "address", - "name": "_to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "_amount", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "_maxGas", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "_gasPriceBid", - "type": "uint256" - }, - { - "internalType": "bytes", - "name": "_data", - "type": "bytes" - } - ], - "name": "outboundTransfer", - "outputs": [ - { - "internalType": "bytes", - "name": "", - "type": "bytes" - } - ], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [], - "name": "postUpgradeInit", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "router", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "newL2DefaultGateway", - "type": "address" - } - ], - "name": "setDefaultGateway", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address[]", - "name": "_l1Token", - "type": "address[]" - }, - { - "internalType": "address[]", - "name": "_gateway", - "type": "address[]" - } - ], - "name": "setGateway", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - } - ], - "bytecode": "0x608060405234801561001057600080fd5b50611161806100206000396000f3fe6080604052600436106100bd5760003560e01c8063a0c76a961161006f578063a0c76a9614610423578063a7e28d48146104fc578063bda009fe1461052f578063d2ce7d6514610562578063ed08fdc6146105fc578063f7c9362f1461062f578063f887ea4014610662576100bd565b806303295802146100c25780632db09c1c146100f35780632e567b36146101085780634201f985146101a0578063485cc955146102d05780637b3a3c8b1461030b57806395fcea781461040e575b600080fd5b3480156100ce57600080fd5b506100d7610677565b604080516001600160a01b039092168252519081900360200190f35b3480156100ff57600080fd5b506100d7610686565b61019e600480360360a081101561011e57600080fd5b6001600160a01b03823581169260208101358216926040820135909216916060820135919081019060a081016080820135600160201b81111561016057600080fd5b82018360208201111561017257600080fd5b803590602001918460018302840111600160201b8311171561019357600080fd5b509092509050610695565b005b3480156101ac57600080fd5b5061019e600480360360408110156101c357600080fd5b810190602081018135600160201b8111156101dd57600080fd5b8201836020820111156101ef57600080fd5b803590602001918460208302840111600160201b8311171561021057600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295949360208101935035915050600160201b81111561025f57600080fd5b82018360208201111561027157600080fd5b803590602001918460208302840111600160201b8311171561029257600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295506106d9945050505050565b3480156102dc57600080fd5b5061019e600480360360408110156102f357600080fd5b506001600160a01b0381358116916020013516610853565b6103996004803603608081101561032157600080fd5b6001600160a01b03823581169260208101359091169160408201359190810190608081016060820135600160201b81111561035b57600080fd5b82018360208201111561036d57600080fd5b803590602001918460018302840111600160201b8311171561038e57600080fd5b509092509050610863565b6040805160208082528351818301528351919283929083019185019080838360005b838110156103d35781810151838201526020016103bb565b50505050905090810190601f1680156104005780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561041a57600080fd5b5061019e61087f565b34801561042f57600080fd5b50610399600480360360a081101561044657600080fd5b6001600160a01b03823581169260208101358216926040820135909216916060820135919081019060a081016080820135600160201b81111561048857600080fd5b82018360208201111561049a57600080fd5b803590602001918460018302840111600160201b831117156104bb57600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295506108dc945050505050565b34801561050857600080fd5b506100d76004803603602081101561051f57600080fd5b50356001600160a01b0316610ade565b34801561053b57600080fd5b506100d76004803603602081101561055257600080fd5b50356001600160a01b0316610b8f565b610399600480360360c081101561057857600080fd5b6001600160a01b0382358116926020810135909116916040820135916060810135916080820135919081019060c0810160a0820135600160201b8111156105be57600080fd5b8201836020820111156105d057600080fd5b803590602001918460018302840111600160201b831117156105f157600080fd5b509092509050610bf1565b34801561060857600080fd5b506100d76004803603602081101561061f57600080fd5b50356001600160a01b0316610e46565b34801561063b57600080fd5b5061019e6004803603602081101561065257600080fd5b50356001600160a01b0316610e61565b34801561066e57600080fd5b506100d7610f35565b6003546001600160a01b031681565b6000546001600160a01b031681565b6040805162461bcd60e51b815260206004820152601460248201527327a7262cafa7aaaa2127aaa7222fa927aaaa22a960611b604482015290519081900360640190fd5b6000546001600160a01b031633148061070d57506000546001600160a01b031661070233610f44565b6001600160a01b0316145b610759576040805162461bcd60e51b81526020600482015260186024820152774f4e4c595f434f554e544552504152545f4741544557415960401b604482015290519081900360640190fd5b805182511461076457fe5b60005b825181101561084e5781818151811061077c57fe5b60200260200101516002600085848151811061079457fe5b60200260200101516001600160a01b03166001600160a01b0316815260200190815260200160002060006101000a8154816001600160a01b0302191690836001600160a01b031602179055508181815181106107ec57fe5b60200260200101516001600160a01b031683828151811061080957fe5b60200260200101516001600160a01b03167f812ca95fe4492a9e2d1f2723c2c40c03a60a27b059581ae20ac4e4d73bfba35460405160405180910390a3600101610767565b505050565b61085f82600083610f53565b5050565b60606108758686866000808888610bf1565b9695505050505050565b6000610889610fca565b9050336001600160a01b038216146108d9576040805162461bcd60e51b815260206004820152600e60248201526d2727aa2fa32927a6afa0a226a4a760911b604482015290519081900360640190fd5b50565b606060006108e987610b8f565b9050806001600160a01b031663a0c76a9688888888886040518663ffffffff1660e01b815260040180866001600160a01b03166001600160a01b03168152602001856001600160a01b03166001600160a01b03168152602001846001600160a01b03166001600160a01b0316815260200183815260200180602001828103825283818151815260200191508051906020019080838360005b83811015610999578181015183820152602001610981565b50505050905090810190601f1680156109c65780820380516001836020036101000a031916815260200191505b50965050505050505060006040518083038186803b1580156109e757600080fd5b505afa1580156109fb573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526020811015610a2457600080fd5b8101908080516040519392919084600160201b821115610a4357600080fd5b908301906020820185811115610a5857600080fd5b8251600160201b811182820188101715610a7157600080fd5b82525081516020918201929091019080838360005b83811015610a9e578181015183820152602001610a86565b50505050905090810190601f168015610acb5780820380516001836020036101000a031916815260200191505b5060405250505091505095945050505050565b600080610aea83610b8f565b90506001600160a01b038116610b04576000915050610b8a565b806001600160a01b031663a7e28d48846040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b158015610b5a57600080fd5b505afa158015610b6e573d6000803e3d6000fd5b505050506040513d6020811015610b8457600080fd5b50519150505b919050565b6001600160a01b038082166000908152600260205260409020541680610bbd57506003546001600160a01b03165b6001600160a01b03811660011480610be45750610be2816001600160a01b0316610fef565b155b15610b8a57506000610b8a565b60606000610bfe89610b8f565b90506060610c0d338686610ff5565b604080516001600160a01b0385811682529151929350818c169233928e16917f85291dff2161a93c2f12c819d31889c96c63042116f5bc5a205aa701c2c429f5919081900360200190a4816001600160a01b031663d2ce7d65348c8c8c8c8c886040518863ffffffff1660e01b815260040180876001600160a01b03166001600160a01b03168152602001866001600160a01b03166001600160a01b0316815260200185815260200184815260200183815260200180602001828103825283818151815260200191508051906020019080838360005b83811015610cfb578181015183820152602001610ce3565b50505050905090810190601f168015610d285780820380516001836020036101000a031916815260200191505b509750505050505050506000604051808303818588803b158015610d4b57600080fd5b505af1158015610d5f573d6000803e3d6000fd5b50505050506040513d6000823e601f3d908101601f191682016040526020811015610d8957600080fd5b8101908080516040519392919084600160201b821115610da857600080fd5b908301906020820185811115610dbd57600080fd5b8251600160201b811182820188101715610dd657600080fd5b82525081516020918201929091019080838360005b83811015610e03578181015183820152602001610deb565b50505050905090810190601f168015610e305780820380516001836020036101000a031916815260200191505b5060405250505092505050979650505050505050565b6002602052600090815260409020546001600160a01b031681565b6000546001600160a01b0316331480610e9557506000546001600160a01b0316610e8a33610f44565b6001600160a01b0316145b610ee1576040805162461bcd60e51b81526020600482015260186024820152774f4e4c595f434f554e544552504152545f4741544557415960401b604482015290519081900360640190fd5b600380546001600160a01b0383166001600160a01b0319909116811790915560408051918252517f3a8f8eb961383a94d41d193e16a3af73eaddfd5764a4c640257323a1603ac3319181900360200190a150565b6001546001600160a01b031681565b61111061111160901b01190190565b6001600160a01b03821615610f9c576040805162461bcd60e51b815260206004820152600a6024820152692120a22fa927aaaa22a960b11b604482015290519081900360640190fd5b610fa6838361105f565b600380546001600160a01b0319166001600160a01b03929092169190911790555050565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b3b151590565b606083838360405160200180846001600160a01b03166001600160a01b0316815260200180602001828103825284848281815260200192508082843760008184015260408051601f19601f9093018316909401848103909201845252509998505050505050505050565b6001600160a01b0382166110b0576040805162461bcd60e51b81526020600482015260136024820152721253959053125117d0d3d55395115494105495606a1b604482015290519081900360640190fd5b6000546001600160a01b0316156110fd576040805162461bcd60e51b815260206004820152600c60248201526b1053149150511657d253925560a21b604482015290519081900360640190fd5b600080546001600160a01b039384166001600160a01b0319918216179091556001805492909316911617905556fea26469706673582212207198cc8944389c1932c3adbf1316bc74ec7525726bc255b125ee69816950af4464736f6c634300060b0033", - "deployedBytecode": "0x6080604052600436106100bd5760003560e01c8063a0c76a961161006f578063a0c76a9614610423578063a7e28d48146104fc578063bda009fe1461052f578063d2ce7d6514610562578063ed08fdc6146105fc578063f7c9362f1461062f578063f887ea4014610662576100bd565b806303295802146100c25780632db09c1c146100f35780632e567b36146101085780634201f985146101a0578063485cc955146102d05780637b3a3c8b1461030b57806395fcea781461040e575b600080fd5b3480156100ce57600080fd5b506100d7610677565b604080516001600160a01b039092168252519081900360200190f35b3480156100ff57600080fd5b506100d7610686565b61019e600480360360a081101561011e57600080fd5b6001600160a01b03823581169260208101358216926040820135909216916060820135919081019060a081016080820135600160201b81111561016057600080fd5b82018360208201111561017257600080fd5b803590602001918460018302840111600160201b8311171561019357600080fd5b509092509050610695565b005b3480156101ac57600080fd5b5061019e600480360360408110156101c357600080fd5b810190602081018135600160201b8111156101dd57600080fd5b8201836020820111156101ef57600080fd5b803590602001918460208302840111600160201b8311171561021057600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295949360208101935035915050600160201b81111561025f57600080fd5b82018360208201111561027157600080fd5b803590602001918460208302840111600160201b8311171561029257600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295506106d9945050505050565b3480156102dc57600080fd5b5061019e600480360360408110156102f357600080fd5b506001600160a01b0381358116916020013516610853565b6103996004803603608081101561032157600080fd5b6001600160a01b03823581169260208101359091169160408201359190810190608081016060820135600160201b81111561035b57600080fd5b82018360208201111561036d57600080fd5b803590602001918460018302840111600160201b8311171561038e57600080fd5b509092509050610863565b6040805160208082528351818301528351919283929083019185019080838360005b838110156103d35781810151838201526020016103bb565b50505050905090810190601f1680156104005780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561041a57600080fd5b5061019e61087f565b34801561042f57600080fd5b50610399600480360360a081101561044657600080fd5b6001600160a01b03823581169260208101358216926040820135909216916060820135919081019060a081016080820135600160201b81111561048857600080fd5b82018360208201111561049a57600080fd5b803590602001918460018302840111600160201b831117156104bb57600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295506108dc945050505050565b34801561050857600080fd5b506100d76004803603602081101561051f57600080fd5b50356001600160a01b0316610ade565b34801561053b57600080fd5b506100d76004803603602081101561055257600080fd5b50356001600160a01b0316610b8f565b610399600480360360c081101561057857600080fd5b6001600160a01b0382358116926020810135909116916040820135916060810135916080820135919081019060c0810160a0820135600160201b8111156105be57600080fd5b8201836020820111156105d057600080fd5b803590602001918460018302840111600160201b831117156105f157600080fd5b509092509050610bf1565b34801561060857600080fd5b506100d76004803603602081101561061f57600080fd5b50356001600160a01b0316610e46565b34801561063b57600080fd5b5061019e6004803603602081101561065257600080fd5b50356001600160a01b0316610e61565b34801561066e57600080fd5b506100d7610f35565b6003546001600160a01b031681565b6000546001600160a01b031681565b6040805162461bcd60e51b815260206004820152601460248201527327a7262cafa7aaaa2127aaa7222fa927aaaa22a960611b604482015290519081900360640190fd5b6000546001600160a01b031633148061070d57506000546001600160a01b031661070233610f44565b6001600160a01b0316145b610759576040805162461bcd60e51b81526020600482015260186024820152774f4e4c595f434f554e544552504152545f4741544557415960401b604482015290519081900360640190fd5b805182511461076457fe5b60005b825181101561084e5781818151811061077c57fe5b60200260200101516002600085848151811061079457fe5b60200260200101516001600160a01b03166001600160a01b0316815260200190815260200160002060006101000a8154816001600160a01b0302191690836001600160a01b031602179055508181815181106107ec57fe5b60200260200101516001600160a01b031683828151811061080957fe5b60200260200101516001600160a01b03167f812ca95fe4492a9e2d1f2723c2c40c03a60a27b059581ae20ac4e4d73bfba35460405160405180910390a3600101610767565b505050565b61085f82600083610f53565b5050565b60606108758686866000808888610bf1565b9695505050505050565b6000610889610fca565b9050336001600160a01b038216146108d9576040805162461bcd60e51b815260206004820152600e60248201526d2727aa2fa32927a6afa0a226a4a760911b604482015290519081900360640190fd5b50565b606060006108e987610b8f565b9050806001600160a01b031663a0c76a9688888888886040518663ffffffff1660e01b815260040180866001600160a01b03166001600160a01b03168152602001856001600160a01b03166001600160a01b03168152602001846001600160a01b03166001600160a01b0316815260200183815260200180602001828103825283818151815260200191508051906020019080838360005b83811015610999578181015183820152602001610981565b50505050905090810190601f1680156109c65780820380516001836020036101000a031916815260200191505b50965050505050505060006040518083038186803b1580156109e757600080fd5b505afa1580156109fb573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526020811015610a2457600080fd5b8101908080516040519392919084600160201b821115610a4357600080fd5b908301906020820185811115610a5857600080fd5b8251600160201b811182820188101715610a7157600080fd5b82525081516020918201929091019080838360005b83811015610a9e578181015183820152602001610a86565b50505050905090810190601f168015610acb5780820380516001836020036101000a031916815260200191505b5060405250505091505095945050505050565b600080610aea83610b8f565b90506001600160a01b038116610b04576000915050610b8a565b806001600160a01b031663a7e28d48846040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b158015610b5a57600080fd5b505afa158015610b6e573d6000803e3d6000fd5b505050506040513d6020811015610b8457600080fd5b50519150505b919050565b6001600160a01b038082166000908152600260205260409020541680610bbd57506003546001600160a01b03165b6001600160a01b03811660011480610be45750610be2816001600160a01b0316610fef565b155b15610b8a57506000610b8a565b60606000610bfe89610b8f565b90506060610c0d338686610ff5565b604080516001600160a01b0385811682529151929350818c169233928e16917f85291dff2161a93c2f12c819d31889c96c63042116f5bc5a205aa701c2c429f5919081900360200190a4816001600160a01b031663d2ce7d65348c8c8c8c8c886040518863ffffffff1660e01b815260040180876001600160a01b03166001600160a01b03168152602001866001600160a01b03166001600160a01b0316815260200185815260200184815260200183815260200180602001828103825283818151815260200191508051906020019080838360005b83811015610cfb578181015183820152602001610ce3565b50505050905090810190601f168015610d285780820380516001836020036101000a031916815260200191505b509750505050505050506000604051808303818588803b158015610d4b57600080fd5b505af1158015610d5f573d6000803e3d6000fd5b50505050506040513d6000823e601f3d908101601f191682016040526020811015610d8957600080fd5b8101908080516040519392919084600160201b821115610da857600080fd5b908301906020820185811115610dbd57600080fd5b8251600160201b811182820188101715610dd657600080fd5b82525081516020918201929091019080838360005b83811015610e03578181015183820152602001610deb565b50505050905090810190601f168015610e305780820380516001836020036101000a031916815260200191505b5060405250505092505050979650505050505050565b6002602052600090815260409020546001600160a01b031681565b6000546001600160a01b0316331480610e9557506000546001600160a01b0316610e8a33610f44565b6001600160a01b0316145b610ee1576040805162461bcd60e51b81526020600482015260186024820152774f4e4c595f434f554e544552504152545f4741544557415960401b604482015290519081900360640190fd5b600380546001600160a01b0383166001600160a01b0319909116811790915560408051918252517f3a8f8eb961383a94d41d193e16a3af73eaddfd5764a4c640257323a1603ac3319181900360200190a150565b6001546001600160a01b031681565b61111061111160901b01190190565b6001600160a01b03821615610f9c576040805162461bcd60e51b815260206004820152600a6024820152692120a22fa927aaaa22a960b11b604482015290519081900360640190fd5b610fa6838361105f565b600380546001600160a01b0319166001600160a01b03929092169190911790555050565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b3b151590565b606083838360405160200180846001600160a01b03166001600160a01b0316815260200180602001828103825284848281815260200192508082843760008184015260408051601f19601f9093018316909401848103909201845252509998505050505050505050565b6001600160a01b0382166110b0576040805162461bcd60e51b81526020600482015260136024820152721253959053125117d0d3d55395115494105495606a1b604482015290519081900360640190fd5b6000546001600160a01b0316156110fd576040805162461bcd60e51b815260206004820152600c60248201526b1053149150511657d253925560a21b604482015290519081900360640190fd5b600080546001600160a01b039384166001600160a01b0319918216179091556001805492909316911617905556fea26469706673582212207198cc8944389c1932c3adbf1316bc74ec7525726bc255b125ee69816950af4464736f6c634300060b0033", - "linkReferences": {}, - "deployedLinkReferences": {} - } - \ No newline at end of file diff --git a/utils/arbitrum/contracts.ts b/utils/arbitrum/contracts.ts deleted file mode 100644 index 778e2eb5..00000000 --- a/utils/arbitrum/contracts.ts +++ /dev/null @@ -1,37 +0,0 @@ -import { - L1GatewayRouter__factory, - L2GatewayRouter__factory, - ArbSysStub__factory, - Inbox__factory, -} from "../../typechain/"; -import addresses from "./addresses"; -import { CommonOptions } from "./types"; -import network, { NetworkName } from "../network"; - -interface ContractsOptions extends CommonOptions { - forking: boolean; -} - -export default function contracts( - networkName: NetworkName, - options: ContractsOptions -) { - const [l1Provider, l2Provider] = network - .multichain(["eth", "arb"], networkName) - .getProviders(options); - - const arbAddresses = addresses(networkName, options); - - return { - ArbSysStub: ArbSysStub__factory.connect(arbAddresses.ArbSys, l2Provider), - L1GatewayRouter: L1GatewayRouter__factory.connect( - arbAddresses.L1GatewayRouter, - l1Provider - ), - L2GatewayRouter: L2GatewayRouter__factory.connect( - arbAddresses.L2GatewayRouter, - l2Provider - ), - Inbox: Inbox__factory.connect(arbAddresses.Inbox, l1Provider), - }; -} diff --git a/utils/arbitrum/deployment.ts b/utils/arbitrum/deployment.ts deleted file mode 100644 index 3327cff2..00000000 --- a/utils/arbitrum/deployment.ts +++ /dev/null @@ -1,203 +0,0 @@ -import { assert } from "chai"; -import { ethers } from "hardhat"; -import { Overrides, Wallet } from "ethers"; -import { - ERC20Bridged__factory, - IERC20Metadata__factory, - L1ERC20TokenGateway__factory, - L1GatewayRouter__factory, - L2ERC20TokenGateway__factory, - L2GatewayRouter__factory, - OssifiableProxy__factory, -} from "../../typechain"; - -import addresses from "./addresses"; -import { CommonOptions } from "./types"; -import network, { NetworkName } from "../network"; -import { DeployScript, Logger } from "../deployment/DeployScript"; - -interface ArbL1DeployScriptParams { - deployer: Wallet; - admins: { proxy: string; bridge: string }; -} - -interface ArbL2DeployScriptParams extends ArbL1DeployScriptParams { - l2Token?: { name?: string; symbol?: string }; -} - -interface ArbDeploymentOptions extends CommonOptions { - logger?: Logger; - overrides?: Overrides; -} - -export default function deployment( - networkName: NetworkName, - options: ArbDeploymentOptions = {} -) { - const arbAddresses = addresses(networkName, options); - - return { - async erc20TokenGatewayDeployScript( - l1Token: string, - l1Params: ArbL1DeployScriptParams, - l2Params: ArbL2DeployScriptParams - ) { - const [ - expectedL1TokensGatewayImplAddress, - expectedL1TokensGatewayProxyAddress, - ] = await network.predictAddresses(l1Params.deployer, 2); - - const [ - expectedL2TokenImplAddress, - expectedL2TokenProxyAddress, - expectedL2TokensGatewayImplAddress, - expectedL2TokensGatewayProxyAddress, - ] = await network.predictAddresses(l2Params.deployer, 4); - - const l1DeployScript = new DeployScript( - l1Params.deployer, - options?.logger - ) - .addStep({ - factory: L1ERC20TokenGateway__factory, - args: [ - arbAddresses.Inbox, - arbAddresses.L1GatewayRouter, - expectedL2TokensGatewayProxyAddress, - l1Token, - expectedL2TokenProxyAddress, - options?.overrides, - ], - afterDeploy: (c) => - assert.equal(c.address, expectedL1TokensGatewayImplAddress), - }) - .addStep({ - factory: OssifiableProxy__factory, - args: [ - expectedL1TokensGatewayImplAddress, - l1Params.admins.proxy, - L1ERC20TokenGateway__factory.createInterface().encodeFunctionData( - "initialize", - [l1Params.admins.bridge] - ), - options?.overrides, - ], - afterDeploy: (c) => - assert.equal(c.address, expectedL1TokensGatewayProxyAddress), - }); - - const l1TokenInfo = IERC20Metadata__factory.connect( - l1Token, - l1Params.deployer - ); - - const [decimals, l2TokenName, l2TokenSymbol] = await Promise.all([ - l1TokenInfo.decimals(), - l2Params.l2Token?.name ?? l1TokenInfo.name(), - l2Params.l2Token?.symbol ?? l1TokenInfo.symbol(), - ]); - - const l2DeployScript = new DeployScript( - l2Params.deployer, - options?.logger - ) - .addStep({ - factory: ERC20Bridged__factory, - args: [ - l2TokenName, - l2TokenSymbol, - decimals, - expectedL2TokensGatewayProxyAddress, - options?.overrides, - ], - afterDeploy: (c) => - assert.equal(c.address, expectedL2TokenImplAddress), - }) - .addStep({ - factory: OssifiableProxy__factory, - args: [ - expectedL2TokenImplAddress, - l2Params.admins.proxy, - ERC20Bridged__factory.createInterface().encodeFunctionData( - "initialize", - [l2TokenName, l2TokenSymbol] - ), - options?.overrides, - ], - afterDeploy: (c) => - assert.equal(c.address, expectedL2TokenProxyAddress), - }) - .addStep({ - factory: L2ERC20TokenGateway__factory, - args: [ - arbAddresses.ArbSys, - arbAddresses.L2GatewayRouter, - expectedL1TokensGatewayProxyAddress, - l1Token, - expectedL2TokenProxyAddress, - options?.overrides, - ], - afterDeploy: (c) => - assert.equal(c.address, expectedL2TokensGatewayImplAddress), - }) - .addStep({ - factory: OssifiableProxy__factory, - args: [ - expectedL2TokensGatewayImplAddress, - l2Params.admins.proxy, - L2ERC20TokenGateway__factory.createInterface().encodeFunctionData( - "initialize", - [l2Params.admins.bridge] - ), - options?.overrides, - ], - }); - - return [l1DeployScript, l2DeployScript]; - }, - async gatewayRouterDeployScript(l1Deployer: Wallet, l2Deployer: Wallet) { - const [expectedL1GatewayRouter] = await network.predictAddresses( - l1Deployer, - 1 - ); - const [expectedL2GatewayRouter] = await network.predictAddresses( - l2Deployer, - 1 - ); - - const l1DeployScript = new DeployScript( - l1Deployer, - options?.logger - ).addStep({ - factory: L1GatewayRouter__factory, - args: [options?.overrides], - afterDeploy: async (l1GatewayRouter) => { - assert.equal(l1GatewayRouter.address, expectedL1GatewayRouter); - await l1GatewayRouter.initialize( - l1Deployer.address, - ethers.constants.AddressZero, - ethers.constants.AddressZero, - expectedL2GatewayRouter, - arbAddresses.Inbox - ); - }, - }); - - const l2DeployScript = new DeployScript( - l2Deployer, - options?.logger - ).addStep({ - factory: L2GatewayRouter__factory, - args: [options?.overrides], - afterDeploy: async (l2GatewayRouter) => { - assert.equal(l2GatewayRouter.address, expectedL2GatewayRouter); - await l2GatewayRouter.initialize( - expectedL1GatewayRouter, - ethers.constants.AddressZero - ); - }, - }); - return [l1DeployScript, l2DeployScript]; - }, - }; -} diff --git a/utils/arbitrum/index.ts b/utils/arbitrum/index.ts deleted file mode 100644 index 73d4d32b..00000000 --- a/utils/arbitrum/index.ts +++ /dev/null @@ -1,13 +0,0 @@ -import testing from "./testing"; -import addresses from "./addresses"; -import contracts from "./contracts"; -import deployment from "./deployment"; -import messaging from "./messaging"; - -export default { - testing, - addresses, - contracts, - messaging, - deployment, -}; diff --git a/utils/arbitrum/messaging.ts b/utils/arbitrum/messaging.ts deleted file mode 100644 index 5fb57499..00000000 --- a/utils/arbitrum/messaging.ts +++ /dev/null @@ -1,111 +0,0 @@ -import { L1ToL2MessageGasEstimator, L1TransactionReceipt } from "@arbitrum/sdk"; -import { JsonRpcProvider } from "@ethersproject/providers"; -import { BigNumber, BigNumberish } from "ethers"; -import { hexDataLength } from "ethers/lib/utils"; -import network, { NetworkName } from "../network"; -import contracts from "./contracts"; - -import { CommonOptions } from "./types"; - -interface RetryableTicketOptions extends CommonOptions { - forking: boolean; -} - -interface MessageData { - sender: string; - recipient: string; - calldata: string; - callvalue?: BigNumberish; - refundAddress?: string; -} - -const SUBMISSION_PRICE_MULTIPLIER = 2; - -async function getRetryableTicketSendParams( - ethProvider: JsonRpcProvider, - arbProvider: JsonRpcProvider, - msg: MessageData -) { - const l1ToL2MessageGasEstimator = new L1ToL2MessageGasEstimator(arbProvider); - - const { baseFeePerGas } = await ethProvider.getBlock( - await ethProvider.getBlockNumber() - ); - if (!baseFeePerGas) { - throw new Error( - "Latest block did not contain base fee, ensure provider is connected to a network that supports EIP 1559." - ); - } - - const maxSubmissionCost = await l1ToL2MessageGasEstimator - .estimateSubmissionFee( - ethProvider, - baseFeePerGas, - hexDataLength(msg.calldata) + 4 - ) - .then((submissionPrice) => - submissionPrice.mul(SUBMISSION_PRICE_MULTIPLIER) - ); - - const arbGasPriceBid = await arbProvider.getGasPrice(); - - const maxGas = - await l1ToL2MessageGasEstimator.estimateRetryableTicketGasLimit({ - from: msg.sender, - to: msg.recipient, - l2CallValue: BigNumber.from(msg.callvalue || 0), - excessFeeRefundAddress: msg.refundAddress || msg.sender, - callValueRefundAddress: msg.refundAddress || msg.sender, - data: msg.calldata, - }); - - return { - maxGas, - maxSubmissionCost, - gasPriceBid: arbGasPriceBid, - callvalue: maxSubmissionCost.add(arbGasPriceBid.mul(maxGas)), - }; -} - -export default function messaging( - networkName: NetworkName, - options: RetryableTicketOptions -) { - const [ethProvider, arbProvider] = network - .multichain(["eth", "arb"], networkName) - .getProviders(options); - const arbContracts = contracts(networkName, options); - return { - async waitForL2Message(l1TxHash: string) { - const l1TxReceipt = new L1TransactionReceipt( - await ethProvider.getTransactionReceipt(l1TxHash) - ); - const [message] = await l1TxReceipt.getL1ToL2Messages(arbProvider); - return message.waitForStatus(); - }, - async getRetryableTicketSendParams(msg: MessageData) { - return getRetryableTicketSendParams(ethProvider, arbProvider, msg); - }, - async prepareRetryableTicketTx(msg: MessageData) { - const { maxGas, gasPriceBid, maxSubmissionCost, callvalue } = - await getRetryableTicketSendParams(ethProvider, arbProvider, msg); - - return { - callvalue, - calldata: arbContracts.Inbox.interface.encodeFunctionData( - "createRetryableTicket", - [ - msg.recipient, - BigNumber.from(msg.callvalue || 0), - maxSubmissionCost, - msg.refundAddress || msg.sender, - msg.refundAddress || msg.sender, - maxGas, - gasPriceBid, - msg.calldata, - ] - ), - }; - }, - }; -} diff --git a/utils/arbitrum/testing.ts b/utils/arbitrum/testing.ts deleted file mode 100644 index e34dce4c..00000000 --- a/utils/arbitrum/testing.ts +++ /dev/null @@ -1,337 +0,0 @@ -import { - IERC20__factory, - ERC20BridgedStub__factory, - L1ERC20TokenGateway__factory, - L2ERC20TokenGateway__factory, - ArbSysStub__factory, - ERC20Bridged__factory, -} from "../../typechain"; -import contracts from "./contracts"; -import addresses from "./addresses"; -import deployment from "./deployment"; -import testingUtils from "../testing"; -import { BridgingManagement } from "../bridging-management"; -import network, { NetworkName, SignerOrProvider } from "../network"; -import { JsonRpcProvider } from "@ethersproject/providers"; - -export default function testing(networkName: NetworkName) { - const defaultArbAddresses = addresses(networkName); - const ethArbNetworks = network.multichain(["eth", "arb"], networkName); - - const [ethProviderForking, arbProviderForking] = ethArbNetworks.getProviders({ - forking: true, - }); - - return { - async getAcceptanceTestSetup() { - const gatewayContracts = await loadDeployedGateways( - ethProviderForking, - arbProviderForking - ); - - const { L1GatewayRouter, L2GatewayRouter } = contracts(networkName, { - customAddresses: loadGatewayRouterAddresses(networkName), - forking: true, - }); - - return { - l1Provider: ethProviderForking, - l2Provider: arbProviderForking, - ...gatewayContracts, - l1GatewayRouter: L1GatewayRouter, - l2GatewayRouter: L2GatewayRouter, - }; - }, - async getIntegrationTestSetup() { - const hasDeployedContracts = - testingUtils.env.USE_DEPLOYED_CONTRACTS(false); - - const gatewayContracts = hasDeployedContracts - ? await loadDeployedGateways(ethProviderForking, arbProviderForking) - : await deployTestGateway( - networkName, - ethProviderForking, - arbProviderForking - ); - - const [l1ERC20TokenGatewayAdminAddress] = - await BridgingManagement.getAdmins( - gatewayContracts.l1ERC20TokenGateway - ); - - const [l2ERC20TokenGatewayAdminAddress] = - await BridgingManagement.getAdmins( - gatewayContracts.l2ERC20TokenGateway - ); - - const customGatewayRouterAddresses = hasDeployedContracts - ? loadGatewayRouterAddresses(networkName) - : undefined; - - const { - L1GatewayRouter: l1GatewayRouter, - L2GatewayRouter: l2GatewayRouter, - } = contracts(networkName, { - customAddresses: customGatewayRouterAddresses, - forking: true, - }); - - const l1TokensHolder = hasDeployedContracts - ? await testingUtils.impersonate( - testingUtils.env.L1_TOKENS_HOLDER(), - ethProviderForking - ) - : testingUtils.accounts.deployer(ethProviderForking); - - if (hasDeployedContracts) { - await printLoadedTestConfig( - networkName, - l1TokensHolder, - gatewayContracts, - { l1GatewayRouter, l2GatewayRouter } - ); - } - - // if the L1 bridge admin is a contract, remove it's code to - // make it behave as EOA - await ethProviderForking.send("hardhat_setCode", [ - l1ERC20TokenGatewayAdminAddress, - "0x", - ]); - - // same for the L2 bridge admin - await arbProviderForking.send("hardhat_setCode", [ - l2ERC20TokenGatewayAdminAddress, - "0x", - ]); - - const { ArbSysStub } = contracts(networkName, { forking: true }); - - return { - l1GatewayRouter, - l2GatewayRouter, - l1Provider: ethProviderForking, - l2Provider: arbProviderForking, - l1TokensHolder, - ...gatewayContracts, - arbSysStub: ArbSysStub, - l1ERC20TokenGatewayAdmin: await testingUtils.impersonate( - l1ERC20TokenGatewayAdminAddress, - ethProviderForking - ), - l2ERC20TokenGatewayAdmin: await testingUtils.impersonate( - l2ERC20TokenGatewayAdminAddress, - arbProviderForking - ), - }; - }, - async getE2ETestSetup() { - const testerPrivateKey = testingUtils.env.TESTING_PRIVATE_KEY(); - - const [l1Provider, l2Provider] = ethArbNetworks.getProviders({ - forking: false, - }); - - const [l1Tester, l2Tester] = ethArbNetworks.getSigners(testerPrivateKey, { - forking: false, - }); - - const gatewayContracts = await loadDeployedGateways(l1Tester, l2Tester); - - const { - L1GatewayRouter: l1GatewayRouter, - L2GatewayRouter: l2GatewayRouter, - } = contracts(networkName, { - customAddresses: loadGatewayRouterAddresses(networkName), - forking: true, - }); - - await printLoadedTestConfig(networkName, l1Tester, gatewayContracts, { - l1GatewayRouter, - l2GatewayRouter, - }); - - return { - l1Tester, - l2Tester, - l1Provider, - l2Provider, - l1GatewayRouter, - l2GatewayRouter, - ...gatewayContracts, - }; - }, - async stubArbSysContract() { - const deployer = testingUtils.accounts.deployer(arbProviderForking); - const stub = await new ArbSysStub__factory(deployer).deploy(); - const stubBytecode = await arbProviderForking.send("eth_getCode", [ - stub.address, - ]); - - await arbProviderForking.send("hardhat_setCode", [ - defaultArbAddresses.ArbSys, - stubBytecode, - ]); - }, - }; -} - -async function deployTestGateway( - networkName: NetworkName, - ethProvider: JsonRpcProvider, - arbProvider: JsonRpcProvider -) { - const ethDeployer = testingUtils.accounts.deployer(ethProvider); - const arbDeployer = testingUtils.accounts.deployer(arbProvider); - - const l1Token = await new ERC20BridgedStub__factory(ethDeployer).deploy( - "Test Token", - "TT" - ); - - const [ethDeployScript, arbDeployScript] = await deployment( - networkName - ).erc20TokenGatewayDeployScript( - l1Token.address, - { - deployer: ethDeployer, - admins: { proxy: ethDeployer.address, bridge: ethDeployer.address }, - }, - { - deployer: arbDeployer, - admins: { proxy: arbDeployer.address, bridge: arbDeployer.address }, - } - ); - - await ethDeployScript.run(); - await arbDeployScript.run(); - - const l1ERC20TokenBridgeProxyDeployStepIndex = 1; - const l1BridgingManagement = new BridgingManagement( - ethDeployScript.getContractAddress(l1ERC20TokenBridgeProxyDeployStepIndex), - ethDeployer - ); - - const l2ERC20TokenBridgeProxyDeployStepIndex = 3; - const l2BridgingManagement = new BridgingManagement( - arbDeployScript.getContractAddress(l2ERC20TokenBridgeProxyDeployStepIndex), - arbDeployer - ); - - await l1BridgingManagement.setup({ - bridgeAdmin: ethDeployer.address, - depositsEnabled: true, - withdrawalsEnabled: true, - }); - - await l2BridgingManagement.setup({ - bridgeAdmin: arbDeployer.address, - depositsEnabled: true, - withdrawalsEnabled: true, - }); - - return { - l1Token: l1Token.connect(ethProvider), - ...connectGatewayContracts( - { - l2Token: arbDeployScript.getContractAddress(1), - l1ERC20TokenGateway: ethDeployScript.getContractAddress(1), - l2ERC20TokenGateway: arbDeployScript.getContractAddress(3), - }, - ethProvider, - arbProvider - ), - }; -} - -async function loadDeployedGateways( - l1SignerOrProvider: SignerOrProvider, - l2SignerOrProvider: SignerOrProvider -) { - return { - l1Token: IERC20__factory.connect( - testingUtils.env.ARB_L1_TOKEN(), - l1SignerOrProvider - ), - ...connectGatewayContracts( - { - l2Token: testingUtils.env.ARB_L2_TOKEN(), - l1ERC20TokenGateway: testingUtils.env.ARB_L1_ERC20_TOKEN_GATEWAY(), - l2ERC20TokenGateway: testingUtils.env.ARB_L2_ERC20_TOKEN_GATEWAY(), - }, - l1SignerOrProvider, - l2SignerOrProvider - ), - }; -} - -function connectGatewayContracts( - addresses: { - l2Token: string; - l1ERC20TokenGateway: string; - l2ERC20TokenGateway: string; - }, - l1SignerOrProvider: SignerOrProvider, - l2SignerOrProvider: SignerOrProvider -) { - const l1ERC20TokenGateway = L1ERC20TokenGateway__factory.connect( - addresses.l1ERC20TokenGateway, - l1SignerOrProvider - ); - const l2ERC20TokenGateway = L2ERC20TokenGateway__factory.connect( - addresses.l2ERC20TokenGateway, - l2SignerOrProvider - ); - const l2Token = ERC20Bridged__factory.connect( - addresses.l2Token, - l2SignerOrProvider - ); - return { - l2Token, - l1ERC20TokenGateway, - l2ERC20TokenGateway, - }; -} - -function loadGatewayRouterAddresses(networkName: NetworkName) { - const defaultArbAddresses = addresses(networkName); - return { - L1GatewayRouter: testingUtils.env.ARB_L1_GATEWAY_ROUTER( - defaultArbAddresses.L1GatewayRouter - ), - L2GatewayRouter: testingUtils.env.ARB_L2_GATEWAY_ROUTER( - defaultArbAddresses.L2GatewayRouter - ), - }; -} - -async function printLoadedTestConfig( - networkName: NetworkName, - l1TokensHolder: any, - gatewayContracts: any, - gatewayRouters: any -) { - console.log("Using the deployed contracts for integration tests"); - console.log( - "In case of unexpected fails, please, make sure that you are forking correct Ethereum/Arbitrum networks" - ); - console.log(` Network Name: ${networkName}`); - console.log(` L1 Token: ${gatewayContracts.l1Token.address}`); - console.log(` L2 Token: ${gatewayContracts.l2Token.address}`); - const l1TokensHolderAddress = await l1TokensHolder.getAddress(); - console.log(` L1 Tokens Holder: ${l1TokensHolderAddress}`); - const holderBalance = await gatewayContracts.l1Token.balanceOf( - l1TokensHolderAddress - ); - console.log(` L1 Tokens Holder Balance: ${holderBalance.toString()}`); - console.log( - ` L1 ERC20 Token Gateway: ${gatewayContracts.l1ERC20TokenGateway.address}` - ); - console.log( - ` L2 ERC20 Token Gateway: ${gatewayContracts.l2ERC20TokenGateway.address}` - ); - console.log(` L1 Gateway Router: ${gatewayRouters.l1GatewayRouter.address}`); - console.log( - ` L2 Gateway Routery: ${gatewayRouters.l2GatewayRouter.address}` - ); -} diff --git a/utils/arbitrum/types.ts b/utils/arbitrum/types.ts deleted file mode 100644 index e17ed21b..00000000 --- a/utils/arbitrum/types.ts +++ /dev/null @@ -1,15 +0,0 @@ -export type ArbContractNames = - | "Inbox" - | "ArbSys" - | "Bridge" - | "Outbox" - | "L1GatewayRouter" - | "L2GatewayRouter"; - -export type ArbContractAddresses = Record; - -export type CustomArbContractAddresses = Partial; - -export interface CommonOptions { - customAddresses?: CustomArbContractAddresses; -} diff --git a/utils/deployment.ts b/utils/deployment.ts index 617ca5b9..58021774 100644 --- a/utils/deployment.ts +++ b/utils/deployment.ts @@ -1,5 +1,5 @@ import chalk from "chalk"; -import { Wallet } from "ethers"; +import { BigNumber, Wallet } from "ethers"; import env from "./env"; import { DeployScript } from "./deployment/DeployScript"; @@ -10,14 +10,59 @@ interface ChainDeploymentConfig extends BridgingManagerSetupConfig { } interface MultiChainDeploymentConfig { - token: string; + /// L1 + l1TokenNonRebasable: string; + l1RebasableToken: string; + accountingOracle: string; + l2GasLimitForPushingTokenRate: BigNumber; + l1TokenBridge: string; + l1AuthorizedRebaseCaller: string; + + /// L2 + /// Oracle + tokenRateOutdatedDelay: BigNumber; + maxAllowedL2ToL1ClockLag: BigNumber; + maxAllowedTokenRateDeviationPerDayBp: BigNumber; + oldestRateAllowedInPauseTimeSpan: BigNumber; + maxAllowedTimeBetweenTokenRateUpdates: BigNumber; + tokenRateValue: BigNumber; + tokenRateL1Timestamp: BigNumber; + + /// wstETH address to upgrade + l2TokenNonRebasable: string; + + /// bridge + l2TokenBridge: string; + + govBridgeExecutor: string; l1: ChainDeploymentConfig; l2: ChainDeploymentConfig; } export function loadMultiChainDeploymentConfig(): MultiChainDeploymentConfig { return { - token: env.address("TOKEN"), + /// L1 Part + l1TokenNonRebasable: env.address("L1_NON_REBASABLE_TOKEN"), + l1RebasableToken: env.address("L1_REBASABLE_TOKEN"), + accountingOracle: env.address("ACCOUNTING_ORACLE"), + l2GasLimitForPushingTokenRate: BigNumber.from(env.string("L2_GAS_LIMIT_FOR_PUSHING_TOKEN_RATE")), + l1TokenBridge: env.address("L1_TOKEN_BRIDGE"), + l1AuthorizedRebaseCaller: env.address("L1_AUTHORIZED_REBASE_CALLER"), + + /// L2 Part + /// TokenRateOracle + tokenRateOutdatedDelay: BigNumber.from(env.string("TOKEN_RATE_OUTDATED_DELAY")), + maxAllowedL2ToL1ClockLag: BigNumber.from(env.string("MAX_ALLOWED_L2_TO_L1_CLOCK_LAG")), + maxAllowedTokenRateDeviationPerDayBp: BigNumber.from(env.string("MAX_ALLOWED_TOKEN_RATE_DEVIATION_PER_DAY_BP")), + oldestRateAllowedInPauseTimeSpan: BigNumber.from(env.string("OLDEST_RATE_ALLOWED_IN_PAUSE_TIME_SPAN")), + maxAllowedTimeBetweenTokenRateUpdates: BigNumber.from(env.string("MAX_ALLOWED_TIME_BETWEEN_TOKEN_RATE_UPDATES")), + tokenRateValue: BigNumber.from(env.string("TOKEN_RATE")), + tokenRateL1Timestamp: BigNumber.from(env.string("TOKEN_RATE_L1_TIMESTAMP")), + + l2TokenNonRebasable: env.address("L2_TOKEN_NON_REBASABLE"), + l2TokenBridge: env.address("L2_TOKEN_BRIDGE"), + + govBridgeExecutor: env.address("GOV_BRIDGE_EXECUTOR"), l1: { proxyAdmin: env.address("L1_PROXY_ADMIN"), bridgeAdmin: env.address("L1_BRIDGE_ADMIN"), @@ -41,6 +86,12 @@ export function loadMultiChainDeploymentConfig(): MultiChainDeploymentConfig { }; } +export async function printDeploymentConfig() { + const pad = " ".repeat(4); + console.log(`${pad}· Network: ${env.string("NETWORK")}`); + console.log(`${pad}· Forking: ${env.bool("FORKING")}`); +} + export async function printMultiChainDeploymentConfig( title: string, l1Deployer: Wallet, @@ -49,8 +100,13 @@ export async function printMultiChainDeploymentConfig( l1DeployScript: DeployScript, l2DeployScript: DeployScript ) { - const { token, l1, l2 } = deploymentParams; - console.log(chalk.bold(`${title} :: ${chalk.underline(token)}\n`)); + const { l1TokenNonRebasable, l1RebasableToken, l1, l2 } = deploymentParams; + console.log(chalk.bold(`${title} :: ${chalk.underline(l1TokenNonRebasable)} :: ${chalk.underline(l1RebasableToken)}\n`)); + + console.log(chalk.bold(" · Deployment Params:")); + await printDeploymentConfig(); + console.log(); + console.log(chalk.bold(" · L1 Deployment Params:")); await printChainDeploymentConfig(l1Deployer, l1); console.log(); diff --git a/utils/deployment/DeployScript.ts b/utils/deployment/DeployScript.ts index a6adb1d9..3e9f7b8c 100644 --- a/utils/deployment/DeployScript.ts +++ b/utils/deployment/DeployScript.ts @@ -170,8 +170,6 @@ export class DeployScript { 10: "opt_mainnet", 11155420: "opt_sepolia", 31337: "hardhat", - 42161: "arb_mainnet", - 421613: "arb_sepolia", }; const networkName = networkNameByChainId[chainId] || ""; const arsString = stepInfo.args.map((a) => `"${a.value}"`).join(" "); diff --git a/utils/lido.ts b/utils/lido.ts index ac3de401..f31f0ef3 100644 --- a/utils/lido.ts +++ b/utils/lido.ts @@ -16,9 +16,9 @@ const ARAGON_MAINNET = { }; const ARAGON_SEPOLIA = { - agent: "0x4333218072D5d7008546737786663c38B4D561A4", - voting: "0xbc0B67b4553f4CF52a913DE9A6eD0057E2E758Db", - tokenManager: "0xDfe76d11b365f5e0023343A367f0b311701B3bc1", + agent: "0x32A0E5828B62AAb932362a4816ae03b860b65e83", + voting: "0x39A0EbdEE54cB319f4F42141daaBDb6ba25D341A", + tokenManager: "0xC73cd4B2A7c1CBC5BF046eB4A7019365558ABF66", }; const ARAGON_CONTRACTS_BY_NAME = { diff --git a/utils/network.ts b/utils/network.ts index 1564aa27..30603cda 100644 --- a/utils/network.ts +++ b/utils/network.ts @@ -6,7 +6,7 @@ import { HardhatRuntimeEnvironment, HttpNetworkConfig } from "hardhat/types"; import env from "./env"; -type ChainNameShort = "arb" | "opt" | "eth"; +type ChainNameShort = "opt" | "eth"; export type NetworkName = "sepolia" | "mainnet"; export type SignerOrProvider = Signer | Provider; @@ -15,10 +15,6 @@ const HARDHAT_NETWORK_NAMES = { sepolia: "eth_sepolia", mainnet: "eth_mainnet", }, - arb: { - sepolia: "arb_sepolia", - mainnet: "arb_mainnet", - }, opt: { sepolia: "opt_sepolia", mainnet: "opt_mainnet", @@ -30,10 +26,6 @@ const HARDHAT_NETWORK_NAMES_FORK = { sepolia: "eth_sepolia_fork", mainnet: "eth_mainnet_fork", }, - arb: { - sepolia: "arb_sepolia_fork", - mainnet: "arb_mainnet_fork", - }, opt: { sepolia: "opt_sepolia_fork", mainnet: "opt_mainnet_fork", @@ -125,10 +117,6 @@ function getChainId(protocol: ChainNameShort, networkName: NetworkName) { mainnet: 10, sepolia: 11155420, }, - arb: { - mainnet: 42161, - sepolia: 421613, - }, }; const chainId = chainIds[protocol][networkName]; if (!chainId) { @@ -142,9 +130,6 @@ function getBlockExplorerBaseUrlByChainId(chainId: number) { // ethereum 1: "https://etherscan.io", 11155111: "https://sepolia.etherscan.io", - // arbitrum - 42161: "https://arbiscan.io", - 421613: "https://sepolia-rollup-explorer.arbitrum.io", // optimism 10: "https://optimistic.etherscan.io", 11155420: "https://blockscout.com/optimism/sepolia", diff --git a/utils/optimism/LidoBridgeAdapter.ts b/utils/optimism/LidoBridgeAdapter.ts new file mode 100644 index 00000000..ac561d4b --- /dev/null +++ b/utils/optimism/LidoBridgeAdapter.ts @@ -0,0 +1,80 @@ +import { StandardBridgeAdapter, toAddress } from "@eth-optimism/sdk"; +import { hexStringEquals } from "@eth-optimism/core-utils"; +import { Contract } from 'ethers'; + +export class LidoBridgeAdapter extends StandardBridgeAdapter { + async supportsTokenPair(l1Token: Contract, l2Token: Contract) { + const l1Bridge = new Contract(this.l1Bridge.address, [ + { + inputs: [], + name: 'L1_TOKEN_NON_REBASABLE', + outputs: [ + { + internalType: 'address', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'L2_TOKEN_NON_REBASABLE', + outputs: [ + { + internalType: 'address', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'L1_TOKEN_REBASABLE', + outputs: [ + { + internalType: 'address', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'L2_TOKEN_REBASABLE', + outputs: [ + { + internalType: 'address', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + ], this.messenger.l1Provider); + + const allowedL1RebasableToken = await l1Bridge.L1_TOKEN_REBASABLE(); + const allowedL1NonRebasableToken = await l1Bridge.L1_TOKEN_NON_REBASABLE(); + + if ((!(0, hexStringEquals)(allowedL1RebasableToken, (0, toAddress)(l1Token))) && + (!(0, hexStringEquals)(allowedL1NonRebasableToken, (0, toAddress)(l1Token)))) + { + return false; + } + + const allowedL2RebasableToken = await l1Bridge.L2_TOKEN_REBASABLE(); + const allowedL2NonRebasableToken = await l1Bridge.L2_TOKEN_NON_REBASABLE(); + + if ((!(0, hexStringEquals)(allowedL2RebasableToken, (0, toAddress)(l2Token))) && + (!(0, hexStringEquals)(allowedL2NonRebasableToken, (0, toAddress)(l2Token)))) { + return false; + } + return true; + } +} diff --git a/utils/optimism/deployment.ts b/utils/optimism/deployment.ts index c3b6aa3a..c652cdda 100644 --- a/utils/optimism/deployment.ts +++ b/utils/optimism/deployment.ts @@ -1,66 +1,168 @@ import { assert } from "chai"; -import { Overrides, Wallet } from "ethers"; +import { BigNumber, Wallet } from "ethers"; +import addresses from "./addresses"; +import { OptDeploymentOptions, DeployScriptParams } from "./types"; +import network, { NetworkName } from "../network"; +import { DeployScript, Logger } from "../deployment/DeployScript"; import { - ERC20Bridged__factory, - IERC20Metadata__factory, - L1ERC20TokenBridge__factory, - L2ERC20TokenBridge__factory, + ERC20BridgedPermit__factory, + ERC20RebasableBridgedPermit__factory, + L1LidoTokensBridge__factory, + L2ERC20ExtendedTokensBridge__factory, OssifiableProxy__factory, + TokenRateOracle__factory, + TokenRateNotifier__factory, + OpStackTokenRatePusher__factory, + IERC20Metadata__factory } from "../../typechain"; -import addresses from "./addresses"; -import { CommonOptions } from "./types"; -import network, { NetworkName } from "../network"; -import { DeployScript, Logger } from "../deployment/DeployScript"; +interface OptL1DeployScriptParams extends DeployScriptParams { + l1TokenNonRebasable: string; + l1TokenRebasable: string; + accountingOracle: string; + l2GasLimitForPushingTokenRate: BigNumber; + l1AuthorizedRebaseCaller: string; +} -interface OptL1DeployScriptParams { - deployer: Wallet; - admins: { proxy: string; bridge: string }; +interface OptL2DeployScriptParams extends DeployScriptParams { + l2TokenNonRebasable: { + name?: string; + symbol?: string; + version: string; + decimals?: number; + }; + l2TokenRebasable: { + name?: string; + symbol?: string; + version: string; + decimals?: number; + }; + tokenRateOracle: { + tokenRateOutdatedDelay: BigNumber; + maxAllowedL2ToL1ClockLag: BigNumber; + maxAllowedTokenRateDeviationPerDayBp: BigNumber; + oldestRateAllowedInPauseTimeSpan: BigNumber; + maxAllowedTimeBetweenTokenRateUpdates: BigNumber; + tokenRate: BigNumber; + l1Timestamp: BigNumber; + } } -interface OptL2DeployScriptParams extends OptL1DeployScriptParams { - l2Token?: { name?: string; symbol?: string }; +export class L1DeployAllScript extends DeployScript { + + constructor( + deployer: Wallet, + bridgeImplAddress: string, + bridgeProxyAddress: string, + tokenRateNotifierImplAddress: string, + opStackTokenRatePusherImplAddress: string, + logger?: Logger + ) { + super(deployer, logger); + this.bridgeImplAddress = bridgeImplAddress; + this.bridgeProxyAddress = bridgeProxyAddress; + this.tokenRateNotifierImplAddress = tokenRateNotifierImplAddress; + this.opStackTokenRatePusherImplAddress = opStackTokenRatePusherImplAddress; + } + + public bridgeImplAddress: string; + public bridgeProxyAddress: string; + public tokenRateNotifierImplAddress: string; + public opStackTokenRatePusherImplAddress: string; } -interface OptDeploymentOptions extends CommonOptions { - logger?: Logger; - overrides?: Overrides; +export class L2DeployAllScript extends DeployScript { + + constructor( + deployer: Wallet, + tokenImplAddress: string, + tokenProxyAddress: string, + tokenRebasableImplAddress: string, + tokenRebasableProxyAddress: string, + tokenBridgeImplAddress: string, + tokenBridgeProxyAddress: string, + tokenRateOracleImplAddress: string, + tokenRateOracleProxyAddress: string, + logger?: Logger + ) { + super(deployer, logger); + this.tokenImplAddress = tokenImplAddress; + this.tokenProxyAddress = tokenProxyAddress; + this.tokenRebasableImplAddress = tokenRebasableImplAddress; + this.tokenRebasableProxyAddress = tokenRebasableProxyAddress; + this.tokenBridgeImplAddress = tokenBridgeImplAddress; + this.tokenBridgeProxyAddress = tokenBridgeProxyAddress; + this.tokenRateOracleImplAddress = tokenRateOracleImplAddress; + this.tokenRateOracleProxyAddress = tokenRateOracleProxyAddress; + } + + public tokenImplAddress: string; + public tokenProxyAddress: string; + public tokenRebasableImplAddress: string; + public tokenRebasableProxyAddress: string; + public tokenBridgeImplAddress: string; + public tokenBridgeProxyAddress: string; + public tokenRateOracleImplAddress: string; + public tokenRateOracleProxyAddress: string; } -export default function deployment( +/// Deploy all from scratch +/// L1 part +/// L1LidoTokensBridge + Proxy +/// TokenRateNotifier +/// OpStackTokenRatePusher +/// L2 part +/// TokenRateOracle + Proxy +/// ERC20BridgedPermit + Proxy +/// ERC20RebasableBridgedPermit + Proxy +/// L2ERC20ExtendedTokensBridge + Proxy +export default function deploymentAll( networkName: NetworkName, options: OptDeploymentOptions = {} ) { const optAddresses = addresses(networkName, options); return { - async erc20TokenBridgeDeployScript( - l1Token: string, + async deployAllScript( l1Params: OptL1DeployScriptParams, - l2Params: OptL2DeployScriptParams - ) { + l2Params: OptL2DeployScriptParams, + ): Promise<[L1DeployAllScript, L2DeployAllScript]> { + const [ expectedL1TokenBridgeImplAddress, expectedL1TokenBridgeProxyAddress, - ] = await network.predictAddresses(l1Params.deployer, 2); + expectedL1TokenRateNotifierImplAddress, + expectedL1OpStackTokenRatePusherImplAddress, + ] = await network.predictAddresses(l1Params.deployer, l1Params.contractsShift + 4); const [ + expectedL2TokenRateOracleImplAddress, + expectedL2TokenRateOracleProxyAddress, expectedL2TokenImplAddress, expectedL2TokenProxyAddress, + expectedL2TokenRebasableImplAddress, + expectedL2TokenRebasableProxyAddress, expectedL2TokenBridgeImplAddress, - expectedL2TokenBridgeProxyAddress, - ] = await network.predictAddresses(l2Params.deployer, 4); + expectedL2TokenBridgeProxyAddress + ] = await network.predictAddresses(l2Params.deployer, l2Params.contractsShift + 8); - const l1DeployScript = new DeployScript( + const l1DeployScript = new L1DeployAllScript( l1Params.deployer, + expectedL1TokenBridgeImplAddress, + expectedL1TokenBridgeProxyAddress, + expectedL1TokenRateNotifierImplAddress, + expectedL1OpStackTokenRatePusherImplAddress, options?.logger ) .addStep({ - factory: L1ERC20TokenBridge__factory, + factory: L1LidoTokensBridge__factory, args: [ optAddresses.L1CrossDomainMessenger, expectedL2TokenBridgeProxyAddress, - l1Token, + l1Params.l1TokenNonRebasable, + l1Params.l1TokenRebasable, expectedL2TokenProxyAddress, + expectedL2TokenRebasableProxyAddress, + l1Params.accountingOracle, options?.overrides, ], afterDeploy: (c) => @@ -71,7 +173,7 @@ export default function deployment( args: [ expectedL1TokenBridgeImplAddress, l1Params.admins.proxy, - L1ERC20TokenBridge__factory.createInterface().encodeFunctionData( + L1LidoTokensBridge__factory.createInterface().encodeFunctionData( "initialize", [l1Params.admins.bridge] ), @@ -79,29 +181,106 @@ export default function deployment( ], afterDeploy: (c) => assert.equal(c.address, expectedL1TokenBridgeProxyAddress), + }) + .addStep({ + factory: TokenRateNotifier__factory, + args: [ + l1Params.deployer.address, + l1Params.l1AuthorizedRebaseCaller, + options?.overrides, + ], + afterDeploy: (c) => + assert.equal(c.address, expectedL1TokenRateNotifierImplAddress), + }) + .addStep({ + factory: OpStackTokenRatePusher__factory, + args: [ + optAddresses.L1CrossDomainMessenger, + l1Params.l1TokenNonRebasable, + l1Params.accountingOracle, + expectedL2TokenRateOracleProxyAddress, + l1Params.l2GasLimitForPushingTokenRate, + options?.overrides, + ], + afterDeploy: (c) => + assert.equal(c.address, expectedL1OpStackTokenRatePusherImplAddress), }); - const l1TokenInfo = IERC20Metadata__factory.connect( - l1Token, + const l1TokenNonRebasableInfo = IERC20Metadata__factory.connect( + l1Params.l1TokenNonRebasable, + l1Params.deployer + ); + + const l1TokenRebasableInfo = IERC20Metadata__factory.connect( + l1Params.l1TokenRebasable, l1Params.deployer ); - const [decimals, l2TokenName, l2TokenSymbol] = await Promise.all([ - l1TokenInfo.decimals(), - l2Params.l2Token?.name ?? l1TokenInfo.name(), - l2Params.l2Token?.symbol ?? l1TokenInfo.symbol(), + const [ + l2TokenNonRebasableDecimals, l2TokenNonRebasableName, l2TokenNonRebasableSymbol, + l2TokenRebasableDecimals, l2TokenRebasableName, l2TokenRebasableSymbol + ] = await Promise.all([ + l1TokenNonRebasableInfo.decimals(), + l2Params.l2TokenNonRebasable?.name ?? l1TokenNonRebasableInfo.name(), + l2Params.l2TokenNonRebasable?.symbol ?? l1TokenNonRebasableInfo.symbol(), + l1TokenRebasableInfo.decimals(), + l2Params.l2TokenRebasable?.name ?? l1TokenRebasableInfo.name(), + l2Params.l2TokenRebasable?.symbol ?? l1TokenRebasableInfo.symbol(), ]); - const l2DeployScript = new DeployScript( + const l2DeployScript = new L2DeployAllScript( l2Params.deployer, + expectedL2TokenImplAddress, + expectedL2TokenProxyAddress, + expectedL2TokenRebasableImplAddress, + expectedL2TokenRebasableProxyAddress, + expectedL2TokenBridgeImplAddress, + expectedL2TokenBridgeProxyAddress, + expectedL2TokenRateOracleImplAddress, + expectedL2TokenRateOracleProxyAddress, options?.logger ) .addStep({ - factory: ERC20Bridged__factory, + factory: TokenRateOracle__factory, + args: [ + optAddresses.L2CrossDomainMessenger, + expectedL2TokenBridgeProxyAddress, + expectedL1OpStackTokenRatePusherImplAddress, + l2Params.tokenRateOracle.tokenRateOutdatedDelay, + l2Params.tokenRateOracle.maxAllowedL2ToL1ClockLag, + l2Params.tokenRateOracle.maxAllowedTokenRateDeviationPerDayBp, + l2Params.tokenRateOracle.oldestRateAllowedInPauseTimeSpan, + l2Params.tokenRateOracle.maxAllowedTimeBetweenTokenRateUpdates, + options?.overrides, + ], + afterDeploy: (c) => + assert.equal(c.address, expectedL2TokenRateOracleImplAddress), + }) + .addStep({ + factory: OssifiableProxy__factory, + args: [ + expectedL2TokenRateOracleImplAddress, + l2Params.admins.proxy, + TokenRateOracle__factory.createInterface().encodeFunctionData( + "initialize", + [ + l2Params.admins.bridge, + l2Params.tokenRateOracle.tokenRate, + l2Params.tokenRateOracle.l1Timestamp + ] + ), + options?.overrides, + ], + afterDeploy: (c) => + assert.equal(c.address, expectedL2TokenRateOracleProxyAddress), + }) + .addStep({ + factory: ERC20BridgedPermit__factory, args: [ - l2TokenName, - l2TokenSymbol, - decimals, + l2TokenNonRebasableName, + l2TokenNonRebasableSymbol, + l2Params.l2TokenNonRebasable.version, + l2TokenNonRebasableDecimals, expectedL2TokenBridgeProxyAddress, options?.overrides, ], @@ -113,9 +292,13 @@ export default function deployment( args: [ expectedL2TokenImplAddress, l2Params.admins.proxy, - ERC20Bridged__factory.createInterface().encodeFunctionData( + ERC20BridgedPermit__factory.createInterface().encodeFunctionData( "initialize", - [l2TokenName, l2TokenSymbol] + [ + l2TokenNonRebasableName, + l2TokenNonRebasableSymbol, + l2Params.l2TokenNonRebasable.version + ] ), options?.overrides, ], @@ -123,12 +306,47 @@ export default function deployment( assert.equal(c.address, expectedL2TokenProxyAddress), }) .addStep({ - factory: L2ERC20TokenBridge__factory, + factory: ERC20RebasableBridgedPermit__factory, + args: [ + l2TokenRebasableName, + l2TokenRebasableSymbol, + l2Params.l2TokenRebasable.version, + l2TokenRebasableDecimals, + expectedL2TokenProxyAddress, + expectedL2TokenRateOracleProxyAddress, + expectedL2TokenBridgeProxyAddress, + options?.overrides, + ], + afterDeploy: (c) => + assert.equal(c.address, expectedL2TokenRebasableImplAddress), + }) + .addStep({ + factory: OssifiableProxy__factory, + args: [ + expectedL2TokenRebasableImplAddress, + l2Params.admins.proxy, + ERC20RebasableBridgedPermit__factory.createInterface().encodeFunctionData( + "initialize", + [ + l2TokenRebasableName, + l2TokenRebasableSymbol, + l2Params.l2TokenRebasable.version + ] + ), + options?.overrides, + ], + afterDeploy: (c) => + assert.equal(c.address, expectedL2TokenRebasableProxyAddress), + }) + .addStep({ + factory: L2ERC20ExtendedTokensBridge__factory, args: [ optAddresses.L2CrossDomainMessenger, expectedL1TokenBridgeProxyAddress, - l1Token, + l1Params.l1TokenNonRebasable, + l1Params.l1TokenRebasable, expectedL2TokenProxyAddress, + expectedL2TokenRebasableProxyAddress, options?.overrides, ], afterDeploy: (c) => @@ -139,7 +357,7 @@ export default function deployment( args: [ expectedL2TokenBridgeImplAddress, l2Params.admins.proxy, - L2ERC20TokenBridge__factory.createInterface().encodeFunctionData( + L2ERC20ExtendedTokensBridge__factory.createInterface().encodeFunctionData( "initialize", [l2Params.admins.bridge] ), @@ -147,7 +365,7 @@ export default function deployment( ], }); - return [l1DeployScript, l2DeployScript]; + return [l1DeployScript as L1DeployAllScript, l2DeployScript as L2DeployAllScript]; }, }; } diff --git a/utils/optimism/deploymentOracle.ts b/utils/optimism/deploymentOracle.ts new file mode 100644 index 00000000..ad2fa31d --- /dev/null +++ b/utils/optimism/deploymentOracle.ts @@ -0,0 +1,168 @@ +import { assert } from "chai"; +import { BigNumber, Wallet } from "ethers"; +import { ethers } from "hardhat"; +import addresses from "./addresses"; +import { DeployScriptParams, OptDeploymentOptions } from "./types"; +import network, { NetworkName } from "../network"; +import { DeployScript, Logger } from "../deployment/DeployScript"; +import { + OssifiableProxy__factory, + TokenRateOracle__factory, + TokenRateNotifier__factory, + OpStackTokenRatePusher__factory +} from "../../typechain"; + +interface OptDeployScriptParams extends DeployScriptParams { + l1AuthorizedRebaseCaller: string; +} + +interface OptL2DeployScriptParams extends DeployScriptParams { + tokenRateOracle: { + maxAllowedL2ToL1ClockLag: BigNumber; + maxAllowedTokenRateDeviationPerDayBp: BigNumber; + oldestRateAllowedInPauseTimeSpan: BigNumber; + maxAllowedTimeBetweenTokenRateUpdates: BigNumber; + tokenRate: BigNumber; + l1Timestamp: BigNumber; + } +} + +export class OracleL1DeployScript extends DeployScript { + constructor( + deployer: Wallet, + tokenRateNotifierImplAddress: string, + opStackTokenRatePusherImplAddress: string, + logger?: Logger + ) { + super(deployer, logger); + this.tokenRateNotifierImplAddress = tokenRateNotifierImplAddress; + this.opStackTokenRatePusherImplAddress = opStackTokenRatePusherImplAddress; + } + + public tokenRateNotifierImplAddress: string; + public opStackTokenRatePusherImplAddress: string; +} + +export class OracleL2DeployScript extends DeployScript { + constructor( + deployer: Wallet, + tokenRateOracleImplAddress: string, + tokenRateOracleProxyAddress: string, + logger?: Logger + ) { + super(deployer, logger); + this.tokenRateOracleImplAddress = tokenRateOracleImplAddress; + this.tokenRateOracleProxyAddress = tokenRateOracleProxyAddress; + } + + public tokenRateOracleImplAddress: string; + public tokenRateOracleProxyAddress: string; +} + +/// Deploy Oracle + L1 part to push rate +/// L1 part +/// TokenRateNotifier +/// OpStackTokenRatePusher +/// L2 part +/// TokenRateOracle + proxy +export default function deploymentOracle( + networkName: NetworkName, + options: OptDeploymentOptions = {} +) { + const optAddresses = addresses(networkName, options); + return { + async oracleDeployScript( + l1Token: string, + l2ERC20TokenBridge: string, + accountingOracle: string, + l2GasLimitForPushingTokenRate: number, + tokenRateOutdatedDelay: number, + l1Params: OptDeployScriptParams, + l2Params: OptL2DeployScriptParams, + ): Promise<[OracleL1DeployScript, OracleL2DeployScript]> { + + const [ + expectedL1TokenRateNotifierImplAddress, + expectedL1OpStackTokenRatePusherImplAddress, + ] = await network.predictAddresses(l1Params.deployer, 2); + + const [ + expectedL2TokenRateOracleImplAddress, + expectedL2TokenRateOracleProxyAddress + ] = await network.predictAddresses(l2Params.deployer, 2); + + const l1DeployScript = new OracleL1DeployScript( + l1Params.deployer, + expectedL1TokenRateNotifierImplAddress, + expectedL1OpStackTokenRatePusherImplAddress, + options?.logger + ) + .addStep({ + factory: TokenRateNotifier__factory, + args: [ + l1Params.deployer.address, + l1Params.l1AuthorizedRebaseCaller, + options?.overrides, + ], + afterDeploy: (c) => + assert.equal(c.address, expectedL1TokenRateNotifierImplAddress), + }) + .addStep({ + factory: OpStackTokenRatePusher__factory, + args: [ + optAddresses.L1CrossDomainMessenger, + l1Token, + accountingOracle, + expectedL2TokenRateOracleProxyAddress, + l2GasLimitForPushingTokenRate, + options?.overrides, + ], + afterDeploy: (c) => + assert.equal(c.address, expectedL1OpStackTokenRatePusherImplAddress), + }); + + const l2DeployScript = new OracleL2DeployScript( + l2Params.deployer, + expectedL2TokenRateOracleImplAddress, + expectedL2TokenRateOracleProxyAddress, + options?.logger + ) + .addStep({ + factory: TokenRateOracle__factory, + args: [ + optAddresses.L2CrossDomainMessenger, + l2ERC20TokenBridge, + expectedL1OpStackTokenRatePusherImplAddress, + tokenRateOutdatedDelay, + l2Params.tokenRateOracle.maxAllowedL2ToL1ClockLag, + l2Params.tokenRateOracle.maxAllowedTokenRateDeviationPerDayBp, + l2Params.tokenRateOracle.oldestRateAllowedInPauseTimeSpan, + l2Params.tokenRateOracle.maxAllowedTimeBetweenTokenRateUpdates, + options?.overrides, + ], + afterDeploy: (c) => + assert.equal(c.address, expectedL2TokenRateOracleImplAddress), + }) + .addStep({ + factory: OssifiableProxy__factory, + args: [ + expectedL2TokenRateOracleImplAddress, + l2Params.admins.proxy, + TokenRateOracle__factory.createInterface().encodeFunctionData( + "initialize", + [ + l2Params.admins.bridge, + l2Params.tokenRateOracle.tokenRate, + l2Params.tokenRateOracle.l1Timestamp + ] + ), + options?.overrides, + ], + afterDeploy: (c) => + assert.equal(c.address, expectedL2TokenRateOracleProxyAddress), + }); + + return [l1DeployScript as OracleL1DeployScript, l2DeployScript as OracleL2DeployScript]; + }, + }; +} diff --git a/utils/optimism/index.ts b/utils/optimism/index.ts index 0ca0e9a2..330f3644 100644 --- a/utils/optimism/index.ts +++ b/utils/optimism/index.ts @@ -1,6 +1,5 @@ import addresses from "./addresses"; import contracts from "./contracts"; -import deployment from "./deployment"; import testing from "./testing"; import messaging from "./messaging"; @@ -8,6 +7,6 @@ export default { testing, addresses, contracts, - messaging, - deployment, + messaging }; + diff --git a/utils/optimism/testing.ts b/utils/optimism/testing.ts index 635d2e6a..6f38f783 100644 --- a/utils/optimism/testing.ts +++ b/utils/optimism/testing.ts @@ -1,21 +1,26 @@ import { Signer } from "ethers"; import { JsonRpcProvider } from "@ethersproject/providers"; - +import { BigNumber } from "ethers"; import { IERC20, ERC20Bridged, IERC20__factory, - L1ERC20TokenBridge, - L2ERC20TokenBridge, - ERC20Bridged__factory, + L1LidoTokensBridge, + L2ERC20ExtendedTokensBridge, + ERC20BridgedPermit__factory, ERC20BridgedStub__factory, - L1ERC20TokenBridge__factory, - L2ERC20TokenBridge__factory, + ERC20WrapperStub__factory, + TokenRateOracle__factory, + L1LidoTokensBridge__factory, + L2ERC20ExtendedTokensBridge__factory, CrossDomainMessengerStub__factory, + ERC20RebasableBridgedPermit__factory, + AccountingOracleStub__factory, + IAccountingOracle__factory, } from "../../typechain"; import addresses from "./addresses"; import contracts from "./contracts"; -import deployment from "./deployment"; +import deploymentAll from "./deployment"; import testingUtils from "../testing"; import { BridgingManagement } from "../bridging-management"; import network, { NetworkName, SignerOrProvider } from "../network"; @@ -43,7 +48,10 @@ export default function testing(networkName: NetworkName) { ...bridgeContracts, }; }, - async getIntegrationTestSetup() { + async getIntegrationTestSetup( + totalPooledEther: BigNumber, + totalShares: BigNumber + ) { const hasDeployedContracts = testingUtils.env.USE_DEPLOYED_CONTRACTS(false); @@ -53,13 +61,13 @@ export default function testing(networkName: NetworkName) { const bridgeContracts = hasDeployedContracts ? await loadDeployedBridges(ethProvider, optProvider) - : await deployTestBridge(networkName, ethProvider, optProvider); + : await deployTestBridge(networkName, totalPooledEther, totalShares, ethProvider, optProvider); - const [l1ERC20TokenBridgeAdminAddress] = - await BridgingManagement.getAdmins(bridgeContracts.l1ERC20TokenBridge); + const [l1ERC20ExtendedTokensAdminAddress] = + await BridgingManagement.getAdmins(bridgeContracts.l1LidoTokensBridge); - const [l2ERC20TokenBridgeAdminAddress] = - await BridgingManagement.getAdmins(bridgeContracts.l2ERC20TokenBridge); + const [l2ERC20ExtendedTokensBridgeAdminAddress] = + await BridgingManagement.getAdmins(bridgeContracts.l2ERC20ExtendedTokensBridge); const l1TokensHolder = hasDeployedContracts ? await testingUtils.impersonate( @@ -79,13 +87,13 @@ export default function testing(networkName: NetworkName) { // if the L1 bridge admin is a contract, remove it's code to // make it behave as EOA await ethProvider.send("hardhat_setCode", [ - l1ERC20TokenBridgeAdminAddress, + l1ERC20ExtendedTokensAdminAddress, "0x", ]); // same for the L2 bridge admin await optProvider.send("hardhat_setCode", [ - l2ERC20TokenBridgeAdminAddress, + l2ERC20ExtendedTokensBridgeAdminAddress, "0x", ]); @@ -98,12 +106,12 @@ export default function testing(networkName: NetworkName) { ...bridgeContracts, l1CrossDomainMessenger: optContracts.L1CrossDomainMessengerStub, l2CrossDomainMessenger: optContracts.L2CrossDomainMessenger, - l1ERC20TokenBridgeAdmin: await testingUtils.impersonate( - l1ERC20TokenBridgeAdminAddress, + l1ERC20ExtendedTokensBridgeAdmin: await testingUtils.impersonate( + l1ERC20ExtendedTokensAdminAddress, ethProvider ), - l2ERC20TokenBridgeAdmin: await testingUtils.impersonate( - l2ERC20TokenBridgeAdminAddress, + l2ERC20ExtendedTokensBridgeAdmin: await testingUtils.impersonate( + l2ERC20ExtendedTokensBridgeAdminAddress, optProvider ) }; @@ -152,15 +160,26 @@ async function loadDeployedBridges( l2SignerOrProvider: SignerOrProvider ) { return { - l1Token: IERC20__factory.connect( - testingUtils.env.OPT_L1_TOKEN(), + l1Token: ERC20WrapperStub__factory.connect( + testingUtils.env.OPT_L1_NON_REBASABLE_TOKEN(), + l1SignerOrProvider + ), + l1TokenRebasable: IERC20__factory.connect( + testingUtils.env.OPT_L1_REBASABLE_TOKEN(), + l1SignerOrProvider + ), + accountingOracle: AccountingOracleStub__factory.connect( + testingUtils.env.OPT_L1_ACCOUNTING_ORACLE(), l1SignerOrProvider ), + ...connectBridgeContracts( { - l2Token: testingUtils.env.OPT_L2_TOKEN(), - l1ERC20TokenBridge: testingUtils.env.OPT_L1_ERC20_TOKEN_BRIDGE(), - l2ERC20TokenBridge: testingUtils.env.OPT_L2_ERC20_TOKEN_BRIDGE(), + tokenRateOracle: testingUtils.env.OPT_L2_TOKEN_RATE_ORACLE(), + l2Token: testingUtils.env.OPT_L2_NON_REBASABLE_TOKEN(), + l2TokenRebasable: testingUtils.env.OPT_L2_REBASABLE_TOKEN(), + l1LidoTokensBridge: testingUtils.env.OPT_L1_ERC20_TOKEN_BRIDGE(), + l2ERC20ExtendedTokensBridge: testingUtils.env.OPT_L2_ERC20_TOKEN_BRIDGE(), }, l1SignerOrProvider, l2SignerOrProvider @@ -170,43 +189,96 @@ async function loadDeployedBridges( async function deployTestBridge( networkName: NetworkName, + totalPooledEther: BigNumber, + totalShares: BigNumber, ethProvider: JsonRpcProvider, optProvider: JsonRpcProvider ) { + const tokenRate = BigNumber.from(10).pow(27) + .mul(totalPooledEther) + .div(totalShares); + const genesisTime = 1; + const secondsPerSlot = 2; + const lastProcessingRefSlot = 3; + const maxAllowedL2ToL1ClockLag = BigNumber.from(86400); + const maxAllowedTokenRateDeviationPerDay = BigNumber.from(500); + const oldestRateAllowedInPauseTimeSpan = BigNumber.from(86400*3); + const maxAllowedTimeBetweenTokenRateUpdates = BigNumber.from(3600); + const tokenRateOutdatedDelay = BigNumber.from(86400); + const ethDeployer = testingUtils.accounts.deployer(ethProvider); const optDeployer = testingUtils.accounts.deployer(optProvider); - const l1Token = await new ERC20BridgedStub__factory(ethDeployer).deploy( - "Test Token", - "TT" + const l1TokenRebasable = await new ERC20BridgedStub__factory(ethDeployer).deploy( + "Test Token Rebasable", + "TTR" ); - const [ethDeployScript, optDeployScript] = await deployment( + const l1TokenNonRebasable = await new ERC20WrapperStub__factory(ethDeployer).deploy( + l1TokenRebasable.address, + "Test Non Rebasable Token", + "TT", + totalPooledEther, + totalShares + ); + + const accountingOracle = await new AccountingOracleStub__factory(ethDeployer).deploy( + genesisTime, + secondsPerSlot, + lastProcessingRefSlot + ); + + const [ethDeployScript, optDeployScript] = await deploymentAll( networkName - ).erc20TokenBridgeDeployScript( - l1Token.address, + ).deployAllScript( { + l1TokenNonRebasable: l1TokenNonRebasable.address, + l1TokenRebasable: l1TokenRebasable.address, + accountingOracle: accountingOracle.address, + l2GasLimitForPushingTokenRate: BigNumber.from(300_000), + l1AuthorizedRebaseCaller: ethDeployer.address, deployer: ethDeployer, admins: { proxy: ethDeployer.address, bridge: ethDeployer.address }, + contractsShift: 0 }, { deployer: optDeployer, admins: { proxy: optDeployer.address, bridge: optDeployer.address }, + contractsShift: 0, + tokenRateOracle: { + tokenRateOutdatedDelay: tokenRateOutdatedDelay, + maxAllowedL2ToL1ClockLag: maxAllowedL2ToL1ClockLag, + maxAllowedTokenRateDeviationPerDayBp: maxAllowedTokenRateDeviationPerDay, + oldestRateAllowedInPauseTimeSpan: oldestRateAllowedInPauseTimeSpan, + maxAllowedTimeBetweenTokenRateUpdates: maxAllowedTimeBetweenTokenRateUpdates, + tokenRate: tokenRate, + l1Timestamp: BigNumber.from('1000') + }, + l2TokenNonRebasable: { + name: "wstETH", + symbol: "WST", + version: "1", + decimals: 18 + }, + l2TokenRebasable: { + name: "stETH", + symbol: "ST", + version: "1", + decimals: 18 + } } ); await ethDeployScript.run(); await optDeployScript.run(); - const l1ERC20TokenBridgeProxyDeployStepIndex = 1; const l1BridgingManagement = new BridgingManagement( - ethDeployScript.getContractAddress(l1ERC20TokenBridgeProxyDeployStepIndex), + ethDeployScript.bridgeProxyAddress, ethDeployer ); - const l2ERC20TokenBridgeProxyDeployStepIndex = 3; const l2BridgingManagement = new BridgingManagement( - optDeployScript.getContractAddress(l2ERC20TokenBridgeProxyDeployStepIndex), + optDeployScript.tokenBridgeProxyAddress, optDeployer ); @@ -223,12 +295,16 @@ async function deployTestBridge( }); return { - l1Token: l1Token.connect(ethProvider), + l1Token: l1TokenNonRebasable.connect(ethProvider), + l1TokenRebasable: l1TokenRebasable.connect(ethProvider), + accountingOracle: accountingOracle.connect(ethProvider), ...connectBridgeContracts( { - l2Token: optDeployScript.getContractAddress(1), - l1ERC20TokenBridge: ethDeployScript.getContractAddress(1), - l2ERC20TokenBridge: optDeployScript.getContractAddress(3), + tokenRateOracle: optDeployScript.tokenRateOracleProxyAddress, + l2Token: optDeployScript.tokenProxyAddress, + l2TokenRebasable: optDeployScript.tokenRebasableProxyAddress, + l1LidoTokensBridge: ethDeployScript.bridgeProxyAddress, + l2ERC20ExtendedTokensBridge: optDeployScript.tokenBridgeProxyAddress }, ethProvider, optProvider @@ -238,29 +314,42 @@ async function deployTestBridge( function connectBridgeContracts( addresses: { + tokenRateOracle: string; l2Token: string; - l1ERC20TokenBridge: string; - l2ERC20TokenBridge: string; + l2TokenRebasable: string; + l1LidoTokensBridge: string; + l2ERC20ExtendedTokensBridge: string; }, ethSignerOrProvider: SignerOrProvider, optSignerOrProvider: SignerOrProvider ) { - const l1ERC20TokenBridge = L1ERC20TokenBridge__factory.connect( - addresses.l1ERC20TokenBridge, + + const l1LidoTokensBridge = L1LidoTokensBridge__factory.connect( + addresses.l1LidoTokensBridge, ethSignerOrProvider ); - const l2ERC20TokenBridge = L2ERC20TokenBridge__factory.connect( - addresses.l2ERC20TokenBridge, + const l2ERC20ExtendedTokensBridge = L2ERC20ExtendedTokensBridge__factory.connect( + addresses.l2ERC20ExtendedTokensBridge, optSignerOrProvider ); - const l2Token = ERC20Bridged__factory.connect( + const l2Token = ERC20BridgedPermit__factory.connect( addresses.l2Token, optSignerOrProvider ); + const l2TokenRebasable = ERC20RebasableBridgedPermit__factory.connect( + addresses.l2TokenRebasable, + optSignerOrProvider + ); + const tokenRateOracle = TokenRateOracle__factory.connect( + addresses.tokenRateOracle, + optSignerOrProvider + ); return { + tokenRateOracle, l2Token, - l1ERC20TokenBridge, - l2ERC20TokenBridge, + l2TokenRebasable, + l1LidoTokensBridge, + l2ERC20ExtendedTokensBridge }; } @@ -269,8 +358,8 @@ async function printLoadedTestConfig( bridgeContracts: { l1Token: IERC20; l2Token: ERC20Bridged; - l1ERC20TokenBridge: L1ERC20TokenBridge; - l2ERC20TokenBridge: L2ERC20TokenBridge; + l1LidoTokensBridge: L1LidoTokensBridge; + l2ERC20ExtendedTokensBridge: L2ERC20ExtendedTokensBridge; }, l1TokensHolder?: Signer ) { @@ -290,10 +379,10 @@ async function printLoadedTestConfig( console.log(` · L1 Tokens Holder Balance: ${holderBalance.toString()}`); } console.log( - ` · L1 ERC20 Token Bridge: ${bridgeContracts.l1ERC20TokenBridge.address}` + ` · L1 ERC20 Token Bridge: ${bridgeContracts.l1LidoTokensBridge.address}` ); console.log( - ` · L2 ERC20 Token Bridge: ${bridgeContracts.l2ERC20TokenBridge.address}` + ` · L2 ERC20 Token Bridge: ${bridgeContracts.l2ERC20ExtendedTokensBridge.address}` ); console.log(); } diff --git a/utils/optimism/types.ts b/utils/optimism/types.ts index 38cea940..461be4c1 100644 --- a/utils/optimism/types.ts +++ b/utils/optimism/types.ts @@ -1,3 +1,6 @@ +import { Overrides, Wallet } from "ethers"; +import { Logger } from "../deployment/DeployScript"; + export type OptContractNames = | "L1CrossDomainMessenger" | "L2CrossDomainMessenger"; @@ -7,3 +10,17 @@ export type CustomOptContractAddresses = Partial; export interface CommonOptions { customAddresses?: CustomOptContractAddresses; } + +export interface DeployScriptParams { + deployer: Wallet; + admins: { + proxy: string; + bridge: string + }; + contractsShift: number; +} + +export interface OptDeploymentOptions extends CommonOptions { + logger?: Logger; + overrides?: Overrides; +} diff --git a/utils/optimism/upgrade.ts b/utils/optimism/upgrade.ts new file mode 100644 index 00000000..ceea1f87 --- /dev/null +++ b/utils/optimism/upgrade.ts @@ -0,0 +1,331 @@ +import { assert } from "chai"; +import { BigNumber, Wallet } from "ethers"; +import addresses from "./addresses"; +import { OptDeploymentOptions, DeployScriptParams } from "./types"; +import network, { NetworkName } from "../network"; +import { DeployScript, Logger } from "../deployment/DeployScript"; +import { + ERC20BridgedPermit__factory, + ERC20RebasableBridgedPermit__factory, + L1LidoTokensBridge__factory, + L2ERC20ExtendedTokensBridge__factory, + OssifiableProxy__factory, + TokenRateOracle__factory, + TokenRateNotifier__factory, + OpStackTokenRatePusher__factory, + IERC20Metadata__factory +} from "../../typechain"; + +interface OptL1UpgradeScriptParams extends DeployScriptParams { + l1TokenNonRebasable: string; + l1TokenRebasable: string; + accountingOracle: string; + l2GasLimitForPushingTokenRate: BigNumber; + l1TokenBridge: string; + l1AuthorizedRebaseCaller: string; +} + +interface OptL2UpgradeScriptParams extends DeployScriptParams { + l2TokenBridge: string; + l2TokenNonRebasable: { + address: string; + name?: string; + symbol?: string; + version: string; + decimals?: BigNumber; + }; + l2TokenRebasable: { + name?: string; + symbol?: string; + version: string; + decimals?: BigNumber; + }; + tokenRateOracle: { + constructor: { + tokenRateOutdatedDelay: BigNumber; + maxAllowedL2ToL1ClockLag: BigNumber; + maxAllowedTokenRateDeviationPerDayBp: BigNumber; + oldestRateAllowedInPauseTimeSpan: BigNumber; + maxAllowedTimeBetweenTokenRateUpdates: BigNumber; + } + initialize: { + tokenRate: BigNumber; + l1Timestamp: BigNumber; + } + } +} + +export class L1UpgradeScript extends DeployScript { + + constructor( + deployer: Wallet, + bridgeProxyAddress: string, + bridgeImplAddress: string, + tokenRateNotifierImplAddress: string, + opStackTokenRatePusherImplAddress: string, + logger?: Logger + ) { + super(deployer, logger); + this.bridgeProxyAddress = bridgeProxyAddress; + this.bridgeImplAddress = bridgeImplAddress; + this.tokenRateNotifierImplAddress = tokenRateNotifierImplAddress; + this.opStackTokenRatePusherImplAddress = opStackTokenRatePusherImplAddress; + } + + public bridgeProxyAddress: string; + public bridgeImplAddress: string; + public tokenRateNotifierImplAddress: string; + public opStackTokenRatePusherImplAddress: string; +} + +export class L2UpgradeScript extends DeployScript { + + constructor( + deployer: Wallet, + tokenImplAddress: string, + tokenRebasableImplAddress: string, + tokenRebasableProxyAddress: string, + tokenBridgeProxyAddress: string, + tokenBridgeImplAddress: string, + tokenRateOracleImplAddress: string, + tokenRateOracleProxyAddress: string, + logger?: Logger + ) { + super(deployer, logger); + this.tokenImplAddress = tokenImplAddress; + this.tokenRebasableImplAddress = tokenRebasableImplAddress; + this.tokenRebasableProxyAddress = tokenRebasableProxyAddress; + this.tokenBridgeProxyAddress = tokenBridgeProxyAddress; + this.tokenBridgeImplAddress = tokenBridgeImplAddress; + this.tokenRateOracleImplAddress = tokenRateOracleImplAddress; + this.tokenRateOracleProxyAddress = tokenRateOracleProxyAddress; + } + + public tokenImplAddress: string; + public tokenRebasableImplAddress: string; + public tokenRebasableProxyAddress: string; + public tokenBridgeProxyAddress: string; + public tokenBridgeImplAddress: string; + public tokenRateOracleImplAddress: string; + public tokenRateOracleProxyAddress: string; +} + + +/// L1 part +/// new TokenRateNotifier Impl +/// new OpStackTokenRatePusher Impl +/// new L1Bridge Impl +/// L2 part +/// TokenRateOracle + proxy +/// new L2Bridge Impl +/// RebasableToken(stETH) Impl and Proxy (because it was never deployed before) +/// Non-rebasable token (wstETH) new Impl with Permissions + +export default function upgrade( + networkName: NetworkName, + options: OptDeploymentOptions = {} +) { + const optAddresses = addresses(networkName, options); + return { + async upgradeScript( + l1Params: OptL1UpgradeScriptParams, + l2Params: OptL2UpgradeScriptParams, + ): Promise<[L1UpgradeScript, L2UpgradeScript]> { + + const [ + expectedL1TokenBridgeImplAddress, + expectedL1TokenRateNotifierImplAddress, + expectedL1OpStackTokenRatePusherImplAddress, + ] = await network.predictAddresses(l1Params.deployer, l1Params.contractsShift + 3); + + const [ + // Oracle + Proxy + expectedL2TokenRateOracleImplAddress, + expectedL2TokenRateOracleProxyAddress, + // wstETH Impl + expectedL2TokenImplAddress, + // stETH Impl + Proxy + expectedL2TokenRebasableImplAddress, + expectedL2TokenRebasableProxyAddress, + // L2Bridge Impl + expectedL2TokenBridgeImplAddress + ] = await network.predictAddresses(l2Params.deployer, l2Params.contractsShift + 6); + + const l1UpgradeScript = new L1UpgradeScript( + l1Params.deployer, + l1Params.l1TokenBridge, + expectedL1TokenBridgeImplAddress, + expectedL1TokenRateNotifierImplAddress, + expectedL1OpStackTokenRatePusherImplAddress, + options?.logger + ) + .addStep({ + factory: L1LidoTokensBridge__factory, + args: [ + optAddresses.L1CrossDomainMessenger, + l2Params.l2TokenBridge, + l1Params.l1TokenNonRebasable, + l1Params.l1TokenRebasable, + l2Params.l2TokenNonRebasable.address, + expectedL2TokenRebasableProxyAddress, + l1Params.accountingOracle, + options?.overrides, + ], + afterDeploy: (c) => + assert.equal(c.address, expectedL1TokenBridgeImplAddress), + }) + .addStep({ + factory: TokenRateNotifier__factory, + args: [ + l1Params.deployer.address, + l1Params.l1AuthorizedRebaseCaller, + options?.overrides, + ], + afterDeploy: (c) => + assert.equal(c.address, expectedL1TokenRateNotifierImplAddress), + }) + .addStep({ + factory: OpStackTokenRatePusher__factory, + args: [ + optAddresses.L1CrossDomainMessenger, + l1Params.l1TokenNonRebasable, + l1Params.accountingOracle, + expectedL2TokenRateOracleProxyAddress, + l1Params.l2GasLimitForPushingTokenRate, + options?.overrides, + ], + afterDeploy: (c) => + assert.equal(c.address, expectedL1OpStackTokenRatePusherImplAddress), + }); + + const l1TokenNonRebasableInfo = IERC20Metadata__factory.connect( + l1Params.l1TokenNonRebasable, + l1Params.deployer + ); + + const l1TokenRebasableInfo = IERC20Metadata__factory.connect( + l1Params.l1TokenRebasable, + l1Params.deployer + ); + const [ + l2TokenNonRebasableDecimals, l2TokenNonRebasableName, l2TokenNonRebasableSymbol, + l2TokenRebasableDecimals, l2TokenRebasableName, l2TokenRebasableSymbol + ] = await Promise.all([ + l1TokenNonRebasableInfo.decimals(), + l2Params.l2TokenNonRebasable?.name ?? l1TokenNonRebasableInfo.name(), + l2Params.l2TokenNonRebasable?.symbol ?? l1TokenNonRebasableInfo.symbol(), + l1TokenRebasableInfo.decimals(), + l2Params.l2TokenRebasable?.name ?? l1TokenRebasableInfo.name(), + l2Params.l2TokenRebasable?.symbol ?? l1TokenRebasableInfo.symbol(), + ]); + + const l2UpgradeScript = new L2UpgradeScript( + l2Params.deployer, + expectedL2TokenImplAddress, + expectedL2TokenRebasableImplAddress, + expectedL2TokenRebasableProxyAddress, + l2Params.l2TokenBridge, + expectedL2TokenBridgeImplAddress, + expectedL2TokenRateOracleImplAddress, + expectedL2TokenRateOracleProxyAddress, + options?.logger + ) + .addStep({ + factory: TokenRateOracle__factory, + args: [ + optAddresses.L2CrossDomainMessenger, + l2Params.l2TokenBridge, + expectedL1OpStackTokenRatePusherImplAddress, + l2Params.tokenRateOracle.constructor.tokenRateOutdatedDelay, + l2Params.tokenRateOracle.constructor.maxAllowedL2ToL1ClockLag, + l2Params.tokenRateOracle.constructor.maxAllowedTokenRateDeviationPerDayBp, + l2Params.tokenRateOracle.constructor.oldestRateAllowedInPauseTimeSpan, + l2Params.tokenRateOracle.constructor.maxAllowedTimeBetweenTokenRateUpdates, + options?.overrides, + ], + afterDeploy: (c) => + assert.equal(c.address, expectedL2TokenRateOracleImplAddress), + }) + .addStep({ + factory: OssifiableProxy__factory, + args: [ + expectedL2TokenRateOracleImplAddress, + l2Params.admins.proxy, + TokenRateOracle__factory.createInterface().encodeFunctionData( + "initialize", + [ + l2Params.admins.bridge, + l2Params.tokenRateOracle.initialize.tokenRate, + l2Params.tokenRateOracle.initialize.l1Timestamp + ] + ), + options?.overrides, + ], + afterDeploy: (c) => + assert.equal(c.address, expectedL2TokenRateOracleProxyAddress), + }) + .addStep({ + factory: ERC20BridgedPermit__factory, + args: [ + l2TokenNonRebasableName, + l2TokenNonRebasableSymbol, + l2Params.l2TokenNonRebasable.version, + l2TokenNonRebasableDecimals, + l2Params.l2TokenBridge, + options?.overrides, + ], + afterDeploy: (c) => + assert.equal(c.address, expectedL2TokenImplAddress), + }) + .addStep({ + factory: ERC20RebasableBridgedPermit__factory, + args: [ + l2TokenRebasableName, + l2TokenRebasableSymbol, + l2Params.l2TokenRebasable.version, + l2TokenRebasableDecimals, + l2Params.l2TokenNonRebasable.address, + expectedL2TokenRateOracleProxyAddress, + l2Params.l2TokenBridge, + options?.overrides, + ], + afterDeploy: (c) => + assert.equal(c.address, expectedL2TokenRebasableImplAddress), + }) + .addStep({ + factory: OssifiableProxy__factory, + args: [ + expectedL2TokenRebasableImplAddress, + l2Params.admins.proxy, + ERC20RebasableBridgedPermit__factory.createInterface().encodeFunctionData( + "initialize", + [ + l2TokenRebasableName, + l2TokenRebasableSymbol, + l2Params.l2TokenRebasable.version + ] + ), + options?.overrides, + ], + afterDeploy: (c) => + assert.equal(c.address, expectedL2TokenRebasableProxyAddress), + }) + .addStep({ + factory: L2ERC20ExtendedTokensBridge__factory, + args: [ + optAddresses.L2CrossDomainMessenger, + l1Params.l1TokenBridge, + l1Params.l1TokenNonRebasable, + l1Params.l1TokenRebasable, + l2Params.l2TokenNonRebasable.address, + expectedL2TokenRebasableProxyAddress, + options?.overrides, + ], + afterDeploy: (c) => + assert.equal(c.address, expectedL2TokenBridgeImplAddress), + }); + + return [l1UpgradeScript as L1UpgradeScript, l2UpgradeScript as L2UpgradeScript]; + }, + }; +} diff --git a/utils/testing/contractsFactory.ts b/utils/testing/contractsFactory.ts new file mode 100644 index 00000000..8d377eea --- /dev/null +++ b/utils/testing/contractsFactory.ts @@ -0,0 +1,129 @@ +import hre from "hardhat"; +import { BigNumber } from "ethers"; +import { SignerWithAddress } from "@nomiclabs/hardhat-ethers/signers"; +import { + ERC20BridgedPermit__factory, + TokenRateOracle__factory, + ERC20RebasableBridgedPermit__factory, + OssifiableProxy__factory, + TokenRateOracle, + ERC20BridgedPermit +} from "../../typechain"; + +export async function erc20BridgedPermitUnderProxy( + deployer: SignerWithAddress, + holder: SignerWithAddress, + name: string, + symbol: string, + version: string, + decimals: BigNumber, + bridge: string +) { + const erc20BridgedPermitImpl = await new ERC20BridgedPermit__factory(deployer).deploy( + name, + symbol, + version, + decimals, + bridge + ); + + const erc20BridgedPermitProxy = await new OssifiableProxy__factory(deployer).deploy( + erc20BridgedPermitImpl.address, + deployer.address, + ERC20BridgedPermit__factory.createInterface().encodeFunctionData("initialize", [ + name, + symbol, + version + ]) + ); + + return ERC20BridgedPermit__factory.connect( + erc20BridgedPermitProxy.address, + holder + ); +} + +export async function tokenRateOracleUnderProxy( + deployer: SignerWithAddress, + messenger: string, + l2ERC20TokenBridge: string, + l1TokenRatePusher: string, + tokenRateOutdatedDelay: BigNumber, + maxAllowedL2ToL1ClockLag: BigNumber, + maxAllowedTokenRateDeviationPerDay: BigNumber, + oldestRateAllowedInPauseTimeSpan: BigNumber, + maxAllowedTimeBetweenTokenRateUpdates: BigNumber, + tokenRate: BigNumber, + rateL1Timestamp: BigNumber +) { + const tokenRateOracleImpl = await new TokenRateOracle__factory(deployer).deploy( + messenger, + l2ERC20TokenBridge, + l1TokenRatePusher, + tokenRateOutdatedDelay, + maxAllowedL2ToL1ClockLag, + maxAllowedTokenRateDeviationPerDay, + oldestRateAllowedInPauseTimeSpan, + maxAllowedTimeBetweenTokenRateUpdates + ); + + const tokenRateOracleProxy = new OssifiableProxy__factory(deployer); + + const unsignedTx = tokenRateOracleProxy.getDeployTransaction(tokenRateOracleImpl.address, + deployer.address, + tokenRateOracleImpl.interface.encodeFunctionData("initialize", [ + deployer.address, + tokenRate, + rateL1Timestamp + ])); + + const response = await deployer.sendTransaction(unsignedTx); + const provider = await hre.ethers.provider; + const contractReceipt = await response.wait(); + const blockTimestampOfDeployment = BigNumber.from((await provider.getBlock(contractReceipt.blockNumber)).timestamp); + const txResponse = await response.wait(); + + const tokenRateOracle = TokenRateOracle__factory.connect( + txResponse.contractAddress, + deployer + ); + + return { tokenRateOracle, blockTimestampOfDeployment }; +} + +export async function erc20RebasableBridgedPermitUnderProxy( + deployer: SignerWithAddress, + holder: SignerWithAddress, + name: string, + symbol: string, + version: string, + decimals: BigNumber, + tokenRateOracle: TokenRateOracle, + erc20BridgedPermit: ERC20BridgedPermit, + bridge: string +) { + const erc20RebasableBridgedPermitImpl = await new ERC20RebasableBridgedPermit__factory(deployer).deploy( + name, + symbol, + version, + decimals, + erc20BridgedPermit.address, + tokenRateOracle.address, + bridge + ); + + const erc20RebasableBridgedPermitProxy = await new OssifiableProxy__factory(deployer).deploy( + erc20RebasableBridgedPermitImpl.address, + deployer.address, + ERC20RebasableBridgedPermit__factory.createInterface().encodeFunctionData("initialize", [ + name, + symbol, + version, + ]) + ); + + return ERC20RebasableBridgedPermit__factory.connect( + erc20RebasableBridgedPermitProxy.address, + holder + ); +} diff --git a/utils/testing/e2e.ts b/utils/testing/e2e.ts index 010596e7..760d474a 100644 --- a/utils/testing/e2e.ts +++ b/utils/testing/e2e.ts @@ -6,37 +6,18 @@ const abiCoder = ethers.utils.defaultAbiCoder; export const E2E_TEST_CONTRACTS_OPTIMISM = { l1: { - l1Token: "0xaF8a2F0aE374b03376155BF745A3421Dac711C12", - l1LDOToken: "0xcAdf242b97BFdD1Cb4Fd282E5FcADF965883065f", - l1ERC20TokenBridge: "0x2DD0CD60b6048549ab576f06BC20EC53B457244E", - aragonVoting: "0x86f4C03aB9fCE83970Ce3FC7C23f25339f484EE5", - tokenManager: "0x4A63e41611B7c70DA6f42a806dFBcECB0B2D314F", - agent: "0x80720229bdB8caf9f67ddf871e98a76655A39AFe", - l1CrossDomainMessenger: "0x4361d0F75A0186C05f971c566dC6bEa5957483fD", + l1Token: "0xB82381A3fBD3FaFA77B3a7bE693342618240067b", + l1LDOToken: "0xd06dF83b8ad6D89C86a187fba4Eae918d497BdCB", + l1ERC20ExtendedTokensBridge: "0x4Abf633d9c0F4aEebB4C2E3213c7aa1b8505D332", + aragonVoting: "0x39A0EbdEE54cB319f4F42141daaBDb6ba25D341A", + tokenManager: "0xC73cd4B2A7c1CBC5BF046eB4A7019365558ABF66", + agent: "0x32A0E5828B62AAb932362a4816ae03b860b65e83", + l1CrossDomainMessenger: "0x58Cc85b8D04EA49cC6DBd3CbFFd00B4B8D6cb3ef", }, l2: { - l2Token: "0x4c2ECf847C89d5De3187F1b0081E4dcdBe063C68", - l2ERC20TokenBridge: "0x0A5c6AB7B41E066b5C40907dd06063703be21B19", - govBridgeExecutor: "0x2365F00fFD70958EC2c20B601D501e4b75798D93", - }, -}; - -export const E2E_TEST_CONTRACTS_ARBITRUM = { - l1: { - l1Token: "0x7AEE39c46f20135114e85A03C02aB4FE73fB8127", - l1GatewayRouter: "0xa2a8F940752aDc4A3278B63B96d56D72D2b075B1", - l1ERC20TokenGateway: "0x46b10f1E65f19876F50bfdD59C9B39E9De6B9150", - aragonVoting: "0x04F9590D3EEC8e619D7714ffeF664aD3fd53b880", - tokenManager: "0x1ee7e87486f9ae6e27a5e58310a5319394360cf0", - agent: "0x12869c3349f993c5c20bab9482b7d16aff0ae2f9", - l1LDOToken: "0x84b4c77b260910fc02dddac41ef0e45e658b18af", - inbox: "0x578BAde599406A8fE3d24Fd7f7211c0911F5B29e", - }, - l2: { - l2Token: "0x57FA50b80f79b9140fe7249A93D432d9fa8C4192", - l2GatewayRouter: "0x57f54f87C44d816f60b92864e23b8c0897D4d81D", - l2ERC20TokenGateway: "0xD06491e4C8B3107B83dC134894C4c96ED8ddbfa2", - govBridgeExecutor: "0x4e8CC9024Ea3FE886623025fF2aD0CA4bb3D1F42", + l2Token: "0x24B47cd3A74f1799b32B2de11073764Cb1bb318B", + l2ERC20ExtendedTokensBridge: "0xdBA2760246f315203F8B716b3a7590F0FFdc704a", + govBridgeExecutor: "0xf695357C66bA514150Da95b189acb37b46DDe602", }, }; @@ -84,40 +65,5 @@ export const encodeEVMScript = ( ); }; -export const createArbitrumVoting = async ( - ctx: any, - executorCalldata: string, - options: Record = {} -) => { - const messageCalldata = await ctx.inbox.interface.encodeFunctionData( - "createRetryableTicket", - [ - ctx.govBridgeExecutor.address, - 0, - options.maxSubmissionCost || wei`0.01 ether`, - ctx.l2Tester.address, - ctx.l2Tester.address, - options.maxGas || 3000000, - options.gasPriceBid || 5000000000, - executorCalldata, - ] - ); - - const agentCalldata = ctx.agent.interface.encodeFunctionData("execute", [ - ctx.inbox.address, - options.callValue || wei`0.01 ether`, - messageCalldata, - ]); - const agentEvmScript = encodeEVMScript(ctx.agent.address, agentCalldata); - - const newVoteCalldata = - "0xd5db2c80" + - abiCoder.encode(["bytes", "string"], [agentEvmScript, ""]).substring(2); - const votingEvmScript = encodeEVMScript(ctx.voting.address, newVoteCalldata); - const newVotingTx = await ctx.tokenMnanager.forward(votingEvmScript); - - await newVotingTx.wait(); -}; - export const sleep = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms)); diff --git a/utils/testing/env.ts b/utils/testing/env.ts index faf8acd6..bebddeb4 100644 --- a/utils/testing/env.ts +++ b/utils/testing/env.ts @@ -4,41 +4,35 @@ export default { USE_DEPLOYED_CONTRACTS(defaultValue: boolean = false) { return env.bool("TESTING_USE_DEPLOYED_CONTRACTS", defaultValue); }, - - ARB_L1_TOKEN() { - return env.address("TESTING_ARB_L1_TOKEN"); - }, - ARB_L2_TOKEN() { - return env.address("TESTING_ARB_L2_TOKEN"); - }, - ARB_L1_ERC20_TOKEN_GATEWAY() { - return env.address("TESTING_ARB_L1_ERC20_TOKEN_GATEWAY"); + OPT_L1_NON_REBASABLE_TOKEN() { + return env.address("TESTING_OPT_L1_NON_REBASABLE_TOKEN"); }, - ARB_L2_ERC20_TOKEN_GATEWAY() { - return env.address("TESTING_ARB_L2_ERC20_TOKEN_GATEWAY"); + OPT_L1_REBASABLE_TOKEN() { + return env.address("TESTING_OPT_L1_REBASABLE_TOKEN"); }, - ARB_L1_GATEWAY_ROUTER(defaultValue?: string) { - return env.address("TESTING_ARB_L1_GATEWAY_ROUTER", defaultValue); + OPT_L1_ACCOUNTING_ORACLE() { + return env.address("TESTING_OPT_L1_ACCOUNTING_ORACLE"); }, - ARB_L2_GATEWAY_ROUTER(defaultValue?: string) { - return env.address("TESTING_ARB_L2_GATEWAY_ROUTER", defaultValue); - }, - ARB_GOV_BRIDGE_EXECUTOR() { - return env.address("TESTING_ARB_GOV_BRIDGE_EXECUTOR"); + OPT_L1_ERC20_TOKEN_BRIDGE() { + return env.address("TESTING_OPT_L1_ERC20_TOKEN_BRIDGE"); }, - OPT_L1_TOKEN() { - return env.address("TESTING_OPT_L1_TOKEN"); + OPT_L2_TOKEN_RATE_ORACLE() { + return env.address("TESTING_OPT_L2_TOKEN_RATE_ORACLE"); }, - OPT_L2_TOKEN() { - return env.address("TESTING_OPT_L2_TOKEN"); + OPT_L2_NON_REBASABLE_TOKEN() { + return env.address("TESTING_OPT_L2_NON_REBASABLE_TOKEN"); }, - OPT_L1_ERC20_TOKEN_BRIDGE() { - return env.address("TESTING_OPT_L1_ERC20_TOKEN_BRIDGE"); + OPT_L2_REBASABLE_TOKEN() { + return env.address("TESTING_OPT_L2_REBASABLE_TOKEN"); }, OPT_L2_ERC20_TOKEN_BRIDGE() { return env.address("TESTING_OPT_L2_ERC20_TOKEN_BRIDGE"); }, + + OPT_L1_TOKEN_RATE_NOTIFIER() { + return env.address("TESTING_OPT_L1_TOKEN_RATE_NOTIFIER"); + }, OPT_GOV_BRIDGE_EXECUTOR() { return env.address("TESTING_OPT_GOV_BRIDGE_EXECUTOR"); }, diff --git a/utils/testing/helpers.ts b/utils/testing/helpers.ts new file mode 100644 index 00000000..6fd5de4b --- /dev/null +++ b/utils/testing/helpers.ts @@ -0,0 +1,92 @@ +import { utils, BigNumber, ethers } from "ethers"; +import { ContractTransaction } from "@ethersproject/contracts"; +import { JsonRpcProvider } from "@ethersproject/providers"; +import { AccountingOracleStub } from "../../typechain"; +import { SignerWithAddress } from "@nomiclabs/hardhat-ethers/signers"; +import { getContractAddress } from "ethers/lib/utils"; + +export async function getContractTransactionTimestamp(provider: JsonRpcProvider, tx: ContractTransaction) { + const contractReceipt = await tx.wait(); + return BigNumber.from((await provider.getBlock(contractReceipt.blockNumber)).timestamp); +} + +export async function getBlockTimestamp(provider: JsonRpcProvider, secondsToShift: number) { + const blockNumber = await provider.getBlockNumber(); + return BigNumber.from((await provider.getBlock(blockNumber)).timestamp + secondsToShift); +} + +export async function tokenRateAndTimestampPacked(tokenRate: BigNumber, blockTimestamp: BigNumber, data: string) { + return ethers.utils.hexConcat( + [ + ethers.utils.hexZeroPad(tokenRate.toHexString(), 16), + ethers.utils.hexZeroPad(blockTimestamp.toHexString(), 5), + data + ] + ); +} + +export async function refSlotTimestamp(accountingOracle: AccountingOracleStub) { + const genesisTime = await accountingOracle.GENESIS_TIME(); + const secondsPerSlot = await accountingOracle.SECONDS_PER_SLOT(); + const lastProcessingRefSlot = await accountingOracle.getLastProcessingRefSlot(); + return genesisTime.add(secondsPerSlot.mul(lastProcessingRefSlot)); +} + +export function getInterfaceID(contractInterface: utils.Interface) { + let interfaceID = ethers.constants.Zero; + const functions: string[] = Object.keys(contractInterface.functions); + for (let i = 0; i < functions.length; i++) { + interfaceID = interfaceID.xor(contractInterface.getSighash(functions[i])); + } + return interfaceID; +} + +export async function predictAddresses(account: SignerWithAddress, txsCount: number) { + const currentNonce = await account.getTransactionCount(); + + const res: string[] = []; + for (let i = 0; i < txsCount; ++i) { + res.push( + getContractAddress({ + from: account.address, + nonce: currentNonce + i, + }) + ); + } + return res; +} + +export function getExchangeRate(decimals: BigNumber, totalPooledEther: BigNumber, totalShares: BigNumber) { + return (BigNumber.from(10).pow(decimals)).mul(totalPooledEther).div(totalShares); +} + +/// token / rate +export function nonRebasableFromRebasableL1(rebasable: BigNumber, totalPooledEther: BigNumber, totalShares: BigNumber) { + return rebasable + .mul(totalShares) + .div(totalPooledEther); +} + +/// token * rate +export function rebasableFromNonRebasableL1(rebasable: BigNumber, totalPooledEther: BigNumber, totalShares: BigNumber) { + return rebasable + .mul(totalPooledEther) + .div(totalShares); +} + +export function nonRebasableFromRebasableL2(rebasable: BigNumber, decimals: BigNumber, exchangeRate: BigNumber) { + return rebasable + .mul(BigNumber.from(10).pow(decimals)) + .div(exchangeRate); +} + +export function rebasableFromNonRebasableL2(nonRebasable: BigNumber, decimals: BigNumber, exchangeRate: BigNumber) { + return nonRebasable + .mul(exchangeRate) + .div(BigNumber.from(10).pow(decimals)); +} + +export function almostEqual(num1: BigNumber, num2: BigNumber) { + const delta = (num1.sub(num2)).abs(); + return delta.lte(BigNumber.from('2')); +} diff --git a/utils/testing/index.ts b/utils/testing/index.ts index 3df84575..6033d5cc 100644 --- a/utils/testing/index.ts +++ b/utils/testing/index.ts @@ -11,5 +11,5 @@ export default { env, accounts, impersonate, - setBalance, + setBalance }; diff --git a/utils/testing/permit-helpers.ts b/utils/testing/permit-helpers.ts new file mode 100644 index 00000000..16531c79 --- /dev/null +++ b/utils/testing/permit-helpers.ts @@ -0,0 +1,116 @@ +import { BigNumberish, Signer } from "ethers"; +import { ExternallyOwnedAccount } from "@ethersproject/abstract-signer"; + +import { keccak256, toUtf8Bytes, defaultAbiCoder } from "ethers/lib/utils"; +import { ecsign as ecSignBuf } from "ethereumjs-util"; + +const PERMIT_TYPE_HASH = streccak( + 'Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)' +) +const TRANSFER_WITH_AUTHORIZATION_TYPE_HASH = streccak( + 'TransferWithAuthorization(address from,address to,uint256 value,uint256 validAfter,uint256 validBefore,bytes32 nonce)' +) + +interface Eip1271Contract { + address: string; + sign( + hash: string + ): Promise<[string, string, string] & { v: string; r: string; s: string }>; +} + +async function signEOA(digest: string, account: ExternallyOwnedAccount) { + return ecSign(digest, account.privateKey) +} + +async function signEIP1271(digest: string, eip1271Contract: Eip1271Contract) { + const sig = await eip1271Contract.sign(digest) + return { v: sig.v, r: sig.r, s: sig.s } +} + +export async function signEOAorEIP1271(digest: string, signer: Eip1271Contract | ExternallyOwnedAccount) { + if (signer.hasOwnProperty('sign')) { + return await signEIP1271(digest, signer as Eip1271Contract); + } else { + return await signEOA(digest, signer as ExternallyOwnedAccount); + } +} + +export function makeDomainSeparator(name: string, version: string, chainId: BigNumberish, verifyingContract: string) { + return keccak256( + defaultAbiCoder.encode( + ['bytes32', 'bytes32', 'bytes32', 'uint256', 'address'], + [ + streccak('EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)'), + streccak(name), + streccak(version), + chainId, + verifyingContract, + ] + ) + ) +} + +export async function signPermit( + owner: string, + signer: ExternallyOwnedAccount | Eip1271Contract, + spender: string, + value: number, + deadline: string, + nonce: number, + domainSeparator: string +) { + const digest = calculatePermitDigest(owner, spender, value, nonce, deadline, domainSeparator) + return await signEOAorEIP1271(digest, signer) +} + +export function calculatePermitDigest(owner: string, spender: string, value: number, nonce: number, deadline: string, domainSeparator: string) { + return calculateEIP712Digest( + domainSeparator, + PERMIT_TYPE_HASH, + ['address', 'address', 'uint256', 'uint256', 'uint256'], + [owner, spender, value, nonce, deadline] + ) +} + +export function calculateTransferAuthorizationDigest(from: string, to: string, value: number, validAfter: string, validBefore: string, nonce: string, domainSeparator: string) { + return calculateEIP712Digest( + domainSeparator, + TRANSFER_WITH_AUTHORIZATION_TYPE_HASH, + ['address', 'address', 'uint256', 'uint256', 'uint256', 'bytes32'], + [from, to, value, validAfter, validBefore, nonce] + ) +} + +function calculateEIP712Digest(domainSeparator: string, typeHash: string, types: string[], parameters: unknown[]) { + const structHash = keccak256(defaultAbiCoder.encode(['bytes32', ...types], [typeHash, ...parameters])); + const data = '0x1901' + strip0x(domainSeparator) + strip0x(structHash) + return keccak256(data) +} + +function ecSign(digest: string, privateKey: string) { + const { v, r, s } = ecSignBuf(bufferFromHexString(digest), bufferFromHexString(privateKey)) + return { v, r: hexStringFromBuffer(r), s: hexStringFromBuffer(s) } +} + +function strip0x(s: string) { + return s.substr(0, 2) === '0x' ? s.substr(2) : s +} + + +function hex(n: number, byteLen = undefined) { + const s = n.toString(16) + return byteLen === undefined ? s : s.padStart(byteLen * 2, '0') +} + + +export function streccak(s: string) { + return keccak256(toUtf8Bytes(s)); +} + +function hexStringFromBuffer(buf: Buffer) { + return '0x' + buf.toString('hex') +} + +function bufferFromHexString(hex: string) { + return Buffer.from(strip0x(hex), 'hex') +} diff --git a/utils/testing/scenario.ts b/utils/testing/scenario.ts index 66998a17..af008bdc 100644 --- a/utils/testing/scenario.ts +++ b/utils/testing/scenario.ts @@ -1,6 +1,6 @@ import { CtxFactory, StepTest, CtxFn } from "./types"; -class ScenarioTest { +export class ScenarioTest { private afterFn?: CtxFn; private beforeFn?: CtxFn; diff --git a/utils/testing/unit.ts b/utils/testing/unit.ts index a282e77e..f6d83c95 100644 --- a/utils/testing/unit.ts +++ b/utils/testing/unit.ts @@ -5,7 +5,7 @@ export function unit(title: string, ctxFactory: CtxFactory) return new UnitTest(title, ctxFactory); } -class UnitTest { +export class UnitTest { public readonly title: string; private readonly ctxFactory: CtxFactory;