编译器
0.8.24+commit.e11b9ed9
文件 1 的 12:Aggregator.sol
pragma solidity ^0.8.15;
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "./IAggregator.sol";
import "./FixinTokenSpender.sol";
import "./ReentrancyGuard.sol";
import "./IERC721.sol";
import "./IERC1155.sol";
abstract contract Aggregator is IAggregator, ReentrancyGuard, FixinTokenSpender {
uint256 private constant SEAPORT_MARKET_ID = 1;
address private constant SEAPORT = 0x0000000000000068F116a894984e2DB1123eB395;
uint256 private constant LOOTEX_MARKET_ID = 2;
address private constant LOOTEX = 0x5C019E4D86CD7Fa9a8c1C3d9D53FF90b3198705d;
uint256 private constant MARKETS_DATA_SLOT = 0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e563;
uint256 private constant ETH_VALUE_MASK = (1 << 168) - 1;
uint256 private constant PROXY_MASK = (1 << 160) - 1;
function batchBuyWithETH(bytes calldata tradeBytes) external override payable {
uint256 ethBalanceBefore;
assembly { ethBalanceBefore := sub(selfbalance(), callvalue()) }
_trade(tradeBytes);
assembly {
if eq(selfbalance(), ethBalanceBefore) {
return(0, 0)
}
if gt(selfbalance(), ethBalanceBefore) {
let success := call(gas(), caller(), sub(selfbalance(), ethBalanceBefore), 0, 0, 0, 0)
return(0, 0)
}
}
revert("Failed to return ETH.");
}
function batchBuyWithERC20s(
ERC20Pair[] calldata erc20Pairs,
bytes calldata tradeBytes,
address[] calldata dustTokens
) external override payable nonReentrant {
_transferERC20Pairs(erc20Pairs);
_trade(tradeBytes);
_returnDust(dustTokens);
assembly {
if gt(selfbalance(), 0) {
let success := call(gas(), caller(), selfbalance(), 0, 0, 0, 0)
}
}
}
function acceptWithERC721(
ERC721Pair[] calldata erc721Pairs,
ERC20Pair[] calldata erc20Pairs,
address[] calldata dustTokens,
bytes calldata tradeBytes
) external override payable nonReentrant {
_transferERC20Pairs(erc20Pairs);
_transferERC721Pairs(erc721Pairs);
_trade(tradeBytes);
_returnDust(dustTokens);
_returnERC721(erc721Pairs);
assembly {
if gt(selfbalance(), 0) {
let success := call(gas(), caller(), selfbalance(), 0, 0, 0, 0)
}
}
}
function acceptWithERC1155(
ERC1155Pair[] calldata erc1155Pairs,
ERC20Pair[] calldata erc20Pairs,
address[] calldata dustTokens,
bytes calldata tradeBytes
) external override payable nonReentrant {
_transferERC20Pairs(erc20Pairs);
_transferERC1155Pairs(erc1155Pairs);
_trade(tradeBytes);
_returnDust(dustTokens);
_returnERC1155(erc1155Pairs);
assembly {
if gt(selfbalance(), 0) {
let success := call(gas(), caller(), selfbalance(), 0, 0, 0, 0)
}
}
}
function _trade(bytes calldata tradeBytes) internal {
assembly {
let anySuccess
let itemLength
let end := add(tradeBytes.offset, tradeBytes.length)
let ptr := mload(0x40)
for { let offset := tradeBytes.offset } lt(offset, end) { offset := add(add(offset, 28), itemLength) } {
let head := calldataload(offset)
itemLength := and(shr(32, head), 0xffffffff)
calldatacopy(ptr, add(offset, 28), itemLength)
let marketId := shr(240, head)
if eq(marketId, SEAPORT_MARKET_ID) {
if iszero(call(gas(), SEAPORT, and(shr(64, head), ETH_VALUE_MASK), ptr, itemLength, 0, 0)) {
_revertOrContinue(head)
continue
}
anySuccess := 1
continue
}
if eq(marketId, LOOTEX_MARKET_ID) {
if iszero(call(gas(), LOOTEX, and(shr(64, head), ETH_VALUE_MASK), ptr, itemLength, 0, 0)) {
_revertOrContinue(head)
continue
}
anySuccess := 1
continue
}
let market := sload(add(MARKETS_DATA_SLOT, marketId))
if iszero(byte(10, market)) {
if iszero(byte(2, head)) {
mstore(0, 0x08c379a000000000000000000000000000000000000000000000000000000000)
mstore(0x20, 0x0000002000000000000000000000000000000000000000000000000000000000)
mstore(0x40, 0x00000010496e616374697665206d61726b65742e000000000000000000000000)
mstore(0x60, 0)
revert(0, 0x64)
}
continue
}
if iszero(byte(11, market)) {
if iszero(call(gas(), and(market, PROXY_MASK), and(shr(64, head), ETH_VALUE_MASK), ptr, itemLength, 0, 0)) {
_revertOrContinue(head)
continue
}
anySuccess := 1
continue
}
if iszero(delegatecall(gas(), and(market, PROXY_MASK), ptr, itemLength, 0, 0)) {
_revertOrContinue(head)
continue
}
anySuccess := 1
}
if iszero(anySuccess) {
if gt(tradeBytes.length, 0) {
if iszero(returndatasize()) {
mstore(0, 0x08c379a000000000000000000000000000000000000000000000000000000000)
mstore(0x20, 0x0000002000000000000000000000000000000000000000000000000000000000)
mstore(0x40, 0x000000134e6f206f72646572207375636365656465642e000000000000000000)
mstore(0x60, 0)
revert(0, 0x64)
}
returndatacopy(0, 0, returndatasize())
revert(0, returndatasize())
}
}
function _revertOrContinue(head) {
if iszero(byte(2, head)) {
if iszero(returndatasize()) {
mstore(0, head)
revert(0, 0x20)
}
returndatacopy(0, 0, returndatasize())
revert(0, returndatasize())
}
}
}
}
function _transferERC20Pairs(ERC20Pair[] calldata erc20Pairs) internal {
if (erc20Pairs.length > 0) {
assembly {
let ptr := mload(0x40)
let end := add(erc20Pairs.offset, mul(erc20Pairs.length, 0x40))
mstore(ptr, 0x23b872dd00000000000000000000000000000000000000000000000000000000)
mstore(add(ptr, 0x04), caller())
mstore(add(ptr, 0x24), address())
for { let offset := erc20Pairs.offset } lt(offset, end) { offset := add(offset, 0x40) } {
let amount := calldataload(add(offset, 0x20))
if gt(amount, 0) {
mstore(add(ptr, 0x44), amount)
let success := call(gas(), calldataload(offset), 0, ptr, 0x64, 0, 0)
}
}
}
}
}
function _transferERC721Pairs(ERC721Pair[] calldata erc721Pairs) internal{
if (erc721Pairs.length > 0){
for(uint256 i = 0 ; i < erc721Pairs.length; i++){
IERC721(erc721Pairs[i].nft).transferFrom(msg.sender, address(this), erc721Pairs[i].id);
}
}
}
function _transferERC1155Pairs(ERC1155Pair[] calldata erc1155Pairs) internal{
if (erc1155Pairs.length > 0){
for(uint256 i = 0 ; i < erc1155Pairs.length; i++){
IERC1155(erc1155Pairs[i].nft).safeTransferFrom(msg.sender, address(this), erc1155Pairs[i].id, erc1155Pairs[i].amount, "");
}
}
}
function _returnDust(address[] calldata tokens) internal {
for (uint256 i; i < tokens.length; ) {
_transferERC20WithoutCheck(tokens[i], msg.sender, IERC20(tokens[i]).balanceOf(address(this)));
unchecked { ++i; }
}
}
function _returnERC721(ERC721Pair[] calldata erc721Pairs) internal {
for(uint256 i = 0 ; i < erc721Pairs.length; i++){
address nftAddr = erc721Pairs[i].nft;
uint256 nftId = erc721Pairs[i].id;
if (IERC721(nftAddr).ownerOf(nftId) == address(this) ){
IERC721(nftAddr).transferFrom(address(this), msg.sender, nftId);
}
}
}
function _returnERC1155(ERC1155Pair[] calldata erc1155Pairs) internal {
for(uint256 i = 0 ; i < erc1155Pairs.length; i++){
address nftAddr = erc1155Pairs[i].nft;
uint256 nftId = erc1155Pairs[i].id;
uint256 remainAmount = IERC1155(nftAddr).balanceOf(address(this), nftId);
if (remainAmount > 0 ){
IERC1155(nftAddr).safeTransferFrom(address(this), msg.sender, nftId, remainAmount, "");
}
}
}
}
文件 2 的 12:FixinTokenSpender.sol
pragma solidity ^0.8.15;
abstract contract FixinTokenSpender {
uint256 constant private ADDRESS_MASK = (1 << 160) - 1;
function _transferERC20From(address token, address owner, address to, uint256 amount) internal {
uint256 success;
assembly {
let ptr := mload(0x40)
mstore(ptr, 0x23b872dd00000000000000000000000000000000000000000000000000000000)
mstore(add(ptr, 0x04), and(owner, ADDRESS_MASK))
mstore(add(ptr, 0x24), and(to, ADDRESS_MASK))
mstore(add(ptr, 0x44), amount)
success := call(gas(), and(token, ADDRESS_MASK), 0, ptr, 0x64, ptr, 32)
let rdsize := returndatasize()
success := and(
success,
or(
iszero(rdsize),
and(
iszero(lt(rdsize, 32)),
eq(mload(ptr), 1)
)
)
)
}
require(success != 0, "_transferERC20/TRANSFER_FAILED");
}
function _transferERC20(address token, address to, uint256 amount) internal {
uint256 success;
assembly {
let ptr := mload(0x40)
mstore(ptr, 0xa9059cbb00000000000000000000000000000000000000000000000000000000)
mstore(add(ptr, 0x04), and(to, ADDRESS_MASK))
mstore(add(ptr, 0x24), amount)
success := call(gas(), and(token, ADDRESS_MASK), 0, ptr, 0x44, ptr, 32)
let rdsize := returndatasize()
success := and(
success,
or(
iszero(rdsize),
and(
iszero(lt(rdsize, 32)),
eq(mload(ptr), 1)
)
)
)
}
require(success != 0, "_transferERC20/TRANSFER_FAILED");
}
function _transferERC20FromWithoutCheck(address token, address owner, address to, uint256 amount) internal {
assembly {
if gt(amount, 0) {
let ptr := mload(0x40)
mstore(ptr, 0x23b872dd00000000000000000000000000000000000000000000000000000000)
mstore(add(ptr, 0x04), and(owner, ADDRESS_MASK))
mstore(add(ptr, 0x24), and(to, ADDRESS_MASK))
mstore(add(ptr, 0x44), amount)
let success := call(gas(), and(token, ADDRESS_MASK), 0, ptr, 0x64, 0, 0)
}
}
}
function _transferERC20WithoutCheck(address token, address to, uint256 amount) internal {
assembly {
if gt(amount, 0) {
let ptr := mload(0x40)
mstore(ptr, 0xa9059cbb00000000000000000000000000000000000000000000000000000000)
mstore(add(ptr, 0x04), and(to, ADDRESS_MASK))
mstore(add(ptr, 0x24), amount)
let success := call(gas(), and(token, ADDRESS_MASK), 0, ptr, 0x44, 0, 0)
}
}
}
function _transferEth(address recipient, uint256 amount) internal {
assembly {
if gt(amount, 0) {
if iszero(call(gas(), recipient, amount, 0, 0, 0, 0)) {
mstore(0, 0x08c379a000000000000000000000000000000000000000000000000000000000)
mstore(0x20, 0x0000002000000000000000000000000000000000000000000000000000000000)
mstore(0x40, 0x0000001c5f7472616e736665724574682f5452414e534645525f4641494c4544)
mstore(0x60, 0)
revert(0, 0x64)
}
}
}
}
}
文件 3 的 12:IAggregator.sol
pragma solidity ^0.8.15;
interface IAggregator {
struct ERC20Pair {
address token;
uint256 amount;
}
struct ERC721Pair {
address nft;
uint256 id;
}
struct ERC1155Pair {
address nft;
uint256 id;
uint256 amount;
}
function batchBuyWithETH(bytes calldata tradeBytes) external payable;
function batchBuyWithERC20s(
ERC20Pair[] calldata erc20Pairs,
bytes calldata tradeBytes,
address[] calldata dustTokens
) external payable;
function acceptWithERC721(
ERC721Pair[] calldata erc721Pairs,
ERC20Pair[] calldata erc20Pairs,
address[] calldata dustTokens,
bytes calldata tradeBytes
) external payable;
function acceptWithERC1155(
ERC1155Pair[] calldata erc1155Pairs,
ERC20Pair[] calldata erc20Pairs,
address[] calldata dustTokens,
bytes calldata tradeBytes
) external payable;
}
文件 4 的 12:IERC1155.sol
pragma solidity ^0.8.20;
import "@openzeppelin/contracts/interfaces/IERC165.sol";
interface IERC1155 is IERC165 {
event TransferSingle(address indexed operator, address indexed from, address indexed to, uint256 id, uint256 value);
event TransferBatch(
address indexed operator,
address indexed from,
address indexed to,
uint256[] ids,
uint256[] values
);
event ApprovalForAll(address indexed account, address indexed operator, bool approved);
event URI(string value, uint256 indexed id);
function balanceOf(address account, uint256 id) external view returns (uint256);
function balanceOfBatch(
address[] calldata accounts,
uint256[] calldata ids
) external view returns (uint256[] memory);
function setApprovalForAll(address operator, bool approved) external;
function isApprovedForAll(address account, address operator) external view returns (bool);
function safeTransferFrom(address from, address to, uint256 id, uint256 value, bytes calldata data) external;
function safeBatchTransferFrom(
address from,
address to,
uint256[] calldata ids,
uint256[] calldata values,
bytes calldata data
) external;
}
文件 5 的 12:IERC165.sol
pragma solidity ^0.8.20;
interface IERC165 {
function supportsInterface(bytes4 interfaceId) external view returns (bool);
}
文件 6 的 12:IERC20.sol
pragma solidity ^0.8.20;
interface IERC20 {
event Transfer(address indexed from, address indexed to, uint256 value);
event Approval(address indexed owner, address indexed spender, uint256 value);
function totalSupply() external view returns (uint256);
function balanceOf(address account) external view returns (uint256);
function transfer(address to, uint256 value) external returns (bool);
function allowance(address owner, address spender) external view returns (uint256);
function approve(address spender, uint256 value) external returns (bool);
function transferFrom(address from, address to, uint256 value) external returns (bool);
}
文件 7 的 12:IERC721.sol
pragma solidity ^0.8.20;
import "@openzeppelin/contracts/interfaces/IERC165.sol";
interface IERC721 is IERC165 {
event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);
event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);
event ApprovalForAll(address indexed owner, address indexed operator, bool approved);
function balanceOf(address owner) external view returns (uint256 balance);
function ownerOf(uint256 tokenId) external view returns (address owner);
function safeTransferFrom(address from, address to, uint256 tokenId, bytes calldata data) external;
function safeTransferFrom(address from, address to, uint256 tokenId) external;
function transferFrom(address from, address to, uint256 tokenId) external;
function approve(address to, uint256 tokenId) external;
function setApprovalForAll(address operator, bool approved) external;
function getApproved(uint256 tokenId) external view returns (address operator);
function isApprovedForAll(address owner, address operator) external view returns (bool);
}
文件 8 的 12:LibFeatureStorage.sol
pragma solidity ^0.8.15;
library LibFeatureStorage {
uint256 constant STORAGE_ID_FEATURE = 1 << 128;
struct Storage {
mapping(bytes4 => address) featureImpls;
mapping(address => string) featureNames;
bytes4[] methodIDs;
mapping(bytes4 => string) methodNames;
}
function getStorage() internal pure returns (Storage storage stor) {
assembly { stor.slot := STORAGE_ID_FEATURE }
}
}
文件 9 的 12:LibOwnableStorage.sol
pragma solidity ^0.8.15;
library LibOwnableStorage {
uint256 constant STORAGE_ID_OWNABLE = 2 << 128;
struct Storage {
uint256 reentrancyStatus;
address owner;
}
function getStorage() internal pure returns (Storage storage stor) {
assembly { stor.slot := STORAGE_ID_OWNABLE }
}
}
文件 10 的 12:LootexSwap.sol
pragma solidity ^0.8.15;
import "./IERC1155.sol";
import "./LibFeatureStorage.sol";
import "./Aggregator.sol";
import "./Ownable.sol";
import "./IERC721.sol";
contract LootexSwap is Aggregator, Ownable {
struct Method {
bytes4 methodID;
string methodName;
}
struct Feature {
address feature;
string name;
Method[] methods;
}
event FeatureFunctionUpdated(
bytes4 indexed methodID,
address oldFeature,
address newFeature
);
function registerFeatures(Feature[] calldata features) external onlyOwner {
unchecked {
for (uint256 i = 0; i < features.length; ++i) {
registerFeature(features[i]);
}
}
}
function registerFeature(Feature calldata feature) public onlyOwner {
unchecked {
address impl = feature.feature;
require(impl != address(0), "registerFeature: invalid feature address.");
LibFeatureStorage.Storage storage stor = LibFeatureStorage.getStorage();
stor.featureNames[impl] = feature.name;
Method[] calldata methods = feature.methods;
for (uint256 i = 0; i < methods.length; ++i) {
bytes4 methodID = methods[i].methodID;
address oldFeature = stor.featureImpls[methodID];
if (oldFeature == address(0)) {
stor.methodIDs.push(methodID);
}
stor.featureImpls[methodID] = impl;
stor.methodNames[methodID] = methods[i].methodName;
emit FeatureFunctionUpdated(methodID, oldFeature, impl);
}
}
}
function unregister(bytes4[] calldata methodIDs) external onlyOwner {
unchecked {
uint256 removedFeatureCount;
LibFeatureStorage.Storage storage stor = LibFeatureStorage.getStorage();
for (uint256 i = 0; i < methodIDs.length; ++i) {
bytes4 methodID = methodIDs[i];
address impl = stor.featureImpls[methodID];
if (impl != address(0)) {
removedFeatureCount++;
stor.featureImpls[methodID] = address(0);
}
emit FeatureFunctionUpdated(methodID, impl, address(0));
}
if (removedFeatureCount == 0) {
return;
}
bytes4[] storage storMethodIDs = stor.methodIDs;
for (uint256 i = storMethodIDs.length; i > 0; --i) {
bytes4 methodID = storMethodIDs[i - 1];
if (stor.featureImpls[methodID] == address(0)) {
if (i != storMethodIDs.length) {
storMethodIDs[i - 1] = storMethodIDs[storMethodIDs.length - 1];
}
delete storMethodIDs[storMethodIDs.length - 1];
storMethodIDs.pop();
if (removedFeatureCount == 1) {
return;
}
--removedFeatureCount;
}
}
}
}
receive() external payable {}
uint256 private constant STORAGE_ID_FEATURE = 1 << 128;
fallback() external payable {
assembly {
calldatacopy(0, 0, 4)
mstore(0x20, STORAGE_ID_FEATURE)
let impl := sload(keccak256(0, 0x40))
if iszero(impl) {
mstore(0, 0x08c379a000000000000000000000000000000000000000000000000000000000)
mstore(0x20, 0x0000002000000000000000000000000000000000000000000000000000000000)
mstore(0x40, 0x000000174e6f7420696d706c656d656e746564206d6574686f642e0000000000)
mstore(0x60, 0)
revert(0, 0x64)
}
calldatacopy(0, 0, calldatasize())
if iszero(delegatecall(gas(), impl, 0, calldatasize(), 0, 0)) {
returndatacopy(0, 0, returndatasize())
revert(0, returndatasize())
}
returndatacopy(0, 0, returndatasize())
return(0, returndatasize())
}
}
function approveERC20(IERC20 token, address operator, uint256 amount) external onlyOwner {
token.approve(operator, amount);
}
function approveERC721(IERC721 token, address operator, bool approved) external {
token.setApprovalForAll(operator, approved);
}
function approveERC1155(IERC1155 token, address operator, bool approved) external {
token.setApprovalForAll(operator, approved);
}
function rescueETH(address recipient) external onlyOwner {
address to = (recipient != address(0)) ? recipient : msg.sender;
_transferEth(to, address(this).balance);
}
function rescueERC20(address asset, address recipient) external onlyOwner {
address to = (recipient != address(0)) ? recipient : msg.sender;
_transferERC20(asset, to, IERC20(asset).balanceOf(address(this)));
}
function rescueERC721(address asset, uint256[] calldata ids , address recipient) external onlyOwner {
assembly {
mstore(0, 0x23b872dd00000000000000000000000000000000000000000000000000000000)
mstore(0x4, address())
switch recipient
case 0 { mstore(0x24, caller()) }
default { mstore(0x24, recipient) }
for { let offset := ids.offset } lt(offset, calldatasize()) { offset := add(offset, 0x20) } {
mstore(0x44, calldataload(offset))
if iszero(call(gas(), asset, 0, 0, 0x64, 0, 0)) {
returndatacopy(0, 0, returndatasize())
revert(0, returndatasize())
}
}
}
}
function onERC1155Received(address, address, uint256, uint256, bytes calldata) external virtual returns (bytes4) {
return this.onERC1155Received.selector;
}
function onERC1155BatchReceived(address, address, uint256[] calldata, uint256[] calldata, bytes calldata) external virtual returns (bytes4) {
return this.onERC1155BatchReceived.selector;
}
function onERC721Received(address, address, uint256, bytes calldata) external virtual returns (bytes4) {
return 0x150b7a02;
}
function onERC721Received(address, uint256, bytes calldata) external virtual returns (bytes4) {
return 0xf0b9e5ba;
}
function supportsInterface(bytes4 interfaceId) external virtual returns (bool) {
return interfaceId == this.supportsInterface.selector;
}
}
文件 11 的 12:Ownable.sol
pragma solidity ^0.8.15;
import "./LibOwnableStorage.sol";
abstract contract Ownable {
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
constructor() {
if (owner() == address(0)) {
_transferOwnership(msg.sender);
}
}
function owner() public view virtual returns (address) {
return LibOwnableStorage.getStorage().owner;
}
modifier onlyOwner() {
require(owner() == msg.sender, "Ownable: caller is not the owner");
_;
}
function transferOwnership(address newOwner) public virtual onlyOwner {
require(newOwner != address(0), "Ownable: new owner is the zero address");
_transferOwnership(newOwner);
}
function _transferOwnership(address newOwner) private {
LibOwnableStorage.Storage storage stor = LibOwnableStorage.getStorage();
address oldOwner = stor.owner;
stor.owner = newOwner;
emit OwnershipTransferred(oldOwner, newOwner);
}
}
文件 12 的 12:ReentrancyGuard.sol
pragma solidity ^0.8.15;
import "./LibOwnableStorage.sol";
abstract contract ReentrancyGuard {
constructor() {
LibOwnableStorage.Storage storage stor = LibOwnableStorage.getStorage();
if (stor.reentrancyStatus == 0) {
stor.reentrancyStatus = 1;
}
}
modifier nonReentrant() {
LibOwnableStorage.Storage storage stor = LibOwnableStorage.getStorage();
require(stor.reentrancyStatus == 1, "ReentrancyGuard: reentrant call");
stor.reentrancyStatus = 2;
_;
stor.reentrancyStatus = 1;
}
}
{
"compilationTarget": {
"src/LootexSwap.sol": "LootexSwap"
},
"evmVersion": "paris",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs"
},
"optimizer": {
"enabled": true,
"runs": 200
},
"remappings": [
":@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/",
":ds-test/=lib/openzeppelin-contracts/lib/forge-std/lib/ds-test/src/",
":erc4626-tests/=lib/openzeppelin-contracts/lib/erc4626-tests/",
":forge-std/=lib/forge-std/src/",
":openzeppelin-contracts/=lib/openzeppelin-contracts/"
]
}
[{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes4","name":"methodID","type":"bytes4"},{"indexed":false,"internalType":"address","name":"oldFeature","type":"address"},{"indexed":false,"internalType":"address","name":"newFeature","type":"address"}],"name":"FeatureFunctionUpdated","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"},{"stateMutability":"payable","type":"fallback"},{"inputs":[{"components":[{"internalType":"address","name":"nft","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"}],"internalType":"struct IAggregator.ERC1155Pair[]","name":"erc1155Pairs","type":"tuple[]"},{"components":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"internalType":"struct IAggregator.ERC20Pair[]","name":"erc20Pairs","type":"tuple[]"},{"internalType":"address[]","name":"dustTokens","type":"address[]"},{"internalType":"bytes","name":"tradeBytes","type":"bytes"}],"name":"acceptWithERC1155","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"nft","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"}],"internalType":"struct IAggregator.ERC721Pair[]","name":"erc721Pairs","type":"tuple[]"},{"components":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"internalType":"struct IAggregator.ERC20Pair[]","name":"erc20Pairs","type":"tuple[]"},{"internalType":"address[]","name":"dustTokens","type":"address[]"},{"internalType":"bytes","name":"tradeBytes","type":"bytes"}],"name":"acceptWithERC721","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"contract IERC1155","name":"token","type":"address"},{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"approveERC1155","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IERC20","name":"token","type":"address"},{"internalType":"address","name":"operator","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"approveERC20","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IERC721","name":"token","type":"address"},{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"approveERC721","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"internalType":"struct IAggregator.ERC20Pair[]","name":"erc20Pairs","type":"tuple[]"},{"internalType":"bytes","name":"tradeBytes","type":"bytes"},{"internalType":"address[]","name":"dustTokens","type":"address[]"}],"name":"batchBuyWithERC20s","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"bytes","name":"tradeBytes","type":"bytes"}],"name":"batchBuyWithETH","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256[]","name":"","type":"uint256[]"},{"internalType":"uint256[]","name":"","type":"uint256[]"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"onERC1155BatchReceived","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"onERC1155Received","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"onERC721Received","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"onERC721Received","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"feature","type":"address"},{"internalType":"string","name":"name","type":"string"},{"components":[{"internalType":"bytes4","name":"methodID","type":"bytes4"},{"internalType":"string","name":"methodName","type":"string"}],"internalType":"struct LootexSwap.Method[]","name":"methods","type":"tuple[]"}],"internalType":"struct LootexSwap.Feature","name":"feature","type":"tuple"}],"name":"registerFeature","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"feature","type":"address"},{"internalType":"string","name":"name","type":"string"},{"components":[{"internalType":"bytes4","name":"methodID","type":"bytes4"},{"internalType":"string","name":"methodName","type":"string"}],"internalType":"struct LootexSwap.Method[]","name":"methods","type":"tuple[]"}],"internalType":"struct LootexSwap.Feature[]","name":"features","type":"tuple[]"}],"name":"registerFeatures","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"asset","type":"address"},{"internalType":"address","name":"recipient","type":"address"}],"name":"rescueERC20","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"asset","type":"address"},{"internalType":"uint256[]","name":"ids","type":"uint256[]"},{"internalType":"address","name":"recipient","type":"address"}],"name":"rescueERC721","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"recipient","type":"address"}],"name":"rescueETH","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4[]","name":"methodIDs","type":"bytes4[]"}],"name":"unregister","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]