Files
gru_emoney_token-factory/src/BridgeVault138.sol
defiQUG e8ae376e90 Enhance API services with validation and error handling improvements
- Integrated Zod validation schemas across various API routes to ensure input integrity and improve error handling.
- Updated `mapping-service`, `orchestrator`, `packet-service`, and `webhook-service` to utilize validation middleware for request parameters and bodies.
- Improved error handling in webhook management, packet generation, and compliance routes to provide clearer feedback on request failures.
- Added new validation schemas for various endpoints, enhancing overall API robustness and maintainability.
- Updated dependencies in `package.json` to include the new validation library.
2025-12-12 20:23:45 -08:00

126 lines
5.0 KiB
Solidity

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
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);
}
}