- 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.
114 lines
3.9 KiB
Solidity
114 lines
3.9 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 "./interfaces/IRailEscrowVault.sol";
|
|
import "./libraries/RailTypes.sol";
|
|
|
|
/**
|
|
* @title RailEscrowVault
|
|
* @notice Holds tokens locked for outbound rail transfers
|
|
* @dev Similar pattern to BridgeVault138. Manages per-trigger escrow tracking.
|
|
*/
|
|
contract RailEscrowVault is IRailEscrowVault, AccessControl {
|
|
bytes32 public constant SETTLEMENT_OPERATOR_ROLE = keccak256("SETTLEMENT_OPERATOR_ROLE");
|
|
|
|
using SafeERC20 for IERC20;
|
|
|
|
// token => triggerId => escrow amount
|
|
mapping(address => mapping(uint256 => uint256)) private _escrow;
|
|
// token => total escrow amount
|
|
mapping(address => uint256) private _totalEscrow;
|
|
|
|
/**
|
|
* @notice Initializes the vault with an admin address
|
|
* @param admin Address that will receive DEFAULT_ADMIN_ROLE
|
|
*/
|
|
constructor(address admin) {
|
|
_grantRole(DEFAULT_ADMIN_ROLE, admin);
|
|
}
|
|
|
|
/**
|
|
* @notice Locks tokens for a rail transfer
|
|
* @dev Requires SETTLEMENT_OPERATOR_ROLE. Transfers tokens from user to vault.
|
|
* @param token Token address to lock
|
|
* @param from Address to transfer tokens from
|
|
* @param amount Amount to lock
|
|
* @param triggerId The trigger ID associated with this escrow
|
|
* @param rail The payment rail type
|
|
*/
|
|
function lock(
|
|
address token,
|
|
address from,
|
|
uint256 amount,
|
|
uint256 triggerId,
|
|
RailTypes.Rail rail
|
|
) external override onlyRole(SETTLEMENT_OPERATOR_ROLE) {
|
|
require(token != address(0), "RailEscrowVault: zero token");
|
|
require(from != address(0), "RailEscrowVault: zero from");
|
|
require(amount > 0, "RailEscrowVault: zero amount");
|
|
require(triggerId > 0, "RailEscrowVault: zero triggerId");
|
|
|
|
// Transfer tokens from user to vault
|
|
IERC20(token).safeTransferFrom(from, address(this), amount);
|
|
|
|
// Update escrow tracking
|
|
_escrow[token][triggerId] += amount;
|
|
_totalEscrow[token] += amount;
|
|
|
|
emit Locked(token, from, amount, triggerId, uint8(rail));
|
|
}
|
|
|
|
/**
|
|
* @notice Releases escrowed tokens
|
|
* @dev Requires SETTLEMENT_OPERATOR_ROLE. Transfers tokens from vault to recipient.
|
|
* @param token Token address to release
|
|
* @param to Recipient address
|
|
* @param amount Amount to release
|
|
* @param triggerId The trigger ID associated with this escrow
|
|
*/
|
|
function release(
|
|
address token,
|
|
address to,
|
|
uint256 amount,
|
|
uint256 triggerId
|
|
) external override onlyRole(SETTLEMENT_OPERATOR_ROLE) {
|
|
require(token != address(0), "RailEscrowVault: zero token");
|
|
require(to != address(0), "RailEscrowVault: zero to");
|
|
require(amount > 0, "RailEscrowVault: zero amount");
|
|
require(triggerId > 0, "RailEscrowVault: zero triggerId");
|
|
require(_escrow[token][triggerId] >= amount, "RailEscrowVault: insufficient escrow");
|
|
|
|
// Update escrow tracking
|
|
_escrow[token][triggerId] -= amount;
|
|
_totalEscrow[token] -= amount;
|
|
|
|
// Transfer tokens to recipient
|
|
IERC20(token).safeTransfer(to, amount);
|
|
|
|
emit Released(token, to, amount, triggerId);
|
|
}
|
|
|
|
/**
|
|
* @notice Returns the escrow amount for a specific trigger
|
|
* @param token Token address
|
|
* @param triggerId The trigger ID
|
|
* @return The escrow amount
|
|
*/
|
|
function getEscrowAmount(address token, uint256 triggerId) external view override returns (uint256) {
|
|
return _escrow[token][triggerId];
|
|
}
|
|
|
|
/**
|
|
* @notice Returns the total escrow amount for a token
|
|
* @param token Token address
|
|
* @return The total escrow amount
|
|
*/
|
|
function getTotalEscrow(address token) external view override returns (uint256) {
|
|
return _totalEscrow[token];
|
|
}
|
|
}
|
|
|