Skip to content

Commit

Permalink
EPROD-1030 deploy BTC ERC20 on BTC bridge deploy (#168)
Browse files Browse the repository at this point in the history
  • Loading branch information
veeso authored Oct 3, 2024
1 parent 76a01e0 commit 8d383da
Show file tree
Hide file tree
Showing 24 changed files with 715 additions and 361 deletions.
2 changes: 1 addition & 1 deletion solidity/.env.sample
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
# Deployer account
PRIVATE_KEY=
PRIVATE_KEY="ac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80"
12 changes: 12 additions & 0 deletions solidity/.prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"singleQuote": true,
"trailingComma": "all",
"overrides": [
{
"files": ["*.ts", "*.tsx"],
"options": {
"parser": "typescript"
}
}
]
}
51 changes: 23 additions & 28 deletions solidity/hardhat.config.ts
Original file line number Diff line number Diff line change
@@ -1,59 +1,54 @@

import { HardhatUserConfig } from "hardhat/config";
import "@nomicfoundation/hardhat-toolbox";
import "@nomicfoundation/hardhat-foundry";
import "@openzeppelin/hardhat-upgrades";
import { HardhatUserConfig } from 'hardhat/config';
import '@nomicfoundation/hardhat-toolbox';
import '@nomicfoundation/hardhat-foundry';
import '@openzeppelin/hardhat-upgrades';
import * as dotenv from 'dotenv';
dotenv.config();


/// Tasks that are used to interact with the BFT contract
import "./tasks/deploy-bft";
import "./tasks/fee-charge-address";
import "./tasks/deploy-fee-charge";
import "./tasks/deploy-wrapped-token-deployer";
import "./tasks/upgrade-bft";
import "./tasks/pause-unpause";

import './tasks/deploy-bft';
import './tasks/fee-charge-address';
import './tasks/deploy-fee-charge';
import './tasks/deploy-wrapped-token';
import './tasks/deploy-wrapped-token-deployer';
import './tasks/upgrade-bft';
import './tasks/pause-unpause';

const MAINNET_URL = "https://mainnet.bitfinity.network"
const MAINNET_URL = 'https://mainnet.bitfinity.network';

const TESTNET_URL = "https://testnet.bitfinity.network"

const DEPLOYER_PRIVATE_KEY = process.env.PRIVATE_KEY || "";
const TESTNET_URL = 'https://testnet.bitfinity.network';

const DEPLOYER_PRIVATE_KEY = process.env.PRIVATE_KEY || '';

const config: HardhatUserConfig = {
networks: {
localhost: {
url: "http://127.0.0.1:8545",
accounts: [`0x${DEPLOYER_PRIVATE_KEY}`]
url: 'http://127.0.0.1:8545',
accounts: [`0x${DEPLOYER_PRIVATE_KEY}`],
},
mainnet: {
url: MAINNET_URL,
accounts: [`0x${DEPLOYER_PRIVATE_KEY}`]
accounts: [`0x${DEPLOYER_PRIVATE_KEY}`],
},
testnet: {
url: TESTNET_URL,
accounts: [`0x${DEPLOYER_PRIVATE_KEY}`]
}
accounts: [`0x${DEPLOYER_PRIVATE_KEY}`],
},
},
solidity: {
version: '0.8.25',
settings: {
optimizer: {
enabled: true,
runs: 200
runs: 200,
},
outputSelection: {
'*': {
'*': ['storageLayout'],
},
},
}
}
}


},
},
};

export default config;
34 changes: 24 additions & 10 deletions solidity/hardhat.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,28 +4,36 @@ This document provides comprehensive information about the Hardhat tasks availab

## Table of Contents

1. [Setup](#setup)
2. [Available Tasks](#available-tasks)
3. [BFT Contract Upgrade Process](#bft-contract-upgrade-process)
- [OpenZeppelin UUPS Proxy Pattern](#openzeppelin-uups-proxy-pattern)
- [Upgrade Methods](#upgrade-methods)
- [Upgrade Considerations](#upgrade-considerations)
4. [Usage Examples](#usage-examples)
5. [Best Practices and Notes](#best-practices-and-notes)
6. [Troubleshooting](#troubleshooting)
7. [Additional Resources](#additional-resources)
- [BitFusion SDK Hardhat Tasks and Contract Upgrade Guide](#bitfusion-sdk-hardhat-tasks-and-contract-upgrade-guide)
- [Table of Contents](#table-of-contents)
- [Setup](#setup)
- [Available Tasks](#available-tasks)
- [BFT Contract Upgrade Process](#bft-contract-upgrade-process)
- [OpenZeppelin UUPS Proxy Pattern](#openzeppelin-uups-proxy-pattern)
- [Upgrade Methods](#upgrade-methods)
- [Controlled Upgrade (Step-by-Step)](#controlled-upgrade-step-by-step)
- [One-Go Upgrade](#one-go-upgrade)
- [Upgrade Considerations](#upgrade-considerations)
- [Usage Examples](#usage-examples)
- [Best Practices and Notes](#best-practices-and-notes)
- [Troubleshooting](#troubleshooting)
- [Additional Resources](#additional-resources)

## Setup

1. Install Node.js and yarn.
2. Clone the repository and navigate to the project directory.
3. Install dependencies:

```sh
yarn install
```

4. Create a `.env` file in the root directory with your environment variables:

```env
PRIVATE_KEY=your_private_key
```

5. Configure your hardhat config file with appropriate network settings.

Expand All @@ -49,6 +57,12 @@ npx hardhat deploy-fee-charge --network <network> --bridges <bridge_addresses> [
npx hardhat deploy-wrapped-token-deployer --network <network>
```

- Deploy WrappedToken contract:

```bash
npx hardhat deploy-wrapped-token --network <network> --wrapped-token-deployer <address> --name <name> --symbol <symbol> --decimals <decimals> --owner <address>
```

- Compute Fee Charge Address:

```bash
Expand Down
12 changes: 7 additions & 5 deletions solidity/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
"test": "test"
},
"scripts": {
"prettier": "prettier --config .prettierrc --write \"tasks/**/*.ts\" \"hardhat.config.ts\"",
"test": "echo \"Error: no test specified\" && exit 1"
},
"repository": {
Expand Down Expand Up @@ -37,20 +38,21 @@
"@nomicfoundation/hardhat-toolbox": "^5.0.0",
"@nomicfoundation/hardhat-verify": "^2.0.0",
"@nomicfoundation/ignition-core": "^0.15.5",
"@openzeppelin/hardhat-upgrades": "^3.1.1",
"@typechain/ethers-v6": "^0.5.0",
"@typechain/hardhat": "^9.0.0",
"@types/chai": "^4.2.0",
"@types/mocha": ">=9.1.0",
"chai": "^4.2.0",
"dotenv": "^16.4.5",
"ethers": "^6.4.0",
"hardhat": "^2.22.5",
"hardhat-gas-reporter": "^1.0.8",
"prettier": "^3.3.3",
"solidity-coverage": "^0.8.1",
"ts-node": ">=8.0.0",
"typechain": "^8.3.0",
"typescript": ">=4.5.0",
"tsconfig-paths": "^4.2.0",
"@openzeppelin/hardhat-upgrades": "^3.1.1",
"dotenv": "^16.4.5"
"typechain": "^8.3.0",
"typescript": ">=4.5.0"
}
}
}
22 changes: 19 additions & 3 deletions solidity/src/WrappedTokenDeployer.sol
Original file line number Diff line number Diff line change
@@ -1,10 +1,18 @@
// SPDX-License-Identifier: MIT
pragma solidity >=0.5.0;

import "src/WrappedToken.sol";
import "src/interfaces/IWrappedTokenDeployer.sol";
import 'src/WrappedToken.sol';
import 'src/interfaces/IWrappedTokenDeployer.sol';

contract WrappedTokenDeployer is IWrappedTokenDeployer {
/// Event emitted when a new ERC20 compatible token is deployed.
event ERC20Deployed(
address indexed token,
string name,
string symbol,
uint8 decimals
);

/// Creates a new ERC20 compatible token contract and returns its address.
function deployERC20(
string memory name,
Expand All @@ -13,7 +21,15 @@ contract WrappedTokenDeployer is IWrappedTokenDeployer {
address owner
) external returns (address) {
// Create the new token
WrappedToken wrappedERC20 = new WrappedToken(name, symbol, decimals, owner);
WrappedToken wrappedERC20 = new WrappedToken(
name,
symbol,
decimals,
owner
);

emit ERC20Deployed(address(wrappedERC20), name, symbol, decimals);

return address(wrappedERC20);
}
}
56 changes: 35 additions & 21 deletions solidity/tasks/deploy-bft.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { task } from "hardhat/config";
import { boolean } from "hardhat/internal/core/params/argumentTypes";
import { HardhatRuntimeEnvironment } from "hardhat/types";
import { task } from 'hardhat/config';
import { boolean } from 'hardhat/internal/core/params/argumentTypes';
import { HardhatRuntimeEnvironment } from 'hardhat/types';

/// Deploys the BFT contract using the provided parameters.
///
Expand All @@ -15,27 +15,41 @@ import { HardhatRuntimeEnvironment } from "hardhat/types";
/// 4. Wait for the deployment to be confirmed.
/// 5. Log the deployed proxy address and implementation address.

task("deploy-bft", "Deploys the BFT contract")
.addParam("minterAddress", "The address of the minter")
.addParam("feeChargeAddress", "The address of the fee charge")
.addParam("wrappedTokenDeployerAddress", "The address of the wrapped token deployer")
.addParam("isWrappedSide", "Is the wrapped side", undefined, boolean)
.addOptionalParam("owner", "The owner of the contract")
.addOptionalParam("controllers", "The controllers of the contract")
task('deploy-bft', 'Deploys the BFT contract')
.addParam('minterAddress', 'The address of the minter')
.addParam('feeChargeAddress', 'The address of the fee charge')
.addParam(
'wrappedTokenDeployerAddress',
'The address of the wrapped token deployer',
)
.addParam('isWrappedSide', 'Is the wrapped side', undefined, boolean)
.addOptionalParam('owner', 'The owner of the contract')
.addOptionalParam('controllers', 'The controllers of the contract')
.setAction(
async (
{ minterAddress, feeChargeAddress, wrappedTokenDeployerAddress, isWrappedSide, owner, controllers },
{
minterAddress,
feeChargeAddress,
wrappedTokenDeployerAddress,
isWrappedSide,
owner,
controllers,
},
hre: HardhatRuntimeEnvironment,
) => {
console.log("Compiling contract");
await hre.run("compile");
console.log("Contract compiled");
console.log('Compiling contract');
await hre.run('compile');
console.log('Contract compiled');

let controllersArr = controllers ? controllers.split(",") : [];
let controllersArr = controllers ? controllers.split(',') : [];
let ownerAddress = owner || hre.ethers.ZeroAddress;

// Validate the arguments that it are addresses
const addressesToValidate = [minterAddress, feeChargeAddress, wrappedTokenDeployerAddress];
const addressesToValidate = [
minterAddress,
feeChargeAddress,
wrappedTokenDeployerAddress,
];
if (owner) addressesToValidate.push(ownerAddress);
if (controllers) addressesToValidate.push(...controllersArr);

Expand All @@ -46,15 +60,14 @@ task("deploy-bft", "Deploys the BFT contract")
}
}

console.log("Deploying BFT contract");
console.log('Deploying BFT contract');
const { network } = hre.hardhatArguments;

if (!network) {
throw new Error("Please specify a network");
throw new Error('Please specify a network');
}

const BFTBridge = await hre.ethers.getContractFactory("BFTBridge");

const BFTBridge = await hre.ethers.getContractFactory('BFTBridge');

const bridge = await hre.upgrades.deployProxy(BFTBridge, [
minterAddress,
Expand All @@ -72,7 +85,8 @@ task("deploy-bft", "Deploys the BFT contract")
const proxyAddress = await bridge.getAddress();

// Get implementation address
const implementationAddress = await hre.upgrades.erc1967.getImplementationAddress(proxyAddress);
const implementationAddress =
await hre.upgrades.erc1967.getImplementationAddress(proxyAddress);

console.log(`BFT deployed to: ${proxyAddress}`);
console.log(`Implementation deployed to: ${implementationAddress}`);
Expand Down
29 changes: 16 additions & 13 deletions solidity/tasks/deploy-fee-charge.ts
Original file line number Diff line number Diff line change
@@ -1,25 +1,25 @@
/// A task for deploying the fee charge contract

import { task } from "hardhat/config";
import { task } from 'hardhat/config';

task("deploy-fee-charge", "Deploys the fee charge contract")
.addParam("bridges", "The addresses of the bridges")
.addOptionalParam("expectedAddress", "The expected address of the fee charge")
task('deploy-fee-charge', 'Deploys the fee charge contract')
.addParam('bridges', 'The addresses of the bridges')
.addOptionalParam('expectedAddress', 'The expected address of the fee charge')
.setAction(async ({ bridges, expectedAddress }, hre) => {
const { network } = hre.hardhatArguments;

console.log("Compiling contract");
await hre.run("compile");
console.log("Contract compiled");
console.log('Compiling contract');
await hre.run('compile');
console.log('Contract compiled');

if (!network) {
throw new Error("Please specify a network");
throw new Error('Please specify a network');
}

let bridgesArr: string[] = bridges ? bridges.split(",") : [];
let bridgesArr: string[] = bridges ? bridges.split(',') : [];

if (bridgesArr.length === 0) {
throw new Error("Bridges must be a non-empty array of addresses");
throw new Error('Bridges must be a non-empty array of addresses');
}

// Validate the arguments that it is address
Expand All @@ -29,7 +29,7 @@ task("deploy-fee-charge", "Deploys the fee charge contract")
}
}

const FeeCharge = await hre.ethers.getContractFactory("FeeCharge");
const FeeCharge = await hre.ethers.getContractFactory('FeeCharge');
const feeCharge = await FeeCharge.deploy(bridgesArr);

// Wait for the deployment to be confirmed
Expand All @@ -39,12 +39,15 @@ task("deploy-fee-charge", "Deploys the fee charge contract")
const feeChargeAddress = await feeCharge.getAddress();

// Check if the fee charge address is as expected
if (expectedAddress !== undefined && feeChargeAddress.toLowerCase() !== expectedAddress.toLowerCase()) {
if (
expectedAddress !== undefined &&
feeChargeAddress.toLowerCase() !== expectedAddress.toLowerCase()
) {
console.error(
`Expected Address: ${expectedAddress} but got ${feeChargeAddress}`,
);

throw new Error("Fee charge address does not match the expected address");
throw new Error('Fee charge address does not match the expected address');
}

console.log(`Fee charge address: ${feeChargeAddress}`);
Expand Down
Loading

0 comments on commit 8d383da

Please sign in to comment.