文件 1 的 23:ContextUpgradeable.sol
pragma solidity ^0.8.0;
import "../proxy/Initializable.sol";
abstract contract ContextUpgradeable is Initializable {
function __Context_init() internal initializer {
__Context_init_unchained();
}
function __Context_init_unchained() internal initializer {
}
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
this;
return msg.data;
}
uint256[50] private __gap;
}
文件 2 的 23:ERC1155HolderUpgradeable.sol
pragma solidity ^0.8.0;
import "./ERC1155ReceiverUpgradeable.sol";
abstract contract ERC1155HolderUpgradeable is ERC1155ReceiverUpgradeable {
function onERC1155Received(address, address, uint256, uint256, bytes memory) public virtual override returns (bytes4) {
return this.onERC1155Received.selector;
}
function onERC1155BatchReceived(address, address, uint256[] memory, uint256[] memory, bytes memory) public virtual override returns (bytes4) {
return this.onERC1155BatchReceived.selector;
}
}
文件 3 的 23:ERC1155ReceiverUpgradeable.sol
pragma solidity ^0.8.0;
import "./IERC1155ReceiverUpgradeable.sol";
import "../util/ERC165Upgradeable.sol";
abstract contract ERC1155ReceiverUpgradeable is ERC165Upgradeable, IERC1155ReceiverUpgradeable {
function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165Upgradeable, IERC165Upgradeable) returns (bool) {
return interfaceId == type(IERC1155ReceiverUpgradeable).interfaceId
|| super.supportsInterface(interfaceId);
}
}
文件 4 的 23:ERC165Upgradeable.sol
pragma solidity ^0.8.0;
import "../interface/IERC165Upgradeable.sol";
abstract contract ERC165Upgradeable is IERC165Upgradeable {
function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
return interfaceId == type(IERC165Upgradeable).interfaceId;
}
}
文件 5 的 23:ERC721HolderUpgradeable.sol
pragma solidity ^0.8.0;
import "./IERC721ReceiverUpgradeable.sol";
contract ERC721HolderUpgradeable is IERC721ReceiverUpgradeable {
function onERC721Received(
address,
address,
uint256,
bytes memory
) public virtual override returns (bytes4) {
return this.onERC721Received.selector;
}
}
文件 6 的 23:IBeacon.sol
pragma solidity ^0.8.0;
interface IBeacon {
function childImplementation() external view returns (address);
function upgradeChildTo(address newImplementation) external;
}
文件 7 的 23:IERC1155ReceiverUpgradeable.sol
pragma solidity ^0.8.0;
import "../interface/IERC165Upgradeable.sol";
interface IERC1155ReceiverUpgradeable is IERC165Upgradeable {
function onERC1155Received(
address operator,
address from,
uint256 id,
uint256 value,
bytes calldata data
)
external
returns(bytes4);
function onERC1155BatchReceived(
address operator,
address from,
uint256[] calldata ids,
uint256[] calldata values,
bytes calldata data
)
external
returns(bytes4);
}
文件 8 的 23:IERC1155Upgradeable.sol
pragma solidity ^0.8.0;
import "../interface/IERC165Upgradeable.sol";
interface IERC1155Upgradeable is IERC165Upgradeable {
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 amount, bytes calldata data) external;
function safeBatchTransferFrom(address from, address to, uint256[] calldata ids, uint256[] calldata amounts, bytes calldata data) external;
}
文件 9 的 23:IERC165.sol
pragma solidity ^0.8.0;
interface IERC165 {
function supportsInterface(bytes4 interfaceId) external view returns (bool);
}
文件 10 的 23:IERC165Upgradeable.sol
pragma solidity ^0.8.0;
interface IERC165Upgradeable {
function supportsInterface(bytes4 interfaceId) external view returns (bool);
}
文件 11 的 23:IERC20Upgradeable.sol
pragma solidity ^0.8.0;
interface IERC20Upgradeable {
function totalSupply() external view returns (uint256);
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);
event Transfer(address indexed from, address indexed to, uint256 value);
event Approval(address indexed owner, address indexed spender, uint256 value);
}
文件 12 的 23:IERC721.sol
pragma solidity ^0.8.0;
import "./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
) external;
function transferFrom(
address from,
address to,
uint256 tokenId
) external;
function approve(address to, uint256 tokenId) external;
function getApproved(uint256 tokenId)
external
view
returns (address operator);
function setApprovalForAll(address operator, bool _approved) external;
function isApprovedForAll(address owner, address operator)
external
view
returns (bool);
function safeTransferFrom(
address from,
address to,
uint256 tokenId,
bytes calldata data
) external;
}
文件 13 的 23:IERC721ReceiverUpgradeable.sol
pragma solidity ^0.8.0;
interface IERC721ReceiverUpgradeable {
function onERC721Received(address operator, address from, uint256 tokenId, bytes calldata data) external returns (bytes4);
}
文件 14 的 23:INFTXEligibility.sol
pragma solidity ^0.8.0;
interface INFTXEligibility {
function name() external pure returns (string memory);
function finalized() external view returns (bool);
function targetAsset() external pure returns (address);
function checkAllEligible(uint256[] calldata tokenIds)
external
view
returns (bool);
function checkEligible(uint256[] calldata tokenIds)
external
view
returns (bool[] memory);
function checkAllIneligible(uint256[] calldata tokenIds)
external
view
returns (bool);
function checkIsEligible(uint256 tokenId) external view returns (bool);
function __NFTXEligibility_init_bytes(bytes calldata configData) external;
function beforeMintHook(uint256[] calldata tokenIds) external;
function afterMintHook(uint256[] calldata tokenIds) external;
function beforeRedeemHook(uint256[] calldata tokenIds) external;
function afterRedeemHook(uint256[] calldata tokenIds) external;
}
文件 15 的 23:INFTXFeeDistributor.sol
pragma solidity ^0.8.0;
interface INFTXFeeDistributor {
struct FeeReceiver {
uint256 allocPoint;
address receiver;
bool isContract;
}
function nftxVaultFactory() external returns (address);
function lpStaking() external returns (address);
function treasury() external returns (address);
function defaultTreasuryAlloc() external returns (uint256);
function defaultLPAlloc() external returns (uint256);
function allocTotal(uint256 vaultId) external returns (uint256);
function specificTreasuryAlloc(uint256 vaultId) external returns (uint256);
function __FeeDistributor__init__(address _lpStaking, address _treasury) external;
function rescueTokens(address token) external;
function distribute(uint256 vaultId) external;
function addReceiver(uint256 _vaultId, uint256 _allocPoint, address _receiver, bool _isContract) external;
function initializeVaultReceivers(uint256 _vaultId) external;
function changeMultipleReceiverAlloc(
uint256[] memory _vaultIds,
uint256[] memory _receiverIdxs,
uint256[] memory allocPoints
) external;
function changeMultipleReceiverAddress(
uint256[] memory _vaultIds,
uint256[] memory _receiverIdxs,
address[] memory addresses,
bool[] memory isContracts
) external;
function changeReceiverAlloc(uint256 _vaultId, uint256 _idx, uint256 _allocPoint) external;
function changeReceiverAddress(uint256 _vaultId, uint256 _idx, address _address, bool _isContract) external;
function removeReceiver(uint256 _vaultId, uint256 _receiverIdx) external;
function setTreasuryAddress(address _treasury) external;
function setDefaultTreasuryAlloc(uint256 _allocPoint) external;
function setSpecificTreasuryAlloc(uint256 _vaultId, uint256 _allocPoint) external;
function setLPStakingAddress(address _lpStaking) external;
function setNFTXVaultFactory(address _factory) external;
function setDefaultLPAlloc(uint256 _allocPoint) external;
}
文件 16 的 23:INFTXLPStaking.sol
pragma solidity ^0.8.0;
interface INFTXLPStaking {
function nftxVaultFactory() external view returns (address);
function rewardDistTokenImpl() external view returns (address);
function stakingTokenProvider() external view returns (address);
function vaultToken(address _stakingToken) external view returns (address);
function stakingToken(address _vaultToken) external view returns (address);
function rewardDistributionToken(uint256 vaultId) external view returns (address);
function newRewardDistributionToken(uint256 vaultId) external view returns (address);
function oldRewardDistributionToken(uint256 vaultId) external view returns (address);
function unusedRewardDistributionToken(uint256 vaultId) external view returns (address);
function rewardDistributionTokenAddr(address stakingToken, address rewardToken) external view returns (address);
function __NFTXLPStaking__init(address _stakingTokenProvider) external;
function setNFTXVaultFactory(address newFactory) external;
function setStakingTokenProvider(address newProvider) external;
function addPoolForVault(uint256 vaultId) external;
function updatePoolForVault(uint256 vaultId) external;
function updatePoolForVaults(uint256[] calldata vaultId) external;
function receiveRewards(uint256 vaultId, uint256 amount) external returns (bool);
function deposit(uint256 vaultId, uint256 amount) external;
function timelockDepositFor(uint256 vaultId, address account, uint256 amount, uint256 timelockLength) external;
function exit(uint256 vaultId, uint256 amount) external;
function rescue(uint256 vaultId) external;
function withdraw(uint256 vaultId, uint256 amount) external;
function claimRewards(uint256 vaultId) external;
}
文件 17 的 23:INFTXVault.sol
pragma solidity ^0.8.0;
import "../interface/INFTXEligibility.sol";
import "../token/IERC20Upgradeable.sol";
import "../interface/INFTXVaultFactory.sol";
interface INFTXVault is IERC20Upgradeable {
function manager() external view returns (address);
function assetAddress() external view returns (address);
function vaultFactory() external view returns (INFTXVaultFactory);
function eligibilityStorage() external view returns (INFTXEligibility);
function is1155() external view returns (bool);
function allowAllItems() external view returns (bool);
function enableMint() external view returns (bool);
function enableRandomRedeem() external view returns (bool);
function enableTargetRedeem() external view returns (bool);
function enableRandomSwap() external view returns (bool);
function enableTargetSwap() external view returns (bool);
function vaultId() external view returns (uint256);
function nftIdAt(uint256 holdingsIndex) external view returns (uint256);
function allHoldings() external view returns (uint256[] memory);
function totalHoldings() external view returns (uint256);
function mintFee() external view returns (uint256);
function randomRedeemFee() external view returns (uint256);
function targetRedeemFee() external view returns (uint256);
function randomSwapFee() external view returns (uint256);
function targetSwapFee() external view returns (uint256);
function vaultFees() external view returns (uint256, uint256, uint256, uint256, uint256);
event VaultInit(
uint256 indexed vaultId,
address assetAddress,
bool is1155,
bool allowAllItems
);
event ManagerSet(address manager);
event EligibilityDeployed(uint256 moduleIndex, address eligibilityAddr);
event EnableMintUpdated(bool enabled);
event EnableRandomRedeemUpdated(bool enabled);
event EnableTargetRedeemUpdated(bool enabled);
event EnableRandomSwapUpdated(bool enabled);
event EnableTargetSwapUpdated(bool enabled);
event Minted(uint256[] nftIds, uint256[] amounts, address to);
event Redeemed(uint256[] nftIds, uint256[] specificIds, address to);
event Swapped(
uint256[] nftIds,
uint256[] amounts,
uint256[] specificIds,
uint256[] redeemedIds,
address to
);
function __NFTXVault_init(
string calldata _name,
string calldata _symbol,
address _assetAddress,
bool _is1155,
bool _allowAllItems
) external;
function finalizeVault() external;
function setVaultMetadata(
string memory name_,
string memory symbol_
) external;
function setVaultFeatures(
bool _enableMint,
bool _enableRandomRedeem,
bool _enableTargetRedeem,
bool _enableRandomSwap,
bool _enableTargetSwap
) external;
function setFees(
uint256 _mintFee,
uint256 _randomRedeemFee,
uint256 _targetRedeemFee,
uint256 _randomSwapFee,
uint256 _targetSwapFee
) external;
function disableVaultFees() external;
function deployEligibilityStorage(
uint256 moduleIndex,
bytes calldata initData
) external returns (address);
function setManager(address _manager) external;
function mint(
uint256[] calldata tokenIds,
uint256[] calldata amounts
) external returns (uint256);
function mintTo(
uint256[] calldata tokenIds,
uint256[] calldata amounts,
address to
) external returns (uint256);
function redeem(uint256 amount, uint256[] calldata specificIds)
external
returns (uint256[] calldata);
function redeemTo(
uint256 amount,
uint256[] calldata specificIds,
address to
) external returns (uint256[] calldata);
function swap(
uint256[] calldata tokenIds,
uint256[] calldata amounts,
uint256[] calldata specificIds
) external returns (uint256[] calldata);
function swapTo(
uint256[] calldata tokenIds,
uint256[] calldata amounts,
uint256[] calldata specificIds,
address to
) external returns (uint256[] calldata);
function allValidNFTs(uint256[] calldata tokenIds)
external
view
returns (bool);
}
文件 18 的 23:INFTXVaultFactory.sol
pragma solidity ^0.8.0;
import "../proxy/IBeacon.sol";
interface INFTXVaultFactory is IBeacon {
function numVaults() external view returns (uint256);
function zapContract() external view returns (address);
function feeDistributor() external view returns (address);
function eligibilityManager() external view returns (address);
function vault(uint256 vaultId) external view returns (address);
function allVaults() external view returns (address[] memory);
function vaultsForAsset(address asset) external view returns (address[] memory);
function isLocked(uint256 id) external view returns (bool);
function excludedFromFees(address addr) external view returns (bool);
function factoryMintFee() external view returns (uint64);
function factoryRandomRedeemFee() external view returns (uint64);
function factoryTargetRedeemFee() external view returns (uint64);
function factoryRandomSwapFee() external view returns (uint64);
function factoryTargetSwapFee() external view returns (uint64);
function vaultFees(uint256 vaultId) external view returns (uint256, uint256, uint256, uint256, uint256);
event NewFeeDistributor(address oldDistributor, address newDistributor);
event NewZapContract(address oldZap, address newZap);
event FeeExclusion(address feeExcluded, bool excluded);
event NewEligibilityManager(address oldEligManager, address newEligManager);
event NewVault(uint256 indexed vaultId, address vaultAddress, address assetAddress);
event UpdateVaultFees(uint256 vaultId, uint256 mintFee, uint256 randomRedeemFee, uint256 targetRedeemFee, uint256 randomSwapFee, uint256 targetSwapFee);
event DisableVaultFees(uint256 vaultId);
event UpdateFactoryFees(uint256 mintFee, uint256 randomRedeemFee, uint256 targetRedeemFee, uint256 randomSwapFee, uint256 targetSwapFee);
function __NFTXVaultFactory_init(address _vaultImpl, address _feeDistributor) external;
function createVault(
string calldata name,
string calldata symbol,
address _assetAddress,
bool is1155,
bool allowAllItems
) external returns (uint256);
function setFeeDistributor(address _feeDistributor) external;
function setEligibilityManager(address _eligibilityManager) external;
function setZapContract(address _zapContract) external;
function setFeeExclusion(address _excludedAddr, bool excluded) external;
function setFactoryFees(
uint256 mintFee,
uint256 randomRedeemFee,
uint256 targetRedeemFee,
uint256 randomSwapFee,
uint256 targetSwapFee
) external;
function setVaultFees(
uint256 vaultId,
uint256 mintFee,
uint256 randomRedeemFee,
uint256 targetRedeemFee,
uint256 randomSwapFee,
uint256 targetSwapFee
) external;
function disableVaultFees(uint256 vaultId) external;
}
文件 19 的 23:ITimelockRewardDistributionToken.sol
pragma solidity ^0.8.0;
import "../token/IERC20Upgradeable.sol";
interface ITimelockRewardDistributionToken is IERC20Upgradeable {
function distributeRewards(uint amount) external;
function __TimelockRewardDistributionToken_init(IERC20Upgradeable _target, string memory _name, string memory _symbol) external;
function mint(address account, address to, uint256 amount) external;
function timelockMint(address account, uint256 amount, uint256 timelockLength) external;
function burnFrom(address account, uint256 amount) external;
function withdrawReward(address user) external;
function dividendOf(address _owner) external view returns(uint256);
function withdrawnRewardOf(address _owner) external view returns(uint256);
function accumulativeRewardOf(address _owner) external view returns(uint256);
function timelockUntil(address account) external view returns (uint256);
}
文件 20 的 23:IUniswapV2Router01.sol
pragma solidity ^0.8.0;
interface IUniswapV2Router01 {
function factory() external pure returns (address);
function WETH() external pure returns (address);
function addLiquidity(
address tokenA,
address tokenB,
uint256 amountADesired,
uint256 amountBDesired,
uint256 amountAMin,
uint256 amountBMin,
address to,
uint256 deadline
) external returns (uint256 amountA, uint256 amountB, uint256 liquidity);
function addLiquidityETH(
address token,
uint256 amountTokenDesired,
uint256 amountTokenMin,
uint256 amountETHMin,
address to,
uint256 deadline
)
external
payable
returns (uint256 amountToken, uint256 amountETH, uint256 liquidity);
function removeLiquidity(
address tokenA,
address tokenB,
uint256 liquidity,
uint256 amountAMin,
uint256 amountBMin,
address to,
uint256 deadline
) external returns (uint256 amountA, uint256 amountB);
function removeLiquidityETH(
address token,
uint256 liquidity,
uint256 amountTokenMin,
uint256 amountETHMin,
address to,
uint256 deadline
) external returns (uint256 amountToken, uint256 amountETH);
function removeLiquidityWithPermit(
address tokenA,
address tokenB,
uint256 liquidity,
uint256 amountAMin,
uint256 amountBMin,
address to,
uint256 deadline,
bool approveMax,
uint8 v,
bytes32 r,
bytes32 s
) external returns (uint256 amountA, uint256 amountB);
function removeLiquidityETHWithPermit(
address token,
uint256 liquidity,
uint256 amountTokenMin,
uint256 amountETHMin,
address to,
uint256 deadline,
bool approveMax,
uint8 v,
bytes32 r,
bytes32 s
) external returns (uint256 amountToken, uint256 amountETH);
function swapExactTokensForTokens(
uint256 amountIn,
uint256 amountOutMin,
address[] calldata path,
address to,
uint256 deadline
) external returns (uint256[] memory amounts);
function swapTokensForExactTokens(
uint256 amountOut,
uint256 amountInMax,
address[] calldata path,
address to,
uint256 deadline
) external returns (uint256[] memory amounts);
function swapExactETHForTokens(
uint256 amountOutMin,
address[] calldata path,
address to,
uint256 deadline
) external payable returns (uint256[] memory amounts);
function swapTokensForExactETH(
uint256 amountOut,
uint256 amountInMax,
address[] calldata path,
address to,
uint256 deadline
) external returns (uint256[] memory amounts);
function swapExactTokensForETH(
uint256 amountIn,
uint256 amountOutMin,
address[] calldata path,
address to,
uint256 deadline
) external returns (uint256[] memory amounts);
function swapETHForExactTokens(
uint256 amountOut,
address[] calldata path,
address to,
uint256 deadline
) external payable returns (uint256[] memory amounts);
function quote(uint256 amountA, uint256 reserveA, uint256 reserveB)
external
pure
returns (uint256 amountB);
function getAmountOut(
uint256 amountIn,
uint256 reserveIn,
uint256 reserveOut
) external pure returns (uint256 amountOut);
function getAmountIn(
uint256 amountOut,
uint256 reserveIn,
uint256 reserveOut
) external pure returns (uint256 amountIn);
function getAmountsOut(uint256 amountIn, address[] calldata path)
external
view
returns (uint256[] memory amounts);
function getAmountsIn(uint256 amountOut, address[] calldata path)
external
view
returns (uint256[] memory amounts);
}
文件 21 的 23:Initializable.sol
pragma solidity ^0.8.0;
abstract contract Initializable {
bool private _initialized;
bool private _initializing;
modifier initializer() {
require(_initializing || !_initialized, "Initializable: contract is already initialized");
bool isTopLevelCall = !_initializing;
if (isTopLevelCall) {
_initializing = true;
_initialized = true;
}
_;
if (isTopLevelCall) {
_initializing = false;
}
}
}
文件 22 的 23:NFTXMarketplaceZap.sol
pragma solidity ^0.8.0;
import "./interface/INFTXVault.sol";
import "./interface/INFTXVaultFactory.sol";
import "./interface/INFTXFeeDistributor.sol";
import "./interface/INFTXLPStaking.sol";
import "./interface/ITimelockRewardDistributionToken.sol";
import "./interface/IUniswapV2Router01.sol";
import "./testing/IERC721.sol";
import "./token/IERC1155Upgradeable.sol";
import "./token/IERC20Upgradeable.sol";
import "./token/ERC721HolderUpgradeable.sol";
import "./token/ERC1155HolderUpgradeable.sol";
import "./util/OwnableUpgradeable.sol";
interface IWETH {
function deposit() external payable;
function transfer(address to, uint value) external returns (bool);
function withdraw(uint) external;
function balanceOf(address to) external view returns (uint256);
}
abstract contract ReentrancyGuard {
uint256 private constant _NOT_ENTERED = 1;
uint256 private constant _ENTERED = 2;
uint256 private _status;
constructor() {
_status = _NOT_ENTERED;
}
modifier nonReentrant() {
require(_status != _ENTERED, "ReentrancyGuard: reentrant call");
_status = _ENTERED;
_;
_status = _NOT_ENTERED;
}
}
abstract contract Ownable {
address private _owner;
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
constructor() {
_setOwner(msg.sender);
}
function owner() public view virtual returns (address) {
return _owner;
}
modifier onlyOwner() {
require(owner() == msg.sender, "Ownable: caller is not the owner");
_;
}
function renounceOwnership() public virtual onlyOwner {
_setOwner(address(0));
}
function transferOwnership(address newOwner) public virtual onlyOwner {
require(newOwner != address(0), "Ownable: new owner is the zero address");
_setOwner(newOwner);
}
function _setOwner(address newOwner) private {
address oldOwner = _owner;
_owner = newOwner;
emit OwnershipTransferred(oldOwner, newOwner);
}
}
contract NFTXMarketplaceZap is Ownable, ReentrancyGuard, ERC721HolderUpgradeable, ERC1155HolderUpgradeable {
IWETH public immutable WETH;
INFTXLPStaking public immutable lpStaking;
INFTXVaultFactory public immutable nftxFactory;
IUniswapV2Router01 public immutable sushiRouter;
uint256 constant BASE = 10**18;
event Buy(uint256 count, uint256 ethSpent, address to);
event Sell(uint256 count, uint256 ethReceived, address to);
event Swap(uint256 count, uint256 ethSpent, address to);
constructor(address _nftxFactory, address _sushiRouter) Ownable() ReentrancyGuard() {
nftxFactory = INFTXVaultFactory(_nftxFactory);
lpStaking = INFTXLPStaking(INFTXFeeDistributor(INFTXVaultFactory(_nftxFactory).feeDistributor()).lpStaking());
sushiRouter = IUniswapV2Router01(_sushiRouter);
WETH = IWETH(IUniswapV2Router01(_sushiRouter).WETH());
IERC20Upgradeable(address(IUniswapV2Router01(_sushiRouter).WETH())).approve(_sushiRouter, type(uint256).max);
}
function mintAndSell721(
uint256 vaultId,
uint256[] memory ids,
uint256 minWethOut,
address[] calldata path,
address to
) public nonReentrant {
require(to != address(0));
require(ids.length != 0);
(address vault, uint256 vaultBalance) = _mint721(vaultId, ids);
uint256[] memory amounts = _sellVaultTokenETH(vault, minWethOut, vaultBalance, path, to);
emit Sell(ids.length, amounts[1], to);
}
function mintAndSell721WETH(
uint256 vaultId,
uint256[] memory ids,
uint256 minWethOut,
address[] calldata path,
address to
) public nonReentrant {
require(to != address(0));
require(ids.length != 0);
(address vault, uint256 vaultBalance) = _mint721(vaultId, ids);
uint256[] memory amounts = _sellVaultTokenWETH(vault, minWethOut, vaultBalance, path, to);
emit Sell(ids.length, amounts[1], to);
}
function buyAndSwap721(
uint256 vaultId,
uint256[] memory idsIn,
uint256[] memory specificIds,
address[] calldata path,
address to
) public payable nonReentrant {
require(to != address(0));
require(idsIn.length != 0);
WETH.deposit{value: msg.value}();
INFTXVault vault = INFTXVault(nftxFactory.vault(vaultId));
uint256 redeemFees = (vault.targetSwapFee() * specificIds.length) + (
vault.randomSwapFee() * (idsIn.length - specificIds.length)
);
uint256[] memory amounts = _buyVaultToken(address(vault), redeemFees, msg.value, path);
_swap721(vaultId, idsIn, specificIds, to);
emit Swap(idsIn.length, amounts[0], to);
uint256 remaining = WETH.balanceOf(address(this));
WETH.withdraw(remaining);
(bool success, ) = payable(to).call{value: remaining}("");
require(success, "Address: unable to send value, recipient may have reverted");
}
function buyAndSwap721WETH(
uint256 vaultId,
uint256[] memory idsIn,
uint256[] memory specificIds,
uint256 maxWethIn,
address[] calldata path,
address to
) public nonReentrant {
require(to != address(0));
require(idsIn.length != 0);
IERC20Upgradeable(address(WETH)).transferFrom(msg.sender, address(this), maxWethIn);
INFTXVault vault = INFTXVault(nftxFactory.vault(vaultId));
uint256 redeemFees = (vault.targetSwapFee() * specificIds.length) + (
vault.randomSwapFee() * (idsIn.length - specificIds.length)
);
uint256[] memory amounts = _buyVaultToken(address(vault), redeemFees, maxWethIn, path);
_swap721(vaultId, idsIn, specificIds, to);
emit Swap(idsIn.length, amounts[0], to);
uint256 remaining = WETH.balanceOf(address(this));
WETH.transfer(to, remaining);
}
function buyAndSwap1155(
uint256 vaultId,
uint256[] memory idsIn,
uint256[] memory amounts,
uint256[] memory specificIds,
address[] calldata path,
address to
) public payable nonReentrant {
require(to != address(0));
require(idsIn.length != 0);
WETH.deposit{value: msg.value}();
uint256 count;
for (uint256 i = 0; i < idsIn.length; i++) {
uint256 amount = amounts[i];
require(amount > 0, "Transferring < 1");
count += amount;
}
INFTXVault vault = INFTXVault(nftxFactory.vault(vaultId));
uint256 redeemFees = (vault.targetSwapFee() * specificIds.length) + (
vault.randomSwapFee() * (count - specificIds.length)
);
uint256[] memory swapAmounts = _buyVaultToken(address(vault), redeemFees, msg.value, path);
_swap1155(vaultId, idsIn, amounts, specificIds, to);
emit Swap(count, swapAmounts[0], to);
uint256 remaining = WETH.balanceOf(address(this));
WETH.withdraw(remaining);
(bool success, ) = payable(to).call{value: remaining}("");
require(success, "Address: unable to send value, recipient may have reverted");
}
function buyAndSwap1155WETH(
uint256 vaultId,
uint256[] memory idsIn,
uint256[] memory amounts,
uint256[] memory specificIds,
uint256 maxWethIn,
address[] calldata path,
address to
) public payable nonReentrant {
require(to != address(0));
require(idsIn.length != 0);
IERC20Upgradeable(address(WETH)).transferFrom(msg.sender, address(this), maxWethIn);
uint256 count;
for (uint256 i = 0; i < idsIn.length; i++) {
uint256 amount = amounts[i];
require(amount > 0, "Transferring < 1");
count += amount;
}
INFTXVault vault = INFTXVault(nftxFactory.vault(vaultId));
uint256 redeemFees = (vault.targetSwapFee() * specificIds.length) + (
vault.randomSwapFee() * (count - specificIds.length)
);
uint256[] memory swapAmounts = _buyVaultToken(address(vault), redeemFees, msg.value, path);
_swap1155(vaultId, idsIn, amounts, specificIds, to);
emit Swap(count, swapAmounts[0], to);
uint256 remaining = WETH.balanceOf(address(this));
WETH.transfer(to, remaining);
}
function buyAndRedeem(
uint256 vaultId,
uint256 amount,
uint256[] memory specificIds,
address[] calldata path,
address to
) public payable nonReentrant {
require(to != address(0));
require(amount != 0);
WETH.deposit{value: msg.value}();
INFTXVault vault = INFTXVault(nftxFactory.vault(vaultId));
uint256 totalFee = (vault.targetRedeemFee() * specificIds.length) + (
vault.randomRedeemFee() * (amount - specificIds.length)
);
uint256[] memory amounts = _buyVaultToken(address(vault), (amount*BASE)+totalFee, msg.value, path);
_redeem(vaultId, amount, specificIds, to);
emit Buy(amount, amounts[0], to);
uint256 remaining = WETH.balanceOf(address(this));
WETH.withdraw(remaining);
(bool success, ) = payable(to).call{value: remaining}("");
require(success, "Address: unable to send value, recipient may have reverted");
}
function buyAndRedeemWETH(
uint256 vaultId,
uint256 amount,
uint256[] memory specificIds,
uint256 maxWethIn,
address[] calldata path,
address to
) public nonReentrant {
require(to != address(0));
require(amount != 0);
IERC20Upgradeable(address(WETH)).transferFrom(msg.sender, address(this), maxWethIn);
INFTXVault vault = INFTXVault(nftxFactory.vault(vaultId));
uint256 totalFee = (vault.targetRedeemFee() * specificIds.length) + (
vault.randomRedeemFee() * (amount - specificIds.length)
);
uint256[] memory amounts = _buyVaultToken(address(vault), (amount*BASE) + totalFee, maxWethIn, path);
_redeem(vaultId, amount, specificIds, to);
emit Buy(amount, amounts[0], to);
uint256 remaining = WETH.balanceOf(address(this));
WETH.transfer(to, remaining);
}
function mintAndSell1155(
uint256 vaultId,
uint256[] memory ids,
uint256[] memory amounts,
uint256 minWethOut,
address[] calldata path,
address to
) public nonReentrant {
require(to != address(0));
require(ids.length != 0);
(address vault, uint256 vaultTokenBalance) = _mint1155(vaultId, ids, amounts);
uint256[] memory amounts = _sellVaultTokenETH(vault, minWethOut, vaultTokenBalance, path, to);
uint256 count;
for (uint256 i = 0; i < ids.length; i++) {
count += amounts[i];
}
emit Sell(count, amounts[1], to);
}
function mintAndSell1155WETH(
uint256 vaultId,
uint256[] memory ids,
uint256[] memory amounts,
uint256 minWethOut,
address[] calldata path,
address to
) public nonReentrant {
require(to != address(0));
require(ids.length != 0);
(address vault, uint256 vaultTokenBalance) = _mint1155(vaultId, ids, amounts);
_sellVaultTokenWETH(vault, minWethOut, vaultTokenBalance, path, to);
uint256 count;
for (uint256 i = 0; i < ids.length; i++) {
count += amounts[i];
}
emit Sell(count, amounts[1], to);
}
function _mint721(
uint256 vaultId,
uint256[] memory ids
) internal returns (address, uint256) {
address vault = nftxFactory.vault(vaultId);
require(vault != address(0), "NFTXZap: Vault does not exist");
address assetAddress = INFTXVault(vault).assetAddress();
for (uint256 i = 0; i < ids.length; i++) {
transferFromERC721(assetAddress, ids[i], vault);
approveERC721(assetAddress, vault, ids[i]);
}
uint256[] memory emptyIds;
uint256 count = INFTXVault(vault).mint(ids, emptyIds);
uint256 balance = (count * BASE) - (count * INFTXVault(vault).mintFee());
require(balance == IERC20Upgradeable(vault).balanceOf(address(this)), "Did not receive expected balance");
return (vault, balance);
}
function _swap721(
uint256 vaultId,
uint256[] memory idsIn,
uint256[] memory idsOut,
address to
) internal returns (address) {
address vault = nftxFactory.vault(vaultId);
require(vault != address(0), "NFTXZap: Vault does not exist");
address assetAddress = INFTXVault(vault).assetAddress();
for (uint256 i = 0; i < idsIn.length; i++) {
transferFromERC721(assetAddress, idsIn[i], vault);
approveERC721(assetAddress, vault, idsIn[i]);
}
uint256[] memory emptyIds;
INFTXVault(vault).swapTo(idsIn, emptyIds, idsOut, to);
return (vault);
}
function _swap1155(
uint256 vaultId,
uint256[] memory idsIn,
uint256[] memory amounts,
uint256[] memory idsOut,
address to
) internal returns (address) {
address vault = nftxFactory.vault(vaultId);
require(vault != address(0), "NFTXZap: Vault does not exist");
address assetAddress = INFTXVault(vault).assetAddress();
IERC1155Upgradeable(assetAddress).safeBatchTransferFrom(msg.sender, address(this), idsIn, amounts, "");
IERC1155Upgradeable(assetAddress).setApprovalForAll(vault, true);
INFTXVault(vault).swapTo(idsIn, amounts, idsOut, to);
return (vault);
}
function _redeem(
uint256 vaultId,
uint256 amount,
uint256[] memory specificIds,
address to
) internal {
address vault = nftxFactory.vault(vaultId);
require(vault != address(0), "NFTXZap: Vault does not exist");
INFTXVault(vault).redeemTo(amount, specificIds, to);
}
function _mint1155(
uint256 vaultId,
uint256[] memory ids,
uint256[] memory amounts
) internal returns (address, uint256) {
address vault = nftxFactory.vault(vaultId);
require(vault != address(0), "NFTXZap: Vault does not exist");
address assetAddress = INFTXVault(vault).assetAddress();
IERC1155Upgradeable(assetAddress).safeBatchTransferFrom(msg.sender, address(this), ids, amounts, "");
IERC1155Upgradeable(assetAddress).setApprovalForAll(vault, true);
uint256 count = INFTXVault(vault).mint(ids, amounts);
uint256 balance = (count * BASE) - INFTXVault(vault).mintFee()*count;
require(balance == IERC20Upgradeable(vault).balanceOf(address(this)), "Did not receive expected balance");
return (vault, balance);
}
function _buyVaultToken(
address vault,
uint256 minTokenOut,
uint256 maxWethIn,
address[] calldata path
) internal returns (uint256[] memory) {
uint256[] memory amounts = sushiRouter.swapTokensForExactTokens(
minTokenOut,
maxWethIn,
path,
address(this),
block.timestamp
);
return amounts;
}
function _sellVaultTokenWETH(
address vault,
uint256 minWethOut,
uint256 maxTokenIn,
address[] calldata path,
address to
) internal returns (uint256[] memory) {
IERC20Upgradeable(vault).approve(address(sushiRouter), maxTokenIn);
uint256[] memory amounts = sushiRouter.swapExactTokensForTokens(
maxTokenIn,
minWethOut,
path,
to,
block.timestamp
);
return amounts;
}
function _sellVaultTokenETH(
address vault,
uint256 minWethOut,
uint256 maxTokenIn,
address[] calldata path,
address to
) internal returns (uint256[] memory) {
IERC20Upgradeable(vault).approve(address(sushiRouter), maxTokenIn);
uint256[] memory amounts = sushiRouter.swapExactTokensForETH(
maxTokenIn,
minWethOut,
path,
to,
block.timestamp
);
return amounts;
}
function transferFromERC721(address assetAddr, uint256 tokenId, address to) internal virtual {
address kitties = 0x06012c8cf97BEaD5deAe237070F9587f8E7A266d;
address punks = 0xb47e3cd837dDF8e4c57F05d70Ab865de6e193BBB;
bytes memory data;
if (assetAddr == kitties) {
data = abi.encodeWithSignature("transferFrom(address,address,uint256)", msg.sender, address(this), tokenId);
} else if (assetAddr == punks) {
bytes memory punkIndexToAddress = abi.encodeWithSignature("punkIndexToAddress(uint256)", tokenId);
(bool checkSuccess, bytes memory result) = address(assetAddr).staticcall(punkIndexToAddress);
(address owner) = abi.decode(result, (address));
require(checkSuccess && owner == msg.sender, "Not the owner");
data = abi.encodeWithSignature("buyPunk(uint256)", tokenId);
} else {
data = abi.encodeWithSignature("safeTransferFrom(address,address,uint256)", msg.sender, to, tokenId);
}
(bool success, bytes memory resultData) = address(assetAddr).call(data);
require(success, string(resultData));
}
function approveERC721(address assetAddr, address to, uint256 tokenId) internal virtual {
address kitties = 0x06012c8cf97BEaD5deAe237070F9587f8E7A266d;
address punks = 0xb47e3cd837dDF8e4c57F05d70Ab865de6e193BBB;
bytes memory data;
if (assetAddr == kitties) {
data = abi.encodeWithSignature("approve(address,uint256)", to, tokenId);
} else if (assetAddr == punks) {
data = abi.encodeWithSignature("offerPunkForSaleToAddress(uint256,uint256,address)", tokenId, 0, to);
} else {
return;
}
(bool success, bytes memory resultData) = address(assetAddr).call(data);
require(success, string(resultData));
}
function pairFor(address tokenA, address tokenB) internal view returns (address pair) {
(address token0, address token1) = sortTokens(tokenA, tokenB);
pair = address(uint160(uint256(keccak256(abi.encodePacked(
hex'ff',
sushiRouter.factory(),
keccak256(abi.encodePacked(token0, token1)),
hex'e18a34eb0e04b04f7a0ac29a6e80748dca96319b42c54d679cb821dca90c6303'
)))));
}
function sortTokens(address tokenA, address tokenB) internal pure returns (address token0, address token1) {
require(tokenA != tokenB, 'UniswapV2Library: IDENTICAL_ADDRESSES');
(token0, token1) = tokenA < tokenB ? (tokenA, tokenB) : (tokenB, tokenA);
require(token0 != address(0), 'UniswapV2Library: ZERO_ADDRESS');
}
receive() external payable {
}
}
文件 23 的 23:OwnableUpgradeable.sol
pragma solidity ^0.8.0;
import "./ContextUpgradeable.sol";
import "../proxy/Initializable.sol";
abstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {
address private _owner;
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
function __Ownable_init() internal initializer {
__Context_init_unchained();
__Ownable_init_unchained();
}
function __Ownable_init_unchained() internal initializer {
address msgSender = _msgSender();
_owner = msgSender;
emit OwnershipTransferred(address(0), msgSender);
}
function owner() public view virtual returns (address) {
return _owner;
}
modifier onlyOwner() {
require(owner() == _msgSender(), "Ownable: caller is not the owner");
_;
}
function renounceOwnership() public virtual onlyOwner {
emit OwnershipTransferred(_owner, address(0));
_owner = address(0);
}
function transferOwnership(address newOwner) public virtual onlyOwner {
require(newOwner != address(0), "Ownable: new owner is the zero address");
emit OwnershipTransferred(_owner, newOwner);
_owner = newOwner;
}
uint256[49] private __gap;
}
{
"compilationTarget": {
"contracts/solidity/NFTXMarketplaceZap.sol": "NFTXMarketplaceZap"
},
"evmVersion": "istanbul",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs"
},
"optimizer": {
"enabled": true,
"runs": 1000
},
"remappings": []
}
[{"inputs":[{"internalType":"address","name":"_nftxFactory","type":"address"},{"internalType":"address","name":"_sushiRouter","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"count","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"ethSpent","type":"uint256"},{"indexed":false,"internalType":"address","name":"to","type":"address"}],"name":"Buy","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":"uint256","name":"count","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"ethReceived","type":"uint256"},{"indexed":false,"internalType":"address","name":"to","type":"address"}],"name":"Sell","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"count","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"ethSpent","type":"uint256"},{"indexed":false,"internalType":"address","name":"to","type":"address"}],"name":"Swap","type":"event"},{"inputs":[],"name":"WETH","outputs":[{"internalType":"contract IWETH","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"vaultId","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256[]","name":"specificIds","type":"uint256[]"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"address","name":"to","type":"address"}],"name":"buyAndRedeem","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"vaultId","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256[]","name":"specificIds","type":"uint256[]"},{"internalType":"uint256","name":"maxWethIn","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"address","name":"to","type":"address"}],"name":"buyAndRedeemWETH","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"vaultId","type":"uint256"},{"internalType":"uint256[]","name":"idsIn","type":"uint256[]"},{"internalType":"uint256[]","name":"amounts","type":"uint256[]"},{"internalType":"uint256[]","name":"specificIds","type":"uint256[]"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"address","name":"to","type":"address"}],"name":"buyAndSwap1155","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"vaultId","type":"uint256"},{"internalType":"uint256[]","name":"idsIn","type":"uint256[]"},{"internalType":"uint256[]","name":"amounts","type":"uint256[]"},{"internalType":"uint256[]","name":"specificIds","type":"uint256[]"},{"internalType":"uint256","name":"maxWethIn","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"address","name":"to","type":"address"}],"name":"buyAndSwap1155WETH","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"vaultId","type":"uint256"},{"internalType":"uint256[]","name":"idsIn","type":"uint256[]"},{"internalType":"uint256[]","name":"specificIds","type":"uint256[]"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"address","name":"to","type":"address"}],"name":"buyAndSwap721","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"vaultId","type":"uint256"},{"internalType":"uint256[]","name":"idsIn","type":"uint256[]"},{"internalType":"uint256[]","name":"specificIds","type":"uint256[]"},{"internalType":"uint256","name":"maxWethIn","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"address","name":"to","type":"address"}],"name":"buyAndSwap721WETH","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"lpStaking","outputs":[{"internalType":"contract INFTXLPStaking","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"vaultId","type":"uint256"},{"internalType":"uint256[]","name":"ids","type":"uint256[]"},{"internalType":"uint256[]","name":"amounts","type":"uint256[]"},{"internalType":"uint256","name":"minWethOut","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"address","name":"to","type":"address"}],"name":"mintAndSell1155","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"vaultId","type":"uint256"},{"internalType":"uint256[]","name":"ids","type":"uint256[]"},{"internalType":"uint256[]","name":"amounts","type":"uint256[]"},{"internalType":"uint256","name":"minWethOut","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"address","name":"to","type":"address"}],"name":"mintAndSell1155WETH","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"vaultId","type":"uint256"},{"internalType":"uint256[]","name":"ids","type":"uint256[]"},{"internalType":"uint256","name":"minWethOut","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"address","name":"to","type":"address"}],"name":"mintAndSell721","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"vaultId","type":"uint256"},{"internalType":"uint256[]","name":"ids","type":"uint256[]"},{"internalType":"uint256","name":"minWethOut","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"address","name":"to","type":"address"}],"name":"mintAndSell721WETH","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"nftxFactory","outputs":[{"internalType":"contract INFTXVaultFactory","name":"","type":"address"}],"stateMutability":"view","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":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"sushiRouter","outputs":[{"internalType":"contract IUniswapV2Router01","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]