编译器
0.8.27+commit.40a35a09
文件 1 的 20:BaseReactor.sol
pragma solidity ^0.8.26;
import { ISignatureTransfer } from "permit2/src/interfaces/ISignatureTransfer.sol";
import { SafeTransferLib } from "solady/src/utils/SafeTransferLib.sol";
import { IOracle } from "../interfaces/IOracle.sol";
import {
CrossChainOrder,
ISettlementContract,
Input,
Output,
ResolvedCrossChainOrder
} from "../interfaces/ISettlementContract.sol";
import { OrderContext, OrderKey, OrderStatus, OutputDescription, ReactorInfo } from "../interfaces/Structs.sol";
import { FillerDataLib } from "../libs/FillerDataLib.sol";
import { IsContractLib } from "../libs/IsContractLib.sol";
import {
CannotProveOrder,
ChallengeDeadlinePassed,
InitiateDeadlineAfterFill,
InitiateDeadlinePassed,
InvalidDeadlineOrder,
InvalidSettlementAddress,
MinOrderPurchaseDiscountTooLow,
OnlyFiller,
OrderAlreadyClaimed,
OrderNotReadyForOptimisticPayout,
OrderFinal,
ProofPeriodHasNotPassed,
PurchaseTimePassed,
WrongChain,
WrongOrderStatus
} from "../interfaces/Errors.sol";
import { ReactorPayments } from "./helpers/ReactorPayments.sol";
import { ResolverERC7683 } from "./helpers/ResolverERC7683.sol";
abstract contract BaseReactor is ReactorPayments, ResolverERC7683 {
bytes32 public constant VERSION_FLAGS = bytes32(uint256(1));
event OrderInitiated(bytes32 indexed orderHash, address indexed caller, bytes filler, OrderKey orderKey);
event OrderProven(bytes32 indexed orderHash, address indexed prover);
event OptimisticPayout(bytes32 indexed orderHash);
event OrderChallenged(bytes32 indexed orderHash, address indexed disputer);
event FraudAccepted(bytes32 indexed orderHash);
event OrderPurchased(bytes32 indexed orderHash, address newFiller);
event OrderPurchaseDetailsModified(bytes32 indexed orderHash, bytes fillerdata);
event OrderBroadcast(bytes32 indexed orderHash, CrossChainOrder order, bytes signature);
mapping(bytes32 orderKeyHash => OrderContext orderContext) internal _orders;
constructor(address permit2, address owner) payable ReactorPayments(permit2, owner) { }
function _orderKeyHash(
OrderKey memory orderKey
) internal pure returns (bytes32 orderKeyHash) {
return orderKeyHash = keccak256(abi.encode(orderKey));
}
function getOrderKeyHash(
OrderKey calldata orderKey
) external pure returns (bytes32 orderKeyHash) {
return orderKeyHash = _orderKeyHash(orderKey);
}
function getOrderContext(
bytes32 orderKeyHash
) external view returns (OrderContext memory orderContext) {
return orderContext = _orders[orderKeyHash];
}
function getOrderContext(
OrderKey calldata orderKey
) external view returns (OrderContext memory orderContext) {
return orderContext = _orders[_orderKeyHash(orderKey)];
}
function broadcast(
CrossChainOrder calldata order,
bytes calldata signature
) external {
if (order.settlementContract != address(this)) revert InvalidSettlementAddress();
if (order.originChainId != block.chainid) revert WrongChain(uint32(block.chainid), order.originChainId);
if (order.initiateDeadline < block.timestamp) revert InitiateDeadlinePassed();
if (order.fillDeadline < order.initiateDeadline) revert InitiateDeadlineAfterFill();
bytes32 orderHash = _orderKeyHash(_resolveKey(order, signature[0:0]));
emit OrderBroadcast(orderHash, order, signature);
}
function initiate(
CrossChainOrder calldata order,
bytes calldata signature,
bytes calldata fillerData
) external returns (OrderKey memory orderKey) {
if (order.settlementContract != address(this)) revert InvalidSettlementAddress();
if (order.originChainId != block.chainid) revert WrongChain(uint32(block.chainid), order.originChainId);
if (order.initiateDeadline < block.timestamp) revert InitiateDeadlinePassed();
if (order.fillDeadline < order.initiateDeadline) revert InitiateDeadlineAfterFill();
(
address fillerAddress,
uint32 orderPurchaseDeadline,
uint16 orderPurchaseDiscount,
bytes32 identifier,
uint256 fillerDataPointer
) = FillerDataLib.decode(fillerData);
bytes32 witness;
string memory witnessTypeString;
uint256[] memory permittedAmounts;
(orderKey, permittedAmounts, witness, witnessTypeString) = _initiate(order, fillerData[fillerDataPointer:]);
ReactorInfo memory reactorInfo = orderKey.reactorContext;
if (
order.fillDeadline > reactorInfo.challengeDeadline
|| reactorInfo.challengeDeadline > reactorInfo.proofDeadline
) {
revert InvalidDeadlineOrder();
}
bytes32 orderHash = _orderKeyHash(orderKey);
OrderContext storage orderContext = _orders[orderHash];
bool defaultChallenge = (reactorInfo.proofDeadline == reactorInfo.challengeDeadline) && (orderKey.collateral.challengerCollateralAmount == 0);
if (defaultChallenge) orderContext.challenger = orderKey.swapper;
if (orderContext.status != OrderStatus.Unfilled) revert OrderAlreadyClaimed(orderContext.status);
orderContext.status = defaultChallenge ? OrderStatus.Challenged : OrderStatus.Claimed;
orderContext.fillerAddress = fillerAddress;
orderContext.orderPurchaseDeadline = orderPurchaseDeadline;
orderContext.orderPurchaseDiscount = orderPurchaseDiscount;
if (identifier != bytes32(0)) orderContext.identifier = identifier;
IsContractLib.checkCodeSize(orderKey.collateral.collateralToken);
SafeTransferLib.safeTransferFrom(
orderKey.collateral.collateralToken, msg.sender, address(this), orderKey.collateral.fillerCollateralAmount
);
_collectTokensViaPermit2(
orderKey, permittedAmounts, order.initiateDeadline, order.swapper, witness, witnessTypeString, signature
);
emit OrderInitiated(orderHash, msg.sender, fillerData, orderKey);
}
function proveOrderFulfilment(OrderKey calldata orderKey, bytes calldata executionData) external {
bytes32 orderHash = _orderKeyHash(orderKey);
OrderContext storage orderContext = _orders[orderHash];
OrderStatus status = orderContext.status;
address fillerAddress = orderContext.fillerAddress;
if (status != OrderStatus.Claimed && status != OrderStatus.Challenged) {
revert WrongOrderStatus(orderContext.status);
}
orderContext.status = OrderStatus.Proven;
if (!IOracle(orderKey.localOracle).isProven(orderKey.outputs, orderKey.reactorContext.fillDeadline)) {
revert CannotProveOrder();
}
_deliverTokens(orderKey.inputs, fillerAddress, governanceFee);
address collateralToken = orderKey.collateral.collateralToken;
uint256 fillerCollateralAmount = orderKey.collateral.fillerCollateralAmount;
if (status == OrderStatus.Challenged) {
fillerCollateralAmount += orderKey.collateral.challengerCollateralAmount;
}
SafeTransferLib.safeTransfer(collateralToken, fillerAddress, fillerCollateralAmount);
bytes32 identifier = orderContext.identifier;
if (identifier != bytes32(0)) FillerDataLib.execute(identifier, orderHash, executionData);
emit OrderProven(orderHash, msg.sender);
}
function optimisticPayout(OrderKey calldata orderKey, bytes calldata executionData) external {
bytes32 orderHash = _orderKeyHash(orderKey);
OrderContext storage orderContext = _orders[orderHash];
if (orderContext.status != OrderStatus.Claimed) revert WrongOrderStatus(orderContext.status);
orderContext.status = OrderStatus.OptimiscallyFilled;
uint256 challengeDeadline = orderKey.reactorContext.challengeDeadline;
if (block.timestamp <= challengeDeadline) {
revert OrderNotReadyForOptimisticPayout(uint32(challengeDeadline));
}
address fillerAddress = orderContext.fillerAddress;
_deliverTokens(orderKey.inputs, fillerAddress, governanceFee);
address collateralToken = orderKey.collateral.collateralToken;
uint256 fillerCollateralAmount = orderKey.collateral.fillerCollateralAmount;
SafeTransferLib.safeTransfer(collateralToken, fillerAddress, fillerCollateralAmount);
bytes32 identifier = orderContext.identifier;
if (identifier != bytes32(0)) FillerDataLib.execute(identifier, orderHash, executionData);
emit OptimisticPayout(orderHash);
}
function dispute(
OrderKey calldata orderKey
) external {
bytes32 orderKeyHash = _orderKeyHash(orderKey);
OrderContext storage orderContext = _orders[orderKeyHash];
if (orderContext.status != OrderStatus.Claimed) revert WrongOrderStatus(orderContext.status);
if (uint256(orderKey.reactorContext.challengeDeadline) < block.timestamp) revert ChallengeDeadlinePassed();
orderContext.challenger = msg.sender;
orderContext.status = OrderStatus.Challenged;
SafeTransferLib.safeTransferFrom(
orderKey.collateral.collateralToken,
msg.sender,
address(this),
orderKey.collateral.challengerCollateralAmount
);
emit OrderChallenged(orderKeyHash, msg.sender);
}
function completeDispute(
OrderKey calldata orderKey
) external {
bytes32 orderKeyHash = _orderKeyHash(orderKey);
OrderContext storage orderContext = _orders[orderKeyHash];
uint256 proofDeadline = orderKey.reactorContext.proofDeadline;
if (block.timestamp <= proofDeadline) {
revert ProofPeriodHasNotPassed(uint32(proofDeadline));
}
if (orderContext.status != OrderStatus.Challenged) revert WrongOrderStatus(orderContext.status);
orderContext.status = OrderStatus.Fraud;
_deliverTokens(orderKey.inputs, orderKey.swapper, 0);
unchecked {
address collateralToken = orderKey.collateral.collateralToken;
uint256 fillerCollateralAmount = orderKey.collateral.fillerCollateralAmount;
uint256 challengerCollateralAmount = orderKey.collateral.challengerCollateralAmount;
uint256 swapperCollateralAmount = fillerCollateralAmount / 2;
SafeTransferLib.safeTransfer(collateralToken, orderKey.swapper, swapperCollateralAmount);
SafeTransferLib.safeTransfer(
collateralToken,
orderContext.challenger,
challengerCollateralAmount + fillerCollateralAmount - swapperCollateralAmount
);
}
emit FraudAccepted(orderKeyHash);
}
function purchaseOrder(OrderKey calldata orderKey, bytes calldata fillerData, uint256 minDiscount) external {
bytes32 orderKeyHash = _orderKeyHash(orderKey);
OrderContext storage orderContext = _orders[orderKeyHash];
{
OrderStatus status = orderContext.status;
if (status != OrderStatus.Claimed && status != OrderStatus.Challenged) {
revert WrongOrderStatus(orderContext.status);
}
}
if (orderContext.orderPurchaseDeadline < block.timestamp) {
revert PurchaseTimePassed();
}
(
address fillerAddress,
uint32 orderPurchaseDeadline,
uint16 orderPurchaseDiscount,
bytes32 identifier,
uint256 fillerDataPointer
) = FillerDataLib.decode(fillerData);
address oldFillerAddress = orderContext.fillerAddress;
uint16 oldOrderPurchaseDiscount = orderContext.orderPurchaseDiscount;
bytes32 oldIdentifier = orderContext.identifier;
if (minDiscount > oldOrderPurchaseDiscount) {
revert MinOrderPurchaseDiscountTooLow(minDiscount, oldOrderPurchaseDiscount);
}
orderContext.fillerAddress = fillerAddress;
orderContext.orderPurchaseDeadline = orderPurchaseDeadline;
orderContext.orderPurchaseDiscount = orderPurchaseDiscount;
orderContext.identifier = identifier;
address collateralToken = orderKey.collateral.collateralToken;
uint256 collateralAmount = orderKey.collateral.fillerCollateralAmount;
SafeTransferLib.safeTransferFrom(collateralToken, msg.sender, oldFillerAddress, collateralAmount);
_collectTokensFromMsgSender(orderKey.inputs, oldFillerAddress, oldOrderPurchaseDiscount);
if (oldIdentifier != bytes32(0)) {
FillerDataLib.execute(identifier, orderKeyHash, fillerData[fillerDataPointer:]);
}
emit OrderPurchased(orderKeyHash, msg.sender);
}
function modifyOrderFillerdata(OrderKey calldata orderKey, bytes calldata fillerData) external {
bytes32 orderKeyHash = _orderKeyHash(orderKey);
OrderContext storage orderContext = _orders[orderKeyHash];
OrderStatus status = orderContext.status;
if (
status == OrderStatus.Fraud ||
status == OrderStatus.OptimiscallyFilled ||
status == OrderStatus.Proven
) revert OrderFinal();
address currentFiller = orderContext.fillerAddress;
if (currentFiller == address(0) || currentFiller != msg.sender) revert OnlyFiller();
(
address newFillerAddress,
uint32 newOrderPurchaseDeadline,
uint16 newOrderPurchaseDiscount,
bytes32 newIdentifier,
) = FillerDataLib.decode(fillerData);
if (newFillerAddress != currentFiller) orderContext.fillerAddress = newFillerAddress;
orderContext.orderPurchaseDeadline = newOrderPurchaseDeadline;
orderContext.orderPurchaseDiscount = newOrderPurchaseDiscount;
orderContext.identifier = newIdentifier;
emit OrderPurchaseDetailsModified(orderKeyHash, fillerData);
}
}
文件 2 的 20:CanCollectGovernanceFee.sol
pragma solidity ^0.8.26;
import { Ownable } from "solady/src/auth/Ownable.sol";
import { SafeTransferLib } from "solady/src/utils/SafeTransferLib.sol";
import { IsContractLib } from "./IsContractLib.sol";
abstract contract ICanCollectGovernanceFee {
function _calcFee(uint256 amount, uint256 fee) internal pure virtual returns (uint256 amountLessFee);
function _calcFee(
uint256 amount
) internal view virtual returns (uint256 amountLessFee);
}
abstract contract CanCollectGovernanceFee is Ownable, ICanCollectGovernanceFee {
error GovernanceFeeTooHigh();
error GovernanceFeeChangeNotReady();
event GovernanceFeesDistributed(address indexed to, address[] tokens, uint256[] collectedAmounts);
event NextGovernanceFee(uint64 nextGovernanceFee, uint64 nextGovernanceFeeTime);
event GovernanceFeeChanged(uint64 oldGovernanceFee, uint64 newGovernanceFee);
uint64 public governanceFee = 0;
uint64 public nextGovernanceFee = 0;
uint64 public nextGovernanceFeeTime = type(uint64).max;
uint64 constant GOVERNANCE_FEE_CHANGE_DELAY = 7 days;
uint256 constant GOVERNANCE_FEE_DENOM = 10 ** 18;
uint256 constant MAX_GOVERNANCE_FEE = 10 ** 18 * 0.1;
constructor(
address owner
) payable {
_initializeOwner(owner);
}
mapping(address token => uint256 amount) internal _governanceTokens;
function getGovernanceTokens(
address token
) external view returns (uint256 amountTokens) {
return amountTokens = _governanceTokens[token];
}
function _collectGovernanceFee(
address token,
uint256 amount,
uint256 fee
) internal returns (uint256 amountLessFee) {
unchecked {
uint256 governanceShare = _calcFee(amount, fee);
amountLessFee = amount - governanceShare;
if (governanceShare != 0) _governanceTokens[token] = _governanceTokens[token] + governanceShare;
}
}
function _collectGovernanceFee(address token, uint256 amount) internal returns (uint256 amountLessFee) {
return amountLessFee = _collectGovernanceFee(token, amount, governanceFee);
}
function _calcFee(uint256 amount, uint256 fee) internal pure override returns (uint256 amountFee) {
unchecked {
if (amount >= type(uint256).max / fee) return amountFee = 0;
return amountFee = amount * fee / GOVERNANCE_FEE_DENOM;
}
}
function _calcFee(
uint256 amount
) internal view override returns (uint256 amountFee) {
return _calcFee(amount, governanceFee);
}
function setGovernanceFee(
uint64 _nextGovernanceFee
) external onlyOwner {
if (_nextGovernanceFee > MAX_GOVERNANCE_FEE) revert GovernanceFeeTooHigh();
nextGovernanceFee = _nextGovernanceFee;
nextGovernanceFeeTime = uint64(block.timestamp) + GOVERNANCE_FEE_CHANGE_DELAY;
emit NextGovernanceFee(nextGovernanceFee, nextGovernanceFeeTime);
}
function applyGovernanceFee() external {
if (block.timestamp < nextGovernanceFeeTime) revert GovernanceFeeChangeNotReady();
uint64 oldGovernanceFee = governanceFee;
governanceFee = nextGovernanceFee;
emit GovernanceFeeChanged(oldGovernanceFee, nextGovernanceFee);
}
function distributeGovernanceTokens(
address[] calldata tokens,
address to
) external onlyOwner returns (uint256[] memory collectedAmounts) {
unchecked {
uint256 numTokens = tokens.length;
collectedAmounts = new uint256[](numTokens);
for (uint256 i = 0; i < numTokens; ++i) {
address token = tokens[i];
uint256 tokensToBeClaimed = _governanceTokens[token];
_governanceTokens[token] = 0;
collectedAmounts[i] = tokensToBeClaimed;
SafeTransferLib.safeTransfer(token, to, tokensToBeClaimed);
}
}
emit GovernanceFeesDistributed(to, tokens, collectedAmounts);
}
}
文件 3 的 20:CrossChainLimitOrderType.sol
pragma solidity ^0.8.26;
import { CrossChainOrder, Input } from "../../interfaces/ISettlementContract.sol";
import { OutputDescription } from "../../interfaces/Structs.sol";
import { CrossChainOrderType } from "./CrossChainOrderType.sol";
struct CatalystLimitOrderData {
uint32 proofDeadline;
uint32 challengeDeadline;
address collateralToken;
uint256 fillerCollateralAmount;
uint256 challengerCollateralAmount;
address localOracle;
Input[] inputs;
OutputDescription[] outputs;
}
library CrossChainLimitOrderType {
bytes constant LIMIT_ORDER_DATA_TYPE = abi.encodePacked(
LIMIT_ORDER_DATA_TYPE_ONLY, CrossChainOrderType.INPUT_TYPE_STUB, CrossChainOrderType.OUTPUT_TYPE_STUB
);
bytes constant LIMIT_ORDER_DATA_TYPE_ONLY = abi.encodePacked(
"CatalystLimitOrderData(",
"uint32 proofDeadline,",
"uint32 challengeDeadline,",
"address collateralToken,",
"uint256 fillerCollateralAmount,",
"uint256 challengerCollateralAmount,",
"address localOracle,",
"Input[] inputs,",
"OutputDescription[] outputs",
")"
);
bytes constant LIMIT_CROSS_CHAIN_ORDER_TYPE = abi.encodePacked(
CrossChainOrderType.CROSS_CHAIN_ORDER_TYPE_NO_DATA_STUB, "CatalystLimitOrderData orderData", ")"
);
string constant PERMIT2_LIMIT_ORDER_WITNESS_STRING_TYPE = string(
abi.encodePacked(
"CrossChainOrder witness)",
LIMIT_ORDER_DATA_TYPE_ONLY,
LIMIT_CROSS_CHAIN_ORDER_TYPE,
CrossChainOrderType.INPUT_TYPE_STUB,
CrossChainOrderType.OUTPUT_TYPE_STUB,
CrossChainOrderType.TOKEN_PERMISSIONS_TYPE
)
);
bytes32 constant LIMIT_ORDER_DATA_TYPE_HASH = keccak256(LIMIT_ORDER_DATA_TYPE);
function decodeOrderData(
bytes calldata orderBytes
) internal pure returns (CatalystLimitOrderData memory limitData) {
return limitData = abi.decode(orderBytes, (CatalystLimitOrderData));
}
function hashOrderDataM(
CatalystLimitOrderData memory orderData
) internal pure returns (bytes32) {
return keccak256(
bytes.concat(
abi.encode(
LIMIT_ORDER_DATA_TYPE_HASH,
orderData.proofDeadline,
orderData.challengeDeadline,
orderData.collateralToken,
orderData.fillerCollateralAmount,
orderData.challengerCollateralAmount,
orderData.localOracle
),
abi.encode(
CrossChainOrderType.hashInputs(orderData.inputs), CrossChainOrderType.hashOutputs(orderData.outputs)
)
)
);
}
function crossOrderHash(
CrossChainOrder calldata order,
CatalystLimitOrderData memory limitOrderData
) internal pure returns (bytes32) {
return keccak256(
abi.encode(
keccak256(abi.encodePacked(LIMIT_CROSS_CHAIN_ORDER_TYPE, LIMIT_ORDER_DATA_TYPE)),
order.settlementContract,
order.swapper,
order.nonce,
order.originChainId,
order.initiateDeadline,
order.fillDeadline,
hashOrderDataM(limitOrderData)
)
);
}
}
文件 4 的 20:CrossChainOrderType.sol
pragma solidity ^0.8.26;
import { CrossChainOrder, Input } from "../../interfaces/ISettlementContract.sol";
import { OutputDescription } from "../../interfaces/Structs.sol";
library CrossChainOrderType {
bytes constant CROSS_CHAIN_ORDER_TYPE_NO_DATA_STUB = abi.encodePacked(
"CrossChainOrder(",
"address settlementContract,",
"address swapper,",
"uint256 nonce,",
"uint32 originChainId,",
"uint32 initiateDeadline,",
"uint32 fillDeadline,"
);
bytes constant INPUT_TYPE_STUB = abi.encodePacked("Input(", "address token,", "uint256 amount", ")");
bytes constant OUTPUT_TYPE_STUB = abi.encodePacked(
"OutputDescription(",
"bytes32 remoteOracle,",
"bytes32 token,",
"uint256 amount,",
"bytes32 recipient,",
"uint32 chainId,",
"bytes remoteCall",
")"
);
string constant TOKEN_PERMISSIONS_TYPE = "TokenPermissions(address token,uint256 amount)";
function hashInput(
Input memory input
) internal pure returns (bytes32) {
return keccak256(abi.encode(keccak256(INPUT_TYPE_STUB), input.token, input.amount));
}
function hashOutput(
OutputDescription memory output
) internal pure returns (bytes32) {
return keccak256(
abi.encode(
keccak256(OUTPUT_TYPE_STUB),
output.remoteOracle,
output.token,
output.amount,
output.recipient,
output.chainId,
keccak256(output.remoteCall)
)
);
}
function hashInputs(
Input[] memory inputs
) internal pure returns (bytes32) {
unchecked {
bytes memory currentHash = new bytes(32 * inputs.length);
for (uint256 i = 0; i < inputs.length; ++i) {
bytes32 inputHash = hashInput(inputs[i]);
assembly {
mstore(add(add(currentHash, 0x20), mul(i, 0x20)), inputHash)
}
}
return keccak256(currentHash);
}
}
function hashOutputs(
OutputDescription[] memory outputs
) internal pure returns (bytes32) {
unchecked {
bytes memory currentHash = new bytes(32 * outputs.length);
for (uint256 i = 0; i < outputs.length; ++i) {
bytes32 outputHash = hashOutput(outputs[i]);
assembly {
mstore(add(add(currentHash, 0x20), mul(i, 0x20)), outputHash)
}
}
return keccak256(currentHash);
}
}
}
文件 5 的 20:Errors.sol
pragma solidity >=0.8.0;
import { OrderContext, OrderStatus } from "../interfaces/Structs.sol";
error CannotProveOrder();
error ChallengeDeadlinePassed();
error CodeSize0();
error FailedValidation();
error FillDeadlineFarInFuture();
error FillDeadlineInPast();
error InitiateDeadlineAfterFill();
error InitiateDeadlinePassed();
error InvalidDeadlineOrder();
error InvalidSettlementAddress();
error LengthsDoesNotMatch(uint256, uint256);
error MinOrderPurchaseDiscountTooLow(uint256 minimum, uint256 configured);
error OnlyFiller();
error OrderAlreadyClaimed(OrderStatus orderStatus);
error OrderNotReadyForOptimisticPayout(uint32 time);
error OrderFinal();
error ProofPeriodHasNotPassed(uint32 time);
error PurchaseTimePassed();
error WrongChain(uint32 expected, uint32 actual);
error WrongOrderStatus(OrderStatus actual);
error WrongRemoteOracle(bytes32 addressThis, bytes32 expected);
文件 6 的 20:FillerDataLib.sol
pragma solidity ^0.8.26;
import { ISignatureTransfer } from "permit2/src/interfaces/ISignatureTransfer.sol";
import { ICrossCatsCallback } from "../interfaces/ICrossCatsCallback.sol";
import { Input } from "../interfaces/ISettlementContract.sol";
import { OrderKey } from "../interfaces/Structs.sol";
library FillerDataLib {
error NotImplemented(bytes1 version);
error IdentifierMismatch();
function decode(
bytes calldata fillerData
)
internal
view
returns (
address fillerAddress,
uint32 orderPurchaseDeadline,
uint16 orderPurchaseDiscount,
bytes32 identifier,
uint256 pointer
)
{
if (fillerData.length == 0) {
return (msg.sender, 0, 0, bytes32(0), 0);
}
bytes1 version = fillerData[0];
if (version == 0x00) {
return (msg.sender, 0, 0, bytes32(0), 1);
}
if (version == VERSION_1) {
(fillerAddress, orderPurchaseDeadline, orderPurchaseDiscount) = _decode1(fillerData);
return (fillerAddress, orderPurchaseDeadline, orderPurchaseDiscount, bytes32(0), V1_ORDER_DISCOUNT_END);
}
if (version == VERSION_2) {
(fillerAddress, orderPurchaseDeadline, orderPurchaseDiscount, identifier) = _decode2(fillerData);
return (fillerAddress, orderPurchaseDeadline, orderPurchaseDiscount, identifier, V2_CALLDATA_HASH_END);
}
revert NotImplemented(version);
}
function execute(bytes32 identifier, bytes32 orderKeyHash, bytes calldata executionData) internal {
if (identifier != keccak256(executionData)) revert IdentifierMismatch();
address toCall = address(bytes20(executionData[0:20]));
bytes calldata dataToCall = executionData[20:];
ICrossCatsCallback(toCall).inputsFilled(orderKeyHash, dataToCall);
}
bytes1 private constant VERSION_1 = 0x01;
uint256 private constant V1_ADDRESS_START = 1;
uint256 private constant V1_ADDRESS_END = 21;
uint256 private constant V1_ORDER_PURCHASE_DEADLINE_START = V1_ADDRESS_END;
uint256 private constant V1_ORDER_PURCHASE_DEADLINE_END = 25;
uint256 private constant V1_ORDER_DISCOUNT_START = V1_ORDER_PURCHASE_DEADLINE_END;
uint256 private constant V1_ORDER_DISCOUNT_END = 27;
function _decode1(
bytes calldata fillerData
) private pure returns (address fillerAddress, uint32 orderPurchaseDeadline, uint16 orderPurchaseDiscount) {
fillerAddress = address(uint160(bytes20(fillerData[V1_ADDRESS_START:V1_ADDRESS_END])));
orderPurchaseDeadline =
uint32(bytes4(fillerData[V1_ORDER_PURCHASE_DEADLINE_START:V1_ORDER_PURCHASE_DEADLINE_END]));
orderPurchaseDiscount = uint16(bytes2(fillerData[V1_ORDER_DISCOUNT_START:V1_ORDER_DISCOUNT_END]));
}
function _encode1(
address fillerAddress,
uint32 orderPurchaseDeadline,
uint16 orderPurchaseDiscount
) internal pure returns (bytes memory fillerData) {
return bytes.concat(
VERSION_1, bytes20(fillerAddress), bytes4(orderPurchaseDeadline), bytes2(orderPurchaseDiscount)
);
}
bytes1 private constant VERSION_2 = 0x02;
uint256 private constant V2_ADDRESS_START = 1;
uint256 private constant V2_ADDRESS_END = 21;
uint256 private constant V2_ORDER_PURCHASE_DEADLINE_START = V2_ADDRESS_END;
uint256 private constant V2_ORDER_PURCHASE_DEADLINE_END = 25;
uint256 private constant V2_ORDER_DISCOUNT_START = V2_ORDER_PURCHASE_DEADLINE_END;
uint256 private constant V2_ORDER_DISCOUNT_END = 27;
uint256 private constant V2_CALLDATA_HASH_START = V2_ORDER_DISCOUNT_END;
uint256 private constant V2_CALLDATA_HASH_END = 59;
function _decode2(
bytes calldata fillerData
)
private
pure
returns (address fillerAddress, uint32 orderPurchaseDeadline, uint16 orderPurchaseDiscount, bytes32 identifier)
{
fillerAddress = address(uint160(bytes20(fillerData[V2_ADDRESS_START:V2_ADDRESS_END])));
orderPurchaseDeadline =
uint32(bytes4(fillerData[V2_ORDER_PURCHASE_DEADLINE_START:V2_ORDER_PURCHASE_DEADLINE_END]));
orderPurchaseDiscount = uint16(bytes2(fillerData[V2_ORDER_DISCOUNT_START:V2_ORDER_DISCOUNT_END]));
identifier = bytes32(fillerData[V2_CALLDATA_HASH_START:V2_CALLDATA_HASH_END]);
}
function _encode2(
address fillerAddress,
uint32 orderPurchaseDeadline,
uint16 orderPurchaseDiscount,
bytes32 identifier
) internal pure returns (bytes memory fillerData) {
return bytes.concat(
VERSION_2, bytes20(fillerAddress), bytes4(orderPurchaseDeadline), bytes2(orderPurchaseDiscount), identifier
);
}
}
文件 7 的 20:ICrossCatsCallback.sol
pragma solidity >=0.8.0;
interface ICrossCatsCallback {
function outputFilled(bytes32 token, uint256 amount, bytes calldata executionData) external;
function inputsFilled(bytes32 orderKeyHash, bytes calldata executionData) external;
}
文件 8 的 20:IEIP712.sol
pragma solidity ^0.8.0;
interface IEIP712 {
function DOMAIN_SEPARATOR() external view returns (bytes32);
}
文件 9 的 20:IOracle.sol
pragma solidity >=0.8.0;
import { OutputDescription } from "./Structs.sol";
interface IOracle {
function isProven(OutputDescription[] calldata outputs, uint32 fillDeadline) external view returns (bool proven);
}
文件 10 的 20:ISettlementContract.sol
pragma solidity >=0.8.0;
import { OrderKey } from "./Structs.sol";
struct CrossChainOrder {
address settlementContract;
address swapper;
uint256 nonce;
uint32 originChainId;
uint32 initiateDeadline;
uint32 fillDeadline;
bytes orderData;
}
struct ResolvedCrossChainOrder {
address settlementContract;
address swapper;
uint256 nonce;
uint32 originChainId;
uint32 initiateDeadline;
uint32 fillDeadline;
Input[] swapperInputs;
Output[] swapperOutputs;
Output[] fillerOutputs;
}
struct Input {
address token;
uint256 amount;
}
struct Output {
bytes32 token;
uint256 amount;
bytes32 recipient;
uint32 chainId;
}
interface ISettlementContract {
function initiate(
CrossChainOrder calldata order,
bytes calldata signature,
bytes calldata fillerData
) external returns (OrderKey memory orderKey);
function resolve(
CrossChainOrder calldata order,
bytes calldata fillerData
) external view returns (ResolvedCrossChainOrder memory);
}
文件 11 的 20:ISignatureTransfer.sol
pragma solidity ^0.8.0;
import {IEIP712} from "./IEIP712.sol";
interface ISignatureTransfer is IEIP712 {
error InvalidAmount(uint256 maxAmount);
error LengthMismatch();
event UnorderedNonceInvalidation(address indexed owner, uint256 word, uint256 mask);
struct TokenPermissions {
address token;
uint256 amount;
}
struct PermitTransferFrom {
TokenPermissions permitted;
uint256 nonce;
uint256 deadline;
}
struct SignatureTransferDetails {
address to;
uint256 requestedAmount;
}
struct PermitBatchTransferFrom {
TokenPermissions[] permitted;
uint256 nonce;
uint256 deadline;
}
function nonceBitmap(address, uint256) external view returns (uint256);
function permitTransferFrom(
PermitTransferFrom memory permit,
SignatureTransferDetails calldata transferDetails,
address owner,
bytes calldata signature
) external;
function permitWitnessTransferFrom(
PermitTransferFrom memory permit,
SignatureTransferDetails calldata transferDetails,
address owner,
bytes32 witness,
string calldata witnessTypeString,
bytes calldata signature
) external;
function permitTransferFrom(
PermitBatchTransferFrom memory permit,
SignatureTransferDetails[] calldata transferDetails,
address owner,
bytes calldata signature
) external;
function permitWitnessTransferFrom(
PermitBatchTransferFrom memory permit,
SignatureTransferDetails[] calldata transferDetails,
address owner,
bytes32 witness,
string calldata witnessTypeString,
bytes calldata signature
) external;
function invalidateUnorderedNonces(uint256 wordPos, uint256 mask) external;
}
文件 12 的 20:IsContractLib.sol
pragma solidity ^0.8.26;
import { CodeSize0 } from "../interfaces/Errors.sol";
library IsContractLib {
function checkCodeSize(
address addr
) internal view {
uint256 size;
assembly ("memory-safe") {
size := extcodesize(addr)
}
if (size == 0) revert CodeSize0();
}
}
文件 13 的 20:LimitOrderReactor.sol
pragma solidity ^0.8.26;
import { CrossChainOrder, Input, ResolvedCrossChainOrder } from "../interfaces/ISettlementContract.sol";
import { Collateral, OrderKey, OutputDescription, ReactorInfo } from "../interfaces/Structs.sol";
import { CatalystLimitOrderData, CrossChainLimitOrderType } from "../libs/ordertypes/CrossChainLimitOrderType.sol";
import { CrossChainOrderType } from "../libs/ordertypes/CrossChainOrderType.sol";
import { BaseReactor } from "./BaseReactor.sol";
contract LimitOrderReactor is BaseReactor {
constructor(address permit2, address owner) payable BaseReactor(permit2, owner) { }
function _initiate(
CrossChainOrder calldata order,
bytes calldata
)
internal
pure
override
returns (
OrderKey memory orderKey,
uint256[] memory permittedAmounts,
bytes32 witness,
string memory witnessTypeString
)
{
CatalystLimitOrderData memory limitOrderData = CrossChainLimitOrderType.decodeOrderData(order.orderData);
uint256 numInputs = limitOrderData.inputs.length;
permittedAmounts = new uint256[](numInputs);
for (uint256 i = 0; i < numInputs; ++i) {
permittedAmounts[i] = limitOrderData.inputs[i].amount;
}
witness = CrossChainLimitOrderType.crossOrderHash(order, limitOrderData);
witnessTypeString = CrossChainLimitOrderType.PERMIT2_LIMIT_ORDER_WITNESS_STRING_TYPE;
orderKey = _resolveKey(order, limitOrderData);
}
function _resolveKey(
CrossChainOrder calldata order,
bytes calldata
) internal pure override returns (OrderKey memory orderKey) {
CatalystLimitOrderData memory limitData = CrossChainLimitOrderType.decodeOrderData(order.orderData);
return _resolveKey(order, limitData);
}
function _resolveKey(
CrossChainOrder calldata order,
CatalystLimitOrderData memory limitData
) internal pure returns (OrderKey memory orderKey) {
Input[] memory inputs = limitData.inputs;
OutputDescription[] memory outputs = limitData.outputs;
orderKey = OrderKey({
reactorContext: ReactorInfo({
reactor: order.settlementContract,
fillDeadline: order.fillDeadline,
challengeDeadline: limitData.challengeDeadline,
proofDeadline: limitData.proofDeadline
}),
swapper: order.swapper,
nonce: uint96(order.nonce),
collateral: Collateral({
collateralToken: limitData.collateralToken,
fillerCollateralAmount: limitData.fillerCollateralAmount,
challengerCollateralAmount: limitData.challengerCollateralAmount
}),
originChainId: order.originChainId,
localOracle: limitData.localOracle,
inputs: inputs,
outputs: outputs
});
}
}
文件 14 的 20:Ownable.sol
pragma solidity ^0.8.4;
abstract contract Ownable {
error Unauthorized();
error NewOwnerIsZeroAddress();
error NoHandoverRequest();
error AlreadyInitialized();
event OwnershipTransferred(address indexed oldOwner, address indexed newOwner);
event OwnershipHandoverRequested(address indexed pendingOwner);
event OwnershipHandoverCanceled(address indexed pendingOwner);
uint256 private constant _OWNERSHIP_TRANSFERRED_EVENT_SIGNATURE =
0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0;
uint256 private constant _OWNERSHIP_HANDOVER_REQUESTED_EVENT_SIGNATURE =
0xdbf36a107da19e49527a7176a1babf963b4b0ff8cde35ee35d6cd8f1f9ac7e1d;
uint256 private constant _OWNERSHIP_HANDOVER_CANCELED_EVENT_SIGNATURE =
0xfa7b8eab7da67f412cc9575ed43464468f9bfbae89d1675917346ca6d8fe3c92;
bytes32 internal constant _OWNER_SLOT =
0xffffffffffffffffffffffffffffffffffffffffffffffffffffffff74873927;
uint256 private constant _HANDOVER_SLOT_SEED = 0x389a75e1;
function _guardInitializeOwner() internal pure virtual returns (bool guard) {}
function _initializeOwner(address newOwner) internal virtual {
if (_guardInitializeOwner()) {
assembly {
let ownerSlot := _OWNER_SLOT
if sload(ownerSlot) {
mstore(0x00, 0x0dc149f0)
revert(0x1c, 0x04)
}
newOwner := shr(96, shl(96, newOwner))
sstore(ownerSlot, or(newOwner, shl(255, iszero(newOwner))))
log3(0, 0, _OWNERSHIP_TRANSFERRED_EVENT_SIGNATURE, 0, newOwner)
}
} else {
assembly {
newOwner := shr(96, shl(96, newOwner))
sstore(_OWNER_SLOT, newOwner)
log3(0, 0, _OWNERSHIP_TRANSFERRED_EVENT_SIGNATURE, 0, newOwner)
}
}
}
function _setOwner(address newOwner) internal virtual {
if (_guardInitializeOwner()) {
assembly {
let ownerSlot := _OWNER_SLOT
newOwner := shr(96, shl(96, newOwner))
log3(0, 0, _OWNERSHIP_TRANSFERRED_EVENT_SIGNATURE, sload(ownerSlot), newOwner)
sstore(ownerSlot, or(newOwner, shl(255, iszero(newOwner))))
}
} else {
assembly {
let ownerSlot := _OWNER_SLOT
newOwner := shr(96, shl(96, newOwner))
log3(0, 0, _OWNERSHIP_TRANSFERRED_EVENT_SIGNATURE, sload(ownerSlot), newOwner)
sstore(ownerSlot, newOwner)
}
}
}
function _checkOwner() internal view virtual {
assembly {
if iszero(eq(caller(), sload(_OWNER_SLOT))) {
mstore(0x00, 0x82b42900)
revert(0x1c, 0x04)
}
}
}
function _ownershipHandoverValidFor() internal view virtual returns (uint64) {
return 48 * 3600;
}
function transferOwnership(address newOwner) public payable virtual onlyOwner {
assembly {
if iszero(shl(96, newOwner)) {
mstore(0x00, 0x7448fbae)
revert(0x1c, 0x04)
}
}
_setOwner(newOwner);
}
function renounceOwnership() public payable virtual onlyOwner {
_setOwner(address(0));
}
function requestOwnershipHandover() public payable virtual {
unchecked {
uint256 expires = block.timestamp + _ownershipHandoverValidFor();
assembly {
mstore(0x0c, _HANDOVER_SLOT_SEED)
mstore(0x00, caller())
sstore(keccak256(0x0c, 0x20), expires)
log2(0, 0, _OWNERSHIP_HANDOVER_REQUESTED_EVENT_SIGNATURE, caller())
}
}
}
function cancelOwnershipHandover() public payable virtual {
assembly {
mstore(0x0c, _HANDOVER_SLOT_SEED)
mstore(0x00, caller())
sstore(keccak256(0x0c, 0x20), 0)
log2(0, 0, _OWNERSHIP_HANDOVER_CANCELED_EVENT_SIGNATURE, caller())
}
}
function completeOwnershipHandover(address pendingOwner) public payable virtual onlyOwner {
assembly {
mstore(0x0c, _HANDOVER_SLOT_SEED)
mstore(0x00, pendingOwner)
let handoverSlot := keccak256(0x0c, 0x20)
if gt(timestamp(), sload(handoverSlot)) {
mstore(0x00, 0x6f5e8818)
revert(0x1c, 0x04)
}
sstore(handoverSlot, 0)
}
_setOwner(pendingOwner);
}
function owner() public view virtual returns (address result) {
assembly {
result := sload(_OWNER_SLOT)
}
}
function ownershipHandoverExpiresAt(address pendingOwner)
public
view
virtual
returns (uint256 result)
{
assembly {
mstore(0x0c, _HANDOVER_SLOT_SEED)
mstore(0x00, pendingOwner)
result := sload(keccak256(0x0c, 0x20))
}
}
modifier onlyOwner() virtual {
_checkOwner();
_;
}
}
文件 15 的 20:Permit2Lib.sol
pragma solidity ^0.8.26;
import { ISignatureTransfer } from "permit2/src/interfaces/ISignatureTransfer.sol";
import { IsContractLib } from "./IsContractLib.sol";
import { Input } from "../interfaces/ISettlementContract.sol";
import { OrderKey } from "../interfaces/Structs.sol";
library Permit2Lib {
function toPermit(
OrderKey memory order,
uint256[] memory permittedAmounts,
address to,
uint32 deadline
)
internal
view
returns (
ISignatureTransfer.PermitBatchTransferFrom memory permitBatch,
ISignatureTransfer.SignatureTransferDetails[] memory transferDetails
)
{
uint256 numInputs = order.inputs.length;
ISignatureTransfer.TokenPermissions[] memory permitted = new ISignatureTransfer.TokenPermissions[](numInputs);
transferDetails = new ISignatureTransfer.SignatureTransferDetails[](numInputs);
for (uint256 i; i < numInputs; ++i) {
IsContractLib.checkCodeSize(order.inputs[i].token);
permitted[i] =
ISignatureTransfer.TokenPermissions({ token: order.inputs[i].token, amount: permittedAmounts[i] });
transferDetails[i] =
ISignatureTransfer.SignatureTransferDetails({ to: to, requestedAmount: order.inputs[i].amount });
}
permitBatch =
ISignatureTransfer.PermitBatchTransferFrom({ permitted: permitted, nonce: order.nonce, deadline: deadline });
}
function inputsToPermittedAmounts(
Input[] memory inputs
) internal pure returns (uint256[] memory permittedAmounts) {
uint256 numInputs = inputs.length;
permittedAmounts = new uint256[](numInputs);
for (uint256 i = 0; i < numInputs; ++i) {
permittedAmounts[i] = inputs[i].amount;
}
}
}
文件 16 的 20:ReactorAbstractions.sol
pragma solidity ^0.8.26;
import { CrossChainOrder, ISettlementContract, Input, Output } from "../../interfaces/ISettlementContract.sol";
import { OrderKey } from "../../interfaces/Structs.sol";
abstract contract ReactorAbstractions is ISettlementContract {
function _initiate(
CrossChainOrder calldata order,
bytes calldata fillerData
)
internal
virtual
returns (
OrderKey memory orderKey,
uint256[] memory permittedAmounts,
bytes32 witness,
string memory witnessTypeString
);
function _resolveKey(
CrossChainOrder calldata order,
bytes calldata fillerData
) internal view virtual returns (OrderKey memory);
}
文件 17 的 20:ReactorPayments.sol
pragma solidity ^0.8.26;
import { ISignatureTransfer } from "permit2/src/interfaces/ISignatureTransfer.sol";
import { SafeTransferLib } from "solady/src/utils/SafeTransferLib.sol";
import { Input } from "../../interfaces/ISettlementContract.sol";
import { OrderContext, OrderKey } from "../../interfaces/Structs.sol";
import { CanCollectGovernanceFee } from "../../libs/CanCollectGovernanceFee.sol";
import { Permit2Lib } from "../../libs/Permit2Lib.sol";
abstract contract ReactorPayments is CanCollectGovernanceFee {
using Permit2Lib for OrderKey;
ISignatureTransfer public immutable PERMIT2;
constructor(address permit2, address owner) payable CanCollectGovernanceFee(owner) {
PERMIT2 = ISignatureTransfer(permit2);
}
function _collectTokensViaPermit2(
OrderKey memory orderKey,
uint256[] memory permittedAmounts,
uint32 permitDeadline,
address owner,
bytes32 witness,
string memory witnessTypeString,
bytes calldata signature
) internal virtual {
(
ISignatureTransfer.PermitBatchTransferFrom memory permitBatch,
ISignatureTransfer.SignatureTransferDetails[] memory transferDetails
) = orderKey.toPermit(permittedAmounts, address(this), permitDeadline);
PERMIT2.permitWitnessTransferFrom(permitBatch, transferDetails, owner, witness, witnessTypeString, signature);
}
function _collectTokensFromMsgSender(Input[] calldata inputs, address to, uint16 discount) internal virtual {
address from = msg.sender;
uint256 numInputs = inputs.length;
unchecked {
for (uint256 i = 0; i < numInputs; ++i) {
Input calldata input = inputs[i];
address token = input.token;
uint256 amount = input.amount;
amount = (discount != 0 && amount < type(uint256).max / uint256(discount))
? amount - (amount * uint256(discount)) / uint256(type(uint16).max)
: amount;
SafeTransferLib.safeTransferFrom(token, from, to, amount);
}
}
}
function _deliverTokens(Input[] calldata inputs, address to, uint256 fee) internal virtual {
uint256 numInputs = inputs.length;
for (uint256 i; i < numInputs; ++i) {
Input calldata input = inputs[i];
address token = input.token;
uint256 amount = input.amount;
amount = fee == 0 ? amount : _collectGovernanceFee(token, amount, fee);
SafeTransferLib.safeTransfer(token, to, amount);
}
}
}
文件 18 的 20:ResolverERC7683.sol
pragma solidity ^0.8.26;
import { CrossChainOrder, Input, Output, ResolvedCrossChainOrder } from "../../interfaces/ISettlementContract.sol";
import { OrderKey, OutputDescription } from "../../interfaces/Structs.sol";
import { FillerDataLib } from "../../libs/FillerDataLib.sol";
import { ICanCollectGovernanceFee } from "../../libs/CanCollectGovernanceFee.sol";
import { ReactorAbstractions } from "./ReactorAbstractions.sol";
abstract contract ResolverERC7683 is ICanCollectGovernanceFee, ReactorAbstractions {
function resolveKey(
CrossChainOrder calldata order,
bytes calldata fillerData
) external view returns (OrderKey memory orderKey) {
return orderKey = _resolveKey(order, fillerData);
}
function _resolve(
CrossChainOrder calldata order,
bytes calldata fillerData
) internal view virtual returns (ResolvedCrossChainOrder memory resolvedOrder) {
OrderKey memory orderKey = _resolveKey(order, fillerData);
(address fillerAddress,,,,) = FillerDataLib.decode(fillerData);
Input[] memory swapperInputs = orderKey.inputs;
uint256 numOutputs = orderKey.outputs.length;
Output[] memory swapperOutputs = new Output[](numOutputs);
for (uint256 i = 0; i < numOutputs; ++i) {
OutputDescription memory catalystOutput = orderKey.outputs[i];
swapperOutputs[i] = Output({
token: catalystOutput.token,
amount: catalystOutput.amount,
recipient: catalystOutput.recipient,
chainId: catalystOutput.chainId
});
}
uint256 numInputs = swapperInputs.length;
Output[] memory fillerOutputs = new Output[](numInputs);
Output memory fillerOutput;
unchecked {
for (uint256 i; i < numInputs; ++i) {
Input memory input = swapperInputs[i];
fillerOutput = Output({
token: bytes32(uint256(uint160(input.token))),
amount: input.amount - _calcFee(input.amount),
recipient: bytes32(uint256(uint160(fillerAddress))),
chainId: uint32(block.chainid)
});
fillerOutputs[i] = fillerOutput;
}
}
resolvedOrder = ResolvedCrossChainOrder({
settlementContract: order.settlementContract,
swapper: order.swapper,
nonce: order.nonce,
originChainId: order.originChainId,
initiateDeadline: order.initiateDeadline,
fillDeadline: order.fillDeadline,
swapperInputs: swapperInputs,
swapperOutputs: swapperOutputs,
fillerOutputs: fillerOutputs
});
}
function resolve(
CrossChainOrder calldata order,
bytes calldata fillerData
) external view returns (ResolvedCrossChainOrder memory resolvedOrder) {
return _resolve(order, fillerData);
}
}
文件 19 的 20:SafeTransferLib.sol
pragma solidity ^0.8.4;
library SafeTransferLib {
error ETHTransferFailed();
error TransferFromFailed();
error TransferFailed();
error ApproveFailed();
error Permit2Failed();
error Permit2AmountOverflow();
uint256 internal constant GAS_STIPEND_NO_STORAGE_WRITES = 2300;
uint256 internal constant GAS_STIPEND_NO_GRIEF = 100000;
bytes32 internal constant DAI_DOMAIN_SEPARATOR =
0xdbb8cf42e1ecb028be3f3dbc922e1d878b963f411dc388ced501601c60f7c6f7;
address internal constant WETH9 = 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2;
address internal constant PERMIT2 = 0x000000000022D473030F116dDEE9F6B43aC78BA3;
function safeTransferETH(address to, uint256 amount) internal {
assembly {
if iszero(call(gas(), to, amount, codesize(), 0x00, codesize(), 0x00)) {
mstore(0x00, 0xb12d13eb)
revert(0x1c, 0x04)
}
}
}
function safeTransferAllETH(address to) internal {
assembly {
if iszero(call(gas(), to, selfbalance(), codesize(), 0x00, codesize(), 0x00)) {
mstore(0x00, 0xb12d13eb)
revert(0x1c, 0x04)
}
}
}
function forceSafeTransferETH(address to, uint256 amount, uint256 gasStipend) internal {
assembly {
if lt(selfbalance(), amount) {
mstore(0x00, 0xb12d13eb)
revert(0x1c, 0x04)
}
if iszero(call(gasStipend, to, amount, codesize(), 0x00, codesize(), 0x00)) {
mstore(0x00, to)
mstore8(0x0b, 0x73)
mstore8(0x20, 0xff)
if iszero(create(amount, 0x0b, 0x16)) { revert(codesize(), codesize()) }
}
}
}
function forceSafeTransferAllETH(address to, uint256 gasStipend) internal {
assembly {
if iszero(call(gasStipend, to, selfbalance(), codesize(), 0x00, codesize(), 0x00)) {
mstore(0x00, to)
mstore8(0x0b, 0x73)
mstore8(0x20, 0xff)
if iszero(create(selfbalance(), 0x0b, 0x16)) { revert(codesize(), codesize()) }
}
}
}
function forceSafeTransferETH(address to, uint256 amount) internal {
assembly {
if lt(selfbalance(), amount) {
mstore(0x00, 0xb12d13eb)
revert(0x1c, 0x04)
}
if iszero(call(GAS_STIPEND_NO_GRIEF, to, amount, codesize(), 0x00, codesize(), 0x00)) {
mstore(0x00, to)
mstore8(0x0b, 0x73)
mstore8(0x20, 0xff)
if iszero(create(amount, 0x0b, 0x16)) { revert(codesize(), codesize()) }
}
}
}
function forceSafeTransferAllETH(address to) internal {
assembly {
if iszero(call(GAS_STIPEND_NO_GRIEF, to, selfbalance(), codesize(), 0x00, codesize(), 0x00)) {
mstore(0x00, to)
mstore8(0x0b, 0x73)
mstore8(0x20, 0xff)
if iszero(create(selfbalance(), 0x0b, 0x16)) { revert(codesize(), codesize()) }
}
}
}
function trySafeTransferETH(address to, uint256 amount, uint256 gasStipend)
internal
returns (bool success)
{
assembly {
success := call(gasStipend, to, amount, codesize(), 0x00, codesize(), 0x00)
}
}
function trySafeTransferAllETH(address to, uint256 gasStipend)
internal
returns (bool success)
{
assembly {
success := call(gasStipend, to, selfbalance(), codesize(), 0x00, codesize(), 0x00)
}
}
function safeTransferFrom(address token, address from, address to, uint256 amount) internal {
assembly {
let m := mload(0x40)
mstore(0x60, amount)
mstore(0x40, to)
mstore(0x2c, shl(96, from))
mstore(0x0c, 0x23b872dd000000000000000000000000)
if iszero(
and(
or(eq(mload(0x00), 1), iszero(returndatasize())),
call(gas(), token, 0, 0x1c, 0x64, 0x00, 0x20)
)
) {
mstore(0x00, 0x7939f424)
revert(0x1c, 0x04)
}
mstore(0x60, 0)
mstore(0x40, m)
}
}
function trySafeTransferFrom(address token, address from, address to, uint256 amount)
internal
returns (bool success)
{
assembly {
let m := mload(0x40)
mstore(0x60, amount)
mstore(0x40, to)
mstore(0x2c, shl(96, from))
mstore(0x0c, 0x23b872dd000000000000000000000000)
success :=
and(
or(eq(mload(0x00), 1), iszero(returndatasize())),
call(gas(), token, 0, 0x1c, 0x64, 0x00, 0x20)
)
mstore(0x60, 0)
mstore(0x40, m)
}
}
function safeTransferAllFrom(address token, address from, address to)
internal
returns (uint256 amount)
{
assembly {
let m := mload(0x40)
mstore(0x40, to)
mstore(0x2c, shl(96, from))
mstore(0x0c, 0x70a08231000000000000000000000000)
if iszero(
and(
gt(returndatasize(), 0x1f),
staticcall(gas(), token, 0x1c, 0x24, 0x60, 0x20)
)
) {
mstore(0x00, 0x7939f424)
revert(0x1c, 0x04)
}
mstore(0x00, 0x23b872dd)
amount := mload(0x60)
if iszero(
and(
or(eq(mload(0x00), 1), iszero(returndatasize())),
call(gas(), token, 0, 0x1c, 0x64, 0x00, 0x20)
)
) {
mstore(0x00, 0x7939f424)
revert(0x1c, 0x04)
}
mstore(0x60, 0)
mstore(0x40, m)
}
}
function safeTransfer(address token, address to, uint256 amount) internal {
assembly {
mstore(0x14, to)
mstore(0x34, amount)
mstore(0x00, 0xa9059cbb000000000000000000000000)
if iszero(
and(
or(eq(mload(0x00), 1), iszero(returndatasize())),
call(gas(), token, 0, 0x10, 0x44, 0x00, 0x20)
)
) {
mstore(0x00, 0x90b8ec18)
revert(0x1c, 0x04)
}
mstore(0x34, 0)
}
}
function safeTransferAll(address token, address to) internal returns (uint256 amount) {
assembly {
mstore(0x00, 0x70a08231)
mstore(0x20, address())
if iszero(
and(
gt(returndatasize(), 0x1f),
staticcall(gas(), token, 0x1c, 0x24, 0x34, 0x20)
)
) {
mstore(0x00, 0x90b8ec18)
revert(0x1c, 0x04)
}
mstore(0x14, to)
amount := mload(0x34)
mstore(0x00, 0xa9059cbb000000000000000000000000)
if iszero(
and(
or(eq(mload(0x00), 1), iszero(returndatasize())),
call(gas(), token, 0, 0x10, 0x44, 0x00, 0x20)
)
) {
mstore(0x00, 0x90b8ec18)
revert(0x1c, 0x04)
}
mstore(0x34, 0)
}
}
function safeApprove(address token, address to, uint256 amount) internal {
assembly {
mstore(0x14, to)
mstore(0x34, amount)
mstore(0x00, 0x095ea7b3000000000000000000000000)
if iszero(
and(
or(eq(mload(0x00), 1), iszero(returndatasize())),
call(gas(), token, 0, 0x10, 0x44, 0x00, 0x20)
)
) {
mstore(0x00, 0x3e3f8f73)
revert(0x1c, 0x04)
}
mstore(0x34, 0)
}
}
function safeApproveWithRetry(address token, address to, uint256 amount) internal {
assembly {
mstore(0x14, to)
mstore(0x34, amount)
mstore(0x00, 0x095ea7b3000000000000000000000000)
if iszero(
and(
or(eq(mload(0x00), 1), iszero(returndatasize())),
call(gas(), token, 0, 0x10, 0x44, 0x00, 0x20)
)
) {
mstore(0x34, 0)
mstore(0x00, 0x095ea7b3000000000000000000000000)
pop(call(gas(), token, 0, 0x10, 0x44, codesize(), 0x00))
mstore(0x34, amount)
if iszero(
and(
or(eq(mload(0x00), 1), iszero(returndatasize())),
call(gas(), token, 0, 0x10, 0x44, 0x00, 0x20)
)
) {
mstore(0x00, 0x3e3f8f73)
revert(0x1c, 0x04)
}
}
mstore(0x34, 0)
}
}
function balanceOf(address token, address account) internal view returns (uint256 amount) {
assembly {
mstore(0x14, account)
mstore(0x00, 0x70a08231000000000000000000000000)
amount :=
mul(
mload(0x20),
and(
gt(returndatasize(), 0x1f),
staticcall(gas(), token, 0x10, 0x24, 0x20, 0x20)
)
)
}
}
function safeTransferFrom2(address token, address from, address to, uint256 amount) internal {
if (!trySafeTransferFrom(token, from, to, amount)) {
permit2TransferFrom(token, from, to, amount);
}
}
function permit2TransferFrom(address token, address from, address to, uint256 amount)
internal
{
assembly {
let m := mload(0x40)
mstore(add(m, 0x74), shr(96, shl(96, token)))
mstore(add(m, 0x54), amount)
mstore(add(m, 0x34), to)
mstore(add(m, 0x20), shl(96, from))
mstore(m, 0x36c78516000000000000000000000000)
let p := PERMIT2
let exists := eq(chainid(), 1)
if iszero(exists) { exists := iszero(iszero(extcodesize(p))) }
if iszero(and(call(gas(), p, 0, add(m, 0x10), 0x84, codesize(), 0x00), exists)) {
mstore(0x00, 0x7939f4248757f0fd)
revert(add(0x18, shl(2, iszero(iszero(shr(160, amount))))), 0x04)
}
}
}
function permit2(
address token,
address owner,
address spender,
uint256 amount,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) internal {
bool success;
assembly {
for {} shl(96, xor(token, WETH9)) {} {
mstore(0x00, 0x3644e515)
if iszero(
and(
lt(iszero(mload(0x00)), eq(returndatasize(), 0x20)),
staticcall(5000, token, 0x1c, 0x04, 0x00, 0x20)
)
) { break }
let m := mload(0x40)
mstore(add(m, 0x34), spender)
mstore(add(m, 0x20), shl(96, owner))
mstore(add(m, 0x74), deadline)
if eq(mload(0x00), DAI_DOMAIN_SEPARATOR) {
mstore(0x14, owner)
mstore(0x00, 0x7ecebe00000000000000000000000000)
mstore(add(m, 0x94), staticcall(gas(), token, 0x10, 0x24, add(m, 0x54), 0x20))
mstore(m, 0x8fcbaf0c000000000000000000000000)
mstore(add(m, 0xb4), and(0xff, v))
mstore(add(m, 0xd4), r)
mstore(add(m, 0xf4), s)
success := call(gas(), token, 0, add(m, 0x10), 0x104, codesize(), 0x00)
break
}
mstore(m, 0xd505accf000000000000000000000000)
mstore(add(m, 0x54), amount)
mstore(add(m, 0x94), and(0xff, v))
mstore(add(m, 0xb4), r)
mstore(add(m, 0xd4), s)
success := call(gas(), token, 0, add(m, 0x10), 0xe4, codesize(), 0x00)
break
}
}
if (!success) simplePermit2(token, owner, spender, amount, deadline, v, r, s);
}
function simplePermit2(
address token,
address owner,
address spender,
uint256 amount,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) internal {
assembly {
let m := mload(0x40)
mstore(m, 0x927da105)
{
let addressMask := shr(96, not(0))
mstore(add(m, 0x20), and(addressMask, owner))
mstore(add(m, 0x40), and(addressMask, token))
mstore(add(m, 0x60), and(addressMask, spender))
mstore(add(m, 0xc0), and(addressMask, spender))
}
let p := mul(PERMIT2, iszero(shr(160, amount)))
if iszero(
and(
gt(returndatasize(), 0x5f),
staticcall(gas(), p, add(m, 0x1c), 0x64, add(m, 0x60), 0x60)
)
) {
mstore(0x00, 0x6b836e6b8757f0fd)
revert(add(0x18, shl(2, iszero(p))), 0x04)
}
mstore(m, 0x2b67b570)
mstore(add(m, 0x60), amount)
mstore(add(m, 0x80), 0xffffffffffff)
mstore(add(m, 0xe0), deadline)
mstore(add(m, 0x100), 0x100)
mstore(add(m, 0x120), 0x41)
mstore(add(m, 0x140), r)
mstore(add(m, 0x160), s)
mstore(add(m, 0x180), shl(248, v))
if iszero(call(gas(), p, 0, add(m, 0x1c), 0x184, codesize(), 0x00)) {
mstore(0x00, 0x6b836e6b)
revert(0x1c, 0x04)
}
}
}
}
文件 20 的 20:Structs.sol
pragma solidity >=0.8.0;
import { Input } from "./ISettlementContract.sol";
enum OrderStatus {
Unfilled,
Deposited,
Claimed,
Challenged,
Fraud,
OptimiscallyFilled,
Proven
}
struct OrderContext {
OrderStatus status;
address fillerAddress;
uint32 orderPurchaseDeadline;
uint16 orderPurchaseDiscount;
address challenger;
bytes32 identifier;
}
struct OutputDescription {
bytes32 remoteOracle;
bytes32 token;
uint256 amount;
bytes32 recipient;
uint32 chainId;
bytes remoteCall;
}
struct OrderKey {
ReactorInfo reactorContext;
address swapper;
uint96 nonce;
Collateral collateral;
uint32 originChainId;
address localOracle;
Input[] inputs;
OutputDescription[] outputs;
}
struct ReactorInfo {
address reactor;
uint32 fillDeadline;
uint32 challengeDeadline;
uint32 proofDeadline;
}
struct Collateral {
address collateralToken;
uint256 fillerCollateralAmount;
uint256 challengerCollateralAmount;
}
{
"compilationTarget": {
"src/reactors/LimitOrderReactor.sol": "LimitOrderReactor"
},
"evmVersion": "paris",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs"
},
"optimizer": {
"enabled": true,
"runs": 10000
},
"remappings": [
":@lazyledger/protobuf3-solidity-lib/=lib/GeneralisedIncentives/lib/vibc-core-smart-contracts/lib/protobuf3-solidity-lib/",
":@openzeppelin-upgradeable/=lib/GeneralisedIncentives/lib/vibc-core-smart-contracts/lib/openzeppelin-contracts-upgradeable/",
":@openzeppelin/=lib/GeneralisedIncentives/lib/vibc-core-smart-contracts/lib/openzeppelin-contracts/",
":GeneralisedIncentives/=lib/GeneralisedIncentives/src/",
":base64/=lib/GeneralisedIncentives/lib/vibc-core-smart-contracts/lib/base64/",
":bitcoinprism-evm/=lib/bitcoinprism-evm/",
":clones-with-immutable-args/=lib/GeneralisedIncentives/lib/vibc-core-smart-contracts/lib/optimism/packages/contracts-bedrock/lib/clones-with-immutable-args/src/",
":ds-test/=lib/forge-std/lib/ds-test/src/",
":erc4626-tests/=lib/GeneralisedIncentives/lib/openzeppelin-contracts/lib/erc4626-tests/",
":forge-gas-snapshot/=lib/permit2/lib/forge-gas-snapshot/src/",
":forge-std/=lib/forge-std/src/",
":openzeppelin-contracts-upgradeable/=lib/GeneralisedIncentives/lib/vibc-core-smart-contracts/lib/openzeppelin-contracts-upgradeable/",
":openzeppelin-contracts/=lib/GeneralisedIncentives/lib/openzeppelin-contracts/",
":openzeppelin/=lib/GeneralisedIncentives/lib/openzeppelin-contracts/contracts/",
":optimism/=lib/GeneralisedIncentives/lib/vibc-core-smart-contracts/lib/",
":permit2/=lib/permit2/",
":proto/=lib/GeneralisedIncentives/lib/vibc-core-smart-contracts/lib/proto/",
":protobuf3-solidity-lib/=lib/GeneralisedIncentives/lib/vibc-core-smart-contracts/lib/protobuf3-solidity-lib/contracts/",
":safe-contracts/=lib/GeneralisedIncentives/lib/vibc-core-smart-contracts/lib/optimism/packages/contracts-bedrock/lib/safe-contracts/contracts/",
":solady/=lib/solady/",
":solmate/=lib/permit2/lib/solmate/",
":vibc-core-smart-contracts/=lib/GeneralisedIncentives/lib/vibc-core-smart-contracts/"
],
"viaIR": true
}
[{"inputs":[{"internalType":"address","name":"permit2","type":"address"},{"internalType":"address","name":"owner","type":"address"}],"stateMutability":"payable","type":"constructor"},{"inputs":[],"name":"AlreadyInitialized","type":"error"},{"inputs":[],"name":"CannotProveOrder","type":"error"},{"inputs":[],"name":"ChallengeDeadlinePassed","type":"error"},{"inputs":[],"name":"CodeSize0","type":"error"},{"inputs":[],"name":"GovernanceFeeChangeNotReady","type":"error"},{"inputs":[],"name":"GovernanceFeeTooHigh","type":"error"},{"inputs":[],"name":"IdentifierMismatch","type":"error"},{"inputs":[],"name":"InitiateDeadlineAfterFill","type":"error"},{"inputs":[],"name":"InitiateDeadlinePassed","type":"error"},{"inputs":[],"name":"InvalidDeadlineOrder","type":"error"},{"inputs":[],"name":"InvalidSettlementAddress","type":"error"},{"inputs":[{"internalType":"uint256","name":"minimum","type":"uint256"},{"internalType":"uint256","name":"configured","type":"uint256"}],"name":"MinOrderPurchaseDiscountTooLow","type":"error"},{"inputs":[],"name":"NewOwnerIsZeroAddress","type":"error"},{"inputs":[],"name":"NoHandoverRequest","type":"error"},{"inputs":[{"internalType":"bytes1","name":"version","type":"bytes1"}],"name":"NotImplemented","type":"error"},{"inputs":[],"name":"OnlyFiller","type":"error"},{"inputs":[{"internalType":"enum OrderStatus","name":"orderStatus","type":"uint8"}],"name":"OrderAlreadyClaimed","type":"error"},{"inputs":[],"name":"OrderFinal","type":"error"},{"inputs":[{"internalType":"uint32","name":"time","type":"uint32"}],"name":"OrderNotReadyForOptimisticPayout","type":"error"},{"inputs":[{"internalType":"uint32","name":"time","type":"uint32"}],"name":"ProofPeriodHasNotPassed","type":"error"},{"inputs":[],"name":"PurchaseTimePassed","type":"error"},{"inputs":[],"name":"Unauthorized","type":"error"},{"inputs":[{"internalType":"uint32","name":"expected","type":"uint32"},{"internalType":"uint32","name":"actual","type":"uint32"}],"name":"WrongChain","type":"error"},{"inputs":[{"internalType":"enum OrderStatus","name":"actual","type":"uint8"}],"name":"WrongOrderStatus","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"orderHash","type":"bytes32"}],"name":"FraudAccepted","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint64","name":"oldGovernanceFee","type":"uint64"},{"indexed":false,"internalType":"uint64","name":"newGovernanceFee","type":"uint64"}],"name":"GovernanceFeeChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"address[]","name":"tokens","type":"address[]"},{"indexed":false,"internalType":"uint256[]","name":"collectedAmounts","type":"uint256[]"}],"name":"GovernanceFeesDistributed","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint64","name":"nextGovernanceFee","type":"uint64"},{"indexed":false,"internalType":"uint64","name":"nextGovernanceFeeTime","type":"uint64"}],"name":"NextGovernanceFee","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"orderHash","type":"bytes32"}],"name":"OptimisticPayout","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"orderHash","type":"bytes32"},{"components":[{"internalType":"address","name":"settlementContract","type":"address"},{"internalType":"address","name":"swapper","type":"address"},{"internalType":"uint256","name":"nonce","type":"uint256"},{"internalType":"uint32","name":"originChainId","type":"uint32"},{"internalType":"uint32","name":"initiateDeadline","type":"uint32"},{"internalType":"uint32","name":"fillDeadline","type":"uint32"},{"internalType":"bytes","name":"orderData","type":"bytes"}],"indexed":false,"internalType":"struct CrossChainOrder","name":"order","type":"tuple"},{"indexed":false,"internalType":"bytes","name":"signature","type":"bytes"}],"name":"OrderBroadcast","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"orderHash","type":"bytes32"},{"indexed":true,"internalType":"address","name":"disputer","type":"address"}],"name":"OrderChallenged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"orderHash","type":"bytes32"},{"indexed":true,"internalType":"address","name":"caller","type":"address"},{"indexed":false,"internalType":"bytes","name":"filler","type":"bytes"},{"components":[{"components":[{"internalType":"address","name":"reactor","type":"address"},{"internalType":"uint32","name":"fillDeadline","type":"uint32"},{"internalType":"uint32","name":"challengeDeadline","type":"uint32"},{"internalType":"uint32","name":"proofDeadline","type":"uint32"}],"internalType":"struct ReactorInfo","name":"reactorContext","type":"tuple"},{"internalType":"address","name":"swapper","type":"address"},{"internalType":"uint96","name":"nonce","type":"uint96"},{"components":[{"internalType":"address","name":"collateralToken","type":"address"},{"internalType":"uint256","name":"fillerCollateralAmount","type":"uint256"},{"internalType":"uint256","name":"challengerCollateralAmount","type":"uint256"}],"internalType":"struct Collateral","name":"collateral","type":"tuple"},{"internalType":"uint32","name":"originChainId","type":"uint32"},{"internalType":"address","name":"localOracle","type":"address"},{"components":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"internalType":"struct Input[]","name":"inputs","type":"tuple[]"},{"components":[{"internalType":"bytes32","name":"remoteOracle","type":"bytes32"},{"internalType":"bytes32","name":"token","type":"bytes32"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes32","name":"recipient","type":"bytes32"},{"internalType":"uint32","name":"chainId","type":"uint32"},{"internalType":"bytes","name":"remoteCall","type":"bytes"}],"internalType":"struct OutputDescription[]","name":"outputs","type":"tuple[]"}],"indexed":false,"internalType":"struct OrderKey","name":"orderKey","type":"tuple"}],"name":"OrderInitiated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"orderHash","type":"bytes32"},{"indexed":true,"internalType":"address","name":"prover","type":"address"}],"name":"OrderProven","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"orderHash","type":"bytes32"},{"indexed":false,"internalType":"bytes","name":"fillerdata","type":"bytes"}],"name":"OrderPurchaseDetailsModified","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"orderHash","type":"bytes32"},{"indexed":false,"internalType":"address","name":"newFiller","type":"address"}],"name":"OrderPurchased","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"pendingOwner","type":"address"}],"name":"OwnershipHandoverCanceled","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"pendingOwner","type":"address"}],"name":"OwnershipHandoverRequested","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"oldOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"inputs":[],"name":"PERMIT2","outputs":[{"internalType":"contract ISignatureTransfer","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"VERSION_FLAGS","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"applyGovernanceFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"settlementContract","type":"address"},{"internalType":"address","name":"swapper","type":"address"},{"internalType":"uint256","name":"nonce","type":"uint256"},{"internalType":"uint32","name":"originChainId","type":"uint32"},{"internalType":"uint32","name":"initiateDeadline","type":"uint32"},{"internalType":"uint32","name":"fillDeadline","type":"uint32"},{"internalType":"bytes","name":"orderData","type":"bytes"}],"internalType":"struct CrossChainOrder","name":"order","type":"tuple"},{"internalType":"bytes","name":"signature","type":"bytes"}],"name":"broadcast","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"cancelOwnershipHandover","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"components":[{"components":[{"internalType":"address","name":"reactor","type":"address"},{"internalType":"uint32","name":"fillDeadline","type":"uint32"},{"internalType":"uint32","name":"challengeDeadline","type":"uint32"},{"internalType":"uint32","name":"proofDeadline","type":"uint32"}],"internalType":"struct ReactorInfo","name":"reactorContext","type":"tuple"},{"internalType":"address","name":"swapper","type":"address"},{"internalType":"uint96","name":"nonce","type":"uint96"},{"components":[{"internalType":"address","name":"collateralToken","type":"address"},{"internalType":"uint256","name":"fillerCollateralAmount","type":"uint256"},{"internalType":"uint256","name":"challengerCollateralAmount","type":"uint256"}],"internalType":"struct Collateral","name":"collateral","type":"tuple"},{"internalType":"uint32","name":"originChainId","type":"uint32"},{"internalType":"address","name":"localOracle","type":"address"},{"components":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"internalType":"struct Input[]","name":"inputs","type":"tuple[]"},{"components":[{"internalType":"bytes32","name":"remoteOracle","type":"bytes32"},{"internalType":"bytes32","name":"token","type":"bytes32"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes32","name":"recipient","type":"bytes32"},{"internalType":"uint32","name":"chainId","type":"uint32"},{"internalType":"bytes","name":"remoteCall","type":"bytes"}],"internalType":"struct OutputDescription[]","name":"outputs","type":"tuple[]"}],"internalType":"struct OrderKey","name":"orderKey","type":"tuple"}],"name":"completeDispute","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"pendingOwner","type":"address"}],"name":"completeOwnershipHandover","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"components":[{"components":[{"internalType":"address","name":"reactor","type":"address"},{"internalType":"uint32","name":"fillDeadline","type":"uint32"},{"internalType":"uint32","name":"challengeDeadline","type":"uint32"},{"internalType":"uint32","name":"proofDeadline","type":"uint32"}],"internalType":"struct ReactorInfo","name":"reactorContext","type":"tuple"},{"internalType":"address","name":"swapper","type":"address"},{"internalType":"uint96","name":"nonce","type":"uint96"},{"components":[{"internalType":"address","name":"collateralToken","type":"address"},{"internalType":"uint256","name":"fillerCollateralAmount","type":"uint256"},{"internalType":"uint256","name":"challengerCollateralAmount","type":"uint256"}],"internalType":"struct Collateral","name":"collateral","type":"tuple"},{"internalType":"uint32","name":"originChainId","type":"uint32"},{"internalType":"address","name":"localOracle","type":"address"},{"components":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"internalType":"struct Input[]","name":"inputs","type":"tuple[]"},{"components":[{"internalType":"bytes32","name":"remoteOracle","type":"bytes32"},{"internalType":"bytes32","name":"token","type":"bytes32"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes32","name":"recipient","type":"bytes32"},{"internalType":"uint32","name":"chainId","type":"uint32"},{"internalType":"bytes","name":"remoteCall","type":"bytes"}],"internalType":"struct OutputDescription[]","name":"outputs","type":"tuple[]"}],"internalType":"struct OrderKey","name":"orderKey","type":"tuple"}],"name":"dispute","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"tokens","type":"address[]"},{"internalType":"address","name":"to","type":"address"}],"name":"distributeGovernanceTokens","outputs":[{"internalType":"uint256[]","name":"collectedAmounts","type":"uint256[]"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"getGovernanceTokens","outputs":[{"internalType":"uint256","name":"amountTokens","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"orderKeyHash","type":"bytes32"}],"name":"getOrderContext","outputs":[{"components":[{"internalType":"enum OrderStatus","name":"status","type":"uint8"},{"internalType":"address","name":"fillerAddress","type":"address"},{"internalType":"uint32","name":"orderPurchaseDeadline","type":"uint32"},{"internalType":"uint16","name":"orderPurchaseDiscount","type":"uint16"},{"internalType":"address","name":"challenger","type":"address"},{"internalType":"bytes32","name":"identifier","type":"bytes32"}],"internalType":"struct OrderContext","name":"orderContext","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"components":[{"internalType":"address","name":"reactor","type":"address"},{"internalType":"uint32","name":"fillDeadline","type":"uint32"},{"internalType":"uint32","name":"challengeDeadline","type":"uint32"},{"internalType":"uint32","name":"proofDeadline","type":"uint32"}],"internalType":"struct ReactorInfo","name":"reactorContext","type":"tuple"},{"internalType":"address","name":"swapper","type":"address"},{"internalType":"uint96","name":"nonce","type":"uint96"},{"components":[{"internalType":"address","name":"collateralToken","type":"address"},{"internalType":"uint256","name":"fillerCollateralAmount","type":"uint256"},{"internalType":"uint256","name":"challengerCollateralAmount","type":"uint256"}],"internalType":"struct Collateral","name":"collateral","type":"tuple"},{"internalType":"uint32","name":"originChainId","type":"uint32"},{"internalType":"address","name":"localOracle","type":"address"},{"components":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"internalType":"struct Input[]","name":"inputs","type":"tuple[]"},{"components":[{"internalType":"bytes32","name":"remoteOracle","type":"bytes32"},{"internalType":"bytes32","name":"token","type":"bytes32"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes32","name":"recipient","type":"bytes32"},{"internalType":"uint32","name":"chainId","type":"uint32"},{"internalType":"bytes","name":"remoteCall","type":"bytes"}],"internalType":"struct OutputDescription[]","name":"outputs","type":"tuple[]"}],"internalType":"struct OrderKey","name":"orderKey","type":"tuple"}],"name":"getOrderContext","outputs":[{"components":[{"internalType":"enum OrderStatus","name":"status","type":"uint8"},{"internalType":"address","name":"fillerAddress","type":"address"},{"internalType":"uint32","name":"orderPurchaseDeadline","type":"uint32"},{"internalType":"uint16","name":"orderPurchaseDiscount","type":"uint16"},{"internalType":"address","name":"challenger","type":"address"},{"internalType":"bytes32","name":"identifier","type":"bytes32"}],"internalType":"struct OrderContext","name":"orderContext","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"components":[{"internalType":"address","name":"reactor","type":"address"},{"internalType":"uint32","name":"fillDeadline","type":"uint32"},{"internalType":"uint32","name":"challengeDeadline","type":"uint32"},{"internalType":"uint32","name":"proofDeadline","type":"uint32"}],"internalType":"struct ReactorInfo","name":"reactorContext","type":"tuple"},{"internalType":"address","name":"swapper","type":"address"},{"internalType":"uint96","name":"nonce","type":"uint96"},{"components":[{"internalType":"address","name":"collateralToken","type":"address"},{"internalType":"uint256","name":"fillerCollateralAmount","type":"uint256"},{"internalType":"uint256","name":"challengerCollateralAmount","type":"uint256"}],"internalType":"struct Collateral","name":"collateral","type":"tuple"},{"internalType":"uint32","name":"originChainId","type":"uint32"},{"internalType":"address","name":"localOracle","type":"address"},{"components":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"internalType":"struct Input[]","name":"inputs","type":"tuple[]"},{"components":[{"internalType":"bytes32","name":"remoteOracle","type":"bytes32"},{"internalType":"bytes32","name":"token","type":"bytes32"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes32","name":"recipient","type":"bytes32"},{"internalType":"uint32","name":"chainId","type":"uint32"},{"internalType":"bytes","name":"remoteCall","type":"bytes"}],"internalType":"struct OutputDescription[]","name":"outputs","type":"tuple[]"}],"internalType":"struct OrderKey","name":"orderKey","type":"tuple"}],"name":"getOrderKeyHash","outputs":[{"internalType":"bytes32","name":"orderKeyHash","type":"bytes32"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"governanceFee","outputs":[{"internalType":"uint64","name":"","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"settlementContract","type":"address"},{"internalType":"address","name":"swapper","type":"address"},{"internalType":"uint256","name":"nonce","type":"uint256"},{"internalType":"uint32","name":"originChainId","type":"uint32"},{"internalType":"uint32","name":"initiateDeadline","type":"uint32"},{"internalType":"uint32","name":"fillDeadline","type":"uint32"},{"internalType":"bytes","name":"orderData","type":"bytes"}],"internalType":"struct CrossChainOrder","name":"order","type":"tuple"},{"internalType":"bytes","name":"signature","type":"bytes"},{"internalType":"bytes","name":"fillerData","type":"bytes"}],"name":"initiate","outputs":[{"components":[{"components":[{"internalType":"address","name":"reactor","type":"address"},{"internalType":"uint32","name":"fillDeadline","type":"uint32"},{"internalType":"uint32","name":"challengeDeadline","type":"uint32"},{"internalType":"uint32","name":"proofDeadline","type":"uint32"}],"internalType":"struct ReactorInfo","name":"reactorContext","type":"tuple"},{"internalType":"address","name":"swapper","type":"address"},{"internalType":"uint96","name":"nonce","type":"uint96"},{"components":[{"internalType":"address","name":"collateralToken","type":"address"},{"internalType":"uint256","name":"fillerCollateralAmount","type":"uint256"},{"internalType":"uint256","name":"challengerCollateralAmount","type":"uint256"}],"internalType":"struct Collateral","name":"collateral","type":"tuple"},{"internalType":"uint32","name":"originChainId","type":"uint32"},{"internalType":"address","name":"localOracle","type":"address"},{"components":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"internalType":"struct Input[]","name":"inputs","type":"tuple[]"},{"components":[{"internalType":"bytes32","name":"remoteOracle","type":"bytes32"},{"internalType":"bytes32","name":"token","type":"bytes32"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes32","name":"recipient","type":"bytes32"},{"internalType":"uint32","name":"chainId","type":"uint32"},{"internalType":"bytes","name":"remoteCall","type":"bytes"}],"internalType":"struct OutputDescription[]","name":"outputs","type":"tuple[]"}],"internalType":"struct OrderKey","name":"orderKey","type":"tuple"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"components":[{"internalType":"address","name":"reactor","type":"address"},{"internalType":"uint32","name":"fillDeadline","type":"uint32"},{"internalType":"uint32","name":"challengeDeadline","type":"uint32"},{"internalType":"uint32","name":"proofDeadline","type":"uint32"}],"internalType":"struct ReactorInfo","name":"reactorContext","type":"tuple"},{"internalType":"address","name":"swapper","type":"address"},{"internalType":"uint96","name":"nonce","type":"uint96"},{"components":[{"internalType":"address","name":"collateralToken","type":"address"},{"internalType":"uint256","name":"fillerCollateralAmount","type":"uint256"},{"internalType":"uint256","name":"challengerCollateralAmount","type":"uint256"}],"internalType":"struct Collateral","name":"collateral","type":"tuple"},{"internalType":"uint32","name":"originChainId","type":"uint32"},{"internalType":"address","name":"localOracle","type":"address"},{"components":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"internalType":"struct Input[]","name":"inputs","type":"tuple[]"},{"components":[{"internalType":"bytes32","name":"remoteOracle","type":"bytes32"},{"internalType":"bytes32","name":"token","type":"bytes32"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes32","name":"recipient","type":"bytes32"},{"internalType":"uint32","name":"chainId","type":"uint32"},{"internalType":"bytes","name":"remoteCall","type":"bytes"}],"internalType":"struct OutputDescription[]","name":"outputs","type":"tuple[]"}],"internalType":"struct OrderKey","name":"orderKey","type":"tuple"},{"internalType":"bytes","name":"fillerData","type":"bytes"}],"name":"modifyOrderFillerdata","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"nextGovernanceFee","outputs":[{"internalType":"uint64","name":"","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"nextGovernanceFeeTime","outputs":[{"internalType":"uint64","name":"","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"components":[{"internalType":"address","name":"reactor","type":"address"},{"internalType":"uint32","name":"fillDeadline","type":"uint32"},{"internalType":"uint32","name":"challengeDeadline","type":"uint32"},{"internalType":"uint32","name":"proofDeadline","type":"uint32"}],"internalType":"struct ReactorInfo","name":"reactorContext","type":"tuple"},{"internalType":"address","name":"swapper","type":"address"},{"internalType":"uint96","name":"nonce","type":"uint96"},{"components":[{"internalType":"address","name":"collateralToken","type":"address"},{"internalType":"uint256","name":"fillerCollateralAmount","type":"uint256"},{"internalType":"uint256","name":"challengerCollateralAmount","type":"uint256"}],"internalType":"struct Collateral","name":"collateral","type":"tuple"},{"internalType":"uint32","name":"originChainId","type":"uint32"},{"internalType":"address","name":"localOracle","type":"address"},{"components":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"internalType":"struct Input[]","name":"inputs","type":"tuple[]"},{"components":[{"internalType":"bytes32","name":"remoteOracle","type":"bytes32"},{"internalType":"bytes32","name":"token","type":"bytes32"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes32","name":"recipient","type":"bytes32"},{"internalType":"uint32","name":"chainId","type":"uint32"},{"internalType":"bytes","name":"remoteCall","type":"bytes"}],"internalType":"struct OutputDescription[]","name":"outputs","type":"tuple[]"}],"internalType":"struct OrderKey","name":"orderKey","type":"tuple"},{"internalType":"bytes","name":"executionData","type":"bytes"}],"name":"optimisticPayout","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"result","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"pendingOwner","type":"address"}],"name":"ownershipHandoverExpiresAt","outputs":[{"internalType":"uint256","name":"result","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"components":[{"internalType":"address","name":"reactor","type":"address"},{"internalType":"uint32","name":"fillDeadline","type":"uint32"},{"internalType":"uint32","name":"challengeDeadline","type":"uint32"},{"internalType":"uint32","name":"proofDeadline","type":"uint32"}],"internalType":"struct ReactorInfo","name":"reactorContext","type":"tuple"},{"internalType":"address","name":"swapper","type":"address"},{"internalType":"uint96","name":"nonce","type":"uint96"},{"components":[{"internalType":"address","name":"collateralToken","type":"address"},{"internalType":"uint256","name":"fillerCollateralAmount","type":"uint256"},{"internalType":"uint256","name":"challengerCollateralAmount","type":"uint256"}],"internalType":"struct Collateral","name":"collateral","type":"tuple"},{"internalType":"uint32","name":"originChainId","type":"uint32"},{"internalType":"address","name":"localOracle","type":"address"},{"components":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"internalType":"struct Input[]","name":"inputs","type":"tuple[]"},{"components":[{"internalType":"bytes32","name":"remoteOracle","type":"bytes32"},{"internalType":"bytes32","name":"token","type":"bytes32"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes32","name":"recipient","type":"bytes32"},{"internalType":"uint32","name":"chainId","type":"uint32"},{"internalType":"bytes","name":"remoteCall","type":"bytes"}],"internalType":"struct OutputDescription[]","name":"outputs","type":"tuple[]"}],"internalType":"struct OrderKey","name":"orderKey","type":"tuple"},{"internalType":"bytes","name":"executionData","type":"bytes"}],"name":"proveOrderFulfilment","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"components":[{"internalType":"address","name":"reactor","type":"address"},{"internalType":"uint32","name":"fillDeadline","type":"uint32"},{"internalType":"uint32","name":"challengeDeadline","type":"uint32"},{"internalType":"uint32","name":"proofDeadline","type":"uint32"}],"internalType":"struct ReactorInfo","name":"reactorContext","type":"tuple"},{"internalType":"address","name":"swapper","type":"address"},{"internalType":"uint96","name":"nonce","type":"uint96"},{"components":[{"internalType":"address","name":"collateralToken","type":"address"},{"internalType":"uint256","name":"fillerCollateralAmount","type":"uint256"},{"internalType":"uint256","name":"challengerCollateralAmount","type":"uint256"}],"internalType":"struct Collateral","name":"collateral","type":"tuple"},{"internalType":"uint32","name":"originChainId","type":"uint32"},{"internalType":"address","name":"localOracle","type":"address"},{"components":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"internalType":"struct Input[]","name":"inputs","type":"tuple[]"},{"components":[{"internalType":"bytes32","name":"remoteOracle","type":"bytes32"},{"internalType":"bytes32","name":"token","type":"bytes32"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes32","name":"recipient","type":"bytes32"},{"internalType":"uint32","name":"chainId","type":"uint32"},{"internalType":"bytes","name":"remoteCall","type":"bytes"}],"internalType":"struct OutputDescription[]","name":"outputs","type":"tuple[]"}],"internalType":"struct OrderKey","name":"orderKey","type":"tuple"},{"internalType":"bytes","name":"fillerData","type":"bytes"},{"internalType":"uint256","name":"minDiscount","type":"uint256"}],"name":"purchaseOrder","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"requestOwnershipHandover","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"settlementContract","type":"address"},{"internalType":"address","name":"swapper","type":"address"},{"internalType":"uint256","name":"nonce","type":"uint256"},{"internalType":"uint32","name":"originChainId","type":"uint32"},{"internalType":"uint32","name":"initiateDeadline","type":"uint32"},{"internalType":"uint32","name":"fillDeadline","type":"uint32"},{"internalType":"bytes","name":"orderData","type":"bytes"}],"internalType":"struct CrossChainOrder","name":"order","type":"tuple"},{"internalType":"bytes","name":"fillerData","type":"bytes"}],"name":"resolve","outputs":[{"components":[{"internalType":"address","name":"settlementContract","type":"address"},{"internalType":"address","name":"swapper","type":"address"},{"internalType":"uint256","name":"nonce","type":"uint256"},{"internalType":"uint32","name":"originChainId","type":"uint32"},{"internalType":"uint32","name":"initiateDeadline","type":"uint32"},{"internalType":"uint32","name":"fillDeadline","type":"uint32"},{"components":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"internalType":"struct Input[]","name":"swapperInputs","type":"tuple[]"},{"components":[{"internalType":"bytes32","name":"token","type":"bytes32"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes32","name":"recipient","type":"bytes32"},{"internalType":"uint32","name":"chainId","type":"uint32"}],"internalType":"struct Output[]","name":"swapperOutputs","type":"tuple[]"},{"components":[{"internalType":"bytes32","name":"token","type":"bytes32"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes32","name":"recipient","type":"bytes32"},{"internalType":"uint32","name":"chainId","type":"uint32"}],"internalType":"struct Output[]","name":"fillerOutputs","type":"tuple[]"}],"internalType":"struct ResolvedCrossChainOrder","name":"resolvedOrder","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"settlementContract","type":"address"},{"internalType":"address","name":"swapper","type":"address"},{"internalType":"uint256","name":"nonce","type":"uint256"},{"internalType":"uint32","name":"originChainId","type":"uint32"},{"internalType":"uint32","name":"initiateDeadline","type":"uint32"},{"internalType":"uint32","name":"fillDeadline","type":"uint32"},{"internalType":"bytes","name":"orderData","type":"bytes"}],"internalType":"struct CrossChainOrder","name":"order","type":"tuple"},{"internalType":"bytes","name":"fillerData","type":"bytes"}],"name":"resolveKey","outputs":[{"components":[{"components":[{"internalType":"address","name":"reactor","type":"address"},{"internalType":"uint32","name":"fillDeadline","type":"uint32"},{"internalType":"uint32","name":"challengeDeadline","type":"uint32"},{"internalType":"uint32","name":"proofDeadline","type":"uint32"}],"internalType":"struct ReactorInfo","name":"reactorContext","type":"tuple"},{"internalType":"address","name":"swapper","type":"address"},{"internalType":"uint96","name":"nonce","type":"uint96"},{"components":[{"internalType":"address","name":"collateralToken","type":"address"},{"internalType":"uint256","name":"fillerCollateralAmount","type":"uint256"},{"internalType":"uint256","name":"challengerCollateralAmount","type":"uint256"}],"internalType":"struct Collateral","name":"collateral","type":"tuple"},{"internalType":"uint32","name":"originChainId","type":"uint32"},{"internalType":"address","name":"localOracle","type":"address"},{"components":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"internalType":"struct Input[]","name":"inputs","type":"tuple[]"},{"components":[{"internalType":"bytes32","name":"remoteOracle","type":"bytes32"},{"internalType":"bytes32","name":"token","type":"bytes32"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes32","name":"recipient","type":"bytes32"},{"internalType":"uint32","name":"chainId","type":"uint32"},{"internalType":"bytes","name":"remoteCall","type":"bytes"}],"internalType":"struct OutputDescription[]","name":"outputs","type":"tuple[]"}],"internalType":"struct OrderKey","name":"orderKey","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint64","name":"_nextGovernanceFee","type":"uint64"}],"name":"setGovernanceFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"payable","type":"function"}]