Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
Latest 1 from a total of 1 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
0x60806040 | 15587500 | 662 days ago | IN | Create: Sales721ForEth | 0 ETH | 0.02362742 |
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Contract Name:
Sales721ForEth
Compiler Version
v0.6.12+commit.27d51765
Optimization Enabled:
Yes with 200 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT pragma solidity ^0.6.12; pragma experimental ABIEncoderV2; import "./Dependencies/Ownable.sol"; import "./Dependencies/SafeMath.sol"; import "./Dependencies/SafeERC20.sol"; import "./Dependencies/IERC20.sol"; import "./Dependencies/IERC721.sol"; import "./Dependencies/ReentrancyGuard.sol"; contract Sales721ForEth is Ownable, ReentrancyGuard { using SafeMath for uint256; using SafeERC20 for IERC20; // set the saleIDCounter initial value to 1 uint256 private saleIDCounter = 1; bool private onlyInitOnce; struct BaseSale { // the sale setter address seller; // addresses of token to sell address tokenAddresses; // tokenIDs of token to sell uint256[] tokenIDs; // address of token to pay address payTokenAddress; // price of token to pay uint256 price; // address of receiver address receiver; uint256 startTime; uint256 endTime; // whether the sale is available bool isAvailable; } struct FlashSale { BaseSale base; // max number of token could be bought from an address uint256 purchaseLimitation; } struct Auction { BaseSale base; // the minimum increment in a bid uint256 minBidIncrement; // the highest price so far uint256 highestBidPrice; // the highest bidder so far address highestBidder; } struct Activity { uint256 limitation; uint256 activityId; uint256[] salesIDs; bool isEnable; } struct WhitelistActivity { bool isWhitelist; mapping(address => bool) whitelists; } // whitelist to set sale mapping(address => bool) public whitelist; // sale ID -> flash sale mapping(uint256 => FlashSale) flashSales; // sale ID -> mapping(address => how many tokens have bought) mapping(uint256 => mapping(address => uint256)) flashSaleIDToPurchaseRecord; // sale ID -> auction mapping(uint256 => Auction) auctions; // filter to check repetition mapping(address => mapping(uint256 => bool)) repetitionFilter; address public testServerAddress; address public serverAddress; // sale ID -> server hash mapping(bytes32 => uint256) serverHashMap; // whitelist to set sale mapping(uint256 => bool) public flashSaleOnProd; //activityId => activity mapping(uint256 => Activity) public activityMap; //salesId => activityId mapping(uint256 => uint256) public activityIndex; //activityID => WhitelistActivity mapping(uint256 => WhitelistActivity) public activityWhitelist; event SetWhitelist(address _member, bool _isAdded); event SetFlashSale( uint256 _saleID, address _flashSaleSetter, address _tokenAddresses, uint256[] _tokenIDs, address _payTokenAddress, uint256 _price, address _receiver, uint256 _purchaseLimitation, uint256 _startTime, uint256 _endTime ); event UpdateFlashSale( uint256 _saleID, address _operator, address _newTokenAddresses, uint256[] _newTokenIDs, address _newPayTokenAddress, uint256 _newPrice, address _newReceiver, uint256 _newPurchaseLimitation, uint256 _newStartTime, uint256 _newEndTime ); event CancelFlashSale(uint256 _saleID, address _operator); event FlashSaleExpired(uint256 _saleID, address _operator); event Purchase( uint256 _saleID, address _buyer, address _tokenAddresses, uint256[] _tokenIDs, address _payTokenAddress, uint256 _totalPayment ); event SetAuction( uint256 _saleID, address _auctionSetter, address _tokenAddresses, uint256[] _tokenIDs, address _payTokenAddress, uint256 _initialPrice, address _receiver, uint256 _minBidIncrement, uint256 _startTime, uint256 _endTime ); event UpdateAuction( uint256 _saleID, address _operator, address _newTokenAddresses, uint256[] _newTokenIDs, address _newPayTokenAddress, uint256 _newInitialPrice, address _newReceiver, uint256 _newMinBidIncrement, uint256 _newStartTime, uint256 _newEndTime ); event RefundToPreviousBidder( uint256 _saleID, address _previousBidder, address _payTokenAddress, uint256 _refundAmount ); event CancelAuction(uint256 _saleID, address _operator); event NewBidderTransfer(uint256 _saleID, address _newBidder, address _payTokenAddress, uint256 _bidPrice); event SettleAuction( uint256 _saleID, address _operator, address _receiver, address _highestBidder, address _tokenAddresses, uint256[] _tokenIDs, address _payTokenAddress, uint256 _highestBidPrice ); event MainCoin(uint256 totalPayment); modifier onlyWhitelist() { require(whitelist[msg.sender], "the caller isn't in the whitelist"); _; } function init(address _newOwner) public { require(!onlyInitOnce, "already initialized"); _transferOwnership(_newOwner); onlyInitOnce = true; } function getActivity(uint256 id) external view returns (Activity memory) { return activityMap[id]; } //return the amount of all sales function getActivityTotalAmount(uint256 activityId, address puchaser) public view returns (uint256) { Activity memory activity = activityMap[activityId]; uint256 total; for (uint256 i = 0; i < activity.salesIDs.length; i++) { uint256 saleId = activity.salesIDs[i]; total = total + flashSaleIDToPurchaseRecord[saleId][puchaser]; } return total; } function setActivity(Activity memory activity) external onlyOwner { activityMap[activity.activityId] = activity; for (uint256 i = 0; i < activity.salesIDs.length; i++) { uint256 saleId = activity.salesIDs[i]; activityIndex[saleId] = activity.activityId; } } function setWhitelist(address _member, bool _status) external onlyOwner { whitelist[_member] = _status; emit SetWhitelist(_member, _status); } // set auction by the member in whitelist function setAuction( address _tokenAddresses, uint256[] memory _tokenIDs, address _payTokenAddress, uint256 _initialPrice, address _receiver, uint256 _minBidIncrement, uint256 _startTime, uint256 _duration ) external nonReentrant onlyWhitelist { // 1. check the validity of params _checkAuctionParams( msg.sender, _tokenAddresses, _tokenIDs, _initialPrice, _minBidIncrement, _startTime, _duration ); // 2. build auction Auction memory auction = Auction({ base: BaseSale({ seller: msg.sender, tokenAddresses: _tokenAddresses, tokenIDs: _tokenIDs, payTokenAddress: _payTokenAddress, price: _initialPrice, receiver: _receiver, startTime: _startTime, endTime: _startTime.add(_duration), isAvailable: true }), minBidIncrement: _minBidIncrement, highestBidPrice: 0, highestBidder: address(0) }); // 3. store auction uint256 currentSaleID = saleIDCounter; saleIDCounter = saleIDCounter.add(1); auctions[currentSaleID] = auction; emit SetAuction( currentSaleID, auction.base.seller, auction.base.tokenAddresses, auction.base.tokenIDs, auction.base.payTokenAddress, auction.base.price, auction.base.receiver, auction.minBidIncrement, auction.base.startTime, auction.base.endTime ); } // update auction by the member in whitelist function updateAuction( uint256 _saleID, address _tokenAddresses, uint256[] memory _tokenIDs, address _payTokenAddress, uint256 _initialPrice, address _receiver, uint256 _minBidIncrement, uint256 _startTime, uint256 _duration ) external nonReentrant onlyWhitelist { Auction memory auction = _getAuctionByID(_saleID); // 1. make sure that the auction doesn't start require(auction.base.startTime > now, "it's not allowed to update the auction after the start of it"); require(auction.base.isAvailable, "the auction has been cancelled"); require(auction.base.seller == msg.sender, "the auction can only be updated by its setter"); // 2. check the validity of params to update _checkAuctionParams( msg.sender, _tokenAddresses, _tokenIDs, _initialPrice, _minBidIncrement, _startTime, _duration ); // 3. update the auction auction.base.tokenAddresses = _tokenAddresses; auction.base.tokenIDs = _tokenIDs; auction.base.payTokenAddress = _payTokenAddress; auction.base.price = _initialPrice; auction.base.receiver = _receiver; auction.base.startTime = _startTime; auction.base.endTime = _startTime.add(_duration); auction.minBidIncrement = _minBidIncrement; auctions[_saleID] = auction; emit UpdateAuction( _saleID, auction.base.seller, auction.base.tokenAddresses, auction.base.tokenIDs, auction.base.payTokenAddress, auction.base.price, auction.base.receiver, auction.minBidIncrement, auction.base.startTime, auction.base.endTime ); } // cancel the auction function cancelAuction(uint256 _saleID) external nonReentrant onlyWhitelist { Auction memory auction = _getAuctionByID(_saleID); require(auction.base.isAvailable, "the auction isn't available"); require(auction.base.seller == msg.sender, "the auction can only be cancelled by its setter"); if (auction.highestBidPrice != 0) { // some bid has paid for this auction IERC20(auction.base.payTokenAddress).safeTransfer(auction.highestBidder, auction.highestBidPrice); emit RefundToPreviousBidder( _saleID, auction.highestBidder, auction.base.payTokenAddress, auction.highestBidPrice ); } auctions[_saleID].base.isAvailable = false; emit CancelAuction(_saleID, msg.sender); } // bid for the target auction function bid(uint256 _saleID, uint256 _bidPrice) external nonReentrant { Auction memory auction = _getAuctionByID(_saleID); // check the validity of the target auction require(auction.base.isAvailable, "the auction isn't available"); require(auction.base.seller != msg.sender, "the setter can't bid for its own auction"); uint256 currentTime = now; require(currentTime >= auction.base.startTime, "the auction doesn't start"); require(currentTime < auction.base.endTime, "the auction has expired"); IERC20 payToken = IERC20(auction.base.payTokenAddress); // check bid price in auction if (auction.highestBidPrice != 0) { // not first bid require( _bidPrice.sub(auction.highestBidPrice) >= auction.minBidIncrement, "the bid price must be larger than the sum of current highest one and minimum bid increment" ); // refund to the previous highest bidder from this contract payToken.safeTransfer(auction.highestBidder, auction.highestBidPrice); emit RefundToPreviousBidder( _saleID, auction.highestBidder, auction.base.payTokenAddress, auction.highestBidPrice ); } else { // first bid require(_bidPrice == auction.base.price, "first bid must follow the initial price set in the auction"); } // update storage auctions auctions[_saleID].highestBidPrice = _bidPrice; auctions[_saleID].highestBidder = msg.sender; // transfer the bid price into this contract payToken.safeApprove(address(this), 0); payToken.safeApprove(address(this), _bidPrice); payToken.safeTransferFrom(msg.sender, address(this), _bidPrice); emit NewBidderTransfer(_saleID, msg.sender, auction.base.payTokenAddress, _bidPrice); } // settle the auction by the member in whitelist function settleAuction(uint256 _saleID) external nonReentrant onlyWhitelist { Auction memory auction = _getAuctionByID(_saleID); // check the validity of the target auction require(auction.base.isAvailable, "only the available auction can be settled"); require(auction.base.endTime <= now, "the auction can only be settled after its end time"); if (auction.highestBidPrice != 0) { // the auction has been bidden // transfer pay token to the receiver from this contract IERC20(auction.base.payTokenAddress).safeTransfer(auction.base.receiver, auction.highestBidPrice); // transfer erc721s to the bidder who keeps the highest price for (uint256 i = 0; i < auction.base.tokenIDs.length; i++) { IERC721(auction.base.tokenAddresses).safeTransferFrom( auction.base.seller, auction.highestBidder, auction.base.tokenIDs[i] ); } } // close the auction auctions[_saleID].base.isAvailable = false; emit SettleAuction( _saleID, msg.sender, auction.base.receiver, auction.highestBidder, auction.base.tokenAddresses, auction.base.tokenIDs, auction.base.payTokenAddress, auction.highestBidPrice ); } event AddTokens(uint256[] _tokenIds, uint256 _saleID); function addTokenIdToSale( uint256 _saleID, address _tokenAddresses, uint256[] memory _tokenIDs ) external onlyWhitelist { uint256 standardLen = _tokenIDs.length; require(standardLen > 0, "length of tokenAddresses must be > 0"); require(flashSales[_saleID].base.startTime > now, "it's not allowed to update the sale after the start of it"); require(flashSales[_saleID].base.seller == msg.sender, "the sale can only be updated by its setter"); IERC721 tokenAddressCached = IERC721(_tokenAddresses); for (uint256 i = 0; i < _tokenIDs.length; i++) { uint256 tokenId = _tokenIDs[i]; require( tokenAddressCached.ownerOf(tokenId) == flashSales[_saleID].base.seller, "unmatched ownership of target ERC721 token" ); flashSales[_saleID].base.tokenIDs.push(tokenId); } emit AddTokens(_tokenIDs, _saleID); } // set flash sale by the member in whitelist // NOTE: set 0 duration if you don't want an endTime function setFlashSale( address _tokenAddresses, uint256[] memory _tokenIDs, address _payTokenAddress, uint256 _price, address _receiver, uint256 _purchaseLimitation, uint256 _startTime, uint256 _duration, bool prod ) external nonReentrant onlyWhitelist { // 1. check the validity of params _checkFlashSaleParams(msg.sender, _tokenAddresses, _tokenIDs, _price, _startTime, _purchaseLimitation); // 2. build flash sale uint256 endTime; if (_duration != 0) { endTime = _startTime.add(_duration); } FlashSale memory flashSale = FlashSale({ base: BaseSale({ seller: msg.sender, tokenAddresses: _tokenAddresses, tokenIDs: _tokenIDs, payTokenAddress: _payTokenAddress, price: _price, receiver: _receiver, startTime: _startTime, endTime: endTime, isAvailable: true }), purchaseLimitation: _purchaseLimitation }); // 3. store flash sale uint256 currentSaleID = saleIDCounter; saleIDCounter = saleIDCounter.add(1); flashSales[currentSaleID] = flashSale; //if true then prod env else test env flashSaleOnProd[currentSaleID] = prod; emit SetFlashSale( currentSaleID, flashSale.base.seller, flashSale.base.tokenAddresses, flashSale.base.tokenIDs, flashSale.base.payTokenAddress, flashSale.base.price, flashSale.base.receiver, flashSale.purchaseLimitation, flashSale.base.startTime, flashSale.base.endTime ); } // update the flash sale before starting // NOTE: set 0 duration if you don't want an endTime function updateFlashSale( uint256 _saleID, address _tokenAddresses, uint256[] memory _tokenIDs, address _payTokenAddress, uint256 _price, address _receiver, uint256 _purchaseLimitation, uint256 _startTime, uint256 _duration ) external nonReentrant onlyWhitelist { FlashSale memory flashSale = _getFlashSaleByID(_saleID); // 1. make sure that the flash sale doesn't start require(flashSale.base.startTime > now, "it's not allowed to update the flash sale after the start of it"); require(flashSale.base.isAvailable, "the flash sale has been cancelled"); require(flashSale.base.seller == msg.sender, "the flash sale can only be updated by its setter"); // 2. check the validity of params to update _checkFlashSaleParams(msg.sender, _tokenAddresses, _tokenIDs, _price, _startTime, _purchaseLimitation); // 3. update flash sale uint256 endTime; if (_duration != 0) { endTime = _startTime.add(_duration); } flashSale.base.tokenAddresses = _tokenAddresses; flashSale.base.tokenIDs = _tokenIDs; flashSale.base.payTokenAddress = _payTokenAddress; flashSale.base.price = _price; flashSale.base.receiver = _receiver; flashSale.base.startTime = _startTime; flashSale.base.endTime = endTime; flashSale.purchaseLimitation = _purchaseLimitation; flashSales[_saleID] = flashSale; emit UpdateFlashSale( _saleID, flashSale.base.seller, flashSale.base.tokenAddresses, flashSale.base.tokenIDs, flashSale.base.payTokenAddress, flashSale.base.price, flashSale.base.receiver, flashSale.purchaseLimitation, flashSale.base.startTime, flashSale.base.endTime ); } // cancel the flash sale function cancelFlashSale(uint256 _saleID) external onlyWhitelist { FlashSale memory flashSale = _getFlashSaleByID(_saleID); require(flashSale.base.isAvailable, "the flash sale isn't available"); require(flashSale.base.seller == msg.sender, "the flash sale can only be cancelled by its setter"); flashSales[_saleID].base.isAvailable = false; emit CancelFlashSale(_saleID, msg.sender); } function setServerAddress(address targetAddress) public onlyOwner { serverAddress = targetAddress; } function setTestServerAddress(address targetAddress) public onlyOwner { testServerAddress = targetAddress; } function setFlashSaleEnv(uint256 _saleID, bool isProd) public nonReentrant onlyOwner { flashSaleOnProd[_saleID] = isProd; } function setActivityWhitelist( uint256 _activityId, address[] calldata users ) external onlyOwner{ activityWhitelist[_activityId].isWhitelist = true; for (uint256 i = 0; i < users.length; i++) { activityWhitelist[_activityId].whitelists[users[i]] = true; } } // rush to purchase by anyone function purchase( uint256 _saleID, uint256 _amount, bytes32 hash, uint8 v, bytes32 r, bytes32 s ) external payable nonReentrant { if (flashSaleOnProd[_saleID] == true) { require(ecrecover(hash, v, r, s) == serverAddress, "verify prod server sign failed"); } else { require(ecrecover(hash, v, r, s) == testServerAddress, "verify test server sign failed"); } // we have set saleIDCounter initial value to 1 to prevent when _saleID = 0 from can not being purchased require(serverHashMap[hash] != _saleID, "sign hash repeat"); FlashSale memory flashSale = _getFlashSaleByID(_saleID); // check the validity require(_amount > 0, "amount should be > 0"); require(flashSale.base.isAvailable, "the flash sale isn't available"); require(flashSale.base.seller != msg.sender, "the setter can't make a purchase from its own flash sale"); uint256 currentTime = now; require(currentTime >= flashSale.base.startTime, "the flash sale doesn't start"); // check whether the end time arrives if (flashSale.base.endTime != 0 && flashSale.base.endTime <= currentTime) { // the flash sale has been set an end time and expired flashSales[_saleID].base.isAvailable = false; emit FlashSaleExpired(_saleID, msg.sender); return; } // check the purchase record of the buyer uint256 newPurchaseRecord = flashSaleIDToPurchaseRecord[_saleID][msg.sender].add(_amount); //activity model uint256 activityId = activityIndex[_saleID]; if (activityMap[activityId].isEnable) { //check if need the whitelist require(!activityWhitelist[activityId].isWhitelist || activityWhitelist[activityId].whitelists[msg.sender], "Not in the Whitelist"); Activity memory activity = activityMap[activityId]; uint256 activityAmount = getActivityTotalAmount(activity.activityId, msg.sender); require( activityAmount.add(_amount) <= activity.limitation, "total amount to purchase for activity exceeds the limitation of an address" ); } require( newPurchaseRecord <= flashSale.purchaseLimitation, "total amount to purchase exceeds the limitation of an address" ); // check whether the amount of token rest in flash sale is sufficient for this trade require(_amount <= flashSale.base.tokenIDs.length, "insufficient amount of token for this trade"); // pay the receiver flashSaleIDToPurchaseRecord[_saleID][msg.sender] = newPurchaseRecord; uint256 totalPayment = flashSale.base.price.mul(_amount); //IERC20(flashSale.base.payTokenAddress).safeTransferFrom(msg.sender, flashSale.base.receiver, totalPayment); if (flashSale.base.payTokenAddress != address(0)) { IERC20(flashSale.base.payTokenAddress).safeTransferFrom(msg.sender, flashSale.base.receiver, totalPayment); } else { require(msg.value >= totalPayment, "amount should be > totalPayment"); emit MainCoin(totalPayment); payable(flashSale.base.receiver).transfer(totalPayment); } // transfer erc721 tokens to buyer uint256[] memory tokenIDsRecord = new uint256[](_amount); uint256 targetIndex = flashSale.base.tokenIDs.length - 1; for (uint256 i = 0; i < _amount; i++) { IERC721(flashSale.base.tokenAddresses).safeTransferFrom( flashSale.base.seller, msg.sender, flashSale.base.tokenIDs[targetIndex] ); tokenIDsRecord[i] = flashSale.base.tokenIDs[targetIndex]; targetIndex--; flashSales[_saleID].base.tokenIDs.pop(); } if (flashSales[_saleID].base.tokenIDs.length == 0) { flashSales[_saleID].base.isAvailable = false; } serverHashMap[hash] = _saleID; //event Purchase(uint _saleID, address _buyer, address _tokenAddresses, uint[] _tokenIDs, address _payTokenAddress, uint _totalPayment); emit Purchase( _saleID, msg.sender, flashSale.base.tokenAddresses, tokenIDsRecord, flashSale.base.payTokenAddress, totalPayment ); } function getFlashSaleTokenRemaining(uint256 _saleID) public view returns (uint256) { // check whether the flash sale ID exists FlashSale memory flashSale = _getFlashSaleByID(_saleID); return flashSale.base.tokenIDs.length; } function getFlashSalePurchaseRecord(uint256 _saleID, address _buyer) public view returns (uint256) { // check whether the flash sale ID exists _getFlashSaleByID(_saleID); return flashSaleIDToPurchaseRecord[_saleID][_buyer]; } function getAuctionTokenAmount(uint256 _saleID) public view returns (uint256 amount) { Auction memory auction = auctions[_saleID]; amount = auction.base.tokenIDs.length; } function getFlashSaleTokenAmount(uint256 _saleID) public view returns (uint256 amount) { FlashSale memory flashSale = flashSales[_saleID]; amount = flashSale.base.tokenIDs.length; } function getAuction(uint256 _saleID) public view returns (Auction memory) { return _getAuctionByID(_saleID); } function getFlashSale(uint256 _saleID) public view returns (FlashSale memory) { return _getFlashSaleByID(_saleID); } function getCurrentSaleID() external view returns (uint256) { return saleIDCounter; } function _getAuctionByID(uint256 _saleID) internal view returns (Auction memory auction) { auction = auctions[_saleID]; require(auction.base.seller != address(0), "the target auction doesn't exist"); } function _getFlashSaleByID(uint256 _saleID) internal view returns (FlashSale memory flashSale) { flashSale = flashSales[_saleID]; require(flashSale.base.seller != address(0), "the target flash sale doesn't exist"); } function _checkAuctionParams( address _baseSaleSetter, address _tokenAddresses, uint256[] memory _tokenIDs, uint256 _initialPrice, uint256 _minBidIncrement, uint256 _startTime, uint256 _duration ) internal { _checkBaseSaleParams(_baseSaleSetter, _tokenAddresses, _tokenIDs, _initialPrice, _startTime); require(_minBidIncrement > 0, "minBidIncrement must be > 0"); require(_duration > 0, "duration must be > 0"); } function _checkFlashSaleParams( address _baseSaleSetter, address _tokenAddresses, uint256[] memory _tokenIDs, uint256 _price, uint256 _startTime, uint256 _purchaseLimitation ) internal { uint256 standardLen = _checkBaseSaleParams(_baseSaleSetter, _tokenAddresses, _tokenIDs, _price, _startTime); require(_purchaseLimitation > 0, "purchaseLimitation must be > 0"); /* require(_purchaseLimitation <= standardLen, "purchaseLimitation must be <= the length of tokenAddresses");*/ } function _checkBaseSaleParams( address _baseSaleSetter, address _tokenAddresses, uint256[] memory _tokenIDs, uint256 _price, uint256 _startTime ) internal returns (uint256 standardLen) { standardLen = _tokenIDs.length; // check whether the sale setter has the target tokens && approval IERC721 tokenAddressCached = IERC721(_tokenAddresses); uint256 tokenIDCached; for (uint256 i = 0; i < standardLen; i++) { tokenIDCached = _tokenIDs[i]; // check repetition require(!repetitionFilter[address(tokenAddressCached)][tokenIDCached], "repetitive ERC721 tokens"); repetitionFilter[address(tokenAddressCached)][tokenIDCached] = true; require( tokenAddressCached.ownerOf(tokenIDCached) == _baseSaleSetter, "unmatched ownership of target ERC721 token" ); require( tokenAddressCached.getApproved(tokenIDCached) == address(this) || tokenAddressCached.isApprovedForAll(_baseSaleSetter, address(this)), "the contract hasn't been approved for ERC721 transferring" ); } require(_price >= 0, "the price or the initial price must be >= 0"); require(_startTime >= now, "startTime must be >= now"); // clear filter for (uint256 i = 0; i < standardLen; i++) { repetitionFilter[_tokenAddresses][_tokenIDs[i]] = false; } } using Address for address payable; using Address for address; function withdraw( address token, address to, uint256 amount ) external onlyOwner { if (token.isContract()) { IERC20(token).safeTransfer(to, amount); } else { payable(to).sendValue(amount); } emit EmergencyWithdraw(token, to, amount); } event EmergencyWithdraw(address token, address to, uint256 amount); }
// SPDX-License-Identifier: MIT pragma solidity ^0.6.12; import "./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 () internal { 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; } function _transferOwnership(address newOwner) internal { require(newOwner != address(0), "Ownable: new owner is the zero address"); emit OwnershipTransferred(_owner, newOwner); _owner = newOwner; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.6.12; /** * @dev Wrappers over Solidity's arithmetic operations with added overflow * checks. * * Arithmetic operations in Solidity wrap on overflow. This can easily result * in bugs, because programmers usually assume that an overflow raises an * error, which is the standard behavior in high level programming languages. * `SafeMath` restores this intuition by reverting the transaction when an * operation overflows. * * Using this library instead of the unchecked operations eliminates an entire * class of bugs, so it's recommended to use it always. */ library SafeMath { /** * @dev Returns the addition of two unsigned integers, with an overflow flag. * * _Available since v3.4._ */ function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) { uint256 c = a + b; if (c < a) return (false, 0); return (true, c); } /** * @dev Returns the substraction of two unsigned integers, with an overflow flag. * * _Available since v3.4._ */ function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) { if (b > a) return (false, 0); return (true, a - b); } /** * @dev Returns the multiplication of two unsigned integers, with an overflow flag. * * _Available since v3.4._ */ function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) { // Gas optimization: this is cheaper than requiring 'a' not being zero, but the // benefit is lost if 'b' is also tested. // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522 if (a == 0) return (true, 0); uint256 c = a * b; if (c / a != b) return (false, 0); return (true, c); } /** * @dev Returns the division of two unsigned integers, with a division by zero flag. * * _Available since v3.4._ */ function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) { if (b == 0) return (false, 0); return (true, a / b); } /** * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag. * * _Available since v3.4._ */ function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) { if (b == 0) return (false, 0); return (true, a % b); } /** * @dev Returns the addition of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `+` operator. * * Requirements: * * - Addition cannot overflow. */ function add(uint256 a, uint256 b) internal pure returns (uint256) { uint256 c = a + b; require(c >= a, "SafeMath: addition overflow"); return c; } /** * @dev Returns the subtraction of two unsigned integers, reverting on * overflow (when the result is negative). * * Counterpart to Solidity's `-` operator. * * Requirements: * * - Subtraction cannot overflow. */ function sub(uint256 a, uint256 b) internal pure returns (uint256) { require(b <= a, "SafeMath: subtraction overflow"); return a - b; } /** * @dev Returns the multiplication of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `*` operator. * * Requirements: * * - Multiplication cannot overflow. */ function mul(uint256 a, uint256 b) internal pure returns (uint256) { if (a == 0) return 0; uint256 c = a * b; require(c / a == b, "SafeMath: multiplication overflow"); return c; } /** * @dev Returns the integer division of two unsigned integers, reverting on * division by zero. The result is rounded towards zero. * * Counterpart to Solidity's `/` operator. Note: this function uses a * `revert` opcode (which leaves remaining gas untouched) while Solidity * uses an invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function div(uint256 a, uint256 b) internal pure returns (uint256) { require(b > 0, "SafeMath: division by zero"); return a / b; } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * reverting when dividing by zero. * * Counterpart to Solidity's `%` operator. This function uses a `revert` * opcode (which leaves remaining gas untouched) while Solidity uses an * invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function mod(uint256 a, uint256 b) internal pure returns (uint256) { require(b > 0, "SafeMath: modulo by zero"); return a % b; } /** * @dev Returns the subtraction of two unsigned integers, reverting with custom message on * overflow (when the result is negative). * * CAUTION: This function is deprecated because it requires allocating memory for the error * message unnecessarily. For custom revert reasons use {trySub}. * * Counterpart to Solidity's `-` operator. * * Requirements: * * - Subtraction cannot overflow. */ function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b <= a, errorMessage); return a - b; } /** * @dev Returns the integer division of two unsigned integers, reverting with custom message on * division by zero. The result is rounded towards zero. * * CAUTION: This function is deprecated because it requires allocating memory for the error * message unnecessarily. For custom revert reasons use {tryDiv}. * * Counterpart to Solidity's `/` operator. Note: this function uses a * `revert` opcode (which leaves remaining gas untouched) while Solidity * uses an invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b > 0, errorMessage); return a / b; } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * reverting with custom message when dividing by zero. * * CAUTION: This function is deprecated because it requires allocating memory for the error * message unnecessarily. For custom revert reasons use {tryMod}. * * Counterpart to Solidity's `%` operator. This function uses a `revert` * opcode (which leaves remaining gas untouched) while Solidity uses an * invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b > 0, errorMessage); return a % b; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.6.12; import "./IERC20.sol"; import "./SafeMath.sol"; import "./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 SafeMath for uint256; 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).add(value); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal { uint256 newAllowance = token.allowance(address(this), spender).sub(value, "SafeERC20: decreased allowance below zero"); _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.6.12; /** * @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.6.12; import "./IERC165.sol"; /** * @dev Required interface of an ERC721 compliant contract. */ interface IERC721 is IERC165 { /** * @dev Emitted when `tokenId` token is transferred from `from` to `to`. */ event Transfer(address indexed from, address indexed to, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token. */ event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets. */ event ApprovalForAll(address indexed owner, address indexed operator, bool approved); /** * @dev Returns the number of tokens in ``owner``'s account. */ function balanceOf(address owner) external view returns (uint256 balance); /** * @dev Returns the owner of the `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function ownerOf(uint256 tokenId) external view returns (address owner); /** * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients * are aware of the ERC721 protocol to prevent tokens from being forever locked. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must be have been allowed to move this token by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom(address from, address to, uint256 tokenId) external; /** * @dev Transfers `tokenId` token from `from` to `to`. * * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must be owned by `from`. * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. * * Emits a {Transfer} event. */ function transferFrom(address from, address to, uint256 tokenId) external; /** * @dev Gives permission to `to` to transfer `tokenId` token to another account. * The approval is cleared when the token is transferred. * * Only a single account can be approved at a time, so approving the zero address clears previous approvals. * * Requirements: * * - The caller must own the token or be an approved operator. * - `tokenId` must exist. * * Emits an {Approval} event. */ function approve(address to, uint256 tokenId) external; /** * @dev Returns the account approved for `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function getApproved(uint256 tokenId) external view returns (address operator); /** * @dev Approve or remove `operator` as an operator for the caller. * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller. * * Requirements: * * - The `operator` cannot be the caller. * * Emits an {ApprovalForAll} event. */ function setApprovalForAll(address operator, bool _approved) external; /** * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`. * * See {setApprovalForAll} */ function isApprovedForAll(address owner, address operator) external view returns (bool); /** * @dev Safely transfers `tokenId` token from `from` to `to`. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom(address from, address to, uint256 tokenId, bytes calldata data) external; }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.0 <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 () internal { _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.6.12; /* * @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 GSN 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 payable) { return msg.sender; } function _msgData() internal view virtual returns (bytes memory) { 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.6.12; /** * @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); } } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.6.12; /** * @dev Interface of the ERC165 standard, as defined in the * https://eips.ethereum.org/EIPS/eip-165[EIP]. * * Implementers can declare support of contract interfaces, which can then be * queried by others ({ERC165Checker}). * * For an implementation, see {ERC165}. */ interface IERC165 { /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] * to learn more about how these ids are created. * * This function call must use less than 30 000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); }
{ "optimizer": { "enabled": true, "runs": 200 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256[]","name":"_tokenIds","type":"uint256[]"},{"indexed":false,"internalType":"uint256","name":"_saleID","type":"uint256"}],"name":"AddTokens","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_saleID","type":"uint256"},{"indexed":false,"internalType":"address","name":"_operator","type":"address"}],"name":"CancelAuction","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_saleID","type":"uint256"},{"indexed":false,"internalType":"address","name":"_operator","type":"address"}],"name":"CancelFlashSale","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"EmergencyWithdraw","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_saleID","type":"uint256"},{"indexed":false,"internalType":"address","name":"_operator","type":"address"}],"name":"FlashSaleExpired","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"totalPayment","type":"uint256"}],"name":"MainCoin","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_saleID","type":"uint256"},{"indexed":false,"internalType":"address","name":"_newBidder","type":"address"},{"indexed":false,"internalType":"address","name":"_payTokenAddress","type":"address"},{"indexed":false,"internalType":"uint256","name":"_bidPrice","type":"uint256"}],"name":"NewBidderTransfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_saleID","type":"uint256"},{"indexed":false,"internalType":"address","name":"_buyer","type":"address"},{"indexed":false,"internalType":"address","name":"_tokenAddresses","type":"address"},{"indexed":false,"internalType":"uint256[]","name":"_tokenIDs","type":"uint256[]"},{"indexed":false,"internalType":"address","name":"_payTokenAddress","type":"address"},{"indexed":false,"internalType":"uint256","name":"_totalPayment","type":"uint256"}],"name":"Purchase","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_saleID","type":"uint256"},{"indexed":false,"internalType":"address","name":"_previousBidder","type":"address"},{"indexed":false,"internalType":"address","name":"_payTokenAddress","type":"address"},{"indexed":false,"internalType":"uint256","name":"_refundAmount","type":"uint256"}],"name":"RefundToPreviousBidder","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_saleID","type":"uint256"},{"indexed":false,"internalType":"address","name":"_auctionSetter","type":"address"},{"indexed":false,"internalType":"address","name":"_tokenAddresses","type":"address"},{"indexed":false,"internalType":"uint256[]","name":"_tokenIDs","type":"uint256[]"},{"indexed":false,"internalType":"address","name":"_payTokenAddress","type":"address"},{"indexed":false,"internalType":"uint256","name":"_initialPrice","type":"uint256"},{"indexed":false,"internalType":"address","name":"_receiver","type":"address"},{"indexed":false,"internalType":"uint256","name":"_minBidIncrement","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_startTime","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_endTime","type":"uint256"}],"name":"SetAuction","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_saleID","type":"uint256"},{"indexed":false,"internalType":"address","name":"_flashSaleSetter","type":"address"},{"indexed":false,"internalType":"address","name":"_tokenAddresses","type":"address"},{"indexed":false,"internalType":"uint256[]","name":"_tokenIDs","type":"uint256[]"},{"indexed":false,"internalType":"address","name":"_payTokenAddress","type":"address"},{"indexed":false,"internalType":"uint256","name":"_price","type":"uint256"},{"indexed":false,"internalType":"address","name":"_receiver","type":"address"},{"indexed":false,"internalType":"uint256","name":"_purchaseLimitation","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_startTime","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_endTime","type":"uint256"}],"name":"SetFlashSale","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_member","type":"address"},{"indexed":false,"internalType":"bool","name":"_isAdded","type":"bool"}],"name":"SetWhitelist","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_saleID","type":"uint256"},{"indexed":false,"internalType":"address","name":"_operator","type":"address"},{"indexed":false,"internalType":"address","name":"_receiver","type":"address"},{"indexed":false,"internalType":"address","name":"_highestBidder","type":"address"},{"indexed":false,"internalType":"address","name":"_tokenAddresses","type":"address"},{"indexed":false,"internalType":"uint256[]","name":"_tokenIDs","type":"uint256[]"},{"indexed":false,"internalType":"address","name":"_payTokenAddress","type":"address"},{"indexed":false,"internalType":"uint256","name":"_highestBidPrice","type":"uint256"}],"name":"SettleAuction","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_saleID","type":"uint256"},{"indexed":false,"internalType":"address","name":"_operator","type":"address"},{"indexed":false,"internalType":"address","name":"_newTokenAddresses","type":"address"},{"indexed":false,"internalType":"uint256[]","name":"_newTokenIDs","type":"uint256[]"},{"indexed":false,"internalType":"address","name":"_newPayTokenAddress","type":"address"},{"indexed":false,"internalType":"uint256","name":"_newInitialPrice","type":"uint256"},{"indexed":false,"internalType":"address","name":"_newReceiver","type":"address"},{"indexed":false,"internalType":"uint256","name":"_newMinBidIncrement","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_newStartTime","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_newEndTime","type":"uint256"}],"name":"UpdateAuction","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_saleID","type":"uint256"},{"indexed":false,"internalType":"address","name":"_operator","type":"address"},{"indexed":false,"internalType":"address","name":"_newTokenAddresses","type":"address"},{"indexed":false,"internalType":"uint256[]","name":"_newTokenIDs","type":"uint256[]"},{"indexed":false,"internalType":"address","name":"_newPayTokenAddress","type":"address"},{"indexed":false,"internalType":"uint256","name":"_newPrice","type":"uint256"},{"indexed":false,"internalType":"address","name":"_newReceiver","type":"address"},{"indexed":false,"internalType":"uint256","name":"_newPurchaseLimitation","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_newStartTime","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_newEndTime","type":"uint256"}],"name":"UpdateFlashSale","type":"event"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"activityIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"activityMap","outputs":[{"internalType":"uint256","name":"limitation","type":"uint256"},{"internalType":"uint256","name":"activityId","type":"uint256"},{"internalType":"bool","name":"isEnable","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"activityWhitelist","outputs":[{"internalType":"bool","name":"isWhitelist","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_saleID","type":"uint256"},{"internalType":"address","name":"_tokenAddresses","type":"address"},{"internalType":"uint256[]","name":"_tokenIDs","type":"uint256[]"}],"name":"addTokenIdToSale","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_saleID","type":"uint256"},{"internalType":"uint256","name":"_bidPrice","type":"uint256"}],"name":"bid","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_saleID","type":"uint256"}],"name":"cancelAuction","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_saleID","type":"uint256"}],"name":"cancelFlashSale","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"flashSaleOnProd","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"getActivity","outputs":[{"components":[{"internalType":"uint256","name":"limitation","type":"uint256"},{"internalType":"uint256","name":"activityId","type":"uint256"},{"internalType":"uint256[]","name":"salesIDs","type":"uint256[]"},{"internalType":"bool","name":"isEnable","type":"bool"}],"internalType":"struct Sales721ForEth.Activity","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"activityId","type":"uint256"},{"internalType":"address","name":"puchaser","type":"address"}],"name":"getActivityTotalAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_saleID","type":"uint256"}],"name":"getAuction","outputs":[{"components":[{"components":[{"internalType":"address","name":"seller","type":"address"},{"internalType":"address","name":"tokenAddresses","type":"address"},{"internalType":"uint256[]","name":"tokenIDs","type":"uint256[]"},{"internalType":"address","name":"payTokenAddress","type":"address"},{"internalType":"uint256","name":"price","type":"uint256"},{"internalType":"address","name":"receiver","type":"address"},{"internalType":"uint256","name":"startTime","type":"uint256"},{"internalType":"uint256","name":"endTime","type":"uint256"},{"internalType":"bool","name":"isAvailable","type":"bool"}],"internalType":"struct Sales721ForEth.BaseSale","name":"base","type":"tuple"},{"internalType":"uint256","name":"minBidIncrement","type":"uint256"},{"internalType":"uint256","name":"highestBidPrice","type":"uint256"},{"internalType":"address","name":"highestBidder","type":"address"}],"internalType":"struct Sales721ForEth.Auction","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_saleID","type":"uint256"}],"name":"getAuctionTokenAmount","outputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getCurrentSaleID","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_saleID","type":"uint256"}],"name":"getFlashSale","outputs":[{"components":[{"components":[{"internalType":"address","name":"seller","type":"address"},{"internalType":"address","name":"tokenAddresses","type":"address"},{"internalType":"uint256[]","name":"tokenIDs","type":"uint256[]"},{"internalType":"address","name":"payTokenAddress","type":"address"},{"internalType":"uint256","name":"price","type":"uint256"},{"internalType":"address","name":"receiver","type":"address"},{"internalType":"uint256","name":"startTime","type":"uint256"},{"internalType":"uint256","name":"endTime","type":"uint256"},{"internalType":"bool","name":"isAvailable","type":"bool"}],"internalType":"struct Sales721ForEth.BaseSale","name":"base","type":"tuple"},{"internalType":"uint256","name":"purchaseLimitation","type":"uint256"}],"internalType":"struct Sales721ForEth.FlashSale","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_saleID","type":"uint256"},{"internalType":"address","name":"_buyer","type":"address"}],"name":"getFlashSalePurchaseRecord","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_saleID","type":"uint256"}],"name":"getFlashSaleTokenAmount","outputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_saleID","type":"uint256"}],"name":"getFlashSaleTokenRemaining","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_newOwner","type":"address"}],"name":"init","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_saleID","type":"uint256"},{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"bytes32","name":"hash","type":"bytes32"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"purchase","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"serverAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"limitation","type":"uint256"},{"internalType":"uint256","name":"activityId","type":"uint256"},{"internalType":"uint256[]","name":"salesIDs","type":"uint256[]"},{"internalType":"bool","name":"isEnable","type":"bool"}],"internalType":"struct Sales721ForEth.Activity","name":"activity","type":"tuple"}],"name":"setActivity","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_activityId","type":"uint256"},{"internalType":"address[]","name":"users","type":"address[]"}],"name":"setActivityWhitelist","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_tokenAddresses","type":"address"},{"internalType":"uint256[]","name":"_tokenIDs","type":"uint256[]"},{"internalType":"address","name":"_payTokenAddress","type":"address"},{"internalType":"uint256","name":"_initialPrice","type":"uint256"},{"internalType":"address","name":"_receiver","type":"address"},{"internalType":"uint256","name":"_minBidIncrement","type":"uint256"},{"internalType":"uint256","name":"_startTime","type":"uint256"},{"internalType":"uint256","name":"_duration","type":"uint256"}],"name":"setAuction","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_tokenAddresses","type":"address"},{"internalType":"uint256[]","name":"_tokenIDs","type":"uint256[]"},{"internalType":"address","name":"_payTokenAddress","type":"address"},{"internalType":"uint256","name":"_price","type":"uint256"},{"internalType":"address","name":"_receiver","type":"address"},{"internalType":"uint256","name":"_purchaseLimitation","type":"uint256"},{"internalType":"uint256","name":"_startTime","type":"uint256"},{"internalType":"uint256","name":"_duration","type":"uint256"},{"internalType":"bool","name":"prod","type":"bool"}],"name":"setFlashSale","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_saleID","type":"uint256"},{"internalType":"bool","name":"isProd","type":"bool"}],"name":"setFlashSaleEnv","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"targetAddress","type":"address"}],"name":"setServerAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"targetAddress","type":"address"}],"name":"setTestServerAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_member","type":"address"},{"internalType":"bool","name":"_status","type":"bool"}],"name":"setWhitelist","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_saleID","type":"uint256"}],"name":"settleAuction","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"testServerAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_saleID","type":"uint256"},{"internalType":"address","name":"_tokenAddresses","type":"address"},{"internalType":"uint256[]","name":"_tokenIDs","type":"uint256[]"},{"internalType":"address","name":"_payTokenAddress","type":"address"},{"internalType":"uint256","name":"_initialPrice","type":"uint256"},{"internalType":"address","name":"_receiver","type":"address"},{"internalType":"uint256","name":"_minBidIncrement","type":"uint256"},{"internalType":"uint256","name":"_startTime","type":"uint256"},{"internalType":"uint256","name":"_duration","type":"uint256"}],"name":"updateAuction","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_saleID","type":"uint256"},{"internalType":"address","name":"_tokenAddresses","type":"address"},{"internalType":"uint256[]","name":"_tokenIDs","type":"uint256[]"},{"internalType":"address","name":"_payTokenAddress","type":"address"},{"internalType":"uint256","name":"_price","type":"uint256"},{"internalType":"address","name":"_receiver","type":"address"},{"internalType":"uint256","name":"_purchaseLimitation","type":"uint256"},{"internalType":"uint256","name":"_startTime","type":"uint256"},{"internalType":"uint256","name":"_duration","type":"uint256"}],"name":"updateFlashSale","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"whitelist","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
608060405260016002553480156200001657600080fd5b5060006200002362000077565b600080546001600160a01b0319166001600160a01b0383169081178255604051929350917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a350600180556200007b565b3390565b61519a806200008b6000396000f3fe60806040526004361061021a5760003560e01c80638dccc36d11610123578063c4f6e995116100ab578063db420fe31161006f578063db420fe31461064e578063e21e3f4b14610663578063eee44acb14610683578063f25e9015146106a3578063f2fde38b146106c35761021a565b8063c4f6e995146105b9578063d341e395146105d9578063d6f4935d146105f9578063d8199fe414610619578063d9caed121461062e5761021a565b806396ec9b38116100f257806396ec9b38146105245780639b19251a14610544578063a4a6187914610564578063aed35df414610584578063b612a025146105995761021a565b80638dccc36d14610497578063911627da146104b7578063922635d8146104d757806396b5a755146105045761021a565b806340d1d824116101a6578063598647f811610175578063598647f8146103e45780636c4ced8b14610404578063715018a61461043357806378bd7935146104485780638da5cb5b146104755761021a565b806340d1d8241461037157806347b64eb0146103915780634fd501d8146103b157806353d6fd59146103c45761021a565b80631efb65d2116101ed5780631efb65d2146102c457806324ef85e1146102e45780632e993611146103045780633377cbaf14610324578063400d837b146103515761021a565b80630452b9681461021f57806316918bfa1461025557806319ab453c146102825780631a72e588146102a4575b600080fd5b34801561022b57600080fd5b5061023f61023a366004613bcd565b6106e3565b60405161024c9190614f53565b60405180910390f35b34801561026157600080fd5b50610275610270366004613bfd565b6106fc565b60405161024c9190614f85565b34801561028e57600080fd5b506102a261029d366004613924565b6107fb565b005b3480156102b057600080fd5b506102a26102bf366004613c78565b610840565b3480156102d057600080fd5b506102a26102df366004613c78565b610b31565b3480156102f057600080fd5b506102a26102ff366004613a34565b610e59565b34801561031057600080fd5b506102a261031f366004613bcd565b6110d7565b34801561033057600080fd5b5061034461033f366004613bcd565b6112f1565b60405161024c9190613fe6565b34801561035d57600080fd5b506102a261036c36600461399c565b611306565b34801561037d57600080fd5b5061027561038c366004613bfd565b61157a565b34801561039d57600080fd5b506102a26103ac366004613924565b6115af565b6102a26103bf366004613ddc565b611610565b3480156103d057600080fd5b506102a26103df366004613ae3565b611d8a565b3480156103f057600080fd5b506102a26103ff366004613dbb565b611e2b565b34801561041057600080fd5b5061042461041f366004613bcd565b61208b565b60405161024c939291906150d3565b34801561043f57600080fd5b506102a26120af565b34801561045457600080fd5b50610468610463366004613bcd565b612138565b60405161024c9190614f05565b34801561048157600080fd5b5061048a612149565b60405161024c9190613f3e565b3480156104a357600080fd5b506102a26104b2366004613924565b612158565b3480156104c357600080fd5b506102756104d2366004613bcd565b6121b9565b3480156104e357600080fd5b506104f76104f2366004613bcd565b6121cb565b60405161024c9190614ebd565b34801561051057600080fd5b506102a261051f366004613bcd565b612265565b34801561053057600080fd5b5061027561053f366004613bcd565b6123ee565b34801561055057600080fd5b5061034461055f366004613924565b61240e565b34801561057057600080fd5b5061034461057f366004613bcd565b612423565b34801561059057600080fd5b50610275612438565b3480156105a557600080fd5b506102a26105b4366004613d1e565b61243e565b3480156105c557600080fd5b506102756105d4366004613bcd565b61250b565b3480156105e557600080fd5b506102a26105f4366004613c21565b612627565b34801561060557600080fd5b506102a2610614366004613bcd565b61282a565b34801561062557600080fd5b5061048a612905565b34801561063a57600080fd5b506102a261064936600461395c565b612914565b34801561065a57600080fd5b5061048a6129d6565b34801561066f57600080fd5b506102a261067e366004613d97565b6129e5565b34801561068f57600080fd5b5061027561069e366004613bcd565b612a70565b3480156106af57600080fd5b506102a26106be366004613b37565b612ba5565b3480156106cf57600080fd5b506102a26106de366004613924565b612c87565b6106eb613751565b6106f482612d47565b90505b919050565b6000610706613771565b6000848152600d60209081526040918290208251608081018452815481526001820154818401526002820180548551818602810186018752818152929593949386019383018282801561077857602002820191906000526020600020905b815481526020019060010190808311610764575b50505091835250506003919091015460ff16151560209091015290506000805b8260400151518110156107f0576000836040015182815181106107b757fe5b60209081029190910181015160009081526006825260408082206001600160a01b038a1683529092522054929092019150600101610798565b509150505b92915050565b60035460ff16156108275760405162461bcd60e51b815260040161081e906146af565b60405180910390fd5b61083081612cc6565b506003805460ff19166001179055565b600260015414156108635760405162461bcd60e51b815260040161081e90614daf565b60026001553360009081526004602052604090205460ff166108975760405162461bcd60e51b815260040161081e9061435a565b61089f613751565b6108a88a612d47565b905042816000015160c00151116108d15760405162461bcd60e51b815260040161081e90614229565b805161010001516108f45760405162461bcd60e51b815260040161081e906146dc565b8051516001600160a01b0316331461091e5760405162461bcd60e51b815260040161081e90614442565b61092c338a8a898789612e73565b600082156109415761093e8484612ead565b90505b81516001600160a01b03808c16602092830152835160409081018c905284518b831660609091015284516080018a9052845189831660a090910152845160c001879052845160e00184905282850188905260008e8152600584528190208551805182549085166001600160a01b03199182161783558186015160018401805491909616911617909355908201518051869492939284926109ea926002850192919091019061379b565b5060608201518160030160006101000a8154816001600160a01b0302191690836001600160a01b031602179055506080820151816004015560a08201518160050160006101000a8154816001600160a01b0302191690836001600160a01b0316021790555060c0820151816006015560e082015181600701556101008201518160080160006101000a81548160ff0219169083151502179055505050602082015181600901559050507f929ba8b4f3c95a0f8b21c07523f66eff127cd5221441dc06fdee198ffcd5f8ad8b836000015160000151846000015160200151856000015160400151866000015160600151876000015160800151886000015160a0015189602001518a6000015160c001518b6000015160e00151604051610b189a99989796959493929190615069565b60405180910390a1505060018055505050505050505050565b60026001541415610b545760405162461bcd60e51b815260040161081e90614daf565b60026001553360009081526004602052604090205460ff16610b885760405162461bcd60e51b815260040161081e9061435a565b610b906137e6565b610b998a612ed9565b905042816000015160c0015111610bc25760405162461bcd60e51b815260040161081e90614d52565b80516101000151610be55760405162461bcd60e51b815260040161081e90614a53565b8051516001600160a01b03163314610c0f5760405162461bcd60e51b815260040161081e90614b27565b610c1e338a8a89888888613024565b80516001600160a01b03808b16602090920191909152815160400189905281518882166060909101528151608001879052815190861660a090910152805160c001839052610c6c8383612ead565b815160e00152602080820185905260008b8152600782526040908190208351805182546001600160a01b039182166001600160a01b03199182161784558286015160018501805491909316911617905591820151805185949293928492610cdc926002850192919091019061379b565b5060608201518160030160006101000a8154816001600160a01b0302191690836001600160a01b031602179055506080820151816004015560a08201518160050160006101000a8154816001600160a01b0302191690836001600160a01b0316021790555060c0820151816006015560e082015181600701556101008201518160080160006101000a81548160ff021916908315150217905550505060208201518160090155604082015181600a0155606082015181600b0160006101000a8154816001600160a01b0302191690836001600160a01b031602179055509050507fd63adfd44826c87ece3083feed98529b1adf82a87e5a6da33e21700f3f0319458a826000015160000151836000015160200151846000015160400151856000015160600151866000015160800151876000015160a001518860200151896000015160c001518a6000015160e00151604051610e419a99989796959493929190615069565b60405180910390a15050600180555050505050505050565b60026001541415610e7c5760405162461bcd60e51b815260040161081e90614daf565b60026001553360009081526004602052604090205460ff16610eb05760405162461bcd60e51b815260040161081e9061435a565b610ebe338a8a898789612e73565b60008215610ed357610ed08484612ead565b90505b610edb613751565b506040805161016081018252339181019182526001600160a01b038c81166060830152608082018c90528a811660a083015260c082018a9052881660e08201526101008101869052610120810183905260016101408201819052918152602081018790526002549091610f4f908290612ead565b60029081556000828152600560209081526040918290208551805182546001600160a01b039182166001600160a01b03199182161784558285015160018501805491909316911617905592830151805187959294938593610fb6939085019291019061379b565b506060828101516003830180546001600160a01b039283166001600160a01b031991821617909155608080860151600486015560a0808701516005870180549190951693169290921790925560c080860151600686015560e0808701516007870155610100909601516008909501805495151560ff199687161790556020978801516009909701969096556000888152600c885260409081902080548d1515961695909517909455885180518189015182870151958301519483015193830151998c015198830151929097015195517f11ed0be6ce391c981a002586d18807296088f0ad8747d50b4d20655c51cc33b0996110bd998c999398939796959491939092615069565b60405180910390a150506001805550505050505050505050565b600260015414156110fa5760405162461bcd60e51b815260040161081e90614daf565b60026001553360009081526004602052604090205460ff1661112e5760405162461bcd60e51b815260040161081e9061435a565b6111366137e6565b61113f82612ed9565b805161010001519091506111655760405162461bcd60e51b815260040161081e906144da565b805160e0015142101561118a5760405162461bcd60e51b815260040161081e90614ad5565b60408101511561126c57805160a081015160408301516060909201516111bc926001600160a01b039091169190613072565b60005b8151604001515181101561126a578160000151602001516001600160a01b03166342842e0e8360000151600001518460600151856000015160400151858151811061120657fe5b60200260200101516040518463ffffffff1660e01b815260040161122c93929190613f6c565b600060405180830381600087803b15801561124657600080fd5b505af115801561125a573d6000803e3d6000fd5b5050600190920191506111bf9050565b505b600082815260076020908152604091829020600801805460ff19169055825160a0810151606080860151938301518386015191909301518686015195517f31f1beabaa0429887bbc894478865975b3be525a1c8b6e03ba6fd41345b45458966112e1968a963396959194909391929091614fa5565b60405180910390a1505060018055565b600f6020526000908152604090205460ff1681565b600260015414156113295760405162461bcd60e51b815260040161081e90614daf565b60026001553360009081526004602052604090205460ff1661135d5760405162461bcd60e51b815260040161081e9061435a565b61136c33898988878787613024565b6113746137e6565b604080516101a0810190915233608082019081526001600160a01b038b811660a084015260c083018b905289811660e0840152610100830189905287166101208301526101408201859052819061016082016113d08787612ead565b8152600160209182018190529183528201879052600060408301819052606090920191909152600254919250611407908290612ead565b60029081556000828152600760209081526040918290208551805182546001600160a01b039182166001600160a01b0319918216178455828501516001850180549190931691161790559283015180518795929493859361146e939085019291019061379b565b506060828101516003830180546001600160a01b03199081166001600160a01b0393841617909155608080860151600486015560a080870151600587018054851691861691909117905560c080880151600688015560e0808901516007890155610100909801516008909701805460ff19169715159790971790965560208981015160098a01556040808b0151600a8b015599860151600b909901805490941698909416979097179091558851805181840151828a0151958301519383015198830151948c015196830151929097015198517fd38229560d70ff33a43c34fffbb9b2b4eb7ca98a70f2fe7dd1deca2c0ece3cf999610e41998c9993989397969094909392909190615069565b600061158583612d47565b505060009182526006602090815260408084206001600160a01b0393909316845291905290205490565b6115b76130cd565b6001600160a01b03166115c8612149565b6001600160a01b0316146115ee5760405162461bcd60e51b815260040161081e90614a1e565b600a80546001600160a01b0319166001600160a01b0392909216919091179055565b600260015414156116335760405162461bcd60e51b815260040161081e90614daf565b600260019081556000878152600c602052604090205460ff16151514156116dd57600a546040805160008152602001908190526001600160a01b0390911690600190611686908790879087908790613ff1565b6020604051602081039080840390855afa1580156116a8573d6000803e3d6000fd5b505050602060405103516001600160a01b0316146116d85760405162461bcd60e51b815260040161081e9061471d565b611761565b6009546040805160008152602001908190526001600160a01b039091169060019061170f908790879087908790613ff1565b6020604051602081039080840390855afa158015611731573d6000803e3d6000fd5b505050602060405103516001600160a01b0316146117615760405162461bcd60e51b815260040161081e90614678565b6000848152600b602052604090205486141561178f5760405162461bcd60e51b815260040161081e90614856565b611797613751565b6117a087612d47565b9050600086116117c25760405162461bcd60e51b815260040161081e906141fb565b805161010001516117e55760405162461bcd60e51b815260040161081e90614079565b8051516001600160a01b03163314156118105760405162461bcd60e51b815260040161081e906140f3565b805160c0015142908110156118375760405162461bcd60e51b815260040161081e9061498a565b815160e00151158015906118505750815160e001518110155b156118af5760008881526005602052604090819020600801805460ff19169055517f90022e1d8eedbbb3c33615d39a0b09d7b55aea384712055d32661146c5a661f3906118a0908a903390614f8e565b60405180910390a15050611d7e565b60008881526006602090815260408083203384529091528120546118d39089612ead565b60008a8152600e6020908152604080832054808452600d909252909120600301549192509060ff1615611a2d576000818152600f602052604090205460ff16158061193a57506000818152600f6020908152604080832033845260010190915290205460ff165b6119565760405162461bcd60e51b815260040161081e90614bab565b61195e613771565b6000828152600d6020908152604091829020825160808101845281548152600182015481840152600282018054855181860281018601875281815292959394938601938301828280156119d057602002820191906000526020600020905b8154815260200190600101908083116119bc575b50505091835250506003919091015460ff1615156020918201528101519091506000906119fd90336106fc565b8251909150611a0c828d612ead565b1115611a2a5760405162461bcd60e51b815260040161081e9061439b565b50505b8360200151821115611a515760405162461bcd60e51b815260040161081e90614754565b83516040015151891115611a775760405162461bcd60e51b815260040161081e90614a8a565b60008a81526006602090815260408083203384529091528120839055845160800151611aa3908b6130d1565b8551606001519091506001600160a01b031615611ae457845160a0810151606090910151611adf916001600160a01b039091169033908461310b565b611b7a565b80341015611b045760405162461bcd60e51b815260040161081e9061417e565b7fa2d23878d5ab22445fbabd6fe02046a90b67448968da82383900084d250d529281604051611b339190614f85565b60405180910390a1845160a001516040516001600160a01b039091169082156108fc029083906000818181858888f19350505050158015611b78573d6000803e3d6000fd5b505b60608a67ffffffffffffffff81118015611b9357600080fd5b50604051908082528060200260200182016040528015611bbd578160200160208202803683370190505b50865160400151519091506000190160005b8c811015611cdc578760000151602001516001600160a01b03166342842e0e896000015160000151338b60000151604001518681518110611c0c57fe5b60200260200101516040518463ffffffff1660e01b8152600401611c3293929190613f6c565b600060405180830381600087803b158015611c4c57600080fd5b505af1158015611c60573d6000803e3d6000fd5b505050508760000151604001518281518110611c7857fe5b6020026020010151838281518110611c8c57fe5b60209081029190910181019190915260008f815260059091526040902060020180546000199093019280611cbc57fe5b600082815260208120820160001990810191909155019055600101611bcf565b5060008d815260056020526040902060020154611d0d5760008d8152600560205260409020600801805460ff191690555b8c600b60008d8152602001908152602001600020819055507fe266a5c8012d7c80c559afb035891cd33e867ac3350c54c4bca825ade265088d8d33896000015160200151858b600001516060015188604051611d6e96959493929190615000565b60405180910390a1505050505050505b50506001805550505050565b611d926130cd565b6001600160a01b0316611da3612149565b6001600160a01b031614611dc95760405162461bcd60e51b815260040161081e90614a1e565b6001600160a01b03821660009081526004602052604090819020805460ff1916831515179055517ff6019ec0a78d156d249a1ec7579e2321f6ac7521d6e1d2eacf90ba4a184dcceb90611e1f9084908490613f90565b60405180910390a15050565b60026001541415611e4e5760405162461bcd60e51b815260040161081e90614daf565b6002600155611e5b6137e6565b611e6483612ed9565b80516101000151909150611e8a5760405162461bcd60e51b815260040161081e90614880565b8051516001600160a01b0316331415611eb55760405162461bcd60e51b815260040161081e90614492565b805160c001514290811015611edc5760405162461bcd60e51b815260040161081e906147e8565b815160e001518110611f005760405162461bcd60e51b815260040161081e90614e86565b815160600151604083015115611fb35760208301516040840151611f2590869061312c565b1015611f435760405162461bcd60e51b815260040161081e90614c28565b60608301516040840151611f61916001600160a01b03841691613072565b7fe8f267296dd98f54fe66007a36688e8b79a64988383c42d63995938d8e143dd98584606001518560000151606001518660400151604051611fa69493929190615044565b60405180910390a1611fd7565b8251608001518414611fd75760405162461bcd60e51b815260040161081e906149c1565b6000858152600760205260408120600a8101869055600b0180546001600160a01b03191633179055612015906001600160a01b038316903090613154565b6120296001600160a01b0382163086613154565b61203e6001600160a01b03821633308761310b565b8251606001516040517fc96310726d5afa93813f4276097a5d37645001323ca859d67ed71d1db0785dfb9161207891889133918990615044565b60405180910390a1505060018055505050565b600d6020526000908152604090208054600182015460039092015490919060ff1683565b6120b76130cd565b6001600160a01b03166120c8612149565b6001600160a01b0316146120ee5760405162461bcd60e51b815260040161081e90614a1e565b600080546040516001600160a01b03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600080546001600160a01b0319169055565b6121406137e6565b6106f482612ed9565b6000546001600160a01b031690565b6121606130cd565b6001600160a01b0316612171612149565b6001600160a01b0316146121975760405162461bcd60e51b815260040161081e90614a1e565b600980546001600160a01b0319166001600160a01b0392909216919091179055565b600e6020526000908152604090205481565b6121d3613771565b6000828152600d60209081526040918290208251608081018452815481526001820154818401526002820180548551818602810186018752818152929593949386019383018282801561224557602002820191906000526020600020905b815481526020019060010190808311612231575b50505091835250506003919091015460ff16151560209091015292915050565b600260015414156122885760405162461bcd60e51b815260040161081e90614daf565b60026001553360009081526004602052604090205460ff166122bc5760405162461bcd60e51b815260040161081e9061435a565b6122c46137e6565b6122cd82612ed9565b805161010001519091506122f35760405162461bcd60e51b815260040161081e90614880565b8051516001600160a01b0316331461231d5760405162461bcd60e51b815260040161081e90614bd9565b6040810151156123a357612355816060015182604001518360000151606001516001600160a01b03166130729092919063ffffffff16565b7fe8f267296dd98f54fe66007a36688e8b79a64988383c42d63995938d8e143dd9828260600151836000015160600151846040015160405161239a9493929190615044565b60405180910390a15b60008281526007602052604090819020600801805460ff19169055517f2a6445a420b30cbabfffd85287bfa6c0c8f9b5f65d48637922da74abf357e52b906112e19084903390614f8e565b60006123f8613751565b61240183612d47565b5160400151519392505050565b60046020526000908152604090205460ff1681565b600c6020526000908152604090205460ff1681565b60025490565b6124466130cd565b6001600160a01b0316612457612149565b6001600160a01b03161461247d5760405162461bcd60e51b815260040161081e90614a1e565b6000838152600f60205260408120805460ff191660011790555b81811015612505576000848152600f60205260408120600191908201908585858181106124c057fe5b90506020020160208101906124d59190613924565b6001600160a01b031681526020810191909152604001600020805460ff1916911515919091179055600101612497565b50505050565b6000612515613751565b60008381526005602090815260409182902082516101608101845281546001600160a01b039081168286019081526001840154909116606083015260028301805486518187028101870190975280875292959394869492938693608087019390929091908301828280156125a857602002820191906000526020600020905b815481526020019060010190808311612594575b505050918352505060038201546001600160a01b0390811660208084019190915260048401546040808501919091526005850154909216606084015260068401546080840152600784015460a084015260089093015460ff16151560c09092019190915291835260099390930154919092015290510151519392505050565b3360009081526004602052604090205460ff166126565760405162461bcd60e51b815260040161081e9061435a565b8051806126755760405162461bcd60e51b815260040161081e9061455a565b60008481526005602052604090206006015442106126a55760405162461bcd60e51b815260040161081e906148b7565b6000848152600560205260409020546001600160a01b031633146126db5760405162461bcd60e51b815260040161081e9061430f565b8260005b83518110156127e95760008482815181106126f657fe5b602090810291909101810151600089815260059092526040918290205491516331a9108f60e11b81529092506001600160a01b0391821691851690636352211e90612745908590600401614f85565b60206040518083038186803b15801561275d57600080fd5b505afa158015612771573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127959190613940565b6001600160a01b0316146127bb5760405162461bcd60e51b815260040161081e90614de6565b60008781526005602090815260408220600201805460018181018355918452919092200191909155016126df565b507f9fb33f4b0149c5f78fc6753547dba139088c5f19b41fa58239d32f85eaa22935838660405161281b929190613fc4565b60405180910390a15050505050565b3360009081526004602052604090205460ff166128595760405162461bcd60e51b815260040161081e9061435a565b612861613751565b61286a82612d47565b805161010001519091506128905760405162461bcd60e51b815260040161081e90614079565b8051516001600160a01b031633146128ba5760405162461bcd60e51b815260040161081e906142bd565b60008281526005602052604090819020600801805460ff19169055517ff3da86c38149b3ff13eb97ec00d936dffd9cb29a827e1c0fc9dae4a939137fc890611e1f9084903390614f8e565b6009546001600160a01b031681565b61291c6130cd565b6001600160a01b031661292d612149565b6001600160a01b0316146129535760405162461bcd60e51b815260040161081e90614a1e565b612965836001600160a01b0316613217565b156129835761297e6001600160a01b0384168383613072565b612996565b6129966001600160a01b0383168261321d565b7ff24ef89f38eadc1bde50701ad6e4d6d11a2dc24f7cf834a486991f38833285048383836040516129c993929190613f6c565b60405180910390a1505050565b600a546001600160a01b031681565b60026001541415612a085760405162461bcd60e51b815260040161081e90614daf565b6002600155612a156130cd565b6001600160a01b0316612a26612149565b6001600160a01b031614612a4c5760405162461bcd60e51b815260040161081e90614a1e565b6000918252600c6020526040909120805460ff191691151591909117905560018055565b6000612a7a6137e6565b60008381526007602090815260409182902082516101a08101845281546001600160a01b0390811660808301908152600184015490911660a08301526002830180548651818702810187019097528087529295939486949293869360c08701939092909190830182828015612b0e57602002820191906000526020600020905b815481526020019060010190808311612afa575b505050918352505060038201546001600160a01b0390811660208084019190915260048401546040808501919091526005850154831660608086019190915260068601546080860152600786015460a086015260089095015460ff16151560c090940193909352938552600986015493850193909352600a85015484820152600b9094015490911691015290510151519392505050565b612bad6130cd565b6001600160a01b0316612bbe612149565b6001600160a01b031614612be45760405162461bcd60e51b815260040161081e90614a1e565b602080820180516000908152600d8352604090819020845181559151600183015583015180518493612c1d92600285019291019061379b565b50606091909101516003909101805460ff191691151591909117905560005b816040015151811015612c8357600082604001518281518110612c5b57fe5b602090810291909101810151848201516000918252600e909252604090205550600101612c3c565b5050565b612c8f6130cd565b6001600160a01b0316612ca0612149565b6001600160a01b031614612cc65760405162461bcd60e51b815260040161081e90614a1e565b6001600160a01b038116612cec5760405162461bcd60e51b815260040161081e906141b5565b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b0319166001600160a01b0392909216919091179055565b612d4f613751565b60008281526005602090815260409182902082516101608101845281546001600160a01b03908116828601908152600184015490911660608301526002830180548651818702810187019097528087529295939486949293869360808701939092909190830182828015612de257602002820191906000526020600020905b815481526020019060010190808311612dce575b505050918352505060038201546001600160a01b039081166020808401919091526004840154604084015260058401548216606084015260068401546080840152600784015460a084015260089093015460ff16151560c090920191909152918352600993909301549190920152815151919250166106f75760405162461bcd60e51b815260040161081e906140b0565b6000612e8287878787876132b9565b905060008211612ea45760405162461bcd60e51b815260040161081e906147b1565b50505050505050565b600082820183811015612ed25760405162461bcd60e51b815260040161081e90614286565b9392505050565b612ee16137e6565b60008281526007602090815260409182902082516101a08101845281546001600160a01b0390811660808301908152600184015490911660a08301526002830180548651818702810187019097528087529295939486949293869360c08701939092909190830182828015612f7557602002820191906000526020600020905b815481526020019060010190808311612f61575b505050918352505060038201546001600160a01b0390811660208084019190915260048401546040808501919091526005850154831660608086019190915260068601546080860152600786015460a086015260089095015460ff16151560c090940193909352938552600986015493850193909352600a85015490840152600b9093015481169190920152815151919250166106f75760405162461bcd60e51b815260040161081e90614914565b61303187878787866132b9565b50600083116130525760405162461bcd60e51b815260040161081e9061440b565b60008111612ea45760405162461bcd60e51b815260040161081e90614150565b6130c88363a9059cbb60e01b8484604051602401613091929190613fab565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b0319909316929092179091526135b1565b505050565b3390565b6000826130e0575060006107f5565b828202828482816130ed57fe5b0414612ed25760405162461bcd60e51b815260040161081e90614949565b612505846323b872dd60e01b85858560405160240161309193929190613f6c565b60008282111561314e5760405162461bcd60e51b815260040161081e90614523565b50900390565b8015806131dc5750604051636eb1769f60e11b81526001600160a01b0384169063dd62ed3e9061318a9030908690600401613f52565b60206040518083038186803b1580156131a257600080fd5b505afa1580156131b6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906131da9190613be5565b155b6131f85760405162461bcd60e51b815260040161081e90614e30565b6130c88363095ea7b360e01b8484604051602401613091929190613fab565b3b151590565b8047101561323d5760405162461bcd60e51b815260040161081e906145fb565b6000826001600160a01b03168260405161325690613f3b565b60006040518083038185875af1925050503d8060008114613293576040519150601f19603f3d011682016040523d82523d6000602084013e613298565b606091505b50509050806130c85760405162461bcd60e51b815260040161081e9061459e565b8251846000805b83811015613520578681815181106132d457fe5b6020908102919091018101516001600160a01b0385166000908152600883526040808220838352909352919091205490925060ff16156133265760405162461bcd60e51b815260040161081e9061481f565b6001600160a01b03808416600081815260086020908152604080832087845290915290819020805460ff19166001179055516331a9108f60e11b8152918b1691636352211e9061337a908690600401614f85565b60206040518083038186803b15801561339257600080fd5b505afa1580156133a6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906133ca9190613940565b6001600160a01b0316146133f05760405162461bcd60e51b815260040161081e90614de6565b60405163020604bf60e21b815230906001600160a01b0385169063081812fc9061341e908690600401614f85565b60206040518083038186803b15801561343657600080fd5b505afa15801561344a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061346e9190613940565b6001600160a01b031614806134fc575060405163e985e9c560e01b81526001600160a01b0384169063e985e9c5906134ac908c903090600401613f52565b60206040518083038186803b1580156134c457600080fd5b505afa1580156134d8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906134fc9190613b1b565b6135185760405162461bcd60e51b815260040161081e90614cab565b6001016132c0565b50428410156135415760405162461bcd60e51b815260040161081e90614042565b60005b838110156135a5576001600160a01b0388166000908152600860205260408120885182908a908590811061357457fe5b6020908102919091018101518252810191909152604001600020805460ff1916911515919091179055600101613544565b50505095945050505050565b6060613606826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166136409092919063ffffffff16565b8051909150156130c857808060200190518101906136249190613b1b565b6130c85760405162461bcd60e51b815260040161081e90614d08565b606061364f8484600085613657565b949350505050565b6060824710156136795760405162461bcd60e51b815260040161081e90614632565b61368285613217565b61369e5760405162461bcd60e51b815260040161081e90614b74565b60006060866001600160a01b031685876040516136bb9190613f1f565b60006040518083038185875af1925050503d80600081146136f8576040519150601f19603f3d011682016040523d82523d6000602084013e6136fd565b606091505b509150915061370d828286613718565b979650505050505050565b60608315613727575081612ed2565b8251156137375782518084602001fd5b8160405162461bcd60e51b815260040161081e919061400f565b604051806040016040528061376461381d565b8152602001600081525090565b60405180608001604052806000815260200160008152602001606081526020016000151581525090565b8280548282559060005260206000209081019282156137d6579160200282015b828111156137d65782518255916020019190600101906137bb565b506137e292915061388f565b5090565b60405180608001604052806137f961381d565b8152602001600081526020016000815260200160006001600160a01b031681525090565b60405180610120016040528060006001600160a01b0316815260200160006001600160a01b031681526020016060815260200160006001600160a01b031681526020016000815260200160006001600160a01b0316815260200160008152602001600081526020016000151581525090565b5b808211156137e25760008155600101613890565b600082601f8301126138b4578081fd5b813567ffffffffffffffff8111156138ca578182fd5b60208082026138da8282016150eb565b838152935081840185830182870184018810156138f657600080fd5b600092505b848310156139195780358252600192909201919083019083016138fb565b505050505092915050565b600060208284031215613935578081fd5b8135612ed28161513e565b600060208284031215613951578081fd5b8151612ed28161513e565b600080600060608486031215613970578182fd5b833561397b8161513e565b9250602084013561398b8161513e565b929592945050506040919091013590565b600080600080600080600080610100898b0312156139b8578384fd5b88356139c38161513e565b9750602089013567ffffffffffffffff8111156139de578485fd5b6139ea8b828c016138a4565b97505060408901356139fb8161513e565b9550606089013594506080890135613a128161513e565b979a969950949793969560a0850135955060c08501359460e001359350915050565b60008060008060008060008060006101208a8c031215613a52578081fd5b8935613a5d8161513e565b985060208a013567ffffffffffffffff811115613a78578182fd5b613a848c828d016138a4565b98505060408a0135613a958161513e565b965060608a0135955060808a0135613aac8161513e565b945060a08a0135935060c08a0135925060e08a013591506101008a0135613ad281615156565b809150509295985092959850929598565b60008060408385031215613af5578182fd5b8235613b008161513e565b91506020830135613b1081615156565b809150509250929050565b600060208284031215613b2c578081fd5b8151612ed281615156565b600060208284031215613b48578081fd5b813567ffffffffffffffff80821115613b5f578283fd5b9083019060808286031215613b72578283fd5b613b7c60806150eb565b8235815260208301356020820152604083013582811115613b9b578485fd5b613ba7878286016138a4565b60408301525060608301359250613bbd83615156565b6060810192909252509392505050565b600060208284031215613bde578081fd5b5035919050565b600060208284031215613bf6578081fd5b5051919050565b60008060408385031215613c0f578182fd5b823591506020830135613b108161513e565b600080600060608486031215613c35578081fd5b833592506020840135613c478161513e565b9150604084013567ffffffffffffffff811115613c62578182fd5b613c6e868287016138a4565b9150509250925092565b60008060008060008060008060006101208a8c031215613c96578283fd5b8935985060208a0135613ca88161513e565b975060408a013567ffffffffffffffff811115613cc3578384fd5b613ccf8c828d016138a4565b97505060608a0135613ce08161513e565b955060808a0135945060a08a0135613cf78161513e565b8094505060c08a0135925060e08a013591506101008a013590509295985092959850929598565b600080600060408486031215613d32578081fd5b83359250602084013567ffffffffffffffff80821115613d50578283fd5b818601915086601f830112613d63578283fd5b813581811115613d71578384fd5b8760208083028501011115613d84578384fd5b6020830194508093505050509250925092565b60008060408385031215613da9578182fd5b823591506020830135613b1081615156565b60008060408385031215613dcd578182fd5b50508035926020909101359150565b60008060008060008060c08789031215613df4578384fd5b863595506020870135945060408701359350606087013560ff81168114613e19578283fd5b9598949750929560808101359460a0909101359350915050565b6001600160a01b03169052565b6000815180845260208085019450808401835b83811015613e6f57815187529582019590820190600101613e53565b509495945050505050565b15159052565b600061012060018060a01b0383511684526020830151613ea36020860182613e33565b506040830151816040860152613ebb82860182613e40565b9150506060830151613ed06060860182613e33565b506080830151608085015260a0830151613eed60a0860182613e33565b5060c083015160c085015260e083015160e085015261010080840151613f1582870182613e7a565b5090949350505050565b60008251613f31818460208701615112565b9190910192915050565b90565b6001600160a01b0391909116815260200190565b6001600160a01b0392831681529116602082015260400190565b6001600160a01b039384168152919092166020820152604081019190915260600190565b6001600160a01b039290921682521515602082015260400190565b6001600160a01b03929092168252602082015260400190565b600060408252613fd76040830185613e40565b90508260208301529392505050565b901515815260200190565b93845260ff9290921660208401526040830152606082015260800190565b600060208252825180602084015261402e816040850160208701615112565b601f01601f19169190910160400192915050565b60208082526018908201527f737461727454696d65206d757374206265203e3d206e6f770000000000000000604082015260600190565b6020808252601e908201527f74686520666c6173682073616c652069736e277420617661696c61626c650000604082015260600190565b60208082526023908201527f7468652074617267657420666c6173682073616c6520646f65736e27742065786040820152621a5cdd60ea1b606082015260800190565b60208082526038908201527f746865207365747465722063616e2774206d616b65206120707572636861736560408201527f2066726f6d20697473206f776e20666c6173682073616c650000000000000000606082015260800190565b60208082526014908201527306475726174696f6e206d757374206265203e20360641b604082015260600190565b6020808252601f908201527f616d6f756e742073686f756c64206265203e20746f74616c5061796d656e7400604082015260600190565b60208082526026908201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160408201526564647265737360d01b606082015260800190565b6020808252601490820152730616d6f756e742073686f756c64206265203e20360641b604082015260600190565b6020808252603f908201527f69742773206e6f7420616c6c6f77656420746f2075706461746520746865206660408201527f6c6173682073616c6520616674657220746865207374617274206f6620697400606082015260800190565b6020808252601b908201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604082015260600190565b60208082526032908201527f74686520666c6173682073616c652063616e206f6e6c792062652063616e6365604082015271363632b210313c9034ba399039b2ba3a32b960711b606082015260800190565b6020808252602b908201527f746865202073616c652063616e206f6e6c79206265207570646174656420627960408201526a1034ba399039b2ba3a32b960a91b606082015260800190565b60208082526021908201527f7468652063616c6c65722069736e277420696e207468652077686974656c69736040820152601d60fa1b606082015260800190565b6020808252604a908201527f746f74616c20616d6f756e7420746f20707572636861736520666f722061637460408201527f6976697479206578636565647320746865206c696d69746174696f6e206f6620606082015269616e206164647265737360b01b608082015260a00190565b6020808252601b908201527f6d696e426964496e6372656d656e74206d757374206265203e20300000000000604082015260600190565b60208082526030908201527f74686520666c6173682073616c652063616e206f6e6c7920626520757064617460408201526f32b210313c9034ba399039b2ba3a32b960811b606082015260800190565b60208082526028908201527f746865207365747465722063616e27742062696420666f7220697473206f776e6040820152671030bab1ba34b7b760c11b606082015260800190565b60208082526029908201527f6f6e6c792074686520617661696c61626c652061756374696f6e2063616e206260408201526819481cd95d1d1b195960ba1b606082015260800190565b6020808252601e908201527f536166654d6174683a207375627472616374696f6e206f766572666c6f770000604082015260600190565b60208082526024908201527f6c656e677468206f6620746f6b656e416464726573736573206d7573742062656040820152630203e20360e41b606082015260800190565b6020808252603a908201527f416464726573733a20756e61626c6520746f2073656e642076616c75652c207260408201527f6563697069656e74206d61792068617665207265766572746564000000000000606082015260800190565b6020808252601d908201527f416464726573733a20696e73756666696369656e742062616c616e6365000000604082015260600190565b60208082526026908201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6040820152651c8818d85b1b60d21b606082015260800190565b6020808252601e908201527f766572696679207465737420736572766572207369676e206661696c65640000604082015260600190565b602080825260139082015272185b1c9958591e481a5b9a5d1a585b1a5e9959606a1b604082015260600190565b60208082526021908201527f74686520666c6173682073616c6520686173206265656e2063616e63656c6c656040820152601960fa1b606082015260800190565b6020808252601e908201527f7665726966792070726f6420736572766572207369676e206661696c65640000604082015260600190565b6020808252603d908201527f746f74616c20616d6f756e7420746f207075726368617365206578636565647360408201527f20746865206c696d69746174696f6e206f6620616e2061646472657373000000606082015260800190565b6020808252601e908201527f70757263686173654c696d69746174696f6e206d757374206265203e20300000604082015260600190565b60208082526019908201527f7468652061756374696f6e20646f65736e277420737461727400000000000000604082015260600190565b60208082526018908201527f726570657469746976652045524337323120746f6b656e730000000000000000604082015260600190565b60208082526010908201526f1cda59db881a185cda081c995c19585d60821b604082015260600190565b6020808252601b908201527f7468652061756374696f6e2069736e277420617661696c61626c650000000000604082015260600190565b6020808252603a908201527f69742773206e6f7420616c6c6f77656420746f2075706461746520746865202060408201527f73616c6520616674657220746865207374617274206f66206974000000000000606082015260800190565b6020808252818101527f746865207461726765742061756374696f6e20646f65736e2774206578697374604082015260600190565b60208082526021908201527f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f6040820152607760f81b606082015260800190565b6020808252601c908201527f74686520666c6173682073616c6520646f65736e277420737461727400000000604082015260600190565b6020808252603a908201527f666972737420626964206d75737420666f6c6c6f772074686520696e6974696160408201527f6c2070726963652073657420696e207468652061756374696f6e000000000000606082015260800190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b6020808252601e908201527f7468652061756374696f6e20686173206265656e2063616e63656c6c65640000604082015260600190565b6020808252602b908201527f696e73756666696369656e7420616d6f756e74206f6620746f6b656e20666f7260408201526a207468697320747261646560a81b606082015260800190565b60208082526032908201527f7468652061756374696f6e2063616e206f6e6c7920626520736574746c65642060408201527161667465722069747320656e642074696d6560701b606082015260800190565b6020808252602d908201527f7468652061756374696f6e2063616e206f6e6c7920626520757064617465642060408201526c313c9034ba399039b2ba3a32b960991b606082015260800190565b6020808252601d908201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604082015260600190565b602080825260149082015273139bdd081a5b881d1a194815da1a5d195b1a5cdd60621b604082015260600190565b6020808252602f908201527f7468652061756374696f6e2063616e206f6e6c792062652063616e63656c6c6560408201526e3210313c9034ba399039b2ba3a32b960891b606082015260800190565b6020808252605a908201527f74686520626964207072696365206d757374206265206c61726765722074686160408201527f6e207468652073756d206f662063757272656e742068696768657374206f6e6560608201527f20616e64206d696e696d756d2062696420696e6372656d656e74000000000000608082015260a00190565b60208082526039908201527f74686520636f6e7472616374206861736e2774206265656e20617070726f766560408201527f6420666f7220455243373231207472616e7366657272696e6700000000000000606082015260800190565b6020808252602a908201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6040820152691bdd081cdd58d8d9595960b21b606082015260800190565b6020808252603c908201527f69742773206e6f7420616c6c6f77656420746f2075706461746520746865206160408201527f756374696f6e20616674657220746865207374617274206f6620697400000000606082015260800190565b6020808252601f908201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604082015260600190565b6020808252602a908201527f756e6d617463686564206f776e657273686970206f6620746172676574204552604082015269219b9918903a37b5b2b760b11b606082015260800190565b60208082526036908201527f5361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f60408201527520746f206e6f6e2d7a65726f20616c6c6f77616e636560501b606082015260800190565b60208082526017908201527f7468652061756374696f6e206861732065787069726564000000000000000000604082015260600190565b6000602082528251602083015260208301516040830152604083015160806060840152614eed60a0840182613e40565b90506060840151151560808401528091505092915050565b600060208252825160806020840152614f2160a0840182613e80565b9050602084015160408401526040840151606084015260018060a01b0360608501511660808401528091505092915050565b600060208252825160406020840152614f6f6060840182613e80565b9050602084015160408401528091505092915050565b90815260200190565b9182526001600160a01b0316602082015260400190565b8881526001600160a01b03888116602083015287811660408301528681166060830152858116608083015261010060a08301819052600091614fe984830188613e40565b951660c0840152505060e001529695505050505050565b600087825260018060a01b038088166020840152808716604084015260c0606084015261503060c0840187613e40565b941660808301525060a00152949350505050565b9384526001600160a01b03928316602085015291166040830152606082015260800190565b8a81526001600160a01b038a8116602083015289811660408301526101406060830181905260009161509d8483018c613e40565b998116608085015260a084019890985250509390941660c084015260e08301919091526101008201526101200152949350505050565b92835260208301919091521515604082015260600190565b60405181810167ffffffffffffffff8111828210171561510a57600080fd5b604052919050565b60005b8381101561512d578181015183820152602001615115565b838111156125055750506000910152565b6001600160a01b038116811461515357600080fd5b50565b801515811461515357600080fdfea2646970667358221220698ab25d977996821558d6a918a9e93ffd827a8e36209656b862e6671c47ca1b64736f6c634300060c0033
Deployed Bytecode
0x60806040526004361061021a5760003560e01c80638dccc36d11610123578063c4f6e995116100ab578063db420fe31161006f578063db420fe31461064e578063e21e3f4b14610663578063eee44acb14610683578063f25e9015146106a3578063f2fde38b146106c35761021a565b8063c4f6e995146105b9578063d341e395146105d9578063d6f4935d146105f9578063d8199fe414610619578063d9caed121461062e5761021a565b806396ec9b38116100f257806396ec9b38146105245780639b19251a14610544578063a4a6187914610564578063aed35df414610584578063b612a025146105995761021a565b80638dccc36d14610497578063911627da146104b7578063922635d8146104d757806396b5a755146105045761021a565b806340d1d824116101a6578063598647f811610175578063598647f8146103e45780636c4ced8b14610404578063715018a61461043357806378bd7935146104485780638da5cb5b146104755761021a565b806340d1d8241461037157806347b64eb0146103915780634fd501d8146103b157806353d6fd59146103c45761021a565b80631efb65d2116101ed5780631efb65d2146102c457806324ef85e1146102e45780632e993611146103045780633377cbaf14610324578063400d837b146103515761021a565b80630452b9681461021f57806316918bfa1461025557806319ab453c146102825780631a72e588146102a4575b600080fd5b34801561022b57600080fd5b5061023f61023a366004613bcd565b6106e3565b60405161024c9190614f53565b60405180910390f35b34801561026157600080fd5b50610275610270366004613bfd565b6106fc565b60405161024c9190614f85565b34801561028e57600080fd5b506102a261029d366004613924565b6107fb565b005b3480156102b057600080fd5b506102a26102bf366004613c78565b610840565b3480156102d057600080fd5b506102a26102df366004613c78565b610b31565b3480156102f057600080fd5b506102a26102ff366004613a34565b610e59565b34801561031057600080fd5b506102a261031f366004613bcd565b6110d7565b34801561033057600080fd5b5061034461033f366004613bcd565b6112f1565b60405161024c9190613fe6565b34801561035d57600080fd5b506102a261036c36600461399c565b611306565b34801561037d57600080fd5b5061027561038c366004613bfd565b61157a565b34801561039d57600080fd5b506102a26103ac366004613924565b6115af565b6102a26103bf366004613ddc565b611610565b3480156103d057600080fd5b506102a26103df366004613ae3565b611d8a565b3480156103f057600080fd5b506102a26103ff366004613dbb565b611e2b565b34801561041057600080fd5b5061042461041f366004613bcd565b61208b565b60405161024c939291906150d3565b34801561043f57600080fd5b506102a26120af565b34801561045457600080fd5b50610468610463366004613bcd565b612138565b60405161024c9190614f05565b34801561048157600080fd5b5061048a612149565b60405161024c9190613f3e565b3480156104a357600080fd5b506102a26104b2366004613924565b612158565b3480156104c357600080fd5b506102756104d2366004613bcd565b6121b9565b3480156104e357600080fd5b506104f76104f2366004613bcd565b6121cb565b60405161024c9190614ebd565b34801561051057600080fd5b506102a261051f366004613bcd565b612265565b34801561053057600080fd5b5061027561053f366004613bcd565b6123ee565b34801561055057600080fd5b5061034461055f366004613924565b61240e565b34801561057057600080fd5b5061034461057f366004613bcd565b612423565b34801561059057600080fd5b50610275612438565b3480156105a557600080fd5b506102a26105b4366004613d1e565b61243e565b3480156105c557600080fd5b506102756105d4366004613bcd565b61250b565b3480156105e557600080fd5b506102a26105f4366004613c21565b612627565b34801561060557600080fd5b506102a2610614366004613bcd565b61282a565b34801561062557600080fd5b5061048a612905565b34801561063a57600080fd5b506102a261064936600461395c565b612914565b34801561065a57600080fd5b5061048a6129d6565b34801561066f57600080fd5b506102a261067e366004613d97565b6129e5565b34801561068f57600080fd5b5061027561069e366004613bcd565b612a70565b3480156106af57600080fd5b506102a26106be366004613b37565b612ba5565b3480156106cf57600080fd5b506102a26106de366004613924565b612c87565b6106eb613751565b6106f482612d47565b90505b919050565b6000610706613771565b6000848152600d60209081526040918290208251608081018452815481526001820154818401526002820180548551818602810186018752818152929593949386019383018282801561077857602002820191906000526020600020905b815481526020019060010190808311610764575b50505091835250506003919091015460ff16151560209091015290506000805b8260400151518110156107f0576000836040015182815181106107b757fe5b60209081029190910181015160009081526006825260408082206001600160a01b038a1683529092522054929092019150600101610798565b509150505b92915050565b60035460ff16156108275760405162461bcd60e51b815260040161081e906146af565b60405180910390fd5b61083081612cc6565b506003805460ff19166001179055565b600260015414156108635760405162461bcd60e51b815260040161081e90614daf565b60026001553360009081526004602052604090205460ff166108975760405162461bcd60e51b815260040161081e9061435a565b61089f613751565b6108a88a612d47565b905042816000015160c00151116108d15760405162461bcd60e51b815260040161081e90614229565b805161010001516108f45760405162461bcd60e51b815260040161081e906146dc565b8051516001600160a01b0316331461091e5760405162461bcd60e51b815260040161081e90614442565b61092c338a8a898789612e73565b600082156109415761093e8484612ead565b90505b81516001600160a01b03808c16602092830152835160409081018c905284518b831660609091015284516080018a9052845189831660a090910152845160c001879052845160e00184905282850188905260008e8152600584528190208551805182549085166001600160a01b03199182161783558186015160018401805491909616911617909355908201518051869492939284926109ea926002850192919091019061379b565b5060608201518160030160006101000a8154816001600160a01b0302191690836001600160a01b031602179055506080820151816004015560a08201518160050160006101000a8154816001600160a01b0302191690836001600160a01b0316021790555060c0820151816006015560e082015181600701556101008201518160080160006101000a81548160ff0219169083151502179055505050602082015181600901559050507f929ba8b4f3c95a0f8b21c07523f66eff127cd5221441dc06fdee198ffcd5f8ad8b836000015160000151846000015160200151856000015160400151866000015160600151876000015160800151886000015160a0015189602001518a6000015160c001518b6000015160e00151604051610b189a99989796959493929190615069565b60405180910390a1505060018055505050505050505050565b60026001541415610b545760405162461bcd60e51b815260040161081e90614daf565b60026001553360009081526004602052604090205460ff16610b885760405162461bcd60e51b815260040161081e9061435a565b610b906137e6565b610b998a612ed9565b905042816000015160c0015111610bc25760405162461bcd60e51b815260040161081e90614d52565b80516101000151610be55760405162461bcd60e51b815260040161081e90614a53565b8051516001600160a01b03163314610c0f5760405162461bcd60e51b815260040161081e90614b27565b610c1e338a8a89888888613024565b80516001600160a01b03808b16602090920191909152815160400189905281518882166060909101528151608001879052815190861660a090910152805160c001839052610c6c8383612ead565b815160e00152602080820185905260008b8152600782526040908190208351805182546001600160a01b039182166001600160a01b03199182161784558286015160018501805491909316911617905591820151805185949293928492610cdc926002850192919091019061379b565b5060608201518160030160006101000a8154816001600160a01b0302191690836001600160a01b031602179055506080820151816004015560a08201518160050160006101000a8154816001600160a01b0302191690836001600160a01b0316021790555060c0820151816006015560e082015181600701556101008201518160080160006101000a81548160ff021916908315150217905550505060208201518160090155604082015181600a0155606082015181600b0160006101000a8154816001600160a01b0302191690836001600160a01b031602179055509050507fd63adfd44826c87ece3083feed98529b1adf82a87e5a6da33e21700f3f0319458a826000015160000151836000015160200151846000015160400151856000015160600151866000015160800151876000015160a001518860200151896000015160c001518a6000015160e00151604051610e419a99989796959493929190615069565b60405180910390a15050600180555050505050505050565b60026001541415610e7c5760405162461bcd60e51b815260040161081e90614daf565b60026001553360009081526004602052604090205460ff16610eb05760405162461bcd60e51b815260040161081e9061435a565b610ebe338a8a898789612e73565b60008215610ed357610ed08484612ead565b90505b610edb613751565b506040805161016081018252339181019182526001600160a01b038c81166060830152608082018c90528a811660a083015260c082018a9052881660e08201526101008101869052610120810183905260016101408201819052918152602081018790526002549091610f4f908290612ead565b60029081556000828152600560209081526040918290208551805182546001600160a01b039182166001600160a01b03199182161784558285015160018501805491909316911617905592830151805187959294938593610fb6939085019291019061379b565b506060828101516003830180546001600160a01b039283166001600160a01b031991821617909155608080860151600486015560a0808701516005870180549190951693169290921790925560c080860151600686015560e0808701516007870155610100909601516008909501805495151560ff199687161790556020978801516009909701969096556000888152600c885260409081902080548d1515961695909517909455885180518189015182870151958301519483015193830151998c015198830151929097015195517f11ed0be6ce391c981a002586d18807296088f0ad8747d50b4d20655c51cc33b0996110bd998c999398939796959491939092615069565b60405180910390a150506001805550505050505050505050565b600260015414156110fa5760405162461bcd60e51b815260040161081e90614daf565b60026001553360009081526004602052604090205460ff1661112e5760405162461bcd60e51b815260040161081e9061435a565b6111366137e6565b61113f82612ed9565b805161010001519091506111655760405162461bcd60e51b815260040161081e906144da565b805160e0015142101561118a5760405162461bcd60e51b815260040161081e90614ad5565b60408101511561126c57805160a081015160408301516060909201516111bc926001600160a01b039091169190613072565b60005b8151604001515181101561126a578160000151602001516001600160a01b03166342842e0e8360000151600001518460600151856000015160400151858151811061120657fe5b60200260200101516040518463ffffffff1660e01b815260040161122c93929190613f6c565b600060405180830381600087803b15801561124657600080fd5b505af115801561125a573d6000803e3d6000fd5b5050600190920191506111bf9050565b505b600082815260076020908152604091829020600801805460ff19169055825160a0810151606080860151938301518386015191909301518686015195517f31f1beabaa0429887bbc894478865975b3be525a1c8b6e03ba6fd41345b45458966112e1968a963396959194909391929091614fa5565b60405180910390a1505060018055565b600f6020526000908152604090205460ff1681565b600260015414156113295760405162461bcd60e51b815260040161081e90614daf565b60026001553360009081526004602052604090205460ff1661135d5760405162461bcd60e51b815260040161081e9061435a565b61136c33898988878787613024565b6113746137e6565b604080516101a0810190915233608082019081526001600160a01b038b811660a084015260c083018b905289811660e0840152610100830189905287166101208301526101408201859052819061016082016113d08787612ead565b8152600160209182018190529183528201879052600060408301819052606090920191909152600254919250611407908290612ead565b60029081556000828152600760209081526040918290208551805182546001600160a01b039182166001600160a01b0319918216178455828501516001850180549190931691161790559283015180518795929493859361146e939085019291019061379b565b506060828101516003830180546001600160a01b03199081166001600160a01b0393841617909155608080860151600486015560a080870151600587018054851691861691909117905560c080880151600688015560e0808901516007890155610100909801516008909701805460ff19169715159790971790965560208981015160098a01556040808b0151600a8b015599860151600b909901805490941698909416979097179091558851805181840151828a0151958301519383015198830151948c015196830151929097015198517fd38229560d70ff33a43c34fffbb9b2b4eb7ca98a70f2fe7dd1deca2c0ece3cf999610e41998c9993989397969094909392909190615069565b600061158583612d47565b505060009182526006602090815260408084206001600160a01b0393909316845291905290205490565b6115b76130cd565b6001600160a01b03166115c8612149565b6001600160a01b0316146115ee5760405162461bcd60e51b815260040161081e90614a1e565b600a80546001600160a01b0319166001600160a01b0392909216919091179055565b600260015414156116335760405162461bcd60e51b815260040161081e90614daf565b600260019081556000878152600c602052604090205460ff16151514156116dd57600a546040805160008152602001908190526001600160a01b0390911690600190611686908790879087908790613ff1565b6020604051602081039080840390855afa1580156116a8573d6000803e3d6000fd5b505050602060405103516001600160a01b0316146116d85760405162461bcd60e51b815260040161081e9061471d565b611761565b6009546040805160008152602001908190526001600160a01b039091169060019061170f908790879087908790613ff1565b6020604051602081039080840390855afa158015611731573d6000803e3d6000fd5b505050602060405103516001600160a01b0316146117615760405162461bcd60e51b815260040161081e90614678565b6000848152600b602052604090205486141561178f5760405162461bcd60e51b815260040161081e90614856565b611797613751565b6117a087612d47565b9050600086116117c25760405162461bcd60e51b815260040161081e906141fb565b805161010001516117e55760405162461bcd60e51b815260040161081e90614079565b8051516001600160a01b03163314156118105760405162461bcd60e51b815260040161081e906140f3565b805160c0015142908110156118375760405162461bcd60e51b815260040161081e9061498a565b815160e00151158015906118505750815160e001518110155b156118af5760008881526005602052604090819020600801805460ff19169055517f90022e1d8eedbbb3c33615d39a0b09d7b55aea384712055d32661146c5a661f3906118a0908a903390614f8e565b60405180910390a15050611d7e565b60008881526006602090815260408083203384529091528120546118d39089612ead565b60008a8152600e6020908152604080832054808452600d909252909120600301549192509060ff1615611a2d576000818152600f602052604090205460ff16158061193a57506000818152600f6020908152604080832033845260010190915290205460ff165b6119565760405162461bcd60e51b815260040161081e90614bab565b61195e613771565b6000828152600d6020908152604091829020825160808101845281548152600182015481840152600282018054855181860281018601875281815292959394938601938301828280156119d057602002820191906000526020600020905b8154815260200190600101908083116119bc575b50505091835250506003919091015460ff1615156020918201528101519091506000906119fd90336106fc565b8251909150611a0c828d612ead565b1115611a2a5760405162461bcd60e51b815260040161081e9061439b565b50505b8360200151821115611a515760405162461bcd60e51b815260040161081e90614754565b83516040015151891115611a775760405162461bcd60e51b815260040161081e90614a8a565b60008a81526006602090815260408083203384529091528120839055845160800151611aa3908b6130d1565b8551606001519091506001600160a01b031615611ae457845160a0810151606090910151611adf916001600160a01b039091169033908461310b565b611b7a565b80341015611b045760405162461bcd60e51b815260040161081e9061417e565b7fa2d23878d5ab22445fbabd6fe02046a90b67448968da82383900084d250d529281604051611b339190614f85565b60405180910390a1845160a001516040516001600160a01b039091169082156108fc029083906000818181858888f19350505050158015611b78573d6000803e3d6000fd5b505b60608a67ffffffffffffffff81118015611b9357600080fd5b50604051908082528060200260200182016040528015611bbd578160200160208202803683370190505b50865160400151519091506000190160005b8c811015611cdc578760000151602001516001600160a01b03166342842e0e896000015160000151338b60000151604001518681518110611c0c57fe5b60200260200101516040518463ffffffff1660e01b8152600401611c3293929190613f6c565b600060405180830381600087803b158015611c4c57600080fd5b505af1158015611c60573d6000803e3d6000fd5b505050508760000151604001518281518110611c7857fe5b6020026020010151838281518110611c8c57fe5b60209081029190910181019190915260008f815260059091526040902060020180546000199093019280611cbc57fe5b600082815260208120820160001990810191909155019055600101611bcf565b5060008d815260056020526040902060020154611d0d5760008d8152600560205260409020600801805460ff191690555b8c600b60008d8152602001908152602001600020819055507fe266a5c8012d7c80c559afb035891cd33e867ac3350c54c4bca825ade265088d8d33896000015160200151858b600001516060015188604051611d6e96959493929190615000565b60405180910390a1505050505050505b50506001805550505050565b611d926130cd565b6001600160a01b0316611da3612149565b6001600160a01b031614611dc95760405162461bcd60e51b815260040161081e90614a1e565b6001600160a01b03821660009081526004602052604090819020805460ff1916831515179055517ff6019ec0a78d156d249a1ec7579e2321f6ac7521d6e1d2eacf90ba4a184dcceb90611e1f9084908490613f90565b60405180910390a15050565b60026001541415611e4e5760405162461bcd60e51b815260040161081e90614daf565b6002600155611e5b6137e6565b611e6483612ed9565b80516101000151909150611e8a5760405162461bcd60e51b815260040161081e90614880565b8051516001600160a01b0316331415611eb55760405162461bcd60e51b815260040161081e90614492565b805160c001514290811015611edc5760405162461bcd60e51b815260040161081e906147e8565b815160e001518110611f005760405162461bcd60e51b815260040161081e90614e86565b815160600151604083015115611fb35760208301516040840151611f2590869061312c565b1015611f435760405162461bcd60e51b815260040161081e90614c28565b60608301516040840151611f61916001600160a01b03841691613072565b7fe8f267296dd98f54fe66007a36688e8b79a64988383c42d63995938d8e143dd98584606001518560000151606001518660400151604051611fa69493929190615044565b60405180910390a1611fd7565b8251608001518414611fd75760405162461bcd60e51b815260040161081e906149c1565b6000858152600760205260408120600a8101869055600b0180546001600160a01b03191633179055612015906001600160a01b038316903090613154565b6120296001600160a01b0382163086613154565b61203e6001600160a01b03821633308761310b565b8251606001516040517fc96310726d5afa93813f4276097a5d37645001323ca859d67ed71d1db0785dfb9161207891889133918990615044565b60405180910390a1505060018055505050565b600d6020526000908152604090208054600182015460039092015490919060ff1683565b6120b76130cd565b6001600160a01b03166120c8612149565b6001600160a01b0316146120ee5760405162461bcd60e51b815260040161081e90614a1e565b600080546040516001600160a01b03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600080546001600160a01b0319169055565b6121406137e6565b6106f482612ed9565b6000546001600160a01b031690565b6121606130cd565b6001600160a01b0316612171612149565b6001600160a01b0316146121975760405162461bcd60e51b815260040161081e90614a1e565b600980546001600160a01b0319166001600160a01b0392909216919091179055565b600e6020526000908152604090205481565b6121d3613771565b6000828152600d60209081526040918290208251608081018452815481526001820154818401526002820180548551818602810186018752818152929593949386019383018282801561224557602002820191906000526020600020905b815481526020019060010190808311612231575b50505091835250506003919091015460ff16151560209091015292915050565b600260015414156122885760405162461bcd60e51b815260040161081e90614daf565b60026001553360009081526004602052604090205460ff166122bc5760405162461bcd60e51b815260040161081e9061435a565b6122c46137e6565b6122cd82612ed9565b805161010001519091506122f35760405162461bcd60e51b815260040161081e90614880565b8051516001600160a01b0316331461231d5760405162461bcd60e51b815260040161081e90614bd9565b6040810151156123a357612355816060015182604001518360000151606001516001600160a01b03166130729092919063ffffffff16565b7fe8f267296dd98f54fe66007a36688e8b79a64988383c42d63995938d8e143dd9828260600151836000015160600151846040015160405161239a9493929190615044565b60405180910390a15b60008281526007602052604090819020600801805460ff19169055517f2a6445a420b30cbabfffd85287bfa6c0c8f9b5f65d48637922da74abf357e52b906112e19084903390614f8e565b60006123f8613751565b61240183612d47565b5160400151519392505050565b60046020526000908152604090205460ff1681565b600c6020526000908152604090205460ff1681565b60025490565b6124466130cd565b6001600160a01b0316612457612149565b6001600160a01b03161461247d5760405162461bcd60e51b815260040161081e90614a1e565b6000838152600f60205260408120805460ff191660011790555b81811015612505576000848152600f60205260408120600191908201908585858181106124c057fe5b90506020020160208101906124d59190613924565b6001600160a01b031681526020810191909152604001600020805460ff1916911515919091179055600101612497565b50505050565b6000612515613751565b60008381526005602090815260409182902082516101608101845281546001600160a01b039081168286019081526001840154909116606083015260028301805486518187028101870190975280875292959394869492938693608087019390929091908301828280156125a857602002820191906000526020600020905b815481526020019060010190808311612594575b505050918352505060038201546001600160a01b0390811660208084019190915260048401546040808501919091526005850154909216606084015260068401546080840152600784015460a084015260089093015460ff16151560c09092019190915291835260099390930154919092015290510151519392505050565b3360009081526004602052604090205460ff166126565760405162461bcd60e51b815260040161081e9061435a565b8051806126755760405162461bcd60e51b815260040161081e9061455a565b60008481526005602052604090206006015442106126a55760405162461bcd60e51b815260040161081e906148b7565b6000848152600560205260409020546001600160a01b031633146126db5760405162461bcd60e51b815260040161081e9061430f565b8260005b83518110156127e95760008482815181106126f657fe5b602090810291909101810151600089815260059092526040918290205491516331a9108f60e11b81529092506001600160a01b0391821691851690636352211e90612745908590600401614f85565b60206040518083038186803b15801561275d57600080fd5b505afa158015612771573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127959190613940565b6001600160a01b0316146127bb5760405162461bcd60e51b815260040161081e90614de6565b60008781526005602090815260408220600201805460018181018355918452919092200191909155016126df565b507f9fb33f4b0149c5f78fc6753547dba139088c5f19b41fa58239d32f85eaa22935838660405161281b929190613fc4565b60405180910390a15050505050565b3360009081526004602052604090205460ff166128595760405162461bcd60e51b815260040161081e9061435a565b612861613751565b61286a82612d47565b805161010001519091506128905760405162461bcd60e51b815260040161081e90614079565b8051516001600160a01b031633146128ba5760405162461bcd60e51b815260040161081e906142bd565b60008281526005602052604090819020600801805460ff19169055517ff3da86c38149b3ff13eb97ec00d936dffd9cb29a827e1c0fc9dae4a939137fc890611e1f9084903390614f8e565b6009546001600160a01b031681565b61291c6130cd565b6001600160a01b031661292d612149565b6001600160a01b0316146129535760405162461bcd60e51b815260040161081e90614a1e565b612965836001600160a01b0316613217565b156129835761297e6001600160a01b0384168383613072565b612996565b6129966001600160a01b0383168261321d565b7ff24ef89f38eadc1bde50701ad6e4d6d11a2dc24f7cf834a486991f38833285048383836040516129c993929190613f6c565b60405180910390a1505050565b600a546001600160a01b031681565b60026001541415612a085760405162461bcd60e51b815260040161081e90614daf565b6002600155612a156130cd565b6001600160a01b0316612a26612149565b6001600160a01b031614612a4c5760405162461bcd60e51b815260040161081e90614a1e565b6000918252600c6020526040909120805460ff191691151591909117905560018055565b6000612a7a6137e6565b60008381526007602090815260409182902082516101a08101845281546001600160a01b0390811660808301908152600184015490911660a08301526002830180548651818702810187019097528087529295939486949293869360c08701939092909190830182828015612b0e57602002820191906000526020600020905b815481526020019060010190808311612afa575b505050918352505060038201546001600160a01b0390811660208084019190915260048401546040808501919091526005850154831660608086019190915260068601546080860152600786015460a086015260089095015460ff16151560c090940193909352938552600986015493850193909352600a85015484820152600b9094015490911691015290510151519392505050565b612bad6130cd565b6001600160a01b0316612bbe612149565b6001600160a01b031614612be45760405162461bcd60e51b815260040161081e90614a1e565b602080820180516000908152600d8352604090819020845181559151600183015583015180518493612c1d92600285019291019061379b565b50606091909101516003909101805460ff191691151591909117905560005b816040015151811015612c8357600082604001518281518110612c5b57fe5b602090810291909101810151848201516000918252600e909252604090205550600101612c3c565b5050565b612c8f6130cd565b6001600160a01b0316612ca0612149565b6001600160a01b031614612cc65760405162461bcd60e51b815260040161081e90614a1e565b6001600160a01b038116612cec5760405162461bcd60e51b815260040161081e906141b5565b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b0319166001600160a01b0392909216919091179055565b612d4f613751565b60008281526005602090815260409182902082516101608101845281546001600160a01b03908116828601908152600184015490911660608301526002830180548651818702810187019097528087529295939486949293869360808701939092909190830182828015612de257602002820191906000526020600020905b815481526020019060010190808311612dce575b505050918352505060038201546001600160a01b039081166020808401919091526004840154604084015260058401548216606084015260068401546080840152600784015460a084015260089093015460ff16151560c090920191909152918352600993909301549190920152815151919250166106f75760405162461bcd60e51b815260040161081e906140b0565b6000612e8287878787876132b9565b905060008211612ea45760405162461bcd60e51b815260040161081e906147b1565b50505050505050565b600082820183811015612ed25760405162461bcd60e51b815260040161081e90614286565b9392505050565b612ee16137e6565b60008281526007602090815260409182902082516101a08101845281546001600160a01b0390811660808301908152600184015490911660a08301526002830180548651818702810187019097528087529295939486949293869360c08701939092909190830182828015612f7557602002820191906000526020600020905b815481526020019060010190808311612f61575b505050918352505060038201546001600160a01b0390811660208084019190915260048401546040808501919091526005850154831660608086019190915260068601546080860152600786015460a086015260089095015460ff16151560c090940193909352938552600986015493850193909352600a85015490840152600b9093015481169190920152815151919250166106f75760405162461bcd60e51b815260040161081e90614914565b61303187878787866132b9565b50600083116130525760405162461bcd60e51b815260040161081e9061440b565b60008111612ea45760405162461bcd60e51b815260040161081e90614150565b6130c88363a9059cbb60e01b8484604051602401613091929190613fab565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b0319909316929092179091526135b1565b505050565b3390565b6000826130e0575060006107f5565b828202828482816130ed57fe5b0414612ed25760405162461bcd60e51b815260040161081e90614949565b612505846323b872dd60e01b85858560405160240161309193929190613f6c565b60008282111561314e5760405162461bcd60e51b815260040161081e90614523565b50900390565b8015806131dc5750604051636eb1769f60e11b81526001600160a01b0384169063dd62ed3e9061318a9030908690600401613f52565b60206040518083038186803b1580156131a257600080fd5b505afa1580156131b6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906131da9190613be5565b155b6131f85760405162461bcd60e51b815260040161081e90614e30565b6130c88363095ea7b360e01b8484604051602401613091929190613fab565b3b151590565b8047101561323d5760405162461bcd60e51b815260040161081e906145fb565b6000826001600160a01b03168260405161325690613f3b565b60006040518083038185875af1925050503d8060008114613293576040519150601f19603f3d011682016040523d82523d6000602084013e613298565b606091505b50509050806130c85760405162461bcd60e51b815260040161081e9061459e565b8251846000805b83811015613520578681815181106132d457fe5b6020908102919091018101516001600160a01b0385166000908152600883526040808220838352909352919091205490925060ff16156133265760405162461bcd60e51b815260040161081e9061481f565b6001600160a01b03808416600081815260086020908152604080832087845290915290819020805460ff19166001179055516331a9108f60e11b8152918b1691636352211e9061337a908690600401614f85565b60206040518083038186803b15801561339257600080fd5b505afa1580156133a6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906133ca9190613940565b6001600160a01b0316146133f05760405162461bcd60e51b815260040161081e90614de6565b60405163020604bf60e21b815230906001600160a01b0385169063081812fc9061341e908690600401614f85565b60206040518083038186803b15801561343657600080fd5b505afa15801561344a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061346e9190613940565b6001600160a01b031614806134fc575060405163e985e9c560e01b81526001600160a01b0384169063e985e9c5906134ac908c903090600401613f52565b60206040518083038186803b1580156134c457600080fd5b505afa1580156134d8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906134fc9190613b1b565b6135185760405162461bcd60e51b815260040161081e90614cab565b6001016132c0565b50428410156135415760405162461bcd60e51b815260040161081e90614042565b60005b838110156135a5576001600160a01b0388166000908152600860205260408120885182908a908590811061357457fe5b6020908102919091018101518252810191909152604001600020805460ff1916911515919091179055600101613544565b50505095945050505050565b6060613606826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166136409092919063ffffffff16565b8051909150156130c857808060200190518101906136249190613b1b565b6130c85760405162461bcd60e51b815260040161081e90614d08565b606061364f8484600085613657565b949350505050565b6060824710156136795760405162461bcd60e51b815260040161081e90614632565b61368285613217565b61369e5760405162461bcd60e51b815260040161081e90614b74565b60006060866001600160a01b031685876040516136bb9190613f1f565b60006040518083038185875af1925050503d80600081146136f8576040519150601f19603f3d011682016040523d82523d6000602084013e6136fd565b606091505b509150915061370d828286613718565b979650505050505050565b60608315613727575081612ed2565b8251156137375782518084602001fd5b8160405162461bcd60e51b815260040161081e919061400f565b604051806040016040528061376461381d565b8152602001600081525090565b60405180608001604052806000815260200160008152602001606081526020016000151581525090565b8280548282559060005260206000209081019282156137d6579160200282015b828111156137d65782518255916020019190600101906137bb565b506137e292915061388f565b5090565b60405180608001604052806137f961381d565b8152602001600081526020016000815260200160006001600160a01b031681525090565b60405180610120016040528060006001600160a01b0316815260200160006001600160a01b031681526020016060815260200160006001600160a01b031681526020016000815260200160006001600160a01b0316815260200160008152602001600081526020016000151581525090565b5b808211156137e25760008155600101613890565b600082601f8301126138b4578081fd5b813567ffffffffffffffff8111156138ca578182fd5b60208082026138da8282016150eb565b838152935081840185830182870184018810156138f657600080fd5b600092505b848310156139195780358252600192909201919083019083016138fb565b505050505092915050565b600060208284031215613935578081fd5b8135612ed28161513e565b600060208284031215613951578081fd5b8151612ed28161513e565b600080600060608486031215613970578182fd5b833561397b8161513e565b9250602084013561398b8161513e565b929592945050506040919091013590565b600080600080600080600080610100898b0312156139b8578384fd5b88356139c38161513e565b9750602089013567ffffffffffffffff8111156139de578485fd5b6139ea8b828c016138a4565b97505060408901356139fb8161513e565b9550606089013594506080890135613a128161513e565b979a969950949793969560a0850135955060c08501359460e001359350915050565b60008060008060008060008060006101208a8c031215613a52578081fd5b8935613a5d8161513e565b985060208a013567ffffffffffffffff811115613a78578182fd5b613a848c828d016138a4565b98505060408a0135613a958161513e565b965060608a0135955060808a0135613aac8161513e565b945060a08a0135935060c08a0135925060e08a013591506101008a0135613ad281615156565b809150509295985092959850929598565b60008060408385031215613af5578182fd5b8235613b008161513e565b91506020830135613b1081615156565b809150509250929050565b600060208284031215613b2c578081fd5b8151612ed281615156565b600060208284031215613b48578081fd5b813567ffffffffffffffff80821115613b5f578283fd5b9083019060808286031215613b72578283fd5b613b7c60806150eb565b8235815260208301356020820152604083013582811115613b9b578485fd5b613ba7878286016138a4565b60408301525060608301359250613bbd83615156565b6060810192909252509392505050565b600060208284031215613bde578081fd5b5035919050565b600060208284031215613bf6578081fd5b5051919050565b60008060408385031215613c0f578182fd5b823591506020830135613b108161513e565b600080600060608486031215613c35578081fd5b833592506020840135613c478161513e565b9150604084013567ffffffffffffffff811115613c62578182fd5b613c6e868287016138a4565b9150509250925092565b60008060008060008060008060006101208a8c031215613c96578283fd5b8935985060208a0135613ca88161513e565b975060408a013567ffffffffffffffff811115613cc3578384fd5b613ccf8c828d016138a4565b97505060608a0135613ce08161513e565b955060808a0135945060a08a0135613cf78161513e565b8094505060c08a0135925060e08a013591506101008a013590509295985092959850929598565b600080600060408486031215613d32578081fd5b83359250602084013567ffffffffffffffff80821115613d50578283fd5b818601915086601f830112613d63578283fd5b813581811115613d71578384fd5b8760208083028501011115613d84578384fd5b6020830194508093505050509250925092565b60008060408385031215613da9578182fd5b823591506020830135613b1081615156565b60008060408385031215613dcd578182fd5b50508035926020909101359150565b60008060008060008060c08789031215613df4578384fd5b863595506020870135945060408701359350606087013560ff81168114613e19578283fd5b9598949750929560808101359460a0909101359350915050565b6001600160a01b03169052565b6000815180845260208085019450808401835b83811015613e6f57815187529582019590820190600101613e53565b509495945050505050565b15159052565b600061012060018060a01b0383511684526020830151613ea36020860182613e33565b506040830151816040860152613ebb82860182613e40565b9150506060830151613ed06060860182613e33565b506080830151608085015260a0830151613eed60a0860182613e33565b5060c083015160c085015260e083015160e085015261010080840151613f1582870182613e7a565b5090949350505050565b60008251613f31818460208701615112565b9190910192915050565b90565b6001600160a01b0391909116815260200190565b6001600160a01b0392831681529116602082015260400190565b6001600160a01b039384168152919092166020820152604081019190915260600190565b6001600160a01b039290921682521515602082015260400190565b6001600160a01b03929092168252602082015260400190565b600060408252613fd76040830185613e40565b90508260208301529392505050565b901515815260200190565b93845260ff9290921660208401526040830152606082015260800190565b600060208252825180602084015261402e816040850160208701615112565b601f01601f19169190910160400192915050565b60208082526018908201527f737461727454696d65206d757374206265203e3d206e6f770000000000000000604082015260600190565b6020808252601e908201527f74686520666c6173682073616c652069736e277420617661696c61626c650000604082015260600190565b60208082526023908201527f7468652074617267657420666c6173682073616c6520646f65736e27742065786040820152621a5cdd60ea1b606082015260800190565b60208082526038908201527f746865207365747465722063616e2774206d616b65206120707572636861736560408201527f2066726f6d20697473206f776e20666c6173682073616c650000000000000000606082015260800190565b60208082526014908201527306475726174696f6e206d757374206265203e20360641b604082015260600190565b6020808252601f908201527f616d6f756e742073686f756c64206265203e20746f74616c5061796d656e7400604082015260600190565b60208082526026908201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160408201526564647265737360d01b606082015260800190565b6020808252601490820152730616d6f756e742073686f756c64206265203e20360641b604082015260600190565b6020808252603f908201527f69742773206e6f7420616c6c6f77656420746f2075706461746520746865206660408201527f6c6173682073616c6520616674657220746865207374617274206f6620697400606082015260800190565b6020808252601b908201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604082015260600190565b60208082526032908201527f74686520666c6173682073616c652063616e206f6e6c792062652063616e6365604082015271363632b210313c9034ba399039b2ba3a32b960711b606082015260800190565b6020808252602b908201527f746865202073616c652063616e206f6e6c79206265207570646174656420627960408201526a1034ba399039b2ba3a32b960a91b606082015260800190565b60208082526021908201527f7468652063616c6c65722069736e277420696e207468652077686974656c69736040820152601d60fa1b606082015260800190565b6020808252604a908201527f746f74616c20616d6f756e7420746f20707572636861736520666f722061637460408201527f6976697479206578636565647320746865206c696d69746174696f6e206f6620606082015269616e206164647265737360b01b608082015260a00190565b6020808252601b908201527f6d696e426964496e6372656d656e74206d757374206265203e20300000000000604082015260600190565b60208082526030908201527f74686520666c6173682073616c652063616e206f6e6c7920626520757064617460408201526f32b210313c9034ba399039b2ba3a32b960811b606082015260800190565b60208082526028908201527f746865207365747465722063616e27742062696420666f7220697473206f776e6040820152671030bab1ba34b7b760c11b606082015260800190565b60208082526029908201527f6f6e6c792074686520617661696c61626c652061756374696f6e2063616e206260408201526819481cd95d1d1b195960ba1b606082015260800190565b6020808252601e908201527f536166654d6174683a207375627472616374696f6e206f766572666c6f770000604082015260600190565b60208082526024908201527f6c656e677468206f6620746f6b656e416464726573736573206d7573742062656040820152630203e20360e41b606082015260800190565b6020808252603a908201527f416464726573733a20756e61626c6520746f2073656e642076616c75652c207260408201527f6563697069656e74206d61792068617665207265766572746564000000000000606082015260800190565b6020808252601d908201527f416464726573733a20696e73756666696369656e742062616c616e6365000000604082015260600190565b60208082526026908201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6040820152651c8818d85b1b60d21b606082015260800190565b6020808252601e908201527f766572696679207465737420736572766572207369676e206661696c65640000604082015260600190565b602080825260139082015272185b1c9958591e481a5b9a5d1a585b1a5e9959606a1b604082015260600190565b60208082526021908201527f74686520666c6173682073616c6520686173206265656e2063616e63656c6c656040820152601960fa1b606082015260800190565b6020808252601e908201527f7665726966792070726f6420736572766572207369676e206661696c65640000604082015260600190565b6020808252603d908201527f746f74616c20616d6f756e7420746f207075726368617365206578636565647360408201527f20746865206c696d69746174696f6e206f6620616e2061646472657373000000606082015260800190565b6020808252601e908201527f70757263686173654c696d69746174696f6e206d757374206265203e20300000604082015260600190565b60208082526019908201527f7468652061756374696f6e20646f65736e277420737461727400000000000000604082015260600190565b60208082526018908201527f726570657469746976652045524337323120746f6b656e730000000000000000604082015260600190565b60208082526010908201526f1cda59db881a185cda081c995c19585d60821b604082015260600190565b6020808252601b908201527f7468652061756374696f6e2069736e277420617661696c61626c650000000000604082015260600190565b6020808252603a908201527f69742773206e6f7420616c6c6f77656420746f2075706461746520746865202060408201527f73616c6520616674657220746865207374617274206f66206974000000000000606082015260800190565b6020808252818101527f746865207461726765742061756374696f6e20646f65736e2774206578697374604082015260600190565b60208082526021908201527f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f6040820152607760f81b606082015260800190565b6020808252601c908201527f74686520666c6173682073616c6520646f65736e277420737461727400000000604082015260600190565b6020808252603a908201527f666972737420626964206d75737420666f6c6c6f772074686520696e6974696160408201527f6c2070726963652073657420696e207468652061756374696f6e000000000000606082015260800190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b6020808252601e908201527f7468652061756374696f6e20686173206265656e2063616e63656c6c65640000604082015260600190565b6020808252602b908201527f696e73756666696369656e7420616d6f756e74206f6620746f6b656e20666f7260408201526a207468697320747261646560a81b606082015260800190565b60208082526032908201527f7468652061756374696f6e2063616e206f6e6c7920626520736574746c65642060408201527161667465722069747320656e642074696d6560701b606082015260800190565b6020808252602d908201527f7468652061756374696f6e2063616e206f6e6c7920626520757064617465642060408201526c313c9034ba399039b2ba3a32b960991b606082015260800190565b6020808252601d908201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604082015260600190565b602080825260149082015273139bdd081a5b881d1a194815da1a5d195b1a5cdd60621b604082015260600190565b6020808252602f908201527f7468652061756374696f6e2063616e206f6e6c792062652063616e63656c6c6560408201526e3210313c9034ba399039b2ba3a32b960891b606082015260800190565b6020808252605a908201527f74686520626964207072696365206d757374206265206c61726765722074686160408201527f6e207468652073756d206f662063757272656e742068696768657374206f6e6560608201527f20616e64206d696e696d756d2062696420696e6372656d656e74000000000000608082015260a00190565b60208082526039908201527f74686520636f6e7472616374206861736e2774206265656e20617070726f766560408201527f6420666f7220455243373231207472616e7366657272696e6700000000000000606082015260800190565b6020808252602a908201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6040820152691bdd081cdd58d8d9595960b21b606082015260800190565b6020808252603c908201527f69742773206e6f7420616c6c6f77656420746f2075706461746520746865206160408201527f756374696f6e20616674657220746865207374617274206f6620697400000000606082015260800190565b6020808252601f908201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604082015260600190565b6020808252602a908201527f756e6d617463686564206f776e657273686970206f6620746172676574204552604082015269219b9918903a37b5b2b760b11b606082015260800190565b60208082526036908201527f5361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f60408201527520746f206e6f6e2d7a65726f20616c6c6f77616e636560501b606082015260800190565b60208082526017908201527f7468652061756374696f6e206861732065787069726564000000000000000000604082015260600190565b6000602082528251602083015260208301516040830152604083015160806060840152614eed60a0840182613e40565b90506060840151151560808401528091505092915050565b600060208252825160806020840152614f2160a0840182613e80565b9050602084015160408401526040840151606084015260018060a01b0360608501511660808401528091505092915050565b600060208252825160406020840152614f6f6060840182613e80565b9050602084015160408401528091505092915050565b90815260200190565b9182526001600160a01b0316602082015260400190565b8881526001600160a01b03888116602083015287811660408301528681166060830152858116608083015261010060a08301819052600091614fe984830188613e40565b951660c0840152505060e001529695505050505050565b600087825260018060a01b038088166020840152808716604084015260c0606084015261503060c0840187613e40565b941660808301525060a00152949350505050565b9384526001600160a01b03928316602085015291166040830152606082015260800190565b8a81526001600160a01b038a8116602083015289811660408301526101406060830181905260009161509d8483018c613e40565b998116608085015260a084019890985250509390941660c084015260e08301919091526101008201526101200152949350505050565b92835260208301919091521515604082015260600190565b60405181810167ffffffffffffffff8111828210171561510a57600080fd5b604052919050565b60005b8381101561512d578181015183820152602001615115565b838111156125055750506000910152565b6001600160a01b038116811461515357600080fd5b50565b801515811461515357600080fdfea2646970667358221220698ab25d977996821558d6a918a9e93ffd827a8e36209656b862e6671c47ca1b64736f6c634300060c0033
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 26 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
Loading...
Loading
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.