文件 1 的 10:IERC20.sol
pragma solidity >=0.6.9;
interface IERC20 {
function totalSupply() external view returns (uint256);
function decimals() external view returns (uint8);
function name() external view returns (string memory);
function symbol() external view returns (string memory);
function balanceOf(address account) external view returns (uint256);
function transfer(address recipient, uint256 amount) external returns (bool);
function allowance(address owner, address spender) external view returns (uint256);
function approve(address spender, uint256 amount) external returns (bool);
function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);
}
文件 2 的 10:ITransitSwapFees.sol
pragma solidity >=0.6.9;
interface ITransitSwapFees {
function getFeeRate(address trader, uint256 tradeAmount, uint8 swapType, string memory channel) external view returns (uint payFees);
}
文件 3 的 10:Ownable.sol
pragma solidity ^0.8.0;
abstract contract Ownable {
address private _owner;
address private _pendingOwner;
address private _executor;
address private _pendingExecutor;
bool internal _initialized;
event OwnershipTransferStarted(address indexed previousOwner, address indexed newOwner);
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
event ExecutorshipTransferStarted(address indexed previousExecutor, address indexed newExecutor);
event ExecutorshipTransferred(address indexed previousExecutor, address indexed newExecutor);
constructor(address newExecutor) {
require(!_initialized, "Ownable: initialized");
_transferOwnership(msg.sender);
_transferExecutorship(newExecutor);
_initialized = true;
}
modifier onlyOwner() {
_checkOwner();
_;
}
modifier onlyExecutor() {
_checkExecutor();
_;
}
function owner() public view virtual returns (address) {
return _owner;
}
function executor() public view virtual returns (address) {
return _executor;
}
function pendingOwner() public view virtual returns (address) {
return _pendingOwner;
}
function pendingExecutor() public view virtual returns (address) {
return _pendingExecutor;
}
function _checkOwner() internal view virtual {
require(owner() == msg.sender, "Ownable: caller is not the owner");
}
function _checkExecutor() internal view virtual {
require(executor() == msg.sender, "Ownable: caller is not the executor");
}
function renounceOwnership() public virtual onlyOwner {
_transferOwnership(address(0));
}
function transferOwnership(address newOwner) public virtual onlyOwner {
_pendingOwner = newOwner;
emit OwnershipTransferStarted(owner(), newOwner);
}
function transferExecutorship(address newExecutor) public virtual onlyExecutor {
_pendingExecutor = newExecutor;
emit ExecutorshipTransferStarted(executor(), newExecutor);
}
function _transferOwnership(address newOwner) internal virtual {
delete _pendingOwner;
address oldOwner = _owner;
_owner = newOwner;
emit OwnershipTransferred(oldOwner, newOwner);
}
function _transferExecutorship(address newExecutor) internal virtual {
delete _pendingExecutor;
address oldExecutor = _executor;
_executor = newExecutor;
emit ExecutorshipTransferred(oldExecutor, newExecutor);
}
function acceptOwnership() external {
address sender = msg.sender;
require(pendingOwner() == sender, "Ownable: caller is not the new owner");
_transferOwnership(sender);
}
function acceptExecutorship() external {
address sender = msg.sender;
require(pendingExecutor() == sender, "Ownable: caller is not the new executor");
_transferExecutorship(sender);
}
}
文件 4 的 10:Pausable.sol
pragma solidity ^0.8.0;
abstract contract Pausable {
event Paused(address account);
event Unpaused(address account);
bool private _paused;
constructor() {
_paused = false;
}
modifier whenNotPaused() {
_requireNotPaused();
_;
}
modifier whenPaused() {
_requirePaused();
_;
}
function paused() public view virtual returns (bool) {
return _paused;
}
function _requireNotPaused() internal view virtual {
require(!paused(), "Pausable: paused");
}
function _requirePaused() internal view virtual {
require(paused(), "Pausable: not paused");
}
function _pause() internal virtual whenNotPaused {
_paused = true;
emit Paused(msg.sender);
}
function _unpause() internal virtual whenPaused {
_paused = false;
emit Unpaused(msg.sender);
}
}
文件 5 的 10:ReentrancyGuard.sol
pragma solidity ^0.8.0;
abstract contract ReentrancyGuard {
uint256 private constant _NOT_ENTERED = 1;
uint256 private constant _ENTERED = 2;
uint256 private _status;
constructor() {
_status = _NOT_ENTERED;
}
modifier nonReentrant() {
_nonReentrantBefore();
_;
_nonReentrantAfter();
}
function _nonReentrantBefore() private {
require(_status != _ENTERED, "ReentrancyGuard: reentrant call");
_status = _ENTERED;
}
function _nonReentrantAfter() private {
_status = _NOT_ENTERED;
}
}
文件 6 的 10:RevertReasonParser.sol
pragma solidity >=0.6.0;
library RevertReasonParser {
function parse(bytes memory data, string memory prefix) internal pure returns (string memory) {
if (data.length >= 68 && data[0] == "\x08" && data[1] == "\xc3" && data[2] == "\x79" && data[3] == "\xa0") {
string memory reason;
assembly {
reason := add(data, 68)
}
require(data.length >= 68 + bytes(reason).length, "Invalid revert reason");
return string(abi.encodePacked(prefix, "Error(", reason, ")"));
}
else if (data.length == 36 && data[0] == "\x4e" && data[1] == "\x48" && data[2] == "\x7b" && data[3] == "\x71") {
uint256 code;
assembly {
code := mload(add(data, 36))
}
return string(abi.encodePacked(prefix, "Panic(", _toHex(code), ")"));
}
return string(abi.encodePacked(prefix, "Unknown(", _toHex(data), ")"));
}
function _toHex(uint256 value) private pure returns(string memory) {
return _toHex(abi.encodePacked(value));
}
function _toHex(bytes memory data) private pure returns(string memory) {
bytes16 alphabet = 0x30313233343536373839616263646566;
bytes memory str = new bytes(2 + data.length * 2);
str[0] = "0";
str[1] = "x";
for (uint256 i = 0; i < data.length; i++) {
str[2 * i + 2] = alphabet[uint8(data[i] >> 4)];
str[2 * i + 3] = alphabet[uint8(data[i] & 0x0f)];
}
return string(str);
}
}
文件 7 的 10:SafeMath.sol
pragma solidity >=0.6.0;
library SafeMath {
function add(uint x, uint y) internal pure returns (uint z) {
require((z = x + y) >= x, 'ds-math-add-overflow');
}
function sub(uint x, uint y) internal pure returns (uint z) {
require((z = x - y) <= x, 'ds-math-sub-underflow');
}
function mul(uint x, uint y) internal pure returns (uint z) {
require(y == 0 || (z = x * y) / y == x, 'ds-math-mul-overflow');
}
function div(uint x, uint y) internal pure returns (uint z) {
require(y != 0 , 'ds-math-div-zero');
z = x / y;
}
}
文件 8 的 10:TransferHelper.sol
pragma solidity >=0.6.0;
library TransferHelper {
address private constant _ETH_ADDRESS = address(0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE);
address private constant _ZERO_ADDRESS = address(0);
function isETH(address token) internal pure returns (bool) {
return (token == _ZERO_ADDRESS || token == _ETH_ADDRESS);
}
function safeApprove(address token, address to, uint value) internal {
(bool success, bytes memory data) = token.call(abi.encodeWithSelector(0x095ea7b3, to, value));
require(success && (data.length == 0 || abi.decode(data, (bool))), 'TransferHelper: APPROVE_FAILED');
}
function safeTransfer(address token, address to, uint value) internal {
(bool success, bytes memory data) = token.call(abi.encodeWithSelector(0xa9059cbb, to, value));
require(success && (data.length == 0 || abi.decode(data, (bool))), 'TransferHelper: TRANSFER_TOKEN_FAILED');
}
function safeTransferWithoutRequire(address token, address to, uint256 value) internal returns (bool) {
(bool success, bytes memory data) = token.call(abi.encodeWithSelector(0xa9059cbb, to, value));
return (success && (data.length == 0 || abi.decode(data, (bool))));
}
function safeTransferFrom(address token, address from, address to, uint value) internal {
(bool success, bytes memory data) = token.call(abi.encodeWithSelector(0x23b872dd, from, to, value));
require(success && (data.length == 0 || abi.decode(data, (bool))), 'TransferHelper: TRANSFER_FROM_FAILED');
}
function safeTransferETH(address to, uint value) internal {
(bool success,) = to.call{value:value}(new bytes(0));
require(success, 'TransferHelper: TRANSFER_FAILED');
}
function safeDeposit(address wrapped, uint value) internal {
(bool success, bytes memory data) = wrapped.call{value:value}(abi.encodeWithSelector(0xd0e30db0));
require(success && (data.length == 0 || abi.decode(data, (bool))), 'TransferHelper: DEPOSIT_FAILED');
}
function safeWithdraw(address wrapped, uint value) internal {
(bool success, bytes memory data) = wrapped.call{value:0}(abi.encodeWithSelector(0x2e1a7d4d, value));
require(success && (data.length == 0 || abi.decode(data, (bool))), 'TransferHelper: WITHDRAW_FAILED');
}
}
文件 9 的 10:TransitStructs.sol
pragma solidity ^0.8.0;
library TransitStructs {
enum SwapTypes {aggregatePreMode, aggregatePostMode, swap, cross}
enum Flag {aggregate, swap, cross}
struct TransitSwapDescription {
uint8 swapType;
address srcToken;
address dstToken;
address srcReceiver;
address dstReceiver;
uint256 amount;
uint256 minReturnAmount;
string channel;
uint256 toChainID;
address wrappedNative;
}
struct CallbytesDescription {
uint8 flag;
address srcToken;
bytes calldatas;
}
struct AggregateDescription {
address dstToken;
address receiver;
uint[] amounts;
uint[] needTransfer;
address[] callers;
address[] approveProxy;
bytes[] calls;
}
struct SwapDescription {
address[][] paths;
address[][] pairs;
uint[] fees;
address receiver;
uint deadline;
}
struct CrossDescription {
address caller;
uint256 amount;
bool needWrapped;
bytes calls;
}
function decodeAggregateDesc(bytes calldata calldatas) internal pure returns (AggregateDescription memory desc) {
desc = abi.decode(calldatas, (AggregateDescription));
}
function decodeSwapDesc(bytes calldata calldatas) internal pure returns (SwapDescription memory desc) {
desc = abi.decode(calldatas, (SwapDescription));
}
function decodeCrossDesc(bytes calldata calldatas) internal pure returns (CrossDescription memory desc) {
desc = abi.decode(calldatas, (CrossDescription));
}
}
文件 10 的 10:TransitSwapRouter.sol
pragma solidity ^0.8.0;
import "./libraries/ReentrancyGuard.sol";
import "./libraries/RevertReasonParser.sol";
import "./libraries/TransferHelper.sol";
import "./libraries/TransitStructs.sol";
import "./libraries/Ownable.sol";
import "./libraries/Pausable.sol";
import "./libraries/SafeMath.sol";
import "./interfaces/IERC20.sol";
import "./interfaces/ITransitSwapFees.sol";
contract TransitSwapRouter is Ownable, ReentrancyGuard, Pausable {
using SafeMath for uint256;
address private _transit_swap;
address private _transit_cross;
address private _transit_fees;
mapping(uint8 => bool) private _swap_type_mode;
event Receipt(address from, uint256 amount);
event Withdraw(address indexed token, address indexed executor, address indexed recipient, uint amount);
event ChangeTransitSwap(address indexed previousTransit, address indexed newTransit);
event ChangeTransitCross(address indexed previousTransit, address indexed newTransit);
event ChangeTransitFees(address indexed previousTransitFees, address indexed newTransitFees);
event ChangeSwapTypeMode(uint8[] types, bool[] newModes);
event TransitSwapped(address indexed srcToken, address indexed dstToken, address indexed dstReceiver, address trader, bool feeMode, uint256 amount, uint256 returnAmount, uint256 minReturnAmount, uint256 fee, uint256 toChainID, string channel, uint256 time);
constructor(address transitSwap_, address transitCross_, address transitFees_, address executor) Ownable (executor) {
_transit_swap = transitSwap_;
_transit_cross = transitCross_;
_transit_fees = transitFees_;
}
receive() external payable {
emit Receipt(msg.sender, msg.value);
}
function transitSwap() external view returns (address) {
return _transit_swap;
}
function transitCross() external view returns (address) {
return _transit_cross;
}
function transitFees() external view returns (address) {
return _transit_fees;
}
function swapTypeMode(uint8 swapType) external view returns (bool) {
return _swap_type_mode[swapType];
}
function changeTransitSwap(address newTransit) external onlyExecutor {
address oldTransit = _transit_swap;
_transit_swap = newTransit;
emit ChangeTransitSwap(oldTransit, newTransit);
}
function changeTransitCross(address newTransit) external onlyExecutor {
address oldTransit = _transit_cross;
_transit_cross = newTransit;
emit ChangeTransitCross(oldTransit, newTransit);
}
function changeTransitFees(address newTransitFees) external onlyExecutor {
address oldTransitFees = _transit_fees;
_transit_fees = newTransitFees;
emit ChangeTransitFees(oldTransitFees, newTransitFees);
}
function changeSwapTypeMode(uint8[] memory swapTypes) external onlyExecutor {
bool[] memory newModes = new bool[](swapTypes.length);
for (uint index; index < swapTypes.length; index++) {
_swap_type_mode[swapTypes[index]] = !_swap_type_mode[swapTypes[index]];
newModes[index] = _swap_type_mode[swapTypes[index]];
}
emit ChangeSwapTypeMode(swapTypes, newModes);
}
function changePause(bool paused) external onlyExecutor {
if (paused) {
_pause();
} else {
_unpause();
}
}
function _beforeSwap(bool preTradeModel, TransitStructs.TransitSwapDescription calldata desc) private returns (uint256 swapAmount, uint256 fee, uint256 beforeBalance) {
if (preTradeModel) {
fee = ITransitSwapFees(_transit_fees).getFeeRate(msg.sender, desc.amount, desc.swapType, desc.channel);
}
if (TransferHelper.isETH(desc.srcToken)) {
require(msg.value == desc.amount, "TransitSwap: invalid msg.value");
swapAmount = desc.amount.sub(fee);
} else {
if (preTradeModel) {
TransferHelper.safeTransferFrom(desc.srcToken, msg.sender, address(this), desc.amount);
TransferHelper.safeTransfer(desc.srcToken, desc.srcReceiver, desc.amount.sub(fee));
} else {
TransferHelper.safeTransferFrom(desc.srcToken, msg.sender, desc.srcReceiver, desc.amount);
}
}
if (TransferHelper.isETH(desc.dstToken)) {
if (preTradeModel) {
beforeBalance = desc.dstReceiver.balance;
} else {
if (desc.swapType == uint8(TransitStructs.SwapTypes.swap)) {
beforeBalance = IERC20(desc.wrappedNative).balanceOf(address(this));
} else {
beforeBalance = address(this).balance;
}
}
} else {
if (preTradeModel) {
beforeBalance = IERC20(desc.dstToken).balanceOf(desc.dstReceiver);
} else {
beforeBalance = IERC20(desc.dstToken).balanceOf(address(this));
}
}
}
function _afterSwap(bool preTradeModel, TransitStructs.TransitSwapDescription calldata desc, uint256 beforeBalance) private returns (uint256 returnAmount, uint256 fee) {
if (TransferHelper.isETH(desc.dstToken)) {
if (preTradeModel) {
returnAmount = desc.dstReceiver.balance.sub(beforeBalance);
require(returnAmount >= desc.minReturnAmount, "TransitSwap: insufficient return amount");
} else {
if (desc.swapType == uint8(TransitStructs.SwapTypes.swap)) {
returnAmount = IERC20(desc.wrappedNative).balanceOf(address(this)).sub(beforeBalance);
TransferHelper.safeWithdraw(desc.wrappedNative, returnAmount);
} else {
returnAmount = address(this).balance.sub(beforeBalance);
}
fee = ITransitSwapFees(_transit_fees).getFeeRate(msg.sender, returnAmount, desc.swapType, desc.channel);
returnAmount = returnAmount.sub(fee);
require(returnAmount >= desc.minReturnAmount, "TransitSwap: insufficient return amount");
TransferHelper.safeTransferETH(desc.dstReceiver, returnAmount);
}
} else {
if (preTradeModel) {
returnAmount = IERC20(desc.dstToken).balanceOf(desc.dstReceiver).sub(beforeBalance);
require(returnAmount >= desc.minReturnAmount, "TransitSwap: insufficient return amount");
} else {
returnAmount = IERC20(desc.dstToken).balanceOf(address(this)).sub(beforeBalance);
fee = ITransitSwapFees(_transit_fees).getFeeRate(msg.sender, returnAmount, desc.swapType, desc.channel);
returnAmount = returnAmount.sub(fee);
uint256 receiverBeforeBalance = IERC20(desc.dstToken).balanceOf(desc.dstReceiver);
TransferHelper.safeTransfer(desc.dstToken, desc.dstReceiver, returnAmount);
returnAmount = IERC20(desc.dstToken).balanceOf(desc.dstReceiver).sub(receiverBeforeBalance);
require(returnAmount >= desc.minReturnAmount, "TransitSwap: insufficient return amount");
}
}
}
function swap(TransitStructs.TransitSwapDescription calldata desc, TransitStructs.CallbytesDescription calldata callbytesDesc) external payable nonReentrant whenNotPaused {
require(callbytesDesc.calldatas.length > 0, "TransitSwap: data should be not zero");
require(desc.amount > 0, "TransitSwap: amount should be greater than 0");
require(desc.dstReceiver != address(0), "TransitSwap: receiver should be not address(0)");
require(desc.minReturnAmount > 0, "TransitSwap: minReturnAmount should be greater than 0");
if (callbytesDesc.flag == uint8(TransitStructs.Flag.aggregate)) {
require(desc.srcToken == callbytesDesc.srcToken, "TransitSwap: invalid callbytesDesc");
}
bool preTradeModel = !_swap_type_mode[desc.swapType];
(uint256 swapAmount, uint256 fee, uint256 beforeBalance) = _beforeSwap(preTradeModel, desc);
{
(bool success, bytes memory result) = _transit_swap.call{value:swapAmount}(abi.encodeWithSelector(0xccbe4007, callbytesDesc));
if (!success) {
revert(RevertReasonParser.parse(result,"TransitSwap:"));
}
}
(uint256 returnAmount, uint256 postFee) = _afterSwap(preTradeModel, desc, beforeBalance);
if (postFee > fee) {
fee = postFee;
}
_emitTransit(desc, preTradeModel, fee, returnAmount);
}
function _beforeCross(TransitStructs.TransitSwapDescription calldata desc) private returns (uint256 swapAmount, uint256 fee, uint256 beforeBalance) {
fee = ITransitSwapFees(_transit_fees).getFeeRate(msg.sender, desc.amount, desc.swapType, desc.channel);
if (TransferHelper.isETH(desc.srcToken)) {
require(msg.value == desc.amount, "TransitSwap: invalid msg.value");
swapAmount = desc.amount.sub(fee);
} else {
beforeBalance = IERC20(desc.srcToken).balanceOf(_transit_cross);
if (fee == 0) {
TransferHelper.safeTransferFrom(desc.srcToken, msg.sender, _transit_cross, desc.amount);
} else {
TransferHelper.safeTransferFrom(desc.srcToken, msg.sender, address(this), desc.amount);
TransferHelper.safeTransfer(desc.srcToken, _transit_cross, desc.amount.sub(fee));
}
}
}
function cross(TransitStructs.TransitSwapDescription calldata desc, TransitStructs.CallbytesDescription calldata callbytesDesc) external payable nonReentrant whenNotPaused {
require(callbytesDesc.calldatas.length > 0, "TransitSwap: data should be not zero");
require(desc.amount > 0, "TransitSwap: amount should be greater than 0");
require(desc.srcToken == callbytesDesc.srcToken, "TransitSwap: invalid callbytesDesc");
(uint256 swapAmount, uint256 fee, uint256 beforeBalance) = _beforeCross(desc);
{
(bool success, bytes memory result) = _transit_cross.call{value:swapAmount}(abi.encodeWithSelector(0xccbe4007, callbytesDesc));
if (!success) {
revert(RevertReasonParser.parse(result,"TransitSwap:"));
}
}
if (!TransferHelper.isETH(desc.srcToken)) {
require(IERC20(desc.srcToken).balanceOf(_transit_cross) >= beforeBalance, "TransitSwap: invalid cross");
}
_emitTransit(desc, true, fee, 0);
}
function _emitTransit(TransitStructs.TransitSwapDescription calldata desc, bool preTradeModel, uint256 fee, uint256 returnAmount) private {
emit TransitSwapped(
desc.srcToken,
desc.dstToken,
desc.dstReceiver,
msg.sender,
preTradeModel,
desc.amount,
returnAmount,
desc.minReturnAmount,
fee,
desc.toChainID,
desc.channel,
block.timestamp
);
}
function withdrawTokens(address[] memory tokens, address recipient) external onlyExecutor {
for(uint index; index < tokens.length; index++) {
uint amount;
if(TransferHelper.isETH(tokens[index])) {
amount = address(this).balance;
TransferHelper.safeTransferETH(recipient, amount);
} else {
amount = IERC20(tokens[index]).balanceOf(address(this));
TransferHelper.safeTransferWithoutRequire(tokens[index], recipient, amount);
}
emit Withdraw(tokens[index], msg.sender, recipient, amount);
}
}
}
{
"compilationTarget": {
"TransitSwapRouter.sol": "TransitSwapRouter"
},
"evmVersion": "london",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs"
},
"optimizer": {
"enabled": true,
"runs": 200
},
"remappings": []
}
[{"inputs":[{"internalType":"address","name":"transitSwap_","type":"address"},{"internalType":"address","name":"transitCross_","type":"address"},{"internalType":"address","name":"transitFees_","type":"address"},{"internalType":"address","name":"executor","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint8[]","name":"types","type":"uint8[]"},{"indexed":false,"internalType":"bool[]","name":"newModes","type":"bool[]"}],"name":"ChangeSwapTypeMode","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousTransit","type":"address"},{"indexed":true,"internalType":"address","name":"newTransit","type":"address"}],"name":"ChangeTransitCross","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousTransitFees","type":"address"},{"indexed":true,"internalType":"address","name":"newTransitFees","type":"address"}],"name":"ChangeTransitFees","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousTransit","type":"address"},{"indexed":true,"internalType":"address","name":"newTransit","type":"address"}],"name":"ChangeTransitSwap","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousExecutor","type":"address"},{"indexed":true,"internalType":"address","name":"newExecutor","type":"address"}],"name":"ExecutorshipTransferStarted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousExecutor","type":"address"},{"indexed":true,"internalType":"address","name":"newExecutor","type":"address"}],"name":"ExecutorshipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferStarted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"from","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Receipt","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"srcToken","type":"address"},{"indexed":true,"internalType":"address","name":"dstToken","type":"address"},{"indexed":true,"internalType":"address","name":"dstReceiver","type":"address"},{"indexed":false,"internalType":"address","name":"trader","type":"address"},{"indexed":false,"internalType":"bool","name":"feeMode","type":"bool"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"returnAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"minReturnAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"fee","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"toChainID","type":"uint256"},{"indexed":false,"internalType":"string","name":"channel","type":"string"},{"indexed":false,"internalType":"uint256","name":"time","type":"uint256"}],"name":"TransitSwapped","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"token","type":"address"},{"indexed":true,"internalType":"address","name":"executor","type":"address"},{"indexed":true,"internalType":"address","name":"recipient","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Withdraw","type":"event"},{"inputs":[],"name":"acceptExecutorship","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"acceptOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"paused","type":"bool"}],"name":"changePause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint8[]","name":"swapTypes","type":"uint8[]"}],"name":"changeSwapTypeMode","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newTransit","type":"address"}],"name":"changeTransitCross","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newTransitFees","type":"address"}],"name":"changeTransitFees","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newTransit","type":"address"}],"name":"changeTransitSwap","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"uint8","name":"swapType","type":"uint8"},{"internalType":"address","name":"srcToken","type":"address"},{"internalType":"address","name":"dstToken","type":"address"},{"internalType":"address","name":"srcReceiver","type":"address"},{"internalType":"address","name":"dstReceiver","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"minReturnAmount","type":"uint256"},{"internalType":"string","name":"channel","type":"string"},{"internalType":"uint256","name":"toChainID","type":"uint256"},{"internalType":"address","name":"wrappedNative","type":"address"}],"internalType":"struct TransitStructs.TransitSwapDescription","name":"desc","type":"tuple"},{"components":[{"internalType":"uint8","name":"flag","type":"uint8"},{"internalType":"address","name":"srcToken","type":"address"},{"internalType":"bytes","name":"calldatas","type":"bytes"}],"internalType":"struct TransitStructs.CallbytesDescription","name":"callbytesDesc","type":"tuple"}],"name":"cross","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"executor","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pendingExecutor","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pendingOwner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"uint8","name":"swapType","type":"uint8"},{"internalType":"address","name":"srcToken","type":"address"},{"internalType":"address","name":"dstToken","type":"address"},{"internalType":"address","name":"srcReceiver","type":"address"},{"internalType":"address","name":"dstReceiver","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"minReturnAmount","type":"uint256"},{"internalType":"string","name":"channel","type":"string"},{"internalType":"uint256","name":"toChainID","type":"uint256"},{"internalType":"address","name":"wrappedNative","type":"address"}],"internalType":"struct TransitStructs.TransitSwapDescription","name":"desc","type":"tuple"},{"components":[{"internalType":"uint8","name":"flag","type":"uint8"},{"internalType":"address","name":"srcToken","type":"address"},{"internalType":"bytes","name":"calldatas","type":"bytes"}],"internalType":"struct TransitStructs.CallbytesDescription","name":"callbytesDesc","type":"tuple"}],"name":"swap","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint8","name":"swapType","type":"uint8"}],"name":"swapTypeMode","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newExecutor","type":"address"}],"name":"transferExecutorship","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"transitCross","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"transitFees","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"transitSwap","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"tokens","type":"address[]"},{"internalType":"address","name":"recipient","type":"address"}],"name":"withdrawTokens","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]