-
Notifications
You must be signed in to change notification settings - Fork 36
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Adding Base module for canonical TBTC (#673)
Part of #542 This PR is a continuation of tBTC expansion to L2s - BASE chain. Code was largely copied from the existing cross-chain/* modules with some naming modifications, addresses and chain ids. It creates a new cross-chain/base module to bring tBTC to BASE with the help of Wormhole. Here's a diagram to illustrate the flow ``` +----------------------------+ +-------------------------------------------------------------------+ | Ethereum | | Base | | | | | | +----------------------+ | | +----------------------+ +---------------------+ +----------+ | | | Wormhole TokenBridge |--|---------|--| Wormhole TokenBridge |--| BaseWormholeGateway |--| BaseTBTC | | | +----------------------+ | | +----------------------+ +---------------------+ +----------+ | | | | | +----------------------------+ +-------------------------------------------------------------------+ ``` - `Wormhole TokenBridge` on Ethereum - holds all `TBTC` bridged to BASE. This is an external contract created by the Wormhole team. - `Wormhole TokenBridge` on BASE - mints Wormhole wrapped `TBTC` ie. `wormholeTBTC`. This is an external contract created by the Wormhole team. - `BaseWormholeGateway` on BASE - acts as a vending machine that wraps and unwraps `wormholeTBTC` to the canonical `tBTC` token on BASE. This is an upgradable Gateway behind OZ transparent proxy. The Threshold team creates it. - `BaseTBTC` canonical `tBTC` token on BASE. It is upgradable behind OZ transparent proxy. The Threshold team creates it. All the ownership of Threshold-created contracts is transferred to the Threshold governance including a proxy admin ownership. A couple of things to pay closer attention at: - addresses under the `external/` dir - gateway address to a wormhole chain id: `30` - gateway addresses to other wormhole chains id: `23 - Arbitrum`, `24 - Optimism`, `5 - Polygon` - Goerli BASE and Mainnet BASE chain ids: `84531` and `8453` ## Deploy on BASE testnet / mainnet Create a `.envrc` file and include the following: ``` export L2_CHAIN_API_URL=<API_URL> // e.g. "https://goerli.base.org" export L2_ACCOUNTS_PRIVATE_KEYS=<0xOWNER_PRIV_KEY> export BASESCAN_API_KEY=<API_KEY> // needs to be created on [basescan](https://basescan.org/) ``` ```sh yarn deploy --network <network> ``` where `network` can be: - `baseGeorli` // testnet - `base` // mainnet ## Useful links: https://docs.base.org/network-information/ https://docs.wormhole.com/wormhole/supported-environments/evm#base TODO: - [ ] Register TBTC on BASE using Portal on [Testnet](https://testnet.portal-bridge-ui.pages.dev/18c38dbb6a/#/register) and [Mainnet](https://www.portalbridge.com/#/register). After that replace the address in `BaseWormholeTBTC.json` under `external/base` ~and `external/goerliBase`~ with a newly registered token.
- Loading branch information
Showing
47 changed files
with
14,063 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
artifacts/ | ||
build/ | ||
cache/ | ||
deployments/ | ||
export/ | ||
hardhat-dependency-compiler/ | ||
typechain/ | ||
export.json |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
{ | ||
"root": true, | ||
"extends": ["@thesis-co"], | ||
"parserOptions": { | ||
"ecmaVersion": 2017, | ||
"sourceType": "module" | ||
}, | ||
"env": { | ||
"es6": true, | ||
"mocha": true | ||
}, | ||
"rules": { | ||
"new-cap": "off", | ||
"import/no-extraneous-dependencies": "off", | ||
"@typescript-eslint/no-use-before-define": "off", | ||
"no-plusplus": ["error", { "allowForLoopAfterthoughts": true }] | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
# Hardhat | ||
/artifacts/ | ||
/build/ | ||
/cache/ | ||
/export/ | ||
/external/npm | ||
/typechain/ | ||
/export.json | ||
/deployments/* | ||
!/deployments/mainnet/ | ||
!/deployments/base/ | ||
!/deployments/baseGoerli/ | ||
|
||
# OZ | ||
/.openzeppelin/unknown-*.json |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
{ | ||
"require": "ts-node/register/files" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
.openzeppelin/ | ||
artifacts/ | ||
build/ | ||
cache/ | ||
deployments/ | ||
export/ | ||
hardhat-dependency-compiler/ | ||
typechain/ | ||
export.json |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
module.exports = { | ||
...require("@thesis-co/prettier-config"), | ||
overrides: [ | ||
{ | ||
files: "*.sol", | ||
options: { | ||
tabWidth: 4, | ||
}, | ||
}, | ||
], | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
{ | ||
"extends": "keep", | ||
"plugins": [], | ||
"rules": { | ||
"func-visibility": ["error", { "ignoreConstructors": true }] | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
hardhat-dependency-compiler/ | ||
node_modules/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
node_modules/@thesis-co/eslint-config/.tsconfig-eslint.json |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
:toc: macro | ||
|
||
= Threshold cross-chain - Base | ||
|
||
This package brings Bitcoin to Ethereum L2 Base. For more details please | ||
see link:https://github.com/keep-network/tbtc-v2/blob/main/docs/rfc/rfc-8.adoc[RFC 8: Cross-chain Tokenized Threshold BTC] | ||
|
||
== How it works? | ||
|
||
``` | ||
+----------------------------+ +-------------------------------------------------------------------+ | ||
| Ethereum | | Base | | ||
| | | | | ||
| +----------------------+ | | +----------------------+ +---------------------+ +----------+ | | ||
| | Wormhole TokenBridge |--|---------|--| Wormhole TokenBridge |--| BaseWormholeGateway |--| BaseTBTC | | | ||
| +----------------------+ | | +----------------------+ +---------------------+ +----------+ | | ||
| | | | | ||
+----------------------------+ +-------------------------------------------------------------------+ | ||
``` | ||
|
||
- `BaseTBTC` canonical tBTC token on Base with a minting authority | ||
delegated to `BaseWormholeGateway`. | ||
- `BaseWormholeGateway` is a smart contract wrapping and unwrapping | ||
Wormhole-specific tBTC representation into the canonical `BaseTBTC` token. | ||
|
||
=== Updating Wormhole Gateway mapping | ||
|
||
The deployment scripts are responsible for managing updates of the tBTC gateway | ||
addresses across various chains. These addresses are stored in the `external/` | ||
directory for a specific network. | ||
It is important to note that these addresses should remain constant for the | ||
mainnet network. However, there may be instances where a new version of a | ||
cross-chain module is deployed to the testing network, which would require a | ||
manual update of the corresponding address. | ||
|
||
=== Deploy contracts | ||
|
||
To deploy all contracts on the given network, please run: | ||
``` | ||
yarn deploy --network <network> | ||
``` | ||
|
||
Supported networks: | ||
- `hardhat` - for local development | ||
- `baseGoerli` - L2 testing network | ||
- `base` - L2 mainnet | ||
|
||
Currently, this module does not deploy any contracts on L1. All the existing | ||
Wormhole contract addresses that are used in this module are stored under | ||
`external/<network>` dir. | ||
|
||
If contracts haven't been built yet or changes occurred, `deploy` task will build | ||
the contracts before running the deployment script. This command produces | ||
an `export.json` file containing contract deployment info. Note that for the | ||
chains other than `hardhat` the following environment variables are needed: | ||
|
||
- `L2_CHAIN_API_URL` - URL to access blockchain services, e.g. `https://goerli.base.org` | ||
- `L2_ACCOUNTS_PRIVATE_KEYS` - Private keys for the deployer and council `<0xOwnerPrivKey,0xCouncilPrivKey>` | ||
- `BASESCAN_API_KEY` - Base Etherscan API key |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
// SPDX-License-Identifier: GPL-3.0-only | ||
|
||
pragma solidity ^0.8.17; | ||
|
||
import "@keep-network/tbtc-v2/contracts/l2/L2TBTC.sol"; | ||
|
||
/// @notice Canonical tBTC Token on Base - upgraded version. | ||
/// @dev This contract is intended solely for testing purposes. As it currently | ||
/// stands in the implementation of L2TBTC.sol, there are no reserved | ||
/// storage gap slots available, thereby limiting the upgradability to a | ||
/// child contract only. | ||
contract BaseTBTCUpgraded is L2TBTC { | ||
string public newVar; | ||
|
||
function initializeV2(string memory _newVar) public { | ||
newVar = _newVar; | ||
} | ||
} |
18 changes: 18 additions & 0 deletions
18
cross-chain/base/contracts/test/BaseWormholeGatewayUpgraded.sol
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
// SPDX-License-Identifier: GPL-3.0-only | ||
|
||
pragma solidity ^0.8.17; | ||
|
||
import "@keep-network/tbtc-v2/contracts/l2/L2WormholeGateway.sol"; | ||
|
||
/// @notice Wormhole gateway for L2 Base - upgraded version. | ||
/// @dev This contract is intended solely for testing purposes. As it currently | ||
/// stands in the implementation of L2WormholeGateway.sol, there are no | ||
/// reserved storage gap slots available, thereby limiting the upgradability | ||
/// to a child contract only. | ||
contract BaseWormholeGatewayUpgraded is L2WormholeGateway { | ||
string public newVar; | ||
|
||
function initializeV2(string memory _newVar) public { | ||
newVar = _newVar; | ||
} | ||
} |
28 changes: 28 additions & 0 deletions
28
cross-chain/base/deploy_l2/00_resolve_arbitrum_wormhole_gateway.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
import type { HardhatRuntimeEnvironment } from "hardhat/types" | ||
import type { DeployFunction } from "hardhat-deploy/types" | ||
|
||
const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { | ||
const { helpers, deployments } = hre | ||
const { log } = deployments | ||
|
||
const ArbitrumWormholeGateway = await deployments.getOrNull( | ||
"ArbitrumWormholeGateway" | ||
) | ||
|
||
if ( | ||
ArbitrumWormholeGateway && | ||
helpers.address.isValid(ArbitrumWormholeGateway.address) | ||
) { | ||
log( | ||
`using existing ArbitrumWormholeGateway at ${ArbitrumWormholeGateway.address}` | ||
) | ||
} else if (hre.network.name === "hardhat") { | ||
log("using fake ArbitrumWormholeGateway for hardhat network") | ||
} else { | ||
throw new Error("deployed ArbitrumWormholeGateway contract not found") | ||
} | ||
} | ||
|
||
export default func | ||
|
||
func.tags = ["ArbitrumWormholeGateway"] |
21 changes: 21 additions & 0 deletions
21
cross-chain/base/deploy_l2/00_resolve_base_token_bridge.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
import type { HardhatRuntimeEnvironment } from "hardhat/types" | ||
import type { DeployFunction } from "hardhat-deploy/types" | ||
|
||
const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { | ||
const { helpers, deployments } = hre | ||
const { log } = deployments | ||
|
||
const BaseTokenBridge = await deployments.getOrNull("BaseTokenBridge") | ||
|
||
if (BaseTokenBridge && helpers.address.isValid(BaseTokenBridge.address)) { | ||
log(`using existing Base TokenBridge at ${BaseTokenBridge.address}`) | ||
} else if (hre.network.name === "hardhat") { | ||
log("using fake Base TokenBridge for hardhat network") | ||
} else { | ||
throw new Error("deployed Base TokenBridge contract not found") | ||
} | ||
} | ||
|
||
export default func | ||
|
||
func.tags = ["BaseTokenBridge"] |
21 changes: 21 additions & 0 deletions
21
cross-chain/base/deploy_l2/00_resolve_base_wormhole_tbtc.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
import type { HardhatRuntimeEnvironment } from "hardhat/types" | ||
import type { DeployFunction } from "hardhat-deploy/types" | ||
|
||
const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { | ||
const { helpers, deployments } = hre | ||
const { log } = deployments | ||
|
||
const BaseWormholeTBTC = await deployments.getOrNull("BaseWormholeTBTC") | ||
|
||
if (BaseWormholeTBTC && helpers.address.isValid(BaseWormholeTBTC.address)) { | ||
log(`using existing Base WormholeTBTC at ${BaseWormholeTBTC.address}`) | ||
} else if (hre.network.name === "hardhat") { | ||
log("using fake Base WormholeTBTC for hardhat network") | ||
} else { | ||
throw new Error("deployed Base WormholeTBTC contract not found") | ||
} | ||
} | ||
|
||
export default func | ||
|
||
func.tags = ["BaseWormholeTBTC"] |
28 changes: 28 additions & 0 deletions
28
cross-chain/base/deploy_l2/00_resolve_optimism_wormhole_gateway.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
import type { HardhatRuntimeEnvironment } from "hardhat/types" | ||
import type { DeployFunction } from "hardhat-deploy/types" | ||
|
||
const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { | ||
const { helpers, deployments } = hre | ||
const { log } = deployments | ||
|
||
const OptimismWormholeGateway = await deployments.getOrNull( | ||
"OptimismWormholeGateway" | ||
) | ||
|
||
if ( | ||
OptimismWormholeGateway && | ||
helpers.address.isValid(OptimismWormholeGateway.address) | ||
) { | ||
log( | ||
`using existing OptimismWormholeGateway at ${OptimismWormholeGateway.address}` | ||
) | ||
} else if (hre.network.name === "hardhat") { | ||
log("using fake OptimismWormholeGateway for hardhat network") | ||
} else { | ||
throw new Error("deployed OptimismWormholeGateway contract not found") | ||
} | ||
} | ||
|
||
export default func | ||
|
||
func.tags = ["OptimismWormholeGateway"] |
28 changes: 28 additions & 0 deletions
28
cross-chain/base/deploy_l2/00_resolve_polygon_wormhole_gateway.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
import type { HardhatRuntimeEnvironment } from "hardhat/types" | ||
import type { DeployFunction } from "hardhat-deploy/types" | ||
|
||
const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { | ||
const { helpers, deployments } = hre | ||
const { log } = deployments | ||
|
||
const PolygonWormholeGateway = await deployments.getOrNull( | ||
"PolygonWormholeGateway" | ||
) | ||
|
||
if ( | ||
PolygonWormholeGateway && | ||
helpers.address.isValid(PolygonWormholeGateway.address) | ||
) { | ||
log( | ||
`using existing PolygonWormholeGateway at ${PolygonWormholeGateway.address}` | ||
) | ||
} else if (hre.network.name === "hardhat") { | ||
log("using fake PolygonWormholeGateway for hardhat network") | ||
} else { | ||
throw new Error("deployed PolygonWormholeGateway contract not found") | ||
} | ||
} | ||
|
||
export default func | ||
|
||
func.tags = ["PolygonWormholeGateway"] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
import type { HardhatRuntimeEnvironment } from "hardhat/types" | ||
import type { DeployFunction } from "hardhat-deploy/types" | ||
|
||
const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { | ||
const { ethers, getNamedAccounts, helpers } = hre | ||
const { deployer } = await getNamedAccounts() | ||
|
||
const [, proxyDeployment] = await helpers.upgrades.deployProxy("BaseTBTC", { | ||
contractName: "@keep-network/tbtc-v2/contracts/l2/L2TBTC.sol:L2TBTC", | ||
initializerArgs: ["Base tBTC v2", "tBTC"], | ||
factoryOpts: { signer: await ethers.getSigner(deployer) }, | ||
proxyOpts: { | ||
kind: "transparent", | ||
}, | ||
}) | ||
|
||
// TODO: Investigate the possibility of adding Tenderly verification for | ||
// L2 and upgradable proxy. | ||
|
||
// Contracts can be verified on L2 Base Etherscan in a similar way as we | ||
// do it on L1 Etherscan | ||
if (hre.network.tags.basescan) { | ||
// We use `verify` instead of `verify:verify` as the `verify` task is defined | ||
// in "@openzeppelin/hardhat-upgrades" to verify the proxy’s implementation | ||
// contract, the proxy itself and any proxy-related contracts, as well as | ||
// link the proxy to the implementation contract’s ABI on (Ether)scan. | ||
await hre.run("verify", { | ||
address: proxyDeployment.address, | ||
constructorArgsParams: proxyDeployment.args, | ||
}) | ||
} | ||
} | ||
|
||
export default func | ||
|
||
func.tags = ["BaseTBTC"] |
Oops, something went wrong.