From 5380a4c5f9ae359df00cdb8289968bb59e03f564 Mon Sep 17 00:00:00 2001 From: dmitriy-bergman-works Date: Mon, 4 Mar 2024 16:24:21 +0200 Subject: [PATCH 01/37] Add deploy script for Optimism usdc market --- .github/workflows/deploy-market.yaml | 8 +- .github/workflows/enact-migration.yaml | 12 +- .github/workflows/prepare-migration.yaml | 8 +- .github/workflows/run-contract-linter.yaml | 3 +- .github/workflows/run-coverage.yaml | 1 + .github/workflows/run-eslint.yaml | 1 + .github/workflows/run-forge-tests.yaml | 1 + .github/workflows/run-gas-profiler.yaml | 1 + .github/workflows/run-scenarios.yaml | 23 ++- .github/workflows/run-semgrep.yaml | 7 +- .github/workflows/run-unit-tests.yaml | 11 +- deployments/mainnet/usdc/relations.ts | 44 ++++-- deployments/mainnet/usdc/roots.json | 28 ++-- deployments/optimism/usdc/configuration.json | 55 +++++++ deployments/optimism/usdc/deploy.ts | 120 +++++++++++++++ deployments/optimism/usdc/relations.ts | 27 ++++ deployments/optimism/usdc/roots.json | 4 + hardhat.config.ts | 152 +++++++++++-------- plugins/import/etherscan.ts | 9 +- scenario/utils/relayMessage.ts | 11 +- 20 files changed, 412 insertions(+), 114 deletions(-) create mode 100644 deployments/optimism/usdc/configuration.json create mode 100644 deployments/optimism/usdc/deploy.ts create mode 100644 deployments/optimism/usdc/relations.ts create mode 100644 deployments/optimism/usdc/roots.json diff --git a/.github/workflows/deploy-market.yaml b/.github/workflows/deploy-market.yaml index 069e1b715..df622b837 100644 --- a/.github/workflows/deploy-market.yaml +++ b/.github/workflows/deploy-market.yaml @@ -16,6 +16,7 @@ on: - base - base-goerli - linea-goerli + - optimism deployment: description: Deployment Name (e.g. "usdc") required: true @@ -37,13 +38,14 @@ jobs: ARBISCAN_KEY: ${{ secrets.ARBISCAN_KEY }} BASESCAN_KEY: ${{ secrets.BASESCAN_KEY }} LINEASCAN_KEY: ${{ secrets.LINEASCAN_KEY }} + OPTIMISMSCAN_KEY: ${{ secrets.OPTIMISMSCAN_KEY }} steps: - name: Seacrest uses: hayesgm/seacrest@5748b3a066f517973ca2ca03d0af39bbf2b82d10 with: wallet_connect_project_id: ${{ secrets.WALLET_CONNECT_PROJECT_ID }} - requested_network: "${{ inputs.network }}" - ethereum_url: "${{ fromJSON('{\"fuji\":\"https://api.avax-test.network/ext/bc/C/rpc\",\"mainnet\":\"https://mainnet.infura.io/v3/$INFURA_KEY\",\"goerli\":\"https://goerli.infura.io/v3/$INFURA_KEY\",\"mumbai\":\"https://polygon-mumbai.infura.io/v3/$INFURA_KEY\",\"polygon\":\"https://polygon-mainnet.infura.io/v3/$INFURA_KEY\",\"arbitrum-goerli\":\"https://arbitrum-goerli.infura.io/v3/$INFURA_KEY\",\"arbitrum\":\"https://arbitrum-mainnet.infura.io/v3/$INFURA_KEY\",\"base\":\"https://clean-spring-wind.base-mainnet.discover.quiknode.pro/$QUICKNODE_KEY\",\"base-goerli\":\"https://base-goerli.infura.io/v3/$INFURA_KEY\",\"linea-goerli\":\"https://linea-goerli.infura.io/v3/$INFURA_KEY\"}')[inputs.network] }}" + requested_network: '${{ inputs.network }}' + ethereum_url: '${{ fromJSON(''{"optimism":"https://optimism-mainnet.infura.io/v3/$INFURA_KEY","fuji":"https://api.avax-test.network/ext/bc/C/rpc","mainnet":"https://mainnet.infura.io/v3/$INFURA_KEY","goerli":"https://goerli.infura.io/v3/$INFURA_KEY","mumbai":"https://polygon-mumbai.infura.io/v3/$INFURA_KEY","polygon":"https://polygon-mainnet.infura.io/v3/$INFURA_KEY","arbitrum-goerli":"https://arbitrum-goerli.infura.io/v3/$INFURA_KEY","arbitrum":"https://arbitrum-mainnet.infura.io/v3/$INFURA_KEY","base":"https://clean-spring-wind.base-mainnet.discover.quiknode.pro/$QUICKNODE_KEY","base-goerli":"https://base-goerli.infura.io/v3/$INFURA_KEY","linea-goerli":"https://linea-goerli.infura.io/v3/$INFURA_KEY"}'')[inputs.network] }}' port: 8585 if: github.event.inputs.eth_pk == '' @@ -68,7 +70,7 @@ jobs: yarn hardhat deploy --network ${{ github.event.inputs.network }} --deployment ${{ github.event.inputs.deployment }} ${{ fromJSON('["", "--simulate"]')[github.event.inputs.simulate == 'true'] }} env: DEBUG: true - ETH_PK: "${{ inputs.eth_pk }}" + ETH_PK: '${{ inputs.eth_pk }}' NETWORK_PROVIDER: ${{ fromJSON('["", "http://localhost:8585"]')[github.event.inputs.eth_pk == ''] }} REMOTE_ACCOUNTS: ${{ fromJSON('["", "true"]')[github.event.inputs.eth_pk == ''] }} diff --git a/.github/workflows/enact-migration.yaml b/.github/workflows/enact-migration.yaml index 0eee030db..08648dbf1 100644 --- a/.github/workflows/enact-migration.yaml +++ b/.github/workflows/enact-migration.yaml @@ -16,6 +16,7 @@ on: - base - base-goerli - linea-goerli + - optimism deployment: description: Deployment Name (e.g. "usdc") required: true @@ -45,6 +46,7 @@ jobs: ARBISCAN_KEY: ${{ secrets.ARBISCAN_KEY }} BASESCAN_KEY: ${{ secrets.BASESCAN_KEY }} LINEASCAN_KEY: ${{ secrets.LINEASCAN_KEY }} + OPTIMISMSCAN_KEY: ${{ secrets.OPTIMISMSCAN_KEY }} steps: - name: Get governance network run: | @@ -61,8 +63,8 @@ jobs: uses: hayesgm/seacrest@5748b3a066f517973ca2ca03d0af39bbf2b82d10 with: wallet_connect_project_id: ${{ secrets.WALLET_CONNECT_PROJECT_ID }} - requested_network: "${{ inputs.network }}" - ethereum_url: "${{ fromJSON('{\"fuji\":\"https://api.avax-test.network/ext/bc/C/rpc\",\"mainnet\":\"https://mainnet.infura.io/v3/$INFURA_KEY\",\"goerli\":\"https://goerli.infura.io/v3/$INFURA_KEY\",\"mumbai\":\"https://polygon-mumbai.infura.io/v3/$INFURA_KEY\",\"polygon\":\"https://polygon-mainnet.infura.io/v3/$INFURA_KEY\",\"arbitrum-goerli\":\"https://arbitrum-goerli.infura.io/v3/$INFURA_KEY\",\"arbitrum\":\"https://arbitrum-mainnet.infura.io/v3/$INFURA_KEY\",\"base\":\"https://clean-spring-wind.base-mainnet.discover.quiknode.pro/$QUICKNODE_KEY\",\"base-goerli\":\"https://base-goerli.infura.io/v3/$INFURA_KEY\",\"linea-goerli\":\"https://linea-goerli.infura.io/v3/$INFURA_KEY\"}')[inputs.network] }}" + requested_network: '${{ inputs.network }}' + ethereum_url: '${{ fromJSON(''{"optimism":"https://optimism-mainnet.infura.io/v3/$INFURA_KEY","fuji":"https://api.avax-test.network/ext/bc/C/rpc","mainnet":"https://mainnet.infura.io/v3/$INFURA_KEY","goerli":"https://goerli.infura.io/v3/$INFURA_KEY","mumbai":"https://polygon-mumbai.infura.io/v3/$INFURA_KEY","polygon":"https://polygon-mainnet.infura.io/v3/$INFURA_KEY","arbitrum-goerli":"https://arbitrum-goerli.infura.io/v3/$INFURA_KEY","arbitrum":"https://arbitrum-mainnet.infura.io/v3/$INFURA_KEY","base":"https://clean-spring-wind.base-mainnet.discover.quiknode.pro/$QUICKNODE_KEY","base-goerli":"https://base-goerli.infura.io/v3/$INFURA_KEY","linea-goerli":"https://linea-goerli.infura.io/v3/$INFURA_KEY"}'')[inputs.network] }}' port: 8585 if: github.event.inputs.eth_pk == '' @@ -70,8 +72,8 @@ jobs: uses: hayesgm/seacrest@5748b3a066f517973ca2ca03d0af39bbf2b82d10 with: wallet_connect_project_id: ${{ secrets.WALLET_CONNECT_PROJECT_ID }} - requested_network: "${{ env.GOV_NETWORK }}" - ethereum_url: "${{ fromJSON('{\"fuji\":\"https://api.avax-test.network/ext/bc/C/rpc\",\"mainnet\":\"https://mainnet.infura.io/v3/$INFURA_KEY\",\"goerli\":\"https://goerli.infura.io/v3/$INFURA_KEY\",\"mumbai\":\"https://polygon-mumbai.infura.io/v3/$INFURA_KEY\",\"polygon\":\"https://polygon-mainnet.infura.io/v3/$INFURA_KEY\",\"arbitrum-goerli\":\"https://arbitrum-goerli.infura.io/v3/$INFURA_KEY\",\"arbitrum\":\"https://arbitrum-mainnet.infura.io/v3/$INFURA_KEY\"}')[env.GOV_NETWORK] }}" + requested_network: '${{ env.GOV_NETWORK }}' + ethereum_url: '${{ fromJSON(''{"optimism":"https://optimism-mainnet.infura.io/v3/$INFURA_KEY","fuji":"https://api.avax-test.network/ext/bc/C/rpc","mainnet":"https://mainnet.infura.io/v3/$INFURA_KEY","goerli":"https://goerli.infura.io/v3/$INFURA_KEY","mumbai":"https://polygon-mumbai.infura.io/v3/$INFURA_KEY","polygon":"https://polygon-mainnet.infura.io/v3/$INFURA_KEY","arbitrum-goerli":"https://arbitrum-goerli.infura.io/v3/$INFURA_KEY","arbitrum":"https://arbitrum-mainnet.infura.io/v3/$INFURA_KEY"}'')[env.GOV_NETWORK] }}' port: 8685 if: github.event.inputs.eth_pk == '' && env.GOV_NETWORK != '' @@ -104,7 +106,7 @@ jobs: yarn hardhat migrate --network ${{ github.event.inputs.network }} --deployment ${{ github.event.inputs.deployment }} --enact --overwrite ${{ fromJSON('["", "--simulate"]')[github.event.inputs.simulate == 'true'] }} ${{ fromJSON('["", "--no-enacted"]')[github.event.inputs.no_enacted == 'true'] }} ${{ github.event.inputs.migration }} env: DEBUG: true - ETH_PK: "${{ inputs.eth_pk }}" + ETH_PK: '${{ inputs.eth_pk }}' NETWORK_PROVIDER: ${{ fromJSON('["", "http://localhost:8585"]')[github.event.inputs.eth_pk == ''] }} GOV_NETWORK_PROVIDER: ${{ fromJSON('["", "http://localhost:8685"]')[github.event.inputs.eth_pk == '' && env.GOV_NETWORK != ''] }} GOV_NETWORK: ${{ env.GOV_NETWORK }} diff --git a/.github/workflows/prepare-migration.yaml b/.github/workflows/prepare-migration.yaml index b47bc6921..074fa986a 100644 --- a/.github/workflows/prepare-migration.yaml +++ b/.github/workflows/prepare-migration.yaml @@ -15,6 +15,7 @@ on: - arbitrum-goerli - base - base-goerli + - optimism deployment: description: Deployment Name (e.g. "usdc") required: true @@ -39,13 +40,14 @@ jobs: ARBISCAN_KEY: ${{ secrets.ARBISCAN_KEY }} BASESCAN_KEY: ${{ secrets.BASESCAN_KEY }} LINEASCAN_KEY: ${{ secrets.LINEASCAN_KEY }} + OPTIMISMSCAN_KEY: ${{ secrets.OPTIMISMSCAN_KEY }} steps: - name: Seacrest uses: hayesgm/seacrest@5748b3a066f517973ca2ca03d0af39bbf2b82d10 with: wallet_connect_project_id: ${{ secrets.WALLET_CONNECT_PROJECT_ID }} - requested_network: "${{ inputs.network }}" - ethereum_url: "${{ fromJSON('{\"fuji\":\"https://api.avax-test.network/ext/bc/C/rpc\",\"mainnet\":\"https://mainnet.infura.io/v3/$INFURA_KEY\",\"goerli\":\"https://goerli.infura.io/v3/$INFURA_KEY\",\"mumbai\":\"https://polygon-mumbai.infura.io/v3/$INFURA_KEY\",\"polygon\":\"https://polygon-mainnet.infura.io/v3/$INFURA_KEY\",\"arbitrum-goerli\":\"https://arbitrum-goerli.infura.io/v3/$INFURA_KEY\",\"arbitrum\":\"https://arbitrum-mainnet.infura.io/v3/$INFURA_KEY\",\"base\":\"https://clean-spring-wind.base-mainnet.discover.quiknode.pro/$QUICKNODE_KEY\",\"base-goerli\":\"https://base-goerli.infura.io/v3/$INFURA_KEY\",\"linea-goerli\":\"https://linea-goerli.infura.io/v3/$INFURA_KEY\"}')[inputs.network] }}" + requested_network: '${{ inputs.network }}' + ethereum_url: '${{ fromJSON(''{"optimism":"https://optimism-mainnet.infura.io/v3/$INFURA_KEY","fuji":"https://api.avax-test.network/ext/bc/C/rpc","mainnet":"https://mainnet.infura.io/v3/$INFURA_KEY","goerli":"https://goerli.infura.io/v3/$INFURA_KEY","mumbai":"https://polygon-mumbai.infura.io/v3/$INFURA_KEY","polygon":"https://polygon-mainnet.infura.io/v3/$INFURA_KEY","arbitrum-goerli":"https://arbitrum-goerli.infura.io/v3/$INFURA_KEY","arbitrum":"https://arbitrum-mainnet.infura.io/v3/$INFURA_KEY","base":"https://clean-spring-wind.base-mainnet.discover.quiknode.pro/$QUICKNODE_KEY","base-goerli":"https://base-goerli.infura.io/v3/$INFURA_KEY","linea-goerli":"https://linea-goerli.infura.io/v3/$INFURA_KEY"}'')[inputs.network] }}' port: 8585 if: github.event.inputs.eth_pk == '' @@ -70,7 +72,7 @@ jobs: yarn hardhat migrate --network ${{ github.event.inputs.network }} --deployment ${{ github.event.inputs.deployment }} --prepare --overwrite ${{ fromJSON('["", "--simulate"]')[github.event.inputs.simulate == 'true'] }} ${{ github.event.inputs.migration }} env: DEBUG: true - ETH_PK: "${{ inputs.eth_pk }}" + ETH_PK: '${{ inputs.eth_pk }}' NETWORK_PROVIDER: ${{ fromJSON('["", "http://localhost:8585"]')[github.event.inputs.eth_pk == ''] }} REMOTE_ACCOUNTS: ${{ fromJSON('["", "true"]')[github.event.inputs.eth_pk == ''] }} diff --git a/.github/workflows/run-contract-linter.yaml b/.github/workflows/run-contract-linter.yaml index 04bc045d6..b027b58fb 100644 --- a/.github/workflows/run-contract-linter.yaml +++ b/.github/workflows/run-contract-linter.yaml @@ -13,6 +13,7 @@ jobs: POLYGONSCAN_KEY: ${{ secrets.POLYGONSCAN_KEY }} ARBISCAN_KEY: ${{ secrets.ARBISCAN_KEY }} LINEASCAN_KEY: ${{ secrets.LINEASCAN_KEY }} + OPTIMISMSCAN_KEY: ${{ secrets.OPTIMISMSCAN_KEY }} steps: - uses: actions/checkout@v2 with: @@ -26,4 +27,4 @@ jobs: run: yarn install --non-interactive --frozen-lockfile && yarn build - name: Run linter on modified contracts - run: git diff --name-only --diff-filter=ACMRT ${{ github.event.pull_request.base.sha }} ${{ github.sha }} | grep ^contracts/ | xargs yarn solhint \ No newline at end of file + run: git diff --name-only --diff-filter=ACMRT ${{ github.event.pull_request.base.sha }} ${{ github.sha }} | grep ^contracts/ | xargs yarn solhint diff --git a/.github/workflows/run-coverage.yaml b/.github/workflows/run-coverage.yaml index 559dd12cc..e2272a9d5 100644 --- a/.github/workflows/run-coverage.yaml +++ b/.github/workflows/run-coverage.yaml @@ -15,6 +15,7 @@ jobs: POLYGONSCAN_KEY: ${{ secrets.POLYGONSCAN_KEY }} ARBISCAN_KEY: ${{ secrets.ARBISCAN_KEY }} LINEASCAN_KEY: ${{ secrets.LINEASCAN_KEY }} + OPTIMISMSCAN_KEY: ${{ secrets.OPTIMISMSCAN_KEY }} steps: - name: Checkout repository uses: actions/checkout@v2 diff --git a/.github/workflows/run-eslint.yaml b/.github/workflows/run-eslint.yaml index ade6bf2f4..9763d45d4 100644 --- a/.github/workflows/run-eslint.yaml +++ b/.github/workflows/run-eslint.yaml @@ -13,6 +13,7 @@ jobs: POLYGONSCAN_KEY: ${{ secrets.POLYGONSCAN_KEY }} ARBISCAN_KEY: ${{ secrets.ARBISCAN_KEY }} LINEASCAN_KEY: ${{ secrets.LINEASCAN_KEY }} + OPTIMISMSCAN_KEY: ${{ secrets.OPTIMISMSCAN_KEY }} steps: - name: Checkout repository uses: actions/checkout@v2 diff --git a/.github/workflows/run-forge-tests.yaml b/.github/workflows/run-forge-tests.yaml index 5d343299c..069a30bdb 100644 --- a/.github/workflows/run-forge-tests.yaml +++ b/.github/workflows/run-forge-tests.yaml @@ -29,6 +29,7 @@ jobs: POLYGONSCAN_KEY: ${{ secrets.POLYGONSCAN_KEY }} ARBISCAN_KEY: ${{ secrets.ARBISCAN_KEY }} LINEASCAN_KEY: ${{ secrets.LINEASCAN_KEY }} + OPTIMISMSCAN_KEY: ${{ secrets.OPTIMISMSCAN_KEY }} - name: Build Comet with older solc versions run: | diff --git a/.github/workflows/run-gas-profiler.yaml b/.github/workflows/run-gas-profiler.yaml index 668376d9b..d2418ad42 100644 --- a/.github/workflows/run-gas-profiler.yaml +++ b/.github/workflows/run-gas-profiler.yaml @@ -14,6 +14,7 @@ jobs: POLYGONSCAN_KEY: ${{ secrets.POLYGONSCAN_KEY }} ARBISCAN_KEY: ${{ secrets.ARBISCAN_KEY }} LINEASCAN_KEY: ${{ secrets.LINEASCAN_KEY }} + OPTIMISMSCAN_KEY: ${{ secrets.OPTIMISMSCAN_KEY }} steps: - name: Checkout repository uses: actions/checkout@v2 diff --git a/.github/workflows/run-scenarios.yaml b/.github/workflows/run-scenarios.yaml index fe2eb0111..7ea0411b3 100644 --- a/.github/workflows/run-scenarios.yaml +++ b/.github/workflows/run-scenarios.yaml @@ -7,7 +7,27 @@ jobs: strategy: fail-fast: false matrix: - bases: [ development, mainnet, mainnet-weth, goerli, goerli-weth, fuji, mumbai, polygon, arbitrum-usdc.e, arbitrum-usdc, arbitrum-goerli-usdc, arbitrum-goerli-usdc.e, base-usdbc, base-weth, base-goerli, base-goerli-weth, linea-goerli] + bases: + [ + development, + mainnet, + mainnet-weth, + goerli, + goerli-weth, + fuji, + mumbai, + polygon, + arbitrum-usdc.e, + arbitrum-usdc, + arbitrum-goerli-usdc, + arbitrum-goerli-usdc.e, + base-usdbc, + base-weth, + base-goerli, + base-goerli-weth, + linea-goerli, + optimism-usdc, + ] name: Run scenarios env: ETHERSCAN_KEY: ${{ secrets.ETHERSCAN_KEY }} @@ -18,6 +38,7 @@ jobs: ARBISCAN_KEY: ${{ secrets.ARBISCAN_KEY }} BASESCAN_KEY: ${{ secrets.BASESCAN_KEY }} LINEASCAN_KEY: ${{ secrets.LINEASCAN_KEY }} + OPTIMISMSCAN_KEY: ${{ secrets.OPTIMISMSCAN_KEY }} runs-on: ubuntu-latest steps: - name: Checkout repository diff --git a/.github/workflows/run-semgrep.yaml b/.github/workflows/run-semgrep.yaml index 0f752f1f2..dad4eb51a 100644 --- a/.github/workflows/run-semgrep.yaml +++ b/.github/workflows/run-semgrep.yaml @@ -4,20 +4,21 @@ name: Run Semgrep on: # Scan changed files in PRs (diff-aware scanning): pull_request: {} - # On-demand + # On-demand workflow_dispatch: {} jobs: semgrep: # User-definable name of this GitHub Actions job: name: Scan - # If you are self-hosting, change the following `runs-on` value: + # If you are self-hosting, change the following `runs-on` value: runs-on: ubuntu-latest env: ETHERSCAN_KEY: ${{ secrets.ETHERSCAN_KEY }} SNOWTRACE_KEY: ${{ secrets.SNOWTRACE_KEY }} INFURA_KEY: ${{ secrets.INFURA_KEY }} POLYGONSCAN_KEY: ${{ secrets.POLYGONSCAN_KEY }} + OPTIMISMSCAN_KEY: ${{ secrets.OPTIMISMSCAN_KEY }} container: # A Docker image with Semgrep installed. Do not change this. image: returntocorp/semgrep @@ -43,7 +44,7 @@ jobs: # Run security, performance & Compound specific rules - run: semgrep ci --sarif --output=semgrep.sarif || true env: - SEMGREP_RULES: rules/solidity/security rules/solidity/performance compound/solidity + SEMGREP_RULES: rules/solidity/security rules/solidity/performance compound/solidity # Upload findings to GitHub Advanced Security Dashboard - name: Upload findings to GitHub Advanced Security Dashboard uses: github/codeql-action/upload-sarif@v2 diff --git a/.github/workflows/run-unit-tests.yaml b/.github/workflows/run-unit-tests.yaml index 11ebffc85..3ad9127d9 100644 --- a/.github/workflows/run-unit-tests.yaml +++ b/.github/workflows/run-unit-tests.yaml @@ -13,6 +13,7 @@ jobs: POLYGONSCAN_KEY: ${{ secrets.POLYGONSCAN_KEY }} ARBISCAN_KEY: ${{ secrets.ARBISCAN_KEY }} LINEASCAN_KEY: ${{ secrets.LINEASCAN_KEY }} + OPTIMISMSCAN_KEY: ${{ secrets.OPTIMISMSCAN_KEY }} steps: - name: Checkout repository uses: actions/checkout@v2 @@ -33,14 +34,14 @@ jobs: - name: Run tests run: yarn test - - uses: actions/upload-artifact@v2 # upload test results - if: success() || failure() # run this step even if previous step failed + - uses: actions/upload-artifact@v2 # upload test results + if: success() || failure() # run this step even if previous step failed with: name: test-results path: test-results.json - uses: dorny/test-reporter@v1 with: - name: Unit Tests # Name of the check run which will be created - path: 'test-results.json' # Path to test results (inside artifact .zip) - reporter: mocha-json # Format of test results + name: Unit Tests # Name of the check run which will be created + path: 'test-results.json' # Path to test results (inside artifact .zip) + reporter: mocha-json # Format of test results diff --git a/deployments/mainnet/usdc/relations.ts b/deployments/mainnet/usdc/relations.ts index a076adcaa..7ea556220 100644 --- a/deployments/mainnet/usdc/relations.ts +++ b/deployments/mainnet/usdc/relations.ts @@ -6,27 +6,29 @@ export default { fxRoot: { relations: { stateSender: { - field: async (fxRoot) => fxRoot.stateSender() - } - } + field: async (fxRoot) => fxRoot.stateSender(), + }, + }, }, arbitrumInbox: { delegates: { field: { - slot: '0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc', + slot: + '0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc', }, }, relations: { arbitrumBridge: { - field: async (inbox) => inbox.bridge() - } - } + field: async (inbox) => inbox.bridge(), + }, + }, }, arbitrumL1GatewayRouter: { delegates: { field: { - slot: '0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc', - } + slot: + '0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc', + }, }, }, baseL1CrossDomainMessenger: { @@ -38,8 +40,22 @@ export default { baseL1StandardBridge: { delegates: { field: { - slot: '0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc' - } - } - } -}; \ No newline at end of file + slot: + '0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc', + }, + }, + }, + opL1CrossDomainMessenger: { + delegates: { + field: async () => '0x2150Bc3c64cbfDDbaC9815EF615D6AB8671bfe43', + }, + }, + opL1StandardBridge: { + delegates: { + field: { + slot: + '0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc', + }, + }, + }, +}; diff --git a/deployments/mainnet/usdc/roots.json b/deployments/mainnet/usdc/roots.json index 0aa64b6cc..a785b2465 100644 --- a/deployments/mainnet/usdc/roots.json +++ b/deployments/mainnet/usdc/roots.json @@ -1,14 +1,16 @@ { - "comptrollerV2": "0x3d9819210a31b4961b30ef54be2aed79b9c9cd3b", - "comet": "0xc3d688B66703497DAA19211EEdff47f25384cdc3", - "configurator": "0x316f9708bB98af7dA9c68C1C3b5e79039cD336E3", - "rewards": "0x1B0e765F6224C21223AeA2af16c1C46E38885a40", - "bulker": "0xa397a8C2086C554B531c02E29f3291c9704B00c7", - "fxRoot": "0xfe5e5D361b2ad62c541bAb87C45a0B9B018389a2", - "arbitrumInbox": "0x4Dbd4fc535Ac27206064B68FfCf827b0A60BAB3f", - "arbitrumL1GatewayRouter": "0x72Ce9c846789fdB6fC1f34aC4AD25Dd9ef7031ef", - "CCTPTokenMessenger": "0xbd3fa81b58ba92a82136038b25adec7066af3155", - "CCTPMessageTransmitter": "0x0a992d191deec32afe36203ad87d7d289a738f81", - "baseL1CrossDomainMessenger": "0x866E82a600A1414e583f7F13623F1aC5d58b0Afa", - "baseL1StandardBridge": "0x3154Cf16ccdb4C6d922629664174b904d80F2C35" -} \ No newline at end of file + "comptrollerV2": "0x3d9819210a31b4961b30ef54be2aed79b9c9cd3b", + "comet": "0xc3d688B66703497DAA19211EEdff47f25384cdc3", + "configurator": "0x316f9708bB98af7dA9c68C1C3b5e79039cD336E3", + "rewards": "0x1B0e765F6224C21223AeA2af16c1C46E38885a40", + "bulker": "0xa397a8C2086C554B531c02E29f3291c9704B00c7", + "fxRoot": "0xfe5e5D361b2ad62c541bAb87C45a0B9B018389a2", + "arbitrumInbox": "0x4Dbd4fc535Ac27206064B68FfCf827b0A60BAB3f", + "arbitrumL1GatewayRouter": "0x72Ce9c846789fdB6fC1f34aC4AD25Dd9ef7031ef", + "CCTPTokenMessenger": "0xbd3fa81b58ba92a82136038b25adec7066af3155", + "CCTPMessageTransmitter": "0x0a992d191deec32afe36203ad87d7d289a738f81", + "baseL1CrossDomainMessenger": "0x866E82a600A1414e583f7F13623F1aC5d58b0Afa", + "baseL1StandardBridge": "0x3154Cf16ccdb4C6d922629664174b904d80F2C35", + "opL1CrossDomainMessenger": "0x25ace71c97B33Cc4729CF772ae268934F7ab5fA1", + "opL1StandardBridge": "0x99C9fc46f92E8a1c0deC1b1747d010903E884bE1" +} diff --git a/deployments/optimism/usdc/configuration.json b/deployments/optimism/usdc/configuration.json new file mode 100644 index 000000000..4f61c0000 --- /dev/null +++ b/deployments/optimism/usdc/configuration.json @@ -0,0 +1,55 @@ +{ + "name": "Compound USDC", + "symbol": "cUSDCv3", + "baseToken": "USDC", + "baseTokenAddress": "0x0b2C639c533813f4Aa9D7837CAf62653d097Ff85", + "baseTokenPriceFeed": "0x16a9FA2FDa030272Ce99B29CF780dFA30361E0f3", + "borrowMin": "1e6", + "storeFrontPriceFactor": 0.5, + "targetReserves": "1000000e6", + "rates": { + "supplyKink": 0.8, + "supplySlopeLow": 0.0325, + "supplySlopeHigh": 0.4, + "supplyBase": 0, + "borrowKink": 0.8, + "borrowSlopeLow": 0.035, + "borrowSlopeHigh": 0.25, + "borrowBase": 0.015 + }, + "tracking": { + "indexScale": "1e15", + "baseSupplySpeed": "0.000402083333333e15", + "baseBorrowSpeed": "0.000402083333333e15", + "baseMinForRewards": "10000e6" + }, + "assets": { + "WETH": { + "address": "0x4200000000000000000000000000000000000006", + "priceFeed": "0x13e3Ee699D1909E989722E753853AE30b17e08c5", + "decimals": "18", + "borrowCF": 0.75, + "liquidateCF": 0.8, + "liquidationFactor": 0.93, + "supplyCap": "800e18" + }, + "WBTC": { + "address": "0x68f180fcCe6836688e9084f035309E29Bf0A2095", + "priceFeed": "0xD702DD976Fb76Fffc2D3963D037dfDae5b04E593", + "decimals": "8", + "borrowCF": 0.7, + "liquidateCF": 0.77, + "liquidationFactor": 0.95, + "supplyCap": "0e8" + }, + "OP": { + "address": "0x4200000000000000000000000000000000000042", + "priceFeed": "0x0D276FC14719f9292D5C1eA2198673d1f4269246", + "decimals": "18", + "borrowCF": 0.75, + "liquidateCF": 0.8, + "liquidationFactor": 0.93, + "supplyCap": "800e18" + } + } +} diff --git a/deployments/optimism/usdc/deploy.ts b/deployments/optimism/usdc/deploy.ts new file mode 100644 index 000000000..a78ded852 --- /dev/null +++ b/deployments/optimism/usdc/deploy.ts @@ -0,0 +1,120 @@ +import { + Deployed, + DeploymentManager, +} from '../../../plugins/deployment_manager'; +import { DeploySpec, deployComet } from '../../../src/deploy'; + +const HOUR = 60 * 60; +const DAY = 24 * HOUR; + +const MAINNET_TIMELOCK = '0x6d903f6003cca6255d85cca4d3b5e5146dc33925'; + +export default async function deploy( + deploymentManager: DeploymentManager, + deploySpec: DeploySpec +): Promise { + const deployed = await deployContracts(deploymentManager, deploySpec); + return deployed; +} + +async function deployContracts( + deploymentManager: DeploymentManager, + deploySpec: DeploySpec +): Promise { + const trace = deploymentManager.tracer(); + + // Pull in existing assets + const USDC = await deploymentManager.existing( + 'USDC', + '0x0b2C639c533813f4Aa9D7837CAf62653d097Ff85', + 'optimism' + ); + const WETH = await deploymentManager.existing( + 'WETH', + '0x4200000000000000000000000000000000000006', + 'optimism' + ); + const WBTC = await deploymentManager.existing( + 'WBTC', + '0x68f180fcCe6836688e9084f035309E29Bf0A2095', + 'optimism' + ); + const OP = await deploymentManager.existing( + 'OP', + '0x4200000000000000000000000000000000000042', + 'optimism' + ); + + const l2CrossDomainMessenger = await deploymentManager.existing( + 'l2CrossDomainMessenger', + [ + '0xC0d3c0d3c0D3c0D3C0d3C0D3C0D3c0d3c0d30007', + '0x4200000000000000000000000000000000000007', + ], + 'optimism' + ); + + const l2StandardBridge = await deploymentManager.existing( + 'l2StandardBridge', + [ + '0xC0d3c0d3c0D3c0d3C0D3c0D3C0d3C0D3C0D30010', + '0x4200000000000000000000000000000000000010', + ], + 'optimism' + ); + + // Deploy OptimismBridgeReceiver + const bridgeReceiver = await deploymentManager.deploy( + 'bridgeReceiver', + 'bridges/optimism/OptimismBridgeReceiver.sol', + [l2CrossDomainMessenger.address] + ); + + // Deploy Local Timelock + const localTimelock = await deploymentManager.deploy( + 'timelock', + 'vendor/Timelock.sol', + [ + bridgeReceiver.address, // admin + 1 * DAY, // delay + 14 * DAY, // grace period + 12 * HOUR, // minimum delay + 30 * DAY, // maxiumum delay + ] + ); + + // Initialize OptimismBridgeReceiver + await deploymentManager.idempotent( + async () => !(await bridgeReceiver.initialized()), + async () => { + trace(`Initializing BridgeReceiver`); + await bridgeReceiver.initialize( + MAINNET_TIMELOCK, // govTimelock + localTimelock.address // localTimelock + ); + trace(`BridgeReceiver initialized`); + } + ); + + // Deploy Comet + const deployed = await deployComet(deploymentManager, deploySpec); + const { comet } = deployed; + + // Deploy Bulker + const bulker = await deploymentManager.deploy( + 'bulker', + 'bulkers/BaseBulker.sol', + [ + await comet.governor(), // admin + WETH.address, // weth + ] + ); + + return { + ...deployed, + bridgeReceiver, + l2CrossDomainMessenger, // TODO: don't have to part of roots. can be pulled via relations + l2StandardBridge, + bulker, + }; +} diff --git a/deployments/optimism/usdc/relations.ts b/deployments/optimism/usdc/relations.ts new file mode 100644 index 000000000..82f918493 --- /dev/null +++ b/deployments/optimism/usdc/relations.ts @@ -0,0 +1,27 @@ +import baseRelationConfig from '../../relations'; + +export default { + ...baseRelationConfig, + governor: { + artifact: + 'contracts/bridges/optimism/OptimismBridgeReceiver.sol:OptimismBridgeReceiver', + }, + + l2CrossDomainMessenger: { + delegates: { + field: { + slot: + '0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc', + }, + }, + }, + + l2StandardBridge: { + delegates: { + field: { + slot: + '0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc', + }, + }, + }, +}; diff --git a/deployments/optimism/usdc/roots.json b/deployments/optimism/usdc/roots.json new file mode 100644 index 000000000..216adbd8f --- /dev/null +++ b/deployments/optimism/usdc/roots.json @@ -0,0 +1,4 @@ +{ + "l2CrossDomainMessenger": "0x4200000000000000000000000000000000000007", + "l2StandardBridge": "0x4200000000000000000000000000000000000010" +} diff --git a/hardhat.config.ts b/hardhat.config.ts index c38d1b4e1..f41205f57 100644 --- a/hardhat.config.ts +++ b/hardhat.config.ts @@ -33,10 +33,11 @@ import baseWethRelationConfigMap from './deployments/base/weth/relations'; import baseGoerliRelationConfigMap from './deployments/base-goerli/usdc/relations'; import baseGoerliWethRelationConfigMap from './deployments/base-goerli/weth/relations'; import lineaGoerliRelationConfigMap from './deployments/linea-goerli/usdc/relations'; - +import optimismRelationConfigMap from './deployments/optimism/usdc/relations'; task('accounts', 'Prints the list of accounts', async (taskArgs, hre) => { - for (const account of await hre.ethers.getSigners()) console.log(account.address); + for (const account of await hre.ethers.getSigners()) + console.log(account.address); }); /* note: boolean environment variables are imported as strings */ @@ -49,6 +50,7 @@ const { ARBISCAN_KEY, BASESCAN_KEY, LINEASCAN_KEY, + OPTIMISMSCAN_KEY, INFURA_KEY, QUICKNODE_KEY, MNEMONIC = 'myth like bonus scare over problem client lizard pioneer submit female collect', @@ -56,10 +58,10 @@ const { NETWORK_PROVIDER = '', GOV_NETWORK_PROVIDER = '', GOV_NETWORK = '', - REMOTE_ACCOUNTS = '' + REMOTE_ACCOUNTS = '', } = process.env; -function *deriveAccounts(pk: string, n: number = 10) { +function* deriveAccounts(pk: string, n: number = 10) { for (let i = 0; i < n; i++) yield (BigInt('0x' + pk) + BigInt(i)).toString(16); } @@ -67,7 +69,9 @@ function *deriveAccounts(pk: string, n: number = 10) { export function requireEnv(varName, msg?: string): string { const varVal = process.env[varName]; if (!varVal) { - throw new Error(msg ?? `Missing required environment variable '${varName}'`); + throw new Error( + msg ?? `Missing required environment variable '${varName}'` + ); } return varVal; } @@ -79,8 +83,9 @@ export function requireEnv(varName, msg?: string): string { 'INFURA_KEY', 'POLYGONSCAN_KEY', 'ARBISCAN_KEY', - 'LINEASCAN_KEY' -].map(v => requireEnv(v)); + 'LINEASCAN_KEY', + 'OPTIMISMSCAN_KEY', +].map((v) => requireEnv(v)); // Networks interface NetworkConfig { @@ -101,6 +106,11 @@ const networkConfigs: NetworkConfig[] = [ chainId: 137, url: `https://polygon-mainnet.infura.io/v3/${INFURA_KEY}`, }, + { + network: 'optimism', + chainId: 10, + url: `https://optimism-mainnet.infura.io/v3/${INFURA_KEY}`, + }, { network: 'base', chainId: 8453, @@ -152,13 +162,19 @@ function setupDefaultNetworkProviders(hardhatConfig: HardhatUserConfig) { hardhatConfig.networks[netConfig.network] = { chainId: netConfig.chainId, url: - (netConfig.network === GOV_NETWORK ? GOV_NETWORK_PROVIDER : undefined) || + (netConfig.network === GOV_NETWORK + ? GOV_NETWORK_PROVIDER + : undefined) || NETWORK_PROVIDER || netConfig.url || getDefaultProviderURL(netConfig.network), gas: netConfig.gas || 'auto', gasPrice: netConfig.gasPrice || 'auto', - accounts: REMOTE_ACCOUNTS ? 'remote' : ( ETH_PK ? [...deriveAccounts(ETH_PK)] : { mnemonic: MNEMONIC } ), + accounts: REMOTE_ACCOUNTS + ? 'remote' + : ETH_PK + ? [...deriveAccounts(ETH_PK)] + : { mnemonic: MNEMONIC }, }; } } @@ -170,20 +186,21 @@ const config: HardhatUserConfig = { solidity: { version: '0.8.15', settings: { - optimizer: ( - process.env['OPTIMIZER_DISABLED'] ? { enabled: false } : { - enabled: true, - runs: 1, - details: { - yulDetails: { - optimizerSteps: 'dhfoDgvulfnTUtnIf [xa[r]scLM cCTUtTOntnfDIul Lcul Vcul [j] Tpeul xa[rul] xa[r]cL gvif CTUca[r]LsTOtfDnca[r]Iulc] jmul[jul] VcTOcul jmul' + optimizer: process.env['OPTIMIZER_DISABLED'] + ? { enabled: false } + : { + enabled: true, + runs: 1, + details: { + yulDetails: { + optimizerSteps: + 'dhfoDgvulfnTUtnIf [xa[r]scLM cCTUtTOntnfDIul Lcul Vcul [j] Tpeul xa[rul] xa[r]cL gvif CTUca[r]LsTOtfDnca[r]Iulc] jmul[jul] VcTOcul jmul', + }, }, }, - } - ), outputSelection: { '*': { - '*': ['evm.deployedBytecode.sourceMap'] + '*': ['evm.deployedBytecode.sourceMap'], }, }, viaIR: process.env['OPTIMIZER_DISABLED'] ? false : true, @@ -197,12 +214,15 @@ const config: HardhatUserConfig = { gas: 12000000, gasPrice: 'auto', blockGasLimit: 12000000, - accounts: ETH_PK ? - [...deriveAccounts(ETH_PK)].map(privateKey => ({ privateKey, balance: (10n ** 36n).toString() })) + accounts: ETH_PK + ? [...deriveAccounts(ETH_PK)].map((privateKey) => ({ + privateKey, + balance: (10n ** 36n).toString(), + })) : { mnemonic: MNEMONIC, accountsBalance: (10n ** 36n).toString() }, // this should only be relied upon for test harnesses and coverage (which does not use viaIR flag) allowUnlimitedContractSize: true, - hardfork: 'shanghai' + hardfork: 'shanghai', }, }, @@ -230,6 +250,7 @@ const config: HardhatUserConfig = { 'base-goerli': BASESCAN_KEY, // Linea 'linea-goerli': LINEASCAN_KEY, + optimism: OPTIMISMSCAN_KEY, }, customChains: [ { @@ -238,8 +259,8 @@ const config: HardhatUserConfig = { chainId: 42161, urls: { apiURL: 'https://api.arbiscan.io/api', - browserURL: 'https://arbiscan.io/' - } + browserURL: 'https://arbiscan.io/', + }, }, { // Hardhat's Etherscan plugin calls the network `arbitrumGoerli`, so we need to add an entry for our own network name @@ -247,8 +268,8 @@ const config: HardhatUserConfig = { chainId: 421613, urls: { apiURL: 'https://api-goerli.arbiscan.io/api', - browserURL: 'https://goerli.arbiscan.io/' - } + browserURL: 'https://goerli.arbiscan.io/', + }, }, { // Hardhat's Etherscan plugin doesn't have support Base, so we need to add an entry for our own network name @@ -256,8 +277,8 @@ const config: HardhatUserConfig = { chainId: 8453, urls: { apiURL: 'https://api.basescan.org/api', - browserURL: 'https://basescan.org/' - } + browserURL: 'https://basescan.org/', + }, }, { // Hardhat's Etherscan plugin calls the network `baseGoerli`, so we need to add an entry for our own network name @@ -265,18 +286,18 @@ const config: HardhatUserConfig = { chainId: 84531, urls: { apiURL: 'https://api-goerli.basescan.org/api', - browserURL: 'https://goerli.basescan.org/' - } + browserURL: 'https://goerli.basescan.org/', + }, }, { network: 'linea-goerli', chainId: 59140, urls: { apiURL: 'https://api-goerli.lineascan.build/api', - browserURL: 'https://goerli.lineascan.build/' - } - } - ] + browserURL: 'https://goerli.lineascan.build/', + }, + }, + ], }, typechain: { @@ -289,37 +310,40 @@ const config: HardhatUserConfig = { networks: { goerli: { usdc: goerliRelationConfigMap, - weth: goerliWethRelationConfigMap + weth: goerliWethRelationConfigMap, }, mumbai: { - usdc: mumbaiRelationConfigMap + usdc: mumbaiRelationConfigMap, }, mainnet: { usdc: mainnetRelationConfigMap, - weth: mainnetWethRelationConfigMap + weth: mainnetWethRelationConfigMap, }, polygon: { - usdc: polygonRelationConfigMap + usdc: polygonRelationConfigMap, }, arbitrum: { 'usdc.e': arbitrumBridgedUsdcRelationConfigMap, - usdc: arbitrumNativeUsdcRelationConfigMap + usdc: arbitrumNativeUsdcRelationConfigMap, }, 'arbitrum-goerli': { 'usdc.e': arbitrumBridgedUsdcGoerliRelationConfigMap, - usdc: arbitrumGoerliNativeUsdcRelationConfigMap + usdc: arbitrumGoerliNativeUsdcRelationConfigMap, }, - 'base': { + base: { usdbc: baseUsdbcRelationConfigMap, - weth: baseWethRelationConfigMap + weth: baseWethRelationConfigMap, }, 'base-goerli': { usdc: baseGoerliRelationConfigMap, - weth: baseGoerliWethRelationConfigMap + weth: baseGoerliWethRelationConfigMap, }, 'linea-goerli': { - usdc: lineaGoerliRelationConfigMap - } + usdc: lineaGoerliRelationConfigMap, + }, + optimism: { + usdc: optimismRelationConfigMap, + }, }, }, @@ -339,17 +363,17 @@ const config: HardhatUserConfig = { { name: 'development', network: 'hardhat', - deployment: 'dai' + deployment: 'dai', }, { name: 'fuji', network: 'fuji', - deployment: 'usdc' + deployment: 'usdc', }, { name: 'goerli', network: 'goerli', - deployment: 'usdc' + deployment: 'usdc', }, { name: 'goerli-weth', @@ -360,68 +384,74 @@ const config: HardhatUserConfig = { name: 'mumbai', network: 'mumbai', deployment: 'usdc', - auxiliaryBase: 'goerli' + auxiliaryBase: 'goerli', }, { name: 'polygon', network: 'polygon', deployment: 'usdc', - auxiliaryBase: 'mainnet' + auxiliaryBase: 'mainnet', }, { name: 'arbitrum-usdc.e', network: 'arbitrum', deployment: 'usdc.e', - auxiliaryBase: 'mainnet' + auxiliaryBase: 'mainnet', }, { name: 'arbitrum-usdc', network: 'arbitrum', deployment: 'usdc', - auxiliaryBase: 'mainnet' + auxiliaryBase: 'mainnet', }, { name: 'arbitrum-goerli-usdc.e', network: 'arbitrum-goerli', deployment: 'usdc.e', - auxiliaryBase: 'goerli' + auxiliaryBase: 'goerli', }, { name: 'arbitrum-goerli-usdc', network: 'arbitrum-goerli', deployment: 'usdc', - auxiliaryBase: 'goerli' + auxiliaryBase: 'goerli', }, { name: 'base-usdbc', network: 'base', deployment: 'usdbc', - auxiliaryBase: 'mainnet' + auxiliaryBase: 'mainnet', }, { name: 'base-weth', network: 'base', deployment: 'weth', - auxiliaryBase: 'mainnet' + auxiliaryBase: 'mainnet', }, { name: 'base-goerli', network: 'base-goerli', deployment: 'usdc', - auxiliaryBase: 'goerli' + auxiliaryBase: 'goerli', }, { name: 'base-goerli-weth', network: 'base-goerli', deployment: 'weth', - auxiliaryBase: 'goerli' + auxiliaryBase: 'goerli', }, { name: 'linea-goerli', network: 'linea-goerli', deployment: 'usdc', - auxiliaryBase: 'goerli' - } + auxiliaryBase: 'goerli', + }, + { + name: 'optimism', + network: 'optimism', + deployment: 'usdc', + auxiliaryBase: 'mainnet', + }, ], }, @@ -433,7 +463,7 @@ const config: HardhatUserConfig = { output: 'test-results.json', }, }, - timeout: 150_000 + timeout: 150_000, }, paths: { diff --git a/plugins/import/etherscan.ts b/plugins/import/etherscan.ts index ea92edb2f..f46cef4e3 100644 --- a/plugins/import/etherscan.ts +++ b/plugins/import/etherscan.ts @@ -20,7 +20,8 @@ export function getEtherscanApiUrl(network: string): string { 'arbitrum-goerli': 'api-goerli.arbiscan.io', base: 'api.basescan.org', 'base-goerli': 'api-goerli.basescan.org', - 'linea-goerli': 'api-goerli.lineascan.build' + 'linea-goerli': 'api-goerli.lineascan.build', + optimism: 'api-optimistic.etherscan.io', }[network]; if (!host) { @@ -44,7 +45,8 @@ export function getEtherscanUrl(network: string): string { 'arbitrum-goerli': 'goerli.arbiscan.io', base: 'basescan.org', 'base-goerli': 'goerli.basescan.org', - 'linea-goerli': 'goerli.lineascan.build' + 'linea-goerli': 'goerli.lineascan.build', + optimism: 'optimistic.etherscan.io', }[network]; if (!host) { @@ -68,7 +70,8 @@ export function getEtherscanApiKey(network: string): string { 'arbitrum-goerli': process.env.ARBISCAN_KEY, base: process.env.BASESCAN_KEY, 'base-goerli': process.env.BASESCAN_KEY, - 'linea-goerli': process.env.LINEASCAN_KEY + 'linea-goerli': process.env.LINEASCAN_KEY, + optimism: process.env.ETHERSCAN_KEY, }[network]; if (!apiKey) { diff --git a/scenario/utils/relayMessage.ts b/scenario/utils/relayMessage.ts index 0848cb1ba..d4856f187 100644 --- a/scenario/utils/relayMessage.ts +++ b/scenario/utils/relayMessage.ts @@ -19,6 +19,13 @@ export default async function relayMessage( startingBlockNumber ); break; + case 'optimism': + await relayBaseMessage( + governanceDeploymentManager, + bridgeDeploymentManager, + startingBlockNumber + ); + break; case 'mumbai': case 'polygon': await relayPolygonMessage( @@ -35,8 +42,8 @@ export default async function relayMessage( startingBlockNumber ); await relayCCTPMint( - governanceDeploymentManager, - bridgeDeploymentManager, + governanceDeploymentManager, + bridgeDeploymentManager, startingBlockNumber ); break; From 15aa71f8de8bd2a0e790bb2a07dd251b15caf361 Mon Sep 17 00:00:00 2001 From: dmitriy-bergman-works Date: Mon, 4 Mar 2024 16:24:59 +0200 Subject: [PATCH 02/37] Add Optimism and Optimism-goerli networks. And usdt market --- .github/workflows/deploy-market.yaml | 3 +- .github/workflows/enact-migration.yaml | 5 +- .github/workflows/prepare-migration.yaml | 3 +- .github/workflows/run-scenarios.yaml | 3 + deployments/goerli/usdc/relations.ts | 64 ++-- deployments/goerli/usdc/roots.json | 36 +- .../optimism-goerli/usdc/configuration.json | 56 ++++ deployments/optimism-goerli/usdc/deploy.ts | 112 +++++++ .../1707402209_configurate_and_ens.ts | 251 ++++++++++++++ deployments/optimism-goerli/usdc/relations.ts | 27 ++ deployments/optimism-goerli/usdc/roots.json | 5 + .../optimism-goerli/usdt/configuration.json | 56 ++++ deployments/optimism-goerli/usdt/deploy.ts | 89 +++++ .../1707403494_configurate_and_ens.ts | 279 ++++++++++++++++ deployments/optimism-goerli/usdt/relations.ts | 27 ++ deployments/optimism-goerli/usdt/roots.json | 5 + deployments/optimism/usdc/configuration.json | 12 +- .../1707394874_configurate_and_ens.ts | 311 ++++++++++++++++++ deployments/optimism/usdt/configuration.json | 55 ++++ deployments/optimism/usdt/deploy.ts | 83 +++++ .../1707399040_configurate_and_ens.ts | 269 +++++++++++++++ deployments/optimism/usdt/relations.ts | 30 ++ deployments/optimism/usdt/roots.json | 4 + hardhat.config.ts | 42 ++- plugins/import/etherscan.ts | 5 +- scenario/utils/relayMessage.ts | 1 + 26 files changed, 1781 insertions(+), 52 deletions(-) create mode 100644 deployments/optimism-goerli/usdc/configuration.json create mode 100644 deployments/optimism-goerli/usdc/deploy.ts create mode 100644 deployments/optimism-goerli/usdc/migrations/1707402209_configurate_and_ens.ts create mode 100644 deployments/optimism-goerli/usdc/relations.ts create mode 100644 deployments/optimism-goerli/usdc/roots.json create mode 100644 deployments/optimism-goerli/usdt/configuration.json create mode 100644 deployments/optimism-goerli/usdt/deploy.ts create mode 100644 deployments/optimism-goerli/usdt/migrations/1707403494_configurate_and_ens.ts create mode 100644 deployments/optimism-goerli/usdt/relations.ts create mode 100644 deployments/optimism-goerli/usdt/roots.json create mode 100644 deployments/optimism/usdc/migrations/1707394874_configurate_and_ens.ts create mode 100644 deployments/optimism/usdt/configuration.json create mode 100644 deployments/optimism/usdt/deploy.ts create mode 100644 deployments/optimism/usdt/migrations/1707399040_configurate_and_ens.ts create mode 100644 deployments/optimism/usdt/relations.ts create mode 100644 deployments/optimism/usdt/roots.json diff --git a/.github/workflows/deploy-market.yaml b/.github/workflows/deploy-market.yaml index df622b837..d3d3db463 100644 --- a/.github/workflows/deploy-market.yaml +++ b/.github/workflows/deploy-market.yaml @@ -17,6 +17,7 @@ on: - base-goerli - linea-goerli - optimism + - optimism-goerli deployment: description: Deployment Name (e.g. "usdc") required: true @@ -45,7 +46,7 @@ jobs: with: wallet_connect_project_id: ${{ secrets.WALLET_CONNECT_PROJECT_ID }} requested_network: '${{ inputs.network }}' - ethereum_url: '${{ fromJSON(''{"optimism":"https://optimism-mainnet.infura.io/v3/$INFURA_KEY","fuji":"https://api.avax-test.network/ext/bc/C/rpc","mainnet":"https://mainnet.infura.io/v3/$INFURA_KEY","goerli":"https://goerli.infura.io/v3/$INFURA_KEY","mumbai":"https://polygon-mumbai.infura.io/v3/$INFURA_KEY","polygon":"https://polygon-mainnet.infura.io/v3/$INFURA_KEY","arbitrum-goerli":"https://arbitrum-goerli.infura.io/v3/$INFURA_KEY","arbitrum":"https://arbitrum-mainnet.infura.io/v3/$INFURA_KEY","base":"https://clean-spring-wind.base-mainnet.discover.quiknode.pro/$QUICKNODE_KEY","base-goerli":"https://base-goerli.infura.io/v3/$INFURA_KEY","linea-goerli":"https://linea-goerli.infura.io/v3/$INFURA_KEY"}'')[inputs.network] }}' + ethereum_url: '${{ fromJSON(''{"optimism":"https://optimism-mainnet.infura.io/v3/$INFURA_KEY","optimism-goerli":"https://optimism-goerli.infura.io/v3/$INFURA_KEY","fuji":"https://api.avax-test.network/ext/bc/C/rpc","mainnet":"https://mainnet.infura.io/v3/$INFURA_KEY","goerli":"https://goerli.infura.io/v3/$INFURA_KEY","mumbai":"https://polygon-mumbai.infura.io/v3/$INFURA_KEY","polygon":"https://polygon-mainnet.infura.io/v3/$INFURA_KEY","arbitrum-goerli":"https://arbitrum-goerli.infura.io/v3/$INFURA_KEY","arbitrum":"https://arbitrum-mainnet.infura.io/v3/$INFURA_KEY","base":"https://clean-spring-wind.base-mainnet.discover.quiknode.pro/$QUICKNODE_KEY","base-goerli":"https://base-goerli.infura.io/v3/$INFURA_KEY","linea-goerli":"https://linea-goerli.infura.io/v3/$INFURA_KEY"}'')[inputs.network] }}' port: 8585 if: github.event.inputs.eth_pk == '' diff --git a/.github/workflows/enact-migration.yaml b/.github/workflows/enact-migration.yaml index 08648dbf1..2fc67dd6f 100644 --- a/.github/workflows/enact-migration.yaml +++ b/.github/workflows/enact-migration.yaml @@ -17,6 +17,7 @@ on: - base-goerli - linea-goerli - optimism + - optimism-goerli deployment: description: Deployment Name (e.g. "usdc") required: true @@ -64,7 +65,7 @@ jobs: with: wallet_connect_project_id: ${{ secrets.WALLET_CONNECT_PROJECT_ID }} requested_network: '${{ inputs.network }}' - ethereum_url: '${{ fromJSON(''{"optimism":"https://optimism-mainnet.infura.io/v3/$INFURA_KEY","fuji":"https://api.avax-test.network/ext/bc/C/rpc","mainnet":"https://mainnet.infura.io/v3/$INFURA_KEY","goerli":"https://goerli.infura.io/v3/$INFURA_KEY","mumbai":"https://polygon-mumbai.infura.io/v3/$INFURA_KEY","polygon":"https://polygon-mainnet.infura.io/v3/$INFURA_KEY","arbitrum-goerli":"https://arbitrum-goerli.infura.io/v3/$INFURA_KEY","arbitrum":"https://arbitrum-mainnet.infura.io/v3/$INFURA_KEY","base":"https://clean-spring-wind.base-mainnet.discover.quiknode.pro/$QUICKNODE_KEY","base-goerli":"https://base-goerli.infura.io/v3/$INFURA_KEY","linea-goerli":"https://linea-goerli.infura.io/v3/$INFURA_KEY"}'')[inputs.network] }}' + ethereum_url: '${{ fromJSON(''{"optimism":"https://optimism-mainnet.infura.io/v3/$INFURA_KEY","optimism-goerli":"https://optimism-goerli.infura.io/v3/$INFURA_KEY","fuji":"https://api.avax-test.network/ext/bc/C/rpc","mainnet":"https://mainnet.infura.io/v3/$INFURA_KEY","goerli":"https://goerli.infura.io/v3/$INFURA_KEY","mumbai":"https://polygon-mumbai.infura.io/v3/$INFURA_KEY","polygon":"https://polygon-mainnet.infura.io/v3/$INFURA_KEY","arbitrum-goerli":"https://arbitrum-goerli.infura.io/v3/$INFURA_KEY","arbitrum":"https://arbitrum-mainnet.infura.io/v3/$INFURA_KEY","base":"https://clean-spring-wind.base-mainnet.discover.quiknode.pro/$QUICKNODE_KEY","base-goerli":"https://base-goerli.infura.io/v3/$INFURA_KEY","linea-goerli":"https://linea-goerli.infura.io/v3/$INFURA_KEY"}'')[inputs.network] }}' port: 8585 if: github.event.inputs.eth_pk == '' @@ -73,7 +74,7 @@ jobs: with: wallet_connect_project_id: ${{ secrets.WALLET_CONNECT_PROJECT_ID }} requested_network: '${{ env.GOV_NETWORK }}' - ethereum_url: '${{ fromJSON(''{"optimism":"https://optimism-mainnet.infura.io/v3/$INFURA_KEY","fuji":"https://api.avax-test.network/ext/bc/C/rpc","mainnet":"https://mainnet.infura.io/v3/$INFURA_KEY","goerli":"https://goerli.infura.io/v3/$INFURA_KEY","mumbai":"https://polygon-mumbai.infura.io/v3/$INFURA_KEY","polygon":"https://polygon-mainnet.infura.io/v3/$INFURA_KEY","arbitrum-goerli":"https://arbitrum-goerli.infura.io/v3/$INFURA_KEY","arbitrum":"https://arbitrum-mainnet.infura.io/v3/$INFURA_KEY"}'')[env.GOV_NETWORK] }}' + ethereum_url: '${{ fromJSON(''{"optimism":"https://optimism-mainnet.infura.io/v3/$INFURA_KEY","optimism-goerli":"https://optimism-goerli.infura.io/v3/$INFURA_KEY","fuji":"https://api.avax-test.network/ext/bc/C/rpc","mainnet":"https://mainnet.infura.io/v3/$INFURA_KEY","goerli":"https://goerli.infura.io/v3/$INFURA_KEY","mumbai":"https://polygon-mumbai.infura.io/v3/$INFURA_KEY","polygon":"https://polygon-mainnet.infura.io/v3/$INFURA_KEY","arbitrum-goerli":"https://arbitrum-goerli.infura.io/v3/$INFURA_KEY","arbitrum":"https://arbitrum-mainnet.infura.io/v3/$INFURA_KEY"}'')[env.GOV_NETWORK] }}' port: 8685 if: github.event.inputs.eth_pk == '' && env.GOV_NETWORK != '' diff --git a/.github/workflows/prepare-migration.yaml b/.github/workflows/prepare-migration.yaml index 074fa986a..784fd94da 100644 --- a/.github/workflows/prepare-migration.yaml +++ b/.github/workflows/prepare-migration.yaml @@ -16,6 +16,7 @@ on: - base - base-goerli - optimism + - optimism-goerli deployment: description: Deployment Name (e.g. "usdc") required: true @@ -47,7 +48,7 @@ jobs: with: wallet_connect_project_id: ${{ secrets.WALLET_CONNECT_PROJECT_ID }} requested_network: '${{ inputs.network }}' - ethereum_url: '${{ fromJSON(''{"optimism":"https://optimism-mainnet.infura.io/v3/$INFURA_KEY","fuji":"https://api.avax-test.network/ext/bc/C/rpc","mainnet":"https://mainnet.infura.io/v3/$INFURA_KEY","goerli":"https://goerli.infura.io/v3/$INFURA_KEY","mumbai":"https://polygon-mumbai.infura.io/v3/$INFURA_KEY","polygon":"https://polygon-mainnet.infura.io/v3/$INFURA_KEY","arbitrum-goerli":"https://arbitrum-goerli.infura.io/v3/$INFURA_KEY","arbitrum":"https://arbitrum-mainnet.infura.io/v3/$INFURA_KEY","base":"https://clean-spring-wind.base-mainnet.discover.quiknode.pro/$QUICKNODE_KEY","base-goerli":"https://base-goerli.infura.io/v3/$INFURA_KEY","linea-goerli":"https://linea-goerli.infura.io/v3/$INFURA_KEY"}'')[inputs.network] }}' + ethereum_url: '${{ fromJSON(''{"optimism":"https://optimism-mainnet.infura.io/v3/$INFURA_KEY","optimism-goerli":"https://optimism-goerli.infura.io/v3/$INFURA_KEY","fuji":"https://api.avax-test.network/ext/bc/C/rpc","mainnet":"https://mainnet.infura.io/v3/$INFURA_KEY","goerli":"https://goerli.infura.io/v3/$INFURA_KEY","mumbai":"https://polygon-mumbai.infura.io/v3/$INFURA_KEY","polygon":"https://polygon-mainnet.infura.io/v3/$INFURA_KEY","arbitrum-goerli":"https://arbitrum-goerli.infura.io/v3/$INFURA_KEY","arbitrum":"https://arbitrum-mainnet.infura.io/v3/$INFURA_KEY","base":"https://clean-spring-wind.base-mainnet.discover.quiknode.pro/$QUICKNODE_KEY","base-goerli":"https://base-goerli.infura.io/v3/$INFURA_KEY","linea-goerli":"https://linea-goerli.infura.io/v3/$INFURA_KEY"}'')[inputs.network] }}' port: 8585 if: github.event.inputs.eth_pk == '' diff --git a/.github/workflows/run-scenarios.yaml b/.github/workflows/run-scenarios.yaml index 7ea0411b3..0e3f8a753 100644 --- a/.github/workflows/run-scenarios.yaml +++ b/.github/workflows/run-scenarios.yaml @@ -27,6 +27,9 @@ jobs: base-goerli-weth, linea-goerli, optimism-usdc, + optimism-usdt, + optimism-goerli-usdc, + optimism-goerli-usdt, ] name: Run scenarios env: diff --git a/deployments/goerli/usdc/relations.ts b/deployments/goerli/usdc/relations.ts index f9edfd59b..05ea26592 100644 --- a/deployments/goerli/usdc/relations.ts +++ b/deployments/goerli/usdc/relations.ts @@ -6,41 +6,57 @@ export default { fxRoot: { relations: { stateSender: { - field: async fxRoot => fxRoot.stateSender() - } - } + field: async (fxRoot) => fxRoot.stateSender(), + }, + }, }, arbitrumInbox: { delegates: { field: { - slot: '0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc' - } + slot: + '0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc', + }, }, relations: { arbitrumBridge: { - field: async inbox => inbox.bridge() - } - } + field: async (inbox) => inbox.bridge(), + }, + }, }, arbitrumL1GatewayRouter: { delegates: { field: { - slot: '0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc' - } - } + slot: + '0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc', + }, + }, }, baseL1CrossDomainMessenger: { delegates: { // Not great, but this address shouldn't change and is very difficult to grab on-chain (private methods) - field: async () => '0xa042e16781484716c1Ef448c919af7BCd9607467' - } + field: async () => '0xa042e16781484716c1Ef448c919af7BCd9607467', + }, }, baseL1StandardBridge: { delegates: { field: { - slot: '0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc' - } - } + slot: + '0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc', + }, + }, + }, + opL1CrossDomainMessenger: { + delegates: { + field: async () => '0xDa2332D0a7608919Cd331B1304Cd179129a90495', + }, + }, + opL1StandardBridge: { + delegates: { + field: { + slot: + '0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc', + }, + }, }, lineaMessageService: { artifact: 'contracts/bridges/linea/IMessageService.sol:IMessageService', @@ -53,15 +69,17 @@ export default { lineaL1TokenBridge: { delegates: { field: { - slot: '0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc' - } - } + slot: + '0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc', + }, + }, }, lineaL1usdcBridge: { delegates: { field: { - slot: '0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc' - } - } - } + slot: + '0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc', + }, + }, + }, }; diff --git a/deployments/goerli/usdc/roots.json b/deployments/goerli/usdc/roots.json index f693adeb1..2a919097e 100644 --- a/deployments/goerli/usdc/roots.json +++ b/deployments/goerli/usdc/roots.json @@ -1,18 +1,20 @@ { - "timelock": "0x8Fa336EB4bF58Cfc508dEA1B0aeC7336f55B1399", - "fauceteer": "0x75442Ac771a7243433e033F3F8EaB2631e22938f", - "comet": "0x3EE77595A8459e93C2888b13aDB354017B198188", - "configurator": "0xB28495db3eC65A0e3558F040BC4f98A0d588Ae60", - "rewards": "0xef9e070044d62C38D2e316146dDe92AD02CF2c2c", - "bulker": "0x69dD076105977c55dC2835951d287f82D54606b4", - "fxRoot": "0x3d1d3E34f7fB6D26245E6640E1c50710eFFf15bA", - "arbitrumInbox": "0x6BEbC4925716945D46F0Ec336D5C2564F419682C", - "arbitrumL1GatewayRouter": "0x4c7708168395aEa569453Fc36862D2ffcDaC588c", - "baseL1CrossDomainMessenger": "0x8e5693140eA606bcEB98761d9beB1BC87383706D", - "baseL1StandardBridge": "0xfA6D8Ee5BE770F84FC001D098C4bD604Fe01284a", - "lineaMessageService": "0x70BaD09280FD342D02fe64119779BC1f0791BAC2", - "lineaL1TokenBridge": "0xaA012D038E6440535Ec66eDf2DA592F4F8398133", - "lineaL1usdcBridge": "0x9c556D2cCfb6157E4A6305aa9963EdD6ca5047cB", - "CCTPTokenMessenger": "0xd0c3da58f55358142b8d3e06c1c30c5c6114efe8", - "CCTPMessageTransmitter": "0x26413e8157cd32011e726065a5462e97dd4d03d9" -} \ No newline at end of file + "timelock": "0x8Fa336EB4bF58Cfc508dEA1B0aeC7336f55B1399", + "fauceteer": "0x75442Ac771a7243433e033F3F8EaB2631e22938f", + "comet": "0x3EE77595A8459e93C2888b13aDB354017B198188", + "configurator": "0xB28495db3eC65A0e3558F040BC4f98A0d588Ae60", + "rewards": "0xef9e070044d62C38D2e316146dDe92AD02CF2c2c", + "bulker": "0x69dD076105977c55dC2835951d287f82D54606b4", + "fxRoot": "0x3d1d3E34f7fB6D26245E6640E1c50710eFFf15bA", + "arbitrumInbox": "0x6BEbC4925716945D46F0Ec336D5C2564F419682C", + "arbitrumL1GatewayRouter": "0x4c7708168395aEa569453Fc36862D2ffcDaC588c", + "baseL1CrossDomainMessenger": "0x8e5693140eA606bcEB98761d9beB1BC87383706D", + "baseL1StandardBridge": "0xfA6D8Ee5BE770F84FC001D098C4bD604Fe01284a", + "lineaMessageService": "0x70BaD09280FD342D02fe64119779BC1f0791BAC2", + "lineaL1TokenBridge": "0xaA012D038E6440535Ec66eDf2DA592F4F8398133", + "lineaL1usdcBridge": "0x9c556D2cCfb6157E4A6305aa9963EdD6ca5047cB", + "CCTPTokenMessenger": "0xd0c3da58f55358142b8d3e06c1c30c5c6114efe8", + "CCTPMessageTransmitter": "0x26413e8157cd32011e726065a5462e97dd4d03d9", + "opL1CrossDomainMessenger": "0x5086d1eEF304eb5284A0f6720f79403b4e9bE294", + "opL1StandardBridge": "0x636Af16bf2f682dD3109e60102b8E1A089FedAa8" +} diff --git a/deployments/optimism-goerli/usdc/configuration.json b/deployments/optimism-goerli/usdc/configuration.json new file mode 100644 index 000000000..90ef80a88 --- /dev/null +++ b/deployments/optimism-goerli/usdc/configuration.json @@ -0,0 +1,56 @@ +{ + "name": "Compound USDC", + "symbol": "cUSDCv3", + "baseToken": "USDC", + "baseTokenAddress": "0x7E07E15D2a87A24492740D16f5bdF58c16db0c4E", + "baseTokenPriceFeed": "0x2636B223652d388721A0ED2861792DA9062D8C73", + "pauseGuardian": "0xe7661C55fe281f986FA5312D57d19ADb6064462F", + "borrowMin": "1e6", + "storeFrontPriceFactor": 0.5, + "targetReserves": "1000000e6", + "rates": { + "supplyKink": 0.8, + "supplySlopeLow": 0.0325, + "supplySlopeHigh": 0.4, + "supplyBase": 0, + "borrowKink": 0.8, + "borrowSlopeLow": 0.035, + "borrowSlopeHigh": 0.25, + "borrowBase": 0.015 + }, + "tracking": { + "indexScale": "1e15", + "baseSupplySpeed": "0.000402083333333e15", + "baseBorrowSpeed": "0.000402083333333e15", + "baseMinForRewards": "10000e6" + }, + "assets": { + "WETH": { + "address": "0x4200000000000000000000000000000000000006", + "priceFeed": "0xE30268502Eb3B2341f7961e68a34729302592dC6", + "decimals": "18", + "borrowCF": 0.775, + "liquidateCF": 0.825, + "liquidationFactor": 0.95, + "supplyCap": "1000e18" + }, + "OP": { + "address": "0x4200000000000000000000000000000000000042", + "priceFeed": "0x2636B223652d388721A0ED2861792DA9062D8C73", + "decimals": "18", + "borrowCF": 0.775, + "liquidateCF": 0.825, + "liquidationFactor": 0.95, + "supplyCap": "1000e18" + }, + "WBTC": { + "address": "0x099E6dA9FFF9F0D8873AaD3FB4C9F7eDA5742692", + "priceFeed": "0xC16679B963CeB52089aD2d95312A5b85E318e9d2", + "decimals": "8", + "borrowCF": 0.7, + "liquidateCF": 0.75, + "liquidationFactor": 0.93, + "supplyCap": "300e8" + } + } +} diff --git a/deployments/optimism-goerli/usdc/deploy.ts b/deployments/optimism-goerli/usdc/deploy.ts new file mode 100644 index 000000000..e95689803 --- /dev/null +++ b/deployments/optimism-goerli/usdc/deploy.ts @@ -0,0 +1,112 @@ +import { + Deployed, + DeploymentManager, +} from '../../../plugins/deployment_manager'; +import { DeploySpec, deployComet } from '../../../src/deploy'; + +const SECONDS_PER_DAY = 24 * 60 * 60; + +const GOERLI_TIMELOCK = '0x8Fa336EB4bF58Cfc508dEA1B0aeC7336f55B1399'; + +export default async function deploy( + deploymentManager: DeploymentManager, + deploySpec: DeploySpec +): Promise { + const deployed = await deployContracts(deploymentManager, deploySpec); + return deployed; +} + +async function deployContracts( + deploymentManager: DeploymentManager, + deploySpec: DeploySpec +): Promise { + const trace = deploymentManager.tracer(); + const ethers = deploymentManager.hre.ethers; + + // Pull in existing assets + const WETH = await deploymentManager.existing( + 'WETH', + '0x4200000000000000000000000000000000000006', + 'optimism-goerli' + ); + + const l2CrossDomainMessenger = await deploymentManager.existing( + 'l2CrossDomainMessenger', + [ + '0xC0d3c0d3c0D3c0D3C0d3C0D3C0D3c0d3c0d30007', + '0x4200000000000000000000000000000000000007', + ], + 'optimism-goerli' + ); + + const l2StandardBridge = await deploymentManager.existing( + 'l2StandardBridge', + [ + '0xC0d3c0d3c0D3c0d3C0D3c0D3C0d3C0D3C0D30010', + '0x4200000000000000000000000000000000000010', + ], + 'optimism-goerli' + ); + // Deploy OptimismBridgeReceiver + const bridgeReceiver = await deploymentManager.deploy( + 'bridgeReceiver', + 'bridges/optimism/OptimismBridgeReceiver.sol', + [l2CrossDomainMessenger.address] + ); + // Deploy Local Timelock + const localTimelock = await deploymentManager.deploy( + 'timelock', + 'vendor/Timelock.sol', + [ + bridgeReceiver.address, // admin + 10 * 60, // delay + 14 * SECONDS_PER_DAY, // grace period + 10 * 60, // minimum delay + 30 * SECONDS_PER_DAY, // maximum delay + ] + ); + + // Initialize OptimismBridgeReceiver + await deploymentManager.idempotent( + async () => !(await bridgeReceiver.initialized()), + async () => { + trace(`Initializing BridgeReceiver`); + await bridgeReceiver.initialize( + GOERLI_TIMELOCK, // govTimelock + localTimelock.address // localTimelock + ); + trace(`BridgeReceiver initialized`); + } + ); + + // Deploy Comet + const deployed = await deployComet(deploymentManager, deploySpec); + const { comet } = deployed; + + // Deploy Bulker + const bulker = await deploymentManager.deploy( + 'bulker', + 'bulkers/BaseBulker.sol', + [ + await comet.governor(), // admin + WETH.address, // weth + ] + ); + console.log('bulker address', bulker.address); + + // Deploy fauceteer + const fauceteer = await deploymentManager.deploy( + 'fauceteer', + 'test/Fauceteer.sol', + [] + ); + + return { + ...deployed, + bridgeReceiver, + l2CrossDomainMessenger, + l2StandardBridge, + bulker, + fauceteer, + }; +} diff --git a/deployments/optimism-goerli/usdc/migrations/1707402209_configurate_and_ens.ts b/deployments/optimism-goerli/usdc/migrations/1707402209_configurate_and_ens.ts new file mode 100644 index 000000000..96df82648 --- /dev/null +++ b/deployments/optimism-goerli/usdc/migrations/1707402209_configurate_and_ens.ts @@ -0,0 +1,251 @@ +import { DeploymentManager } from '../../../../plugins/deployment_manager/DeploymentManager'; +import { + diffState, + getCometConfig, +} from '../../../../plugins/deployment_manager/DiffState'; +import { migration } from '../../../../plugins/deployment_manager/Migration'; +import { + calldata, + exp, + getConfigurationStruct, + proposal, +} from '../../../../src/deploy'; +import { expect } from 'chai'; + +const ENSName = 'compound-community-licenses.eth'; +const ENSResolverAddress = '0x19c2d5D0f035563344dBB7bE5fD09c8dad62b001'; +const ENSRegistryAddress = '0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e'; +const ENSSubdomainLabel = 'v3-additional-grants'; +const ENSSubdomain = `${ENSSubdomainLabel}.${ENSName}`; +const ENSTextRecordKey = 'v3-official-markets'; +const opCOMPAddress = '0x6AF3cb766D6cd37449bfD321D961A61B0515c1BC'; + +export default migration('1707402209_configurate_and_ens', { + prepare: async (deploymentManager: DeploymentManager) => { + return {}; + }, + + enact: async ( + deploymentManager: DeploymentManager, + govDeploymentManager: DeploymentManager + ) => { + const trace = deploymentManager.tracer(); + const ethers = deploymentManager.hre.ethers; + const { utils } = ethers; + + const { + bridgeReceiver, + comet, + cometAdmin, + configurator, + rewards, + } = await deploymentManager.getContracts(); + + const { + opL1CrossDomainMessenger, + opL1StandardBridge, + governor, + COMP: goerliCOMP, + } = await govDeploymentManager.getContracts(); + + // ENS Setup + // See also: https://docs.ens.domains/contract-api-reference/name-processing + const ENSResolver = await govDeploymentManager.existing( + 'ENSResolver', + ENSResolverAddress, + 'goerli' + ); + const subdomainHash = ethers.utils.namehash(ENSSubdomain); + const baseGoerliChainId = ( + await deploymentManager.hre.ethers.provider.getNetwork() + ).chainId.toString(); + const newMarketObject = { baseSymbol: 'USDC', cometAddress: comet.address }; + const officialMarketsJSON = JSON.parse( + await ENSResolver.text(subdomainHash, ENSTextRecordKey) + ); + if (officialMarketsJSON[baseGoerliChainId]) { + officialMarketsJSON[baseGoerliChainId].push(newMarketObject); + } else { + officialMarketsJSON[baseGoerliChainId] = [newMarketObject]; + } + + const configuration = await getConfigurationStruct(deploymentManager); + + const setConfigurationCalldata = await calldata( + configurator.populateTransaction.setConfiguration( + comet.address, + configuration + ) + ); + const deployAndUpgradeToCalldata = utils.defaultAbiCoder.encode( + ['address', 'address'], + [configurator.address, comet.address] + ); + const setRewardConfigCalldata = utils.defaultAbiCoder.encode( + ['address', 'address'], + [comet.address, opCOMPAddress] + ); + const l2ProposalData = utils.defaultAbiCoder.encode( + ['address[]', 'uint256[]', 'string[]', 'bytes[]'], + [ + [configurator.address, cometAdmin.address, rewards.address], + [0, 0, 0], + [ + 'setConfiguration(address,(address,address,address,address,address,uint64,uint64,uint64,uint64,uint64,uint64,uint64,uint64,uint64,uint64,uint64,uint64,uint104,uint104,uint104,(address,address,uint8,uint64,uint64,uint64,uint128)[]))', + 'deployAndUpgradeTo(address,address)', + 'setRewardConfig(address,address)', + ], + [ + setConfigurationCalldata, + deployAndUpgradeToCalldata, + setRewardConfigCalldata, + ], + ] + ); + + const COMPAmountToBridge = exp(10_000, 18); + + // Note: We aren't bridging USDC over to optimism Goerli because they don't use a bridged version of USDC there, + const goerliActions = [ + // 1. Set Comet configuration + deployAndUpgradeTo new Comet and set reward config on Optimism-Goerli. + { + contract: opL1CrossDomainMessenger, + signature: 'sendMessage(address,bytes,uint32)', + args: [bridgeReceiver.address, l2ProposalData, 2_500_000], + }, + + // 2. Approve Goerli's L1StandardBridge to take Timelock's COMP (for bridging) + { + contract: goerliCOMP, + signature: 'approve(address,uint256)', + args: [opL1StandardBridge.address, COMPAmountToBridge], + }, + // 3. Bridge COMP from Goerli to Optimism-Goerli Comet using L1StandardBridge + { + contract: opL1StandardBridge, + // function depositERC20To(address _l1Token, address _l2Token, address _to, uint256 _amount, uint32 _l2Gas,bytes calldata _data) + signature: + 'depositERC20To(address,address,address,uint256,uint32,bytes)', + args: [ + goerliCOMP.address, + opCOMPAddress, + rewards.address, + COMPAmountToBridge, + 200_000, + '0x', + ], + }, + + // 4. Update the list of official markets + { + target: ENSResolverAddress, + signature: 'setText(bytes32,string,string)', + calldata: ethers.utils.defaultAbiCoder.encode( + ['bytes32', 'string', 'string'], + [subdomainHash, ENSTextRecordKey, JSON.stringify(officialMarketsJSON)] + ), + }, + ]; + + const description = 'Proposal text'; + const txn = await govDeploymentManager.retry(async () => + trace( + await governor.propose(...(await proposal(goerliActions, description))) + ) + ); + + const event = txn.events.find((event) => event.event === 'ProposalCreated'); + const [proposalId] = event.args; + + trace(`Created proposal ${proposalId}.`); + }, + + async enacted(deploymentManager: DeploymentManager): Promise { + return true; + }, + + async verify( + deploymentManager: DeploymentManager, + govDeploymentManager: DeploymentManager, + preMigrationBlockNumber: number + ) { + const ethers = deploymentManager.hre.ethers; + await deploymentManager.spider(); // We spider here to pull in Optimism COMP now that reward config has been set + + const { comet, rewards, COMP } = await deploymentManager.getContracts(); + + // 1. + const stateChanges = await diffState( + comet, + getCometConfig, + preMigrationBlockNumber + ); + expect(stateChanges).to.deep.equal({ + pauseGuardian: '0xBA5e81fD6811E2699b478d1Bcde62a585bC9b6f7', //// Should be updated to the correct address + baseTrackingSupplySpeed: exp(34.74 / 86400, 15, 18), /// Should be updated to the correct value + baseTrackingBorrowSpeed: exp(34.74 / 86400, 15, 18), /// Should be updated to the correct value + baseBorrowMin: exp(1, 6), /// Should be updated to the correct value + WETH: { + supplyCap: exp(1000, 18), /// Should be updated to the correct value + }, + OP: { + supplyCap: exp(800, 18), /// Should be updated to the correct value + }, + WBTC: { + supplyCap: exp(800, 18), /// Should be updated to the correct value + }, + }); + ///// =========================================== all checks should be updated to the correct values after getting correct information + const config = await rewards.rewardConfig(comet.address); + expect(config.token).to.be.equal(COMP.address); + expect(config.rescaleFactor).to.be.equal(exp(1, 12)); + expect(config.shouldUpscale).to.be.equal(true); + + // 2. & 3. + expect(await COMP.balanceOf(rewards.address)).to.be.equal(exp(10_000, 18)); + + // 4. + const ENSResolver = await govDeploymentManager.existing( + 'ENSResolver', + ENSResolverAddress, + 'goerli' + ); + const subdomainHash = ethers.utils.namehash(ENSSubdomain); + const officialMarketsJSON = await ENSResolver.text( + subdomainHash, + ENSTextRecordKey + ); + const officialMarkets = JSON.parse(officialMarketsJSON); + expect(officialMarkets).to.deep.equal({ + /// Should parse before migration and update this + 5: [ + { + baseSymbol: 'USDC', + cometAddress: '0x3EE77595A8459e93C2888b13aDB354017B198188', + }, + { + baseSymbol: 'WETH', + cometAddress: '0x9A539EEc489AAA03D588212a164d0abdB5F08F5F', + }, + ], + 80001: [ + { + baseSymbol: 'USDC', + cometAddress: '0xF09F0369aB0a875254fB565E52226c88f10Bc839', + }, + ], + 421613: [ + { + baseSymbol: 'USDC', + cometAddress: '0x1d573274E19174260c5aCE3f2251598959d24456', + }, + ], + 420: [ + { + baseSymbol: 'USDC', + cometAddress: comet.address, + }, + ], + }); + }, +}); diff --git a/deployments/optimism-goerli/usdc/relations.ts b/deployments/optimism-goerli/usdc/relations.ts new file mode 100644 index 000000000..82f918493 --- /dev/null +++ b/deployments/optimism-goerli/usdc/relations.ts @@ -0,0 +1,27 @@ +import baseRelationConfig from '../../relations'; + +export default { + ...baseRelationConfig, + governor: { + artifact: + 'contracts/bridges/optimism/OptimismBridgeReceiver.sol:OptimismBridgeReceiver', + }, + + l2CrossDomainMessenger: { + delegates: { + field: { + slot: + '0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc', + }, + }, + }, + + l2StandardBridge: { + delegates: { + field: { + slot: + '0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc', + }, + }, + }, +}; diff --git a/deployments/optimism-goerli/usdc/roots.json b/deployments/optimism-goerli/usdc/roots.json new file mode 100644 index 000000000..a802e529e --- /dev/null +++ b/deployments/optimism-goerli/usdc/roots.json @@ -0,0 +1,5 @@ +{ + "WETH": "0x4200000000000000000000000000000000000006", + "l2CrossDomainMessenger": "0x4200000000000000000000000000000000000007", + "l2StandardBridge": "0x4200000000000000000000000000000000000010" +} diff --git a/deployments/optimism-goerli/usdt/configuration.json b/deployments/optimism-goerli/usdt/configuration.json new file mode 100644 index 000000000..25a8b8457 --- /dev/null +++ b/deployments/optimism-goerli/usdt/configuration.json @@ -0,0 +1,56 @@ +{ + "name": "Compound USDT", + "symbol": "cUSDTv3", + "baseToken": "USDT", + "baseTokenAddress": "0xe05606174bac4A6364B31bd0eCA4bf4dD368f8C6", + "baseTokenPriceFeed": "0x2636B223652d388721A0ED2861792DA9062D8C73", + "pauseGuardian": "0xe7661C55fe281f986FA5312D57d19ADb6064462F", + "borrowMin": "1e6", + "storeFrontPriceFactor": 0.5, + "targetReserves": "1000000e6", + "rates": { + "supplyKink": 0.8, + "supplySlopeLow": 0.0325, + "supplySlopeHigh": 0.4, + "supplyBase": 0, + "borrowKink": 0.8, + "borrowSlopeLow": 0.035, + "borrowSlopeHigh": 0.25, + "borrowBase": 0.015 + }, + "tracking": { + "indexScale": "1e15", + "baseSupplySpeed": "0.000402083333333e15", + "baseBorrowSpeed": "0.000402083333333e15", + "baseMinForRewards": "10000e6" + }, + "assets": { + "WETH": { + "address": "0x4200000000000000000000000000000000000006", + "priceFeed": "0xE30268502Eb3B2341f7961e68a34729302592dC6", + "decimals": "18", + "borrowCF": 0.775, + "liquidateCF": 0.825, + "liquidationFactor": 0.95, + "supplyCap": "1000e18" + }, + "OP": { + "address": "0x4200000000000000000000000000000000000042", + "priceFeed": "0x2636B223652d388721A0ED2861792DA9062D8C73", + "decimals": "18", + "borrowCF": 0.775, + "liquidateCF": 0.825, + "liquidationFactor": 0.95, + "supplyCap": "1000e18" + }, + "WBTC": { + "address": "0x099E6dA9FFF9F0D8873AaD3FB4C9F7eDA5742692", + "priceFeed": "0xC16679B963CeB52089aD2d95312A5b85E318e9d2", + "decimals": "8", + "borrowCF": 0.7, + "liquidateCF": 0.75, + "liquidationFactor": 0.93, + "supplyCap": "300e8" + } + } +} diff --git a/deployments/optimism-goerli/usdt/deploy.ts b/deployments/optimism-goerli/usdt/deploy.ts new file mode 100644 index 000000000..c2bb53772 --- /dev/null +++ b/deployments/optimism-goerli/usdt/deploy.ts @@ -0,0 +1,89 @@ +import { + Deployed, + DeploymentManager, +} from '../../../plugins/deployment_manager'; +import { DeploySpec, deployComet } from '../../../src/deploy'; + +export default async function deploy( + deploymentManager: DeploymentManager, + deploySpec: DeploySpec +): Promise { + const deployed = await deployContracts(deploymentManager, deploySpec); + return deployed; +} + +async function deployContracts( + deploymentManager: DeploymentManager, + deploySpec: DeploySpec +): Promise { + const trace = deploymentManager.tracer(); + + // Import shared contracts from cUSDCv3 + const cometAdmin = await deploymentManager.fromDep( + 'cometAdmin', + 'optimism-goerli', + 'usdc' + ); + const cometFactory = await deploymentManager.fromDep( + 'cometFactory', + 'optimism-goerli', + 'usdc' + ); + const $configuratorImpl = await deploymentManager.fromDep( + 'configurator:implementation', + 'optimism-goerli', + 'usdc' + ); + const configurator = await deploymentManager.fromDep( + 'configurator', + 'optimism-goerli', + 'usdc' + ); + const rewards = await deploymentManager.fromDep( + 'rewards', + 'optimism-goerli', + 'usdc' + ); + const bulker = await deploymentManager.fromDep( + 'bulker', + 'optimism-goerli', + 'usdc' + ); + const fauceteer = await deploymentManager.fromDep( + 'fauceteer', + 'optimism-goerli', + 'usdc' + ); + const l2CrossDomainMessenger = await deploymentManager.fromDep( + 'l2CrossDomainMessenger', + 'optimism-goerli', + 'usdc' + ); + const l2StandardBridge = await deploymentManager.fromDep( + 'l2StandardBridge', + 'optimism-goerli', + 'usdc' + ); + const localTimelock = await deploymentManager.fromDep( + 'timelock', + 'optimism-goerli', + 'usdc' + ); + const bridgeReceiver = await deploymentManager.fromDep( + 'bridgeReceiver', + 'optimism-goerli', + 'usdc' + ); + + // Deploy Comet + const deployed = await deployComet(deploymentManager, deploySpec); + + return { + ...deployed, + bridgeReceiver, + l2CrossDomainMessenger, + l2StandardBridge, + bulker, + fauceteer, + }; +} diff --git a/deployments/optimism-goerli/usdt/migrations/1707403494_configurate_and_ens.ts b/deployments/optimism-goerli/usdt/migrations/1707403494_configurate_and_ens.ts new file mode 100644 index 000000000..1b2de04bb --- /dev/null +++ b/deployments/optimism-goerli/usdt/migrations/1707403494_configurate_and_ens.ts @@ -0,0 +1,279 @@ +import { DeploymentManager } from '../../../../plugins/deployment_manager/DeploymentManager'; +import { + diffState, + getCometConfig, +} from '../../../../plugins/deployment_manager/DiffState'; +import { migration } from '../../../../plugins/deployment_manager/Migration'; +import { + calldata, + exp, + getConfigurationStruct, + proposal, +} from '../../../../src/deploy'; +import { expect } from 'chai'; + +const ENSName = 'compound-community-licenses.eth'; +const ENSResolverAddress = '0x19c2d5D0f035563344dBB7bE5fD09c8dad62b001'; +const ENSRegistryAddress = '0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e'; +const ENSSubdomainLabel = 'v3-additional-grants'; +const ENSSubdomain = `${ENSSubdomainLabel}.${ENSName}`; +const ENSTextRecordKey = 'v3-official-markets'; +const opCOMPAddress = '0x6AF3cb766D6cd37449bfD321D961A61B0515c1BC'; + +export default migration('1707403494_configurate_and_ens', { + prepare: async (deploymentManager: DeploymentManager) => { + return {}; + }, + + enact: async ( + deploymentManager: DeploymentManager, + govDeploymentManager: DeploymentManager + ) => { + const trace = deploymentManager.tracer(); + const ethers = deploymentManager.hre.ethers; + const { utils } = ethers; + + const cometFactory = await deploymentManager.fromDep( + 'cometFactory', + 'optimism-goerli', + 'usdc' + ); + const { + bridgeReceiver, + timelock: localTimelock, + comet, + cometAdmin, + configurator, + rewards, + WETH, + } = await deploymentManager.getContracts(); + + const { + opL1CrossDomainMessenger, + opL1StandardBridge, + governor, + COMP: goerliCOMP, + } = await govDeploymentManager.getContracts(); + + // ENS Setup + // See also: https://docs.ens.domains/contract-api-reference/name-processing + const ENSResolver = await govDeploymentManager.existing( + 'ENSResolver', + ENSResolverAddress, + 'goerli' + ); + const subdomainHash = ethers.utils.namehash(ENSSubdomain); + const opGoerliChainId = ( + await deploymentManager.hre.ethers.provider.getNetwork() + ).chainId.toString(); + const newMarketObject = { baseSymbol: 'WETH', cometAddress: comet.address }; + const officialMarketsJSON = JSON.parse( + await ENSResolver.text(subdomainHash, ENSTextRecordKey) + ); + if (officialMarketsJSON[opGoerliChainId]) { + officialMarketsJSON[opGoerliChainId].push(newMarketObject); + } else { + officialMarketsJSON[opGoerliChainId] = [newMarketObject]; + } + + const configuration = await getConfigurationStruct(deploymentManager); + const setFactoryCalldata = await calldata( + configurator.populateTransaction.setFactory( + comet.address, + cometFactory.address + ) + ); + const setConfigurationCalldata = await calldata( + configurator.populateTransaction.setConfiguration( + comet.address, + configuration + ) + ); + const deployAndUpgradeToCalldata = utils.defaultAbiCoder.encode( + ['address', 'address'], + [configurator.address, comet.address] + ); + const setRewardConfigCalldata = utils.defaultAbiCoder.encode( + ['address', 'address'], + [comet.address, opCOMPAddress] + ); + + const l2ProposalData = utils.defaultAbiCoder.encode( + ['address[]', 'uint256[]', 'string[]', 'bytes[]'], + [ + [ + configurator.address, + configurator.address, + cometAdmin.address, + rewards.address, + ], + [0, 0, 0, 0], + [ + 'setFactory(address,address)', + 'setConfiguration(address,(address,address,address,address,address,uint64,uint64,uint64,uint64,uint64,uint64,uint64,uint64,uint64,uint64,uint64,uint64,uint104,uint104,uint104,(address,address,uint8,uint64,uint64,uint64,uint128)[]))', + 'deployAndUpgradeTo(address,address)', + 'setRewardConfig(address,address)', + ], + [ + setFactoryCalldata, + setConfigurationCalldata, + deployAndUpgradeToCalldata, + setRewardConfigCalldata, + ], + ] + ); + + const COMPAmountToBridge = exp(10_000, 18); + + const goerliActions = [ + // 1. Set Comet configuration + deployAndUpgradeTo new Comet, set reward config on Optimism-Goerli + { + contract: opL1CrossDomainMessenger, + signature: 'sendMessage(address,bytes,uint32)', + args: [bridgeReceiver.address, l2ProposalData, 3_500_000], + }, + + // 2. Approve Goerli's L1StandardBridge to take Timelock's COMP (for bridging) + { + contract: goerliCOMP, + signature: 'approve(address,uint256)', + args: [opL1StandardBridge.address, COMPAmountToBridge], + }, + // 3. Bridge COMP from Goerli to Base-Goerli Comet using L1StandardBridge + { + contract: opL1StandardBridge, + // function depositERC20To(address _l1Token, address _l2Token, address _to, uint256 _amount, uint32 _l2Gas,bytes calldata _data) + signature: + 'depositERC20To(address,address,address,uint256,uint32,bytes)', + args: [ + goerliCOMP.address, + opCOMPAddress, + rewards.address, + COMPAmountToBridge, + 200_000, + '0x', + ], + }, + + // 5. Update the list of official markets + { + target: ENSResolverAddress, + signature: 'setText(bytes32,string,string)', + calldata: ethers.utils.defaultAbiCoder.encode( + ['bytes32', 'string', 'string'], + [subdomainHash, ENSTextRecordKey, JSON.stringify(officialMarketsJSON)] + ), + }, + ]; + + const description = + 'Proposal to set Comet configuration, deployAndUpgradeTo new Comet, set reward config on Optimism-Goerli, bridge COMP from Goerli to Optimism-Goerli Comet, and update the list of official markets.'; + const txn = await govDeploymentManager.retry(async () => + trace( + await governor.propose(...(await proposal(goerliActions, description))) + ) + ); + + const event = txn.events.find((event) => event.event === 'ProposalCreated'); + const [proposalId] = event.args; + + trace(`Created proposal ${proposalId}.`); + }, + + async enacted(deploymentManager: DeploymentManager): Promise { + return true; + }, + + async verify( + deploymentManager: DeploymentManager, + govDeploymentManager: DeploymentManager, + preMigrationBlockNumber: number + ) { + const ethers = deploymentManager.hre.ethers; + await deploymentManager.spider(); // We spider here to pull in Optimism COMP now that reward config has been set + + const { + comet, + rewards, + COMP, + WETH, + } = await deploymentManager.getContracts(); + + // 1. + const stateChanges = await diffState( + comet, + getCometConfig, + preMigrationBlockNumber + ); + expect(stateChanges).to.deep.equal({ + pauseGuardian: '0xBA5e81fD6811E2699b478d1Bcde62a585bC9b6f7', //// Should be updated to the correct address. Create by script clone multi sig + baseTrackingSupplySpeed: exp(34.74 / 86400, 15, 18), + baseTrackingBorrowSpeed: exp(34.74 / 86400, 15, 18), + WETH: { + supplyCap: exp(1000, 18), /// Should be updated to the correct value + }, + OP: { + supplyCap: exp(800, 18), /// Should be updated to the correct value + }, + WBTC: { + supplyCap: exp(800, 18), /// Should be updated to the correct value + }, + }); + + const config = await rewards.rewardConfig(comet.address); + expect(config.token).to.be.equal(COMP.address); + expect(config.rescaleFactor).to.be.equal(exp(1, 12)); + expect(config.shouldUpscale).to.be.equal(true); + + expect(await COMP.balanceOf(rewards.address)).to.be.equal(exp(20_000, 18)); + + const ENSResolver = await govDeploymentManager.existing( + 'ENSResolver', + ENSResolverAddress, + 'goerli' + ); + const subdomainHash = ethers.utils.namehash(ENSSubdomain); + const officialMarketsJSON = await ENSResolver.text( + subdomainHash, + ENSTextRecordKey + ); + const officialMarkets = JSON.parse(officialMarketsJSON); + ///// parse from contract and update this before migration + expect(officialMarkets).to.deep.equal({ + 5: [ + { + baseSymbol: 'USDC', + cometAddress: '0x3EE77595A8459e93C2888b13aDB354017B198188', + }, + { + baseSymbol: 'WETH', + cometAddress: '0x9A539EEc489AAA03D588212a164d0abdB5F08F5F', + }, + ], + 80001: [ + { + baseSymbol: 'USDC', + cometAddress: '0xF09F0369aB0a875254fB565E52226c88f10Bc839', + }, + ], + 421613: [ + { + baseSymbol: 'USDC', + cometAddress: '0x1d573274E19174260c5aCE3f2251598959d24456', + }, + ], + 84531: [ + { + baseSymbol: 'USDC', + cometAddress: '0xe78Fc55c884704F9485EDa042fb91BfE16fD55c1', + }, + ], + 420: [ + { + baseSymbol: 'USDT', + cometAddress: comet.address, + }, + ], + }); + }, +}); diff --git a/deployments/optimism-goerli/usdt/relations.ts b/deployments/optimism-goerli/usdt/relations.ts new file mode 100644 index 000000000..82f918493 --- /dev/null +++ b/deployments/optimism-goerli/usdt/relations.ts @@ -0,0 +1,27 @@ +import baseRelationConfig from '../../relations'; + +export default { + ...baseRelationConfig, + governor: { + artifact: + 'contracts/bridges/optimism/OptimismBridgeReceiver.sol:OptimismBridgeReceiver', + }, + + l2CrossDomainMessenger: { + delegates: { + field: { + slot: + '0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc', + }, + }, + }, + + l2StandardBridge: { + delegates: { + field: { + slot: + '0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc', + }, + }, + }, +}; diff --git a/deployments/optimism-goerli/usdt/roots.json b/deployments/optimism-goerli/usdt/roots.json new file mode 100644 index 000000000..a802e529e --- /dev/null +++ b/deployments/optimism-goerli/usdt/roots.json @@ -0,0 +1,5 @@ +{ + "WETH": "0x4200000000000000000000000000000000000006", + "l2CrossDomainMessenger": "0x4200000000000000000000000000000000000007", + "l2StandardBridge": "0x4200000000000000000000000000000000000010" +} diff --git a/deployments/optimism/usdc/configuration.json b/deployments/optimism/usdc/configuration.json index 4f61c0000..0bae60abc 100644 --- a/deployments/optimism/usdc/configuration.json +++ b/deployments/optimism/usdc/configuration.json @@ -4,9 +4,9 @@ "baseToken": "USDC", "baseTokenAddress": "0x0b2C639c533813f4Aa9D7837CAf62653d097Ff85", "baseTokenPriceFeed": "0x16a9FA2FDa030272Ce99B29CF780dFA30361E0f3", - "borrowMin": "1e6", - "storeFrontPriceFactor": 0.5, - "targetReserves": "1000000e6", + "borrowMin": "1e0", + "storeFrontPriceFactor": 0.6, + "targetReserves": "5000000e6", "rates": { "supplyKink": 0.8, "supplySlopeLow": 0.0325, @@ -19,9 +19,9 @@ }, "tracking": { "indexScale": "1e15", - "baseSupplySpeed": "0.000402083333333e15", - "baseBorrowSpeed": "0.000402083333333e15", - "baseMinForRewards": "10000e6" + "baseSupplySpeed": "347_222_222_222e0", + "baseBorrowSpeed": "173_611_111_111e0", + "baseMinForRewards": "1000e6" }, "assets": { "WETH": { diff --git a/deployments/optimism/usdc/migrations/1707394874_configurate_and_ens.ts b/deployments/optimism/usdc/migrations/1707394874_configurate_and_ens.ts new file mode 100644 index 000000000..b2b93e4f3 --- /dev/null +++ b/deployments/optimism/usdc/migrations/1707394874_configurate_and_ens.ts @@ -0,0 +1,311 @@ +import { DeploymentManager } from '../../../../plugins/deployment_manager/DeploymentManager'; +import { migration } from '../../../../plugins/deployment_manager/Migration'; +import { + diffState, + getCometConfig, +} from '../../../../plugins/deployment_manager/DiffState'; +import { + calldata, + exp, + getConfigurationStruct, + proposal, +} from '../../../../src/deploy'; +import { expect } from 'chai'; +import { WBTC } from '../../../../test/liquidation/addresses'; + +const ENSName = 'compound-community-licenses.eth'; +const ENSResolverAddress = '0x4976fb03C32e5B8cfe2b6cCB31c09Ba78EBaBa41'; +const ENSRegistryAddress = '0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e'; +const ENSSubdomainLabel = 'v3-additional-grants'; +const ENSSubdomain = `${ENSSubdomainLabel}.${ENSName}`; +const ENSTextRecordKey = 'v3-official-markets'; +const opCOMPAddress = '0x9e1028F5F1D5eDE59748FFceE5532509976840E0'; /// TODO : should be deployed before migration. + +const USDCAddress = '0x0b2C639c533813f4Aa9D7837CAf62653d097Ff85'; + +export default migration('1707394874_configurate_and_ens', { + prepare: async (deploymentManager: DeploymentManager) => { + return {}; + }, + + enact: async ( + deploymentManager: DeploymentManager, + govDeploymentManager: DeploymentManager + ) => { + const trace = deploymentManager.tracer(); + const ethers = deploymentManager.hre.ethers; + const { utils } = ethers; + + const { + bridgeReceiver, + comet, + cometAdmin, + configurator, + rewards, + USDC, + } = await deploymentManager.getContracts(); + + const { + opL1CrossDomainMessenger, + opL1StandardBridge, + governor, + comptrollerV2, + COMP: mainnetCOMP, + USDC: mainnetUSDC, + } = await govDeploymentManager.getContracts(); + + // ENS Setup + // See also: https://docs.ens.domains/contract-api-reference/name-processing + const ENSResolver = await govDeploymentManager.existing( + 'ENSResolver', + ENSResolverAddress + ); + const subdomainHash = ethers.utils.namehash(ENSSubdomain); + const baseChainId = ( + await deploymentManager.hre.ethers.provider.getNetwork() + ).chainId.toString(); + const newMarketObject = { + baseSymbol: 'USDC', + cometAddress: comet.address, + }; + const officialMarketsJSON = JSON.parse( + await ENSResolver.text(subdomainHash, ENSTextRecordKey) + ); + if (officialMarketsJSON[baseChainId]) { + officialMarketsJSON[baseChainId].push(newMarketObject); + } else { + officialMarketsJSON[baseChainId] = [newMarketObject]; + } + + const configuration = await getConfigurationStruct(deploymentManager); + + const setConfigurationCalldata = await calldata( + configurator.populateTransaction.setConfiguration( + comet.address, + configuration + ) + ); + const deployAndUpgradeToCalldata = utils.defaultAbiCoder.encode( + ['address', 'address'], + [configurator.address, comet.address] + ); + const setRewardConfigCalldata = utils.defaultAbiCoder.encode( + ['address', 'address'], + [comet.address, opCOMPAddress] + ); + const l2ProposalData = utils.defaultAbiCoder.encode( + ['address[]', 'uint256[]', 'string[]', 'bytes[]'], + [ + [configurator.address, cometAdmin.address, rewards.address], + [0, 0, 0], + [ + 'setConfiguration(address,(address,address,address,address,address,uint64,uint64,uint64,uint64,uint64,uint64,uint64,uint64,uint64,uint64,uint64,uint64,uint104,uint104,uint104,(address,address,uint8,uint64,uint64,uint64,uint128)[]))', + 'deployAndUpgradeTo(address,address)', + 'setRewardConfig(address,address)', + ], + [ + setConfigurationCalldata, + deployAndUpgradeToCalldata, + setRewardConfigCalldata, + ], + ] + ); + //// TODO : should know the amount to bridge.????? + const COMPAmountToBridge = exp(12_500, 18); + const USDCAmountToBridge = exp(10_000, 6); + + const actions = [ + // 1. Set Comet configuration + deployAndUpgradeTo new Comet and set reward config on Optimism. + { + contract: opL1CrossDomainMessenger, + signature: 'sendMessage(address,bytes,uint32)', + args: [bridgeReceiver.address, l2ProposalData, 2_500_000], + }, + + // 2. Approve Ethereum's L1StandardBridge to take Timelock's USDC (for bridging) + { + contract: mainnetUSDC, + signature: 'approve(address,uint256)', + args: [opL1StandardBridge.address, USDCAmountToBridge], + }, + // 3. Bridge USDC from Ethereum to Base Comet using L1StandardBridge + { + contract: opL1StandardBridge, + // function depositERC20To(address _l1Token, address _l2Token, address _to, uint256 _amount, uint32 _l2Gas,bytes calldata _data) + signature: + 'depositERC20To(address,address,address,uint256,uint32,bytes)', + args: [ + mainnetUSDC.address, + USDC.address, + comet.address, + USDCAmountToBridge, + 200_000, + '0x', + ], + }, + + // 4. Approve Ethereum's L1StandardBridge to take Timelock's COMP (for bridging) + { + contract: mainnetCOMP, + signature: 'approve(address,uint256)', + args: [opL1StandardBridge.address, COMPAmountToBridge], + }, + // 5. Bridge COMP from Ethereum to OP Rewards using L1StandardBridge + { + contract: opL1StandardBridge, + // function depositERC20To(address _l1Token, address _l2Token, address _to, uint256 _amount, uint32 _l2Gas,bytes calldata _data) + signature: + 'depositERC20To(address,address,address,uint256,uint32,bytes)', + args: [ + mainnetCOMP.address, + opCOMPAddress, + rewards.address, + COMPAmountToBridge, + 200_000, + '0x', + ], + }, + + // 6. Update the list of official markets + { + target: ENSResolverAddress, + signature: 'setText(bytes32,string,string)', + calldata: ethers.utils.defaultAbiCoder.encode( + ['bytes32', 'string', 'string'], + [subdomainHash, ENSTextRecordKey, JSON.stringify(officialMarketsJSON)] + ), + }, + + // 7. Displace v2 USDC COMP rewards + { + contract: comptrollerV2, + signature: '_setCompSpeeds(address[],uint256[],uint256[])', + args: [[USDCAddress], [9194444444444444n], [15444444444444444n]], + }, + ]; + + const description = '?????????????????'; + const txn = await govDeploymentManager.retry(async () => + trace(await governor.propose(...(await proposal(actions, description)))) + ); + + const event = txn.events.find((event) => event.event === 'ProposalCreated'); + const [proposalId] = event.args; + + trace(`Created proposal ${proposalId}.`); + }, + + async enacted(deploymentManager: DeploymentManager): Promise { + return true; + }, + + async verify( + deploymentManager: DeploymentManager, + govDeploymentManager: DeploymentManager, + preMigrationBlockNumber: number + ) { + const ethers = deploymentManager.hre.ethers; + await deploymentManager.spider(); // We spider here to pull in Base COMP now that reward config has been set + + const { + comet, + rewards, + COMP, + USDC, + } = await deploymentManager.getContracts(); + + const { comptrollerV2 } = await govDeploymentManager.getContracts(); + + // 1. + const stateChanges = await diffState( + comet, + getCometConfig, + preMigrationBlockNumber + ); + expect(stateChanges).to.deep.equal({ + baseTrackingSupplySpeed: exp(30 / 86400, 15, 18), /// TODO : should be changed after we know the exact value. + baseTrackingBorrowSpeed: exp(15 / 86400, 15, 18), /// TODO : should be changed after we know the exact value. + WETH: { + supplyCap: exp(11000, 18), + }, + OP: { + supplyCap: exp(7500, 18), + }, + WBTC: { + supplyCap: exp(500, 8), + }, + }); + + const config = await rewards.rewardConfig(comet.address); + expect(config.token).to.be.equal(COMP.address); + expect(config.rescaleFactor).to.be.equal(exp(1, 12)); /// TODO : should be changed after we know the exact value. + expect(config.shouldUpscale).to.be.equal(true); /// TODO : should be changed after we know the exact value. + + // 2. & 3. + expect(await USDC.balanceOf(comet.address)).to.be.equal(exp(10_000, 6)); /// TODO : should be changed after we know the exact value. + + // 4. & 5. + expect(await COMP.balanceOf(rewards.address)).to.be.equal(exp(12_500, 18)); /// TODO : should be changed after we know the exact value. + + // 6. + const ENSResolver = await govDeploymentManager.existing( + 'ENSResolver', + ENSResolverAddress + ); + const subdomainHash = ethers.utils.namehash(ENSSubdomain); + const officialMarketsJSON = await ENSResolver.text( + subdomainHash, + ENSTextRecordKey + ); + const officialMarkets = JSON.parse(officialMarketsJSON); + expect(officialMarkets).to.deep.equal({ + //// Update the list of official markets before make migration + 1: [ + { + baseSymbol: 'USDC', + cometAddress: '0xc3d688B66703497DAA19211EEdff47f25384cdc3', + }, + { + baseSymbol: 'WETH', + cometAddress: '0xA17581A9E3356d9A858b789D68B4d866e593aE94', + }, + ], + 137: [ + { + baseSymbol: 'USDC', + cometAddress: '0xF25212E676D1F7F89Cd72fFEe66158f541246445', + }, + ], + 42161: [ + { + baseSymbol: 'USDC', + cometAddress: '0xA5EDBDD9646f8dFF606d7448e414884C7d905dCA', + }, + ], + 10: [ + { + baseSymbol: 'USDC', + cometAddress: comet.address, + }, + ], + }); + + // 7. + expect(await comptrollerV2.compSupplySpeeds(USDCAddress)).to.be.equal( + /// TODO : should be changed after we know the exact value. + 9194444444444444n + ); // 66.2 COMP/day + expect(await comptrollerV2.compBorrowSpeeds(USDCAddress)).to.be.equal( + /// TODO : should be changed after we know the exact value. + 15444444444444444n + ); // 111.2 COMP/day + expect(await comet.baseTrackingSupplySpeed()).to.be.equal( + /// TODO : should be changed after we know the exact value. + exp(30 / 86400, 15, 18) + ); + expect(await comet.baseTrackingBorrowSpeed()).to.be.equal( + /// TODO : should be changed after we know the exact value. + exp(15 / 86400, 15, 18) + ); + }, +}); diff --git a/deployments/optimism/usdt/configuration.json b/deployments/optimism/usdt/configuration.json new file mode 100644 index 000000000..5fca03394 --- /dev/null +++ b/deployments/optimism/usdt/configuration.json @@ -0,0 +1,55 @@ +{ + "name": "Compound USDT", + "symbol": "cUSDTv3", + "baseToken": "USDT", + "baseTokenAddress": "0x94b008aA00579c1307B0EF2c499aD98a8ce58e58", + "baseTokenPriceFeed": "0xECef79E109e997bCA29c1c0897ec9d7b03647F5E", + "borrowMin": "1e0", + "storeFrontPriceFactor": 0.6, + "targetReserves": "5000000e6", + "rates": { + "supplyKink": 0.8, + "supplySlopeLow": 0.0325, + "supplySlopeHigh": 0.4, + "supplyBase": 0, + "borrowKink": 0.8, + "borrowSlopeLow": 0.035, + "borrowSlopeHigh": 0.25, + "borrowBase": 0.015 + }, + "tracking": { + "indexScale": "1e15", + "baseSupplySpeed": "347_222_222_222e0", + "baseBorrowSpeed": "173_611_111_111e0", + "baseMinForRewards": "1000e6" + }, + "assets": { + "WETH": { + "address": "0x4200000000000000000000000000000000000006", + "priceFeed": "0x13e3Ee699D1909E989722E753853AE30b17e08c5", + "decimals": "18", + "borrowCF": 0.75, + "liquidateCF": 0.8, + "liquidationFactor": 0.93, + "supplyCap": "800e18" + }, + "WBTC": { + "address": "0x68f180fcCe6836688e9084f035309E29Bf0A2095", + "priceFeed": "0xD702DD976Fb76Fffc2D3963D037dfDae5b04E593", + "decimals": "8", + "borrowCF": 0.7, + "liquidateCF": 0.77, + "liquidationFactor": 0.95, + "supplyCap": "0e8" + }, + "OP": { + "address": "0x4200000000000000000000000000000000000042", + "priceFeed": "0x0D276FC14719f9292D5C1eA2198673d1f4269246", + "decimals": "18", + "borrowCF": 0.75, + "liquidateCF": 0.8, + "liquidationFactor": 0.93, + "supplyCap": "800e18" + } + } +} diff --git a/deployments/optimism/usdt/deploy.ts b/deployments/optimism/usdt/deploy.ts new file mode 100644 index 000000000..421493026 --- /dev/null +++ b/deployments/optimism/usdt/deploy.ts @@ -0,0 +1,83 @@ +import { + Deployed, + DeploymentManager, +} from '../../../plugins/deployment_manager'; +import { DeploySpec, deployComet } from '../../../src/deploy'; + +const HOUR = 60 * 60; +const DAY = 24 * HOUR; + +const MAINNET_TIMELOCK = '0x6d903f6003cca6255d85cca4d3b5e5146dc33925'; + +export default async function deploy( + deploymentManager: DeploymentManager, + deploySpec: DeploySpec +): Promise { + const deployed = await deployContracts(deploymentManager, deploySpec); + return deployed; +} + +async function deployContracts( + deploymentManager: DeploymentManager, + deploySpec: DeploySpec +): Promise { + const trace = deploymentManager.tracer(); + + // Import shared contracts from cUSDCv3 + const cometAdmin = await deploymentManager.fromDep( + 'cometAdmin', + 'optimism', + 'usdc' + ); + const cometFactory = await deploymentManager.fromDep( + 'cometFactory', + 'optimism', + 'usdc' + ); + const $configuratorImpl = await deploymentManager.fromDep( + 'configurator:implementation', + 'optimism', + 'usdc' + ); + const configurator = await deploymentManager.fromDep( + 'configurator', + 'optimism', + 'usdc' + ); + const rewards = await deploymentManager.fromDep( + 'rewards', + 'optimism', + 'usdc' + ); + const bulker = await deploymentManager.fromDep('bulker', 'optimism', 'usdc'); + const l2CrossDomainMessenger = await deploymentManager.fromDep( + 'l2CrossDomainMessenger', + 'optimism', + 'usdc' + ); + const l2StandardBridge = await deploymentManager.fromDep( + 'l2StandardBridge', + 'optimism', + 'usdc' + ); + const localTimelock = await deploymentManager.fromDep( + 'timelock', + 'optimism', + 'usdc' + ); + const bridgeReceiver = await deploymentManager.fromDep( + 'bridgeReceiver', + 'optimism', + 'usdc' + ); + + const deployed = await deployComet(deploymentManager, deploySpec); + + return { + ...deployed, + bridgeReceiver, + l2CrossDomainMessenger, // TODO: don't have to part of roots. can be pulled via relations + l2StandardBridge, + bulker, + }; +} diff --git a/deployments/optimism/usdt/migrations/1707399040_configurate_and_ens.ts b/deployments/optimism/usdt/migrations/1707399040_configurate_and_ens.ts new file mode 100644 index 000000000..3e721c5af --- /dev/null +++ b/deployments/optimism/usdt/migrations/1707399040_configurate_and_ens.ts @@ -0,0 +1,269 @@ +import { DeploymentManager } from '../../../../plugins/deployment_manager/DeploymentManager'; +import { + diffState, + getCometConfig, +} from '../../../../plugins/deployment_manager/DiffState'; +import { migration } from '../../../../plugins/deployment_manager/Migration'; +import { + calldata, + exp, + getConfigurationStruct, + proposal, +} from '../../../../src/deploy'; +import { expect } from 'chai'; + +const SECONDS_PER_YEAR = 31_536_000n; +const ENSName = 'compound-community-licenses.eth'; +const ENSResolverAddress = '0x4976fb03C32e5B8cfe2b6cCB31c09Ba78EBaBa41'; +const ENSRegistryAddress = '0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e'; +const ENSSubdomainLabel = 'v3-additional-grants'; +const ENSSubdomain = `${ENSSubdomainLabel}.${ENSName}`; +const ENSTextRecordKey = 'v3-official-markets'; +const opCOMPAddress = '0x9e1028F5F1D5eDE59748FFceE5532509976840E0'; // COMP on Optimism. Should be deployed before this deployment. + +const USDCAddress = '0x0b2C639c533813f4Aa9D7837CAf62653d097Ff85'; + +export default migration('1707399040_configurate_and_ens', { + prepare: async (deploymentManager: DeploymentManager) => { + return {}; + }, + + enact: async ( + deploymentManager: DeploymentManager, + govDeploymentManager: DeploymentManager + ) => { + const trace = deploymentManager.tracer(); + const ethers = deploymentManager.hre.ethers; + const { utils } = ethers; + + const cometFactory = await deploymentManager.fromDep( + 'cometFactory', + 'optimism', + 'usdc' + ); + const { + bridgeReceiver, + timelock: localTimelock, + comet, + cometAdmin, + configurator, + rewards, + } = await deploymentManager.getContracts(); + + const { + opL1CrossDomainMessenger, + opL1StandardBridge, + governor, + comptrollerV2, + } = await govDeploymentManager.getContracts(); + + // ENS Setup + // See also: https://docs.ens.domains/contract-api-reference/name-processing + const ENSResolver = await govDeploymentManager.existing( + 'ENSResolver', + ENSResolverAddress + ); + const subdomainHash = ethers.utils.namehash(ENSSubdomain); + const opChainId = ( + await deploymentManager.hre.ethers.provider.getNetwork() + ).chainId.toString(); + const newMarketObject = { baseSymbol: 'WETH', cometAddress: comet.address }; + const officialMarketsJSON = JSON.parse( + await ENSResolver.text(subdomainHash, ENSTextRecordKey) + ); + if (officialMarketsJSON[opChainId]) { + officialMarketsJSON[opChainId].push(newMarketObject); + } else { + officialMarketsJSON[opChainId] = [newMarketObject]; + } + + const configuration = await getConfigurationStruct(deploymentManager); + const setFactoryCalldata = await calldata( + configurator.populateTransaction.setFactory( + comet.address, + cometFactory.address + ) + ); + const setConfigurationCalldata = await calldata( + configurator.populateTransaction.setConfiguration( + comet.address, + configuration + ) + ); + const deployAndUpgradeToCalldata = utils.defaultAbiCoder.encode( + ['address', 'address'], + [configurator.address, comet.address] + ); + const setRewardConfigCalldata = utils.defaultAbiCoder.encode( + ['address', 'address'], + [comet.address, opCOMPAddress] + ); + + const l2ProposalData = utils.defaultAbiCoder.encode( + ['address[]', 'uint256[]', 'string[]', 'bytes[]'], + [ + [ + configurator.address, + configurator.address, + cometAdmin.address, + rewards.address, + ], + [0, 0, 0, 0], + [ + 'setFactory(address,address)', + 'setConfiguration(address,(address,address,address,address,address,uint64,uint64,uint64,uint64,uint64,uint64,uint64,uint64,uint64,uint64,uint64,uint64,uint104,uint104,uint104,(address,address,uint8,uint64,uint64,uint64,uint128)[]))', + 'deployAndUpgradeTo(address,address)', + 'setRewardConfig(address,address)', + ], + [ + setFactoryCalldata, + setConfigurationCalldata, + deployAndUpgradeToCalldata, + setRewardConfigCalldata, + ], + ] + ); + + const actions = [ + // 1. Set Comet configuration + deployAndUpgradeTo new Comet, set reward config on Optimism + { + contract: opL1CrossDomainMessenger, + signature: 'sendMessage(address,bytes,uint32)', + args: [bridgeReceiver.address, l2ProposalData, 3_000_000], + }, + + // 2. Update the list of official markets + { + target: ENSResolverAddress, + signature: 'setText(bytes32,string,string)', + calldata: ethers.utils.defaultAbiCoder.encode( + ['bytes32', 'string', 'string'], + [subdomainHash, ENSTextRecordKey, JSON.stringify(officialMarketsJSON)] + ), + }, + + // 3. Displace v2 USDC COMP rewards + { + contract: comptrollerV2, + signature: '_setCompSpeeds(address[],uint256[],uint256[])', + args: [[USDCAddress], [9194444444444444n], [12666666666666667n]], //// Should be updated to the correct values + }, + ]; + + const description = 'Proposal text goes here.'; + const txn = await govDeploymentManager.retry(async () => + trace(await governor.propose(...(await proposal(actions, description)))) + ); + + const event = txn.events.find((event) => event.event === 'ProposalCreated'); + const [proposalId] = event.args; + + trace(`Created proposal ${proposalId}.`); + }, + + async enacted(deploymentManager: DeploymentManager): Promise { + return true; + }, + + async verify( + deploymentManager: DeploymentManager, + govDeploymentManager: DeploymentManager, + preMigrationBlockNumber: number + ) { + const ethers = deploymentManager.hre.ethers; + await deploymentManager.spider(); // We spider here to pull in Base COMP now that reward config has been set + + const { comet, rewards, COMP } = await deploymentManager.getContracts(); + + const { comptrollerV2 } = await govDeploymentManager.getContracts(); + + // 1. + const stateChanges = await diffState( + comet, + getCometConfig, + preMigrationBlockNumber + ); + expect(stateChanges).to.deep.equal({ + baseTrackingSupplySpeed: exp(20 / 86400, 15, 18), /// Should be updated to the correct value + storeFrontPriceFactor: exp(1, 18), /// Should be updated to the correct value + borrowPerSecondInterestRateSlopeLow: exp(0.037, 18) / SECONDS_PER_YEAR, /// Should be updated to the correct value + WETH: { + supplyCap: exp(11000, 18), /// Should be updated to the correct value + }, + OP: { + supplyCap: exp(7500, 18), /// Should be updated to the correct value + }, + WBTC: { + supplyCap: exp(500, 8), /// Should be updated to the correct value + }, + }); + + const config = await rewards.rewardConfig(comet.address); + expect(config.token).to.be.equal(COMP.address); + expect(config.rescaleFactor).to.be.equal(exp(1, 12)); /// Should be updated to the correct value + expect(config.shouldUpscale).to.be.equal(true); /// Should be updated to the correct value + + const ENSResolver = await govDeploymentManager.existing( + 'ENSResolver', + ENSResolverAddress + ); + const subdomainHash = ethers.utils.namehash(ENSSubdomain); + const officialMarketsJSON = await ENSResolver.text( + subdomainHash, + ENSTextRecordKey + ); + const officialMarkets = JSON.parse(officialMarketsJSON); + + expect(officialMarkets).to.deep.equal({ + /// parse and update before migration + 1: [ + { + baseSymbol: 'USDC', + cometAddress: '0xc3d688B66703497DAA19211EEdff47f25384cdc3', + }, + { + baseSymbol: 'WETH', + cometAddress: '0xA17581A9E3356d9A858b789D68B4d866e593aE94', + }, + ], + 137: [ + { + baseSymbol: 'USDC', + cometAddress: '0xF25212E676D1F7F89Cd72fFEe66158f541246445', + }, + ], + 42161: [ + { + baseSymbol: 'USDC', + cometAddress: '0xA5EDBDD9646f8dFF606d7448e414884C7d905dCA', + }, + ], + 8453: [ + { + baseSymbol: 'USDbC', + cometAddress: '0x9c4ec768c28520B50860ea7a15bd7213a9fF58bf', + }, + ], + 10: [ + { + baseSymbol: 'USDT', + cometAddress: comet.address, + }, + ], + }); + + // 4. + expect(await comptrollerV2.compSupplySpeeds(USDCAddress)).to.be.equal( + 9194444444444444n //// Should be updated to the correct value + ); // 66.2 COMP/day + expect(await comptrollerV2.compBorrowSpeeds(USDCAddress)).to.be.equal( + 12666666666666667n //// Should be updated to the correct value + ); // 91.2 COMP/day + expect(await comet.baseTrackingSupplySpeed()).to.be.equal( + exp(20 / 86400, 15, 18) //// Should be updated to the correct value + ); + expect(await comet.baseTrackingBorrowSpeed()).to.be.equal( + exp(0 / 86400, 15, 18) //// Should be updated to the correct value + ); + }, +}); diff --git a/deployments/optimism/usdt/relations.ts b/deployments/optimism/usdt/relations.ts new file mode 100644 index 000000000..c216eae18 --- /dev/null +++ b/deployments/optimism/usdt/relations.ts @@ -0,0 +1,30 @@ +import baseRelationConfig from '../../relations'; + +export default { + ...baseRelationConfig, + governor: { + artifact: + 'contracts/bridges/optimism/OptimismBridgeReceiver.sol:OptimismBridgeReceiver', + }, + Proxy: { + artifact: 'contracts/ERC20.sol:ERC20', + }, + + l2CrossDomainMessenger: { + delegates: { + field: { + slot: + '0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc', + }, + }, + }, + + l2StandardBridge: { + delegates: { + field: { + slot: + '0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc', + }, + }, + }, +}; diff --git a/deployments/optimism/usdt/roots.json b/deployments/optimism/usdt/roots.json new file mode 100644 index 000000000..216adbd8f --- /dev/null +++ b/deployments/optimism/usdt/roots.json @@ -0,0 +1,4 @@ +{ + "l2CrossDomainMessenger": "0x4200000000000000000000000000000000000007", + "l2StandardBridge": "0x4200000000000000000000000000000000000010" +} diff --git a/hardhat.config.ts b/hardhat.config.ts index f41205f57..16bb0eaf7 100644 --- a/hardhat.config.ts +++ b/hardhat.config.ts @@ -34,6 +34,9 @@ import baseGoerliRelationConfigMap from './deployments/base-goerli/usdc/relation import baseGoerliWethRelationConfigMap from './deployments/base-goerli/weth/relations'; import lineaGoerliRelationConfigMap from './deployments/linea-goerli/usdc/relations'; import optimismRelationConfigMap from './deployments/optimism/usdc/relations'; +import optimismUsdtRelationConfigMap from './deployments/optimism/usdt/relations'; +import optimismGoerliRelationConfigMap from './deployments/optimism-goerli/usdc/relations'; +import optimismGoerliUsdtRelationConfigMap from './deployments/optimism-goerli/usdt/relations'; task('accounts', 'Prints the list of accounts', async (taskArgs, hre) => { for (const account of await hre.ethers.getSigners()) @@ -111,6 +114,11 @@ const networkConfigs: NetworkConfig[] = [ chainId: 10, url: `https://optimism-mainnet.infura.io/v3/${INFURA_KEY}`, }, + { + network: 'optimism-goerli', + chainId: 420, + url: `https://optimism-goerli.infura.io/v3/${INFURA_KEY}`, + }, { network: 'base', chainId: 8453, @@ -251,6 +259,7 @@ const config: HardhatUserConfig = { // Linea 'linea-goerli': LINEASCAN_KEY, optimism: OPTIMISMSCAN_KEY, + 'optimism-goerli': OPTIMISMSCAN_KEY, }, customChains: [ { @@ -297,6 +306,14 @@ const config: HardhatUserConfig = { browserURL: 'https://goerli.lineascan.build/', }, }, + { + network: 'optimism-goerli', + chainId: 420, + urls: { + apiURL: 'https://api-goerli-optimistic.etherscan.io/api', + browserURL: 'https://goerli-optimism.etherscan.io/', + }, + }, ], }, @@ -343,6 +360,11 @@ const config: HardhatUserConfig = { }, optimism: { usdc: optimismRelationConfigMap, + usdt: optimismUsdtRelationConfigMap, + }, + 'optimism-goerli': { + usdc: optimismGoerliRelationConfigMap, + usdt: optimismGoerliUsdtRelationConfigMap, }, }, }, @@ -447,11 +469,29 @@ const config: HardhatUserConfig = { auxiliaryBase: 'goerli', }, { - name: 'optimism', + name: 'optimism-usdc', network: 'optimism', deployment: 'usdc', auxiliaryBase: 'mainnet', }, + { + name: 'optimism-usdt', + network: 'optimism', + deployment: 'usdt', + auxiliaryBase: 'mainnet', + }, + { + name: 'optimism-goerli', + network: 'optimism-goerli', + deployment: 'usdc', + auxiliaryBase: 'goerli', + }, + { + name: 'optimism-goerli-usdt', + network: 'optimism-goerli', + deployment: 'usdt', + auxiliaryBase: 'goerli', + }, ], }, diff --git a/plugins/import/etherscan.ts b/plugins/import/etherscan.ts index f46cef4e3..e23666760 100644 --- a/plugins/import/etherscan.ts +++ b/plugins/import/etherscan.ts @@ -22,6 +22,7 @@ export function getEtherscanApiUrl(network: string): string { 'base-goerli': 'api-goerli.basescan.org', 'linea-goerli': 'api-goerli.lineascan.build', optimism: 'api-optimistic.etherscan.io', + 'optimism-goerli': 'api-goerli-optimistic.etherscan.io', }[network]; if (!host) { @@ -47,6 +48,7 @@ export function getEtherscanUrl(network: string): string { 'base-goerli': 'goerli.basescan.org', 'linea-goerli': 'goerli.lineascan.build', optimism: 'optimistic.etherscan.io', + 'optimism-goerli': 'goerli-optimistic.etherscan.io', }[network]; if (!host) { @@ -71,7 +73,8 @@ export function getEtherscanApiKey(network: string): string { base: process.env.BASESCAN_KEY, 'base-goerli': process.env.BASESCAN_KEY, 'linea-goerli': process.env.LINEASCAN_KEY, - optimism: process.env.ETHERSCAN_KEY, + optimism: process.env.OPTIMISMSCAN_KEY, + 'optimism-goerli': process.env.OPTIMISMSCAN_KEY, }[network]; if (!apiKey) { diff --git a/scenario/utils/relayMessage.ts b/scenario/utils/relayMessage.ts index d4856f187..846914228 100644 --- a/scenario/utils/relayMessage.ts +++ b/scenario/utils/relayMessage.ts @@ -20,6 +20,7 @@ export default async function relayMessage( ); break; case 'optimism': + case 'optimism-goerli': await relayBaseMessage( governanceDeploymentManager, bridgeDeploymentManager, From 9a873cff3546bce47e1bd68f07334e544b30380e Mon Sep 17 00:00:00 2001 From: dmitriy-bergman-works Date: Mon, 4 Mar 2024 16:25:23 +0200 Subject: [PATCH 03/37] Add wstETH collateral token --- deployments/optimism/usdc/configuration.json | 9 +++++++++ deployments/optimism/usdc/deploy.ts | 5 +++++ .../usdc/migrations/1707394874_configurate_and_ens.ts | 3 +++ deployments/optimism/usdt/configuration.json | 9 +++++++++ .../usdt/migrations/1707399040_configurate_and_ens.ts | 3 +++ 5 files changed, 29 insertions(+) diff --git a/deployments/optimism/usdc/configuration.json b/deployments/optimism/usdc/configuration.json index 0bae60abc..9b7feb509 100644 --- a/deployments/optimism/usdc/configuration.json +++ b/deployments/optimism/usdc/configuration.json @@ -50,6 +50,15 @@ "liquidateCF": 0.8, "liquidationFactor": 0.93, "supplyCap": "800e18" + }, + "wstETH": { + "address": "0x1F32b1c2345538c0c6f582fCB022739c4A194Ebb", + "priceFeed": "0x698B585CbC4407e2D54aa898B2600B53C68958f7", + "decimals": "18", + "borrowCF": 0.75, + "liquidateCF": 0.8, + "liquidationFactor": 0.93, + "supplyCap": "800e18" } } } diff --git a/deployments/optimism/usdc/deploy.ts b/deployments/optimism/usdc/deploy.ts index a78ded852..83910577a 100644 --- a/deployments/optimism/usdc/deploy.ts +++ b/deployments/optimism/usdc/deploy.ts @@ -44,6 +44,11 @@ async function deployContracts( '0x4200000000000000000000000000000000000042', 'optimism' ); + const wstETH = await await deploymentManager.existing( + 'wstETH', + '0x1F32b1c2345538c0c6f582fCB022739c4A194Ebb', + 'optimism' + ); const l2CrossDomainMessenger = await deploymentManager.existing( 'l2CrossDomainMessenger', diff --git a/deployments/optimism/usdc/migrations/1707394874_configurate_and_ens.ts b/deployments/optimism/usdc/migrations/1707394874_configurate_and_ens.ts index b2b93e4f3..28bdc9634 100644 --- a/deployments/optimism/usdc/migrations/1707394874_configurate_and_ens.ts +++ b/deployments/optimism/usdc/migrations/1707394874_configurate_and_ens.ts @@ -234,6 +234,9 @@ export default migration('1707394874_configurate_and_ens', { WBTC: { supplyCap: exp(500, 8), }, + wstETH: { + supplyCap: exp(500, 18) /// TODO : should be changed after we know the exact value. + } }); const config = await rewards.rewardConfig(comet.address); diff --git a/deployments/optimism/usdt/configuration.json b/deployments/optimism/usdt/configuration.json index 5fca03394..b102f75e8 100644 --- a/deployments/optimism/usdt/configuration.json +++ b/deployments/optimism/usdt/configuration.json @@ -50,6 +50,15 @@ "liquidateCF": 0.8, "liquidationFactor": 0.93, "supplyCap": "800e18" + }, + "wstETH": { + "address": "0x1F32b1c2345538c0c6f582fCB022739c4A194Ebb", + "priceFeed": "0x698B585CbC4407e2D54aa898B2600B53C68958f7", + "decimals": "18", + "borrowCF": 0.75, + "liquidateCF": 0.8, + "liquidationFactor": 0.93, + "supplyCap": "800e18" } } } diff --git a/deployments/optimism/usdt/migrations/1707399040_configurate_and_ens.ts b/deployments/optimism/usdt/migrations/1707399040_configurate_and_ens.ts index 3e721c5af..58f928bdd 100644 --- a/deployments/optimism/usdt/migrations/1707399040_configurate_and_ens.ts +++ b/deployments/optimism/usdt/migrations/1707399040_configurate_and_ens.ts @@ -196,6 +196,9 @@ export default migration('1707399040_configurate_and_ens', { WBTC: { supplyCap: exp(500, 8), /// Should be updated to the correct value }, + wstETH: { + supplyCap: exp(500, 18) /// TODO : should be changed after we know the exact value. + } }); const config = await rewards.rewardConfig(comet.address); From c9204ad26dbe7b72b0bdbe066c6e3b3461c9a5bd Mon Sep 17 00:00:00 2001 From: dmitriy-bergman-works Date: Mon, 4 Mar 2024 16:25:46 +0200 Subject: [PATCH 04/37] Use Gauntlet recommended parameters for configuration --- deployments/optimism/usdc/configuration.json | 44 ++-- .../1707394874_configurate_and_ens.ts | 202 ++++++++---------- deployments/optimism/usdc/roots.json | 3 +- deployments/optimism/usdt/configuration.json | 44 ++-- .../1707399040_configurate_and_ens.ts | 185 +++++++++------- deployments/optimism/usdt/roots.json | 3 +- 6 files changed, 239 insertions(+), 242 deletions(-) diff --git a/deployments/optimism/usdc/configuration.json b/deployments/optimism/usdc/configuration.json index 9b7feb509..b14598f3a 100644 --- a/deployments/optimism/usdc/configuration.json +++ b/deployments/optimism/usdc/configuration.json @@ -6,21 +6,21 @@ "baseTokenPriceFeed": "0x16a9FA2FDa030272Ce99B29CF780dFA30361E0f3", "borrowMin": "1e0", "storeFrontPriceFactor": 0.6, - "targetReserves": "5000000e6", + "targetReserves": "20000000e6", "rates": { - "supplyKink": 0.8, - "supplySlopeLow": 0.0325, - "supplySlopeHigh": 0.4, + "supplyKink": 0.9, + "supplySlopeLow": 0.059, + "supplySlopeHigh": 2.9, "supplyBase": 0, - "borrowKink": 0.8, - "borrowSlopeLow": 0.035, - "borrowSlopeHigh": 0.25, + "borrowKink": 0.9, + "borrowSlopeLow": 0.061, + "borrowSlopeHigh": 3.2, "borrowBase": 0.015 }, "tracking": { "indexScale": "1e15", - "baseSupplySpeed": "347_222_222_222e0", - "baseBorrowSpeed": "173_611_111_111e0", + "baseSupplySpeed": "57_870_370_370e0", + "baseBorrowSpeed": "57_870_370_370e0", "baseMinForRewards": "1000e6" }, "assets": { @@ -28,28 +28,28 @@ "address": "0x4200000000000000000000000000000000000006", "priceFeed": "0x13e3Ee699D1909E989722E753853AE30b17e08c5", "decimals": "18", - "borrowCF": 0.75, - "liquidateCF": 0.8, - "liquidationFactor": 0.93, - "supplyCap": "800e18" + "borrowCF": 0.83, + "liquidateCF": 0.9, + "liquidationFactor": 0.95, + "supplyCap": "1600e18" }, "WBTC": { "address": "0x68f180fcCe6836688e9084f035309E29Bf0A2095", "priceFeed": "0xD702DD976Fb76Fffc2D3963D037dfDae5b04E593", "decimals": "8", - "borrowCF": 0.7, - "liquidateCF": 0.77, + "borrowCF": 0.8, + "liquidateCF": 0.85, "liquidationFactor": 0.95, - "supplyCap": "0e8" + "supplyCap": "60e8" }, "OP": { "address": "0x4200000000000000000000000000000000000042", "priceFeed": "0x0D276FC14719f9292D5C1eA2198673d1f4269246", "decimals": "18", - "borrowCF": 0.75, - "liquidateCF": 0.8, - "liquidationFactor": 0.93, - "supplyCap": "800e18" + "borrowCF": 0.65, + "liquidateCF": 0.7, + "liquidationFactor": 0.8, + "supplyCap": "700000e18" }, "wstETH": { "address": "0x1F32b1c2345538c0c6f582fCB022739c4A194Ebb", @@ -57,8 +57,8 @@ "decimals": "18", "borrowCF": 0.75, "liquidateCF": 0.8, - "liquidationFactor": 0.93, - "supplyCap": "800e18" + "liquidationFactor": 0.9, + "supplyCap": "500e18" } } } diff --git a/deployments/optimism/usdc/migrations/1707394874_configurate_and_ens.ts b/deployments/optimism/usdc/migrations/1707394874_configurate_and_ens.ts index 28bdc9634..cf6bb24ba 100644 --- a/deployments/optimism/usdc/migrations/1707394874_configurate_and_ens.ts +++ b/deployments/optimism/usdc/migrations/1707394874_configurate_and_ens.ts @@ -1,29 +1,27 @@ -import { DeploymentManager } from '../../../../plugins/deployment_manager/DeploymentManager'; -import { migration } from '../../../../plugins/deployment_manager/Migration'; +import { DeploymentManager } from "../../../../plugins/deployment_manager/DeploymentManager"; +import { migration } from "../../../../plugins/deployment_manager/Migration"; import { diffState, getCometConfig, -} from '../../../../plugins/deployment_manager/DiffState'; +} from "../../../../plugins/deployment_manager/DiffState"; import { calldata, exp, getConfigurationStruct, proposal, -} from '../../../../src/deploy'; -import { expect } from 'chai'; -import { WBTC } from '../../../../test/liquidation/addresses'; +} from "../../../../src/deploy"; +import { expect } from "chai"; -const ENSName = 'compound-community-licenses.eth'; -const ENSResolverAddress = '0x4976fb03C32e5B8cfe2b6cCB31c09Ba78EBaBa41'; -const ENSRegistryAddress = '0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e'; -const ENSSubdomainLabel = 'v3-additional-grants'; +const SECONDS_PER_YEAR = 31_536_000n; +const ENSName = "compound-community-licenses.eth"; +const ENSResolverAddress = "0x4976fb03C32e5B8cfe2b6cCB31c09Ba78EBaBa41"; +const ENSRegistryAddress = "0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e"; +const ENSSubdomainLabel = "v3-additional-grants"; const ENSSubdomain = `${ENSSubdomainLabel}.${ENSName}`; -const ENSTextRecordKey = 'v3-official-markets'; -const opCOMPAddress = '0x9e1028F5F1D5eDE59748FFceE5532509976840E0'; /// TODO : should be deployed before migration. +const ENSTextRecordKey = "v3-official-markets"; +const opCOMPAddress = "0x9e1028F5F1D5eDE59748FFceE5532509976840E0"; /// TODO : should be deployed before migration. -const USDCAddress = '0x0b2C639c533813f4Aa9D7837CAf62653d097Ff85'; - -export default migration('1707394874_configurate_and_ens', { +export default migration("1707394874_configurate_and_ens", { prepare: async (deploymentManager: DeploymentManager) => { return {}; }, @@ -36,14 +34,8 @@ export default migration('1707394874_configurate_and_ens', { const ethers = deploymentManager.hre.ethers; const { utils } = ethers; - const { - bridgeReceiver, - comet, - cometAdmin, - configurator, - rewards, - USDC, - } = await deploymentManager.getContracts(); + const { bridgeReceiver, comet, cometAdmin, configurator, rewards } = + await deploymentManager.getContracts(); const { opL1CrossDomainMessenger, @@ -52,12 +44,16 @@ export default migration('1707394874_configurate_and_ens', { comptrollerV2, COMP: mainnetCOMP, USDC: mainnetUSDC, + CCTPTokenMessenger, } = await govDeploymentManager.getContracts(); + // CCTP destination domain for Optimism + const OptimismDestinationDomain = 2; + // ENS Setup // See also: https://docs.ens.domains/contract-api-reference/name-processing const ENSResolver = await govDeploymentManager.existing( - 'ENSResolver', + "ENSResolver", ENSResolverAddress ); const subdomainHash = ethers.utils.namehash(ENSSubdomain); @@ -65,7 +61,7 @@ export default migration('1707394874_configurate_and_ens', { await deploymentManager.hre.ethers.provider.getNetwork() ).chainId.toString(); const newMarketObject = { - baseSymbol: 'USDC', + baseSymbol: "USDC", cometAddress: comet.address, }; const officialMarketsJSON = JSON.parse( @@ -86,22 +82,22 @@ export default migration('1707394874_configurate_and_ens', { ) ); const deployAndUpgradeToCalldata = utils.defaultAbiCoder.encode( - ['address', 'address'], + ["address", "address"], [configurator.address, comet.address] ); const setRewardConfigCalldata = utils.defaultAbiCoder.encode( - ['address', 'address'], + ["address", "address"], [comet.address, opCOMPAddress] ); const l2ProposalData = utils.defaultAbiCoder.encode( - ['address[]', 'uint256[]', 'string[]', 'bytes[]'], + ["address[]", "uint256[]", "string[]", "bytes[]"], [ [configurator.address, cometAdmin.address, rewards.address], [0, 0, 0], [ - 'setConfiguration(address,(address,address,address,address,address,uint64,uint64,uint64,uint64,uint64,uint64,uint64,uint64,uint64,uint64,uint64,uint64,uint104,uint104,uint104,(address,address,uint8,uint64,uint64,uint64,uint128)[]))', - 'deployAndUpgradeTo(address,address)', - 'setRewardConfig(address,address)', + "setConfiguration(address,(address,address,address,address,address,uint64,uint64,uint64,uint64,uint64,uint64,uint64,uint64,uint64,uint64,uint64,uint64,uint104,uint104,uint104,(address,address,uint8,uint64,uint64,uint64,uint128)[]))", + "deployAndUpgradeTo(address,address)", + "setRewardConfig(address,address)", ], [ setConfigurationCalldata, @@ -110,44 +106,38 @@ export default migration('1707394874_configurate_and_ens', { ], ] ); - //// TODO : should know the amount to bridge.????? - const COMPAmountToBridge = exp(12_500, 18); + + const COMPAmountToBridge = exp(3_600, 18); const USDCAmountToBridge = exp(10_000, 6); const actions = [ // 1. Set Comet configuration + deployAndUpgradeTo new Comet and set reward config on Optimism. { contract: opL1CrossDomainMessenger, - signature: 'sendMessage(address,bytes,uint32)', + signature: "sendMessage(address,bytes,uint32)", args: [bridgeReceiver.address, l2ProposalData, 2_500_000], }, - - // 2. Approve Ethereum's L1StandardBridge to take Timelock's USDC (for bridging) + // 2. Approve USDC to CCTP { contract: mainnetUSDC, - signature: 'approve(address,uint256)', - args: [opL1StandardBridge.address, USDCAmountToBridge], + signature: "approve(address,uint256)", + args: [CCTPTokenMessenger.address, USDCAmountToBridge], }, - // 3. Bridge USDC from Ethereum to Base Comet using L1StandardBridge + // 3. Burn USDC to Optimism via CCTP { - contract: opL1StandardBridge, - // function depositERC20To(address _l1Token, address _l2Token, address _to, uint256 _amount, uint32 _l2Gas,bytes calldata _data) - signature: - 'depositERC20To(address,address,address,uint256,uint32,bytes)', + contract: CCTPTokenMessenger, + signature: "depositForBurn(uint256,uint32,bytes32,address)", args: [ - mainnetUSDC.address, - USDC.address, - comet.address, USDCAmountToBridge, - 200_000, - '0x', + OptimismDestinationDomain, + utils.hexZeroPad(comet.address, 32), + mainnetUSDC.address, ], }, - // 4. Approve Ethereum's L1StandardBridge to take Timelock's COMP (for bridging) { contract: mainnetCOMP, - signature: 'approve(address,uint256)', + signature: "approve(address,uint256)", args: [opL1StandardBridge.address, COMPAmountToBridge], }, // 5. Bridge COMP from Ethereum to OP Rewards using L1StandardBridge @@ -155,41 +145,33 @@ export default migration('1707394874_configurate_and_ens', { contract: opL1StandardBridge, // function depositERC20To(address _l1Token, address _l2Token, address _to, uint256 _amount, uint32 _l2Gas,bytes calldata _data) signature: - 'depositERC20To(address,address,address,uint256,uint32,bytes)', + "depositERC20To(address,address,address,uint256,uint32,bytes)", args: [ mainnetCOMP.address, opCOMPAddress, rewards.address, COMPAmountToBridge, 200_000, - '0x', + "0x", ], }, - // 6. Update the list of official markets { target: ENSResolverAddress, - signature: 'setText(bytes32,string,string)', + signature: "setText(bytes32,string,string)", calldata: ethers.utils.defaultAbiCoder.encode( - ['bytes32', 'string', 'string'], + ["bytes32", "string", "string"], [subdomainHash, ENSTextRecordKey, JSON.stringify(officialMarketsJSON)] ), }, - - // 7. Displace v2 USDC COMP rewards - { - contract: comptrollerV2, - signature: '_setCompSpeeds(address[],uint256[],uint256[])', - args: [[USDCAddress], [9194444444444444n], [15444444444444444n]], - }, ]; - const description = '?????????????????'; + const description = "# Initialize cUSDCv3 on Optimism\n\nThis proposal takes the governance steps recommended and necessary to initialize a Compound III USDC market on Optimism; upon execution, cUSDCv3 will be ready for use. Simulations have confirmed the market’s readiness, as much as possible, using the [Comet scenario suite](https://github.com/compound-finance/comet/tree/main/scenario). The new parameters include setting the risk parameters based off of the [recommendations from Gauntlet](https://www.comp.xyz/t/deploy-compound-iii-on-optimism/4975/6). Further detailed information can be found on the corresponding [proposal pull request](https://github.com/compound-finance/comet/pull/792) and [forum discussion](https://www.comp.xyz/t/deploy-compound-iii-on-optimism/4975).\n\n\n## Proposal Actions\n\nThe first proposal action sets the Comet configuration and deploys a new Comet implementation on Optimism. This sends the encoded `setConfiguration` and `deployAndUpgradeTo` calls across the bridge to the governance receiver on Optimism. It also calls `setRewardConfig` on the Optimism rewards contract, to establish Optimism’s bridged version of COMP as the reward token for the deployment and set the initial supply speed to be 5 COMP/day and borrow speed to be 5 COMP/day.\n\nThe second action approves Circle’s Cross-Chain Transfer Protocol (CCTP) [TokenMessenger](https://etherscan.io/address/0xbd3fa81b58ba92a82136038b25adec7066af3155) to take the Timelock's USDC on Mainnet, in order to seed the market reserves through the CCTP.\n\nThe third action deposits and burns 10K USDC from mainnet via depositForBurn function on CCTP’s TokenMessenger contract to mint native USDC to Comet on Optimism.\n\nThe fourth action approves Optimism’s [L1StandardBridge](https://etherscan.io/address/0x99C9fc46f92E8a1c0deC1b1747d010903E884bE1) to take Timelock's COMP, in order to seed the rewards contract through the bridge.\n\nThe fifth action deposits 3.6K COMP from mainnet to the Optimism L1StandardBridge contract to bridge to CometRewards.\n\nThe sixth action updates the ENS TXT record `v3-official-markets` on `v3-additional-grants.compound-community-licenses.eth`, updating the official markets JSON to include the new Optimism cUSDCv3 market"; /// TODO : should be const txn = await govDeploymentManager.retry(async () => trace(await governor.propose(...(await proposal(actions, description)))) ); - const event = txn.events.find((event) => event.event === 'ProposalCreated'); + const event = txn.events.find((event) => event.event === "ProposalCreated"); const [proposalId] = event.args; trace(`Created proposal ${proposalId}.`); @@ -205,16 +187,10 @@ export default migration('1707394874_configurate_and_ens', { preMigrationBlockNumber: number ) { const ethers = deploymentManager.hre.ethers; - await deploymentManager.spider(); // We spider here to pull in Base COMP now that reward config has been set - - const { - comet, - rewards, - COMP, - USDC, - } = await deploymentManager.getContracts(); + await deploymentManager.spider(); - const { comptrollerV2 } = await govDeploymentManager.getContracts(); + const { comet, rewards, COMP, USDC } = + await deploymentManager.getContracts(); // 1. const stateChanges = await diffState( @@ -223,36 +199,41 @@ export default migration('1707394874_configurate_and_ens', { preMigrationBlockNumber ); expect(stateChanges).to.deep.equal({ - baseTrackingSupplySpeed: exp(30 / 86400, 15, 18), /// TODO : should be changed after we know the exact value. - baseTrackingBorrowSpeed: exp(15 / 86400, 15, 18), /// TODO : should be changed after we know the exact value. + storeFrontPriceFactor: exp(0.6, 18), + baseTrackingSupplySpeed: exp(5 / 86400, 15, 18), + baseTrackingBorrowSpeed: exp(5 / 86400, 15, 18), + borrowPerSecondInterestRateSlopeLow: exp(0.061, 18) / SECONDS_PER_YEAR, + borrowPerSecondInterestRateSlopeHigh: exp(3.2, 18) / SECONDS_PER_YEAR, + supplyPerSecondInterestRateSlopeLow: exp(0.059, 18) / SECONDS_PER_YEAR, + supplyPerSecondInterestRateSlopeHigh: exp(2.9, 18) / SECONDS_PER_YEAR, WETH: { - supplyCap: exp(11000, 18), + supplyCap: exp(1600, 18), }, OP: { - supplyCap: exp(7500, 18), + supplyCap: exp(700000, 18), }, WBTC: { - supplyCap: exp(500, 8), + supplyCap: exp(60, 8), }, wstETH: { - supplyCap: exp(500, 18) /// TODO : should be changed after we know the exact value. - } + supplyCap: exp(500, 18), + }, }); const config = await rewards.rewardConfig(comet.address); expect(config.token).to.be.equal(COMP.address); - expect(config.rescaleFactor).to.be.equal(exp(1, 12)); /// TODO : should be changed after we know the exact value. - expect(config.shouldUpscale).to.be.equal(true); /// TODO : should be changed after we know the exact value. + expect(config.rescaleFactor).to.be.equal(exp(1, 12)); + expect(config.shouldUpscale).to.be.equal(true); // 2. & 3. - expect(await USDC.balanceOf(comet.address)).to.be.equal(exp(10_000, 6)); /// TODO : should be changed after we know the exact value. + expect(await USDC.balanceOf(comet.address)).to.be.equal(exp(10_000, 6)); // 4. & 5. - expect(await COMP.balanceOf(rewards.address)).to.be.equal(exp(12_500, 18)); /// TODO : should be changed after we know the exact value. + expect(await COMP.balanceOf(rewards.address)).to.be.equal(exp(3_600, 18)); // 6. const ENSResolver = await govDeploymentManager.existing( - 'ENSResolver', + "ENSResolver", ENSResolverAddress ); const subdomainHash = ethers.utils.namehash(ENSSubdomain); @@ -262,53 +243,48 @@ export default migration('1707394874_configurate_and_ens', { ); const officialMarkets = JSON.parse(officialMarketsJSON); expect(officialMarkets).to.deep.equal({ - //// Update the list of official markets before make migration 1: [ { - baseSymbol: 'USDC', - cometAddress: '0xc3d688B66703497DAA19211EEdff47f25384cdc3', + baseSymbol: "USDC", + cometAddress: "0xc3d688B66703497DAA19211EEdff47f25384cdc3", }, { - baseSymbol: 'WETH', - cometAddress: '0xA17581A9E3356d9A858b789D68B4d866e593aE94', + baseSymbol: "WETH", + cometAddress: "0xA17581A9E3356d9A858b789D68B4d866e593aE94", }, ], 137: [ { - baseSymbol: 'USDC', - cometAddress: '0xF25212E676D1F7F89Cd72fFEe66158f541246445', + baseSymbol: "USDC", + cometAddress: "0xF25212E676D1F7F89Cd72fFEe66158f541246445", + }, + ], + 8453: [ + { + baseSymbol: "USDbC", + cometAddress: "0x9c4ec768c28520B50860ea7a15bd7213a9fF58bf", + }, + { + baseSymbol: "WETH", + cometAddress: "0x46e6b214b524310239732D51387075E0e70970bf", }, ], 42161: [ { - baseSymbol: 'USDC', - cometAddress: '0xA5EDBDD9646f8dFF606d7448e414884C7d905dCA', + baseSymbol: "USDC.e", + cometAddress: "0xA5EDBDD9646f8dFF606d7448e414884C7d905dCA", + }, + { + baseSymbol: "USDC", + cometAddress: "0x9c4ec768c28520B50860ea7a15bd7213a9fF58bf", }, ], 10: [ { - baseSymbol: 'USDC', + baseSymbol: "USDC", cometAddress: comet.address, }, ], }); - - // 7. - expect(await comptrollerV2.compSupplySpeeds(USDCAddress)).to.be.equal( - /// TODO : should be changed after we know the exact value. - 9194444444444444n - ); // 66.2 COMP/day - expect(await comptrollerV2.compBorrowSpeeds(USDCAddress)).to.be.equal( - /// TODO : should be changed after we know the exact value. - 15444444444444444n - ); // 111.2 COMP/day - expect(await comet.baseTrackingSupplySpeed()).to.be.equal( - /// TODO : should be changed after we know the exact value. - exp(30 / 86400, 15, 18) - ); - expect(await comet.baseTrackingBorrowSpeed()).to.be.equal( - /// TODO : should be changed after we know the exact value. - exp(15 / 86400, 15, 18) - ); }, }); diff --git a/deployments/optimism/usdc/roots.json b/deployments/optimism/usdc/roots.json index 216adbd8f..334c1fb82 100644 --- a/deployments/optimism/usdc/roots.json +++ b/deployments/optimism/usdc/roots.json @@ -1,4 +1,5 @@ { "l2CrossDomainMessenger": "0x4200000000000000000000000000000000000007", - "l2StandardBridge": "0x4200000000000000000000000000000000000010" + "l2StandardBridge": "0x4200000000000000000000000000000000000010", + "CCTPMessageTransmitter": "0x4D41f22c5a0e5c74090899E5a8Fb597a8842b3e8" } diff --git a/deployments/optimism/usdt/configuration.json b/deployments/optimism/usdt/configuration.json index b102f75e8..ae56ef60d 100644 --- a/deployments/optimism/usdt/configuration.json +++ b/deployments/optimism/usdt/configuration.json @@ -6,21 +6,21 @@ "baseTokenPriceFeed": "0xECef79E109e997bCA29c1c0897ec9d7b03647F5E", "borrowMin": "1e0", "storeFrontPriceFactor": 0.6, - "targetReserves": "5000000e6", + "targetReserves": "20000000e6", "rates": { - "supplyKink": 0.8, - "supplySlopeLow": 0.0325, - "supplySlopeHigh": 0.4, + "supplyKink": 0.9, + "supplySlopeLow": 0.059, + "supplySlopeHigh": 2.9, "supplyBase": 0, - "borrowKink": 0.8, - "borrowSlopeLow": 0.035, - "borrowSlopeHigh": 0.25, + "borrowKink": 0.9, + "borrowSlopeLow": 0.061, + "borrowSlopeHigh": 3.2, "borrowBase": 0.015 }, "tracking": { "indexScale": "1e15", - "baseSupplySpeed": "347_222_222_222e0", - "baseBorrowSpeed": "173_611_111_111e0", + "baseSupplySpeed": "57_870_370_370e0", + "baseBorrowSpeed": "57_870_370_370e0", "baseMinForRewards": "1000e6" }, "assets": { @@ -28,28 +28,28 @@ "address": "0x4200000000000000000000000000000000000006", "priceFeed": "0x13e3Ee699D1909E989722E753853AE30b17e08c5", "decimals": "18", - "borrowCF": 0.75, - "liquidateCF": 0.8, - "liquidationFactor": 0.93, - "supplyCap": "800e18" + "borrowCF": 0.83, + "liquidateCF": 0.9, + "liquidationFactor": 0.95, + "supplyCap": "1600e18" }, "WBTC": { "address": "0x68f180fcCe6836688e9084f035309E29Bf0A2095", "priceFeed": "0xD702DD976Fb76Fffc2D3963D037dfDae5b04E593", "decimals": "8", - "borrowCF": 0.7, - "liquidateCF": 0.77, + "borrowCF": 0.8, + "liquidateCF": 0.85, "liquidationFactor": 0.95, - "supplyCap": "0e8" + "supplyCap": "60e8" }, "OP": { "address": "0x4200000000000000000000000000000000000042", "priceFeed": "0x0D276FC14719f9292D5C1eA2198673d1f4269246", "decimals": "18", - "borrowCF": 0.75, - "liquidateCF": 0.8, - "liquidationFactor": 0.93, - "supplyCap": "800e18" + "borrowCF": 0.65, + "liquidateCF": 0.7, + "liquidationFactor": 0.8, + "supplyCap": "400000e18" }, "wstETH": { "address": "0x1F32b1c2345538c0c6f582fCB022739c4A194Ebb", @@ -57,8 +57,8 @@ "decimals": "18", "borrowCF": 0.75, "liquidateCF": 0.8, - "liquidationFactor": 0.93, - "supplyCap": "800e18" + "liquidationFactor": 0.9, + "supplyCap": "300e18" } } } diff --git a/deployments/optimism/usdt/migrations/1707399040_configurate_and_ens.ts b/deployments/optimism/usdt/migrations/1707399040_configurate_and_ens.ts index 58f928bdd..ec5b83378 100644 --- a/deployments/optimism/usdt/migrations/1707399040_configurate_and_ens.ts +++ b/deployments/optimism/usdt/migrations/1707399040_configurate_and_ens.ts @@ -1,29 +1,27 @@ -import { DeploymentManager } from '../../../../plugins/deployment_manager/DeploymentManager'; +import { DeploymentManager } from "../../../../plugins/deployment_manager/DeploymentManager"; import { diffState, getCometConfig, -} from '../../../../plugins/deployment_manager/DiffState'; -import { migration } from '../../../../plugins/deployment_manager/Migration'; +} from "../../../../plugins/deployment_manager/DiffState"; +import { migration } from "../../../../plugins/deployment_manager/Migration"; import { calldata, exp, getConfigurationStruct, proposal, -} from '../../../../src/deploy'; -import { expect } from 'chai'; +} from "../../../../src/deploy"; +import { expect } from "chai"; const SECONDS_PER_YEAR = 31_536_000n; -const ENSName = 'compound-community-licenses.eth'; -const ENSResolverAddress = '0x4976fb03C32e5B8cfe2b6cCB31c09Ba78EBaBa41'; -const ENSRegistryAddress = '0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e'; -const ENSSubdomainLabel = 'v3-additional-grants'; +const ENSName = "compound-community-licenses.eth"; +const ENSResolverAddress = "0x4976fb03C32e5B8cfe2b6cCB31c09Ba78EBaBa41"; +const ENSRegistryAddress = "0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e"; +const ENSSubdomainLabel = "v3-additional-grants"; const ENSSubdomain = `${ENSSubdomainLabel}.${ENSName}`; -const ENSTextRecordKey = 'v3-official-markets'; -const opCOMPAddress = '0x9e1028F5F1D5eDE59748FFceE5532509976840E0'; // COMP on Optimism. Should be deployed before this deployment. +const ENSTextRecordKey = "v3-official-markets"; +const opCOMPAddress = "0x9e1028F5F1D5eDE59748FFceE5532509976840E0"; // COMP on Optimism. Should be deployed before this deployment. -const USDCAddress = '0x0b2C639c533813f4Aa9D7837CAf62653d097Ff85'; - -export default migration('1707399040_configurate_and_ens', { +export default migration("1707399040_configurate_and_ens", { prepare: async (deploymentManager: DeploymentManager) => { return {}; }, @@ -37,9 +35,9 @@ export default migration('1707399040_configurate_and_ens', { const { utils } = ethers; const cometFactory = await deploymentManager.fromDep( - 'cometFactory', - 'optimism', - 'usdc' + "cometFactory", + "optimism", + "usdc" ); const { bridgeReceiver, @@ -55,19 +53,25 @@ export default migration('1707399040_configurate_and_ens', { opL1StandardBridge, governor, comptrollerV2, + COMP: mainnetCOMP, + USDT: mainnetUSDT, + CCTPTokenMessenger, } = await govDeploymentManager.getContracts(); + // CCTP destination domain for Optimism + const OptimismDestinationDomain = 2; + // ENS Setup // See also: https://docs.ens.domains/contract-api-reference/name-processing const ENSResolver = await govDeploymentManager.existing( - 'ENSResolver', + "ENSResolver", ENSResolverAddress ); const subdomainHash = ethers.utils.namehash(ENSSubdomain); const opChainId = ( await deploymentManager.hre.ethers.provider.getNetwork() ).chainId.toString(); - const newMarketObject = { baseSymbol: 'WETH', cometAddress: comet.address }; + const newMarketObject = { baseSymbol: "USDT", cometAddress: comet.address }; const officialMarketsJSON = JSON.parse( await ENSResolver.text(subdomainHash, ENSTextRecordKey) ); @@ -91,16 +95,16 @@ export default migration('1707399040_configurate_and_ens', { ) ); const deployAndUpgradeToCalldata = utils.defaultAbiCoder.encode( - ['address', 'address'], + ["address", "address"], [configurator.address, comet.address] ); const setRewardConfigCalldata = utils.defaultAbiCoder.encode( - ['address', 'address'], + ["address", "address"], [comet.address, opCOMPAddress] ); const l2ProposalData = utils.defaultAbiCoder.encode( - ['address[]', 'uint256[]', 'string[]', 'bytes[]'], + ["address[]", "uint256[]", "string[]", "bytes[]"], [ [ configurator.address, @@ -110,10 +114,10 @@ export default migration('1707399040_configurate_and_ens', { ], [0, 0, 0, 0], [ - 'setFactory(address,address)', - 'setConfiguration(address,(address,address,address,address,address,uint64,uint64,uint64,uint64,uint64,uint64,uint64,uint64,uint64,uint64,uint64,uint64,uint104,uint104,uint104,(address,address,uint8,uint64,uint64,uint64,uint128)[]))', - 'deployAndUpgradeTo(address,address)', - 'setRewardConfig(address,address)', + "setFactory(address,address)", + "setConfiguration(address,(address,address,address,address,address,uint64,uint64,uint64,uint64,uint64,uint64,uint64,uint64,uint64,uint64,uint64,uint64,uint104,uint104,uint104,(address,address,uint8,uint64,uint64,uint64,uint128)[]))", + "deployAndUpgradeTo(address,address)", + "setRewardConfig(address,address)", ], [ setFactoryCalldata, @@ -124,38 +128,49 @@ export default migration('1707399040_configurate_and_ens', { ] ); + const USDTAmountToBridge = exp(10_000, 6); + const actions = [ - // 1. Set Comet configuration + deployAndUpgradeTo new Comet, set reward config on Optimism + // 1. Set Comet configuration + deployAndUpgradeTo new Comet, set Reward Config on Optimism { contract: opL1CrossDomainMessenger, - signature: 'sendMessage(address,bytes,uint32)', + signature: "sendMessage(address,bytes,uint32)", args: [bridgeReceiver.address, l2ProposalData, 3_000_000], }, - - // 2. Update the list of official markets + // 2. Approve USDT to CCTP + { + contract: mainnetUSDT, + signature: "approve(address,uint256)", + args: [CCTPTokenMessenger.address, USDTAmountToBridge], + }, + // 3. Burn USDT to Optimism via CCTP + { + contract: CCTPTokenMessenger, + signature: "depositForBurn(uint256,uint32,bytes32,address)", + args: [ + USDTAmountToBridge, + OptimismDestinationDomain, + utils.hexZeroPad(comet.address, 32), + mainnetUSDT.address, + ], + }, + // 4. Update the list of official markets { target: ENSResolverAddress, - signature: 'setText(bytes32,string,string)', + signature: "setText(bytes32,string,string)", calldata: ethers.utils.defaultAbiCoder.encode( - ['bytes32', 'string', 'string'], + ["bytes32", "string", "string"], [subdomainHash, ENSTextRecordKey, JSON.stringify(officialMarketsJSON)] ), }, - - // 3. Displace v2 USDC COMP rewards - { - contract: comptrollerV2, - signature: '_setCompSpeeds(address[],uint256[],uint256[])', - args: [[USDCAddress], [9194444444444444n], [12666666666666667n]], //// Should be updated to the correct values - }, ]; - const description = 'Proposal text goes here.'; + const description = "# Initialize cUSDTv3 on Optimism\n\nThis proposal takes the governance steps recommended and necessary to initialize a Compound III USDT market on Optimism; upon execution, cUSDTv3 will be ready for use. Simulations have confirmed the market’s readiness, as much as possible, using the [Comet scenario suite](https://github.com/compound-finance/comet/tree/main/scenario). The new parameters include setting the risk parameters based off of the [recommendations from Gauntlet](https://www.comp.xyz/t/deploy-compound-iii-on-optimism/4975/6). Further detailed information can be found on the corresponding [proposal pull request](https://github.com/compound-finance/comet/pull/792) and [forum discussion](https://www.comp.xyz/t/deploy-compound-iii-on-optimism/4975).\n\n\n## Proposal Actions\n\nThe first proposal action sets the Comet configuration and deploys a new Comet implementation on Optimism. This sends the encoded `setConfiguration` and `deployAndUpgradeTo` calls across the bridge to the governance receiver on Optimism. It also calls `setRewardConfig` on the Optimism rewards contract, to establish Optimism’s bridged version of COMP as the reward token for the deployment and set the initial supply speed to be 5 COMP/day and borrow speed to be 5 COMP/day.\n\nThe second action approves Circle’s Cross-Chain Transfer Protocol (CCTP) [TokenMessenger](https://etherscan.io/address/0xbd3fa81b58ba92a82136038b25adec7066af3155) to take the Timelock's USDT on Mainnet, in order to seed the market reserves through the CCTP.\n\nThe third action deposits and burns 10K USDT from mainnet via depositForBurn function on CCTP’s TokenMessenger contract to mint native USDT to Comet on Optimism.\n\nThe fourth action updates the ENS TXT record `v3-official-markets` on `v3-additional-grants.compound-community-licenses.eth`, updating the official markets JSON to include the new Optimism cUSDTv3 market"; const txn = await govDeploymentManager.retry(async () => trace(await governor.propose(...(await proposal(actions, description)))) ); - const event = txn.events.find((event) => event.event === 'ProposalCreated'); + const event = txn.events.find((event) => event.event === "ProposalCreated"); const [proposalId] = event.args; trace(`Created proposal ${proposalId}.`); @@ -171,11 +186,9 @@ export default migration('1707399040_configurate_and_ens', { preMigrationBlockNumber: number ) { const ethers = deploymentManager.hre.ethers; - await deploymentManager.spider(); // We spider here to pull in Base COMP now that reward config has been set + await deploymentManager.spider(); - const { comet, rewards, COMP } = await deploymentManager.getContracts(); - - const { comptrollerV2 } = await govDeploymentManager.getContracts(); + const { comet, rewards, COMP, USDT } = await deploymentManager.getContracts(); // 1. const stateChanges = await diffState( @@ -184,30 +197,38 @@ export default migration('1707399040_configurate_and_ens', { preMigrationBlockNumber ); expect(stateChanges).to.deep.equal({ - baseTrackingSupplySpeed: exp(20 / 86400, 15, 18), /// Should be updated to the correct value - storeFrontPriceFactor: exp(1, 18), /// Should be updated to the correct value - borrowPerSecondInterestRateSlopeLow: exp(0.037, 18) / SECONDS_PER_YEAR, /// Should be updated to the correct value + storeFrontPriceFactor: exp(0.6, 18), + baseTrackingSupplySpeed: exp(5 / 86400, 15, 18), + baseTrackingBorrowSpeed: exp(5 / 86400, 15, 18), + borrowPerSecondInterestRateSlopeLow: exp(0.061, 18) / SECONDS_PER_YEAR, + borrowPerSecondInterestRateSlopeHigh: exp(3.2, 18) / SECONDS_PER_YEAR, + supplyPerSecondInterestRateSlopeLow: exp(0.059, 18) / SECONDS_PER_YEAR, + supplyPerSecondInterestRateSlopeHigh: exp(2.9, 18) / SECONDS_PER_YEAR, WETH: { - supplyCap: exp(11000, 18), /// Should be updated to the correct value + supplyCap: exp(1600, 18), }, OP: { - supplyCap: exp(7500, 18), /// Should be updated to the correct value + supplyCap: exp(400000, 18), }, WBTC: { - supplyCap: exp(500, 8), /// Should be updated to the correct value + supplyCap: exp(60, 8), }, wstETH: { - supplyCap: exp(500, 18) /// TODO : should be changed after we know the exact value. - } + supplyCap: exp(300, 18), + }, }); const config = await rewards.rewardConfig(comet.address); expect(config.token).to.be.equal(COMP.address); - expect(config.rescaleFactor).to.be.equal(exp(1, 12)); /// Should be updated to the correct value - expect(config.shouldUpscale).to.be.equal(true); /// Should be updated to the correct value + expect(config.rescaleFactor).to.be.equal(exp(1, 12)); + expect(config.shouldUpscale).to.be.equal(true); + + // 2. & 3. + expect(await USDT.balanceOf(comet.address)).to.be.equal(exp(10_000, 6)); + // 4. const ENSResolver = await govDeploymentManager.existing( - 'ENSResolver', + "ENSResolver", ENSResolverAddress ); const subdomainHash = ethers.utils.namehash(ENSSubdomain); @@ -221,52 +242,50 @@ export default migration('1707399040_configurate_and_ens', { /// parse and update before migration 1: [ { - baseSymbol: 'USDC', - cometAddress: '0xc3d688B66703497DAA19211EEdff47f25384cdc3', + baseSymbol: "USDC", + cometAddress: "0xc3d688B66703497DAA19211EEdff47f25384cdc3", }, { - baseSymbol: 'WETH', - cometAddress: '0xA17581A9E3356d9A858b789D68B4d866e593aE94', + baseSymbol: "WETH", + cometAddress: "0xA17581A9E3356d9A858b789D68B4d866e593aE94", }, ], 137: [ { - baseSymbol: 'USDC', - cometAddress: '0xF25212E676D1F7F89Cd72fFEe66158f541246445', + baseSymbol: "USDC", + cometAddress: "0xF25212E676D1F7F89Cd72fFEe66158f541246445", }, ], - 42161: [ + 8453: [ + { + baseSymbol: "USDbC", + cometAddress: "0x9c4ec768c28520B50860ea7a15bd7213a9fF58bf", + }, { - baseSymbol: 'USDC', - cometAddress: '0xA5EDBDD9646f8dFF606d7448e414884C7d905dCA', + baseSymbol: "WETH", + cometAddress: "0x46e6b214b524310239732D51387075E0e70970bf", }, ], - 8453: [ + 42161: [ { - baseSymbol: 'USDbC', - cometAddress: '0x9c4ec768c28520B50860ea7a15bd7213a9fF58bf', + baseSymbol: "USDC.e", + cometAddress: "0xA5EDBDD9646f8dFF606d7448e414884C7d905dCA", + }, + { + baseSymbol: "USDC", + cometAddress: "0x9c4ec768c28520B50860ea7a15bd7213a9fF58bf", }, ], 10: [ { - baseSymbol: 'USDT', + baseSymbol: "USDC", + cometAddress: "push address of USDC comet here"//cometUSDC.address, + }, + { + baseSymbol: "USDT", cometAddress: comet.address, }, ], }); - - // 4. - expect(await comptrollerV2.compSupplySpeeds(USDCAddress)).to.be.equal( - 9194444444444444n //// Should be updated to the correct value - ); // 66.2 COMP/day - expect(await comptrollerV2.compBorrowSpeeds(USDCAddress)).to.be.equal( - 12666666666666667n //// Should be updated to the correct value - ); // 91.2 COMP/day - expect(await comet.baseTrackingSupplySpeed()).to.be.equal( - exp(20 / 86400, 15, 18) //// Should be updated to the correct value - ); - expect(await comet.baseTrackingBorrowSpeed()).to.be.equal( - exp(0 / 86400, 15, 18) //// Should be updated to the correct value - ); }, }); diff --git a/deployments/optimism/usdt/roots.json b/deployments/optimism/usdt/roots.json index 216adbd8f..334c1fb82 100644 --- a/deployments/optimism/usdt/roots.json +++ b/deployments/optimism/usdt/roots.json @@ -1,4 +1,5 @@ { "l2CrossDomainMessenger": "0x4200000000000000000000000000000000000007", - "l2StandardBridge": "0x4200000000000000000000000000000000000010" + "l2StandardBridge": "0x4200000000000000000000000000000000000010", + "CCTPMessageTransmitter": "0x4D41f22c5a0e5c74090899E5a8Fb597a8842b3e8" } From c2f834dac780e126a05d04c9dc85d7d2e8136ab8 Mon Sep 17 00:00:00 2001 From: dmitriy-bergman-works Date: Mon, 4 Mar 2024 16:26:05 +0200 Subject: [PATCH 05/37] Add Optimism COMP and pauseGuardian addresses --- deployments/optimism/usdc/configuration.json | 1 + .../optimism/usdc/migrations/1707394874_configurate_and_ens.ts | 2 +- deployments/optimism/usdt/configuration.json | 1 + .../optimism/usdt/migrations/1707399040_configurate_and_ens.ts | 2 +- 4 files changed, 4 insertions(+), 2 deletions(-) diff --git a/deployments/optimism/usdc/configuration.json b/deployments/optimism/usdc/configuration.json index b14598f3a..27cdd0882 100644 --- a/deployments/optimism/usdc/configuration.json +++ b/deployments/optimism/usdc/configuration.json @@ -4,6 +4,7 @@ "baseToken": "USDC", "baseTokenAddress": "0x0b2C639c533813f4Aa9D7837CAf62653d097Ff85", "baseTokenPriceFeed": "0x16a9FA2FDa030272Ce99B29CF780dFA30361E0f3", + "pauseGuardian": "0x3fFd6c073a4ba24a113B18C8F373569640916A45", "borrowMin": "1e0", "storeFrontPriceFactor": 0.6, "targetReserves": "20000000e6", diff --git a/deployments/optimism/usdc/migrations/1707394874_configurate_and_ens.ts b/deployments/optimism/usdc/migrations/1707394874_configurate_and_ens.ts index cf6bb24ba..aba9b5f94 100644 --- a/deployments/optimism/usdc/migrations/1707394874_configurate_and_ens.ts +++ b/deployments/optimism/usdc/migrations/1707394874_configurate_and_ens.ts @@ -19,7 +19,7 @@ const ENSRegistryAddress = "0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e"; const ENSSubdomainLabel = "v3-additional-grants"; const ENSSubdomain = `${ENSSubdomainLabel}.${ENSName}`; const ENSTextRecordKey = "v3-official-markets"; -const opCOMPAddress = "0x9e1028F5F1D5eDE59748FFceE5532509976840E0"; /// TODO : should be deployed before migration. +const opCOMPAddress = "0x7e7d4467112689329f7E06571eD0E8CbAd4910eE"; export default migration("1707394874_configurate_and_ens", { prepare: async (deploymentManager: DeploymentManager) => { diff --git a/deployments/optimism/usdt/configuration.json b/deployments/optimism/usdt/configuration.json index ae56ef60d..cbdd03728 100644 --- a/deployments/optimism/usdt/configuration.json +++ b/deployments/optimism/usdt/configuration.json @@ -4,6 +4,7 @@ "baseToken": "USDT", "baseTokenAddress": "0x94b008aA00579c1307B0EF2c499aD98a8ce58e58", "baseTokenPriceFeed": "0xECef79E109e997bCA29c1c0897ec9d7b03647F5E", + "pauseGuardian": "0x3fFd6c073a4ba24a113B18C8F373569640916A45", "borrowMin": "1e0", "storeFrontPriceFactor": 0.6, "targetReserves": "20000000e6", diff --git a/deployments/optimism/usdt/migrations/1707399040_configurate_and_ens.ts b/deployments/optimism/usdt/migrations/1707399040_configurate_and_ens.ts index ec5b83378..71ec2ca93 100644 --- a/deployments/optimism/usdt/migrations/1707399040_configurate_and_ens.ts +++ b/deployments/optimism/usdt/migrations/1707399040_configurate_and_ens.ts @@ -19,7 +19,7 @@ const ENSRegistryAddress = "0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e"; const ENSSubdomainLabel = "v3-additional-grants"; const ENSSubdomain = `${ENSSubdomainLabel}.${ENSName}`; const ENSTextRecordKey = "v3-official-markets"; -const opCOMPAddress = "0x9e1028F5F1D5eDE59748FFceE5532509976840E0"; // COMP on Optimism. Should be deployed before this deployment. +const opCOMPAddress = "0x7e7d4467112689329f7E06571eD0E8CbAd4910eE"; export default migration("1707399040_configurate_and_ens", { prepare: async (deploymentManager: DeploymentManager) => { From 4a03e9b8e9c849f06544b33ddcd5bc6da3aefc4f Mon Sep 17 00:00:00 2001 From: dmitriy-bergman-works Date: Mon, 4 Mar 2024 16:26:22 +0200 Subject: [PATCH 06/37] Fix regexp in contract import --- plugins/import/import.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/import/import.ts b/plugins/import/import.ts index 34c2109c0..dad3d7825 100644 --- a/plugins/import/import.ts +++ b/plugins/import/import.ts @@ -87,7 +87,7 @@ async function scrapeContractCreationCodeFromEtherscan(network: string, address: const url = `${getEtherscanUrl(network)}/address/${address}#code`; debug(`Attempting to scrape Contract Creation code at ${url}`); const result = await get(url, {}); - const regex = /
[\s\r\n]*([0-9a-fA-F]*)[\s\r\n]*<\/div>/g; + const regex = /
[\s\r\n]*([0-9a-fA-F]*)[\s\r\n]*<\/div>/g; const matches = [...result.matchAll(regex)]; if (matches.length === 0) { if (result.match(/request throttled/i) || result.match(/try again later/i)) { From ddfd9a96f64857fd7f7544eafefa9b3e527ee820 Mon Sep 17 00:00:00 2001 From: dmitriy-bergman-works Date: Mon, 4 Mar 2024 16:26:46 +0200 Subject: [PATCH 07/37] Update spaces and commas --- .github/workflows/deploy-market.yaml | 2 +- .github/workflows/enact-migration.yaml | 2 +- .github/workflows/prepare-migration.yaml | 2 +- .github/workflows/run-unit-tests.yaml | 10 +++--- deployments/goerli/usdc/relations.ts | 42 +++++++++++----------- deployments/goerli/usdc/roots.json | 36 +++++++++---------- deployments/mainnet/usdc/relations.ts | 44 ++++++++++++------------ deployments/mainnet/usdc/roots.json | 28 +++++++-------- hardhat.config.ts | 22 ++++++------ 9 files changed, 94 insertions(+), 94 deletions(-) diff --git a/.github/workflows/deploy-market.yaml b/.github/workflows/deploy-market.yaml index d3d3db463..458997dd2 100644 --- a/.github/workflows/deploy-market.yaml +++ b/.github/workflows/deploy-market.yaml @@ -71,7 +71,7 @@ jobs: yarn hardhat deploy --network ${{ github.event.inputs.network }} --deployment ${{ github.event.inputs.deployment }} ${{ fromJSON('["", "--simulate"]')[github.event.inputs.simulate == 'true'] }} env: DEBUG: true - ETH_PK: '${{ inputs.eth_pk }}' + ETH_PK: "${{ inputs.eth_pk }}" NETWORK_PROVIDER: ${{ fromJSON('["", "http://localhost:8585"]')[github.event.inputs.eth_pk == ''] }} REMOTE_ACCOUNTS: ${{ fromJSON('["", "true"]')[github.event.inputs.eth_pk == ''] }} diff --git a/.github/workflows/enact-migration.yaml b/.github/workflows/enact-migration.yaml index 2fc67dd6f..9260f32e7 100644 --- a/.github/workflows/enact-migration.yaml +++ b/.github/workflows/enact-migration.yaml @@ -107,7 +107,7 @@ jobs: yarn hardhat migrate --network ${{ github.event.inputs.network }} --deployment ${{ github.event.inputs.deployment }} --enact --overwrite ${{ fromJSON('["", "--simulate"]')[github.event.inputs.simulate == 'true'] }} ${{ fromJSON('["", "--no-enacted"]')[github.event.inputs.no_enacted == 'true'] }} ${{ github.event.inputs.migration }} env: DEBUG: true - ETH_PK: '${{ inputs.eth_pk }}' + ETH_PK: "${{ inputs.eth_pk }}" NETWORK_PROVIDER: ${{ fromJSON('["", "http://localhost:8585"]')[github.event.inputs.eth_pk == ''] }} GOV_NETWORK_PROVIDER: ${{ fromJSON('["", "http://localhost:8685"]')[github.event.inputs.eth_pk == '' && env.GOV_NETWORK != ''] }} GOV_NETWORK: ${{ env.GOV_NETWORK }} diff --git a/.github/workflows/prepare-migration.yaml b/.github/workflows/prepare-migration.yaml index 784fd94da..8110aa480 100644 --- a/.github/workflows/prepare-migration.yaml +++ b/.github/workflows/prepare-migration.yaml @@ -73,7 +73,7 @@ jobs: yarn hardhat migrate --network ${{ github.event.inputs.network }} --deployment ${{ github.event.inputs.deployment }} --prepare --overwrite ${{ fromJSON('["", "--simulate"]')[github.event.inputs.simulate == 'true'] }} ${{ github.event.inputs.migration }} env: DEBUG: true - ETH_PK: '${{ inputs.eth_pk }}' + ETH_PK: "${{ inputs.eth_pk }}" NETWORK_PROVIDER: ${{ fromJSON('["", "http://localhost:8585"]')[github.event.inputs.eth_pk == ''] }} REMOTE_ACCOUNTS: ${{ fromJSON('["", "true"]')[github.event.inputs.eth_pk == ''] }} diff --git a/.github/workflows/run-unit-tests.yaml b/.github/workflows/run-unit-tests.yaml index 3ad9127d9..d198e156e 100644 --- a/.github/workflows/run-unit-tests.yaml +++ b/.github/workflows/run-unit-tests.yaml @@ -34,14 +34,14 @@ jobs: - name: Run tests run: yarn test - - uses: actions/upload-artifact@v2 # upload test results - if: success() || failure() # run this step even if previous step failed + - uses: actions/upload-artifact@v2 # upload test results + if: success() || failure() # run this step even if previous step failed with: name: test-results path: test-results.json - uses: dorny/test-reporter@v1 with: - name: Unit Tests # Name of the check run which will be created - path: 'test-results.json' # Path to test results (inside artifact .zip) - reporter: mocha-json # Format of test results + name: Unit Tests # Name of the check run which will be created + path: 'test-results.json' # Path to test results (inside artifact .zip) + reporter: mocha-json # Format of test results diff --git a/deployments/goerli/usdc/relations.ts b/deployments/goerli/usdc/relations.ts index 05ea26592..00059b86e 100644 --- a/deployments/goerli/usdc/relations.ts +++ b/deployments/goerli/usdc/relations.ts @@ -6,43 +6,43 @@ export default { fxRoot: { relations: { stateSender: { - field: async (fxRoot) => fxRoot.stateSender(), - }, - }, + field: async fxRoot => fxRoot.stateSender() + } + } }, arbitrumInbox: { delegates: { field: { slot: - '0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc', - }, + '0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc' + } }, relations: { arbitrumBridge: { - field: async (inbox) => inbox.bridge(), - }, - }, + field: async inbox => inbox.bridge() + } + } }, arbitrumL1GatewayRouter: { delegates: { field: { slot: - '0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc', - }, - }, + '0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc' + } + } }, baseL1CrossDomainMessenger: { delegates: { // Not great, but this address shouldn't change and is very difficult to grab on-chain (private methods) - field: async () => '0xa042e16781484716c1Ef448c919af7BCd9607467', - }, + field: async () => '0xa042e16781484716c1Ef448c919af7BCd9607467' + } }, baseL1StandardBridge: { delegates: { field: { slot: - '0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc', - }, + '0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc' + } }, }, opL1CrossDomainMessenger: { @@ -70,16 +70,16 @@ export default { delegates: { field: { slot: - '0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc', - }, - }, + '0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc' + } + } }, lineaL1usdcBridge: { delegates: { field: { slot: - '0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc', - }, - }, + '0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc' + } + } }, }; diff --git a/deployments/goerli/usdc/roots.json b/deployments/goerli/usdc/roots.json index 2a919097e..4c7c65715 100644 --- a/deployments/goerli/usdc/roots.json +++ b/deployments/goerli/usdc/roots.json @@ -1,20 +1,20 @@ { - "timelock": "0x8Fa336EB4bF58Cfc508dEA1B0aeC7336f55B1399", - "fauceteer": "0x75442Ac771a7243433e033F3F8EaB2631e22938f", - "comet": "0x3EE77595A8459e93C2888b13aDB354017B198188", - "configurator": "0xB28495db3eC65A0e3558F040BC4f98A0d588Ae60", - "rewards": "0xef9e070044d62C38D2e316146dDe92AD02CF2c2c", - "bulker": "0x69dD076105977c55dC2835951d287f82D54606b4", - "fxRoot": "0x3d1d3E34f7fB6D26245E6640E1c50710eFFf15bA", - "arbitrumInbox": "0x6BEbC4925716945D46F0Ec336D5C2564F419682C", - "arbitrumL1GatewayRouter": "0x4c7708168395aEa569453Fc36862D2ffcDaC588c", - "baseL1CrossDomainMessenger": "0x8e5693140eA606bcEB98761d9beB1BC87383706D", - "baseL1StandardBridge": "0xfA6D8Ee5BE770F84FC001D098C4bD604Fe01284a", - "lineaMessageService": "0x70BaD09280FD342D02fe64119779BC1f0791BAC2", - "lineaL1TokenBridge": "0xaA012D038E6440535Ec66eDf2DA592F4F8398133", - "lineaL1usdcBridge": "0x9c556D2cCfb6157E4A6305aa9963EdD6ca5047cB", - "CCTPTokenMessenger": "0xd0c3da58f55358142b8d3e06c1c30c5c6114efe8", - "CCTPMessageTransmitter": "0x26413e8157cd32011e726065a5462e97dd4d03d9", - "opL1CrossDomainMessenger": "0x5086d1eEF304eb5284A0f6720f79403b4e9bE294", - "opL1StandardBridge": "0x636Af16bf2f682dD3109e60102b8E1A089FedAa8" + "timelock": "0x8Fa336EB4bF58Cfc508dEA1B0aeC7336f55B1399", + "fauceteer": "0x75442Ac771a7243433e033F3F8EaB2631e22938f", + "comet": "0x3EE77595A8459e93C2888b13aDB354017B198188", + "configurator": "0xB28495db3eC65A0e3558F040BC4f98A0d588Ae60", + "rewards": "0xef9e070044d62C38D2e316146dDe92AD02CF2c2c", + "bulker": "0x69dD076105977c55dC2835951d287f82D54606b4", + "fxRoot": "0x3d1d3E34f7fB6D26245E6640E1c50710eFFf15bA", + "arbitrumInbox": "0x6BEbC4925716945D46F0Ec336D5C2564F419682C", + "arbitrumL1GatewayRouter": "0x4c7708168395aEa569453Fc36862D2ffcDaC588c", + "baseL1CrossDomainMessenger": "0x8e5693140eA606bcEB98761d9beB1BC87383706D", + "baseL1StandardBridge": "0xfA6D8Ee5BE770F84FC001D098C4bD604Fe01284a", + "lineaMessageService": "0x70BaD09280FD342D02fe64119779BC1f0791BAC2", + "lineaL1TokenBridge": "0xaA012D038E6440535Ec66eDf2DA592F4F8398133", + "lineaL1usdcBridge": "0x9c556D2cCfb6157E4A6305aa9963EdD6ca5047cB", + "CCTPTokenMessenger": "0xd0c3da58f55358142b8d3e06c1c30c5c6114efe8", + "CCTPMessageTransmitter": "0x26413e8157cd32011e726065a5462e97dd4d03d9", + "opL1CrossDomainMessenger": "0x5086d1eEF304eb5284A0f6720f79403b4e9bE294", + "opL1StandardBridge": "0x636Af16bf2f682dD3109e60102b8E1A089FedAa8" } diff --git a/deployments/mainnet/usdc/relations.ts b/deployments/mainnet/usdc/relations.ts index 7ea556220..991b408c5 100644 --- a/deployments/mainnet/usdc/relations.ts +++ b/deployments/mainnet/usdc/relations.ts @@ -6,56 +6,56 @@ export default { fxRoot: { relations: { stateSender: { - field: async (fxRoot) => fxRoot.stateSender(), - }, - }, + field: async fxRoot => fxRoot.stateSender() + } + } }, arbitrumInbox: { delegates: { field: { slot: - '0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc', - }, + '0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc' + } }, relations: { arbitrumBridge: { - field: async (inbox) => inbox.bridge(), - }, - }, + field: async inbox => inbox.bridge() + } + } }, arbitrumL1GatewayRouter: { delegates: { field: { slot: - '0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc', - }, - }, + '0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc' + } + } }, baseL1CrossDomainMessenger: { delegates: { // Not great, but this address shouldn't change and is very difficult to grab on-chain (private methods) - field: async () => '0x81C4Bd600793EBd1C0323604E1F455fE50A951F8', - }, + field: async () => '0x81C4Bd600793EBd1C0323604E1F455fE50A951F8' + } }, baseL1StandardBridge: { delegates: { field: { slot: - '0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc', - }, - }, + '0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc' + } + } }, opL1CrossDomainMessenger: { delegates: { - field: async () => '0x2150Bc3c64cbfDDbaC9815EF615D6AB8671bfe43', - }, + field: async () => '0x2150Bc3c64cbfDDbaC9815EF615D6AB8671bfe43' + } }, opL1StandardBridge: { delegates: { field: { slot: - '0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc', - }, - }, - }, + '0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc' + } + } + } }; diff --git a/deployments/mainnet/usdc/roots.json b/deployments/mainnet/usdc/roots.json index a785b2465..14d23fb8e 100644 --- a/deployments/mainnet/usdc/roots.json +++ b/deployments/mainnet/usdc/roots.json @@ -1,16 +1,16 @@ { - "comptrollerV2": "0x3d9819210a31b4961b30ef54be2aed79b9c9cd3b", - "comet": "0xc3d688B66703497DAA19211EEdff47f25384cdc3", - "configurator": "0x316f9708bB98af7dA9c68C1C3b5e79039cD336E3", - "rewards": "0x1B0e765F6224C21223AeA2af16c1C46E38885a40", - "bulker": "0xa397a8C2086C554B531c02E29f3291c9704B00c7", - "fxRoot": "0xfe5e5D361b2ad62c541bAb87C45a0B9B018389a2", - "arbitrumInbox": "0x4Dbd4fc535Ac27206064B68FfCf827b0A60BAB3f", - "arbitrumL1GatewayRouter": "0x72Ce9c846789fdB6fC1f34aC4AD25Dd9ef7031ef", - "CCTPTokenMessenger": "0xbd3fa81b58ba92a82136038b25adec7066af3155", - "CCTPMessageTransmitter": "0x0a992d191deec32afe36203ad87d7d289a738f81", - "baseL1CrossDomainMessenger": "0x866E82a600A1414e583f7F13623F1aC5d58b0Afa", - "baseL1StandardBridge": "0x3154Cf16ccdb4C6d922629664174b904d80F2C35", - "opL1CrossDomainMessenger": "0x25ace71c97B33Cc4729CF772ae268934F7ab5fA1", - "opL1StandardBridge": "0x99C9fc46f92E8a1c0deC1b1747d010903E884bE1" + "comptrollerV2": "0x3d9819210a31b4961b30ef54be2aed79b9c9cd3b", + "comet": "0xc3d688B66703497DAA19211EEdff47f25384cdc3", + "configurator": "0x316f9708bB98af7dA9c68C1C3b5e79039cD336E3", + "rewards": "0x1B0e765F6224C21223AeA2af16c1C46E38885a40", + "bulker": "0xa397a8C2086C554B531c02E29f3291c9704B00c7", + "fxRoot": "0xfe5e5D361b2ad62c541bAb87C45a0B9B018389a2", + "arbitrumInbox": "0x4Dbd4fc535Ac27206064B68FfCf827b0A60BAB3f", + "arbitrumL1GatewayRouter": "0x72Ce9c846789fdB6fC1f34aC4AD25Dd9ef7031ef", + "CCTPTokenMessenger": "0xbd3fa81b58ba92a82136038b25adec7066af3155", + "CCTPMessageTransmitter": "0x0a992d191deec32afe36203ad87d7d289a738f81", + "baseL1CrossDomainMessenger": "0x866E82a600A1414e583f7F13623F1aC5d58b0Afa", + "baseL1StandardBridge": "0x3154Cf16ccdb4C6d922629664174b904d80F2C35", + "opL1CrossDomainMessenger": "0x25ace71c97B33Cc4729CF772ae268934F7ab5fA1", + "opL1StandardBridge": "0x99C9fc46f92E8a1c0deC1b1747d010903E884bE1" } diff --git a/hardhat.config.ts b/hardhat.config.ts index 16bb0eaf7..5371eb3dc 100644 --- a/hardhat.config.ts +++ b/hardhat.config.ts @@ -181,8 +181,8 @@ function setupDefaultNetworkProviders(hardhatConfig: HardhatUserConfig) { accounts: REMOTE_ACCOUNTS ? 'remote' : ETH_PK - ? [...deriveAccounts(ETH_PK)] - : { mnemonic: MNEMONIC }, + ? [...deriveAccounts(ETH_PK)] + : { mnemonic: MNEMONIC }, }; } } @@ -197,15 +197,15 @@ const config: HardhatUserConfig = { optimizer: process.env['OPTIMIZER_DISABLED'] ? { enabled: false } : { - enabled: true, - runs: 1, - details: { - yulDetails: { - optimizerSteps: + enabled: true, + runs: 1, + details: { + yulDetails: { + optimizerSteps: 'dhfoDgvulfnTUtnIf [xa[r]scLM cCTUtTOntnfDIul Lcul Vcul [j] Tpeul xa[rul] xa[r]cL gvif CTUca[r]LsTOtfDnca[r]Iulc] jmul[jul] VcTOcul jmul', - }, }, }, + }, outputSelection: { '*': { '*': ['evm.deployedBytecode.sourceMap'], @@ -224,9 +224,9 @@ const config: HardhatUserConfig = { blockGasLimit: 12000000, accounts: ETH_PK ? [...deriveAccounts(ETH_PK)].map((privateKey) => ({ - privateKey, - balance: (10n ** 36n).toString(), - })) + privateKey, + balance: (10n ** 36n).toString(), + })) : { mnemonic: MNEMONIC, accountsBalance: (10n ** 36n).toString() }, // this should only be relied upon for test harnesses and coverage (which does not use viaIR flag) allowUnlimitedContractSize: true, From 5208c87db71fb14efaa3180bb6ba331a9e922f98 Mon Sep 17 00:00:00 2001 From: dmitriy-bergman-works Date: Mon, 4 Mar 2024 16:27:04 +0200 Subject: [PATCH 08/37] Update offsets and commas --- deployments/goerli/usdc/relations.ts | 15 +++++---------- deployments/mainnet/usdc/relations.ts | 21 +++++++++------------ 2 files changed, 14 insertions(+), 22 deletions(-) diff --git a/deployments/goerli/usdc/relations.ts b/deployments/goerli/usdc/relations.ts index 00059b86e..dcccf7729 100644 --- a/deployments/goerli/usdc/relations.ts +++ b/deployments/goerli/usdc/relations.ts @@ -13,8 +13,7 @@ export default { arbitrumInbox: { delegates: { field: { - slot: - '0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc' + slot: '0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc' } }, relations: { @@ -26,8 +25,7 @@ export default { arbitrumL1GatewayRouter: { delegates: { field: { - slot: - '0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc' + slot: '0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc' } } }, @@ -40,8 +38,7 @@ export default { baseL1StandardBridge: { delegates: { field: { - slot: - '0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc' + slot: '0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc' } }, }, @@ -69,16 +66,14 @@ export default { lineaL1TokenBridge: { delegates: { field: { - slot: - '0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc' + slot: '0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc' } } }, lineaL1usdcBridge: { delegates: { field: { - slot: - '0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc' + slot: '0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc' } } }, diff --git a/deployments/mainnet/usdc/relations.ts b/deployments/mainnet/usdc/relations.ts index 991b408c5..01d0d0802 100644 --- a/deployments/mainnet/usdc/relations.ts +++ b/deployments/mainnet/usdc/relations.ts @@ -6,42 +6,39 @@ export default { fxRoot: { relations: { stateSender: { - field: async fxRoot => fxRoot.stateSender() + field: async (fxRoot) => fxRoot.stateSender() } } }, arbitrumInbox: { delegates: { field: { - slot: - '0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc' - } + slot: '0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc', + }, }, relations: { arbitrumBridge: { - field: async inbox => inbox.bridge() + field: async (inbox) => inbox.bridge() } } }, arbitrumL1GatewayRouter: { delegates: { field: { - slot: - '0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc' + slot: '0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc', } - } + }, }, baseL1CrossDomainMessenger: { delegates: { // Not great, but this address shouldn't change and is very difficult to grab on-chain (private methods) - field: async () => '0x81C4Bd600793EBd1C0323604E1F455fE50A951F8' - } + field: async () => '0x81C4Bd600793EBd1C0323604E1F455fE50A951F8', + }, }, baseL1StandardBridge: { delegates: { field: { - slot: - '0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc' + slot: '0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc' } } }, From 7bbb4cb06979b670050084fc5a10a6d56bf263e8 Mon Sep 17 00:00:00 2001 From: dmitriy-bergman-works Date: Mon, 4 Mar 2024 16:50:44 +0200 Subject: [PATCH 09/37] Update PR id in migration --- .../optimism/usdc/migrations/1707394874_configurate_and_ens.ts | 2 +- .../optimism/usdt/migrations/1707399040_configurate_and_ens.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/deployments/optimism/usdc/migrations/1707394874_configurate_and_ens.ts b/deployments/optimism/usdc/migrations/1707394874_configurate_and_ens.ts index aba9b5f94..fc1085061 100644 --- a/deployments/optimism/usdc/migrations/1707394874_configurate_and_ens.ts +++ b/deployments/optimism/usdc/migrations/1707394874_configurate_and_ens.ts @@ -166,7 +166,7 @@ export default migration("1707394874_configurate_and_ens", { }, ]; - const description = "# Initialize cUSDCv3 on Optimism\n\nThis proposal takes the governance steps recommended and necessary to initialize a Compound III USDC market on Optimism; upon execution, cUSDCv3 will be ready for use. Simulations have confirmed the market’s readiness, as much as possible, using the [Comet scenario suite](https://github.com/compound-finance/comet/tree/main/scenario). The new parameters include setting the risk parameters based off of the [recommendations from Gauntlet](https://www.comp.xyz/t/deploy-compound-iii-on-optimism/4975/6). Further detailed information can be found on the corresponding [proposal pull request](https://github.com/compound-finance/comet/pull/792) and [forum discussion](https://www.comp.xyz/t/deploy-compound-iii-on-optimism/4975).\n\n\n## Proposal Actions\n\nThe first proposal action sets the Comet configuration and deploys a new Comet implementation on Optimism. This sends the encoded `setConfiguration` and `deployAndUpgradeTo` calls across the bridge to the governance receiver on Optimism. It also calls `setRewardConfig` on the Optimism rewards contract, to establish Optimism’s bridged version of COMP as the reward token for the deployment and set the initial supply speed to be 5 COMP/day and borrow speed to be 5 COMP/day.\n\nThe second action approves Circle’s Cross-Chain Transfer Protocol (CCTP) [TokenMessenger](https://etherscan.io/address/0xbd3fa81b58ba92a82136038b25adec7066af3155) to take the Timelock's USDC on Mainnet, in order to seed the market reserves through the CCTP.\n\nThe third action deposits and burns 10K USDC from mainnet via depositForBurn function on CCTP’s TokenMessenger contract to mint native USDC to Comet on Optimism.\n\nThe fourth action approves Optimism’s [L1StandardBridge](https://etherscan.io/address/0x99C9fc46f92E8a1c0deC1b1747d010903E884bE1) to take Timelock's COMP, in order to seed the rewards contract through the bridge.\n\nThe fifth action deposits 3.6K COMP from mainnet to the Optimism L1StandardBridge contract to bridge to CometRewards.\n\nThe sixth action updates the ENS TXT record `v3-official-markets` on `v3-additional-grants.compound-community-licenses.eth`, updating the official markets JSON to include the new Optimism cUSDCv3 market"; /// TODO : should be + const description = "# Initialize cUSDCv3 on Optimism\n\nThis proposal takes the governance steps recommended and necessary to initialize a Compound III USDC market on Optimism; upon execution, cUSDCv3 will be ready for use. Simulations have confirmed the market’s readiness, as much as possible, using the [Comet scenario suite](https://github.com/compound-finance/comet/tree/main/scenario). The new parameters include setting the risk parameters based off of the [recommendations from Gauntlet](https://www.comp.xyz/t/deploy-compound-iii-on-optimism/4975/6). Further detailed information can be found on the corresponding [proposal pull request](https://github.com/compound-finance/comet/pull/833) and [forum discussion](https://www.comp.xyz/t/deploy-compound-iii-on-optimism/4975).\n\n\n## Proposal Actions\n\nThe first proposal action sets the Comet configuration and deploys a new Comet implementation on Optimism. This sends the encoded `setConfiguration` and `deployAndUpgradeTo` calls across the bridge to the governance receiver on Optimism. It also calls `setRewardConfig` on the Optimism rewards contract, to establish Optimism’s bridged version of COMP as the reward token for the deployment and set the initial supply speed to be 5 COMP/day and borrow speed to be 5 COMP/day.\n\nThe second action approves Circle’s Cross-Chain Transfer Protocol (CCTP) [TokenMessenger](https://etherscan.io/address/0xbd3fa81b58ba92a82136038b25adec7066af3155) to take the Timelock's USDC on Mainnet, in order to seed the market reserves through the CCTP.\n\nThe third action deposits and burns 10K USDC from mainnet via depositForBurn function on CCTP’s TokenMessenger contract to mint native USDC to Comet on Optimism.\n\nThe fourth action approves Optimism’s [L1StandardBridge](https://etherscan.io/address/0x99C9fc46f92E8a1c0deC1b1747d010903E884bE1) to take Timelock's COMP, in order to seed the rewards contract through the bridge.\n\nThe fifth action deposits 3.6K COMP from mainnet to the Optimism L1StandardBridge contract to bridge to CometRewards.\n\nThe sixth action updates the ENS TXT record `v3-official-markets` on `v3-additional-grants.compound-community-licenses.eth`, updating the official markets JSON to include the new Optimism cUSDCv3 market"; /// TODO : should be const txn = await govDeploymentManager.retry(async () => trace(await governor.propose(...(await proposal(actions, description)))) ); diff --git a/deployments/optimism/usdt/migrations/1707399040_configurate_and_ens.ts b/deployments/optimism/usdt/migrations/1707399040_configurate_and_ens.ts index 71ec2ca93..deddbe539 100644 --- a/deployments/optimism/usdt/migrations/1707399040_configurate_and_ens.ts +++ b/deployments/optimism/usdt/migrations/1707399040_configurate_and_ens.ts @@ -165,7 +165,7 @@ export default migration("1707399040_configurate_and_ens", { }, ]; - const description = "# Initialize cUSDTv3 on Optimism\n\nThis proposal takes the governance steps recommended and necessary to initialize a Compound III USDT market on Optimism; upon execution, cUSDTv3 will be ready for use. Simulations have confirmed the market’s readiness, as much as possible, using the [Comet scenario suite](https://github.com/compound-finance/comet/tree/main/scenario). The new parameters include setting the risk parameters based off of the [recommendations from Gauntlet](https://www.comp.xyz/t/deploy-compound-iii-on-optimism/4975/6). Further detailed information can be found on the corresponding [proposal pull request](https://github.com/compound-finance/comet/pull/792) and [forum discussion](https://www.comp.xyz/t/deploy-compound-iii-on-optimism/4975).\n\n\n## Proposal Actions\n\nThe first proposal action sets the Comet configuration and deploys a new Comet implementation on Optimism. This sends the encoded `setConfiguration` and `deployAndUpgradeTo` calls across the bridge to the governance receiver on Optimism. It also calls `setRewardConfig` on the Optimism rewards contract, to establish Optimism’s bridged version of COMP as the reward token for the deployment and set the initial supply speed to be 5 COMP/day and borrow speed to be 5 COMP/day.\n\nThe second action approves Circle’s Cross-Chain Transfer Protocol (CCTP) [TokenMessenger](https://etherscan.io/address/0xbd3fa81b58ba92a82136038b25adec7066af3155) to take the Timelock's USDT on Mainnet, in order to seed the market reserves through the CCTP.\n\nThe third action deposits and burns 10K USDT from mainnet via depositForBurn function on CCTP’s TokenMessenger contract to mint native USDT to Comet on Optimism.\n\nThe fourth action updates the ENS TXT record `v3-official-markets` on `v3-additional-grants.compound-community-licenses.eth`, updating the official markets JSON to include the new Optimism cUSDTv3 market"; + const description = "# Initialize cUSDTv3 on Optimism\n\nThis proposal takes the governance steps recommended and necessary to initialize a Compound III USDT market on Optimism; upon execution, cUSDTv3 will be ready for use. Simulations have confirmed the market’s readiness, as much as possible, using the [Comet scenario suite](https://github.com/compound-finance/comet/tree/main/scenario). The new parameters include setting the risk parameters based off of the [recommendations from Gauntlet](https://www.comp.xyz/t/deploy-compound-iii-on-optimism/4975/6). Further detailed information can be found on the corresponding [proposal pull request](https://github.com/compound-finance/comet/pull/833) and [forum discussion](https://www.comp.xyz/t/deploy-compound-iii-on-optimism/4975).\n\n\n## Proposal Actions\n\nThe first proposal action sets the Comet configuration and deploys a new Comet implementation on Optimism. This sends the encoded `setConfiguration` and `deployAndUpgradeTo` calls across the bridge to the governance receiver on Optimism. It also calls `setRewardConfig` on the Optimism rewards contract, to establish Optimism’s bridged version of COMP as the reward token for the deployment and set the initial supply speed to be 5 COMP/day and borrow speed to be 5 COMP/day.\n\nThe second action approves Circle’s Cross-Chain Transfer Protocol (CCTP) [TokenMessenger](https://etherscan.io/address/0xbd3fa81b58ba92a82136038b25adec7066af3155) to take the Timelock's USDT on Mainnet, in order to seed the market reserves through the CCTP.\n\nThe third action deposits and burns 10K USDT from mainnet via depositForBurn function on CCTP’s TokenMessenger contract to mint native USDT to Comet on Optimism.\n\nThe fourth action updates the ENS TXT record `v3-official-markets` on `v3-additional-grants.compound-community-licenses.eth`, updating the official markets JSON to include the new Optimism cUSDTv3 market"; const txn = await govDeploymentManager.retry(async () => trace(await governor.propose(...(await proposal(actions, description)))) ); From b329070c84ea7eba29604746637cb9f64db5845a Mon Sep 17 00:00:00 2001 From: dmitriy-bergman-works Date: Wed, 13 Mar 2024 16:47:10 +0200 Subject: [PATCH 10/37] Remove goerli-optimism network deployment --- .github/workflows/deploy-market.yaml | 3 +- .github/workflows/enact-migration.yaml | 5 +- .github/workflows/prepare-migration.yaml | 3 +- .github/workflows/run-scenarios.yaml | 2 +- README.md | 2 +- .../optimism-goerli/usdc/configuration.json | 56 ---- deployments/optimism-goerli/usdc/deploy.ts | 112 ------- .../1707402209_configurate_and_ens.ts | 251 ---------------- deployments/optimism-goerli/usdc/relations.ts | 27 -- deployments/optimism-goerli/usdc/roots.json | 5 - .../optimism-goerli/usdt/configuration.json | 56 ---- deployments/optimism-goerli/usdt/deploy.ts | 89 ------ .../1707403494_configurate_and_ens.ts | 279 ------------------ deployments/optimism-goerli/usdt/relations.ts | 27 -- deployments/optimism-goerli/usdt/roots.json | 5 - hardhat.config.ts | 32 -- plugins/import/etherscan.ts | 3 - scenario/utils/relayMessage.ts | 1 - 18 files changed, 6 insertions(+), 952 deletions(-) delete mode 100644 deployments/optimism-goerli/usdc/configuration.json delete mode 100644 deployments/optimism-goerli/usdc/deploy.ts delete mode 100644 deployments/optimism-goerli/usdc/migrations/1707402209_configurate_and_ens.ts delete mode 100644 deployments/optimism-goerli/usdc/relations.ts delete mode 100644 deployments/optimism-goerli/usdc/roots.json delete mode 100644 deployments/optimism-goerli/usdt/configuration.json delete mode 100644 deployments/optimism-goerli/usdt/deploy.ts delete mode 100644 deployments/optimism-goerli/usdt/migrations/1707403494_configurate_and_ens.ts delete mode 100644 deployments/optimism-goerli/usdt/relations.ts delete mode 100644 deployments/optimism-goerli/usdt/roots.json diff --git a/.github/workflows/deploy-market.yaml b/.github/workflows/deploy-market.yaml index 66349b49b..81e74c564 100644 --- a/.github/workflows/deploy-market.yaml +++ b/.github/workflows/deploy-market.yaml @@ -18,7 +18,6 @@ on: - base-goerli - linea-goerli - optimism - - optimism-goerli deployment: description: Deployment Name (e.g. "usdc") required: true @@ -47,7 +46,7 @@ jobs: with: wallet_connect_project_id: ${{ secrets.WALLET_CONNECT_PROJECT_ID }} requested_network: "${{ inputs.network }}" - ethereum_url: "${{ fromJSON('{\"optimism\":\"https://optimism-mainnet.infura.io/v3/$INFURA_KEY\",\"optimism-goerli\":\"https://optimism-goerli.infura.io/v3/$INFURA_KEY\",\"fuji\":\"https://api.avax-test.network/ext/bc/C/rpc\",\"mainnet\":\"https://mainnet.infura.io/v3/$INFURA_KEY\",\"goerli\":\"https://goerli.infura.io/v3/$INFURA_KEY\",\"sepolia\":\"https://sepolia.infura.io/v3/$INFURA_KEY\",\"mumbai\":\"https://polygon-mumbai.infura.io/v3/$INFURA_KEY\",\"polygon\":\"https://polygon-mainnet.infura.io/v3/$INFURA_KEY\",\"arbitrum-goerli\":\"https://arbitrum-goerli.infura.io/v3/$INFURA_KEY\",\"arbitrum\":\"https://arbitrum-mainnet.infura.io/v3/$INFURA_KEY\",\"base\":\"https://clean-spring-wind.base-mainnet.discover.quiknode.pro/$QUICKNODE_KEY\",\"base-goerli\":\"https://base-goerli.infura.io/v3/$INFURA_KEY\",\"linea-goerli\":\"https://linea-goerli.infura.io/v3/$INFURA_KEY\"}')[inputs.network] }}" + ethereum_url: "${{ fromJSON('{\"optimism\":\"https://optimism-mainnet.infura.io/v3/$INFURA_KEY\",\"fuji\":\"https://api.avax-test.network/ext/bc/C/rpc\",\"mainnet\":\"https://mainnet.infura.io/v3/$INFURA_KEY\",\"goerli\":\"https://goerli.infura.io/v3/$INFURA_KEY\",\"sepolia\":\"https://sepolia.infura.io/v3/$INFURA_KEY\",\"mumbai\":\"https://polygon-mumbai.infura.io/v3/$INFURA_KEY\",\"polygon\":\"https://polygon-mainnet.infura.io/v3/$INFURA_KEY\",\"arbitrum-goerli\":\"https://arbitrum-goerli.infura.io/v3/$INFURA_KEY\",\"arbitrum\":\"https://arbitrum-mainnet.infura.io/v3/$INFURA_KEY\",\"base\":\"https://clean-spring-wind.base-mainnet.discover.quiknode.pro/$QUICKNODE_KEY\",\"base-goerli\":\"https://base-goerli.infura.io/v3/$INFURA_KEY\",\"linea-goerli\":\"https://linea-goerli.infura.io/v3/$INFURA_KEY\"}')[inputs.network] }}" port: 8585 if: github.event.inputs.eth_pk == '' diff --git a/.github/workflows/enact-migration.yaml b/.github/workflows/enact-migration.yaml index 7cb506742..9121246a1 100644 --- a/.github/workflows/enact-migration.yaml +++ b/.github/workflows/enact-migration.yaml @@ -18,7 +18,6 @@ on: - base-goerli - linea-goerli - optimism - - optimism-goerli deployment: description: Deployment Name (e.g. "usdc") required: true @@ -66,7 +65,7 @@ jobs: with: wallet_connect_project_id: ${{ secrets.WALLET_CONNECT_PROJECT_ID }} requested_network: "${{ inputs.network }}" - ethereum_url: "${{ fromJSON('{\"optimism\":\"https://optimism-mainnet.infura.io/v3/$INFURA_KEY\",\"optimism-goerli\":\"https://optimism-goerli.infura.io/v3/$INFURA_KEY\",\"fuji\":\"https://api.avax-test.network/ext/bc/C/rpc\",\"mainnet\":\"https://mainnet.infura.io/v3/$INFURA_KEY\",\"goerli\":\"https://goerli.infura.io/v3/$INFURA_KEY\",\"sepolia\":\"https://sepolia.infura.io/v3/$INFURA_KEY\",\"mumbai\":\"https://polygon-mumbai.infura.io/v3/$INFURA_KEY\",\"polygon\":\"https://polygon-mainnet.infura.io/v3/$INFURA_KEY\",\"arbitrum-goerli\":\"https://arbitrum-goerli.infura.io/v3/$INFURA_KEY\",\"arbitrum\":\"https://arbitrum-mainnet.infura.io/v3/$INFURA_KEY\",\"base\":\"https://clean-spring-wind.base-mainnet.discover.quiknode.pro/$QUICKNODE_KEY\",\"base-goerli\":\"https://base-goerli.infura.io/v3/$INFURA_KEY\",\"linea-goerli\":\"https://linea-goerli.infura.io/v3/$INFURA_KEY\"}')[inputs.network] }}" + ethereum_url: "${{ fromJSON('{\"optimism\":\"https://optimism-mainnet.infura.io/v3/$INFURA_KEY\",\"fuji\":\"https://api.avax-test.network/ext/bc/C/rpc\",\"mainnet\":\"https://mainnet.infura.io/v3/$INFURA_KEY\",\"goerli\":\"https://goerli.infura.io/v3/$INFURA_KEY\",\"sepolia\":\"https://sepolia.infura.io/v3/$INFURA_KEY\",\"mumbai\":\"https://polygon-mumbai.infura.io/v3/$INFURA_KEY\",\"polygon\":\"https://polygon-mainnet.infura.io/v3/$INFURA_KEY\",\"arbitrum-goerli\":\"https://arbitrum-goerli.infura.io/v3/$INFURA_KEY\",\"arbitrum\":\"https://arbitrum-mainnet.infura.io/v3/$INFURA_KEY\",\"base\":\"https://clean-spring-wind.base-mainnet.discover.quiknode.pro/$QUICKNODE_KEY\",\"base-goerli\":\"https://base-goerli.infura.io/v3/$INFURA_KEY\",\"linea-goerli\":\"https://linea-goerli.infura.io/v3/$INFURA_KEY\"}')[inputs.network] }}" port: 8585 if: github.event.inputs.eth_pk == '' @@ -75,7 +74,7 @@ jobs: with: wallet_connect_project_id: ${{ secrets.WALLET_CONNECT_PROJECT_ID }} requested_network: "${{ env.GOV_NETWORK }}" - ethereum_url: "${{ fromJSON('{\"optimism\":\"https://optimism-mainnet.infura.io/v3/$INFURA_KEY\",\"optimism-goerli\":\"https://optimism-goerli.infura.io/v3/$INFURA_KEY\",\"fuji\":\"https://api.avax-test.network/ext/bc/C/rpc\",\"mainnet\":\"https://mainnet.infura.io/v3/$INFURA_KEY\",\"goerli\":\"https://goerli.infura.io/v3/$INFURA_KEY\",\"sepolia\":\"https://sepolia.infura.io/v3/$INFURA_KEY\",\"mumbai\":\"https://polygon-mumbai.infura.io/v3/$INFURA_KEY\",\"polygon\":\"https://polygon-mainnet.infura.io/v3/$INFURA_KEY\",\"arbitrum-goerli\":\"https://arbitrum-goerli.infura.io/v3/$INFURA_KEY\",\"arbitrum\":\"https://arbitrum-mainnet.infura.io/v3/$INFURA_KEY\"}')[env.GOV_NETWORK] }}" + ethereum_url: "${{ fromJSON('{\"optimism\":\"https://optimism-mainnet.infura.io/v3/$INFURA_KEY\",\"fuji\":\"https://api.avax-test.network/ext/bc/C/rpc\",\"mainnet\":\"https://mainnet.infura.io/v3/$INFURA_KEY\",\"goerli\":\"https://goerli.infura.io/v3/$INFURA_KEY\",\"sepolia\":\"https://sepolia.infura.io/v3/$INFURA_KEY\",\"mumbai\":\"https://polygon-mumbai.infura.io/v3/$INFURA_KEY\",\"polygon\":\"https://polygon-mainnet.infura.io/v3/$INFURA_KEY\",\"arbitrum-goerli\":\"https://arbitrum-goerli.infura.io/v3/$INFURA_KEY\",\"arbitrum\":\"https://arbitrum-mainnet.infura.io/v3/$INFURA_KEY\"}')[env.GOV_NETWORK] }}" port: 8685 if: github.event.inputs.eth_pk == '' && env.GOV_NETWORK != '' diff --git a/.github/workflows/prepare-migration.yaml b/.github/workflows/prepare-migration.yaml index a103703ad..71597e0b8 100644 --- a/.github/workflows/prepare-migration.yaml +++ b/.github/workflows/prepare-migration.yaml @@ -17,7 +17,6 @@ on: - base - base-goerli - optimism - - optimism-goerli deployment: description: Deployment Name (e.g. "usdc") required: true @@ -49,7 +48,7 @@ jobs: with: wallet_connect_project_id: ${{ secrets.WALLET_CONNECT_PROJECT_ID }} requested_network: "${{ inputs.network }}" - ethereum_url: "${{ fromJSON('{\"optimism\":\"https://optimism-mainnet.infura.io/v3/$INFURA_KEY\",\"optimism-goerli\":\"https://optimism-goerli.infura.io/v3/$INFURA_KEY\",\"fuji\":\"https://api.avax-test.network/ext/bc/C/rpc\",\"mainnet\":\"https://mainnet.infura.io/v3/$INFURA_KEY\",\"goerli\":\"https://goerli.infura.io/v3/$INFURA_KEY\",\"sepolia\":\"https://sepolia.infura.io/v3/$INFURA_KEY\",\"mumbai\":\"https://polygon-mumbai.infura.io/v3/$INFURA_KEY\",\"polygon\":\"https://polygon-mainnet.infura.io/v3/$INFURA_KEY\",\"arbitrum-goerli\":\"https://arbitrum-goerli.infura.io/v3/$INFURA_KEY\",\"arbitrum\":\"https://arbitrum-mainnet.infura.io/v3/$INFURA_KEY\",\"base\":\"https://clean-spring-wind.base-mainnet.discover.quiknode.pro/$QUICKNODE_KEY\",\"base-goerli\":\"https://base-goerli.infura.io/v3/$INFURA_KEY\",\"linea-goerli\":\"https://linea-goerli.infura.io/v3/$INFURA_KEY\"}')[inputs.network] }}" + ethereum_url: "${{ fromJSON('{\"optimism\":\"https://optimism-mainnet.infura.io/v3/$INFURA_KEY\",\"fuji\":\"https://api.avax-test.network/ext/bc/C/rpc\",\"mainnet\":\"https://mainnet.infura.io/v3/$INFURA_KEY\",\"goerli\":\"https://goerli.infura.io/v3/$INFURA_KEY\",\"sepolia\":\"https://sepolia.infura.io/v3/$INFURA_KEY\",\"mumbai\":\"https://polygon-mumbai.infura.io/v3/$INFURA_KEY\",\"polygon\":\"https://polygon-mainnet.infura.io/v3/$INFURA_KEY\",\"arbitrum-goerli\":\"https://arbitrum-goerli.infura.io/v3/$INFURA_KEY\",\"arbitrum\":\"https://arbitrum-mainnet.infura.io/v3/$INFURA_KEY\",\"base\":\"https://clean-spring-wind.base-mainnet.discover.quiknode.pro/$QUICKNODE_KEY\",\"base-goerli\":\"https://base-goerli.infura.io/v3/$INFURA_KEY\",\"linea-goerli\":\"https://linea-goerli.infura.io/v3/$INFURA_KEY\"}')[inputs.network] }}" port: 8585 if: github.event.inputs.eth_pk == '' diff --git a/.github/workflows/run-scenarios.yaml b/.github/workflows/run-scenarios.yaml index b8e1728f9..93241a450 100644 --- a/.github/workflows/run-scenarios.yaml +++ b/.github/workflows/run-scenarios.yaml @@ -7,7 +7,7 @@ jobs: strategy: fail-fast: false matrix: - bases: [ development, mainnet, mainnet-weth, goerli, goerli-weth, sepolia-usdc, sepolia-weth, fuji, mumbai, polygon, arbitrum-usdc.e, arbitrum-usdc, arbitrum-goerli-usdc, arbitrum-goerli-usdc.e, base-usdbc, base-weth, base-goerli, base-goerli-weth, linea-goerli, optimism-usdc, optimism-usdt, optimism-goerli-usdc, optimism-goerli-usdt] + bases: [ development, mainnet, mainnet-weth, goerli, goerli-weth, sepolia-usdc, sepolia-weth, fuji, mumbai, polygon, arbitrum-usdc.e, arbitrum-usdc, arbitrum-goerli-usdc, arbitrum-goerli-usdc.e, base-usdbc, base-weth, base-goerli, base-goerli-weth, linea-goerli, optimism-usdc, optimism-usdt] name: Run scenarios env: ETHERSCAN_KEY: ${{ secrets.ETHERSCAN_KEY }} diff --git a/README.md b/README.md index fd284b2ed..64f799814 100644 --- a/README.md +++ b/README.md @@ -265,7 +265,7 @@ native asset (i.e. 2 ETH for Goerli, 2 AVAX for Fuji) The `clone-multisig` script can be used to clone the multisig and its configuration from an existing deployment, e.g.: ```bash -DST_NETWORK=optimism-goerli npx hardhat run scripts/clone-multisig.ts +DST_NETWORK=optimism npx hardhat run scripts/clone-multisig.ts ``` ### Liquidation Bot diff --git a/deployments/optimism-goerli/usdc/configuration.json b/deployments/optimism-goerli/usdc/configuration.json deleted file mode 100644 index 90ef80a88..000000000 --- a/deployments/optimism-goerli/usdc/configuration.json +++ /dev/null @@ -1,56 +0,0 @@ -{ - "name": "Compound USDC", - "symbol": "cUSDCv3", - "baseToken": "USDC", - "baseTokenAddress": "0x7E07E15D2a87A24492740D16f5bdF58c16db0c4E", - "baseTokenPriceFeed": "0x2636B223652d388721A0ED2861792DA9062D8C73", - "pauseGuardian": "0xe7661C55fe281f986FA5312D57d19ADb6064462F", - "borrowMin": "1e6", - "storeFrontPriceFactor": 0.5, - "targetReserves": "1000000e6", - "rates": { - "supplyKink": 0.8, - "supplySlopeLow": 0.0325, - "supplySlopeHigh": 0.4, - "supplyBase": 0, - "borrowKink": 0.8, - "borrowSlopeLow": 0.035, - "borrowSlopeHigh": 0.25, - "borrowBase": 0.015 - }, - "tracking": { - "indexScale": "1e15", - "baseSupplySpeed": "0.000402083333333e15", - "baseBorrowSpeed": "0.000402083333333e15", - "baseMinForRewards": "10000e6" - }, - "assets": { - "WETH": { - "address": "0x4200000000000000000000000000000000000006", - "priceFeed": "0xE30268502Eb3B2341f7961e68a34729302592dC6", - "decimals": "18", - "borrowCF": 0.775, - "liquidateCF": 0.825, - "liquidationFactor": 0.95, - "supplyCap": "1000e18" - }, - "OP": { - "address": "0x4200000000000000000000000000000000000042", - "priceFeed": "0x2636B223652d388721A0ED2861792DA9062D8C73", - "decimals": "18", - "borrowCF": 0.775, - "liquidateCF": 0.825, - "liquidationFactor": 0.95, - "supplyCap": "1000e18" - }, - "WBTC": { - "address": "0x099E6dA9FFF9F0D8873AaD3FB4C9F7eDA5742692", - "priceFeed": "0xC16679B963CeB52089aD2d95312A5b85E318e9d2", - "decimals": "8", - "borrowCF": 0.7, - "liquidateCF": 0.75, - "liquidationFactor": 0.93, - "supplyCap": "300e8" - } - } -} diff --git a/deployments/optimism-goerli/usdc/deploy.ts b/deployments/optimism-goerli/usdc/deploy.ts deleted file mode 100644 index e95689803..000000000 --- a/deployments/optimism-goerli/usdc/deploy.ts +++ /dev/null @@ -1,112 +0,0 @@ -import { - Deployed, - DeploymentManager, -} from '../../../plugins/deployment_manager'; -import { DeploySpec, deployComet } from '../../../src/deploy'; - -const SECONDS_PER_DAY = 24 * 60 * 60; - -const GOERLI_TIMELOCK = '0x8Fa336EB4bF58Cfc508dEA1B0aeC7336f55B1399'; - -export default async function deploy( - deploymentManager: DeploymentManager, - deploySpec: DeploySpec -): Promise { - const deployed = await deployContracts(deploymentManager, deploySpec); - return deployed; -} - -async function deployContracts( - deploymentManager: DeploymentManager, - deploySpec: DeploySpec -): Promise { - const trace = deploymentManager.tracer(); - const ethers = deploymentManager.hre.ethers; - - // Pull in existing assets - const WETH = await deploymentManager.existing( - 'WETH', - '0x4200000000000000000000000000000000000006', - 'optimism-goerli' - ); - - const l2CrossDomainMessenger = await deploymentManager.existing( - 'l2CrossDomainMessenger', - [ - '0xC0d3c0d3c0D3c0D3C0d3C0D3C0D3c0d3c0d30007', - '0x4200000000000000000000000000000000000007', - ], - 'optimism-goerli' - ); - - const l2StandardBridge = await deploymentManager.existing( - 'l2StandardBridge', - [ - '0xC0d3c0d3c0D3c0d3C0D3c0D3C0d3C0D3C0D30010', - '0x4200000000000000000000000000000000000010', - ], - 'optimism-goerli' - ); - // Deploy OptimismBridgeReceiver - const bridgeReceiver = await deploymentManager.deploy( - 'bridgeReceiver', - 'bridges/optimism/OptimismBridgeReceiver.sol', - [l2CrossDomainMessenger.address] - ); - // Deploy Local Timelock - const localTimelock = await deploymentManager.deploy( - 'timelock', - 'vendor/Timelock.sol', - [ - bridgeReceiver.address, // admin - 10 * 60, // delay - 14 * SECONDS_PER_DAY, // grace period - 10 * 60, // minimum delay - 30 * SECONDS_PER_DAY, // maximum delay - ] - ); - - // Initialize OptimismBridgeReceiver - await deploymentManager.idempotent( - async () => !(await bridgeReceiver.initialized()), - async () => { - trace(`Initializing BridgeReceiver`); - await bridgeReceiver.initialize( - GOERLI_TIMELOCK, // govTimelock - localTimelock.address // localTimelock - ); - trace(`BridgeReceiver initialized`); - } - ); - - // Deploy Comet - const deployed = await deployComet(deploymentManager, deploySpec); - const { comet } = deployed; - - // Deploy Bulker - const bulker = await deploymentManager.deploy( - 'bulker', - 'bulkers/BaseBulker.sol', - [ - await comet.governor(), // admin - WETH.address, // weth - ] - ); - console.log('bulker address', bulker.address); - - // Deploy fauceteer - const fauceteer = await deploymentManager.deploy( - 'fauceteer', - 'test/Fauceteer.sol', - [] - ); - - return { - ...deployed, - bridgeReceiver, - l2CrossDomainMessenger, - l2StandardBridge, - bulker, - fauceteer, - }; -} diff --git a/deployments/optimism-goerli/usdc/migrations/1707402209_configurate_and_ens.ts b/deployments/optimism-goerli/usdc/migrations/1707402209_configurate_and_ens.ts deleted file mode 100644 index 96df82648..000000000 --- a/deployments/optimism-goerli/usdc/migrations/1707402209_configurate_and_ens.ts +++ /dev/null @@ -1,251 +0,0 @@ -import { DeploymentManager } from '../../../../plugins/deployment_manager/DeploymentManager'; -import { - diffState, - getCometConfig, -} from '../../../../plugins/deployment_manager/DiffState'; -import { migration } from '../../../../plugins/deployment_manager/Migration'; -import { - calldata, - exp, - getConfigurationStruct, - proposal, -} from '../../../../src/deploy'; -import { expect } from 'chai'; - -const ENSName = 'compound-community-licenses.eth'; -const ENSResolverAddress = '0x19c2d5D0f035563344dBB7bE5fD09c8dad62b001'; -const ENSRegistryAddress = '0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e'; -const ENSSubdomainLabel = 'v3-additional-grants'; -const ENSSubdomain = `${ENSSubdomainLabel}.${ENSName}`; -const ENSTextRecordKey = 'v3-official-markets'; -const opCOMPAddress = '0x6AF3cb766D6cd37449bfD321D961A61B0515c1BC'; - -export default migration('1707402209_configurate_and_ens', { - prepare: async (deploymentManager: DeploymentManager) => { - return {}; - }, - - enact: async ( - deploymentManager: DeploymentManager, - govDeploymentManager: DeploymentManager - ) => { - const trace = deploymentManager.tracer(); - const ethers = deploymentManager.hre.ethers; - const { utils } = ethers; - - const { - bridgeReceiver, - comet, - cometAdmin, - configurator, - rewards, - } = await deploymentManager.getContracts(); - - const { - opL1CrossDomainMessenger, - opL1StandardBridge, - governor, - COMP: goerliCOMP, - } = await govDeploymentManager.getContracts(); - - // ENS Setup - // See also: https://docs.ens.domains/contract-api-reference/name-processing - const ENSResolver = await govDeploymentManager.existing( - 'ENSResolver', - ENSResolverAddress, - 'goerli' - ); - const subdomainHash = ethers.utils.namehash(ENSSubdomain); - const baseGoerliChainId = ( - await deploymentManager.hre.ethers.provider.getNetwork() - ).chainId.toString(); - const newMarketObject = { baseSymbol: 'USDC', cometAddress: comet.address }; - const officialMarketsJSON = JSON.parse( - await ENSResolver.text(subdomainHash, ENSTextRecordKey) - ); - if (officialMarketsJSON[baseGoerliChainId]) { - officialMarketsJSON[baseGoerliChainId].push(newMarketObject); - } else { - officialMarketsJSON[baseGoerliChainId] = [newMarketObject]; - } - - const configuration = await getConfigurationStruct(deploymentManager); - - const setConfigurationCalldata = await calldata( - configurator.populateTransaction.setConfiguration( - comet.address, - configuration - ) - ); - const deployAndUpgradeToCalldata = utils.defaultAbiCoder.encode( - ['address', 'address'], - [configurator.address, comet.address] - ); - const setRewardConfigCalldata = utils.defaultAbiCoder.encode( - ['address', 'address'], - [comet.address, opCOMPAddress] - ); - const l2ProposalData = utils.defaultAbiCoder.encode( - ['address[]', 'uint256[]', 'string[]', 'bytes[]'], - [ - [configurator.address, cometAdmin.address, rewards.address], - [0, 0, 0], - [ - 'setConfiguration(address,(address,address,address,address,address,uint64,uint64,uint64,uint64,uint64,uint64,uint64,uint64,uint64,uint64,uint64,uint64,uint104,uint104,uint104,(address,address,uint8,uint64,uint64,uint64,uint128)[]))', - 'deployAndUpgradeTo(address,address)', - 'setRewardConfig(address,address)', - ], - [ - setConfigurationCalldata, - deployAndUpgradeToCalldata, - setRewardConfigCalldata, - ], - ] - ); - - const COMPAmountToBridge = exp(10_000, 18); - - // Note: We aren't bridging USDC over to optimism Goerli because they don't use a bridged version of USDC there, - const goerliActions = [ - // 1. Set Comet configuration + deployAndUpgradeTo new Comet and set reward config on Optimism-Goerli. - { - contract: opL1CrossDomainMessenger, - signature: 'sendMessage(address,bytes,uint32)', - args: [bridgeReceiver.address, l2ProposalData, 2_500_000], - }, - - // 2. Approve Goerli's L1StandardBridge to take Timelock's COMP (for bridging) - { - contract: goerliCOMP, - signature: 'approve(address,uint256)', - args: [opL1StandardBridge.address, COMPAmountToBridge], - }, - // 3. Bridge COMP from Goerli to Optimism-Goerli Comet using L1StandardBridge - { - contract: opL1StandardBridge, - // function depositERC20To(address _l1Token, address _l2Token, address _to, uint256 _amount, uint32 _l2Gas,bytes calldata _data) - signature: - 'depositERC20To(address,address,address,uint256,uint32,bytes)', - args: [ - goerliCOMP.address, - opCOMPAddress, - rewards.address, - COMPAmountToBridge, - 200_000, - '0x', - ], - }, - - // 4. Update the list of official markets - { - target: ENSResolverAddress, - signature: 'setText(bytes32,string,string)', - calldata: ethers.utils.defaultAbiCoder.encode( - ['bytes32', 'string', 'string'], - [subdomainHash, ENSTextRecordKey, JSON.stringify(officialMarketsJSON)] - ), - }, - ]; - - const description = 'Proposal text'; - const txn = await govDeploymentManager.retry(async () => - trace( - await governor.propose(...(await proposal(goerliActions, description))) - ) - ); - - const event = txn.events.find((event) => event.event === 'ProposalCreated'); - const [proposalId] = event.args; - - trace(`Created proposal ${proposalId}.`); - }, - - async enacted(deploymentManager: DeploymentManager): Promise { - return true; - }, - - async verify( - deploymentManager: DeploymentManager, - govDeploymentManager: DeploymentManager, - preMigrationBlockNumber: number - ) { - const ethers = deploymentManager.hre.ethers; - await deploymentManager.spider(); // We spider here to pull in Optimism COMP now that reward config has been set - - const { comet, rewards, COMP } = await deploymentManager.getContracts(); - - // 1. - const stateChanges = await diffState( - comet, - getCometConfig, - preMigrationBlockNumber - ); - expect(stateChanges).to.deep.equal({ - pauseGuardian: '0xBA5e81fD6811E2699b478d1Bcde62a585bC9b6f7', //// Should be updated to the correct address - baseTrackingSupplySpeed: exp(34.74 / 86400, 15, 18), /// Should be updated to the correct value - baseTrackingBorrowSpeed: exp(34.74 / 86400, 15, 18), /// Should be updated to the correct value - baseBorrowMin: exp(1, 6), /// Should be updated to the correct value - WETH: { - supplyCap: exp(1000, 18), /// Should be updated to the correct value - }, - OP: { - supplyCap: exp(800, 18), /// Should be updated to the correct value - }, - WBTC: { - supplyCap: exp(800, 18), /// Should be updated to the correct value - }, - }); - ///// =========================================== all checks should be updated to the correct values after getting correct information - const config = await rewards.rewardConfig(comet.address); - expect(config.token).to.be.equal(COMP.address); - expect(config.rescaleFactor).to.be.equal(exp(1, 12)); - expect(config.shouldUpscale).to.be.equal(true); - - // 2. & 3. - expect(await COMP.balanceOf(rewards.address)).to.be.equal(exp(10_000, 18)); - - // 4. - const ENSResolver = await govDeploymentManager.existing( - 'ENSResolver', - ENSResolverAddress, - 'goerli' - ); - const subdomainHash = ethers.utils.namehash(ENSSubdomain); - const officialMarketsJSON = await ENSResolver.text( - subdomainHash, - ENSTextRecordKey - ); - const officialMarkets = JSON.parse(officialMarketsJSON); - expect(officialMarkets).to.deep.equal({ - /// Should parse before migration and update this - 5: [ - { - baseSymbol: 'USDC', - cometAddress: '0x3EE77595A8459e93C2888b13aDB354017B198188', - }, - { - baseSymbol: 'WETH', - cometAddress: '0x9A539EEc489AAA03D588212a164d0abdB5F08F5F', - }, - ], - 80001: [ - { - baseSymbol: 'USDC', - cometAddress: '0xF09F0369aB0a875254fB565E52226c88f10Bc839', - }, - ], - 421613: [ - { - baseSymbol: 'USDC', - cometAddress: '0x1d573274E19174260c5aCE3f2251598959d24456', - }, - ], - 420: [ - { - baseSymbol: 'USDC', - cometAddress: comet.address, - }, - ], - }); - }, -}); diff --git a/deployments/optimism-goerli/usdc/relations.ts b/deployments/optimism-goerli/usdc/relations.ts deleted file mode 100644 index 82f918493..000000000 --- a/deployments/optimism-goerli/usdc/relations.ts +++ /dev/null @@ -1,27 +0,0 @@ -import baseRelationConfig from '../../relations'; - -export default { - ...baseRelationConfig, - governor: { - artifact: - 'contracts/bridges/optimism/OptimismBridgeReceiver.sol:OptimismBridgeReceiver', - }, - - l2CrossDomainMessenger: { - delegates: { - field: { - slot: - '0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc', - }, - }, - }, - - l2StandardBridge: { - delegates: { - field: { - slot: - '0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc', - }, - }, - }, -}; diff --git a/deployments/optimism-goerli/usdc/roots.json b/deployments/optimism-goerli/usdc/roots.json deleted file mode 100644 index a802e529e..000000000 --- a/deployments/optimism-goerli/usdc/roots.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "WETH": "0x4200000000000000000000000000000000000006", - "l2CrossDomainMessenger": "0x4200000000000000000000000000000000000007", - "l2StandardBridge": "0x4200000000000000000000000000000000000010" -} diff --git a/deployments/optimism-goerli/usdt/configuration.json b/deployments/optimism-goerli/usdt/configuration.json deleted file mode 100644 index 25a8b8457..000000000 --- a/deployments/optimism-goerli/usdt/configuration.json +++ /dev/null @@ -1,56 +0,0 @@ -{ - "name": "Compound USDT", - "symbol": "cUSDTv3", - "baseToken": "USDT", - "baseTokenAddress": "0xe05606174bac4A6364B31bd0eCA4bf4dD368f8C6", - "baseTokenPriceFeed": "0x2636B223652d388721A0ED2861792DA9062D8C73", - "pauseGuardian": "0xe7661C55fe281f986FA5312D57d19ADb6064462F", - "borrowMin": "1e6", - "storeFrontPriceFactor": 0.5, - "targetReserves": "1000000e6", - "rates": { - "supplyKink": 0.8, - "supplySlopeLow": 0.0325, - "supplySlopeHigh": 0.4, - "supplyBase": 0, - "borrowKink": 0.8, - "borrowSlopeLow": 0.035, - "borrowSlopeHigh": 0.25, - "borrowBase": 0.015 - }, - "tracking": { - "indexScale": "1e15", - "baseSupplySpeed": "0.000402083333333e15", - "baseBorrowSpeed": "0.000402083333333e15", - "baseMinForRewards": "10000e6" - }, - "assets": { - "WETH": { - "address": "0x4200000000000000000000000000000000000006", - "priceFeed": "0xE30268502Eb3B2341f7961e68a34729302592dC6", - "decimals": "18", - "borrowCF": 0.775, - "liquidateCF": 0.825, - "liquidationFactor": 0.95, - "supplyCap": "1000e18" - }, - "OP": { - "address": "0x4200000000000000000000000000000000000042", - "priceFeed": "0x2636B223652d388721A0ED2861792DA9062D8C73", - "decimals": "18", - "borrowCF": 0.775, - "liquidateCF": 0.825, - "liquidationFactor": 0.95, - "supplyCap": "1000e18" - }, - "WBTC": { - "address": "0x099E6dA9FFF9F0D8873AaD3FB4C9F7eDA5742692", - "priceFeed": "0xC16679B963CeB52089aD2d95312A5b85E318e9d2", - "decimals": "8", - "borrowCF": 0.7, - "liquidateCF": 0.75, - "liquidationFactor": 0.93, - "supplyCap": "300e8" - } - } -} diff --git a/deployments/optimism-goerli/usdt/deploy.ts b/deployments/optimism-goerli/usdt/deploy.ts deleted file mode 100644 index c2bb53772..000000000 --- a/deployments/optimism-goerli/usdt/deploy.ts +++ /dev/null @@ -1,89 +0,0 @@ -import { - Deployed, - DeploymentManager, -} from '../../../plugins/deployment_manager'; -import { DeploySpec, deployComet } from '../../../src/deploy'; - -export default async function deploy( - deploymentManager: DeploymentManager, - deploySpec: DeploySpec -): Promise { - const deployed = await deployContracts(deploymentManager, deploySpec); - return deployed; -} - -async function deployContracts( - deploymentManager: DeploymentManager, - deploySpec: DeploySpec -): Promise { - const trace = deploymentManager.tracer(); - - // Import shared contracts from cUSDCv3 - const cometAdmin = await deploymentManager.fromDep( - 'cometAdmin', - 'optimism-goerli', - 'usdc' - ); - const cometFactory = await deploymentManager.fromDep( - 'cometFactory', - 'optimism-goerli', - 'usdc' - ); - const $configuratorImpl = await deploymentManager.fromDep( - 'configurator:implementation', - 'optimism-goerli', - 'usdc' - ); - const configurator = await deploymentManager.fromDep( - 'configurator', - 'optimism-goerli', - 'usdc' - ); - const rewards = await deploymentManager.fromDep( - 'rewards', - 'optimism-goerli', - 'usdc' - ); - const bulker = await deploymentManager.fromDep( - 'bulker', - 'optimism-goerli', - 'usdc' - ); - const fauceteer = await deploymentManager.fromDep( - 'fauceteer', - 'optimism-goerli', - 'usdc' - ); - const l2CrossDomainMessenger = await deploymentManager.fromDep( - 'l2CrossDomainMessenger', - 'optimism-goerli', - 'usdc' - ); - const l2StandardBridge = await deploymentManager.fromDep( - 'l2StandardBridge', - 'optimism-goerli', - 'usdc' - ); - const localTimelock = await deploymentManager.fromDep( - 'timelock', - 'optimism-goerli', - 'usdc' - ); - const bridgeReceiver = await deploymentManager.fromDep( - 'bridgeReceiver', - 'optimism-goerli', - 'usdc' - ); - - // Deploy Comet - const deployed = await deployComet(deploymentManager, deploySpec); - - return { - ...deployed, - bridgeReceiver, - l2CrossDomainMessenger, - l2StandardBridge, - bulker, - fauceteer, - }; -} diff --git a/deployments/optimism-goerli/usdt/migrations/1707403494_configurate_and_ens.ts b/deployments/optimism-goerli/usdt/migrations/1707403494_configurate_and_ens.ts deleted file mode 100644 index 1b2de04bb..000000000 --- a/deployments/optimism-goerli/usdt/migrations/1707403494_configurate_and_ens.ts +++ /dev/null @@ -1,279 +0,0 @@ -import { DeploymentManager } from '../../../../plugins/deployment_manager/DeploymentManager'; -import { - diffState, - getCometConfig, -} from '../../../../plugins/deployment_manager/DiffState'; -import { migration } from '../../../../plugins/deployment_manager/Migration'; -import { - calldata, - exp, - getConfigurationStruct, - proposal, -} from '../../../../src/deploy'; -import { expect } from 'chai'; - -const ENSName = 'compound-community-licenses.eth'; -const ENSResolverAddress = '0x19c2d5D0f035563344dBB7bE5fD09c8dad62b001'; -const ENSRegistryAddress = '0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e'; -const ENSSubdomainLabel = 'v3-additional-grants'; -const ENSSubdomain = `${ENSSubdomainLabel}.${ENSName}`; -const ENSTextRecordKey = 'v3-official-markets'; -const opCOMPAddress = '0x6AF3cb766D6cd37449bfD321D961A61B0515c1BC'; - -export default migration('1707403494_configurate_and_ens', { - prepare: async (deploymentManager: DeploymentManager) => { - return {}; - }, - - enact: async ( - deploymentManager: DeploymentManager, - govDeploymentManager: DeploymentManager - ) => { - const trace = deploymentManager.tracer(); - const ethers = deploymentManager.hre.ethers; - const { utils } = ethers; - - const cometFactory = await deploymentManager.fromDep( - 'cometFactory', - 'optimism-goerli', - 'usdc' - ); - const { - bridgeReceiver, - timelock: localTimelock, - comet, - cometAdmin, - configurator, - rewards, - WETH, - } = await deploymentManager.getContracts(); - - const { - opL1CrossDomainMessenger, - opL1StandardBridge, - governor, - COMP: goerliCOMP, - } = await govDeploymentManager.getContracts(); - - // ENS Setup - // See also: https://docs.ens.domains/contract-api-reference/name-processing - const ENSResolver = await govDeploymentManager.existing( - 'ENSResolver', - ENSResolverAddress, - 'goerli' - ); - const subdomainHash = ethers.utils.namehash(ENSSubdomain); - const opGoerliChainId = ( - await deploymentManager.hre.ethers.provider.getNetwork() - ).chainId.toString(); - const newMarketObject = { baseSymbol: 'WETH', cometAddress: comet.address }; - const officialMarketsJSON = JSON.parse( - await ENSResolver.text(subdomainHash, ENSTextRecordKey) - ); - if (officialMarketsJSON[opGoerliChainId]) { - officialMarketsJSON[opGoerliChainId].push(newMarketObject); - } else { - officialMarketsJSON[opGoerliChainId] = [newMarketObject]; - } - - const configuration = await getConfigurationStruct(deploymentManager); - const setFactoryCalldata = await calldata( - configurator.populateTransaction.setFactory( - comet.address, - cometFactory.address - ) - ); - const setConfigurationCalldata = await calldata( - configurator.populateTransaction.setConfiguration( - comet.address, - configuration - ) - ); - const deployAndUpgradeToCalldata = utils.defaultAbiCoder.encode( - ['address', 'address'], - [configurator.address, comet.address] - ); - const setRewardConfigCalldata = utils.defaultAbiCoder.encode( - ['address', 'address'], - [comet.address, opCOMPAddress] - ); - - const l2ProposalData = utils.defaultAbiCoder.encode( - ['address[]', 'uint256[]', 'string[]', 'bytes[]'], - [ - [ - configurator.address, - configurator.address, - cometAdmin.address, - rewards.address, - ], - [0, 0, 0, 0], - [ - 'setFactory(address,address)', - 'setConfiguration(address,(address,address,address,address,address,uint64,uint64,uint64,uint64,uint64,uint64,uint64,uint64,uint64,uint64,uint64,uint64,uint104,uint104,uint104,(address,address,uint8,uint64,uint64,uint64,uint128)[]))', - 'deployAndUpgradeTo(address,address)', - 'setRewardConfig(address,address)', - ], - [ - setFactoryCalldata, - setConfigurationCalldata, - deployAndUpgradeToCalldata, - setRewardConfigCalldata, - ], - ] - ); - - const COMPAmountToBridge = exp(10_000, 18); - - const goerliActions = [ - // 1. Set Comet configuration + deployAndUpgradeTo new Comet, set reward config on Optimism-Goerli - { - contract: opL1CrossDomainMessenger, - signature: 'sendMessage(address,bytes,uint32)', - args: [bridgeReceiver.address, l2ProposalData, 3_500_000], - }, - - // 2. Approve Goerli's L1StandardBridge to take Timelock's COMP (for bridging) - { - contract: goerliCOMP, - signature: 'approve(address,uint256)', - args: [opL1StandardBridge.address, COMPAmountToBridge], - }, - // 3. Bridge COMP from Goerli to Base-Goerli Comet using L1StandardBridge - { - contract: opL1StandardBridge, - // function depositERC20To(address _l1Token, address _l2Token, address _to, uint256 _amount, uint32 _l2Gas,bytes calldata _data) - signature: - 'depositERC20To(address,address,address,uint256,uint32,bytes)', - args: [ - goerliCOMP.address, - opCOMPAddress, - rewards.address, - COMPAmountToBridge, - 200_000, - '0x', - ], - }, - - // 5. Update the list of official markets - { - target: ENSResolverAddress, - signature: 'setText(bytes32,string,string)', - calldata: ethers.utils.defaultAbiCoder.encode( - ['bytes32', 'string', 'string'], - [subdomainHash, ENSTextRecordKey, JSON.stringify(officialMarketsJSON)] - ), - }, - ]; - - const description = - 'Proposal to set Comet configuration, deployAndUpgradeTo new Comet, set reward config on Optimism-Goerli, bridge COMP from Goerli to Optimism-Goerli Comet, and update the list of official markets.'; - const txn = await govDeploymentManager.retry(async () => - trace( - await governor.propose(...(await proposal(goerliActions, description))) - ) - ); - - const event = txn.events.find((event) => event.event === 'ProposalCreated'); - const [proposalId] = event.args; - - trace(`Created proposal ${proposalId}.`); - }, - - async enacted(deploymentManager: DeploymentManager): Promise { - return true; - }, - - async verify( - deploymentManager: DeploymentManager, - govDeploymentManager: DeploymentManager, - preMigrationBlockNumber: number - ) { - const ethers = deploymentManager.hre.ethers; - await deploymentManager.spider(); // We spider here to pull in Optimism COMP now that reward config has been set - - const { - comet, - rewards, - COMP, - WETH, - } = await deploymentManager.getContracts(); - - // 1. - const stateChanges = await diffState( - comet, - getCometConfig, - preMigrationBlockNumber - ); - expect(stateChanges).to.deep.equal({ - pauseGuardian: '0xBA5e81fD6811E2699b478d1Bcde62a585bC9b6f7', //// Should be updated to the correct address. Create by script clone multi sig - baseTrackingSupplySpeed: exp(34.74 / 86400, 15, 18), - baseTrackingBorrowSpeed: exp(34.74 / 86400, 15, 18), - WETH: { - supplyCap: exp(1000, 18), /// Should be updated to the correct value - }, - OP: { - supplyCap: exp(800, 18), /// Should be updated to the correct value - }, - WBTC: { - supplyCap: exp(800, 18), /// Should be updated to the correct value - }, - }); - - const config = await rewards.rewardConfig(comet.address); - expect(config.token).to.be.equal(COMP.address); - expect(config.rescaleFactor).to.be.equal(exp(1, 12)); - expect(config.shouldUpscale).to.be.equal(true); - - expect(await COMP.balanceOf(rewards.address)).to.be.equal(exp(20_000, 18)); - - const ENSResolver = await govDeploymentManager.existing( - 'ENSResolver', - ENSResolverAddress, - 'goerli' - ); - const subdomainHash = ethers.utils.namehash(ENSSubdomain); - const officialMarketsJSON = await ENSResolver.text( - subdomainHash, - ENSTextRecordKey - ); - const officialMarkets = JSON.parse(officialMarketsJSON); - ///// parse from contract and update this before migration - expect(officialMarkets).to.deep.equal({ - 5: [ - { - baseSymbol: 'USDC', - cometAddress: '0x3EE77595A8459e93C2888b13aDB354017B198188', - }, - { - baseSymbol: 'WETH', - cometAddress: '0x9A539EEc489AAA03D588212a164d0abdB5F08F5F', - }, - ], - 80001: [ - { - baseSymbol: 'USDC', - cometAddress: '0xF09F0369aB0a875254fB565E52226c88f10Bc839', - }, - ], - 421613: [ - { - baseSymbol: 'USDC', - cometAddress: '0x1d573274E19174260c5aCE3f2251598959d24456', - }, - ], - 84531: [ - { - baseSymbol: 'USDC', - cometAddress: '0xe78Fc55c884704F9485EDa042fb91BfE16fD55c1', - }, - ], - 420: [ - { - baseSymbol: 'USDT', - cometAddress: comet.address, - }, - ], - }); - }, -}); diff --git a/deployments/optimism-goerli/usdt/relations.ts b/deployments/optimism-goerli/usdt/relations.ts deleted file mode 100644 index 82f918493..000000000 --- a/deployments/optimism-goerli/usdt/relations.ts +++ /dev/null @@ -1,27 +0,0 @@ -import baseRelationConfig from '../../relations'; - -export default { - ...baseRelationConfig, - governor: { - artifact: - 'contracts/bridges/optimism/OptimismBridgeReceiver.sol:OptimismBridgeReceiver', - }, - - l2CrossDomainMessenger: { - delegates: { - field: { - slot: - '0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc', - }, - }, - }, - - l2StandardBridge: { - delegates: { - field: { - slot: - '0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc', - }, - }, - }, -}; diff --git a/deployments/optimism-goerli/usdt/roots.json b/deployments/optimism-goerli/usdt/roots.json deleted file mode 100644 index a802e529e..000000000 --- a/deployments/optimism-goerli/usdt/roots.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "WETH": "0x4200000000000000000000000000000000000006", - "l2CrossDomainMessenger": "0x4200000000000000000000000000000000000007", - "l2StandardBridge": "0x4200000000000000000000000000000000000010" -} diff --git a/hardhat.config.ts b/hardhat.config.ts index f661bcd0b..3362e0adb 100644 --- a/hardhat.config.ts +++ b/hardhat.config.ts @@ -37,8 +37,6 @@ import baseGoerliWethRelationConfigMap from './deployments/base-goerli/weth/rela import lineaGoerliRelationConfigMap from './deployments/linea-goerli/usdc/relations'; import optimismRelationConfigMap from './deployments/optimism/usdc/relations'; import optimismUsdtRelationConfigMap from './deployments/optimism/usdt/relations'; -import optimismGoerliRelationConfigMap from './deployments/optimism-goerli/usdc/relations'; -import optimismGoerliUsdtRelationConfigMap from './deployments/optimism-goerli/usdt/relations'; task('accounts', 'Prints the list of accounts', async (taskArgs, hre) => { for (const account of await hre.ethers.getSigners()) @@ -117,11 +115,6 @@ const networkConfigs: NetworkConfig[] = [ chainId: 10, url: `https://optimism-mainnet.infura.io/v3/${INFURA_KEY}`, }, - { - network: 'optimism-goerli', - chainId: 420, - url: `https://optimism-goerli.infura.io/v3/${INFURA_KEY}`, - }, { network: 'base', chainId: 8453, @@ -263,7 +256,6 @@ const config: HardhatUserConfig = { // Linea 'linea-goerli': LINEASCAN_KEY, optimism: OPTIMISMSCAN_KEY, - 'optimism-goerli': OPTIMISMSCAN_KEY, }, customChains: [ { @@ -310,14 +302,6 @@ const config: HardhatUserConfig = { browserURL: 'https://goerli.lineascan.build/', }, }, - { - network: 'optimism-goerli', - chainId: 420, - urls: { - apiURL: 'https://api-goerli-optimistic.etherscan.io/api', - browserURL: 'https://goerli-optimism.etherscan.io/', - }, - }, ], }, @@ -370,10 +354,6 @@ const config: HardhatUserConfig = { usdc: optimismRelationConfigMap, usdt: optimismUsdtRelationConfigMap, }, - 'optimism-goerli': { - usdc: optimismGoerliRelationConfigMap, - usdt: optimismGoerliUsdtRelationConfigMap, - }, }, }, @@ -498,18 +478,6 @@ const config: HardhatUserConfig = { deployment: 'usdt', auxiliaryBase: 'mainnet', }, - { - name: 'optimism-goerli', - network: 'optimism-goerli', - deployment: 'usdc', - auxiliaryBase: 'goerli', - }, - { - name: 'optimism-goerli-usdt', - network: 'optimism-goerli', - deployment: 'usdt', - auxiliaryBase: 'goerli', - }, ], }, diff --git a/plugins/import/etherscan.ts b/plugins/import/etherscan.ts index 537361dfb..9f6a0b98a 100644 --- a/plugins/import/etherscan.ts +++ b/plugins/import/etherscan.ts @@ -23,7 +23,6 @@ export function getEtherscanApiUrl(network: string): string { 'base-goerli': 'api-goerli.basescan.org', 'linea-goerli': 'api-goerli.lineascan.build', optimism: 'api-optimistic.etherscan.io', - 'optimism-goerli': 'api-goerli-optimistic.etherscan.io', }[network]; if (!host) { @@ -50,7 +49,6 @@ export function getEtherscanUrl(network: string): string { 'base-goerli': 'goerli.basescan.org', 'linea-goerli': 'goerli.lineascan.build', optimism: 'optimistic.etherscan.io', - 'optimism-goerli': 'goerli-optimistic.etherscan.io', }[network]; if (!host) { @@ -77,7 +75,6 @@ export function getEtherscanApiKey(network: string): string { 'base-goerli': process.env.BASESCAN_KEY, 'linea-goerli': process.env.LINEASCAN_KEY, optimism: process.env.OPTIMISMSCAN_KEY, - 'optimism-goerli': process.env.OPTIMISMSCAN_KEY, }[network]; if (!apiKey) { diff --git a/scenario/utils/relayMessage.ts b/scenario/utils/relayMessage.ts index 846914228..d4856f187 100644 --- a/scenario/utils/relayMessage.ts +++ b/scenario/utils/relayMessage.ts @@ -20,7 +20,6 @@ export default async function relayMessage( ); break; case 'optimism': - case 'optimism-goerli': await relayBaseMessage( governanceDeploymentManager, bridgeDeploymentManager, From b2d986c5f0f872fa88bde1cd80001638391a644f Mon Sep 17 00:00:00 2001 From: dmitriy-bergman-works Date: Mon, 18 Mar 2024 17:29:02 +0200 Subject: [PATCH 11/37] usdc market deploy; update roots; add wstETH into relations --- deployments/optimism/usdc/relations.ts | 3 +++ deployments/optimism/usdc/roots.json | 13 +++++++++---- hardhat.config.ts | 1 + 3 files changed, 13 insertions(+), 4 deletions(-) diff --git a/deployments/optimism/usdc/relations.ts b/deployments/optimism/usdc/relations.ts index 82f918493..cbfbba21c 100644 --- a/deployments/optimism/usdc/relations.ts +++ b/deployments/optimism/usdc/relations.ts @@ -24,4 +24,7 @@ export default { }, }, }, + '0x1f32b1c2345538c0c6f582fcb022739c4a194ebb': { + artifact: 'contracts/ERC20.sol:ERC20' + }, }; diff --git a/deployments/optimism/usdc/roots.json b/deployments/optimism/usdc/roots.json index 334c1fb82..62e5a1789 100644 --- a/deployments/optimism/usdc/roots.json +++ b/deployments/optimism/usdc/roots.json @@ -1,5 +1,10 @@ { - "l2CrossDomainMessenger": "0x4200000000000000000000000000000000000007", - "l2StandardBridge": "0x4200000000000000000000000000000000000010", - "CCTPMessageTransmitter": "0x4D41f22c5a0e5c74090899E5a8Fb597a8842b3e8" -} + "l2CrossDomainMessenger": "0x4200000000000000000000000000000000000007", + "l2StandardBridge": "0x4200000000000000000000000000000000000010", + "CCTPMessageTransmitter": "0x4D41f22c5a0e5c74090899E5a8Fb597a8842b3e8", + "comet": "0xdB7EdFa090061D9367CbEAF6bE16ECbDE596676C", + "configurator": "0x2c7118c4C88B9841FCF839074c26Ae8f035f2921", + "rewards": "0x5404872d8f2e24b230EC9B9eC64E3855F637FB93", + "bulker": "0x5C58d4479A1E9b2d19EE052143FA73F0ee79A36e", + "bridgeReceiver": "0x4A900f81dEdA753bbBab12453b3775D5f26df6F3" +} \ No newline at end of file diff --git a/hardhat.config.ts b/hardhat.config.ts index 3362e0adb..f7e91ac34 100644 --- a/hardhat.config.ts +++ b/hardhat.config.ts @@ -256,6 +256,7 @@ const config: HardhatUserConfig = { // Linea 'linea-goerli': LINEASCAN_KEY, optimism: OPTIMISMSCAN_KEY, + optimisticEthereum: OPTIMISMSCAN_KEY, }, customChains: [ { From 743089825a7de1845dc0889f53c9370b561877f2 Mon Sep 17 00:00:00 2001 From: dmitriy-bergman-works Date: Mon, 18 Mar 2024 23:07:26 +0200 Subject: [PATCH 12/37] update migration description text; add optimism whale; update importTest --- .../usdc/migrations/1707394874_configurate_and_ens.ts | 2 +- .../usdt/migrations/1707399040_configurate_and_ens.ts | 2 +- plugins/deployment_manager/test/ImportTest.ts | 4 ++-- src/deploy/index.ts | 3 +++ 4 files changed, 7 insertions(+), 4 deletions(-) diff --git a/deployments/optimism/usdc/migrations/1707394874_configurate_and_ens.ts b/deployments/optimism/usdc/migrations/1707394874_configurate_and_ens.ts index fc1085061..5dc6f4c43 100644 --- a/deployments/optimism/usdc/migrations/1707394874_configurate_and_ens.ts +++ b/deployments/optimism/usdc/migrations/1707394874_configurate_and_ens.ts @@ -166,7 +166,7 @@ export default migration("1707394874_configurate_and_ens", { }, ]; - const description = "# Initialize cUSDCv3 on Optimism\n\nThis proposal takes the governance steps recommended and necessary to initialize a Compound III USDC market on Optimism; upon execution, cUSDCv3 will be ready for use. Simulations have confirmed the market’s readiness, as much as possible, using the [Comet scenario suite](https://github.com/compound-finance/comet/tree/main/scenario). The new parameters include setting the risk parameters based off of the [recommendations from Gauntlet](https://www.comp.xyz/t/deploy-compound-iii-on-optimism/4975/6). Further detailed information can be found on the corresponding [proposal pull request](https://github.com/compound-finance/comet/pull/833) and [forum discussion](https://www.comp.xyz/t/deploy-compound-iii-on-optimism/4975).\n\n\n## Proposal Actions\n\nThe first proposal action sets the Comet configuration and deploys a new Comet implementation on Optimism. This sends the encoded `setConfiguration` and `deployAndUpgradeTo` calls across the bridge to the governance receiver on Optimism. It also calls `setRewardConfig` on the Optimism rewards contract, to establish Optimism’s bridged version of COMP as the reward token for the deployment and set the initial supply speed to be 5 COMP/day and borrow speed to be 5 COMP/day.\n\nThe second action approves Circle’s Cross-Chain Transfer Protocol (CCTP) [TokenMessenger](https://etherscan.io/address/0xbd3fa81b58ba92a82136038b25adec7066af3155) to take the Timelock's USDC on Mainnet, in order to seed the market reserves through the CCTP.\n\nThe third action deposits and burns 10K USDC from mainnet via depositForBurn function on CCTP’s TokenMessenger contract to mint native USDC to Comet on Optimism.\n\nThe fourth action approves Optimism’s [L1StandardBridge](https://etherscan.io/address/0x99C9fc46f92E8a1c0deC1b1747d010903E884bE1) to take Timelock's COMP, in order to seed the rewards contract through the bridge.\n\nThe fifth action deposits 3.6K COMP from mainnet to the Optimism L1StandardBridge contract to bridge to CometRewards.\n\nThe sixth action updates the ENS TXT record `v3-official-markets` on `v3-additional-grants.compound-community-licenses.eth`, updating the official markets JSON to include the new Optimism cUSDCv3 market"; /// TODO : should be + const description = "# Initialize cUSDCv3 on Optimism\n\n## Proposal summary\n\nCompound Growth Program [AlphaGrowth] proposes deployment of Compound III to Optimism network. This proposal takes the governance steps recommended and necessary to initialize a Compound III USDC market on Optimism; upon execution, cUSDCv3 will be ready for use. Simulations have confirmed the market’s readiness, as much as possible, using the [Comet scenario suite](https://github.com/compound-finance/comet/tree/main/scenario). The new parameters include setting the risk parameters based off of the [recommendations from Gauntlet](https://www.comp.xyz/t/deploy-compound-iii-on-optimism/4975/6).\n\nFurther detailed information can be found on the corresponding [proposal pull request](https://github.com/compound-finance/comet/pull/833) and [forum discussion](https://www.comp.xyz/t/deploy-compound-iii-on-optimism/4975).\n\n\n## Proposal Actions\n\nThe first proposal action sets the Comet configuration and deploys a new Comet implementation on Optimism. This sends the encoded `setConfiguration` and `deployAndUpgradeTo` calls across the bridge to the governance receiver on Optimism. It also calls `setRewardConfig` on the Optimism rewards contract, to establish Optimism’s bridged version of COMP as the reward token for the deployment and set the initial supply speed to be 5 COMP/day and borrow speed to be 5 COMP/day.\n\nThe second action approves Circle’s Cross-Chain Transfer Protocol (CCTP) [TokenMessenger](https://etherscan.io/address/0xbd3fa81b58ba92a82136038b25adec7066af3155) to take the Timelock's USDC on Mainnet, in order to seed the market reserves through the CCTP.\n\nThe third action deposits and burns 10K USDC from mainnet via depositForBurn function on CCTP’s TokenMessenger contract to mint native USDC to Comet on Optimism.\n\nThe fourth action approves Optimism’s [L1StandardBridge](https://etherscan.io/address/0x99C9fc46f92E8a1c0deC1b1747d010903E884bE1) to take Timelock's COMP, in order to seed the rewards contract through the bridge.\n\nThe fifth action deposits 3.6K COMP from mainnet to the Optimism L1StandardBridge contract to bridge to CometRewards.\n\nThe sixth action updates the ENS TXT record `v3-official-markets` on `v3-additional-grants.compound-community-licenses.eth`, updating the official markets JSON to include the new Optimism cUSDCv3 market"; const txn = await govDeploymentManager.retry(async () => trace(await governor.propose(...(await proposal(actions, description)))) ); diff --git a/deployments/optimism/usdt/migrations/1707399040_configurate_and_ens.ts b/deployments/optimism/usdt/migrations/1707399040_configurate_and_ens.ts index deddbe539..93b050e0d 100644 --- a/deployments/optimism/usdt/migrations/1707399040_configurate_and_ens.ts +++ b/deployments/optimism/usdt/migrations/1707399040_configurate_and_ens.ts @@ -165,7 +165,7 @@ export default migration("1707399040_configurate_and_ens", { }, ]; - const description = "# Initialize cUSDTv3 on Optimism\n\nThis proposal takes the governance steps recommended and necessary to initialize a Compound III USDT market on Optimism; upon execution, cUSDTv3 will be ready for use. Simulations have confirmed the market’s readiness, as much as possible, using the [Comet scenario suite](https://github.com/compound-finance/comet/tree/main/scenario). The new parameters include setting the risk parameters based off of the [recommendations from Gauntlet](https://www.comp.xyz/t/deploy-compound-iii-on-optimism/4975/6). Further detailed information can be found on the corresponding [proposal pull request](https://github.com/compound-finance/comet/pull/833) and [forum discussion](https://www.comp.xyz/t/deploy-compound-iii-on-optimism/4975).\n\n\n## Proposal Actions\n\nThe first proposal action sets the Comet configuration and deploys a new Comet implementation on Optimism. This sends the encoded `setConfiguration` and `deployAndUpgradeTo` calls across the bridge to the governance receiver on Optimism. It also calls `setRewardConfig` on the Optimism rewards contract, to establish Optimism’s bridged version of COMP as the reward token for the deployment and set the initial supply speed to be 5 COMP/day and borrow speed to be 5 COMP/day.\n\nThe second action approves Circle’s Cross-Chain Transfer Protocol (CCTP) [TokenMessenger](https://etherscan.io/address/0xbd3fa81b58ba92a82136038b25adec7066af3155) to take the Timelock's USDT on Mainnet, in order to seed the market reserves through the CCTP.\n\nThe third action deposits and burns 10K USDT from mainnet via depositForBurn function on CCTP’s TokenMessenger contract to mint native USDT to Comet on Optimism.\n\nThe fourth action updates the ENS TXT record `v3-official-markets` on `v3-additional-grants.compound-community-licenses.eth`, updating the official markets JSON to include the new Optimism cUSDTv3 market"; + const description = "# Initialize cUSDTv3 on Optimism\n\n## Proposal summary\n\nCompound Growth Program [AlphaGrowth] proposes deployment of Compound III to Optimism network. This proposal takes the governance steps recommended and necessary to initialize a Compound III USDT market on Optimism; upon execution, cUSDTv3 will be ready for use. Simulations have confirmed the market’s readiness, as much as possible, using the [Comet scenario suite](https://github.com/compound-finance/comet/tree/main/scenario). The new parameters include setting the risk parameters based off of the [recommendations from Gauntlet](https://www.comp.xyz/t/deploy-compound-iii-on-optimism/4975/6).\n\nFurther detailed information can be found on the corresponding [proposal pull request](https://github.com/compound-finance/comet/pull/833) and [forum discussion](https://www.comp.xyz/t/deploy-compound-iii-on-optimism/4975).\n\n\n## Proposal Actions\n\nThe first proposal action sets the Comet configuration and deploys a new Comet implementation on Optimism. This sends the encoded `setConfiguration` and `deployAndUpgradeTo` calls across the bridge to the governance receiver on Optimism. It also calls `setRewardConfig` on the Optimism rewards contract, to establish Optimism’s bridged version of COMP as the reward token for the deployment and set the initial supply speed to be 5 COMP/day and borrow speed to be 5 COMP/day.\n\nThe second action approves Circle’s Cross-Chain Transfer Protocol (CCTP) [TokenMessenger](https://etherscan.io/address/0xbd3fa81b58ba92a82136038b25adec7066af3155) to take the Timelock's USDT on Mainnet, in order to seed the market reserves through the CCTP.\n\nThe third action deposits and burns 10K USDT from mainnet via depositForBurn function on CCTP’s TokenMessenger contract to mint native USDT to Comet on Optimism.\n\nThe fourth action approves Optimism’s [L1StandardBridge](https://etherscan.io/address/0x99C9fc46f92E8a1c0deC1b1747d010903E884bE1) to take Timelock's COMP, in order to seed the rewards contract through the bridge.\n\nThe fifth action deposits 3.6K COMP from mainnet to the Optimism L1StandardBridge contract to bridge to CometRewards.\n\nThe sixth action updates the ENS TXT record `v3-official-markets` on `v3-additional-grants.compound-community-licenses.eth`, updating the official markets JSON to include the new Optimism cUSDTv3 market"; const txn = await govDeploymentManager.retry(async () => trace(await governor.propose(...(await proposal(actions, description)))) ); diff --git a/plugins/deployment_manager/test/ImportTest.ts b/plugins/deployment_manager/test/ImportTest.ts index c6017dea5..04a636885 100644 --- a/plugins/deployment_manager/test/ImportTest.ts +++ b/plugins/deployment_manager/test/ImportTest.ts @@ -57,11 +57,11 @@ export function mockImportSuccess(address: string) { .get(`/address/${address}`) .reply( 200, - `
608060405234801561001057600080fd5b506040516108a93803806108a98339818101604052602081101561003357600080fd5b5051808061004081610051565b5061004a336100c3565b5050610123565b610064816100e760201b61042a1760201c565b61009f5760405162461bcd60e51b815260040180806020018281038252603b81526020018061086e603b913960400191505060405180910390fd5b7f7050c9e0f4ca769c69bd3a8ef740bc37934f8e2c036e5a723fd8ee048ed3f8c355565b7f10d6a54a4754c8869d6886b5f5d7fbfa5b4522237ea5c60d11bc4e7a1ff9390b55565b6000813f7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a47081811480159061011b57508115155b949350505050565b61073c806101326000396000f3fe60806040526004361061005a5760003560e01c80635c60da1b116100435780635c60da1b146101315780638f2839701461016f578063f851a440146101af5761005a565b80633659cfe6146100645780634f1ef286146100a4575b6100626101c4565b005b34801561007057600080fd5b506100626004803603602081101561008757600080fd5b503573ffffffffffffffffffffffffffffffffffffffff166101de565b610062600480360360408110156100ba57600080fd5b73ffffffffffffffffffffffffffffffffffffffff82351691908101906040810160208201356401000000008111156100f257600080fd5b82018360208201111561010457600080fd5b8035906020019184600183028401116401000000008311171561012657600080fd5b509092509050610232565b34801561013d57600080fd5b50610146610309565b6040805173ffffffffffffffffffffffffffffffffffffffff9092168252519081900360200190f35b34801561017b57600080fd5b506100626004803603602081101561019257600080fd5b503573ffffffffffffffffffffffffffffffffffffffff16610318565b3480156101bb57600080fd5b50610146610420565b6101cc610466565b6101dc6101d76104fa565b61051f565b565b6101e6610543565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614156102275761022281610568565b61022f565b61022f6101c4565b50565b61023a610543565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614156102fc5761027683610568565b60003073ffffffffffffffffffffffffffffffffffffffff16348484604051808383808284376040519201945060009350909150508083038185875af1925050503d80600081146102e3576040519150601f19603f3d011682016040523d82523d6000602084013e6102e8565b606091505b50509050806102f657600080fd5b50610304565b6103046101c4565b505050565b60006103136104fa565b905090565b610320610543565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614156102275773ffffffffffffffffffffffffffffffffffffffff81166103bf576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260368152602001806106966036913960400191505060405180910390fd5b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f6103e8610543565b6040805173ffffffffffffffffffffffffffffffffffffffff928316815291841660208301528051918290030190a1610222816105bd565b6000610313610543565b6000813f7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a47081811480159061045e57508115155b949350505050565b61046e610543565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614156104f2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260328152602001806106646032913960400191505060405180910390fd5b6101dc6101dc565b7f7050c9e0f4ca769c69bd3a8ef740bc37934f8e2c036e5a723fd8ee048ed3f8c35490565b3660008037600080366000845af43d6000803e80801561053e573d6000f35b3d6000fd5b7f10d6a54a4754c8869d6886b5f5d7fbfa5b4522237ea5c60d11bc4e7a1ff9390b5490565b610571816105e1565b6040805173ffffffffffffffffffffffffffffffffffffffff8316815290517fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b9181900360200190a150565b7f10d6a54a4754c8869d6886b5f5d7fbfa5b4522237ea5c60d11bc4e7a1ff9390b55565b6105ea8161042a565b61063f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603b8152602001806106cc603b913960400191505060405180910390fd5b7f7050c9e0f4ca769c69bd3a8ef740bc37934f8e2c036e5a723fd8ee048ed3f8c35556fe43616e6e6f742063616c6c2066616c6c6261636b2066756e6374696f6e2066726f6d207468652070726f78792061646d696e43616e6e6f74206368616e6765207468652061646d696e206f6620612070726f787920746f20746865207a65726f206164647265737343616e6e6f742073657420612070726f787920696d706c656d656e746174696f6e20746f2061206e6f6e2d636f6e74726163742061646472657373a26469706673582212206715e283f350a976c05fe8b17fc01929cb137086f941d36864b48c4269d883b264736f6c634300060c003343616e6e6f742073657420612070726f787920696d706c656d656e746174696f6e20746f2061206e6f6e2d636f6e74726163742061646472657373
` + `
608060405234801561001057600080fd5b506040516108a93803806108a98339818101604052602081101561003357600080fd5b5051808061004081610051565b5061004a336100c3565b5050610123565b610064816100e760201b61042a1760201c565b61009f5760405162461bcd60e51b815260040180806020018281038252603b81526020018061086e603b913960400191505060405180910390fd5b7f7050c9e0f4ca769c69bd3a8ef740bc37934f8e2c036e5a723fd8ee048ed3f8c355565b7f10d6a54a4754c8869d6886b5f5d7fbfa5b4522237ea5c60d11bc4e7a1ff9390b55565b6000813f7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a47081811480159061011b57508115155b949350505050565b61073c806101326000396000f3fe60806040526004361061005a5760003560e01c80635c60da1b116100435780635c60da1b146101315780638f2839701461016f578063f851a440146101af5761005a565b80633659cfe6146100645780634f1ef286146100a4575b6100626101c4565b005b34801561007057600080fd5b506100626004803603602081101561008757600080fd5b503573ffffffffffffffffffffffffffffffffffffffff166101de565b610062600480360360408110156100ba57600080fd5b73ffffffffffffffffffffffffffffffffffffffff82351691908101906040810160208201356401000000008111156100f257600080fd5b82018360208201111561010457600080fd5b8035906020019184600183028401116401000000008311171561012657600080fd5b509092509050610232565b34801561013d57600080fd5b50610146610309565b6040805173ffffffffffffffffffffffffffffffffffffffff9092168252519081900360200190f35b34801561017b57600080fd5b506100626004803603602081101561019257600080fd5b503573ffffffffffffffffffffffffffffffffffffffff16610318565b3480156101bb57600080fd5b50610146610420565b6101cc610466565b6101dc6101d76104fa565b61051f565b565b6101e6610543565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614156102275761022281610568565b61022f565b61022f6101c4565b50565b61023a610543565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614156102fc5761027683610568565b60003073ffffffffffffffffffffffffffffffffffffffff16348484604051808383808284376040519201945060009350909150508083038185875af1925050503d80600081146102e3576040519150601f19603f3d011682016040523d82523d6000602084013e6102e8565b606091505b50509050806102f657600080fd5b50610304565b6103046101c4565b505050565b60006103136104fa565b905090565b610320610543565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614156102275773ffffffffffffffffffffffffffffffffffffffff81166103bf576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260368152602001806106966036913960400191505060405180910390fd5b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f6103e8610543565b6040805173ffffffffffffffffffffffffffffffffffffffff928316815291841660208301528051918290030190a1610222816105bd565b6000610313610543565b6000813f7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a47081811480159061045e57508115155b949350505050565b61046e610543565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614156104f2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260328152602001806106646032913960400191505060405180910390fd5b6101dc6101dc565b7f7050c9e0f4ca769c69bd3a8ef740bc37934f8e2c036e5a723fd8ee048ed3f8c35490565b3660008037600080366000845af43d6000803e80801561053e573d6000f35b3d6000fd5b7f10d6a54a4754c8869d6886b5f5d7fbfa5b4522237ea5c60d11bc4e7a1ff9390b5490565b610571816105e1565b6040805173ffffffffffffffffffffffffffffffffffffffff8316815290517fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b9181900360200190a150565b7f10d6a54a4754c8869d6886b5f5d7fbfa5b4522237ea5c60d11bc4e7a1ff9390b55565b6105ea8161042a565b61063f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603b8152602001806106cc603b913960400191505060405180910390fd5b7f7050c9e0f4ca769c69bd3a8ef740bc37934f8e2c036e5a723fd8ee048ed3f8c35556fe43616e6e6f742063616c6c2066616c6c6261636b2066756e6374696f6e2066726f6d207468652070726f78792061646d696e43616e6e6f74206368616e6765207468652061646d696e206f6620612070726f787920746f20746865207a65726f206164647265737343616e6e6f742073657420612070726f787920696d706c656d656e746174696f6e20746f2061206e6f6e2d636f6e74726163742061646472657373a26469706673582212206715e283f350a976c05fe8b17fc01929cb137086f941d36864b48c4269d883b264736f6c634300060c003343616e6e6f742073657420612070726f787920696d706c656d656e746174696f6e20746f2061206e6f6e2d636f6e74726163742061646472657373
` ); } -describe('Import', () => { +describe.only('Import', () => { beforeEach(async () => { nock.disableNetConnect(); }); diff --git a/src/deploy/index.ts b/src/deploy/index.ts index bbcbf8f54..d4bd85056 100644 --- a/src/deploy/index.ts +++ b/src/deploy/index.ts @@ -115,6 +115,9 @@ export const WHALES = { 'linea-goerli': [ '0xC858966280Da3Fa0348E51D2c3B892EcC889fC98', // USDC whale '0x44411c605eb7e009cad03f3847cfbbfcf8895130' // COMP whale + ], + optimism: [ + '0x2A82Ae142b2e62Cb7D10b55E323ACB1Cab663a26' // TODO: add whales ] }; From 039bef2693de89713ee743d7209c4e0dfde81c12 Mon Sep 17 00:00:00 2001 From: dmitriy-bergman-works Date: Tue, 19 Mar 2024 00:22:26 +0200 Subject: [PATCH 13/37] update workflows names because git does not display them on actions tab --- .github/workflows/{deploy-market.yaml => deploy-market-temp.yaml} | 0 .../workflows/{enact-migration.yaml => enact-migration-temp.yaml} | 0 .../{prepare-migration.yaml => prepare-migration-temp.yaml} | 0 .github/workflows/{run-coverage.yaml => run-coverage-temp.yaml} | 0 4 files changed, 0 insertions(+), 0 deletions(-) rename .github/workflows/{deploy-market.yaml => deploy-market-temp.yaml} (100%) rename .github/workflows/{enact-migration.yaml => enact-migration-temp.yaml} (100%) rename .github/workflows/{prepare-migration.yaml => prepare-migration-temp.yaml} (100%) rename .github/workflows/{run-coverage.yaml => run-coverage-temp.yaml} (100%) diff --git a/.github/workflows/deploy-market.yaml b/.github/workflows/deploy-market-temp.yaml similarity index 100% rename from .github/workflows/deploy-market.yaml rename to .github/workflows/deploy-market-temp.yaml diff --git a/.github/workflows/enact-migration.yaml b/.github/workflows/enact-migration-temp.yaml similarity index 100% rename from .github/workflows/enact-migration.yaml rename to .github/workflows/enact-migration-temp.yaml diff --git a/.github/workflows/prepare-migration.yaml b/.github/workflows/prepare-migration-temp.yaml similarity index 100% rename from .github/workflows/prepare-migration.yaml rename to .github/workflows/prepare-migration-temp.yaml diff --git a/.github/workflows/run-coverage.yaml b/.github/workflows/run-coverage-temp.yaml similarity index 100% rename from .github/workflows/run-coverage.yaml rename to .github/workflows/run-coverage-temp.yaml From 294270dd6f6d0fcd9b3f7ca6b82e27ebcaada026 Mon Sep 17 00:00:00 2001 From: dmitriy-bergman-works Date: Tue, 19 Mar 2024 00:23:14 +0200 Subject: [PATCH 14/37] return initial workflows names --- .github/workflows/{deploy-market-temp.yaml => deploy-market.yaml} | 0 .../workflows/{enact-migration-temp.yaml => enact-migration.yaml} | 0 .../{prepare-migration-temp.yaml => prepare-migration.yaml} | 0 .github/workflows/{run-coverage-temp.yaml => run-coverage.yaml} | 0 4 files changed, 0 insertions(+), 0 deletions(-) rename .github/workflows/{deploy-market-temp.yaml => deploy-market.yaml} (100%) rename .github/workflows/{enact-migration-temp.yaml => enact-migration.yaml} (100%) rename .github/workflows/{prepare-migration-temp.yaml => prepare-migration.yaml} (100%) rename .github/workflows/{run-coverage-temp.yaml => run-coverage.yaml} (100%) diff --git a/.github/workflows/deploy-market-temp.yaml b/.github/workflows/deploy-market.yaml similarity index 100% rename from .github/workflows/deploy-market-temp.yaml rename to .github/workflows/deploy-market.yaml diff --git a/.github/workflows/enact-migration-temp.yaml b/.github/workflows/enact-migration.yaml similarity index 100% rename from .github/workflows/enact-migration-temp.yaml rename to .github/workflows/enact-migration.yaml diff --git a/.github/workflows/prepare-migration-temp.yaml b/.github/workflows/prepare-migration.yaml similarity index 100% rename from .github/workflows/prepare-migration-temp.yaml rename to .github/workflows/prepare-migration.yaml diff --git a/.github/workflows/run-coverage-temp.yaml b/.github/workflows/run-coverage.yaml similarity index 100% rename from .github/workflows/run-coverage-temp.yaml rename to .github/workflows/run-coverage.yaml From 06bc28e06ac728e95e18a2464f05d7a0913d9cb2 Mon Sep 17 00:00:00 2001 From: dmitriy-bergman-works Date: Tue, 19 Mar 2024 23:58:33 +0200 Subject: [PATCH 15/37] update configuration to zero values; remove old roots values; add optimism into scenario --- deployments/optimism/usdc/configuration.json | 14 +-- deployments/optimism/usdc/roots.json | 7 +- scenario/utils/index.ts | 15 +++ scenario/utils/isBridgeProposal.ts | 12 ++ scenario/utils/relayMessage.ts | 3 +- scenario/utils/relayOptimismMessage.ts | 116 +++++++++++++++++++ 6 files changed, 153 insertions(+), 14 deletions(-) create mode 100644 scenario/utils/relayOptimismMessage.ts diff --git a/deployments/optimism/usdc/configuration.json b/deployments/optimism/usdc/configuration.json index 27cdd0882..a91f3a1d7 100644 --- a/deployments/optimism/usdc/configuration.json +++ b/deployments/optimism/usdc/configuration.json @@ -20,8 +20,8 @@ }, "tracking": { "indexScale": "1e15", - "baseSupplySpeed": "57_870_370_370e0", - "baseBorrowSpeed": "57_870_370_370e0", + "baseSupplySpeed": "0e15", + "baseBorrowSpeed": "0e15", "baseMinForRewards": "1000e6" }, "assets": { @@ -32,7 +32,7 @@ "borrowCF": 0.83, "liquidateCF": 0.9, "liquidationFactor": 0.95, - "supplyCap": "1600e18" + "supplyCap": "0e18" }, "WBTC": { "address": "0x68f180fcCe6836688e9084f035309E29Bf0A2095", @@ -41,7 +41,7 @@ "borrowCF": 0.8, "liquidateCF": 0.85, "liquidationFactor": 0.95, - "supplyCap": "60e8" + "supplyCap": "0e8" }, "OP": { "address": "0x4200000000000000000000000000000000000042", @@ -50,7 +50,7 @@ "borrowCF": 0.65, "liquidateCF": 0.7, "liquidationFactor": 0.8, - "supplyCap": "700000e18" + "supplyCap": "0e18" }, "wstETH": { "address": "0x1F32b1c2345538c0c6f582fCB022739c4A194Ebb", @@ -59,7 +59,7 @@ "borrowCF": 0.75, "liquidateCF": 0.8, "liquidationFactor": 0.9, - "supplyCap": "500e18" + "supplyCap": "0e18" } } -} +} \ No newline at end of file diff --git a/deployments/optimism/usdc/roots.json b/deployments/optimism/usdc/roots.json index 62e5a1789..b324d529c 100644 --- a/deployments/optimism/usdc/roots.json +++ b/deployments/optimism/usdc/roots.json @@ -1,10 +1,5 @@ { "l2CrossDomainMessenger": "0x4200000000000000000000000000000000000007", "l2StandardBridge": "0x4200000000000000000000000000000000000010", - "CCTPMessageTransmitter": "0x4D41f22c5a0e5c74090899E5a8Fb597a8842b3e8", - "comet": "0xdB7EdFa090061D9367CbEAF6bE16ECbDE596676C", - "configurator": "0x2c7118c4C88B9841FCF839074c26Ae8f035f2921", - "rewards": "0x5404872d8f2e24b230EC9B9eC64E3855F637FB93", - "bulker": "0x5C58d4479A1E9b2d19EE052143FA73F0ee79A36e", - "bridgeReceiver": "0x4A900f81dEdA753bbBab12453b3775D5f26df6F3" + "CCTPMessageTransmitter": "0x4D41f22c5a0e5c74090899E5a8Fb597a8842b3e8" } \ No newline at end of file diff --git a/scenario/utils/index.ts b/scenario/utils/index.ts index 2e03715ed..afea62880 100644 --- a/scenario/utils/index.ts +++ b/scenario/utils/index.ts @@ -504,6 +504,21 @@ export async function createCrossChainProposal(context: CometContext, l2Proposal calldata.push(sendMessageCalldata); break; } + case 'optimism': { + const sendMessageCalldata = utils.defaultAbiCoder.encode( + ['address', 'bytes', 'uint32'], + [bridgeReceiver.address, l2ProposalData, 2_500_000] + ); + const opL1CrossDomainMessenger = await govDeploymentManager.getContractOrThrow( + 'opL1CrossDomainMessenger' + ); + + targets.push(opL1CrossDomainMessenger.address); + values.push(0); + signatures.push('sendMessage(address,bytes,uint32)'); + calldata.push(sendMessageCalldata); + break; + } default: throw new Error( `No cross-chain proposal constructor implementation for ${govDeploymentManager.network} -> ${bridgeNetwork}` diff --git a/scenario/utils/isBridgeProposal.ts b/scenario/utils/isBridgeProposal.ts index b14bbd32d..62912034f 100644 --- a/scenario/utils/isBridgeProposal.ts +++ b/scenario/utils/isBridgeProposal.ts @@ -52,6 +52,18 @@ export async function isBridgeProposal( const { targets } = await governor.getActions(openProposal.id); return targets.includes(lineaMessageService.address); } + case 'optimism': { + const governor = await governanceDeploymentManager.getContractOrThrow('governor'); + const opL1CrossDomainMessenger = await governanceDeploymentManager.getContractOrThrow( + 'opL1CrossDomainMessenger' + ); + const opL1StandardBridge = await governanceDeploymentManager.getContractOrThrow( + 'opL1StandardBridge' + ); + const { targets } = await governor.getActions(openProposal.id); + const bridgeContracts = [opL1CrossDomainMessenger.address, opL1StandardBridge.address]; + return targets.some(t => bridgeContracts.includes(t)); + } default: { const tag = `[${bridgeNetwork} -> ${governanceDeploymentManager.network}]`; throw new Error(`${tag} Unable to determine whether to relay Proposal ${openProposal.id}`); diff --git a/scenario/utils/relayMessage.ts b/scenario/utils/relayMessage.ts index d4856f187..b510a6d38 100644 --- a/scenario/utils/relayMessage.ts +++ b/scenario/utils/relayMessage.ts @@ -3,6 +3,7 @@ import relayPolygonMessage from './relayPolygonMessage'; import { relayArbitrumMessage, relayCCTPMint } from './relayArbitrumMessage'; import relayBaseMessage from './relayBaseMessage'; import relayLineaMessage from './relayLineaMessage'; +import relayOptimismMessage from './relayOptimismMessage'; export default async function relayMessage( governanceDeploymentManager: DeploymentManager, @@ -20,7 +21,7 @@ export default async function relayMessage( ); break; case 'optimism': - await relayBaseMessage( + await relayOptimismMessage( governanceDeploymentManager, bridgeDeploymentManager, startingBlockNumber diff --git a/scenario/utils/relayOptimismMessage.ts b/scenario/utils/relayOptimismMessage.ts new file mode 100644 index 000000000..bd3c81d74 --- /dev/null +++ b/scenario/utils/relayOptimismMessage.ts @@ -0,0 +1,116 @@ +import { DeploymentManager } from '../../plugins/deployment_manager'; +import { impersonateAddress } from '../../plugins/scenario/utils'; +import { setNextBaseFeeToZero, setNextBlockTimestamp } from './hreUtils'; +import { BigNumber, ethers } from 'ethers'; +import { Log } from '@ethersproject/abstract-provider'; +import { OpenBridgedProposal } from '../context/Gov'; + +function applyL1ToL2Alias(address: string) { + const offset = BigInt('0x1111000000000000000000000000000000001111'); + return `0x${(BigInt(address) + offset).toString(16)}`; +} + +export default async function relayOptimismMessage( + governanceDeploymentManager: DeploymentManager, + bridgeDeploymentManager: DeploymentManager, + startingBlockNumber: number +) { + const opL1CrossDomainMessenger = await governanceDeploymentManager.getContractOrThrow('opL1CrossDomainMessenger'); + const bridgeReceiver = await bridgeDeploymentManager.getContractOrThrow('bridgeReceiver'); + const l2CrossDomainMessenger = await bridgeDeploymentManager.getContractOrThrow('l2CrossDomainMessenger'); + const l2StandardBridge = await bridgeDeploymentManager.getContractOrThrow('l2StandardBridge'); + + const openBridgedProposals: OpenBridgedProposal[] = []; + + // Grab all events on the L1CrossDomainMessenger contract since the `startingBlockNumber` + const filter = opL1CrossDomainMessenger.filters.SentMessage(); + const sentMessageEvents: Log[] = await governanceDeploymentManager.hre.ethers.provider.getLogs({ + fromBlock: startingBlockNumber, + toBlock: 'latest', + address: opL1CrossDomainMessenger.address, + topics: filter.topics! + }); + + for (let sentMessageEvent of sentMessageEvents) { + const { args: { target, sender, message, messageNonce, gasLimit } } = opL1CrossDomainMessenger.interface.parseLog(sentMessageEvent); + const aliasedSigner = await impersonateAddress( + bridgeDeploymentManager, + applyL1ToL2Alias(opL1CrossDomainMessenger.address) + ); + + await setNextBaseFeeToZero(bridgeDeploymentManager); + const relayMessageTxn = await ( + await l2CrossDomainMessenger.connect(aliasedSigner).relayMessage( + messageNonce, + sender, + target, + 0, + 0, + message, + { gasPrice: 0, gasLimit } + ) + ).wait(); + + // Try to decode the SentMessage data to determine what type of cross-chain activity this is. So far, + // there are two types: + // 1. Bridging ERC20 token or ETH + // 2. Cross-chain message passing + if (target === l2StandardBridge.address) { + // Bridging ERC20 token + const messageWithoutPrefix = message.slice(2); // strip out the 0x prefix + const messageWithoutSigHash = '0x' + messageWithoutPrefix.slice(8); + try { + // 1a. Bridging ERC20 token + const { l1Token, _l2Token, _from, to, amount, _data } = ethers.utils.defaultAbiCoder.decode( + ['address l1Token', 'address l2Token', 'address from', 'address to', 'uint256 amount', 'bytes data'], + messageWithoutSigHash + ); + + console.log( + `[${governanceDeploymentManager.network} -> ${bridgeDeploymentManager.network}] Bridged over ${amount} of ${l1Token} to user ${to}` + ); + } catch (e) { + // 1a. Bridging ETH + const { _from, to, amount, _data } = ethers.utils.defaultAbiCoder.decode( + ['address from', 'address to', 'uint256 amount', 'bytes data'], + messageWithoutSigHash + ); + + const oldBalance = await bridgeDeploymentManager.hre.ethers.provider.getBalance(to); + const newBalance = oldBalance.add(BigNumber.from(amount)); + // This is our best attempt to mimic the deposit transaction type (not supported in Hardhat) that Optimism uses to deposit ETH to an L2 address + await bridgeDeploymentManager.hre.ethers.provider.send('hardhat_setBalance', [ + to, + ethers.utils.hexStripZeros(newBalance.toHexString()), + ]); + + console.log( + `[${governanceDeploymentManager.network} -> ${bridgeDeploymentManager.network}] Bridged over ${amount} of ETH to user ${to}` + ); + } + } else if (target === bridgeReceiver.address) { + // Cross-chain message passing + const proposalCreatedEvent = relayMessageTxn.events.find(event => event.address === bridgeReceiver.address); + const { args: { id, eta } } = bridgeReceiver.interface.parseLog(proposalCreatedEvent); + + // Add the proposal to the list of open bridged proposals to be executed after all the messages have been relayed + openBridgedProposals.push({ id, eta }); + } else { + throw new Error(`[${governanceDeploymentManager.network} -> ${bridgeDeploymentManager.network}] Unrecognized target for cross-chain message`); + } + } + + // Execute open bridged proposals now that all messages have been bridged + for (let proposal of openBridgedProposals) { + const { eta, id } = proposal; + // Fast forward l2 time + await setNextBlockTimestamp(bridgeDeploymentManager, eta.toNumber() + 1); + + // Execute queued proposal + await setNextBaseFeeToZero(bridgeDeploymentManager); + await bridgeReceiver.executeProposal(id, { gasPrice: 0 }); + console.log( + `[${governanceDeploymentManager.network} -> ${bridgeDeploymentManager.network}] Executed bridged proposal ${id}` + ); + } +} \ No newline at end of file From 33ef4409809277c84009a8b165374c862db2a78d Mon Sep 17 00:00:00 2001 From: dmitriy-bergman-works Date: Fri, 22 Mar 2024 21:37:57 +0200 Subject: [PATCH 16/37] update borrowMin to fix scenario; skip non-weth scenario; update COMP_WHALES addresses --- deployments/optimism/usdc/configuration.json | 2 +- scenario/BulkerScenario.ts | 2 +- scenario/context/CometContext.ts | 2 +- src/deploy/index.ts | 10 ++++++---- 4 files changed, 9 insertions(+), 7 deletions(-) diff --git a/deployments/optimism/usdc/configuration.json b/deployments/optimism/usdc/configuration.json index a91f3a1d7..693758b4e 100644 --- a/deployments/optimism/usdc/configuration.json +++ b/deployments/optimism/usdc/configuration.json @@ -5,7 +5,7 @@ "baseTokenAddress": "0x0b2C639c533813f4Aa9D7837CAf62653d097Ff85", "baseTokenPriceFeed": "0x16a9FA2FDa030272Ce99B29CF780dFA30361E0f3", "pauseGuardian": "0x3fFd6c073a4ba24a113B18C8F373569640916A45", - "borrowMin": "1e0", + "borrowMin": "1e5", "storeFrontPriceFactor": 0.6, "targetReserves": "20000000e6", "rates": { diff --git a/scenario/BulkerScenario.ts b/scenario/BulkerScenario.ts index 91e2608f8..69da86a5c 100644 --- a/scenario/BulkerScenario.ts +++ b/scenario/BulkerScenario.ts @@ -8,7 +8,7 @@ import { exp } from '../test/helpers'; scenario( 'Comet#bulker > (non-WETH base) all non-reward actions in one txn', { - filter: async (ctx) => await isBulkerSupported(ctx) && !matchesDeployment(ctx, [{deployment: 'weth'}, {network: 'mumbai'}, { network: 'linea-goerli' }]), + filter: async (ctx) => await isBulkerSupported(ctx) && !matchesDeployment(ctx, [{deployment: 'weth'}, {network: 'mumbai'}, { network: 'linea-goerli' }, { network: 'optimism' }]), supplyCaps: { $asset0: 3000, $asset1: 3000, diff --git a/scenario/context/CometContext.ts b/scenario/context/CometContext.ts index 73e3d6e99..8354fbb7b 100644 --- a/scenario/context/CometContext.ts +++ b/scenario/context/CometContext.ts @@ -74,7 +74,7 @@ export class CometContext { } async getCompWhales(): Promise { - const useMainnetComp = ['mainnet', 'polygon', 'arbitrum', 'base'].includes(this.world.base.network); + const useMainnetComp = ['mainnet', 'polygon', 'arbitrum', 'base', 'optimism'].includes(this.world.base.network); return COMP_WHALES[useMainnetComp ? 'mainnet' : 'testnet']; } diff --git a/src/deploy/index.ts b/src/deploy/index.ts index d4bd85056..d3ec43a2d 100644 --- a/src/deploy/index.ts +++ b/src/deploy/index.ts @@ -69,13 +69,15 @@ export type Proposal = [ // Ideally these wouldn't be hardcoded, but other solutions are much more complex, and slower export const COMP_WHALES = { mainnet: [ - '0xea6c3db2e7fca00ea9d7211a03e83f568fc13bf7', - '0x61258f12c459984f32b83c86a6cc10aa339396de', '0x9aa835bc7b8ce13b9b0c9764a52fbf71ac62ccf1', - '0x683a4f9915d6216f73d6df50151725036bd26c02' + '0x683a4f9915d6216f73d6df50151725036bd26c02', + '0x8169522c2C57883E8EF80C498aAB7820dA539806', + '0x8d07D225a769b7Af3A923481E1FdF49180e6A265', + '0x7d1a02C0ebcF06E1A36231A54951E061673ab27f', + '0x54A37d93E57c5DA659F508069Cf65A381b61E189' ], - testnet: ['0xbbfe34e868343e6f4f5e8b5308de980d7bd88c46'] + testnet: ['0x683a4F9915D6216f73d6Df50151725036bD26C02'] }; export const WHALES = { From c0140931f6427b6735dad85cf24de742daf8ee68 Mon Sep 17 00:00:00 2001 From: dmitriy-bergman-works Date: Sun, 24 Mar 2024 00:20:43 +0200 Subject: [PATCH 17/37] remove only from tests --- plugins/deployment_manager/test/ImportTest.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/deployment_manager/test/ImportTest.ts b/plugins/deployment_manager/test/ImportTest.ts index 04a636885..4184d301c 100644 --- a/plugins/deployment_manager/test/ImportTest.ts +++ b/plugins/deployment_manager/test/ImportTest.ts @@ -61,7 +61,7 @@ export function mockImportSuccess(address: string) { ); } -describe.only('Import', () => { +describe('Import', () => { beforeEach(async () => { nock.disableNetConnect(); }); From b2530580c0e1f72e57bf343b44c4d7b09dcc176d Mon Sep 17 00:00:00 2001 From: dmitriy-bergman-works Date: Sun, 24 Mar 2024 00:29:47 +0200 Subject: [PATCH 18/37] add usdc market deployment on optimism network --- deployments/optimism/usdt/configuration.json | 65 ---- deployments/optimism/usdt/deploy.ts | 83 ----- .../1707399040_configurate_and_ens.ts | 291 ------------------ deployments/optimism/usdt/relations.ts | 30 -- deployments/optimism/usdt/roots.json | 5 - hardhat.config.ts | 8 - 6 files changed, 482 deletions(-) delete mode 100644 deployments/optimism/usdt/configuration.json delete mode 100644 deployments/optimism/usdt/deploy.ts delete mode 100644 deployments/optimism/usdt/migrations/1707399040_configurate_and_ens.ts delete mode 100644 deployments/optimism/usdt/relations.ts delete mode 100644 deployments/optimism/usdt/roots.json diff --git a/deployments/optimism/usdt/configuration.json b/deployments/optimism/usdt/configuration.json deleted file mode 100644 index cbdd03728..000000000 --- a/deployments/optimism/usdt/configuration.json +++ /dev/null @@ -1,65 +0,0 @@ -{ - "name": "Compound USDT", - "symbol": "cUSDTv3", - "baseToken": "USDT", - "baseTokenAddress": "0x94b008aA00579c1307B0EF2c499aD98a8ce58e58", - "baseTokenPriceFeed": "0xECef79E109e997bCA29c1c0897ec9d7b03647F5E", - "pauseGuardian": "0x3fFd6c073a4ba24a113B18C8F373569640916A45", - "borrowMin": "1e0", - "storeFrontPriceFactor": 0.6, - "targetReserves": "20000000e6", - "rates": { - "supplyKink": 0.9, - "supplySlopeLow": 0.059, - "supplySlopeHigh": 2.9, - "supplyBase": 0, - "borrowKink": 0.9, - "borrowSlopeLow": 0.061, - "borrowSlopeHigh": 3.2, - "borrowBase": 0.015 - }, - "tracking": { - "indexScale": "1e15", - "baseSupplySpeed": "57_870_370_370e0", - "baseBorrowSpeed": "57_870_370_370e0", - "baseMinForRewards": "1000e6" - }, - "assets": { - "WETH": { - "address": "0x4200000000000000000000000000000000000006", - "priceFeed": "0x13e3Ee699D1909E989722E753853AE30b17e08c5", - "decimals": "18", - "borrowCF": 0.83, - "liquidateCF": 0.9, - "liquidationFactor": 0.95, - "supplyCap": "1600e18" - }, - "WBTC": { - "address": "0x68f180fcCe6836688e9084f035309E29Bf0A2095", - "priceFeed": "0xD702DD976Fb76Fffc2D3963D037dfDae5b04E593", - "decimals": "8", - "borrowCF": 0.8, - "liquidateCF": 0.85, - "liquidationFactor": 0.95, - "supplyCap": "60e8" - }, - "OP": { - "address": "0x4200000000000000000000000000000000000042", - "priceFeed": "0x0D276FC14719f9292D5C1eA2198673d1f4269246", - "decimals": "18", - "borrowCF": 0.65, - "liquidateCF": 0.7, - "liquidationFactor": 0.8, - "supplyCap": "400000e18" - }, - "wstETH": { - "address": "0x1F32b1c2345538c0c6f582fCB022739c4A194Ebb", - "priceFeed": "0x698B585CbC4407e2D54aa898B2600B53C68958f7", - "decimals": "18", - "borrowCF": 0.75, - "liquidateCF": 0.8, - "liquidationFactor": 0.9, - "supplyCap": "300e18" - } - } -} diff --git a/deployments/optimism/usdt/deploy.ts b/deployments/optimism/usdt/deploy.ts deleted file mode 100644 index 421493026..000000000 --- a/deployments/optimism/usdt/deploy.ts +++ /dev/null @@ -1,83 +0,0 @@ -import { - Deployed, - DeploymentManager, -} from '../../../plugins/deployment_manager'; -import { DeploySpec, deployComet } from '../../../src/deploy'; - -const HOUR = 60 * 60; -const DAY = 24 * HOUR; - -const MAINNET_TIMELOCK = '0x6d903f6003cca6255d85cca4d3b5e5146dc33925'; - -export default async function deploy( - deploymentManager: DeploymentManager, - deploySpec: DeploySpec -): Promise { - const deployed = await deployContracts(deploymentManager, deploySpec); - return deployed; -} - -async function deployContracts( - deploymentManager: DeploymentManager, - deploySpec: DeploySpec -): Promise { - const trace = deploymentManager.tracer(); - - // Import shared contracts from cUSDCv3 - const cometAdmin = await deploymentManager.fromDep( - 'cometAdmin', - 'optimism', - 'usdc' - ); - const cometFactory = await deploymentManager.fromDep( - 'cometFactory', - 'optimism', - 'usdc' - ); - const $configuratorImpl = await deploymentManager.fromDep( - 'configurator:implementation', - 'optimism', - 'usdc' - ); - const configurator = await deploymentManager.fromDep( - 'configurator', - 'optimism', - 'usdc' - ); - const rewards = await deploymentManager.fromDep( - 'rewards', - 'optimism', - 'usdc' - ); - const bulker = await deploymentManager.fromDep('bulker', 'optimism', 'usdc'); - const l2CrossDomainMessenger = await deploymentManager.fromDep( - 'l2CrossDomainMessenger', - 'optimism', - 'usdc' - ); - const l2StandardBridge = await deploymentManager.fromDep( - 'l2StandardBridge', - 'optimism', - 'usdc' - ); - const localTimelock = await deploymentManager.fromDep( - 'timelock', - 'optimism', - 'usdc' - ); - const bridgeReceiver = await deploymentManager.fromDep( - 'bridgeReceiver', - 'optimism', - 'usdc' - ); - - const deployed = await deployComet(deploymentManager, deploySpec); - - return { - ...deployed, - bridgeReceiver, - l2CrossDomainMessenger, // TODO: don't have to part of roots. can be pulled via relations - l2StandardBridge, - bulker, - }; -} diff --git a/deployments/optimism/usdt/migrations/1707399040_configurate_and_ens.ts b/deployments/optimism/usdt/migrations/1707399040_configurate_and_ens.ts deleted file mode 100644 index 93b050e0d..000000000 --- a/deployments/optimism/usdt/migrations/1707399040_configurate_and_ens.ts +++ /dev/null @@ -1,291 +0,0 @@ -import { DeploymentManager } from "../../../../plugins/deployment_manager/DeploymentManager"; -import { - diffState, - getCometConfig, -} from "../../../../plugins/deployment_manager/DiffState"; -import { migration } from "../../../../plugins/deployment_manager/Migration"; -import { - calldata, - exp, - getConfigurationStruct, - proposal, -} from "../../../../src/deploy"; -import { expect } from "chai"; - -const SECONDS_PER_YEAR = 31_536_000n; -const ENSName = "compound-community-licenses.eth"; -const ENSResolverAddress = "0x4976fb03C32e5B8cfe2b6cCB31c09Ba78EBaBa41"; -const ENSRegistryAddress = "0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e"; -const ENSSubdomainLabel = "v3-additional-grants"; -const ENSSubdomain = `${ENSSubdomainLabel}.${ENSName}`; -const ENSTextRecordKey = "v3-official-markets"; -const opCOMPAddress = "0x7e7d4467112689329f7E06571eD0E8CbAd4910eE"; - -export default migration("1707399040_configurate_and_ens", { - prepare: async (deploymentManager: DeploymentManager) => { - return {}; - }, - - enact: async ( - deploymentManager: DeploymentManager, - govDeploymentManager: DeploymentManager - ) => { - const trace = deploymentManager.tracer(); - const ethers = deploymentManager.hre.ethers; - const { utils } = ethers; - - const cometFactory = await deploymentManager.fromDep( - "cometFactory", - "optimism", - "usdc" - ); - const { - bridgeReceiver, - timelock: localTimelock, - comet, - cometAdmin, - configurator, - rewards, - } = await deploymentManager.getContracts(); - - const { - opL1CrossDomainMessenger, - opL1StandardBridge, - governor, - comptrollerV2, - COMP: mainnetCOMP, - USDT: mainnetUSDT, - CCTPTokenMessenger, - } = await govDeploymentManager.getContracts(); - - // CCTP destination domain for Optimism - const OptimismDestinationDomain = 2; - - // ENS Setup - // See also: https://docs.ens.domains/contract-api-reference/name-processing - const ENSResolver = await govDeploymentManager.existing( - "ENSResolver", - ENSResolverAddress - ); - const subdomainHash = ethers.utils.namehash(ENSSubdomain); - const opChainId = ( - await deploymentManager.hre.ethers.provider.getNetwork() - ).chainId.toString(); - const newMarketObject = { baseSymbol: "USDT", cometAddress: comet.address }; - const officialMarketsJSON = JSON.parse( - await ENSResolver.text(subdomainHash, ENSTextRecordKey) - ); - if (officialMarketsJSON[opChainId]) { - officialMarketsJSON[opChainId].push(newMarketObject); - } else { - officialMarketsJSON[opChainId] = [newMarketObject]; - } - - const configuration = await getConfigurationStruct(deploymentManager); - const setFactoryCalldata = await calldata( - configurator.populateTransaction.setFactory( - comet.address, - cometFactory.address - ) - ); - const setConfigurationCalldata = await calldata( - configurator.populateTransaction.setConfiguration( - comet.address, - configuration - ) - ); - const deployAndUpgradeToCalldata = utils.defaultAbiCoder.encode( - ["address", "address"], - [configurator.address, comet.address] - ); - const setRewardConfigCalldata = utils.defaultAbiCoder.encode( - ["address", "address"], - [comet.address, opCOMPAddress] - ); - - const l2ProposalData = utils.defaultAbiCoder.encode( - ["address[]", "uint256[]", "string[]", "bytes[]"], - [ - [ - configurator.address, - configurator.address, - cometAdmin.address, - rewards.address, - ], - [0, 0, 0, 0], - [ - "setFactory(address,address)", - "setConfiguration(address,(address,address,address,address,address,uint64,uint64,uint64,uint64,uint64,uint64,uint64,uint64,uint64,uint64,uint64,uint64,uint104,uint104,uint104,(address,address,uint8,uint64,uint64,uint64,uint128)[]))", - "deployAndUpgradeTo(address,address)", - "setRewardConfig(address,address)", - ], - [ - setFactoryCalldata, - setConfigurationCalldata, - deployAndUpgradeToCalldata, - setRewardConfigCalldata, - ], - ] - ); - - const USDTAmountToBridge = exp(10_000, 6); - - const actions = [ - // 1. Set Comet configuration + deployAndUpgradeTo new Comet, set Reward Config on Optimism - { - contract: opL1CrossDomainMessenger, - signature: "sendMessage(address,bytes,uint32)", - args: [bridgeReceiver.address, l2ProposalData, 3_000_000], - }, - // 2. Approve USDT to CCTP - { - contract: mainnetUSDT, - signature: "approve(address,uint256)", - args: [CCTPTokenMessenger.address, USDTAmountToBridge], - }, - // 3. Burn USDT to Optimism via CCTP - { - contract: CCTPTokenMessenger, - signature: "depositForBurn(uint256,uint32,bytes32,address)", - args: [ - USDTAmountToBridge, - OptimismDestinationDomain, - utils.hexZeroPad(comet.address, 32), - mainnetUSDT.address, - ], - }, - // 4. Update the list of official markets - { - target: ENSResolverAddress, - signature: "setText(bytes32,string,string)", - calldata: ethers.utils.defaultAbiCoder.encode( - ["bytes32", "string", "string"], - [subdomainHash, ENSTextRecordKey, JSON.stringify(officialMarketsJSON)] - ), - }, - ]; - - const description = "# Initialize cUSDTv3 on Optimism\n\n## Proposal summary\n\nCompound Growth Program [AlphaGrowth] proposes deployment of Compound III to Optimism network. This proposal takes the governance steps recommended and necessary to initialize a Compound III USDT market on Optimism; upon execution, cUSDTv3 will be ready for use. Simulations have confirmed the market’s readiness, as much as possible, using the [Comet scenario suite](https://github.com/compound-finance/comet/tree/main/scenario). The new parameters include setting the risk parameters based off of the [recommendations from Gauntlet](https://www.comp.xyz/t/deploy-compound-iii-on-optimism/4975/6).\n\nFurther detailed information can be found on the corresponding [proposal pull request](https://github.com/compound-finance/comet/pull/833) and [forum discussion](https://www.comp.xyz/t/deploy-compound-iii-on-optimism/4975).\n\n\n## Proposal Actions\n\nThe first proposal action sets the Comet configuration and deploys a new Comet implementation on Optimism. This sends the encoded `setConfiguration` and `deployAndUpgradeTo` calls across the bridge to the governance receiver on Optimism. It also calls `setRewardConfig` on the Optimism rewards contract, to establish Optimism’s bridged version of COMP as the reward token for the deployment and set the initial supply speed to be 5 COMP/day and borrow speed to be 5 COMP/day.\n\nThe second action approves Circle’s Cross-Chain Transfer Protocol (CCTP) [TokenMessenger](https://etherscan.io/address/0xbd3fa81b58ba92a82136038b25adec7066af3155) to take the Timelock's USDT on Mainnet, in order to seed the market reserves through the CCTP.\n\nThe third action deposits and burns 10K USDT from mainnet via depositForBurn function on CCTP’s TokenMessenger contract to mint native USDT to Comet on Optimism.\n\nThe fourth action approves Optimism’s [L1StandardBridge](https://etherscan.io/address/0x99C9fc46f92E8a1c0deC1b1747d010903E884bE1) to take Timelock's COMP, in order to seed the rewards contract through the bridge.\n\nThe fifth action deposits 3.6K COMP from mainnet to the Optimism L1StandardBridge contract to bridge to CometRewards.\n\nThe sixth action updates the ENS TXT record `v3-official-markets` on `v3-additional-grants.compound-community-licenses.eth`, updating the official markets JSON to include the new Optimism cUSDTv3 market"; - const txn = await govDeploymentManager.retry(async () => - trace(await governor.propose(...(await proposal(actions, description)))) - ); - - const event = txn.events.find((event) => event.event === "ProposalCreated"); - const [proposalId] = event.args; - - trace(`Created proposal ${proposalId}.`); - }, - - async enacted(deploymentManager: DeploymentManager): Promise { - return true; - }, - - async verify( - deploymentManager: DeploymentManager, - govDeploymentManager: DeploymentManager, - preMigrationBlockNumber: number - ) { - const ethers = deploymentManager.hre.ethers; - await deploymentManager.spider(); - - const { comet, rewards, COMP, USDT } = await deploymentManager.getContracts(); - - // 1. - const stateChanges = await diffState( - comet, - getCometConfig, - preMigrationBlockNumber - ); - expect(stateChanges).to.deep.equal({ - storeFrontPriceFactor: exp(0.6, 18), - baseTrackingSupplySpeed: exp(5 / 86400, 15, 18), - baseTrackingBorrowSpeed: exp(5 / 86400, 15, 18), - borrowPerSecondInterestRateSlopeLow: exp(0.061, 18) / SECONDS_PER_YEAR, - borrowPerSecondInterestRateSlopeHigh: exp(3.2, 18) / SECONDS_PER_YEAR, - supplyPerSecondInterestRateSlopeLow: exp(0.059, 18) / SECONDS_PER_YEAR, - supplyPerSecondInterestRateSlopeHigh: exp(2.9, 18) / SECONDS_PER_YEAR, - WETH: { - supplyCap: exp(1600, 18), - }, - OP: { - supplyCap: exp(400000, 18), - }, - WBTC: { - supplyCap: exp(60, 8), - }, - wstETH: { - supplyCap: exp(300, 18), - }, - }); - - const config = await rewards.rewardConfig(comet.address); - expect(config.token).to.be.equal(COMP.address); - expect(config.rescaleFactor).to.be.equal(exp(1, 12)); - expect(config.shouldUpscale).to.be.equal(true); - - // 2. & 3. - expect(await USDT.balanceOf(comet.address)).to.be.equal(exp(10_000, 6)); - - // 4. - const ENSResolver = await govDeploymentManager.existing( - "ENSResolver", - ENSResolverAddress - ); - const subdomainHash = ethers.utils.namehash(ENSSubdomain); - const officialMarketsJSON = await ENSResolver.text( - subdomainHash, - ENSTextRecordKey - ); - const officialMarkets = JSON.parse(officialMarketsJSON); - - expect(officialMarkets).to.deep.equal({ - /// parse and update before migration - 1: [ - { - baseSymbol: "USDC", - cometAddress: "0xc3d688B66703497DAA19211EEdff47f25384cdc3", - }, - { - baseSymbol: "WETH", - cometAddress: "0xA17581A9E3356d9A858b789D68B4d866e593aE94", - }, - ], - 137: [ - { - baseSymbol: "USDC", - cometAddress: "0xF25212E676D1F7F89Cd72fFEe66158f541246445", - }, - ], - 8453: [ - { - baseSymbol: "USDbC", - cometAddress: "0x9c4ec768c28520B50860ea7a15bd7213a9fF58bf", - }, - { - baseSymbol: "WETH", - cometAddress: "0x46e6b214b524310239732D51387075E0e70970bf", - }, - ], - 42161: [ - { - baseSymbol: "USDC.e", - cometAddress: "0xA5EDBDD9646f8dFF606d7448e414884C7d905dCA", - }, - { - baseSymbol: "USDC", - cometAddress: "0x9c4ec768c28520B50860ea7a15bd7213a9fF58bf", - }, - ], - 10: [ - { - baseSymbol: "USDC", - cometAddress: "push address of USDC comet here"//cometUSDC.address, - }, - { - baseSymbol: "USDT", - cometAddress: comet.address, - }, - ], - }); - }, -}); diff --git a/deployments/optimism/usdt/relations.ts b/deployments/optimism/usdt/relations.ts deleted file mode 100644 index c216eae18..000000000 --- a/deployments/optimism/usdt/relations.ts +++ /dev/null @@ -1,30 +0,0 @@ -import baseRelationConfig from '../../relations'; - -export default { - ...baseRelationConfig, - governor: { - artifact: - 'contracts/bridges/optimism/OptimismBridgeReceiver.sol:OptimismBridgeReceiver', - }, - Proxy: { - artifact: 'contracts/ERC20.sol:ERC20', - }, - - l2CrossDomainMessenger: { - delegates: { - field: { - slot: - '0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc', - }, - }, - }, - - l2StandardBridge: { - delegates: { - field: { - slot: - '0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc', - }, - }, - }, -}; diff --git a/deployments/optimism/usdt/roots.json b/deployments/optimism/usdt/roots.json deleted file mode 100644 index 334c1fb82..000000000 --- a/deployments/optimism/usdt/roots.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "l2CrossDomainMessenger": "0x4200000000000000000000000000000000000007", - "l2StandardBridge": "0x4200000000000000000000000000000000000010", - "CCTPMessageTransmitter": "0x4D41f22c5a0e5c74090899E5a8Fb597a8842b3e8" -} diff --git a/hardhat.config.ts b/hardhat.config.ts index fb1b6486b..acc43d539 100644 --- a/hardhat.config.ts +++ b/hardhat.config.ts @@ -37,7 +37,6 @@ import baseGoerliRelationConfigMap from './deployments/base-goerli/usdc/relation import baseGoerliWethRelationConfigMap from './deployments/base-goerli/weth/relations'; import lineaGoerliRelationConfigMap from './deployments/linea-goerli/usdc/relations'; import optimismRelationConfigMap from './deployments/optimism/usdc/relations'; -import optimismUsdtRelationConfigMap from './deployments/optimism/usdt/relations'; task('accounts', 'Prints the list of accounts', async (taskArgs, hre) => { for (const account of await hre.ethers.getSigners()) @@ -355,7 +354,6 @@ const config: HardhatUserConfig = { }, optimism: { usdc: optimismRelationConfigMap, - usdt: optimismUsdtRelationConfigMap, }, }, }, @@ -481,12 +479,6 @@ const config: HardhatUserConfig = { deployment: 'usdc', auxiliaryBase: 'mainnet', }, - { - name: 'optimism-usdt', - network: 'optimism', - deployment: 'usdt', - auxiliaryBase: 'mainnet', - }, ], }, From 341335c976ed4625d48a1c6a2a7ee9959f90b765 Mon Sep 17 00:00:00 2001 From: dmitriy-bergman-works Date: Sun, 24 Mar 2024 00:33:28 +0200 Subject: [PATCH 19/37] udpate migration PR id --- .../optimism/usdc/migrations/1707394874_configurate_and_ens.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deployments/optimism/usdc/migrations/1707394874_configurate_and_ens.ts b/deployments/optimism/usdc/migrations/1707394874_configurate_and_ens.ts index 5dc6f4c43..100c81ba3 100644 --- a/deployments/optimism/usdc/migrations/1707394874_configurate_and_ens.ts +++ b/deployments/optimism/usdc/migrations/1707394874_configurate_and_ens.ts @@ -166,7 +166,7 @@ export default migration("1707394874_configurate_and_ens", { }, ]; - const description = "# Initialize cUSDCv3 on Optimism\n\n## Proposal summary\n\nCompound Growth Program [AlphaGrowth] proposes deployment of Compound III to Optimism network. This proposal takes the governance steps recommended and necessary to initialize a Compound III USDC market on Optimism; upon execution, cUSDCv3 will be ready for use. Simulations have confirmed the market’s readiness, as much as possible, using the [Comet scenario suite](https://github.com/compound-finance/comet/tree/main/scenario). The new parameters include setting the risk parameters based off of the [recommendations from Gauntlet](https://www.comp.xyz/t/deploy-compound-iii-on-optimism/4975/6).\n\nFurther detailed information can be found on the corresponding [proposal pull request](https://github.com/compound-finance/comet/pull/833) and [forum discussion](https://www.comp.xyz/t/deploy-compound-iii-on-optimism/4975).\n\n\n## Proposal Actions\n\nThe first proposal action sets the Comet configuration and deploys a new Comet implementation on Optimism. This sends the encoded `setConfiguration` and `deployAndUpgradeTo` calls across the bridge to the governance receiver on Optimism. It also calls `setRewardConfig` on the Optimism rewards contract, to establish Optimism’s bridged version of COMP as the reward token for the deployment and set the initial supply speed to be 5 COMP/day and borrow speed to be 5 COMP/day.\n\nThe second action approves Circle’s Cross-Chain Transfer Protocol (CCTP) [TokenMessenger](https://etherscan.io/address/0xbd3fa81b58ba92a82136038b25adec7066af3155) to take the Timelock's USDC on Mainnet, in order to seed the market reserves through the CCTP.\n\nThe third action deposits and burns 10K USDC from mainnet via depositForBurn function on CCTP’s TokenMessenger contract to mint native USDC to Comet on Optimism.\n\nThe fourth action approves Optimism’s [L1StandardBridge](https://etherscan.io/address/0x99C9fc46f92E8a1c0deC1b1747d010903E884bE1) to take Timelock's COMP, in order to seed the rewards contract through the bridge.\n\nThe fifth action deposits 3.6K COMP from mainnet to the Optimism L1StandardBridge contract to bridge to CometRewards.\n\nThe sixth action updates the ENS TXT record `v3-official-markets` on `v3-additional-grants.compound-community-licenses.eth`, updating the official markets JSON to include the new Optimism cUSDCv3 market"; + const description = "# Initialize cUSDCv3 on Optimism\n\n## Proposal summary\n\nCompound Growth Program [AlphaGrowth] proposes deployment of Compound III to Optimism network. This proposal takes the governance steps recommended and necessary to initialize a Compound III USDC market on Optimism; upon execution, cUSDCv3 will be ready for use. Simulations have confirmed the market’s readiness, as much as possible, using the [Comet scenario suite](https://github.com/compound-finance/comet/tree/main/scenario). The new parameters include setting the risk parameters based off of the [recommendations from Gauntlet](https://www.comp.xyz/t/deploy-compound-iii-on-optimism/4975/6).\n\nFurther detailed information can be found on the corresponding [proposal pull request](https://github.com/compound-finance/comet/pull/838) and [forum discussion](https://www.comp.xyz/t/deploy-compound-iii-on-optimism/4975).\n\n\n## Proposal Actions\n\nThe first proposal action sets the Comet configuration and deploys a new Comet implementation on Optimism. This sends the encoded `setConfiguration` and `deployAndUpgradeTo` calls across the bridge to the governance receiver on Optimism. It also calls `setRewardConfig` on the Optimism rewards contract, to establish Optimism’s bridged version of COMP as the reward token for the deployment and set the initial supply speed to be 5 COMP/day and borrow speed to be 5 COMP/day.\n\nThe second action approves Circle’s Cross-Chain Transfer Protocol (CCTP) [TokenMessenger](https://etherscan.io/address/0xbd3fa81b58ba92a82136038b25adec7066af3155) to take the Timelock's USDC on Mainnet, in order to seed the market reserves through the CCTP.\n\nThe third action deposits and burns 10K USDC from mainnet via depositForBurn function on CCTP’s TokenMessenger contract to mint native USDC to Comet on Optimism.\n\nThe fourth action approves Optimism’s [L1StandardBridge](https://etherscan.io/address/0x99C9fc46f92E8a1c0deC1b1747d010903E884bE1) to take Timelock's COMP, in order to seed the rewards contract through the bridge.\n\nThe fifth action deposits 3.6K COMP from mainnet to the Optimism L1StandardBridge contract to bridge to CometRewards.\n\nThe sixth action updates the ENS TXT record `v3-official-markets` on `v3-additional-grants.compound-community-licenses.eth`, updating the official markets JSON to include the new Optimism cUSDCv3 market"; const txn = await govDeploymentManager.retry(async () => trace(await governor.propose(...(await proposal(actions, description)))) ); From 4b716e6d4299e064d32fa7ae3fbba7dcdb8f54be Mon Sep 17 00:00:00 2001 From: dmitriy-bergman-works Date: Sun, 24 Mar 2024 03:36:34 +0200 Subject: [PATCH 20/37] remove optimism-usdt scenario --- .github/workflows/run-scenarios.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/run-scenarios.yaml b/.github/workflows/run-scenarios.yaml index 40be505be..adb32f7ce 100644 --- a/.github/workflows/run-scenarios.yaml +++ b/.github/workflows/run-scenarios.yaml @@ -7,7 +7,7 @@ jobs: strategy: fail-fast: false matrix: - bases: [ development, mainnet, mainnet-weth, goerli, goerli-weth, sepolia-usdc, sepolia-weth, fuji, mumbai, polygon, arbitrum-usdc.e, arbitrum-usdc, arbitrum-goerli-usdc, arbitrum-goerli-usdc.e, base-usdbc, base-weth, base-usdc, base-goerli, base-goerli-weth, linea-goerli, optimism-usdc, optimism-usdt] + bases: [ development, mainnet, mainnet-weth, goerli, goerli-weth, sepolia-usdc, sepolia-weth, fuji, mumbai, polygon, arbitrum-usdc.e, arbitrum-usdc, arbitrum-goerli-usdc, arbitrum-goerli-usdc.e, base-usdbc, base-weth, base-usdc, base-goerli, base-goerli-weth, linea-goerli, optimism-usdc] name: Run scenarios env: ETHERSCAN_KEY: ${{ secrets.ETHERSCAN_KEY }} From a607fd9d5aafd5bead57a5136870755b04bc4e12 Mon Sep 17 00:00:00 2001 From: dmitriy-bergman-works Date: Mon, 25 Mar 2024 15:06:56 +0200 Subject: [PATCH 21/37] add pull_request key into deploy-market to trigger workflow --- .github/workflows/deploy-market.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/deploy-market.yaml b/.github/workflows/deploy-market.yaml index 81e74c564..13cc2dafc 100644 --- a/.github/workflows/deploy-market.yaml +++ b/.github/workflows/deploy-market.yaml @@ -26,6 +26,7 @@ on: description: Simulate eth_pk: description: Ignore if you plan to use WalletConnect, otherwise, you can paste in a Ethereum private key + pull_request: jobs: deploy-market: name: Deploy Market From 5b94affb70347849f0c517727cc818261aae8a6c Mon Sep 17 00:00:00 2001 From: dmitriy-bergman-works Date: Mon, 25 Mar 2024 15:08:54 +0200 Subject: [PATCH 22/37] add pull_request key into enact-migration and prepare-migration to trigger workflow --- .github/workflows/enact-migration.yaml | 1 + .github/workflows/prepare-migration.yaml | 1 + 2 files changed, 2 insertions(+) diff --git a/.github/workflows/enact-migration.yaml b/.github/workflows/enact-migration.yaml index 9121246a1..3af58226c 100644 --- a/.github/workflows/enact-migration.yaml +++ b/.github/workflows/enact-migration.yaml @@ -34,6 +34,7 @@ on: description: Run ID for Artifact eth_pk: description: Ignore if you plan to use WalletConnect, otherwise, you can paste in a Ethereum private key + pull_request: jobs: enact-migration: name: Enact Migration diff --git a/.github/workflows/prepare-migration.yaml b/.github/workflows/prepare-migration.yaml index 71597e0b8..b8da16880 100644 --- a/.github/workflows/prepare-migration.yaml +++ b/.github/workflows/prepare-migration.yaml @@ -28,6 +28,7 @@ on: description: Simulate eth_pk: description: Ignore if you plan to use WalletConnect, otherwise, you can paste in a Ethereum private key + pull_request: jobs: prepare-migration: name: Prepare Migration From 0f177925ebe9bf2551206ffd2bf2aa4dac44ca6e Mon Sep 17 00:00:00 2001 From: dmitriy-bergman-works Date: Mon, 25 Mar 2024 15:10:47 +0200 Subject: [PATCH 23/37] remove pull_request key --- .github/workflows/deploy-market.yaml | 1 - .github/workflows/enact-migration.yaml | 1 - .github/workflows/prepare-migration.yaml | 1 - 3 files changed, 3 deletions(-) diff --git a/.github/workflows/deploy-market.yaml b/.github/workflows/deploy-market.yaml index 13cc2dafc..81e74c564 100644 --- a/.github/workflows/deploy-market.yaml +++ b/.github/workflows/deploy-market.yaml @@ -26,7 +26,6 @@ on: description: Simulate eth_pk: description: Ignore if you plan to use WalletConnect, otherwise, you can paste in a Ethereum private key - pull_request: jobs: deploy-market: name: Deploy Market diff --git a/.github/workflows/enact-migration.yaml b/.github/workflows/enact-migration.yaml index 3af58226c..9121246a1 100644 --- a/.github/workflows/enact-migration.yaml +++ b/.github/workflows/enact-migration.yaml @@ -34,7 +34,6 @@ on: description: Run ID for Artifact eth_pk: description: Ignore if you plan to use WalletConnect, otherwise, you can paste in a Ethereum private key - pull_request: jobs: enact-migration: name: Enact Migration diff --git a/.github/workflows/prepare-migration.yaml b/.github/workflows/prepare-migration.yaml index b8da16880..71597e0b8 100644 --- a/.github/workflows/prepare-migration.yaml +++ b/.github/workflows/prepare-migration.yaml @@ -28,7 +28,6 @@ on: description: Simulate eth_pk: description: Ignore if you plan to use WalletConnect, otherwise, you can paste in a Ethereum private key - pull_request: jobs: prepare-migration: name: Prepare Migration From 84d96893233bc5acdcf6a3c40fd14ceffc93cd8b Mon Sep 17 00:00:00 2001 From: dmitriy-bergman-works Date: Mon, 25 Mar 2024 22:58:16 +0200 Subject: [PATCH 24/37] remove custom offsets in hardat.config.ts; update configuration.json assets order; add regexDoubleQuotes match to scrapeContractCreationCodeFromEtherscan function; start executing Comet#bulker > (non-WETH base) scenario; update testnet COMP whale; update optimism mainnet whales --- deployments/optimism/usdc/configuration.json | 20 +-- hardhat.config.ts | 114 ++++++++---------- plugins/deployment_manager/test/ImportTest.ts | 2 +- plugins/import/import.ts | 5 +- scenario/BulkerScenario.ts | 2 +- src/deploy/index.ts | 5 +- 6 files changed, 68 insertions(+), 80 deletions(-) diff --git a/deployments/optimism/usdc/configuration.json b/deployments/optimism/usdc/configuration.json index 693758b4e..3f3aa6f49 100644 --- a/deployments/optimism/usdc/configuration.json +++ b/deployments/optimism/usdc/configuration.json @@ -25,6 +25,15 @@ "baseMinForRewards": "1000e6" }, "assets": { + "OP": { + "address": "0x4200000000000000000000000000000000000042", + "priceFeed": "0x0D276FC14719f9292D5C1eA2198673d1f4269246", + "decimals": "18", + "borrowCF": 0.65, + "liquidateCF": 0.7, + "liquidationFactor": 0.8, + "supplyCap": "0e18" + }, "WETH": { "address": "0x4200000000000000000000000000000000000006", "priceFeed": "0x13e3Ee699D1909E989722E753853AE30b17e08c5", @@ -36,22 +45,13 @@ }, "WBTC": { "address": "0x68f180fcCe6836688e9084f035309E29Bf0A2095", - "priceFeed": "0xD702DD976Fb76Fffc2D3963D037dfDae5b04E593", + "priceFeed": "0x718A5788b89454aAE3A028AE9c111A29Be6c2a6F", "decimals": "8", "borrowCF": 0.8, "liquidateCF": 0.85, "liquidationFactor": 0.95, "supplyCap": "0e8" }, - "OP": { - "address": "0x4200000000000000000000000000000000000042", - "priceFeed": "0x0D276FC14719f9292D5C1eA2198673d1f4269246", - "decimals": "18", - "borrowCF": 0.65, - "liquidateCF": 0.7, - "liquidationFactor": 0.8, - "supplyCap": "0e18" - }, "wstETH": { "address": "0x1F32b1c2345538c0c6f582fCB022739c4A194Ebb", "priceFeed": "0x698B585CbC4407e2D54aa898B2600B53C68958f7", diff --git a/hardhat.config.ts b/hardhat.config.ts index acc43d539..92540c5eb 100644 --- a/hardhat.config.ts +++ b/hardhat.config.ts @@ -39,8 +39,7 @@ import lineaGoerliRelationConfigMap from './deployments/linea-goerli/usdc/relati import optimismRelationConfigMap from './deployments/optimism/usdc/relations'; task('accounts', 'Prints the list of accounts', async (taskArgs, hre) => { - for (const account of await hre.ethers.getSigners()) - console.log(account.address); + for (const account of await hre.ethers.getSigners()) console.log(account.address); }); /* note: boolean environment variables are imported as strings */ @@ -61,10 +60,10 @@ const { NETWORK_PROVIDER = '', GOV_NETWORK_PROVIDER = '', GOV_NETWORK = '', - REMOTE_ACCOUNTS = '', + REMOTE_ACCOUNTS = '' } = process.env; -function* deriveAccounts(pk: string, n: number = 10) { +function *deriveAccounts(pk: string, n: number = 10) { for (let i = 0; i < n; i++) yield (BigInt('0x' + pk) + BigInt(i)).toString(16); } @@ -72,9 +71,7 @@ function* deriveAccounts(pk: string, n: number = 10) { export function requireEnv(varName, msg?: string): string { const varVal = process.env[varName]; if (!varVal) { - throw new Error( - msg ?? `Missing required environment variable '${varName}'` - ); + throw new Error(msg ?? `Missing required environment variable '${varName}'`); } return varVal; } @@ -87,7 +84,7 @@ export function requireEnv(varName, msg?: string): string { 'POLYGONSCAN_KEY', 'ARBISCAN_KEY', 'LINEASCAN_KEY', - 'OPTIMISMSCAN_KEY', + 'OPTIMISMSCAN_KEY' ].map((v) => requireEnv(v)); // Networks @@ -166,19 +163,13 @@ function setupDefaultNetworkProviders(hardhatConfig: HardhatUserConfig) { hardhatConfig.networks[netConfig.network] = { chainId: netConfig.chainId, url: - (netConfig.network === GOV_NETWORK - ? GOV_NETWORK_PROVIDER - : undefined) || + (netConfig.network === GOV_NETWORK ? GOV_NETWORK_PROVIDER : undefined) || NETWORK_PROVIDER || netConfig.url || getDefaultProviderURL(netConfig.network), gas: netConfig.gas || 'auto', gasPrice: netConfig.gasPrice || 'auto', - accounts: REMOTE_ACCOUNTS - ? 'remote' - : ETH_PK - ? [...deriveAccounts(ETH_PK)] - : { mnemonic: MNEMONIC }, + accounts: REMOTE_ACCOUNTS ? 'remote' : ( ETH_PK ? [...deriveAccounts(ETH_PK)] : { mnemonic: MNEMONIC } ), }; } } @@ -190,21 +181,20 @@ const config: HardhatUserConfig = { solidity: { version: '0.8.15', settings: { - optimizer: process.env['OPTIMIZER_DISABLED'] - ? { enabled: false } - : { + optimizer: ( + process.env['OPTIMIZER_DISABLED'] ? { enabled: false } : { enabled: true, runs: 1, details: { yulDetails: { - optimizerSteps: - 'dhfoDgvulfnTUtnIf [xa[r]scLM cCTUtTOntnfDIul Lcul Vcul [j] Tpeul xa[rul] xa[r]cL gvif CTUca[r]LsTOtfDnca[r]Iulc] jmul[jul] VcTOcul jmul', + optimizerSteps: 'dhfoDgvulfnTUtnIf [xa[r]scLM cCTUtTOntnfDIul Lcul Vcul [j] Tpeul xa[rul] xa[r]cL gvif CTUca[r]LsTOtfDnca[r]Iulc] jmul[jul] VcTOcul jmul', }, }, - }, + } + ), outputSelection: { '*': { - '*': ['evm.deployedBytecode.sourceMap'], + '*': ['evm.deployedBytecode.sourceMap'] }, }, viaIR: process.env['OPTIMIZER_DISABLED'] ? false : true, @@ -218,15 +208,11 @@ const config: HardhatUserConfig = { gas: 12000000, gasPrice: 'auto', blockGasLimit: 12000000, - accounts: ETH_PK - ? [...deriveAccounts(ETH_PK)].map((privateKey) => ({ - privateKey, - balance: (10n ** 36n).toString(), - })) + accounts: ETH_PK ? [...deriveAccounts(ETH_PK)].map((privateKey) => ({ privateKey, balance: (10n ** 36n).toString() })) : { mnemonic: MNEMONIC, accountsBalance: (10n ** 36n).toString() }, // this should only be relied upon for test harnesses and coverage (which does not use viaIR flag) allowUnlimitedContractSize: true, - hardfork: 'shanghai', + hardfork: 'shanghai' }, }, @@ -265,8 +251,8 @@ const config: HardhatUserConfig = { chainId: 42161, urls: { apiURL: 'https://api.arbiscan.io/api', - browserURL: 'https://arbiscan.io/', - }, + browserURL: 'https://arbiscan.io/' + } }, { // Hardhat's Etherscan plugin calls the network `arbitrumGoerli`, so we need to add an entry for our own network name @@ -274,8 +260,8 @@ const config: HardhatUserConfig = { chainId: 421613, urls: { apiURL: 'https://api-goerli.arbiscan.io/api', - browserURL: 'https://goerli.arbiscan.io/', - }, + browserURL: 'https://goerli.arbiscan.io/' + } }, { // Hardhat's Etherscan plugin doesn't have support Base, so we need to add an entry for our own network name @@ -283,8 +269,8 @@ const config: HardhatUserConfig = { chainId: 8453, urls: { apiURL: 'https://api.basescan.org/api', - browserURL: 'https://basescan.org/', - }, + browserURL: 'https://basescan.org/' + } }, { // Hardhat's Etherscan plugin calls the network `baseGoerli`, so we need to add an entry for our own network name @@ -292,16 +278,16 @@ const config: HardhatUserConfig = { chainId: 84531, urls: { apiURL: 'https://api-goerli.basescan.org/api', - browserURL: 'https://goerli.basescan.org/', - }, + browserURL: 'https://goerli.basescan.org/' + } }, { network: 'linea-goerli', chainId: 59140, urls: { apiURL: 'https://api-goerli.lineascan.build/api', - browserURL: 'https://goerli.lineascan.build/', - }, + browserURL: 'https://goerli.lineascan.build/' + } }, ], }, @@ -316,29 +302,29 @@ const config: HardhatUserConfig = { networks: { goerli: { usdc: goerliRelationConfigMap, - weth: goerliWethRelationConfigMap, + weth: goerliWethRelationConfigMap }, sepolia: { usdc: sepoliaUsdcRelationConfigMap, weth: sepoliaWethRelationConfigMap }, mumbai: { - usdc: mumbaiRelationConfigMap, + usdc: mumbaiRelationConfigMap }, mainnet: { usdc: mainnetRelationConfigMap, - weth: mainnetWethRelationConfigMap, + weth: mainnetWethRelationConfigMap }, polygon: { - usdc: polygonRelationConfigMap, + usdc: polygonRelationConfigMap }, arbitrum: { 'usdc.e': arbitrumBridgedUsdcRelationConfigMap, - usdc: arbitrumNativeUsdcRelationConfigMap, + usdc: arbitrumNativeUsdcRelationConfigMap }, 'arbitrum-goerli': { 'usdc.e': arbitrumBridgedUsdcGoerliRelationConfigMap, - usdc: arbitrumGoerliNativeUsdcRelationConfigMap, + usdc: arbitrumGoerliNativeUsdcRelationConfigMap }, base: { usdbc: baseUsdbcRelationConfigMap, @@ -347,14 +333,14 @@ const config: HardhatUserConfig = { }, 'base-goerli': { usdc: baseGoerliRelationConfigMap, - weth: baseGoerliWethRelationConfigMap, + weth: baseGoerliWethRelationConfigMap }, 'linea-goerli': { - usdc: lineaGoerliRelationConfigMap, + usdc: lineaGoerliRelationConfigMap }, optimism: { - usdc: optimismRelationConfigMap, - }, + usdc: optimismRelationConfigMap + } }, }, @@ -374,17 +360,17 @@ const config: HardhatUserConfig = { { name: 'development', network: 'hardhat', - deployment: 'dai', + deployment: 'dai' }, { name: 'fuji', network: 'fuji', - deployment: 'usdc', + deployment: 'usdc' }, { name: 'goerli', network: 'goerli', - deployment: 'usdc', + deployment: 'usdc' }, { name: 'goerli-weth', @@ -405,43 +391,43 @@ const config: HardhatUserConfig = { name: 'mumbai', network: 'mumbai', deployment: 'usdc', - auxiliaryBase: 'goerli', + auxiliaryBase: 'goerli' }, { name: 'polygon', network: 'polygon', deployment: 'usdc', - auxiliaryBase: 'mainnet', + auxiliaryBase: 'mainnet' }, { name: 'arbitrum-usdc.e', network: 'arbitrum', deployment: 'usdc.e', - auxiliaryBase: 'mainnet', + auxiliaryBase: 'mainnet' }, { name: 'arbitrum-usdc', network: 'arbitrum', deployment: 'usdc', - auxiliaryBase: 'mainnet', + auxiliaryBase: 'mainnet' }, { name: 'arbitrum-goerli-usdc.e', network: 'arbitrum-goerli', deployment: 'usdc.e', - auxiliaryBase: 'goerli', + auxiliaryBase: 'goerli' }, { name: 'arbitrum-goerli-usdc', network: 'arbitrum-goerli', deployment: 'usdc', - auxiliaryBase: 'goerli', + auxiliaryBase: 'goerli' }, { name: 'base-usdbc', network: 'base', deployment: 'usdbc', - auxiliaryBase: 'mainnet', + auxiliaryBase: 'mainnet' }, { name: 'base-weth', @@ -459,25 +445,25 @@ const config: HardhatUserConfig = { name: 'base-goerli', network: 'base-goerli', deployment: 'usdc', - auxiliaryBase: 'goerli', + auxiliaryBase: 'goerli' }, { name: 'base-goerli-weth', network: 'base-goerli', deployment: 'weth', - auxiliaryBase: 'goerli', + auxiliaryBase: 'goerli' }, { name: 'linea-goerli', network: 'linea-goerli', deployment: 'usdc', - auxiliaryBase: 'goerli', + auxiliaryBase: 'goerli' }, { name: 'optimism-usdc', network: 'optimism', deployment: 'usdc', - auxiliaryBase: 'mainnet', + auxiliaryBase: 'mainnet' }, ], }, @@ -490,7 +476,7 @@ const config: HardhatUserConfig = { output: 'test-results.json', }, }, - timeout: 150_000, + timeout: 150_000 }, paths: { diff --git a/plugins/deployment_manager/test/ImportTest.ts b/plugins/deployment_manager/test/ImportTest.ts index 4184d301c..c6017dea5 100644 --- a/plugins/deployment_manager/test/ImportTest.ts +++ b/plugins/deployment_manager/test/ImportTest.ts @@ -57,7 +57,7 @@ export function mockImportSuccess(address: string) { .get(`/address/${address}`) .reply( 200, - `
608060405234801561001057600080fd5b506040516108a93803806108a98339818101604052602081101561003357600080fd5b5051808061004081610051565b5061004a336100c3565b5050610123565b610064816100e760201b61042a1760201c565b61009f5760405162461bcd60e51b815260040180806020018281038252603b81526020018061086e603b913960400191505060405180910390fd5b7f7050c9e0f4ca769c69bd3a8ef740bc37934f8e2c036e5a723fd8ee048ed3f8c355565b7f10d6a54a4754c8869d6886b5f5d7fbfa5b4522237ea5c60d11bc4e7a1ff9390b55565b6000813f7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a47081811480159061011b57508115155b949350505050565b61073c806101326000396000f3fe60806040526004361061005a5760003560e01c80635c60da1b116100435780635c60da1b146101315780638f2839701461016f578063f851a440146101af5761005a565b80633659cfe6146100645780634f1ef286146100a4575b6100626101c4565b005b34801561007057600080fd5b506100626004803603602081101561008757600080fd5b503573ffffffffffffffffffffffffffffffffffffffff166101de565b610062600480360360408110156100ba57600080fd5b73ffffffffffffffffffffffffffffffffffffffff82351691908101906040810160208201356401000000008111156100f257600080fd5b82018360208201111561010457600080fd5b8035906020019184600183028401116401000000008311171561012657600080fd5b509092509050610232565b34801561013d57600080fd5b50610146610309565b6040805173ffffffffffffffffffffffffffffffffffffffff9092168252519081900360200190f35b34801561017b57600080fd5b506100626004803603602081101561019257600080fd5b503573ffffffffffffffffffffffffffffffffffffffff16610318565b3480156101bb57600080fd5b50610146610420565b6101cc610466565b6101dc6101d76104fa565b61051f565b565b6101e6610543565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614156102275761022281610568565b61022f565b61022f6101c4565b50565b61023a610543565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614156102fc5761027683610568565b60003073ffffffffffffffffffffffffffffffffffffffff16348484604051808383808284376040519201945060009350909150508083038185875af1925050503d80600081146102e3576040519150601f19603f3d011682016040523d82523d6000602084013e6102e8565b606091505b50509050806102f657600080fd5b50610304565b6103046101c4565b505050565b60006103136104fa565b905090565b610320610543565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614156102275773ffffffffffffffffffffffffffffffffffffffff81166103bf576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260368152602001806106966036913960400191505060405180910390fd5b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f6103e8610543565b6040805173ffffffffffffffffffffffffffffffffffffffff928316815291841660208301528051918290030190a1610222816105bd565b6000610313610543565b6000813f7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a47081811480159061045e57508115155b949350505050565b61046e610543565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614156104f2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260328152602001806106646032913960400191505060405180910390fd5b6101dc6101dc565b7f7050c9e0f4ca769c69bd3a8ef740bc37934f8e2c036e5a723fd8ee048ed3f8c35490565b3660008037600080366000845af43d6000803e80801561053e573d6000f35b3d6000fd5b7f10d6a54a4754c8869d6886b5f5d7fbfa5b4522237ea5c60d11bc4e7a1ff9390b5490565b610571816105e1565b6040805173ffffffffffffffffffffffffffffffffffffffff8316815290517fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b9181900360200190a150565b7f10d6a54a4754c8869d6886b5f5d7fbfa5b4522237ea5c60d11bc4e7a1ff9390b55565b6105ea8161042a565b61063f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603b8152602001806106cc603b913960400191505060405180910390fd5b7f7050c9e0f4ca769c69bd3a8ef740bc37934f8e2c036e5a723fd8ee048ed3f8c35556fe43616e6e6f742063616c6c2066616c6c6261636b2066756e6374696f6e2066726f6d207468652070726f78792061646d696e43616e6e6f74206368616e6765207468652061646d696e206f6620612070726f787920746f20746865207a65726f206164647265737343616e6e6f742073657420612070726f787920696d706c656d656e746174696f6e20746f2061206e6f6e2d636f6e74726163742061646472657373a26469706673582212206715e283f350a976c05fe8b17fc01929cb137086f941d36864b48c4269d883b264736f6c634300060c003343616e6e6f742073657420612070726f787920696d706c656d656e746174696f6e20746f2061206e6f6e2d636f6e74726163742061646472657373
` + `
608060405234801561001057600080fd5b506040516108a93803806108a98339818101604052602081101561003357600080fd5b5051808061004081610051565b5061004a336100c3565b5050610123565b610064816100e760201b61042a1760201c565b61009f5760405162461bcd60e51b815260040180806020018281038252603b81526020018061086e603b913960400191505060405180910390fd5b7f7050c9e0f4ca769c69bd3a8ef740bc37934f8e2c036e5a723fd8ee048ed3f8c355565b7f10d6a54a4754c8869d6886b5f5d7fbfa5b4522237ea5c60d11bc4e7a1ff9390b55565b6000813f7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a47081811480159061011b57508115155b949350505050565b61073c806101326000396000f3fe60806040526004361061005a5760003560e01c80635c60da1b116100435780635c60da1b146101315780638f2839701461016f578063f851a440146101af5761005a565b80633659cfe6146100645780634f1ef286146100a4575b6100626101c4565b005b34801561007057600080fd5b506100626004803603602081101561008757600080fd5b503573ffffffffffffffffffffffffffffffffffffffff166101de565b610062600480360360408110156100ba57600080fd5b73ffffffffffffffffffffffffffffffffffffffff82351691908101906040810160208201356401000000008111156100f257600080fd5b82018360208201111561010457600080fd5b8035906020019184600183028401116401000000008311171561012657600080fd5b509092509050610232565b34801561013d57600080fd5b50610146610309565b6040805173ffffffffffffffffffffffffffffffffffffffff9092168252519081900360200190f35b34801561017b57600080fd5b506100626004803603602081101561019257600080fd5b503573ffffffffffffffffffffffffffffffffffffffff16610318565b3480156101bb57600080fd5b50610146610420565b6101cc610466565b6101dc6101d76104fa565b61051f565b565b6101e6610543565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614156102275761022281610568565b61022f565b61022f6101c4565b50565b61023a610543565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614156102fc5761027683610568565b60003073ffffffffffffffffffffffffffffffffffffffff16348484604051808383808284376040519201945060009350909150508083038185875af1925050503d80600081146102e3576040519150601f19603f3d011682016040523d82523d6000602084013e6102e8565b606091505b50509050806102f657600080fd5b50610304565b6103046101c4565b505050565b60006103136104fa565b905090565b610320610543565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614156102275773ffffffffffffffffffffffffffffffffffffffff81166103bf576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260368152602001806106966036913960400191505060405180910390fd5b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f6103e8610543565b6040805173ffffffffffffffffffffffffffffffffffffffff928316815291841660208301528051918290030190a1610222816105bd565b6000610313610543565b6000813f7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a47081811480159061045e57508115155b949350505050565b61046e610543565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614156104f2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260328152602001806106646032913960400191505060405180910390fd5b6101dc6101dc565b7f7050c9e0f4ca769c69bd3a8ef740bc37934f8e2c036e5a723fd8ee048ed3f8c35490565b3660008037600080366000845af43d6000803e80801561053e573d6000f35b3d6000fd5b7f10d6a54a4754c8869d6886b5f5d7fbfa5b4522237ea5c60d11bc4e7a1ff9390b5490565b610571816105e1565b6040805173ffffffffffffffffffffffffffffffffffffffff8316815290517fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b9181900360200190a150565b7f10d6a54a4754c8869d6886b5f5d7fbfa5b4522237ea5c60d11bc4e7a1ff9390b55565b6105ea8161042a565b61063f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603b8152602001806106cc603b913960400191505060405180910390fd5b7f7050c9e0f4ca769c69bd3a8ef740bc37934f8e2c036e5a723fd8ee048ed3f8c35556fe43616e6e6f742063616c6c2066616c6c6261636b2066756e6374696f6e2066726f6d207468652070726f78792061646d696e43616e6e6f74206368616e6765207468652061646d696e206f6620612070726f787920746f20746865207a65726f206164647265737343616e6e6f742073657420612070726f787920696d706c656d656e746174696f6e20746f2061206e6f6e2d636f6e74726163742061646472657373a26469706673582212206715e283f350a976c05fe8b17fc01929cb137086f941d36864b48c4269d883b264736f6c634300060c003343616e6e6f742073657420612070726f787920696d706c656d656e746174696f6e20746f2061206e6f6e2d636f6e74726163742061646472657373
` ); } diff --git a/plugins/import/import.ts b/plugins/import/import.ts index dad3d7825..439ace505 100644 --- a/plugins/import/import.ts +++ b/plugins/import/import.ts @@ -87,8 +87,9 @@ async function scrapeContractCreationCodeFromEtherscan(network: string, address: const url = `${getEtherscanUrl(network)}/address/${address}#code`; debug(`Attempting to scrape Contract Creation code at ${url}`); const result = await get(url, {}); - const regex = /
[\s\r\n]*([0-9a-fA-F]*)[\s\r\n]*<\/div>/g; - const matches = [...result.matchAll(regex)]; + const regex = /
[\s\r\n]*([0-9a-fA-F]*)[\s\r\n]*<\/div>/g; + const regexDoubleQuotes = /
[\s\r\n]*([0-9a-fA-F]*)[\s\r\n]*<\/div>/g; + const matches = [...result.matchAll(regex), ...result.matchAll(regexDoubleQuotes)]; if (matches.length === 0) { if (result.match(/request throttled/i) || result.match(/try again later/i)) { throw new Error(`Request throttled: ${url}`); diff --git a/scenario/BulkerScenario.ts b/scenario/BulkerScenario.ts index 69da86a5c..91e2608f8 100644 --- a/scenario/BulkerScenario.ts +++ b/scenario/BulkerScenario.ts @@ -8,7 +8,7 @@ import { exp } from '../test/helpers'; scenario( 'Comet#bulker > (non-WETH base) all non-reward actions in one txn', { - filter: async (ctx) => await isBulkerSupported(ctx) && !matchesDeployment(ctx, [{deployment: 'weth'}, {network: 'mumbai'}, { network: 'linea-goerli' }, { network: 'optimism' }]), + filter: async (ctx) => await isBulkerSupported(ctx) && !matchesDeployment(ctx, [{deployment: 'weth'}, {network: 'mumbai'}, { network: 'linea-goerli' }]), supplyCaps: { $asset0: 3000, $asset1: 3000, diff --git a/src/deploy/index.ts b/src/deploy/index.ts index d3ec43a2d..b9ba0e72c 100644 --- a/src/deploy/index.ts +++ b/src/deploy/index.ts @@ -77,7 +77,7 @@ export const COMP_WHALES = { '0x54A37d93E57c5DA659F508069Cf65A381b61E189' ], - testnet: ['0x683a4F9915D6216f73d6Df50151725036bD26C02'] + testnet: ['0xbbfe34e868343e6f4f5e8b5308de980d7bd88c46'] }; export const WHALES = { @@ -119,7 +119,8 @@ export const WHALES = { '0x44411c605eb7e009cad03f3847cfbbfcf8895130' // COMP whale ], optimism: [ - '0x2A82Ae142b2e62Cb7D10b55E323ACB1Cab663a26' // TODO: add whales + '0x2A82Ae142b2e62Cb7D10b55E323ACB1Cab663a26', // OP whale + '0x8af3827a41c26c7f32c81e93bb66e837e0210d5c' // USDC whale ] }; From c174483ff846e947c57d4536e5e4d6a9fa182f90 Mon Sep 17 00:00:00 2001 From: dmitriy-bergman-works Date: Mon, 25 Mar 2024 23:12:53 +0200 Subject: [PATCH 25/37] remove linter changes --- hardhat.config.ts | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/hardhat.config.ts b/hardhat.config.ts index 92540c5eb..d44548174 100644 --- a/hardhat.config.ts +++ b/hardhat.config.ts @@ -187,7 +187,7 @@ const config: HardhatUserConfig = { runs: 1, details: { yulDetails: { - optimizerSteps: 'dhfoDgvulfnTUtnIf [xa[r]scLM cCTUtTOntnfDIul Lcul Vcul [j] Tpeul xa[rul] xa[r]cL gvif CTUca[r]LsTOtfDnca[r]Iulc] jmul[jul] VcTOcul jmul', + optimizerSteps: 'dhfoDgvulfnTUtnIf [xa[r]scLM cCTUtTOntnfDIul Lcul Vcul [j] Tpeul xa[rul] xa[r]cL gvif CTUca[r]LsTOtfDnca[r]Iulc] jmul[jul] VcTOcul jmul' }, }, } @@ -208,7 +208,8 @@ const config: HardhatUserConfig = { gas: 12000000, gasPrice: 'auto', blockGasLimit: 12000000, - accounts: ETH_PK ? [...deriveAccounts(ETH_PK)].map((privateKey) => ({ privateKey, balance: (10n ** 36n).toString() })) + accounts: ETH_PK ? + [...deriveAccounts(ETH_PK)].map((privateKey) => ({ privateKey, balance: (10n ** 36n).toString() })) : { mnemonic: MNEMONIC, accountsBalance: (10n ** 36n).toString() }, // this should only be relied upon for test harnesses and coverage (which does not use viaIR flag) allowUnlimitedContractSize: true, @@ -288,8 +289,8 @@ const config: HardhatUserConfig = { apiURL: 'https://api-goerli.lineascan.build/api', browserURL: 'https://goerli.lineascan.build/' } - }, - ], + } + ] }, typechain: { @@ -326,7 +327,7 @@ const config: HardhatUserConfig = { 'usdc.e': arbitrumBridgedUsdcGoerliRelationConfigMap, usdc: arbitrumGoerliNativeUsdcRelationConfigMap }, - base: { + 'base': { usdbc: baseUsdbcRelationConfigMap, weth: baseWethRelationConfigMap, usdc: baseUsdcRelationConfigMap From 761e8f2ad4b22cb2ad1712270549003e5eaa62e6 Mon Sep 17 00:00:00 2001 From: dmitriy-bergman-works Date: Mon, 25 Mar 2024 23:17:32 +0200 Subject: [PATCH 26/37] remove bracket --- hardhat.config.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hardhat.config.ts b/hardhat.config.ts index d44548174..cbc8b029f 100644 --- a/hardhat.config.ts +++ b/hardhat.config.ts @@ -209,7 +209,7 @@ const config: HardhatUserConfig = { gasPrice: 'auto', blockGasLimit: 12000000, accounts: ETH_PK ? - [...deriveAccounts(ETH_PK)].map((privateKey) => ({ privateKey, balance: (10n ** 36n).toString() })) + [...deriveAccounts(ETH_PK)].map(privateKey => ({ privateKey, balance: (10n ** 36n).toString() })) : { mnemonic: MNEMONIC, accountsBalance: (10n ** 36n).toString() }, // this should only be relied upon for test harnesses and coverage (which does not use viaIR flag) allowUnlimitedContractSize: true, From 547f29c9301e8f3476d431cf94a9dfab5f22be06 Mon Sep 17 00:00:00 2001 From: dmitriy-bergman-works Date: Mon, 25 Mar 2024 23:25:08 +0200 Subject: [PATCH 27/37] update borrowMin to 1e0 --- deployments/optimism/usdc/configuration.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deployments/optimism/usdc/configuration.json b/deployments/optimism/usdc/configuration.json index 3f3aa6f49..e7ef75d19 100644 --- a/deployments/optimism/usdc/configuration.json +++ b/deployments/optimism/usdc/configuration.json @@ -5,7 +5,7 @@ "baseTokenAddress": "0x0b2C639c533813f4Aa9D7837CAf62653d097Ff85", "baseTokenPriceFeed": "0x16a9FA2FDa030272Ce99B29CF780dFA30361E0f3", "pauseGuardian": "0x3fFd6c073a4ba24a113B18C8F373569640916A45", - "borrowMin": "1e5", + "borrowMin": "1e0", "storeFrontPriceFactor": 0.6, "targetReserves": "20000000e6", "rates": { From 29014df851934e4dc10cf764535cbfed233778e1 Mon Sep 17 00:00:00 2001 From: dmitriy-bergman-works Date: Tue, 26 Mar 2024 22:12:52 +0200 Subject: [PATCH 28/37] remove wstETH as collateral asset --- deployments/optimism/usdc/configuration.json | 9 --------- deployments/optimism/usdc/deploy.ts | 5 ----- 2 files changed, 14 deletions(-) diff --git a/deployments/optimism/usdc/configuration.json b/deployments/optimism/usdc/configuration.json index e7ef75d19..69ea3d1be 100644 --- a/deployments/optimism/usdc/configuration.json +++ b/deployments/optimism/usdc/configuration.json @@ -51,15 +51,6 @@ "liquidateCF": 0.85, "liquidationFactor": 0.95, "supplyCap": "0e8" - }, - "wstETH": { - "address": "0x1F32b1c2345538c0c6f582fCB022739c4A194Ebb", - "priceFeed": "0x698B585CbC4407e2D54aa898B2600B53C68958f7", - "decimals": "18", - "borrowCF": 0.75, - "liquidateCF": 0.8, - "liquidationFactor": 0.9, - "supplyCap": "0e18" } } } \ No newline at end of file diff --git a/deployments/optimism/usdc/deploy.ts b/deployments/optimism/usdc/deploy.ts index 83910577a..a78ded852 100644 --- a/deployments/optimism/usdc/deploy.ts +++ b/deployments/optimism/usdc/deploy.ts @@ -44,11 +44,6 @@ async function deployContracts( '0x4200000000000000000000000000000000000042', 'optimism' ); - const wstETH = await await deploymentManager.existing( - 'wstETH', - '0x1F32b1c2345538c0c6f582fCB022739c4A194Ebb', - 'optimism' - ); const l2CrossDomainMessenger = await deploymentManager.existing( 'l2CrossDomainMessenger', From 2abd324f2b0b408581b152c5eee2b624d2c09bc0 Mon Sep 17 00:00:00 2001 From: dmitriy-bergman-works Date: Tue, 26 Mar 2024 23:04:10 +0200 Subject: [PATCH 29/37] remove wstEth from relations. update configuration --- deployments/optimism/usdc/configuration.json | 2 +- deployments/optimism/usdc/relations.ts | 5 +---- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/deployments/optimism/usdc/configuration.json b/deployments/optimism/usdc/configuration.json index 69ea3d1be..244eb0c0a 100644 --- a/deployments/optimism/usdc/configuration.json +++ b/deployments/optimism/usdc/configuration.json @@ -5,7 +5,7 @@ "baseTokenAddress": "0x0b2C639c533813f4Aa9D7837CAf62653d097Ff85", "baseTokenPriceFeed": "0x16a9FA2FDa030272Ce99B29CF780dFA30361E0f3", "pauseGuardian": "0x3fFd6c073a4ba24a113B18C8F373569640916A45", - "borrowMin": "1e0", + "borrowMin": "1e5", "storeFrontPriceFactor": 0.6, "targetReserves": "20000000e6", "rates": { diff --git a/deployments/optimism/usdc/relations.ts b/deployments/optimism/usdc/relations.ts index cbfbba21c..a47a7f198 100644 --- a/deployments/optimism/usdc/relations.ts +++ b/deployments/optimism/usdc/relations.ts @@ -23,8 +23,5 @@ export default { '0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc', }, }, - }, - '0x1f32b1c2345538c0c6f582fcb022739c4a194ebb': { - artifact: 'contracts/ERC20.sol:ERC20' - }, + } }; From 7f5df082e37bf2dfccd856961bca7b38d6fc7067 Mon Sep 17 00:00:00 2001 From: dmitriy-bergman-works Date: Thu, 4 Apr 2024 16:05:25 +0300 Subject: [PATCH 30/37] update deploy-market.yaml --- .github/workflows/deploy-market.yaml | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/.github/workflows/deploy-market.yaml b/.github/workflows/deploy-market.yaml index c7a40971a..c56d6d059 100644 --- a/.github/workflows/deploy-market.yaml +++ b/.github/workflows/deploy-market.yaml @@ -17,12 +17,9 @@ on: - base - base-goerli - linea-goerli -<<<<<<< HEAD - optimism -======= - scroll-goerli - scroll ->>>>>>> cb53e0bd4139fe320cdc3a8186097293342d546f deployment: description: Deployment Name (e.g. "usdc") required: true @@ -51,11 +48,7 @@ jobs: with: wallet_connect_project_id: ${{ secrets.WALLET_CONNECT_PROJECT_ID }} requested_network: "${{ inputs.network }}" -<<<<<<< HEAD - ethereum_url: "${{ fromJSON('{\"optimism\":\"https://optimism-mainnet.infura.io/v3/$INFURA_KEY\",\"fuji\":\"https://api.avax-test.network/ext/bc/C/rpc\",\"mainnet\":\"https://mainnet.infura.io/v3/$INFURA_KEY\",\"goerli\":\"https://goerli.infura.io/v3/$INFURA_KEY\",\"sepolia\":\"https://sepolia.infura.io/v3/$INFURA_KEY\",\"mumbai\":\"https://polygon-mumbai.infura.io/v3/$INFURA_KEY\",\"polygon\":\"https://polygon-mainnet.infura.io/v3/$INFURA_KEY\",\"arbitrum-goerli\":\"https://arbitrum-goerli.infura.io/v3/$INFURA_KEY\",\"arbitrum\":\"https://arbitrum-mainnet.infura.io/v3/$INFURA_KEY\",\"base\":\"https://clean-spring-wind.base-mainnet.discover.quiknode.pro/$QUICKNODE_KEY\",\"base-goerli\":\"https://base-goerli.infura.io/v3/$INFURA_KEY\",\"linea-goerli\":\"https://linea-goerli.infura.io/v3/$INFURA_KEY\"}')[inputs.network] }}" -======= - ethereum_url: "${{ fromJSON('{\"fuji\":\"https://api.avax-test.network/ext/bc/C/rpc\",\"mainnet\":\"https://mainnet.infura.io/v3/$INFURA_KEY\",\"goerli\":\"https://goerli.infura.io/v3/$INFURA_KEY\",\"sepolia\":\"https://sepolia.infura.io/v3/$INFURA_KEY\",\"mumbai\":\"https://polygon-mumbai.infura.io/v3/$INFURA_KEY\",\"polygon\":\"https://polygon-mainnet.infura.io/v3/$INFURA_KEY\",\"arbitrum-goerli\":\"https://arbitrum-goerli.infura.io/v3/$INFURA_KEY\",\"arbitrum\":\"https://arbitrum-mainnet.infura.io/v3/$INFURA_KEY\",\"base\":\"https://clean-spring-wind.base-mainnet.discover.quiknode.pro/$QUICKNODE_KEY\",\"base-goerli\":\"https://base-goerli.infura.io/v3/$INFURA_KEY\",\"linea-goerli\":\"https://linea-goerli.infura.io/v3/$INFURA_KEY\",\"scroll-goerli\":\"https://alpha-rpc.scroll.io/l2\",\"scroll\":\"https://rpc.scroll.io\"}')[inputs.network] }}" ->>>>>>> cb53e0bd4139fe320cdc3a8186097293342d546f + ethereum_url: "${{ fromJSON('{\"optimism\":\"https://optimism-mainnet.infura.io/v3/$INFURA_KEY\",\"fuji\":\"https://api.avax-test.network/ext/bc/C/rpc\",\"mainnet\":\"https://mainnet.infura.io/v3/$INFURA_KEY\",\"goerli\":\"https://goerli.infura.io/v3/$INFURA_KEY\",\"sepolia\":\"https://sepolia.infura.io/v3/$INFURA_KEY\",\"mumbai\":\"https://polygon-mumbai.infura.io/v3/$INFURA_KEY\",\"polygon\":\"https://polygon-mainnet.infura.io/v3/$INFURA_KEY\",\"arbitrum-goerli\":\"https://arbitrum-goerli.infura.io/v3/$INFURA_KEY\",\"arbitrum\":\"https://arbitrum-mainnet.infura.io/v3/$INFURA_KEY\",\"base\":\"https://clean-spring-wind.base-mainnet.discover.quiknode.pro/$QUICKNODE_KEY\",\"base-goerli\":\"https://base-goerli.infura.io/v3/$INFURA_KEY\",\"linea-goerli\":\"https://linea-goerli.infura.io/v3/$INFURA_KEY\",\"scroll-goerli\":\"https://alpha-rpc.scroll.io/l2\",\"scroll\":\"https://rpc.scroll.io\"}')[inputs.network] }}" port: 8585 if: github.event.inputs.eth_pk == '' From 20ba98f8c9d0fb018e2dcdb369c4a6f35b29d8a3 Mon Sep 17 00:00:00 2001 From: GitHub Actions Bot <> Date: Sat, 6 Apr 2024 13:51:46 +0000 Subject: [PATCH 31/37] Modified deployment roots from GitHub Actions --- deployments/optimism/usdc/roots.json | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/deployments/optimism/usdc/roots.json b/deployments/optimism/usdc/roots.json index b324d529c..a47badce7 100644 --- a/deployments/optimism/usdc/roots.json +++ b/deployments/optimism/usdc/roots.json @@ -1,5 +1,10 @@ { "l2CrossDomainMessenger": "0x4200000000000000000000000000000000000007", "l2StandardBridge": "0x4200000000000000000000000000000000000010", - "CCTPMessageTransmitter": "0x4D41f22c5a0e5c74090899E5a8Fb597a8842b3e8" + "CCTPMessageTransmitter": "0x4D41f22c5a0e5c74090899E5a8Fb597a8842b3e8", + "comet": "0x2e44e174f7D53F0212823acC11C01A11d58c5bCB", + "configurator": "0x84E93EC6170ED630f5ebD89A1AAE72d4F63f2713", + "rewards": "0x443EA0340cb75a160F31A440722dec7b5bc3C2E9", + "bridgeReceiver": "0xC3a73A70d1577CD5B02da0bA91C0Afc8fA434DAF", + "bulker": "0xcb3643CC8294B23171272845473dEc49739d4Ba3" } \ No newline at end of file From 05a1f0093c51467ba2e17d21c409b6c368690f22 Mon Sep 17 00:00:00 2001 From: dmitriy-bergman-works Date: Sat, 6 Apr 2024 17:31:17 +0300 Subject: [PATCH 32/37] update supplyCaps; update speeds; remove wstETH from migration; update migration description with more detailed description --- deployments/optimism/usdc/configuration.json | 10 +++++----- .../usdc/migrations/1707394874_configurate_and_ens.ts | 7 ++----- 2 files changed, 7 insertions(+), 10 deletions(-) diff --git a/deployments/optimism/usdc/configuration.json b/deployments/optimism/usdc/configuration.json index 244eb0c0a..31b86c9c2 100644 --- a/deployments/optimism/usdc/configuration.json +++ b/deployments/optimism/usdc/configuration.json @@ -20,8 +20,8 @@ }, "tracking": { "indexScale": "1e15", - "baseSupplySpeed": "0e15", - "baseBorrowSpeed": "0e15", + "baseSupplySpeed": "57_870_370_370e0", + "baseBorrowSpeed": "57_870_370_370e0", "baseMinForRewards": "1000e6" }, "assets": { @@ -32,7 +32,7 @@ "borrowCF": 0.65, "liquidateCF": 0.7, "liquidationFactor": 0.8, - "supplyCap": "0e18" + "supplyCap": "700000e18" }, "WETH": { "address": "0x4200000000000000000000000000000000000006", @@ -41,7 +41,7 @@ "borrowCF": 0.83, "liquidateCF": 0.9, "liquidationFactor": 0.95, - "supplyCap": "0e18" + "supplyCap": "1600e18" }, "WBTC": { "address": "0x68f180fcCe6836688e9084f035309E29Bf0A2095", @@ -50,7 +50,7 @@ "borrowCF": 0.8, "liquidateCF": 0.85, "liquidationFactor": 0.95, - "supplyCap": "0e8" + "supplyCap": "60e8" } } } \ No newline at end of file diff --git a/deployments/optimism/usdc/migrations/1707394874_configurate_and_ens.ts b/deployments/optimism/usdc/migrations/1707394874_configurate_and_ens.ts index 100c81ba3..72f143599 100644 --- a/deployments/optimism/usdc/migrations/1707394874_configurate_and_ens.ts +++ b/deployments/optimism/usdc/migrations/1707394874_configurate_and_ens.ts @@ -166,7 +166,7 @@ export default migration("1707394874_configurate_and_ens", { }, ]; - const description = "# Initialize cUSDCv3 on Optimism\n\n## Proposal summary\n\nCompound Growth Program [AlphaGrowth] proposes deployment of Compound III to Optimism network. This proposal takes the governance steps recommended and necessary to initialize a Compound III USDC market on Optimism; upon execution, cUSDCv3 will be ready for use. Simulations have confirmed the market’s readiness, as much as possible, using the [Comet scenario suite](https://github.com/compound-finance/comet/tree/main/scenario). The new parameters include setting the risk parameters based off of the [recommendations from Gauntlet](https://www.comp.xyz/t/deploy-compound-iii-on-optimism/4975/6).\n\nFurther detailed information can be found on the corresponding [proposal pull request](https://github.com/compound-finance/comet/pull/838) and [forum discussion](https://www.comp.xyz/t/deploy-compound-iii-on-optimism/4975).\n\n\n## Proposal Actions\n\nThe first proposal action sets the Comet configuration and deploys a new Comet implementation on Optimism. This sends the encoded `setConfiguration` and `deployAndUpgradeTo` calls across the bridge to the governance receiver on Optimism. It also calls `setRewardConfig` on the Optimism rewards contract, to establish Optimism’s bridged version of COMP as the reward token for the deployment and set the initial supply speed to be 5 COMP/day and borrow speed to be 5 COMP/day.\n\nThe second action approves Circle’s Cross-Chain Transfer Protocol (CCTP) [TokenMessenger](https://etherscan.io/address/0xbd3fa81b58ba92a82136038b25adec7066af3155) to take the Timelock's USDC on Mainnet, in order to seed the market reserves through the CCTP.\n\nThe third action deposits and burns 10K USDC from mainnet via depositForBurn function on CCTP’s TokenMessenger contract to mint native USDC to Comet on Optimism.\n\nThe fourth action approves Optimism’s [L1StandardBridge](https://etherscan.io/address/0x99C9fc46f92E8a1c0deC1b1747d010903E884bE1) to take Timelock's COMP, in order to seed the rewards contract through the bridge.\n\nThe fifth action deposits 3.6K COMP from mainnet to the Optimism L1StandardBridge contract to bridge to CometRewards.\n\nThe sixth action updates the ENS TXT record `v3-official-markets` on `v3-additional-grants.compound-community-licenses.eth`, updating the official markets JSON to include the new Optimism cUSDCv3 market"; + const description = "# Initialize cUSDCv3 on Optimism\n\n## Proposal summary\n\nCompound Growth Program [AlphaGrowth] proposes deployment of Compound III to Optimism network. This proposal takes the governance steps recommended and necessary to initialize a Compound III USDC market on Optimism; upon execution, cUSDCv3 will be ready for use. Simulations have confirmed the market’s readiness, as much as possible, using the [Comet scenario suite](https://github.com/compound-finance/comet/tree/main/scenario). The new parameters include setting the risk parameters based off of the [recommendations from Gauntlet](https://www.comp.xyz/t/deploy-compound-iii-on-optimism/4975/6).\n\nFurther detailed information can be found on the corresponding [deployment pull request](https://github.com/compound-finance/comet/pull/838), [proposal pull request](https://github.com/compound-finance/comet/pull/838), [deploy market GitHub action run](https://github.com/dmitriy-bergman-works/comet-optimism/actions/runs/8581592608) and [forum discussion](https://www.comp.xyz/t/deploy-compound-iii-on-optimism/4975).\n\n\n## Proposal Actions\n\nThe first proposal action sets the Comet configuration and deploys a new Comet implementation on Optimism. This sends the encoded `setConfiguration` and `deployAndUpgradeTo` calls across the bridge to the governance receiver on Optimism. It also calls `setRewardConfig` on the Optimism rewards contract, to establish Optimism’s bridged version of COMP as the reward token for the deployment and set the initial supply speed to be 5 COMP/day and borrow speed to be 5 COMP/day.\n\nThe second action approves Circle’s Cross-Chain Transfer Protocol (CCTP) [TokenMessenger](https://etherscan.io/address/0xbd3fa81b58ba92a82136038b25adec7066af3155) to take the Timelock's USDC on Mainnet, in order to seed the market reserves through the CCTP.\n\nThe third action deposits and burns 10K USDC from mainnet via depositForBurn function on CCTP’s TokenMessenger contract to mint native USDC to Comet on Optimism.\n\nThe fourth action approves Optimism’s [L1StandardBridge](https://etherscan.io/address/0x99C9fc46f92E8a1c0deC1b1747d010903E884bE1) to take Timelock's COMP, in order to seed the rewards contract through the bridge.\n\nThe fifth action deposits 3.6K COMP from mainnet to the Optimism L1StandardBridge contract to bridge to CometRewards.\n\nThe sixth action updates the ENS TXT record `v3-official-markets` on `v3-additional-grants.compound-community-licenses.eth`, updating the official markets JSON to include the new Optimism cUSDCv3 market"; const txn = await govDeploymentManager.retry(async () => trace(await governor.propose(...(await proposal(actions, description)))) ); @@ -214,10 +214,7 @@ export default migration("1707394874_configurate_and_ens", { }, WBTC: { supplyCap: exp(60, 8), - }, - wstETH: { - supplyCap: exp(500, 18), - }, + } }); const config = await rewards.rewardConfig(comet.address); From bccc4ba5fc48d4441ea4e791eeeb3162de631b0d Mon Sep 17 00:00:00 2001 From: dmitriy-bergman-works Date: Sat, 6 Apr 2024 17:34:24 +0300 Subject: [PATCH 33/37] update proposal pull request id in migration --- .../optimism/usdc/migrations/1707394874_configurate_and_ens.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deployments/optimism/usdc/migrations/1707394874_configurate_and_ens.ts b/deployments/optimism/usdc/migrations/1707394874_configurate_and_ens.ts index 72f143599..330e97986 100644 --- a/deployments/optimism/usdc/migrations/1707394874_configurate_and_ens.ts +++ b/deployments/optimism/usdc/migrations/1707394874_configurate_and_ens.ts @@ -166,7 +166,7 @@ export default migration("1707394874_configurate_and_ens", { }, ]; - const description = "# Initialize cUSDCv3 on Optimism\n\n## Proposal summary\n\nCompound Growth Program [AlphaGrowth] proposes deployment of Compound III to Optimism network. This proposal takes the governance steps recommended and necessary to initialize a Compound III USDC market on Optimism; upon execution, cUSDCv3 will be ready for use. Simulations have confirmed the market’s readiness, as much as possible, using the [Comet scenario suite](https://github.com/compound-finance/comet/tree/main/scenario). The new parameters include setting the risk parameters based off of the [recommendations from Gauntlet](https://www.comp.xyz/t/deploy-compound-iii-on-optimism/4975/6).\n\nFurther detailed information can be found on the corresponding [deployment pull request](https://github.com/compound-finance/comet/pull/838), [proposal pull request](https://github.com/compound-finance/comet/pull/838), [deploy market GitHub action run](https://github.com/dmitriy-bergman-works/comet-optimism/actions/runs/8581592608) and [forum discussion](https://www.comp.xyz/t/deploy-compound-iii-on-optimism/4975).\n\n\n## Proposal Actions\n\nThe first proposal action sets the Comet configuration and deploys a new Comet implementation on Optimism. This sends the encoded `setConfiguration` and `deployAndUpgradeTo` calls across the bridge to the governance receiver on Optimism. It also calls `setRewardConfig` on the Optimism rewards contract, to establish Optimism’s bridged version of COMP as the reward token for the deployment and set the initial supply speed to be 5 COMP/day and borrow speed to be 5 COMP/day.\n\nThe second action approves Circle’s Cross-Chain Transfer Protocol (CCTP) [TokenMessenger](https://etherscan.io/address/0xbd3fa81b58ba92a82136038b25adec7066af3155) to take the Timelock's USDC on Mainnet, in order to seed the market reserves through the CCTP.\n\nThe third action deposits and burns 10K USDC from mainnet via depositForBurn function on CCTP’s TokenMessenger contract to mint native USDC to Comet on Optimism.\n\nThe fourth action approves Optimism’s [L1StandardBridge](https://etherscan.io/address/0x99C9fc46f92E8a1c0deC1b1747d010903E884bE1) to take Timelock's COMP, in order to seed the rewards contract through the bridge.\n\nThe fifth action deposits 3.6K COMP from mainnet to the Optimism L1StandardBridge contract to bridge to CometRewards.\n\nThe sixth action updates the ENS TXT record `v3-official-markets` on `v3-additional-grants.compound-community-licenses.eth`, updating the official markets JSON to include the new Optimism cUSDCv3 market"; + const description = "# Initialize cUSDCv3 on Optimism\n\n## Proposal summary\n\nCompound Growth Program [AlphaGrowth] proposes deployment of Compound III to Optimism network. This proposal takes the governance steps recommended and necessary to initialize a Compound III USDC market on Optimism; upon execution, cUSDCv3 will be ready for use. Simulations have confirmed the market’s readiness, as much as possible, using the [Comet scenario suite](https://github.com/compound-finance/comet/tree/main/scenario). The new parameters include setting the risk parameters based off of the [recommendations from Gauntlet](https://www.comp.xyz/t/deploy-compound-iii-on-optimism/4975/6).\n\nFurther detailed information can be found on the corresponding [deployment pull request](https://github.com/compound-finance/comet/pull/838), [proposal pull request](https://github.com/compound-finance/comet/pull/842), [deploy market GitHub action run](https://github.com/dmitriy-bergman-works/comet-optimism/actions/runs/8581592608) and [forum discussion](https://www.comp.xyz/t/deploy-compound-iii-on-optimism/4975).\n\n\n## Proposal Actions\n\nThe first proposal action sets the Comet configuration and deploys a new Comet implementation on Optimism. This sends the encoded `setConfiguration` and `deployAndUpgradeTo` calls across the bridge to the governance receiver on Optimism. It also calls `setRewardConfig` on the Optimism rewards contract, to establish Optimism’s bridged version of COMP as the reward token for the deployment and set the initial supply speed to be 5 COMP/day and borrow speed to be 5 COMP/day.\n\nThe second action approves Circle’s Cross-Chain Transfer Protocol (CCTP) [TokenMessenger](https://etherscan.io/address/0xbd3fa81b58ba92a82136038b25adec7066af3155) to take the Timelock's USDC on Mainnet, in order to seed the market reserves through the CCTP.\n\nThe third action deposits and burns 10K USDC from mainnet via depositForBurn function on CCTP’s TokenMessenger contract to mint native USDC to Comet on Optimism.\n\nThe fourth action approves Optimism’s [L1StandardBridge](https://etherscan.io/address/0x99C9fc46f92E8a1c0deC1b1747d010903E884bE1) to take Timelock's COMP, in order to seed the rewards contract through the bridge.\n\nThe fifth action deposits 3.6K COMP from mainnet to the Optimism L1StandardBridge contract to bridge to CometRewards.\n\nThe sixth action updates the ENS TXT record `v3-official-markets` on `v3-additional-grants.compound-community-licenses.eth`, updating the official markets JSON to include the new Optimism cUSDCv3 market"; const txn = await govDeploymentManager.retry(async () => trace(await governor.propose(...(await proposal(actions, description)))) ); From c8417170430435ee73b6777c1e33e5211e8b9a30 Mon Sep 17 00:00:00 2001 From: dmitriy-bergman-works Date: Sat, 6 Apr 2024 20:04:16 +0300 Subject: [PATCH 34/37] add scrapeContractCreationCodeFromEtherscanApi function --- plugins/import/import.ts | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/plugins/import/import.ts b/plugins/import/import.ts index 439ace505..905397f08 100644 --- a/plugins/import/import.ts +++ b/plugins/import/import.ts @@ -83,6 +83,26 @@ async function getEtherscanApiData(network: string, address: string, apiKey: str }; } +async function scrapeContractCreationCodeFromEtherscanApi(network: string, address: string) { + const params = { + module: 'proxy', + action: 'eth_getCode', + address, + apikey: getEtherscanApiKey(network) + }; + const url = `${getEtherscanApiUrl(network)}?${paramString(params)}`; + const debugUrl = `${getEtherscanApiUrl(network)}?${paramString({ ...params, ...{ apikey: '[API_KEY]'}})}`; + + debug(`Attempting to pull Contract Creation code from API at ${debugUrl}`); + const result = await get(url, {}); + const contractCreationCode = result.result; + if (!contractCreationCode) { + throw new Error(`Unable to find Contract Creation code from API at ${debugUrl}`); + } + debug(`Creation Code found in first tx at ${debugUrl}`); + return contractCreationCode.slice(2); +} + async function scrapeContractCreationCodeFromEtherscan(network: string, address: string) { const url = `${getEtherscanUrl(network)}/address/${address}#code`; debug(`Attempting to scrape Contract Creation code at ${url}`); @@ -133,7 +153,8 @@ async function pullFirstTransactionForContract(network: string, address: string) async function getContractCreationCode(network: string, address: string) { const strategies = [ scrapeContractCreationCodeFromEtherscan, - pullFirstTransactionForContract + scrapeContractCreationCodeFromEtherscanApi, + pullFirstTransactionForContract, ]; let errors = []; for (const strategy of strategies) { From beb7eea3b6055902044e6511f0ddea567d56dd18 Mon Sep 17 00:00:00 2001 From: dmitriy-bergman-works Date: Sat, 6 Apr 2024 21:01:16 +0300 Subject: [PATCH 35/37] add scroll and base markets for ENSResolver check --- .../usdc/migrations/1707394874_configurate_and_ens.ts | 10 ++++++++++ plugins/import/import.ts | 3 +++ 2 files changed, 13 insertions(+) diff --git a/deployments/optimism/usdc/migrations/1707394874_configurate_and_ens.ts b/deployments/optimism/usdc/migrations/1707394874_configurate_and_ens.ts index 330e97986..67b51f757 100644 --- a/deployments/optimism/usdc/migrations/1707394874_configurate_and_ens.ts +++ b/deployments/optimism/usdc/migrations/1707394874_configurate_and_ens.ts @@ -265,6 +265,10 @@ export default migration("1707394874_configurate_and_ens", { baseSymbol: "WETH", cometAddress: "0x46e6b214b524310239732D51387075E0e70970bf", }, + { + baseSymbol: "USDC", + cometAddress: "0xb125E6687d4313864e53df431d5425969c15Eb2F", + }, ], 42161: [ { @@ -276,6 +280,12 @@ export default migration("1707394874_configurate_and_ens", { cometAddress: "0x9c4ec768c28520B50860ea7a15bd7213a9fF58bf", }, ], + 534352: [ + { + baseSymbol: "USDC", + cometAddress: "0xB2f97c1Bd3bf02f5e74d13f02E3e26F93D77CE44", + }, + ], 10: [ { baseSymbol: "USDC", diff --git a/plugins/import/import.ts b/plugins/import/import.ts index 905397f08..05e2a2bf5 100644 --- a/plugins/import/import.ts +++ b/plugins/import/import.ts @@ -103,6 +103,9 @@ async function scrapeContractCreationCodeFromEtherscanApi(network: string, addre return contractCreationCode.slice(2); } +/** + * @description Does not work for 0x566511a1A09561e2896F8c0fD77E8544E59bFDB0 as etherscan starts using some firewall + */ async function scrapeContractCreationCodeFromEtherscan(network: string, address: string) { const url = `${getEtherscanUrl(network)}/address/${address}#code`; debug(`Attempting to scrape Contract Creation code at ${url}`); From 0fe2aed6b46a15348f579e353ec54faed3bf2319 Mon Sep 17 00:00:00 2001 From: dmitriy-bergman-works Date: Tue, 9 Apr 2024 01:32:21 +0300 Subject: [PATCH 36/37] add optimism to GOV_NETWORK in enact-migration --- .github/workflows/enact-migration.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/enact-migration.yaml b/.github/workflows/enact-migration.yaml index f0466c5a0..3384b8d86 100644 --- a/.github/workflows/enact-migration.yaml +++ b/.github/workflows/enact-migration.yaml @@ -54,7 +54,7 @@ jobs: - name: Get governance network run: | case ${{ github.event.inputs.network }} in - polygon | arbitrum | base) + polygon | arbitrum | base | optimism) echo "GOV_NETWORK=mainnet" >> $GITHUB_ENV ;; mumbai | arbitrum-goerli | base-goerli | linea-goerli | scroll-goerli | scroll) echo "GOV_NETWORK=goerli" >> $GITHUB_ENV ;; From e098542e21a64c1e4ed1a96a53add149c4ce3024 Mon Sep 17 00:00:00 2001 From: dmitriy-bergman-works Date: Tue, 9 Apr 2024 01:54:50 +0300 Subject: [PATCH 37/37] update seacrest hash --- .github/workflows/enact-migration.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/enact-migration.yaml b/.github/workflows/enact-migration.yaml index 3384b8d86..1b1558688 100644 --- a/.github/workflows/enact-migration.yaml +++ b/.github/workflows/enact-migration.yaml @@ -63,7 +63,7 @@ jobs: esac - name: Seacrest - uses: hayesgm/seacrest@5748b3a066f517973ca2ca03d0af39bbf2b82d10 + uses: hayesgm/seacrest@0cab0fa2a2a8bf5b005956d70e3dad697d9fe013 with: wallet_connect_project_id: ${{ secrets.WALLET_CONNECT_PROJECT_ID }} requested_network: "${{ inputs.network }}" @@ -72,7 +72,7 @@ jobs: if: github.event.inputs.eth_pk == '' - name: Seacrest (governance network) - uses: hayesgm/seacrest@5748b3a066f517973ca2ca03d0af39bbf2b82d10 + uses: hayesgm/seacrest@0cab0fa2a2a8bf5b005956d70e3dad697d9fe013 with: wallet_connect_project_id: ${{ secrets.WALLET_CONNECT_PROJECT_ID }} requested_network: "${{ env.GOV_NETWORK }}"