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
This commit is contained in:
70
contracts/flash/UniversalCCIPFlashBridgeAdapter.sol
Normal file
70
contracts/flash/UniversalCCIPFlashBridgeAdapter.sol
Normal file
@@ -0,0 +1,70 @@
|
||||
// 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 {}
|
||||
}
|
||||
Reference in New Issue
Block a user