-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(btc-staking): UTXOGateway and BTC staking test (#132)
* feat: UTXOGateway for btc staking and testing * chore: fix solhint
- Loading branch information
Showing
87 changed files
with
7,316 additions
and
5,239 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
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
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 |
---|---|---|
|
@@ -28,3 +28,4 @@ node_modules | |
.secrets | ||
|
||
script/integration/*.json | ||
yarn-error.log |
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
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,127 @@ | ||
# ClientChainGateway Documentation | ||
|
||
The ClientChainGateway serves as the primary interface for stakers to interact with the Exocore network. It functions as a LayerZero application capable of cross-chain messaging and manages both Vault and Capsule contracts. | ||
|
||
## Overview | ||
|
||
ClientChainGateway implements two types of restaking: | ||
1. LST (Liquid Staking Token) Restaking | ||
2. NST (Native Staking Token) Restaking | ||
|
||
## LST Restaking Functions | ||
|
||
### Deposit Operations | ||
- `deposit(address token, uint256 amount)` | ||
- Deposits whitelisted tokens into Exocore | ||
- Locks tokens in a Vault contract | ||
- Sends cross-chain message to Exocore for accounting | ||
- Always considered successful on Exocore side | ||
- Requires relay fee in ETH for cross-chain message | ||
|
||
- `depositThenDelegateTo(address token, uint256 amount, string operator)` | ||
- Combines deposit and delegate operations | ||
- Deposits tokens and immediately delegates to specified operator | ||
- More gas-efficient than separate calls | ||
- Delegation can fail if operator is not registered | ||
- Requires relay fee in ETH for cross-chain message | ||
|
||
### Delegation Operations | ||
- `delegateTo(string operator, address token, uint256 amount)` | ||
- Delegates previously deposited tokens to an operator | ||
- Requires prior deposit | ||
- Sends cross-chain message to Exocore | ||
- Updates delegation accounting on Exocore | ||
- Requires relay fee in ETH for cross-chain message | ||
|
||
- `undelegateFrom(string operator, address token, uint256 amount)` | ||
- Undelegates tokens from an operator | ||
- Requires prior delegation | ||
- Sends cross-chain message to Exocore | ||
- Initiates unbonding period | ||
- Requires relay fee in ETH for cross-chain message | ||
|
||
### Withdrawal Operations | ||
- `claimPrincipalFromExocore(address token, uint256 principalAmount)` | ||
- Initiates withdrawal process from Exocore | ||
- Sends cross-chain message to Exocore | ||
- Awaits response to unlock balance in Vault | ||
- Does not transfer tokens to user | ||
- Requires relay fee in ETH for cross-chain message | ||
|
||
- `withdrawPrincipal(address token, uint256 amount, address recipient)` | ||
- Transfers unlocked tokens from Vault to recipient | ||
- Must be called after successful `claimPrincipalFromExocore` | ||
- No cross-chain message required | ||
- Direct transfer from Vault | ||
- No relay fee needed | ||
|
||
## NST Restaking Functions | ||
|
||
### Setup Operations | ||
- `createExoCapsule()` | ||
- Creates Capsule contract for staker | ||
- Used as withdrawal credentials | ||
- Required before staking to beacon chain | ||
- Returns capsule address | ||
- No relay fee needed | ||
|
||
- `stake(bytes pubkey, bytes signature, bytes32 depositDataRoot)` | ||
- Stakes ETH to Ethereum beacon chain | ||
- Creates validator with ExoCapsule as withdrawal credentials | ||
- Preparation step for NST restaking | ||
- Payable function accepting exactly 32 ETH for beacon chain staking | ||
- No relay fee needed | ||
|
||
### Deposit Operations | ||
- `verifyAndDepositNativeStake(bytes32[] validatorContainer, BeaconChainProofs.ValidatorContainerProof proof)` | ||
- Verifies beacon chain proof of withdrawal credentials | ||
- Confirms validator is using correct ExoCapsule | ||
- Sends message to Exocore to account for validator balance | ||
- Required for NST restaking activation | ||
- Requires relay fee in ETH for cross-chain message | ||
|
||
### Withdrawal Operations | ||
- `processBeaconChainWithdrawal(bytes32[] validatorContainer, BeaconChainProofs.ValidatorContainerProof validatorProof, bytes32[] withdrawalContainer, BeaconChainProofs.WithdrawalProof withdrawalProof)` | ||
- Processes beacon chain withdrawals | ||
- Verifies withdrawal proofs | ||
- Sends message to Exocore to unlock ETH in Capsule | ||
- Similar to `claimPrincipalFromExocore` for LSTs | ||
- Requires relay fee in ETH for cross-chain message | ||
|
||
- `withdrawNonBeaconChainETHFromCapsule(address payable recipient, uint256 amountToWithdraw)` | ||
- Withdraws non-beacon chain ETH from Capsule | ||
- For ETH not related to beacon chain staking | ||
- Direct transfer from Capsule | ||
- No relay fee needed | ||
|
||
## Common Workflows | ||
|
||
### LST Deposit and Delegate | ||
1. Call `deposit` or `depositThenDelegateTo` | ||
2. If using separate calls, wait for deposit confirmation | ||
3. Call `delegateTo` if needed | ||
4. Tokens are now staked and delegated on Exocore | ||
|
||
### LST Withdrawal | ||
1. Call `claimPrincipalFromExocore` | ||
2. Wait for cross-chain message confirmation | ||
3. Call `withdrawPrincipal` to receive tokens | ||
|
||
### NST Restaking | ||
1. Call `createExoCapsule` | ||
2. Call `stake` to become validator | ||
3. Call `verifyAndDepositNativeStake` with proofs | ||
4. ETH is now restaked on Exocore | ||
|
||
### NST Withdrawal | ||
1. Initiate withdrawal on beacon chain | ||
2. Call `processBeaconChainWithdrawal` with proofs | ||
3. ETH is unlocked in Capsule | ||
4. Use `withdrawNonBeaconChainETHFromCapsule` if needed | ||
|
||
## Notes | ||
- All cross-chain operations require LayerZero fees in ETH | ||
- `stake` function requires exactly 32 ETH for beacon chain staking | ||
- Other payable functions only accept ETH for relay fees | ||
- NST operations require valid beacon chain proofs | ||
- Delegation requires registered operators on Exocore |
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,153 @@ | ||
# BTC Staking E2E Testing Guide | ||
|
||
This guide walks through setting up and testing the BTC staking functionality in a local development environment. | ||
|
||
## Prerequisites | ||
|
||
- Docker and Docker Compose | ||
- Node.js (v16+) | ||
- npm or yarn | ||
- Git | ||
|
||
## Setup Steps | ||
|
||
### Start Bitcoin Regtest Node | ||
|
||
1. First, clone and set up the Esplora explorer: | ||
|
||
```bash | ||
git clone https://github.com/ExocoreNetwork/esplora.git | ||
cd esplora | ||
``` | ||
|
||
2. Start the Bitcoin regtest node, esplora, send test token to faucet and activate auto mining by running script: | ||
|
||
```bash | ||
./start-regtest.sh -h | ||
Start a Bitcoin regtest node with automatic mining and fund a predefined test faucet | ||
|
||
Usage: ./start-regtest.sh [amount_btc] [mining_interval_seconds] | ||
|
||
Arguments: | ||
amount_btc Amount of BTC to send to faucet (default: 100) | ||
mining_interval_seconds Block mining interval in seconds (default: 30) | ||
|
||
Faucet Information(only for regtest): | ||
Private Key: 0xee01cfc3f08cdb020064f31ff1a993aa9ecc1d38e684665742faa705685532a6 | ||
Address: bcrt1qvj7e5av2eqrhhvle56f9aqtjpxgywwnt5tem5y | ||
|
||
Example: | ||
./start-regtest.sh 50 60 | ||
``` | ||
|
||
NOTICE: Some amount of test BTC would be sent to the faucet address with known private key | ||
|
||
### Start Exocore Node | ||
|
||
1. Set up and start the Exocore node: | ||
|
||
```bash | ||
# Clone the repository | ||
git clone https://github.com/ExocoreNetwork/exocore.git | ||
cd exocore | ||
|
||
# Switch to develop branch | ||
git checkout develop | ||
|
||
# Start local node | ||
./local_node.sh | ||
``` | ||
|
||
### Deploy UTXO Gateway Contract | ||
|
||
1. Clone repo and set up the UTXO gateway contract: | ||
|
||
```bash | ||
git clone https://github.com/ExocoreNetwork/exocore-contracts.git | ||
cd exocore-contracts | ||
npm run deploy:utxogateway | ||
``` | ||
|
||
Before running the deployment command, please replace the URL path of `exocore_localnet` in `hardhat.config.js` with the URL path of your set up Exocore node, and also set the private key of the Exocore account in `hardhat.config.js` in your local `.env` file. We need at least 3 accounts (`deployer` == `faucet`, `owner` and `witness1`) to execute the deployment script. | ||
|
||
```javascript | ||
exocore_localnet: { | ||
url: "http://127.0.0.1:8545", | ||
chainId: 232, | ||
accounts: [ | ||
process.env.LOCAL_EXOCORE_FUNDED_ACCOUNT_PRIVATE_KEY, // Deployer/Faucet: Requires minimum 3 eth balance | ||
process.env.TEST_ACCOUNT_ONE_PRIVATE_KEY, // Owner: the owner of the UTXOGateway contract | ||
process.env.TEST_ACCOUNT_TWO_PRIVATE_KEY, // Witness1: the only witness for current implementation, also needed by bridge | ||
process.env.TEST_ACCOUNT_THREE_PRIVATE_KEY, | ||
process.env.TEST_ACCOUNT_FOUR_PRIVATE_KEY, | ||
process.env.TEST_ACCOUNT_FIVE_PRIVATE_KEY, | ||
process.env.TEST_ACCOUNT_SIX_PRIVATE_KEY, | ||
] | ||
} | ||
``` | ||
|
||
This would deploy UTXOGateway contract on exocore node and setup it: | ||
|
||
- set deployed contract as authorized gateway | ||
- set required proofs count | ||
- set authorized witness and transfer tokens to it as fee | ||
- activate BTC staking by registering Bitcoin chain and token | ||
|
||
The final output would be stored under `script/deployments/utxogateway.json` | ||
|
||
### Start UTXO Bridge | ||
|
||
1. Clone the UTXO bridge service: | ||
|
||
```bash | ||
# Clone the repository | ||
git clone https://github.com/ExocoreNetwork/utxo-restaking.git | ||
cd utxo-restaking | ||
git checkout btc-restaking-v2 | ||
``` | ||
|
||
2. Configure the bridge service with address of deployed UTXOGateway contract, witness address and its private key and other required parameters: | ||
|
||
```bash | ||
# Copy .env.example to .env and set the required variables | ||
cp .env.example .env | ||
``` | ||
|
||
```env | ||
BITCOIN_RPC // URL of the esplora API | ||
VAULT_ADDRESS // Address of the BTC vault | ||
MIN_CONFIRMATIONS // Minimum number of confirmations for a Bitcoin transaction | ||
EXOCORE_RPC // URL of the Exocore node | ||
CONTRACT_ADDRESS // Address of the UTXOGateway contract | ||
WITNESS_ADDRESS // Address of the witness | ||
WALLET_PRIV_KEY // Private key of the signing wallet, should be the same as the witness for current implementation | ||
``` | ||
|
||
NOTICE: We'd better set `MIN_CONFIRMATIONS` to 1 to avoid timeouts | ||
|
||
3. Start the bridge service: | ||
|
||
```bash | ||
# Start bridge services | ||
docker-compose up | ||
``` | ||
|
||
### Run E2E Tests | ||
|
||
1. Go back to the exocore-contracts directory and run the BTC staking E2E test: | ||
|
||
```bash | ||
npx hardhat test test/integration/btc-staking-e2e.test.js | ||
``` | ||
|
||
Before running the test, please configure the test environment variables in your local `.env` file with required parameters like the secret key of BTC faucet and others. | ||
|
||
```env | ||
BITCOIN_FAUCET_PRIVATE_KEY // Private key of the BTC faucet | ||
BITCOIN_ESPLORA_API_URL // URL of the esplora API | ||
BITCOIN_STAKER_PRIVATE_KEY // Private key of the staker | ||
BITCOIN_TX_FEE // Transaction fee for BTC deposit | ||
DUST_THRESHOLD // Dust threshold for BTC deposit | ||
``` | ||
|
||
This test would simulate the process of building a valid Bitcoin deposit transaction, broadcasting it to the Bitcoin network and waiting for it to be confirmed, and finally checking staker's balance on Exocore. |
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
Submodule create3-factory
added at
6b834a
Oops, something went wrong.