Skip to content

Commit

Permalink
merge base branch
Browse files Browse the repository at this point in the history
  • Loading branch information
DZGoldman committed Jul 6, 2023
1 parent 13a41e8 commit 00472f7
Show file tree
Hide file tree
Showing 74 changed files with 3,255 additions and 1,105 deletions.
276 changes: 145 additions & 131 deletions .gas-snapshot

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,4 @@ files/local/l1ArbProtocolTransferTXs.json
files/local/l1ArbTokenBridgeTransferTXs.json
files/local/l1NovaProtocolTransferTXs.json
files/local/l1NovaTokenBridgeTransferTXs.json
dist/
66 changes: 63 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,66 @@ Finally, let's make sure owership of protocol assets has been succsessfully tran
yarn verify:ownership:transfer
```




### ArbitrumFoundationVestingWallet Deployer

#### Deploy
- Set `ARB_URL` and `ARB_KEY` env vars
- Set FoundationWalletDeploymentConfig variables (for target chain) in [config file](./scripts/foundation-wallet-deployment/config.ts)
- run ```yarn hardhat compile ```
- run ```yarn deploy:foundation-wallet ```

#### Verify Deployment
_Verify contract's bytecode on Arbiscan and verify that contract's parameters were set correctly_
- Set `ARB_URL` and `ARBISCAN_API_KEY` env vars
- Set DeployedWallet address (for target chain) in [config file](./scripts/foundation-wallet-deployment/config.ts)
- run ```yarn verify:foundation-wallet ```
### Guide for deploying vesting wallets
Vesting wallets deployer script can be used to deploy vesting wallets. Script will deploy wallet factory contract, and then call `createWallets` function in a loop, 5 wallets at a time. Currently script does not contain logic for transfering tokens to deployed wallets, it only deploys wallets. Deployer script can handle failures, ie. if execution is unexpectedly terminated script can be re-run and it will continue deploying wallets which haven't been deployed. It is important to notice assumption that input list of recipients does not change between runs.

Input for the script is list of recipients/beneficiaries and it should have following format:
```
{
"0xbf7258ead721d9ecc04a8476cf4f863f1b754497": ["1", "340"],
"0xb98637f3750707fe6d1f0b35dbaf5fc8de65c63d": ["2"],
"0x28e7A8CD861E9fd6D253bffE80B0704752Fd6A0D": ["650", "1100", "2500"]
}
```
Input format defines beneficiary address as key and a list of token amounts as value. Actual token amounts are not used in script as atm we're not doing token transfers.

Output format containing deployed addresses will look like this:
```
{
"vestingWalletFactory": "0x24067223381F042fF36fb87818196dB4D2C56E9B",
"beneficiaries": [
{
"beneficiary": "0xbf7258Ead721d9eCC04a8476Cf4F863F1b754497",
"walletAddresses": [
"0x10956D45F1d221D3b98898d0e7af28C20541057F",
"0xA10AF745eC1245fC61ed63f891ce6ee5D8E57Ba3"
]
},
{
"beneficiary": "0xb98637f3750707FE6d1F0b35dbAF5fC8De65c63d",
"walletAddresses": [
"0xE54D680B7DCA2eb6761d0797a5247bD03FB7DF16"
]
},
{
"beneficiary": "0x28e7A8CD861E9fd6D253bffE80B0704752Fd6A0D",
"walletAddresses": [
"0x1e4e5273cb79a55296CDe3351925ad6FbdFFDfe1",
"0x7afD37b828dA31ea4313fAD334A4B7A5A7832489",
"0xAd47B4D46d927C6A1150107A26FC4286b08eB5F2"
]
}
]
}
```

Deployment steps:
- prepare `.env`, ie. `cp files/goerli/.env-sample .env`
- `.env` shall include: `ARB_KEY`, `ARB_URL`, `VESTED_RECIPIENTS_FILE_LOCATION` and `DEPLOYED_WALLETS_FILE_LOCATION`
- prepare `vestingWalletRecipients.json` in a location which is pointed to by `VESTED_RECIPIENTS_FILE_LOCATION`
- run `yarn build`
- run deployer: `yarn deploy:vested-wallets`
- run verifier: `yarn verify:vested-wallets`
Binary file added audits/trail_of_bits_aips1-1and1-2__5_6_2023.pdf
Binary file not shown.
8 changes: 8 additions & 0 deletions docs/foundation-vesting-wallet.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# Arbitrum Foundation Administrative Budget Wallet

The Arbitrum Foundation Administrative Budget Wallet implements the contract specified in [AIP-1.1](https://forum.arbitrum.foundation/t/proposal-aip-1-1-lockup-budget-transparency/13360). The wallet escrows funds which are unlocked over a linear four year schedule; once unlocked, funds can be claimed by a multisig wallet controlled by the Arbitrum Foundation.

Escrowed $ARB cannot be used to vote on governance proposals. Additionally, the Budget Wallet delegates its votes to the "exclude address" (see ["Vote Exclusion"](./overview.md)); thus, its escrowed $ARB isn't counted towards the governance quorum denominator.

As per AIP-1.1, the DAO has the ability to change the Budget Wallet's unlock schedule. This can be done via a governance proposal which migrates the wallet's funds to a new wallet which enforces a new schedule (see [here](../test/ArbitrumFoundationVestingWallet.t.sol) for test code). Note that the DAO is also the proxy-owner of the Budget Wallet and thus could vote to upgrade its implementation logic arbitrarily; however, for adjusting its unlock schedule, the migration method is the preferable recommendation.

3 changes: 2 additions & 1 deletion docs/overview.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ Governance is responsible for the following assets:
- **Arb One L2 parameters** - All Arbitrum chains have a chain "owner" that can set certain parameters. Read more [here](https://github.com/OffchainLabs/nitro/blob/master/precompiles/ArbOwner.go). Governance has control over the chain owner.
- **Arb Nova L2 parameters** - same as Arb One L2 parameters.
- **Governance contracts** - Governance has the ability to upgrade and modify itself.
- **Arbitrum Foundation Administrative Budget Wallet** — see [here](./foundation-vesting-wallet.md) for info.

## Proposal types

Expand Down Expand Up @@ -144,7 +145,7 @@ The contracts in the diagram encode ownership chains that ensure only governance

This means that forming a proposal involves working backwards from the target, wrapping the data multiple times to define the path the upgrade will take.

You can read more about how the path is encoded in the [proposal lifecycle document](./docs/proposal_lifecycle_example.md)
You can read more about how the path is encoded in the [proposal lifecycle document](./proposal_lifecycle_example.md)

## Proposal Cancellation
Both governor contracts have the affordance to cancel proposals scheduled in the L2 Timelock. The Security Council can likewise cancel proposals [via calling L2ArbitrumGovernor.relay](src/gov-action-contracts/governance/CancelTimelockOperation.sol). Note that although the core-governor Security Council has the affordance to cancel proposals in the L2 timelock via calling `cancel` directly, for clarity and consistency, it should use the aforementioned `relay` method.
Expand Down
48 changes: 48 additions & 0 deletions docs/submit_a_proposal.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# Submit a Proposal Example: AIP-1.2

Here, we'll go through an example of how an $ARB delegate can permissionlessly submit a DAO proposal using the Tally web app. We'll use [AIP-1.2](https://forum.arbitrum.foundation/t/proposal-aip-1-2-foundation-and-dao-governance/13362) and [AIP-1.1](https://forum.arbitrum.foundation/t/proposal-aip-1-1-lockup-budget-transparency/13360) as our examples.

To start, review the 7 general steps to submit a proposal using Tally in the Arbitrum Foundation docs [here](https://docs.arbitrum.foundation/how-tos/create-submit-dao-proposal#step-2-submit-your-on-chain-proposal-using-tally).


## Submitting AIP-1.2
For our example of AIP-1.2, do the following in particular:
- **Governor Selection (step 4):**
- Select the "Arbitrum Core" governor.
- _Explanation: AIP-1.2 updates the DAO Constitution Hash and sets the proposal thresholds for both governors to new values; both these these are constitutional actions, so the Core Governor must be used._
- **Proposal Title / Description (step 5):**
- Give the proposal a title and description; the title and description should be the same as the title and description in the corresponding [snapshot post](https://snapshot.org/#/arbitrumfoundation.eth/proposal/0x373dfa89fc9c5ccba8ed83fa3fa4f233edd270075b5f8f4f3902b408318d9d17), with any info about steps prior to proposal submission removed. You can use the description the [proposal JSON data here](../scripts/proposals/AIP12/data/42161-AIP1.2-data.json).
- **Proposal Action (step 6)**:
1. Select `Custom Action`
1. In the `Enter the Target Address` Field" use `0x0000000000000000000000000000000000000064` (the ArbSys precompile).
1. In the `Contract method` dropdown, select `sendTxToL1`.
1. For the `destination` address field, use the [l1ArbitrumTimelock](https://etherscan.io/address/0xE6841D92B0C345144506576eC13ECf5103aC7f49#readProxyContract) address (`0xE6841D92B0C345144506576eC13ECf5103aC7f49`) as provided in the [proposal JSON data](../scripts/proposals/AIP12/data/42161-AIP1.2-data.json).
- _Explanation: all executable core governor proposals will use the previous 4 steps; since constitutional proposals require a "round trip" before effectuating, their first step is to use ArbSys to encode an L2 to L1 message to the L1 timelock; for more, see ["Proposal Lifecycle Example"](./proposal_lifecycle_example.md)._
1. For the `data` bytes field, use the `calldata` bytes in the [proposal JSON data](../scripts/proposals/AIP12/data/42161-AIP1.2-data.json). See below for instructions on regenerating / verifying the calldata locally.
- _Explanation: all defining details of a particular core governor proposal are encoding in this calldata, i.e., the [governance action contract address](https://arbiscan.io/address/0x6274106eedD4848371D2C09e0352d67B795ED516) as well as the appropriate inbox/upgrade executor addresses such that the proposal targets the appropriate chain (in this case, Arbitrum One). We use scripts to generate a proposal's calldata_
1. For the `ETH`/ `value` field, use `0`.
- _Explanation: The Governor allows proposals to include callvalue, tho the vast majority of proposals won't require any_.

## Generating AIP-1.2 Calldata Locally
Note that the data is already generated and committed to the git repo; run these steps to regeneate / confirm it.
1. git clone this repo
1. run `yarn install` and `yarn build`
1. Set the following environment variables:
- `ARB_URL`: An RPC endpoint for Arbitrum One, e.g. "https://arb1.arbitrum.io/rpc"
- `ETH_URL`: An RPC endpoint for L1 Ethereun, e.g., "https://mainnet.infura.io/v3/YOUR-KEY-HERE"
1. Run: `yarn ts-node ./scripts/proposals/AIP12/generateProposalData.ts`
Output will appear in logs and will be written to the [proposal JSON data](../scripts/proposals/AIP12/data/42161-AIP1.2-data.json) file.


## Submitting AIP-1.1
- **Governor Selection (step 4):**
- Select "Arbitrum Treasury" governor.
- _Explanation: AIP-1.1 deals with the Arbitrum's Foundation budget management and relevant transparency; as per the constitution, this qualifies it as a "non-constitution" proposal — such propoposals use the Treasury governor._
- **Proposal Title / Description (step 5):**
- The on-chain proposal should have the same title and description as its corresponding [snapshot post](https://snapshot.org/#/arbitrumfoundation.eth/proposal/0x7203289844e807781e8d2ec110d4b97a79a29944cae06a52dbe315a16381a2ae).
- **Proposal Action (step 6)**:
1. Select `Custom Action`
1. In the `Enter the Target Address` Field" use `0x9E43f733Da0445b35f038FB34a6Fb8C2947B984C`, a contract ("AIP1Point1Target") deployed for AIP-1.1
1. In the `Contract method` dropdown, select `effectuate`.
1. For the `ETH`/ `value` field, use `0`.
- _Explanation: AIP-1.1 technically doesn't require any on-chain execution. We use a designated contract anyway as a formality and for bookkeeping purposes_
8 changes: 5 additions & 3 deletions files/goerli/.env-sample
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@

## governance deployment
# should be set to "false" when deploying to production!
DEPLOY_TO_LOCAL_ENVIRONMENT="false"
Expand All @@ -24,8 +25,9 @@ ARB_L2_TXS_FILE_LOCATION="./files/goerli/arbTransferAssetsTXs.json"
# DAO_RECIPIENTS_KEY=""
# DAO_RECIPIENTS_FILE_LOCATION=""

# only required for distributing to vested wallets
# VESTED_RECIPIENTS_FILE_LOCATION=""

# required for running proposal tests
# TEAM_KEY=""

# required for deploying vested wallets
VESTED_RECIPIENTS_FILE_LOCATION="./files/goerli/vestingWalletRecipients.json"
DEPLOYED_WALLETS_FILE_LOCATION="./files/goerli/deployedWallets.json"
31 changes: 31 additions & 0 deletions files/goerli/deployedContracts.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
{
"l1UpgradeExecutorLogic": "0x625cc9ea502fE5B937984D8DD81aD39ef6622D51",
"l2TimelockLogic": "0x625cc9ea502fE5B937984D8DD81aD39ef6622D51",
"l2GovernorLogic": "0xBBcbf9CB8E959BE5A23Cf8f8189Ac4a8cf8ccCAd",
"l2FixedDelegateLogic": "0xe432838Abf83472d17E808c2fFF31313D24059E7",
"l2TokenLogic": "0x33A7991a70AD174822ddfa2618Df9C8f17c04563",
"l2UpgradeExecutorLogic": "0x3137E58456cAF67918F3a77B4A70fB24AC036804",
"l1GovernanceFactory": "0xBBcbf9CB8E959BE5A23Cf8f8189Ac4a8cf8ccCAd",
"l2GovernanceFactory": "0xc7A327663F46a9D78cf2b31ebc157dE6D6bf1552",
"l1ReverseCustomGatewayLogic": "0xe432838Abf83472d17E808c2fFF31313D24059E7",
"l1ReverseCustomGatewayProxy": "0x33A7991a70AD174822ddfa2618Df9C8f17c04563",
"l2ReverseCustomGatewayLogic": "0xECCc8dE9b0a0F1074D8dc6E1092964A3Bc400a41",
"l2ReverseCustomGatewayProxy": "0x584d4D9bED1bEb39f02bb51dE07F493D3A5CdaA0",
"l1TokenLogic": "0xc7A327663F46a9D78cf2b31ebc157dE6D6bf1552",
"l1TokenProxy": "0xECCc8dE9b0a0F1074D8dc6E1092964A3Bc400a41",
"l2CoreGoverner": "0xa584d185244DCbCa8A98dBdB4e550a5De3A64c81",
"l2CoreTimelock": "0x9ECEB85516AA549Dd2A458255Df4330625216a91",
"l2Executor": "0x67AcB531A05160A81dCD03079347f264c4FA2da3",
"l2ProxyAdmin": "0x8CfA7Dc239B15E2b4cA6E4B4F4d044f49d5558d4",
"l2Token": "0xF861378B543525ae0C47d33C90C954Dc774Ac1F9",
"l2TreasuryGoverner": "0x5C7f047cC1564b120DEabFC29B67c60a7c6d6BD2",
"l2ArbTreasury": "0xDA4d3D030B469c3D42B0613202341a6b00E8836e",
"arbitrumDAOConstitution": "0x71929e930A27CCA210B93d5485Ea63Bb7e298028",
"l2TreasuryTimelock": "0xE0B4995bDeAd6F5FE85D876F3A59b44d1be27350",
"l1Executor": "0x9b082cBFCDA26dE9F38010ADc8D52f4652504b27",
"l1ProxyAdmin": "0x2cD70932105955489e4c452FDcd531a6B811b394",
"l1Timelock": "0x364188EcF8E0733cB90d8EbeD90d56E56205dDfE",
"l2TokenDistributor": "0x9AfB2254c24eb480e36dee66A4F26b5C540b6615",
"l1AddressRegistry": "0x8b194bEae1d3e0788A1a35173978001ACDFba668",
"l2AddressRegistry": "0xAAa6704eeA535c8a07Cbe647680b440264f74f08"
}
1 change: 1 addition & 0 deletions files/local/.env-sample
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ VESTED_RECIPIENTS_FILE_LOCATION="./files/local/vestingWalletRecipients.json"
DAO_RECIPIENTS_FILE_LOCATION="./files/local/daoRecipients.json"
CLAIM_RECIPIENTS_FILE_LOCATION="./files/local/claimRecipients.json"
DEPLOYED_CONTRACTS_FILE_LOCATION="./files/local/deployedContracts.json"
DEPLOYED_WALLETS_FILE_LOCATION="./files/local/deployedWallets.json"

ARB_L1_PROTOCOL_TRANSFER_TXS_FILE_LOCATION="./files/local/l1ArbProtocolTransferTXs.json"
ARB_L1_TOKEN_BRIDGE_TRANSFER_TXS_FILE_LOCATION="./files/local/l1ArbTokenBridgeTransferTXs.json"
Expand Down
12 changes: 7 additions & 5 deletions files/local/vestingWalletRecipients.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
{
"0xbf7258ead721d9ecc04a8476cf4f863f1b754497": "1",
"0xb98637f3750707fe6d1f0b35dbaf5fc8de65c63d": "2",
"0x417996f1c009db8e238a6203625717c80a94b222": "4567",
"0x3243ed9fdcde2345890ddeaf6b083ca4cf0f68f2": "675670",
"0xcbd6832ebc203e49e2b771897067fce3c58575ac": "500"
"0xbf7258ead721d9ecc04a8476cf4f863f1b754497": ["1", "340"],
"0xb98637f3750707fe6d1f0b35dbaf5fc8de65c63d": ["2"],
"0x417996f1c009db8e238a6203625717c80a94b222": ["4567"],
"0x3243ed9fdcde2345890ddeaf6b083ca4cf0f68f2": ["675670"],
"0xcbd6832ebc203e49e2b771897067fce3c58575ac": ["500"],
"0xeCBea367C0fe731C9B985c0714c614fF541f90De": ["100", "101"],
"0x28e7A8CD861E9fd6D253bffE80B0704752Fd6A0D": ["650", "1100", "2500"]
}
5 changes: 3 additions & 2 deletions files/mainnet/.env-sample
Original file line number Diff line number Diff line change
Expand Up @@ -29,5 +29,6 @@ NOVA_L2_TXS_FILE_LOCATION="./files/mainnet/novaTransferAssetsTXs.json"
# DAO_RECIPIENTS_KEY=""
# DAO_RECIPIENTS_FILE_LOCATION=""

# only required for distributing to vested wallets
# VESTED_RECIPIENTS_FILE_LOCATION=""
# required for deploying vested wallets
VESTED_RECIPIENTS_FILE_LOCATION="./files/mainnet/vestingWalletRecipients.json"
DEPLOYED_WALLETS_FILE_LOCATION="./files/mainnet/deployedWallets.json"
35 changes: 35 additions & 0 deletions files/mainnet/deployedContracts.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
{
"l1UpgradeExecutorLogic": "0x86f0cf42Ad673B3D666d103E009EC142D1298a17",
"l2TimelockLogic": "0x41740588b86B4e0629b83A4e28786FF94361c3A3",
"l2GovernorLogic": "0x065620d99E1785Ccf56Fa95462d3012Eb844FDC9",
"l2FixedDelegateLogic": "0x9F43ab02cACc8e709b05936a92dC85b76D1523c4",
"l2TokenLogic": "0xC4ed0A9Ea70d5bCC69f748547650d32cC219D882",
"l2UpgradeExecutorLogic": "0x7A013834D54e9B22d1978aAe3aaDDC909Aa79115",
"l1GovernanceFactory": "0x1517114701A2dd2205F4ED1E27E3dcaDDc020a0c",
"l2GovernanceFactory": "0xDec539A8B29703F7a85f7160bBB6B8882c1D4d29",
"l1ReverseCustomGatewayLogic": "0x4e8C24617C4592895d52Ac6df29D9647e9D01Bb5",
"l1ReverseCustomGatewayProxy": "0xbbcE8aA77782F13D4202a230d978F361B011dB27",
"l2ReverseCustomGatewayLogic": "0x5D96786d3Eb13CAd05c9Fd7d0f7bb9560b4E5056",
"l2ReverseCustomGatewayProxy": "0xCaD7828a19b363A2B44717AFB1786B5196974D8E",
"l1TokenLogic": "0xAD0C361Ef902A7D9851Ca7DcC85535DA2d3C6Fc7",
"l1TokenProxy": "0xB50721BCf8d664c30412Cfbc6cf7a15145234ad1",
"novaProxyAdmin": "0xf58eA15B20983116c21b05c876cc8e6CDAe5C2b9",
"novaUpgradeExecutorLogic": "0x3096EAEdcb3A3B665552660F4d921E565D0073cB",
"novaUpgradeExecutorProxy": "0x86a02dD71363c440b21F4c0E5B2Ad01Ffe1A7482",
"novaTokenLogic": "0x099bC495EA4Fd828FEe7C636F0Ab84d0f501B96d",
"novaTokenProxy": "0xf823C3cD3CeBE0a1fA952ba88Dc9EEf8e0Bf46AD",
"l2CoreGoverner": "0xf07DeD9dC292157749B6Fd268E37DF6EA38395B9",
"l2CoreTimelock": "0x34d45e99f7D8c45ed05B5cA72D54bbD1fb3F98f0",
"l2Executor": "0xCF57572261c7c2BCF21ffD220ea7d1a27D40A827",
"l2ProxyAdmin": "0xdb216562328215E010F819B5aBe947bad4ca961e",
"l2Token": "0x912CE59144191C1204E64559FE8253a0e49E6548",
"l2TreasuryGoverner": "0x789fC99093B09aD01C34DC7251D0C89ce743e5a4",
"l2ArbTreasury": "0xF3FC178157fb3c87548bAA86F9d24BA38E649B58",
"arbitrumDAOConstitution": "0x1D62fFeB72e4c360CcBbacf7c965153b00260417",
"l2TreasuryTimelock": "0xbFc1FECa8B09A5c5D3EFfE7429eBE24b9c09EF58",
"l1Executor": "0x3ffFbAdAF827559da092217e474760E2b2c3CeDd",
"l1ProxyAdmin": "0x5613AF0474EB9c528A34701A5b1662E3C8FA0678",
"l1Timelock": "0xE6841D92B0C345144506576eC13ECf5103aC7f49",
"l1AddressRegistry": "0xd514C2b3aaBDBfa10800B9C96dc1eB25427520A0",
"l2AddressRegistry":"0x56C4E9Eb6c63aCDD19AeC2b1a00e4f0d7aBda9d3"
}
6 changes: 5 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
"gen:recipients": "ts-node ./scripts/genRecipients.ts",
"deploy:governance": "ts-node ./scripts/governanceDeployer.ts",
"deploy:note-store": "ts-node ./scripts/deployNoteStore.ts",
"deploy:vested-wallets": "ts-node ./scripts/vestedWalletsDeployer.ts",
"verify:vested-wallets": "ts-node ./scripts/vestedWalletsDeploymentVerifier.ts",
"verify:governance": "ts-node ./scripts/governanceDeploymentVerifier.ts",
"allocate:tokens": "ts-node ./scripts/tokenAllocator.ts",
"allocate:dao:tokens": "ts-node ./scripts/tokenDaoAllocator.ts",
Expand All @@ -24,12 +26,14 @@
"execute:ownership:transfer": "ts-node ./scripts/executeLocalProtocolOwnershipTransfer.ts",
"verify:ownership:transfer": "ts-node ./scripts/protocolOwnershipVerifier.ts",
"verify:contracts:etherscan": "ts-node ./scripts/verifyContractsCode.ts",
"deploy:foundation-wallet": "tsc && node ./dist/scripts/foundation-wallet-deployment/deploy.js",
"verify:foundation-wallet": "tsc && node ./dist/scripts/foundation-wallet-deployment/verifyDeployment.js",
"test:integration": "hardhat test",
"test:proposals": "ts-node ./scripts/proposalTests.ts",
"format:sol": "forge fmt"
},
"devDependencies": {
"@arbitrum/sdk": "^3.0.0",
"@arbitrum/sdk": "^3.1.6",
"@ethersproject/abi": "^5.7.0",
"@ethersproject/providers": "^5.7.2",
"@nomicfoundation/hardhat-chai-matchers": "^1.0.4",
Expand Down
Loading

0 comments on commit 00472f7

Please sign in to comment.