Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Contract Source Code Verified (Exact Match)
Contract Name:
Token
Compiler Version
v0.8.24+commit.e11b9ed9
Optimization Enabled:
Yes with 200 runs
Other Settings:
paris EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: None pragma solidity ^0.8.24; import "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol"; import "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol"; import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol"; import "@uniswap/v2-periphery/contracts/interfaces/IUniswapV2Router02.sol"; import "@uniswap/v2-core/contracts/interfaces/IUniswapV2Factory.sol"; import "./interfaces/IERC721A.sol"; import "./interfaces/ITeamFinanceLocker.sol"; import "./interfaces/ITokenWhitelist.sol"; /// This token was incubated and launched by PROOF: https://proofplatform.io/projects. The smart contract is audited by SourceHat: https://sourcehat.com/ contract Token is ITokenWhitelist, Initializable, ERC20Upgradeable, OwnableUpgradeable { struct UserInfo { bool isFeeExempt; bool isTxLimitExempt; bool isWhitelisted; } IUniswapV2Router02 public uniswapV2Router; address public pair; address payable public mainWallet; address payable public secondaryWallet; IERC721A public proofPassNFT; bool public isWhitelistActive; uint256 public whitelistEndTime; uint256 public whitelistDuration; uint256 public launchedAt; uint256 public maxTxAmount; uint256 public maxWallet; uint256 public initMaxWallet; bool public checkMaxHoldings = true; bool public maxWalletChanged; uint256 public swapping; bool public swapEnabled; uint256 public swapTokensAtAmount; FeeInfo public feeTokens; FeeInfo public buyFees; FeeInfo public sellFees; uint256 public restingBuyTotal; uint256 public restingSellTotal; bool public buyTaxesSettled; bool public sellTaxesSettled; bool public proofFeeReduced; bool public proofFeeRemoved; bool public cancelled; uint256 public lockID; uint256 public lpLockDuration; mapping (address => UserInfo) public userInfo; mapping (uint256 => uint256) public swapThrottle; uint256 public maxSwapsPerBlock; IDataStore public immutable DATA_STORE; DataStoreAddressResponse public addresses; DataStoreLimitsResponse public limits; event SwapAndLiquify(uint256 tokensAutoLiq, uint256 ethAutoLiq); event SwapAndLiquifyEnabledUpdated(bool enabled); event TokenCancelled(uint256 returnedETH); constructor(IDataStore dataStore) { DATA_STORE = dataStore; _disableInitializers(); } function initialize(bytes calldata params) initializer public payable lockTheSwap { TokenInfo memory token = abi.decode(params, (TokenInfo)); __ERC20_init(token.name, token.symbol); __Ownable_init(token.owner); DataStoreLimitsResponse memory _limits = DATA_STORE.getLimits(); limits = _limits; (token.buyFees.proof, token.sellFees.proof) = (2,2); _validateFees(token.buyFees, token.sellFees); restingBuyTotal = token.buyFees.total; restingSellTotal = token.sellFees.total; token.buyFees.main = 15 - token.buyFees.proof - token.buyFees.secondary - token.buyFees.liquidity; token.buyFees.total = 15; token.sellFees.main = 20 - token.sellFees.proof - token.sellFees.secondary - token.sellFees.liquidity; token.sellFees.total = 20; buyFees = token.buyFees; sellFees = token.sellFees; // set addresses mainWallet = payable(token.mainWallet); secondaryWallet = payable(token.secondaryWallet); DataStoreAddressResponse memory _addresses = DATA_STORE.getPlatformAddresses(); addresses = _addresses; proofPassNFT = IERC721A(_addresses.proofPassNFT); IUniswapV2Router02 _uniswapV2Router = IUniswapV2Router02(_addresses.router); uniswapV2Router = _uniswapV2Router; pair = IUniswapV2Factory(_uniswapV2Router.factory()) .createPair(address(this), _uniswapV2Router.WETH()); // set basic data lpLockDuration = token.lpLockDuration; swapTokensAtAmount = token.totalSupply * _limits.swapTokensAtAmount / _limits.denominator; // 125 / 100000 maxTxAmount = token.totalSupply * _limits.initMaxTx / _limits.denominator; initMaxWallet = token.initMaxWallet; maxWallet = token.totalSupply * token.initMaxWallet / 100000; // 100 = .1% maxSwapsPerBlock = 4; userInfo[address(this)] = UserInfo(true, true, true); userInfo[pair].isTxLimitExempt = true; userInfo[pair].isWhitelisted = true; whitelistDuration = token.whitelistDuration; _setWhitelisted(token.whitelist); uint256 amountToPair = token.totalSupply * token.percentToLP / 100; super._update(address(0), address(this), amountToPair); // mint to contract for liquidity super._update(address(0), owner(), token.totalSupply - amountToPair); // mint to owner _approve(address(this), address(uniswapV2Router), type(uint256).max); addLiquidity(amountToPair, msg.value, address(this)); } function launch(uint256 bundleBuyAmount) external payable onlyOwner lockTheSwap { if (launchedAt != 0 || cancelled) { revert InvalidConfiguration(); } // enable trading checkMaxHoldings = true; swapEnabled = true; whitelistEndTime = block.timestamp + whitelistDuration; isWhitelistActive = true; launchedAt = block.timestamp; if (bundleBuyAmount != 0) { //execute bundle buy address[] memory path = new address[](2); path[0] = uniswapV2Router.WETH(); path[1] = address(this); uniswapV2Router.swapExactETHForTokens{ value: bundleBuyAmount }( 0, path, msg.sender, block.timestamp ); } // add NFT snapshot uint256 len = proofPassNFT.totalSupply() + 1; for (uint256 i = 1; i < len; ) { userInfo[proofPassNFT.ownerOf(i)].isWhitelisted = true; unchecked { ++i; } } // lock liquidity uint256 lpBalance = IERC20(pair).balanceOf(address(this)); IERC20(pair).approve(addresses.locker, lpBalance); lockID = ITeamFinanceLocker(addresses.locker).lockToken{value: address(this).balance}(pair, msg.sender, lpBalance, block.timestamp + lpLockDuration, false, address(0)); } function cancel() external onlyOwner lockTheSwap { if (launchedAt != 0) { revert InvalidConfiguration(); } IERC20(pair).approve(address(uniswapV2Router), IERC20(pair).balanceOf(address(this))); (uint256 ethAmt) = uniswapV2Router.removeLiquidityETHSupportingFeeOnTransferTokens( address(this), IERC20(pair).balanceOf(address(this)), 0, // liq pool should be untouchable 0, // liq pool should be untouchable msg.sender, block.timestamp ); emit TokenCancelled(ethAmt); cancelled = true; // send the tokens and eth back to the owner uint256 bal = address(this).balance; if (bal > 0) { address(msg.sender).call{value: bal}(""); } } function _update( address from, address to, uint256 amount ) internal override { if (swapping == 2 || from == owner() || to == owner() || from == address(this) || to == address(this) || amount == 0) { super._update(from, to, amount); return; } if (launchedAt == 0) { revert TradingNotEnabled(); } UserInfo storage sender = userInfo[from]; UserInfo storage recipient = userInfo[to]; if (isWhitelistActive) { if (block.timestamp < whitelistEndTime) { if (!sender.isWhitelisted || !recipient.isWhitelisted) { revert NotWhitelisted(); } } else { isWhitelistActive = false; } } //start at anywhere from 0.1% to 0.5%, increase by 0.1%, every 10 blocks, until it reaches 1% if (!maxWalletChanged) { uint256 secondsPassed = block.timestamp - launchedAt; uint256 percentage = initMaxWallet + (100 * (secondsPassed / 120)); if (percentage > 950) { percentage = 1000; maxWalletChanged = true; } uint256 newMax = totalSupply() * percentage / 100000; if (newMax != maxWallet) { maxWallet = newMax; } } if (checkMaxHoldings) { if (!recipient.isTxLimitExempt && amount + balanceOf(to) > maxWallet) { revert ExceedsMaxWalletAmount(); } } uint256 total = feeTokens.total; bool canSwap = total >= swapTokensAtAmount; if ( canSwap && swapEnabled && from != pair && swapThrottle[block.number] < maxSwapsPerBlock ) { ++swapThrottle[block.number]; processFees(total, swapTokensAtAmount); } if (!sender.isFeeExempt && !recipient.isFeeExempt) { FeeInfo storage _buyFees = buyFees; FeeInfo storage _sellFees = sellFees; if (!proofFeeRemoved) { uint256 secondsPassed = block.timestamp - launchedAt; if (!proofFeeReduced && secondsPassed > 1 days) { uint256 totalBuy = _buyFees.total - _buyFees.proof; if (totalBuy == 0) { _buyFees.total = 0; _buyFees.proof = 0; } else { buyFees.main = _buyFees.main + 1; //move proof fee to main fee, total doesn't change _buyFees.proof = 1; //decrementing proof fee by 1% } uint256 totalSell = _sellFees.total - _sellFees.proof; if (totalSell == 0) { _sellFees.total = 0; _sellFees.proof = 0; } else { _sellFees.main = _sellFees.main + 1; //same as the buy fee logic _sellFees.proof = 1; } proofFeeReduced = true; } else if (secondsPassed > 31 days) { //move proof fee to main fee _buyFees.main += _buyFees.proof; _sellFees.main += _sellFees.proof; _buyFees.proof = 0; _sellFees.proof = 0; proofFeeRemoved = true; } else { if (!buyTaxesSettled) { uint256 restingTotal = restingBuyTotal; uint256 feeTotal = restingTotal; if (secondsPassed < 1801) { //fee starts at 15%, decreases by 1% every 2 minutes until we reach the restingTotal. feeTotal = 15 - (secondsPassed / 120); } if (feeTotal <= restingTotal) { _buyFees.total = restingTotal; _buyFees.main = restingTotal - _buyFees.liquidity - _buyFees.secondary - _buyFees.proof; buyTaxesSettled = true; } else if (feeTotal != _buyFees.total) { _buyFees.total = feeTotal; //extra fees get sent to the main wallet _buyFees.main = feeTotal - _buyFees.liquidity - _buyFees.secondary - _buyFees.proof; } } if (!sellTaxesSettled) { uint256 restingTotal = restingSellTotal; uint256 feeTotal = restingTotal; if (secondsPassed < 2401) { feeTotal = 20 - (secondsPassed / 120); } if (feeTotal <= restingTotal) { _sellFees.total = restingTotal; _sellFees.main = restingTotal - _sellFees.liquidity - _sellFees.secondary - _sellFees.proof; sellTaxesSettled = true; } else if (feeTotal != _sellFees.total) { _sellFees.total = feeTotal; _sellFees.main = feeTotal - _sellFees.liquidity - _sellFees.secondary - _sellFees.proof; } } } } uint256 fees; if (to == pair) { //sell fees = _calculateFees(_sellFees, amount); } else if (from == pair) { //buy fees = _calculateFees(_buyFees, amount); } if (fees > 0) { amount -= fees; super._update(from, address(this), fees); } } super._update(from, to, amount); } function _calculateFees(FeeInfo memory feeRate, uint256 amount) internal returns (uint256 fees) { if (feeRate.total != 0) { fees = amount * feeRate.total / 100; FeeInfo storage _feeTokens = feeTokens; _feeTokens.main += fees * feeRate.main / feeRate.total; _feeTokens.secondary += fees * feeRate.secondary / feeRate.total; _feeTokens.liquidity += fees * feeRate.liquidity / feeRate.total; _feeTokens.proof += fees * feeRate.proof / feeRate.total; _feeTokens.total += fees; } } function processFees(uint256 total, uint256 amountToSwap) internal lockTheSwap { FeeInfo storage _feeTokens = feeTokens; FeeInfo memory swapTokens; swapTokens.main = amountToSwap * _feeTokens.main / total; swapTokens.secondary = amountToSwap * _feeTokens.secondary / total; swapTokens.liquidity = amountToSwap * _feeTokens.liquidity / total; swapTokens.proof = amountToSwap * _feeTokens.proof / total; uint256 amountToPair = swapTokens.liquidity / 2; swapTokens.total = amountToSwap - amountToPair; uint256 ethBalance = swapTokensForETH(swapTokens.total); FeeInfo memory ethSplit; ethSplit.main = ethBalance * swapTokens.main / swapTokens.total; if (ethSplit.main > 0) { address(mainWallet).call{value: ethSplit.main}(""); } ethSplit.secondary = ethBalance * swapTokens.secondary / swapTokens.total; if (ethSplit.secondary > 0) { address(secondaryWallet).call{value: ethSplit.secondary}(""); } ethSplit.proof = ethBalance * swapTokens.proof / swapTokens.total; if (ethSplit.proof > 0) { uint256 revenueSplit = ethSplit.proof / 2; address(addresses.proofStaking).call{value: revenueSplit}(""); address(addresses.proofWallet).call{value: ethSplit.proof - revenueSplit}(""); } uint256 amountPaired; ethSplit.liquidity = address(this).balance; if (amountToPair > 0 && ethSplit.liquidity > 0) { amountPaired = addLiquidity(amountToPair, ethSplit.liquidity, address(0xdead)); emit SwapAndLiquify(amountToPair, ethSplit.liquidity); } uint256 liquidityAdjustment = swapTokens.liquidity - (amountToPair - amountPaired); _feeTokens.main -= swapTokens.main; _feeTokens.secondary -= swapTokens.secondary; _feeTokens.liquidity -= liquidityAdjustment; _feeTokens.proof -= swapTokens.proof; _feeTokens.total -= swapTokens.main + swapTokens.secondary + swapTokens.proof + liquidityAdjustment; } function swapTokensForETH(uint256 tokenAmount) internal returns (uint256 ethBalance) { uint256 ethBalBefore = address(this).balance; address[] memory path = new address[](2); path[0] = address(this); path[1] = uniswapV2Router.WETH(); uniswapV2Router.swapExactTokensForETHSupportingFeeOnTransferTokens( tokenAmount, 0, // accept any amount of ETH path, address(this), block.timestamp ); ethBalance = address(this).balance - ethBalBefore; } function addLiquidity(uint256 tokenAmount, uint256 ethAmount, address recipient) private returns (uint256) { (uint256 amountA,,) = uniswapV2Router.addLiquidityETH{value: ethAmount}( address(this), tokenAmount, 0, // slippage is unavoidable 0, // slippage is unavoidable recipient, block.timestamp ); return amountA; } function changeFees( uint256 liquidityBuy, uint256 mainBuy, uint256 secondaryBuy, uint256 liquiditySell, uint256 mainSell, uint256 secondarySell ) external onlyOwner { if (!buyTaxesSettled || !sellTaxesSettled) { revert InvalidConfiguration(); } FeeInfo memory _buyFees; _buyFees.liquidity = liquidityBuy; _buyFees.main = mainBuy; _buyFees.secondary = secondaryBuy; FeeInfo memory _sellFees; _sellFees.liquidity = liquiditySell; _sellFees.main = mainSell; _sellFees.secondary = secondarySell; (_buyFees.proof, _sellFees.proof) = launchedAt != 0 ? _calculateProofFee() : (2,2); _validateFees(_buyFees, _sellFees); buyFees = _buyFees; sellFees = _sellFees; } function _calculateProofFee() internal returns (uint256, uint256) { uint256 secondsPassed = block.timestamp - launchedAt; if (secondsPassed > 31 days) { proofFeeRemoved = true; return (0,0); } else if (secondsPassed > 1 days) { proofFeeReduced = true; return (1,1); } else { return (2,2); } } function _validateFees(FeeInfo memory _buyFees, FeeInfo memory _sellFees) internal view { _buyFees.total = _buyFees.liquidity + _buyFees.main + _buyFees.secondary; if (_buyFees.total == 0) { _buyFees.proof = 0; } else { _buyFees.total += _buyFees.proof; } _sellFees.total = _sellFees.liquidity + _sellFees.main + _sellFees.secondary; if (_sellFees.total == 0) { _sellFees.proof = 0; } else { _sellFees.total += _sellFees.proof; } if (_buyFees.total > limits.maxBuyFee || _sellFees.total > limits.maxSellFee) { revert InvalidConfiguration(); } } function setCheckMaxHoldingsEnabled(bool _enabled) external onlyOwner{ checkMaxHoldings = _enabled; } function setFeeExempt(address account, bool value) public onlyOwner { userInfo[account].isFeeExempt = value; } function setFeeExempt(address[] memory accounts) public onlyOwner { uint256 len = accounts.length; for (uint256 i; i < len; i++) { userInfo[accounts[i]].isFeeExempt = true; } } function setMainWallet(address newWallet) external onlyOwner { mainWallet = payable(newWallet); } function setSecondaryWallet(address newWallet) external onlyOwner { secondaryWallet = payable(newWallet); } function setSwapAndLiquifyEnabled(bool _enabled) external onlyOwner { swapEnabled = _enabled; emit SwapAndLiquifyEnabledUpdated(_enabled); } function setSwapAtAmount(uint256 amount) external onlyOwner { swapTokensAtAmount = amount; } function setMaxSwapsPerBlock(uint256 _maxSwaps) external onlyOwner { maxSwapsPerBlock = _maxSwaps; } function _setWhitelisted(address[] memory accounts) internal { uint256 len = accounts.length; for (uint256 i; i < len; i++) { userInfo[accounts[i]].isWhitelisted = true; } } function withdrawStuckTokens() external onlyOwner { super._update(address(this), _msgSender(), balanceOf(address(this)) - feeTokens.total); } function getCirculatingSupply() external view returns (uint256) { return totalSupply() - balanceOf(address(0xdead)); } modifier lockTheSwap() { swapping = 2; _; swapping = 1; } function decimals() public view virtual override returns (uint8) { return 9; } function version() public pure returns (uint8) { return 3; } receive() external payable {} }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (access/Ownable.sol) pragma solidity ^0.8.20; import {ContextUpgradeable} from "../utils/ContextUpgradeable.sol"; import {Initializable} from "../proxy/utils/Initializable.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 OwnableUpgradeable is Initializable, ContextUpgradeable { /// @custom:storage-location erc7201:openzeppelin.storage.Ownable struct OwnableStorage { address _owner; } // keccak256(abi.encode(uint256(keccak256("openzeppelin.storage.Ownable")) - 1)) & ~bytes32(uint256(0xff)) bytes32 private constant OwnableStorageLocation = 0x9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c199300; function _getOwnableStorage() private pure returns (OwnableStorage storage $) { assembly { $.slot := OwnableStorageLocation } } /** * @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. */ function __Ownable_init(address initialOwner) internal onlyInitializing { __Ownable_init_unchained(initialOwner); } function __Ownable_init_unchained(address initialOwner) internal onlyInitializing { 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) { OwnableStorage storage $ = _getOwnableStorage(); 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 { OwnableStorage storage $ = _getOwnableStorage(); address oldOwner = $._owner; $._owner = newOwner; emit OwnershipTransferred(oldOwner, newOwner); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (proxy/utils/Initializable.sol) pragma solidity ^0.8.20; /** * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect. * * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be * reused. This mechanism prevents re-execution of each "step" but allows the creation of new initialization steps in * case an upgrade adds a module that needs to be initialized. * * For example: * * [.hljs-theme-light.nopadding] * ```solidity * contract MyToken is ERC20Upgradeable { * function initialize() initializer public { * __ERC20_init("MyToken", "MTK"); * } * } * * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable { * function initializeV2() reinitializer(2) public { * __ERC20Permit_init("MyToken"); * } * } * ``` * * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}. * * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity. * * [CAUTION] * ==== * Avoid leaving a contract uninitialized. * * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed: * * [.hljs-theme-light.nopadding] * ``` * /// @custom:oz-upgrades-unsafe-allow constructor * constructor() { * _disableInitializers(); * } * ``` * ==== */ abstract contract Initializable { /** * @dev Storage of the initializable contract. * * It's implemented on a custom ERC-7201 namespace to reduce the risk of storage collisions * when using with upgradeable contracts. * * @custom:storage-location erc7201:openzeppelin.storage.Initializable */ struct InitializableStorage { /** * @dev Indicates that the contract has been initialized. */ uint64 _initialized; /** * @dev Indicates that the contract is in the process of being initialized. */ bool _initializing; } // keccak256(abi.encode(uint256(keccak256("openzeppelin.storage.Initializable")) - 1)) & ~bytes32(uint256(0xff)) bytes32 private constant INITIALIZABLE_STORAGE = 0xf0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00; /** * @dev The contract is already initialized. */ error InvalidInitialization(); /** * @dev The contract is not initializing. */ error NotInitializing(); /** * @dev Triggered when the contract has been initialized or reinitialized. */ event Initialized(uint64 version); /** * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope, * `onlyInitializing` functions can be used to initialize parent contracts. * * Similar to `reinitializer(1)`, except that in the context of a constructor an `initializer` may be invoked any * number of times. This behavior in the constructor can be useful during testing and is not expected to be used in * production. * * Emits an {Initialized} event. */ modifier initializer() { // solhint-disable-next-line var-name-mixedcase InitializableStorage storage $ = _getInitializableStorage(); // Cache values to avoid duplicated sloads bool isTopLevelCall = !$._initializing; uint64 initialized = $._initialized; // Allowed calls: // - initialSetup: the contract is not in the initializing state and no previous version was // initialized // - construction: the contract is initialized at version 1 (no reininitialization) and the // current contract is just being deployed bool initialSetup = initialized == 0 && isTopLevelCall; bool construction = initialized == 1 && address(this).code.length == 0; if (!initialSetup && !construction) { revert InvalidInitialization(); } $._initialized = 1; if (isTopLevelCall) { $._initializing = true; } _; if (isTopLevelCall) { $._initializing = false; emit Initialized(1); } } /** * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be * used to initialize parent contracts. * * A reinitializer may be used after the original initialization step. This is essential to configure modules that * are added through upgrades and that require initialization. * * When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer` * cannot be nested. If one is invoked in the context of another, execution will revert. * * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in * a contract, executing them in the right order is up to the developer or operator. * * WARNING: Setting the version to 2**64 - 1 will prevent any future reinitialization. * * Emits an {Initialized} event. */ modifier reinitializer(uint64 version) { // solhint-disable-next-line var-name-mixedcase InitializableStorage storage $ = _getInitializableStorage(); if ($._initializing || $._initialized >= version) { revert InvalidInitialization(); } $._initialized = version; $._initializing = true; _; $._initializing = false; emit Initialized(version); } /** * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the * {initializer} and {reinitializer} modifiers, directly or indirectly. */ modifier onlyInitializing() { _checkInitializing(); _; } /** * @dev Reverts if the contract is not in an initializing state. See {onlyInitializing}. */ function _checkInitializing() internal view virtual { if (!_isInitializing()) { revert NotInitializing(); } } /** * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call. * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized * to any version. It is recommended to use this to lock implementation contracts that are designed to be called * through proxies. * * Emits an {Initialized} event the first time it is successfully executed. */ function _disableInitializers() internal virtual { // solhint-disable-next-line var-name-mixedcase InitializableStorage storage $ = _getInitializableStorage(); if ($._initializing) { revert InvalidInitialization(); } if ($._initialized != type(uint64).max) { $._initialized = type(uint64).max; emit Initialized(type(uint64).max); } } /** * @dev Returns the highest version that has been initialized. See {reinitializer}. */ function _getInitializedVersion() internal view returns (uint64) { return _getInitializableStorage()._initialized; } /** * @dev Returns `true` if the contract is currently initializing. See {onlyInitializing}. */ function _isInitializing() internal view returns (bool) { return _getInitializableStorage()._initializing; } /** * @dev Returns a pointer to the storage namespace. */ // solhint-disable-next-line var-name-mixedcase function _getInitializableStorage() private pure returns (InitializableStorage storage $) { assembly { $.slot := INITIALIZABLE_STORAGE } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/ERC20.sol) pragma solidity ^0.8.20; import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import {IERC20Metadata} from "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol"; import {ContextUpgradeable} from "../../utils/ContextUpgradeable.sol"; import {IERC20Errors} from "@openzeppelin/contracts/interfaces/draft-IERC6093.sol"; import {Initializable} from "../../proxy/utils/Initializable.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 ERC20 * applications. * * Additionally, an {Approval} event is emitted on calls to {transferFrom}. * This allows applications to reconstruct the allowance for all accounts just * by listening to said events. Other implementations of the EIP may not emit * these events, as it isn't required by the specification. */ abstract contract ERC20Upgradeable is Initializable, ContextUpgradeable, IERC20, IERC20Metadata, IERC20Errors { /// @custom:storage-location erc7201:openzeppelin.storage.ERC20 struct ERC20Storage { mapping(address account => uint256) _balances; mapping(address account => mapping(address spender => uint256)) _allowances; uint256 _totalSupply; string _name; string _symbol; } // keccak256(abi.encode(uint256(keccak256("openzeppelin.storage.ERC20")) - 1)) & ~bytes32(uint256(0xff)) bytes32 private constant ERC20StorageLocation = 0x52c63247e1f47db19d5ce0460030c497f067ca4cebf71ba98eeadabe20bace00; function _getERC20Storage() private pure returns (ERC20Storage storage $) { assembly { $.slot := ERC20StorageLocation } } /** * @dev Sets the values for {name} and {symbol}. * * All two of these values are immutable: they can only be set once during * construction. */ function __ERC20_init(string memory name_, string memory symbol_) internal onlyInitializing { __ERC20_init_unchained(name_, symbol_); } function __ERC20_init_unchained(string memory name_, string memory symbol_) internal onlyInitializing { ERC20Storage storage $ = _getERC20Storage(); $._name = name_; $._symbol = symbol_; } /** * @dev Returns the name of the token. */ function name() public view virtual returns (string memory) { ERC20Storage storage $ = _getERC20Storage(); return $._name; } /** * @dev Returns the symbol of the token, usually a shorter version of the * name. */ function symbol() public view virtual returns (string memory) { ERC20Storage storage $ = _getERC20Storage(); 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; } /** * @dev See {IERC20-totalSupply}. */ function totalSupply() public view virtual returns (uint256) { ERC20Storage storage $ = _getERC20Storage(); return $._totalSupply; } /** * @dev See {IERC20-balanceOf}. */ function balanceOf(address account) public view virtual returns (uint256) { ERC20Storage storage $ = _getERC20Storage(); 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; } /** * @dev See {IERC20-allowance}. */ function allowance(address owner, address spender) public view virtual returns (uint256) { ERC20Storage storage $ = _getERC20Storage(); 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}. * * Emits an {Approval} event indicating the updated allowance. This is not * required by the EIP. See the note at the beginning of {ERC20}. * * 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 { ERC20Storage storage $ = _getERC20Storage(); 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: * ``` * 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 { ERC20Storage storage $ = _getERC20Storage(); 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.0.1) (utils/Context.sol) pragma solidity ^0.8.20; import {Initializable} from "../proxy/utils/Initializable.sol"; /** * @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 ContextUpgradeable is Initializable { function __Context_init() internal onlyInitializing { } function __Context_init_unchained() internal onlyInitializing { } 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.0.0) (interfaces/draft-IERC6093.sol) pragma solidity ^0.8.20; /** * @dev Standard ERC20 Errors * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC20 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 ERC721 Errors * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC721 tokens. */ interface IERC721Errors { /** * @dev Indicates that an address can't be an owner. For example, `address(0)` is a forbidden owner in EIP-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 ERC1155 Errors * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC1155 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.0.0) (token/ERC20/extensions/IERC20Metadata.sol) pragma solidity ^0.8.20; import {IERC20} from "../IERC20.sol"; /** * @dev Interface for the optional metadata functions from the ERC20 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.0.0) (token/ERC20/IERC20.sol) pragma solidity ^0.8.20; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ 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); }
pragma solidity >=0.5.0; interface IUniswapV2Factory { event PairCreated(address indexed token0, address indexed token1, address pair, uint); function feeTo() external view returns (address); function feeToSetter() external view returns (address); function getPair(address tokenA, address tokenB) external view returns (address pair); function allPairs(uint) external view returns (address pair); function allPairsLength() external view returns (uint); function createPair(address tokenA, address tokenB) external returns (address pair); function setFeeTo(address) external; function setFeeToSetter(address) external; }
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 swapExactTokensForTokens( uint amountIn, uint amountOutMin, address[] calldata path, address to, uint deadline ) external returns (uint[] memory amounts); function swapTokensForExactTokens( uint amountOut, uint amountInMax, address[] calldata path, address to, uint deadline ) external returns (uint[] memory amounts); function swapExactETHForTokens(uint amountOutMin, address[] calldata path, address to, uint deadline) external payable returns (uint[] memory amounts); function swapTokensForExactETH(uint amountOut, uint amountInMax, address[] calldata path, address to, uint deadline) external returns (uint[] memory amounts); function swapExactTokensForETH(uint amountIn, uint amountOutMin, address[] calldata path, address to, uint deadline) external returns (uint[] memory amounts); function swapETHForExactTokens(uint amountOut, address[] calldata path, address to, uint deadline) external payable returns (uint[] memory amounts); function quote(uint amountA, uint reserveA, uint reserveB) external pure returns (uint amountB); function getAmountOut(uint amountIn, uint reserveIn, uint reserveOut) external pure returns (uint amountOut); function getAmountIn(uint amountOut, uint reserveIn, uint reserveOut) external pure returns (uint amountIn); function getAmountsOut(uint amountIn, address[] calldata path) external view returns (uint[] memory amounts); function getAmountsIn(uint amountOut, address[] calldata path) external view returns (uint[] memory amounts); }
pragma solidity >=0.6.2; import './IUniswapV2Router01.sol'; interface IUniswapV2Router02 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, uint deadline ) external; function swapExactETHForTokensSupportingFeeOnTransferTokens( uint amountOutMin, address[] calldata path, address to, uint deadline ) external payable; function swapExactTokensForETHSupportingFeeOnTransferTokens( uint amountIn, uint amountOutMin, address[] calldata path, address to, uint deadline ) external; }
// SPDX-License-Identifier: None pragma solidity ^0.8.24; interface IDataStoreResponse { struct DataStoreAddressResponse { address locker; address payable proofWallet; address payable proofStaking; address proofPassNFT; address router; } struct DataStoreLimitsResponse { uint initMaxTx; uint swapTokensAtAmount; uint maxTxUpper; uint maxTxLower; uint maxWalletUpper; uint maxWalletLower; uint maxBuyFee; uint maxSellFee; uint denominator; } } interface IDataStore is IDataStoreResponse { function getAddresses(string[] memory addrKeys) external view returns (address[] memory); function getUints(string[] memory uintKeys) external view returns (uint256[] memory); function getPlatformAddresses() external view returns (DataStoreAddressResponse memory); function getLimits() external view returns (DataStoreLimitsResponse memory); }
// SPDX-License-Identifier: None pragma solidity ^0.8.24; interface IERC721A { function totalSupply() external returns (uint256); function ownerOf(uint256) external returns (address); }
// SPDX-License-Identifier: None pragma solidity ^0.8.24; interface ITeamFinanceLocker { function lockToken( address _tokenAddress, address _withdrawalAddress, uint256 _amount, uint256 _unlockTime, bool _mintNFT, address referrer ) external payable returns (uint256 _id); }
// SPDX-License-Identifier: None pragma solidity ^0.8.24; import "./IDataStore.sol"; interface ITokenWhitelist is IDataStoreResponse { struct TokenInfo { string name; string symbol; address owner; address mainWallet; address secondaryWallet; uint256 totalSupply; uint256 percentToLP; uint256 lpLockDuration; uint256 initMaxWallet; FeeInfo buyFees; FeeInfo sellFees; address[] whitelist; uint256 whitelistDuration; address rewardToken; } struct FeeInfo { uint256 main; uint256 secondary; uint256 liquidity; uint256 proof; uint256 total; } error ExceedsMaxTxAmount(); error ExceedsMaxWalletAmount(); error InvalidConfiguration(); error TradingNotEnabled(); error NotWhitelisted(); }
{ "optimizer": { "enabled": true, "runs": 200, "details": { "yul": true } }, "viaIR": true, "evmVersion": "paris", "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"contract IDataStore","name":"dataStore","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"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":"ExceedsMaxTxAmount","type":"error"},{"inputs":[],"name":"ExceedsMaxWalletAmount","type":"error"},{"inputs":[],"name":"InvalidConfiguration","type":"error"},{"inputs":[],"name":"InvalidInitialization","type":"error"},{"inputs":[],"name":"NotInitializing","type":"error"},{"inputs":[],"name":"NotWhitelisted","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":"TradingNotEnabled","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":"uint64","name":"version","type":"uint64"}],"name":"Initialized","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"tokensAutoLiq","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"ethAutoLiq","type":"uint256"}],"name":"SwapAndLiquify","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bool","name":"enabled","type":"bool"}],"name":"SwapAndLiquifyEnabledUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"returnedETH","type":"uint256"}],"name":"TokenCancelled","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":"DATA_STORE","outputs":[{"internalType":"contract IDataStore","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"addresses","outputs":[{"internalType":"address","name":"locker","type":"address"},{"internalType":"address payable","name":"proofWallet","type":"address"},{"internalType":"address payable","name":"proofStaking","type":"address"},{"internalType":"address","name":"proofPassNFT","type":"address"},{"internalType":"address","name":"router","type":"address"}],"stateMutability":"view","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":"buyFees","outputs":[{"internalType":"uint256","name":"main","type":"uint256"},{"internalType":"uint256","name":"secondary","type":"uint256"},{"internalType":"uint256","name":"liquidity","type":"uint256"},{"internalType":"uint256","name":"proof","type":"uint256"},{"internalType":"uint256","name":"total","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"buyTaxesSettled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"cancel","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"cancelled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"liquidityBuy","type":"uint256"},{"internalType":"uint256","name":"mainBuy","type":"uint256"},{"internalType":"uint256","name":"secondaryBuy","type":"uint256"},{"internalType":"uint256","name":"liquiditySell","type":"uint256"},{"internalType":"uint256","name":"mainSell","type":"uint256"},{"internalType":"uint256","name":"secondarySell","type":"uint256"}],"name":"changeFees","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"checkMaxHoldings","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"feeTokens","outputs":[{"internalType":"uint256","name":"main","type":"uint256"},{"internalType":"uint256","name":"secondary","type":"uint256"},{"internalType":"uint256","name":"liquidity","type":"uint256"},{"internalType":"uint256","name":"proof","type":"uint256"},{"internalType":"uint256","name":"total","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getCirculatingSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"initMaxWallet","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"params","type":"bytes"}],"name":"initialize","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"isWhitelistActive","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"bundleBuyAmount","type":"uint256"}],"name":"launch","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"launchedAt","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"limits","outputs":[{"internalType":"uint256","name":"initMaxTx","type":"uint256"},{"internalType":"uint256","name":"swapTokensAtAmount","type":"uint256"},{"internalType":"uint256","name":"maxTxUpper","type":"uint256"},{"internalType":"uint256","name":"maxTxLower","type":"uint256"},{"internalType":"uint256","name":"maxWalletUpper","type":"uint256"},{"internalType":"uint256","name":"maxWalletLower","type":"uint256"},{"internalType":"uint256","name":"maxBuyFee","type":"uint256"},{"internalType":"uint256","name":"maxSellFee","type":"uint256"},{"internalType":"uint256","name":"denominator","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lockID","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lpLockDuration","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"mainWallet","outputs":[{"internalType":"address payable","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxSwapsPerBlock","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxTxAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxWallet","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxWalletChanged","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pair","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"proofFeeReduced","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"proofFeeRemoved","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"proofPassNFT","outputs":[{"internalType":"contract IERC721A","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"restingBuyTotal","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"restingSellTotal","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"secondaryWallet","outputs":[{"internalType":"address payable","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"sellFees","outputs":[{"internalType":"uint256","name":"main","type":"uint256"},{"internalType":"uint256","name":"secondary","type":"uint256"},{"internalType":"uint256","name":"liquidity","type":"uint256"},{"internalType":"uint256","name":"proof","type":"uint256"},{"internalType":"uint256","name":"total","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"sellTaxesSettled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"_enabled","type":"bool"}],"name":"setCheckMaxHoldingsEnabled","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"bool","name":"value","type":"bool"}],"name":"setFeeExempt","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"accounts","type":"address[]"}],"name":"setFeeExempt","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newWallet","type":"address"}],"name":"setMainWallet","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_maxSwaps","type":"uint256"}],"name":"setMaxSwapsPerBlock","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newWallet","type":"address"}],"name":"setSecondaryWallet","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_enabled","type":"bool"}],"name":"setSwapAndLiquifyEnabled","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"setSwapAtAmount","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"swapEnabled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"swapThrottle","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"swapTokensAtAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"swapping","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":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"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":"uniswapV2Router","outputs":[{"internalType":"contract IUniswapV2Router02","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"userInfo","outputs":[{"internalType":"bool","name":"isFeeExempt","type":"bool"},{"internalType":"bool","name":"isTxLimitExempt","type":"bool"},{"internalType":"bool","name":"isWhitelisted","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"version","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"whitelistDuration","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"whitelistEndTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"withdrawStuckTokens","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]
Contract Creation Code
60a03462000121576001600160401b0390601f62003d6038819003918201601f19168301918483118484101762000126578084926020946040528339810103126200012157516001600160a01b03811681036200012157600160ff19600b541617600b556080527ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a009081549060ff8260401c166200010f578080831603620000c9575b604051613c2390816200013d8239608051818181610a38015281816118140152611a230152f35b6001600160401b031990911681179091556040519081527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d290602090a1388080620000a2565b60405163f92ee8a960e01b8152600490fd5b600080fd5b634e487b7160e01b600052604160045260246000fdfe608080604052600436101561001d575b50361561001b57600080fd5b005b60003560e01c90816306fdde031461266057508063095ea7b3146125df5780631694505e146125b65780631732cded1461259857806318160ddd1461256d5780631959a0021461251457806323b62b75146124eb57806323b872dd146124385780632b112e49146123e75780632ffe729a146123c9578063313ce567146123ad57806332a8db871461238f578063439fab91146114b65780634a829e79146114905780634b78286a1461144d578063524513d614611427578063530275011461140557806354fd4d50146113e95780636402511e146113c85780636ddd1713146113a557806370a082311461135e578063715018a6146112f45780638183b3c8146112a9578063838420131461128457806383ebc78d1461126657806385b12c7c14610dee578063860aefcf14610d8a57806388cda87314610d65578063893fea8b14610d3c5780638c0b5e2214610d1e5780638da5cb5b14610ce85780638ebfc79614610c9157806395d89b4114610bb35780639679266914610b955780639a82a09a14610b715780639ff77da414610b45578063a8aa1b3114610b1c578063a9059cbb14610aeb578063bb44f3ac14610aca578063bee0d6ad14610a85578063bf56b37114610a67578063c1d07cc214610a22578063c275c231146109ec578063c49b9a801461098e578063caee54401461096b578063cb29813c1461087e578063d0a5eb4e1461083b578063da0321cd146107ea578063dd62ed3e146107a1578063de35eb2414610783578063e0f3ccf51461073e578063e2f4560514610720578063e4748b9e146106d7578063ea8a1af014610443578063ebdfd72214610425578063ec3a1d4b14610407578063f2fde38b146103de578063f66a79a0146103b5578063f8b45b0514610397578063f8f989281461031c578063f9546621146102fe5763f9f4bfdd146102d4573861000f565b346102f95760003660031901126102f957602060ff815460081c166040519015158152f35b600080fd5b346102f95760003660031901126102f9576020602154604051908152f35b346102f9576020806003193601126102f9576004356001600160401b0381116102f95761034d903690600401612840565b610355612e1e565b80519060005b82811061036457005b6001906001600160a01b036103798285612a1e565b51166000526023855260406000208260ff198254161790550161035b565b346102f95760003660031901126102f9576020600954604051908152f35b346102f95760003660031901126102f9576003546040516001600160a01b039091168152602090f35b346102f95760203660031901126102f95761001b6103fa61274a565b610402612e1e565b612ae2565b346102f95760003660031901126102f9576020600654604051908152f35b346102f95760003660031901126102f9576020600554604051908152f35b346102f95760003660031901126102f95761045c612e1e565b6002600c556007546106c5576001546000546040516370a0823160e01b80825230600483015260209390926001600160a01b0392918316919083168582602481865afa908115610627578692600092610692575b5060405163095ea7b360e01b81526001600160a01b039091166004820152602481019190915291829081600081604481015b03925af1801561062757610665575b5082816000541691600154169260246040518095819382523060048301525afa8015610627578392600091610633575b5060405163af2979eb60e01b81523060048201526024810191909152600060448201819052606482018190523360848301524260a4830152909291839160c4918391905af180156106275782906000906105da575b7fcb4776c88e89a1336e8703163e15bfe474d287d489b9ea0fbc19157d673036bc9250604051908152a1805464ff00000000191664010000000017905547806105c1575b6001600c55005b600080808093335af1506105d3612ab2565b50806105ba565b5081813d8311610620575b6105ef8183612808565b810103126102f957817fcb4776c88e89a1336e8703163e15bfe474d287d489b9ea0fbc19157d673036bc9151610576565b503d6105e5565b6040513d6000823e3d90fd5b83819492503d831161065e575b61064a8183612808565b810103126102f95790518291906000610521565b503d610640565b61068490843d861161068b575b61067c8183612808565b810190612a6f565b50836104f1565b503d610672565b8381949293503d83116106be575b6106aa8183612808565b810103126102f957905185916104e26104b0565b503d6106a0565b60405163c52a9bd360e01b8152600490fd5b346102f95760003660031901126102f957601454601554601654601754601854604080519586526020860194909452928401919091526060830152608082015260a090f35b0390f35b346102f95760003660031901126102f9576020600e54604051908152f35b346102f95760003660031901126102f957601954601a54601b54601c54601d54604080519586526020860194909452928401919091526060830152608082015260a090f35b346102f95760003660031901126102f9576020602254604051908152f35b346102f95760403660031901126102f9576107ba61274a565b6107cb6107c5612760565b9161278a565b9060018060a01b03166000526020526020604060002054604051908152f35b346102f95760003660031901126102f95760a0600180821b038060265416908060275416908060285416816029541691602a5416926040519485526020850152604084015260608301526080820152f35b346102f95760203660031901126102f95761085461274a565b61085c612e1e565b600280546001600160a01b0319166001600160a01b0392909216919091179055005b346102f95760c03660031901126102f957610897612e1e565b60205460ff81161590811561095c575b506106c55760806108b6612a87565b604081019060043582526024358152602081019060443582526108d7612a87565b9284604085019260643584526084358652602086019260a4358452600754151560001461095157610906612e57565b919091965b606084019260608a0198895283526109238985612bac565b83516014555160155551601655516017550151601855835160195551601a5551601b5551601c550151601d55005b60029060029661090b565b60ff915060081c1615816108a7565b346102f95760003660031901126102f957602060ff600b54166040519015158152f35b346102f95760203660031901126102f9577f53726dfcaf90650aa7eb35524f4d3220f07413c8d6cb404cc8c18bf5591bc15960206109ca6127c3565b6109d2612e1e565b151560ff19600d541660ff821617600d55604051908152a1005b346102f95760203660031901126102f957610a056127c3565b610a0d612e1e565b60ff8019600b54169115151617600b55600080f35b346102f95760003660031901126102f9576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b346102f95760003660031901126102f9576020600754604051908152f35b346102f95760003660031901126102f957600f54601054601154601254601354604080519586526020860194909452928401919091526060830152608082015260a090f35b346102f95760203660031901126102f957610ae3612e1e565b600435602555005b346102f95760403660031901126102f957610b11610b0761274a565b6024359033612b56565b602060405160018152f35b346102f95760003660031901126102f9576001546040516001600160a01b039091168152602090f35b346102f95760203660031901126102f95760043560005260246020526020604060002054604051908152f35b346102f95760003660031901126102f957602060ff8154821c166040519015158152f35b346102f95760003660031901126102f9576020602554604051908152f35b346102f95760003660031901126102f9576040516000600080516020613b4e833981519152805490610be4826128a8565b80855291602091600191828116908115610c645750600114610c1d575b61071c86610c1181880382612808565b60405191829182612701565b60009081529350600080516020613bae8339815191525b838510610c5157505050508101602001610c118261071c85610c01565b8054868601840152938201938101610c34565b905086955061071c96935060209250610c1194915060ff191682840152151560051b820101929385610c01565b346102f95760403660031901126102f957610caa61274a565b60243580151581036102f95761001b91610cc2612e1e565b60018060a01b0316600052602360205260406000209060ff801983541691151516179055565b346102f95760003660031901126102f957600080516020613b6e833981519152546040516001600160a01b039091168152602090f35b346102f95760003660031901126102f9576020600854604051908152f35b346102f95760003660031901126102f9576004546040516001600160a01b039091168152602090f35b346102f95760003660031901126102f957602060ff815460101c166040519015158152f35b346102f95760003660031901126102f957610120602b54602c54602d54602e54602f5460305490603154926032549460335496604051988952602089015260408801526060870152608086015260a085015260c084015260e0830152610100820152f35b6020806003193601126102f957600435610e06612e1e565b6002600c5560075415801590611259575b6106c5576001908160ff198181600b541617600b55600d541617600d55610e40600654426129de565b6005556004805460ff60a01b1916600160a01b17905542600755806110e0575b509060018060a01b0360008282600454166004604051809481936318160ddd60e01b83525af1908115610627576000916110b3575b5083810180911161109d57835b81811061100a575050808354166040516370a0823160e01b81523060048201528381602481855afa908115610627578490600092610fd9575b5060265460405163095ea7b360e01b81529085166001600160a01b031660048201526024810183905292839081600081604481015b03925af1918215610627578492610fbc575b5060c4836026541693479087541690610f3d602254426129de565b956040519687958694635af06fed60e01b865260048601523360248601526044850152606484015260006084840152600060a48401525af191821561062757600092610f8e575b5050602155600c55005b90809250813d8311610fb5575b610fa58183612808565b810103126102f957518280610f84565b503d610f9b565b610fd290833d851161068b5761067c8183612808565b5085610f22565b80939250813d8311611003575b610ff08183612808565b810103126102f957905183610f10610edb565b503d610fe6565b6000908484600454166024604051809581936331a9108f60e11b83528660048401525af19182156106275786928591600091611064575b50166000526023855260406000206201000062ff00001982541617905501610ea2565b935050508482813d8311611096575b61107d8183612808565b810103126102f957836110908793612997565b88611041565b503d611073565b634e487b7160e01b600052601160045260246000fd5b90508281813d83116110d9575b6110ca8183612808565b810103126102f9575184610e95565b503d6110c0565b6040516110ec816127ed565b60028152604036858301376000546040516315ab88c960e31b81526001600160a01b03918216918682600481865afa91821561062757600092611218575b5092611176929160009461113d836129eb565b911690523061114b82612a0e565b52604051948580948193637ff36ab560e01b8352876004840152608060248401526084830190612a32565b33604483015242606483015203925af180156106275715610e60573d806000833e6111a18183612808565b81019083818303126102f9578051906001600160401b0382116102f9570181601f820112156102f95780519084806111d884612829565b6111e56040519182612808565b848152019260051b8201019283116102f9578401905b828210611209575050610e60565b815181529084019084016111fb565b929150928683813d8311611252575b6112318183612808565b810103126102f95760009361124861117694612997565b929350909361112a565b503d611227565b5060ff8254831c16610e17565b346102f95760003660031901126102f9576020601e54604051908152f35b346102f95760003660031901126102f957602060ff815460181c166040519015158152f35b346102f95760003660031901126102f9576112c2612e1e565b30600052600080516020613b2e83398151915260205261001b6112ed604060002054601354906128e2565b3330612ceb565b346102f95760003660031901126102f95761130d612e1e565b600080516020613b6e83398151915280546001600160a01b031981169091556000906001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08280a3005b346102f95760203660031901126102f9576001600160a01b0361137f61274a565b16600052600080516020613b2e8339815191526020526020604060002054604051908152f35b346102f95760003660031901126102f957602060ff600d54166040519015158152f35b346102f95760203660031901126102f9576113e1612e1e565b600435600e55005b346102f95760003660031901126102f957602060405160038152f35b346102f95760003660031901126102f957602060ff8154166040519015158152f35b346102f95760003660031901126102f957602060ff60045460a01c166040519015158152f35b346102f95760203660031901126102f95761146661274a565b61146e612e1e565b600380546001600160a01b0319166001600160a01b0392909216919091179055005b346102f95760003660031901126102f957602060ff600b5460081c166040519015158152f35b60203660031901126102f9576004356001600160401b0381116102f957366023820112156102f95780600401356001600160401b0381116102f957810160248101913683116102f957600080516020613bce83398151915254926001600160401b0384168015908161237f575b6001149081612375575b15908161236c575b5061235a5760016001600160401b0319851617600080516020613bce8339815191525560ff8460401c161561232d575b6002600c556020828403126102f9576024820135926001600160401b0384116102f9576102c0908484019003126102f957604051926101c084018481106001600160401b03821117611efa57604052602481840101356001600160401b0381116102f9578260246115da92848701010161290a565b8452604481840101356001600160401b0381116102f95782602461160292848701010161290a565b6020850152611615606482850101612776565b6040850152611628608482850101612776565b606085015261163b60a482850101612776565b608085015282810160c481013560a086015260e481013560c086015261010481013560e086015261012481013561010086015261167d90839061014401612951565b610120850152611693826101e483860101612951565b6101408501526102848184010135926001600160401b0384116102f9576116c76102c49360246116e0968585010101612840565b610160860152016102a481013561018085015201612776565b6101a08201528051916020820151916116f76139f6565b6116ff6139f6565b83516001600160401b038111611efa57611727600080516020613b0e833981519152546128a8565b601f81116122b7575b506020601f821160011461222857819293949560009261221d575b50508160011b916000199060031b1c191617600080516020613b0e833981519152555b82516001600160401b038111611efa57611796600080516020613b4e833981519152546128a8565b601f81116121a7575b506020601f8211600114612119578192939460009261210e575b50508160011b916000199060031b1c191617600080516020613b4e833981519152555b60408101516117fe906001600160a01b03166117f66139f6565b6104026139f6565b604051636f89e40960e01b8152610120816004817f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03165afa9081156106275760009161205e575b508051602b556020810151602c556040810151602d556060810151602e556080810151602f5560a081015160305560c081015160315560e081015160325561010081015160335560026060610120840151018160606101408601510152526118c061012083015161014084015190612bac565b60606101208301516080810151601e5560806101408501510151601f550151600f03600f811161109d576119016119119160206101208601510151906128e2565b60406101208501510151906128e2565b61012083015152600f60806101208401510152606061014083015101516014036014811161109d576119506119609160206101408601510151906128e2565b60406101408501510151906128e2565b61014083015152601460806101408401510152608061012083015180516014556020810151601555604081015160165560608101516017550151601855608061014083015180516019556020810151601a556040810151601b556060810151601c550151601d5560018060a01b036060830151166001600160601b0360a01b600254161760025560018060a01b036080830151166001600160601b0360a01b60035416176003556040519063cca3e97f60e01b825260a082600481600180851b037f0000000000000000000000000000000000000000000000000000000000000000165afa91821561062757600092611fd0575b508151602680546001600160a01b03199081166001600160a01b039384161790915560208085015160278054841691851691909117905560408086015160288054851691861691909117905560608601516029805485169186169182179055608090960151602a80548516919095169081179094556004805484169096178655600080549093168417909255905163c45a015560e01b815293849081845afa92831561062757600093611f8f575b506020600491604051928380926315ab88c960e31b82525afa90811561062757600091611f4b575b506040516364e329cb60e11b81523060048201526001600160a01b0391821660248201529260209184916044918391600091165af1801561062757600090611f10575b611bd6925060018060a01b03166001600160601b0360a01b600154161760015560e0830151602255611bb7611bab60a08501516020840151906129ab565b610100830151906129be565b600e55610100611bcd60a08501518351906129ab565b910151906129be565b600855620186a0611bf461010083015180600a5560a08401516129ab565b0460095560046025556040518060608101106001600160401b03606083011117611efa5760608101604052600181526020810160018152604082019060018252306000526023602052611c5b604060002093511515849060ff801983541691151516179055565b518254915162ffff001990921690151560081b61ff00161790151560101b62ff000016179055600180546001600160a01b0390811660009081526040808220805461ff00191661010017905592549091168152908120805462ff00001916620100001790556101808201516006556101608201518051915b828110611ec157505050611d2c6064611cf560a084015160c0850151906129ab565b0491611d018330612c61565b611d268360a0600180821b03600080516020613b6e83398151915254169301516128e2565b90612c61565b6000546001600160a01b03163015611ea8578015611e8f57611de791606091611d543061278a565b81600052602052600019806040600020556040519081527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560203092a36000805460405163f305d71960e01b81523060048201819052602482019490945260448101839052606481019290925260848201929092524260a48201529283916001600160a01b0316908290819060c4820190565b039134905af1801561062757611e64575b506001600c5560401c60ff1615611e0b57005b68ff000000000000000019600080516020613bce8339815191525416600080516020613bce833981519152557fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d2602060405160018152a1005b606090813d8311611e88575b611e7a8183612808565b810103126102f95781611df8565b503d611e70565b604051634a1406b160e11b815260006004820152602490fd5b60405163e602df0560e01b815260006004820152602490fd5b6001906001600160a01b03611ed68285612a1e565b5116600052602360205260406000206201000062ff00001982541617905501611cd3565b634e487b7160e01b600052604160045260246000fd5b506020823d602011611f43575b81611f2a60209383612808565b810103126102f957611f3e611bd692612997565b611b6d565b3d9150611f1d565b90506020813d602011611f87575b81611f6660209383612808565b810103126102f9576000926044611f7e602093612997565b92505092611b2a565b3d9150611f59565b9092506020813d602011611fc8575b81611fab60209383612808565b810103126102f9576020611fc0600492612997565b939150611b02565b3d9150611f9e565b90915060a0813d60a011612056575b81611fec60a09383612808565b810103126102f95761204a608060405192612006846127d2565b61200f81612997565b845261201d60208201612997565b602085015261202e60408201612997565b604085015261203f60608201612997565b606085015201612997565b60808201529084611a54565b3d9150611fdf565b9050610120813d61012011612106575b8161207c6101209383612808565b810103126102f95760405190816101208101106001600160401b0361012084011117611efa57610100906101208301604052805183526020810151602084015260408101516040840152606081015160608401526080810151608084015260a081015160a084015260c081015160c084015260e081015160e084015201516101008201528361184d565b3d915061206e565b0151905084806117b9565b600080516020613b4e833981519152600052600080516020613bae8339815191529060005b601f198416811061218f5750600193949583601f19811610612176575b505050811b01600080516020613b4e833981519152556117dc565b015160001960f88460031b161c1916905584808061215b565b9091602060018192858a01518155019301910161213e565b600080516020613b4e833981519152600052601f820160051c600080516020613bae8339815191520160208310612208575b601f820160051c600080516020613bae8339815191520181106121fc575061179f565b600081556001016121d9565b50600080516020613bae8339815191526121d9565b01519050858061174b565b600080516020613b0e833981519152600052600080516020613aee8339815191529060005b601f198416811061229f575060019394959683601f19811610612286575b505050811b01600080516020613b0e8339815191525561176e565b015160001960f88460031b161c1916905585808061226b565b9091602060018192858b01518155019301910161224d565b600080516020613b0e833981519152600052601f820160051c600080516020613aee8339815191520160208310612318575b601f820160051c600080516020613aee83398151915201811061230c5750611730565b600081556001016122e9565b50600080516020613aee8339815191526122e9565b68ffffffffffffffffff1984166801000000000000000117600080516020613bce83398151915255611565565b60405163f92ee8a960e01b8152600490fd5b90501585611535565b303b15915061152d565b604086901c60ff16159150611523565b346102f95760003660031901126102f9576020601f54604051908152f35b346102f95760003660031901126102f957602060405160098152f35b346102f95760003660031901126102f9576020600a54604051908152f35b346102f95760003660031901126102f9576020612430600080516020613b8e8339815191525461dead600052600080516020613b2e8339815191528352604060002054906128e2565b604051908152f35b346102f95760603660031901126102f95761245161274a565b612459612760565b604435906124668361278a565b33600052602052604060002054926000198403612488575b610b119350612b56565b8284106124c5576001600160a01b03811615611ea8573315611e8f5782610b11946124b28361278a565b336000526020520360406000205561247e565b604051637dc7a0d960e11b81523360048201526024810185905260448101849052606490fd5b346102f95760003660031901126102f9576002546040516001600160a01b039091168152602090f35b346102f95760203660031901126102f9576001600160a01b0361253561274a565b166000526023602052606060406000205460ff6040519181811615158352818160081c161515602084015260101c1615156040820152f35b346102f95760003660031901126102f9576020600080516020613b8e83398151915254604051908152f35b346102f95760003660031901126102f9576020600c54604051908152f35b346102f95760003660031901126102f9576000546040516001600160a01b039091168152602090f35b346102f95760403660031901126102f9576125f861274a565b602435903315611ea8576001600160a01b0316908115611e8f5761261b3361278a565b82600052602052806040600020556040519081527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560203392a3602060405160018152f35b346102f95760003660031901126102f9576000600080516020613b0e83398151915280549061268e826128a8565b80855291602091600191828116908115610c6457506001146126ba5761071c86610c1181880382612808565b60009081529350600080516020613aee8339815191525b8385106126ee57505050508101602001610c118261071c85610c01565b80548686018401529382019381016126d1565b6020808252825181830181905290939260005b82811061273657505060409293506000838284010152601f8019910116010190565b818101860151848201604001528501612714565b600435906001600160a01b03821682036102f957565b602435906001600160a01b03821682036102f957565b35906001600160a01b03821682036102f957565b6001600160a01b031660009081527f52c63247e1f47db19d5ce0460030c497f067ca4cebf71ba98eeadabe20bace016020526040902090565b6004359081151582036102f957565b60a081019081106001600160401b03821117611efa57604052565b606081019081106001600160401b03821117611efa57604052565b90601f801991011681019081106001600160401b03821117611efa57604052565b6001600160401b038111611efa5760051b60200190565b9080601f830112156102f957602090823561285a81612829565b936128686040519586612808565b81855260208086019260051b8201019283116102f957602001905b828210612891575050505090565b83809161289d84612776565b815201910190612883565b90600182811c921680156128d8575b60208310146128c257565b634e487b7160e01b600052602260045260246000fd5b91607f16916128b7565b9190820391821161109d57565b6001600160401b038111611efa57601f01601f191660200190565b81601f820112156102f957803590612921826128ef565b9261292f6040519485612808565b828452602083830101116102f957816000926020809301838601378301015290565b91908260a09103126102f957604051612969816127d2565b6080808294803584526020810135602085015260408101356040850152606081013560608501520135910152565b51906001600160a01b03821682036102f957565b8181029291811591840414171561109d57565b81156129c8570490565b634e487b7160e01b600052601260045260246000fd5b9190820180921161109d57565b8051156129f85760200190565b634e487b7160e01b600052603260045260246000fd5b8051600110156129f85760400190565b80518210156129f85760209160051b010190565b90815180825260208080930193019160005b828110612a52575050505090565b83516001600160a01b031685529381019392810192600101612a44565b908160209103126102f9575180151581036102f95790565b60405190612a94826127d2565b60006080838281528260208201528260408201528260608201520152565b3d15612add573d90612ac3826128ef565b91612ad16040519384612808565b82523d6000602084013e565b606090565b6001600160a01b03908116908115612b3d57600080516020613b6e83398151915280546001600160a01b031981168417909155167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0600080a3565b604051631e4fbdf760e01b815260006004820152602490fd5b91906001600160a01b0380841615612b9357811615612b7a57612b7892612eb5565b565b60405163ec442f0560e01b815260006004820152602490fd5b604051634b637e8f60e11b815260006004820152602490fd5b612bca612bbf60408301518351906129de565b6020830151906129de565b60808201818152919080612c4c5750606060009101525b612bff612bf460408401518451906129de565b6020840151906129de565b60808301818152929080612c375750606060009101525b5160315410908115612c2a575b506106c557565b9050516032541038612c23565b6060612c45920151906129de565b8252612c16565b6060612c5a920151906129de565b8152612be1565b907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef6020600092600080516020613b8e83398151915294612ca38287546129de565b86556001600160a01b03169485158514612cc7578181540390555b604051908152a3565b50848452600080516020613b2e833981519152825260408420818154019055612cbe565b6001600160a01b0380821692909183612d8b57507fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91602091600080516020613b8e833981519152612d3e8782546129de565b90555b169384612d6657600080516020613b8e833981519152818154039055604051908152a3565b84600052600080516020613b2e83398151915282526040600020818154019055612cbe565b83600052600080516020613b2e8339815191528060205260406000205491868310612deb575091857fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef949260209487600052855203604060002055612d41565b60405163391434e360e21b81526001600160a01b0391909116600482015260248101929092525060448101859052606490fd5b600080516020613b6e833981519152546001600160a01b03163303612e3f57565b60405163118cdaa760e01b8152336004820152602490fd5b612e63600754426128e2565b6228de80811115612e8a5750630100000063ff000000196020541617602055600090600090565b620151801015612ead576201000062ff0000196020541617602055600190600190565b600290600290565b929190600c549360026000951480156139d2575b80156139ae575b801561399c575b801561398a575b8015613982575b612f745760075415613970576001600160a01b038181168652602360205260408087209184168752862060045490919060a081901c60ff1661391a575b50600b5460ff8160081c161561389a575b5060ff600b541661383d575b60135490600e5482101580613831575b80613819575b80613802575b613337575b60ff9150541615908161332a575b50612f7f575b612b78939450612ceb565b60205460189060ff81831c1615613073575b506001549495612b7895909185916001600160a01b03908116908616810361301b575050612ff09150604051612fc6816127d2565b6019548152601a546020820152601b546040820152601c546060820152601d546080820152613a25565b80612fff575b50849350612f74565b9261300d84613015926128e2565b933083612ceb565b38612ff6565b6001600160a01b03851614613032575b5050612ff0565b61306c925060405190613044826127d2565b6014548252601554602083015260165460408301526017546060830152546080820152613a25565b833861302b565b61307f600754426128e2565b9060ff8160101c16158061331e575b1561313c5750506130a38154601754906128e2565b61312157858155856017555b6130be601d54601c54906128e2565b6130eb578386612b789697601d5580601c555b6201000062ff00001960205416176020555b969550612f91565b6019546001810180911161310d57612b78959685916019556001601c556130d1565b634e487b7160e01b87526011600452602487fd5b6014546001810180911161310d5760145560016017556130af565b6228de8082111561319157505083612b78959661315d6017546014546129de565b60145561316e601c546019546129de565b6019558060175580601c55630100000063ff0000001960205416176020556130e3565b60ff1615613276575b60ff60205460081c16156131b5575b5083612b7895966130e3565b601f548091610961811061324c575b509596612b789686929081811161321a57506131f66131ed826131ff93601d55601b54906128e2565b601a54906128e2565b601c54906128e2565b60195561010061ff001960205416176020555b9695506131a9565b9050601d54810361322c575b50613212565b6131f66131ed8261324393601d55601b54906128e2565b60195538613226565b60789150046014036014811161326257856131c4565b634e487b7160e01b88526011600452602488fd5b601e548061070983106132f9575b8181116132c957506132ab6132a2826132b4938655601654906128e2565b601554906128e2565b601754906128e2565b601455600160ff19602054161760205561319a565b9050825481036132da575b5061319a565b6132ab6132a2826132f0938655601654906128e2565b601455386132d4565b5060788204600f03600f81111561328457634e487b7160e01b89526011600452602489fd5b5062015180821161308e565b60ff915054161538612f6e565b438852602460205260408820805460001981146137ee576001019055600e54916002600c556133b5613367612a87565b9161337d81613378600f54886129ab565b6129be565b835261338f81613378601054886129ab565b60208401526133a481613378601154886129ab565b6040840152613378601254866129ab565b60608201526133cc604082015160011c80946128e2565b80608083015247908a6040516133e1816127ed565b600281526040366020830137306133f7826129eb565b5281546040516315ab88c960e31b81526001600160a01b0390911690602081600481855afa9081156137e35784916137a5575b5061343483612a0e565b6001600160a01b039091169052803b156137a15761347c938360405180968195829463791ac94760e01b8452600484015283602484015260a0604484015260a4830190612a32565b30606483015242608483015203925af1801561379657613765575b506134a290476128e2565b928961350c6135016134b2612a87565b96836134cd6134c28851846129ab565b6080890151906129be565b808a528061373f575b506134e86134c26020890151846129ab565b8060208b015280613719575b50506060860151906129ab565b6080850151906129be565b60608601818152816136ca575b50505089934790816040820152821515806136c1575b6135d6575b5050816135bc61355b6135c19361355560ff9860406135c9980151926128e2565b906128e2565b916135698151600f546128e2565b600f5561357c60208201516010546128e2565b60105561358b836011546128e2565b60115561359e60608201516012546128e2565b60125560606135b382516020840151906129de565b910151906129de565b6129de565b6013546128e2565b6013556001600c55612f60565b909450606060018060a01b036000541660c46040518098819363f305d71960e01b8352306004840152876024840152600060448401526000606484015261dead60848401524260a48401525af194851561062757600095613689575b50916135bc61355b6135c1936135556135c9967f28fc98272ce761178794ad6768050fea1648e07f1e2ffe15afd3a290f838148660408060ff9c9301518151908682526020820152a1985050935050819350613534565b9450916060853d6060116136b9575b816136a560609383612808565b810103126102f957935193916135bc613632565b3d9150613698565b5081151561352f565b82809291613704829360011c838080808460018060a01b03602854165af1506136f1612ab2565b5060018060a01b036027541692516128e2565b905af150613710612ab2565b50893880613519565b600354829182918291906001600160a01b03165af150613737612ab2565b5083386134f4565b600254829182918291906001600160a01b03165af15061375d612ab2565b5083386134d6565b6001600160401b03819b929b1161378257604052986134a2613497565b634e487b7160e01b82526041600452602482fd5b6040513d8d823e3d90fd5b8280fd5b90506020813d6020116137db575b816137c060209383612808565b810103126137d7576137d190612997565b3861342a565b8380fd5b3d91506137b3565b6040513d86823e3d90fd5b634e487b7160e01b8a52601160045260248afd5b504388526024602052604088205460255411612f5b565b506001546001600160a01b0385811691161415612f55565b5060ff600d5416612f4f565b60ff825460081c161580613863575b15612f3f5760405163fd42866160e01b8152600490fd5b506001600160a01b0384168752600080516020613b2e833981519152602052604087205461389190866129de565b6009541061384c565b6138a6600754426128e2565b6078600a54910460648181020481036137ee57916138cf6138f092620186a094606402906129de565b906103b68211613904575b50600080516020613b8e833981519152546129ab565b04600954810315612f335760095538612f33565b61ff00191661010017600b55506103e8386138da565b600554421015613961575060ff815460101c16158015613952575b613940575b38612f22565b604051630b094f2760e31b8152600490fd5b5060ff825460101c1615613935565b60ff60a01b191660045561393a565b6040516312f1f92360e01b8152600490fd5b508215612ee5565b506001600160a01b0382163014612ede565b506001600160a01b0381163014612ed7565b50600080516020613b6e833981519152546001600160a01b03838116911614612ed0565b50600080516020613b6e833981519152546001600160a01b03828116911614612ec9565b60ff600080516020613bce8339815191525460401c1615613a1357565b604051631afcd79f60e31b8152600490fd5b6080810180516000949381613a3b575b50505050565b613ad293955060606064613a56613aca9594613ac2946129ab565b0496613a79613a71613a6983518b6129ab565b8651906129be565b600f546129de565b600f55613a98613a90613a6960208401518b6129ab565b6010546129de565b601055613ab7613aaf613a6960408401518b6129ab565b6011546129de565b6011550151866129ab565b9051906129be565b6012546129de565b601255613ae1826013546129de565b60135538808080613a3556fe2ae08a8e29253f69ac5d979a101956ab8f8d9d7ded63fa7a83b16fc47648eab052c63247e1f47db19d5ce0460030c497f067ca4cebf71ba98eeadabe20bace0352c63247e1f47db19d5ce0460030c497f067ca4cebf71ba98eeadabe20bace0052c63247e1f47db19d5ce0460030c497f067ca4cebf71ba98eeadabe20bace049016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c19930052c63247e1f47db19d5ce0460030c497f067ca4cebf71ba98eeadabe20bace0246a2803e59a4de4e7a4c574b1243f25977ac4c77d5a1a4a609b5394cebb4a2aaf0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00a264697066735822122065b92cda523c2335ba474f725eb3f93bea2600b8fc9f01605fee5de9549f7fa464736f6c634300081800330000000000000000000000008a85eb1fff988a1b01136279174c969d681a0151
Deployed Bytecode
0x608080604052600436101561001d575b50361561001b57600080fd5b005b60003560e01c90816306fdde031461266057508063095ea7b3146125df5780631694505e146125b65780631732cded1461259857806318160ddd1461256d5780631959a0021461251457806323b62b75146124eb57806323b872dd146124385780632b112e49146123e75780632ffe729a146123c9578063313ce567146123ad57806332a8db871461238f578063439fab91146114b65780634a829e79146114905780634b78286a1461144d578063524513d614611427578063530275011461140557806354fd4d50146113e95780636402511e146113c85780636ddd1713146113a557806370a082311461135e578063715018a6146112f45780638183b3c8146112a9578063838420131461128457806383ebc78d1461126657806385b12c7c14610dee578063860aefcf14610d8a57806388cda87314610d65578063893fea8b14610d3c5780638c0b5e2214610d1e5780638da5cb5b14610ce85780638ebfc79614610c9157806395d89b4114610bb35780639679266914610b955780639a82a09a14610b715780639ff77da414610b45578063a8aa1b3114610b1c578063a9059cbb14610aeb578063bb44f3ac14610aca578063bee0d6ad14610a85578063bf56b37114610a67578063c1d07cc214610a22578063c275c231146109ec578063c49b9a801461098e578063caee54401461096b578063cb29813c1461087e578063d0a5eb4e1461083b578063da0321cd146107ea578063dd62ed3e146107a1578063de35eb2414610783578063e0f3ccf51461073e578063e2f4560514610720578063e4748b9e146106d7578063ea8a1af014610443578063ebdfd72214610425578063ec3a1d4b14610407578063f2fde38b146103de578063f66a79a0146103b5578063f8b45b0514610397578063f8f989281461031c578063f9546621146102fe5763f9f4bfdd146102d4573861000f565b346102f95760003660031901126102f957602060ff815460081c166040519015158152f35b600080fd5b346102f95760003660031901126102f9576020602154604051908152f35b346102f9576020806003193601126102f9576004356001600160401b0381116102f95761034d903690600401612840565b610355612e1e565b80519060005b82811061036457005b6001906001600160a01b036103798285612a1e565b51166000526023855260406000208260ff198254161790550161035b565b346102f95760003660031901126102f9576020600954604051908152f35b346102f95760003660031901126102f9576003546040516001600160a01b039091168152602090f35b346102f95760203660031901126102f95761001b6103fa61274a565b610402612e1e565b612ae2565b346102f95760003660031901126102f9576020600654604051908152f35b346102f95760003660031901126102f9576020600554604051908152f35b346102f95760003660031901126102f95761045c612e1e565b6002600c556007546106c5576001546000546040516370a0823160e01b80825230600483015260209390926001600160a01b0392918316919083168582602481865afa908115610627578692600092610692575b5060405163095ea7b360e01b81526001600160a01b039091166004820152602481019190915291829081600081604481015b03925af1801561062757610665575b5082816000541691600154169260246040518095819382523060048301525afa8015610627578392600091610633575b5060405163af2979eb60e01b81523060048201526024810191909152600060448201819052606482018190523360848301524260a4830152909291839160c4918391905af180156106275782906000906105da575b7fcb4776c88e89a1336e8703163e15bfe474d287d489b9ea0fbc19157d673036bc9250604051908152a1805464ff00000000191664010000000017905547806105c1575b6001600c55005b600080808093335af1506105d3612ab2565b50806105ba565b5081813d8311610620575b6105ef8183612808565b810103126102f957817fcb4776c88e89a1336e8703163e15bfe474d287d489b9ea0fbc19157d673036bc9151610576565b503d6105e5565b6040513d6000823e3d90fd5b83819492503d831161065e575b61064a8183612808565b810103126102f95790518291906000610521565b503d610640565b61068490843d861161068b575b61067c8183612808565b810190612a6f565b50836104f1565b503d610672565b8381949293503d83116106be575b6106aa8183612808565b810103126102f957905185916104e26104b0565b503d6106a0565b60405163c52a9bd360e01b8152600490fd5b346102f95760003660031901126102f957601454601554601654601754601854604080519586526020860194909452928401919091526060830152608082015260a090f35b0390f35b346102f95760003660031901126102f9576020600e54604051908152f35b346102f95760003660031901126102f957601954601a54601b54601c54601d54604080519586526020860194909452928401919091526060830152608082015260a090f35b346102f95760003660031901126102f9576020602254604051908152f35b346102f95760403660031901126102f9576107ba61274a565b6107cb6107c5612760565b9161278a565b9060018060a01b03166000526020526020604060002054604051908152f35b346102f95760003660031901126102f95760a0600180821b038060265416908060275416908060285416816029541691602a5416926040519485526020850152604084015260608301526080820152f35b346102f95760203660031901126102f95761085461274a565b61085c612e1e565b600280546001600160a01b0319166001600160a01b0392909216919091179055005b346102f95760c03660031901126102f957610897612e1e565b60205460ff81161590811561095c575b506106c55760806108b6612a87565b604081019060043582526024358152602081019060443582526108d7612a87565b9284604085019260643584526084358652602086019260a4358452600754151560001461095157610906612e57565b919091965b606084019260608a0198895283526109238985612bac565b83516014555160155551601655516017550151601855835160195551601a5551601b5551601c550151601d55005b60029060029661090b565b60ff915060081c1615816108a7565b346102f95760003660031901126102f957602060ff600b54166040519015158152f35b346102f95760203660031901126102f9577f53726dfcaf90650aa7eb35524f4d3220f07413c8d6cb404cc8c18bf5591bc15960206109ca6127c3565b6109d2612e1e565b151560ff19600d541660ff821617600d55604051908152a1005b346102f95760203660031901126102f957610a056127c3565b610a0d612e1e565b60ff8019600b54169115151617600b55600080f35b346102f95760003660031901126102f9576040517f0000000000000000000000008a85eb1fff988a1b01136279174c969d681a01516001600160a01b03168152602090f35b346102f95760003660031901126102f9576020600754604051908152f35b346102f95760003660031901126102f957600f54601054601154601254601354604080519586526020860194909452928401919091526060830152608082015260a090f35b346102f95760203660031901126102f957610ae3612e1e565b600435602555005b346102f95760403660031901126102f957610b11610b0761274a565b6024359033612b56565b602060405160018152f35b346102f95760003660031901126102f9576001546040516001600160a01b039091168152602090f35b346102f95760203660031901126102f95760043560005260246020526020604060002054604051908152f35b346102f95760003660031901126102f957602060ff8154821c166040519015158152f35b346102f95760003660031901126102f9576020602554604051908152f35b346102f95760003660031901126102f9576040516000600080516020613b4e833981519152805490610be4826128a8565b80855291602091600191828116908115610c645750600114610c1d575b61071c86610c1181880382612808565b60405191829182612701565b60009081529350600080516020613bae8339815191525b838510610c5157505050508101602001610c118261071c85610c01565b8054868601840152938201938101610c34565b905086955061071c96935060209250610c1194915060ff191682840152151560051b820101929385610c01565b346102f95760403660031901126102f957610caa61274a565b60243580151581036102f95761001b91610cc2612e1e565b60018060a01b0316600052602360205260406000209060ff801983541691151516179055565b346102f95760003660031901126102f957600080516020613b6e833981519152546040516001600160a01b039091168152602090f35b346102f95760003660031901126102f9576020600854604051908152f35b346102f95760003660031901126102f9576004546040516001600160a01b039091168152602090f35b346102f95760003660031901126102f957602060ff815460101c166040519015158152f35b346102f95760003660031901126102f957610120602b54602c54602d54602e54602f5460305490603154926032549460335496604051988952602089015260408801526060870152608086015260a085015260c084015260e0830152610100820152f35b6020806003193601126102f957600435610e06612e1e565b6002600c5560075415801590611259575b6106c5576001908160ff198181600b541617600b55600d541617600d55610e40600654426129de565b6005556004805460ff60a01b1916600160a01b17905542600755806110e0575b509060018060a01b0360008282600454166004604051809481936318160ddd60e01b83525af1908115610627576000916110b3575b5083810180911161109d57835b81811061100a575050808354166040516370a0823160e01b81523060048201528381602481855afa908115610627578490600092610fd9575b5060265460405163095ea7b360e01b81529085166001600160a01b031660048201526024810183905292839081600081604481015b03925af1918215610627578492610fbc575b5060c4836026541693479087541690610f3d602254426129de565b956040519687958694635af06fed60e01b865260048601523360248601526044850152606484015260006084840152600060a48401525af191821561062757600092610f8e575b5050602155600c55005b90809250813d8311610fb5575b610fa58183612808565b810103126102f957518280610f84565b503d610f9b565b610fd290833d851161068b5761067c8183612808565b5085610f22565b80939250813d8311611003575b610ff08183612808565b810103126102f957905183610f10610edb565b503d610fe6565b6000908484600454166024604051809581936331a9108f60e11b83528660048401525af19182156106275786928591600091611064575b50166000526023855260406000206201000062ff00001982541617905501610ea2565b935050508482813d8311611096575b61107d8183612808565b810103126102f957836110908793612997565b88611041565b503d611073565b634e487b7160e01b600052601160045260246000fd5b90508281813d83116110d9575b6110ca8183612808565b810103126102f9575184610e95565b503d6110c0565b6040516110ec816127ed565b60028152604036858301376000546040516315ab88c960e31b81526001600160a01b03918216918682600481865afa91821561062757600092611218575b5092611176929160009461113d836129eb565b911690523061114b82612a0e565b52604051948580948193637ff36ab560e01b8352876004840152608060248401526084830190612a32565b33604483015242606483015203925af180156106275715610e60573d806000833e6111a18183612808565b81019083818303126102f9578051906001600160401b0382116102f9570181601f820112156102f95780519084806111d884612829565b6111e56040519182612808565b848152019260051b8201019283116102f9578401905b828210611209575050610e60565b815181529084019084016111fb565b929150928683813d8311611252575b6112318183612808565b810103126102f95760009361124861117694612997565b929350909361112a565b503d611227565b5060ff8254831c16610e17565b346102f95760003660031901126102f9576020601e54604051908152f35b346102f95760003660031901126102f957602060ff815460181c166040519015158152f35b346102f95760003660031901126102f9576112c2612e1e565b30600052600080516020613b2e83398151915260205261001b6112ed604060002054601354906128e2565b3330612ceb565b346102f95760003660031901126102f95761130d612e1e565b600080516020613b6e83398151915280546001600160a01b031981169091556000906001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08280a3005b346102f95760203660031901126102f9576001600160a01b0361137f61274a565b16600052600080516020613b2e8339815191526020526020604060002054604051908152f35b346102f95760003660031901126102f957602060ff600d54166040519015158152f35b346102f95760203660031901126102f9576113e1612e1e565b600435600e55005b346102f95760003660031901126102f957602060405160038152f35b346102f95760003660031901126102f957602060ff8154166040519015158152f35b346102f95760003660031901126102f957602060ff60045460a01c166040519015158152f35b346102f95760203660031901126102f95761146661274a565b61146e612e1e565b600380546001600160a01b0319166001600160a01b0392909216919091179055005b346102f95760003660031901126102f957602060ff600b5460081c166040519015158152f35b60203660031901126102f9576004356001600160401b0381116102f957366023820112156102f95780600401356001600160401b0381116102f957810160248101913683116102f957600080516020613bce83398151915254926001600160401b0384168015908161237f575b6001149081612375575b15908161236c575b5061235a5760016001600160401b0319851617600080516020613bce8339815191525560ff8460401c161561232d575b6002600c556020828403126102f9576024820135926001600160401b0384116102f9576102c0908484019003126102f957604051926101c084018481106001600160401b03821117611efa57604052602481840101356001600160401b0381116102f9578260246115da92848701010161290a565b8452604481840101356001600160401b0381116102f95782602461160292848701010161290a565b6020850152611615606482850101612776565b6040850152611628608482850101612776565b606085015261163b60a482850101612776565b608085015282810160c481013560a086015260e481013560c086015261010481013560e086015261012481013561010086015261167d90839061014401612951565b610120850152611693826101e483860101612951565b6101408501526102848184010135926001600160401b0384116102f9576116c76102c49360246116e0968585010101612840565b610160860152016102a481013561018085015201612776565b6101a08201528051916020820151916116f76139f6565b6116ff6139f6565b83516001600160401b038111611efa57611727600080516020613b0e833981519152546128a8565b601f81116122b7575b506020601f821160011461222857819293949560009261221d575b50508160011b916000199060031b1c191617600080516020613b0e833981519152555b82516001600160401b038111611efa57611796600080516020613b4e833981519152546128a8565b601f81116121a7575b506020601f8211600114612119578192939460009261210e575b50508160011b916000199060031b1c191617600080516020613b4e833981519152555b60408101516117fe906001600160a01b03166117f66139f6565b6104026139f6565b604051636f89e40960e01b8152610120816004817f0000000000000000000000008a85eb1fff988a1b01136279174c969d681a01516001600160a01b03165afa9081156106275760009161205e575b508051602b556020810151602c556040810151602d556060810151602e556080810151602f5560a081015160305560c081015160315560e081015160325561010081015160335560026060610120840151018160606101408601510152526118c061012083015161014084015190612bac565b60606101208301516080810151601e5560806101408501510151601f550151600f03600f811161109d576119016119119160206101208601510151906128e2565b60406101208501510151906128e2565b61012083015152600f60806101208401510152606061014083015101516014036014811161109d576119506119609160206101408601510151906128e2565b60406101408501510151906128e2565b61014083015152601460806101408401510152608061012083015180516014556020810151601555604081015160165560608101516017550151601855608061014083015180516019556020810151601a556040810151601b556060810151601c550151601d5560018060a01b036060830151166001600160601b0360a01b600254161760025560018060a01b036080830151166001600160601b0360a01b60035416176003556040519063cca3e97f60e01b825260a082600481600180851b037f0000000000000000000000008a85eb1fff988a1b01136279174c969d681a0151165afa91821561062757600092611fd0575b508151602680546001600160a01b03199081166001600160a01b039384161790915560208085015160278054841691851691909117905560408086015160288054851691861691909117905560608601516029805485169186169182179055608090960151602a80548516919095169081179094556004805484169096178655600080549093168417909255905163c45a015560e01b815293849081845afa92831561062757600093611f8f575b506020600491604051928380926315ab88c960e31b82525afa90811561062757600091611f4b575b506040516364e329cb60e11b81523060048201526001600160a01b0391821660248201529260209184916044918391600091165af1801561062757600090611f10575b611bd6925060018060a01b03166001600160601b0360a01b600154161760015560e0830151602255611bb7611bab60a08501516020840151906129ab565b610100830151906129be565b600e55610100611bcd60a08501518351906129ab565b910151906129be565b600855620186a0611bf461010083015180600a5560a08401516129ab565b0460095560046025556040518060608101106001600160401b03606083011117611efa5760608101604052600181526020810160018152604082019060018252306000526023602052611c5b604060002093511515849060ff801983541691151516179055565b518254915162ffff001990921690151560081b61ff00161790151560101b62ff000016179055600180546001600160a01b0390811660009081526040808220805461ff00191661010017905592549091168152908120805462ff00001916620100001790556101808201516006556101608201518051915b828110611ec157505050611d2c6064611cf560a084015160c0850151906129ab565b0491611d018330612c61565b611d268360a0600180821b03600080516020613b6e83398151915254169301516128e2565b90612c61565b6000546001600160a01b03163015611ea8578015611e8f57611de791606091611d543061278a565b81600052602052600019806040600020556040519081527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560203092a36000805460405163f305d71960e01b81523060048201819052602482019490945260448101839052606481019290925260848201929092524260a48201529283916001600160a01b0316908290819060c4820190565b039134905af1801561062757611e64575b506001600c5560401c60ff1615611e0b57005b68ff000000000000000019600080516020613bce8339815191525416600080516020613bce833981519152557fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d2602060405160018152a1005b606090813d8311611e88575b611e7a8183612808565b810103126102f95781611df8565b503d611e70565b604051634a1406b160e11b815260006004820152602490fd5b60405163e602df0560e01b815260006004820152602490fd5b6001906001600160a01b03611ed68285612a1e565b5116600052602360205260406000206201000062ff00001982541617905501611cd3565b634e487b7160e01b600052604160045260246000fd5b506020823d602011611f43575b81611f2a60209383612808565b810103126102f957611f3e611bd692612997565b611b6d565b3d9150611f1d565b90506020813d602011611f87575b81611f6660209383612808565b810103126102f9576000926044611f7e602093612997565b92505092611b2a565b3d9150611f59565b9092506020813d602011611fc8575b81611fab60209383612808565b810103126102f9576020611fc0600492612997565b939150611b02565b3d9150611f9e565b90915060a0813d60a011612056575b81611fec60a09383612808565b810103126102f95761204a608060405192612006846127d2565b61200f81612997565b845261201d60208201612997565b602085015261202e60408201612997565b604085015261203f60608201612997565b606085015201612997565b60808201529084611a54565b3d9150611fdf565b9050610120813d61012011612106575b8161207c6101209383612808565b810103126102f95760405190816101208101106001600160401b0361012084011117611efa57610100906101208301604052805183526020810151602084015260408101516040840152606081015160608401526080810151608084015260a081015160a084015260c081015160c084015260e081015160e084015201516101008201528361184d565b3d915061206e565b0151905084806117b9565b600080516020613b4e833981519152600052600080516020613bae8339815191529060005b601f198416811061218f5750600193949583601f19811610612176575b505050811b01600080516020613b4e833981519152556117dc565b015160001960f88460031b161c1916905584808061215b565b9091602060018192858a01518155019301910161213e565b600080516020613b4e833981519152600052601f820160051c600080516020613bae8339815191520160208310612208575b601f820160051c600080516020613bae8339815191520181106121fc575061179f565b600081556001016121d9565b50600080516020613bae8339815191526121d9565b01519050858061174b565b600080516020613b0e833981519152600052600080516020613aee8339815191529060005b601f198416811061229f575060019394959683601f19811610612286575b505050811b01600080516020613b0e8339815191525561176e565b015160001960f88460031b161c1916905585808061226b565b9091602060018192858b01518155019301910161224d565b600080516020613b0e833981519152600052601f820160051c600080516020613aee8339815191520160208310612318575b601f820160051c600080516020613aee83398151915201811061230c5750611730565b600081556001016122e9565b50600080516020613aee8339815191526122e9565b68ffffffffffffffffff1984166801000000000000000117600080516020613bce83398151915255611565565b60405163f92ee8a960e01b8152600490fd5b90501585611535565b303b15915061152d565b604086901c60ff16159150611523565b346102f95760003660031901126102f9576020601f54604051908152f35b346102f95760003660031901126102f957602060405160098152f35b346102f95760003660031901126102f9576020600a54604051908152f35b346102f95760003660031901126102f9576020612430600080516020613b8e8339815191525461dead600052600080516020613b2e8339815191528352604060002054906128e2565b604051908152f35b346102f95760603660031901126102f95761245161274a565b612459612760565b604435906124668361278a565b33600052602052604060002054926000198403612488575b610b119350612b56565b8284106124c5576001600160a01b03811615611ea8573315611e8f5782610b11946124b28361278a565b336000526020520360406000205561247e565b604051637dc7a0d960e11b81523360048201526024810185905260448101849052606490fd5b346102f95760003660031901126102f9576002546040516001600160a01b039091168152602090f35b346102f95760203660031901126102f9576001600160a01b0361253561274a565b166000526023602052606060406000205460ff6040519181811615158352818160081c161515602084015260101c1615156040820152f35b346102f95760003660031901126102f9576020600080516020613b8e83398151915254604051908152f35b346102f95760003660031901126102f9576020600c54604051908152f35b346102f95760003660031901126102f9576000546040516001600160a01b039091168152602090f35b346102f95760403660031901126102f9576125f861274a565b602435903315611ea8576001600160a01b0316908115611e8f5761261b3361278a565b82600052602052806040600020556040519081527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560203392a3602060405160018152f35b346102f95760003660031901126102f9576000600080516020613b0e83398151915280549061268e826128a8565b80855291602091600191828116908115610c6457506001146126ba5761071c86610c1181880382612808565b60009081529350600080516020613aee8339815191525b8385106126ee57505050508101602001610c118261071c85610c01565b80548686018401529382019381016126d1565b6020808252825181830181905290939260005b82811061273657505060409293506000838284010152601f8019910116010190565b818101860151848201604001528501612714565b600435906001600160a01b03821682036102f957565b602435906001600160a01b03821682036102f957565b35906001600160a01b03821682036102f957565b6001600160a01b031660009081527f52c63247e1f47db19d5ce0460030c497f067ca4cebf71ba98eeadabe20bace016020526040902090565b6004359081151582036102f957565b60a081019081106001600160401b03821117611efa57604052565b606081019081106001600160401b03821117611efa57604052565b90601f801991011681019081106001600160401b03821117611efa57604052565b6001600160401b038111611efa5760051b60200190565b9080601f830112156102f957602090823561285a81612829565b936128686040519586612808565b81855260208086019260051b8201019283116102f957602001905b828210612891575050505090565b83809161289d84612776565b815201910190612883565b90600182811c921680156128d8575b60208310146128c257565b634e487b7160e01b600052602260045260246000fd5b91607f16916128b7565b9190820391821161109d57565b6001600160401b038111611efa57601f01601f191660200190565b81601f820112156102f957803590612921826128ef565b9261292f6040519485612808565b828452602083830101116102f957816000926020809301838601378301015290565b91908260a09103126102f957604051612969816127d2565b6080808294803584526020810135602085015260408101356040850152606081013560608501520135910152565b51906001600160a01b03821682036102f957565b8181029291811591840414171561109d57565b81156129c8570490565b634e487b7160e01b600052601260045260246000fd5b9190820180921161109d57565b8051156129f85760200190565b634e487b7160e01b600052603260045260246000fd5b8051600110156129f85760400190565b80518210156129f85760209160051b010190565b90815180825260208080930193019160005b828110612a52575050505090565b83516001600160a01b031685529381019392810192600101612a44565b908160209103126102f9575180151581036102f95790565b60405190612a94826127d2565b60006080838281528260208201528260408201528260608201520152565b3d15612add573d90612ac3826128ef565b91612ad16040519384612808565b82523d6000602084013e565b606090565b6001600160a01b03908116908115612b3d57600080516020613b6e83398151915280546001600160a01b031981168417909155167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0600080a3565b604051631e4fbdf760e01b815260006004820152602490fd5b91906001600160a01b0380841615612b9357811615612b7a57612b7892612eb5565b565b60405163ec442f0560e01b815260006004820152602490fd5b604051634b637e8f60e11b815260006004820152602490fd5b612bca612bbf60408301518351906129de565b6020830151906129de565b60808201818152919080612c4c5750606060009101525b612bff612bf460408401518451906129de565b6020840151906129de565b60808301818152929080612c375750606060009101525b5160315410908115612c2a575b506106c557565b9050516032541038612c23565b6060612c45920151906129de565b8252612c16565b6060612c5a920151906129de565b8152612be1565b907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef6020600092600080516020613b8e83398151915294612ca38287546129de565b86556001600160a01b03169485158514612cc7578181540390555b604051908152a3565b50848452600080516020613b2e833981519152825260408420818154019055612cbe565b6001600160a01b0380821692909183612d8b57507fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91602091600080516020613b8e833981519152612d3e8782546129de565b90555b169384612d6657600080516020613b8e833981519152818154039055604051908152a3565b84600052600080516020613b2e83398151915282526040600020818154019055612cbe565b83600052600080516020613b2e8339815191528060205260406000205491868310612deb575091857fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef949260209487600052855203604060002055612d41565b60405163391434e360e21b81526001600160a01b0391909116600482015260248101929092525060448101859052606490fd5b600080516020613b6e833981519152546001600160a01b03163303612e3f57565b60405163118cdaa760e01b8152336004820152602490fd5b612e63600754426128e2565b6228de80811115612e8a5750630100000063ff000000196020541617602055600090600090565b620151801015612ead576201000062ff0000196020541617602055600190600190565b600290600290565b929190600c549360026000951480156139d2575b80156139ae575b801561399c575b801561398a575b8015613982575b612f745760075415613970576001600160a01b038181168652602360205260408087209184168752862060045490919060a081901c60ff1661391a575b50600b5460ff8160081c161561389a575b5060ff600b541661383d575b60135490600e5482101580613831575b80613819575b80613802575b613337575b60ff9150541615908161332a575b50612f7f575b612b78939450612ceb565b60205460189060ff81831c1615613073575b506001549495612b7895909185916001600160a01b03908116908616810361301b575050612ff09150604051612fc6816127d2565b6019548152601a546020820152601b546040820152601c546060820152601d546080820152613a25565b80612fff575b50849350612f74565b9261300d84613015926128e2565b933083612ceb565b38612ff6565b6001600160a01b03851614613032575b5050612ff0565b61306c925060405190613044826127d2565b6014548252601554602083015260165460408301526017546060830152546080820152613a25565b833861302b565b61307f600754426128e2565b9060ff8160101c16158061331e575b1561313c5750506130a38154601754906128e2565b61312157858155856017555b6130be601d54601c54906128e2565b6130eb578386612b789697601d5580601c555b6201000062ff00001960205416176020555b969550612f91565b6019546001810180911161310d57612b78959685916019556001601c556130d1565b634e487b7160e01b87526011600452602487fd5b6014546001810180911161310d5760145560016017556130af565b6228de8082111561319157505083612b78959661315d6017546014546129de565b60145561316e601c546019546129de565b6019558060175580601c55630100000063ff0000001960205416176020556130e3565b60ff1615613276575b60ff60205460081c16156131b5575b5083612b7895966130e3565b601f548091610961811061324c575b509596612b789686929081811161321a57506131f66131ed826131ff93601d55601b54906128e2565b601a54906128e2565b601c54906128e2565b60195561010061ff001960205416176020555b9695506131a9565b9050601d54810361322c575b50613212565b6131f66131ed8261324393601d55601b54906128e2565b60195538613226565b60789150046014036014811161326257856131c4565b634e487b7160e01b88526011600452602488fd5b601e548061070983106132f9575b8181116132c957506132ab6132a2826132b4938655601654906128e2565b601554906128e2565b601754906128e2565b601455600160ff19602054161760205561319a565b9050825481036132da575b5061319a565b6132ab6132a2826132f0938655601654906128e2565b601455386132d4565b5060788204600f03600f81111561328457634e487b7160e01b89526011600452602489fd5b5062015180821161308e565b60ff915054161538612f6e565b438852602460205260408820805460001981146137ee576001019055600e54916002600c556133b5613367612a87565b9161337d81613378600f54886129ab565b6129be565b835261338f81613378601054886129ab565b60208401526133a481613378601154886129ab565b6040840152613378601254866129ab565b60608201526133cc604082015160011c80946128e2565b80608083015247908a6040516133e1816127ed565b600281526040366020830137306133f7826129eb565b5281546040516315ab88c960e31b81526001600160a01b0390911690602081600481855afa9081156137e35784916137a5575b5061343483612a0e565b6001600160a01b039091169052803b156137a15761347c938360405180968195829463791ac94760e01b8452600484015283602484015260a0604484015260a4830190612a32565b30606483015242608483015203925af1801561379657613765575b506134a290476128e2565b928961350c6135016134b2612a87565b96836134cd6134c28851846129ab565b6080890151906129be565b808a528061373f575b506134e86134c26020890151846129ab565b8060208b015280613719575b50506060860151906129ab565b6080850151906129be565b60608601818152816136ca575b50505089934790816040820152821515806136c1575b6135d6575b5050816135bc61355b6135c19361355560ff9860406135c9980151926128e2565b906128e2565b916135698151600f546128e2565b600f5561357c60208201516010546128e2565b60105561358b836011546128e2565b60115561359e60608201516012546128e2565b60125560606135b382516020840151906129de565b910151906129de565b6129de565b6013546128e2565b6013556001600c55612f60565b909450606060018060a01b036000541660c46040518098819363f305d71960e01b8352306004840152876024840152600060448401526000606484015261dead60848401524260a48401525af194851561062757600095613689575b50916135bc61355b6135c1936135556135c9967f28fc98272ce761178794ad6768050fea1648e07f1e2ffe15afd3a290f838148660408060ff9c9301518151908682526020820152a1985050935050819350613534565b9450916060853d6060116136b9575b816136a560609383612808565b810103126102f957935193916135bc613632565b3d9150613698565b5081151561352f565b82809291613704829360011c838080808460018060a01b03602854165af1506136f1612ab2565b5060018060a01b036027541692516128e2565b905af150613710612ab2565b50893880613519565b600354829182918291906001600160a01b03165af150613737612ab2565b5083386134f4565b600254829182918291906001600160a01b03165af15061375d612ab2565b5083386134d6565b6001600160401b03819b929b1161378257604052986134a2613497565b634e487b7160e01b82526041600452602482fd5b6040513d8d823e3d90fd5b8280fd5b90506020813d6020116137db575b816137c060209383612808565b810103126137d7576137d190612997565b3861342a565b8380fd5b3d91506137b3565b6040513d86823e3d90fd5b634e487b7160e01b8a52601160045260248afd5b504388526024602052604088205460255411612f5b565b506001546001600160a01b0385811691161415612f55565b5060ff600d5416612f4f565b60ff825460081c161580613863575b15612f3f5760405163fd42866160e01b8152600490fd5b506001600160a01b0384168752600080516020613b2e833981519152602052604087205461389190866129de565b6009541061384c565b6138a6600754426128e2565b6078600a54910460648181020481036137ee57916138cf6138f092620186a094606402906129de565b906103b68211613904575b50600080516020613b8e833981519152546129ab565b04600954810315612f335760095538612f33565b61ff00191661010017600b55506103e8386138da565b600554421015613961575060ff815460101c16158015613952575b613940575b38612f22565b604051630b094f2760e31b8152600490fd5b5060ff825460101c1615613935565b60ff60a01b191660045561393a565b6040516312f1f92360e01b8152600490fd5b508215612ee5565b506001600160a01b0382163014612ede565b506001600160a01b0381163014612ed7565b50600080516020613b6e833981519152546001600160a01b03838116911614612ed0565b50600080516020613b6e833981519152546001600160a01b03828116911614612ec9565b60ff600080516020613bce8339815191525460401c1615613a1357565b604051631afcd79f60e31b8152600490fd5b6080810180516000949381613a3b575b50505050565b613ad293955060606064613a56613aca9594613ac2946129ab565b0496613a79613a71613a6983518b6129ab565b8651906129be565b600f546129de565b600f55613a98613a90613a6960208401518b6129ab565b6010546129de565b601055613ab7613aaf613a6960408401518b6129ab565b6011546129de565b6011550151866129ab565b9051906129be565b6012546129de565b601255613ae1826013546129de565b60135538808080613a3556fe2ae08a8e29253f69ac5d979a101956ab8f8d9d7ded63fa7a83b16fc47648eab052c63247e1f47db19d5ce0460030c497f067ca4cebf71ba98eeadabe20bace0352c63247e1f47db19d5ce0460030c497f067ca4cebf71ba98eeadabe20bace0052c63247e1f47db19d5ce0460030c497f067ca4cebf71ba98eeadabe20bace049016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c19930052c63247e1f47db19d5ce0460030c497f067ca4cebf71ba98eeadabe20bace0246a2803e59a4de4e7a4c574b1243f25977ac4c77d5a1a4a609b5394cebb4a2aaf0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00a264697066735822122065b92cda523c2335ba474f725eb3f93bea2600b8fc9f01605fee5de9549f7fa464736f6c63430008180033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
0000000000000000000000008a85eb1fff988a1b01136279174c969d681a0151
-----Decoded View---------------
Arg [0] : dataStore (address): 0x8a85eB1FfF988a1B01136279174c969D681a0151
-----Encoded View---------------
1 Constructor Arguments found :
Arg [0] : 0000000000000000000000008a85eb1fff988a1b01136279174c969d681a0151
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
Loading...
Loading
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.