Files
smom-dbis-138/contracts/reserve/StablecoinReserveVault.sol
defiQUG 50ab378da9 feat: Implement Universal Cross-Chain Asset Hub - All phases complete
PRODUCTION-GRADE IMPLEMENTATION - All 7 Phases Done

This is a complete, production-ready implementation of an infinitely
extensible cross-chain asset hub that will never box you in architecturally.

## Implementation Summary

### Phase 1: Foundation 
- UniversalAssetRegistry: 10+ asset types with governance
- Asset Type Handlers: ERC20, GRU, ISO4217W, Security, Commodity
- GovernanceController: Hybrid timelock (1-7 days)
- TokenlistGovernanceSync: Auto-sync tokenlist.json

### Phase 2: Bridge Infrastructure 
- UniversalCCIPBridge: Main bridge (258 lines)
- GRUCCIPBridge: GRU layer conversions
- ISO4217WCCIPBridge: eMoney/CBDC compliance
- SecurityCCIPBridge: Accredited investor checks
- CommodityCCIPBridge: Certificate validation
- BridgeOrchestrator: Asset-type routing

### Phase 3: Liquidity Integration 
- LiquidityManager: Multi-provider orchestration
- DODOPMMProvider: DODO PMM wrapper
- PoolManager: Auto-pool creation

### Phase 4: Extensibility 
- PluginRegistry: Pluggable components
- ProxyFactory: UUPS/Beacon proxy deployment
- ConfigurationRegistry: Zero hardcoded addresses
- BridgeModuleRegistry: Pre/post hooks

### Phase 5: Vault Integration 
- VaultBridgeAdapter: Vault-bridge interface
- BridgeVaultExtension: Operation tracking

### Phase 6: Testing & Security 
- Integration tests: Full flows
- Security tests: Access control, reentrancy
- Fuzzing tests: Edge cases
- Audit preparation: AUDIT_SCOPE.md

### Phase 7: Documentation & Deployment 
- System architecture documentation
- Developer guides (adding new assets)
- Deployment scripts (5 phases)
- Deployment checklist

## Extensibility (Never Box In)

7 mechanisms to prevent architectural lock-in:
1. Plugin Architecture - Add asset types without core changes
2. Upgradeable Contracts - UUPS proxies
3. Registry-Based Config - No hardcoded addresses
4. Modular Bridges - Asset-specific contracts
5. Composable Compliance - Stackable modules
6. Multi-Source Liquidity - Pluggable providers
7. Event-Driven - Loose coupling

## Statistics

- Contracts: 30+ created (~5,000+ LOC)
- Asset Types: 10+ supported (infinitely extensible)
- Tests: 5+ files (integration, security, fuzzing)
- Documentation: 8+ files (architecture, guides, security)
- Deployment Scripts: 5 files
- Extensibility Mechanisms: 7

## Result

A future-proof system supporting:
- ANY asset type (tokens, GRU, eMoney, CBDCs, securities, commodities, RWAs)
- ANY chain (EVM + future non-EVM via CCIP)
- WITH governance (hybrid risk-based approval)
- WITH liquidity (PMM integrated)
- WITH compliance (built-in modules)
- WITHOUT architectural limitations

Add carbon credits, real estate, tokenized bonds, insurance products,
or any future asset class via plugins. No redesign ever needed.

Status: Ready for Testing → Audit → Production
2026-01-24 07:01:37 -08:00

254 lines
9.3 KiB
Solidity

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;
import "@openzeppelin/contracts/access/AccessControl.sol";
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import "@openzeppelin/contracts/utils/ReentrancyGuard.sol";
import "../tokens/CompliantUSDT.sol";
import "../tokens/CompliantUSDC.sol";
/**
* @title StablecoinReserveVault
* @notice 1:1 backing mechanism for CompliantUSDT and CompliantUSDC with official tokens
* @dev Locks official USDT/USDC, mints cUSDT/cUSDC 1:1. Can be deployed on Ethereum Mainnet
* or connected via cross-chain bridge to Chain 138 for minting.
*
* IMPORTANT: This contract should be deployed on Ethereum Mainnet where official USDT/USDC exist.
* For Chain 138 deployment, tokens would be bridged/locked via cross-chain infrastructure.
*/
contract StablecoinReserveVault is AccessControl, ReentrancyGuard {
using SafeERC20 for IERC20;
bytes32 public constant RESERVE_OPERATOR_ROLE = keccak256("RESERVE_OPERATOR_ROLE");
bytes32 public constant REDEMPTION_OPERATOR_ROLE = keccak256("REDEMPTION_OPERATOR_ROLE");
// Official token addresses on Ethereum Mainnet
// These can be overridden in constructor for different networks
address public immutable officialUSDT;
address public immutable officialUSDC;
// Compliant token contracts (on Chain 138 or same network)
CompliantUSDT public immutable compliantUSDT;
CompliantUSDC public immutable compliantUSDC;
// Reserve tracking
uint256 public usdtReserveBalance;
uint256 public usdcReserveBalance;
// Total minted (for verification)
uint256 public totalCUSDTMinted;
uint256 public totalCUSDCMinted;
// Pause mechanism
bool public paused;
event ReserveDeposited(address indexed token, uint256 amount, address indexed depositor);
event ReserveWithdrawn(address indexed token, uint256 amount, address indexed recipient);
event CompliantTokensMinted(address indexed token, uint256 amount, address indexed recipient);
event CompliantTokensBurned(address indexed token, uint256 amount, address indexed redeemer);
event Paused(address indexed account);
event Unpaused(address indexed account);
modifier whenNotPaused() {
require(!paused, "StablecoinReserveVault: paused");
_;
}
/**
* @notice Constructor
* @param admin Admin address (will receive DEFAULT_ADMIN_ROLE)
* @param officialUSDT_ Official USDT token address (on Ethereum Mainnet: 0xdAC17F958D2ee523a2206206994597C13D831ec7)
* @param officialUSDC_ Official USDC token address (on Ethereum Mainnet: 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48)
* @param compliantUSDT_ CompliantUSDT contract address
* @param compliantUSDC_ CompliantUSDC contract address
*/
constructor(
address admin,
address officialUSDT_,
address officialUSDC_,
address compliantUSDT_,
address compliantUSDC_
) {
require(admin != address(0), "StablecoinReserveVault: zero admin");
require(officialUSDT_ != address(0), "StablecoinReserveVault: zero USDT");
require(officialUSDC_ != address(0), "StablecoinReserveVault: zero USDC");
require(compliantUSDT_ != address(0), "StablecoinReserveVault: zero cUSDT");
require(compliantUSDC_ != address(0), "StablecoinReserveVault: zero cUSDC");
_grantRole(DEFAULT_ADMIN_ROLE, admin);
_grantRole(RESERVE_OPERATOR_ROLE, admin);
_grantRole(REDEMPTION_OPERATOR_ROLE, admin);
officialUSDT = officialUSDT_;
officialUSDC = officialUSDC_;
compliantUSDT = CompliantUSDT(compliantUSDT_);
compliantUSDC = CompliantUSDC(compliantUSDC_);
}
/**
* @notice Deposit official USDT and mint cUSDT 1:1
* @dev Transfers USDT from caller, mints cUSDT to caller
* @param amount Amount of USDT to deposit (6 decimals)
*/
function depositUSDT(uint256 amount) external whenNotPaused nonReentrant {
require(amount > 0, "StablecoinReserveVault: zero amount");
// Transfer official USDT from caller
IERC20(officialUSDT).safeTransferFrom(msg.sender, address(this), amount);
// Update reserve
usdtReserveBalance += amount;
totalCUSDTMinted += amount;
// Mint cUSDT to caller
compliantUSDT.mint(msg.sender, amount);
emit ReserveDeposited(officialUSDT, amount, msg.sender);
emit CompliantTokensMinted(address(compliantUSDT), amount, msg.sender);
}
/**
* @notice Deposit official USDC and mint cUSDC 1:1
* @dev Transfers USDC from caller, mints cUSDC to caller
* @param amount Amount of USDC to deposit (6 decimals)
*/
function depositUSDC(uint256 amount) external whenNotPaused nonReentrant {
require(amount > 0, "StablecoinReserveVault: zero amount");
// Transfer official USDC from caller
IERC20(officialUSDC).safeTransferFrom(msg.sender, address(this), amount);
// Update reserve
usdcReserveBalance += amount;
totalCUSDCMinted += amount;
// Mint cUSDC to caller
compliantUSDC.mint(msg.sender, amount);
emit ReserveDeposited(officialUSDC, amount, msg.sender);
emit CompliantTokensMinted(address(compliantUSDC), amount, msg.sender);
}
/**
* @notice Redeem cUSDT for official USDT 1:1
* @dev Burns cUSDT from caller, transfers USDT to caller
* @param amount Amount of cUSDT to redeem (6 decimals)
*/
function redeemUSDT(uint256 amount) external whenNotPaused nonReentrant {
require(amount > 0, "StablecoinReserveVault: zero amount");
require(usdtReserveBalance >= amount, "StablecoinReserveVault: insufficient reserve");
// Burn cUSDT from caller
compliantUSDT.burn(amount);
// Update reserve
usdtReserveBalance -= amount;
totalCUSDTMinted -= amount;
// Transfer official USDT to caller
IERC20(officialUSDT).safeTransfer(msg.sender, amount);
emit CompliantTokensBurned(address(compliantUSDT), amount, msg.sender);
emit ReserveWithdrawn(officialUSDT, amount, msg.sender);
}
/**
* @notice Redeem cUSDC for official USDC 1:1
* @dev Burns cUSDC from caller, transfers USDC to caller
* @param amount Amount of cUSDC to redeem (6 decimals)
*/
function redeemUSDC(uint256 amount) external whenNotPaused nonReentrant {
require(amount > 0, "StablecoinReserveVault: zero amount");
require(usdcReserveBalance >= amount, "StablecoinReserveVault: insufficient reserve");
// Burn cUSDC from caller
compliantUSDC.burn(amount);
// Update reserve
usdcReserveBalance -= amount;
totalCUSDCMinted -= amount;
// Transfer official USDC to caller
IERC20(officialUSDC).safeTransfer(msg.sender, amount);
emit CompliantTokensBurned(address(compliantUSDC), amount, msg.sender);
emit ReserveWithdrawn(officialUSDC, amount, msg.sender);
}
/**
* @notice Get reserve backing ratio
* @param token Address of compliant token (cUSDT or cUSDC)
* @return reserveBalance Current reserve balance
* @return tokenSupply Current token supply
* @return backingRatio Backing ratio (10000 = 100%)
*/
function getBackingRatio(address token) external view returns (
uint256 reserveBalance,
uint256 tokenSupply,
uint256 backingRatio
) {
if (token == address(compliantUSDT)) {
reserveBalance = usdtReserveBalance;
tokenSupply = compliantUSDT.totalSupply();
} else if (token == address(compliantUSDC)) {
reserveBalance = usdcReserveBalance;
tokenSupply = compliantUSDC.totalSupply();
} else {
revert("StablecoinReserveVault: unsupported token");
}
backingRatio = tokenSupply > 0
? (reserveBalance * 10000) / tokenSupply
: 0;
}
/**
* @notice Check if reserves are adequate
* @return usdtAdequate True if USDT reserves are adequate
* @return usdcAdequate True if USDC reserves are adequate
*/
function checkReserveAdequacy() external view returns (bool usdtAdequate, bool usdcAdequate) {
uint256 cUSDTSupply = compliantUSDT.totalSupply();
uint256 cUSDCSupply = compliantUSDC.totalSupply();
usdtAdequate = usdtReserveBalance >= cUSDTSupply;
usdcAdequate = usdcReserveBalance >= cUSDCSupply;
}
/**
* @notice Pause all operations
*/
function pause() external onlyRole(DEFAULT_ADMIN_ROLE) {
paused = true;
emit Paused(msg.sender);
}
/**
* @notice Unpause all operations
*/
function unpause() external onlyRole(DEFAULT_ADMIN_ROLE) {
paused = false;
emit Unpaused(msg.sender);
}
/**
* @notice Emergency withdrawal (admin only, after pause)
* @dev Can be used to recover funds in emergency situations
*/
function emergencyWithdraw(address token, uint256 amount, address recipient)
external
onlyRole(DEFAULT_ADMIN_ROLE)
whenPaused
{
require(recipient != address(0), "StablecoinReserveVault: zero recipient");
IERC20(token).safeTransfer(recipient, amount);
}
modifier whenPaused() {
require(paused, "StablecoinReserveVault: not paused");
_;
}
}