- 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
82 lines
3.4 KiB
Solidity
82 lines
3.4 KiB
Solidity
// SPDX-License-Identifier: MIT
|
|
pragma solidity ^0.8.20;
|
|
|
|
import {IAtomicQuoteEngine} from "./interfaces/IAtomicQuoteEngine.sol";
|
|
import {IAtomicBridgeCoordinator} from "./interfaces/IAtomicBridgeCoordinator.sol";
|
|
import {IAtomicLiquidityVault} from "./interfaces/IAtomicLiquidityVault.sol";
|
|
import {IAtomicFulfillerRegistry} from "./interfaces/IAtomicFulfillerRegistry.sol";
|
|
import {AtomicFeePolicy} from "./AtomicFeePolicy.sol";
|
|
import {AtomicTypes} from "./AtomicTypes.sol";
|
|
|
|
contract AtomicQuoteEngine is IAtomicQuoteEngine {
|
|
IAtomicBridgeCoordinator public immutable coordinator;
|
|
IAtomicLiquidityVault public immutable vault;
|
|
IAtomicFulfillerRegistry public immutable fulfillerRegistry;
|
|
AtomicFeePolicy public immutable feePolicy;
|
|
|
|
constructor(
|
|
address coordinator_,
|
|
address vault_,
|
|
address fulfillerRegistry_,
|
|
address feePolicy_
|
|
) {
|
|
coordinator = IAtomicBridgeCoordinator(coordinator_);
|
|
vault = IAtomicLiquidityVault(vault_);
|
|
fulfillerRegistry = IAtomicFulfillerRegistry(fulfillerRegistry_);
|
|
feePolicy = AtomicFeePolicy(feePolicy_);
|
|
}
|
|
|
|
function quote(
|
|
bytes32 corridorId,
|
|
uint256 amountIn,
|
|
uint256 minAmountOut,
|
|
address fulfiller
|
|
) external view returns (AtomicTypes.AtomicQuote memory q) {
|
|
AtomicTypes.CorridorConfig memory cfg = coordinator.getCorridorConfig(corridorId);
|
|
AtomicTypes.CorridorLiquidityState memory state = vault.getCorridorLiquidityState(corridorId, cfg.assetOut);
|
|
(uint256 fulfillerFee, uint256 protocolFee) = feePolicy.quoteFees(corridorId, amountIn);
|
|
uint256 requiredBond = feePolicy.requiredBond(corridorId, minAmountOut);
|
|
bool authorized = fulfillerRegistry.isFulfillerAuthorized(fulfiller, corridorId);
|
|
bool bondSufficient = fulfillerRegistry.canCover(fulfiller, requiredBond);
|
|
|
|
q = AtomicTypes.AtomicQuote({
|
|
routeClass: _routeClass(cfg, state, amountIn, minAmountOut, authorized, bondSufficient),
|
|
availableLiquidity: state.freeLiquidity > state.targetBuffer ? state.freeLiquidity - state.targetBuffer : 0,
|
|
freeLiquidity: state.freeLiquidity,
|
|
fulfillerFee: fulfillerFee,
|
|
protocolFee: protocolFee,
|
|
requiredBond: requiredBond,
|
|
settlementBacklog: state.settlementBacklog,
|
|
deadlineWindow: cfg.fulfilmentTimeout,
|
|
corridorEnabled: cfg.enabled,
|
|
corridorDegraded: cfg.degraded,
|
|
fulfillerAuthorized: authorized,
|
|
fulfillerBondSufficient: bondSufficient
|
|
});
|
|
}
|
|
|
|
function _routeClass(
|
|
AtomicTypes.CorridorConfig memory cfg,
|
|
AtomicTypes.CorridorLiquidityState memory state,
|
|
uint256 amountIn,
|
|
uint256 minAmountOut,
|
|
bool authorized,
|
|
bool bondSufficient
|
|
) internal pure returns (AtomicTypes.RouteClass) {
|
|
if (!cfg.enabled || cfg.degraded) {
|
|
return AtomicTypes.RouteClass.Blocked;
|
|
}
|
|
if (
|
|
amountIn > cfg.maxNotional ||
|
|
minAmountOut > state.freeLiquidity ||
|
|
state.settlementBacklog > cfg.maxSettlementBacklog
|
|
) {
|
|
return AtomicTypes.RouteClass.Blocked;
|
|
}
|
|
if (!authorized || !bondSufficient) {
|
|
return AtomicTypes.RouteClass.Planning;
|
|
}
|
|
return AtomicTypes.RouteClass.ExecutionReady;
|
|
}
|
|
}
|