Files
smom-dbis-138/contracts/flash/UniversalCCIPFlashBridgeAdapter.sol
defiQUG 76aa419320 feat: bridges, PMM, flash workflow, token-aggregation, and deployment docs
- CCIP/trustless bridge contracts, GRU tokens, DEX/PMM tests, reserve vault.
- Token-aggregation service routes, planner, chain config, relay env templates.
- Config snapshots and multi-chain deployment markdown updates.
- gitignore services/btc-intake/dist/ (tsc output); do not track dist.

Run forge build && forge test before deploy (large solc graph).

Made-with: Cursor
2026-04-07 23:40:52 -07:00

71 lines
2.7 KiB
Solidity

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import {SafeERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import {UniversalCCIPBridge} from "../bridge/UniversalCCIPBridge.sol";
import {ICrossChainFlashBridge} from "./interfaces/ICrossChainFlashBridge.sol";
/**
* @title UniversalCCIPFlashBridgeAdapter
* @notice Pulls `token` from the caller (e.g. `CrossChainFlashBorrower`) and forwards a `UniversalCCIPBridge.bridge` call.
* @dev `extraData` (see `ICrossChainFlashBridge`): if empty, uses `assetType = 0`, `usePMM/useVault = false`, empty proofs.
* If non-empty: `abi.encode(bytes32 assetType, bool usePMM, bool useVault, bytes complianceProof, bytes vaultInstructions)`.
* Native value is forwarded for CCIP fees on the underlying bridge.
*/
contract UniversalCCIPFlashBridgeAdapter is ICrossChainFlashBridge {
using SafeERC20 for IERC20;
UniversalCCIPBridge public immutable universalBridge;
constructor(address universalBridge_) {
require(universalBridge_ != address(0), "UniversalCCIPFlashBridgeAdapter: zero bridge");
universalBridge = UniversalCCIPBridge(payable(universalBridge_));
}
function bridgeTokensFrom(
address token,
uint256 amount,
uint64 destinationChainSelector,
address recipientOnDestination,
bytes calldata extraData
) external payable override returns (bytes32 messageId) {
IERC20(token).safeTransferFrom(msg.sender, address(this), amount);
IERC20(token).forceApprove(address(universalBridge), amount);
bytes32 assetType;
bool usePMM;
bool useVault;
bytes memory complianceProof;
bytes memory vaultInstructions;
if (extraData.length == 0) {
assetType = bytes32(0);
usePMM = false;
useVault = false;
complianceProof = "";
vaultInstructions = "";
} else {
(assetType, usePMM, useVault, complianceProof, vaultInstructions) =
abi.decode(extraData, (bytes32, bool, bool, bytes, bytes));
}
UniversalCCIPBridge.BridgeOperation memory op = UniversalCCIPBridge.BridgeOperation({
token: token,
amount: amount,
destinationChain: destinationChainSelector,
recipient: recipientOnDestination,
assetType: assetType,
usePMM: usePMM,
useVault: useVault,
complianceProof: complianceProof,
vaultInstructions: vaultInstructions
});
messageId = universalBridge.bridge{value: msg.value}(op);
IERC20(token).forceApprove(address(universalBridge), 0);
}
receive() external payable {}
}