Replace foundry with HyperlaneCoreDeployer (#28)

This PR replaces foundry with the SDK deployment tooling.

To deploy hyperlane to a new chain, users add their `ChainMetadata` to `config/chains.ts`, and their `MultisigIsmConfig(s)` to `config/multisig_ism.ts`, and run:
```
yarn ts-node scripts/deploy.ts --local foochain --remotes goerli mumbai --key 0x1234...
```

This script deploys core, IGP, ISM, and TestRecipient contracts to the local chain, and IGP, ISM, and TestRecipient contracts to the remote chains, writing contract addresses to `artifacts/addresses.json`, and agent config to `artifacts/agent_config.json`

Users can test their deployment by running:
```
yarn ts-node scripts/test-messages.ts --chains foochain goerli mumbai --key 0x1234...
```

This script dispatches messages between each pair of provided chains, regularly polling the mailboxes to check to see if they were delivered.
asaj/ci-2
Asa Oines 2 years ago committed by GitHub
parent b839529296
commit 1fdf00846f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 9
      .github/workflows/ci.yml
  2. 8
      .gitignore
  3. 4
      .gitmodules
  4. 60
      README.md
  5. 22
      artifacts/addresses.json
  6. 84
      ci.sh
  7. 24
      config/chains.ts
  8. 96
      config/multisig_ism.json
  9. 19
      config/multisig_ism.ts
  10. 119
      config/networks.json
  11. 24
      config/start_blocks.ts
  12. 14
      foundry.toml
  13. 80
      lib/BytesLib.sol
  14. 105
      lib/CheckLib.sol
  15. 247
      lib/ConfigLib.sol
  16. 165
      lib/DeployLib.sol
  17. 1
      lib/forge-std
  18. 20
      package.json
  19. 42
      scripts/CheckMessage.s.sol
  20. 35
      scripts/DeployCore.s.sol
  21. 39
      scripts/DeployMultisigIsm.s.sol
  22. 44
      scripts/SendTestMessage.s.sol
  23. 18
      scripts/deploy.ts
  24. 167
      scripts/test-messages.ts
  25. 53
      src/TestRecipientDeployer.ts
  26. 159
      src/config.ts
  27. 172
      src/deployer.ts
  28. 37
      src/json.ts
  29. 28
      tsconfig.json
  30. 340
      yarn.lock

@ -12,9 +12,6 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v3
with:
submodules: recursive
- uses: actions/cache@v3 - uses: actions/cache@v3
with: with:
path: '**/node_modules' path: '**/node_modules'
@ -32,7 +29,7 @@ jobs:
exit 1 exit 1
fi fi
build: deploy:
needs: [yarn-install] needs: [yarn-install]
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
@ -47,8 +44,8 @@ jobs:
with: with:
version: nightly version: nightly
- name: Build - name: deploy
run: forge build run: ./ci.sh
lint: lint:
needs: [yarn-install] needs: [yarn-install]

8
.gitignore vendored

@ -1,6 +1,4 @@
node_modules/ node_modules/
broadcast/ dist/
out/ artifacts/
forge-cache/ .yarn*
cache/
config/*_agent_config.json

4
.gitmodules vendored

@ -1,4 +0,0 @@
[submodule "lib/forge-std"]
path = lib/forge-std
url = https://github.com/foundry-rs/forge-std
tag = v1.1.1

@ -14,61 +14,43 @@ For more detailed instructions on how to deploy Hyperlane to the EVM chain of yo
### Setup ### Setup
- Installing foundry
See https://github.com/foundry-rs/foundry#installation
- Installing dependencies - Installing dependencies
```bash ```bash
yarn install yarn install
git submodule init && git submodule update --remote
``` ```
### Deploying core contracts ### Deploying contracts
This script is used to incrementally deploy the core Hyperlane smart contracts to a new chain. If you're deploying to a new chain, ensure there is a corresponding entry `config/networks.ts` and `config/multisig_ism.ts`.
If a contract address for `$LOCAL` is set to `0x0` in `./config/networks.json`, that contract will be deployed. If not, the script will assert that the contract is configured according to the config in `./config`. This script is used to deploy the following core Hyperlane contracts to a new chain.
The Hyperlane protocol expects exactly one instance of these contracts on every supported chain.
If you're deploying to a new chain, ensure there is a corresponding entry for `$LOCAL` in `./config/networks.json` with all contract addresses set to `0x0`. - A `Mailbox` for sending and receiving messages
- `ValidatorAnnounce` for registering validators
The script deploys: This script also deploys the following contracts to all chains, new and existing.
The Hyperlane protocol expects many instances of these contracts on every supported chains
- A `ProxyAdmin`, used to administer `TransparentUpgradableProxies` for `Mailbox` and `InterchainGasPaymaster` - An `ISM` (MultisigISM) for verifying inbound messages from remote chains
- A `Mailbox`, which applications can use to send and receive messages - An `InterchainGasPaymaster` for paying relayers for message delivery
- A `MultisigIsm`. Applications can optionally use this ISM to verify interchain messages sent to the local chain. - A `TestRecipient` contract that can be used to test that interchain messages can be delivered
- An `InterchainGasPaymaster`. Applications can optionally use this contract to pay a relayer to deliver their interchain messages to remote chains.
- A `TestRecipient`. Users can send messages to this contract to verify that everything is working properly.
```bash ```bash
# The name of the chain to deploy to. Used to configure the localDomain for the DEBUG=hyperlane* yarn ts-node script scripts/deploy.ts --local anvil \
# Mailbox contract. --remotes goerli sepolia \
export LOCAL=YOUR_CHAIN_NAME --key 0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80
# An RPC url for the chain to deploy to.
export RPC_URL=YOUR_CHAIN_RPC_URL
# The comma separated name(s) of the chains to receive messages from.
# Used to configure the default MultisigIsm.
export REMOTES=ethereum,polygon,avalanche,celo,arbitrum,optimism,bsc,moonbeam
# Pass whatever wallet option you would like to use https://book.getfoundry.sh/reference/forge/forge-script#wallet-options---raw
forge script scripts/DeployCore.s.sol --broadcast --rpc-url $RPC_URL
``` ```
### Deploying a MultisigIsm ### Sending test messages
This script is used to deploy a `MultigsigIsm` to the chain of your choice. It will be initialized to verify messages from `$REMOTES` using the config for each remote chain specified in `./config/multisig_ism.json`.
Applications can optionally use this ISM to verify interchain messages. This script is used to verify that Hyperlane messages can be sent between specified chains.
The script will also deploy a `TestRecipient`, configured to use the deployed ISM. Users should have first deployed `TestRecipient` contracts to each of the specified chains.
```bash ```
# This address will wind up owning the MultisigIsm after it's deployed. DEBUG=hyperlane* yarn ts-node scripts/test-messages.ts \
export OWNER=0x1234 --chains anvil goerli sepolia \
# An RPC url for the chain to deploy to. --key 0x6f0311f4a0722954c46050bb9f088c4890999e16b64ad02784d24b5fd6d09061
export RPC_URL=YOUR_CHAIN_RPC_URL
# The comma separated name(s) of the chain(s) to receive messages from.
export REMOTES=YOUR_CHAIN_NAME
forge script scripts/DeployMultisigIsm.s.sol --broadcast --rpc-url $RPC_URL --private-key $PRIVATE_KEY
``` ```

@ -0,0 +1,22 @@
{
"anvil1": {
"validatorAnnounce": "0x38a024C0b412B9d1db8BC398140D00F5Af3093D4",
"proxyAdmin": "0xD42912755319665397FF090fBB63B1a31aE87Cee",
"mailbox": "0x525C7063E7C20997BaaE9bDa922159152D0e8417",
"multisigIsm": "0xCA8c8688914e0F7096c920146cd0Ad85cD7Ae8b9",
"testRecipient": "0x976fcd02f7C4773dd89C309fBF55D5923B4c98a1",
"storageGasOracle": "0xfcDB4564c18A9134002b9771816092C9693622e3",
"interchainGasPaymaster": "0x32EEce76C2C2e8758584A83Ee2F522D4788feA0f",
"defaultIsmInterchainGasPaymaster": "0x02b0B4EFd909240FCB2Eb5FAe060dC60D112E3a4"
},
"anvil2": {
"multisigIsm": "0xF32D39ff9f6Aa7a7A64d7a4F00a54826Ef791a55",
"testRecipient": "0x976fcd02f7C4773dd89C309fBF55D5923B4c98a1",
"proxyAdmin": "0xD42912755319665397FF090fBB63B1a31aE87Cee",
"storageGasOracle": "0xfcDB4564c18A9134002b9771816092C9693622e3",
"interchainGasPaymaster": "0x32EEce76C2C2e8758584A83Ee2F522D4788feA0f",
"defaultIsmInterchainGasPaymaster": "0x02b0B4EFd909240FCB2Eb5FAe060dC60D112E3a4",
"validatorAnnounce": "0x5FeaeBfB4439F3516c74939A9D04e95AFE82C4ae",
"mailbox": "0xB0f05d25e41FbC2b52013099ED9616f1206Ae21B"
}
}

84
ci.sh

@ -0,0 +1,84 @@
for CHAIN in anvil1 anvil2
do
mkdir ./artifacts/$CHAIN ./artifacts/$CHAIN/state \
./artifacts/$CHAIN/validator ./artifacts/$CHAIN/relayer
chmod 777 ./artifacts/$CHAIN -R
done
anvil --chain-id 31337 -p 8545 --state ./artifacts/anvil1/state > /dev/null &
ANVIL_1_PID=$!
anvil --chain-id 31338 -p 8555 --state ./artifacts/anvil2/state > /dev/null &
ANVIL_2_PID=$!
sleep 1
set -e
for i in "anvil1 anvil2 --no-write-agent-config" "anvil2 anvil1 --write-agent-config"
do
set -- $i
echo "Deploying contracts to $1"
DEBUG=hyperlane* yarn ts-node scripts/deploy.ts --local $1 --remotes $2 \
--key 0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80 $3
done
for i in "anvil1 8545 ANVIL1" "anvil2 8555 ANVIL2"
do
set -- $i
echo "Running validator on $1"
# Won't work on anything but linux due to -net=host
docker run --mount type=bind,source="$(pwd)/artifacts",target=/config --net=host \
-e CONFIG_FILES=/config/agent_config.json -e HYP_VALIDATOR_ORIGINCHAINNAME=$1 \
-e HYP_VALIDATOR_REORGPERIOD=1 -e HYP_VALIDATOR_INTERVAL=1 \
-e HYP_BASE_CHAINS_${3}_CONNECTION_URL=http://127.0.0.1:${2} \
-e HYP_VALIDATOR_VALIDATOR_TYPE=hexKey \
-e HYP_VALIDATOR_VALIDATOR_KEY=0x2a871d0798f97d79848a013d4936a73bf4cc922c825d33c1cf7073dff6d409c6 \
-e HYP_VALIDATOR_CHECKPOINTSYNCER_TYPE=localStorage \
-e HYP_VALIDATOR_CHECKPOINTSYNCER_PATH=/config/${1}/validator \
-e HYP_BASE_TRACING_LEVEL=info -e HYP_BASE_TRACING_FMT=pretty \
gcr.io/abacus-labs-dev/hyperlane-agent:5bf8aed-20230323-140136 ./validator &
done
sleep 10
for i in "anvil1 8545" "anvil2 8555"
do
set -- $i
echo "Announcing validator on $1"
VALIDATOR_ANNOUNCE_ADDRESS=$(cat ./artifacts/addresses.json | jq -r ".$1.validatorAnnounce")
VALIDATOR=$(cat ./artifacts/$1/validator/announcement.json | jq -r '.value.validator')
STORAGE_LOCATION=$(cat ./artifacts/$1/validator/announcement.json | jq -r '.value.storage_location')
SIGNATURE=$(cat ./artifacts/$1/validator/announcement.json | jq -r '.serialized_signature')
cast send $VALIDATOR_ANNOUNCE_ADDRESS \
"announce(address, string calldata, bytes calldata)(bool)" \
$VALIDATOR $STORAGE_LOCATION $SIGNATURE --rpc-url http://127.0.0.1:$2 \
--private-key 0x8b3a350cf5c34c9194ca85829a2df0ec3153be0318b5e2d3348e872092edffba
done
for i in "anvil1 anvil2 ANVIL2" "anvil2 anvil1 ANVIL1"
do
set -- $i
echo "Running relayer on $1"
docker run --mount type=bind,source="$(pwd)/artifacts",target=/config --net=host \
-e CONFIG_FILES=/config/agent_config.json \
-e HYP_BASE_CHAINS_ANVIL1_CONNECTION_URL=http://127.0.0.1:8545 \
-e HYP_BASE_CHAINS_ANVIL2_CONNECTION_URL=http://127.0.0.1:8555 \
-e HYP_BASE_TRACING_LEVEL=info -e HYP_BASE_TRACING_FMT=pretty \
-e HYP_RELAYER_ORIGINCHAINNAME=$1 -e HYP_RELAYER_DESTINATIONCHAINNAMES=$2 \
-e HYP_RELAYER_ALLOWLOCALCHECKPOINTSYNCERS=true -e HYP_RELAYER_DB=/config/$1/relayer \
-e HYP_RELAYER_GASPAYMENTENFORCEMENT='[{"type":"none"}]' \
-e HYP_BASE_CHAINS_${3}_SIGNER_TYPE=hexKey \
-e HYP_BASE_CHAINS_${3}_SIGNER_KEY=0xdbda1821b80551c9d65939329250298aa3472ba22feea921c0cf5d620ea67b97 \
gcr.io/abacus-labs-dev/hyperlane-agent:5bf8aed-20230323-140136 ./relayer &
done
DEBUG=hyperlane* yarn ts-node scripts/test-messages.ts --chains anvil1 anvil2 --key 0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80 --timeout 60
docker ps -aq | xargs docker stop | xargs docker rm
kill $ANVIL_1_PID
kill $ANVIL_2_PID

@ -0,0 +1,24 @@
import { ChainMap, ChainMetadata } from '@hyperlane-xyz/sdk';
export const chains: ChainMap<ChainMetadata> = {
// ----------- Your chains here -----------------
anvil: {
name: 'anvil1',
// anvil default chain id
chainId: 31337,
publicRpcUrls: [
{
http: 'http://127.0.0.1:8545',
},
],
},
anvil2: {
name: 'anvil2',
chainId: 31338,
publicRpcUrls: [
{
http: 'http://127.0.0.1:8555',
},
],
},
};

@ -1,96 +0,0 @@
{
"foochain": {
"threshold": 1,
"validators": ["0xb17861defd784d13c257f2430c4724ffa7ffc554"]
},
"alfajores": {
"threshold": 2,
"validators": [
"0xe6072396568e73ce6803b12b7e04164e839f1e54",
"0x9f177f51289b22515f41f95872e1511391b8e105",
"0x15f77400845eb1c971ad08de050861d5508cad6c"
]
},
"fuji": {
"threshold": 2,
"validators": [
"0x9fa19ead5ec76e437948b35e227511b106293c40",
"0x227e7d6507762ece0c94678f8c103eff9d682476",
"0x2379e43740e4aa4fde48cf4f00a3106df1d8420d"
]
},
"mumbai": {
"threshold": 2,
"validators": [
"0x0a664ea799447da6b15645cf8b9e82072a68343f",
"0x6ae6f12929a960aba24ba74ea310e3d37d0ac045",
"0x51f70c047cd73bc7873273707501568857a619c4"
]
},
"bsctestnet": {
"threshold": 2,
"validators": [
"0x23338c8714976dd4a57eaeff17cbd26d7e275c08",
"0x85a618d7450ebc37e0d682371f08dac94eec7a76",
"0x95b76562e4ba1791a27ba4236801271c9115b141"
]
},
"goerli": {
"threshold": 2,
"validators": [
"0xf43fbd072fd38e1121d4b3b0b8a35116bbb01ea9",
"0xa33020552a21f35e75bd385c6ab95c3dfa82d930",
"0x0bba4043ff242f8bf3f39bafa8930a84d644d947"
]
},
"moonbasealpha": {
"threshold": 2,
"validators": [
"0x890c2aeac157c3f067f3e42b8afc797939c59a32",
"0x1b06d6fe69b972ed7420c83599d5a5c0fc185904",
"0xe70b85206a968a99a597581f0fa09c99e7681093"
]
},
"optimismgoerli": {
"threshold": 2,
"validators": [
"0xbb8d77eefbecc55db6e5a19b0fc3dc290776f189",
"0x69792508b4ddaa3ca52241ccfcd1e0b119a1ee65",
"0x11ddb46c6b653e0cdd7ad5bee32ae316e18f8453"
]
},
"arbitrumgoerli": {
"threshold": 2,
"validators": [
"0xce798fa21e323f6b24d9838a10ffecdefdfc4f30",
"0xa792d39dca4426927e0f00c1618d61c9cb41779d",
"0xdf181fcc11dfac5d01467e4547101a856dd5aa04"
]
},
"test1": {
"threshold": 2,
"validators": [
"0xf2561178e8ad8cadd161a855adc6eb02282b426d",
"0x28d638618aca345450604a4bb17e50ce6fe6ee0e",
"0x8dc5bd07ffd0a0053bbf4499747ba6da8442ab36"
]
},
"test2": {
"threshold": 2,
"validators": [
"0xf2561178e8ad8cadd161a855adc6eb02282b426d",
"0x28d638618aca345450604a4bb17e50ce6fe6ee0e",
"0x8dc5bd07ffd0a0053bbf4499747ba6da8442ab36"
]
},
"test3": {
"threshold": 2,
"validators": [
"0xf2561178e8ad8cadd161a855adc6eb02282b426d",
"0x28d638618aca345450604a4bb17e50ce6fe6ee0e",
"0x8dc5bd07ffd0a0053bbf4499747ba6da8442ab36"
]
}
}

@ -0,0 +1,19 @@
import { ChainMap, MultisigIsmConfig } from '@hyperlane-xyz/sdk';
export const multisigIsmConfig: ChainMap<MultisigIsmConfig> = {
// ----------- Your chains here -----------------
anvil1: {
threshold: 1,
validators: [
// Last anvil address
'0xa0ee7a142d267c1f36714e4a8f75612f20a79720',
],
},
anvil2: {
threshold: 1,
validators: [
// Last anvil address
'0xa0ee7a142d267c1f36714e4a8f75612f20a79720',
],
},
};

@ -1,119 +0,0 @@
{
"foochain": {
"id": 1174786466,
"owner": "0xfaD1C94469700833717Fa8a3017278BC1cA8031C",
"contracts": {
"testRecipient": "0xB7f8BC63BbcaD18155201308C8f3540b07f84F5e",
"create2Factory": "0x0000000000000000000000000000000000000000",
"mailbox": "0x610178dA211FEF7D417bC0e6FeD39F05609AD788",
"validatorAnnounce": "0xA51c1fc2f0D1a1b8494Ed1FE312d7C3a78Ed91C0",
"interchainGasPaymaster": "0xCf7Ed3AccA5a467e9e704C703E8D87F634fB0Fc9",
"proxyAdmin": "0x5FbDB2315678afecb367f032d93F642f64180aa3"
}
},
"alfajores": {
"id": 44787,
"owner": "0xfaD1C94469700833717Fa8a3017278BC1cA8031C",
"contracts": {
"proxyAdmin": "0x4e4D563e2cBFC35c4BC16003685443Fae2FA702f",
"mailbox": "0xCC737a94FecaeC165AbCf12dED095BB13F037685",
"interchainGasPaymaster": "0x8f9C3888bFC8a5B25AED115A82eCbb788b196d2a",
"create2Factory": "0xc97D8e6f57b0d64971453dDc6EB8483fec9d163a",
"validatorAnnounce": "0x3Fc742696D5dc9846e04f7A1823D92cb51695f9a",
"testRecipient": "0xBC3cFeca7Df5A45d61BC60E7898E63670e1654aE"
}
},
"fuji": {
"id": 43113,
"owner": "0xfaD1C94469700833717Fa8a3017278BC1cA8031C",
"contracts": {
"proxyAdmin": "0x4e4D563e2cBFC35c4BC16003685443Fae2FA702f",
"mailbox": "0xCC737a94FecaeC165AbCf12dED095BB13F037685",
"interchainGasPaymaster": "0x8f9C3888bFC8a5B25AED115A82eCbb788b196d2a",
"create2Factory": "0xc97D8e6f57b0d64971453dDc6EB8483fec9d163a",
"validatorAnnounce": "0x3Fc742696D5dc9846e04f7A1823D92cb51695f9a",
"testRecipient": "0xBC3cFeca7Df5A45d61BC60E7898E63670e1654aE"
}
},
"mumbai": {
"id": 80001,
"owner": "0xfaD1C94469700833717Fa8a3017278BC1cA8031C",
"contracts": {
"proxyAdmin": "0x4e4D563e2cBFC35c4BC16003685443Fae2FA702f",
"mailbox": "0xCC737a94FecaeC165AbCf12dED095BB13F037685",
"interchainGasPaymaster": "0x8f9C3888bFC8a5B25AED115A82eCbb788b196d2a",
"create2Factory": "0xc97D8e6f57b0d64971453dDc6EB8483fec9d163a",
"validatorAnnounce": "0x3Fc742696D5dc9846e04f7A1823D92cb51695f9a",
"testRecipient": "0xBC3cFeca7Df5A45d61BC60E7898E63670e1654aE"
}
},
"bsctestnet": {
"id": 97,
"owner": "0xfaD1C94469700833717Fa8a3017278BC1cA8031C",
"contracts": {
"proxyAdmin": "0x4e4D563e2cBFC35c4BC16003685443Fae2FA702f",
"mailbox": "0xCC737a94FecaeC165AbCf12dED095BB13F037685",
"interchainGasPaymaster": "0x8f9C3888bFC8a5B25AED115A82eCbb788b196d2a",
"create2Factory": "0xc97D8e6f57b0d64971453dDc6EB8483fec9d163a",
"validatorAnnounce": "0x3Fc742696D5dc9846e04f7A1823D92cb51695f9a",
"testRecipient": "0xBC3cFeca7Df5A45d61BC60E7898E63670e1654aE"
}
},
"goerli": {
"id": 5,
"owner": "0xfaD1C94469700833717Fa8a3017278BC1cA8031C",
"contracts": {
"proxyAdmin": "0x4e4D563e2cBFC35c4BC16003685443Fae2FA702f",
"mailbox": "0xCC737a94FecaeC165AbCf12dED095BB13F037685",
"interchainGasPaymaster": "0x8f9C3888bFC8a5B25AED115A82eCbb788b196d2a",
"create2Factory": "0xc97D8e6f57b0d64971453dDc6EB8483fec9d163a",
"validatorAnnounce": "0x3Fc742696D5dc9846e04f7A1823D92cb51695f9a",
"testRecipient": "0xBC3cFeca7Df5A45d61BC60E7898E63670e1654aE"
}
},
"moonbasealpha": {
"id": 1287,
"owner": "0xfaD1C94469700833717Fa8a3017278BC1cA8031C",
"contracts": {
"proxyAdmin": "0x4e4D563e2cBFC35c4BC16003685443Fae2FA702f",
"mailbox": "0xCC737a94FecaeC165AbCf12dED095BB13F037685",
"interchainGasPaymaster": "0x8f9C3888bFC8a5B25AED115A82eCbb788b196d2a",
"create2Factory": "0xc97D8e6f57b0d64971453dDc6EB8483fec9d163a",
"validatorAnnounce": "0x3Fc742696D5dc9846e04f7A1823D92cb51695f9a",
"testRecipient": "0xBC3cFeca7Df5A45d61BC60E7898E63670e1654aE"
}
},
"optimismgoerli": {
"id": 420,
"owner": "0xfaD1C94469700833717Fa8a3017278BC1cA8031C",
"contracts": {
"proxyAdmin": "0x4e4D563e2cBFC35c4BC16003685443Fae2FA702f",
"mailbox": "0xCC737a94FecaeC165AbCf12dED095BB13F037685",
"interchainGasPaymaster": "0x8f9C3888bFC8a5B25AED115A82eCbb788b196d2a",
"create2Factory": "0xc97D8e6f57b0d64971453dDc6EB8483fec9d163a",
"validatorAnnounce": "0x3Fc742696D5dc9846e04f7A1823D92cb51695f9a",
"testRecipient": "0xBC3cFeca7Df5A45d61BC60E7898E63670e1654aE"
}
},
"arbitrumgoerli": {
"id": 421613,
"owner": "0xfaD1C94469700833717Fa8a3017278BC1cA8031C",
"contracts": {
"proxyAdmin": "0x4e4D563e2cBFC35c4BC16003685443Fae2FA702f",
"mailbox": "0xCC737a94FecaeC165AbCf12dED095BB13F037685",
"interchainGasPaymaster": "0x8f9C3888bFC8a5B25AED115A82eCbb788b196d2a",
"create2Factory": "0xc97D8e6f57b0d64971453dDc6EB8483fec9d163a",
"validatorAnnounce": "0x3Fc742696D5dc9846e04f7A1823D92cb51695f9a",
"testRecipient": "0xBC3cFeca7Df5A45d61BC60E7898E63670e1654aE"
}
},
"test1": {
"id": 13371
},
"test2": {
"id": 13372
},
"test3": {
"id": 13373
}
}

@ -0,0 +1,24 @@
import { ChainMap } from '@hyperlane-xyz/sdk';
export const startBlocks: ChainMap<number> = {
// --------------- Mainnets ---------------------
celo: 16884144,
ethereum: 16271503,
avalanche: 24145479,
polygon: 37313389,
bsc: 25063295,
arbitrum: 49073182,
optimism: 55698988,
moonbeam: 2595747,
gnosis: 25900000,
// --------------- Testnets ---------------------
alfajores: 14863532,
fuji: 16330615,
mumbai: 29390033,
bsctestnet: 25001629,
goerli: 8039005,
sepolia: 3082913,
moonbasealpha: 3310405,
optimismgoerli: 3055263,
arbitrumgoerli: 1941997,
};

@ -1,14 +0,0 @@
[profile.default]
src = 'scripts'
out = 'out'
libs = ['node_modules', 'lib']
test = 'test'
cache_path = 'forge-cache'
allow_paths = ["../node_modules"]
solc = '0.8.17'
optimizer = true
optimizer_runs = 999_999
fs_permissions = [{ access = "read-write", path = "./"}]
[profile.ci]
verbosity = 4

@ -1,80 +0,0 @@
// from https://gist.github.com/rmeissner/76d6345796909ee41fb9f36fdaa4d15f
pragma solidity >=0.8.0 <0.9.0;
library BytesLib {
function slice(
bytes memory _bytes,
uint256 _start,
uint256 _length
) internal pure returns (bytes memory) {
require(_length + 31 >= _length, "slice_overflow");
require(_bytes.length >= _start + _length, "slice_outOfBounds");
bytes memory tempBytes;
// Check length is 0. `iszero` return 1 for `true` and 0 for `false`.
assembly {
switch iszero(_length)
case 0 {
// Get a location of some free memory and store it in tempBytes as
// Solidity does for memory variables.
tempBytes := mload(0x40)
// Calculate length mod 32 to handle slices that are not a multiple of 32 in size.
let lengthmod := and(_length, 31)
// tempBytes will have the following format in memory: <length><data>
// When copying data we will offset the start forward to avoid allocating additional memory
// Therefore part of the length area will be written, but this will be overwritten later anyways.
// In case no offset is require, the start is set to the data region (0x20 from the tempBytes)
// mc will be used to keep track where to copy the data to.
let mc := add(
add(tempBytes, lengthmod),
mul(0x20, iszero(lengthmod))
)
let end := add(mc, _length)
for {
// Same logic as for mc is applied and additionally the start offset specified for the method is added
let cc := add(
add(
add(_bytes, lengthmod),
mul(0x20, iszero(lengthmod))
),
_start
)
} lt(mc, end) {
// increase `mc` and `cc` to read the next word from memory
mc := add(mc, 0x20)
cc := add(cc, 0x20)
} {
// Copy the data from source (cc location) to the slice data (mc location)
mstore(mc, mload(cc))
}
// Store the length of the slice. This will overwrite any partial data that
// was copied when having slices that are not a multiple of 32.
mstore(tempBytes, _length)
// update free-memory pointer
// allocating the array padded to 32 bytes like the compiler does now
// To set the used memory as a multiple of 32, add 31 to the actual memory usage (mc)
// and remove the modulo 32 (the `and` with `not(31)`)
mstore(0x40, and(add(mc, 31), not(31)))
}
// if we want a zero-length slice let's just return a zero-length array
default {
tempBytes := mload(0x40)
// zero out the 32 bytes slice we are about to return
// we need to do it because Solidity does not garbage collect
mstore(tempBytes, 0)
// update free-memory pointer
// tempBytes uses 32 bytes in memory (even when empty) for the length.
mstore(0x40, add(tempBytes, 0x20))
}
}
return tempBytes;
}
}

@ -1,105 +0,0 @@
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.17;
import "../lib/forge-std/src/console.sol";
import {ConfigLib} from "../lib/ConfigLib.sol";
import {MultisigIsm} from "@hyperlane-xyz/core/contracts/isms/MultisigIsm.sol";
import {TransparentUpgradeableProxy} from "@hyperlane-xyz/core/contracts/upgrade/TransparentUpgradeableProxy.sol";
library CheckLib {
function check(
ConfigLib.HyperlaneDomainConfig memory config,
ConfigLib.MultisigIsmConfig memory ismConfig
) internal view {
checkOwners(config);
checkAdmins(config);
checkMailboxIsm(config, ismConfig);
console.log(
"Succesfully checked Hyperlane deployment for %s",
config.chainName
);
}
function checkOwners(
ConfigLib.HyperlaneDomainConfig memory config
) private view {
require(
config.admin.owner() == config.owner,
"ProxyAdmin owner misconfigured"
);
require(
config.igp.owner() == config.owner,
"InterchainGasPaymaster owner misconfigured"
);
require(
config.mailbox.owner() == config.owner,
"Mailbox owner misconfigured"
);
}
function checkAdmins(
ConfigLib.HyperlaneDomainConfig memory config
) private view {
require(
config.admin.getProxyAdmin(
TransparentUpgradeableProxy(payable(address(config.igp)))
) == address(config.admin),
"InterchainGasPaymaster proxy admin misconfigured"
);
require(
config.admin.getProxyAdmin(
TransparentUpgradeableProxy(payable(address(config.mailbox)))
) == address(config.admin),
"Mailbox proxy admin misconfigured"
);
}
function checkMailboxIsm(
ConfigLib.HyperlaneDomainConfig memory config,
ConfigLib.MultisigIsmConfig memory ismConfig
) private view {
MultisigIsm ism = MultisigIsm(address(config.mailbox.defaultIsm()));
check(ismConfig, ism, config.owner);
}
function contains(
address[] memory set,
address element
) internal pure returns (bool) {
for (uint256 i = 0; i < set.length; i++) {
if (set[i] == element) {
return true;
}
}
return false;
}
function check(
ConfigLib.MultisigIsmConfig memory config,
MultisigIsm ism,
address owner
) internal view {
require(ism.owner() == owner, "MultisigIsm owner misconfigured");
for (uint256 i = 0; i < config.domains.length; i++) {
ConfigLib.MultisigIsmDomainConfig memory domain = config.domains[i];
require(
domain.threshold == ism.threshold(domain.domainId),
string.concat(
"Default MultisigIsm threshold misconfigured for",
domain.chainName
)
);
address[] memory validators = ism.validators(domain.domainId);
require(domain.validators.length == validators.length);
for (uint256 j = 0; j < validators.length; j++) {
require(
contains(domain.validators, validators[j]),
string.concat(
"Default MultisigIsm validator set misconfigured for ",
domain.chainName
)
);
}
}
}
}

@ -1,247 +0,0 @@
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.17;
import "../lib/forge-std/src/Script.sol";
import {Vm} from "../lib/forge-std/src/Vm.sol";
import {BytesLib} from "../lib/BytesLib.sol";
import {MultisigIsm} from "@hyperlane-xyz/core/contracts/isms/MultisigIsm.sol";
import {Mailbox} from "@hyperlane-xyz/core/contracts/Mailbox.sol";
import {InterchainGasPaymaster} from "@hyperlane-xyz/core/contracts/igps/InterchainGasPaymaster.sol";
import {ValidatorAnnounce} from "@hyperlane-xyz/core/contracts/ValidatorAnnounce.sol";
import {ProxyAdmin} from "@hyperlane-xyz/core/contracts/upgrade/ProxyAdmin.sol";
import {TransparentUpgradeableProxy} from "@hyperlane-xyz/core/contracts/upgrade/TransparentUpgradeableProxy.sol";
import {Create2Factory} from "@hyperlane-xyz/core/contracts/Create2Factory.sol";
import {TestRecipient} from "@hyperlane-xyz/core/contracts/test/TestRecipient.sol";
library ConfigLib {
using stdJson for string;
using BytesLib for bytes;
struct HyperlaneDomainConfig {
string chainName;
uint32 domainId;
address owner;
Mailbox mailbox;
InterchainGasPaymaster igp;
ProxyAdmin admin;
Create2Factory create2;
ValidatorAnnounce validatorAnnounce;
TestRecipient testRecipient;
}
struct MultisigIsmDomainConfig {
string chainName;
uint32 domainId;
uint8 threshold;
address[] validators;
}
struct MultisigIsmConfig {
MultisigIsmDomainConfig[] domains;
}
function readContractAddress(
Vm vm,
string memory chainName,
string memory contractName
) private view returns (address) {
string memory json = vm.readFile("config/networks.json");
string memory prefix = ".contracts.";
try
vm.parseJson(
json,
string.concat(
".",
chainName,
string.concat(prefix, contractName)
)
)
returns (bytes memory result) {
address parsedAddr = abi.decode(result, (address));
return parsedAddr == address(0x20) ? address(0) : parsedAddr;
} catch {
return address(0);
}
}
function readHyperlaneDomainConfig(
Vm vm,
string memory chainName
) internal view returns (HyperlaneDomainConfig memory) {
string memory json = vm.readFile("config/networks.json");
// console.log(json);
uint32 domainId = abi.decode(
vm.parseJson(json, string.concat(".", chainName, ".id")),
(uint32)
);
address owner = abi.decode(
vm.parseJson(json, string.concat(".", chainName, ".owner")),
(address)
);
Mailbox mailbox = Mailbox(
readContractAddress(vm, chainName, "mailbox")
);
InterchainGasPaymaster igp = InterchainGasPaymaster(
readContractAddress(vm, chainName, "interchainGasPaymaster")
);
ProxyAdmin admin = ProxyAdmin(
readContractAddress(vm, chainName, "proxyAdmin")
);
Create2Factory create2 = Create2Factory(
readContractAddress(vm, chainName, "create2Factory")
);
TestRecipient recipient = TestRecipient(
readContractAddress(vm, chainName, "testRecipient")
);
ValidatorAnnounce validatorAnnounce = ValidatorAnnounce(
readContractAddress(vm, chainName, "validatorAnnounce")
);
return
HyperlaneDomainConfig(
chainName,
domainId,
owner,
mailbox,
igp,
admin,
create2,
validatorAnnounce,
recipient
);
}
function readMultisigIsmDomainConfig(
Vm vm,
string memory chainName
) private view returns (MultisigIsmDomainConfig memory) {
console.log(chainName);
string memory json = vm.readFile("config/multisig_ism.json");
uint8 threshold = abi.decode(
vm.parseJson(json, string.concat(".", chainName, ".threshold")),
(uint8)
);
address[] memory validators = abi.decode(
vm.parseJson(json, string.concat(".", chainName, ".validators")),
(address[])
);
json = vm.readFile("config/networks.json");
uint32 domainId = abi.decode(
vm.parseJson(json, string.concat(".", chainName, ".id")),
(uint32)
);
return
MultisigIsmDomainConfig(chainName, domainId, threshold, validators);
}
function readMultisigIsmConfig(
Vm vm,
string[] memory chainNames
) internal view returns (MultisigIsmConfig memory) {
MultisigIsmDomainConfig[]
memory domains = new MultisigIsmDomainConfig[](chainNames.length);
for (uint256 i = 0; i < chainNames.length; i++) {
string memory chainName = chainNames[i];
domains[i] = readMultisigIsmDomainConfig(vm, chainName);
}
return MultisigIsmConfig(domains);
}
function writeAgentConfig(
HyperlaneDomainConfig memory config,
Vm vm,
uint256 startBlock
) internal {
string memory baseConfig = "config";
vm.serializeString(
baseConfig,
"domain",
vm.toString(uint256(config.domainId))
);
vm.serializeString(baseConfig, "rpcStyle", "ethereum");
vm.serializeString(baseConfig, "finalityBlocks", "POPULATE_ME");
string memory addresses = "addresses";
vm.serializeAddress(addresses, "mailbox", address(config.mailbox));
vm.serializeAddress(
addresses,
"validatorAnnounce",
address(config.validatorAnnounce)
);
vm.serializeString(
baseConfig,
"addresses",
vm.serializeAddress(
addresses,
"interchainGasPaymaster",
address(config.igp)
)
);
string memory connection = "connection";
vm.serializeString(connection, "type", "http");
vm.serializeString(
baseConfig,
"connection",
vm.serializeString(connection, "url", "")
);
string memory index = "index";
vm.serializeString(
baseConfig,
"index",
vm.serializeString(index, "from", vm.toString(startBlock))
);
vm.serializeString(baseConfig, "name", config.chainName);
vm
.serializeString(
"topLevel",
"chains",
vm.serializeString(
"chainLevel",
config.chainName,
vm.serializeString(baseConfig, "protocol", "ethereum")
)
)
.write(
string.concat(
"./config/",
config.chainName,
"_agent_config.json"
)
);
}
function write(HyperlaneDomainConfig memory config, Vm vm) internal {
string memory contracts = "contracts";
vm.serializeAddress(contracts, "mailbox", address(config.mailbox));
vm.serializeAddress(
contracts,
"interchainGasPaymaster",
address(config.igp)
);
vm.serializeAddress(contracts, "proxyAdmin", address(config.admin));
vm.serializeAddress(
contracts,
"validatorAnnounce",
address(config.validatorAnnounce)
);
vm.serializeAddress(
contracts,
"testRecipient",
address(config.testRecipient)
);
vm
.serializeAddress(
contracts,
"create2Factory",
address(config.create2)
)
.write(
"./config/networks.json",
string.concat(".", config.chainName, ".contracts")
);
}
}

@ -1,165 +0,0 @@
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.17;
import "../lib/forge-std/src/console.sol";
import {ConfigLib} from "../lib/ConfigLib.sol";
import {MultisigIsm} from "@hyperlane-xyz/core/contracts/isms/MultisigIsm.sol";
import {Mailbox} from "@hyperlane-xyz/core/contracts/Mailbox.sol";
import {InterchainGasPaymaster} from "@hyperlane-xyz/core/contracts/igps/InterchainGasPaymaster.sol";
import {ValidatorAnnounce} from "@hyperlane-xyz/core/contracts/ValidatorAnnounce.sol";
import {ProxyAdmin} from "@hyperlane-xyz/core/contracts/upgrade/ProxyAdmin.sol";
import {TransparentUpgradeableProxy} from "@hyperlane-xyz/core/contracts/upgrade/TransparentUpgradeableProxy.sol";
import {Create2Factory} from "@hyperlane-xyz/core/contracts/Create2Factory.sol";
import {TestRecipient} from "@hyperlane-xyz/core/contracts/test/TestRecipient.sol";
library DeployLib {
function deploy(
ConfigLib.HyperlaneDomainConfig memory config,
ConfigLib.MultisigIsmConfig memory ismConfig
) internal {
deployProxyAdmin(config);
deployIgp(config);
deployMailbox(config, ismConfig);
deployTestRecipient(config);
deployValidatorAnnounce(config);
}
function deployValidatorAnnounce(
ConfigLib.HyperlaneDomainConfig memory config
) private {
if (address(config.validatorAnnounce) == address(0)) {
config.validatorAnnounce = new ValidatorAnnounce(
address(config.mailbox)
);
console.log(
"ValidatorAnnounce deployed at address %s",
address(config.validatorAnnounce)
);
} else {
console.log(
"Found ValidatorAnnounce at address %s, skipping deployment",
address(config.validatorAnnounce)
);
}
}
function deployProxyAdmin(
ConfigLib.HyperlaneDomainConfig memory config
) private {
if (address(config.admin) == address(0)) {
config.admin = new ProxyAdmin();
console.log(
"ProxyAdmin deployed at address %s",
address(config.admin)
);
config.admin.transferOwnership(config.owner);
} else {
console.log(
"Found ProxyAdmin at address %s, skipping deployment",
address(config.admin)
);
}
}
function deployIgp(ConfigLib.HyperlaneDomainConfig memory config) private {
require(
address(config.admin) != address(0),
"Must deploy ProxyAdmin before InterchainGasPaymaster"
);
if (address(config.igp) == address(0)) {
InterchainGasPaymaster impl = new InterchainGasPaymaster();
bytes memory initData = abi.encodeCall(
InterchainGasPaymaster.initialize,
()
);
TransparentUpgradeableProxy proxy = new TransparentUpgradeableProxy(
address(impl),
address(config.admin),
initData
);
console.log(
"InterchainGasPaymaster deployed at address %s",
address(proxy)
);
config.igp = InterchainGasPaymaster(address(proxy));
config.igp.transferOwnership(config.owner);
} else {
console.log(
"Found InterchainGasPaymaster at address %s, skipping deployment",
address(config.igp)
);
}
}
function deployMailbox(
ConfigLib.HyperlaneDomainConfig memory config,
ConfigLib.MultisigIsmConfig memory ismConfig
) private {
require(
address(config.admin) != address(0),
"Must deploy ProxyAdmin before Mailbox"
);
if (address(config.mailbox) == address(0)) {
MultisigIsm ism = deploy(ismConfig, config.owner);
Mailbox mailbox = new Mailbox(config.domainId);
bytes memory initData = abi.encodeCall(
Mailbox.initialize,
(config.owner, address(ism))
);
TransparentUpgradeableProxy proxy = new TransparentUpgradeableProxy(
address(mailbox),
address(config.admin),
initData
);
console.log("Mailbox deployed at address %s", address(proxy));
config.mailbox = Mailbox(address(proxy));
} else {
console.log(
"Found Mailbox at address %s, skipping deployment",
address(config.igp)
);
}
}
function deployTestRecipient(
ConfigLib.HyperlaneDomainConfig memory config
) private {
if (address(config.testRecipient) == address(0)) {
config.testRecipient = new TestRecipient();
console.log(
"TestRecipient deployed at address %s",
address(config.testRecipient)
);
} else {
console.log(
"Found TestRecipient at address %s, skipping deployment",
address(config.igp)
);
}
}
function deploy(
ConfigLib.MultisigIsmConfig memory config,
address owner
) internal returns (MultisigIsm) {
// Deploy a default MultisigIsm and enroll validators for remote
// networks.
MultisigIsm ism = new MultisigIsm();
console.log("MultisigIsm deployed at address %s", address(ism));
uint32[] memory remoteDomainIds = new uint32[](config.domains.length);
uint8[] memory remoteThresholds = new uint8[](config.domains.length);
address[][] memory remoteValidators = new address[][](
config.domains.length
);
for (uint256 i = 0; i < config.domains.length; i++) {
remoteDomainIds[i] = config.domains[i].domainId;
remoteThresholds[i] = config.domains[i].threshold;
remoteValidators[i] = config.domains[i].validators;
}
ism.enrollValidators(remoteDomainIds, remoteValidators);
ism.setThresholds(remoteDomainIds, remoteThresholds);
ism.transferOwnership(owner);
return ism;
}
}

@ -1 +0,0 @@
Subproject commit 181c0c686a8421cfb530e06bda9d00632c9d8637

@ -7,11 +7,25 @@
"author": "asa@hyperlane.xyz", "author": "asa@hyperlane.xyz",
"license": "Apache 2.0", "license": "Apache 2.0",
"scripts": { "scripts": {
"prettier": "prettier --write ./scripts ./lib" "build": "tsc",
"prettier": "prettier --write ./config ./scripts ./src"
}, },
"dependencies": { "dependencies": {
"@hyperlane-xyz/core": "1.1.2", "@hyperlane-xyz/core": "1.3.0",
"@hyperlane-xyz/sdk": "^1.3.0",
"@hyperlane-xyz/utils": "^1.3.0",
"@types/node": "^18.14.5",
"@types/yargs": "^17.0.22",
"ethers": "^5.7.2",
"prettier": "^2.8.2", "prettier": "^2.8.2",
"prettier-plugin-solidity": "^1.1.1" "prettier-plugin-solidity": "^1.1.1",
"ts-node": "^10.9.1",
"typescript": "^4.9.5",
"yargs": "^17.7.1"
},
"packageManager": "yarn@1.22.19",
"devDependencies": {
"@types/coingecko-api": "^1.0.10",
"@types/debug": "^4.1.7"
} }
} }

@ -1,42 +0,0 @@
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.17;
import "../lib/forge-std/src/Script.sol";
import "../lib/forge-std/src/console.sol";
import {BytesLib} from "../lib/BytesLib.sol";
import {ConfigLib} from "../lib/ConfigLib.sol";
import {Mailbox} from "@hyperlane-xyz/core/contracts/Mailbox.sol";
import {TypeCasts} from "@hyperlane-xyz/core/contracts/libs/TypeCasts.sol";
// TODO: Maybe take recipient as an arg..
contract CheckMessage is Script {
using TypeCasts for address;
using BytesLib for bytes;
function run() public view {
string memory destination = vm.envString("DESTINATION");
bytes32 messageId = vm.envBytes32("MESSAGE_ID");
Mailbox mailbox = ConfigLib
.readHyperlaneDomainConfig(vm, destination)
.mailbox;
bool delivered = mailbox.delivered(messageId);
if (delivered) {
console.log(
"Message ID '%s' HAS been delivered to %s",
vm.toString(messageId),
destination
);
} else {
console.log(
"Message ID '%s' HAS NOT been delivered to %s",
vm.toString(messageId),
destination
);
}
console.log(
"https://explorer.hyperlane.xyz/message/%s",
string(abi.encodePacked(vm.toString(messageId)).slice(2, 64))
);
}
}

@ -1,35 +0,0 @@
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.17;
import "../lib/forge-std/src/Script.sol";
import {ConfigLib} from "../lib/ConfigLib.sol";
import {CheckLib} from "../lib/CheckLib.sol";
import {DeployLib} from "../lib/DeployLib.sol";
contract DeployCore is Script {
using ConfigLib for ConfigLib.HyperlaneDomainConfig;
using CheckLib for ConfigLib.HyperlaneDomainConfig;
using DeployLib for ConfigLib.HyperlaneDomainConfig;
function run() public {
string memory local = vm.envString("LOCAL");
string[] memory remotes = vm.envString("REMOTES", ",");
ConfigLib.HyperlaneDomainConfig memory config = ConfigLib
.readHyperlaneDomainConfig(vm, local);
ConfigLib.MultisigIsmConfig memory ismConfig = ConfigLib
.readMultisigIsmConfig(vm, remotes);
vm.startBroadcast();
uint256 startBlock = block.number;
config.deploy(ismConfig);
config.check(ismConfig);
// Write the output to disk
config.write(vm);
config.writeAgentConfig(vm, startBlock);
vm.stopBroadcast();
}
}

@ -1,39 +0,0 @@
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.17;
import "../lib/forge-std/src/Script.sol";
import "../lib/forge-std/src/console.sol";
import {ConfigLib} from "../lib/ConfigLib.sol";
import {CheckLib} from "../lib/CheckLib.sol";
import {DeployLib} from "../lib/DeployLib.sol";
import {MultisigIsm} from "@hyperlane-xyz/core/contracts/isms/MultisigIsm.sol";
import {TestRecipient} from "@hyperlane-xyz/core/contracts/test/TestRecipient.sol";
import {InterchainGasPaymaster} from "@hyperlane-xyz/core/contracts/igps/InterchainGasPaymaster.sol";
// TODO: Deploy test recipient, maybe write to networks.
contract DeployMultisigIsm is Script {
using CheckLib for ConfigLib.MultisigIsmConfig;
using DeployLib for ConfigLib.MultisigIsmConfig;
function run() public {
address owner = vm.envAddress("OWNER");
string[] memory remotes = vm.envString("REMOTES", ",");
ConfigLib.MultisigIsmConfig memory config = ConfigLib
.readMultisigIsmConfig(vm, remotes);
vm.startBroadcast();
MultisigIsm ism = config.deploy(owner);
TestRecipient recipient = new TestRecipient();
recipient.setInterchainSecurityModule(address(ism));
console.log("TestRecipient deployed at address %s", address(recipient));
InterchainGasPaymaster igp = new InterchainGasPaymaster();
console.log(
"InterchainGasPaymaster deployed at address %s",
address(igp)
);
config.check(ism, owner);
}
}

@ -1,44 +0,0 @@
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.17;
import "../lib/forge-std/src/Script.sol";
import "../lib/forge-std/src/console.sol";
import {BytesLib} from "../lib/BytesLib.sol";
import {ConfigLib} from "../lib/ConfigLib.sol";
import {Mailbox} from "@hyperlane-xyz/core/contracts/Mailbox.sol";
import {TypeCasts} from "@hyperlane-xyz/core/contracts/libs/TypeCasts.sol";
contract SendTestMessage is Script {
using TypeCasts for address;
using BytesLib for bytes;
function run() public {
string memory origin = vm.envString("ORIGIN");
string memory destination = vm.envString("DESTINATION");
address recipient = vm.envAddress("RECIPIENT");
string memory body = vm.envString("BODY");
Mailbox mailbox = ConfigLib
.readHyperlaneDomainConfig(vm, origin)
.mailbox;
ConfigLib.HyperlaneDomainConfig memory config = ConfigLib
.readHyperlaneDomainConfig(vm, destination);
vm.startBroadcast();
bytes32 messageId = mailbox.dispatch(
config.domainId,
address(recipient).addressToBytes32(),
abi.encode(body)
);
console.log(
"Sent message with ID %s from %s to %s",
vm.toString(messageId),
origin,
destination
);
console.log(
"https://explorer.hyperlane.xyz/message/%s",
string(abi.encodePacked(vm.toString(messageId)).slice(2, 64))
);
}
}

@ -0,0 +1,18 @@
import { HyperlanePermissionlessDeployer } from '../src/deployer';
async function main() {
const deployer = await HyperlanePermissionlessDeployer.fromArgs();
try {
await deployer.deploy();
} catch (e) {
console.error(`Encountered error during deploy`);
console.error(e);
}
}
main()
.then(() => console.info('Deploy completed successfully'))
.catch((e) => {
console.error(e);
process.exit(1);
});

@ -0,0 +1,167 @@
import {
CoreFactories,
coreFactories,
DispatchedMessage,
HyperlaneAddressesMap,
HyperlaneApp,
HyperlaneCore,
HyperlaneIgp,
MultiProvider,
} from '@hyperlane-xyz/sdk';
import {
igpFactories,
IgpFactories,
} from '@hyperlane-xyz/sdk/dist/gas/contracts';
import { utils } from '@hyperlane-xyz/utils';
import { sleep } from '@hyperlane-xyz/utils/dist/src/utils';
import { ethers } from 'ethers';
import yargs from 'yargs';
import {
assertBalances,
assertBytes32,
getMultiProvider,
mergedContractAddresses,
} from '../src/config';
export function getArgs(multiProvider: MultiProvider) {
// Only accept chains for which we have both a connection and contract addresses
const { intersection } = multiProvider.intersect(
Object.keys(mergedContractAddresses),
);
return yargs(process.argv.slice(2))
.describe('chains', 'chain to send message from')
.choices('chains', intersection)
.demandOption('chains')
.array('chains')
.describe('key', 'hexadecimal private key for transaction signing')
.string('key')
.coerce('key', assertBytes32)
.demandOption('key')
.describe('timeout', 'timeout in seconds')
.number('timeout')
.default('timeout', 10 * 60)
.middleware(assertBalances(multiProvider, (argv) => argv.chains)).argv;
}
function coreFromAddressesMap(
addressesMap: HyperlaneAddressesMap<CoreFactories>,
_multiProvider: MultiProvider,
): HyperlaneCore {
const { contractsMap, multiProvider } = HyperlaneApp.fromAddressesMap(
addressesMap,
coreFactories,
_multiProvider,
);
return new HyperlaneCore(contractsMap, multiProvider);
}
function igpFromAddressesMap(
addressesMap: HyperlaneAddressesMap<IgpFactories>,
_multiProvider: MultiProvider,
): HyperlaneIgp {
const { contractsMap, multiProvider } = HyperlaneApp.fromAddressesMap(
addressesMap,
igpFactories,
_multiProvider,
);
return new HyperlaneIgp(contractsMap, multiProvider);
}
async function main() {
let timedOut = false;
const multiProvider = getMultiProvider();
let { chains, key, timeout } = await getArgs(multiProvider);
const timeoutId = setTimeout(() => {
timedOut = true;
}, timeout * 1000);
const signer = new ethers.Wallet(key);
multiProvider.setSharedSigner(signer);
const core = coreFromAddressesMap(mergedContractAddresses, multiProvider);
const igp = igpFromAddressesMap(mergedContractAddresses, multiProvider);
const messages: Set<DispatchedMessage> = new Set();
for (const origin of chains) {
const mailbox = core.getContracts(origin).mailbox;
const defaultIgp =
igp.getContracts(origin).defaultIsmInterchainGasPaymaster;
for (const destination of chains) {
const destinationDomain = multiProvider.getDomainId(destination);
if (origin === destination) continue;
try {
const recipient = mergedContractAddresses[destination]
.testRecipient as string;
if (!recipient) {
throw new Error(`Unable to find TestRecipient for ${destination}`);
}
const messageTx = await mailbox.dispatch(
destinationDomain,
utils.addressToBytes32(recipient),
'0xdeadbeef',
);
const messageReceipt = await multiProvider.handleTx(origin, messageTx);
const dispatchedMessages = core.getDispatchedMessages(messageReceipt);
if (dispatchedMessages.length !== 1) continue;
const dispatchedMessage = dispatchedMessages[0];
console.log(
`Sent message from ${origin} to ${recipient} on ${destination} with message ID ${dispatchedMessage.id}`,
);
// Make gas payment...
const gasAmount = 100_000;
const value = await defaultIgp.quoteGasPayment(
destinationDomain,
gasAmount,
);
const paymentTx = await defaultIgp.payForGas(
dispatchedMessage.id,
destinationDomain,
gasAmount,
await multiProvider.getSignerAddress(origin),
{ value },
);
await paymentTx.wait();
messages.add(dispatchedMessage);
} catch (e) {
console.error(
`Encountered error sending message from ${origin} to ${destination}`,
);
console.error(e);
}
}
}
while (messages.size > 0 && !timedOut) {
for (const message of messages.values()) {
const origin = multiProvider.getChainName(message.parsed.origin);
const destination = multiProvider.getChainName(
message.parsed.destination,
);
const mailbox = core.getContracts(destination).mailbox;
const delivered = await mailbox.delivered(message.id);
if (delivered) {
messages.delete(message);
console.log(
`Message from ${origin} to ${destination} with ID ${
message!.id
} was delivered`,
);
} else {
console.log(
`Message from ${origin} to ${destination} with ID ${
message!.id
} has not yet been delivered`,
);
}
await sleep(5000);
}
}
clearTimeout(timeoutId);
if (timedOut) {
console.error('Timed out waiting for messages to be delivered');
process.exit(1);
}
}
main()
.then(() => console.info('Testing complete'))
.catch((e) => {
console.error(e);
process.exit(1);
});

@ -0,0 +1,53 @@
import { TestRecipient, TestRecipient__factory } from '@hyperlane-xyz/core';
import {
ChainMap,
ChainName,
HyperlaneDeployer,
MultiProvider,
} from '@hyperlane-xyz/sdk';
import { types } from '@hyperlane-xyz/utils';
import debug from 'debug';
// Maps chain name to ISM address
export type TestRecipientConfig = {
ism: types.Address;
};
export type TestRecipientContracts = {
testRecipient: TestRecipient;
};
export type TestRecipientAddresses = {
testRecipient: types.Address;
};
export const testRecipientFactories = {
testRecipient: new TestRecipient__factory(),
};
export class HyperlaneTestRecipientDeployer extends HyperlaneDeployer<
TestRecipientConfig,
typeof testRecipientFactories
> {
constructor(
multiProvider: MultiProvider,
configMap: ChainMap<TestRecipientConfig>,
factoriesOverride = testRecipientFactories,
) {
super(multiProvider, configMap, factoriesOverride, {
logger: debug('hyperlane:TestRecipientDeployer'),
});
}
async deployContracts(
chain: ChainName,
config: TestRecipientConfig,
): Promise<TestRecipientContracts> {
const testRecipient = await this.deployContract(chain, 'testRecipient', []);
const tx = testRecipient.setInterchainSecurityModule(config.ism);
await this.multiProvider.handleTx(chain, tx);
return {
testRecipient,
};
}
}

@ -0,0 +1,159 @@
import {
buildAgentConfig,
ChainMap,
ChainName,
CoreConfig,
defaultMultisigIsmConfigs,
GasOracleContractType,
HyperlaneAddressesMap,
HyperlaneAgentAddresses,
MultiProvider,
MultisigIsmConfig,
multisigIsmVerificationCost,
objFilter,
objMerge,
OverheadIgpConfig,
} from '@hyperlane-xyz/sdk';
import { hyperlaneEnvironments } from '@hyperlane-xyz/sdk/dist/consts/environments';
import { types, utils } from '@hyperlane-xyz/utils';
import { ethers } from 'ethers';
import artifactAddresses from '../artifacts/addresses.json';
import { chains } from '../config/chains';
import { multisigIsmConfig } from '../config/multisig_ism';
import { readJSON } from './json';
export function getMultiProvider() {
const multiProvider = new MultiProvider();
for (const metadata of Object.values(chains)) {
multiProvider.addChain(metadata);
}
return multiProvider;
}
export function assertBytes32(value: string): string {
if (
ethers.utils.isHexString(value) &&
ethers.utils.hexDataLength(value) == 32
) {
return value;
}
throw new Error(`Invalid value ${value}, must be a 32 byte hex string`);
}
export function assertBalances(
multiProvider: MultiProvider,
chainsFunc: (argv: any) => ChainName[],
): (argv: any) => Promise<void> {
return async (argv: any) => {
const chains = chainsFunc(argv);
const signer = new ethers.Wallet(argv.key);
const address = await signer.getAddress();
Promise.all(
chains.map(async (chain: ChainName) => {
const balance = await multiProvider
.getProvider(chain)
.getBalance(address);
if (balance.isZero())
throw new Error(`${address} has no balance on ${chain}`);
}),
);
};
}
export function coerceAddressToBytes32(value: string): string {
if (ethers.utils.isHexString(value)) {
const length = ethers.utils.hexDataLength(value);
if (length == 32) {
return value;
} else if (length == 20) {
return utils.addressToBytes32(value);
}
}
throw new Error(`Invalid value ${value}, must be a 20 or 32 byte hex string`);
}
export function buildCoreConfig(
owner: types.Address,
chains: ChainName[],
): ChainMap<CoreConfig> {
const configMap: ChainMap<CoreConfig> = {};
for (const local of chains) {
const multisigIsmConfigs: ChainMap<MultisigIsmConfig> = {};
const mergedMultisigIsmConfig: ChainMap<MultisigIsmConfig> = objMerge(
defaultMultisigIsmConfigs,
multisigIsmConfig,
);
for (const remote of chains) {
if (local === remote) continue;
multisigIsmConfigs[remote] = mergedMultisigIsmConfig[remote];
}
configMap[local] = {
owner,
multisigIsm: multisigIsmConfigs,
};
}
return configMap;
}
export function buildIgpConfig(
owner: types.Address,
chains: ChainName[],
): ChainMap<OverheadIgpConfig> {
const configMap: ChainMap<OverheadIgpConfig> = {};
for (const local of chains) {
const overhead: ChainMap<number> = {};
const gasOracleType: ChainMap<GasOracleContractType> = {};
for (const remote of chains) {
if (local === remote) continue;
overhead[remote] = multisigIsmVerificationCost(
multisigIsmConfig[remote].threshold,
multisigIsmConfig[remote].validators.length,
);
gasOracleType[remote] = GasOracleContractType.StorageGasOracle;
}
configMap[local] = {
owner,
beneficiary: owner,
gasOracleType,
overhead,
};
}
return configMap;
}
export const sdkContractAddresses = {
...hyperlaneEnvironments.testnet,
...hyperlaneEnvironments.mainnet,
};
export const mergedContractAddresses = objMerge(
sdkContractAddresses,
artifactAddresses,
);
export function buildOverriddenAgentConfig(
chains: ChainName[],
multiProvider: MultiProvider,
startBlocks: ChainMap<number>,
) {
const localAddresses = readJSON('./artifacts', 'addresses.json');
const mergedAddresses: HyperlaneAddressesMap<any> = objMerge(
sdkContractAddresses,
localAddresses,
);
const filteredAddresses: ChainMap<HyperlaneAgentAddresses> = objFilter(
mergedAddresses,
(chain, v): v is HyperlaneAgentAddresses =>
chains.includes(chain) &&
!!v.mailbox &&
!!v.interchainGasPaymaster &&
!!v.validatorAnnounce,
);
return buildAgentConfig(
chains,
multiProvider,
filteredAddresses,
startBlocks,
);
}

@ -0,0 +1,172 @@
import {
ChainMap,
ChainName,
CoreFactories,
HyperlaneContractsMap,
HyperlaneCoreDeployer,
HyperlaneIgpDeployer,
MultiProvider,
objMap,
objMerge,
serializeContractsMap,
} from '@hyperlane-xyz/sdk';
import yargs from 'yargs';
import { LegacyMultisigIsm } from '@hyperlane-xyz/core';
import { ethers } from 'ethers';
import { multisigIsmConfig } from '../config/multisig_ism';
import { startBlocks } from '../config/start_blocks';
import {
assertBalances,
assertBytes32,
buildCoreConfig,
buildIgpConfig,
buildOverriddenAgentConfig,
getMultiProvider,
} from './config';
import { mergeJSON, writeJSON } from './json';
import {
HyperlaneTestRecipientDeployer,
TestRecipientConfig,
} from './TestRecipientDeployer';
export function getArgs(multiProvider: MultiProvider) {
// For each chain, we need:
// - ChainMetadata for the MultiProvider
// - A MultisigIsmConfig
const { intersection } = multiProvider.intersect(
Object.keys(multisigIsmConfig),
);
return yargs(process.argv.slice(2))
.describe('local', 'The chain to deploy to')
.choices('local', intersection)
.demandOption('local')
.array('remotes')
.describe(
'remotes',
"The chains with which 'local' will be able to send and receive messages",
)
.choices('remotes', intersection)
.demandOption('remotes')
.describe('key', 'A hexadecimal private key for transaction signing')
.string('key')
.coerce('key', assertBytes32)
.demandOption('key')
.middleware(
assertBalances(multiProvider, (argv) => argv.remotes.concat(argv.local)),
)
.describe('write-agent-config', 'Whether or not to write agent config')
.default('write-agent-config', true)
.boolean('write-agent-config').argv;
}
type MultisigIsmContracts = {
multisigIsm: LegacyMultisigIsm;
};
export class HyperlanePermissionlessDeployer {
constructor(
public readonly multiProvider: MultiProvider,
public readonly signer: ethers.Signer,
public readonly local: ChainName,
public readonly remotes: ChainName[],
public readonly writeAgentConfig?: boolean,
) {}
static async fromArgs(): Promise<HyperlanePermissionlessDeployer> {
const multiProvider = getMultiProvider();
const { local, remotes, key, writeAgentConfig } = await getArgs(
multiProvider,
);
const signer = new ethers.Wallet(key);
multiProvider.setSharedSigner(signer);
return new HyperlanePermissionlessDeployer(
multiProvider,
signer,
local,
remotes as unknown as string[],
writeAgentConfig,
);
}
get chains(): ChainName[] {
return this.remotes.concat([this.local]);
}
async deploy(): Promise<void> {
let contracts: HyperlaneContractsMap<CoreFactories> = {};
const owner = await this.signer.getAddress();
// First, deploy core contracts to the local chain
// NB: We create core configs for *all* chains because
// we also use coreDeployer to deploy MultisigIsms.
// Once we move that out to a HyperlaneIsmDeployer
// we can just do:
// const coreContracts = await coreDeployer.deploy();
const coreConfig = buildCoreConfig(owner, this.chains);
const coreDeployer = new HyperlaneCoreDeployer(
this.multiProvider,
coreConfig,
);
const coreContracts: HyperlaneContractsMap<CoreFactories> = {};
coreContracts[this.local] = await coreDeployer.deployContracts(
this.local,
coreConfig[this.local],
);
contracts = objMerge(contracts, coreContracts);
// Next, deploy MultisigIsms to the remote chains
// TODO: Would be cleaner if using HyperlaneIsmDeployer
const isms: ChainMap<MultisigIsmContracts> = {};
isms[this.local] = {
multisigIsm: coreContracts[this.local].multisigIsm,
};
for (const remote of this.remotes) {
isms[remote] = {
multisigIsm: await coreDeployer.deployLegacyMultisigIsm(remote),
};
}
contracts = objMerge(contracts, isms);
// Next, deploy TestRecipients to all chains
const testRecipientConfig: ChainMap<TestRecipientConfig> = objMap(
isms,
(chain, ism) => {
return { ism: ism.multisigIsm.address };
},
);
const testRecipientDeployer = new HyperlaneTestRecipientDeployer(
this.multiProvider,
testRecipientConfig,
);
const testRecipients = await testRecipientDeployer.deploy();
contracts = objMerge(contracts, testRecipients);
// Finally, deploy IGPs to all chains
// TODO: Reuse ProxyAdmin on local chain... right now *two* ProxyAdmins are deployed
const igpConfig = buildIgpConfig(owner, this.chains);
const igpDeployer = new HyperlaneIgpDeployer(this.multiProvider, igpConfig);
const igps = await igpDeployer.deploy();
contracts = objMerge(contracts, igps);
const addresses = serializeContractsMap(contracts);
// Write contract address artifacts
mergeJSON('./artifacts/', 'addresses.json', addresses);
startBlocks[this.local] = await this.multiProvider
.getProvider(this.local)
.getBlockNumber();
if (this.writeAgentConfig) {
const agentConfig = buildOverriddenAgentConfig(
this.chains,
this.multiProvider,
startBlocks,
);
// Write AgentConfig artifacts
writeJSON('./artifacts/', 'agent_config.json', agentConfig);
}
}
}

@ -0,0 +1,37 @@
import { objMerge } from '@hyperlane-xyz/sdk';
import fs from 'fs';
import path from 'path';
export function writeJSON(directory: string, filename: string, obj: any) {
if (!fs.existsSync(directory)) {
fs.mkdirSync(directory, { recursive: true });
}
fs.writeFileSync(
path.join(directory, filename),
JSON.stringify(obj, null, 2) + '\n',
);
}
export function mergeJSON(directory: string, filename: string, obj: any) {
if (fs.existsSync(path.join(directory, filename))) {
const previous = readJSON(directory, filename);
writeJSON(directory, filename, objMerge(previous, obj));
} else {
writeJSON(directory, filename, obj);
}
}
export function readFileAtPath(filepath: string) {
if (!fs.existsSync(filepath)) {
throw Error(`file doesn't exist at ${filepath}`);
}
return fs.readFileSync(filepath, 'utf8');
}
export function readJSONAtPath(filepath: string) {
return JSON.parse(readFileAtPath(filepath));
}
export function readJSON(directory: string, filename: string) {
return readJSONAtPath(path.join(directory, filename));
}

@ -0,0 +1,28 @@
{
"compilerOptions": {
"outDir": "./dist/",
"rootDir": "./",
"declaration": true,
"declarationMap": true,
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"incremental": false,
"lib": ["es2015", "es5", "dom", "es2021"],
"module": "commonjs",
"moduleResolution": "node",
"noEmitOnError": true,
"noFallthroughCasesInSwitch": true,
"noImplicitAny": true,
"noImplicitReturns": true,
"noUnusedLocals": true,
"preserveSymlinks": true,
"preserveWatchOutput": true,
"pretty": false,
"resolveJsonModule": true,
"sourceMap": true,
"target": "es6",
"strict": true
},
"exclude": ["./node_modules/", "./dist/"],
"include": ["./src/**/*.ts", "./config/**/*.ts", "./scripts/*.ts"]
}

@ -2,6 +2,13 @@
# yarn lockfile v1 # yarn lockfile v1
"@cspotcode/source-map-support@^0.8.0":
version "0.8.1"
resolved "https://registry.yarnpkg.com/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz#00629c35a688e05a88b1cda684fb9d5e73f000a1"
integrity sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==
dependencies:
"@jridgewell/trace-mapping" "0.3.9"
"@ethersproject/abi@5.7.0", "@ethersproject/abi@^5.7.0": "@ethersproject/abi@5.7.0", "@ethersproject/abi@^5.7.0":
version "5.7.0" version "5.7.0"
resolved "https://registry.yarnpkg.com/@ethersproject/abi/-/abi-5.7.0.tgz#b3f3e045bbbeed1af3947335c247ad625a44e449" resolved "https://registry.yarnpkg.com/@ethersproject/abi/-/abi-5.7.0.tgz#b3f3e045bbbeed1af3947335c247ad625a44e449"
@ -344,22 +351,54 @@
"@ethersproject/properties" "^5.7.0" "@ethersproject/properties" "^5.7.0"
"@ethersproject/strings" "^5.7.0" "@ethersproject/strings" "^5.7.0"
"@hyperlane-xyz/core@1.1.2": "@hyperlane-xyz/core@1.3.0":
version "1.1.2" version "1.3.0"
resolved "https://registry.yarnpkg.com/@hyperlane-xyz/core/-/core-1.1.2.tgz#d084a8420136dffa63abb813ffae60f2feb10ce5" resolved "https://registry.yarnpkg.com/@hyperlane-xyz/core/-/core-1.3.0.tgz#8603ad919926e25e62e53f310d82bd010dd148c9"
integrity sha512-x7yUJ9NxmygQ6b5Y7Y/d9NB23bzA/8lUfbB1cmKx2j2eomST9Gwko9TI/v8KqfPDtB83bW0EFW0G31BgQnXNGg== integrity sha512-1YaTbucXshoijwODk+Iq6cC79iDfexsWd9/PqJZG2ogFfqoU5rO0+atK+40y5OEhLrTwCqUfRAV8K/Q+c3bYbQ==
dependencies: dependencies:
"@hyperlane-xyz/utils" "1.1.2" "@hyperlane-xyz/utils" "1.3.0"
"@openzeppelin/contracts" "^4.8.0" "@openzeppelin/contracts" "^4.8.0"
"@openzeppelin/contracts-upgradeable" "^4.8.0" "@openzeppelin/contracts-upgradeable" "^4.8.0"
"@hyperlane-xyz/utils@1.1.2": "@hyperlane-xyz/sdk@^1.3.0":
version "1.1.2" version "1.3.0"
resolved "https://registry.yarnpkg.com/@hyperlane-xyz/utils/-/utils-1.1.2.tgz#c6f10c79bbac0a5c221991a86f79bf33574a7e91" resolved "https://registry.yarnpkg.com/@hyperlane-xyz/sdk/-/sdk-1.3.0.tgz#3b8fd260ebb6954cb51576b840d837157576ac6b"
integrity sha512-5ox1L3uJBQJ8Gvy4HFjGTLAnr4WppXmNF9OsIJbD/qZYYr4Nk8s9Q6mj/25xej3Y7jxYH6bnJ3opUHLyG9dh/g== integrity sha512-pe/is3KcND01NwvDafS5AsraJGV7cK35agwbZbAXBDWf6ANU8sRXVlvQkGnOQM+lU8kyEGXCSr1TXl8YF7SG/A==
dependencies:
"@hyperlane-xyz/core" "1.3.0"
"@hyperlane-xyz/utils" "1.3.0"
"@wagmi/chains" "^0.2.6"
coingecko-api "^1.0.10"
cross-fetch "^3.1.5"
debug "^4.3.4"
ethers "^5.7.2"
zod "^3.21.2"
"@hyperlane-xyz/utils@1.3.0", "@hyperlane-xyz/utils@^1.3.0":
version "1.3.0"
resolved "https://registry.yarnpkg.com/@hyperlane-xyz/utils/-/utils-1.3.0.tgz#e7ba10b4295d10bc57feda39bb74ca879f2af6f7"
integrity sha512-jwEoJIiAZ3ZG5wlgKsiujjp+0RbvSy524iaZePjF/mqYjTTv/bl8uC5T1MW+5iHz+mgh3gXtRX2PT8yoyhuymQ==
dependencies: dependencies:
ethers "^5.7.2" ethers "^5.7.2"
"@jridgewell/resolve-uri@^3.0.3":
version "3.1.0"
resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz#2203b118c157721addfe69d47b70465463066d78"
integrity sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==
"@jridgewell/sourcemap-codec@^1.4.10":
version "1.4.14"
resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz#add4c98d341472a289190b424efbdb096991bb24"
integrity sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==
"@jridgewell/trace-mapping@0.3.9":
version "0.3.9"
resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz#6534fd5933a53ba7cbf3a17615e273a0d1273ff9"
integrity sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==
dependencies:
"@jridgewell/resolve-uri" "^3.0.3"
"@jridgewell/sourcemap-codec" "^1.4.10"
"@openzeppelin/contracts-upgradeable@^4.8.0": "@openzeppelin/contracts-upgradeable@^4.8.0":
version "4.8.0" version "4.8.0"
resolved "https://registry.yarnpkg.com/@openzeppelin/contracts-upgradeable/-/contracts-upgradeable-4.8.0.tgz#26688982f46969018e3ed3199e72a07c8d114275" resolved "https://registry.yarnpkg.com/@openzeppelin/contracts-upgradeable/-/contracts-upgradeable-4.8.0.tgz#26688982f46969018e3ed3199e72a07c8d114275"
@ -377,16 +416,102 @@
dependencies: dependencies:
antlr4ts "^0.5.0-alpha.4" antlr4ts "^0.5.0-alpha.4"
"@tsconfig/node10@^1.0.7":
version "1.0.9"
resolved "https://registry.yarnpkg.com/@tsconfig/node10/-/node10-1.0.9.tgz#df4907fc07a886922637b15e02d4cebc4c0021b2"
integrity sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==
"@tsconfig/node12@^1.0.7":
version "1.0.11"
resolved "https://registry.yarnpkg.com/@tsconfig/node12/-/node12-1.0.11.tgz#ee3def1f27d9ed66dac6e46a295cffb0152e058d"
integrity sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==
"@tsconfig/node14@^1.0.0":
version "1.0.3"
resolved "https://registry.yarnpkg.com/@tsconfig/node14/-/node14-1.0.3.tgz#e4386316284f00b98435bf40f72f75a09dabf6c1"
integrity sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==
"@tsconfig/node16@^1.0.2":
version "1.0.3"
resolved "https://registry.yarnpkg.com/@tsconfig/node16/-/node16-1.0.3.tgz#472eaab5f15c1ffdd7f8628bd4c4f753995ec79e"
integrity sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ==
"@types/coingecko-api@^1.0.10":
version "1.0.10"
resolved "https://registry.yarnpkg.com/@types/coingecko-api/-/coingecko-api-1.0.10.tgz#e841f75c1dc5c6ab8f251011b28a9aec0576ec19"
integrity sha512-ENJO5JzV7qTj8GfrRWAy8lom4RPQv03stvw2z9riz0z7WOXcaorc8OPov8JEekoGQ397O1BbvgPjZj7bWgqdgg==
"@types/debug@^4.1.7":
version "4.1.7"
resolved "https://registry.yarnpkg.com/@types/debug/-/debug-4.1.7.tgz#7cc0ea761509124709b8b2d1090d8f6c17aadb82"
integrity sha512-9AonUzyTjXXhEOa0DnqpzZi6VHlqKMswga9EXjpXnnqxwLtdvPPtlO8evrI5D9S6asFRCQ6v+wpiUKbw+vKqyg==
dependencies:
"@types/ms" "*"
"@types/ms@*":
version "0.7.31"
resolved "https://registry.yarnpkg.com/@types/ms/-/ms-0.7.31.tgz#31b7ca6407128a3d2bbc27fe2d21b345397f6197"
integrity sha512-iiUgKzV9AuaEkZqkOLDIvlQiL6ltuZd9tGcW3gwpnX8JbuiuhFlEGmmFXEXkN50Cvq7Os88IY2v0dkDqXYWVgA==
"@types/node@^18.14.5":
version "18.15.11"
resolved "https://registry.yarnpkg.com/@types/node/-/node-18.15.11.tgz#b3b790f09cb1696cffcec605de025b088fa4225f"
integrity sha512-E5Kwq2n4SbMzQOn6wnmBjuK9ouqlURrcZDVfbo9ftDDTFt3nk7ZKK4GMOzoYgnpQJKcxwQw+lGaBvvlMo0qN/Q==
"@types/yargs-parser@*":
version "21.0.0"
resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-21.0.0.tgz#0c60e537fa790f5f9472ed2776c2b71ec117351b"
integrity sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA==
"@types/yargs@^17.0.22":
version "17.0.24"
resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-17.0.24.tgz#b3ef8d50ad4aa6aecf6ddc97c580a00f5aa11902"
integrity sha512-6i0aC7jV6QzQB8ne1joVZ0eSFIstHsCrobmOtghM11yGlH0j43FKL2UhWdELkyps0zuf7qVTUVCCR+tgSlyLLw==
dependencies:
"@types/yargs-parser" "*"
"@wagmi/chains@^0.2.6":
version "0.2.15"
resolved "https://registry.yarnpkg.com/@wagmi/chains/-/chains-0.2.15.tgz#77bd1cece0c32a795df2122cbc0564c82b63f855"
integrity sha512-yeNamxRmqq1/PirJqCpKHSJcetZ9ivZdJnCIvNvJifpCz1A2dLlD1+NON11saiyShH7tshS5Eaf0pm9Luna8JQ==
acorn-walk@^8.1.1:
version "8.2.0"
resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-8.2.0.tgz#741210f2e2426454508853a2f44d0ab83b7f69c1"
integrity sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==
acorn@^8.4.1:
version "8.8.2"
resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.8.2.tgz#1b2f25db02af965399b9776b0c2c391276d37c4a"
integrity sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==
aes-js@3.0.0: aes-js@3.0.0:
version "3.0.0" version "3.0.0"
resolved "https://registry.yarnpkg.com/aes-js/-/aes-js-3.0.0.tgz#e21df10ad6c2053295bcbb8dab40b09dbea87e4d" resolved "https://registry.yarnpkg.com/aes-js/-/aes-js-3.0.0.tgz#e21df10ad6c2053295bcbb8dab40b09dbea87e4d"
integrity sha512-H7wUZRn8WpTq9jocdxQ2c8x2sKo9ZVmzfRE13GiNJXfp7NcKYEdvl3vspKjXox6RIG2VtaRe4JFvxG4rqp2Zuw== integrity sha512-H7wUZRn8WpTq9jocdxQ2c8x2sKo9ZVmzfRE13GiNJXfp7NcKYEdvl3vspKjXox6RIG2VtaRe4JFvxG4rqp2Zuw==
ansi-regex@^5.0.1:
version "5.0.1"
resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304"
integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==
ansi-styles@^4.0.0:
version "4.3.0"
resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937"
integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==
dependencies:
color-convert "^2.0.1"
antlr4ts@^0.5.0-alpha.4: antlr4ts@^0.5.0-alpha.4:
version "0.5.0-alpha.4" version "0.5.0-alpha.4"
resolved "https://registry.yarnpkg.com/antlr4ts/-/antlr4ts-0.5.0-alpha.4.tgz#71702865a87478ed0b40c0709f422cf14d51652a" resolved "https://registry.yarnpkg.com/antlr4ts/-/antlr4ts-0.5.0-alpha.4.tgz#71702865a87478ed0b40c0709f422cf14d51652a"
integrity sha512-WPQDt1B74OfPv/IMS2ekXAKkTZIHl88uMetg6q3OTqgFxZ/dxDXI0EWLyZid/1Pe6hTftyg5N7gel5wNAGxXyQ== integrity sha512-WPQDt1B74OfPv/IMS2ekXAKkTZIHl88uMetg6q3OTqgFxZ/dxDXI0EWLyZid/1Pe6hTftyg5N7gel5wNAGxXyQ==
arg@^4.1.0:
version "4.1.3"
resolved "https://registry.yarnpkg.com/arg/-/arg-4.1.3.tgz#269fc7ad5b8e42cb63c896d5666017261c144089"
integrity sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==
bech32@1.1.4: bech32@1.1.4:
version "1.1.4" version "1.1.4"
resolved "https://registry.yarnpkg.com/bech32/-/bech32-1.1.4.tgz#e38c9f37bf179b8eb16ae3a772b40c356d4832e9" resolved "https://registry.yarnpkg.com/bech32/-/bech32-1.1.4.tgz#e38c9f37bf179b8eb16ae3a772b40c356d4832e9"
@ -407,6 +532,56 @@ brorand@^1.1.0:
resolved "https://registry.yarnpkg.com/brorand/-/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f" resolved "https://registry.yarnpkg.com/brorand/-/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f"
integrity sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w== integrity sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w==
cliui@^8.0.1:
version "8.0.1"
resolved "https://registry.yarnpkg.com/cliui/-/cliui-8.0.1.tgz#0c04b075db02cbfe60dc8e6cf2f5486b1a3608aa"
integrity sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==
dependencies:
string-width "^4.2.0"
strip-ansi "^6.0.1"
wrap-ansi "^7.0.0"
coingecko-api@^1.0.10:
version "1.0.10"
resolved "https://registry.yarnpkg.com/coingecko-api/-/coingecko-api-1.0.10.tgz#ac8694d5999f00727fe55f0078ce2917603076b2"
integrity sha512-7YLLC85+daxAw5QlBWoHVBVpJRwoPr4HtwanCr8V/WRjoyHTa1Lb9DQAvv4MDJZHiz4no6HGnDQnddtjV35oRA==
color-convert@^2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3"
integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==
dependencies:
color-name "~1.1.4"
color-name@~1.1.4:
version "1.1.4"
resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2"
integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==
create-require@^1.1.0:
version "1.1.1"
resolved "https://registry.yarnpkg.com/create-require/-/create-require-1.1.1.tgz#c1d7e8f1e5f6cfc9ff65f9cd352d37348756c333"
integrity sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==
cross-fetch@^3.1.5:
version "3.1.5"
resolved "https://registry.yarnpkg.com/cross-fetch/-/cross-fetch-3.1.5.tgz#e1389f44d9e7ba767907f7af8454787952ab534f"
integrity sha512-lvb1SBsI0Z7GDwmuid+mU3kWVBwTVUbe7S0H52yaaAdQOXq2YktTCZdlAcNKFzE6QtRz0snpw9bNiPeOIkkQvw==
dependencies:
node-fetch "2.6.7"
debug@^4.3.4:
version "4.3.4"
resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865"
integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==
dependencies:
ms "2.1.2"
diff@^4.0.1:
version "4.0.2"
resolved "https://registry.yarnpkg.com/diff/-/diff-4.0.2.tgz#60f3aecb89d5fae520c11aa19efc2bb982aade7d"
integrity sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==
elliptic@6.5.4: elliptic@6.5.4:
version "6.5.4" version "6.5.4"
resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.5.4.tgz#da37cebd31e79a1367e941b592ed1fbebd58abbb" resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.5.4.tgz#da37cebd31e79a1367e941b592ed1fbebd58abbb"
@ -420,6 +595,16 @@ elliptic@6.5.4:
minimalistic-assert "^1.0.1" minimalistic-assert "^1.0.1"
minimalistic-crypto-utils "^1.0.1" minimalistic-crypto-utils "^1.0.1"
emoji-regex@^8.0.0:
version "8.0.0"
resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37"
integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==
escalade@^3.1.1:
version "3.1.1"
resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40"
integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==
ethers@^5.7.2: ethers@^5.7.2:
version "5.7.2" version "5.7.2"
resolved "https://registry.yarnpkg.com/ethers/-/ethers-5.7.2.tgz#3a7deeabbb8c030d4126b24f84e525466145872e" resolved "https://registry.yarnpkg.com/ethers/-/ethers-5.7.2.tgz#3a7deeabbb8c030d4126b24f84e525466145872e"
@ -456,6 +641,11 @@ ethers@^5.7.2:
"@ethersproject/web" "5.7.1" "@ethersproject/web" "5.7.1"
"@ethersproject/wordlists" "5.7.0" "@ethersproject/wordlists" "5.7.0"
get-caller-file@^2.0.5:
version "2.0.5"
resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e"
integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==
hash.js@1.1.7, hash.js@^1.0.0, hash.js@^1.0.3: hash.js@1.1.7, hash.js@^1.0.0, hash.js@^1.0.3:
version "1.1.7" version "1.1.7"
resolved "https://registry.yarnpkg.com/hash.js/-/hash.js-1.1.7.tgz#0babca538e8d4ee4a0f8988d68866537a003cf42" resolved "https://registry.yarnpkg.com/hash.js/-/hash.js-1.1.7.tgz#0babca538e8d4ee4a0f8988d68866537a003cf42"
@ -478,6 +668,11 @@ inherits@^2.0.3, inherits@^2.0.4:
resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c"
integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==
is-fullwidth-code-point@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d"
integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==
js-sha3@0.8.0: js-sha3@0.8.0:
version "0.8.0" version "0.8.0"
resolved "https://registry.yarnpkg.com/js-sha3/-/js-sha3-0.8.0.tgz#b9b7a5da73afad7dedd0f8c463954cbde6818840" resolved "https://registry.yarnpkg.com/js-sha3/-/js-sha3-0.8.0.tgz#b9b7a5da73afad7dedd0f8c463954cbde6818840"
@ -490,6 +685,11 @@ lru-cache@^6.0.0:
dependencies: dependencies:
yallist "^4.0.0" yallist "^4.0.0"
make-error@^1.1.1:
version "1.3.6"
resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.6.tgz#2eb2e37ea9b67c4891f684a1394799af484cf7a2"
integrity sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==
minimalistic-assert@^1.0.0, minimalistic-assert@^1.0.1: minimalistic-assert@^1.0.0, minimalistic-assert@^1.0.1:
version "1.0.1" version "1.0.1"
resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7" resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7"
@ -500,6 +700,18 @@ minimalistic-crypto-utils@^1.0.1:
resolved "https://registry.yarnpkg.com/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz#f6c00c1c0b082246e5c4d99dfb8c7c083b2b582a" resolved "https://registry.yarnpkg.com/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz#f6c00c1c0b082246e5c4d99dfb8c7c083b2b582a"
integrity sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg== integrity sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg==
ms@2.1.2:
version "2.1.2"
resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009"
integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==
node-fetch@2.6.7:
version "2.6.7"
resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.7.tgz#24de9fba827e3b4ae44dc8b20256a379160052ad"
integrity sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==
dependencies:
whatwg-url "^5.0.0"
prettier-plugin-solidity@^1.1.1: prettier-plugin-solidity@^1.1.1:
version "1.1.1" version "1.1.1"
resolved "https://registry.yarnpkg.com/prettier-plugin-solidity/-/prettier-plugin-solidity-1.1.1.tgz#4d3375b85f97812ffcbe48d5a8b3fe914d69c91f" resolved "https://registry.yarnpkg.com/prettier-plugin-solidity/-/prettier-plugin-solidity-1.1.1.tgz#4d3375b85f97812ffcbe48d5a8b3fe914d69c91f"
@ -514,6 +726,11 @@ prettier@^2.8.2:
resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.8.2.tgz#c4ea1b5b454d7c4b59966db2e06ed7eec5dfd160" resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.8.2.tgz#c4ea1b5b454d7c4b59966db2e06ed7eec5dfd160"
integrity sha512-BtRV9BcncDyI2tsuS19zzhzoxD8Dh8LiCx7j7tHzrkz8GFXAexeWFdi22mjE1d16dftH2qNaytVxqiRTGlMfpw== integrity sha512-BtRV9BcncDyI2tsuS19zzhzoxD8Dh8LiCx7j7tHzrkz8GFXAexeWFdi22mjE1d16dftH2qNaytVxqiRTGlMfpw==
require-directory@^2.1.1:
version "2.1.1"
resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42"
integrity sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==
scrypt-js@3.0.1: scrypt-js@3.0.1:
version "3.0.1" version "3.0.1"
resolved "https://registry.yarnpkg.com/scrypt-js/-/scrypt-js-3.0.1.tgz#d314a57c2aef69d1ad98a138a21fe9eafa9ee312" resolved "https://registry.yarnpkg.com/scrypt-js/-/scrypt-js-3.0.1.tgz#d314a57c2aef69d1ad98a138a21fe9eafa9ee312"
@ -531,12 +748,117 @@ solidity-comments-extractor@^0.0.7:
resolved "https://registry.yarnpkg.com/solidity-comments-extractor/-/solidity-comments-extractor-0.0.7.tgz#99d8f1361438f84019795d928b931f4e5c39ca19" resolved "https://registry.yarnpkg.com/solidity-comments-extractor/-/solidity-comments-extractor-0.0.7.tgz#99d8f1361438f84019795d928b931f4e5c39ca19"
integrity sha512-wciNMLg/Irp8OKGrh3S2tfvZiZ0NEyILfcRCXCD4mp7SgK/i9gzLfhY2hY7VMCQJ3kH9UB9BzNdibIVMchzyYw== integrity sha512-wciNMLg/Irp8OKGrh3S2tfvZiZ0NEyILfcRCXCD4mp7SgK/i9gzLfhY2hY7VMCQJ3kH9UB9BzNdibIVMchzyYw==
string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3:
version "4.2.3"
resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010"
integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==
dependencies:
emoji-regex "^8.0.0"
is-fullwidth-code-point "^3.0.0"
strip-ansi "^6.0.1"
strip-ansi@^6.0.0, strip-ansi@^6.0.1:
version "6.0.1"
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9"
integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==
dependencies:
ansi-regex "^5.0.1"
tr46@~0.0.3:
version "0.0.3"
resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a"
integrity sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==
ts-node@^10.9.1:
version "10.9.1"
resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-10.9.1.tgz#e73de9102958af9e1f0b168a6ff320e25adcff4b"
integrity sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==
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"
typescript@^4.9.5:
version "4.9.5"
resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.9.5.tgz#095979f9bcc0d09da324d58d03ce8f8374cbe65a"
integrity sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==
v8-compile-cache-lib@^3.0.1:
version "3.0.1"
resolved "https://registry.yarnpkg.com/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz#6336e8d71965cb3d35a1bbb7868445a7c05264bf"
integrity sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==
webidl-conversions@^3.0.0:
version "3.0.1"
resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871"
integrity sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==
whatwg-url@^5.0.0:
version "5.0.0"
resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-5.0.0.tgz#966454e8765462e37644d3626f6742ce8b70965d"
integrity sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==
dependencies:
tr46 "~0.0.3"
webidl-conversions "^3.0.0"
wrap-ansi@^7.0.0:
version "7.0.0"
resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43"
integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==
dependencies:
ansi-styles "^4.0.0"
string-width "^4.1.0"
strip-ansi "^6.0.0"
ws@7.4.6: ws@7.4.6:
version "7.4.6" version "7.4.6"
resolved "https://registry.yarnpkg.com/ws/-/ws-7.4.6.tgz#5654ca8ecdeee47c33a9a4bf6d28e2be2980377c" resolved "https://registry.yarnpkg.com/ws/-/ws-7.4.6.tgz#5654ca8ecdeee47c33a9a4bf6d28e2be2980377c"
integrity sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A== integrity sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A==
y18n@^5.0.5:
version "5.0.8"
resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55"
integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==
yallist@^4.0.0: yallist@^4.0.0:
version "4.0.0" version "4.0.0"
resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72"
integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==
yargs-parser@^21.1.1:
version "21.1.1"
resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-21.1.1.tgz#9096bceebf990d21bb31fa9516e0ede294a77d35"
integrity sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==
yargs@^17.7.1:
version "17.7.1"
resolved "https://registry.yarnpkg.com/yargs/-/yargs-17.7.1.tgz#34a77645201d1a8fc5213ace787c220eabbd0967"
integrity sha512-cwiTb08Xuv5fqF4AovYacTFNxk62th7LKJ6BL9IGUpTJrWoU7/7WdQGTP2SjKf1dUNBGzDd28p/Yfs/GI6JrLw==
dependencies:
cliui "^8.0.1"
escalade "^3.1.1"
get-caller-file "^2.0.5"
require-directory "^2.1.1"
string-width "^4.2.3"
y18n "^5.0.5"
yargs-parser "^21.1.1"
yn@3.1.1:
version "3.1.1"
resolved "https://registry.yarnpkg.com/yn/-/yn-3.1.1.tgz#1e87401a09d767c1d5eab26a6e4c185182d2eb50"
integrity sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==
zod@^3.21.2:
version "3.21.4"
resolved "https://registry.yarnpkg.com/zod/-/zod-3.21.4.tgz#10882231d992519f0a10b5dd58a38c9dabbb64db"
integrity sha512-m46AKbrzKVzOzs/DZgVnG5H55N1sv1M8qZU3A8RIKbs3mrACDNeIOeilDymVb2HdmP8uwshOCF4uJ8uM9rCqJw==

Loading…
Cancel
Save