302 lines
8.0 KiB
Markdown
302 lines
8.0 KiB
Markdown
# Reserve Backing Mechanism Documentation
|
|
|
|
**Date**: 2025-01-12
|
|
**Status**: Implementation Guide
|
|
**Purpose**: Legacy mainnet reserve-vault integration notes for official USDT/USDC custody and PMM mirror liquidity.
|
|
|
|
---
|
|
|
|
## Canonical taxonomy note
|
|
|
|
Chain 138 `c*` assets such as cUSDT and cUSDC are **GRU M1 eMoney / tokenized fiat instruments**, not Tether USDT or Circle USDC issuances and not generic stablecoins. Their primary backing model is the GRU reserve and attestation framework documented in `docs/04-configuration/CHAIN138_RWA_AND_TRANSPORT_ARCHITECTURE.md` and `docs/04-configuration/GRU_HUB_TOKEN_NAMING.md`.
|
|
|
|
This document covers the legacy `StablecoinReserveVault` integration surface for custody of **official third-party USDT/USDC** and mirror-liquidity workflows. Treat official USDT/USDC as quote-side / redemption assets, not as the legal identity of Chain 138 `c*` eMoney.
|
|
|
|
## Overview
|
|
|
|
The reserve-vault surface can custody official Tether USDT and Circle USDC tokens and expose operational checks for routes that exchange Chain 138 eMoney against those public issuer assets. It is not the canonical source of truth for GRU M1 issuance backing.
|
|
|
|
---
|
|
|
|
## Architecture
|
|
|
|
### Contract: StablecoinReserveVault
|
|
|
|
**Location**: `contracts/reserve/StablecoinReserveVault.sol`
|
|
|
|
**Purpose**:
|
|
- Lock official third-party USDT/USDC tokens for designated mirror-liquidity or redemption workflows
|
|
- Track vault balances and operational reserves for official-token custody
|
|
- Support controlled exchange workflows between Chain 138 eMoney and public issuer assets where policy permits
|
|
|
|
**Key Features**:
|
|
- Operational face-value accounting for official-token custody workflows
|
|
- Reserve tracking and verification
|
|
- Pause mechanism for emergencies
|
|
- Access control with role-based permissions
|
|
|
|
---
|
|
|
|
## Deployment
|
|
|
|
### Prerequisites
|
|
|
|
1. **Official Token Addresses** (Ethereum Mainnet):
|
|
- USDT: `0xdAC17F958D2ee523a2206206994597C13D831ec7`
|
|
- USDC: `0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48`
|
|
|
|
2. **Compliant Token Addresses** (Chain 138):
|
|
- cUSDT: `0x93E66202A11B1772E55407B32B44e5Cd8eda7f22`
|
|
- cUSDC: `0xf22258f57794CC8E06237084b353Ab30fFfa640b`
|
|
|
|
3. **Network Requirements**:
|
|
- Vault should be deployed on Ethereum Mainnet (or network with official tokens)
|
|
- Chain 138 cUSDT/cUSDC remain GRU M1 eMoney instruments; bridge and mirror workflows must preserve that taxonomy
|
|
|
|
### Deployment Steps
|
|
|
|
#### Step 1: Set Environment Variables
|
|
|
|
```bash
|
|
# In .env file
|
|
PRIVATE_KEY=0x...
|
|
ETH_MAINNET_RPC_URL=https://eth-mainnet.g.alchemy.com/v2/YOUR_KEY
|
|
|
|
# Official tokens (Ethereum Mainnet)
|
|
OFFICIAL_USDT_ADDRESS=0xdAC17F958D2ee523a2206206994597C13D831ec7
|
|
OFFICIAL_USDC_ADDRESS=0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48
|
|
|
|
# Compliant tokens (Chain 138)
|
|
COMPLIANT_USDT_ADDRESS=0x93E66202A11B1772E55407B32B44e5Cd8eda7f22
|
|
COMPLIANT_USDC_ADDRESS=0xf22258f57794CC8E06237084b353Ab30fFfa640b
|
|
|
|
# Admin address
|
|
RESERVE_VAULT_ADMIN=0x...
|
|
```
|
|
|
|
#### Step 2: Deploy Contract
|
|
|
|
```bash
|
|
cd smom-dbis-138
|
|
|
|
forge script script/reserve/DeployStablecoinReserveVault.s.sol:DeployStablecoinReserveVault \
|
|
--rpc-url $ETH_MAINNET_RPC_URL \
|
|
--broadcast \
|
|
--legacy \
|
|
--gas-price 30000000000 \
|
|
--via-ir \
|
|
-vv
|
|
|
|
# Save deployed address
|
|
export STABLECOIN_RESERVE_VAULT_ADDRESS=<deployed_address>
|
|
```
|
|
|
|
#### Step 3: Verify Deployment
|
|
|
|
```bash
|
|
# Check vault address
|
|
cast call $STABLECOIN_RESERVE_VAULT_ADDRESS "officialUSDT()" --rpc-url $ETH_MAINNET_RPC_URL
|
|
cast call $STABLECOIN_RESERVE_VAULT_ADDRESS "officialUSDC()" --rpc-url $ETH_MAINNET_RPC_URL
|
|
cast call $STABLECOIN_RESERVE_VAULT_ADDRESS "paused()" --rpc-url $ETH_MAINNET_RPC_URL
|
|
```
|
|
|
|
---
|
|
|
|
## Operations
|
|
|
|
### Deposit and Mint
|
|
|
|
Users can deposit official tokens and receive compliant tokens 1:1.
|
|
|
|
#### Deposit USDT → Mint cUSDT
|
|
|
|
```bash
|
|
# 1. Approve USDT to vault
|
|
cast send $OFFICIAL_USDT_ADDRESS \
|
|
"approve(address,uint256)" \
|
|
$STABLECOIN_RESERVE_VAULT_ADDRESS \
|
|
1000000000000 \
|
|
--rpc-url $ETH_MAINNET_RPC_URL \
|
|
--private-key $PRIVATE_KEY \
|
|
--gas-price 30000000000 \
|
|
--legacy
|
|
|
|
# 2. Deposit USDT (amount in base units with 6 decimals)
|
|
# Example: 1,000,000 USDT = 1000000000000 (1e12)
|
|
cast send $STABLECOIN_RESERVE_VAULT_ADDRESS \
|
|
"depositUSDT(uint256)" \
|
|
1000000000000 \
|
|
--rpc-url $ETH_MAINNET_RPC_URL \
|
|
--private-key $PRIVATE_KEY \
|
|
--gas-price 30000000000 \
|
|
--legacy
|
|
```
|
|
|
|
#### Deposit USDC → Mint cUSDC
|
|
|
|
Similar process for USDC:
|
|
|
|
```bash
|
|
# Approve and deposit
|
|
cast send $OFFICIAL_USDC_ADDRESS \
|
|
"approve(address,uint256)" \
|
|
$STABLECOIN_RESERVE_VAULT_ADDRESS \
|
|
1000000000000 \
|
|
--rpc-url $ETH_MAINNET_RPC_URL \
|
|
--private-key $PRIVATE_KEY \
|
|
--gas-price 30000000000 \
|
|
--legacy
|
|
|
|
cast send $STABLECOIN_RESERVE_VAULT_ADDRESS \
|
|
"depositUSDC(uint256)" \
|
|
1000000000000 \
|
|
--rpc-url $ETH_MAINNET_RPC_URL \
|
|
--private-key $PRIVATE_KEY \
|
|
--gas-price 30000000000 \
|
|
--legacy
|
|
```
|
|
|
|
### Redemption
|
|
|
|
Users can redeem compliant tokens for official tokens 1:1.
|
|
|
|
#### Redeem cUSDT → Receive USDT
|
|
|
|
```bash
|
|
cast send $STABLECOIN_RESERVE_VAULT_ADDRESS \
|
|
"redeemUSDT(uint256)" \
|
|
1000000000000 \
|
|
--rpc-url $ETH_MAINNET_RPC_URL \
|
|
--private-key $PRIVATE_KEY \
|
|
--gas-price 30000000000 \
|
|
--legacy
|
|
```
|
|
|
|
#### Redeem cUSDC → Receive USDC
|
|
|
|
```bash
|
|
cast send $STABLECOIN_RESERVE_VAULT_ADDRESS \
|
|
"redeemUSDC(uint256)" \
|
|
1000000000000 \
|
|
--rpc-url $ETH_MAINNET_RPC_URL \
|
|
--private-key $PRIVATE_KEY \
|
|
--gas-price 30000000000 \
|
|
--legacy
|
|
```
|
|
|
|
### Verification
|
|
|
|
#### Check Reserve Balances
|
|
|
|
```bash
|
|
# USDT reserve
|
|
cast call $STABLECOIN_RESERVE_VAULT_ADDRESS "usdtReserveBalance()" --rpc-url $ETH_MAINNET_RPC_URL | cast --to-dec
|
|
|
|
# USDC reserve
|
|
cast call $STABLECOIN_RESERVE_VAULT_ADDRESS "usdcReserveBalance()" --rpc-url $ETH_MAINNET_RPC_URL | cast --to-dec
|
|
```
|
|
|
|
#### Check Backing Ratio
|
|
|
|
```bash
|
|
# For cUSDT
|
|
cast call $STABLECOIN_RESERVE_VAULT_ADDRESS \
|
|
"getBackingRatio(address)" \
|
|
$COMPLIANT_USDT_ADDRESS \
|
|
--rpc-url $ETH_MAINNET_RPC_URL
|
|
|
|
# Returns: (reserveBalance, tokenSupply, backingRatio)
|
|
# backingRatio = 10000 means 100% backed
|
|
```
|
|
|
|
#### Check Reserve Adequacy
|
|
|
|
```bash
|
|
cast call $STABLECOIN_RESERVE_VAULT_ADDRESS "checkReserveAdequacy()" --rpc-url $ETH_MAINNET_RPC_URL
|
|
```
|
|
|
|
---
|
|
|
|
## Access Control
|
|
|
|
### Roles
|
|
|
|
- **DEFAULT_ADMIN_ROLE**: Can pause/unpause, emergency withdraw
|
|
- **RESERVE_OPERATOR_ROLE**: Can manage reserves (currently same as admin)
|
|
- **REDEMPTION_OPERATOR_ROLE**: Can process redemptions (currently same as admin)
|
|
|
|
### Pause Mechanism
|
|
|
|
```bash
|
|
# Pause all operations
|
|
cast send $STABLECOIN_RESERVE_VAULT_ADDRESS \
|
|
"pause()" \
|
|
--rpc-url $ETH_MAINNET_RPC_URL \
|
|
--private-key $PRIVATE_KEY \
|
|
--gas-price 30000000000 \
|
|
--legacy
|
|
|
|
# Unpause
|
|
cast send $STABLECOIN_RESERVE_VAULT_ADDRESS \
|
|
"unpause()" \
|
|
--rpc-url $ETH_MAINNET_RPC_URL \
|
|
--private-key $PRIVATE_KEY \
|
|
--gas-price 30000000000 \
|
|
--legacy
|
|
```
|
|
|
|
### Emergency Withdrawal
|
|
|
|
```bash
|
|
# Can only be called when paused
|
|
cast send $STABLECOIN_RESERVE_VAULT_ADDRESS \
|
|
"emergencyWithdraw(address,uint256,address)" \
|
|
$OFFICIAL_USDT_ADDRESS \
|
|
<amount> \
|
|
<recipient> \
|
|
--rpc-url $ETH_MAINNET_RPC_URL \
|
|
--private-key $PRIVATE_KEY \
|
|
--gas-price 30000000000 \
|
|
--legacy
|
|
```
|
|
|
|
---
|
|
|
|
## Security Considerations
|
|
|
|
1. **1:1 Backing**: Always maintain reserves >= token supply
|
|
2. **Access Control**: Use multi-sig for admin role in production
|
|
3. **Pause Mechanism**: Test pause/unpause functionality
|
|
4. **Emergency Procedures**: Have emergency withdrawal plan
|
|
5. **Audit**: Conduct security audit before mainnet deployment
|
|
6. **Monitoring**: Monitor reserve balances and backing ratios
|
|
|
|
---
|
|
|
|
## Integration with Cross-Chain Bridge
|
|
|
|
For Chain 138 deployment, integrate with cross-chain bridge:
|
|
|
|
1. Deploy vault on Ethereum Mainnet
|
|
2. Connect to Chain 138 via bridge (CCIP or custom bridge)
|
|
3. Bridge operations:
|
|
- Lock official tokens on Mainnet → Mint cUSDT/cUSDC on Chain 138
|
|
- Burn cUSDT/cUSDC on Chain 138 → Unlock official tokens on Mainnet
|
|
|
|
---
|
|
|
|
## Example Usage Script
|
|
|
|
See `scripts/setup-reserve-vault.sh` for automated setup and verification.
|
|
|
|
---
|
|
|
|
## Next Steps
|
|
|
|
1. Deploy vault contract
|
|
2. Fund with initial reserves
|
|
3. Enable deposits
|
|
4. Monitor backing ratios
|
|
5. Integrate with DODO PMM pools for exchangeability
|
|
|