Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
Latest 1 from a total of 1 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
0x60806040 | 18830766 | 300 days ago | IN | 0 ETH | 0.14378154 |
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Contract Name:
PresaleV4
Compiler Version
v0.8.21+commit.d9974bed
Optimization Enabled:
Yes with 200 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT pragma solidity 0.8.21; import "@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol"; import "@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol"; import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol"; import "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol"; import "@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol"; import "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol"; import "@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol"; import "@openzeppelin/contracts-upgradeable/utils/cryptography/MerkleProofUpgradeable.sol"; interface Aggregator { function latestRoundData() external view returns ( uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound ); } interface Vault { function depositByPresale(address user, uint256 amount) external; } contract PresaleV4 is Initializable, ReentrancyGuardUpgradeable, OwnableUpgradeable, PausableUpgradeable { uint256 public totalTokensSold; uint256 public startTime; uint256 public endTime; uint256 public baseDecimals; uint256 public maxTokensToBuy; uint256 public currentStep; uint256[][3] public rounds; uint256 public checkPoint; uint256 public usdRaised; uint256[] public prevCheckpoints; uint256[] public remainingTokensTracker; uint256 public timeConstant; address public paymentWallet; bool public dynamicTimeFlag; address public admin; IERC20Upgradeable public USDTInterface; Aggregator public aggregatorInterface; mapping(address => uint256) public userDeposits; mapping(address => bool) public wertWhitelisted; /** * @dev V2 additions */ mapping(address => uint256) public userDeposits2; /** * @dev V3 additions */ bool public claimStatus; bool public whitelistClaimOnly; IERC20Upgradeable public saleToken; Vault public vaultInterface; bytes32 public claimMerkleRoot; mapping(address => uint256) public userClaimed; mapping(address => bool) public isBlacklisted; mapping(address => bool) public isWhitelisted; event SaleTimeSet(uint256 _start, uint256 _end, uint256 timestamp); event SaleTimeUpdated( bytes32 indexed key, uint256 prevValue, uint256 newValue, uint256 timestamp ); event TokensBought( address indexed user, uint256 indexed tokensBought, address indexed purchaseToken, uint256 amountPaid, uint256 usdEq, uint256 timestamp ); event TokensClaimed( address indexed user, uint256 amount, uint256 timestamp ); event MaxTokensUpdated( uint256 prevValue, uint256 newValue, uint256 timestamp ); /// @custom:oz-upgrades-unsafe-allow constructor constructor() { _disableInitializers(); } function initializeV4() external reinitializer(4) {} /** * @dev To pause the presale */ function pause() external onlyOwner { _pause(); } /** * @dev To unpause the presale */ function unpause() external onlyOwner { _unpause(); } /** * @dev To calculate the price in USD for given amount of tokens. * @param _amount No of tokens */ function calculatePrice(uint256 _amount) public view returns (uint256) { uint256 USDTAmount; uint256 total = checkPoint == 0 ? totalTokensSold : checkPoint; if ( _amount + total > rounds[0][currentStep] || block.timestamp >= rounds[2][currentStep] ) { require(currentStep < (rounds[0].length - 1), "Wrong params"); if (block.timestamp >= rounds[2][currentStep]) { require( rounds[0][currentStep] + _amount <= rounds[0][currentStep + 1], "Cant Purchase More in individual tx" ); USDTAmount = _amount * rounds[1][currentStep + 1]; } else { require( total + _amount <= rounds[0][currentStep + 1], "Cant Purchase More in individual tx" ); uint256 tokenAmountForCurrentPrice = rounds[0][currentStep] - total; USDTAmount = tokenAmountForCurrentPrice * rounds[1][currentStep] + (_amount - tokenAmountForCurrentPrice) * rounds[1][currentStep + 1]; } } else USDTAmount = _amount * rounds[1][currentStep]; return USDTAmount; } /** * @dev To update the sale times * @param _startTime New start time * @param _endTime New end time */ function changeSaleTimes( uint256 _startTime, uint256 _endTime ) external onlyOwner { require(_startTime > 0 || _endTime > 0, "Invalid parameters"); if (_startTime > 0) { require(block.timestamp < startTime, "Sale already started"); require(block.timestamp < _startTime, "Sale time in past"); uint256 prevValue = startTime; startTime = _startTime; emit SaleTimeUpdated( bytes32("START"), prevValue, _startTime, block.timestamp ); } if (_endTime > 0) { require(_endTime > startTime, "Invalid endTime"); uint256 prevValue = endTime; endTime = _endTime; emit SaleTimeUpdated( bytes32("END"), prevValue, _endTime, block.timestamp ); } } /** * @dev To get latest ETH price in 10**18 format */ function getLatestPrice() public view returns (uint256) { (, int256 price, , , ) = aggregatorInterface.latestRoundData(); price = (price * (10 ** 10)); return uint256(price); } modifier checkSaleState(uint256 amount) { require( block.timestamp >= startTime && block.timestamp <= endTime, "Invalid time for buying" ); require(amount > 0, "Invalid sale amount"); require(amount <= maxTokensToBuy, "Amount exceeds max tokens to buy"); _; } /** * @dev To buy into a presale using USDT * @param amount No of tokens to buy */ function buyWithUSDT( uint256 amount ) external checkSaleState(amount) whenNotPaused returns (bool) { _buyWithUSDT(amount); return true; } /** * @dev To buy into a presale using ETH * @param amount No of tokens to buy */ function buyWithEth( uint256 amount ) external payable checkSaleState(amount) whenNotPaused nonReentrant returns (bool) { _buyWithEth(amount); return true; } /** * @dev To buy into a presale and stake using USDT * @param amount No of tokens to buy */ function buyWithUSDTAndStake( uint256 amount ) external checkSaleState(amount) whenNotPaused returns (bool) { uint256 amountDecimals = amount * baseDecimals; require( amountDecimals <= saleToken.balanceOf(address(this)), "Amount exceeds tokens remaining for sale" ); _buyWithUSDT(amount); _stakeTokens(amountDecimals); userClaimed[_msgSender()] += amountDecimals; emit TokensClaimed(_msgSender(), amountDecimals, block.timestamp); return true; } /** * @dev To buy into a presale and stake using ETH * @param amount No of tokens to buy */ function buyWithEthAndStake( uint256 amount ) external payable checkSaleState(amount) whenNotPaused nonReentrant returns (bool) { uint256 amountDecimals = amount * baseDecimals; require( amountDecimals <= saleToken.balanceOf(address(this)), "Amount exceeds tokens remaining for sale" ); _buyWithEth(amount); _stakeTokens(amountDecimals); userClaimed[_msgSender()] += amountDecimals; emit TokensClaimed(_msgSender(), amountDecimals, block.timestamp); return true; } function _buyWithUSDT(uint256 amount) internal { uint256 usdPrice = calculatePrice(amount); totalTokensSold += amount; if (checkPoint != 0) checkPoint += amount; uint256 total = totalTokensSold > checkPoint ? totalTokensSold : checkPoint; if ( total > rounds[0][currentStep] || block.timestamp >= rounds[2][currentStep] ) { if (block.timestamp >= rounds[2][currentStep]) { checkPoint = rounds[0][currentStep] + amount; } else { if (dynamicTimeFlag) { manageTimeDiff(); } } uint256 unsoldTokens = total > rounds[0][currentStep] ? 0 : rounds[0][currentStep] - total; remainingTokensTracker.push(unsoldTokens); currentStep += 1; } userDeposits2[_msgSender()] += (amount * baseDecimals); usdRaised += usdPrice; uint256 ourAllowance = USDTInterface.allowance( _msgSender(), address(this) ); uint256 price = usdPrice / (10 ** 12); require(price <= ourAllowance, "Make sure to add enough allowance"); (bool success, ) = address(USDTInterface).call( abi.encodeWithSignature( "transferFrom(address,address,uint256)", _msgSender(), paymentWallet, price ) ); require(success, "Token payment failed"); emit TokensBought( _msgSender(), amount, address(USDTInterface), price, usdPrice, block.timestamp ); } function _buyWithEth(uint256 amount) internal { uint256 usdPrice = calculatePrice(amount); uint256 ethAmount = (usdPrice * baseDecimals) / getLatestPrice(); require(msg.value >= ethAmount, "Less payment"); totalTokensSold += amount; if (checkPoint != 0) checkPoint += amount; uint256 total = totalTokensSold > checkPoint ? totalTokensSold : checkPoint; if ( total > rounds[0][currentStep] || block.timestamp >= rounds[2][currentStep] ) { if (block.timestamp >= rounds[2][currentStep]) { checkPoint = rounds[0][currentStep] + amount; } else { if (dynamicTimeFlag) { manageTimeDiff(); } } uint256 unsoldTokens = total > rounds[0][currentStep] ? 0 : rounds[0][currentStep] - total; remainingTokensTracker.push(unsoldTokens); currentStep += 1; } userDeposits2[_msgSender()] += (amount * baseDecimals); usdRaised += usdPrice; sendValue(payable(paymentWallet), ethAmount); uint256 excess = msg.value - ethAmount; if (excess > 0) sendValue(payable(_msgSender()), excess); emit TokensBought( _msgSender(), amount, address(0), ethAmount, usdPrice, block.timestamp ); } function _transferTokens(uint256 amount) internal { bool success = saleToken.transfer(_msgSender(), amount); require(success, "Token transfer failed"); } function _stakeTokens(uint256 amount) internal { vaultInterface.depositByPresale(_msgSender(), amount); } /** * @dev Helper funtion to get ETH price for given amount * @param amount No of tokens to buy */ function ethBuyHelper( uint256 amount ) external view returns (uint256 ethAmount) { uint256 usdPrice = calculatePrice(amount); ethAmount = (usdPrice * baseDecimals) / getLatestPrice(); } /** * @dev Helper funtion to get USDT price for given amount * @param amount No of tokens to buy */ function usdtBuyHelper( uint256 amount ) external view returns (uint256 usdPrice) { usdPrice = calculatePrice(amount); usdPrice = usdPrice / (10 ** 12); } function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Low balance"); (bool success, ) = recipient.call{value: amount}(""); require(success, "ETH Payment failed"); } function startClaim() external onlyOwner returns (bool) { require(claimStatus == false, "Claim already set"); claimStatus = true; return true; } /** * @dev To claim tokens */ function claim( uint256 _amount, bytes32[] memory _proof ) external whenNotPaused returns (bool) { require(claimStatus, "Claim has not started yet"); uint256 tokensToClaim = _claim(_amount, _proof); _transferTokens(tokensToClaim); return true; } /** * @dev To claim and stake tokens */ function claimAndStake( uint256 _amount, bytes32[] memory _proof ) external whenNotPaused returns (bool) { uint256 tokensToClaim = _claim(_amount, _proof); _stakeTokens(tokensToClaim); return true; } function _claim( uint256 _amount, bytes32[] memory _proof ) internal returns (uint256) { require(claimMerkleRoot != 0, "Merkle root not set"); require(!isBlacklisted[_msgSender()], "This Address is Blacklisted"); if (whitelistClaimOnly) { require( isWhitelisted[_msgSender()], "User not whitelisted for claim" ); } bytes32 leaf = keccak256( bytes.concat(keccak256(abi.encode(msg.sender, _amount))) ); require( MerkleProofUpgradeable.verify(_proof, claimMerkleRoot, leaf), "Invalid proof" ); uint256 tokensToClaim = _amount - userClaimed[_msgSender()]; require(tokensToClaim > 0, "Nothing to claim"); require( tokensToClaim <= saleToken.balanceOf(address(this)), "Amount exceeds tokens remaining for claim" ); userClaimed[_msgSender()] += tokensToClaim; emit TokensClaimed(_msgSender(), tokensToClaim, block.timestamp); return tokensToClaim; } /** * @dev To withdraw all sale tokens from contract */ function withdrawRemainingTokens() external onlyOwner { uint256 balance = saleToken.balanceOf(address(this)); require(balance > 0, "No tokens to withdraw"); _transferTokens(balance); } /** * @dev To add users to blacklist which restricts blacklisted users from claiming * @param _usersToBlacklist addresses of the users */ function blacklistUsers( address[] calldata _usersToBlacklist ) external onlyOwner { for (uint256 i = 0; i < _usersToBlacklist.length; i++) { isBlacklisted[_usersToBlacklist[i]] = true; } } /** * @dev To remove users from blacklist which restricts blacklisted users from claiming * @param _userToRemoveFromBlacklist addresses of the users */ function removeFromBlacklist( address[] calldata _userToRemoveFromBlacklist ) external onlyOwner { for (uint256 i = 0; i < _userToRemoveFromBlacklist.length; i++) { isBlacklisted[_userToRemoveFromBlacklist[i]] = false; } } /** * @dev To add users to whitelist which restricts users from claiming if claimWhitelistStatus is true * @param _usersToWhitelist addresses of the users */ function whitelistUsers( address[] calldata _usersToWhitelist ) external onlyOwner { for (uint256 i = 0; i < _usersToWhitelist.length; i++) { isWhitelisted[_usersToWhitelist[i]] = true; } } /** * @dev To remove users from whitelist which restricts users from claiming if claimWhitelistStatus is true * @param _userToRemoveFromWhitelist addresses of the users */ function removeFromWhitelist( address[] calldata _userToRemoveFromWhitelist ) external onlyOwner { for (uint256 i = 0; i < _userToRemoveFromWhitelist.length; i++) { isWhitelisted[_userToRemoveFromWhitelist[i]] = false; } } function changeMaxTokensToBuy(uint256 _maxTokensToBuy) external onlyOwner { require(_maxTokensToBuy > 0, "Zero max tokens to buy value"); uint256 prevValue = maxTokensToBuy; maxTokensToBuy = _maxTokensToBuy; emit MaxTokensUpdated(prevValue, _maxTokensToBuy, block.timestamp); } /** * @dev To set status for claim whitelisting * @param _status bool value */ function setClaimWhitelistStatus(bool _status) external onlyOwner { whitelistClaimOnly = _status; } function changeRoundsData(uint256[][3] memory _rounds) external onlyOwner { rounds = _rounds; } /** * @dev To set payment wallet address * @param _newPaymentWallet new payment wallet address */ function changePaymentWallet(address _newPaymentWallet) external onlyOwner { require(_newPaymentWallet != address(0), "address cannot be zero"); paymentWallet = _newPaymentWallet; } /** * @dev to set merkleroot for claim verification * @param _merkleRoot bytes32 */ function setClaimMerkleRoot(bytes32 _merkleRoot) external onlyOwner { claimMerkleRoot = _merkleRoot; } /** * @dev To manage time gap between two rounds */ function manageTimeDiff() internal { for (uint256 i; i < rounds[2].length - currentStep; i++) { rounds[2][currentStep + i] = block.timestamp + i * timeConstant; } } /** * @dev To set time constant for manageTimeDiff() * @param _timeConstant time in <days>*24*60*60 format */ function setTimeConstant(uint256 _timeConstant) external onlyOwner { timeConstant = _timeConstant; } /** * @dev To get array of round details at once * @param _no array index */ function roundDetails( uint256 _no ) external view returns (uint256[] memory) { return rounds[_no]; } /** * @dev To increment the rounds from backend */ function incrementCurrentStep() external { require( msg.sender == admin || msg.sender == owner(), "caller not admin or owner" ); prevCheckpoints.push(checkPoint); if (dynamicTimeFlag) { manageTimeDiff(); } if (checkPoint < rounds[0][currentStep]) { remainingTokensTracker.push(rounds[0][currentStep] - checkPoint); checkPoint = rounds[0][currentStep]; } currentStep++; } /** * @dev To change details of the round * @param _step round for which you want to change the details * @param _checkpoint token tracker amount */ function setCurrentStep( uint256 _step, uint256 _checkpoint ) external onlyOwner { currentStep = _step; checkPoint = _checkpoint; } /** * @dev To set time shift functionality on/off * @param _dynamicTimeFlag bool value */ function setDynamicTimeFlag(bool _dynamicTimeFlag) external onlyOwner { dynamicTimeFlag = _dynamicTimeFlag; } function trackRemainingTokens() external view returns (uint256[] memory) { return remainingTokensTracker; } /** * @dev To set time shift functionality on/off * @param _index index of the round we need to change * @param _newNoOfTokens number of tokens to be sold * @param _newPrice price for the round * @param _newTime new end time */ function changeIndividualRoundData( uint256 _index, uint256 _newNoOfTokens, uint256 _newPrice, uint256 _newTime ) external onlyOwner returns (bool) { require(_index < rounds[0].length, "invalid index"); if (_newNoOfTokens > 0) { rounds[0][_index] = _newNoOfTokens; } if (_newPrice > 0) { rounds[1][_index] = _newPrice; } if (_newTime > 0) { rounds[2][_index] = _newTime; } return true; } /** * @dev To set time shift functionality on/off * @param _newNoOfTokens number of tokens to be sold * @param _newPrice price for the round * @param _newTime new end time */ function addNewRound( uint256 _newNoOfTokens, uint256 _newPrice, uint256 _newTime ) external onlyOwner returns (bool) { require(_newNoOfTokens > 0, "invalid no of tokens"); require(_newPrice > 0, "invalid new price"); require(_newTime > 0, "invalid new time"); rounds[0].push(_newNoOfTokens); rounds[1].push(_newPrice); rounds[2].push(_newTime); return true; } /** * @dev To set admin * @param _admin new admin wallet address */ function setAdmin(address _admin) external onlyOwner { admin = _admin; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable.sol) pragma solidity ^0.8.0; import "../utils/ContextUpgradeable.sol"; import "../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. * * By default, the owner account will be the one that deploys the contract. 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 { address private _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the deployer as the initial owner. */ function __Ownable_init() internal onlyInitializing { __Ownable_init_unchained(); } function __Ownable_init_unchained() internal onlyInitializing { _transferOwnership(_msgSender()); } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { _checkOwner(); _; } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if the sender is not the owner. */ function _checkOwner() internal view virtual { require(owner() == _msgSender(), "Ownable: caller is not the owner"); } /** * @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 { require(newOwner != address(0), "Ownable: new owner is the zero address"); _transferOwnership(newOwner); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Internal function without access restriction. */ function _transferOwnership(address newOwner) internal virtual { address oldOwner = _owner; _owner = newOwner; emit OwnershipTransferred(oldOwner, newOwner); } /** * @dev This empty reserved space is put in place to allow future versions to add new * variables without shifting down storage in the inheritance chain. * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps */ uint256[49] private __gap; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (proxy/utils/Initializable.sol) pragma solidity ^0.8.2; import "../../utils/AddressUpgradeable.sol"; /** * @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 Indicates that the contract has been initialized. * @custom:oz-retyped-from bool */ uint8 private _initialized; /** * @dev Indicates that the contract is in the process of being initialized. */ bool private _initializing; /** * @dev Triggered when the contract has been initialized or reinitialized. */ event Initialized(uint8 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 functions marked with `initializer` can be nested in the context of a * constructor. * * Emits an {Initialized} event. */ modifier initializer() { bool isTopLevelCall = !_initializing; require( (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1), "Initializable: contract is already initialized" ); _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 255 will prevent any future reinitialization. * * Emits an {Initialized} event. */ modifier reinitializer(uint8 version) { require(!_initializing && _initialized < version, "Initializable: contract is already initialized"); _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() { require(_initializing, "Initializable: contract is not initializing"); _; } /** * @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 { require(!_initializing, "Initializable: contract is initializing"); if (_initialized != type(uint8).max) { _initialized = type(uint8).max; emit Initialized(type(uint8).max); } } /** * @dev Returns the highest version that has been initialized. See {reinitializer}. */ function _getInitializedVersion() internal view returns (uint8) { return _initialized; } /** * @dev Returns `true` if the contract is currently initializing. See {onlyInitializing}. */ function _isInitializing() internal view returns (bool) { return _initializing; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (security/Pausable.sol) pragma solidity ^0.8.0; import "../utils/ContextUpgradeable.sol"; import "../proxy/utils/Initializable.sol"; /** * @dev Contract module which allows children to implement an emergency stop * mechanism that can be triggered by an authorized account. * * This module is used through inheritance. It will make available the * modifiers `whenNotPaused` and `whenPaused`, which can be applied to * the functions of your contract. Note that they will not be pausable by * simply including this module, only once the modifiers are put in place. */ abstract contract PausableUpgradeable is Initializable, ContextUpgradeable { /** * @dev Emitted when the pause is triggered by `account`. */ event Paused(address account); /** * @dev Emitted when the pause is lifted by `account`. */ event Unpaused(address account); bool private _paused; /** * @dev Initializes the contract in unpaused state. */ function __Pausable_init() internal onlyInitializing { __Pausable_init_unchained(); } function __Pausable_init_unchained() internal onlyInitializing { _paused = false; } /** * @dev Modifier to make a function callable only when the contract is not paused. * * Requirements: * * - The contract must not be paused. */ modifier whenNotPaused() { _requireNotPaused(); _; } /** * @dev Modifier to make a function callable only when the contract is paused. * * Requirements: * * - The contract must be paused. */ modifier whenPaused() { _requirePaused(); _; } /** * @dev Returns true if the contract is paused, and false otherwise. */ function paused() public view virtual returns (bool) { return _paused; } /** * @dev Throws if the contract is paused. */ function _requireNotPaused() internal view virtual { require(!paused(), "Pausable: paused"); } /** * @dev Throws if the contract is not paused. */ function _requirePaused() internal view virtual { require(paused(), "Pausable: not paused"); } /** * @dev Triggers stopped state. * * Requirements: * * - The contract must not be paused. */ function _pause() internal virtual whenNotPaused { _paused = true; emit Paused(_msgSender()); } /** * @dev Returns to normal state. * * Requirements: * * - The contract must be paused. */ function _unpause() internal virtual whenPaused { _paused = false; emit Unpaused(_msgSender()); } /** * @dev This empty reserved space is put in place to allow future versions to add new * variables without shifting down storage in the inheritance chain. * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps */ uint256[49] private __gap; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (security/ReentrancyGuard.sol) pragma solidity ^0.8.0; import "../proxy/utils/Initializable.sol"; /** * @dev Contract module that helps prevent reentrant calls to a function. * * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier * available, which can be applied to functions to make sure there are no nested * (reentrant) calls to them. * * Note that because there is a single `nonReentrant` guard, functions marked as * `nonReentrant` may not call one another. This can be worked around by making * those functions `private`, and then adding `external` `nonReentrant` entry * points to them. * * TIP: If you would like to learn more about reentrancy and alternative ways * to protect against it, check out our blog post * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul]. */ abstract contract ReentrancyGuardUpgradeable is Initializable { // Booleans are more expensive than uint256 or any type that takes up a full // word because each write operation emits an extra SLOAD to first read the // slot's contents, replace the bits taken up by the boolean, and then write // back. This is the compiler's defense against contract upgrades and // pointer aliasing, and it cannot be disabled. // The values being non-zero value makes deployment a bit more expensive, // but in exchange the refund on every call to nonReentrant will be lower in // amount. Since refunds are capped to a percentage of the total // transaction's gas, it is best to keep them low in cases like this one, to // increase the likelihood of the full refund coming into effect. uint256 private constant _NOT_ENTERED = 1; uint256 private constant _ENTERED = 2; uint256 private _status; function __ReentrancyGuard_init() internal onlyInitializing { __ReentrancyGuard_init_unchained(); } function __ReentrancyGuard_init_unchained() internal onlyInitializing { _status = _NOT_ENTERED; } /** * @dev Prevents a contract from calling itself, directly or indirectly. * Calling a `nonReentrant` function from another `nonReentrant` * function is not supported. It is possible to prevent this from happening * by making the `nonReentrant` function external, and making it call a * `private` function that does the actual work. */ modifier nonReentrant() { _nonReentrantBefore(); _; _nonReentrantAfter(); } function _nonReentrantBefore() private { // On the first call to nonReentrant, _status will be _NOT_ENTERED require(_status != _ENTERED, "ReentrancyGuard: reentrant call"); // Any calls to nonReentrant after this point will fail _status = _ENTERED; } function _nonReentrantAfter() private { // By storing the original value once again, a refund is triggered (see // https://eips.ethereum.org/EIPS/eip-2200) _status = _NOT_ENTERED; } /** * @dev Returns true if the reentrancy guard is currently set to "entered", which indicates there is a * `nonReentrant` function in the call stack. */ function _reentrancyGuardEntered() internal view returns (bool) { return _status == _ENTERED; } /** * @dev This empty reserved space is put in place to allow future versions to add new * variables without shifting down storage in the inheritance chain. * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps */ uint256[49] private __gap; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20Upgradeable { /** * @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 amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` 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 amount) 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 `amount` 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 amount) external returns (bool); /** * @dev Moves `amount` tokens from `from` to `to` using the * allowance mechanism. `amount` 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 amount) external returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol) pragma solidity ^0.8.1; /** * @dev Collection of functions related to the address type */ library AddressUpgradeable { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * * Furthermore, `isContract` will also return true if the target contract within * the same transaction is already scheduled for destruction by `SELFDESTRUCT`, * which only has an effect at the end of a transaction. * ==== * * [IMPORTANT] * ==== * You shouldn't rely on `isContract` to protect against flash loan attacks! * * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract * constructor. * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize/address.code.length, which returns 0 // for contracts in construction, since the code is only stored at the end // of the constructor execution. return account.code.length > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); (bool success, ) = recipient.call{value: amount}(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain `call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value, string memory errorMessage ) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall( address target, bytes memory data, string memory errorMessage ) internal view returns (bytes memory) { (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { return functionDelegateCall(target, data, "Address: low-level delegate call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract. * * _Available since v4.8._ */ function verifyCallResultFromTarget( address target, bool success, bytes memory returndata, string memory errorMessage ) internal view returns (bytes memory) { if (success) { if (returndata.length == 0) { // only check isContract if the call was successful and the return data is empty // otherwise we already know that it was a contract require(isContract(target), "Address: call to non-contract"); } return returndata; } else { _revert(returndata, errorMessage); } } /** * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason or using the provided one. * * _Available since v4.3._ */ function verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) internal pure returns (bytes memory) { if (success) { return returndata; } else { _revert(returndata, errorMessage); } } function _revert(bytes memory returndata, string memory errorMessage) private pure { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly /// @solidity memory-safe-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/Context.sol) pragma solidity ^0.8.0; import "../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; } /** * @dev This empty reserved space is put in place to allow future versions to add new * variables without shifting down storage in the inheritance chain. * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps */ uint256[50] private __gap; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.2) (utils/cryptography/MerkleProof.sol) pragma solidity ^0.8.0; /** * @dev These functions deal with verification of Merkle Tree proofs. * * The tree and the proofs can be generated using our * https://github.com/OpenZeppelin/merkle-tree[JavaScript library]. * You will find a quickstart guide in the readme. * * WARNING: You should avoid using leaf values that are 64 bytes long prior to * hashing, or use a hash function other than keccak256 for hashing leaves. * This is because the concatenation of a sorted pair of internal nodes in * the merkle tree could be reinterpreted as a leaf value. * OpenZeppelin's JavaScript library generates merkle trees that are safe * against this attack out of the box. */ library MerkleProofUpgradeable { /** * @dev Returns true if a `leaf` can be proved to be a part of a Merkle tree * defined by `root`. For this, a `proof` must be provided, containing * sibling hashes on the branch from the leaf to the root of the tree. Each * pair of leaves and each pair of pre-images are assumed to be sorted. */ function verify(bytes32[] memory proof, bytes32 root, bytes32 leaf) internal pure returns (bool) { return processProof(proof, leaf) == root; } /** * @dev Calldata version of {verify} * * _Available since v4.7._ */ function verifyCalldata(bytes32[] calldata proof, bytes32 root, bytes32 leaf) internal pure returns (bool) { return processProofCalldata(proof, leaf) == root; } /** * @dev Returns the rebuilt hash obtained by traversing a Merkle tree up * from `leaf` using `proof`. A `proof` is valid if and only if the rebuilt * hash matches the root of the tree. When processing the proof, the pairs * of leafs & pre-images are assumed to be sorted. * * _Available since v4.4._ */ function processProof(bytes32[] memory proof, bytes32 leaf) internal pure returns (bytes32) { bytes32 computedHash = leaf; for (uint256 i = 0; i < proof.length; i++) { computedHash = _hashPair(computedHash, proof[i]); } return computedHash; } /** * @dev Calldata version of {processProof} * * _Available since v4.7._ */ function processProofCalldata(bytes32[] calldata proof, bytes32 leaf) internal pure returns (bytes32) { bytes32 computedHash = leaf; for (uint256 i = 0; i < proof.length; i++) { computedHash = _hashPair(computedHash, proof[i]); } return computedHash; } /** * @dev Returns true if the `leaves` can be simultaneously proven to be a part of a merkle tree defined by * `root`, according to `proof` and `proofFlags` as described in {processMultiProof}. * * CAUTION: Not all merkle trees admit multiproofs. See {processMultiProof} for details. * * _Available since v4.7._ */ function multiProofVerify( bytes32[] memory proof, bool[] memory proofFlags, bytes32 root, bytes32[] memory leaves ) internal pure returns (bool) { return processMultiProof(proof, proofFlags, leaves) == root; } /** * @dev Calldata version of {multiProofVerify} * * CAUTION: Not all merkle trees admit multiproofs. See {processMultiProof} for details. * * _Available since v4.7._ */ function multiProofVerifyCalldata( bytes32[] calldata proof, bool[] calldata proofFlags, bytes32 root, bytes32[] memory leaves ) internal pure returns (bool) { return processMultiProofCalldata(proof, proofFlags, leaves) == root; } /** * @dev Returns the root of a tree reconstructed from `leaves` and sibling nodes in `proof`. The reconstruction * proceeds by incrementally reconstructing all inner nodes by combining a leaf/inner node with either another * leaf/inner node or a proof sibling node, depending on whether each `proofFlags` item is true or false * respectively. * * CAUTION: Not all merkle trees admit multiproofs. To use multiproofs, it is sufficient to ensure that: 1) the tree * is complete (but not necessarily perfect), 2) the leaves to be proven are in the opposite order they are in the * tree (i.e., as seen from right to left starting at the deepest layer and continuing at the next layer). * * _Available since v4.7._ */ function processMultiProof( bytes32[] memory proof, bool[] memory proofFlags, bytes32[] memory leaves ) internal pure returns (bytes32 merkleRoot) { // This function rebuilds the root hash by traversing the tree up from the leaves. The root is rebuilt by // consuming and producing values on a queue. The queue starts with the `leaves` array, then goes onto the // `hashes` array. At the end of the process, the last hash in the `hashes` array should contain the root of // the merkle tree. uint256 leavesLen = leaves.length; uint256 proofLen = proof.length; uint256 totalHashes = proofFlags.length; // Check proof validity. require(leavesLen + proofLen - 1 == totalHashes, "MerkleProof: invalid multiproof"); // The xxxPos values are "pointers" to the next value to consume in each array. All accesses are done using // `xxx[xxxPos++]`, which return the current value and increment the pointer, thus mimicking a queue's "pop". bytes32[] memory hashes = new bytes32[](totalHashes); uint256 leafPos = 0; uint256 hashPos = 0; uint256 proofPos = 0; // At each step, we compute the next hash using two values: // - a value from the "main queue". If not all leaves have been consumed, we get the next leaf, otherwise we // get the next hash. // - depending on the flag, either another value from the "main queue" (merging branches) or an element from the // `proof` array. for (uint256 i = 0; i < totalHashes; i++) { bytes32 a = leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++]; bytes32 b = proofFlags[i] ? (leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++]) : proof[proofPos++]; hashes[i] = _hashPair(a, b); } if (totalHashes > 0) { require(proofPos == proofLen, "MerkleProof: invalid multiproof"); unchecked { return hashes[totalHashes - 1]; } } else if (leavesLen > 0) { return leaves[0]; } else { return proof[0]; } } /** * @dev Calldata version of {processMultiProof}. * * CAUTION: Not all merkle trees admit multiproofs. See {processMultiProof} for details. * * _Available since v4.7._ */ function processMultiProofCalldata( bytes32[] calldata proof, bool[] calldata proofFlags, bytes32[] memory leaves ) internal pure returns (bytes32 merkleRoot) { // This function rebuilds the root hash by traversing the tree up from the leaves. The root is rebuilt by // consuming and producing values on a queue. The queue starts with the `leaves` array, then goes onto the // `hashes` array. At the end of the process, the last hash in the `hashes` array should contain the root of // the merkle tree. uint256 leavesLen = leaves.length; uint256 proofLen = proof.length; uint256 totalHashes = proofFlags.length; // Check proof validity. require(leavesLen + proofLen - 1 == totalHashes, "MerkleProof: invalid multiproof"); // The xxxPos values are "pointers" to the next value to consume in each array. All accesses are done using // `xxx[xxxPos++]`, which return the current value and increment the pointer, thus mimicking a queue's "pop". bytes32[] memory hashes = new bytes32[](totalHashes); uint256 leafPos = 0; uint256 hashPos = 0; uint256 proofPos = 0; // At each step, we compute the next hash using two values: // - a value from the "main queue". If not all leaves have been consumed, we get the next leaf, otherwise we // get the next hash. // - depending on the flag, either another value from the "main queue" (merging branches) or an element from the // `proof` array. for (uint256 i = 0; i < totalHashes; i++) { bytes32 a = leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++]; bytes32 b = proofFlags[i] ? (leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++]) : proof[proofPos++]; hashes[i] = _hashPair(a, b); } if (totalHashes > 0) { require(proofPos == proofLen, "MerkleProof: invalid multiproof"); unchecked { return hashes[totalHashes - 1]; } } else if (leavesLen > 0) { return leaves[0]; } else { return proof[0]; } } function _hashPair(bytes32 a, bytes32 b) private pure returns (bytes32) { return a < b ? _efficientHash(a, b) : _efficientHash(b, a); } function _efficientHash(bytes32 a, bytes32 b) private pure returns (bytes32 value) { /// @solidity memory-safe-assembly assembly { mstore(0x00, a) mstore(0x20, b) value := keccak256(0x00, 0x40) } } }
{ "optimizer": { "enabled": true, "runs": 200 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint8","name":"version","type":"uint8"}],"name":"Initialized","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"prevValue","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newValue","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"MaxTokensUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_start","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_end","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"SaleTimeSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"key","type":"bytes32"},{"indexed":false,"internalType":"uint256","name":"prevValue","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newValue","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"SaleTimeUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokensBought","type":"uint256"},{"indexed":true,"internalType":"address","name":"purchaseToken","type":"address"},{"indexed":false,"internalType":"uint256","name":"amountPaid","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"usdEq","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"TokensBought","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"TokensClaimed","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"inputs":[],"name":"USDTInterface","outputs":[{"internalType":"contract IERC20Upgradeable","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_newNoOfTokens","type":"uint256"},{"internalType":"uint256","name":"_newPrice","type":"uint256"},{"internalType":"uint256","name":"_newTime","type":"uint256"}],"name":"addNewRound","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"admin","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"aggregatorInterface","outputs":[{"internalType":"contract Aggregator","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"baseDecimals","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"_usersToBlacklist","type":"address[]"}],"name":"blacklistUsers","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"buyWithEth","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"buyWithEthAndStake","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"buyWithUSDT","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"buyWithUSDTAndStake","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"calculatePrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_index","type":"uint256"},{"internalType":"uint256","name":"_newNoOfTokens","type":"uint256"},{"internalType":"uint256","name":"_newPrice","type":"uint256"},{"internalType":"uint256","name":"_newTime","type":"uint256"}],"name":"changeIndividualRoundData","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_maxTokensToBuy","type":"uint256"}],"name":"changeMaxTokensToBuy","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_newPaymentWallet","type":"address"}],"name":"changePaymentWallet","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[][3]","name":"_rounds","type":"uint256[][3]"}],"name":"changeRoundsData","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_startTime","type":"uint256"},{"internalType":"uint256","name":"_endTime","type":"uint256"}],"name":"changeSaleTimes","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"checkPoint","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"bytes32[]","name":"_proof","type":"bytes32[]"}],"name":"claim","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"bytes32[]","name":"_proof","type":"bytes32[]"}],"name":"claimAndStake","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"claimMerkleRoot","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"claimStatus","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"currentStep","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"dynamicTimeFlag","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"endTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"ethBuyHelper","outputs":[{"internalType":"uint256","name":"ethAmount","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getLatestPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"incrementCurrentStep","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"initializeV4","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"isBlacklisted","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"isWhitelisted","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxTokensToBuy","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"paymentWallet","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"prevCheckpoints","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"remainingTokensTracker","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"_userToRemoveFromBlacklist","type":"address[]"}],"name":"removeFromBlacklist","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_userToRemoveFromWhitelist","type":"address[]"}],"name":"removeFromWhitelist","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_no","type":"uint256"}],"name":"roundDetails","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"rounds","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"saleToken","outputs":[{"internalType":"contract IERC20Upgradeable","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_admin","type":"address"}],"name":"setAdmin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_merkleRoot","type":"bytes32"}],"name":"setClaimMerkleRoot","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_status","type":"bool"}],"name":"setClaimWhitelistStatus","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_step","type":"uint256"},{"internalType":"uint256","name":"_checkpoint","type":"uint256"}],"name":"setCurrentStep","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_dynamicTimeFlag","type":"bool"}],"name":"setDynamicTimeFlag","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_timeConstant","type":"uint256"}],"name":"setTimeConstant","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"startClaim","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"startTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"timeConstant","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalTokensSold","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"trackRemainingTokens","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"unpause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"usdRaised","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"usdtBuyHelper","outputs":[{"internalType":"uint256","name":"usdPrice","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"userClaimed","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"userDeposits","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"userDeposits2","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"vaultInterface","outputs":[{"internalType":"contract Vault","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"wertWhitelisted","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"whitelistClaimOnly","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"_usersToWhitelist","type":"address[]"}],"name":"whitelistUsers","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdrawRemainingTokens","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
608060405234801562000010575f80fd5b506200001b62000021565b620000df565b5f54610100900460ff16156200008d5760405162461bcd60e51b815260206004820152602760248201527f496e697469616c697a61626c653a20636f6e747261637420697320696e697469604482015266616c697a696e6760c81b606482015260840160405180910390fd5b5f5460ff90811614620000dd575f805460ff191660ff9081179091556040519081527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b565b61385980620000ed5f395ff3fe6080604052600436106103c9575f3560e01c806389daf799116101f4578063c49cc64511610113578063e985e367116100a8578063f2fde38b11610078578063f2fde38b14610ad3578063f597573f14610af2578063f851a44014610b11578063fd1e296214610b30578063fe575a8714610b4f575f80fd5b8063e985e36714610a66578063eadd94ec14610a8b578063ecbfc07714610aa0578063edec5f2714610ab4575f80fd5b8063d279a321116100e3578063d279a321146109ea578063e19648db14610a09578063e32204dd14610a28578063e6da921314610a47575f80fd5b8063c49cc64514610983578063c8adff01146109a2578063cad00556146109b6578063cff805ab146109d5575f80fd5b8063a6d42e4e11610189578063b025384711610159578063b0253847146108fa578063ba166a3914610919578063bb3d676a14610945578063c23326f314610964575f80fd5b8063a6d42e4e14610884578063a7c60160146108a3578063ae104265146108c2578063ae87fc4b146108e1575f80fd5b80638e15f473116101c45780638e15f473146108275780639a89c1fb1461083b5780639c4dab521461085a5780639cfa0f7c1461086f575f80fd5b806389daf799146107ac5780638afbf669146107cb5780638d9830bd146107df5780638da5cb5b1461080a575f80fd5b80633f4ba83a116102eb5780635ea8293411610280578063704b6c0211610250578063704b6c021461073d578063715018a61461075c5780637649b9571461077057806378e97925146107835780638456cb5914610798575f80fd5b80635ea82934146106be57806363b20117146106f557806363e408791461070a578063641046f414610729575f80fd5b806354a08606116102bb57806354a08606146106505780635bc34f71146106645780635c975abb146106795780635df4f35314610690575f80fd5b80633f4ba83a146105ea57806343568eae146105fe57806353d9920714610613578063548db17414610631575f80fd5b806329a5a0b61161036157806336d76a951161033157806336d76a95146105535780633af32abf146105725780633b7fcdca146105a05780633d9c8d8b146105cb575f80fd5b806329a5a0b6146104eb5780632f52ebb71461050a5780633197cbb61461052957806333f761781461053e575f80fd5b80631ddc60911161039c5780631ddc60911461046e5780631fa2bc921461048d57806323a8f1c0146104ad578063278c278b146104cc575f80fd5b80630a200fc7146103cd5780630ba36dcd146103ee5780630dc9c8381461042c5780631d1ee4a31461044b575b5f80fd5b3480156103d8575f80fd5b506103ec6103e73660046131d4565b610b7d565b005b3480156103f9575f80fd5b506104196104083660046131ef565b60db6020525f908152604090205481565b6040519081526020015b60405180910390f35b348015610437575f80fd5b506103ec610446366004613215565b610ba3565b61045e610459366004613235565b610d82565b6040519015158152602001610423565b348015610479575f80fd5b506103ec6104883660046131d4565b610f27565b348015610498575f80fd5b5060d75461045e90600160a01b900460ff1681565b3480156104b8575f80fd5b506103ec6104c7366004613235565b610f49565b3480156104d7575f80fd5b506103ec6104e6366004613235565b610f56565b3480156104f6575f80fd5b50610419610505366004613235565b610ff8565b348015610515575f80fd5b5061045e6105243660046132dd565b61102b565b348015610534575f80fd5b5061041960cb5481565b348015610549575f80fd5b5061041960cc5481565b34801561055e575f80fd5b5061045e61056d3660046132dd565b6110a8565b34801561057d575f80fd5b5061045e61058c3660046131ef565b60e36020525f908152604090205460ff1681565b3480156105ab575f80fd5b506104196105ba3660046131ef565b60e16020525f908152604090205481565b3480156105d6575f80fd5b5061045e6105e536600461337a565b6110c7565b3480156105f5575f80fd5b506103ec611196565b348015610609575f80fd5b5061041960d65481565b34801561061e575f80fd5b5060de5461045e90610100900460ff1681565b34801561063c575f80fd5b506103ec61064b3660046133a9565b6111a8565b34801561065b575f80fd5b506103ec611223565b34801561066f575f80fd5b5061041960ce5481565b348015610684575f80fd5b5060975460ff1661045e565b34801561069b575f80fd5b5061045e6106aa3660046131ef565b60dc6020525f908152604090205460ff1681565b3480156106c9575f80fd5b5060df546106dd906001600160a01b031681565b6040516001600160a01b039091168152602001610423565b348015610700575f80fd5b5061041960c95481565b348015610715575f80fd5b50610419610724366004613235565b6112f7565b348015610734575f80fd5b506103ec611312565b348015610748575f80fd5b506103ec6107573660046131ef565b611476565b348015610767575f80fd5b506103ec6114a0565b61045e61077e366004613235565b6114b1565b34801561078e575f80fd5b5061041960ca5481565b3480156107a3575f80fd5b506103ec61154a565b3480156107b7575f80fd5b506103ec6107c63660046133a9565b61155a565b3480156107d6575f80fd5b506103ec6115d0565b3480156107ea575f80fd5b506104196107f93660046131ef565b60dd6020525f908152604090205481565b348015610815575f80fd5b506065546001600160a01b03166106dd565b348015610832575f80fd5b5061041961169d565b348015610846575f80fd5b506103ec610855366004613215565b61172a565b348015610865575f80fd5b5061041960e05481565b34801561087a575f80fd5b5061041960cd5481565b34801561088f575f80fd5b506103ec61089e366004613418565b61173d565b3480156108ae575f80fd5b5061045e6108bd366004613235565b611752565b3480156108cd575f80fd5b506104196108dc366004613235565b6117df565b3480156108ec575f80fd5b5060de5461045e9060ff1681565b348015610905575f80fd5b5061045e610914366004613500565b611ac1565b348015610924575f80fd5b50610938610933366004613235565b611c2c565b6040516104239190613529565b348015610950575f80fd5b506103ec61095f3660046133a9565b611c96565b34801561096f575f80fd5b5061041961097e366004613235565b611d0d565b34801561098e575f80fd5b5060da546106dd906001600160a01b031681565b3480156109ad575f80fd5b50610938611d2c565b3480156109c1575f80fd5b506103ec6109d03660046131ef565b611d82565b3480156109e0575f80fd5b5061041960d25481565b3480156109f5575f80fd5b5061045e610a04366004613235565b611dfb565b348015610a14575f80fd5b50610419610a23366004613235565b611f8e565b348015610a33575f80fd5b5060d7546106dd906001600160a01b031681565b348015610a52575f80fd5b50610419610a61366004613215565b611f9d565b348015610a71575f80fd5b5060de546106dd906201000090046001600160a01b031681565b348015610a96575f80fd5b5061041960d35481565b348015610aab575f80fd5b5061045e611fcc565b348015610abf575f80fd5b506103ec610ace3660046133a9565b612030565b348015610ade575f80fd5b506103ec610aed3660046131ef565b6120a7565b348015610afd575f80fd5b5060d9546106dd906001600160a01b031681565b348015610b1c575f80fd5b5060d8546106dd906001600160a01b031681565b348015610b3b575f80fd5b506103ec610b4a366004613235565b61211d565b348015610b5a575f80fd5b5061045e610b693660046131ef565b60e26020525f908152604090205460ff1681565b610b8561212a565b60d78054911515600160a01b0260ff60a01b19909216919091179055565b610bab61212a565b5f821180610bb857505f81115b610bfe5760405162461bcd60e51b8152602060048201526012602482015271496e76616c696420706172616d657465727360701b60448201526064015b60405180910390fd5b8115610ce35760ca544210610c4c5760405162461bcd60e51b815260206004820152601460248201527314d85b1948185b1c9958591e481cdd185c9d195960621b6044820152606401610bf5565b814210610c8f5760405162461bcd60e51b815260206004820152601160248201527014d85b19481d1a5b59481a5b881c185cdd607a1b6044820152606401610bf5565b60ca8054908390556040805182815260208101859052428183015290516414d510549560da1b917fddd2ed237e6993c9380182683f2c8bec486aaaa429528852cd74dbdb96cea0b2919081900360600190a2505b8015610d7e5760ca548111610d2c5760405162461bcd60e51b815260206004820152600f60248201526e496e76616c696420656e6454696d6560881b6044820152606401610bf5565b60cb8054908290556040805182815260208101849052428183015290516211539160ea1b917fddd2ed237e6993c9380182683f2c8bec486aaaa429528852cd74dbdb96cea0b2919081900360600190a2505b5050565b5f8160ca544210158015610d98575060cb544211155b610db45760405162461bcd60e51b8152600401610bf59061356c565b5f8111610dd35760405162461bcd60e51b8152600401610bf5906135a3565b60cd54811115610df55760405162461bcd60e51b8152600401610bf5906135d0565b610dfd612184565b610e056121ca565b5f60cc5484610e149190613619565b60de546040516370a0823160e01b81523060048201529192506201000090046001600160a01b0316906370a0823190602401602060405180830381865afa158015610e61573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610e859190613630565b811115610ea45760405162461bcd60e51b8152600401610bf590613647565b610ead84612223565b610eb68161251a565b335f90815260e1602052604081208054839290610ed490849061368f565b90915550506040805182815242602082015233917f9923b4306c6c030f2bdfbf156517d5983b87e15b96176da122cd4f2effa4ba7b910160405180910390a26001925050610f2160018055565b50919050565b610f2f61212a565b60de80549115156101000261ff0019909216919091179055565b610f5161212a565b60d655565b610f5e61212a565b5f8111610fad5760405162461bcd60e51b815260206004820152601c60248201527f5a65726f206d617820746f6b656e7320746f206275792076616c7565000000006044820152606401610bf5565b60cd8054908290556040805182815260208101849052428183015290517f76f9e5e1f6af6a9f180708b77a5c99210fbf19b91f1f194f3918c262b8edf77c9181900360600190a15050565b5f80611003836117df565b905061100d61169d565b60cc5461101a9083613619565b61102491906136a2565b9392505050565b5f611034612184565b60de5460ff166110865760405162461bcd60e51b815260206004820152601960248201527f436c61696d20686173206e6f74207374617274656420796574000000000000006044820152606401610bf5565b5f611091848461258a565b905061109c816128c5565b60019150505b92915050565b5f6110b1612184565b5f6110bc848461258a565b905061109c8161251a565b5f6110d061212a565b60cf5485106111115760405162461bcd60e51b815260206004820152600d60248201526c0d2dcecc2d8d2c840d2dcc8caf609b1b6044820152606401610bf5565b8315611139578360cf5f01868154811061112d5761112d6136c1565b5f918252602090912001555b8215611162578260cf6001018681548110611156576111566136c1565b5f918252602090912001555b811561118b578160cf600201868154811061117f5761117f6136c1565b5f918252602090912001555b506001949350505050565b61119e61212a565b6111a6612994565b565b6111b061212a565b5f5b8181101561121e575f60e35f8585858181106111d0576111d06136c1565b90506020020160208101906111e591906131ef565b6001600160a01b0316815260208101919091526040015f20805460ff191691151591909117905580611216816136d5565b9150506111b2565b505050565b5f54600490610100900460ff1615801561124357505f5460ff8083169116105b6112a65760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401610bf5565b5f805461ffff191660ff83169081176101001761ff0019169091556040519081527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a150565b5f611301826117df565b90506110a264e8d4a51000826136a2565b60d8546001600160a01b031633148061133557506065546001600160a01b031633145b6113815760405162461bcd60e51b815260206004820152601960248201527f63616c6c6572206e6f742061646d696e206f72206f776e6572000000000000006044820152606401610bf5565b60d25460d480546001810182555f919091527f9780e26d96b1f2a9a18ef8fc72d589dbf03ef788137b64f43897e83a91e7feec015560d754600160a01b900460ff16156113d0576113d06129e6565b60cf5f0160ce54815481106113e7576113e76136c1565b905f5260205f20015460d25410156114605760d25460d59060cf5f0160ce5481548110611416576114166136c1565b905f5260205f20015461142991906136ed565b81546001810183555f92835260208320015560cf0160ce5481548110611451576114516136c1565b5f9182526020909120015460d2555b60ce8054905f61146f836136d5565b9190505550565b61147e61212a565b60d880546001600160a01b0319166001600160a01b0392909216919091179055565b6114a861212a565b6111a65f612a54565b5f8160ca5442101580156114c7575060cb544211155b6114e35760405162461bcd60e51b8152600401610bf59061356c565b5f81116115025760405162461bcd60e51b8152600401610bf5906135a3565b60cd548111156115245760405162461bcd60e51b8152600401610bf5906135d0565b61152c612184565b6115346121ca565b61153d83612223565b60019150610f2160018055565b61155261212a565b6111a6612aa5565b61156261212a565b5f5b8181101561121e575f60e25f858585818110611582576115826136c1565b905060200201602081019061159791906131ef565b6001600160a01b0316815260208101919091526040015f20805460ff1916911515919091179055806115c8816136d5565b915050611564565b6115d861212a565b60de546040516370a0823160e01b81523060048201525f916201000090046001600160a01b0316906370a0823190602401602060405180830381865afa158015611624573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906116489190613630565b90505f81116116915760405162461bcd60e51b81526020600482015260156024820152744e6f20746f6b656e7320746f20776974686472617760581b6044820152606401610bf5565b61169a816128c5565b50565b5f8060da5f9054906101000a90046001600160a01b03166001600160a01b031663feaf968c6040518163ffffffff1660e01b815260040160a060405180830381865afa1580156116ef573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611713919061371e565b505050915050806402540be4006110a2919061376a565b61173261212a565b60ce9190915560d255565b61174561212a565b610d7e60cf8260036130e7565b5f8160ca544210158015611768575060cb544211155b6117845760405162461bcd60e51b8152600401610bf59061356c565b5f81116117a35760405162461bcd60e51b8152600401610bf5906135a3565b60cd548111156117c55760405162461bcd60e51b8152600401610bf5906135d0565b6117cd612184565b6117d683612ae2565b50600192915050565b5f805f60d2545f146117f35760d2546117f7565b60c9545b905060cf5f0160ce5481548110611810576118106136c1565b905f5260205f2001548185611825919061368f565b1180611851575060cf60020160ce5481548110611844576118446136c1565b905f5260205f2001544210155b15611a8b5760cf54611865906001906136ed565b60ce54106118a45760405162461bcd60e51b815260206004820152600c60248201526b57726f6e6720706172616d7360a01b6044820152606401610bf5565b60cf60020160ce54815481106118bc576118bc6136c1565b905f5260205f200154421061198a5760ce5460cf906118dc90600161368f565b815481106118ec576118ec6136c1565b905f5260205f2001548460cf5f60038110611909576119096136c1565b0160ce548154811061191d5761191d6136c1565b905f5260205f200154611930919061368f565b111561194e5760405162461bcd60e51b8152600401610bf590613799565b60ce5460d09061195f90600161368f565b8154811061196f5761196f6136c1565b905f5260205f200154846119839190613619565b9150611aba565b60ce5460cf9061199b90600161368f565b815481106119ab576119ab6136c1565b905f5260205f20015484826119c0919061368f565b11156119de5760405162461bcd60e51b8152600401610bf590613799565b5f8160cf820160ce54815481106119f7576119f76136c1565b905f5260205f200154611a0a91906136ed565b60ce5490915060d090611a1e90600161368f565b81548110611a2e57611a2e6136c1565b905f5260205f2001548186611a4391906136ed565b611a4d9190613619565b60cf60010160ce5481548110611a6557611a656136c1565b905f5260205f20015482611a799190613619565b611a83919061368f565b925050611aba565b60cf60010160ce5481548110611aa357611aa36136c1565b905f5260205f20015484611ab79190613619565b91505b5092915050565b5f611aca61212a565b5f8411611b105760405162461bcd60e51b8152602060048201526014602482015273696e76616c6964206e6f206f6620746f6b656e7360601b6044820152606401610bf5565b5f8311611b535760405162461bcd60e51b8152602060048201526011602482015270696e76616c6964206e657720707269636560781b6044820152606401610bf5565b5f8211611b955760405162461bcd60e51b815260206004820152601060248201526f696e76616c6964206e65772074696d6560801b6044820152606401610bf5565b5060cf805460018082019092557facb8d954e2cfef495862221e91bd7523613cf8808827cb33edfe4904cc51bf29019390935560d080548085019091557fe89d44c8fd6a9bac8af33ce47f56337617d449bf7ff3956b618c646de829cbcb019190915560d1805480840182555f919091527f695fb3134ad82c3b8022bc5464edd0bcc9424ef672b52245dcb6ab2374327ce3015590565b606060cf8260038110611c4157611c416136c1565b01805480602002602001604051908101604052809291908181526020018280548015611c8a57602002820191905f5260205f20905b815481526020019060010190808311611c76575b50505050509050919050565b611c9e61212a565b5f5b8181101561121e57600160e25f858585818110611cbf57611cbf6136c1565b9050602002016020810190611cd491906131ef565b6001600160a01b0316815260208101919091526040015f20805460ff191691151591909117905580611d05816136d5565b915050611ca0565b60d58181548110611d1c575f80fd5b5f91825260209091200154905081565b606060d5805480602002602001604051908101604052809291908181526020018280548015611d7857602002820191905f5260205f20905b815481526020019060010190808311611d64575b5050505050905090565b611d8a61212a565b6001600160a01b038116611dd95760405162461bcd60e51b8152602060048201526016602482015275616464726573732063616e6e6f74206265207a65726f60501b6044820152606401610bf5565b60d780546001600160a01b0319166001600160a01b0392909216919091179055565b5f8160ca544210158015611e11575060cb544211155b611e2d5760405162461bcd60e51b8152600401610bf59061356c565b5f8111611e4c5760405162461bcd60e51b8152600401610bf5906135a3565b60cd54811115611e6e5760405162461bcd60e51b8152600401610bf5906135d0565b611e76612184565b5f60cc5484611e859190613619565b60de546040516370a0823160e01b81523060048201529192506201000090046001600160a01b0316906370a0823190602401602060405180830381865afa158015611ed2573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611ef69190613630565b811115611f155760405162461bcd60e51b8152600401610bf590613647565b611f1e84612ae2565b611f278161251a565b335f90815260e1602052604081208054839290611f4590849061368f565b90915550506040805182815242602082015233917f9923b4306c6c030f2bdfbf156517d5983b87e15b96176da122cd4f2effa4ba7b910160405180910390a25060019392505050565b60d48181548110611d1c575f80fd5b60cf8260038110611fac575f80fd5b018181548110611fba575f80fd5b905f5260205f20015f91509150505481565b5f611fd561212a565b60de5460ff161561201c5760405162461bcd60e51b815260206004820152601160248201527010db185a5b48185b1c9958591e481cd95d607a1b6044820152606401610bf5565b5060de805460ff1916600190811790915590565b61203861212a565b5f5b8181101561121e57600160e35f858585818110612059576120596136c1565b905060200201602081019061206e91906131ef565b6001600160a01b0316815260208101919091526040015f20805460ff19169115159190911790558061209f816136d5565b91505061203a565b6120af61212a565b6001600160a01b0381166121145760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610bf5565b61169a81612a54565b61212561212a565b60e055565b6065546001600160a01b031633146111a65760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610bf5565b60975460ff16156111a65760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b6044820152606401610bf5565b60026001540361221c5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610bf5565b6002600155565b5f61222d826117df565b90505f61223861169d565b60cc546122459084613619565b61224f91906136a2565b9050803410156122905760405162461bcd60e51b815260206004820152600c60248201526b13195cdcc81c185e5b595b9d60a21b6044820152606401610bf5565b8260c95f8282546122a1919061368f565b909155505060d254156122c5578260d25f8282546122bf919061368f565b90915550505b5f60d25460c954116122d95760d2546122dd565b60c9545b905060cf5f0160ce54815481106122f6576122f66136c1565b905f5260205f20015481118061232c575060cf60020160ce548154811061231f5761231f6136c1565b905f5260205f2001544210155b156124525760cf60020160ce5481548110612349576123496136c1565b905f5260205f200154421061238b578360cf5f0160ce5481548110612370576123706136c1565b905f5260205f200154612383919061368f565b60d2556123a5565b60d754600160a01b900460ff16156123a5576123a56129e6565b5f60cf810160ce54815481106123bd576123bd6136c1565b905f5260205f20015482116123fc578160cf5f0160ce54815481106123e4576123e46136c1565b905f5260205f2001546123f791906136ed565b6123fe565b5f5b60d58054600181810183555f9283527f51858de9989bf7441865ebdadbf7382c8838edbf830f5d86a9a51ac773676dd690910183905560ce8054939450909290919061244b90849061368f565b9091555050505b60cc5461245f9085613619565b335f90815260dd60205260408120805490919061247d90849061368f565b925050819055508260d35f828254612495919061368f565b909155505060d7546124b0906001600160a01b031683612f42565b5f6124bb83346136ed565b905080156124cd576124cd3382612f42565b6040805184815260208101869052428183015290515f91879133917f4d8aead3491b7eba4b5c7a65fc17e493b9e63f9e433522fc5f6a85a168fc9d36919081900360600190a45050505050565b60df546001600160a01b03166391c61966336040516001600160e01b031960e084901b1681526001600160a01b039091166004820152602481018490526044015f604051808303815f87803b158015612571575f80fd5b505af1158015612583573d5f803e3d5ffd5b5050505050565b60e0545f9081036125d35760405162461bcd60e51b815260206004820152601360248201527213595c9adb19481c9bdbdd081b9bdd081cd95d606a1b6044820152606401610bf5565b335f90815260e2602052604090205460ff16156126325760405162461bcd60e51b815260206004820152601b60248201527f54686973204164647265737320697320426c61636b6c697374656400000000006044820152606401610bf5565b60de54610100900460ff16156126a057335f90815260e3602052604090205460ff166126a05760405162461bcd60e51b815260206004820152601e60248201527f55736572206e6f742077686974656c697374656420666f7220636c61696d00006044820152606401610bf5565b604080513360208201529081018490525f9060600160408051601f19818403018152828252805160209182012090830152016040516020818303038152906040528051906020012090506126f78360e05483613014565b6127335760405162461bcd60e51b815260206004820152600d60248201526c24b73b30b634b210383937b7b360991b6044820152606401610bf5565b335f90815260e1602052604081205461274c90866136ed565b90505f81116127905760405162461bcd60e51b815260206004820152601060248201526f4e6f7468696e6720746f20636c61696d60801b6044820152606401610bf5565b60de546040516370a0823160e01b8152306004820152620100009091046001600160a01b0316906370a0823190602401602060405180830381865afa1580156127db573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906127ff9190613630565b8111156128605760405162461bcd60e51b815260206004820152602960248201527f416d6f756e74206578636565647320746f6b656e732072656d61696e696e6720604482015268666f7220636c61696d60b81b6064820152608401610bf5565b335f90815260e160205260408120805483929061287e90849061368f565b90915550506040805182815242602082015233917f9923b4306c6c030f2bdfbf156517d5983b87e15b96176da122cd4f2effa4ba7b910160405180910390a2949350505050565b60de545f906201000090046001600160a01b031663a9059cbb336040516001600160e01b031960e084901b1681526001600160a01b039091166004820152602481018590526044016020604051808303815f875af1158015612929573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061294d91906137dc565b905080610d7e5760405162461bcd60e51b8152602060048201526015602482015274151bdad95b881d1c985b9cd9995c8819985a5b1959605a1b6044820152606401610bf5565b61299c613029565b6097805460ff191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa335b6040516001600160a01b03909116815260200160405180910390a1565b5f5b60ce5460d1546129f891906136ed565b81101561169a5760d654612a0c9082613619565b612a16904261368f565b60ce5460d190612a2790849061368f565b81548110612a3757612a376136c1565b5f9182526020909120015580612a4c816136d5565b9150506129e8565b606580546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0905f90a35050565b612aad612184565b6097805460ff191660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a2586129c93390565b5f612aec826117df565b90508160c95f828254612aff919061368f565b909155505060d25415612b23578160d25f828254612b1d919061368f565b90915550505b5f60d25460c95411612b375760d254612b3b565b60c9545b905060cf5f0160ce5481548110612b5457612b546136c1565b905f5260205f200154811180612b8a575060cf60020160ce5481548110612b7d57612b7d6136c1565b905f5260205f2001544210155b15612cb05760cf60020160ce5481548110612ba757612ba76136c1565b905f5260205f2001544210612be9578260cf5f0160ce5481548110612bce57612bce6136c1565b905f5260205f200154612be1919061368f565b60d255612c03565b60d754600160a01b900460ff1615612c0357612c036129e6565b5f60cf810160ce5481548110612c1b57612c1b6136c1565b905f5260205f2001548211612c5a578160cf5f0160ce5481548110612c4257612c426136c1565b905f5260205f200154612c5591906136ed565b612c5c565b5f5b60d58054600181810183555f9283527f51858de9989bf7441865ebdadbf7382c8838edbf830f5d86a9a51ac773676dd690910183905560ce80549394509092909190612ca990849061368f565b9091555050505b60cc54612cbd9084613619565b335f90815260dd602052604081208054909190612cdb90849061368f565b925050819055508160d35f828254612cf3919061368f565b909155505060d9545f906001600160a01b031663dd62ed3e336040516001600160e01b031960e084901b1681526001600160a01b039091166004820152306024820152604401602060405180830381865afa158015612d54573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612d789190613630565b90505f612d8a64e8d4a51000856136a2565b905081811115612de65760405162461bcd60e51b815260206004820152602160248201527f4d616b65207375726520746f2061646420656e6f75676820616c6c6f77616e636044820152606560f81b6064820152608401610bf5565b60d9545f906001600160a01b03163360d7546040516001600160a01b039283166024820152911660448201526064810184905260840160408051601f198184030181529181526020820180516001600160e01b03166323b872dd60e01b17905251612e5191906137f7565b5f604051808303815f865af19150503d805f8114612e8a576040519150601f19603f3d011682016040523d82523d5f602084013e612e8f565b606091505b5050905080612ed75760405162461bcd60e51b8152602060048201526014602482015273151bdad95b881c185e5b595b9d0819985a5b195960621b6044820152606401610bf5565b60d9546001600160a01b031686336001600160a01b03167f4d8aead3491b7eba4b5c7a65fc17e493b9e63f9e433522fc5f6a85a168fc9d36858942604051612f32939291909283526020830191909152604082015260600190565b60405180910390a4505050505050565b80471015612f805760405162461bcd60e51b815260206004820152600b60248201526a4c6f772062616c616e636560a81b6044820152606401610bf5565b5f826001600160a01b0316826040515f6040518083038185875af1925050503d805f8114612fc9576040519150601f19603f3d011682016040523d82523d5f602084013e612fce565b606091505b505090508061121e5760405162461bcd60e51b81526020600482015260126024820152711155120814185e5b595b9d0819985a5b195960721b6044820152606401610bf5565b5f826130208584613072565b14949350505050565b60975460ff166111a65760405162461bcd60e51b815260206004820152601460248201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b6044820152606401610bf5565b5f81815b84518110156130b6576130a282868381518110613095576130956136c1565b60200260200101516130be565b9150806130ae816136d5565b915050613076565b509392505050565b5f8183106130d8575f828152602084905260409020611024565b505f9182526020526040902090565b8260038101928215613127579160200282015b828111156131275782518051613117918491602090910190613137565b50916020019190600101906130fa565b5061313392915061317c565b5090565b828054828255905f5260205f20908101928215613170579160200282015b82811115613170578251825591602001919060010190613155565b50613133929150613198565b80821115613133575f61318f82826131ac565b5060010161317c565b5b80821115613133575f8155600101613199565b5080545f8255905f5260205f209081019061169a9190613198565b801515811461169a575f80fd5b5f602082840312156131e4575f80fd5b8135611024816131c7565b5f602082840312156131ff575f80fd5b81356001600160a01b0381168114611024575f80fd5b5f8060408385031215613226575f80fd5b50508035926020909101359150565b5f60208284031215613245575f80fd5b5035919050565b634e487b7160e01b5f52604160045260245ffd5b6040516060810167ffffffffffffffff811182821017156132835761328361324c565b60405290565b604051601f8201601f1916810167ffffffffffffffff811182821017156132b2576132b261324c565b604052919050565b5f67ffffffffffffffff8211156132d3576132d361324c565b5060051b60200190565b5f80604083850312156132ee575f80fd5b8235915060208084013567ffffffffffffffff81111561330c575f80fd5b8401601f8101861361331c575f80fd5b803561332f61332a826132ba565b613289565b81815260059190911b8201830190838101908883111561334d575f80fd5b928401925b8284101561336b57833582529284019290840190613352565b80955050505050509250929050565b5f805f806080858703121561338d575f80fd5b5050823594602084013594506040840135936060013592509050565b5f80602083850312156133ba575f80fd5b823567ffffffffffffffff808211156133d1575f80fd5b818501915085601f8301126133e4575f80fd5b8135818111156133f2575f80fd5b8660208260051b8501011115613406575f80fd5b60209290920196919550909350505050565b5f6020808385031215613429575f80fd5b823567ffffffffffffffff80821115613440575f80fd5b8185019150601f8681840112613454575f80fd5b61345c613260565b80606085018981111561346d575f80fd5b855b818110156134f157803586811115613486575f8081fd5b87018581018c13613496575f8081fd5b80356134a461332a826132ba565b81815260059190911b82018a01908a8101908e8311156134c3575f8081fd5b928b01925b828410156134e15783358252928b0192908b01906134c8565b875250505092870192870161346f565b50909998505050505050505050565b5f805f60608486031215613512575f80fd5b505081359360208301359350604090920135919050565b602080825282518282018190525f9190848201906040850190845b8181101561356057835183529284019291840191600101613544565b50909695505050505050565b60208082526017908201527f496e76616c69642074696d6520666f7220627579696e67000000000000000000604082015260600190565b602080825260139082015272125b9d985b1a59081cd85b1948185b5bdd5b9d606a1b604082015260600190565b6020808252818101527f416d6f756e742065786365656473206d617820746f6b656e7320746f20627579604082015260600190565b634e487b7160e01b5f52601160045260245ffd5b80820281158282048414176110a2576110a2613605565b5f60208284031215613640575f80fd5b5051919050565b60208082526028908201527f416d6f756e74206578636565647320746f6b656e732072656d61696e696e6720604082015267666f722073616c6560c01b606082015260800190565b808201808211156110a2576110a2613605565b5f826136bc57634e487b7160e01b5f52601260045260245ffd5b500490565b634e487b7160e01b5f52603260045260245ffd5b5f600182016136e6576136e6613605565b5060010190565b818103818111156110a2576110a2613605565b805169ffffffffffffffffffff81168114613719575f80fd5b919050565b5f805f805f60a08688031215613732575f80fd5b61373b86613700565b945060208601519350604086015192506060860151915061375e60808701613700565b90509295509295909350565b8082025f8212600160ff1b8414161561378557613785613605565b81810583148215176110a2576110a2613605565b60208082526023908201527f43616e74205075726368617365204d6f726520696e20696e646976696475616c604082015262040e8f60eb1b606082015260800190565b5f602082840312156137ec575f80fd5b8151611024816131c7565b5f82515f5b8181101561381657602081860181015185830152016137fc565b505f92019182525091905056fea26469706673582212206d92aa41b45e1f64a72a9c7cd0b1d1d378f9f390ffc21ce3f555a90eebdb802564736f6c63430008150033
Deployed Bytecode
0x6080604052600436106103c9575f3560e01c806389daf799116101f4578063c49cc64511610113578063e985e367116100a8578063f2fde38b11610078578063f2fde38b14610ad3578063f597573f14610af2578063f851a44014610b11578063fd1e296214610b30578063fe575a8714610b4f575f80fd5b8063e985e36714610a66578063eadd94ec14610a8b578063ecbfc07714610aa0578063edec5f2714610ab4575f80fd5b8063d279a321116100e3578063d279a321146109ea578063e19648db14610a09578063e32204dd14610a28578063e6da921314610a47575f80fd5b8063c49cc64514610983578063c8adff01146109a2578063cad00556146109b6578063cff805ab146109d5575f80fd5b8063a6d42e4e11610189578063b025384711610159578063b0253847146108fa578063ba166a3914610919578063bb3d676a14610945578063c23326f314610964575f80fd5b8063a6d42e4e14610884578063a7c60160146108a3578063ae104265146108c2578063ae87fc4b146108e1575f80fd5b80638e15f473116101c45780638e15f473146108275780639a89c1fb1461083b5780639c4dab521461085a5780639cfa0f7c1461086f575f80fd5b806389daf799146107ac5780638afbf669146107cb5780638d9830bd146107df5780638da5cb5b1461080a575f80fd5b80633f4ba83a116102eb5780635ea8293411610280578063704b6c0211610250578063704b6c021461073d578063715018a61461075c5780637649b9571461077057806378e97925146107835780638456cb5914610798575f80fd5b80635ea82934146106be57806363b20117146106f557806363e408791461070a578063641046f414610729575f80fd5b806354a08606116102bb57806354a08606146106505780635bc34f71146106645780635c975abb146106795780635df4f35314610690575f80fd5b80633f4ba83a146105ea57806343568eae146105fe57806353d9920714610613578063548db17414610631575f80fd5b806329a5a0b61161036157806336d76a951161033157806336d76a95146105535780633af32abf146105725780633b7fcdca146105a05780633d9c8d8b146105cb575f80fd5b806329a5a0b6146104eb5780632f52ebb71461050a5780633197cbb61461052957806333f761781461053e575f80fd5b80631ddc60911161039c5780631ddc60911461046e5780631fa2bc921461048d57806323a8f1c0146104ad578063278c278b146104cc575f80fd5b80630a200fc7146103cd5780630ba36dcd146103ee5780630dc9c8381461042c5780631d1ee4a31461044b575b5f80fd5b3480156103d8575f80fd5b506103ec6103e73660046131d4565b610b7d565b005b3480156103f9575f80fd5b506104196104083660046131ef565b60db6020525f908152604090205481565b6040519081526020015b60405180910390f35b348015610437575f80fd5b506103ec610446366004613215565b610ba3565b61045e610459366004613235565b610d82565b6040519015158152602001610423565b348015610479575f80fd5b506103ec6104883660046131d4565b610f27565b348015610498575f80fd5b5060d75461045e90600160a01b900460ff1681565b3480156104b8575f80fd5b506103ec6104c7366004613235565b610f49565b3480156104d7575f80fd5b506103ec6104e6366004613235565b610f56565b3480156104f6575f80fd5b50610419610505366004613235565b610ff8565b348015610515575f80fd5b5061045e6105243660046132dd565b61102b565b348015610534575f80fd5b5061041960cb5481565b348015610549575f80fd5b5061041960cc5481565b34801561055e575f80fd5b5061045e61056d3660046132dd565b6110a8565b34801561057d575f80fd5b5061045e61058c3660046131ef565b60e36020525f908152604090205460ff1681565b3480156105ab575f80fd5b506104196105ba3660046131ef565b60e16020525f908152604090205481565b3480156105d6575f80fd5b5061045e6105e536600461337a565b6110c7565b3480156105f5575f80fd5b506103ec611196565b348015610609575f80fd5b5061041960d65481565b34801561061e575f80fd5b5060de5461045e90610100900460ff1681565b34801561063c575f80fd5b506103ec61064b3660046133a9565b6111a8565b34801561065b575f80fd5b506103ec611223565b34801561066f575f80fd5b5061041960ce5481565b348015610684575f80fd5b5060975460ff1661045e565b34801561069b575f80fd5b5061045e6106aa3660046131ef565b60dc6020525f908152604090205460ff1681565b3480156106c9575f80fd5b5060df546106dd906001600160a01b031681565b6040516001600160a01b039091168152602001610423565b348015610700575f80fd5b5061041960c95481565b348015610715575f80fd5b50610419610724366004613235565b6112f7565b348015610734575f80fd5b506103ec611312565b348015610748575f80fd5b506103ec6107573660046131ef565b611476565b348015610767575f80fd5b506103ec6114a0565b61045e61077e366004613235565b6114b1565b34801561078e575f80fd5b5061041960ca5481565b3480156107a3575f80fd5b506103ec61154a565b3480156107b7575f80fd5b506103ec6107c63660046133a9565b61155a565b3480156107d6575f80fd5b506103ec6115d0565b3480156107ea575f80fd5b506104196107f93660046131ef565b60dd6020525f908152604090205481565b348015610815575f80fd5b506065546001600160a01b03166106dd565b348015610832575f80fd5b5061041961169d565b348015610846575f80fd5b506103ec610855366004613215565b61172a565b348015610865575f80fd5b5061041960e05481565b34801561087a575f80fd5b5061041960cd5481565b34801561088f575f80fd5b506103ec61089e366004613418565b61173d565b3480156108ae575f80fd5b5061045e6108bd366004613235565b611752565b3480156108cd575f80fd5b506104196108dc366004613235565b6117df565b3480156108ec575f80fd5b5060de5461045e9060ff1681565b348015610905575f80fd5b5061045e610914366004613500565b611ac1565b348015610924575f80fd5b50610938610933366004613235565b611c2c565b6040516104239190613529565b348015610950575f80fd5b506103ec61095f3660046133a9565b611c96565b34801561096f575f80fd5b5061041961097e366004613235565b611d0d565b34801561098e575f80fd5b5060da546106dd906001600160a01b031681565b3480156109ad575f80fd5b50610938611d2c565b3480156109c1575f80fd5b506103ec6109d03660046131ef565b611d82565b3480156109e0575f80fd5b5061041960d25481565b3480156109f5575f80fd5b5061045e610a04366004613235565b611dfb565b348015610a14575f80fd5b50610419610a23366004613235565b611f8e565b348015610a33575f80fd5b5060d7546106dd906001600160a01b031681565b348015610a52575f80fd5b50610419610a61366004613215565b611f9d565b348015610a71575f80fd5b5060de546106dd906201000090046001600160a01b031681565b348015610a96575f80fd5b5061041960d35481565b348015610aab575f80fd5b5061045e611fcc565b348015610abf575f80fd5b506103ec610ace3660046133a9565b612030565b348015610ade575f80fd5b506103ec610aed3660046131ef565b6120a7565b348015610afd575f80fd5b5060d9546106dd906001600160a01b031681565b348015610b1c575f80fd5b5060d8546106dd906001600160a01b031681565b348015610b3b575f80fd5b506103ec610b4a366004613235565b61211d565b348015610b5a575f80fd5b5061045e610b693660046131ef565b60e26020525f908152604090205460ff1681565b610b8561212a565b60d78054911515600160a01b0260ff60a01b19909216919091179055565b610bab61212a565b5f821180610bb857505f81115b610bfe5760405162461bcd60e51b8152602060048201526012602482015271496e76616c696420706172616d657465727360701b60448201526064015b60405180910390fd5b8115610ce35760ca544210610c4c5760405162461bcd60e51b815260206004820152601460248201527314d85b1948185b1c9958591e481cdd185c9d195960621b6044820152606401610bf5565b814210610c8f5760405162461bcd60e51b815260206004820152601160248201527014d85b19481d1a5b59481a5b881c185cdd607a1b6044820152606401610bf5565b60ca8054908390556040805182815260208101859052428183015290516414d510549560da1b917fddd2ed237e6993c9380182683f2c8bec486aaaa429528852cd74dbdb96cea0b2919081900360600190a2505b8015610d7e5760ca548111610d2c5760405162461bcd60e51b815260206004820152600f60248201526e496e76616c696420656e6454696d6560881b6044820152606401610bf5565b60cb8054908290556040805182815260208101849052428183015290516211539160ea1b917fddd2ed237e6993c9380182683f2c8bec486aaaa429528852cd74dbdb96cea0b2919081900360600190a2505b5050565b5f8160ca544210158015610d98575060cb544211155b610db45760405162461bcd60e51b8152600401610bf59061356c565b5f8111610dd35760405162461bcd60e51b8152600401610bf5906135a3565b60cd54811115610df55760405162461bcd60e51b8152600401610bf5906135d0565b610dfd612184565b610e056121ca565b5f60cc5484610e149190613619565b60de546040516370a0823160e01b81523060048201529192506201000090046001600160a01b0316906370a0823190602401602060405180830381865afa158015610e61573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610e859190613630565b811115610ea45760405162461bcd60e51b8152600401610bf590613647565b610ead84612223565b610eb68161251a565b335f90815260e1602052604081208054839290610ed490849061368f565b90915550506040805182815242602082015233917f9923b4306c6c030f2bdfbf156517d5983b87e15b96176da122cd4f2effa4ba7b910160405180910390a26001925050610f2160018055565b50919050565b610f2f61212a565b60de80549115156101000261ff0019909216919091179055565b610f5161212a565b60d655565b610f5e61212a565b5f8111610fad5760405162461bcd60e51b815260206004820152601c60248201527f5a65726f206d617820746f6b656e7320746f206275792076616c7565000000006044820152606401610bf5565b60cd8054908290556040805182815260208101849052428183015290517f76f9e5e1f6af6a9f180708b77a5c99210fbf19b91f1f194f3918c262b8edf77c9181900360600190a15050565b5f80611003836117df565b905061100d61169d565b60cc5461101a9083613619565b61102491906136a2565b9392505050565b5f611034612184565b60de5460ff166110865760405162461bcd60e51b815260206004820152601960248201527f436c61696d20686173206e6f74207374617274656420796574000000000000006044820152606401610bf5565b5f611091848461258a565b905061109c816128c5565b60019150505b92915050565b5f6110b1612184565b5f6110bc848461258a565b905061109c8161251a565b5f6110d061212a565b60cf5485106111115760405162461bcd60e51b815260206004820152600d60248201526c0d2dcecc2d8d2c840d2dcc8caf609b1b6044820152606401610bf5565b8315611139578360cf5f01868154811061112d5761112d6136c1565b5f918252602090912001555b8215611162578260cf6001018681548110611156576111566136c1565b5f918252602090912001555b811561118b578160cf600201868154811061117f5761117f6136c1565b5f918252602090912001555b506001949350505050565b61119e61212a565b6111a6612994565b565b6111b061212a565b5f5b8181101561121e575f60e35f8585858181106111d0576111d06136c1565b90506020020160208101906111e591906131ef565b6001600160a01b0316815260208101919091526040015f20805460ff191691151591909117905580611216816136d5565b9150506111b2565b505050565b5f54600490610100900460ff1615801561124357505f5460ff8083169116105b6112a65760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401610bf5565b5f805461ffff191660ff83169081176101001761ff0019169091556040519081527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a150565b5f611301826117df565b90506110a264e8d4a51000826136a2565b60d8546001600160a01b031633148061133557506065546001600160a01b031633145b6113815760405162461bcd60e51b815260206004820152601960248201527f63616c6c6572206e6f742061646d696e206f72206f776e6572000000000000006044820152606401610bf5565b60d25460d480546001810182555f919091527f9780e26d96b1f2a9a18ef8fc72d589dbf03ef788137b64f43897e83a91e7feec015560d754600160a01b900460ff16156113d0576113d06129e6565b60cf5f0160ce54815481106113e7576113e76136c1565b905f5260205f20015460d25410156114605760d25460d59060cf5f0160ce5481548110611416576114166136c1565b905f5260205f20015461142991906136ed565b81546001810183555f92835260208320015560cf0160ce5481548110611451576114516136c1565b5f9182526020909120015460d2555b60ce8054905f61146f836136d5565b9190505550565b61147e61212a565b60d880546001600160a01b0319166001600160a01b0392909216919091179055565b6114a861212a565b6111a65f612a54565b5f8160ca5442101580156114c7575060cb544211155b6114e35760405162461bcd60e51b8152600401610bf59061356c565b5f81116115025760405162461bcd60e51b8152600401610bf5906135a3565b60cd548111156115245760405162461bcd60e51b8152600401610bf5906135d0565b61152c612184565b6115346121ca565b61153d83612223565b60019150610f2160018055565b61155261212a565b6111a6612aa5565b61156261212a565b5f5b8181101561121e575f60e25f858585818110611582576115826136c1565b905060200201602081019061159791906131ef565b6001600160a01b0316815260208101919091526040015f20805460ff1916911515919091179055806115c8816136d5565b915050611564565b6115d861212a565b60de546040516370a0823160e01b81523060048201525f916201000090046001600160a01b0316906370a0823190602401602060405180830381865afa158015611624573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906116489190613630565b90505f81116116915760405162461bcd60e51b81526020600482015260156024820152744e6f20746f6b656e7320746f20776974686472617760581b6044820152606401610bf5565b61169a816128c5565b50565b5f8060da5f9054906101000a90046001600160a01b03166001600160a01b031663feaf968c6040518163ffffffff1660e01b815260040160a060405180830381865afa1580156116ef573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611713919061371e565b505050915050806402540be4006110a2919061376a565b61173261212a565b60ce9190915560d255565b61174561212a565b610d7e60cf8260036130e7565b5f8160ca544210158015611768575060cb544211155b6117845760405162461bcd60e51b8152600401610bf59061356c565b5f81116117a35760405162461bcd60e51b8152600401610bf5906135a3565b60cd548111156117c55760405162461bcd60e51b8152600401610bf5906135d0565b6117cd612184565b6117d683612ae2565b50600192915050565b5f805f60d2545f146117f35760d2546117f7565b60c9545b905060cf5f0160ce5481548110611810576118106136c1565b905f5260205f2001548185611825919061368f565b1180611851575060cf60020160ce5481548110611844576118446136c1565b905f5260205f2001544210155b15611a8b5760cf54611865906001906136ed565b60ce54106118a45760405162461bcd60e51b815260206004820152600c60248201526b57726f6e6720706172616d7360a01b6044820152606401610bf5565b60cf60020160ce54815481106118bc576118bc6136c1565b905f5260205f200154421061198a5760ce5460cf906118dc90600161368f565b815481106118ec576118ec6136c1565b905f5260205f2001548460cf5f60038110611909576119096136c1565b0160ce548154811061191d5761191d6136c1565b905f5260205f200154611930919061368f565b111561194e5760405162461bcd60e51b8152600401610bf590613799565b60ce5460d09061195f90600161368f565b8154811061196f5761196f6136c1565b905f5260205f200154846119839190613619565b9150611aba565b60ce5460cf9061199b90600161368f565b815481106119ab576119ab6136c1565b905f5260205f20015484826119c0919061368f565b11156119de5760405162461bcd60e51b8152600401610bf590613799565b5f8160cf820160ce54815481106119f7576119f76136c1565b905f5260205f200154611a0a91906136ed565b60ce5490915060d090611a1e90600161368f565b81548110611a2e57611a2e6136c1565b905f5260205f2001548186611a4391906136ed565b611a4d9190613619565b60cf60010160ce5481548110611a6557611a656136c1565b905f5260205f20015482611a799190613619565b611a83919061368f565b925050611aba565b60cf60010160ce5481548110611aa357611aa36136c1565b905f5260205f20015484611ab79190613619565b91505b5092915050565b5f611aca61212a565b5f8411611b105760405162461bcd60e51b8152602060048201526014602482015273696e76616c6964206e6f206f6620746f6b656e7360601b6044820152606401610bf5565b5f8311611b535760405162461bcd60e51b8152602060048201526011602482015270696e76616c6964206e657720707269636560781b6044820152606401610bf5565b5f8211611b955760405162461bcd60e51b815260206004820152601060248201526f696e76616c6964206e65772074696d6560801b6044820152606401610bf5565b5060cf805460018082019092557facb8d954e2cfef495862221e91bd7523613cf8808827cb33edfe4904cc51bf29019390935560d080548085019091557fe89d44c8fd6a9bac8af33ce47f56337617d449bf7ff3956b618c646de829cbcb019190915560d1805480840182555f919091527f695fb3134ad82c3b8022bc5464edd0bcc9424ef672b52245dcb6ab2374327ce3015590565b606060cf8260038110611c4157611c416136c1565b01805480602002602001604051908101604052809291908181526020018280548015611c8a57602002820191905f5260205f20905b815481526020019060010190808311611c76575b50505050509050919050565b611c9e61212a565b5f5b8181101561121e57600160e25f858585818110611cbf57611cbf6136c1565b9050602002016020810190611cd491906131ef565b6001600160a01b0316815260208101919091526040015f20805460ff191691151591909117905580611d05816136d5565b915050611ca0565b60d58181548110611d1c575f80fd5b5f91825260209091200154905081565b606060d5805480602002602001604051908101604052809291908181526020018280548015611d7857602002820191905f5260205f20905b815481526020019060010190808311611d64575b5050505050905090565b611d8a61212a565b6001600160a01b038116611dd95760405162461bcd60e51b8152602060048201526016602482015275616464726573732063616e6e6f74206265207a65726f60501b6044820152606401610bf5565b60d780546001600160a01b0319166001600160a01b0392909216919091179055565b5f8160ca544210158015611e11575060cb544211155b611e2d5760405162461bcd60e51b8152600401610bf59061356c565b5f8111611e4c5760405162461bcd60e51b8152600401610bf5906135a3565b60cd54811115611e6e5760405162461bcd60e51b8152600401610bf5906135d0565b611e76612184565b5f60cc5484611e859190613619565b60de546040516370a0823160e01b81523060048201529192506201000090046001600160a01b0316906370a0823190602401602060405180830381865afa158015611ed2573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611ef69190613630565b811115611f155760405162461bcd60e51b8152600401610bf590613647565b611f1e84612ae2565b611f278161251a565b335f90815260e1602052604081208054839290611f4590849061368f565b90915550506040805182815242602082015233917f9923b4306c6c030f2bdfbf156517d5983b87e15b96176da122cd4f2effa4ba7b910160405180910390a25060019392505050565b60d48181548110611d1c575f80fd5b60cf8260038110611fac575f80fd5b018181548110611fba575f80fd5b905f5260205f20015f91509150505481565b5f611fd561212a565b60de5460ff161561201c5760405162461bcd60e51b815260206004820152601160248201527010db185a5b48185b1c9958591e481cd95d607a1b6044820152606401610bf5565b5060de805460ff1916600190811790915590565b61203861212a565b5f5b8181101561121e57600160e35f858585818110612059576120596136c1565b905060200201602081019061206e91906131ef565b6001600160a01b0316815260208101919091526040015f20805460ff19169115159190911790558061209f816136d5565b91505061203a565b6120af61212a565b6001600160a01b0381166121145760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610bf5565b61169a81612a54565b61212561212a565b60e055565b6065546001600160a01b031633146111a65760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610bf5565b60975460ff16156111a65760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b6044820152606401610bf5565b60026001540361221c5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610bf5565b6002600155565b5f61222d826117df565b90505f61223861169d565b60cc546122459084613619565b61224f91906136a2565b9050803410156122905760405162461bcd60e51b815260206004820152600c60248201526b13195cdcc81c185e5b595b9d60a21b6044820152606401610bf5565b8260c95f8282546122a1919061368f565b909155505060d254156122c5578260d25f8282546122bf919061368f565b90915550505b5f60d25460c954116122d95760d2546122dd565b60c9545b905060cf5f0160ce54815481106122f6576122f66136c1565b905f5260205f20015481118061232c575060cf60020160ce548154811061231f5761231f6136c1565b905f5260205f2001544210155b156124525760cf60020160ce5481548110612349576123496136c1565b905f5260205f200154421061238b578360cf5f0160ce5481548110612370576123706136c1565b905f5260205f200154612383919061368f565b60d2556123a5565b60d754600160a01b900460ff16156123a5576123a56129e6565b5f60cf810160ce54815481106123bd576123bd6136c1565b905f5260205f20015482116123fc578160cf5f0160ce54815481106123e4576123e46136c1565b905f5260205f2001546123f791906136ed565b6123fe565b5f5b60d58054600181810183555f9283527f51858de9989bf7441865ebdadbf7382c8838edbf830f5d86a9a51ac773676dd690910183905560ce8054939450909290919061244b90849061368f565b9091555050505b60cc5461245f9085613619565b335f90815260dd60205260408120805490919061247d90849061368f565b925050819055508260d35f828254612495919061368f565b909155505060d7546124b0906001600160a01b031683612f42565b5f6124bb83346136ed565b905080156124cd576124cd3382612f42565b6040805184815260208101869052428183015290515f91879133917f4d8aead3491b7eba4b5c7a65fc17e493b9e63f9e433522fc5f6a85a168fc9d36919081900360600190a45050505050565b60df546001600160a01b03166391c61966336040516001600160e01b031960e084901b1681526001600160a01b039091166004820152602481018490526044015f604051808303815f87803b158015612571575f80fd5b505af1158015612583573d5f803e3d5ffd5b5050505050565b60e0545f9081036125d35760405162461bcd60e51b815260206004820152601360248201527213595c9adb19481c9bdbdd081b9bdd081cd95d606a1b6044820152606401610bf5565b335f90815260e2602052604090205460ff16156126325760405162461bcd60e51b815260206004820152601b60248201527f54686973204164647265737320697320426c61636b6c697374656400000000006044820152606401610bf5565b60de54610100900460ff16156126a057335f90815260e3602052604090205460ff166126a05760405162461bcd60e51b815260206004820152601e60248201527f55736572206e6f742077686974656c697374656420666f7220636c61696d00006044820152606401610bf5565b604080513360208201529081018490525f9060600160408051601f19818403018152828252805160209182012090830152016040516020818303038152906040528051906020012090506126f78360e05483613014565b6127335760405162461bcd60e51b815260206004820152600d60248201526c24b73b30b634b210383937b7b360991b6044820152606401610bf5565b335f90815260e1602052604081205461274c90866136ed565b90505f81116127905760405162461bcd60e51b815260206004820152601060248201526f4e6f7468696e6720746f20636c61696d60801b6044820152606401610bf5565b60de546040516370a0823160e01b8152306004820152620100009091046001600160a01b0316906370a0823190602401602060405180830381865afa1580156127db573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906127ff9190613630565b8111156128605760405162461bcd60e51b815260206004820152602960248201527f416d6f756e74206578636565647320746f6b656e732072656d61696e696e6720604482015268666f7220636c61696d60b81b6064820152608401610bf5565b335f90815260e160205260408120805483929061287e90849061368f565b90915550506040805182815242602082015233917f9923b4306c6c030f2bdfbf156517d5983b87e15b96176da122cd4f2effa4ba7b910160405180910390a2949350505050565b60de545f906201000090046001600160a01b031663a9059cbb336040516001600160e01b031960e084901b1681526001600160a01b039091166004820152602481018590526044016020604051808303815f875af1158015612929573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061294d91906137dc565b905080610d7e5760405162461bcd60e51b8152602060048201526015602482015274151bdad95b881d1c985b9cd9995c8819985a5b1959605a1b6044820152606401610bf5565b61299c613029565b6097805460ff191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa335b6040516001600160a01b03909116815260200160405180910390a1565b5f5b60ce5460d1546129f891906136ed565b81101561169a5760d654612a0c9082613619565b612a16904261368f565b60ce5460d190612a2790849061368f565b81548110612a3757612a376136c1565b5f9182526020909120015580612a4c816136d5565b9150506129e8565b606580546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0905f90a35050565b612aad612184565b6097805460ff191660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a2586129c93390565b5f612aec826117df565b90508160c95f828254612aff919061368f565b909155505060d25415612b23578160d25f828254612b1d919061368f565b90915550505b5f60d25460c95411612b375760d254612b3b565b60c9545b905060cf5f0160ce5481548110612b5457612b546136c1565b905f5260205f200154811180612b8a575060cf60020160ce5481548110612b7d57612b7d6136c1565b905f5260205f2001544210155b15612cb05760cf60020160ce5481548110612ba757612ba76136c1565b905f5260205f2001544210612be9578260cf5f0160ce5481548110612bce57612bce6136c1565b905f5260205f200154612be1919061368f565b60d255612c03565b60d754600160a01b900460ff1615612c0357612c036129e6565b5f60cf810160ce5481548110612c1b57612c1b6136c1565b905f5260205f2001548211612c5a578160cf5f0160ce5481548110612c4257612c426136c1565b905f5260205f200154612c5591906136ed565b612c5c565b5f5b60d58054600181810183555f9283527f51858de9989bf7441865ebdadbf7382c8838edbf830f5d86a9a51ac773676dd690910183905560ce80549394509092909190612ca990849061368f565b9091555050505b60cc54612cbd9084613619565b335f90815260dd602052604081208054909190612cdb90849061368f565b925050819055508160d35f828254612cf3919061368f565b909155505060d9545f906001600160a01b031663dd62ed3e336040516001600160e01b031960e084901b1681526001600160a01b039091166004820152306024820152604401602060405180830381865afa158015612d54573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612d789190613630565b90505f612d8a64e8d4a51000856136a2565b905081811115612de65760405162461bcd60e51b815260206004820152602160248201527f4d616b65207375726520746f2061646420656e6f75676820616c6c6f77616e636044820152606560f81b6064820152608401610bf5565b60d9545f906001600160a01b03163360d7546040516001600160a01b039283166024820152911660448201526064810184905260840160408051601f198184030181529181526020820180516001600160e01b03166323b872dd60e01b17905251612e5191906137f7565b5f604051808303815f865af19150503d805f8114612e8a576040519150601f19603f3d011682016040523d82523d5f602084013e612e8f565b606091505b5050905080612ed75760405162461bcd60e51b8152602060048201526014602482015273151bdad95b881c185e5b595b9d0819985a5b195960621b6044820152606401610bf5565b60d9546001600160a01b031686336001600160a01b03167f4d8aead3491b7eba4b5c7a65fc17e493b9e63f9e433522fc5f6a85a168fc9d36858942604051612f32939291909283526020830191909152604082015260600190565b60405180910390a4505050505050565b80471015612f805760405162461bcd60e51b815260206004820152600b60248201526a4c6f772062616c616e636560a81b6044820152606401610bf5565b5f826001600160a01b0316826040515f6040518083038185875af1925050503d805f8114612fc9576040519150601f19603f3d011682016040523d82523d5f602084013e612fce565b606091505b505090508061121e5760405162461bcd60e51b81526020600482015260126024820152711155120814185e5b595b9d0819985a5b195960721b6044820152606401610bf5565b5f826130208584613072565b14949350505050565b60975460ff166111a65760405162461bcd60e51b815260206004820152601460248201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b6044820152606401610bf5565b5f81815b84518110156130b6576130a282868381518110613095576130956136c1565b60200260200101516130be565b9150806130ae816136d5565b915050613076565b509392505050565b5f8183106130d8575f828152602084905260409020611024565b505f9182526020526040902090565b8260038101928215613127579160200282015b828111156131275782518051613117918491602090910190613137565b50916020019190600101906130fa565b5061313392915061317c565b5090565b828054828255905f5260205f20908101928215613170579160200282015b82811115613170578251825591602001919060010190613155565b50613133929150613198565b80821115613133575f61318f82826131ac565b5060010161317c565b5b80821115613133575f8155600101613199565b5080545f8255905f5260205f209081019061169a9190613198565b801515811461169a575f80fd5b5f602082840312156131e4575f80fd5b8135611024816131c7565b5f602082840312156131ff575f80fd5b81356001600160a01b0381168114611024575f80fd5b5f8060408385031215613226575f80fd5b50508035926020909101359150565b5f60208284031215613245575f80fd5b5035919050565b634e487b7160e01b5f52604160045260245ffd5b6040516060810167ffffffffffffffff811182821017156132835761328361324c565b60405290565b604051601f8201601f1916810167ffffffffffffffff811182821017156132b2576132b261324c565b604052919050565b5f67ffffffffffffffff8211156132d3576132d361324c565b5060051b60200190565b5f80604083850312156132ee575f80fd5b8235915060208084013567ffffffffffffffff81111561330c575f80fd5b8401601f8101861361331c575f80fd5b803561332f61332a826132ba565b613289565b81815260059190911b8201830190838101908883111561334d575f80fd5b928401925b8284101561336b57833582529284019290840190613352565b80955050505050509250929050565b5f805f806080858703121561338d575f80fd5b5050823594602084013594506040840135936060013592509050565b5f80602083850312156133ba575f80fd5b823567ffffffffffffffff808211156133d1575f80fd5b818501915085601f8301126133e4575f80fd5b8135818111156133f2575f80fd5b8660208260051b8501011115613406575f80fd5b60209290920196919550909350505050565b5f6020808385031215613429575f80fd5b823567ffffffffffffffff80821115613440575f80fd5b8185019150601f8681840112613454575f80fd5b61345c613260565b80606085018981111561346d575f80fd5b855b818110156134f157803586811115613486575f8081fd5b87018581018c13613496575f8081fd5b80356134a461332a826132ba565b81815260059190911b82018a01908a8101908e8311156134c3575f8081fd5b928b01925b828410156134e15783358252928b0192908b01906134c8565b875250505092870192870161346f565b50909998505050505050505050565b5f805f60608486031215613512575f80fd5b505081359360208301359350604090920135919050565b602080825282518282018190525f9190848201906040850190845b8181101561356057835183529284019291840191600101613544565b50909695505050505050565b60208082526017908201527f496e76616c69642074696d6520666f7220627579696e67000000000000000000604082015260600190565b602080825260139082015272125b9d985b1a59081cd85b1948185b5bdd5b9d606a1b604082015260600190565b6020808252818101527f416d6f756e742065786365656473206d617820746f6b656e7320746f20627579604082015260600190565b634e487b7160e01b5f52601160045260245ffd5b80820281158282048414176110a2576110a2613605565b5f60208284031215613640575f80fd5b5051919050565b60208082526028908201527f416d6f756e74206578636565647320746f6b656e732072656d61696e696e6720604082015267666f722073616c6560c01b606082015260800190565b808201808211156110a2576110a2613605565b5f826136bc57634e487b7160e01b5f52601260045260245ffd5b500490565b634e487b7160e01b5f52603260045260245ffd5b5f600182016136e6576136e6613605565b5060010190565b818103818111156110a2576110a2613605565b805169ffffffffffffffffffff81168114613719575f80fd5b919050565b5f805f805f60a08688031215613732575f80fd5b61373b86613700565b945060208601519350604086015192506060860151915061375e60808701613700565b90509295509295909350565b8082025f8212600160ff1b8414161561378557613785613605565b81810583148215176110a2576110a2613605565b60208082526023908201527f43616e74205075726368617365204d6f726520696e20696e646976696475616c604082015262040e8f60eb1b606082015260800190565b5f602082840312156137ec575f80fd5b8151611024816131c7565b5f82515f5b8181101561381657602081860181015185830152016137fc565b505f92019182525091905056fea26469706673582212206d92aa41b45e1f64a72a9c7cd0b1d1d378f9f390ffc21ce3f555a90eebdb802564736f6c63430008150033
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 27 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
Loading...
Loading
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.