Files
smom-dbis-138/contracts/mirror/TransactionMirror.sol

274 lines
8.3 KiB
Solidity
Raw Normal View History

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;
/**
* @title TransactionMirror
* @notice Mirrors Chain-138 transactions to Ethereum Mainnet for Etherscan visibility
* @dev Logs all Chain-138 transactions as events on Mainnet, making them searchable
* and viewable on Etherscan. This provides transparency and auditability.
*/
contract TransactionMirror {
address public admin;
bool public paused;
// Chain-138 chain ID
uint64 public constant CHAIN_138 = 138;
// Maximum batch size to prevent gas limit issues
uint256 public constant MAX_BATCH_SIZE = 100;
// Transaction structure
struct MirroredTransaction {
bytes32 txHash; // Chain-138 transaction hash
address from; // Sender address
address to; // Recipient address (or contract)
uint256 value; // Value transferred
uint256 blockNumber; // Chain-138 block number
uint256 blockTimestamp; // Block timestamp
uint256 gasUsed; // Gas used
bool success; // Transaction success status
bytes data; // Transaction data (if any)
bytes32 indexedHash; // Indexed hash for searchability
}
// Mapping: txHash => MirroredTransaction
mapping(bytes32 => MirroredTransaction) public transactions;
// Array of all mirrored transaction hashes
bytes32[] public mirroredTxHashes;
// Mapping: txHash => bool (replay protection)
mapping(bytes32 => bool) public processed;
// Events (indexed for Etherscan searchability)
event TransactionMirrored(
bytes32 indexed txHash,
address indexed from,
address indexed to,
uint256 value,
uint256 blockNumber,
uint256 blockTimestamp,
uint256 gasUsed,
bool success
);
event BatchTransactionsMirrored(
uint256 count,
uint256 startBlock,
uint256 endBlock
);
event AdminChanged(address indexed newAdmin);
event Paused();
event Unpaused();
modifier onlyAdmin() {
require(msg.sender == admin, "only admin");
_;
}
modifier whenNotPaused() {
require(!paused, "paused");
_;
}
constructor(address _admin) {
require(_admin != address(0), "zero admin");
admin = _admin;
}
/**
* @notice Mirror a single Chain-138 transaction to Mainnet
* @param txHash Chain-138 transaction hash
* @param from Sender address
* @param to Recipient address
* @param value Value transferred
* @param blockNumber Chain-138 block number
* @param blockTimestamp Block timestamp
* @param gasUsed Gas used
* @param success Transaction success status
* @param data Transaction data (optional)
*/
function mirrorTransaction(
bytes32 txHash,
address from,
address to,
uint256 value,
uint256 blockNumber,
uint256 blockTimestamp,
uint256 gasUsed,
bool success,
bytes calldata data
) external onlyAdmin whenNotPaused {
require(txHash != bytes32(0), "invalid hash");
require(!processed[txHash], "already mirrored");
bytes32 indexedHash = keccak256(abi.encodePacked(CHAIN_138, txHash));
transactions[txHash] = MirroredTransaction({
txHash: txHash,
from: from,
to: to,
value: value,
blockNumber: blockNumber,
blockTimestamp: blockTimestamp,
gasUsed: gasUsed,
success: success,
data: data,
indexedHash: indexedHash
});
mirroredTxHashes.push(txHash);
processed[txHash] = true;
emit TransactionMirrored(
txHash,
from,
to,
value,
blockNumber,
blockTimestamp,
gasUsed,
success
);
}
/**
* @notice Mirror multiple Chain-138 transactions in a batch
* @param txHashes Array of transaction hashes
* @param froms Array of sender addresses
* @param tos Array of recipient addresses
* @param values Array of values
* @param blockNumbers Array of block numbers
* @param blockTimestamps Array of timestamps
* @param gasUseds Array of gas used
* @param successes Array of success statuses
* @param datas Array of transaction data
*/
function mirrorBatchTransactions(
bytes32[] calldata txHashes,
address[] calldata froms,
address[] calldata tos,
uint256[] calldata values,
uint256[] calldata blockNumbers,
uint256[] calldata blockTimestamps,
uint256[] calldata gasUseds,
bool[] calldata successes,
bytes[] calldata datas
) external onlyAdmin whenNotPaused {
uint256 count = txHashes.length;
require(count > 0, "empty batch");
require(count <= MAX_BATCH_SIZE, "batch too large");
require(
count == froms.length &&
count == tos.length &&
count == values.length &&
count == blockNumbers.length &&
count == blockTimestamps.length &&
count == gasUseds.length &&
count == successes.length &&
count == datas.length,
"array length mismatch"
);
uint256 startBlock = blockNumbers[0];
uint256 endBlock = blockNumbers[count - 1];
// Process transactions in batches to avoid stack too deep
for (uint256 i = 0; i < count; i++) {
bytes32 txHash = txHashes[i];
require(txHash != bytes32(0), "invalid hash");
require(!processed[txHash], "already mirrored");
bytes32 indexedHash = keccak256(abi.encodePacked(CHAIN_138, txHash));
transactions[txHash] = MirroredTransaction({
txHash: txHash,
from: froms[i],
to: tos[i],
value: values[i],
blockNumber: blockNumbers[i],
blockTimestamp: blockTimestamps[i],
gasUsed: gasUseds[i],
success: successes[i],
data: datas[i],
indexedHash: indexedHash
});
mirroredTxHashes.push(txHash);
processed[txHash] = true;
emit TransactionMirrored(
txHash,
froms[i],
tos[i],
values[i],
blockNumbers[i],
blockTimestamps[i],
gasUseds[i],
successes[i]
);
}
emit BatchTransactionsMirrored(count, startBlock, endBlock);
}
/**
* @notice Get mirrored transaction details
* @param txHash Chain-138 transaction hash
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
* @return mirroredTx Mirrored transaction structure
*/
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
function getTransaction(bytes32 txHash) external view returns (MirroredTransaction memory mirroredTx) {
require(processed[txHash], "not mirrored");
return transactions[txHash];
}
/**
* @notice Check if a transaction is mirrored
* @param txHash Chain-138 transaction hash
* @return true if mirrored
*/
function isMirrored(bytes32 txHash) external view returns (bool) {
return processed[txHash];
}
/**
* @notice Get total number of mirrored transactions
* @return count Number of mirrored transactions
*/
function getMirroredTransactionCount() external view returns (uint256) {
return mirroredTxHashes.length;
}
/**
* @notice Get mirrored transaction hash at index
* @param index Index in mirroredTxHashes array
* @return txHash Transaction hash
*/
function getMirroredTransaction(uint256 index) external view returns (bytes32) {
require(index < mirroredTxHashes.length, "out of bounds");
return mirroredTxHashes[index];
}
/**
* @notice Admin functions
*/
function setAdmin(address newAdmin) external onlyAdmin {
require(newAdmin != address(0), "zero admin");
admin = newAdmin;
emit AdminChanged(newAdmin);
}
function pause() external onlyAdmin {
paused = true;
emit Paused();
}
function unpause() external onlyAdmin {
paused = false;
emit Unpaused();
}
}