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", }, },