contract-deployments
Tool for deploying and upgrading:
- price feeds
- price feeds adapters
Initial setup
Create an .env file with PRIVATE_KEY=0x123....
line
If first deployment on new blockchain
If is not supported by https://app.safe.global
- if safe factory contracts doesn't exists then you have to first deploy factories - https://wiki.redstone.vip/docs/guidelines/gnosis-safe (then safe instance next step)
- if factories already exists you have to create safe instance with
npx hardhat create-gnosis-safe
(add it to custom-safes.json
)
- check
Upgrades without defender
section for more details
Deployment
- Create new deployment config json in
deployments
dir. (example deployments/example.json
)
- Deployment name should contain name of the network used for deployment like
voltzEthGoerli
(to distinguish contracts deployed between different networks) - For networks listed here: https://docs.gelato.network/developer-services/automate/supported-networks add
gelatoUpdaterAddress: 0xc4D1AE5E796E6d7561cdc8335F85e6B57a36e097
- Run hardhat task to generate and deploy contracts
npx hardhat --network avalanche-fuji deploy-all --name example
- Test if deployed contracts can be updated. Using local fork usage:
FORK="https://canto.slingshot.finance" npx hardhat verify-upgradability-on-fork --name cadenceCantoEth
- All contracts were deployed behind proxies.
- All contracts share common
ProxyAdmin
contract which has common owner
- There exist a common owner per network, so reuse the existing one if they exist.
Testing before upgrades
- scripts/upgrade-tests/common contains common function which can be helpful for testing upgrades
- example testing swell upgrade from V2 to V3 is in file scripts/upgrade-tests/example-with-round-adapter.ts
- each time you want to add new test you should write file like this yourself, this is very dependent on upgrade which will be done
- To run such a test:
FORK="https://eth-mainnet.public.blastapi.io" npx hardhat --network hardhat run scripts/upgrade-tests/example-with-rounds-adapter.ts
- Where FORK is rpc-url of the network which you want to fork. It is forking with latest blockNumber
- rpc-url has to support archival data
Upgrades
- Prepare new contract
- Propose upgrade using task
propose-upgrade
(example npx hardhat propose-upgrade --network avalanche-fuji --name example --initial-contract-name PriceFeedsAdapterVoltzArb --new-contract-name PriceFeedsAdapterVoltzArbProd
) - Send generated URL to owners of multisig
Note: In --no-defender You can also upgrade to concrete impl address instead of deploying new contract. This can be particularly useful, when you want rollback to previous implementation. To do that, we need to pass --new-contract-address
followed by impl address instead of --new-contract-name
. IMPORTANT: be aware that this option doesn't verify if new implementation is safe to upgrade, by verifying source code compatibility.
Verify Single Contract
- To verify single contract just run:
npx hardhat verify --network mainnet DEPLOYED_CONTRACT_ADDRESS
DEPLOYED_CONTRACT_ADDRESS
should not be proxy contract address
Verify sources
- Every time you deploy new contract or update existing you should verify sources
npx hardhat verify-sources --network avalanche --name example
Verify manually (if script doesnt work)
We cannot use hardhat commnad, we have to do this manually
- Go to https://sourcify.dev/
- Click verify contract and choose "Import from Solidity JSON"
- Select solidity version from "hardhat.config.ts" (currently "0.8.17")
- Upload JSON file from "artifacts/build-info"
- On the right section on the screen select contract which require verification f.g. MentoAdapterBaklavaV2
- Populate address with IMPLEMENTATION CONTRACT ADDRESS, not proxy contract address and choose proper chain
- Now verify proxy contract by selecting "Import from Etherscan" on https://sourcify.dev/
- Provide address one of already deployed proxy contracts f.g. "0x68ba9602B2AeE30847412109D2eE89063bf08Ec2" on ethereum mainnet
- Select "TransparentUpgradeableProxy" on the righ section
- Provide address of the REDSTONE ADAPTER and select proper chain
- Adapter contract behind proxy should be verified
Upgrades without defender
npx hardhat create-gnosis-safe --signers 0x3d62C20583AefDAe7959bad67D457e6D24d7A656, 0x2d62C20583AefDAe7959bad67D457e6D24d7A656 --threshold 1 --network mantle
npx hardhat propose-upgrade --network mantle --name mantleMnt --initial-contract-name PriceFeedsAdapterMantleMnt --new-contract-name PriceFeedsAdapterMantleMntV2 --no-defender
- The file with upgrade transaction will be created. Owners of the multi sig has to approve it as in the next step.
LEDGER=2 npx hardhat gnosis-safe-approve --file <<file_name_from_step_2_without_dir_name>> --network mantle
- It is possible to use ledger in this scenario by default using BIP44 derivation path. To use ledger device set
LEDGER
to index of your ledger account in metamask - 44'/60'/0'/0/${process.env.LEDGER}
- If enough people approved. You can approve and execute as single transaction.
LEDGER=2 npx hardhat gnosis-safe-approve --file <<file_name_from_step_2_without_dir_name>> --network mantle --execute
- IMPORTANT: even if transaction finished successfully internal transaction could have failed. Check to be sure in block explorer.
Adding new data feeds to existing adapter
- Update adapter contract, especially
getDataFeedIds
and getDataFeedIndex
functions to support new data feeds - Create and deploy new data feeds contracts
npx hardhat deploy-price-feeds-contracts --network ethereum-goerli --name example --adapter 0x3B025A4E7d442c5CAF9F25Fb9d5A66c23d07C076
, where --name
is the name from deployments
dir (example deployments/example.json
) and --adapter
is the address of already deployed adapter contract - Verify new data feeds contracts