From bc1303238f32b88b466f734c29ac63404927efd4 Mon Sep 17 00:00:00 2001 From: Michalina Date: Tue, 5 Sep 2023 11:40:13 +0200 Subject: [PATCH] Support deployment on Sepolia MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The Görli testnet currently used by Threshold/Keep for development purposes is planned to become deprecated with the end of year 2023. The testnet that is planned to replace it is called [Holešky](https://github.com/eth-clients/holesky), however it's not yet available - it's planned it will become widely accessible on Oct 1, 2023 ([source](https://everstake.one/blog/new-ethereum-testnet-holesky-all-you-need-to-know-now)). Switching our infrastructure to support new testnet is quite time consuming, so moving directly from Görli to Holešky may be quite risky, especially if there would be some delays in the date of Holešky genesis (not meeting the planned timelines is not a rare occurrence in the Ethereum space). As a solution, we decided to switch first to another testnet that is currently live - Sepolia. This testnet's EOL is planned for 2026, which gives us plenty of time to move to Holešky before Sepolia gets deprecated. --- .github/workflows/contracts.yml | 39 ++++++++++++--- .github/workflows/typescript.yml | 2 +- cross-chain/arbitrum/.gitignore | 1 + solidity/contracts/test/SepoliaLightRelay.sol | 48 +++++++++++++++++++ solidity/deploy/01_deploy_light_relay.ts | 3 ++ .../deploy/09_deploy_bridge_governance.ts | 7 ++- .../19_authorize_spv_maintainer_in_bridge.ts | 6 +-- solidity/deploy/24_transfer_tbtc_ownership.ts | 2 +- ..._authorize_bridge_in_reimbursement_pool.ts | 2 +- ..._maintainer_proxy_in_reimbursement_pool.ts | 2 +- ...t_relay_maintainer_proxy_in_light_relay.ts | 4 +- solidity/hardhat.config.ts | 23 +++++++++ 12 files changed, 123 insertions(+), 16 deletions(-) create mode 100644 solidity/contracts/test/SepoliaLightRelay.sol diff --git a/.github/workflows/contracts.yml b/.github/workflows/contracts.yml index 85f0ebdd0..68dcf995f 100644 --- a/.github/workflows/contracts.yml +++ b/.github/workflows/contracts.yml @@ -27,7 +27,7 @@ on: workflow_dispatch: inputs: environment: - description: "Environment (network) for workflow execution, e.g. `goerli`" + description: "Environment (network) for workflow execution, e.g. `sepolia`" required: false upstream_builds: description: "Upstream builds" @@ -185,8 +185,18 @@ jobs: - name: Deploy contracts env: - CHAIN_API_URL: ${{ secrets.GOERLI_ETH_HOSTNAME_HTTP }} - ACCOUNTS_PRIVATE_KEYS: ${{ secrets.GOERLI_ETH_CONTRACT_OWNER_PRIVATE_KEY }} + # Use fake ternary expressions to decide which credentials to use, + # depending on chosen environment. Note: if `GOERLI...` credentials + # are empty, the expressions will be evaluated to the `SEPOLIA...` + # ones. + CHAIN_API_URL: | + ${{ inputs.github.event.inputs.environment == 'goerli' \ + && secrets.GOERLI_ETH_HOSTNAME_HTTP \ + || secrets.SEPOLIA_ETH_HOSTNAME_HTTP }} + ACCOUNTS_PRIVATE_KEYS: | + ${{ inputs.github.event.inputs.environment == 'goerli' \ + && secrets.GOERLI_ETH_CONTRACT_OWNER_PRIVATE_KEY \ + || secrets.SEPOLIA_ETH_CONTRACT_OWNER_PRIVATE_KEY }} run: yarn deploy --network ${{ github.event.inputs.environment }} - name: Bump up package version @@ -268,7 +278,14 @@ jobs: - name: Verify contracts on Etherscan env: ETHERSCAN_API_KEY: ${{ secrets.ETHERSCAN_API_KEY }} - CHAIN_API_URL: ${{ secrets.GOERLI_ETH_HOSTNAME_HTTP }} + # Use fake ternary expression to decide which credentials to use, + # depending on chosen environment. Note: if `GOERLI...` credential + # is empty, the expression will be evaluated to the `SEPOLIA...` + # one. + CHAIN_API_URL: | + ${{ inputs.github.event.inputs.environment == 'goerli' \ + && secrets.GOERLI_ETH_HOSTNAME_HTTP \ + || secrets.SEPOLIA_ETH_HOSTNAME_HTTP }} run: yarn run hardhat --network ${{ github.event.inputs.environment }} etherscan-verify # This job is responsible for publishing packackes with slightly modified @@ -326,8 +343,18 @@ jobs: - name: Deploy contracts env: - CHAIN_API_URL: ${{ secrets.GOERLI_ETH_HOSTNAME_HTTP }} - ACCOUNTS_PRIVATE_KEYS: ${{ secrets.DAPP_DEV_GOERLI_ETH_CONTRACT_OWNER_PRIVATE_KEY }} + # Use fake ternary expressions to decide which credentials to use, + # depending on chosen environment. Note: if `GOERLI...` credentials + # are empty, the expressions will be evaluated to the `SEPOLIA...` + # ones. + CHAIN_API_URL: | + ${{ inputs.github.event.inputs.environment == 'goerli' \ + && secrets.GOERLI_ETH_HOSTNAME_HTTP \ + || secrets.SEPOLIA_ETH_HOSTNAME_HTTP }} + ACCOUNTS_PRIVATE_KEYS: | + ${{ inputs.github.event.inputs.environment == 'goerli' \ + && secrets.DAPP_DEV_GOERLI_ETH_CONTRACT_OWNER_PRIVATE_KEY \ + || secrets.DAPP_DEV_SEPOLIA_ETH_CONTRACT_OWNER_PRIVATE_KEY }} run: yarn deploy --network ${{ github.event.inputs.environment }} - name: Bump up package version diff --git a/.github/workflows/typescript.yml b/.github/workflows/typescript.yml index f4ed3d750..f5b1a8bc1 100644 --- a/.github/workflows/typescript.yml +++ b/.github/workflows/typescript.yml @@ -12,7 +12,7 @@ on: workflow_dispatch: inputs: environment: - description: "Environment (network) for workflow execution, e.g. `goerli`" + description: "Environment (network) for workflow execution, e.g. `sepolia`" required: false upstream_builds: description: "Upstream builds" diff --git a/cross-chain/arbitrum/.gitignore b/cross-chain/arbitrum/.gitignore index bc2e1841e..24d77a6b9 100644 --- a/cross-chain/arbitrum/.gitignore +++ b/cross-chain/arbitrum/.gitignore @@ -10,6 +10,7 @@ !/deployments/mainnet/ !/deployments/arbitrumOne/ !/deployments/arbitrumGoerli/ +!/deployments/arbitrumSepolia/ # OZ /.openzeppelin/unknown-*.json diff --git a/solidity/contracts/test/SepoliaLightRelay.sol b/solidity/contracts/test/SepoliaLightRelay.sol new file mode 100644 index 000000000..816ac9c59 --- /dev/null +++ b/solidity/contracts/test/SepoliaLightRelay.sol @@ -0,0 +1,48 @@ +// SPDX-License-Identifier: GPL-3.0-only + +// ██████████████ ▐████▌ ██████████████ +// ██████████████ ▐████▌ ██████████████ +// ▐████▌ ▐████▌ +// ▐████▌ ▐████▌ +// ██████████████ ▐████▌ ██████████████ +// ██████████████ ▐████▌ ██████████████ +// ▐████▌ ▐████▌ +// ▐████▌ ▐████▌ +// ▐████▌ ▐████▌ +// ▐████▌ ▐████▌ +// ▐████▌ ▐████▌ +// ▐████▌ ▐████▌ + +pragma solidity 0.8.17; + +import {BTCUtils} from "@keep-network/bitcoin-spv-sol/contracts/BTCUtils.sol"; + +import "../relay/LightRelay.sol"; + +/// @title Sepolia Light Relay +/// @notice SepoliaLightRelay is a stub version of LightRelay intended to be +/// used on the Sepolia test network. It allows to set the relay's +/// difficulty based on arbitrary Bitcoin headers thus effectively +/// bypass the validation of difficulties of Bitcoin testnet blocks. +/// Since difficulty in Bitcoin testnet often falls to `1` it would not +/// be possible to validate blocks with the real LightRelay. +/// @dev Notice that SepoliaLightRelay is derived from LightRelay so that the two +/// contracts have the same API and correct bindings can be generated. +contract SepoliaLightRelay is LightRelay { + using BTCUtils for bytes; + using BTCUtils for uint256; + + /// @notice Sets the current and previous difficulty based on the difficulty + /// inferred from the provided Bitcoin headers. + function setDifficultyFromHeaders(bytes memory bitcoinHeaders) + external + onlyOwner + { + uint256 firstHeaderDiff = bitcoinHeaders + .extractTarget() + .calculateDifficulty(); + + currentEpochDifficulty = firstHeaderDiff; + prevEpochDifficulty = firstHeaderDiff; + } +} diff --git a/solidity/deploy/01_deploy_light_relay.ts b/solidity/deploy/01_deploy_light_relay.ts index 2c11de85b..d6fabb348 100644 --- a/solidity/deploy/01_deploy_light_relay.ts +++ b/solidity/deploy/01_deploy_light_relay.ts @@ -9,6 +9,9 @@ const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { if (hre.network.name === "goerli") { return "GoerliLightRelay" } + if (hre.network.name === "sepolia") { + return "SepoliaLightRelay" + } if (hre.network.name === "system_tests") { return "SystemTestRelay" } diff --git a/solidity/deploy/09_deploy_bridge_governance.ts b/solidity/deploy/09_deploy_bridge_governance.ts index 88574375a..ff67e07fe 100644 --- a/solidity/deploy/09_deploy_bridge_governance.ts +++ b/solidity/deploy/09_deploy_bridge_governance.ts @@ -17,8 +17,11 @@ const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { } ) - // 60 seconds for Goerli. 48 hours otherwise. - const GOVERNANCE_DELAY = hre.network.name === "goerli" ? 60 : 172800 + // 60 seconds for Goerli/Sepolia. 48 hours otherwise. + const GOVERNANCE_DELAY = + hre.network.name === "goerli" || hre.network.name === "sepolia" + ? 60 + : 172800 const bridgeGovernance = await deploy("BridgeGovernance", { contract: "BridgeGovernance", diff --git a/solidity/deploy/19_authorize_spv_maintainer_in_bridge.ts b/solidity/deploy/19_authorize_spv_maintainer_in_bridge.ts index 04461e90d..6ea56b7ed 100644 --- a/solidity/deploy/19_authorize_spv_maintainer_in_bridge.ts +++ b/solidity/deploy/19_authorize_spv_maintainer_in_bridge.ts @@ -21,9 +21,9 @@ func.tags = ["AuthorizeSpvMaintainer"] func.dependencies = ["Bridge"] // SPV maintainer can submit SPV proofs to the Bridge. We authorize spvMaintainer -// account for Hardhat network (unit tests) and Goerli (testnet) but we DO NOT -// want to authorize it for Mainnet deployment. SPV maintainer will be authorized -// separately by the Governance when sweeping will be activated. +// account for Hardhat network (unit tests) and Goerli/Sepolia (testnets) but we +// DO NOT want to authorize it for Mainnet deployment. SPV maintainer will be +// authorized separately by the Governance when sweeping will be activated. // // Note that at this point MaintainerProxy contract is already authorized in the // Bridge (see AuthorizeMaintainerProxyInBridge tag). diff --git a/solidity/deploy/24_transfer_tbtc_ownership.ts b/solidity/deploy/24_transfer_tbtc_ownership.ts index f084ec7ee..8bd3af2cb 100644 --- a/solidity/deploy/24_transfer_tbtc_ownership.ts +++ b/solidity/deploy/24_transfer_tbtc_ownership.ts @@ -8,7 +8,7 @@ const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { // In unit tests we cover VendingMachine, VendingMachineV2, and TBTCVault // contracts. All those tests require minting TBTC. To make the test setup // easier, we leave the responsibility of transferring the TBTC ownership - // to the test. In system tests and on Goerli, TBTCVault is the owner of TBTC + // to the test. In system tests and on testnet, TBTCVault is the owner of TBTC // token, just like on v1.0 mainnet, after transferring the ownership from the // VendingMachine. if (hre.network.name !== "hardhat") { diff --git a/solidity/deploy/28_authorize_bridge_in_reimbursement_pool.ts b/solidity/deploy/28_authorize_bridge_in_reimbursement_pool.ts index 6c117aedc..7e4b71ba1 100644 --- a/solidity/deploy/28_authorize_bridge_in_reimbursement_pool.ts +++ b/solidity/deploy/28_authorize_bridge_in_reimbursement_pool.ts @@ -24,6 +24,6 @@ func.dependencies = ["ReimbursementPool", "Bridge"] // On mainnet, the ReimbursementPool ownership is passed to the Threshold // Council / DAO and that address is not controlled by the dev team. // Hence, this step can be executed only for non-mainnet networks such as -// Hardhat (unit tests) and Goerli (testnet). +// Hardhat (unit tests) and Goerli or Sepolia (testnets). func.skip = async (hre: HardhatRuntimeEnvironment): Promise => hre.network.name === "mainnet" diff --git a/solidity/deploy/40_authorize_light_relay_maintainer_proxy_in_reimbursement_pool.ts b/solidity/deploy/40_authorize_light_relay_maintainer_proxy_in_reimbursement_pool.ts index 5a168efcb..0a2e9d771 100644 --- a/solidity/deploy/40_authorize_light_relay_maintainer_proxy_in_reimbursement_pool.ts +++ b/solidity/deploy/40_authorize_light_relay_maintainer_proxy_in_reimbursement_pool.ts @@ -26,6 +26,6 @@ func.dependencies = ["ReimbursementPool", "LightRelayMaintainerProxy"] // On mainnet, the ReimbursementPool ownership is passed to the Threshold // Council / DAO and that address is not controlled by the dev team. // Hence, this step can be executed only for non-mainnet networks such as -// Hardhat (unit tests) and Goerli (testnet). +// Hardhat (unit tests) and Goerli or Sepolia (testnets). func.skip = async (hre: HardhatRuntimeEnvironment): Promise => hre.network.name === "mainnet" diff --git a/solidity/deploy/41_authorize_light_relay_maintainer_proxy_in_light_relay.ts b/solidity/deploy/41_authorize_light_relay_maintainer_proxy_in_light_relay.ts index caf86da21..95e1a64e4 100644 --- a/solidity/deploy/41_authorize_light_relay_maintainer_proxy_in_light_relay.ts +++ b/solidity/deploy/41_authorize_light_relay_maintainer_proxy_in_light_relay.ts @@ -24,4 +24,6 @@ func.tags = ["AuthorizeLightRelayMaintainerProxyInLightRelay"] func.dependencies = ["LightRelay", "LightRelayMaintainerProxy"] func.skip = async (hre: HardhatRuntimeEnvironment): Promise => - hre.network.name === "goerli" || hre.network.name === "system_tests" + hre.network.name === "goerli" + || hre.network.name === "sepolia" + || hre.network.name === "system_tests" diff --git a/solidity/hardhat.config.ts b/solidity/hardhat.config.ts index 1cb7b16a1..b5c91f0b7 100644 --- a/solidity/hardhat.config.ts +++ b/solidity/hardhat.config.ts @@ -117,6 +117,14 @@ const config: HardhatUserConfig = { : undefined, tags: ["tenderly"], }, + sepolia: { + url: process.env.CHAIN_API_URL || "", + chainId: 11155111, + accounts: process.env.ACCOUNTS_PRIVATE_KEYS + ? process.env.ACCOUNTS_PRIVATE_KEYS.split(",") + : undefined, + tags: ["tenderly"], + }, mainnet: { url: process.env.CHAIN_API_URL || "", chainId: 1, @@ -172,6 +180,11 @@ const config: HardhatUserConfig = { "node_modules/@keep-network/random-beacon/artifacts", "node_modules/@keep-network/ecdsa/artifacts", ], + sepolia: [ + "node_modules/@keep-network/tbtc/artifacts", + "node_modules/@keep-network/random-beacon/artifacts", + "node_modules/@keep-network/ecdsa/artifacts", + ], mainnet: ["./external/mainnet"], }, }, @@ -180,16 +193,19 @@ const config: HardhatUserConfig = { deployer: { default: 1, goerli: 0, + sepolia: 0, mainnet: 0, // "0x123694886DBf5Ac94DDA07135349534536D14cAf" }, governance: { default: 2, goerli: 0, + sepolia: 0, mainnet: "0x9f6e831c8f8939dc0c830c6e492e7cef4f9c2f5f", // Threshold Council }, chaosnetOwner: { default: 3, goerli: 0, + sepolia: 0, // Not used for mainnet deployment scripts of `@keepn-network/tbtc-v2`. // Used by `@keep-network/random-beacon` and `@keep-network/ecdsa` // when deploying `SortitionPool`s. @@ -197,36 +213,43 @@ const config: HardhatUserConfig = { esdm: { default: 4, goerli: 0, + sepolia: 0, mainnet: "0x9f6e831c8f8939dc0c830c6e492e7cef4f9c2f5f", // Threshold Council }, keepTechnicalWalletTeam: { default: 5, goerli: 0, + sepolia: 0, mainnet: "0xB3726E69Da808A689F2607939a2D9E958724FC2A", }, keepCommunityMultiSig: { default: 6, goerli: 0, + sepolia: 0, mainnet: "0x19FcB32347ff4656E4E6746b4584192D185d640d", }, treasury: { default: 7, goerli: 0, + sepolia: 0, mainnet: "0x87F005317692D05BAA4193AB0c961c69e175f45f", // Token Holder DAO }, spvMaintainer: { default: 8, goerli: 0, + sepolia: 0, // We are not setting SPV maintainer for mainnet in deployment scripts. }, coordinator: { default: 9, goerli: "0x4815cd81fFc21039a25aCFbD97CE75cCE8579042", + // TODO: add one for sepolia mainnet: "0x0595acCca29654c43Bd67E18578b30a405265234", }, v1Redeemer: { default: 10, goerli: 0, + sepolia: 0, mainnet: "0x8Bac178fA95Cb56D11A94d4f1b2B1F5Fc48A30eA", }, },