Files
smom-dbis-138/contracts/emoney/BridgeVault138.sol
defiQUG 1fb7266469 Add Oracle Aggregator and CCIP Integration
- Introduced Aggregator.sol for Chainlink-compatible oracle functionality, including round-based updates and access control.
- Added OracleWithCCIP.sol to extend Aggregator with CCIP cross-chain messaging capabilities.
- Created .gitmodules to include OpenZeppelin contracts as a submodule.
- Developed a comprehensive deployment guide in NEXT_STEPS_COMPLETE_GUIDE.md for Phase 2 and smart contract deployment.
- Implemented Vite configuration for the orchestration portal, supporting both Vue and React frameworks.
- Added server-side logic for the Multi-Cloud Orchestration Portal, including API endpoints for environment management and monitoring.
- Created scripts for resource import and usage validation across non-US regions.
- Added tests for CCIP error handling and integration to ensure robust functionality.
- Included various new files and directories for the orchestration portal and deployment scripts.
2025-12-12 14:57:48 -08:00

126 lines
5.0 KiB
Solidity

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;
import "@openzeppelin/contracts/access/AccessControl.sol";
import "@openzeppelin/contracts/utils/ReentrancyGuard.sol";
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import "./interfaces/IBridgeVault138.sol";
import "./interfaces/IPolicyManager.sol";
import "./interfaces/IComplianceRegistry.sol";
import "./errors/BridgeErrors.sol";
/// @notice Placeholder for light client verification
/// In production, this should integrate with an actual light client contract
interface ILightClient {
function verifyProof(
bytes32 sourceChain,
bytes32 sourceTx,
bytes calldata proof
) external view returns (bool);
}
/**
* @title BridgeVault138
* @notice Lock/unlock portal for cross-chain token representation
* @dev Manages tokens locked for cross-chain transfers. Lock enforces liens via PolicyManager.
* Unlock requires light client proof verification and compliance checks.
*/
contract BridgeVault138 is IBridgeVault138, AccessControl, ReentrancyGuard {
bytes32 public constant BRIDGE_OPERATOR_ROLE = keccak256("BRIDGE_OPERATOR_ROLE");
using SafeERC20 for IERC20;
IPolicyManager public immutable policyManager;
IComplianceRegistry public immutable complianceRegistry;
ILightClient public lightClient; // Can be set after deployment
/**
* @notice Initializes the bridge vault with registry addresses
* @param admin Address that will receive DEFAULT_ADMIN_ROLE
* @param policyManager_ Address of PolicyManager contract
* @param complianceRegistry_ Address of ComplianceRegistry contract
*/
constructor(address admin, address policyManager_, address complianceRegistry_) {
_grantRole(DEFAULT_ADMIN_ROLE, admin);
policyManager = IPolicyManager(policyManager_);
complianceRegistry = IComplianceRegistry(complianceRegistry_);
}
/**
* @notice Sets the light client contract for proof verification
* @dev Requires DEFAULT_ADMIN_ROLE
* @param lightClient_ Address of the light client contract
*/
function setLightClient(address lightClient_) external onlyRole(DEFAULT_ADMIN_ROLE) {
lightClient = ILightClient(lightClient_);
}
/**
* @notice Locks tokens for cross-chain transfer
* @dev Transfers tokens from user to vault. Enforces liens via PolicyManager.canTransfer.
* @param token Token address to lock
* @param amount Amount to lock
* @param targetChain Target chain identifier
* @param targetRecipient Recipient address on target chain
*/
function lock(
address token,
uint256 amount,
bytes32 targetChain,
address targetRecipient
) external override nonReentrant {
if (token == address(0)) revert BridgeZeroToken();
if (amount == 0) revert BridgeZeroAmount();
if (targetRecipient == address(0)) revert BridgeZeroRecipient();
// Check if transfer would be allowed BEFORE transferring (checks liens, compliance, etc.)
(bool allowed, ) = policyManager.canTransfer(token, msg.sender, address(this), amount);
if (!allowed) revert BridgeTransferBlocked(token, msg.sender, address(this), amount);
// Transfer tokens from user AFTER validation
IERC20(token).safeTransferFrom(msg.sender, address(this), amount);
emit Locked(token, msg.sender, amount, targetChain, targetRecipient);
}
/**
* @notice Unlocks tokens from cross-chain transfer
* @dev Requires BRIDGE_OPERATOR_ROLE. Verifies proof via light client and checks compliance.
* Transfers tokens from vault to recipient.
* @param token Token address to unlock
* @param to Recipient address
* @param amount Amount to unlock
* @param sourceChain Source chain identifier
* @param sourceTx Source transaction hash
* @param proof Proof data for light client verification
*/
function unlock(
address token,
address to,
uint256 amount,
bytes32 sourceChain,
bytes32 sourceTx,
bytes calldata proof
) external override onlyRole(BRIDGE_OPERATOR_ROLE) nonReentrant {
if (token == address(0)) revert BridgeZeroToken();
if (to == address(0)) revert BridgeZeroRecipient();
if (amount == 0) revert BridgeZeroAmount();
// Verify proof via light client
if (address(lightClient) == address(0)) revert BridgeLightClientNotSet();
bool verified = lightClient.verifyProof(sourceChain, sourceTx, proof);
if (!verified) revert BridgeProofVerificationFailed(sourceChain, sourceTx);
// Check compliance
if (!complianceRegistry.isAllowed(to)) revert BridgeRecipientNotCompliant(to);
if (complianceRegistry.isFrozen(to)) revert BridgeRecipientFrozen(to);
// Transfer tokens to recipient
IERC20(token).safeTransfer(to, amount);
emit Unlocked(token, to, amount, sourceChain, sourceTx);
}
}