Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
Latest 1 internal transaction
Advanced mode:
Parent Transaction Hash | Block | From | To | |||
---|---|---|---|---|---|---|
13705903 | 1090 days ago | Contract Creation | 0 ETH |
Loading...
Loading
Contract Name:
IDOSecController
Compiler Version
v0.8.2+commit.661d1103
Optimization Enabled:
Yes with 800 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "@openzeppelin/contracts/access/Ownable.sol"; import "../interfaces/IDOSec/IIDOSecController.sol"; import "../interfaces/IDO/IIDOTier.sol"; import "./IDOSec.sol"; /** @title IDOController * @notice This contract creates IDOs and handle configuration */ contract IDOSecController is Ownable, IIDOSecController { // mapping to check operator mapping(address => bool) public override isOperator; // ido address[] public IDOs; // fee address public feeReceipient; uint256 public feePercent; // 1000: 100%; modifier isOperatorOrOwner() { require(isOperator[msg.sender] || owner() == msg.sender, "Not owner or operator"); _; } constructor(address _feeReceipient, uint256 _feePercent) { _setFeeInfo(_feeReceipient, _feePercent); isOperator[msg.sender] = true; } function getIDOsCount() external view returns (uint256) { return IDOs.length; } function getFeeInfo() external view override returns (address, uint256) { return (feeReceipient, feePercent); } /** * @notice set operator */ function setOperator(address user, bool bSet) external onlyOwner { require(user != address(0), "Invalid address"); isOperator[user] = bSet; } function _setFeeInfo(address _feeReceipient, uint256 _feePercent) internal { require(_feeReceipient != address(0), "Invalid address"); require(_feePercent < 1000, "Invalid percent"); feePercent = _feePercent; feeReceipient = _feeReceipient; } /** * @notice setFeeInfo */ function setFeeInfo(address _feeReceipient, uint256 _feePercent) external onlyOwner { _setFeeInfo(_feeReceipient, _feePercent); } /** * @notice createIDO */ function createIDO( uint256 saleTarget, address fundToken, uint256 fundTarget, uint256 startTime, uint256 endTime, uint256 claimTime, uint256 minFundAmount, uint256 fcfsAmount, string memory meta ) external isOperatorOrOwner returns (address) { IDOSec ido = new IDOSec(this, saleTarget, fundToken, fundTarget); ido.setBaseData(startTime, endTime, claimTime, minFundAmount, fcfsAmount, meta); ido.transferOwnership(msg.sender); IDOs.push(address(ido)); emit NewIDOCreated(address(ido), msg.sender); return address(ido); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "../utils/Context.sol"; /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * 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 Ownable is Context { address private _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the deployer as the initial owner. */ constructor () { address msgSender = _msgSender(); _owner = msgSender; emit OwnershipTransferred(address(0), msgSender); } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { require(owner() == _msgSender(), "Ownable: caller is not the owner"); _; } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions anymore. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby removing any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { emit OwnershipTransferred(_owner, address(0)); _owner = 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"); emit OwnershipTransferred(_owner, newOwner); _owner = newOwner; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; interface IIDOSecController { event NewIDOCreated(address indexed pool, address creator); function isOperator(address) external view returns (bool); function getFeeInfo() external view returns (address, uint256); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; interface IIDOTier { function getTier(address user) external view returns (uint256); function getMultiplier(address user) external view returns (uint256); function getTotalMultiplier() external view returns (uint256); function getMultiplierAtIndex(uint256) external view returns (uint256); function getMultiplierAtTierId(uint256 tierId) external view returns (uint256); function getTierId(address user) external view returns (uint256); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "@openzeppelin/contracts/access/Ownable.sol"; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import "@openzeppelin/contracts/security/ReentrancyGuard.sol"; import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; import "@openzeppelin/contracts/utils/structs/EnumerableSet.sol"; import "../interfaces/IDOSec/IIDOSecController.sol"; /** @title IDO contract does IDO * @notice */ contract IDOSec is Ownable, ReentrancyGuard { using SafeERC20 for IERC20; struct User { uint256 totalFunded; // total funded amount of user uint256 released; // currently released token amount } uint256 public constant ROUNDS_COUNT = 2; // 1: whitelist, 2: fcfs IIDOSecController public controller; uint256 public startTime; uint256 public endTime; uint256 public claimTime; IERC20 public saleToken; uint256 public saleTarget; uint256 public saleRaised; // 0x0 BNB, other: BEP20 address public fundToken; uint256 public fundTarget; uint256 public fundRaised; uint256 public totalReleased; // uint256 public fcfsAmount; // users' fcfs allocation uint256 public minFundAmount; string public meta; // meta data json url // all funder Addresses address[] public funderAddresses; mapping(address => User) public whitelistFunders; mapping(address => User) public fcfsFunders; // vesting info uint256 public cliffTime; // 15 = 1.5%, 1000 = 100% uint256 public distributePercentAtClaim; uint256 public vestingDuration; uint256 public vestingPeriodicity; // whitelist mapping(address => uint256) public whitelistAmount; mapping(uint256 => uint256) public roundsFundRaised; event IDOInitialized(uint256 saleTarget, address fundToken, uint256 fundTarget); event IDOBaseDataChanged( uint256 startTime, uint256 endTime, uint256 claimTime, uint256 minFundAmount, uint256 fcfsAmount, string meta ); event IDOTokenInfoChanged(uint256 saleTarget, uint256 fundTarget); event SaleTokenAddressSet(address saleToken); event VestingSet( uint256 cliffTime, uint256 distributePercentAtClaim, uint256 vestingDuration, uint256 vestingPeriodicity ); event IDOProgressChanged(address buyer, uint256 amount, uint256 fundRaised, uint256 saleRaised, uint256 roundId); event IDOClaimed(address to, uint256 amount); modifier isOperatorOrOwner() { require(controller.isOperator(msg.sender) || owner() == msg.sender, "Not owner or operator"); _; } modifier isNotStarted() { require(startTime > block.timestamp, "Already started"); _; } modifier isOngoing() { require(startTime <= block.timestamp && block.timestamp <= endTime, "Not onging"); _; } modifier isEnded() { require(block.timestamp >= endTime, "Not ended"); _; } modifier isNotEnded() { require(block.timestamp < endTime, "Ended"); _; } modifier isClaimable() { require(block.timestamp >= claimTime, "Not claimable"); _; } modifier onlyEOA() { require(tx.origin == msg.sender, "should be EOA"); _; } modifier canRaise(address addr, uint256 amount) { uint256 currentRoundId = getCurrentRoundId(); uint256 maxAllocation = getMaxAllocation(addr); require(amount > 0, "0 amount"); require(fundRaised + amount <= fundTarget, "Target hit!"); uint256 personalTotal; if (currentRoundId == 1) { personalTotal = amount + whitelistFunders[addr].totalFunded; } else if (currentRoundId == 2) { personalTotal = amount + fcfsFunders[addr].totalFunded; } require(personalTotal >= minFundAmount, "Low amount"); require(personalTotal <= maxAllocation, "Too much amount"); _; } /** * @notice constructor * * @param _controller {address} Controller address * @param _saleTarget {uint256} Total token amount to sell * @param _fundToken {address} Fund token address * @param _fundTarget {uint256} Total amount of fund Token */ constructor( IIDOSecController _controller, uint256 _saleTarget, address _fundToken, uint256 _fundTarget ) { require(address(_controller) != address(0), "Invalid"); require(_saleTarget > 0 && _fundTarget > 0, "Invalid"); saleTarget = _saleTarget; fundToken = _fundToken; fundTarget = _fundTarget; controller = _controller; emit IDOInitialized(saleTarget, fundToken, fundTarget); } /** * @notice setBaseData * * @param _startTime {uint256} timestamp of IDO start time * @param _endTime {uint256} timestamp of IDO end time * @param _claimTime {uint256} timestamp of IDO claim time * @param _minFundAmount {uint256} mimimum fund amount of users * @param _fcfsAmount {uint256} fcfsAmount of buy * @param _meta {string} url of meta data */ function setBaseData( uint256 _startTime, uint256 _endTime, uint256 _claimTime, uint256 _minFundAmount, uint256 _fcfsAmount, string memory _meta ) external isOperatorOrOwner { require(_minFundAmount > 0, "0 minFund"); require(_fcfsAmount > 0, "0 base"); require(_startTime > block.timestamp && _startTime < _endTime && _endTime < _claimTime, "Invalid times"); startTime = _startTime; endTime = _endTime; claimTime = _claimTime; minFundAmount = _minFundAmount; meta = _meta; fcfsAmount = _fcfsAmount; emit IDOBaseDataChanged(startTime, endTime, claimTime, minFundAmount, fcfsAmount, meta); } function getCurrentRoundId() public view returns (uint256) { if (block.timestamp < startTime || block.timestamp > endTime) { return 0; // not started } uint256 roundDuration = (endTime - startTime) / ROUNDS_COUNT; uint256 index = (block.timestamp - startTime) / roundDuration; // 1: white, 2: fcfs return index + 1; } function getRoundTotalAllocation(uint256 currentRoundId) public view returns (uint256) { if (currentRoundId == 0) { return 0; } if (currentRoundId == 1) { return fundTarget; } return fundTarget - roundsFundRaised[1]; } function getMaxAllocation(address addr) public view returns (uint256) { uint256 currentRoundId = getCurrentRoundId(); if (currentRoundId == 0) { return 0; } if (currentRoundId == 1) { // whitelist period return whitelistAmount[addr]; } return fcfsAmount; } function getFundersCount() external view returns (uint256) { return funderAddresses.length; } function getFunderInfo(address funder) external view returns (User memory) { User memory info; info.totalFunded = whitelistFunders[funder].totalFunded + fcfsFunders[funder].totalFunded; info.released = whitelistFunders[funder].released + fcfsFunders[funder].released; return info; } function setStartTime(uint256 _startTime) external isOperatorOrOwner isNotStarted { require(_startTime > block.timestamp, "Invalid"); startTime = _startTime; emit IDOBaseDataChanged(startTime, endTime, claimTime, minFundAmount, fcfsAmount, meta); } function setEndTime(uint256 _endTime) external isOperatorOrOwner isNotEnded { require(_endTime > block.timestamp && _endTime > startTime, "Invalid"); endTime = _endTime; emit IDOBaseDataChanged(startTime, endTime, claimTime, minFundAmount, fcfsAmount, meta); } function setClaimTime(uint256 _claimTime) external isOperatorOrOwner { require(_claimTime > block.timestamp && _claimTime > endTime, "Invalid"); claimTime = _claimTime; emit IDOBaseDataChanged(startTime, endTime, claimTime, minFundAmount, fcfsAmount, meta); } function setFcFsAmount(uint256 _fcfsAmount) external isOperatorOrOwner { require(_fcfsAmount > 0, "Invalid"); fcfsAmount = _fcfsAmount; emit IDOBaseDataChanged(startTime, endTime, claimTime, minFundAmount, fcfsAmount, meta); } function setMinFundAmount(uint256 _minFundAmount) external isOperatorOrOwner { require(_minFundAmount > 0, "Invalid"); minFundAmount = _minFundAmount; emit IDOBaseDataChanged(startTime, endTime, claimTime, minFundAmount, fcfsAmount, meta); } function setMeta(string memory _meta) external isOperatorOrOwner { meta = _meta; emit IDOBaseDataChanged(startTime, endTime, claimTime, minFundAmount, fcfsAmount, meta); } function setSaleToken(IERC20 _saleToken) external isOperatorOrOwner { require(address(_saleToken) != address(0), "Invalid"); saleToken = _saleToken; emit SaleTokenAddressSet(address(saleToken)); } function setSaleTarget(uint256 _saleTarget) external isOperatorOrOwner { require(_saleTarget > 0, "Invalid"); saleTarget = _saleTarget; emit IDOTokenInfoChanged(saleTarget, fundTarget); } function setFundTarget(uint256 _fundTarget) external isOperatorOrOwner { require(_fundTarget > 0, "Invalid"); fundTarget = _fundTarget; emit IDOTokenInfoChanged(saleTarget, fundTarget); } function setVestingInfo( uint256 _cliffTime, uint256 _distributePercentAtClaim, uint256 _vestingDuration, uint256 _vestingPeriodicity ) external isOperatorOrOwner { require(_cliffTime > claimTime, "Invalid Cliff"); require(_distributePercentAtClaim <= 1000, "Invalid tge"); require(_vestingDuration > 0 && _vestingPeriodicity > 0, "0 Duration or Period"); require( (_vestingDuration - (_vestingDuration / _vestingPeriodicity) * _vestingPeriodicity) == 0, "Not divided" ); cliffTime = _cliffTime; distributePercentAtClaim = _distributePercentAtClaim; vestingDuration = _vestingDuration; vestingPeriodicity = _vestingPeriodicity; emit VestingSet(cliffTime, distributePercentAtClaim, vestingDuration, vestingPeriodicity); } function withdrawRemainingSaleToken() external isOperatorOrOwner { require(block.timestamp > endTime, "IDO has not yet ended"); saleToken.safeTransfer(msg.sender, saleToken.balanceOf(address(this)) + totalReleased - saleRaised); } function withdrawFundedBNB() external isOperatorOrOwner isEnded { require(fundToken == address(0), "It's not BNB-buy pool!"); uint256 balance = address(this).balance; (address feeRecipient, uint256 feePercent) = controller.getFeeInfo(); uint256 fee = (balance * (feePercent)) / (1000); uint256 restAmount = balance - (fee); (bool success, ) = payable(feeRecipient).call{ value: fee }(""); require(success, "BNB fee pay failed"); (bool success1, ) = payable(msg.sender).call{ value: restAmount }(""); require(success1, "BNB withdraw failed"); } function withdrawFundedToken() external isOperatorOrOwner isEnded { require(fundToken != address(0), "It's not token-buy pool!"); uint256 balance = IERC20(fundToken).balanceOf(address(this)); (address feeRecipient, uint256 feePercent) = controller.getFeeInfo(); uint256 fee = (balance * feePercent) / 1000; uint256 restAmount = balance - fee; IERC20(fundToken).safeTransfer(feeRecipient, fee); IERC20(fundToken).safeTransfer(msg.sender, restAmount); } function getUnlockedTokenAmount(address addr, uint256 fundedAmount) private view returns (uint256) { require(addr != address(0), "Invalid address!"); if (block.timestamp < claimTime) return 0; uint256 totalSaleToken = (fundedAmount * saleTarget) / fundTarget; uint256 distributeAmountAtClaim = (totalSaleToken * distributePercentAtClaim) / 1000; if (cliffTime > block.timestamp) { return distributeAmountAtClaim; } if (cliffTime == 0) { // vesting info is not set yet return 0; } uint256 finalTime = cliffTime + vestingDuration - vestingPeriodicity; if (block.timestamp >= finalTime) { return totalSaleToken; } uint256 lockedAmount = totalSaleToken - distributeAmountAtClaim; uint256 totalPeridicities = vestingDuration / vestingPeriodicity; uint256 periodicityAmount = lockedAmount / totalPeridicities; uint256 currentperiodicityCount = (block.timestamp - cliffTime) / vestingPeriodicity + 1; uint256 availableAmount = periodicityAmount * currentperiodicityCount; return distributeAmountAtClaim + availableAmount; } function getWhitelistClaimableAmount(address addr) private view returns (uint256) { return getUnlockedTokenAmount(addr, whitelistFunders[addr].totalFunded) - whitelistFunders[addr].released; } function getFCFSClaimableAmount(address addr) private view returns (uint256) { return getUnlockedTokenAmount(addr, fcfsFunders[addr].totalFunded) - fcfsFunders[addr].released; } function getClaimableAmount(address addr) public view returns (uint256) { return getWhitelistClaimableAmount(addr) + getFCFSClaimableAmount(addr); } function _claimTo(address to) private { require(to != address(0), "Invalid address"); uint256 claimableAmount = getClaimableAmount(to); if (claimableAmount > 0) { whitelistFunders[to].released = whitelistFunders[to].released + getWhitelistClaimableAmount(to); fcfsFunders[to].released = fcfsFunders[to].released + getFCFSClaimableAmount(to); saleToken.safeTransfer(to, claimableAmount); totalReleased = totalReleased + claimableAmount; emit IDOClaimed(to, claimableAmount); } } function claim() external isClaimable nonReentrant onlyEOA { uint256 claimableAmount = getClaimableAmount(msg.sender); require(claimableAmount > 0, "Nothing to claim"); _claimTo(msg.sender); } function batchClaim(address[] calldata addrs) external isClaimable nonReentrant onlyEOA { for (uint256 index = 0; index < addrs.length; index++) { _claimTo(addrs[index]); } } function _processBuy(address buyer, uint256 amount) private { uint256 saleTokenAmount = (amount * saleTarget) / fundTarget; uint256 currentRoundId = getCurrentRoundId(); fundRaised = fundRaised + amount; saleRaised = saleRaised + saleTokenAmount; uint256 roundId = currentRoundId; if (currentRoundId == 1) { // whitelist if (whitelistFunders[buyer].totalFunded == 0) { funderAddresses.push(buyer); } whitelistFunders[buyer].totalFunded = whitelistFunders[buyer].totalFunded + amount; } else if (currentRoundId == 2) { // fcfs if (whitelistFunders[buyer].totalFunded == 0 && fcfsFunders[buyer].totalFunded == 0) { funderAddresses.push(buyer); } fcfsFunders[buyer].totalFunded = fcfsFunders[buyer].totalFunded + amount; } roundsFundRaised[roundId] = roundsFundRaised[roundId] + amount; emit IDOProgressChanged(buyer, amount, fundRaised, saleRaised, currentRoundId); } function buyWithBNB() public payable isOngoing canRaise(msg.sender, msg.value) onlyEOA { require(fundToken == address(0), "It's not BNB-buy pool!"); _processBuy(msg.sender, msg.value); } function buy(uint256 amount) public isOngoing canRaise(msg.sender, amount) onlyEOA { require(fundToken != address(0), "It's not token-buy pool!"); _processBuy(msg.sender, amount); IERC20(fundToken).safeTransferFrom(msg.sender, address(this), amount); } function setWhitelist(address[] calldata addrs, uint256[] calldata amounts) external isOperatorOrOwner { require(addrs.length == amounts.length, "Invalid params"); for (uint256 index = 0; index < addrs.length; index++) { whitelistAmount[addrs[index]] = amounts[index]; } } receive() external payable { revert("Something went wrong!"); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /* * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract Context { function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691 return msg.data; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @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 `recipient`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address recipient, 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 `sender` to `recipient` 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 sender, address recipient, uint256 amount) external returns (bool); /** * @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); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /** * @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 ReentrancyGuard { // Booleans are more expensive than uint256 or any type that takes up a full // word because each write operation emits an extra SLOAD to first read the // slot's contents, replace the bits taken up by the boolean, and then write // back. This is the compiler's defense against contract upgrades and // pointer aliasing, and it cannot be disabled. // The values being non-zero value makes deployment a bit more expensive, // but in exchange the refund on every call to nonReentrant will be lower in // amount. Since refunds are capped to a percentage of the total // transaction's gas, it is best to keep them low in cases like this one, to // increase the likelihood of the full refund coming into effect. uint256 private constant _NOT_ENTERED = 1; uint256 private constant _ENTERED = 2; uint256 private _status; constructor () { _status = _NOT_ENTERED; } /** * @dev Prevents a contract from calling itself, directly or indirectly. * Calling a `nonReentrant` function from another `nonReentrant` * function is not supported. It is possible to prevent this from happening * by making the `nonReentrant` function external, and make it call a * `private` function that does the actual work. */ modifier nonReentrant() { // On the first call to nonReentrant, _notEntered will be true require(_status != _ENTERED, "ReentrancyGuard: reentrant call"); // Any calls to nonReentrant after this point will fail _status = _ENTERED; _; // By storing the original value once again, a refund is triggered (see // https://eips.ethereum.org/EIPS/eip-2200) _status = _NOT_ENTERED; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "../IERC20.sol"; import "../../../utils/Address.sol"; /** * @title SafeERC20 * @dev Wrappers around ERC20 operations that throw on failure (when the token * contract returns false). Tokens that return no value (and instead revert or * throw on failure) are also supported, non-reverting calls are assumed to be * successful. * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract, * which allows you to call the safe operations as `token.safeTransfer(...)`, etc. */ library SafeERC20 { using Address for address; function safeTransfer(IERC20 token, address to, uint256 value) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value)); } function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value)); } /** * @dev Deprecated. This function has issues similar to the ones found in * {IERC20-approve}, and its usage is discouraged. * * Whenever possible, use {safeIncreaseAllowance} and * {safeDecreaseAllowance} instead. */ function safeApprove(IERC20 token, address spender, uint256 value) internal { // safeApprove should only be called when setting an initial allowance, // or when resetting it to zero. To increase and decrease it, use // 'safeIncreaseAllowance' and 'safeDecreaseAllowance' // solhint-disable-next-line max-line-length require((value == 0) || (token.allowance(address(this), spender) == 0), "SafeERC20: approve from non-zero to non-zero allowance" ); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value)); } function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal { uint256 newAllowance = token.allowance(address(this), spender) + value; _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal { unchecked { uint256 oldAllowance = token.allowance(address(this), spender); require(oldAllowance >= value, "SafeERC20: decreased allowance below zero"); uint256 newAllowance = oldAllowance - value; _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } } /** * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement * on the return value: the return value is optional (but if data is returned, it must not be false). * @param token The token targeted by the call. * @param data The call data (encoded using abi.encode or one of its variants). */ function _callOptionalReturn(IERC20 token, bytes memory data) private { // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that // the target address contains contract code and also asserts for success in the low-level call. bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed"); if (returndata.length > 0) { // Return data is optional // solhint-disable-next-line max-line-length require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed"); } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /** * @dev Library for managing * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive * types. * * Sets have the following properties: * * - Elements are added, removed, and checked for existence in constant time * (O(1)). * - Elements are enumerated in O(n). No guarantees are made on the ordering. * * ``` * contract Example { * // Add the library methods * using EnumerableSet for EnumerableSet.AddressSet; * * // Declare a set state variable * EnumerableSet.AddressSet private mySet; * } * ``` * * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`) * and `uint256` (`UintSet`) are supported. */ library EnumerableSet { // To implement this library for multiple types with as little code // repetition as possible, we write it in terms of a generic Set type with // bytes32 values. // The Set implementation uses private functions, and user-facing // implementations (such as AddressSet) are just wrappers around the // underlying Set. // This means that we can only create new EnumerableSets for types that fit // in bytes32. struct Set { // Storage of set values bytes32[] _values; // Position of the value in the `values` array, plus 1 because index 0 // means a value is not in the set. mapping (bytes32 => uint256) _indexes; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function _add(Set storage set, bytes32 value) private returns (bool) { if (!_contains(set, value)) { set._values.push(value); // The value is stored at length-1, but we add 1 to all indexes // and use 0 as a sentinel value set._indexes[value] = set._values.length; return true; } else { return false; } } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function _remove(Set storage set, bytes32 value) private returns (bool) { // We read and store the value's index to prevent multiple reads from the same storage slot uint256 valueIndex = set._indexes[value]; if (valueIndex != 0) { // Equivalent to contains(set, value) // To delete an element from the _values array in O(1), we swap the element to delete with the last one in // the array, and then remove the last element (sometimes called as 'swap and pop'). // This modifies the order of the array, as noted in {at}. uint256 toDeleteIndex = valueIndex - 1; uint256 lastIndex = set._values.length - 1; // When the value to delete is the last one, the swap operation is unnecessary. However, since this occurs // so rarely, we still do the swap anyway to avoid the gas cost of adding an 'if' statement. bytes32 lastvalue = set._values[lastIndex]; // Move the last value to the index where the value to delete is set._values[toDeleteIndex] = lastvalue; // Update the index for the moved value set._indexes[lastvalue] = valueIndex; // Replace lastvalue's index to valueIndex // Delete the slot where the moved value was stored set._values.pop(); // Delete the index for the deleted slot delete set._indexes[value]; return true; } else { return false; } } /** * @dev Returns true if the value is in the set. O(1). */ function _contains(Set storage set, bytes32 value) private view returns (bool) { return set._indexes[value] != 0; } /** * @dev Returns the number of values on the set. O(1). */ function _length(Set storage set) private view returns (uint256) { return set._values.length; } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function _at(Set storage set, uint256 index) private view returns (bytes32) { require(set._values.length > index, "EnumerableSet: index out of bounds"); return set._values[index]; } // Bytes32Set struct Bytes32Set { Set _inner; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function add(Bytes32Set storage set, bytes32 value) internal returns (bool) { return _add(set._inner, value); } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) { return _remove(set._inner, value); } /** * @dev Returns true if the value is in the set. O(1). */ function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) { return _contains(set._inner, value); } /** * @dev Returns the number of values in the set. O(1). */ function length(Bytes32Set storage set) internal view returns (uint256) { return _length(set._inner); } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) { return _at(set._inner, index); } // AddressSet struct AddressSet { Set _inner; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function add(AddressSet storage set, address value) internal returns (bool) { return _add(set._inner, bytes32(uint256(uint160(value)))); } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function remove(AddressSet storage set, address value) internal returns (bool) { return _remove(set._inner, bytes32(uint256(uint160(value)))); } /** * @dev Returns true if the value is in the set. O(1). */ function contains(AddressSet storage set, address value) internal view returns (bool) { return _contains(set._inner, bytes32(uint256(uint160(value)))); } /** * @dev Returns the number of values in the set. O(1). */ function length(AddressSet storage set) internal view returns (uint256) { return _length(set._inner); } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(AddressSet storage set, uint256 index) internal view returns (address) { return address(uint160(uint256(_at(set._inner, index)))); } // UintSet struct UintSet { Set _inner; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function add(UintSet storage set, uint256 value) internal returns (bool) { return _add(set._inner, bytes32(value)); } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function remove(UintSet storage set, uint256 value) internal returns (bool) { return _remove(set._inner, bytes32(value)); } /** * @dev Returns true if the value is in the set. O(1). */ function contains(UintSet storage set, uint256 value) internal view returns (bool) { return _contains(set._inner, bytes32(value)); } /** * @dev Returns the number of values on the set. O(1). */ function length(UintSet storage set) internal view returns (uint256) { return _length(set._inner); } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(UintSet storage set, uint256 index) internal view returns (uint256) { return uint256(_at(set._inner, index)); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /** * @dev Collection of functions related to the address type */ library Address { /** * @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 * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize, which returns 0 for contracts in // construction, since the code is only stored at the end of the // constructor execution. uint256 size; // solhint-disable-next-line no-inline-assembly assembly { size := extcodesize(account) } return size > 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://diligence.consensys.net/posts/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.5.11/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"); // solhint-disable-next-line avoid-low-level-calls, avoid-call-value (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 functionCall(target, data, "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"); require(isContract(target), "Address: call to non-contract"); // solhint-disable-next-line avoid-low-level-calls (bool success, bytes memory returndata) = target.call{ value: value }(data); return _verifyCallResult(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) { require(isContract(target), "Address: static call to non-contract"); // solhint-disable-next-line avoid-low-level-calls (bool success, bytes memory returndata) = target.staticcall(data); return _verifyCallResult(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) { require(isContract(target), "Address: delegate call to non-contract"); // solhint-disable-next-line avoid-low-level-calls (bool success, bytes memory returndata) = target.delegatecall(data); return _verifyCallResult(success, returndata, errorMessage); } function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) { if (success) { return returndata; } else { // 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 // solhint-disable-next-line no-inline-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } }
{ "metadata": { "bytecodeHash": "none" }, "optimizer": { "enabled": true, "runs": 800 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"address","name":"_feeReceipient","type":"address"},{"internalType":"uint256","name":"_feePercent","type":"uint256"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"pool","type":"address"},{"indexed":false,"internalType":"address","name":"creator","type":"address"}],"name":"NewIDOCreated","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"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"IDOs","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"saleTarget","type":"uint256"},{"internalType":"address","name":"fundToken","type":"address"},{"internalType":"uint256","name":"fundTarget","type":"uint256"},{"internalType":"uint256","name":"startTime","type":"uint256"},{"internalType":"uint256","name":"endTime","type":"uint256"},{"internalType":"uint256","name":"claimTime","type":"uint256"},{"internalType":"uint256","name":"minFundAmount","type":"uint256"},{"internalType":"uint256","name":"fcfsAmount","type":"uint256"},{"internalType":"string","name":"meta","type":"string"}],"name":"createIDO","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"feePercent","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"feeReceipient","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getFeeInfo","outputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getIDOsCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"isOperator","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_feeReceipient","type":"address"},{"internalType":"uint256","name":"_feePercent","type":"uint256"}],"name":"setFeeInfo","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"},{"internalType":"bool","name":"bSet","type":"bool"}],"name":"setOperator","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
608060405234801561001057600080fd5b50604051614e70380380614e7083398101604081905261002f91610153565b600080546001600160a01b031916339081178255604051909182917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a35061007a828261009e565b5050336000908152600160208190526040909120805460ff1916909117905561018b565b6001600160a01b0382166100eb5760405162461bcd60e51b815260206004820152600f60248201526e496e76616c6964206164647265737360881b60448201526064015b60405180910390fd5b6103e8811061012e5760405162461bcd60e51b815260206004820152600f60248201526e125b9d985b1a59081c195c98d95b9d608a1b60448201526064016100e2565b600455600380546001600160a01b0319166001600160a01b0392909216919091179055565b60008060408385031215610165578182fd5b82516001600160a01b038116811461017b578283fd5b6020939093015192949293505050565b614cd68061019a6000396000f3fe608060405234801561001057600080fd5b50600436106100d35760003560e01c80636d70f7ae11610081578063846ae9ae1161005b578063846ae9ae146101cf5780638da5cb5b146101e2578063f2fde38b146101f3576100d3565b80636d70f7ae1461018b578063715018a6146101be5780637fd6f15c146101c6576100d3565b806326af1f0a116100b257806326af1f0a1461013a5780633740ebb314610165578063558a729714610178576100d3565b806202eab7146100d85780630f2097c0146101135780631a746ae314610128575b600080fd5b6100ef6003546004546001600160a01b0390911691565b604080516001600160a01b0390931683526020830191909152015b60405180910390f35b6101266101213660046108b0565b610206565b005b6002545b60405190815260200161010a565b61014d6101483660046108d9565b610273565b6040516001600160a01b03909116815260200161010a565b60035461014d906001600160a01b031681565b610126610186366004610876565b61029d565b6101ae610199366004610855565b60016020526000908152604090205460ff1681565b604051901515815260200161010a565b61012661036a565b61012c60045481565b61014d6101dd3660046108f1565b61040e565b6000546001600160a01b031661014d565b610126610201366004610855565b61063c565b6000546001600160a01b031633146102655760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064015b60405180910390fd5b61026f828261076d565b5050565b6002818154811061028357600080fd5b6000918252602090912001546001600160a01b0316905081565b6000546001600160a01b031633146102f75760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161025c565b6001600160a01b03821661033f5760405162461bcd60e51b815260206004820152600f60248201526e496e76616c6964206164647265737360881b604482015260640161025c565b6001600160a01b03919091166000908152600160205260409020805460ff1916911515919091179055565b6000546001600160a01b031633146103c45760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161025c565b600080546040516001600160a01b03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600080546001600160a01b0319169055565b3360009081526001602052604081205460ff168061044557503361043a6000546001600160a01b031690565b6001600160a01b0316145b6104915760405162461bcd60e51b815260206004820152601560248201527f4e6f74206f776e6572206f72206f70657261746f720000000000000000000000604482015260640161025c565b6000308b8b8b6040516104a39061082b565b6001600160a01b0394851681526020810193909352921660408201526060810191909152608001604051809103906000f0801580156104e6573d6000803e3d6000fd5b50604051631d48476960e11b81529091506001600160a01b03821690633a908ed290610520908b908b908b908b908b908b906004016109f2565b600060405180830381600087803b15801561053a57600080fd5b505af115801561054e573d6000803e3d6000fd5b505060405163f2fde38b60e01b81523360048201526001600160a01b038416925063f2fde38b9150602401600060405180830381600087803b15801561059357600080fd5b505af11580156105a7573d6000803e3d6000fd5b5050600280546001810182556000919091527f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace0180546001600160a01b0319166001600160a01b0385169081179091556040513381529092507fff0fb79676a39a6f0826771efed31fcdbfca1b939daaa4586f77202abf8e9607915060200160405180910390a29a9950505050505050505050565b6000546001600160a01b031633146106965760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161025c565b6001600160a01b0381166107125760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f6464726573730000000000000000000000000000000000000000000000000000606482015260840161025c565b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b0319166001600160a01b0392909216919091179055565b6001600160a01b0382166107b55760405162461bcd60e51b815260206004820152600f60248201526e496e76616c6964206164647265737360881b604482015260640161025c565b6103e881106108065760405162461bcd60e51b815260206004820152600f60248201527f496e76616c69642070657263656e740000000000000000000000000000000000604482015260640161025c565b600455600380546001600160a01b0319166001600160a01b0392909216919091179055565b61424a8062000a8083390190565b80356001600160a01b038116811461085057600080fd5b919050565b600060208284031215610866578081fd5b61086f82610839565b9392505050565b60008060408385031215610888578081fd5b61089183610839565b9150602083013580151581146108a5578182fd5b809150509250929050565b600080604083850312156108c2578182fd5b6108cb83610839565b946020939093013593505050565b6000602082840312156108ea578081fd5b5035919050565b60008060008060008060008060006101208a8c03121561090f578485fd5b8935985061091f60208b01610839565b975060408a0135965060608a0135955060808a0135945060a08a0135935060c08a0135925060e08a013591506101008a013567ffffffffffffffff80821115610966578283fd5b818c0191508c601f830112610979578283fd5b81358181111561098b5761098b610a69565b604051601f8201601f19908116603f011681019083821181831017156109b3576109b3610a69565b816040528281528f60208487010111156109cb578586fd5b82602086016020830137856020848301015280955050505050509295985092959850929598565b60008782526020878184015286604084015285606084015284608084015260c060a084015283518060c0850152825b81811015610a3d5785810183015185820160e001528201610a21565b81811115610a4e578360e083870101525b50601f01601f19169290920160e00198975050505050505050565b634e487b7160e01b600052604160045260246000fdfe60806040523480156200001157600080fd5b506040516200424a3803806200424a83398101604081905262000034916200018e565b600080546001600160a01b031916339081178255604051909182917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a350600180556001600160a01b038416620000bf5760405162461bcd60e51b8152602060048201526007602482015266125b9d985b1a5960ca1b60448201526064015b60405180910390fd5b600083118015620000d05750600081115b620001085760405162461bcd60e51b8152602060048201526007602482015266125b9d985b1a5960ca1b6044820152606401620000b6565b6007839055600980546001600160a01b038481166001600160a01b03199283161792839055600a849055600280548883169316929092179091556040805186815292909116602083015281018290527f4c46aef738bf79120bb7772c30f13503aa9a3c6c9dd63d188f629bfdff1ccaa49060600160405180910390a150505050620001f4565b60008060008060808587031215620001a4578384fd5b8451620001b181620001db565b602086015160408701519195509350620001cb81620001db565b6060959095015193969295505050565b6001600160a01b0381168114620001f157600080fd5b50565b61404680620002046000396000f3fe6080604052600436106103435760003560e01c8063920b3a7e116101b0578063d96a094a116100ec578063eee35c1e11610095578063f3278a371161006f578063f3278a3714610948578063f77c47911461095d578063f9d3fe941461097d578063fb5f749f1461099d57610395565b8063eee35c1e146108f2578063f013e0e114610908578063f2fde38b1461092857610395565b8063e6c19730116100c6578063e6c1973014610863578063e985e36714610897578063ee12d622146108b757610395565b8063d96a094a1461080d578063e12f3a611461082d578063e33b7de31461084d57610395565b8063bbc4986d11610159578063c8f6036611610133578063c8f6036614610798578063ccb98ffc146107b8578063cd980527146107d8578063d959e916146107f857610395565b8063bbc4986d1461074b578063c71c0b4014610760578063c885044e1461077657610395565b80639bb3fe021161018a5780639bb3fe02146106f5578063a29f481c14610715578063ba4d35b31461073557610395565b8063920b3a7e1461067757806392bd31581461068c57806392e75077146106d557610395565b80634e71d92d1161027f5780635ab7e6c711610228578063715018a611610202578063715018a61461061857806378e979251461062d5780638da5cb5b1461064357806391ad073b1461066157610395565b80635ab7e6c7146105a85780635fbf8156146105d55780636767bba7146105eb57610395565b806355ca52091161025957806355ca52091461055d5780635727e25d1461057357806357b6527e1461058857610395565b80634e71d92d146105125780634f3a49451461052757806350adcdb71461053d57610395565b80633197cbb6116102ec5780633a908ed2116102c65780633a908ed2146104925780633e0a322d146104b2578063421cc337146104d25780634dfc1abc146104f257610395565b80633197cbb61461042e57806334f8953914610444578063354eaf571461047c57610395565b806326b2eb6e1161031d57806326b2eb6e146103e357806327b3bf1114610403578063288575db1461041957610395565b80630f1a64441461039a5780631514617e146103c357806320f1fc61146103d957610395565b366103955760405162461bcd60e51b815260206004820152601560248201527f536f6d657468696e672077656e742077726f6e6721000000000000000000000060448201526064015b60405180910390fd5b600080fd5b3480156103a657600080fd5b506103b060135481565b6040519081526020015b60405180910390f35b3480156103cf57600080fd5b506103b060155481565b6103e16109bd565b005b3480156103ef57600080fd5b506103e16103fe366004613cff565b610c3b565b34801561040f57600080fd5b506103b060055481565b34801561042557600080fd5b506103e1610da4565b34801561043a57600080fd5b506103b060045481565b34801561045057600080fd5b5061046461045f366004613cff565b611068565b6040516001600160a01b0390911681526020016103ba565b34801561048857600080fd5b506103b060145481565b34801561049e57600080fd5b506103e16104ad366004613d60565b611092565b3480156104be57600080fd5b506103e16104cd366004613cff565b6112f3565b3480156104de57600080fd5b506103e16104ed366004613cff565b61149e565b3480156104fe57600080fd5b506103e161050d366004613cc4565b611605565b34801561051e57600080fd5b506103e1611736565b34801561053357600080fd5b506103b060075481565b34801561054957600080fd5b50600954610464906001600160a01b031681565b34801561056957600080fd5b506103b060085481565b34801561057f57600080fd5b506103b061187c565b34801561059457600080fd5b506103b06105a3366004613bb2565b6118ec565b3480156105b457600080fd5b506103b06105c3366004613bb2565b60176020526000908152604090205481565b3480156105e157600080fd5b506103b060165481565b3480156105f757600080fd5b506103b0610606366004613cff565b60186020526000908152604090205481565b34801561062457600080fd5b506103e161193c565b34801561063957600080fd5b506103b060035481565b34801561064f57600080fd5b506000546001600160a01b0316610464565b34801561066d57600080fd5b506103b0600d5481565b34801561068357600080fd5b506010546103b0565b34801561069857600080fd5b506106c06106a7366004613bb2565b6012602052600090815260409020805460019091015482565b604080519283526020830191909152016103ba565b3480156106e157600080fd5b506103e16106f0366004613d2f565b6119e0565b34801561070157600080fd5b506103b0610710366004613cff565b611c86565b34801561072157600080fd5b506103e1610730366004613bb2565b611ce6565b34801561074157600080fd5b506103b0600e5481565b34801561075757600080fd5b506103b0600281565b34801561076c57600080fd5b506103b0600b5481565b34801561078257600080fd5b5061078b611e51565b6040516103ba9190613de6565b3480156107a457600080fd5b506103e16107b3366004613cff565b611edf565b3480156107c457600080fd5b506103e16107d3366004613cff565b61203d565b3480156107e457600080fd5b506103e16107f3366004613cff565b6121f8565b34801561080457600080fd5b506103e1612349565b34801561081957600080fd5b506103e1610828366004613cff565b612527565b34801561083957600080fd5b506103b0610848366004613bb2565b6127bd565b34801561085957600080fd5b506103b0600c5481565b34801561086f57600080fd5b506106c061087e366004613bb2565b6011602052600090815260409020805460019091015482565b3480156108a357600080fd5b50600654610464906001600160a01b031681565b3480156108c357600080fd5b506108d76108d2366004613bb2565b6127db565b604080518251815260209283015192810192909252016103ba565b3480156108fe57600080fd5b506103b0600a5481565b34801561091457600080fd5b506103e1610923366004613c3b565b612875565b34801561093457600080fd5b506103e1610943366004613bb2565b612a34565b34801561095457600080fd5b506103e1612b65565b34801561096957600080fd5b50600254610464906001600160a01b031681565b34801561098957600080fd5b506103e1610998366004613cff565b612ec5565b3480156109a957600080fd5b506103e16109b8366004613bfb565b613017565b42600354111580156109d157506004544211155b610a0a5760405162461bcd60e51b815260206004820152600a6024820152694e6f74206f6e67696e6760b01b604482015260640161038c565b33346000610a1661187c565b90506000610a23846118ec565b905060008311610a605760405162461bcd60e51b81526020600482015260086024820152670c08185b5bdd5b9d60c21b604482015260640161038c565b600a5483600b54610a719190613ee5565b1115610aad5760405162461bcd60e51b815260206004820152600b60248201526a546172676574206869742160a81b604482015260640161038c565b60008260011415610ae2576001600160a01b038516600090815260116020526040902054610adb9085613ee5565b9050610b11565b8260021415610b11576001600160a01b038516600090815260126020526040902054610b0e9085613ee5565b90505b600e54811015610b505760405162461bcd60e51b815260206004820152600a602482015269131bddc8185b5bdd5b9d60b21b604482015260640161038c565b81811115610b925760405162461bcd60e51b815260206004820152600f60248201526e151bdbc81b5d58da08185b5bdd5b9d608a1b604482015260640161038c565b323314610bd15760405162461bcd60e51b815260206004820152600d60248201526c73686f756c6420626520454f4160981b604482015260640161038c565b6009546001600160a01b031615610c2a5760405162461bcd60e51b815260206004820152601660248201527f49742773206e6f7420424e422d62757920706f6f6c2100000000000000000000604482015260640161038c565b610c343334613153565b5050505050565b6002546040516336b87bd760e11b81523360048201526001600160a01b0390911690636d70f7ae9060240160206040518083038186803b158015610c7e57600080fd5b505afa158015610c92573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610cb69190613ca4565b80610cda575033610ccf6000546001600160a01b031690565b6001600160a01b0316145b610d145760405162461bcd60e51b8152602060048201526015602482015260008051602061401a833981519152604482015260640161038c565b60008111610d4e5760405162461bcd60e51b8152602060048201526007602482015266125b9d985b1a5960ca1b604482015260640161038c565b80600e819055507f47954b45256aec82404d303fc1fef420d021b0e70bd9ee69a9cfc77377154cb0600354600454600554600e54600d54600f604051610d9996959493929190613e19565b60405180910390a150565b6002546040516336b87bd760e11b81523360048201526001600160a01b0390911690636d70f7ae9060240160206040518083038186803b158015610de757600080fd5b505afa158015610dfb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e1f9190613ca4565b80610e43575033610e386000546001600160a01b031690565b6001600160a01b0316145b610e7d5760405162461bcd60e51b8152602060048201526015602482015260008051602061401a833981519152604482015260640161038c565b600454421015610ebb5760405162461bcd60e51b8152602060048201526009602482015268139bdd08195b99195960ba1b604482015260640161038c565b6009546001600160a01b0316610f135760405162461bcd60e51b815260206004820152601860248201527f49742773206e6f7420746f6b656e2d62757920706f6f6c210000000000000000604482015260640161038c565b6009546040516370a0823160e01b81523060048201526000916001600160a01b0316906370a082319060240160206040518083038186803b158015610f5757600080fd5b505afa158015610f6b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f8f9190613d17565b600254604080516202eab760e01b8152815193945060009384936001600160a01b0316926202eab79260048082019391829003018186803b158015610fd357600080fd5b505afa158015610fe7573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061100b9190613bce565b909250905060006103e861101f8386613f1d565b6110299190613efd565b905060006110378286613f3c565b600954909150611051906001600160a01b031685846133b7565b600954610c34906001600160a01b031633836133b7565b6010818154811061107857600080fd5b6000918252602090912001546001600160a01b0316905081565b6002546040516336b87bd760e11b81523360048201526001600160a01b0390911690636d70f7ae9060240160206040518083038186803b1580156110d557600080fd5b505afa1580156110e9573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061110d9190613ca4565b806111315750336111266000546001600160a01b031690565b6001600160a01b0316145b61116b5760405162461bcd60e51b8152602060048201526015602482015260008051602061401a833981519152604482015260640161038c565b600083116111bb5760405162461bcd60e51b815260206004820152600960248201527f30206d696e46756e640000000000000000000000000000000000000000000000604482015260640161038c565b6000821161120b5760405162461bcd60e51b815260206004820152600660248201527f3020626173650000000000000000000000000000000000000000000000000000604482015260640161038c565b428611801561121957508486105b801561122457508385105b6112705760405162461bcd60e51b815260206004820152600d60248201527f496e76616c69642074696d657300000000000000000000000000000000000000604482015260640161038c565b600386905560048590556005849055600e839055805161129790600f906020840190613a49565b5081600d819055507f47954b45256aec82404d303fc1fef420d021b0e70bd9ee69a9cfc77377154cb0600354600454600554600e54600d54600f6040516112e396959493929190613e19565b60405180910390a1505050505050565b6002546040516336b87bd760e11b81523360048201526001600160a01b0390911690636d70f7ae9060240160206040518083038186803b15801561133657600080fd5b505afa15801561134a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061136e9190613ca4565b806113925750336113876000546001600160a01b031690565b6001600160a01b0316145b6113cc5760405162461bcd60e51b8152602060048201526015602482015260008051602061401a833981519152604482015260640161038c565b426003541161141d5760405162461bcd60e51b815260206004820152600f60248201527f416c726561647920737461727465640000000000000000000000000000000000604482015260640161038c565b4281116114565760405162461bcd60e51b8152602060048201526007602482015266125b9d985b1a5960ca1b604482015260640161038c565b6003819055600454600554600e54600d546040517f47954b45256aec82404d303fc1fef420d021b0e70bd9ee69a9cfc77377154cb094610d9994879491939092600f90613e19565b6002546040516336b87bd760e11b81523360048201526001600160a01b0390911690636d70f7ae9060240160206040518083038186803b1580156114e157600080fd5b505afa1580156114f5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115199190613ca4565b8061153d5750336115326000546001600160a01b031690565b6001600160a01b0316145b6115775760405162461bcd60e51b8152602060048201526015602482015260008051602061401a833981519152604482015260640161038c565b4281118015611587575060045481115b6115bd5760405162461bcd60e51b8152602060048201526007602482015266125b9d985b1a5960ca1b604482015260640161038c565b6005819055600354600454600e54600d546040517f47954b45256aec82404d303fc1fef420d021b0e70bd9ee69a9cfc77377154cb094610d9994909390928792600f90613e19565b6002546040516336b87bd760e11b81523360048201526001600160a01b0390911690636d70f7ae9060240160206040518083038186803b15801561164857600080fd5b505afa15801561165c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116809190613ca4565b806116a45750336116996000546001600160a01b031690565b6001600160a01b0316145b6116de5760405162461bcd60e51b8152602060048201526015602482015260008051602061401a833981519152604482015260640161038c565b80516116f190600f906020840190613a49565b507f47954b45256aec82404d303fc1fef420d021b0e70bd9ee69a9cfc77377154cb0600354600454600554600e54600d54600f604051610d9996959493929190613e19565b6005544210156117785760405162461bcd60e51b815260206004820152600d60248201526c4e6f7420636c61696d61626c6560981b604482015260640161038c565b600260015414156117cb5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015260640161038c565b600260015532331461180f5760405162461bcd60e51b815260206004820152600d60248201526c73686f756c6420626520454f4160981b604482015260640161038c565b600061181a336127bd565b90506000811161186c5760405162461bcd60e51b815260206004820152601060248201527f4e6f7468696e6720746f20636c61696d00000000000000000000000000000000604482015260640161038c565b6118753361344c565b5060018055565b600060035442108061188f575060045442115b1561189c575060006118e9565b600060026003546004546118b09190613f3c565b6118ba9190613efd565b9050600081600354426118cd9190613f3c565b6118d79190613efd565b90506118e4816001613ee5565b925050505b90565b6000806118f761187c565b905080611908576000915050611937565b80600114156119315750506001600160a01b038116600090815260176020526040902054611937565b5050600d545b919050565b6000546001600160a01b031633146119965760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161038c565b600080546040516001600160a01b03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600080546001600160a01b0319169055565b6002546040516336b87bd760e11b81523360048201526001600160a01b0390911690636d70f7ae9060240160206040518083038186803b158015611a2357600080fd5b505afa158015611a37573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a5b9190613ca4565b80611a7f575033611a746000546001600160a01b031690565b6001600160a01b0316145b611ab95760405162461bcd60e51b8152602060048201526015602482015260008051602061401a833981519152604482015260640161038c565b6005548411611b0a5760405162461bcd60e51b815260206004820152600d60248201527f496e76616c696420436c69666600000000000000000000000000000000000000604482015260640161038c565b6103e8831115611b5c5760405162461bcd60e51b815260206004820152600b60248201527f496e76616c696420746765000000000000000000000000000000000000000000604482015260640161038c565b600082118015611b6c5750600081115b611bb85760405162461bcd60e51b815260206004820152601460248201527f30204475726174696f6e206f7220506572696f64000000000000000000000000604482015260640161038c565b80611bc38184613efd565b611bcd9190613f1d565b611bd79083613f3c565b15611c245760405162461bcd60e51b815260206004820152600b60248201527f4e6f742064697669646564000000000000000000000000000000000000000000604482015260640161038c565b60138490556014839055601582905560168190556040805185815260208101859052908101839052606081018290527f0cdccee4294ef1828512c7a50e43161abfba8be25b7470c13ed771644aa21b2d9060800160405180910390a150505050565b600081611c9557506000611937565b8160011415611ca75750600a54611937565b600160005260186020527ff3794665d3af9b6fb6f858b70185898134f96768ef31c325d52e04f0ac195a4d54600a54611ce09190613f3c565b92915050565b6002546040516336b87bd760e11b81523360048201526001600160a01b0390911690636d70f7ae9060240160206040518083038186803b158015611d2957600080fd5b505afa158015611d3d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d619190613ca4565b80611d85575033611d7a6000546001600160a01b031690565b6001600160a01b0316145b611dbf5760405162461bcd60e51b8152602060048201526015602482015260008051602061401a833981519152604482015260640161038c565b6001600160a01b038116611dff5760405162461bcd60e51b8152602060048201526007602482015266125b9d985b1a5960ca1b604482015260640161038c565b600680546001600160a01b0319166001600160a01b038381169190911791829055604051911681527fdefd52f9aef0138625fe1a6cfbe86a662de840ccb42d91039a1547b6fd65707a90602001610d99565b600f8054611e5e90613f7f565b80601f0160208091040260200160405190810160405280929190818152602001828054611e8a90613f7f565b8015611ed75780601f10611eac57610100808354040283529160200191611ed7565b820191906000526020600020905b815481529060010190602001808311611eba57829003601f168201915b505050505081565b6002546040516336b87bd760e11b81523360048201526001600160a01b0390911690636d70f7ae9060240160206040518083038186803b158015611f2257600080fd5b505afa158015611f36573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f5a9190613ca4565b80611f7e575033611f736000546001600160a01b031690565b6001600160a01b0316145b611fb85760405162461bcd60e51b8152602060048201526015602482015260008051602061401a833981519152604482015260640161038c565b60008111611ff25760405162461bcd60e51b8152602060048201526007602482015266125b9d985b1a5960ca1b604482015260640161038c565b80600d819055507f47954b45256aec82404d303fc1fef420d021b0e70bd9ee69a9cfc77377154cb0600354600454600554600e54600d54600f604051610d9996959493929190613e19565b6002546040516336b87bd760e11b81523360048201526001600160a01b0390911690636d70f7ae9060240160206040518083038186803b15801561208057600080fd5b505afa158015612094573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120b89190613ca4565b806120dc5750336120d16000546001600160a01b031690565b6001600160a01b0316145b6121165760405162461bcd60e51b8152602060048201526015602482015260008051602061401a833981519152604482015260640161038c565b60045442106121675760405162461bcd60e51b815260206004820152600560248201527f456e646564000000000000000000000000000000000000000000000000000000604482015260640161038c565b4281118015612177575060035481115b6121ad5760405162461bcd60e51b8152602060048201526007602482015266125b9d985b1a5960ca1b604482015260640161038c565b806004819055507f47954b45256aec82404d303fc1fef420d021b0e70bd9ee69a9cfc77377154cb0600354600454600554600e54600d54600f604051610d9996959493929190613e19565b6002546040516336b87bd760e11b81523360048201526001600160a01b0390911690636d70f7ae9060240160206040518083038186803b15801561223b57600080fd5b505afa15801561224f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122739190613ca4565b8061229757503361228c6000546001600160a01b031690565b6001600160a01b0316145b6122d15760405162461bcd60e51b8152602060048201526015602482015260008051602061401a833981519152604482015260640161038c565b6000811161230b5760405162461bcd60e51b8152602060048201526007602482015266125b9d985b1a5960ca1b604482015260640161038c565b600a81905560075460408051918252602082018390527ff544f637f7119822ecd07db25a0c73e6f73097def4e5050f15a3370e769db0779101610d99565b6002546040516336b87bd760e11b81523360048201526001600160a01b0390911690636d70f7ae9060240160206040518083038186803b15801561238c57600080fd5b505afa1580156123a0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123c49190613ca4565b806123e85750336123dd6000546001600160a01b031690565b6001600160a01b0316145b6124225760405162461bcd60e51b8152602060048201526015602482015260008051602061401a833981519152604482015260640161038c565b60045442116124735760405162461bcd60e51b815260206004820152601560248201527f49444f20686173206e6f742079657420656e6465640000000000000000000000604482015260640161038c565b600854600c546006546040516370a0823160e01b8152306004820152612525933393909290916001600160a01b03909116906370a082319060240160206040518083038186803b1580156124c657600080fd5b505afa1580156124da573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124fe9190613d17565b6125089190613ee5565b6125129190613f3c565b6006546001600160a01b031691906133b7565b565b426003541115801561253b57506004544211155b6125745760405162461bcd60e51b815260206004820152600a6024820152694e6f74206f6e67696e6760b01b604482015260640161038c565b3381600061258061187c565b9050600061258d846118ec565b9050600083116125ca5760405162461bcd60e51b81526020600482015260086024820152670c08185b5bdd5b9d60c21b604482015260640161038c565b600a5483600b546125db9190613ee5565b11156126175760405162461bcd60e51b815260206004820152600b60248201526a546172676574206869742160a81b604482015260640161038c565b6000826001141561264c576001600160a01b0385166000908152601160205260409020546126459085613ee5565b905061267b565b826002141561267b576001600160a01b0385166000908152601260205260409020546126789085613ee5565b90505b600e548110156126ba5760405162461bcd60e51b815260206004820152600a602482015269131bddc8185b5bdd5b9d60b21b604482015260640161038c565b818111156126fc5760405162461bcd60e51b815260206004820152600f60248201526e151bdbc81b5d58da08185b5bdd5b9d608a1b604482015260640161038c565b32331461273b5760405162461bcd60e51b815260206004820152600d60248201526c73686f756c6420626520454f4160981b604482015260640161038c565b6009546001600160a01b03166127935760405162461bcd60e51b815260206004820152601860248201527f49742773206e6f7420746f6b656e2d62757920706f6f6c210000000000000000604482015260640161038c565b61279d3387613153565b6009546127b5906001600160a01b03163330896135b6565b505050505050565b60006127c8826135f4565b6127d183613628565b611ce09190613ee5565b604080518082019091526000808252602082015260408051808201909152600080825260208201526001600160a01b0383166000908152601260209081526040808320546011909252909120546128329190613ee5565b81526001600160a01b0383166000908152601260209081526040808320600190810154601190935292209091015461286a9190613ee5565b602082015292915050565b6002546040516336b87bd760e11b81523360048201526001600160a01b0390911690636d70f7ae9060240160206040518083038186803b1580156128b857600080fd5b505afa1580156128cc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128f09190613ca4565b806129145750336129096000546001600160a01b031690565b6001600160a01b0316145b61294e5760405162461bcd60e51b8152602060048201526015602482015260008051602061401a833981519152604482015260640161038c565b82811461299d5760405162461bcd60e51b815260206004820152600e60248201527f496e76616c696420706172616d73000000000000000000000000000000000000604482015260640161038c565b60005b83811015610c34578282828181106129c857634e487b7160e01b600052603260045260246000fd5b90506020020135601760008787858181106129f357634e487b7160e01b600052603260045260246000fd5b9050602002016020810190612a089190613bb2565b6001600160a01b0316815260208101919091526040016000205580612a2c81613fba565b9150506129a0565b6000546001600160a01b03163314612a8e5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161038c565b6001600160a01b038116612b0a5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f6464726573730000000000000000000000000000000000000000000000000000606482015260840161038c565b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b0319166001600160a01b0392909216919091179055565b6002546040516336b87bd760e11b81523360048201526001600160a01b0390911690636d70f7ae9060240160206040518083038186803b158015612ba857600080fd5b505afa158015612bbc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612be09190613ca4565b80612c04575033612bf96000546001600160a01b031690565b6001600160a01b0316145b612c3e5760405162461bcd60e51b8152602060048201526015602482015260008051602061401a833981519152604482015260640161038c565b600454421015612c7c5760405162461bcd60e51b8152602060048201526009602482015268139bdd08195b99195960ba1b604482015260640161038c565b6009546001600160a01b031615612cd55760405162461bcd60e51b815260206004820152601660248201527f49742773206e6f7420424e422d62757920706f6f6c2100000000000000000000604482015260640161038c565b600254604080516202eab760e01b81528151479360009384936001600160a01b03909216926202eab7926004808201939291829003018186803b158015612d1b57600080fd5b505afa158015612d2f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d539190613bce565b909250905060006103e8612d678386613f1d565b612d719190613efd565b90506000612d7f8286613f3c565b90506000846001600160a01b03168360405160006040518083038185875af1925050503d8060008114612dce576040519150601f19603f3d011682016040523d82523d6000602084013e612dd3565b606091505b5050905080612e245760405162461bcd60e51b815260206004820152601260248201527f424e422066656520706179206661696c65640000000000000000000000000000604482015260640161038c565b604051600090339084908381818185875af1925050503d8060008114612e66576040519150601f19603f3d011682016040523d82523d6000602084013e612e6b565b606091505b5050905080612ebc5760405162461bcd60e51b815260206004820152601360248201527f424e42207769746864726177206661696c656400000000000000000000000000604482015260640161038c565b50505050505050565b6002546040516336b87bd760e11b81523360048201526001600160a01b0390911690636d70f7ae9060240160206040518083038186803b158015612f0857600080fd5b505afa158015612f1c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f409190613ca4565b80612f64575033612f596000546001600160a01b031690565b6001600160a01b0316145b612f9e5760405162461bcd60e51b8152602060048201526015602482015260008051602061401a833981519152604482015260640161038c565b60008111612fd85760405162461bcd60e51b8152602060048201526007602482015266125b9d985b1a5960ca1b604482015260640161038c565b6007819055600a546040805183815260208101929092527ff544f637f7119822ecd07db25a0c73e6f73097def4e5050f15a3370e769db0779101610d99565b6005544210156130595760405162461bcd60e51b815260206004820152600d60248201526c4e6f7420636c61696d61626c6560981b604482015260640161038c565b600260015414156130ac5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015260640161038c565b60026001553233146130f05760405162461bcd60e51b815260206004820152600d60248201526c73686f756c6420626520454f4160981b604482015260640161038c565b60005b8181101561314a5761313883838381811061311e57634e487b7160e01b600052603260045260246000fd5b90506020020160208101906131339190613bb2565b61344c565b8061314281613fba565b9150506130f3565b50506001805550565b6000600a54600754836131669190613f1d565b6131709190613efd565b9050600061317c61187c565b905082600b5461318c9190613ee5565b600b5560085461319d908390613ee5565b600855806001811415613255576001600160a01b03851660009081526011602052604090205461321357601080546001810182556000919091527f1b6847dc741a1b0cd08d278845f9d819d87b734759afb55fe2de5cb82a9ae6720180546001600160a01b0319166001600160a01b0387161790555b6001600160a01b038516600090815260116020526040902054613237908590613ee5565b6001600160a01b038616600090815260116020526040902055613329565b8160021415613329576001600160a01b03851660009081526011602052604090205415801561329a57506001600160a01b038516600090815260126020526040902054155b156132eb57601080546001810182556000919091527f1b6847dc741a1b0cd08d278845f9d819d87b734759afb55fe2de5cb82a9ae6720180546001600160a01b0319166001600160a01b0387161790555b6001600160a01b03851660009081526012602052604090205461330f908590613ee5565b6001600160a01b0386166000908152601260205260409020555b600081815260186020526040902054613343908590613ee5565b60008281526018602090815260409182902092909255600b5460085482516001600160a01b038a168152938401889052918301526060820152608081018390527f2e10dca68d13f21427d1f4798389c7b999e339c241d547a2da046036d2d79e329060a00160405180910390a15050505050565b6040516001600160a01b03831660248201526044810182905261344790849063a9059cbb60e01b906064015b60408051601f198184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152613652565b505050565b6001600160a01b0381166134a25760405162461bcd60e51b815260206004820152600f60248201527f496e76616c696420616464726573730000000000000000000000000000000000604482015260640161038c565b60006134ad826127bd565b905080156135b2576134be82613628565b6001600160a01b0383166000908152601160205260409020600101546134e49190613ee5565b6001600160a01b038316600090815260116020526040902060010155613509826135f4565b6001600160a01b03831660009081526012602052604090206001015461352f9190613ee5565b6001600160a01b0380841660009081526012602052604090206001019190915560065461355e911683836133b7565b80600c5461356c9190613ee5565b600c55604080516001600160a01b0384168152602081018390527f8b4619cd854e5d0890654f42fdcc881750a2b348ceeda941a1ef61c419bbde1c910160405180910390a15b5050565b6040516001600160a01b03808516602483015283166044820152606481018290526135ee9085906323b872dd60e01b906084016133e3565b50505050565b6001600160a01b03811660009081526012602052604081206001810154905461361e908490613737565b611ce09190613f3c565b6001600160a01b03811660009081526011602052604081206001810154905461361e908490613737565b60006136a7826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166138b89092919063ffffffff16565b80519091501561344757808060200190518101906136c59190613ca4565b6134475760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f74207375636365656400000000000000000000000000000000000000000000606482015260840161038c565b60006001600160a01b03831661378f5760405162461bcd60e51b815260206004820152601060248201527f496e76616c696420616464726573732100000000000000000000000000000000604482015260640161038c565b6005544210156137a157506000611ce0565b6000600a54600754846137b49190613f1d565b6137be9190613efd565b905060006103e8601454836137d39190613f1d565b6137dd9190613efd565b90504260135411156137f2579150611ce09050565b60135461380457600092505050611ce0565b60006016546015546013546138199190613ee5565b6138239190613f3c565b905080421061383757829350505050611ce0565b60006138438385613f3c565b905060006016546015546138579190613efd565b905060006138658284613efd565b905060006016546013544261387a9190613f3c565b6138849190613efd565b61388f906001613ee5565b9050600061389d8284613f1d565b90506138a98188613ee5565b9b9a5050505050505050505050565b60606138c784846000856138d1565b90505b9392505050565b6060824710156139495760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c0000000000000000000000000000000000000000000000000000606482015260840161038c565b843b6139975760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640161038c565b600080866001600160a01b031685876040516139b39190613dca565b60006040518083038185875af1925050503d80600081146139f0576040519150601f19603f3d011682016040523d82523d6000602084013e6139f5565b606091505b5091509150613a05828286613a10565b979650505050505050565b60608315613a1f5750816138ca565b825115613a2f5782518084602001fd5b8160405162461bcd60e51b815260040161038c9190613de6565b828054613a5590613f7f565b90600052602060002090601f016020900481019282613a775760008555613abd565b82601f10613a9057805160ff1916838001178555613abd565b82800160010185558215613abd579182015b82811115613abd578251825591602001919060010190613aa2565b50613ac9929150613acd565b5090565b5b80821115613ac95760008155600101613ace565b60008083601f840112613af3578081fd5b50813567ffffffffffffffff811115613b0a578182fd5b6020830191508360208083028501011115613b2457600080fd5b9250929050565b600082601f830112613b3b578081fd5b813567ffffffffffffffff80821115613b5657613b56613feb565b604051601f8301601f19908116603f01168101908282118183101715613b7e57613b7e613feb565b81604052838152866020858801011115613b96578485fd5b8360208701602083013792830160200193909352509392505050565b600060208284031215613bc3578081fd5b81356138ca81614001565b60008060408385031215613be0578081fd5b8251613beb81614001565b6020939093015192949293505050565b60008060208385031215613c0d578182fd5b823567ffffffffffffffff811115613c23578283fd5b613c2f85828601613ae2565b90969095509350505050565b60008060008060408587031215613c50578182fd5b843567ffffffffffffffff80821115613c67578384fd5b613c7388838901613ae2565b90965094506020870135915080821115613c8b578384fd5b50613c9887828801613ae2565b95989497509550505050565b600060208284031215613cb5578081fd5b815180151581146138ca578182fd5b600060208284031215613cd5578081fd5b813567ffffffffffffffff811115613ceb578182fd5b613cf784828501613b2b565b949350505050565b600060208284031215613d10578081fd5b5035919050565b600060208284031215613d28578081fd5b5051919050565b60008060008060808587031215613d44578384fd5b5050823594602084013594506040840135936060013592509050565b60008060008060008060c08789031215613d78578182fd5b863595506020870135945060408701359350606087013592506080870135915060a087013567ffffffffffffffff811115613db1578182fd5b613dbd89828a01613b2b565b9150509295509295509295565b60008251613ddc818460208701613f53565b9190910192915050565b6000602082528251806020840152613e05816040850160208701613f53565b601f01601f19169190910160400192915050565b60008782526020878184015286604084015285606084015284608084015260c060a084015281845483600282049050600180831680613e5957607f831692505b858310811415613e7757634e487b7160e01b87526022600452602487fd5b60c0880183905260e08801818015613e965760018114613ea757613ed1565b60ff19861682528782019650613ed1565b60008b815260209020895b86811015613ecb57815484820152908501908901613eb2565b83019750505b50949e9d5050505050505050505050505050565b60008219821115613ef857613ef8613fd5565b500190565b600082613f1857634e487b7160e01b81526012600452602481fd5b500490565b6000816000190483118215151615613f3757613f37613fd5565b500290565b600082821015613f4e57613f4e613fd5565b500390565b60005b83811015613f6e578181015183820152602001613f56565b838111156135ee5750506000910152565b600281046001821680613f9357607f821691505b60208210811415613fb457634e487b7160e01b600052602260045260246000fd5b50919050565b6000600019821415613fce57613fce613fd5565b5060010190565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160a01b038116811461401657600080fd5b5056fe4e6f74206f776e6572206f72206f70657261746f720000000000000000000000a164736f6c6343000802000aa164736f6c6343000802000a0000000000000000000000005c09a250787765e84377e705d61c8f7e37333be90000000000000000000000000000000000000000000000000000000000000046
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106100d35760003560e01c80636d70f7ae11610081578063846ae9ae1161005b578063846ae9ae146101cf5780638da5cb5b146101e2578063f2fde38b146101f3576100d3565b80636d70f7ae1461018b578063715018a6146101be5780637fd6f15c146101c6576100d3565b806326af1f0a116100b257806326af1f0a1461013a5780633740ebb314610165578063558a729714610178576100d3565b806202eab7146100d85780630f2097c0146101135780631a746ae314610128575b600080fd5b6100ef6003546004546001600160a01b0390911691565b604080516001600160a01b0390931683526020830191909152015b60405180910390f35b6101266101213660046108b0565b610206565b005b6002545b60405190815260200161010a565b61014d6101483660046108d9565b610273565b6040516001600160a01b03909116815260200161010a565b60035461014d906001600160a01b031681565b610126610186366004610876565b61029d565b6101ae610199366004610855565b60016020526000908152604090205460ff1681565b604051901515815260200161010a565b61012661036a565b61012c60045481565b61014d6101dd3660046108f1565b61040e565b6000546001600160a01b031661014d565b610126610201366004610855565b61063c565b6000546001600160a01b031633146102655760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064015b60405180910390fd5b61026f828261076d565b5050565b6002818154811061028357600080fd5b6000918252602090912001546001600160a01b0316905081565b6000546001600160a01b031633146102f75760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161025c565b6001600160a01b03821661033f5760405162461bcd60e51b815260206004820152600f60248201526e496e76616c6964206164647265737360881b604482015260640161025c565b6001600160a01b03919091166000908152600160205260409020805460ff1916911515919091179055565b6000546001600160a01b031633146103c45760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161025c565b600080546040516001600160a01b03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600080546001600160a01b0319169055565b3360009081526001602052604081205460ff168061044557503361043a6000546001600160a01b031690565b6001600160a01b0316145b6104915760405162461bcd60e51b815260206004820152601560248201527f4e6f74206f776e6572206f72206f70657261746f720000000000000000000000604482015260640161025c565b6000308b8b8b6040516104a39061082b565b6001600160a01b0394851681526020810193909352921660408201526060810191909152608001604051809103906000f0801580156104e6573d6000803e3d6000fd5b50604051631d48476960e11b81529091506001600160a01b03821690633a908ed290610520908b908b908b908b908b908b906004016109f2565b600060405180830381600087803b15801561053a57600080fd5b505af115801561054e573d6000803e3d6000fd5b505060405163f2fde38b60e01b81523360048201526001600160a01b038416925063f2fde38b9150602401600060405180830381600087803b15801561059357600080fd5b505af11580156105a7573d6000803e3d6000fd5b5050600280546001810182556000919091527f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace0180546001600160a01b0319166001600160a01b0385169081179091556040513381529092507fff0fb79676a39a6f0826771efed31fcdbfca1b939daaa4586f77202abf8e9607915060200160405180910390a29a9950505050505050505050565b6000546001600160a01b031633146106965760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161025c565b6001600160a01b0381166107125760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f6464726573730000000000000000000000000000000000000000000000000000606482015260840161025c565b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b0319166001600160a01b0392909216919091179055565b6001600160a01b0382166107b55760405162461bcd60e51b815260206004820152600f60248201526e496e76616c6964206164647265737360881b604482015260640161025c565b6103e881106108065760405162461bcd60e51b815260206004820152600f60248201527f496e76616c69642070657263656e740000000000000000000000000000000000604482015260640161025c565b600455600380546001600160a01b0319166001600160a01b0392909216919091179055565b61424a8062000a8083390190565b80356001600160a01b038116811461085057600080fd5b919050565b600060208284031215610866578081fd5b61086f82610839565b9392505050565b60008060408385031215610888578081fd5b61089183610839565b9150602083013580151581146108a5578182fd5b809150509250929050565b600080604083850312156108c2578182fd5b6108cb83610839565b946020939093013593505050565b6000602082840312156108ea578081fd5b5035919050565b60008060008060008060008060006101208a8c03121561090f578485fd5b8935985061091f60208b01610839565b975060408a0135965060608a0135955060808a0135945060a08a0135935060c08a0135925060e08a013591506101008a013567ffffffffffffffff80821115610966578283fd5b818c0191508c601f830112610979578283fd5b81358181111561098b5761098b610a69565b604051601f8201601f19908116603f011681019083821181831017156109b3576109b3610a69565b816040528281528f60208487010111156109cb578586fd5b82602086016020830137856020848301015280955050505050509295985092959850929598565b60008782526020878184015286604084015285606084015284608084015260c060a084015283518060c0850152825b81811015610a3d5785810183015185820160e001528201610a21565b81811115610a4e578360e083870101525b50601f01601f19169290920160e00198975050505050505050565b634e487b7160e01b600052604160045260246000fdfe60806040523480156200001157600080fd5b506040516200424a3803806200424a83398101604081905262000034916200018e565b600080546001600160a01b031916339081178255604051909182917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a350600180556001600160a01b038416620000bf5760405162461bcd60e51b8152602060048201526007602482015266125b9d985b1a5960ca1b60448201526064015b60405180910390fd5b600083118015620000d05750600081115b620001085760405162461bcd60e51b8152602060048201526007602482015266125b9d985b1a5960ca1b6044820152606401620000b6565b6007839055600980546001600160a01b038481166001600160a01b03199283161792839055600a849055600280548883169316929092179091556040805186815292909116602083015281018290527f4c46aef738bf79120bb7772c30f13503aa9a3c6c9dd63d188f629bfdff1ccaa49060600160405180910390a150505050620001f4565b60008060008060808587031215620001a4578384fd5b8451620001b181620001db565b602086015160408701519195509350620001cb81620001db565b6060959095015193969295505050565b6001600160a01b0381168114620001f157600080fd5b50565b61404680620002046000396000f3fe6080604052600436106103435760003560e01c8063920b3a7e116101b0578063d96a094a116100ec578063eee35c1e11610095578063f3278a371161006f578063f3278a3714610948578063f77c47911461095d578063f9d3fe941461097d578063fb5f749f1461099d57610395565b8063eee35c1e146108f2578063f013e0e114610908578063f2fde38b1461092857610395565b8063e6c19730116100c6578063e6c1973014610863578063e985e36714610897578063ee12d622146108b757610395565b8063d96a094a1461080d578063e12f3a611461082d578063e33b7de31461084d57610395565b8063bbc4986d11610159578063c8f6036611610133578063c8f6036614610798578063ccb98ffc146107b8578063cd980527146107d8578063d959e916146107f857610395565b8063bbc4986d1461074b578063c71c0b4014610760578063c885044e1461077657610395565b80639bb3fe021161018a5780639bb3fe02146106f5578063a29f481c14610715578063ba4d35b31461073557610395565b8063920b3a7e1461067757806392bd31581461068c57806392e75077146106d557610395565b80634e71d92d1161027f5780635ab7e6c711610228578063715018a611610202578063715018a61461061857806378e979251461062d5780638da5cb5b1461064357806391ad073b1461066157610395565b80635ab7e6c7146105a85780635fbf8156146105d55780636767bba7146105eb57610395565b806355ca52091161025957806355ca52091461055d5780635727e25d1461057357806357b6527e1461058857610395565b80634e71d92d146105125780634f3a49451461052757806350adcdb71461053d57610395565b80633197cbb6116102ec5780633a908ed2116102c65780633a908ed2146104925780633e0a322d146104b2578063421cc337146104d25780634dfc1abc146104f257610395565b80633197cbb61461042e57806334f8953914610444578063354eaf571461047c57610395565b806326b2eb6e1161031d57806326b2eb6e146103e357806327b3bf1114610403578063288575db1461041957610395565b80630f1a64441461039a5780631514617e146103c357806320f1fc61146103d957610395565b366103955760405162461bcd60e51b815260206004820152601560248201527f536f6d657468696e672077656e742077726f6e6721000000000000000000000060448201526064015b60405180910390fd5b600080fd5b3480156103a657600080fd5b506103b060135481565b6040519081526020015b60405180910390f35b3480156103cf57600080fd5b506103b060155481565b6103e16109bd565b005b3480156103ef57600080fd5b506103e16103fe366004613cff565b610c3b565b34801561040f57600080fd5b506103b060055481565b34801561042557600080fd5b506103e1610da4565b34801561043a57600080fd5b506103b060045481565b34801561045057600080fd5b5061046461045f366004613cff565b611068565b6040516001600160a01b0390911681526020016103ba565b34801561048857600080fd5b506103b060145481565b34801561049e57600080fd5b506103e16104ad366004613d60565b611092565b3480156104be57600080fd5b506103e16104cd366004613cff565b6112f3565b3480156104de57600080fd5b506103e16104ed366004613cff565b61149e565b3480156104fe57600080fd5b506103e161050d366004613cc4565b611605565b34801561051e57600080fd5b506103e1611736565b34801561053357600080fd5b506103b060075481565b34801561054957600080fd5b50600954610464906001600160a01b031681565b34801561056957600080fd5b506103b060085481565b34801561057f57600080fd5b506103b061187c565b34801561059457600080fd5b506103b06105a3366004613bb2565b6118ec565b3480156105b457600080fd5b506103b06105c3366004613bb2565b60176020526000908152604090205481565b3480156105e157600080fd5b506103b060165481565b3480156105f757600080fd5b506103b0610606366004613cff565b60186020526000908152604090205481565b34801561062457600080fd5b506103e161193c565b34801561063957600080fd5b506103b060035481565b34801561064f57600080fd5b506000546001600160a01b0316610464565b34801561066d57600080fd5b506103b0600d5481565b34801561068357600080fd5b506010546103b0565b34801561069857600080fd5b506106c06106a7366004613bb2565b6012602052600090815260409020805460019091015482565b604080519283526020830191909152016103ba565b3480156106e157600080fd5b506103e16106f0366004613d2f565b6119e0565b34801561070157600080fd5b506103b0610710366004613cff565b611c86565b34801561072157600080fd5b506103e1610730366004613bb2565b611ce6565b34801561074157600080fd5b506103b0600e5481565b34801561075757600080fd5b506103b0600281565b34801561076c57600080fd5b506103b0600b5481565b34801561078257600080fd5b5061078b611e51565b6040516103ba9190613de6565b3480156107a457600080fd5b506103e16107b3366004613cff565b611edf565b3480156107c457600080fd5b506103e16107d3366004613cff565b61203d565b3480156107e457600080fd5b506103e16107f3366004613cff565b6121f8565b34801561080457600080fd5b506103e1612349565b34801561081957600080fd5b506103e1610828366004613cff565b612527565b34801561083957600080fd5b506103b0610848366004613bb2565b6127bd565b34801561085957600080fd5b506103b0600c5481565b34801561086f57600080fd5b506106c061087e366004613bb2565b6011602052600090815260409020805460019091015482565b3480156108a357600080fd5b50600654610464906001600160a01b031681565b3480156108c357600080fd5b506108d76108d2366004613bb2565b6127db565b604080518251815260209283015192810192909252016103ba565b3480156108fe57600080fd5b506103b0600a5481565b34801561091457600080fd5b506103e1610923366004613c3b565b612875565b34801561093457600080fd5b506103e1610943366004613bb2565b612a34565b34801561095457600080fd5b506103e1612b65565b34801561096957600080fd5b50600254610464906001600160a01b031681565b34801561098957600080fd5b506103e1610998366004613cff565b612ec5565b3480156109a957600080fd5b506103e16109b8366004613bfb565b613017565b42600354111580156109d157506004544211155b610a0a5760405162461bcd60e51b815260206004820152600a6024820152694e6f74206f6e67696e6760b01b604482015260640161038c565b33346000610a1661187c565b90506000610a23846118ec565b905060008311610a605760405162461bcd60e51b81526020600482015260086024820152670c08185b5bdd5b9d60c21b604482015260640161038c565b600a5483600b54610a719190613ee5565b1115610aad5760405162461bcd60e51b815260206004820152600b60248201526a546172676574206869742160a81b604482015260640161038c565b60008260011415610ae2576001600160a01b038516600090815260116020526040902054610adb9085613ee5565b9050610b11565b8260021415610b11576001600160a01b038516600090815260126020526040902054610b0e9085613ee5565b90505b600e54811015610b505760405162461bcd60e51b815260206004820152600a602482015269131bddc8185b5bdd5b9d60b21b604482015260640161038c565b81811115610b925760405162461bcd60e51b815260206004820152600f60248201526e151bdbc81b5d58da08185b5bdd5b9d608a1b604482015260640161038c565b323314610bd15760405162461bcd60e51b815260206004820152600d60248201526c73686f756c6420626520454f4160981b604482015260640161038c565b6009546001600160a01b031615610c2a5760405162461bcd60e51b815260206004820152601660248201527f49742773206e6f7420424e422d62757920706f6f6c2100000000000000000000604482015260640161038c565b610c343334613153565b5050505050565b6002546040516336b87bd760e11b81523360048201526001600160a01b0390911690636d70f7ae9060240160206040518083038186803b158015610c7e57600080fd5b505afa158015610c92573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610cb69190613ca4565b80610cda575033610ccf6000546001600160a01b031690565b6001600160a01b0316145b610d145760405162461bcd60e51b8152602060048201526015602482015260008051602061401a833981519152604482015260640161038c565b60008111610d4e5760405162461bcd60e51b8152602060048201526007602482015266125b9d985b1a5960ca1b604482015260640161038c565b80600e819055507f47954b45256aec82404d303fc1fef420d021b0e70bd9ee69a9cfc77377154cb0600354600454600554600e54600d54600f604051610d9996959493929190613e19565b60405180910390a150565b6002546040516336b87bd760e11b81523360048201526001600160a01b0390911690636d70f7ae9060240160206040518083038186803b158015610de757600080fd5b505afa158015610dfb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e1f9190613ca4565b80610e43575033610e386000546001600160a01b031690565b6001600160a01b0316145b610e7d5760405162461bcd60e51b8152602060048201526015602482015260008051602061401a833981519152604482015260640161038c565b600454421015610ebb5760405162461bcd60e51b8152602060048201526009602482015268139bdd08195b99195960ba1b604482015260640161038c565b6009546001600160a01b0316610f135760405162461bcd60e51b815260206004820152601860248201527f49742773206e6f7420746f6b656e2d62757920706f6f6c210000000000000000604482015260640161038c565b6009546040516370a0823160e01b81523060048201526000916001600160a01b0316906370a082319060240160206040518083038186803b158015610f5757600080fd5b505afa158015610f6b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f8f9190613d17565b600254604080516202eab760e01b8152815193945060009384936001600160a01b0316926202eab79260048082019391829003018186803b158015610fd357600080fd5b505afa158015610fe7573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061100b9190613bce565b909250905060006103e861101f8386613f1d565b6110299190613efd565b905060006110378286613f3c565b600954909150611051906001600160a01b031685846133b7565b600954610c34906001600160a01b031633836133b7565b6010818154811061107857600080fd5b6000918252602090912001546001600160a01b0316905081565b6002546040516336b87bd760e11b81523360048201526001600160a01b0390911690636d70f7ae9060240160206040518083038186803b1580156110d557600080fd5b505afa1580156110e9573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061110d9190613ca4565b806111315750336111266000546001600160a01b031690565b6001600160a01b0316145b61116b5760405162461bcd60e51b8152602060048201526015602482015260008051602061401a833981519152604482015260640161038c565b600083116111bb5760405162461bcd60e51b815260206004820152600960248201527f30206d696e46756e640000000000000000000000000000000000000000000000604482015260640161038c565b6000821161120b5760405162461bcd60e51b815260206004820152600660248201527f3020626173650000000000000000000000000000000000000000000000000000604482015260640161038c565b428611801561121957508486105b801561122457508385105b6112705760405162461bcd60e51b815260206004820152600d60248201527f496e76616c69642074696d657300000000000000000000000000000000000000604482015260640161038c565b600386905560048590556005849055600e839055805161129790600f906020840190613a49565b5081600d819055507f47954b45256aec82404d303fc1fef420d021b0e70bd9ee69a9cfc77377154cb0600354600454600554600e54600d54600f6040516112e396959493929190613e19565b60405180910390a1505050505050565b6002546040516336b87bd760e11b81523360048201526001600160a01b0390911690636d70f7ae9060240160206040518083038186803b15801561133657600080fd5b505afa15801561134a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061136e9190613ca4565b806113925750336113876000546001600160a01b031690565b6001600160a01b0316145b6113cc5760405162461bcd60e51b8152602060048201526015602482015260008051602061401a833981519152604482015260640161038c565b426003541161141d5760405162461bcd60e51b815260206004820152600f60248201527f416c726561647920737461727465640000000000000000000000000000000000604482015260640161038c565b4281116114565760405162461bcd60e51b8152602060048201526007602482015266125b9d985b1a5960ca1b604482015260640161038c565b6003819055600454600554600e54600d546040517f47954b45256aec82404d303fc1fef420d021b0e70bd9ee69a9cfc77377154cb094610d9994879491939092600f90613e19565b6002546040516336b87bd760e11b81523360048201526001600160a01b0390911690636d70f7ae9060240160206040518083038186803b1580156114e157600080fd5b505afa1580156114f5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115199190613ca4565b8061153d5750336115326000546001600160a01b031690565b6001600160a01b0316145b6115775760405162461bcd60e51b8152602060048201526015602482015260008051602061401a833981519152604482015260640161038c565b4281118015611587575060045481115b6115bd5760405162461bcd60e51b8152602060048201526007602482015266125b9d985b1a5960ca1b604482015260640161038c565b6005819055600354600454600e54600d546040517f47954b45256aec82404d303fc1fef420d021b0e70bd9ee69a9cfc77377154cb094610d9994909390928792600f90613e19565b6002546040516336b87bd760e11b81523360048201526001600160a01b0390911690636d70f7ae9060240160206040518083038186803b15801561164857600080fd5b505afa15801561165c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116809190613ca4565b806116a45750336116996000546001600160a01b031690565b6001600160a01b0316145b6116de5760405162461bcd60e51b8152602060048201526015602482015260008051602061401a833981519152604482015260640161038c565b80516116f190600f906020840190613a49565b507f47954b45256aec82404d303fc1fef420d021b0e70bd9ee69a9cfc77377154cb0600354600454600554600e54600d54600f604051610d9996959493929190613e19565b6005544210156117785760405162461bcd60e51b815260206004820152600d60248201526c4e6f7420636c61696d61626c6560981b604482015260640161038c565b600260015414156117cb5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015260640161038c565b600260015532331461180f5760405162461bcd60e51b815260206004820152600d60248201526c73686f756c6420626520454f4160981b604482015260640161038c565b600061181a336127bd565b90506000811161186c5760405162461bcd60e51b815260206004820152601060248201527f4e6f7468696e6720746f20636c61696d00000000000000000000000000000000604482015260640161038c565b6118753361344c565b5060018055565b600060035442108061188f575060045442115b1561189c575060006118e9565b600060026003546004546118b09190613f3c565b6118ba9190613efd565b9050600081600354426118cd9190613f3c565b6118d79190613efd565b90506118e4816001613ee5565b925050505b90565b6000806118f761187c565b905080611908576000915050611937565b80600114156119315750506001600160a01b038116600090815260176020526040902054611937565b5050600d545b919050565b6000546001600160a01b031633146119965760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161038c565b600080546040516001600160a01b03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600080546001600160a01b0319169055565b6002546040516336b87bd760e11b81523360048201526001600160a01b0390911690636d70f7ae9060240160206040518083038186803b158015611a2357600080fd5b505afa158015611a37573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a5b9190613ca4565b80611a7f575033611a746000546001600160a01b031690565b6001600160a01b0316145b611ab95760405162461bcd60e51b8152602060048201526015602482015260008051602061401a833981519152604482015260640161038c565b6005548411611b0a5760405162461bcd60e51b815260206004820152600d60248201527f496e76616c696420436c69666600000000000000000000000000000000000000604482015260640161038c565b6103e8831115611b5c5760405162461bcd60e51b815260206004820152600b60248201527f496e76616c696420746765000000000000000000000000000000000000000000604482015260640161038c565b600082118015611b6c5750600081115b611bb85760405162461bcd60e51b815260206004820152601460248201527f30204475726174696f6e206f7220506572696f64000000000000000000000000604482015260640161038c565b80611bc38184613efd565b611bcd9190613f1d565b611bd79083613f3c565b15611c245760405162461bcd60e51b815260206004820152600b60248201527f4e6f742064697669646564000000000000000000000000000000000000000000604482015260640161038c565b60138490556014839055601582905560168190556040805185815260208101859052908101839052606081018290527f0cdccee4294ef1828512c7a50e43161abfba8be25b7470c13ed771644aa21b2d9060800160405180910390a150505050565b600081611c9557506000611937565b8160011415611ca75750600a54611937565b600160005260186020527ff3794665d3af9b6fb6f858b70185898134f96768ef31c325d52e04f0ac195a4d54600a54611ce09190613f3c565b92915050565b6002546040516336b87bd760e11b81523360048201526001600160a01b0390911690636d70f7ae9060240160206040518083038186803b158015611d2957600080fd5b505afa158015611d3d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d619190613ca4565b80611d85575033611d7a6000546001600160a01b031690565b6001600160a01b0316145b611dbf5760405162461bcd60e51b8152602060048201526015602482015260008051602061401a833981519152604482015260640161038c565b6001600160a01b038116611dff5760405162461bcd60e51b8152602060048201526007602482015266125b9d985b1a5960ca1b604482015260640161038c565b600680546001600160a01b0319166001600160a01b038381169190911791829055604051911681527fdefd52f9aef0138625fe1a6cfbe86a662de840ccb42d91039a1547b6fd65707a90602001610d99565b600f8054611e5e90613f7f565b80601f0160208091040260200160405190810160405280929190818152602001828054611e8a90613f7f565b8015611ed75780601f10611eac57610100808354040283529160200191611ed7565b820191906000526020600020905b815481529060010190602001808311611eba57829003601f168201915b505050505081565b6002546040516336b87bd760e11b81523360048201526001600160a01b0390911690636d70f7ae9060240160206040518083038186803b158015611f2257600080fd5b505afa158015611f36573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f5a9190613ca4565b80611f7e575033611f736000546001600160a01b031690565b6001600160a01b0316145b611fb85760405162461bcd60e51b8152602060048201526015602482015260008051602061401a833981519152604482015260640161038c565b60008111611ff25760405162461bcd60e51b8152602060048201526007602482015266125b9d985b1a5960ca1b604482015260640161038c565b80600d819055507f47954b45256aec82404d303fc1fef420d021b0e70bd9ee69a9cfc77377154cb0600354600454600554600e54600d54600f604051610d9996959493929190613e19565b6002546040516336b87bd760e11b81523360048201526001600160a01b0390911690636d70f7ae9060240160206040518083038186803b15801561208057600080fd5b505afa158015612094573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120b89190613ca4565b806120dc5750336120d16000546001600160a01b031690565b6001600160a01b0316145b6121165760405162461bcd60e51b8152602060048201526015602482015260008051602061401a833981519152604482015260640161038c565b60045442106121675760405162461bcd60e51b815260206004820152600560248201527f456e646564000000000000000000000000000000000000000000000000000000604482015260640161038c565b4281118015612177575060035481115b6121ad5760405162461bcd60e51b8152602060048201526007602482015266125b9d985b1a5960ca1b604482015260640161038c565b806004819055507f47954b45256aec82404d303fc1fef420d021b0e70bd9ee69a9cfc77377154cb0600354600454600554600e54600d54600f604051610d9996959493929190613e19565b6002546040516336b87bd760e11b81523360048201526001600160a01b0390911690636d70f7ae9060240160206040518083038186803b15801561223b57600080fd5b505afa15801561224f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122739190613ca4565b8061229757503361228c6000546001600160a01b031690565b6001600160a01b0316145b6122d15760405162461bcd60e51b8152602060048201526015602482015260008051602061401a833981519152604482015260640161038c565b6000811161230b5760405162461bcd60e51b8152602060048201526007602482015266125b9d985b1a5960ca1b604482015260640161038c565b600a81905560075460408051918252602082018390527ff544f637f7119822ecd07db25a0c73e6f73097def4e5050f15a3370e769db0779101610d99565b6002546040516336b87bd760e11b81523360048201526001600160a01b0390911690636d70f7ae9060240160206040518083038186803b15801561238c57600080fd5b505afa1580156123a0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123c49190613ca4565b806123e85750336123dd6000546001600160a01b031690565b6001600160a01b0316145b6124225760405162461bcd60e51b8152602060048201526015602482015260008051602061401a833981519152604482015260640161038c565b60045442116124735760405162461bcd60e51b815260206004820152601560248201527f49444f20686173206e6f742079657420656e6465640000000000000000000000604482015260640161038c565b600854600c546006546040516370a0823160e01b8152306004820152612525933393909290916001600160a01b03909116906370a082319060240160206040518083038186803b1580156124c657600080fd5b505afa1580156124da573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124fe9190613d17565b6125089190613ee5565b6125129190613f3c565b6006546001600160a01b031691906133b7565b565b426003541115801561253b57506004544211155b6125745760405162461bcd60e51b815260206004820152600a6024820152694e6f74206f6e67696e6760b01b604482015260640161038c565b3381600061258061187c565b9050600061258d846118ec565b9050600083116125ca5760405162461bcd60e51b81526020600482015260086024820152670c08185b5bdd5b9d60c21b604482015260640161038c565b600a5483600b546125db9190613ee5565b11156126175760405162461bcd60e51b815260206004820152600b60248201526a546172676574206869742160a81b604482015260640161038c565b6000826001141561264c576001600160a01b0385166000908152601160205260409020546126459085613ee5565b905061267b565b826002141561267b576001600160a01b0385166000908152601260205260409020546126789085613ee5565b90505b600e548110156126ba5760405162461bcd60e51b815260206004820152600a602482015269131bddc8185b5bdd5b9d60b21b604482015260640161038c565b818111156126fc5760405162461bcd60e51b815260206004820152600f60248201526e151bdbc81b5d58da08185b5bdd5b9d608a1b604482015260640161038c565b32331461273b5760405162461bcd60e51b815260206004820152600d60248201526c73686f756c6420626520454f4160981b604482015260640161038c565b6009546001600160a01b03166127935760405162461bcd60e51b815260206004820152601860248201527f49742773206e6f7420746f6b656e2d62757920706f6f6c210000000000000000604482015260640161038c565b61279d3387613153565b6009546127b5906001600160a01b03163330896135b6565b505050505050565b60006127c8826135f4565b6127d183613628565b611ce09190613ee5565b604080518082019091526000808252602082015260408051808201909152600080825260208201526001600160a01b0383166000908152601260209081526040808320546011909252909120546128329190613ee5565b81526001600160a01b0383166000908152601260209081526040808320600190810154601190935292209091015461286a9190613ee5565b602082015292915050565b6002546040516336b87bd760e11b81523360048201526001600160a01b0390911690636d70f7ae9060240160206040518083038186803b1580156128b857600080fd5b505afa1580156128cc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128f09190613ca4565b806129145750336129096000546001600160a01b031690565b6001600160a01b0316145b61294e5760405162461bcd60e51b8152602060048201526015602482015260008051602061401a833981519152604482015260640161038c565b82811461299d5760405162461bcd60e51b815260206004820152600e60248201527f496e76616c696420706172616d73000000000000000000000000000000000000604482015260640161038c565b60005b83811015610c34578282828181106129c857634e487b7160e01b600052603260045260246000fd5b90506020020135601760008787858181106129f357634e487b7160e01b600052603260045260246000fd5b9050602002016020810190612a089190613bb2565b6001600160a01b0316815260208101919091526040016000205580612a2c81613fba565b9150506129a0565b6000546001600160a01b03163314612a8e5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161038c565b6001600160a01b038116612b0a5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f6464726573730000000000000000000000000000000000000000000000000000606482015260840161038c565b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b0319166001600160a01b0392909216919091179055565b6002546040516336b87bd760e11b81523360048201526001600160a01b0390911690636d70f7ae9060240160206040518083038186803b158015612ba857600080fd5b505afa158015612bbc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612be09190613ca4565b80612c04575033612bf96000546001600160a01b031690565b6001600160a01b0316145b612c3e5760405162461bcd60e51b8152602060048201526015602482015260008051602061401a833981519152604482015260640161038c565b600454421015612c7c5760405162461bcd60e51b8152602060048201526009602482015268139bdd08195b99195960ba1b604482015260640161038c565b6009546001600160a01b031615612cd55760405162461bcd60e51b815260206004820152601660248201527f49742773206e6f7420424e422d62757920706f6f6c2100000000000000000000604482015260640161038c565b600254604080516202eab760e01b81528151479360009384936001600160a01b03909216926202eab7926004808201939291829003018186803b158015612d1b57600080fd5b505afa158015612d2f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d539190613bce565b909250905060006103e8612d678386613f1d565b612d719190613efd565b90506000612d7f8286613f3c565b90506000846001600160a01b03168360405160006040518083038185875af1925050503d8060008114612dce576040519150601f19603f3d011682016040523d82523d6000602084013e612dd3565b606091505b5050905080612e245760405162461bcd60e51b815260206004820152601260248201527f424e422066656520706179206661696c65640000000000000000000000000000604482015260640161038c565b604051600090339084908381818185875af1925050503d8060008114612e66576040519150601f19603f3d011682016040523d82523d6000602084013e612e6b565b606091505b5050905080612ebc5760405162461bcd60e51b815260206004820152601360248201527f424e42207769746864726177206661696c656400000000000000000000000000604482015260640161038c565b50505050505050565b6002546040516336b87bd760e11b81523360048201526001600160a01b0390911690636d70f7ae9060240160206040518083038186803b158015612f0857600080fd5b505afa158015612f1c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f409190613ca4565b80612f64575033612f596000546001600160a01b031690565b6001600160a01b0316145b612f9e5760405162461bcd60e51b8152602060048201526015602482015260008051602061401a833981519152604482015260640161038c565b60008111612fd85760405162461bcd60e51b8152602060048201526007602482015266125b9d985b1a5960ca1b604482015260640161038c565b6007819055600a546040805183815260208101929092527ff544f637f7119822ecd07db25a0c73e6f73097def4e5050f15a3370e769db0779101610d99565b6005544210156130595760405162461bcd60e51b815260206004820152600d60248201526c4e6f7420636c61696d61626c6560981b604482015260640161038c565b600260015414156130ac5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015260640161038c565b60026001553233146130f05760405162461bcd60e51b815260206004820152600d60248201526c73686f756c6420626520454f4160981b604482015260640161038c565b60005b8181101561314a5761313883838381811061311e57634e487b7160e01b600052603260045260246000fd5b90506020020160208101906131339190613bb2565b61344c565b8061314281613fba565b9150506130f3565b50506001805550565b6000600a54600754836131669190613f1d565b6131709190613efd565b9050600061317c61187c565b905082600b5461318c9190613ee5565b600b5560085461319d908390613ee5565b600855806001811415613255576001600160a01b03851660009081526011602052604090205461321357601080546001810182556000919091527f1b6847dc741a1b0cd08d278845f9d819d87b734759afb55fe2de5cb82a9ae6720180546001600160a01b0319166001600160a01b0387161790555b6001600160a01b038516600090815260116020526040902054613237908590613ee5565b6001600160a01b038616600090815260116020526040902055613329565b8160021415613329576001600160a01b03851660009081526011602052604090205415801561329a57506001600160a01b038516600090815260126020526040902054155b156132eb57601080546001810182556000919091527f1b6847dc741a1b0cd08d278845f9d819d87b734759afb55fe2de5cb82a9ae6720180546001600160a01b0319166001600160a01b0387161790555b6001600160a01b03851660009081526012602052604090205461330f908590613ee5565b6001600160a01b0386166000908152601260205260409020555b600081815260186020526040902054613343908590613ee5565b60008281526018602090815260409182902092909255600b5460085482516001600160a01b038a168152938401889052918301526060820152608081018390527f2e10dca68d13f21427d1f4798389c7b999e339c241d547a2da046036d2d79e329060a00160405180910390a15050505050565b6040516001600160a01b03831660248201526044810182905261344790849063a9059cbb60e01b906064015b60408051601f198184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152613652565b505050565b6001600160a01b0381166134a25760405162461bcd60e51b815260206004820152600f60248201527f496e76616c696420616464726573730000000000000000000000000000000000604482015260640161038c565b60006134ad826127bd565b905080156135b2576134be82613628565b6001600160a01b0383166000908152601160205260409020600101546134e49190613ee5565b6001600160a01b038316600090815260116020526040902060010155613509826135f4565b6001600160a01b03831660009081526012602052604090206001015461352f9190613ee5565b6001600160a01b0380841660009081526012602052604090206001019190915560065461355e911683836133b7565b80600c5461356c9190613ee5565b600c55604080516001600160a01b0384168152602081018390527f8b4619cd854e5d0890654f42fdcc881750a2b348ceeda941a1ef61c419bbde1c910160405180910390a15b5050565b6040516001600160a01b03808516602483015283166044820152606481018290526135ee9085906323b872dd60e01b906084016133e3565b50505050565b6001600160a01b03811660009081526012602052604081206001810154905461361e908490613737565b611ce09190613f3c565b6001600160a01b03811660009081526011602052604081206001810154905461361e908490613737565b60006136a7826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166138b89092919063ffffffff16565b80519091501561344757808060200190518101906136c59190613ca4565b6134475760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f74207375636365656400000000000000000000000000000000000000000000606482015260840161038c565b60006001600160a01b03831661378f5760405162461bcd60e51b815260206004820152601060248201527f496e76616c696420616464726573732100000000000000000000000000000000604482015260640161038c565b6005544210156137a157506000611ce0565b6000600a54600754846137b49190613f1d565b6137be9190613efd565b905060006103e8601454836137d39190613f1d565b6137dd9190613efd565b90504260135411156137f2579150611ce09050565b60135461380457600092505050611ce0565b60006016546015546013546138199190613ee5565b6138239190613f3c565b905080421061383757829350505050611ce0565b60006138438385613f3c565b905060006016546015546138579190613efd565b905060006138658284613efd565b905060006016546013544261387a9190613f3c565b6138849190613efd565b61388f906001613ee5565b9050600061389d8284613f1d565b90506138a98188613ee5565b9b9a5050505050505050505050565b60606138c784846000856138d1565b90505b9392505050565b6060824710156139495760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c0000000000000000000000000000000000000000000000000000606482015260840161038c565b843b6139975760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640161038c565b600080866001600160a01b031685876040516139b39190613dca565b60006040518083038185875af1925050503d80600081146139f0576040519150601f19603f3d011682016040523d82523d6000602084013e6139f5565b606091505b5091509150613a05828286613a10565b979650505050505050565b60608315613a1f5750816138ca565b825115613a2f5782518084602001fd5b8160405162461bcd60e51b815260040161038c9190613de6565b828054613a5590613f7f565b90600052602060002090601f016020900481019282613a775760008555613abd565b82601f10613a9057805160ff1916838001178555613abd565b82800160010185558215613abd579182015b82811115613abd578251825591602001919060010190613aa2565b50613ac9929150613acd565b5090565b5b80821115613ac95760008155600101613ace565b60008083601f840112613af3578081fd5b50813567ffffffffffffffff811115613b0a578182fd5b6020830191508360208083028501011115613b2457600080fd5b9250929050565b600082601f830112613b3b578081fd5b813567ffffffffffffffff80821115613b5657613b56613feb565b604051601f8301601f19908116603f01168101908282118183101715613b7e57613b7e613feb565b81604052838152866020858801011115613b96578485fd5b8360208701602083013792830160200193909352509392505050565b600060208284031215613bc3578081fd5b81356138ca81614001565b60008060408385031215613be0578081fd5b8251613beb81614001565b6020939093015192949293505050565b60008060208385031215613c0d578182fd5b823567ffffffffffffffff811115613c23578283fd5b613c2f85828601613ae2565b90969095509350505050565b60008060008060408587031215613c50578182fd5b843567ffffffffffffffff80821115613c67578384fd5b613c7388838901613ae2565b90965094506020870135915080821115613c8b578384fd5b50613c9887828801613ae2565b95989497509550505050565b600060208284031215613cb5578081fd5b815180151581146138ca578182fd5b600060208284031215613cd5578081fd5b813567ffffffffffffffff811115613ceb578182fd5b613cf784828501613b2b565b949350505050565b600060208284031215613d10578081fd5b5035919050565b600060208284031215613d28578081fd5b5051919050565b60008060008060808587031215613d44578384fd5b5050823594602084013594506040840135936060013592509050565b60008060008060008060c08789031215613d78578182fd5b863595506020870135945060408701359350606087013592506080870135915060a087013567ffffffffffffffff811115613db1578182fd5b613dbd89828a01613b2b565b9150509295509295509295565b60008251613ddc818460208701613f53565b9190910192915050565b6000602082528251806020840152613e05816040850160208701613f53565b601f01601f19169190910160400192915050565b60008782526020878184015286604084015285606084015284608084015260c060a084015281845483600282049050600180831680613e5957607f831692505b858310811415613e7757634e487b7160e01b87526022600452602487fd5b60c0880183905260e08801818015613e965760018114613ea757613ed1565b60ff19861682528782019650613ed1565b60008b815260209020895b86811015613ecb57815484820152908501908901613eb2565b83019750505b50949e9d5050505050505050505050505050565b60008219821115613ef857613ef8613fd5565b500190565b600082613f1857634e487b7160e01b81526012600452602481fd5b500490565b6000816000190483118215151615613f3757613f37613fd5565b500290565b600082821015613f4e57613f4e613fd5565b500390565b60005b83811015613f6e578181015183820152602001613f56565b838111156135ee5750506000910152565b600281046001821680613f9357607f821691505b60208210811415613fb457634e487b7160e01b600052602260045260246000fd5b50919050565b6000600019821415613fce57613fce613fd5565b5060010190565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160a01b038116811461401657600080fd5b5056fe4e6f74206f776e6572206f72206f70657261746f720000000000000000000000a164736f6c6343000802000aa164736f6c6343000802000a
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
0000000000000000000000005c09a250787765e84377e705d61c8f7e37333be90000000000000000000000000000000000000000000000000000000000000046
-----Decoded View---------------
Arg [0] : _feeReceipient (address): 0x5c09a250787765E84377e705d61c8f7e37333Be9
Arg [1] : _feePercent (uint256): 70
-----Encoded View---------------
2 Constructor Arguments found :
Arg [0] : 0000000000000000000000005c09a250787765e84377e705d61c8f7e37333be9
Arg [1] : 0000000000000000000000000000000000000000000000000000000000000046
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
Loading...
Loading
[ Download: CSV Export ]
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.