Source Code
More Info
Private Name Tags
ContractCreator
TokenTracker
Latest 25 from a total of 30 transactions
| Transaction Hash |
|
Block
|
From
|
To
|
|||||
|---|---|---|---|---|---|---|---|---|---|
| Buy Target NFT | 16109704 | 108 days ago | IN | 0 HYPE | 0.00004468 | ||||
| Set Collection | 16109669 | 108 days ago | IN | 0 HYPE | 0.00000398 | ||||
| Manual Swap Back | 15528901 | 114 days ago | IN | 0 HYPE | 0.00001414 | ||||
| Manual Swap Back | 15528875 | 114 days ago | IN | 0 HYPE | 0.00001414 | ||||
| Manual Swap Back | 15507212 | 114 days ago | IN | 0 HYPE | 0.00016638 | ||||
| Set Swap Setting... | 15507197 | 114 days ago | IN | 0 HYPE | 0.00005045 | ||||
| Manual Swap Back | 15507013 | 114 days ago | IN | 0 HYPE | 0.00061661 | ||||
| Manual Swap Back | 15506995 | 114 days ago | IN | 0 HYPE | 0.0006617 | ||||
| Manual Swap Back | 15506943 | 114 days ago | IN | 0 HYPE | 0.00074443 | ||||
| Manual Swap Back | 15506919 | 114 days ago | IN | 0 HYPE | 0.00083859 | ||||
| Manual Swap Back | 15506912 | 114 days ago | IN | 0 HYPE | 0.0008956 | ||||
| Set Swap Fees | 15506801 | 114 days ago | IN | 0 HYPE | 0.00007957 | ||||
| Approve | 15505102 | 114 days ago | IN | 0 HYPE | 0.00032507 | ||||
| Transfer | 15504983 | 114 days ago | IN | 0 HYPE | 0.00003263 | ||||
| Transfer | 15504877 | 114 days ago | IN | 0 HYPE | 0.00005575 | ||||
| Manual Swap Back | 15504761 | 114 days ago | IN | 0 HYPE | 0.00006666 | ||||
| Set Collection | 15504681 | 114 days ago | IN | 0 HYPE | 0.00118115 | ||||
| Manual Swap Back | 15503510 | 114 days ago | IN | 0 HYPE | 0.00000262 | ||||
| Approve | 15503381 | 114 days ago | IN | 0 HYPE | 0.0363254 | ||||
| Enable Trading | 15503374 | 114 days ago | IN | 0 HYPE | 0.00000346 | ||||
| Add Pair | 15503066 | 114 days ago | IN | 0 HYPE | 0.00001195 | ||||
| Set Price Multip... | 15503063 | 114 days ago | IN | 0 HYPE | 0.00001633 | ||||
| Set Swap Setting... | 15503060 | 114 days ago | IN | 0 HYPE | 0.00004992 | ||||
| Set Royalty Shar... | 15503038 | 114 days ago | IN | 0 HYPE | 0.00000443 | ||||
| Set Royalty Wall... | 15503035 | 114 days ago | IN | 0 HYPE | 0.00000716 |
Latest 23 internal transactions
Advanced mode:
| Parent Transaction Hash | Block | From | To | |||
|---|---|---|---|---|---|---|
| 16109704 | 108 days ago | 9.82939134 HYPE | ||||
| 15507212 | 114 days ago | 0.64032406 HYPE | ||||
| 15507212 | 114 days ago | 7.11471184 HYPE | ||||
| 15507013 | 114 days ago | 0.02600897 HYPE | ||||
| 15507013 | 114 days ago | 0.28898857 HYPE | ||||
| 15506995 | 114 days ago | 0.02632413 HYPE | ||||
| 15506995 | 114 days ago | 0.29249036 HYPE | ||||
| 15506943 | 114 days ago | 0.02664506 HYPE | ||||
| 15506943 | 114 days ago | 0.29605623 HYPE | ||||
| 15506919 | 114 days ago | 0.02697189 HYPE | ||||
| 15506919 | 114 days ago | 0.29968773 HYPE | ||||
| 15506912 | 114 days ago | 0.02730478 HYPE | ||||
| 15506912 | 114 days ago | 0.3033865 HYPE | ||||
| 15505112 | 114 days ago | 0.0285061 HYPE | ||||
| 15505112 | 114 days ago | 0.3167345 HYPE | ||||
| 15505055 | 114 days ago | 0.03697624 HYPE | ||||
| 15505055 | 114 days ago | 0.41084718 HYPE | ||||
| 15504733 | 114 days ago | 0.04044087 HYPE | ||||
| 15504733 | 114 days ago | 0.449343 HYPE | ||||
| 15504715 | 114 days ago | 0.04532198 HYPE | ||||
| 15504715 | 114 days ago | 0.50357759 HYPE | ||||
| 15504682 | 114 days ago | 0.04731348 HYPE | ||||
| 15504682 | 114 days ago | 0.52570541 HYPE |
Cross-Chain Transactions
Loading...
Loading
Contract Name:
HypurrStrategy
Compiler Version
v0.8.20+commit.a1b79de6
Optimization Enabled:
Yes with 50 runs
Other Settings:
paris EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import {ERC20} from "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol";
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import {SafeERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import {ReentrancyGuard} from "@openzeppelin/contracts/utils/ReentrancyGuard.sol";
import {IERC721Receiver} from "@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol";
import {IHyperswapRouter} from "./interfaces/IHyperswapRouter.sol";
import {IERC721} from "./interfaces/IERC721.sol";
import {IHypurrStrategy} from "./interfaces/IHypurrStrategy.sol";
/// @title HypurrStrategy
contract HypurrStrategy is ERC20, Ownable, ReentrancyGuard, IERC721Receiver, IHypurrStrategy {
using SafeERC20 for IERC20;
uint16 public buyFeeBps = 1000;
uint16 public sellFeeBps = 1000;
uint16 public sellFeeBeforeNftBoughtBps = 5000;
uint16 public constant MAX_FEE_BEFORE_NFT_BOUGHT_BPS = 5000;
uint16 public constant MAX_FEE_BPS = 1000;
uint16 public constant BPS_DENOMINATOR = 10000;
uint16 public WALLET_SHARE_BPS = 1000;
uint16 public constant REWARD_BPS_CAP = 100;
address public feeWallet;
address public royaltyWallet;
uint16 public royaltyShareBps;
IHyperswapRouter public immutable router;
address[] public pairs;
address public immutable weth;
bool private inSwap;
bool public tradingEnabled = false;
bool public swapEnabled = true;
uint256 public swapThreshold;
mapping(address => bool) public isExempt;
mapping(address => bool) public isPair;
bool public buyerWhitelistEnabled = false;
mapping(address => bool) public isBuyerWhitelisted;
bool public targetWhitelistEnabled = false;
mapping(address => bool) public isTargetWhitelisted;
IERC721 public collection;
mapping(uint256 => uint256) public nftForSale;
uint256 public priceMultiplier = 12000;
uint256 public currentFees;
uint256 public ethToTwap;
uint256 public twapIncrement = 1 ether;
uint16 public twapRewardBps = 10;
uint256 public twapDelayInSeconds = 1;
uint256 public lastTwapTimestamp;
bool public wasNftBought = false;
error NFTNotForSale();
error NFTIncorrectPayment();
error NotEnoughEth();
error AlreadyNFTOwner();
error NeedToBuyNFT();
error NotNFTOwner();
error InvalidCollection();
modifier lockSwap() {
inSwap = true;
_;
inSwap = false;
}
constructor(
string memory name_,
string memory symbol_,
uint256 supply_,
address router_,
address feeWallet_
) ERC20(name_, symbol_) Ownable(msg.sender) {
require(feeWallet_ != address(0), "fee wallet");
require(router_ != address(0), "router");
router = IHyperswapRouter(router_);
weth = router.WETH();
feeWallet = feeWallet_;
_mint(msg.sender, supply_);
swapThreshold = supply_ / 400;
isExempt[msg.sender] = true;
isExempt[address(this)] = true;
isExempt[feeWallet_] = true;
}
// --- Owner config ---
function setSwapFees(uint16 buy_, uint16 sell_, uint16 sellFeeBeforeNftBought_) external onlyOwner {
require(buy_ <= MAX_FEE_BPS && sell_ <= MAX_FEE_BPS, "fee too high");
buyFeeBps = buy_;
sellFeeBps = sell_;
require(sellFeeBeforeNftBought_ <= MAX_FEE_BEFORE_NFT_BOUGHT_BPS, "sell fee before nft bought too high");
sellFeeBeforeNftBoughtBps = sellFeeBeforeNftBought_;
emit FeesUpdated(buy_, sell_);
}
function setFeeWallet(address wallet_) external onlyOwner {
require(wallet_ != address(0), "wallet");
feeWallet = wallet_;
isExempt[wallet_] = true;
emit FeeWalletUpdated(wallet_);
}
function setWalletShare(uint16 share_) external onlyOwner {
require(share_ <= MAX_FEE_BPS, "share too high");
WALLET_SHARE_BPS = share_;
}
function setRoyaltyWallet(address wallet_) external onlyOwner {
require(wallet_ != address(0), "wallet");
royaltyWallet = wallet_;
}
function setRoyaltyShare(uint16 share_) external onlyOwner {
require(share_ <= MAX_FEE_BPS, "share too high");
royaltyShareBps = share_;
}
function setExempt(address a, bool e) external onlyOwner { isExempt[a] = e; }
function setSwapSettings(bool enabled, uint256 threshold) external onlyOwner { swapEnabled = enabled; swapThreshold = threshold; }
function setPriceMultiplier(uint256 bps) external onlyOwner { require(bps >= 11000 && bps <= 30000, "mult"); priceMultiplier = bps; }
function enableTrading() external onlyOwner {
if (tradingEnabled) revert("enabled");
if (pairs.length == 0) revert("pair");
tradingEnabled = true;
emit TradingEnabled();
}
/// @notice Owner can register an existing pair (LP token is held by this contract)
function addPair(address pair_) external onlyOwner {
require(pair_ != address(0), "pair");
require(!isPair[pair_], "pair exists");
isPair[pair_] = true;
pairs.push(pair_);
emit PairCreated(pair_);
}
function pairsLength() external view returns (uint256) { return pairs.length; }
// --- ERC20 fee on transfer ---
function _update(address from, address to, uint256 amount) internal override {
if (!tradingEnabled && from != owner() && to != owner()) revert("trading");
if (
swapEnabled && !inSwap && balanceOf(address(this)) >= swapThreshold &&
(isPair[from] || isPair[to])
) {
_swapBack();
}
uint256 fees = 0;
uint16 sellFeeCheckBps = wasNftBought ? sellFeeBps : sellFeeBeforeNftBoughtBps;
if (!isExempt[from] && !isExempt[to]) {
if (isPair[from] && buyFeeBps > 0) {
fees = (amount * buyFeeBps) / BPS_DENOMINATOR;
} else if (isPair[to] && sellFeeCheckBps > 0) {
fees = (amount * sellFeeCheckBps) / BPS_DENOMINATOR;
}
}
if (fees > 0) {
super._update(from, address(this), fees);
amount -= fees;
}
super._update(from, to, amount);
}
function _swapBack() internal lockSwap {
uint256 contractBalance = balanceOf(address(this));
if (contractBalance == 0) return;
uint256 amountToSwap = contractBalance > swapThreshold * 2 ? swapThreshold * 2 : contractBalance;
_approve(address(this), address(router), amountToSwap);
address[] memory path = new address[](2);
path[0] = address(this);
path[1] = weth;
uint256 balBefore = address(this).balance;
router.swapExactTokensForETHSupportingFeeOnTransferTokens(
amountToSwap,
0,
path,
address(this),
address(0),
block.timestamp
);
uint256 ethReceived = address(this).balance - balBefore;
if (ethReceived > 0) {
uint256 toWallet = (ethReceived * WALLET_SHARE_BPS) / BPS_DENOMINATOR;
uint256 toProtocol = ethReceived - toWallet;
currentFees += toProtocol;
if (toWallet > 0) {
(bool ok, ) = payable(feeWallet).call{value: toWallet}("");
if (!ok) {
emit FeeWalletPayoutFailed(feeWallet, toWallet);
}
}
emit SwapBack(amountToSwap, ethReceived);
}
}
function manualSwapBack() external onlyOwner {
_swapBack();
}
// --- TWAP processing (buy and burn tokens) ---
function processTokenTwap() external nonReentrant {
require(ethToTwap > 0, "no twap");
require(block.timestamp >= lastTwapTimestamp + twapDelayInSeconds, "twap delay");
uint256 burnAmount = twapIncrement;
if (ethToTwap < twapIncrement) burnAmount = ethToTwap;
uint256 reward = (burnAmount * twapRewardBps) / BPS_DENOMINATOR;
burnAmount -= reward;
ethToTwap -= burnAmount + reward;
lastTwapTimestamp = block.timestamp;
_buyAndBurnTokens(burnAmount);
(bool s, ) = payable(msg.sender).call{value: reward}("");
require(s, "reward");
}
function setTwapParams(uint256 increment, uint256 delaySeconds, uint16 rewardBps) external onlyOwner {
require(rewardBps <= REWARD_BPS_CAP, "reward cap");
twapIncrement = increment;
twapDelayInSeconds = delaySeconds;
twapRewardBps = rewardBps;
}
function _buyAndBurnTokens(uint256 amountIn) internal {
address[] memory path = new address[](2);
path[0] = weth;
path[1] = address(this);
router.swapExactETHForTokensSupportingFeeOnTransferTokens{value: amountIn}(
0,
path,
0x000000000000000000000000000000000000dEaD,
address(0),
block.timestamp
);
}
// --- NFT buy/sell ---
function buyTargetNFT(uint256 value, bytes calldata data, uint256 expectedId, address target) external nonReentrant {
if (buyerWhitelistEnabled) {
require(isBuyerWhitelisted[msg.sender], "buyer wl");
}
if (targetWhitelistEnabled) {
require(isTargetWhitelisted[target], "target wl");
}
require(address(collection) != address(0), "collection");
if (collection.ownerOf(expectedId) == address(this)) revert AlreadyNFTOwner();
if (value > currentFees) revert NotEnoughEth();
uint256 ethBefore = address(this).balance;
uint256 nftBefore = collection.balanceOf(address(this));
(bool ok, bytes memory reason) = target.call{value: value}(data);
if (!ok) {
assembly { revert(add(reason, 0x20), mload(reason)) }
}
uint256 nftAfter = collection.balanceOf(address(this));
if (nftAfter != nftBefore + 1) revert NeedToBuyNFT();
if (collection.ownerOf(expectedId) != address(this)) revert NotNFTOwner();
uint256 cost = ethBefore - address(this).balance;
currentFees -= cost;
uint256 salePrice = (cost * priceMultiplier) / BPS_DENOMINATOR;
uint256 salePriceWithRoyalty = salePrice * BPS_DENOMINATOR / (BPS_DENOMINATOR - royaltyShareBps);
nftForSale[expectedId] = salePriceWithRoyalty;
wasNftBought = true;
emit NFTBoughtByProtocol(expectedId, cost, salePriceWithRoyalty);
}
function _safeOwnerOf(uint256 tokenId) internal view returns (address) {
try collection.ownerOf(tokenId) returns (address o) { return o; } catch { return address(0); }
}
function sellTargetNFT(uint256 tokenId) external payable nonReentrant {
uint256 salePrice = nftForSale[tokenId];
if (salePrice == 0) revert NFTNotForSale();
if (msg.value != salePrice) revert NFTIncorrectPayment();
if (collection.ownerOf(tokenId) != address(this)) revert NotNFTOwner();
collection.transferFrom(address(this), msg.sender, tokenId);
uint256 royalty = (salePrice * royaltyShareBps) / BPS_DENOMINATOR;
if (royalty > 0 && royaltyWallet != address(0)) {
(bool sR, ) = payable(royaltyWallet).call{value: royalty}("");
require(sR, "royalty");
}
delete nftForSale[tokenId];
ethToTwap += salePrice - royalty;
emit NFTSoldByProtocol(tokenId, salePrice, msg.sender);
}
function onERC721Received(
address,
address,
uint256,
bytes calldata
) external override returns (bytes4) {
if (msg.sender != address(collection)) {
revert InvalidCollection();
}
return IERC721Receiver.onERC721Received.selector;
}
// --- Owner config: whitelists and collection checks ---
function setBuyerWhitelistEnabled(bool enabled) external onlyOwner {
buyerWhitelistEnabled = enabled;
emit BuyerWhitelistEnabled(enabled);
}
function setBuyerWhitelist(address account, bool whitelisted) external onlyOwner {
isBuyerWhitelisted[account] = whitelisted;
emit BuyerWhitelistUpdated(account, whitelisted);
}
function setTargetWhitelistEnabled(bool enabled) external onlyOwner {
targetWhitelistEnabled = enabled;
emit TargetWhitelistEnabled(enabled);
}
function setTargetWhitelist(address target, bool whitelisted) external onlyOwner {
isTargetWhitelisted[target] = whitelisted;
emit TargetWhitelistUpdated(target, whitelisted);
}
function setCollection(address nft) external onlyOwner {
require(nft != address(0), "wallet");
collection = IERC721(nft);
emit CollectionUpdated(nft);
}
receive() external payable {}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (access/Ownable.sol)
pragma solidity ^0.8.20;
import {Context} from "../utils/Context.sol";
/**
* @dev Contract module which provides a basic access control mechanism, where
* there is an account (an owner) that can be granted exclusive access to
* specific functions.
*
* The initial owner is set to the address provided by the deployer. This can
* later be changed with {transferOwnership}.
*
* This module is used through inheritance. It will make available the modifier
* `onlyOwner`, which can be applied to your functions to restrict their use to
* the owner.
*/
abstract contract Ownable is Context {
address private _owner;
/**
* @dev The caller account is not authorized to perform an operation.
*/
error OwnableUnauthorizedAccount(address account);
/**
* @dev The owner is not a valid owner account. (eg. `address(0)`)
*/
error OwnableInvalidOwner(address owner);
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
/**
* @dev Initializes the contract setting the address provided by the deployer as the initial owner.
*/
constructor(address initialOwner) {
if (initialOwner == address(0)) {
revert OwnableInvalidOwner(address(0));
}
_transferOwnership(initialOwner);
}
/**
* @dev Throws if called by any account other than the owner.
*/
modifier onlyOwner() {
_checkOwner();
_;
}
/**
* @dev Returns the address of the current owner.
*/
function owner() public view virtual returns (address) {
return _owner;
}
/**
* @dev Throws if the sender is not the owner.
*/
function _checkOwner() internal view virtual {
if (owner() != _msgSender()) {
revert OwnableUnauthorizedAccount(_msgSender());
}
}
/**
* @dev Leaves the contract without owner. It will not be possible to call
* `onlyOwner` functions. Can only be called by the current owner.
*
* NOTE: Renouncing ownership will leave the contract without an owner,
* thereby disabling any functionality that is only available to the owner.
*/
function renounceOwnership() public virtual onlyOwner {
_transferOwnership(address(0));
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Can only be called by the current owner.
*/
function transferOwnership(address newOwner) public virtual onlyOwner {
if (newOwner == address(0)) {
revert OwnableInvalidOwner(address(0));
}
_transferOwnership(newOwner);
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Internal function without access restriction.
*/
function _transferOwnership(address newOwner) internal virtual {
address oldOwner = _owner;
_owner = newOwner;
emit OwnershipTransferred(oldOwner, newOwner);
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.4.0) (interfaces/draft-IERC6093.sol)
pragma solidity >=0.8.4;
/**
* @dev Standard ERC-20 Errors
* Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC-20 tokens.
*/
interface IERC20Errors {
/**
* @dev Indicates an error related to the current `balance` of a `sender`. Used in transfers.
* @param sender Address whose tokens are being transferred.
* @param balance Current balance for the interacting account.
* @param needed Minimum amount required to perform a transfer.
*/
error ERC20InsufficientBalance(address sender, uint256 balance, uint256 needed);
/**
* @dev Indicates a failure with the token `sender`. Used in transfers.
* @param sender Address whose tokens are being transferred.
*/
error ERC20InvalidSender(address sender);
/**
* @dev Indicates a failure with the token `receiver`. Used in transfers.
* @param receiver Address to which tokens are being transferred.
*/
error ERC20InvalidReceiver(address receiver);
/**
* @dev Indicates a failure with the `spender`’s `allowance`. Used in transfers.
* @param spender Address that may be allowed to operate on tokens without being their owner.
* @param allowance Amount of tokens a `spender` is allowed to operate with.
* @param needed Minimum amount required to perform a transfer.
*/
error ERC20InsufficientAllowance(address spender, uint256 allowance, uint256 needed);
/**
* @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals.
* @param approver Address initiating an approval operation.
*/
error ERC20InvalidApprover(address approver);
/**
* @dev Indicates a failure with the `spender` to be approved. Used in approvals.
* @param spender Address that may be allowed to operate on tokens without being their owner.
*/
error ERC20InvalidSpender(address spender);
}
/**
* @dev Standard ERC-721 Errors
* Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC-721 tokens.
*/
interface IERC721Errors {
/**
* @dev Indicates that an address can't be an owner. For example, `address(0)` is a forbidden owner in ERC-20.
* Used in balance queries.
* @param owner Address of the current owner of a token.
*/
error ERC721InvalidOwner(address owner);
/**
* @dev Indicates a `tokenId` whose `owner` is the zero address.
* @param tokenId Identifier number of a token.
*/
error ERC721NonexistentToken(uint256 tokenId);
/**
* @dev Indicates an error related to the ownership over a particular token. Used in transfers.
* @param sender Address whose tokens are being transferred.
* @param tokenId Identifier number of a token.
* @param owner Address of the current owner of a token.
*/
error ERC721IncorrectOwner(address sender, uint256 tokenId, address owner);
/**
* @dev Indicates a failure with the token `sender`. Used in transfers.
* @param sender Address whose tokens are being transferred.
*/
error ERC721InvalidSender(address sender);
/**
* @dev Indicates a failure with the token `receiver`. Used in transfers.
* @param receiver Address to which tokens are being transferred.
*/
error ERC721InvalidReceiver(address receiver);
/**
* @dev Indicates a failure with the `operator`’s approval. Used in transfers.
* @param operator Address that may be allowed to operate on tokens without being their owner.
* @param tokenId Identifier number of a token.
*/
error ERC721InsufficientApproval(address operator, uint256 tokenId);
/**
* @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals.
* @param approver Address initiating an approval operation.
*/
error ERC721InvalidApprover(address approver);
/**
* @dev Indicates a failure with the `operator` to be approved. Used in approvals.
* @param operator Address that may be allowed to operate on tokens without being their owner.
*/
error ERC721InvalidOperator(address operator);
}
/**
* @dev Standard ERC-1155 Errors
* Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC-1155 tokens.
*/
interface IERC1155Errors {
/**
* @dev Indicates an error related to the current `balance` of a `sender`. Used in transfers.
* @param sender Address whose tokens are being transferred.
* @param balance Current balance for the interacting account.
* @param needed Minimum amount required to perform a transfer.
* @param tokenId Identifier number of a token.
*/
error ERC1155InsufficientBalance(address sender, uint256 balance, uint256 needed, uint256 tokenId);
/**
* @dev Indicates a failure with the token `sender`. Used in transfers.
* @param sender Address whose tokens are being transferred.
*/
error ERC1155InvalidSender(address sender);
/**
* @dev Indicates a failure with the token `receiver`. Used in transfers.
* @param receiver Address to which tokens are being transferred.
*/
error ERC1155InvalidReceiver(address receiver);
/**
* @dev Indicates a failure with the `operator`’s approval. Used in transfers.
* @param operator Address that may be allowed to operate on tokens without being their owner.
* @param owner Address of the current owner of a token.
*/
error ERC1155MissingApprovalForAll(address operator, address owner);
/**
* @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals.
* @param approver Address initiating an approval operation.
*/
error ERC1155InvalidApprover(address approver);
/**
* @dev Indicates a failure with the `operator` to be approved. Used in approvals.
* @param operator Address that may be allowed to operate on tokens without being their owner.
*/
error ERC1155InvalidOperator(address operator);
/**
* @dev Indicates an array length mismatch between ids and values in a safeBatchTransferFrom operation.
* Used in batch transfers.
* @param idsLength Length of the array of token identifiers
* @param valuesLength Length of the array of token amounts
*/
error ERC1155InvalidArrayLength(uint256 idsLength, uint256 valuesLength);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.4.0) (interfaces/IERC1363.sol)
pragma solidity >=0.6.2;
import {IERC20} from "./IERC20.sol";
import {IERC165} from "./IERC165.sol";
/**
* @title IERC1363
* @dev Interface of the ERC-1363 standard as defined in the https://eips.ethereum.org/EIPS/eip-1363[ERC-1363].
*
* Defines an extension interface for ERC-20 tokens that supports executing code on a recipient contract
* after `transfer` or `transferFrom`, or code on a spender contract after `approve`, in a single transaction.
*/
interface IERC1363 is IERC20, IERC165 {
/*
* Note: the ERC-165 identifier for this interface is 0xb0202a11.
* 0xb0202a11 ===
* bytes4(keccak256('transferAndCall(address,uint256)')) ^
* bytes4(keccak256('transferAndCall(address,uint256,bytes)')) ^
* bytes4(keccak256('transferFromAndCall(address,address,uint256)')) ^
* bytes4(keccak256('transferFromAndCall(address,address,uint256,bytes)')) ^
* bytes4(keccak256('approveAndCall(address,uint256)')) ^
* bytes4(keccak256('approveAndCall(address,uint256,bytes)'))
*/
/**
* @dev Moves a `value` amount of tokens from the caller's account to `to`
* and then calls {IERC1363Receiver-onTransferReceived} on `to`.
* @param to The address which you want to transfer to.
* @param value The amount of tokens to be transferred.
* @return A boolean value indicating whether the operation succeeded unless throwing.
*/
function transferAndCall(address to, uint256 value) external returns (bool);
/**
* @dev Moves a `value` amount of tokens from the caller's account to `to`
* and then calls {IERC1363Receiver-onTransferReceived} on `to`.
* @param to The address which you want to transfer to.
* @param value The amount of tokens to be transferred.
* @param data Additional data with no specified format, sent in call to `to`.
* @return A boolean value indicating whether the operation succeeded unless throwing.
*/
function transferAndCall(address to, uint256 value, bytes calldata data) external returns (bool);
/**
* @dev Moves a `value` amount of tokens from `from` to `to` using the allowance mechanism
* and then calls {IERC1363Receiver-onTransferReceived} on `to`.
* @param from The address which you want to send tokens from.
* @param to The address which you want to transfer to.
* @param value The amount of tokens to be transferred.
* @return A boolean value indicating whether the operation succeeded unless throwing.
*/
function transferFromAndCall(address from, address to, uint256 value) external returns (bool);
/**
* @dev Moves a `value` amount of tokens from `from` to `to` using the allowance mechanism
* and then calls {IERC1363Receiver-onTransferReceived} on `to`.
* @param from The address which you want to send tokens from.
* @param to The address which you want to transfer to.
* @param value The amount of tokens to be transferred.
* @param data Additional data with no specified format, sent in call to `to`.
* @return A boolean value indicating whether the operation succeeded unless throwing.
*/
function transferFromAndCall(address from, address to, uint256 value, bytes calldata data) external returns (bool);
/**
* @dev Sets a `value` amount of tokens as the allowance of `spender` over the
* caller's tokens and then calls {IERC1363Spender-onApprovalReceived} on `spender`.
* @param spender The address which will spend the funds.
* @param value The amount of tokens to be spent.
* @return A boolean value indicating whether the operation succeeded unless throwing.
*/
function approveAndCall(address spender, uint256 value) external returns (bool);
/**
* @dev Sets a `value` amount of tokens as the allowance of `spender` over the
* caller's tokens and then calls {IERC1363Spender-onApprovalReceived} on `spender`.
* @param spender The address which will spend the funds.
* @param value The amount of tokens to be spent.
* @param data Additional data with no specified format, sent in call to `spender`.
* @return A boolean value indicating whether the operation succeeded unless throwing.
*/
function approveAndCall(address spender, uint256 value, bytes calldata data) external returns (bool);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.4.0) (interfaces/IERC165.sol)
pragma solidity >=0.4.16;
import {IERC165} from "../utils/introspection/IERC165.sol";// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.4.0) (interfaces/IERC20.sol)
pragma solidity >=0.4.16;
import {IERC20} from "../token/ERC20/IERC20.sol";// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.4.0) (token/ERC20/ERC20.sol)
pragma solidity ^0.8.20;
import {IERC20} from "./IERC20.sol";
import {IERC20Metadata} from "./extensions/IERC20Metadata.sol";
import {Context} from "../../utils/Context.sol";
import {IERC20Errors} from "../../interfaces/draft-IERC6093.sol";
/**
* @dev Implementation of the {IERC20} interface.
*
* This implementation is agnostic to the way tokens are created. This means
* that a supply mechanism has to be added in a derived contract using {_mint}.
*
* TIP: For a detailed writeup see our guide
* https://forum.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226[How
* to implement supply mechanisms].
*
* The default value of {decimals} is 18. To change this, you should override
* this function so it returns a different value.
*
* We have followed general OpenZeppelin Contracts guidelines: functions revert
* instead returning `false` on failure. This behavior is nonetheless
* conventional and does not conflict with the expectations of ERC-20
* applications.
*/
abstract contract ERC20 is Context, IERC20, IERC20Metadata, IERC20Errors {
mapping(address account => uint256) private _balances;
mapping(address account => mapping(address spender => uint256)) private _allowances;
uint256 private _totalSupply;
string private _name;
string private _symbol;
/**
* @dev Sets the values for {name} and {symbol}.
*
* Both values are immutable: they can only be set once during construction.
*/
constructor(string memory name_, string memory symbol_) {
_name = name_;
_symbol = symbol_;
}
/**
* @dev Returns the name of the token.
*/
function name() public view virtual returns (string memory) {
return _name;
}
/**
* @dev Returns the symbol of the token, usually a shorter version of the
* name.
*/
function symbol() public view virtual returns (string memory) {
return _symbol;
}
/**
* @dev Returns the number of decimals used to get its user representation.
* For example, if `decimals` equals `2`, a balance of `505` tokens should
* be displayed to a user as `5.05` (`505 / 10 ** 2`).
*
* Tokens usually opt for a value of 18, imitating the relationship between
* Ether and Wei. This is the default value returned by this function, unless
* it's overridden.
*
* NOTE: This information is only used for _display_ purposes: it in
* no way affects any of the arithmetic of the contract, including
* {IERC20-balanceOf} and {IERC20-transfer}.
*/
function decimals() public view virtual returns (uint8) {
return 18;
}
/// @inheritdoc IERC20
function totalSupply() public view virtual returns (uint256) {
return _totalSupply;
}
/// @inheritdoc IERC20
function balanceOf(address account) public view virtual returns (uint256) {
return _balances[account];
}
/**
* @dev See {IERC20-transfer}.
*
* Requirements:
*
* - `to` cannot be the zero address.
* - the caller must have a balance of at least `value`.
*/
function transfer(address to, uint256 value) public virtual returns (bool) {
address owner = _msgSender();
_transfer(owner, to, value);
return true;
}
/// @inheritdoc IERC20
function allowance(address owner, address spender) public view virtual returns (uint256) {
return _allowances[owner][spender];
}
/**
* @dev See {IERC20-approve}.
*
* NOTE: If `value` is the maximum `uint256`, the allowance is not updated on
* `transferFrom`. This is semantically equivalent to an infinite approval.
*
* Requirements:
*
* - `spender` cannot be the zero address.
*/
function approve(address spender, uint256 value) public virtual returns (bool) {
address owner = _msgSender();
_approve(owner, spender, value);
return true;
}
/**
* @dev See {IERC20-transferFrom}.
*
* Skips emitting an {Approval} event indicating an allowance update. This is not
* required by the ERC. See {xref-ERC20-_approve-address-address-uint256-bool-}[_approve].
*
* NOTE: Does not update the allowance if the current allowance
* is the maximum `uint256`.
*
* Requirements:
*
* - `from` and `to` cannot be the zero address.
* - `from` must have a balance of at least `value`.
* - the caller must have allowance for ``from``'s tokens of at least
* `value`.
*/
function transferFrom(address from, address to, uint256 value) public virtual returns (bool) {
address spender = _msgSender();
_spendAllowance(from, spender, value);
_transfer(from, to, value);
return true;
}
/**
* @dev Moves a `value` amount of tokens from `from` to `to`.
*
* This internal function is equivalent to {transfer}, and can be used to
* e.g. implement automatic token fees, slashing mechanisms, etc.
*
* Emits a {Transfer} event.
*
* NOTE: This function is not virtual, {_update} should be overridden instead.
*/
function _transfer(address from, address to, uint256 value) internal {
if (from == address(0)) {
revert ERC20InvalidSender(address(0));
}
if (to == address(0)) {
revert ERC20InvalidReceiver(address(0));
}
_update(from, to, value);
}
/**
* @dev Transfers a `value` amount of tokens from `from` to `to`, or alternatively mints (or burns) if `from`
* (or `to`) is the zero address. All customizations to transfers, mints, and burns should be done by overriding
* this function.
*
* Emits a {Transfer} event.
*/
function _update(address from, address to, uint256 value) internal virtual {
if (from == address(0)) {
// Overflow check required: The rest of the code assumes that totalSupply never overflows
_totalSupply += value;
} else {
uint256 fromBalance = _balances[from];
if (fromBalance < value) {
revert ERC20InsufficientBalance(from, fromBalance, value);
}
unchecked {
// Overflow not possible: value <= fromBalance <= totalSupply.
_balances[from] = fromBalance - value;
}
}
if (to == address(0)) {
unchecked {
// Overflow not possible: value <= totalSupply or value <= fromBalance <= totalSupply.
_totalSupply -= value;
}
} else {
unchecked {
// Overflow not possible: balance + value is at most totalSupply, which we know fits into a uint256.
_balances[to] += value;
}
}
emit Transfer(from, to, value);
}
/**
* @dev Creates a `value` amount of tokens and assigns them to `account`, by transferring it from address(0).
* Relies on the `_update` mechanism
*
* Emits a {Transfer} event with `from` set to the zero address.
*
* NOTE: This function is not virtual, {_update} should be overridden instead.
*/
function _mint(address account, uint256 value) internal {
if (account == address(0)) {
revert ERC20InvalidReceiver(address(0));
}
_update(address(0), account, value);
}
/**
* @dev Destroys a `value` amount of tokens from `account`, lowering the total supply.
* Relies on the `_update` mechanism.
*
* Emits a {Transfer} event with `to` set to the zero address.
*
* NOTE: This function is not virtual, {_update} should be overridden instead
*/
function _burn(address account, uint256 value) internal {
if (account == address(0)) {
revert ERC20InvalidSender(address(0));
}
_update(account, address(0), value);
}
/**
* @dev Sets `value` as the allowance of `spender` over the `owner`'s tokens.
*
* This internal function is equivalent to `approve`, and can be used to
* e.g. set automatic allowances for certain subsystems, etc.
*
* Emits an {Approval} event.
*
* Requirements:
*
* - `owner` cannot be the zero address.
* - `spender` cannot be the zero address.
*
* Overrides to this logic should be done to the variant with an additional `bool emitEvent` argument.
*/
function _approve(address owner, address spender, uint256 value) internal {
_approve(owner, spender, value, true);
}
/**
* @dev Variant of {_approve} with an optional flag to enable or disable the {Approval} event.
*
* By default (when calling {_approve}) the flag is set to true. On the other hand, approval changes made by
* `_spendAllowance` during the `transferFrom` operation set the flag to false. This saves gas by not emitting any
* `Approval` event during `transferFrom` operations.
*
* Anyone who wishes to continue emitting `Approval` events on the`transferFrom` operation can force the flag to
* true using the following override:
*
* ```solidity
* function _approve(address owner, address spender, uint256 value, bool) internal virtual override {
* super._approve(owner, spender, value, true);
* }
* ```
*
* Requirements are the same as {_approve}.
*/
function _approve(address owner, address spender, uint256 value, bool emitEvent) internal virtual {
if (owner == address(0)) {
revert ERC20InvalidApprover(address(0));
}
if (spender == address(0)) {
revert ERC20InvalidSpender(address(0));
}
_allowances[owner][spender] = value;
if (emitEvent) {
emit Approval(owner, spender, value);
}
}
/**
* @dev Updates `owner`'s allowance for `spender` based on spent `value`.
*
* Does not update the allowance value in case of infinite allowance.
* Revert if not enough allowance is available.
*
* Does not emit an {Approval} event.
*/
function _spendAllowance(address owner, address spender, uint256 value) internal virtual {
uint256 currentAllowance = allowance(owner, spender);
if (currentAllowance < type(uint256).max) {
if (currentAllowance < value) {
revert ERC20InsufficientAllowance(spender, currentAllowance, value);
}
unchecked {
_approve(owner, spender, currentAllowance - value, false);
}
}
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.4.0) (token/ERC20/extensions/IERC20Metadata.sol)
pragma solidity >=0.6.2;
import {IERC20} from "../IERC20.sol";
/**
* @dev Interface for the optional metadata functions from the ERC-20 standard.
*/
interface IERC20Metadata is IERC20 {
/**
* @dev Returns the name of the token.
*/
function name() external view returns (string memory);
/**
* @dev Returns the symbol of the token.
*/
function symbol() external view returns (string memory);
/**
* @dev Returns the decimals places of the token.
*/
function decimals() external view returns (uint8);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.4.0) (token/ERC20/IERC20.sol)
pragma solidity >=0.4.16;
/**
* @dev Interface of the ERC-20 standard as defined in the ERC.
*/
interface IERC20 {
/**
* @dev Emitted when `value` tokens are moved from one account (`from`) to
* another (`to`).
*
* Note that `value` may be zero.
*/
event Transfer(address indexed from, address indexed to, uint256 value);
/**
* @dev Emitted when the allowance of a `spender` for an `owner` is set by
* a call to {approve}. `value` is the new allowance.
*/
event Approval(address indexed owner, address indexed spender, uint256 value);
/**
* @dev Returns the value of tokens in existence.
*/
function totalSupply() external view returns (uint256);
/**
* @dev Returns the value of tokens owned by `account`.
*/
function balanceOf(address account) external view returns (uint256);
/**
* @dev Moves a `value` amount of tokens from the caller's account to `to`.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transfer(address to, uint256 value) external returns (bool);
/**
* @dev Returns the remaining number of tokens that `spender` will be
* allowed to spend on behalf of `owner` through {transferFrom}. This is
* zero by default.
*
* This value changes when {approve} or {transferFrom} are called.
*/
function allowance(address owner, address spender) external view returns (uint256);
/**
* @dev Sets a `value` amount of tokens as the allowance of `spender` over the
* caller's tokens.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* IMPORTANT: Beware that changing an allowance with this method brings the risk
* that someone may use both the old and the new allowance by unfortunate
* transaction ordering. One possible solution to mitigate this race
* condition is to first reduce the spender's allowance to 0 and set the
* desired value afterwards:
* https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
*
* Emits an {Approval} event.
*/
function approve(address spender, uint256 value) external returns (bool);
/**
* @dev Moves a `value` amount of tokens from `from` to `to` using the
* allowance mechanism. `value` is then deducted from the caller's
* allowance.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transferFrom(address from, address to, uint256 value) external returns (bool);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.3.0) (token/ERC20/utils/SafeERC20.sol)
pragma solidity ^0.8.20;
import {IERC20} from "../IERC20.sol";
import {IERC1363} from "../../../interfaces/IERC1363.sol";
/**
* @title SafeERC20
* @dev Wrappers around ERC-20 operations that throw on failure (when the token
* contract returns false). Tokens that return no value (and instead revert or
* throw on failure) are also supported, non-reverting calls are assumed to be
* successful.
* To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,
* which allows you to call the safe operations as `token.safeTransfer(...)`, etc.
*/
library SafeERC20 {
/**
* @dev An operation with an ERC-20 token failed.
*/
error SafeERC20FailedOperation(address token);
/**
* @dev Indicates a failed `decreaseAllowance` request.
*/
error SafeERC20FailedDecreaseAllowance(address spender, uint256 currentAllowance, uint256 requestedDecrease);
/**
* @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value,
* non-reverting calls are assumed to be successful.
*/
function safeTransfer(IERC20 token, address to, uint256 value) internal {
_callOptionalReturn(token, abi.encodeCall(token.transfer, (to, value)));
}
/**
* @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the
* calling contract. If `token` returns no value, non-reverting calls are assumed to be successful.
*/
function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {
_callOptionalReturn(token, abi.encodeCall(token.transferFrom, (from, to, value)));
}
/**
* @dev Variant of {safeTransfer} that returns a bool instead of reverting if the operation is not successful.
*/
function trySafeTransfer(IERC20 token, address to, uint256 value) internal returns (bool) {
return _callOptionalReturnBool(token, abi.encodeCall(token.transfer, (to, value)));
}
/**
* @dev Variant of {safeTransferFrom} that returns a bool instead of reverting if the operation is not successful.
*/
function trySafeTransferFrom(IERC20 token, address from, address to, uint256 value) internal returns (bool) {
return _callOptionalReturnBool(token, abi.encodeCall(token.transferFrom, (from, to, value)));
}
/**
* @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value,
* non-reverting calls are assumed to be successful.
*
* IMPORTANT: If the token implements ERC-7674 (ERC-20 with temporary allowance), and if the "client"
* smart contract uses ERC-7674 to set temporary allowances, then the "client" smart contract should avoid using
* this function. Performing a {safeIncreaseAllowance} or {safeDecreaseAllowance} operation on a token contract
* that has a non-zero temporary allowance (for that particular owner-spender) will result in unexpected behavior.
*/
function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {
uint256 oldAllowance = token.allowance(address(this), spender);
forceApprove(token, spender, oldAllowance + value);
}
/**
* @dev Decrease the calling contract's allowance toward `spender` by `requestedDecrease`. If `token` returns no
* value, non-reverting calls are assumed to be successful.
*
* IMPORTANT: If the token implements ERC-7674 (ERC-20 with temporary allowance), and if the "client"
* smart contract uses ERC-7674 to set temporary allowances, then the "client" smart contract should avoid using
* this function. Performing a {safeIncreaseAllowance} or {safeDecreaseAllowance} operation on a token contract
* that has a non-zero temporary allowance (for that particular owner-spender) will result in unexpected behavior.
*/
function safeDecreaseAllowance(IERC20 token, address spender, uint256 requestedDecrease) internal {
unchecked {
uint256 currentAllowance = token.allowance(address(this), spender);
if (currentAllowance < requestedDecrease) {
revert SafeERC20FailedDecreaseAllowance(spender, currentAllowance, requestedDecrease);
}
forceApprove(token, spender, currentAllowance - requestedDecrease);
}
}
/**
* @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value,
* non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval
* to be set to zero before setting it to a non-zero value, such as USDT.
*
* NOTE: If the token implements ERC-7674, this function will not modify any temporary allowance. This function
* only sets the "standard" allowance. Any temporary allowance will remain active, in addition to the value being
* set here.
*/
function forceApprove(IERC20 token, address spender, uint256 value) internal {
bytes memory approvalCall = abi.encodeCall(token.approve, (spender, value));
if (!_callOptionalReturnBool(token, approvalCall)) {
_callOptionalReturn(token, abi.encodeCall(token.approve, (spender, 0)));
_callOptionalReturn(token, approvalCall);
}
}
/**
* @dev Performs an {ERC1363} transferAndCall, with a fallback to the simple {ERC20} transfer if the target has no
* code. This can be used to implement an {ERC721}-like safe transfer that rely on {ERC1363} checks when
* targeting contracts.
*
* Reverts if the returned value is other than `true`.
*/
function transferAndCallRelaxed(IERC1363 token, address to, uint256 value, bytes memory data) internal {
if (to.code.length == 0) {
safeTransfer(token, to, value);
} else if (!token.transferAndCall(to, value, data)) {
revert SafeERC20FailedOperation(address(token));
}
}
/**
* @dev Performs an {ERC1363} transferFromAndCall, with a fallback to the simple {ERC20} transferFrom if the target
* has no code. This can be used to implement an {ERC721}-like safe transfer that rely on {ERC1363} checks when
* targeting contracts.
*
* Reverts if the returned value is other than `true`.
*/
function transferFromAndCallRelaxed(
IERC1363 token,
address from,
address to,
uint256 value,
bytes memory data
) internal {
if (to.code.length == 0) {
safeTransferFrom(token, from, to, value);
} else if (!token.transferFromAndCall(from, to, value, data)) {
revert SafeERC20FailedOperation(address(token));
}
}
/**
* @dev Performs an {ERC1363} approveAndCall, with a fallback to the simple {ERC20} approve if the target has no
* code. This can be used to implement an {ERC721}-like safe transfer that rely on {ERC1363} checks when
* targeting contracts.
*
* NOTE: When the recipient address (`to`) has no code (i.e. is an EOA), this function behaves as {forceApprove}.
* Opposedly, when the recipient address (`to`) has code, this function only attempts to call {ERC1363-approveAndCall}
* once without retrying, and relies on the returned value to be true.
*
* Reverts if the returned value is other than `true`.
*/
function approveAndCallRelaxed(IERC1363 token, address to, uint256 value, bytes memory data) internal {
if (to.code.length == 0) {
forceApprove(token, to, value);
} else if (!token.approveAndCall(to, value, data)) {
revert SafeERC20FailedOperation(address(token));
}
}
/**
* @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
* on the return value: the return value is optional (but if data is returned, it must not be false).
* @param token The token targeted by the call.
* @param data The call data (encoded using abi.encode or one of its variants).
*
* This is a variant of {_callOptionalReturnBool} that reverts if call fails to meet the requirements.
*/
function _callOptionalReturn(IERC20 token, bytes memory data) private {
uint256 returnSize;
uint256 returnValue;
assembly ("memory-safe") {
let success := call(gas(), token, 0, add(data, 0x20), mload(data), 0, 0x20)
// bubble errors
if iszero(success) {
let ptr := mload(0x40)
returndatacopy(ptr, 0, returndatasize())
revert(ptr, returndatasize())
}
returnSize := returndatasize()
returnValue := mload(0)
}
if (returnSize == 0 ? address(token).code.length == 0 : returnValue != 1) {
revert SafeERC20FailedOperation(address(token));
}
}
/**
* @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
* on the return value: the return value is optional (but if data is returned, it must not be false).
* @param token The token targeted by the call.
* @param data The call data (encoded using abi.encode or one of its variants).
*
* This is a variant of {_callOptionalReturn} that silently catches all reverts and returns a bool instead.
*/
function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) {
bool success;
uint256 returnSize;
uint256 returnValue;
assembly ("memory-safe") {
success := call(gas(), token, 0, add(data, 0x20), mload(data), 0, 0x20)
returnSize := returndatasize()
returnValue := mload(0)
}
return success && (returnSize == 0 ? address(token).code.length > 0 : returnValue == 1);
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.4.0) (token/ERC721/IERC721Receiver.sol)
pragma solidity >=0.5.0;
/**
* @title ERC-721 token receiver interface
* @dev Interface for any contract that wants to support safeTransfers
* from ERC-721 asset contracts.
*/
interface IERC721Receiver {
/**
* @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}
* by `operator` from `from`, this function is called.
*
* It must return its Solidity selector to confirm the token transfer.
* If any other value is returned or the interface is not implemented by the recipient, the transfer will be
* reverted.
*
* The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`.
*/
function onERC721Received(
address operator,
address from,
uint256 tokenId,
bytes calldata data
) external returns (bytes4);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol)
pragma solidity ^0.8.20;
/**
* @dev Provides information about the current execution context, including the
* sender of the transaction and its data. While these are generally available
* via msg.sender and msg.data, they should not be accessed in such a direct
* manner, since when dealing with meta-transactions the account sending and
* paying for execution may not be the actual sender (as far as an application
* is concerned).
*
* This contract is only required for intermediate, library-like contracts.
*/
abstract contract Context {
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
function _contextSuffixLength() internal view virtual returns (uint256) {
return 0;
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.4.0) (utils/introspection/IERC165.sol)
pragma solidity >=0.4.16;
/**
* @dev Interface of the ERC-165 standard, as defined in the
* https://eips.ethereum.org/EIPS/eip-165[ERC].
*
* Implementers can declare support of contract interfaces, which can then be
* queried by others ({ERC165Checker}).
*
* For an implementation, see {ERC165}.
*/
interface IERC165 {
/**
* @dev Returns true if this contract implements the interface defined by
* `interfaceId`. See the corresponding
* https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[ERC section]
* to learn more about how these ids are created.
*
* This function call must use less than 30 000 gas.
*/
function supportsInterface(bytes4 interfaceId) external view returns (bool);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.1.0) (utils/ReentrancyGuard.sol)
pragma solidity ^0.8.20;
/**
* @dev Contract module that helps prevent reentrant calls to a function.
*
* Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier
* available, which can be applied to functions to make sure there are no nested
* (reentrant) calls to them.
*
* Note that because there is a single `nonReentrant` guard, functions marked as
* `nonReentrant` may not call one another. This can be worked around by making
* those functions `private`, and then adding `external` `nonReentrant` entry
* points to them.
*
* TIP: If EIP-1153 (transient storage) is available on the chain you're deploying at,
* consider using {ReentrancyGuardTransient} instead.
*
* TIP: If you would like to learn more about reentrancy and alternative ways
* to protect against it, check out our blog post
* https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].
*/
abstract contract ReentrancyGuard {
// Booleans are more expensive than uint256 or any type that takes up a full
// word because each write operation emits an extra SLOAD to first read the
// slot's contents, replace the bits taken up by the boolean, and then write
// back. This is the compiler's defense against contract upgrades and
// pointer aliasing, and it cannot be disabled.
// The values being non-zero value makes deployment a bit more expensive,
// but in exchange the refund on every call to nonReentrant will be lower in
// amount. Since refunds are capped to a percentage of the total
// transaction's gas, it is best to keep them low in cases like this one, to
// increase the likelihood of the full refund coming into effect.
uint256 private constant NOT_ENTERED = 1;
uint256 private constant ENTERED = 2;
uint256 private _status;
/**
* @dev Unauthorized reentrant call.
*/
error ReentrancyGuardReentrantCall();
constructor() {
_status = NOT_ENTERED;
}
/**
* @dev Prevents a contract from calling itself, directly or indirectly.
* Calling a `nonReentrant` function from another `nonReentrant`
* function is not supported. It is possible to prevent this from happening
* by making the `nonReentrant` function external, and making it call a
* `private` function that does the actual work.
*/
modifier nonReentrant() {
_nonReentrantBefore();
_;
_nonReentrantAfter();
}
function _nonReentrantBefore() private {
// On the first call to nonReentrant, _status will be NOT_ENTERED
if (_status == ENTERED) {
revert ReentrancyGuardReentrantCall();
}
// Any calls to nonReentrant after this point will fail
_status = ENTERED;
}
function _nonReentrantAfter() private {
// By storing the original value once again, a refund is triggered (see
// https://eips.ethereum.org/EIPS/eip-2200)
_status = NOT_ENTERED;
}
/**
* @dev Returns true if the reentrancy guard is currently set to "entered", which indicates there is a
* `nonReentrant` function in the call stack.
*/
function _reentrancyGuardEntered() internal view returns (bool) {
return _status == ENTERED;
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
interface IERC721 {
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);
function supportsInterface(bytes4 interfaceId) external view returns (bool);
function owner() external view returns (address);
}// SPDX-License-Identifier: MIT
pragma solidity >=0.6.2;
interface IUniswapV2Router01 {
function factory() external pure returns (address);
function WETH() external pure returns (address);
function addLiquidity(
address tokenA,
address tokenB,
uint amountADesired,
uint amountBDesired,
uint amountAMin,
uint amountBMin,
address to,
uint deadline
) external returns (uint amountA, uint amountB, uint liquidity);
function addLiquidityETH(
address token,
uint amountTokenDesired,
uint amountTokenMin,
uint amountETHMin,
address to,
uint deadline
) external payable returns (uint amountToken, uint amountETH, uint liquidity);
function removeLiquidity(
address tokenA,
address tokenB,
uint liquidity,
uint amountAMin,
uint amountBMin,
address to,
uint deadline
) external returns (uint amountA, uint amountB);
function removeLiquidityETH(
address token,
uint liquidity,
uint amountTokenMin,
uint amountETHMin,
address to,
uint deadline
) external returns (uint amountToken, uint amountETH);
function removeLiquidityWithPermit(
address tokenA,
address tokenB,
uint liquidity,
uint amountAMin,
uint amountBMin,
address to,
uint deadline,
bool approveMax, uint8 v, bytes32 r, bytes32 s
) external returns (uint amountA, uint amountB);
function removeLiquidityETHWithPermit(
address token,
uint liquidity,
uint amountTokenMin,
uint amountETHMin,
address to,
uint deadline,
bool approveMax, uint8 v, bytes32 r, bytes32 s
) external returns (uint amountToken, uint amountETH);
function quote(uint amountA, uint reserveA, uint reserveB) external pure returns (uint amountB);
}
interface IHyperswapRouter is IUniswapV2Router01 {
function removeLiquidityETHSupportingFeeOnTransferTokens(
address token,
uint liquidity,
uint amountTokenMin,
uint amountETHMin,
address to,
uint deadline
) external returns (uint amountETH);
function removeLiquidityETHWithPermitSupportingFeeOnTransferTokens(
address token,
uint liquidity,
uint amountTokenMin,
uint amountETHMin,
address to,
uint deadline,
bool approveMax, uint8 v, bytes32 r, bytes32 s
) external returns (uint amountETH);
function swapExactTokensForTokensSupportingFeeOnTransferTokens(
uint amountIn,
uint amountOutMin,
address[] calldata path,
address to,
address referrer,
uint deadline
) external;
function swapExactETHForTokensSupportingFeeOnTransferTokens(
uint amountOutMin,
address[] calldata path,
address to,
address referrer,
uint deadline
) external payable;
function swapExactTokensForETHSupportingFeeOnTransferTokens(
uint amountIn,
uint amountOutMin,
address[] calldata path,
address to,
address referrer,
uint deadline
) external;
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import {IERC721} from "../interfaces/IERC721.sol";
interface IHypurrStrategy {
// Events
event FeesUpdated(uint16 buyFee, uint16 sellFee);
event FeeWalletUpdated(address wallet);
event TradingEnabled();
event SwapBack(uint256 tokenSold, uint256 ethReceived);
event PairCreated(address pair);
event NFTBoughtByProtocol(uint256 indexed tokenId, uint256 purchasePrice, uint256 listPriceWithRoyalty);
event NFTSoldByProtocol(uint256 indexed tokenId, uint256 price, address buyer);
event FeeWalletPayoutFailed(address wallet, uint256 amount);
event BuyerWhitelistEnabled(bool enabled);
event BuyerWhitelistUpdated(address indexed account, bool whitelisted);
event TargetWhitelistEnabled(bool enabled);
event TargetWhitelistUpdated(address indexed target, bool whitelisted);
event CollectionUpdated(address indexed nft);
// Admin/external actions
function setSwapFees(uint16 buy_, uint16 sell_, uint16 sellFeeBeforeNftBought_) external;
function setFeeWallet(address wallet_) external;
function setWalletShare(uint16 share_) external;
function setRoyaltyWallet(address wallet_) external;
function setRoyaltyShare(uint16 share_) external;
function setExempt(address a, bool e) external;
function setSwapSettings(bool enabled, uint256 threshold) external;
function setPriceMultiplier(uint256 bps) external;
function enableTrading() external;
function addPair(address pair_) external;
function setBuyerWhitelistEnabled(bool enabled) external;
function setBuyerWhitelist(address account, bool whitelisted) external;
function setTargetWhitelistEnabled(bool enabled) external;
function setTargetWhitelist(address target, bool whitelisted) external;
function setCollection(address nft) external;
// TWAP
function processTokenTwap() external;
function setTwapParams(uint256 increment, uint256 delaySeconds, uint16 rewardBps) external;
function manualSwapBack() external;
// NFT
function buyTargetNFT(uint256 value, bytes calldata data, uint256 expectedId, address target) external;
function sellTargetNFT(uint256 tokenId) external payable;
// Views (selected)
function pairsLength() external view returns (uint256);
function pairs(uint256 index) external view returns (address);
function collection() external view returns (IERC721);
function nftForSale(uint256 tokenId) external view returns (uint256);
function currentFees() external view returns (uint256);
function ethToTwap() external view returns (uint256);
function tradingEnabled() external view returns (bool);
}{
"optimizer": {
"enabled": true,
"runs": 50
},
"viaIR": false,
"evmVersion": "paris",
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"string","name":"name_","type":"string"},{"internalType":"string","name":"symbol_","type":"string"},{"internalType":"uint256","name":"supply_","type":"uint256"},{"internalType":"address","name":"router_","type":"address"},{"internalType":"address","name":"feeWallet_","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"AlreadyNFTOwner","type":"error"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"allowance","type":"uint256"},{"internalType":"uint256","name":"needed","type":"uint256"}],"name":"ERC20InsufficientAllowance","type":"error"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"uint256","name":"balance","type":"uint256"},{"internalType":"uint256","name":"needed","type":"uint256"}],"name":"ERC20InsufficientBalance","type":"error"},{"inputs":[{"internalType":"address","name":"approver","type":"address"}],"name":"ERC20InvalidApprover","type":"error"},{"inputs":[{"internalType":"address","name":"receiver","type":"address"}],"name":"ERC20InvalidReceiver","type":"error"},{"inputs":[{"internalType":"address","name":"sender","type":"address"}],"name":"ERC20InvalidSender","type":"error"},{"inputs":[{"internalType":"address","name":"spender","type":"address"}],"name":"ERC20InvalidSpender","type":"error"},{"inputs":[],"name":"InvalidCollection","type":"error"},{"inputs":[],"name":"NFTIncorrectPayment","type":"error"},{"inputs":[],"name":"NFTNotForSale","type":"error"},{"inputs":[],"name":"NeedToBuyNFT","type":"error"},{"inputs":[],"name":"NotEnoughEth","type":"error"},{"inputs":[],"name":"NotNFTOwner","type":"error"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"OwnableInvalidOwner","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"OwnableUnauthorizedAccount","type":"error"},{"inputs":[],"name":"ReentrancyGuardReentrantCall","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bool","name":"enabled","type":"bool"}],"name":"BuyerWhitelistEnabled","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"bool","name":"whitelisted","type":"bool"}],"name":"BuyerWhitelistUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"nft","type":"address"}],"name":"CollectionUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"wallet","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"FeeWalletPayoutFailed","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"wallet","type":"address"}],"name":"FeeWalletUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint16","name":"buyFee","type":"uint16"},{"indexed":false,"internalType":"uint16","name":"sellFee","type":"uint16"}],"name":"FeesUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"purchasePrice","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"listPriceWithRoyalty","type":"uint256"}],"name":"NFTBoughtByProtocol","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"price","type":"uint256"},{"indexed":false,"internalType":"address","name":"buyer","type":"address"}],"name":"NFTSoldByProtocol","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":"pair","type":"address"}],"name":"PairCreated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"tokenSold","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"ethReceived","type":"uint256"}],"name":"SwapBack","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bool","name":"enabled","type":"bool"}],"name":"TargetWhitelistEnabled","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"target","type":"address"},{"indexed":false,"internalType":"bool","name":"whitelisted","type":"bool"}],"name":"TargetWhitelistUpdated","type":"event"},{"anonymous":false,"inputs":[],"name":"TradingEnabled","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[],"name":"BPS_DENOMINATOR","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_FEE_BEFORE_NFT_BOUGHT_BPS","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_FEE_BPS","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"REWARD_BPS_CAP","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"WALLET_SHARE_BPS","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"pair_","type":"address"}],"name":"addPair","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"buyFeeBps","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"},{"internalType":"uint256","name":"expectedId","type":"uint256"},{"internalType":"address","name":"target","type":"address"}],"name":"buyTargetNFT","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"buyerWhitelistEnabled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"collection","outputs":[{"internalType":"contract IERC721","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"currentFees","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"enableTrading","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"ethToTwap","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"feeWallet","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"isBuyerWhitelisted","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"isExempt","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"isPair","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"isTargetWhitelisted","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lastTwapTimestamp","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"manualSwapBack","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"nftForSale","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","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":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"pairs","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pairsLength","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"priceMultiplier","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"processTokenTwap","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"router","outputs":[{"internalType":"contract IHyperswapRouter","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"royaltyShareBps","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"royaltyWallet","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"sellFeeBeforeNftBoughtBps","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"sellFeeBps","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"sellTargetNFT","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"bool","name":"whitelisted","type":"bool"}],"name":"setBuyerWhitelist","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"enabled","type":"bool"}],"name":"setBuyerWhitelistEnabled","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"nft","type":"address"}],"name":"setCollection","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"a","type":"address"},{"internalType":"bool","name":"e","type":"bool"}],"name":"setExempt","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"wallet_","type":"address"}],"name":"setFeeWallet","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"bps","type":"uint256"}],"name":"setPriceMultiplier","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"share_","type":"uint16"}],"name":"setRoyaltyShare","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"wallet_","type":"address"}],"name":"setRoyaltyWallet","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"buy_","type":"uint16"},{"internalType":"uint16","name":"sell_","type":"uint16"},{"internalType":"uint16","name":"sellFeeBeforeNftBought_","type":"uint16"}],"name":"setSwapFees","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"enabled","type":"bool"},{"internalType":"uint256","name":"threshold","type":"uint256"}],"name":"setSwapSettings","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"target","type":"address"},{"internalType":"bool","name":"whitelisted","type":"bool"}],"name":"setTargetWhitelist","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"enabled","type":"bool"}],"name":"setTargetWhitelistEnabled","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"increment","type":"uint256"},{"internalType":"uint256","name":"delaySeconds","type":"uint256"},{"internalType":"uint16","name":"rewardBps","type":"uint16"}],"name":"setTwapParams","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"share_","type":"uint16"}],"name":"setWalletShare","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"swapEnabled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"swapThreshold","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"targetWhitelistEnabled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"tradingEnabled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"transferFrom","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":[],"name":"twapDelayInSeconds","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"twapIncrement","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"twapRewardBps","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"wasNftBought","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"weth","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"stateMutability":"payable","type":"receive"}]Contract Creation Code
60c0604052600780546703e8138803e803e86001600160401b0319909116179055600a805462ffff00191662010000178155600e805460ff199081169091556010805482169055612ee0601455670de0b6b3a76400006017556018805461ffff19169092179091556001601955601b805490911690553480156200008257600080fd5b5060405162003db938038062003db9833981016040819052620000a59162000b9f565b3385856003620000b6838262000cc6565b506004620000c5828262000cc6565b5050506001600160a01b038116620000f857604051631e4fbdf760e01b8152600060048201526024015b60405180910390fd5b6200010381620002a2565b5060016006556001600160a01b0381166200014e5760405162461bcd60e51b815260206004820152600a602482015269199959481dd85b1b195d60b21b6044820152606401620000ef565b6001600160a01b0382166200018f5760405162461bcd60e51b81526020600482015260066024820152653937baba32b960d11b6044820152606401620000ef565b6001600160a01b0382166080819052604080516315ab88c960e31b8152905163ad5c4648916004808201926020929091908290030181865afa158015620001da573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000200919062000d92565b6001600160a01b0390811660a052600780549183166801000000000000000002600160401b600160e01b0319909216919091179055620002413384620002f4565b6200024f6101908462000dcd565b600b55336000908152600c60205260408082208054600160ff19918216811790925530845282842080548216831790556001600160a01b03949094168352912080549092161790555062000ecd92505050565b600580546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6001600160a01b038216620003205760405163ec442f0560e01b815260006004820152602401620000ef565b6200032e6000838362000332565b5050565b600a54610100900460ff161580156200035957506005546001600160a01b03848116911614155b80156200037457506005546001600160a01b03838116911614155b15620003ad5760405162461bcd60e51b815260206004820152600760248201526674726164696e6760c81b6044820152606401620000ef565b600a5462010000900460ff168015620003c95750600a5460ff16155b8015620003e75750600b543060009081526020819052604090205410155b80156200042f57506001600160a01b0383166000908152600d602052604090205460ff16806200042f57506001600160a01b0382166000908152600d602052604090205460ff165b156200043f576200043f620005a9565b601b54600090819060ff166200046457600754640100000000900461ffff1662000472565b60075462010000900461ffff165b6001600160a01b0386166000908152600c602052604090205490915060ff16158015620004b857506001600160a01b0384166000908152600c602052604090205460ff16155b1562000572576001600160a01b0385166000908152600d602052604090205460ff168015620004ec575060075461ffff1615155b156200051d5760075461271090620005099061ffff168562000df0565b62000515919062000dcd565b915062000572565b6001600160a01b0384166000908152600d602052604090205460ff1680156200054a575060008161ffff16115b1562000572576127106200056361ffff83168562000df0565b6200056f919062000dcd565b91505b81156200059557620005868530846200089a565b62000592828462000e10565b92505b620005a28585856200089a565b5050505050565b600a805460ff1916600117905530600090815260208190526040812054905080600003620005d857506200088e565b6000600b546002620005eb919062000df0565b8211620005f9578162000609565b600b546200060990600262000df0565b9050620006203060805183620009cd60201b60201c565b604080516002808252606082018352600092602083019080368337019050509050308160008151811062000658576200065862000e26565b60200260200101906001600160a01b031690816001600160a01b03168152505060a0518160018151811062000691576200069162000e26565b6001600160a01b039283166020918202929092010152608051604051632955261160e11b8152479291909116906352aa4c2290620006df908690600090879030908390429060040162000e3c565b600060405180830381600087803b158015620006fa57600080fd5b505af11580156200070f573d6000803e3d6000fd5b505050506000814762000723919062000e10565b9050801562000888576007546000906127109062000750906601000000000000900461ffff168462000df0565b6200075c919062000dcd565b905060006200076c828462000e10565b9050806015600082825462000782919062000eb7565b909155505081156200084c576007546040516000916801000000000000000090046001600160a01b03169084908381818185875af1925050503d8060008114620007e9576040519150601f19603f3d011682016040523d82523d6000602084013e620007ee565b606091505b50509050806200084a5760075460408051680100000000000000009092046001600160a01b03168252602082018590527f0d55be71cf7461cbc31e2952b797fc3acb4952967c0696106242639fd5e629fc910160405180910390a15b505b60408051878152602081018590527f05ab84b321981d7d9a13402e494604c50821bcb5f2400d128fa06cd6451113d4910160405180910390a150505b50505050505b600a805460ff19169055565b6001600160a01b038316620008c9578060026000828254620008bd919062000eb7565b909155506200093d9050565b6001600160a01b038316600090815260208190526040902054818110156200091e5760405163391434e360e21b81526001600160a01b03851660048201526024810182905260448101839052606401620000ef565b6001600160a01b03841660009081526020819052604090209082900390555b6001600160a01b0382166200095b576002805482900390556200097a565b6001600160a01b03821660009081526020819052604090208054820190555b816001600160a01b0316836001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef83604051620009c091815260200190565b60405180910390a3505050565b620009dc8383836001620009e1565b505050565b6001600160a01b03841662000a0d5760405163e602df0560e01b815260006004820152602401620000ef565b6001600160a01b03831662000a3957604051634a1406b160e11b815260006004820152602401620000ef565b6001600160a01b038085166000908152600160209081526040808320938716835292905220829055801562000ab757826001600160a01b0316846001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9258460405162000aae91815260200190565b60405180910390a35b50505050565b634e487b7160e01b600052604160045260246000fd5b600082601f83011262000ae557600080fd5b81516001600160401b038082111562000b025762000b0262000abd565b604051601f8301601f19908116603f0116810190828211818310171562000b2d5762000b2d62000abd565b8160405283815260209250868385880101111562000b4a57600080fd5b600091505b8382101562000b6e578582018301518183018401529082019062000b4f565b600093810190920192909252949350505050565b80516001600160a01b038116811462000b9a57600080fd5b919050565b600080600080600060a0868803121562000bb857600080fd5b85516001600160401b038082111562000bd057600080fd5b62000bde89838a0162000ad3565b9650602088015191508082111562000bf557600080fd5b5062000c048882890162000ad3565b9450506040860151925062000c1c6060870162000b82565b915062000c2c6080870162000b82565b90509295509295909350565b600181811c9082168062000c4d57607f821691505b60208210810362000c6e57634e487b7160e01b600052602260045260246000fd5b50919050565b601f821115620009dc57600081815260208120601f850160051c8101602086101562000c9d5750805b601f850160051c820191505b8181101562000cbe5782815560010162000ca9565b505050505050565b81516001600160401b0381111562000ce25762000ce262000abd565b62000cfa8162000cf3845462000c38565b8462000c74565b602080601f83116001811462000d32576000841562000d195750858301515b600019600386901b1c1916600185901b17855562000cbe565b600085815260208120601f198616915b8281101562000d635788860151825594840194600190910190840162000d42565b508582101562000d825787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b60006020828403121562000da557600080fd5b62000db08262000b82565b9392505050565b634e487b7160e01b600052601160045260246000fd5b60008262000deb57634e487b7160e01b600052601260045260246000fd5b500490565b808202811582820484141762000e0a5762000e0a62000db7565b92915050565b8181038181111562000e0a5762000e0a62000db7565b634e487b7160e01b600052603260045260246000fd5b600060c082018883526020888185015260c0604085015281885180845260e086019150828a01935060005b8181101562000e8e5784516001600160a01b03168352938301939183019160010162000e67565b50506001600160a01b039788166060860152959096166080840152505060a00152949350505050565b8082018082111562000e0a5762000e0a62000db7565b60805160a051612ea362000f16600039600081816105c701528181611efc015261218b015260008181610b3e01528181611f870152818161210f01526121e40152612ea36000f3fe6080604052600436106103685760003560e01c80637ffe7ca5116101c8578063d0e10326116100f8578063ec0788211161009b578063ec07882114610a95578063f0db975c14610aab578063f25f4b5614610ac5578063f2fde38b14610aec578063f392c71614610b0c578063f887ea4014610b2c578063f8b12eda14610b60578063fcc92ff714610b82578063fdd2bae514610ba257600080fd5b8063d0e10326146109a8578063d50cb88b146109c8578063d51ffa81146109de578063d55be8c6146109fe578063dc84205714610a14578063dd62ed3e14610a2f578063e1a4521814610a4f578063e5e31b1314610a6557600080fd5b80639fde54f51161016b5780639fde54f514610881578063a66dd5c2146108a1578063a9059cbb146108b6578063ad58aca0146108d6578063ad5dff73146108f6578063b91ac78814610926578063c2b7bbb614610946578063cd8684bb14610966578063cdeee6371461098857600080fd5b80637ffe7ca5146107995780638a8c523c146107af5780638da5cb5b146107c45780638ff9e3f8146107d957806390ba7a321461080957806390d49b9d1461083657806395d89b41146108565780639d6f09c11461086b57600080fd5b80633f0d2ec1116102a357806366eb37851161024657806366eb378514610692578063679b48a8146106a75780636ddd1713146106c957806370a08231146106e9578063715018a614610709578063768b5fd51461071e57806377d2300e1461073e57806379f9e975146107595780637de1e5361461077957600080fd5b80633f0d2ec1146105885780633fc8cef3146105b557806340ad5db0146105e957806347080a03146106095780634772b1de146106295780634a8b8e2b146106435780634ada218b1461065d5780635d9644c41461067c57600080fd5b80632081c4ea1161030b5780632081c4ea1461048a57806323b2f392146104aa57806323b872dd146104c057806323cbe1f3146104e057806324abf962146105145780632a640f3414610527578063313ce56714610557578063349757481461057357600080fd5b80630445b6671461037457806306fdde031461039d578063095ea7b3146103bf578063108bdc14146103ef578063150b7a0214610411578063161583f01461044a57806318160ddd146104605780631db527551461047557600080fd5b3661036f57005b600080fd5b34801561038057600080fd5b5061038a600b5481565b6040519081526020015b60405180910390f35b3480156103a957600080fd5b506103b2610bc2565b6040516103949190612856565b3480156103cb57600080fd5b506103df6103da3660046128b9565b610c54565b6040519015158152602001610394565b3480156103fb57600080fd5b5061040f61040a3660046128fa565b610c6e565b005b34801561041d57600080fd5b5061043161042c366004612978565b610cd6565b6040516001600160e01b03199091168152602001610394565b34801561045657600080fd5b5061038a60195481565b34801561046c57600080fd5b5060025461038a565b34801561048157600080fd5b5061040f610d16565b34801561049657600080fd5b5061040f6104a53660046129eb565b610eaa565b3480156104b657600080fd5b5061038a60165481565b3480156104cc57600080fd5b506103df6104db366004612a04565b610f00565b3480156104ec57600080fd5b506007546105019062010000900461ffff1681565b60405161ffff9091168152602001610394565b61040f6105223660046129eb565b610f24565b34801561053357600080fd5b506103df610542366004612a45565b600f6020526000908152604090205460ff1681565b34801561056357600080fd5b5060405160128152602001610394565b34801561057f57600080fd5b5060095461038a565b34801561059457600080fd5b506008546105a8906001600160a01b031681565b6040516103949190612a69565b3480156105c157600080fd5b506105a87f000000000000000000000000000000000000000000000000000000000000000081565b3480156105f557600080fd5b5061040f610604366004612a8f565b6111cb565b34801561061557600080fd5b5061040f610624366004612ad2565b611319565b34801561063557600080fd5b50601b546103df9060ff1681565b34801561064f57600080fd5b50600e546103df9060ff1681565b34801561066957600080fd5b50600a546103df90610100900460ff1681565b34801561068857600080fd5b5061038a60155481565b34801561069e57600080fd5b5061040f611369565b3480156106b357600080fd5b5060085461050190600160a01b900461ffff1681565b3480156106d557600080fd5b50600a546103df9062010000900460ff1681565b3480156106f557600080fd5b5061038a610704366004612a45565b611379565b34801561071557600080fd5b5061040f611394565b34801561072a57600080fd5b5061040f610739366004612a45565b6113a6565b34801561074a57600080fd5b506007546105019061ffff1681565b34801561076557600080fd5b5061040f610774366004612aed565b61141e565b34801561078557600080fd5b506012546105a8906001600160a01b031681565b3480156107a557600080fd5b5061050161138881565b3480156107bb57600080fd5b5061040f61146e565b3480156107d057600080fd5b506105a8611514565b3480156107e557600080fd5b506103df6107f4366004612a45565b60116020526000908152604090205460ff1681565b34801561081557600080fd5b5061038a6108243660046129eb565b60136020526000908152604090205481565b34801561084257600080fd5b5061040f610851366004612a45565b611523565b34801561086257600080fd5b506103b26115c4565b34801561087757600080fd5b5061038a601a5481565b34801561088d57600080fd5b5061040f61089c3660046128fa565b6115d3565b3480156108ad57600080fd5b50610501606481565b3480156108c257600080fd5b506103df6108d13660046128b9565b611606565b3480156108e257600080fd5b5061040f6108f13660046128fa565b611614565b34801561090257600080fd5b506103df610911366004612a45565b600c6020526000908152604090205460ff1681565b34801561093257600080fd5b506105a86109413660046129eb565b611674565b34801561095257600080fd5b5061040f610961366004612a45565b61169e565b34801561097257600080fd5b5060075461050190600160301b900461ffff1681565b34801561099457600080fd5b5061040f6109a3366004612a45565b6117ba565b3480156109b457600080fd5b5061040f6109c3366004612b08565b61180a565b3480156109d457600080fd5b5061038a60145481565b3480156109ea57600080fd5b5061040f6109f9366004612aed565b611832565b348015610a0a57600080fd5b506105016103e881565b348015610a2057600080fd5b506018546105019061ffff1681565b348015610a3b57600080fd5b5061038a610a4a366004612b24565b611882565b348015610a5b57600080fd5b5061050161271081565b348015610a7157600080fd5b506103df610a80366004612a45565b600d6020526000908152604090205460ff1681565b348015610aa157600080fd5b5061038a60175481565b348015610ab757600080fd5b506010546103df9060ff1681565b348015610ad157600080fd5b506007546105a890600160401b90046001600160a01b031681565b348015610af857600080fd5b5061040f610b07366004612a45565b6118ad565b348015610b1857600080fd5b5061040f610b27366004612b5d565b6118e8565b348015610b3857600080fd5b506105a87f000000000000000000000000000000000000000000000000000000000000000081565b348015610b6c57600080fd5b5060075461050190600160201b900461ffff1681565b348015610b8e57600080fd5b5061040f610b9d366004612bc8565b611db8565b348015610bae57600080fd5b5061040f610bbd366004612ad2565b611e22565b606060038054610bd190612bf4565b80601f0160208091040260200160405190810160405280929190818152602001828054610bfd90612bf4565b8015610c4a5780601f10610c1f57610100808354040283529160200191610c4a565b820191906000526020600020905b815481529060010190602001808311610c2d57829003601f168201915b5050505050905090565b600033610c62818585611e6b565b60019150505b92915050565b610c76611e7d565b6001600160a01b038216600081815260116020908152604091829020805460ff191685151590811790915591519182527f52eec1a0372bcc0f149dd096fc04f013047c878bd949d11adecf9b39bc0c71dc91015b60405180910390a25050565b6012546000906001600160a01b03163314610d045760405163517172a160e11b815260040160405180910390fd5b50630a85bd0160e11b95945050505050565b610d1e611eaf565b600060165411610d5f5760405162461bcd60e51b815260206004820152600760248201526606e6f20747761760cc1b60448201526064015b60405180910390fd5b601954601a54610d6f9190612c44565b421015610dab5760405162461bcd60e51b815260206004820152600a602482015269747761702064656c617960b01b6044820152606401610d56565b601754601654811115610dbd57506016545b60185460009061271090610dd59061ffff1684612c57565b610ddf9190612c6e565b9050610deb8183612c90565b9150610df78183612c44565b60166000828254610e089190612c90565b909155505042601a55610e1a82611ed9565b604051600090339083908381818185875af1925050503d8060008114610e5c576040519150601f19603f3d011682016040523d82523d6000602084013e610e61565b606091505b5050905080610e9b5760405162461bcd60e51b81526020600482015260066024820152651c995dd85c9960d21b6044820152606401610d56565b505050610ea86001600655565b565b610eb2611e7d565b612af88110158015610ec657506175308111155b610efb5760405162461bcd60e51b8152600401610d56906020808252600490820152631b5d5b1d60e21b604082015260600190565b601455565b600033610f0e858285612001565b610f19858585612055565b506001949350505050565b610f2c611eaf565b60008181526013602052604081205490819003610f5c5760405163d135e8bd60e01b815260040160405180910390fd5b803414610f7c5760405163499a5b8760e11b815260040160405180910390fd5b6012546040516331a9108f60e11b81526004810184905230916001600160a01b031690636352211e90602401602060405180830381865afa158015610fc5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fe99190612ca3565b6001600160a01b03161461101057604051631022318760e21b815260040160405180910390fd5b6012546040516323b872dd60e01b8152306004820152336024820152604481018490526001600160a01b03909116906323b872dd90606401600060405180830381600087803b15801561106257600080fd5b505af1158015611076573d6000803e3d6000fd5b505060085460009250612710915061109990600160a01b900461ffff1684612c57565b6110a39190612c6e565b90506000811180156110bf57506008546001600160a01b031615155b15611153576008546040516000916001600160a01b03169083908381818185875af1925050503d8060008114611111576040519150601f19603f3d011682016040523d82523d6000602084013e611116565b606091505b50509050806111515760405162461bcd60e51b8152602060048201526007602482015266726f79616c747960c81b6044820152606401610d56565b505b60008381526013602052604081205561116c8183612c90565b6016600082825461117d9190612c44565b90915550506040805183815233602082015284917f89c3b465a41d0ab0891833425d7da4f89bafffceffba56a40bfafff01d68d51e910160405180910390a250506111c86001600655565b50565b6111d3611e7d565b6103e861ffff8416118015906111ef57506103e861ffff831611155b61122a5760405162461bcd60e51b815260206004820152600c60248201526b0cccaca40e8dede40d0d2ced60a31b6044820152606401610d56565b6007805461ffff848116620100000263ffffffff19909216818716179190911790915561138890821611156112ad5760405162461bcd60e51b815260206004820152602360248201527f73656c6c20666565206265666f7265206e667420626f7567687420746f6f20686044820152620d2ced60eb1b6064820152608401610d56565b6007805461ffff8316600160201b0265ffff00000000199091161790556040517f2ac80c14c28700f7b5e36f947d572149fe2e3947bac32c3a8c098f3e03722c119061130c908590859061ffff92831681529116602082015260400190565b60405180910390a1505050565b611321611e7d565b6010805460ff19168215159081179091556040519081527f5d7ec4cc2b9c2911f3721deb89f0cb99972ac6c06be5f269682ddca4ce41f54b906020015b60405180910390a150565b611371611e7d565b610ea86120b4565b6001600160a01b031660009081526020819052604090205490565b61139c611e7d565b610ea860006123c1565b6113ae611e7d565b6001600160a01b0381166113d45760405162461bcd60e51b8152600401610d5690612cc0565b601280546001600160a01b0319166001600160a01b0383169081179091556040517f1c916ba8ddd9af4bcac6dc6280731909c8c6d559b21d4d60fc84e12582b1596390600090a250565b611426611e7d565b6103e861ffff8216111561144c5760405162461bcd60e51b8152600401610d5690612ce0565b6008805461ffff909216600160a01b0261ffff60a01b19909216919091179055565b611476611e7d565b600a54610100900460ff16156114b85760405162461bcd60e51b8152602060048201526007602482015266195b98589b195960ca1b6044820152606401610d56565b6009546000036114da5760405162461bcd60e51b8152600401610d5690612d08565b600a805461ff0019166101001790556040517f799663458a5ef2936f7fa0c99b3336c69c25890f82974f04e811e5bb359186c790600090a1565b6005546001600160a01b031690565b61152b611e7d565b6001600160a01b0381166115515760405162461bcd60e51b8152600401610d5690612cc0565b60078054600160401b600160e01b031916600160401b6001600160a01b038416908102919091179091556000908152600c602052604090819020805460ff19166001179055517f29acee77dafcfa0143d74a7ea236018f3a6e1fa71e27fc59bbfbc6b8ca8edccd9061135e908390612a69565b606060048054610bd190612bf4565b6115db611e7d565b6001600160a01b03919091166000908152600c60205260409020805460ff1916911515919091179055565b600033610c62818585612055565b61161c611e7d565b6001600160a01b0382166000818152600f6020908152604091829020805460ff191685151590811790915591519182527fb73ef82aa45b7f4fbd7aa401e3653c03720cb9564895bea841433c737952c01d9101610cca565b6009818154811061168457600080fd5b6000918252602090912001546001600160a01b0316905081565b6116a6611e7d565b6001600160a01b0381166116cc5760405162461bcd60e51b8152600401610d5690612d08565b6001600160a01b0381166000908152600d602052604090205460ff16156117235760405162461bcd60e51b815260206004820152600b60248201526a706169722065786973747360a81b6044820152606401610d56565b6001600160a01b0381166000818152600d6020526040808220805460ff191660019081179091556009805491820181559092527f6e1540171b6c0c960b71a7020d9f60077f6af931a8bbf590da0223dacf75c7af90910180546001600160a01b031916909217909155517fb14a725aeeb25d591b81b16b4c5b25403dd8867bdd1876fa787867f566206be19061135e908390612a69565b6117c2611e7d565b6001600160a01b0381166117e85760405162461bcd60e51b8152600401610d5690612cc0565b600880546001600160a01b0319166001600160a01b0392909216919091179055565b611812611e7d565b600a8054921515620100000262ff00001990931692909217909155600b55565b61183a611e7d565b6103e861ffff821611156118605760405162461bcd60e51b8152600401610d5690612ce0565b6007805461ffff909216600160301b0261ffff60301b19909216919091179055565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b6118b5611e7d565b6001600160a01b0381166118df576000604051631e4fbdf760e01b8152600401610d569190612a69565b6111c8816123c1565b6118f0611eaf565b600e5460ff161561194557336000908152600f602052604090205460ff166119455760405162461bcd60e51b8152602060048201526008602482015267189d5e595c881ddb60c21b6044820152606401610d56565b60105460ff16156119a4576001600160a01b03811660009081526011602052604090205460ff166119a45760405162461bcd60e51b81526020600482015260096024820152681d185c99d95d081ddb60ba1b6044820152606401610d56565b6012546001600160a01b03166119e95760405162461bcd60e51b815260206004820152600a60248201526931b7b63632b1ba34b7b760b11b6044820152606401610d56565b6012546040516331a9108f60e11b81526004810184905230916001600160a01b031690636352211e90602401602060405180830381865afa158015611a32573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a569190612ca3565b6001600160a01b031603611a7d5760405163085cf94760e41b815260040160405180910390fd5b601554851115611aa05760405163f14a42b760e01b815260040160405180910390fd5b6012546040516370a0823160e01b815247916000916001600160a01b03909116906370a0823190611ad5903090600401612a69565b602060405180830381865afa158015611af2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b169190612d26565b9050600080846001600160a01b0316898989604051611b36929190612d3f565b60006040518083038185875af1925050503d8060008114611b73576040519150601f19603f3d011682016040523d82523d6000602084013e611b78565b606091505b509150915081611b8a57805160208201fd5b6012546040516370a0823160e01b81526000916001600160a01b0316906370a0823190611bbb903090600401612a69565b602060405180830381865afa158015611bd8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611bfc9190612d26565b9050611c09846001612c44565b8114611c2857604051630b7cb52160e41b815260040160405180910390fd5b6012546040516331a9108f60e11b81526004810189905230916001600160a01b031690636352211e90602401602060405180830381865afa158015611c71573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c959190612ca3565b6001600160a01b031614611cbc57604051631022318760e21b815260040160405180910390fd5b6000611cc84787612c90565b90508060156000828254611cdc9190612c90565b909155505060145460009061271090611cf59084612c57565b611cff9190612c6e565b600854909150600090611d1f90600160a01b900461ffff16612710612d4f565b61ffff16611d2f61271084612c57565b611d399190612c6e565b60008b81526013602052604090819020829055601b805460ff19166001179055519091508a907f272af40a157c8d1a7d3bf7ff2920db021097ec61b7e260f97bb50144520ad17790611d979086908590918252602082015260400190565b60405180910390a25050505050505050611db16001600655565b5050505050565b611dc0611e7d565b606461ffff82161115611e025760405162461bcd60e51b815260206004820152600a6024820152690726577617264206361760b41b6044820152606401610d56565b6017929092556019556018805461ffff191661ffff909216919091179055565b611e2a611e7d565b600e805460ff19168215159081179091556040519081527f4d17abbadb127e75c188fbaeb39e24a7db27bb8792eba70075fcaf0c3e89c1e39060200161135e565b611e788383836001612413565b505050565b33611e86611514565b6001600160a01b031614610ea8573360405163118cdaa760e01b8152600401610d569190612a69565b600260065403611ed257604051633ee5aeb560e01b815260040160405180910390fd5b6002600655565b6040805160028082526060820183526000926020830190803683370190505090507f000000000000000000000000000000000000000000000000000000000000000081600081518110611f2e57611f2e612d71565b60200260200101906001600160a01b031690816001600160a01b0316815250503081600181518110611f6257611f62612d71565b6001600160a01b03928316602091820292909201015260405163b4822be360e01b81527f00000000000000000000000000000000000000000000000000000000000000009091169063b4822be3908490611fcb90600090869061dead9083904290600401612dcb565b6000604051808303818588803b158015611fe457600080fd5b505af1158015611ff8573d6000803e3d6000fd5b50505050505050565b600061200d8484611882565b905060001981101561204f578181101561204057828183604051637dc7a0d960e11b8152600401610d5693929190612e08565b61204f84848484036000612413565b50505050565b6001600160a01b03831661207f576000604051634b637e8f60e11b8152600401610d569190612a69565b6001600160a01b0382166120a957600060405163ec442f0560e01b8152600401610d569190612a69565b611e788383836124e8565b600a805460ff1916600117905560006120cc30611379565b9050806000036120dc57506123b5565b6000600b5460026120ed9190612c57565b82116120f95781612107565b600b54612107906002612c57565b9050612134307f000000000000000000000000000000000000000000000000000000000000000083611e6b565b604080516002808252606082018352600092602083019080368337019050509050308160008151811061216957612169612d71565b60200260200101906001600160a01b031690816001600160a01b0316815250507f0000000000000000000000000000000000000000000000000000000000000000816001815181106121bd576121bd612d71565b6001600160a01b039283166020918202929092010152604051632955261160e11b815247917f000000000000000000000000000000000000000000000000000000000000000016906352aa4c22906122249086906000908790309083904290600401612e29565b600060405180830381600087803b15801561223e57600080fd5b505af1158015612252573d6000803e3d6000fd5b50505050600081476122649190612c90565b905080156123af576007546000906127109061228b90600160301b900461ffff1684612c57565b6122959190612c6e565b905060006122a38284612c90565b905080601560008282546122b79190612c44565b9091555050811561237357600754604051600091600160401b90046001600160a01b03169084908381818185875af1925050503d8060008114612316576040519150601f19603f3d011682016040523d82523d6000602084013e61231b565b606091505b50509050806123715760075460408051600160401b9092046001600160a01b03168252602082018590527f0d55be71cf7461cbc31e2952b797fc3acb4952967c0696106242639fd5e629fc910160405180910390a15b505b60408051878152602081018590527f05ab84b321981d7d9a13402e494604c50821bcb5f2400d128fa06cd6451113d4910160405180910390a150505b50505050505b600a805460ff19169055565b600580546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6001600160a01b03841661243d57600060405163e602df0560e01b8152600401610d569190612a69565b6001600160a01b038316612467576000604051634a1406b160e11b8152600401610d569190612a69565b6001600160a01b038085166000908152600160209081526040808320938716835292905220829055801561204f57826001600160a01b0316846001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925846040516124da91815260200190565b60405180910390a350505050565b600a54610100900460ff161580156125195750612503611514565b6001600160a01b0316836001600160a01b031614155b801561253e5750612528611514565b6001600160a01b0316826001600160a01b031614155b156125755760405162461bcd60e51b815260206004820152600760248201526674726164696e6760c81b6044820152606401610d56565b600a5462010000900460ff1680156125905750600a5460ff16155b80156125a65750600b546125a330611379565b10155b80156125ec57506001600160a01b0383166000908152600d602052604090205460ff16806125ec57506001600160a01b0382166000908152600d602052604090205460ff165b156125f9576125f96120b4565b601b54600090819060ff1661261b57600754600160201b900461ffff16612629565b60075462010000900461ffff165b6001600160a01b0386166000908152600c602052604090205490915060ff1615801561266e57506001600160a01b0384166000908152600c602052604090205460ff16155b1561271a576001600160a01b0385166000908152600d602052604090205460ff1680156126a0575060075461ffff1615155b156126cb57600754612710906126ba9061ffff1685612c57565b6126c49190612c6e565b915061271a565b6001600160a01b0384166000908152600d602052604090205460ff1680156126f7575060008161ffff16115b1561271a5761271061270d61ffff831685612c57565b6127179190612c6e565b91505b81156127385761272b85308461273f565b6127358284612c90565b92505b611db18585855b6001600160a01b03831661276a57806002600082825461275f9190612c44565b909155506127c99050565b6001600160a01b038316600090815260208190526040902054818110156127aa5783818360405163391434e360e21b8152600401610d5693929190612e08565b6001600160a01b03841660009081526020819052604090209082900390555b6001600160a01b0382166127e557600280548290039055612804565b6001600160a01b03821660009081526020819052604090208054820190555b816001600160a01b0316836001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8360405161284991815260200190565b60405180910390a3505050565b600060208083528351808285015260005b8181101561288357858101830151858201604001528201612867565b506000604082860101526040601f19601f8301168501019250505092915050565b6001600160a01b03811681146111c857600080fd5b600080604083850312156128cc57600080fd5b82356128d7816128a4565b946020939093013593505050565b803580151581146128f557600080fd5b919050565b6000806040838503121561290d57600080fd5b8235612918816128a4565b9150612926602084016128e5565b90509250929050565b60008083601f84011261294157600080fd5b50813567ffffffffffffffff81111561295957600080fd5b60208301915083602082850101111561297157600080fd5b9250929050565b60008060008060006080868803121561299057600080fd5b853561299b816128a4565b945060208601356129ab816128a4565b935060408601359250606086013567ffffffffffffffff8111156129ce57600080fd5b6129da8882890161292f565b969995985093965092949392505050565b6000602082840312156129fd57600080fd5b5035919050565b600080600060608486031215612a1957600080fd5b8335612a24816128a4565b92506020840135612a34816128a4565b929592945050506040919091013590565b600060208284031215612a5757600080fd5b8135612a62816128a4565b9392505050565b6001600160a01b0391909116815260200190565b803561ffff811681146128f557600080fd5b600080600060608486031215612aa457600080fd5b612aad84612a7d565b9250612abb60208501612a7d565b9150612ac960408501612a7d565b90509250925092565b600060208284031215612ae457600080fd5b612a62826128e5565b600060208284031215612aff57600080fd5b612a6282612a7d565b60008060408385031215612b1b57600080fd5b6128d7836128e5565b60008060408385031215612b3757600080fd5b8235612b42816128a4565b91506020830135612b52816128a4565b809150509250929050565b600080600080600060808688031215612b7557600080fd5b85359450602086013567ffffffffffffffff811115612b9357600080fd5b612b9f8882890161292f565b909550935050604086013591506060860135612bba816128a4565b809150509295509295909350565b600080600060608486031215612bdd57600080fd5b8335925060208401359150612ac960408501612a7d565b600181811c90821680612c0857607f821691505b602082108103612c2857634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052601160045260246000fd5b80820180821115610c6857610c68612c2e565b8082028115828204841417610c6857610c68612c2e565b600082612c8b57634e487b7160e01b600052601260045260246000fd5b500490565b81810381811115610c6857610c68612c2e565b600060208284031215612cb557600080fd5b8151612a62816128a4565b6020808252600690820152651dd85b1b195d60d21b604082015260600190565b6020808252600e908201526d0e6d0c2e4ca40e8dede40d0d2ced60931b604082015260600190565b6020808252600490820152633830b4b960e11b604082015260600190565b600060208284031215612d3857600080fd5b5051919050565b8183823760009101908152919050565b61ffff828116828216039080821115612d6a57612d6a612c2e565b5092915050565b634e487b7160e01b600052603260045260246000fd5b600081518084526020808501945080840160005b83811015612dc05781516001600160a01b031687529582019590820190600101612d9b565b509495945050505050565b85815260a060208201526000612de460a0830187612d87565b6001600160a01b039586166040840152939094166060820152608001529392505050565b6001600160a01b039390931683526020830191909152604082015260600190565b86815285602082015260c060408201526000612e4860c0830187612d87565b6001600160a01b03958616606084015293909416608082015260a0015294935050505056fea264697066735822122027e6ba5b2eaa862a678b70a5d25a98ae882ba3aefbc503d8153d87835edfdc4f64736f6c6343000814003300000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000033b2e3c9fd0803ce8000000000000000000000000000000b4a9c4e6ea8e2191d2fa5b380452a634fb21240a000000000000000000000000c8aec7c3e3ac49fe4cf59c37fe80f572c872c981000000000000000000000000000000000000000000000000000000000000000e487970757272537472617465677900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000075055525253545200000000000000000000000000000000000000000000000000
Deployed Bytecode
0x6080604052600436106103685760003560e01c80637ffe7ca5116101c8578063d0e10326116100f8578063ec0788211161009b578063ec07882114610a95578063f0db975c14610aab578063f25f4b5614610ac5578063f2fde38b14610aec578063f392c71614610b0c578063f887ea4014610b2c578063f8b12eda14610b60578063fcc92ff714610b82578063fdd2bae514610ba257600080fd5b8063d0e10326146109a8578063d50cb88b146109c8578063d51ffa81146109de578063d55be8c6146109fe578063dc84205714610a14578063dd62ed3e14610a2f578063e1a4521814610a4f578063e5e31b1314610a6557600080fd5b80639fde54f51161016b5780639fde54f514610881578063a66dd5c2146108a1578063a9059cbb146108b6578063ad58aca0146108d6578063ad5dff73146108f6578063b91ac78814610926578063c2b7bbb614610946578063cd8684bb14610966578063cdeee6371461098857600080fd5b80637ffe7ca5146107995780638a8c523c146107af5780638da5cb5b146107c45780638ff9e3f8146107d957806390ba7a321461080957806390d49b9d1461083657806395d89b41146108565780639d6f09c11461086b57600080fd5b80633f0d2ec1116102a357806366eb37851161024657806366eb378514610692578063679b48a8146106a75780636ddd1713146106c957806370a08231146106e9578063715018a614610709578063768b5fd51461071e57806377d2300e1461073e57806379f9e975146107595780637de1e5361461077957600080fd5b80633f0d2ec1146105885780633fc8cef3146105b557806340ad5db0146105e957806347080a03146106095780634772b1de146106295780634a8b8e2b146106435780634ada218b1461065d5780635d9644c41461067c57600080fd5b80632081c4ea1161030b5780632081c4ea1461048a57806323b2f392146104aa57806323b872dd146104c057806323cbe1f3146104e057806324abf962146105145780632a640f3414610527578063313ce56714610557578063349757481461057357600080fd5b80630445b6671461037457806306fdde031461039d578063095ea7b3146103bf578063108bdc14146103ef578063150b7a0214610411578063161583f01461044a57806318160ddd146104605780631db527551461047557600080fd5b3661036f57005b600080fd5b34801561038057600080fd5b5061038a600b5481565b6040519081526020015b60405180910390f35b3480156103a957600080fd5b506103b2610bc2565b6040516103949190612856565b3480156103cb57600080fd5b506103df6103da3660046128b9565b610c54565b6040519015158152602001610394565b3480156103fb57600080fd5b5061040f61040a3660046128fa565b610c6e565b005b34801561041d57600080fd5b5061043161042c366004612978565b610cd6565b6040516001600160e01b03199091168152602001610394565b34801561045657600080fd5b5061038a60195481565b34801561046c57600080fd5b5060025461038a565b34801561048157600080fd5b5061040f610d16565b34801561049657600080fd5b5061040f6104a53660046129eb565b610eaa565b3480156104b657600080fd5b5061038a60165481565b3480156104cc57600080fd5b506103df6104db366004612a04565b610f00565b3480156104ec57600080fd5b506007546105019062010000900461ffff1681565b60405161ffff9091168152602001610394565b61040f6105223660046129eb565b610f24565b34801561053357600080fd5b506103df610542366004612a45565b600f6020526000908152604090205460ff1681565b34801561056357600080fd5b5060405160128152602001610394565b34801561057f57600080fd5b5060095461038a565b34801561059457600080fd5b506008546105a8906001600160a01b031681565b6040516103949190612a69565b3480156105c157600080fd5b506105a87f000000000000000000000000555555555555555555555555555555555555555581565b3480156105f557600080fd5b5061040f610604366004612a8f565b6111cb565b34801561061557600080fd5b5061040f610624366004612ad2565b611319565b34801561063557600080fd5b50601b546103df9060ff1681565b34801561064f57600080fd5b50600e546103df9060ff1681565b34801561066957600080fd5b50600a546103df90610100900460ff1681565b34801561068857600080fd5b5061038a60155481565b34801561069e57600080fd5b5061040f611369565b3480156106b357600080fd5b5060085461050190600160a01b900461ffff1681565b3480156106d557600080fd5b50600a546103df9062010000900460ff1681565b3480156106f557600080fd5b5061038a610704366004612a45565b611379565b34801561071557600080fd5b5061040f611394565b34801561072a57600080fd5b5061040f610739366004612a45565b6113a6565b34801561074a57600080fd5b506007546105019061ffff1681565b34801561076557600080fd5b5061040f610774366004612aed565b61141e565b34801561078557600080fd5b506012546105a8906001600160a01b031681565b3480156107a557600080fd5b5061050161138881565b3480156107bb57600080fd5b5061040f61146e565b3480156107d057600080fd5b506105a8611514565b3480156107e557600080fd5b506103df6107f4366004612a45565b60116020526000908152604090205460ff1681565b34801561081557600080fd5b5061038a6108243660046129eb565b60136020526000908152604090205481565b34801561084257600080fd5b5061040f610851366004612a45565b611523565b34801561086257600080fd5b506103b26115c4565b34801561087757600080fd5b5061038a601a5481565b34801561088d57600080fd5b5061040f61089c3660046128fa565b6115d3565b3480156108ad57600080fd5b50610501606481565b3480156108c257600080fd5b506103df6108d13660046128b9565b611606565b3480156108e257600080fd5b5061040f6108f13660046128fa565b611614565b34801561090257600080fd5b506103df610911366004612a45565b600c6020526000908152604090205460ff1681565b34801561093257600080fd5b506105a86109413660046129eb565b611674565b34801561095257600080fd5b5061040f610961366004612a45565b61169e565b34801561097257600080fd5b5060075461050190600160301b900461ffff1681565b34801561099457600080fd5b5061040f6109a3366004612a45565b6117ba565b3480156109b457600080fd5b5061040f6109c3366004612b08565b61180a565b3480156109d457600080fd5b5061038a60145481565b3480156109ea57600080fd5b5061040f6109f9366004612aed565b611832565b348015610a0a57600080fd5b506105016103e881565b348015610a2057600080fd5b506018546105019061ffff1681565b348015610a3b57600080fd5b5061038a610a4a366004612b24565b611882565b348015610a5b57600080fd5b5061050161271081565b348015610a7157600080fd5b506103df610a80366004612a45565b600d6020526000908152604090205460ff1681565b348015610aa157600080fd5b5061038a60175481565b348015610ab757600080fd5b506010546103df9060ff1681565b348015610ad157600080fd5b506007546105a890600160401b90046001600160a01b031681565b348015610af857600080fd5b5061040f610b07366004612a45565b6118ad565b348015610b1857600080fd5b5061040f610b27366004612b5d565b6118e8565b348015610b3857600080fd5b506105a87f000000000000000000000000b4a9c4e6ea8e2191d2fa5b380452a634fb21240a81565b348015610b6c57600080fd5b5060075461050190600160201b900461ffff1681565b348015610b8e57600080fd5b5061040f610b9d366004612bc8565b611db8565b348015610bae57600080fd5b5061040f610bbd366004612ad2565b611e22565b606060038054610bd190612bf4565b80601f0160208091040260200160405190810160405280929190818152602001828054610bfd90612bf4565b8015610c4a5780601f10610c1f57610100808354040283529160200191610c4a565b820191906000526020600020905b815481529060010190602001808311610c2d57829003601f168201915b5050505050905090565b600033610c62818585611e6b565b60019150505b92915050565b610c76611e7d565b6001600160a01b038216600081815260116020908152604091829020805460ff191685151590811790915591519182527f52eec1a0372bcc0f149dd096fc04f013047c878bd949d11adecf9b39bc0c71dc91015b60405180910390a25050565b6012546000906001600160a01b03163314610d045760405163517172a160e11b815260040160405180910390fd5b50630a85bd0160e11b95945050505050565b610d1e611eaf565b600060165411610d5f5760405162461bcd60e51b815260206004820152600760248201526606e6f20747761760cc1b60448201526064015b60405180910390fd5b601954601a54610d6f9190612c44565b421015610dab5760405162461bcd60e51b815260206004820152600a602482015269747761702064656c617960b01b6044820152606401610d56565b601754601654811115610dbd57506016545b60185460009061271090610dd59061ffff1684612c57565b610ddf9190612c6e565b9050610deb8183612c90565b9150610df78183612c44565b60166000828254610e089190612c90565b909155505042601a55610e1a82611ed9565b604051600090339083908381818185875af1925050503d8060008114610e5c576040519150601f19603f3d011682016040523d82523d6000602084013e610e61565b606091505b5050905080610e9b5760405162461bcd60e51b81526020600482015260066024820152651c995dd85c9960d21b6044820152606401610d56565b505050610ea86001600655565b565b610eb2611e7d565b612af88110158015610ec657506175308111155b610efb5760405162461bcd60e51b8152600401610d56906020808252600490820152631b5d5b1d60e21b604082015260600190565b601455565b600033610f0e858285612001565b610f19858585612055565b506001949350505050565b610f2c611eaf565b60008181526013602052604081205490819003610f5c5760405163d135e8bd60e01b815260040160405180910390fd5b803414610f7c5760405163499a5b8760e11b815260040160405180910390fd5b6012546040516331a9108f60e11b81526004810184905230916001600160a01b031690636352211e90602401602060405180830381865afa158015610fc5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fe99190612ca3565b6001600160a01b03161461101057604051631022318760e21b815260040160405180910390fd5b6012546040516323b872dd60e01b8152306004820152336024820152604481018490526001600160a01b03909116906323b872dd90606401600060405180830381600087803b15801561106257600080fd5b505af1158015611076573d6000803e3d6000fd5b505060085460009250612710915061109990600160a01b900461ffff1684612c57565b6110a39190612c6e565b90506000811180156110bf57506008546001600160a01b031615155b15611153576008546040516000916001600160a01b03169083908381818185875af1925050503d8060008114611111576040519150601f19603f3d011682016040523d82523d6000602084013e611116565b606091505b50509050806111515760405162461bcd60e51b8152602060048201526007602482015266726f79616c747960c81b6044820152606401610d56565b505b60008381526013602052604081205561116c8183612c90565b6016600082825461117d9190612c44565b90915550506040805183815233602082015284917f89c3b465a41d0ab0891833425d7da4f89bafffceffba56a40bfafff01d68d51e910160405180910390a250506111c86001600655565b50565b6111d3611e7d565b6103e861ffff8416118015906111ef57506103e861ffff831611155b61122a5760405162461bcd60e51b815260206004820152600c60248201526b0cccaca40e8dede40d0d2ced60a31b6044820152606401610d56565b6007805461ffff848116620100000263ffffffff19909216818716179190911790915561138890821611156112ad5760405162461bcd60e51b815260206004820152602360248201527f73656c6c20666565206265666f7265206e667420626f7567687420746f6f20686044820152620d2ced60eb1b6064820152608401610d56565b6007805461ffff8316600160201b0265ffff00000000199091161790556040517f2ac80c14c28700f7b5e36f947d572149fe2e3947bac32c3a8c098f3e03722c119061130c908590859061ffff92831681529116602082015260400190565b60405180910390a1505050565b611321611e7d565b6010805460ff19168215159081179091556040519081527f5d7ec4cc2b9c2911f3721deb89f0cb99972ac6c06be5f269682ddca4ce41f54b906020015b60405180910390a150565b611371611e7d565b610ea86120b4565b6001600160a01b031660009081526020819052604090205490565b61139c611e7d565b610ea860006123c1565b6113ae611e7d565b6001600160a01b0381166113d45760405162461bcd60e51b8152600401610d5690612cc0565b601280546001600160a01b0319166001600160a01b0383169081179091556040517f1c916ba8ddd9af4bcac6dc6280731909c8c6d559b21d4d60fc84e12582b1596390600090a250565b611426611e7d565b6103e861ffff8216111561144c5760405162461bcd60e51b8152600401610d5690612ce0565b6008805461ffff909216600160a01b0261ffff60a01b19909216919091179055565b611476611e7d565b600a54610100900460ff16156114b85760405162461bcd60e51b8152602060048201526007602482015266195b98589b195960ca1b6044820152606401610d56565b6009546000036114da5760405162461bcd60e51b8152600401610d5690612d08565b600a805461ff0019166101001790556040517f799663458a5ef2936f7fa0c99b3336c69c25890f82974f04e811e5bb359186c790600090a1565b6005546001600160a01b031690565b61152b611e7d565b6001600160a01b0381166115515760405162461bcd60e51b8152600401610d5690612cc0565b60078054600160401b600160e01b031916600160401b6001600160a01b038416908102919091179091556000908152600c602052604090819020805460ff19166001179055517f29acee77dafcfa0143d74a7ea236018f3a6e1fa71e27fc59bbfbc6b8ca8edccd9061135e908390612a69565b606060048054610bd190612bf4565b6115db611e7d565b6001600160a01b03919091166000908152600c60205260409020805460ff1916911515919091179055565b600033610c62818585612055565b61161c611e7d565b6001600160a01b0382166000818152600f6020908152604091829020805460ff191685151590811790915591519182527fb73ef82aa45b7f4fbd7aa401e3653c03720cb9564895bea841433c737952c01d9101610cca565b6009818154811061168457600080fd5b6000918252602090912001546001600160a01b0316905081565b6116a6611e7d565b6001600160a01b0381166116cc5760405162461bcd60e51b8152600401610d5690612d08565b6001600160a01b0381166000908152600d602052604090205460ff16156117235760405162461bcd60e51b815260206004820152600b60248201526a706169722065786973747360a81b6044820152606401610d56565b6001600160a01b0381166000818152600d6020526040808220805460ff191660019081179091556009805491820181559092527f6e1540171b6c0c960b71a7020d9f60077f6af931a8bbf590da0223dacf75c7af90910180546001600160a01b031916909217909155517fb14a725aeeb25d591b81b16b4c5b25403dd8867bdd1876fa787867f566206be19061135e908390612a69565b6117c2611e7d565b6001600160a01b0381166117e85760405162461bcd60e51b8152600401610d5690612cc0565b600880546001600160a01b0319166001600160a01b0392909216919091179055565b611812611e7d565b600a8054921515620100000262ff00001990931692909217909155600b55565b61183a611e7d565b6103e861ffff821611156118605760405162461bcd60e51b8152600401610d5690612ce0565b6007805461ffff909216600160301b0261ffff60301b19909216919091179055565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b6118b5611e7d565b6001600160a01b0381166118df576000604051631e4fbdf760e01b8152600401610d569190612a69565b6111c8816123c1565b6118f0611eaf565b600e5460ff161561194557336000908152600f602052604090205460ff166119455760405162461bcd60e51b8152602060048201526008602482015267189d5e595c881ddb60c21b6044820152606401610d56565b60105460ff16156119a4576001600160a01b03811660009081526011602052604090205460ff166119a45760405162461bcd60e51b81526020600482015260096024820152681d185c99d95d081ddb60ba1b6044820152606401610d56565b6012546001600160a01b03166119e95760405162461bcd60e51b815260206004820152600a60248201526931b7b63632b1ba34b7b760b11b6044820152606401610d56565b6012546040516331a9108f60e11b81526004810184905230916001600160a01b031690636352211e90602401602060405180830381865afa158015611a32573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a569190612ca3565b6001600160a01b031603611a7d5760405163085cf94760e41b815260040160405180910390fd5b601554851115611aa05760405163f14a42b760e01b815260040160405180910390fd5b6012546040516370a0823160e01b815247916000916001600160a01b03909116906370a0823190611ad5903090600401612a69565b602060405180830381865afa158015611af2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b169190612d26565b9050600080846001600160a01b0316898989604051611b36929190612d3f565b60006040518083038185875af1925050503d8060008114611b73576040519150601f19603f3d011682016040523d82523d6000602084013e611b78565b606091505b509150915081611b8a57805160208201fd5b6012546040516370a0823160e01b81526000916001600160a01b0316906370a0823190611bbb903090600401612a69565b602060405180830381865afa158015611bd8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611bfc9190612d26565b9050611c09846001612c44565b8114611c2857604051630b7cb52160e41b815260040160405180910390fd5b6012546040516331a9108f60e11b81526004810189905230916001600160a01b031690636352211e90602401602060405180830381865afa158015611c71573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c959190612ca3565b6001600160a01b031614611cbc57604051631022318760e21b815260040160405180910390fd5b6000611cc84787612c90565b90508060156000828254611cdc9190612c90565b909155505060145460009061271090611cf59084612c57565b611cff9190612c6e565b600854909150600090611d1f90600160a01b900461ffff16612710612d4f565b61ffff16611d2f61271084612c57565b611d399190612c6e565b60008b81526013602052604090819020829055601b805460ff19166001179055519091508a907f272af40a157c8d1a7d3bf7ff2920db021097ec61b7e260f97bb50144520ad17790611d979086908590918252602082015260400190565b60405180910390a25050505050505050611db16001600655565b5050505050565b611dc0611e7d565b606461ffff82161115611e025760405162461bcd60e51b815260206004820152600a6024820152690726577617264206361760b41b6044820152606401610d56565b6017929092556019556018805461ffff191661ffff909216919091179055565b611e2a611e7d565b600e805460ff19168215159081179091556040519081527f4d17abbadb127e75c188fbaeb39e24a7db27bb8792eba70075fcaf0c3e89c1e39060200161135e565b611e788383836001612413565b505050565b33611e86611514565b6001600160a01b031614610ea8573360405163118cdaa760e01b8152600401610d569190612a69565b600260065403611ed257604051633ee5aeb560e01b815260040160405180910390fd5b6002600655565b6040805160028082526060820183526000926020830190803683370190505090507f000000000000000000000000555555555555555555555555555555555555555581600081518110611f2e57611f2e612d71565b60200260200101906001600160a01b031690816001600160a01b0316815250503081600181518110611f6257611f62612d71565b6001600160a01b03928316602091820292909201015260405163b4822be360e01b81527f000000000000000000000000b4a9c4e6ea8e2191d2fa5b380452a634fb21240a9091169063b4822be3908490611fcb90600090869061dead9083904290600401612dcb565b6000604051808303818588803b158015611fe457600080fd5b505af1158015611ff8573d6000803e3d6000fd5b50505050505050565b600061200d8484611882565b905060001981101561204f578181101561204057828183604051637dc7a0d960e11b8152600401610d5693929190612e08565b61204f84848484036000612413565b50505050565b6001600160a01b03831661207f576000604051634b637e8f60e11b8152600401610d569190612a69565b6001600160a01b0382166120a957600060405163ec442f0560e01b8152600401610d569190612a69565b611e788383836124e8565b600a805460ff1916600117905560006120cc30611379565b9050806000036120dc57506123b5565b6000600b5460026120ed9190612c57565b82116120f95781612107565b600b54612107906002612c57565b9050612134307f000000000000000000000000b4a9c4e6ea8e2191d2fa5b380452a634fb21240a83611e6b565b604080516002808252606082018352600092602083019080368337019050509050308160008151811061216957612169612d71565b60200260200101906001600160a01b031690816001600160a01b0316815250507f0000000000000000000000005555555555555555555555555555555555555555816001815181106121bd576121bd612d71565b6001600160a01b039283166020918202929092010152604051632955261160e11b815247917f000000000000000000000000b4a9c4e6ea8e2191d2fa5b380452a634fb21240a16906352aa4c22906122249086906000908790309083904290600401612e29565b600060405180830381600087803b15801561223e57600080fd5b505af1158015612252573d6000803e3d6000fd5b50505050600081476122649190612c90565b905080156123af576007546000906127109061228b90600160301b900461ffff1684612c57565b6122959190612c6e565b905060006122a38284612c90565b905080601560008282546122b79190612c44565b9091555050811561237357600754604051600091600160401b90046001600160a01b03169084908381818185875af1925050503d8060008114612316576040519150601f19603f3d011682016040523d82523d6000602084013e61231b565b606091505b50509050806123715760075460408051600160401b9092046001600160a01b03168252602082018590527f0d55be71cf7461cbc31e2952b797fc3acb4952967c0696106242639fd5e629fc910160405180910390a15b505b60408051878152602081018590527f05ab84b321981d7d9a13402e494604c50821bcb5f2400d128fa06cd6451113d4910160405180910390a150505b50505050505b600a805460ff19169055565b600580546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6001600160a01b03841661243d57600060405163e602df0560e01b8152600401610d569190612a69565b6001600160a01b038316612467576000604051634a1406b160e11b8152600401610d569190612a69565b6001600160a01b038085166000908152600160209081526040808320938716835292905220829055801561204f57826001600160a01b0316846001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925846040516124da91815260200190565b60405180910390a350505050565b600a54610100900460ff161580156125195750612503611514565b6001600160a01b0316836001600160a01b031614155b801561253e5750612528611514565b6001600160a01b0316826001600160a01b031614155b156125755760405162461bcd60e51b815260206004820152600760248201526674726164696e6760c81b6044820152606401610d56565b600a5462010000900460ff1680156125905750600a5460ff16155b80156125a65750600b546125a330611379565b10155b80156125ec57506001600160a01b0383166000908152600d602052604090205460ff16806125ec57506001600160a01b0382166000908152600d602052604090205460ff165b156125f9576125f96120b4565b601b54600090819060ff1661261b57600754600160201b900461ffff16612629565b60075462010000900461ffff165b6001600160a01b0386166000908152600c602052604090205490915060ff1615801561266e57506001600160a01b0384166000908152600c602052604090205460ff16155b1561271a576001600160a01b0385166000908152600d602052604090205460ff1680156126a0575060075461ffff1615155b156126cb57600754612710906126ba9061ffff1685612c57565b6126c49190612c6e565b915061271a565b6001600160a01b0384166000908152600d602052604090205460ff1680156126f7575060008161ffff16115b1561271a5761271061270d61ffff831685612c57565b6127179190612c6e565b91505b81156127385761272b85308461273f565b6127358284612c90565b92505b611db18585855b6001600160a01b03831661276a57806002600082825461275f9190612c44565b909155506127c99050565b6001600160a01b038316600090815260208190526040902054818110156127aa5783818360405163391434e360e21b8152600401610d5693929190612e08565b6001600160a01b03841660009081526020819052604090209082900390555b6001600160a01b0382166127e557600280548290039055612804565b6001600160a01b03821660009081526020819052604090208054820190555b816001600160a01b0316836001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8360405161284991815260200190565b60405180910390a3505050565b600060208083528351808285015260005b8181101561288357858101830151858201604001528201612867565b506000604082860101526040601f19601f8301168501019250505092915050565b6001600160a01b03811681146111c857600080fd5b600080604083850312156128cc57600080fd5b82356128d7816128a4565b946020939093013593505050565b803580151581146128f557600080fd5b919050565b6000806040838503121561290d57600080fd5b8235612918816128a4565b9150612926602084016128e5565b90509250929050565b60008083601f84011261294157600080fd5b50813567ffffffffffffffff81111561295957600080fd5b60208301915083602082850101111561297157600080fd5b9250929050565b60008060008060006080868803121561299057600080fd5b853561299b816128a4565b945060208601356129ab816128a4565b935060408601359250606086013567ffffffffffffffff8111156129ce57600080fd5b6129da8882890161292f565b969995985093965092949392505050565b6000602082840312156129fd57600080fd5b5035919050565b600080600060608486031215612a1957600080fd5b8335612a24816128a4565b92506020840135612a34816128a4565b929592945050506040919091013590565b600060208284031215612a5757600080fd5b8135612a62816128a4565b9392505050565b6001600160a01b0391909116815260200190565b803561ffff811681146128f557600080fd5b600080600060608486031215612aa457600080fd5b612aad84612a7d565b9250612abb60208501612a7d565b9150612ac960408501612a7d565b90509250925092565b600060208284031215612ae457600080fd5b612a62826128e5565b600060208284031215612aff57600080fd5b612a6282612a7d565b60008060408385031215612b1b57600080fd5b6128d7836128e5565b60008060408385031215612b3757600080fd5b8235612b42816128a4565b91506020830135612b52816128a4565b809150509250929050565b600080600080600060808688031215612b7557600080fd5b85359450602086013567ffffffffffffffff811115612b9357600080fd5b612b9f8882890161292f565b909550935050604086013591506060860135612bba816128a4565b809150509295509295909350565b600080600060608486031215612bdd57600080fd5b8335925060208401359150612ac960408501612a7d565b600181811c90821680612c0857607f821691505b602082108103612c2857634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052601160045260246000fd5b80820180821115610c6857610c68612c2e565b8082028115828204841417610c6857610c68612c2e565b600082612c8b57634e487b7160e01b600052601260045260246000fd5b500490565b81810381811115610c6857610c68612c2e565b600060208284031215612cb557600080fd5b8151612a62816128a4565b6020808252600690820152651dd85b1b195d60d21b604082015260600190565b6020808252600e908201526d0e6d0c2e4ca40e8dede40d0d2ced60931b604082015260600190565b6020808252600490820152633830b4b960e11b604082015260600190565b600060208284031215612d3857600080fd5b5051919050565b8183823760009101908152919050565b61ffff828116828216039080821115612d6a57612d6a612c2e565b5092915050565b634e487b7160e01b600052603260045260246000fd5b600081518084526020808501945080840160005b83811015612dc05781516001600160a01b031687529582019590820190600101612d9b565b509495945050505050565b85815260a060208201526000612de460a0830187612d87565b6001600160a01b039586166040840152939094166060820152608001529392505050565b6001600160a01b039390931683526020830191909152604082015260600190565b86815285602082015260c060408201526000612e4860c0830187612d87565b6001600160a01b03958616606084015293909416608082015260a0015294935050505056fea264697066735822122027e6ba5b2eaa862a678b70a5d25a98ae882ba3aefbc503d8153d87835edfdc4f64736f6c63430008140033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
00000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000033b2e3c9fd0803ce8000000000000000000000000000000b4a9c4e6ea8e2191d2fa5b380452a634fb21240a000000000000000000000000c8aec7c3e3ac49fe4cf59c37fe80f572c872c981000000000000000000000000000000000000000000000000000000000000000e487970757272537472617465677900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000075055525253545200000000000000000000000000000000000000000000000000
-----Decoded View---------------
Arg [0] : name_ (string): HypurrStrategy
Arg [1] : symbol_ (string): PURRSTR
Arg [2] : supply_ (uint256): 1000000000000000000000000000
Arg [3] : router_ (address): 0xb4a9C4e6Ea8E2191d2FA5B380452a634Fb21240A
Arg [4] : feeWallet_ (address): 0xc8AEC7C3E3ac49FE4cf59C37fE80F572c872C981
-----Encoded View---------------
9 Constructor Arguments found :
Arg [0] : 00000000000000000000000000000000000000000000000000000000000000a0
Arg [1] : 00000000000000000000000000000000000000000000000000000000000000e0
Arg [2] : 0000000000000000000000000000000000000000033b2e3c9fd0803ce8000000
Arg [3] : 000000000000000000000000b4a9c4e6ea8e2191d2fa5b380452a634fb21240a
Arg [4] : 000000000000000000000000c8aec7c3e3ac49fe4cf59c37fe80f572c872c981
Arg [5] : 000000000000000000000000000000000000000000000000000000000000000e
Arg [6] : 4879707572725374726174656779000000000000000000000000000000000000
Arg [7] : 0000000000000000000000000000000000000000000000000000000000000007
Arg [8] : 5055525253545200000000000000000000000000000000000000000000000000
Loading...
Loading
Loading...
Loading
Loading...
Loading
Net Worth in USD
$0.00
Net Worth in HYPE
Multichain Portfolio | 35 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.