ERC-721
NFT
Overview
Max Total Supply
10,000 LUCHADORES
Holders
1,784
Market
Volume (24H)
N/A
Min Price (24H)
N/A
Max Price (24H)
N/A
Other Info
Token Contract
Balance
18 LUCHADORESLoading...
Loading
Loading...
Loading
Loading...
Loading
# | Exchange | Pair | Price | 24H Volume | % Volume |
---|
Contract Name:
Luchadores
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.0; import "@openzeppelin/contracts/token/ERC721/ERC721Pausable.sol"; import "@openzeppelin/contracts/access/Ownable.sol"; import "@openzeppelin/contracts/utils/ReentrancyGuard.sol"; import "@openzeppelin/contracts/utils/Counters.sol"; import "@openzeppelin/contracts/utils/Strings.sol"; import "@chainlink/contracts/src/v0.6/VRFConsumerBase.sol"; import "@uniswap/v2-periphery/contracts/interfaces/IUniswapV2Router02.sol"; contract Luchadores is ERC721Pausable, Ownable, ReentrancyGuard, VRFConsumerBase { using Counters for Counters.Counter; using Strings for uint256; Counters.Counter private _tokenIds; IUniswapV2Router02 public uniswapRouter; bytes32 internal keyHash = 0xAA77729D3466CA35AE8D28B3BBAC7CC36A5031EFDC430821C02BC31A238AF445; uint256 internal LinkFee = 2 * 10**18; // 2 LINK address private VRFCoordinator = 0xf0d54349aDdcf704F77AE15b96510dEA15cb7952; address private LinkToken = 0x514910771AF9Ca656af840dff83E8264EcF986CA; constructor() public ERC721("Luchadores", "LUCHADORES") VRFConsumerBase(VRFCoordinator, LinkToken) { uniswapRouter = IUniswapV2Router02(0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D); art.baseColor = ["ebebf7", "1c1d2f", "cc0d3d", "d22f94", "890ec1", "1c49d8", "19b554", "13cac6", "f7c23c", "f18e2f"]; art.altColor = ["dadae6", "13141f", "ea184d", "e0369f", "9511d2", "2854e6", "1da951", "11b9b5", "e8b63a", "e28327"]; art.eyeColor = ["3b6ba5", "3b8fa5", "3ba599", "3ba577", "339842", "7fa53b", "a5823b", "a5693b", "844f1d", "4e2906"]; art.skinColor = ["f9d1b7", "f7b897", "f39c77", "ffcb84", "bd7e47", "b97e4b", "b97a50", "5a3214", "50270e", "3a1b09"]; art.spirit[0] = Item("Bull", "<path fill='#A9A18A' d='M21 2V1h-1V0h-1v2h1v1h-3v2h2v1h2V5h1V2zM5 3H4V2h1V0H4v1H3v1H2v3h1v1h2V5h2V3H6z'/><g fill='#000' opacity='.15'><path d='M21 4h1v1h-1zM19 5h-1v1h3V5h-1z'/><path d='M2 4h1v1H2zM4 5H3v1h3V5H5z'/></g>"); art.spirit[1] = Item("Jaguar", "<path class='lucha-base' d='M6 2V1H5v5h1V5h1V3h1V2H7zM18 1v1h-2v1h1v2h1v1h1V1z'/><g fill='#000'><path d='M5 1h1v1H5zM6 2v1h2V2H7zM18 1h1v1h-1zM16 2v1h2V2h-1z' opacity='.3'/><path d='M6 3V2H5v4h1V5h1V3zM18 2v1h-1v2h1v1h1V2z' opacity='.2'/></g>"); art.cape[0] = Item("Classic", "<path class='lucha-alt' d='M20 11H3v12h1v-1h2v-1h12v1h2v1h1V11z'/><g fill='#000'><path opacity='.2' d='M20 11v12h1V11zM3 12v11h1V11H3z'/><path opacity='.5' d='M19 11H4v11h2v-1h12v1h2V11z'/></g>"); art.cape[1] = Item("Hooded", "<path class='lucha-alt' d='M20 11H3v12h1v-1h2v-1h12v1h2v1h1V11z'/><g fill='#000'><path opacity='.2' d='M20 11v12h1V11zM3 12v11h1V11H3z'/><path opacity='.5' d='M19 11H4v11h2v-1h12v1h2V11z'/></g>"); art.torso[0] = Item("Shirt", "<path class='lucha-base' d='M22 12v-1h-1v-1h-1V9H4v1H3v1H2v1H1v5h4v-3h1v1h1v1h1v2h8v-2h1v-1h1v-1h1v3h4v-5z'/><path d='M22 12v-1h-1v-1h-1V9H4v1H3v1H2v1H1v5h4v-3h1v1h1v1h1v2h8v-2h1v-1h1v-1h1v3h4v-5z' fill='#000' opacity='.15'/>"); art.torso[1] = Item("Open Shirt", "<path class='lucha-base' d='M10 9H4v1H3v1H2v1H1v3h4v-1h1v1h1v1h1v2h3V9zM22 12v-1h-1v-1h-1V9h-7v9h3v-2h1v-1h1v-1h1v1h4v-3z'/><path d='M10 9H4v1H3v1H2v1H1v3h4v-1h1v1h1v1h1v2h3V9zM22 12v-1h-1v-1h-1V9h-7v9h3v-2h1v-1h1v-1h1v1h4v-3z' fill='#000' opacity='.15'/>"); art.torso[2] = Item("Singlet", "<path class='lucha-base' d='M16 9H7v3h1-1v4h1v1h8v-1h1v-4h-1 1V9z'/><path fill='#000' opacity='.15' d='M16 9H7v7h1v1h8v-1h1V9z'/>"); art.torso[3] = Item("Suspenders", "<path class='lucha-base' d='M15 9v9h1V9zM8 10v8h1V9H8z'/><path d='M8 10v8h1V9H8zM15 9v9h1V9z' fill='#000' opacity='.15'/>"); art.arms[0] = Item("Gloves", "<path class='lucha-base' d='M5 16H1v3h4v-1h1v-1H5zM22 16h-3v1h-1v1h1v1h4v-3z'/><path class='lucha-alt' d='M3 16H1v1h4v-1H4zM22 16h-3v1h4v-1z'/>"); art.arms[1] = Item("Wrist Bands", "<path class='lucha-base' d='M3 15H1v2h4v-2H4zM22 15h-3v2h4v-2z'/>"); art.arms[2] = Item("Right Band", "<path class='lucha-alt' d='M4 14H1v1h4v-1z'/>"); art.arms[3] = Item("Left Band", "<path class='lucha-base' d='M22 14h-3v1h4v-1z'/>"); art.arms[4] = Item("Arm Bands", "<path class='lucha-base' d='M4 14H1v1h4v-1zM22 14h-3v1h4v-1z'/>"); art.arms[5] = Item("Sleeves", "<path class='lucha-base' d='M22 14h-3v3h4v-3zM3 14H1v3h4v-3H4z'/><path class='lucha-alt' d='M22 14h-3v1h4v-1zM3 14H1v1h4v-1H4z'/>"); art.mask[0] = Item("Split", "<path d='M11 0H9v1H8v1H7v1H6v2H5v5h1v2h1v1h1v1h1v1h3V0z'/>"); art.mask[1] = Item("Cross", "<path d='M14 2h-1V0h-2v2H9v2h2v4h2V4h2V2zM12 13h-1v2h2v-2z'/>"); art.mask[2] = Item("Fierce", "<path d='M17 3v1h-2v1h-1v1h-1v3h5V3zM11 8V6h-1V5H9V4H7V3H6v6h5zM11 13v2h2v-2h-1z'/>"); art.mask[3] = Item("Striped", "<path d='M11 2h2V1h1V0h-4v1h1zM6 10v2h1v-1h1v-1H7zM17 10h-1v1h1v1h1v-2z'/><path d='M16 3h1V2h-1V1h-1v1h-1v1h-1v1h-2V3h-1V2H9V1H8v1H7v1h1v1h1v1h1v1h1v9h2V6h1V5h1V4h1z'/>"); art.mask[4] = Item("Bolt", "<path d='M13 3h-3V2h1V1h1V0H9v1H8v1H7v1H6v2h3v1H8v2H7v2h1V9h1V8h1V7h1V6h1V5h1V4h1V3z'/>"); art.mask[5] = Item("Winged", "<path d='M18 5V3h-1V2h-1v1h-1v1h-1v1h-1v1h-2V5h-1V4H9V3H8V2H7v1H6v2H5v5h1v2h1v-1h1v-1h3V9h2v1h3v1h1v1h1v-2h1V5z'/>"); art.mask[6] = Item("Classic", "<path d='M18 5V3h-1V2h-1v2h-1v1h-1v1h-1v3h-2V6h-1V5H9V4H8V2H7v1H6v2H5v4h1v1h2v3h1v1h6v-1h1v-3h2V9h1V5z'/>"); art.mask[7] = Item("Arrow", "<path d='M18 5V3h-1V2h-1V1h-1V0H9v1H8v1H7v1H6v2H5v5h1v2h1v1h1v1h1v1h1v-4h1V5H9V3h1V2h1V1h2v1h1v1h1v2h-2v6h1v4h1v-1h1v-1h1v-1h1v-2h1V5z'/>"); art.mask[8] = Item("Dash", "<path d='M13 3V2h-2v2h2zM13 1V0h-2v1h1zM10 4H9V1H8v1H7v1H6v2H5v5h1v2h1v1h1v1h1v1h1v-2H9v-3h2V5h-1zM18 5V3h-1V2h-1V1h-1v3h-1v1h-1v5h2v3h-1v2h1v-1h1v-1h1v-1h1v-2h1V5z'/>"); art.mouth[0] = Item("Moustache", "<path fill='#421c03' opacity='.9' d='M14 10H9v3h1v-2h4v2h1v-3z'/>"); art.bottoms[0] = Item("Tights", "<path class='lucha-alt' d='M15 17H8v6h3v-3h2v3h3v-6z'/>"); art.bottoms[1] = Item("Trunk Tights", "<path class='lucha-base' d='M15 17H8v3h8v-3z'/><path class='lucha-alt' d='M15 18v1h-2v4h3v-5zM9 19v-1H8v5h3v-4h-1z'/>"); art.boots[0] = Item("Two Tone", "<path class='lucha-alt' d='M9 22H8v1H7v1h4v-2h-1zM16 23v-1h-3v2h4v-1z'/>"); art.boots[1] = Item("High", "<path class='lucha-alt' d='M9 20H8v1h3v-1h-1zM15 20h-2v1h3v-1z'/>"); } struct Item { bytes12 name; string svg; } struct Art { string[] baseColor; string[] altColor; string[] eyeColor; string[] skinColor; mapping(uint256 => Item) spirit; mapping(uint256 => Item) cape; mapping(uint256 => Item) torso; mapping(uint256 => Item) arms; mapping(uint256 => Item) mask; mapping(uint256 => Item) mouth; mapping(uint256 => Item) bottoms; mapping(uint256 => Item) boots; } Art art; struct Luchador { uint256 dna; } struct VRFRequest { uint256 id; } mapping(uint256 => Luchador) luchadores; mapping(bytes32 => VRFRequest) VRFRequests; event GenerateLuchador( uint256 indexed id, uint256 dna ); function generateLuchador(uint256 _quantity, uint256 _deadline) external payable nonReentrant whenNotPaused { require(_tokenIds.current() < 10000, "maximum luchadores reached"); require(_tokenIds.current() + _quantity <= 10000, "mint quantity exceeds max supply"); require(_quantity > 0 && _quantity <= 20, "mint quantity must be between 1-20"); uint256 amountOut = LinkFee * _quantity; address[] memory path = new address[](2); path[0] = uniswapRouter.WETH(); path[1] = LinkToken; uniswapRouter.swapETHForExactTokens{value: msg.value}(amountOut, path, address(this), _deadline); for (uint256 i = 0; i < _quantity; i++) { getRandomNumber(uint256(blockhash(block.number - i))); } } function getRandomNumber(uint256 _userProvidedSeed) internal { require(LINK.balanceOf(address(this)) >= LinkFee, "Not enough LINK - fill contract"); bytes32 requestId = requestRandomness(keyHash, LinkFee, _userProvidedSeed); _tokenIds.increment(); VRFRequests[requestId] = VRFRequest({ id: _tokenIds.current() }); _safeMint(msg.sender, _tokenIds.current()); } function fulfillRandomness(bytes32 _requestId, uint256 _randomNumber) internal override { luchadores[VRFRequests[_requestId].id].dna = _randomNumber; emit GenerateLuchador(VRFRequests[_requestId].id, _randomNumber); } function imageData(uint256 _tokenId) public view returns (string memory) { require(_exists(_tokenId), "imageData: nonexistent token"); require(luchadores[_tokenId].dna != 0, "imageData: dna not yet generated"); uint8[12] memory dna = splitNumber(luchadores[_tokenId].dna); string memory capeShoulders = (dna[1] == 0 || dna[1] == 1)? "<path class='lucha-alt' d='M20 10V9h-2v1h-1v1h4v-1zM5 9H4v1H3v1h4v-1H6V9z'/><path fill='#000' opacity='.2' d='M6 9H4v1H3v1h4v-1H6zM20 10V9h-2v1h-1v1h4v-1z'/>" : ""; string memory capeHood = dna[1] == 1 ? "<path class='lucha-alt' d='M18 4V3h-1V2h-1V1h-1V0H9v1H8v1H7v1H6v2H5v5h1V6h1V5h2V4h1V3h4v1h1v1h2v1h1v4h1V5h-1z'/><g fill='#000'><path d='M18 4V3h-1V2h-1V1h-1V0H9v1H8v1H7v1H6v2H5v5h1V5h1V4h1V3h1V2h6v1h1v1h1v1h1v5h1V5h-1z' opacity='.2'/><path d='M16 4V3h-1V2H9v1H8v1H7v1h2V4h1V3h4v1h1v1h2V4zM6 5h1v1H6zM17 5h1v1h-1z' opacity='.5'/></g>" : ""; return string(abi.encodePacked( "<svg id='luchador", _tokenId.toString(), "' xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'>", styles(_tokenId, dna), "<g class='lucha-breathe'>", art.spirit[dna[0]].svg, art.cape[dna[1]].svg, "<path class='lucha-skin' d='M22 12v-1h-1v-1h-1V9h-1V5h-1V3h-1V2h-1V1h-1V0H9v1H8v1H7v1H6v2H5v4H4v1H3v1H2v1H1v8h4v-1h1v-2H5v-3h1v1h1v1h1v2h8v-2h1v-1h1v-1h1v3h-1v2h1v1h4v-8z'/>", art.torso[dna[2]].svg, art.arms[dna[3]].svg, capeShoulders, "<path class='lucha-base' d='M18 5V3h-1V2h-1V1h-1V0H9v1H8v1H7v1H6v2H5v5h1v2h1v1h1v1h1v1h6v-1h1v-1h1v-1h1v-2h1V5z'/>", "<g class='lucha-alt'>", art.mask[dna[4]].svg, "</g>", capeHood, "<path fill='#FFF' d='M9 6H6v3h4V6zM17 6h-3v3h4V6z'/><path class='lucha-eyes' d='M16 6h-2v3h3V6zM8 6H7v3h3V6H9z'/><path fill='#FFF' d='M7 6h1v1H7zM16 6h1v1h-1z' opacity='.4'/><path fill='#000' d='M15 7h1v1h-1zM8 7h1v1H8z'/>", "<path class='lucha-skin' d='M14 10H9v3h6v-3z'/>", "<path fill='#000' opacity='.9' d='M13 11h-3v1h4v-1z'/>", art.mouth[dna[5]].svg, "</g>", "<path class='lucha-skin' d='M16 23v-6H8v6H7v1h4v-4h2v4h4v-1z'/>", "<path class='lucha-base' d='M15 17H8v1h1v1h2v1h2v-1h2v-1h1v-1z'/>", art.bottoms[dna[6]].svg, "<path class='lucha-base' d='M9 21H8v2H7v1h4v-3h-1zM16 23v-2h-3v3h4v-1z'/>", art.boots[dna[7]].svg, "</svg>" )); } function styles(uint256 _tokenId, uint8[12] memory _dna) internal view returns (string memory) { return string(abi.encodePacked( "<style>#luchador", _tokenId.toString(), " .lucha-base { fill: #", art.baseColor[_dna[8]], "; } #luchador", _tokenId.toString(), " .lucha-alt { fill: #", art.altColor[_dna[9]], "; } #luchador", _tokenId.toString(), " .lucha-eyes { fill: #", art.eyeColor[_dna[10]], "; } #luchador", _tokenId.toString(), " .lucha-skin { fill: #", art.skinColor[_dna[11]], "; } #luchador", _tokenId.toString(), " .lucha-breathe { animation: 0.5s lucha-breathe infinite alternate ease-in-out; } @keyframes lucha-breathe { from { transform: translateY(0px); } to { transform: translateY(1%); } }</style>" )); } function metadata(uint256 _tokenId) public view returns (string memory) { require(_exists(_tokenId), "metadata: nonexistent token"); require(luchadores[_tokenId].dna != 0, "metadata: dna not yet generated"); uint8[12] memory dna = splitNumber(luchadores[_tokenId].dna); Item[8] memory artItems = [ art.spirit[dna[0]], art.cape[dna[1]], art.torso[dna[2]], art.arms[dna[3]], art.mask[dna[4]], art.mouth[dna[5]], art.bottoms[dna[6]], art.boots[dna[7]] ]; string memory attributes; string[8] memory traitType = ["Spirit", "Cape", "Torso", "Arms", "Mask", "Mouth", "Bottoms", "Boots"]; for (uint256 i = 0; i < artItems.length; i++) { if (artItems[i].name == "") continue; attributes = string(abi.encodePacked(attributes, bytes(attributes).length == 0 ? '{' : ', {', '"trait_type": "', traitType[i],'",', '"value": "', bytes12ToString(artItems[i].name), '"', '}' )); } return string(abi.encodePacked( '{', '"name": "Luchador #', _tokenId.toString(), '",', '"description": "Luchadores are randomly generated using Chainlink VRF and have 100% on-chain art and metadata - Only 10000 will ever exist!",', '"image_data": "', imageData(_tokenId), '",', '"external_url": "https://luchadores.io/luchador/', _tokenId.toString(), '",', '"attributes": [', attributes, ']', '}' )); } function splitNumber(uint256 _number) internal pure returns (uint8[12] memory) { uint8[12] memory numbers; for (uint256 i = 0; i < numbers.length; i++) { numbers[i] = uint8(_number % 10); _number /= 10; } return numbers; } function bytes12ToString(bytes12 _bytes12) internal pure returns (string memory) { uint8 i = 0; while(i < 12 && _bytes12[i] != 0) { i++; } bytes memory bytesArray = new bytes(i); for (i = 0; i < 12 && _bytes12[i] != 0; i++) { bytesArray[i] = _bytes12[i]; } return string(bytesArray); } function pauseSale() public onlyOwner { _pause(); } function unpauseSale() public onlyOwner { _unpause(); } function setLinkFee(uint256 _LinkFee) public onlyOwner { LinkFee = _LinkFee; } function setBaseURI(string memory _baseURI) public onlyOwner { _setBaseURI(_baseURI); } function tokenURI(uint256 _tokenId) public view virtual override returns (string memory) { require(_exists(_tokenId), "ERC721Metadata: URI query for nonexistent token"); string memory baseURI = baseURI(); return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, _tokenId.toString(), ".json")) : ''; } function withdraw() public onlyOwner { (bool success, ) = msg.sender.call{value: address(this).balance}(''); require(success, "Withdrawal failed"); } receive() external payable {} }
// SPDX-License-Identifier: MIT pragma solidity ^0.6.0; import "./vendor/SafeMathChainlink.sol"; import "./interfaces/LinkTokenInterface.sol"; import "./VRFRequestIDBase.sol"; /** **************************************************************************** * @notice Interface for contracts using VRF randomness * ***************************************************************************** * @dev PURPOSE * * @dev Reggie the Random Oracle (not his real job) wants to provide randomness * @dev to Vera the verifier in such a way that Vera can be sure he's not * @dev making his output up to suit himself. Reggie provides Vera a public key * @dev to which he knows the secret key. Each time Vera provides a seed to * @dev Reggie, he gives back a value which is computed completely * @dev deterministically from the seed and the secret key. * * @dev Reggie provides a proof by which Vera can verify that the output was * @dev correctly computed once Reggie tells it to her, but without that proof, * @dev the output is indistinguishable to her from a uniform random sample * @dev from the output space. * * @dev The purpose of this contract is to make it easy for unrelated contracts * @dev to talk to Vera the verifier about the work Reggie is doing, to provide * @dev simple access to a verifiable source of randomness. * ***************************************************************************** * @dev USAGE * * @dev Calling contracts must inherit from VRFConsumerBase, and can * @dev initialize VRFConsumerBase's attributes in their constructor as * @dev shown: * * @dev contract VRFConsumer { * @dev constuctor(<other arguments>, address _vrfCoordinator, address _link) * @dev VRFConsumerBase(_vrfCoordinator, _link) public { * @dev <initialization with other arguments goes here> * @dev } * @dev } * * @dev The oracle will have given you an ID for the VRF keypair they have * @dev committed to (let's call it keyHash), and have told you the minimum LINK * @dev price for VRF service. Make sure your contract has sufficient LINK, and * @dev call requestRandomness(keyHash, fee, seed), where seed is the input you * @dev want to generate randomness from. * * @dev Once the VRFCoordinator has received and validated the oracle's response * @dev to your request, it will call your contract's fulfillRandomness method. * * @dev The randomness argument to fulfillRandomness is the actual random value * @dev generated from your seed. * * @dev The requestId argument is generated from the keyHash and the seed by * @dev makeRequestId(keyHash, seed). If your contract could have concurrent * @dev requests open, you can use the requestId to track which seed is * @dev associated with which randomness. See VRFRequestIDBase.sol for more * @dev details. (See "SECURITY CONSIDERATIONS" for principles to keep in mind, * @dev if your contract could have multiple requests in flight simultaneously.) * * @dev Colliding `requestId`s are cryptographically impossible as long as seeds * @dev differ. (Which is critical to making unpredictable randomness! See the * @dev next section.) * * ***************************************************************************** * @dev SECURITY CONSIDERATIONS * * @dev A method with the ability to call your fulfillRandomness method directly * @dev could spoof a VRF response with any random value, so it's critical that * @dev it cannot be directly called by anything other than this base contract * @dev (specifically, by the VRFConsumerBase.rawFulfillRandomness method). * * @dev For your users to trust that your contract's random behavior is free * @dev from malicious interference, it's best if you can write it so that all * @dev behaviors implied by a VRF response are executed *during* your * @dev fulfillRandomness method. If your contract must store the response (or * @dev anything derived from it) and use it later, you must ensure that any * @dev user-significant behavior which depends on that stored value cannot be * @dev manipulated by a subsequent VRF request. * * @dev Similarly, both miners and the VRF oracle itself have some influence * @dev over the order in which VRF responses appear on the blockchain, so if * @dev your contract could have multiple VRF requests in flight simultaneously, * @dev you must ensure that the order in which the VRF responses arrive cannot * @dev be used to manipulate your contract's user-significant behavior. * * @dev Since the ultimate input to the VRF is mixed with the block hash of the * @dev block in which the request is made, user-provided seeds have no impact * @dev on its economic security properties. They are only included for API * @dev compatability with previous versions of this contract. * * @dev Since the block hash of the block which contains the requestRandomness * @dev call is mixed into the input to the VRF *last*, a sufficiently powerful * @dev miner could, in principle, fork the blockchain to evict the block * @dev containing the request, forcing the request to be included in a * @dev different block with a different hash, and therefore a different input * @dev to the VRF. However, such an attack would incur a substantial economic * @dev cost. This cost scales with the number of blocks the VRF oracle waits * @dev until it calls responds to a request. */ abstract contract VRFConsumerBase is VRFRequestIDBase { using SafeMathChainlink for uint256; /** * @notice fulfillRandomness handles the VRF response. Your contract must * @notice implement it. See "SECURITY CONSIDERATIONS" above for important * @notice principles to keep in mind when implementing your fulfillRandomness * @notice method. * * @dev VRFConsumerBase expects its subcontracts to have a method with this * @dev signature, and will call it once it has verified the proof * @dev associated with the randomness. (It is triggered via a call to * @dev rawFulfillRandomness, below.) * * @param requestId The Id initially returned by requestRandomness * @param randomness the VRF output */ function fulfillRandomness(bytes32 requestId, uint256 randomness) internal virtual; /** * @notice requestRandomness initiates a request for VRF output given _seed * * @dev The fulfillRandomness method receives the output, once it's provided * @dev by the Oracle, and verified by the vrfCoordinator. * * @dev The _keyHash must already be registered with the VRFCoordinator, and * @dev the _fee must exceed the fee specified during registration of the * @dev _keyHash. * * @dev The _seed parameter is vestigial, and is kept only for API * @dev compatibility with older versions. It can't *hurt* to mix in some of * @dev your own randomness, here, but it's not necessary because the VRF * @dev oracle will mix the hash of the block containing your request into the * @dev VRF seed it ultimately uses. * * @param _keyHash ID of public key against which randomness is generated * @param _fee The amount of LINK to send with the request * @param _seed seed mixed into the input of the VRF. * * @return requestId unique ID for this request * * @dev The returned requestId can be used to distinguish responses to * @dev concurrent requests. It is passed as the first argument to * @dev fulfillRandomness. */ function requestRandomness(bytes32 _keyHash, uint256 _fee, uint256 _seed) internal returns (bytes32 requestId) { LINK.transferAndCall(vrfCoordinator, _fee, abi.encode(_keyHash, _seed)); // This is the seed passed to VRFCoordinator. The oracle will mix this with // the hash of the block containing this request to obtain the seed/input // which is finally passed to the VRF cryptographic machinery. uint256 vRFSeed = makeVRFInputSeed(_keyHash, _seed, address(this), nonces[_keyHash]); // nonces[_keyHash] must stay in sync with // VRFCoordinator.nonces[_keyHash][this], which was incremented by the above // successful LINK.transferAndCall (in VRFCoordinator.randomnessRequest). // This provides protection against the user repeating their input seed, // which would result in a predictable/duplicate output, if multiple such // requests appeared in the same block. nonces[_keyHash] = nonces[_keyHash].add(1); return makeRequestId(_keyHash, vRFSeed); } LinkTokenInterface immutable internal LINK; address immutable private vrfCoordinator; // Nonces for each VRF key from which randomness has been requested. // // Must stay in sync with VRFCoordinator[_keyHash][this] mapping(bytes32 /* keyHash */ => uint256 /* nonce */) private nonces; /** * @param _vrfCoordinator address of VRFCoordinator contract * @param _link address of LINK token contract * * @dev https://docs.chain.link/docs/link-token-contracts */ constructor(address _vrfCoordinator, address _link) public { vrfCoordinator = _vrfCoordinator; LINK = LinkTokenInterface(_link); } // rawFulfillRandomness is called by VRFCoordinator when it receives a valid VRF // proof. rawFulfillRandomness then calls fulfillRandomness, after validating // the origin of the call function rawFulfillRandomness(bytes32 requestId, uint256 randomness) external { require(msg.sender == vrfCoordinator, "Only VRFCoordinator can fulfill"); fulfillRandomness(requestId, randomness); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.6.0; contract VRFRequestIDBase { /** * @notice returns the seed which is actually input to the VRF coordinator * * @dev To prevent repetition of VRF output due to repetition of the * @dev user-supplied seed, that seed is combined in a hash with the * @dev user-specific nonce, and the address of the consuming contract. The * @dev risk of repetition is mostly mitigated by inclusion of a blockhash in * @dev the final seed, but the nonce does protect against repetition in * @dev requests which are included in a single block. * * @param _userSeed VRF seed input provided by user * @param _requester Address of the requesting contract * @param _nonce User-specific nonce at the time of the request */ function makeVRFInputSeed(bytes32 _keyHash, uint256 _userSeed, address _requester, uint256 _nonce) internal pure returns (uint256) { return uint256(keccak256(abi.encode(_keyHash, _userSeed, _requester, _nonce))); } /** * @notice Returns the id for this request * @param _keyHash The serviceAgreement ID to be used for this request * @param _vRFInputSeed The seed to be passed directly to the VRF * @return The id for this request * * @dev Note that _vRFInputSeed is not the seed passed by the consuming * @dev contract, but the one generated by makeVRFInputSeed */ function makeRequestId( bytes32 _keyHash, uint256 _vRFInputSeed) internal pure returns (bytes32) { return keccak256(abi.encodePacked(_keyHash, _vRFInputSeed)); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.6.0; interface LinkTokenInterface { function allowance(address owner, address spender) external view returns (uint256 remaining); function approve(address spender, uint256 value) external returns (bool success); function balanceOf(address owner) external view returns (uint256 balance); function decimals() external view returns (uint8 decimalPlaces); function decreaseApproval(address spender, uint256 addedValue) external returns (bool success); function increaseApproval(address spender, uint256 subtractedValue) external; function name() external view returns (string memory tokenName); function symbol() external view returns (string memory tokenSymbol); function totalSupply() external view returns (uint256 totalTokensIssued); function transfer(address to, uint256 value) external returns (bool success); function transferAndCall(address to, uint256 value, bytes calldata data) external returns (bool success); function transferFrom(address from, address to, uint256 value) external returns (bool success); }
// SPDX-License-Identifier: MIT pragma solidity ^0.6.0; /** * @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 SafeMathChainlink { /** * @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"); uint256 c = a - b; return c; } /** * @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) { // 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-solidity/pull/522 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. Reverts 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) { // Solidity only automatically asserts when dividing by 0 require(b > 0, "SafeMath: division by zero"); uint256 c = a / b; // assert(a == b * c + a % b); // There is no case in which this doesn't hold return c; } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * Reverts 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; } }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.0 <0.8.0; import "../utils/Context.sol"; /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * By default, the owner account will be the one that deploys the contract. This * can later be changed with {transferOwnership}. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ abstract contract Ownable is Context { address private _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the deployer as the initial owner. */ constructor () 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; } }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.0 <0.8.0; import "./IERC165.sol"; /** * @dev Implementation of the {IERC165} interface. * * Contracts may inherit from this and call {_registerInterface} to declare * their support of an interface. */ abstract contract ERC165 is IERC165 { /* * bytes4(keccak256('supportsInterface(bytes4)')) == 0x01ffc9a7 */ bytes4 private constant _INTERFACE_ID_ERC165 = 0x01ffc9a7; /** * @dev Mapping of interface ids to whether or not it's supported. */ mapping(bytes4 => bool) private _supportedInterfaces; constructor () internal { // Derived contracts need only register support for their own interfaces, // we register support for ERC165 itself here _registerInterface(_INTERFACE_ID_ERC165); } /** * @dev See {IERC165-supportsInterface}. * * Time complexity O(1), guaranteed to always use less than 30 000 gas. */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { return _supportedInterfaces[interfaceId]; } /** * @dev Registers the contract as an implementer of the interface defined by * `interfaceId`. Support of the actual ERC165 interface is automatic and * registering its interface id is not required. * * See {IERC165-supportsInterface}. * * Requirements: * * - `interfaceId` cannot be the ERC165 invalid interface (`0xffffffff`). */ function _registerInterface(bytes4 interfaceId) internal virtual { require(interfaceId != 0xffffffff, "ERC165: invalid interface id"); _supportedInterfaces[interfaceId] = true; } }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.0 <0.8.0; /** * @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); }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.0 <0.8.0; /** * @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.0 <0.8.0; import "../../utils/Context.sol"; import "./IERC721.sol"; import "./IERC721Metadata.sol"; import "./IERC721Enumerable.sol"; import "./IERC721Receiver.sol"; import "../../introspection/ERC165.sol"; import "../../math/SafeMath.sol"; import "../../utils/Address.sol"; import "../../utils/EnumerableSet.sol"; import "../../utils/EnumerableMap.sol"; import "../../utils/Strings.sol"; /** * @title ERC721 Non-Fungible Token Standard basic implementation * @dev see https://eips.ethereum.org/EIPS/eip-721 */ contract ERC721 is Context, ERC165, IERC721, IERC721Metadata, IERC721Enumerable { using SafeMath for uint256; using Address for address; using EnumerableSet for EnumerableSet.UintSet; using EnumerableMap for EnumerableMap.UintToAddressMap; using Strings for uint256; // Equals to `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))` // which can be also obtained as `IERC721Receiver(0).onERC721Received.selector` bytes4 private constant _ERC721_RECEIVED = 0x150b7a02; // Mapping from holder address to their (enumerable) set of owned tokens mapping (address => EnumerableSet.UintSet) private _holderTokens; // Enumerable mapping from token ids to their owners EnumerableMap.UintToAddressMap private _tokenOwners; // Mapping from token ID to approved address mapping (uint256 => address) private _tokenApprovals; // Mapping from owner to operator approvals mapping (address => mapping (address => bool)) private _operatorApprovals; // Token name string private _name; // Token symbol string private _symbol; // Optional mapping for token URIs mapping (uint256 => string) private _tokenURIs; // Base URI string private _baseURI; /* * bytes4(keccak256('balanceOf(address)')) == 0x70a08231 * bytes4(keccak256('ownerOf(uint256)')) == 0x6352211e * bytes4(keccak256('approve(address,uint256)')) == 0x095ea7b3 * bytes4(keccak256('getApproved(uint256)')) == 0x081812fc * bytes4(keccak256('setApprovalForAll(address,bool)')) == 0xa22cb465 * bytes4(keccak256('isApprovedForAll(address,address)')) == 0xe985e9c5 * bytes4(keccak256('transferFrom(address,address,uint256)')) == 0x23b872dd * bytes4(keccak256('safeTransferFrom(address,address,uint256)')) == 0x42842e0e * bytes4(keccak256('safeTransferFrom(address,address,uint256,bytes)')) == 0xb88d4fde * * => 0x70a08231 ^ 0x6352211e ^ 0x095ea7b3 ^ 0x081812fc ^ * 0xa22cb465 ^ 0xe985e9c5 ^ 0x23b872dd ^ 0x42842e0e ^ 0xb88d4fde == 0x80ac58cd */ bytes4 private constant _INTERFACE_ID_ERC721 = 0x80ac58cd; /* * bytes4(keccak256('name()')) == 0x06fdde03 * bytes4(keccak256('symbol()')) == 0x95d89b41 * bytes4(keccak256('tokenURI(uint256)')) == 0xc87b56dd * * => 0x06fdde03 ^ 0x95d89b41 ^ 0xc87b56dd == 0x5b5e139f */ bytes4 private constant _INTERFACE_ID_ERC721_METADATA = 0x5b5e139f; /* * bytes4(keccak256('totalSupply()')) == 0x18160ddd * bytes4(keccak256('tokenOfOwnerByIndex(address,uint256)')) == 0x2f745c59 * bytes4(keccak256('tokenByIndex(uint256)')) == 0x4f6ccce7 * * => 0x18160ddd ^ 0x2f745c59 ^ 0x4f6ccce7 == 0x780e9d63 */ bytes4 private constant _INTERFACE_ID_ERC721_ENUMERABLE = 0x780e9d63; /** * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection. */ constructor (string memory name_, string memory symbol_) public { _name = name_; _symbol = symbol_; // register the supported interfaces to conform to ERC721 via ERC165 _registerInterface(_INTERFACE_ID_ERC721); _registerInterface(_INTERFACE_ID_ERC721_METADATA); _registerInterface(_INTERFACE_ID_ERC721_ENUMERABLE); } /** * @dev See {IERC721-balanceOf}. */ function balanceOf(address owner) public view virtual override returns (uint256) { require(owner != address(0), "ERC721: balance query for the zero address"); return _holderTokens[owner].length(); } /** * @dev See {IERC721-ownerOf}. */ function ownerOf(uint256 tokenId) public view virtual override returns (address) { return _tokenOwners.get(tokenId, "ERC721: owner query for nonexistent token"); } /** * @dev See {IERC721Metadata-name}. */ function name() public view virtual override returns (string memory) { return _name; } /** * @dev See {IERC721Metadata-symbol}. */ function symbol() public view virtual override returns (string memory) { return _symbol; } /** * @dev See {IERC721Metadata-tokenURI}. */ function tokenURI(uint256 tokenId) public view virtual override returns (string memory) { require(_exists(tokenId), "ERC721Metadata: URI query for nonexistent token"); string memory _tokenURI = _tokenURIs[tokenId]; string memory base = baseURI(); // If there is no base URI, return the token URI. if (bytes(base).length == 0) { return _tokenURI; } // If both are set, concatenate the baseURI and tokenURI (via abi.encodePacked). if (bytes(_tokenURI).length > 0) { return string(abi.encodePacked(base, _tokenURI)); } // If there is a baseURI but no tokenURI, concatenate the tokenID to the baseURI. return string(abi.encodePacked(base, tokenId.toString())); } /** * @dev Returns the base URI set via {_setBaseURI}. This will be * automatically added as a prefix in {tokenURI} to each token's URI, or * to the token ID if no specific URI is set for that token ID. */ function baseURI() public view virtual returns (string memory) { return _baseURI; } /** * @dev See {IERC721Enumerable-tokenOfOwnerByIndex}. */ function tokenOfOwnerByIndex(address owner, uint256 index) public view virtual override returns (uint256) { return _holderTokens[owner].at(index); } /** * @dev See {IERC721Enumerable-totalSupply}. */ function totalSupply() public view virtual override returns (uint256) { // _tokenOwners are indexed by tokenIds, so .length() returns the number of tokenIds return _tokenOwners.length(); } /** * @dev See {IERC721Enumerable-tokenByIndex}. */ function tokenByIndex(uint256 index) public view virtual override returns (uint256) { (uint256 tokenId, ) = _tokenOwners.at(index); return tokenId; } /** * @dev See {IERC721-approve}. */ function approve(address to, uint256 tokenId) public virtual override { address owner = ERC721.ownerOf(tokenId); require(to != owner, "ERC721: approval to current owner"); require(_msgSender() == owner || ERC721.isApprovedForAll(owner, _msgSender()), "ERC721: approve caller is not owner nor approved for all" ); _approve(to, tokenId); } /** * @dev See {IERC721-getApproved}. */ function getApproved(uint256 tokenId) public view virtual override returns (address) { require(_exists(tokenId), "ERC721: approved query for nonexistent token"); return _tokenApprovals[tokenId]; } /** * @dev See {IERC721-setApprovalForAll}. */ function setApprovalForAll(address operator, bool approved) public virtual override { require(operator != _msgSender(), "ERC721: approve to caller"); _operatorApprovals[_msgSender()][operator] = approved; emit ApprovalForAll(_msgSender(), operator, approved); } /** * @dev See {IERC721-isApprovedForAll}. */ function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) { return _operatorApprovals[owner][operator]; } /** * @dev See {IERC721-transferFrom}. */ function transferFrom(address from, address to, uint256 tokenId) public virtual override { //solhint-disable-next-line max-line-length require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: transfer caller is not owner nor approved"); _transfer(from, to, tokenId); } /** * @dev See {IERC721-safeTransferFrom}. */ function safeTransferFrom(address from, address to, uint256 tokenId) public virtual override { safeTransferFrom(from, to, tokenId, ""); } /** * @dev See {IERC721-safeTransferFrom}. */ function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory _data) public virtual override { require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: transfer caller is not owner nor approved"); _safeTransfer(from, to, tokenId, _data); } /** * @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. * * `_data` is additional data, it has no specified format and it is sent in call to `to`. * * This internal function is equivalent to {safeTransferFrom}, and can be used to e.g. * implement alternative mechanisms to perform token transfer, such as signature-based. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function _safeTransfer(address from, address to, uint256 tokenId, bytes memory _data) internal virtual { _transfer(from, to, tokenId); require(_checkOnERC721Received(from, to, tokenId, _data), "ERC721: transfer to non ERC721Receiver implementer"); } /** * @dev Returns whether `tokenId` exists. * * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}. * * Tokens start existing when they are minted (`_mint`), * and stop existing when they are burned (`_burn`). */ function _exists(uint256 tokenId) internal view virtual returns (bool) { return _tokenOwners.contains(tokenId); } /** * @dev Returns whether `spender` is allowed to manage `tokenId`. * * Requirements: * * - `tokenId` must exist. */ function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) { require(_exists(tokenId), "ERC721: operator query for nonexistent token"); address owner = ERC721.ownerOf(tokenId); return (spender == owner || getApproved(tokenId) == spender || ERC721.isApprovedForAll(owner, spender)); } /** * @dev Safely mints `tokenId` and transfers it to `to`. * * Requirements: d* * - `tokenId` must not exist. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function _safeMint(address to, uint256 tokenId) internal virtual { _safeMint(to, tokenId, ""); } /** * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is * forwarded in {IERC721Receiver-onERC721Received} to contract recipients. */ function _safeMint(address to, uint256 tokenId, bytes memory _data) internal virtual { _mint(to, tokenId); require(_checkOnERC721Received(address(0), to, tokenId, _data), "ERC721: transfer to non ERC721Receiver implementer"); } /** * @dev Mints `tokenId` and transfers it to `to`. * * WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible * * Requirements: * * - `tokenId` must not exist. * - `to` cannot be the zero address. * * Emits a {Transfer} event. */ function _mint(address to, uint256 tokenId) internal virtual { require(to != address(0), "ERC721: mint to the zero address"); require(!_exists(tokenId), "ERC721: token already minted"); _beforeTokenTransfer(address(0), to, tokenId); _holderTokens[to].add(tokenId); _tokenOwners.set(tokenId, to); emit Transfer(address(0), to, tokenId); } /** * @dev Destroys `tokenId`. * The approval is cleared when the token is burned. * * Requirements: * * - `tokenId` must exist. * * Emits a {Transfer} event. */ function _burn(uint256 tokenId) internal virtual { address owner = ERC721.ownerOf(tokenId); // internal owner _beforeTokenTransfer(owner, address(0), tokenId); // Clear approvals _approve(address(0), tokenId); // Clear metadata (if any) if (bytes(_tokenURIs[tokenId]).length != 0) { delete _tokenURIs[tokenId]; } _holderTokens[owner].remove(tokenId); _tokenOwners.remove(tokenId); emit Transfer(owner, address(0), tokenId); } /** * @dev Transfers `tokenId` from `from` to `to`. * As opposed to {transferFrom}, this imposes no restrictions on msg.sender. * * Requirements: * * - `to` cannot be the zero address. * - `tokenId` token must be owned by `from`. * * Emits a {Transfer} event. */ function _transfer(address from, address to, uint256 tokenId) internal virtual { require(ERC721.ownerOf(tokenId) == from, "ERC721: transfer of token that is not own"); // internal owner require(to != address(0), "ERC721: transfer to the zero address"); _beforeTokenTransfer(from, to, tokenId); // Clear approvals from the previous owner _approve(address(0), tokenId); _holderTokens[from].remove(tokenId); _holderTokens[to].add(tokenId); _tokenOwners.set(tokenId, to); emit Transfer(from, to, tokenId); } /** * @dev Sets `_tokenURI` as the tokenURI of `tokenId`. * * Requirements: * * - `tokenId` must exist. */ function _setTokenURI(uint256 tokenId, string memory _tokenURI) internal virtual { require(_exists(tokenId), "ERC721Metadata: URI set of nonexistent token"); _tokenURIs[tokenId] = _tokenURI; } /** * @dev Internal function to set the base URI for all token IDs. It is * automatically added as a prefix to the value returned in {tokenURI}, * or to the token ID if {tokenURI} is empty. */ function _setBaseURI(string memory baseURI_) internal virtual { _baseURI = baseURI_; } /** * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address. * The call is not executed if the target address is not a contract. * * @param from address representing the previous owner of the given token ID * @param to target address that will receive the tokens * @param tokenId uint256 ID of the token to be transferred * @param _data bytes optional data to send along with the call * @return bool whether the call correctly returned the expected magic value */ function _checkOnERC721Received(address from, address to, uint256 tokenId, bytes memory _data) private returns (bool) { if (!to.isContract()) { return true; } bytes memory returndata = to.functionCall(abi.encodeWithSelector( IERC721Receiver(to).onERC721Received.selector, _msgSender(), from, tokenId, _data ), "ERC721: transfer to non ERC721Receiver implementer"); bytes4 retval = abi.decode(returndata, (bytes4)); return (retval == _ERC721_RECEIVED); } /** * @dev Approve `to` to operate on `tokenId` * * Emits an {Approval} event. */ function _approve(address to, uint256 tokenId) internal virtual { _tokenApprovals[tokenId] = to; emit Approval(ERC721.ownerOf(tokenId), to, tokenId); // internal owner } /** * @dev Hook that is called before any token transfer. This includes minting * and burning. * * Calling conditions: * * - When `from` and `to` are both non-zero, ``from``'s `tokenId` will be * transferred to `to`. * - When `from` is zero, `tokenId` will be minted for `to`. * - When `to` is zero, ``from``'s `tokenId` will be burned. * - `from` cannot be the zero address. * - `to` cannot be the zero address. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _beforeTokenTransfer(address from, address to, uint256 tokenId) internal virtual { } }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.0 <0.8.0; import "./ERC721.sol"; import "../../utils/Pausable.sol"; /** * @dev ERC721 token with pausable token transfers, minting and burning. * * Useful for scenarios such as preventing trades until the end of an evaluation * period, or having an emergency switch for freezing all token transfers in the * event of a large bug. */ abstract contract ERC721Pausable is ERC721, Pausable { /** * @dev See {ERC721-_beforeTokenTransfer}. * * Requirements: * * - the contract must not be paused. */ function _beforeTokenTransfer(address from, address to, uint256 tokenId) internal virtual override { super._beforeTokenTransfer(from, to, tokenId); require(!paused(), "ERC721Pausable: token transfer while paused"); } }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.2 <0.8.0; import "../../introspection/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.2 <0.8.0; import "./IERC721.sol"; /** * @title ERC-721 Non-Fungible Token Standard, optional enumeration extension * @dev See https://eips.ethereum.org/EIPS/eip-721 */ interface IERC721Enumerable is IERC721 { /** * @dev Returns the total amount of tokens stored by the contract. */ function totalSupply() external view returns (uint256); /** * @dev Returns a token ID owned by `owner` at a given `index` of its token list. * Use along with {balanceOf} to enumerate all of ``owner``'s tokens. */ function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256 tokenId); /** * @dev Returns a token ID at a given `index` of all the tokens stored by the contract. * Use along with {totalSupply} to enumerate all tokens. */ function tokenByIndex(uint256 index) external view returns (uint256); }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.2 <0.8.0; import "./IERC721.sol"; /** * @title ERC-721 Non-Fungible Token Standard, optional metadata extension * @dev See https://eips.ethereum.org/EIPS/eip-721 */ interface IERC721Metadata is IERC721 { /** * @dev Returns the token collection name. */ function name() external view returns (string memory); /** * @dev Returns the token collection symbol. */ function symbol() external view returns (string memory); /** * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token. */ function tokenURI(uint256 tokenId) external view returns (string memory); }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.0 <0.8.0; /** * @title ERC721 token receiver interface * @dev Interface for any contract that wants to support safeTransfers * from ERC721 asset contracts. */ interface IERC721Receiver { /** * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom} * by `operator` from `from`, this function is called. * * It must return its Solidity selector to confirm the token transfer. * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted. * * The selector can be obtained in Solidity with `IERC721.onERC721Received.selector`. */ function onERC721Received(address operator, address from, uint256 tokenId, bytes calldata data) external returns (bytes4); }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.2 <0.8.0; /** * @dev Collection of functions related to the address type */ library Address { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize, which returns 0 for contracts in // construction, since the code is only stored at the end of the // constructor execution. uint256 size; // solhint-disable-next-line no-inline-assembly assembly { size := extcodesize(account) } return size > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); // solhint-disable-next-line avoid-low-level-calls, avoid-call-value (bool success, ) = recipient.call{ value: amount }(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain`call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCall(target, data, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); require(isContract(target), "Address: call to non-contract"); // solhint-disable-next-line avoid-low-level-calls (bool success, bytes memory returndata) = target.call{ value: value }(data); return _verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) { require(isContract(target), "Address: static call to non-contract"); // solhint-disable-next-line avoid-low-level-calls (bool success, bytes memory returndata) = target.staticcall(data); return _verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { return functionDelegateCall(target, data, "Address: low-level delegate call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) { require(isContract(target), "Address: delegate call to non-contract"); // solhint-disable-next-line avoid-low-level-calls (bool success, bytes memory returndata) = target.delegatecall(data); return _verifyCallResult(success, returndata, errorMessage); } function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) { if (success) { return returndata; } else { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly // solhint-disable-next-line no-inline-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.0 <0.8.0; /* * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with 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.0 <0.8.0; import "../math/SafeMath.sol"; /** * @title Counters * @author Matt Condon (@shrugs) * @dev Provides counters that can only be incremented or decremented by one. This can be used e.g. to track the number * of elements in a mapping, issuing ERC721 ids, or counting request ids. * * Include with `using Counters for Counters.Counter;` * Since it is not possible to overflow a 256 bit integer with increments of one, `increment` can skip the {SafeMath} * overflow check, thereby saving gas. This does assume however correct usage, in that the underlying `_value` is never * directly accessed. */ library Counters { using SafeMath for uint256; struct Counter { // This variable should never be directly accessed by users of the library: interactions must be restricted to // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add // this feature: see https://github.com/ethereum/solidity/issues/4637 uint256 _value; // default: 0 } function current(Counter storage counter) internal view returns (uint256) { return counter._value; } function increment(Counter storage counter) internal { // The {SafeMath} overflow check can be skipped here, see the comment at the top counter._value += 1; } function decrement(Counter storage counter) internal { counter._value = counter._value.sub(1); } }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.0 <0.8.0; /** * @dev Library for managing an enumerable variant of Solidity's * https://solidity.readthedocs.io/en/latest/types.html#mapping-types[`mapping`] * type. * * Maps have the following properties: * * - Entries are added, removed, and checked for existence in constant time * (O(1)). * - Entries are enumerated in O(n). No guarantees are made on the ordering. * * ``` * contract Example { * // Add the library methods * using EnumerableMap for EnumerableMap.UintToAddressMap; * * // Declare a set state variable * EnumerableMap.UintToAddressMap private myMap; * } * ``` * * As of v3.0.0, only maps of type `uint256 -> address` (`UintToAddressMap`) are * supported. */ library EnumerableMap { // To implement this library for multiple types with as little code // repetition as possible, we write it in terms of a generic Map type with // bytes32 keys and values. // The Map implementation uses private functions, and user-facing // implementations (such as Uint256ToAddressMap) are just wrappers around // the underlying Map. // This means that we can only create new EnumerableMaps for types that fit // in bytes32. struct MapEntry { bytes32 _key; bytes32 _value; } struct Map { // Storage of map keys and values MapEntry[] _entries; // Position of the entry defined by a key in the `entries` array, plus 1 // because index 0 means a key is not in the map. mapping (bytes32 => uint256) _indexes; } /** * @dev Adds a key-value pair to a map, or updates the value for an existing * key. O(1). * * Returns true if the key was added to the map, that is if it was not * already present. */ function _set(Map storage map, bytes32 key, bytes32 value) private returns (bool) { // We read and store the key's index to prevent multiple reads from the same storage slot uint256 keyIndex = map._indexes[key]; if (keyIndex == 0) { // Equivalent to !contains(map, key) map._entries.push(MapEntry({ _key: key, _value: value })); // The entry is stored at length-1, but we add 1 to all indexes // and use 0 as a sentinel value map._indexes[key] = map._entries.length; return true; } else { map._entries[keyIndex - 1]._value = value; return false; } } /** * @dev Removes a key-value pair from a map. O(1). * * Returns true if the key was removed from the map, that is if it was present. */ function _remove(Map storage map, bytes32 key) private returns (bool) { // We read and store the key's index to prevent multiple reads from the same storage slot uint256 keyIndex = map._indexes[key]; if (keyIndex != 0) { // Equivalent to contains(map, key) // To delete a key-value pair from the _entries array in O(1), we swap the entry to delete with the last one // in the array, and then remove the last entry (sometimes called as 'swap and pop'). // This modifies the order of the array, as noted in {at}. uint256 toDeleteIndex = keyIndex - 1; uint256 lastIndex = map._entries.length - 1; // When the entry to delete is the last one, the swap operation is unnecessary. However, since this occurs // so rarely, we still do the swap anyway to avoid the gas cost of adding an 'if' statement. MapEntry storage lastEntry = map._entries[lastIndex]; // Move the last entry to the index where the entry to delete is map._entries[toDeleteIndex] = lastEntry; // Update the index for the moved entry map._indexes[lastEntry._key] = toDeleteIndex + 1; // All indexes are 1-based // Delete the slot where the moved entry was stored map._entries.pop(); // Delete the index for the deleted slot delete map._indexes[key]; return true; } else { return false; } } /** * @dev Returns true if the key is in the map. O(1). */ function _contains(Map storage map, bytes32 key) private view returns (bool) { return map._indexes[key] != 0; } /** * @dev Returns the number of key-value pairs in the map. O(1). */ function _length(Map storage map) private view returns (uint256) { return map._entries.length; } /** * @dev Returns the key-value pair stored at position `index` in the map. O(1). * * Note that there are no guarantees on the ordering of entries inside the * array, and it may change when more entries are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function _at(Map storage map, uint256 index) private view returns (bytes32, bytes32) { require(map._entries.length > index, "EnumerableMap: index out of bounds"); MapEntry storage entry = map._entries[index]; return (entry._key, entry._value); } /** * @dev Tries to returns the value associated with `key`. O(1). * Does not revert if `key` is not in the map. */ function _tryGet(Map storage map, bytes32 key) private view returns (bool, bytes32) { uint256 keyIndex = map._indexes[key]; if (keyIndex == 0) return (false, 0); // Equivalent to contains(map, key) return (true, map._entries[keyIndex - 1]._value); // All indexes are 1-based } /** * @dev Returns the value associated with `key`. O(1). * * Requirements: * * - `key` must be in the map. */ function _get(Map storage map, bytes32 key) private view returns (bytes32) { uint256 keyIndex = map._indexes[key]; require(keyIndex != 0, "EnumerableMap: nonexistent key"); // Equivalent to contains(map, key) return map._entries[keyIndex - 1]._value; // All indexes are 1-based } /** * @dev Same as {_get}, with a custom error message when `key` is not in the map. * * CAUTION: This function is deprecated because it requires allocating memory for the error * message unnecessarily. For custom revert reasons use {_tryGet}. */ function _get(Map storage map, bytes32 key, string memory errorMessage) private view returns (bytes32) { uint256 keyIndex = map._indexes[key]; require(keyIndex != 0, errorMessage); // Equivalent to contains(map, key) return map._entries[keyIndex - 1]._value; // All indexes are 1-based } // UintToAddressMap struct UintToAddressMap { Map _inner; } /** * @dev Adds a key-value pair to a map, or updates the value for an existing * key. O(1). * * Returns true if the key was added to the map, that is if it was not * already present. */ function set(UintToAddressMap storage map, uint256 key, address value) internal returns (bool) { return _set(map._inner, bytes32(key), bytes32(uint256(uint160(value)))); } /** * @dev Removes a value from a set. O(1). * * Returns true if the key was removed from the map, that is if it was present. */ function remove(UintToAddressMap storage map, uint256 key) internal returns (bool) { return _remove(map._inner, bytes32(key)); } /** * @dev Returns true if the key is in the map. O(1). */ function contains(UintToAddressMap storage map, uint256 key) internal view returns (bool) { return _contains(map._inner, bytes32(key)); } /** * @dev Returns the number of elements in the map. O(1). */ function length(UintToAddressMap storage map) internal view returns (uint256) { return _length(map._inner); } /** * @dev Returns the element stored at position `index` in the set. O(1). * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(UintToAddressMap storage map, uint256 index) internal view returns (uint256, address) { (bytes32 key, bytes32 value) = _at(map._inner, index); return (uint256(key), address(uint160(uint256(value)))); } /** * @dev Tries to returns the value associated with `key`. O(1). * Does not revert if `key` is not in the map. * * _Available since v3.4._ */ function tryGet(UintToAddressMap storage map, uint256 key) internal view returns (bool, address) { (bool success, bytes32 value) = _tryGet(map._inner, bytes32(key)); return (success, address(uint160(uint256(value)))); } /** * @dev Returns the value associated with `key`. O(1). * * Requirements: * * - `key` must be in the map. */ function get(UintToAddressMap storage map, uint256 key) internal view returns (address) { return address(uint160(uint256(_get(map._inner, bytes32(key))))); } /** * @dev Same as {get}, with a custom error message when `key` is not in the map. * * CAUTION: This function is deprecated because it requires allocating memory for the error * message unnecessarily. For custom revert reasons use {tryGet}. */ function get(UintToAddressMap storage map, uint256 key, string memory errorMessage) internal view returns (address) { return address(uint160(uint256(_get(map._inner, bytes32(key), errorMessage)))); } }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.0 <0.8.0; /** * @dev Library for managing * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive * types. * * Sets have the following properties: * * - Elements are added, removed, and checked for existence in constant time * (O(1)). * - Elements are enumerated in O(n). No guarantees are made on the ordering. * * ``` * contract Example { * // Add the library methods * using EnumerableSet for EnumerableSet.AddressSet; * * // Declare a set state variable * EnumerableSet.AddressSet private mySet; * } * ``` * * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`) * and `uint256` (`UintSet`) are supported. */ library EnumerableSet { // To implement this library for multiple types with as little code // repetition as possible, we write it in terms of a generic Set type with // bytes32 values. // The Set implementation uses private functions, and user-facing // implementations (such as AddressSet) are just wrappers around the // underlying Set. // This means that we can only create new EnumerableSets for types that fit // in bytes32. struct Set { // Storage of set values bytes32[] _values; // Position of the value in the `values` array, plus 1 because index 0 // means a value is not in the set. mapping (bytes32 => uint256) _indexes; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function _add(Set storage set, bytes32 value) private returns (bool) { if (!_contains(set, value)) { set._values.push(value); // The value is stored at length-1, but we add 1 to all indexes // and use 0 as a sentinel value set._indexes[value] = set._values.length; return true; } else { return false; } } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function _remove(Set storage set, bytes32 value) private returns (bool) { // We read and store the value's index to prevent multiple reads from the same storage slot uint256 valueIndex = set._indexes[value]; if (valueIndex != 0) { // Equivalent to contains(set, value) // To delete an element from the _values array in O(1), we swap the element to delete with the last one in // the array, and then remove the last element (sometimes called as 'swap and pop'). // This modifies the order of the array, as noted in {at}. uint256 toDeleteIndex = valueIndex - 1; uint256 lastIndex = set._values.length - 1; // When the value to delete is the last one, the swap operation is unnecessary. However, since this occurs // so rarely, we still do the swap anyway to avoid the gas cost of adding an 'if' statement. bytes32 lastvalue = set._values[lastIndex]; // Move the last value to the index where the value to delete is set._values[toDeleteIndex] = lastvalue; // Update the index for the moved value set._indexes[lastvalue] = toDeleteIndex + 1; // All indexes are 1-based // Delete the slot where the moved value was stored set._values.pop(); // Delete the index for the deleted slot delete set._indexes[value]; return true; } else { return false; } } /** * @dev Returns true if the value is in the set. O(1). */ function _contains(Set storage set, bytes32 value) private view returns (bool) { return set._indexes[value] != 0; } /** * @dev Returns the number of values on the set. O(1). */ function _length(Set storage set) private view returns (uint256) { return set._values.length; } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function _at(Set storage set, uint256 index) private view returns (bytes32) { require(set._values.length > index, "EnumerableSet: index out of bounds"); return set._values[index]; } // Bytes32Set struct Bytes32Set { Set _inner; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function add(Bytes32Set storage set, bytes32 value) internal returns (bool) { return _add(set._inner, value); } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) { return _remove(set._inner, value); } /** * @dev Returns true if the value is in the set. O(1). */ function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) { return _contains(set._inner, value); } /** * @dev Returns the number of values in the set. O(1). */ function length(Bytes32Set storage set) internal view returns (uint256) { return _length(set._inner); } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) { return _at(set._inner, index); } // AddressSet struct AddressSet { Set _inner; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function add(AddressSet storage set, address value) internal returns (bool) { return _add(set._inner, bytes32(uint256(uint160(value)))); } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function remove(AddressSet storage set, address value) internal returns (bool) { return _remove(set._inner, bytes32(uint256(uint160(value)))); } /** * @dev Returns true if the value is in the set. O(1). */ function contains(AddressSet storage set, address value) internal view returns (bool) { return _contains(set._inner, bytes32(uint256(uint160(value)))); } /** * @dev Returns the number of values in the set. O(1). */ function length(AddressSet storage set) internal view returns (uint256) { return _length(set._inner); } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(AddressSet storage set, uint256 index) internal view returns (address) { return address(uint160(uint256(_at(set._inner, index)))); } // UintSet struct UintSet { Set _inner; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function add(UintSet storage set, uint256 value) internal returns (bool) { return _add(set._inner, bytes32(value)); } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function remove(UintSet storage set, uint256 value) internal returns (bool) { return _remove(set._inner, bytes32(value)); } /** * @dev Returns true if the value is in the set. O(1). */ function contains(UintSet storage set, uint256 value) internal view returns (bool) { return _contains(set._inner, bytes32(value)); } /** * @dev Returns the number of values on the set. O(1). */ function length(UintSet storage set) internal view returns (uint256) { return _length(set._inner); } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(UintSet storage set, uint256 index) internal view returns (uint256) { return uint256(_at(set._inner, index)); } }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.0 <0.8.0; import "./Context.sol"; /** * @dev Contract module which allows children to implement an emergency stop * mechanism that can be triggered by an authorized account. * * This module is used through inheritance. It will make available the * modifiers `whenNotPaused` and `whenPaused`, which can be applied to * the functions of your contract. Note that they will not be pausable by * simply including this module, only once the modifiers are put in place. */ abstract contract Pausable is Context { /** * @dev Emitted when the pause is triggered by `account`. */ event Paused(address account); /** * @dev Emitted when the pause is lifted by `account`. */ event Unpaused(address account); bool private _paused; /** * @dev Initializes the contract in unpaused state. */ constructor () internal { _paused = false; } /** * @dev Returns true if the contract is paused, and false otherwise. */ function paused() public view virtual returns (bool) { return _paused; } /** * @dev Modifier to make a function callable only when the contract is not paused. * * Requirements: * * - The contract must not be paused. */ modifier whenNotPaused() { require(!paused(), "Pausable: paused"); _; } /** * @dev Modifier to make a function callable only when the contract is paused. * * Requirements: * * - The contract must be paused. */ modifier whenPaused() { require(paused(), "Pausable: not paused"); _; } /** * @dev Triggers stopped state. * * Requirements: * * - The contract must not be paused. */ function _pause() internal virtual whenNotPaused { _paused = true; emit Paused(_msgSender()); } /** * @dev Returns to normal state. * * Requirements: * * - The contract must be paused. */ function _unpause() internal virtual whenPaused { _paused = false; emit Unpaused(_msgSender()); } }
// 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.0 <0.8.0; /** * @dev String operations. */ library Strings { /** * @dev Converts a `uint256` to its ASCII `string` representation. */ function toString(uint256 value) internal pure returns (string memory) { // Inspired by OraclizeAPI's implementation - MIT licence // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol if (value == 0) { return "0"; } uint256 temp = value; uint256 digits; while (temp != 0) { digits++; temp /= 10; } bytes memory buffer = new bytes(digits); uint256 index = digits - 1; temp = value; while (temp != 0) { buffer[index--] = bytes1(uint8(48 + temp % 10)); temp /= 10; } return string(buffer); } }
pragma solidity >=0.6.2; interface IUniswapV2Router01 { function factory() external pure returns (address); function WETH() external pure returns (address); function addLiquidity( address tokenA, address tokenB, uint amountADesired, uint amountBDesired, uint amountAMin, uint amountBMin, address to, uint deadline ) external returns (uint amountA, uint amountB, uint liquidity); function addLiquidityETH( address token, uint amountTokenDesired, uint amountTokenMin, uint amountETHMin, address to, uint deadline ) external payable returns (uint amountToken, uint amountETH, uint liquidity); function removeLiquidity( address tokenA, address tokenB, uint liquidity, uint amountAMin, uint amountBMin, address to, uint deadline ) external returns (uint amountA, uint amountB); function removeLiquidityETH( address token, uint liquidity, uint amountTokenMin, uint amountETHMin, address to, uint deadline ) external returns (uint amountToken, uint amountETH); function removeLiquidityWithPermit( address tokenA, address tokenB, uint liquidity, uint amountAMin, uint amountBMin, address to, uint deadline, bool approveMax, uint8 v, bytes32 r, bytes32 s ) external returns (uint amountA, uint amountB); function removeLiquidityETHWithPermit( address token, uint liquidity, uint amountTokenMin, uint amountETHMin, address to, uint deadline, bool approveMax, uint8 v, bytes32 r, bytes32 s ) external returns (uint amountToken, uint amountETH); function swapExactTokensForTokens( uint amountIn, uint amountOutMin, address[] calldata path, address to, uint deadline ) external returns (uint[] memory amounts); function swapTokensForExactTokens( uint amountOut, uint amountInMax, address[] calldata path, address to, uint deadline ) external returns (uint[] memory amounts); function swapExactETHForTokens(uint amountOutMin, address[] calldata path, address to, uint deadline) external payable returns (uint[] memory amounts); function swapTokensForExactETH(uint amountOut, uint amountInMax, address[] calldata path, address to, uint deadline) external returns (uint[] memory amounts); function swapExactTokensForETH(uint amountIn, uint amountOutMin, address[] calldata path, address to, uint deadline) external returns (uint[] memory amounts); function swapETHForExactTokens(uint amountOut, address[] calldata path, address to, uint deadline) external payable returns (uint[] memory amounts); function quote(uint amountA, uint reserveA, uint reserveB) external pure returns (uint amountB); function getAmountOut(uint amountIn, uint reserveIn, uint reserveOut) external pure returns (uint amountOut); function getAmountIn(uint amountOut, uint reserveIn, uint reserveOut) external pure returns (uint amountIn); function getAmountsOut(uint amountIn, address[] calldata path) external view returns (uint[] memory amounts); function getAmountsIn(uint amountOut, address[] calldata path) external view returns (uint[] memory amounts); }
pragma solidity >=0.6.2; import './IUniswapV2Router01.sol'; interface IUniswapV2Router02 is IUniswapV2Router01 { function removeLiquidityETHSupportingFeeOnTransferTokens( address token, uint liquidity, uint amountTokenMin, uint amountETHMin, address to, uint deadline ) external returns (uint amountETH); function removeLiquidityETHWithPermitSupportingFeeOnTransferTokens( address token, uint liquidity, uint amountTokenMin, uint amountETHMin, address to, uint deadline, bool approveMax, uint8 v, bytes32 r, bytes32 s ) external returns (uint amountETH); function swapExactTokensForTokensSupportingFeeOnTransferTokens( uint amountIn, uint amountOutMin, address[] calldata path, address to, uint deadline ) external; function swapExactETHForTokensSupportingFeeOnTransferTokens( uint amountOutMin, address[] calldata path, address to, uint deadline ) external payable; function swapExactTokensForETHSupportingFeeOnTransferTokens( uint amountIn, uint amountOutMin, address[] calldata path, address to, uint deadline ) external; }
{ "remappings": [], "optimizer": { "enabled": true, "runs": 200 }, "evmVersion": "istanbul", "libraries": {}, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "abi" ] } } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"dna","type":"uint256"}],"name":"GenerateLuchador","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"baseURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_quantity","type":"uint256"},{"internalType":"uint256","name":"_deadline","type":"uint256"}],"name":"generateLuchador","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"imageData","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"metadata","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pauseSale","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"requestId","type":"bytes32"},{"internalType":"uint256","name":"randomness","type":"uint256"}],"name":"rawFulfillRandomness","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_baseURI","type":"string"}],"name":"setBaseURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_LinkFee","type":"uint256"}],"name":"setLinkFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenOfOwnerByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"uniswapRouter","outputs":[{"internalType":"contract IUniswapV2Router02","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"unpauseSale","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]
Contract Creation Code
60c06040527faa77729d3466ca35ae8d28b3bbac7cc36a5031efdc430821c02bc31a238af445600f55671bc16d674ec80000601055601180546001600160a01b031990811673f0d54349addcf704f77ae15b96510dea15cb7952179091556012805490911673514910771af9ca656af840dff83e8264ecf986ca1790553480156200008957600080fd5b50601154601254604080518082018252600a808252694c75636861646f72657360b01b6020808401919091528351808501909452908352694c55434841444f52455360b01b908301526001600160a01b03938416939092169190620000f56301ffc9a760e01b62001cca565b81516200010a90600690602085019062001d53565b5080516200012090600790602084019062001d53565b50620001336380ac58cd60e01b62001cca565b62000145635b5e139f60e01b62001cca565b6200015763780e9d6360e01b62001cca565b5050600a805460ff1916905560006200016f62001d4f565b600a8054610100600160a81b0319166101006001600160a01b03841690810291909117909155604051919250906000907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a3506001600b556001600160601b0319606092831b811660a090815291831b166080908152600e80546001600160a01b031916737a250d5630b4cf539739df2c5dacb4c659f2488d1790556040805161018081018252600661014082018181526565626562663760d01b6101608401528252825180840184528181526518b198b2193360d11b60208281019190915283810191909152835180850185528281526518d8cc190cd960d21b81830152838501528351808501855282815265190c8c998e4d60d21b8183015296830196909652825180840184528181526538393065633160d01b81880152938201939093528151808301835283815265062c66872c8760d31b818701529381019390935280518082018252828152650c4e588d4d4d60d21b8186015260c084015280518082018252828152651899b1b0b19b60d11b8186015260e0840152805180820182528281526566376332336360d01b8186015261010084015280518082019091529081526533189c32993360d11b928101929092526101208101919091526200035f90601390600a62001dd8565b50604080516101808101825260066101408201818152653230b230b29b60d11b610160840152825282518084018452818152651899989a18b360d11b60208281019190915280840191909152835180850185528281526519584c4e0d1960d21b818301528385015283518085018552828152653298199b1cb360d11b81830152606084015283518085018552828152651c9a9898b21960d11b8183015260808401528351808501855282815265191c1a9a329b60d11b8183015260a0840152835180850185528281526531646139353160d01b8183015260c0840152835180850185528281526531316239623560d01b8183015260e0840152835180850185528281526565386236336160d01b8183015261010084015283518085019094529083526565323833323760d01b90830152610120810191909152620004a890601490600a62001dd8565b506040805161018081018252600661014082018181526533623662613560d01b6101608401528252825180840184528181526533623866613560d01b60208281019190915280840191909152835180850185528281526533626135393960d01b8183015283850152835180850185528281526533626135373760d01b818301526060840152835180850185528281526519999c9c1a1960d11b81830152608084015283518085018552828152651bb3309a99b160d11b8183015260a08401528351808501855282815265309a9c1919b160d11b8183015260c08401528351808501855282815265309a9b1c99b160d11b8183015260e084015283518085018552828152650e0d0d198c5960d21b818301526101008401528351808501909452908352651a32991c981b60d11b90830152610120810191909152620005f190601590600a62001dd8565b506040805161018081018252600661014082018181526566396431623760d01b6101608401528252825180840184528181526566376238393760d01b60208281019190915280840191909152835180850185528281526566333963373760d01b81830152838501528351808501855282815265199998d88e0d60d21b818301526060840152835180850185528281526562643765343760d01b8183015260808401528351808501855282815265311c9bb29a3160d11b8183015260a0840152835180850185528281526506239376135360d41b8183015260c084015283518085018552828152650d584ccc8c4d60d21b8183015260e0840152835180850185528281526535303237306560d01b8183015261010084015283518085019094529083526533613162303960d01b908301526101208101919091526200073a90601690600a62001dd8565b50604051806040016040528063109d5b1b60e21b6001600160a01b031916815260200160405180610100016040528060db81526020016200744b60db91399052600080526017602090815281517fd840e16649f6b9a295d95876f4633d3a6b10b55e8162971cf78afd886d5ec89b80546001600160601b03191660a09290921c9190911781558282015180519192620007f9927fd840e16649f6b9a295d95876f4633d3a6b10b55e8162971cf78afd886d5ec89c929091019062001d53565b509050506040518060400160405280652530b3bab0b960d11b6001600160a01b031916815260200160405180610120016040528060f281526020016200735960f29139905260016000526017602090815281517ff36d6bc9642eb6fb6ee9998b09ce990566df752ab06e11f8de7ab633bbd57b8f80546001600160601b03191660a09290921c9190911781558282015180519192620008be927ff36d6bc9642eb6fb6ee9998b09ce990566df752ab06e11f8de7ab633bbd57b90929091019062001d53565b50905050604051806040016040528066436c617373696360c81b6001600160a01b031916815260200160405180610100016040528060c181526020016200772a60c191399052600080526018602090815281517f999d26de3473317ead3eeaf34ca78057f1439db67b6953469c3c96ce9caf6bd780546001600160601b03191660a09290921c919091178155828201518051919262000983927f999d26de3473317ead3eeaf34ca78057f1439db67b6953469c3c96ce9caf6bd8929091019062001d53565b50905050604051806040016040528065121bdbd9195960d21b6001600160a01b031916815260200160405180610100016040528060c181526020016200772a60c19139905260016000526018602090815281517ff3794665d3af9b6fb6f858b70185898134f96768ef31c325d52e04f0ac195a4d80546001600160601b03191660a09290921c919091178155828201518051919262000a48927ff3794665d3af9b6fb6f858b70185898134f96768ef31c325d52e04f0ac195a4e929091019062001d53565b5090505060405180604001604052806414da1a5c9d60da1b6001600160a01b031916815260200160405180610120016040528060e18152602001620070ee60e191399052600080526019602090815281517fd2ac945fcc0096878c763e37d6929b78378c1a2defabde8ba7ee5ed1d6e7a5b280546001600160601b03191660a09290921c919091178155828201518051919262000b0b927fd2ac945fcc0096878c763e37d6929b78378c1a2defabde8ba7ee5ed1d6e7a5b3929091019062001d53565b5090505060405180604001604052806913dc195b8814da1a5c9d60b21b6001600160a01b031916815260200160405180610120016040528060ff81526020016200762b60ff9139905260016000526019602090815281517ffc941c3961fb6541da34150022cddf959da0fb2353866a6bfbd249c2da09291480546001600160601b03191660a09290921c919091178155828201518051919262000bd4927ffc941c3961fb6541da34150022cddf959da0fb2353866a6bfbd249c2da092915929091019062001d53565b5090505060405180604001604052806614da5b99db195d60ca1b6001600160a01b03191681526020016040518060c00160405280608181526020016200790460819139905260026000526019602090815281517f6f678ad17c55bce407239525f4bf7f1fe99197d3eb69bfdd9a0db84a9a11b58180546001600160601b03191660a09290921c919091178155828201518051919262000c99927f6f678ad17c55bce407239525f4bf7f1fe99197d3eb69bfdd9a0db84a9a11b582929091019062001d53565b5090505060405180604001604052806953757370656e6465727360b01b6001600160a01b03191681526020016040518060a001604052806079815260200162007a6160799139905260036000526019602090815281517f3e323a6e0522b016fa22111dfed945f89456f9f44f69eac00209d92607a5b94080546001600160601b03191660a09290921c919091178155828201518051919262000d61927f3e323a6e0522b016fa22111dfed945f89456f9f44f69eac00209d92607a5b941929091019062001d53565b50905050604051806040016040528065476c6f76657360d01b6001600160a01b03191681526020016040518060c00160405280608f815260200162006f34608f9139905260008052601a602090815281517fb75ecc04ed35f89790e98640e901bda41eceff0cb896cf2765fb69768025375080546001600160601b03191660a09290921c919091178155828201518051919262000e24927fb75ecc04ed35f89790e98640e901bda41eceff0cb896cf2765fb697680253751929091019062001d53565b5090505060405180604001604052806a57726973742042616e647360a81b6001600160a01b0319168152602001604051806080016040528060418152602001620072eb6041913990526001600052601a602090815281517ff88cd8d612926ebb404e40725c01084b6e9b3ce0344cde068570342cbd448c6180546001600160601b03191660a09290921c919091178155828201518051919262000eed927ff88cd8d612926ebb404e40725c01084b6e9b3ce0344cde068570342cbd448c62929091019062001d53565b50905050604051806040016040528069149a59da1d0810985b9960b21b6001600160a01b03191681526020016040518060600160405280602d81526020016200732c602d913990526002600052601a602090815281517f4c287b3e2c2cb129ae3ba596d613d760b15affdac7242e12903c37a886ea1c4f80546001600160601b03191660a09290921c919091178155828201518051919262000fb5927f4c287b3e2c2cb129ae3ba596d613d760b15affdac7242e12903c37a886ea1c50929091019062001d53565b509050506040518060400160405280681319599d0810985b9960ba1b6001600160a01b031916815260200160405180606001604052806030815260200162006f046030913990526003600052601a602090815281517f4ac83fca211703e3ddb90093cd219714e5e3715bf0b4fd15b0441390534a24e280546001600160601b03191660a09290921c91909117815582820151805191926200107c927f4ac83fca211703e3ddb90093cd219714e5e3715bf0b4fd15b0441390534a24e3929091019062001d53565b5090505060405180604001604052806841726d2042616e647360b81b6001600160a01b03191681526020016040518060600160405280603f8152602001620075ec603f913990526004600052601a602090815281517f06b28f262ad931a15c9e47271fc159a891b2bcb0da2659cac5bbfed4886cf26e80546001600160601b03191660a09290921c919091178155828201518051919262001143927f06b28f262ad931a15c9e47271fc159a891b2bcb0da2659cac5bbfed4886cf26f929091019062001d53565b50905050604051806040016040528066536c656576657360c81b6001600160a01b03191681526020016040518060c0016040528060818152602001620070046081913990526005600052601a602090815281517f82f07edc09f3a46c1925d02252613a7fcc7be7d03b538b0c268df85f2f13a7ab80546001600160601b03191660a09290921c919091178155828201518051919262001208927f82f07edc09f3a46c1925d02252613a7fcc7be7d03b538b0c268df85f2f13a7ac929091019062001d53565b5090505060405180604001604052806414dc1b1a5d60da1b6001600160a01b03191681526020016040518060600160405280603a8152602001620077eb603a9139905260008052601b602090815281517f584f46c60af19681376031579adb04a2416e54ee5505351c2a8435e3766026ea80546001600160601b03191660a09290921c9190911781558282015180519192620012ca927f584f46c60af19681376031579adb04a2416e54ee5505351c2a8435e3766026eb929091019062001d53565b5090505060405180604001604052806443726f737360d81b6001600160a01b03191681526020016040518060600160405280603d8152602001620075af603d913990526001600052601b602090815281517f9fafca4c9c0d5c2cbf85f49fd8ab8212430ce78c2a0cb75b51e0f9c4f9ace00380546001600160601b03191660a09290921c91909117815582820151805191926200138d927f9fafca4c9c0d5c2cbf85f49fd8ab8212430ce78c2a0cb75b51e0f9c4f9ace004929091019062001d53565b5090505060405180604001604052806546696572636560d01b6001600160a01b0319168152602001604051806080016040528060538152602001620079856053913990526002600052601b602090815281517f1dd2f4b94a51cfb409e6e317a497f7cfd9013960a1c723f830c49c05a25f08a580546001600160601b03191660a09290921c919091178155828201518051919262001451927f1dd2f4b94a51cfb409e6e317a497f7cfd9013960a1c723f830c49c05a25f08a6929091019062001d53565b5090505060405180604001604052806614dd1c9a5c195960ca1b6001600160a01b03191681526020016040518060e0016040528060a881526020016200785c60a8913990526003600052601b602090815281517f804a3d0621e73505f5f0c57c922f3e57d6b48e175551184eb12f80d7b4a9c78380546001600160601b03191660a09290921c919091178155828201518051919262001516927f804a3d0621e73505f5f0c57c922f3e57d6b48e175551184eb12f80d7b4a9c784929091019062001d53565b50905050604051806040016040528063109bdb1d60e21b6001600160a01b031916815260200160405180608001604052806057815260200162007b4c6057913990526004600052601b602090815281517fa952f8c0f40734b22d2328e0f7ff57eeffee78885b9cf2147ff941cc37e1c86e80546001600160601b03191660a09290921c9190911781558282015180519192620015d8927fa952f8c0f40734b22d2328e0f7ff57eeffee78885b9cf2147ff941cc37e1c86f929091019062001d53565b5090505060405180604001604052806515da5b99d95960d21b6001600160a01b03191681526020016040518060a001604052806072815260200162007ada6072913990526005600052601b602090815281517fb48400cb19cf39e58355a7c9fd856f9b5b7298c53856a6766c6b39755ccafa7980546001600160601b03191660a09290921c91909117815582820151805191926200169c927fb48400cb19cf39e58355a7c9fd856f9b5b7298c53856a6766c6b39755ccafa7a929091019062001d53565b50905050604051806040016040528066436c617373696360c81b6001600160a01b03191681526020016040518060a0016040528060698152602001620070856069913990526006600052601b602090815281517ff5ddd0b8f160eab91dc4f82b50a485a96cf6ab0bfb38460d73171763afb6d5cf80546001600160601b03191660a09290921c919091178155828201518051919262001761927ff5ddd0b8f160eab91dc4f82b50a485a96cf6ab0bfb38460d73171763afb6d5d0929091019062001d53565b509050506040518060400160405280644172726f7760d81b6001600160a01b03191681526020016040518060c0016040528060898152602001620075266089913990526007600052601b602090815281517f6fa0adbc19babfec7e85ff6417830cdb284ababb3de438515569d7f3d9b3493180546001600160601b03191660a09290921c919091178155828201518051919262001824927f6fa0adbc19babfec7e85ff6417830cdb284ababb3de438515569d7f3d9b34932929091019062001d53565b50905050604051806040016040528063088c2e6d60e31b6001600160a01b03191681526020016040518060e0016040528060a78152602001620071cf60a7913990526008600052601b602090815281517f90dc0d05fc750d51b3e484087edb4e9beb1a58b38bc8386c0e048690482d89ed80546001600160601b03191660a09290921c9190911781558282015180519192620018e6927f90dc0d05fc750d51b3e484087edb4e9beb1a58b38bc8386c0e048690482d89ee929091019062001d53565b509050506040518060400160405280684d6f7573746163686560b81b6001600160a01b031916815260200160405180608001604052806041815260200162007a2060419139905260008052601c602090815281517fb9c6de81004e18dedadca3e5eabaab449ca91dff6f58efc9461da635fe77f84980546001600160601b03191660a09290921c9190911781558282015180519192620019ac927fb9c6de81004e18dedadca3e5eabaab449ca91dff6f58efc9461da635fe77f84a929091019062001d53565b5090505060405180604001604052806554696768747360d01b6001600160a01b03191681526020016040518060600160405280603781526020016200782560379139905260008052601d602090815281517f0a51588b1664495f089dd83d2d26f247920f94a57a4a09f20cf068efc8f82bd480546001600160601b03191660a09290921c919091178155828201518051919262001a6f927f0a51588b1664495f089dd83d2d26f247920f94a57a4a09f20cf068efc8f82bd5929091019062001d53565b5090505060405180604001604052806b5472756e6b2054696768747360a01b6001600160a01b03191681526020016040518060a0016040528060758152602001620072766075913990526001600052601d602090815281517f9de6abd965d55c3bb0cdbf6fa175050624c6ff8fe86f682dc08f2a450ede227880546001600160601b03191660a09290921c919091178155828201518051919262001b39927f9de6abd965d55c3bb0cdbf6fa175050624c6ff8fe86f682dc08f2a450ede2279929091019062001d53565b5090505060405180604001604052806754776f20546f6e6560c01b6001600160a01b0319168152602001604051806080016040528060488152602001620079d860489139905260008052601e602090815281517f65ce8396b736f5da9d881cc6fbcb11ef9721292dc41ec8c40879fd9edea5744d80546001600160601b03191660a09290921c919091178155828201518051919262001bfe927f65ce8396b736f5da9d881cc6fbcb11ef9721292dc41ec8c40879fd9edea5744e929091019062001d53565b50905050604051806040016040528063090d2ced60e31b6001600160a01b031916815260200160405180608001604052806041815260200162006fc36041913990526001600052601e602090815281517f873299c6a6c39b8b92f01922bb622df4a3236ea2876aac2da76f6c092cf7e98f80546001600160601b03191660a09290921c919091178155828201518051919262001cc0927f873299c6a6c39b8b92f01922bb622df4a3236ea2876aac2da76f6c092cf7e990929091019062001d53565b5090505062001ebb565b6001600160e01b0319808216141562001d2a576040805162461bcd60e51b815260206004820152601c60248201527f4552433136353a20696e76616c696420696e7465726661636520696400000000604482015290519081900360640190fd5b6001600160e01b0319166000908152602081905260409020805460ff19166001179055565b3390565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1062001d9657805160ff191683800117855562001dc6565b8280016001018555821562001dc6579182015b8281111562001dc657825182559160200191906001019062001da9565b5062001dd492915062001e38565b5090565b82805482825590600052602060002090810192821562001e2a579160200282015b8281111562001e2a578251805162001e1991849160209091019062001d53565b509160200191906001019062001df9565b5062001dd492915062001e4f565b5b8082111562001dd4576000815560010162001e39565b8082111562001dd457600062001e66828262001e70565b5060010162001e4f565b50805460018160011615610100020316600290046000825580601f1062001e98575062001eb8565b601f01602090049060005260206000209081019062001eb8919062001e38565b50565b60805160601c60a05160601c61501562001eef60003980611a865280613b605250806136645280613b3152506150156000f3fe6080604052600436106101dc5760003560e01c80636352211e11610102578063a22cb46511610095578063cd8ff65711610064578063cd8ff657146107cd578063e3684e39146107f7578063e985e9c514610821578063f2fde38b1461085c576101e3565b8063a22cb46514610680578063b88d4fde146106bb578063bb33d7291461078e578063c87b56dd146107a3576101e3565b8063735de9f7116100d1578063735de9f7146106115780638da5cb5b1461062657806394985ddd1461063b57806395d89b411461066b576101e3565b80636352211e1461058a5780636c0360eb146105b457806370a08231146105c9578063715018a6146105fc576101e3565b80632f745c591161017a57806355367ba91161014957806355367ba91461048a57806355f804b31461049f5780635a0a3a56146105525780635c975abb14610575576101e3565b80632f745c59146103cf5780633ccfd60b1461040857806342842e0e1461041d5780634f6ccce714610460576101e3565b8063081812fc116101b6578063081812fc146102e4578063095ea7b31461032a57806318160ddd1461036557806323b872dd1461038c576101e3565b806301ffc9a7146101e8578063061ba2f11461023057806306fdde03146102cf576101e3565b366101e357005b600080fd5b3480156101f457600080fd5b5061021c6004803603602081101561020b57600080fd5b50356001600160e01b03191661088f565b604080519115158252519081900360200190f35b34801561023c57600080fd5b5061025a6004803603602081101561025357600080fd5b50356108b2565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561029457818101518382015260200161027c565b50505050905090810190601f1680156102c15780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b3480156102db57600080fd5b5061025a611012565b3480156102f057600080fd5b5061030e6004803603602081101561030757600080fd5b50356110a8565b604080516001600160a01b039092168252519081900360200190f35b34801561033657600080fd5b506103636004803603604081101561034d57600080fd5b506001600160a01b03813516906020013561110a565b005b34801561037157600080fd5b5061037a6111e5565b60408051918252519081900360200190f35b34801561039857600080fd5b50610363600480360360608110156103af57600080fd5b506001600160a01b038135811691602081013590911690604001356111f6565b3480156103db57600080fd5b5061037a600480360360408110156103f257600080fd5b506001600160a01b03813516906020013561124d565b34801561041457600080fd5b50610363611278565b34801561042957600080fd5b506103636004803603606081101561044057600080fd5b506001600160a01b0381358116916020810135909116906040013561136e565b34801561046c57600080fd5b5061037a6004803603602081101561048357600080fd5b5035611389565b34801561049657600080fd5b5061036361139f565b3480156104ab57600080fd5b50610363600480360360208110156104c257600080fd5b8101906020810181356401000000008111156104dd57600080fd5b8201836020820111156104ef57600080fd5b8035906020019184600183028401116401000000008311171561051157600080fd5b91908080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525092955061140b945050505050565b6103636004803603604081101561056857600080fd5b5080359060200135611476565b34801561058157600080fd5b5061021c6118ac565b34801561059657600080fd5b5061030e600480360360208110156105ad57600080fd5b50356118b5565b3480156105c057600080fd5b5061025a6118dd565b3480156105d557600080fd5b5061037a600480360360208110156105ec57600080fd5b50356001600160a01b031661193e565b34801561060857600080fd5b506103636119a6565b34801561061d57600080fd5b5061030e611a58565b34801561063257600080fd5b5061030e611a67565b34801561064757600080fd5b506103636004803603604081101561065e57600080fd5b5080359060200135611a7b565b34801561067757600080fd5b5061025a611b06565b34801561068c57600080fd5b50610363600480360360408110156106a357600080fd5b506001600160a01b0381351690602001351515611b67565b3480156106c757600080fd5b50610363600480360360808110156106de57600080fd5b6001600160a01b0382358116926020810135909116916040820135919081019060808101606082013564010000000081111561071957600080fd5b82018360208201111561072b57600080fd5b8035906020019184600183028401116401000000008311171561074d57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550611c6c945050505050565b34801561079a57600080fd5b50610363611cca565b3480156107af57600080fd5b5061025a600480360360208110156107c657600080fd5b5035611d34565b3480156107d957600080fd5b50610363600480360360208110156107f057600080fd5b5035611e75565b34801561080357600080fd5b5061025a6004803603602081101561081a57600080fd5b5035611edc565b34801561082d57600080fd5b5061021c6004803603604081101561084457600080fd5b506001600160a01b0381358116916020013516612bb9565b34801561086857600080fd5b506103636004803603602081101561087f57600080fd5b50356001600160a01b0316612be7565b6001600160e01b0319811660009081526020819052604090205460ff165b919050565b60606108bd82612cf5565b61090e576040805162461bcd60e51b815260206004820152601c60248201527f696d616765446174613a206e6f6e6578697374656e7420746f6b656e00000000604482015290519081900360640190fd5b6000828152601f602052604090205461096e576040805162461bcd60e51b815260206004820181905260248201527f696d616765446174613a20646e61206e6f74207965742067656e657261746564604482015290519081900360640190fd5b610976614518565b6000838152601f602052604090205461098e90612d02565b90506060816001602002015160ff1615806109b05750602082015160ff166001145b6109c957604051806020016040528060008152506109e3565b6040518060c00160405280609d8152602001614eaa609d91395b90506060826001602002015160ff16600114610a0e5760405180602001604052806000815250610a2b565b60405180610180016040528061014c8152602001614c6e61014c91395b9050610a3685612d50565b610a408685612e2b565b845160ff9081166000908152601760209081526040808320828a01518516845260188352818420828b0151861685526019845282852060608c015187168652601a855283862060808d015188168752601b865284872060a08e015189168852601c875285882060c08f01519099168852601d9096529386206001938401979284019691840195948401948c94908101938c939082019290910190601e908f6007602002015160ff1681526020019081526020016000206001016040516020018080701e39bb339034b21e93b63ab1b430b237b960791b8152506011018d805190602001908083835b60208310610b475780518252601f199092019160209182019101610b28565b6001836020036101000a03801982511681845116808217855250505050505090500180614f78603991396039018c805190602001908083835b60208310610b9f5780518252601f199092019160209182019101610b80565b6001836020036101000a038019825116818451168082178552505050505050905001807f3c6720636c6173733d276c756368612d62726561746865273e000000000000008152506019018b805460018160011615610100020316600290048015610c405780601f10610c1e576101008083540402835291820191610c40565b820191906000526020600020905b815481529060010190602001808311610c2c575b50508a805460018160011615610100020316600290048015610c995780601f10610c77576101008083540402835291820191610c99565b820191906000526020600020905b815481529060010190602001808311610c85575b505080614dfd60ad913960ad0189805460018160011615610100020316600290048015610cfd5780601f10610cdb576101008083540402835291820191610cfd565b820191906000526020600020905b815481529060010190602001808311610ce9575b505088805460018160011615610100020316600290048015610d565780601f10610d34576101008083540402835291820191610d56565b820191906000526020600020905b815481529060010190602001808311610d42575b5050875160208901908083835b60208310610d825780518252601f199092019160209182019101610d63565b6001836020036101000a03801982511681845116808217855250505050505090500180614bcc6072913960720180741e339031b630b9b99e93b63ab1b43096b0b63a139f60591b81525060150186805460018160011615610100020316600290048015610e265780601f10610e04576101008083540402835291820191610e26565b820191906000526020600020905b815481529060010190602001808311610e12575b505080631e17b39f60e11b81525060040185805190602001908083835b60208310610e625780518252601f199092019160209182019101610e43565b6001836020036101000a0380198251168184511680821785525050505050509050018061477960de913960de01602f614fb18239602f01603661465b823960360184805460018160011615610100020316600290048015610efa5780601f10610ed8576101008083540402835291820191610efa565b820191906000526020600020905b815481529060010190602001808311610ee6575b5050631e17b39f60e11b8152600401603f6148578239603f0160416148ee823960410183805460018160011615610100020316600290048015610f745780601f10610f52576101008083540402835291820191610f74565b820191906000526020600020905b815481529060010190602001808311610f60575b505080614b0b6049913960490182805460018160011615610100020316600290048015610fd85780601f10610fb6576101008083540402835291820191610fd8565b820191906000526020600020905b815481529060010190602001808311610fc4575b505080651e17b9bb339f60d11b8152506006019c505050505050505050505050506040516020818303038152906040529350505050919050565b60068054604080516020601f600260001961010060018816150201909516949094049384018190048102820181019092528281526060939092909183018282801561109e5780601f106110735761010080835404028352916020019161109e565b820191906000526020600020905b81548152906001019060200180831161108157829003601f168201915b5050505050905090565b60006110b382612cf5565b6110ee5760405162461bcd60e51b815260040180806020018281038252602c815260200180614adf602c913960400191505060405180910390fd5b506000908152600460205260409020546001600160a01b031690565b6000611115826118b5565b9050806001600160a01b0316836001600160a01b031614156111685760405162461bcd60e51b8152600401808060200182810382526021815260200180614dba6021913960400191505060405180910390fd5b806001600160a01b031661117a6132f5565b6001600160a01b0316148061119b575061119b816111966132f5565b612bb9565b6111d65760405162461bcd60e51b81526004018080602001828103825260388152602001806149a56038913960400191505060405180910390fd5b6111e083836132f9565b505050565b60006111f16002613367565b905090565b6112076112016132f5565b82613372565b6112425760405162461bcd60e51b8152600401808060200182810382526031815260200180614f476031913960400191505060405180910390fd5b6111e0838383613416565b6001600160a01b038216600090815260016020526040812061126f9083613562565b90505b92915050565b6112806132f5565b6001600160a01b0316611291611a67565b6001600160a01b0316146112da576040805162461bcd60e51b81526020600482018190526024820152600080516020614b54833981519152604482015290519081900360640190fd5b604051600090339047908381818185875af1925050503d806000811461131c576040519150601f19603f3d011682016040523d82523d6000602084013e611321565b606091505b505090508061136b576040805162461bcd60e51b815260206004820152601160248201527015da5d1a191c985dd85b0819985a5b1959607a1b604482015290519081900360640190fd5b50565b6111e083838360405180602001604052806000815250611c6c565b60008061139760028461356e565b509392505050565b6113a76132f5565b6001600160a01b03166113b8611a67565b6001600160a01b031614611401576040805162461bcd60e51b81526020600482018190526024820152600080516020614b54833981519152604482015290519081900360640190fd5b61140961358a565b565b6114136132f5565b6001600160a01b0316611424611a67565b6001600160a01b03161461146d576040805162461bcd60e51b81526020600482018190526024820152600080516020614b54833981519152604482015290519081900360640190fd5b61136b8161362a565b6002600b5414156114ce576040805162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015290519081900360640190fd5b6002600b556114db6118ac565b15611520576040805162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b604482015290519081900360640190fd5b61271061152d600d61363d565b1061157f576040805162461bcd60e51b815260206004820152601a60248201527f6d6178696d756d206c75636861646f7265732072656163686564000000000000604482015290519081900360640190fd5b6127108261158d600d61363d565b0111156115e1576040805162461bcd60e51b815260206004820181905260248201527f6d696e74207175616e746974792065786365656473206d617820737570706c79604482015290519081900360640190fd5b6000821180156115f2575060148211155b61162d5760405162461bcd60e51b8152600401808060200182810382526022815260200180614ddb6022913960400191505060405180910390fd5b6010546040805160028082526060808301845293860293926020830190803683375050600e54604080516315ab88c960e31b815290519394506001600160a01b039091169263ad5c464892506004808301926020929190829003018186803b15801561169857600080fd5b505afa1580156116ac573d6000803e3d6000fd5b505050506040513d60208110156116c257600080fd5b5051815182906000906116d157fe5b6001600160a01b0392831660209182029290920101526012548251911690829060019081106116fc57fe5b6001600160a01b03928316602091820292909201810191909152600e5460405163fb3bdb4160e01b815260048101868152306044830181905260648301899052608060248401908152875160848501528751949096169563fb3bdb419534958a958a958d949093909260a490920191878201910280838360005b8381101561178e578181015183820152602001611776565b50505050905001955050505050506000604051808303818588803b1580156117b557600080fd5b505af11580156117c9573d6000803e3d6000fd5b50505050506040513d6000823e601f3d908101601f1916820160405260208110156117f357600080fd5b810190808051604051939291908464010000000082111561181357600080fd5b90830190602082018581111561182857600080fd5b825186602082028301116401000000008211171561184557600080fd5b82525081516020918201928201910280838360005b8381101561187257818101518382015260200161185a565b505050509050016040525050505060005b848110156118a0576118984382900340613641565b600101611883565b50506001600b55505050565b600a5460ff1690565b600061127282604051806060016040528060298152602001614a076029913960029190613781565b60098054604080516020601f600260001961010060018816150201909516949094049384018190048102820181019092528281526060939092909183018282801561109e5780601f106110735761010080835404028352916020019161109e565b60006001600160a01b0382166119855760405162461bcd60e51b815260040180806020018281038252602a8152602001806149dd602a913960400191505060405180910390fd5b6001600160a01b038216600090815260016020526040902061127290613367565b6119ae6132f5565b6001600160a01b03166119bf611a67565b6001600160a01b031614611a08576040805162461bcd60e51b81526020600482018190526024820152600080516020614b54833981519152604482015290519081900360640190fd5b600a5460405160009161010090046001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600a8054610100600160a81b0319169055565b600e546001600160a01b031681565b600a5461010090046001600160a01b031690565b336001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614611af8576040805162461bcd60e51b815260206004820152601f60248201527f4f6e6c7920565246436f6f7264696e61746f722063616e2066756c66696c6c00604482015290519081900360640190fd5b611b02828261378e565b5050565b60078054604080516020601f600260001961010060018816150201909516949094049384018190048102820181019092528281526060939092909183018282801561109e5780601f106110735761010080835404028352916020019161109e565b611b6f6132f5565b6001600160a01b0316826001600160a01b03161415611bd5576040805162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c657200000000000000604482015290519081900360640190fd5b8060056000611be26132f5565b6001600160a01b03908116825260208083019390935260409182016000908120918716808252919093529120805460ff191692151592909217909155611c266132f5565b6001600160a01b03167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c318360405180821515815260200191505060405180910390a35050565b611c7d611c776132f5565b83613372565b611cb85760405162461bcd60e51b8152600401808060200182810382526031815260200180614f476031913960400191505060405180910390fd5b611cc4848484846137ea565b50505050565b611cd26132f5565b6001600160a01b0316611ce3611a67565b6001600160a01b031614611d2c576040805162461bcd60e51b81526020600482018190526024820152600080516020614b54833981519152604482015290519081900360640190fd5b61140961383c565b6060611d3f82612cf5565b611d7a5760405162461bcd60e51b815260040180806020018281038252602f815260200180614b9d602f913960400191505060405180910390fd5b6060611d846118dd565b90506000815111611da45760405180602001604052806000815250611e6e565b80611dae84612d50565b6040516020018083805190602001908083835b60208310611de05780518252601f199092019160209182019101611dc1565b51815160209384036101000a600019018019909216911617905285519190930192850191508083835b60208310611e285780518252601f199092019160209182019101611e09565b6001836020036101000a0380198251168184511680821785525050505050509050018064173539b7b760d91b815250600501925050506040516020818303038152906040525b9392505050565b611e7d6132f5565b6001600160a01b0316611e8e611a67565b6001600160a01b031614611ed7576040805162461bcd60e51b81526020600482018190526024820152600080516020614b54833981519152604482015290519081900360640190fd5b601055565b6060611ee782612cf5565b611f38576040805162461bcd60e51b815260206004820152601b60248201527f6d657461646174613a206e6f6e6578697374656e7420746f6b656e0000000000604482015290519081900360640190fd5b6000828152601f6020526040902054611f98576040805162461bcd60e51b815260206004820152601f60248201527f6d657461646174613a20646e61206e6f74207965742067656e65726174656400604482015290519081900360640190fd5b611fa0614518565b6000838152601f6020526040902054611fb890612d02565b9050611fc2614537565b60408051610100808201808452855160ff166000908152601760209081529085902061014085018652805460a01b6001600160a01b0319168352600180820180548851600293821615909702600019011691909104601f8101849004840286018401909752868552949586959394919361012087019390919083018282801561208c5780601f106120615761010080835404028352916020019161208c565b820191906000526020600020905b81548152906001019060200180831161206f57829003601f168201915b50505091909252505050815260208481015160ff1660009081526018825260409081902081518083018352815460a01b6001600160a01b0319168152600180830180548551600261010094831615949094026000190190911692909204601f810187900487028301870190955284825295850195919492938584019391929183018282801561215c5780601f106121315761010080835404028352916020019161215c565b820191906000526020600020905b81548152906001019060200180831161213f57829003601f168201915b50505091909252505050815260408481015160ff166000908152601960209081529082902082518084018452815460a01b6001600160a01b0319168152600180830180548651600261010094831615949094026000190190911692909204601f81018690048602830186019096528582529584019591949293858101939192919083018282801561222e5780601f106122035761010080835404028352916020019161222e565b820191906000526020600020905b81548152906001019060200180831161221157829003601f168201915b505050919092525050508152606084015160ff166000908152601a602090815260409182902082518084018452815460a01b6001600160a01b0319168152600180830180548651600261010094831615949094026000190190911692909204601f8101869004860283018601909652858252958401959194929385810193919291908301828280156123015780601f106122d657610100808354040283529160200191612301565b820191906000526020600020905b8154815290600101906020018083116122e457829003601f168201915b505050919092525050508152608084015160ff166000908152601b602090815260409182902082518084018452815460a01b6001600160a01b0319168152600180830180548651600261010094831615949094026000190190911692909204601f8101869004860283018601909652858252958401959194929385810193919291908301828280156123d45780601f106123a9576101008083540402835291602001916123d4565b820191906000526020600020905b8154815290600101906020018083116123b757829003601f168201915b50505091909252505050815260a08481015160ff166000908152601c602090815260409182902082518084018452815490941b6001600160a01b0319168452600180820180548551600261010094831615949094026000190190911692909204601f8101859004850283018501909552848252958301959193858401939192918301828280156124a55780601f1061247a576101008083540402835291602001916124a5565b820191906000526020600020905b81548152906001019060200180831161248857829003601f168201915b50505091909252505050815260c084015160ff166000908152601d602090815260409182902082518084018452815460a01b6001600160a01b0319168152600180830180548651600261010094831615949094026000190190911692909204601f8101869004860283018601909652858252958401959194929385810193919291908301828280156125785780601f1061254d57610100808354040283529160200191612578565b820191906000526020600020905b81548152906001019060200180831161255b57829003601f168201915b50505091909252505050815260e084015160ff166000908152601e602090815260409182902082518084018452815460a01b6001600160a01b0319168152600180830180548651600261010094831615949094026000190190911692909204601f81018690048602830186019096528582529584019591949293858101939192919083018282801561264b5780601f106126205761010080835404028352916020019161264b565b820191906000526020600020905b81548152906001019060200180831161262e57829003601f168201915b50505050508152505081525090506060612663614565565b506040805161014081018252600661010082019081526514dc1a5c9a5d60d21b6101208301528152815180830183526004808252634361706560e01b6020838101919091528084019290925283518085018552600580825264546f72736f60d81b8285015284860191909152845180860186528281526341726d7360e01b81850152606085015284518086018652918252634d61736b60e01b828401526080840191909152835180850185528181526409adeeae8d60db1b8184015260a0840152835180850185526007815266426f74746f6d7360c81b8184015260c08401528351808501909452835264426f6f747360d81b9083015260e081019190915260005b60088110156129a15783816008811061277a57fe5b6020020151516001600160a01b03191661279357612999565b8283516000146127be57604051806040016040528060038152602001622c207b60e81b8152506127d9565b604051806040016040528060018152602001607b60f81b8152505b8383600881106127e557fe5b60200201516128048785600881106127f957fe5b6020020151516138bf565b6040516020018085805190602001908083835b602083106128365780518252601f199092019160209182019101612817565b51815160209384036101000a600019018019909216911617905287519190930192870191508083835b6020831061287e5780518252601f19909201916020918201910161285f565b51815160209384036101000a60001901801990921691161790526e113a3930b4ba2fba3cb832911d101160891b919093019081528551600f90910192860191508083835b602083106128e15780518252601f1990920191602091820191016128c2565b51815160209384036101000a600019018019909216911617905261088b60f21b9190930190815269113b30b63ab2911d101160b11b60028201528451600c90910192850191508083835b6020831061294a5780518252601f19909201916020918201910161292b565b5181516020939093036101000a6000190180199091169216919091179052601160f91b920191825250607d60f81b600182015260408051808303601d1901815260029092019052975050505050505b600101612765565b506129ab86612d50565b6129b4876108b2565b6129bd88612d50565b604051607b60f81b602080830191825272226e616d65223a20224c75636861646f72202360681b602184015285518893603401918701908083835b60208310612a175780518252601f1990920191602091820191016129f8565b5181516020939093036101000a600019018019909116921691909117905261088b60f21b920191825250600201608d614a528239608d01806e1134b6b0b3b2afb230ba30911d101160891b815250600f0184805190602001908083835b60208310612a935780518252601f199092019160209182019101612a74565b5181516020939093036101000a600019018019909116921691909117905261088b60f21b9201918252506002016030614c3e823960300183805190602001908083835b60208310612af55780518252601f199092019160209182019101612ad6565b51815160209384036101000a600019018019909216911617905261088b60f21b919093019081526e2261747472696275746573223a205b60881b60028201528451601190910192850191508083835b60208310612b635780518252601f199092019160209182019101612b44565b5181516020939093036101000a6000190180199091169216919091179052605d60f81b920191825250607d60f81b600182015260408051808303601d19018152600290920190529b9a5050505050505050505050565b6001600160a01b03918216600090815260056020908152604080832093909416825291909152205460ff1690565b612bef6132f5565b6001600160a01b0316612c00611a67565b6001600160a01b031614612c49576040805162461bcd60e51b81526020600482018190526024820152600080516020614b54833981519152604482015290519081900360640190fd5b6001600160a01b038116612c8e5760405162461bcd60e51b81526004018080602001828103825260268152602001806148c86026913960400191505060405180910390fd5b600a546040516001600160a01b0380841692610100900416907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3600a80546001600160a01b0390921661010002610100600160a81b0319909216919091179055565b60006112726002836139c5565b612d0a614518565b612d12614518565b60005b600c811015612d4957600a84068282600c8110612d2e57fe5b60ff9092166020929092020152600a84049350600101612d15565b5092915050565b606081612d7557506040805180820190915260018152600360fc1b60208201526108ad565b8160005b8115612d8d57600101600a82049150612d79565b60608167ffffffffffffffff81118015612da657600080fd5b506040519080825280601f01601f191660200182016040528015612dd1576020820181803683370190505b50859350905060001982015b8315612e2257600a840660300160f81b82828060019003935081518110612e0057fe5b60200101906001600160f81b031916908160001a905350600a84049350612ddd565b50949350505050565b6060612e3683612d50565b6013836008602002015160ff1681548110612e4d57fe5b90600052602060002001612e6085612d50565b6014856009602002015160ff1681548110612e7757fe5b90600052602060002001612e8a87612d50565b601587600a602002015160ff1681548110612ea157fe5b90600052602060002001612eb489612d50565b601689600b602002015160ff1681548110612ecb57fe5b90600052602060002001612ede8b612d50565b60405160200180806f1e39ba3cb6329f11b63ab1b430b237b960811b8152506010018a805190602001908083835b60208310612f2b5780518252601f199092019160209182019101612f0c565b6001836020036101000a0380198251168184511680821785525050505050509050018075202e6c756368612d62617365207b2066696c6c3a202360501b81525060160189805460018160011615610100020316600290048015612fc55780601f10612fa3576101008083540402835291820191612fc5565b820191906000526020600020905b815481529060010190602001808311612fb1575b5050806c1d903e9011b63ab1b430b237b960991b815250600d0188805190602001908083835b6020831061300a5780518252601f199092019160209182019101612feb565b6001836020036101000a0380198251168184511680821785525050505050509050018074202e6c756368612d616c74207b2066696c6c3a202360581b815250601501878054600181600116156101000203166002900480156130a35780601f106130815761010080835404028352918201916130a3565b820191906000526020600020905b81548152906001019060200180831161308f575b5050806c1d903e9011b63ab1b430b237b960991b815250600d0186805190602001908083835b602083106130e85780518252601f1990920191602091820191016130c9565b6001836020036101000a0380198251168184511680821785525050505050509050018075202e6c756368612d65796573207b2066696c6c3a202360501b815250601601858054600181600116156101000203166002900480156131825780601f10613160576101008083540402835291820191613182565b820191906000526020600020905b81548152906001019060200180831161316e575b5050806c1d903e9011b63ab1b430b237b960991b815250600d0184805190602001908083835b602083106131c75780518252601f1990920191602091820191016131a8565b6001836020036101000a0380198251168184511680821785525050505050509050018075202e6c756368612d736b696e207b2066696c6c3a202360501b815250601601838054600181600116156101000203166002900480156132615780601f1061323f576101008083540402835291820191613261565b820191906000526020600020905b81548152906001019060200180831161324d575b5050806c1d903e9011b63ab1b430b237b960991b815250600d0182805190602001908083835b602083106132a65780518252601f199092019160209182019101613287565b6001836020036101000a038019825116818451168082178552505050505050905001806146bc60bd913960bd019950505050505050505050604051602081830303815290604052905092915050565b3390565b600081815260046020526040902080546001600160a01b0319166001600160a01b038416908117909155819061332e826118b5565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b60006112728261363d565b600061337d82612cf5565b6133b85760405162461bcd60e51b815260040180806020018281038252602c815260200180614979602c913960400191505060405180910390fd5b60006133c3836118b5565b9050806001600160a01b0316846001600160a01b031614806133fe5750836001600160a01b03166133f3846110a8565b6001600160a01b0316145b8061340e575061340e8185612bb9565b949350505050565b826001600160a01b0316613429826118b5565b6001600160a01b03161461346e5760405162461bcd60e51b8152600401808060200182810382526029815260200180614b746029913960400191505060405180910390fd5b6001600160a01b0382166134b35760405162461bcd60e51b815260040180806020018281038252602481526020018061492f6024913960400191505060405180910390fd5b6134be8383836139d1565b6134c96000826132f9565b6001600160a01b03831660009081526001602052604090206134eb9082613a20565b506001600160a01b038216600090815260016020526040902061350e9082613a2c565b5061351b60028284613a38565b5080826001600160a01b0316846001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4505050565b600061126f8383613a4e565b600080808061357d8686613ab2565b9097909650945050505050565b6135926118ac565b156135d7576040805162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b604482015290519081900360640190fd5b600a805460ff191660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a25861360d6132f5565b604080516001600160a01b039092168252519081900360200190a1565b8051611b0290600990602084019061458d565b5490565b601054604080516370a0823160e01b815230600482015290516001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016916370a08231916024808301926020929190829003018186803b1580156136aa57600080fd5b505afa1580156136be573d6000803e3d6000fd5b505050506040513d60208110156136d457600080fd5b50511015613729576040805162461bcd60e51b815260206004820152601f60248201527f4e6f7420656e6f756768204c494e4b202d2066696c6c20636f6e747261637400604482015290519081900360640190fd5b600061373a600f5460105484613b2d565b9050613746600d613ce0565b604051806020016040528061375b600d61363d565b90526000828152602080526040902090519055611b023361377c600d61363d565b613ce9565b600061340e848484613d03565b60008281526020808052604080832080548452601f83528184208590559285905281805291548251848152925190927f1d584699e20b45cf7fb70771dbd92bb407c244dd750faf0d3c3108aaae7d0e7292908290030190a25050565b6137f5848484613416565b61380184848484613dcd565b611cc45760405162461bcd60e51b81526004018080602001828103825260328152602001806148966032913960400191505060405180910390fd5b6138446118ac565b61388c576040805162461bcd60e51b815260206004820152601460248201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b604482015290519081900360640190fd5b600a805460ff191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa61360d6132f5565b606060005b600c8160ff161080156138f25750828160ff16600c81106138e157fe5b1a60f81b6001600160f81b03191615155b156138ff576001016138c4565b60608160ff1667ffffffffffffffff8111801561391b57600080fd5b506040519080825280601f01601f191660200182016040528015613946576020820181803683370190505b509050600091505b600c8260ff1610801561397c5750838260ff16600c811061396b57fe5b1a60f81b6001600160f81b03191615155b15611e6e57838260ff16600c811061399057fe5b1a60f81b818360ff16815181106139a357fe5b60200101906001600160f81b031916908160001a90535060019091019061394e565b600061126f8383613f35565b6139dc8383836111e0565b6139e46118ac565b156111e05760405162461bcd60e51b815260040180806020018281038252602b815260200180614691602b913960400191505060405180910390fd5b600061126f8383613f4d565b600061126f8383614013565b600061340e84846001600160a01b03851661405d565b81546000908210613a905760405162461bcd60e51b81526004018080602001828103825260228152602001806146396022913960400191505060405180910390fd5b826000018281548110613a9f57fe5b9060005260206000200154905092915050565b815460009081908310613af65760405162461bcd60e51b8152600401808060200182810382526022815260200180614a306022913960400191505060405180910390fd5b6000846000018481548110613b0757fe5b906000526020600020906002020190508060000154816001015492509250509250929050565b60007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316634000aea07f000000000000000000000000000000000000000000000000000000000000000085878660405160200180838152602001828152602001925050506040516020818303038152906040526040518463ffffffff1660e01b815260040180846001600160a01b0316815260200183815260200180602001828103825283818151815260200191508051906020019080838360005b83811015613c09578181015183820152602001613bf1565b50505050905090810190601f168015613c365780820380516001836020036101000a031916815260200191505b50945050505050602060405180830381600087803b158015613c5757600080fd5b505af1158015613c6b573d6000803e3d6000fd5b505050506040513d6020811015613c8157600080fd5b50506000848152600c6020526040812054613ca1908690859030906140f4565b6000868152600c6020526040902054909150613cbe90600161413b565b6000868152600c6020526040902055613cd78582614195565b95945050505050565b80546001019055565b611b028282604051806020016040528060008152506141c1565b60008281526001840160205260408120548281613d9e5760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015613d63578181015183820152602001613d4b565b50505050905090810190601f168015613d905780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b50846000016001820381548110613db157fe5b9060005260206000209060020201600101549150509392505050565b6000613de1846001600160a01b0316614213565b613ded5750600161340e565b6060613efb630a85bd0160e11b613e026132f5565b88878760405160240180856001600160a01b03168152602001846001600160a01b0316815260200183815260200180602001828103825283818151815260200191508051906020019080838360005b83811015613e69578181015183820152602001613e51565b50505050905090810190601f168015613e965780820380516001836020036101000a031916815260200191505b5095505050505050604051602081830303815290604052906001600160e01b0319166020820180516001600160e01b038381831617835250505050604051806060016040528060328152602001614896603291396001600160a01b0388169190614219565b90506000818060200190516020811015613f1457600080fd5b50516001600160e01b031916630a85bd0160e11b1492505050949350505050565b60009081526001919091016020526040902054151590565b600081815260018301602052604081205480156140095783546000198083019190810190600090879083908110613f8057fe5b9060005260206000200154905080876000018481548110613f9d57fe5b600091825260208083209091019290925582815260018981019092526040902090840190558654879080613fcd57fe5b60019003818190600052602060002001600090559055866001016000878152602001908152602001600020600090556001945050505050611272565b6000915050611272565b600061401f8383613f35565b61405557508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155611272565b506000611272565b6000828152600184016020526040812054806140c2575050604080518082018252838152602080820184815286546001818101895560008981528481209551600290930290950191825591519082015586548684528188019092529290912055611e6e565b828560000160018303815481106140d557fe5b9060005260206000209060020201600101819055506000915050611e6e565b60408051602080820196909652808201949094526001600160a01b039290921660608401526080808401919091528151808403909101815260a09092019052805191012090565b60008282018381101561126f576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b604080516020808201949094528082019290925280518083038201815260609092019052805191012090565b6141cb8383614228565b6141d86000848484613dcd565b6111e05760405162461bcd60e51b81526004018080602001828103825260328152602001806148966032913960400191505060405180910390fd5b3b151590565b606061340e8484600085614356565b6001600160a01b038216614283576040805162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f2061646472657373604482015290519081900360640190fd5b61428c81612cf5565b156142de576040805162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e74656400000000604482015290519081900360640190fd5b6142ea600083836139d1565b6001600160a01b038216600090815260016020526040902061430c9082613a2c565b5061431960028284613a38565b5060405181906001600160a01b038416906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b6060824710156143975760405162461bcd60e51b81526004018080602001828103825260268152602001806149536026913960400191505060405180910390fd5b6143a085614213565b6143f1576040805162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015290519081900360640190fd5b60006060866001600160a01b031685876040518082805190602001908083835b602083106144305780518252601f199092019160209182019101614411565b6001836020036101000a03801982511681845116808217855250505050505090500191505060006040518083038185875af1925050503d8060008114614492576040519150601f19603f3d011682016040523d82523d6000602084013e614497565b606091505b50915091506144a78282866144b2565b979650505050505050565b606083156144c1575081611e6e565b8251156144d15782518084602001fd5b60405162461bcd60e51b8152602060048201818152845160248401528451859391928392604401919085019080838360008315613d63578181015183820152602001613d4b565b604051806101800160405280600c906020820280368337509192915050565b6040518061010001604052806008905b61454f61460b565b8152602001906001900390816145475790505090565b6040518061010001604052806008905b60608152602001906001900390816145755790505090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106145ce57805160ff19168380011785556145fb565b828001600101855582156145fb579182015b828111156145fb5782518255916020019190600101906145e0565b50614607929150614623565b5090565b60408051808201909152600081526060602082015290565b5b80821115614607576000815560010161462456fe456e756d657261626c655365743a20696e646578206f7574206f6620626f756e64733c706174682066696c6c3d272330303027206f7061636974793d272e392720643d274d3133203131682d3376316834762d317a272f3e4552433732315061757361626c653a20746f6b656e207472616e73666572207768696c6520706175736564202e6c756368612d62726561746865207b20616e696d6174696f6e3a20302e3573206c756368612d6272656174686520696e66696e69746520616c7465726e61746520656173652d696e2d6f75743b207d20406b65796672616d6573206c756368612d62726561746865207b2066726f6d207b207472616e73666f726d3a207472616e736c6174655928307078293b207d20746f207b207472616e73666f726d3a207472616e736c61746559283125293b207d207d3c2f7374796c653e3c706174682066696c6c3d27234646462720643d274d39203648367633683456367a4d31372036682d337633683456367a272f3e3c7061746820636c6173733d276c756368612d657965732720643d274d31362036682d327633683356367a4d382036483776336833563648397a272f3e3c706174682066696c6c3d27234646462720643d274d3720366831763148377a4d3136203668317631682d317a27206f7061636974793d272e34272f3e3c706174682066696c6c3d27233030302720643d274d3135203768317631682d317a4d3820376831763148387a272f3e3c7061746820636c6173733d276c756368612d736b696e2720643d274d3136203233762d3648387636483776316834762d34683276346834762d317a272f3e4552433732313a207472616e7366657220746f206e6f6e20455243373231526563656976657220696d706c656d656e7465724f776e61626c653a206e6577206f776e657220697320746865207a65726f20616464726573733c7061746820636c6173733d276c756368612d626173652720643d274d31352031374838763168317631683276316832762d316832762d316831762d317a272f3e4552433732313a207472616e7366657220746f20746865207a65726f2061646472657373416464726573733a20696e73756666696369656e742062616c616e636520666f722063616c6c4552433732313a206f70657261746f7220717565727920666f72206e6f6e6578697374656e7420746f6b656e4552433732313a20617070726f76652063616c6c6572206973206e6f74206f776e6572206e6f7220617070726f76656420666f7220616c6c4552433732313a2062616c616e636520717565727920666f7220746865207a65726f20616464726573734552433732313a206f776e657220717565727920666f72206e6f6e6578697374656e7420746f6b656e456e756d657261626c654d61703a20696e646578206f7574206f6620626f756e6473226465736372697074696f6e223a20224c75636861646f726573206172652072616e646f6d6c792067656e657261746564207573696e6720436861696e6c696e6b2056524620616e6420686176652031303025206f6e2d636861696e2061727420616e64206d65746164617461202d204f6e6c792031303030302077696c6c206576657220657869737421222c4552433732313a20617070726f76656420717565727920666f72206e6f6e6578697374656e7420746f6b656e3c7061746820636c6173733d276c756368612d626173652720643d274d3920323148387632483776316834762d33682d317a4d3136203233762d32682d3376336834762d317a272f3e4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65724552433732313a207472616e73666572206f6620746f6b656e2074686174206973206e6f74206f776e4552433732314d657461646174613a2055524920717565727920666f72206e6f6e6578697374656e7420746f6b656e3c7061746820636c6173733d276c756368612d626173652720643d274d313820355633682d315632682d315631682d3156304839763148387631483776314836763248357635683176326831763168317631683176316836762d316831762d316831762d316831762d32683156357a272f3e2265787465726e616c5f75726c223a202268747470733a2f2f6c75636861646f7265732e696f2f6c75636861646f722f3c7061746820636c6173733d276c756368612d616c742720643d274d313820345633682d315632682d315631682d3156304839763148387631483776314836763248357635683156366831563568325634683156336834763168317631683276316831763468315635682d317a272f3e3c672066696c6c3d2723303030273e3c7061746820643d274d313820345633682d315632682d315631682d3156304839763148387631483776314836763248357635683156356831563468315633683156326836763168317631683176316831763568315635682d317a27206f7061636974793d272e32272f3e3c7061746820643d274d313620345633682d31563248397631483876314837763168325634683156336834763168317631683256347a4d3620356831763148367a4d3137203568317631682d317a27206f7061636974793d272e35272f3e3c2f673e4552433732313a20617070726f76616c20746f2063757272656e74206f776e65726d696e74207175616e74697479206d757374206265206265747765656e20312d32303c7061746820636c6173733d276c756368612d736b696e2720643d274d3232203132762d31682d31762d31682d315639682d315635682d315633682d315632682d315631682d3156304839763148387631483776314836763248357634483476314833763148327631483176386834762d316831762d324835762d336831763168317631683176326838762d326831762d316831762d3168317633682d317632683176316834762d387a272f3e3c7061746820636c6173733d276c756368612d616c742720643d274d32302031305639682d327631682d3176316834762d317a4d35203948347631483376316834762d31483656397a272f3e3c706174682066696c6c3d272330303027206f7061636974793d272e322720643d274d36203948347631483376316834762d3148367a4d32302031305639682d327631682d3176316834762d317a272f3e4552433732313a207472616e736665722063616c6c6572206973206e6f74206f776e6572206e6f7220617070726f7665642720786d6c6e733d27687474703a2f2f7777772e77332e6f72672f323030302f737667272076696577426f783d27302030203234203234273e3c7061746820636c6173733d276c756368612d736b696e2720643d274d3134203130483976336836762d337a272f3ea2646970667358221220f07ff78f47503188bddd1cb2cc6410513aab09c35bef87db8e84d77cf54338e964736f6c634300060c00333c7061746820636c6173733d276c756368612d626173652720643d274d3232203134682d3376316834762d317a272f3e3c7061746820636c6173733d276c756368612d626173652720643d274d35203136483176336834762d316831762d3148357a4d3232203136682d337631682d317631683176316834762d337a272f3e3c7061746820636c6173733d276c756368612d616c742720643d274d33203136483176316834762d3148347a4d3232203136682d3376316834762d317a272f3e3c7061746820636c6173733d276c756368612d616c742720643d274d39203230483876316833762d31682d317a4d3135203230682d3276316833762d317a272f3e3c7061746820636c6173733d276c756368612d626173652720643d274d3232203134682d3376336834762d337a4d33203134483176336834762d3348347a272f3e3c7061746820636c6173733d276c756368612d616c742720643d274d3232203134682d3376316834762d317a4d33203134483176316834762d3148347a272f3e3c7061746820643d274d313820355633682d315632682d317632682d317631682d317631682d317633682d325636682d31563548395634483856324837763148367632483576346831763168327633683176316836762d316831762d3368325639683156357a272f3e3c7061746820636c6173733d276c756368612d626173652720643d274d3232203132762d31682d31762d31682d315639483476314833763148327631483176356834762d336831763168317631683176326838762d326831762d316831762d31683176336834762d357a272f3e3c7061746820643d274d3232203132762d31682d31762d31682d315639483476314833763148327631483176356834762d336831763168317631683176326838762d326831762d316831762d31683176336834762d357a272066696c6c3d272330303027206f7061636974793d272e3135272f3e3c7061746820643d274d313320335632682d32763268327a4d313320315630682d32763168317a4d313020344839563148387631483776314836763248357635683176326831763168317631683176316831762d324839762d3368325635682d317a4d313820355633682d315632682d315631682d317633682d317631682d31763568327633682d3176326831762d316831762d316831762d316831762d32683156357a272f3e3c7061746820636c6173733d276c756368612d626173652720643d274d3135203137483876336838762d337a272f3e3c7061746820636c6173733d276c756368612d616c742720643d274d31352031387631682d3276346833762d357a4d39203139762d31483876356833762d34682d317a272f3e3c7061746820636c6173733d276c756368612d626173652720643d274d33203135483176326834762d3248347a4d3232203135682d3376326834762d327a272f3e3c7061746820636c6173733d276c756368612d616c742720643d274d34203134483176316834762d317a272f3e3c7061746820636c6173733d276c756368612d626173652720643d274d36203256314835763568315635683156336831563248377a4d313820317631682d3276316831763268317631683156317a272f3e3c672066696c6c3d2723303030273e3c7061746820643d274d3520316831763148357a4d36203276316832563248377a4d3138203168317631682d317a4d31362032763168325632682d317a27206f7061636974793d272e33272f3e3c7061746820643d274d36203356324835763468315635683156337a4d313820327631682d31763268317631683156327a27206f7061636974793d272e32272f3e3c2f673e3c706174682066696c6c3d27234139413138412720643d274d323120325631682d315630682d31763268317631682d3376326832763168325635683156327a4d352033483456326831563048347631483376314832763368317631683256356832563348367a272f3e3c672066696c6c3d272330303027206f7061636974793d272e3135273e3c7061746820643d274d3231203468317631682d317a4d31392035682d31763168335635682d317a272f3e3c7061746820643d274d3220346831763148327a4d342035483376316833563548357a272f3e3c2f673e3c7061746820643d274d313820355633682d315632682d315631682d3156304839763148387631483776314836763248357635683176326831763168317631683176316831762d3468315635483956336831563268315631683276316831763168317632682d327636683176346831762d316831762d316831762d316831762d32683156357a272f3e3c7061746820643d274d31342032682d315630682d327632483976326832763468325634683256327a4d3132203133682d3176326832762d327a272f3e3c7061746820636c6173733d276c756368612d626173652720643d274d34203134483176316834762d317a4d3232203134682d3376316834762d317a272f3e3c7061746820636c6173733d276c756368612d626173652720643d274d31302039483476314833763148327631483176336834762d31683176316831763168317632683356397a4d3232203132762d31682d31762d31682d315639682d3776396833762d326831762d316831762d31683176316834762d337a272f3e3c7061746820643d274d31302039483476314833763148327631483176336834762d31683176316831763168317632683356397a4d3232203132762d31682d31762d31682d315639682d3776396833762d326831762d316831762d31683176316834762d337a272066696c6c3d272330303027206f7061636974793d272e3135272f3e3c7061746820636c6173733d276c756368612d616c742720643d274d323020313148337631326831762d316832762d3168313276316832763168315631317a272f3e3c672066696c6c3d2723303030273e3c70617468206f7061636974793d272e322720643d274d323020313176313268315631317a4d33203132763131683156313148337a272f3e3c70617468206f7061636974793d272e352720643d274d313920313148347631316832762d31683132763168325631317a272f3e3c2f673e3c7061746820643d274d31312030483976314838763148377631483676324835763568317632683176316831763168317631683356307a272f3e3c7061746820636c6173733d276c756368612d616c742720643d274d3135203137483876366833762d33683276336833762d367a272f3e3c7061746820643d274d313120326832563168315630682d34763168317a4d3620313076326831762d316831762d3148377a4d3137203130682d317631683176316831762d327a272f3e3c7061746820643d274d3136203368315632682d315631682d317631682d317631682d317631682d325633682d3156324839563148387631483776316831763168317631683176316831763968325636683156356831563468317a272f3e3c7061746820636c6173733d276c756368612d626173652720643d274d313620394837763368312d317634683176316838762d316831762d34682d31203156397a272f3e3c706174682066696c6c3d272330303027206f7061636974793d272e31352720643d274d3136203948377637683176316838762d31683156397a272f3e3c7061746820643d274d313720337631682d327631682d317631682d317633683556337a4d313120385636682d31563548395634483756334836763668357a4d313120313376326832762d32682d317a272f3e3c7061746820636c6173733d276c756368612d616c742720643d274d3920323248387631483776316834762d32682d317a4d3136203233762d31682d3376326834762d317a272f3e3c706174682066696c6c3d272334323163303327206f7061636974793d272e392720643d274d3134203130483976336831762d32683476326831762d337a272f3e3c7061746820636c6173733d276c756368612d626173652720643d274d313520397639683156397a4d3820313076386831563948387a272f3e3c7061746820643d274d3820313076386831563948387a4d313520397639683156397a272066696c6c3d272330303027206f7061636974793d272e3135272f3e3c7061746820643d274d313820355633682d315632682d317631682d317631682d317631682d317631682d325635682d3156344839563348385632483776314836763248357635683176326831762d316831762d31683356396832763168337631683176316831762d32683156357a272f3e3c7061746820643d274d31332033682d335632683156316831563048397631483876314837763148367632683376314838763248377632683156396831563868315637683156366831563568315634683156337a272f3e
Deployed Bytecode
0x6080604052600436106101dc5760003560e01c80636352211e11610102578063a22cb46511610095578063cd8ff65711610064578063cd8ff657146107cd578063e3684e39146107f7578063e985e9c514610821578063f2fde38b1461085c576101e3565b8063a22cb46514610680578063b88d4fde146106bb578063bb33d7291461078e578063c87b56dd146107a3576101e3565b8063735de9f7116100d1578063735de9f7146106115780638da5cb5b1461062657806394985ddd1461063b57806395d89b411461066b576101e3565b80636352211e1461058a5780636c0360eb146105b457806370a08231146105c9578063715018a6146105fc576101e3565b80632f745c591161017a57806355367ba91161014957806355367ba91461048a57806355f804b31461049f5780635a0a3a56146105525780635c975abb14610575576101e3565b80632f745c59146103cf5780633ccfd60b1461040857806342842e0e1461041d5780634f6ccce714610460576101e3565b8063081812fc116101b6578063081812fc146102e4578063095ea7b31461032a57806318160ddd1461036557806323b872dd1461038c576101e3565b806301ffc9a7146101e8578063061ba2f11461023057806306fdde03146102cf576101e3565b366101e357005b600080fd5b3480156101f457600080fd5b5061021c6004803603602081101561020b57600080fd5b50356001600160e01b03191661088f565b604080519115158252519081900360200190f35b34801561023c57600080fd5b5061025a6004803603602081101561025357600080fd5b50356108b2565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561029457818101518382015260200161027c565b50505050905090810190601f1680156102c15780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b3480156102db57600080fd5b5061025a611012565b3480156102f057600080fd5b5061030e6004803603602081101561030757600080fd5b50356110a8565b604080516001600160a01b039092168252519081900360200190f35b34801561033657600080fd5b506103636004803603604081101561034d57600080fd5b506001600160a01b03813516906020013561110a565b005b34801561037157600080fd5b5061037a6111e5565b60408051918252519081900360200190f35b34801561039857600080fd5b50610363600480360360608110156103af57600080fd5b506001600160a01b038135811691602081013590911690604001356111f6565b3480156103db57600080fd5b5061037a600480360360408110156103f257600080fd5b506001600160a01b03813516906020013561124d565b34801561041457600080fd5b50610363611278565b34801561042957600080fd5b506103636004803603606081101561044057600080fd5b506001600160a01b0381358116916020810135909116906040013561136e565b34801561046c57600080fd5b5061037a6004803603602081101561048357600080fd5b5035611389565b34801561049657600080fd5b5061036361139f565b3480156104ab57600080fd5b50610363600480360360208110156104c257600080fd5b8101906020810181356401000000008111156104dd57600080fd5b8201836020820111156104ef57600080fd5b8035906020019184600183028401116401000000008311171561051157600080fd5b91908080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525092955061140b945050505050565b6103636004803603604081101561056857600080fd5b5080359060200135611476565b34801561058157600080fd5b5061021c6118ac565b34801561059657600080fd5b5061030e600480360360208110156105ad57600080fd5b50356118b5565b3480156105c057600080fd5b5061025a6118dd565b3480156105d557600080fd5b5061037a600480360360208110156105ec57600080fd5b50356001600160a01b031661193e565b34801561060857600080fd5b506103636119a6565b34801561061d57600080fd5b5061030e611a58565b34801561063257600080fd5b5061030e611a67565b34801561064757600080fd5b506103636004803603604081101561065e57600080fd5b5080359060200135611a7b565b34801561067757600080fd5b5061025a611b06565b34801561068c57600080fd5b50610363600480360360408110156106a357600080fd5b506001600160a01b0381351690602001351515611b67565b3480156106c757600080fd5b50610363600480360360808110156106de57600080fd5b6001600160a01b0382358116926020810135909116916040820135919081019060808101606082013564010000000081111561071957600080fd5b82018360208201111561072b57600080fd5b8035906020019184600183028401116401000000008311171561074d57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550611c6c945050505050565b34801561079a57600080fd5b50610363611cca565b3480156107af57600080fd5b5061025a600480360360208110156107c657600080fd5b5035611d34565b3480156107d957600080fd5b50610363600480360360208110156107f057600080fd5b5035611e75565b34801561080357600080fd5b5061025a6004803603602081101561081a57600080fd5b5035611edc565b34801561082d57600080fd5b5061021c6004803603604081101561084457600080fd5b506001600160a01b0381358116916020013516612bb9565b34801561086857600080fd5b506103636004803603602081101561087f57600080fd5b50356001600160a01b0316612be7565b6001600160e01b0319811660009081526020819052604090205460ff165b919050565b60606108bd82612cf5565b61090e576040805162461bcd60e51b815260206004820152601c60248201527f696d616765446174613a206e6f6e6578697374656e7420746f6b656e00000000604482015290519081900360640190fd5b6000828152601f602052604090205461096e576040805162461bcd60e51b815260206004820181905260248201527f696d616765446174613a20646e61206e6f74207965742067656e657261746564604482015290519081900360640190fd5b610976614518565b6000838152601f602052604090205461098e90612d02565b90506060816001602002015160ff1615806109b05750602082015160ff166001145b6109c957604051806020016040528060008152506109e3565b6040518060c00160405280609d8152602001614eaa609d91395b90506060826001602002015160ff16600114610a0e5760405180602001604052806000815250610a2b565b60405180610180016040528061014c8152602001614c6e61014c91395b9050610a3685612d50565b610a408685612e2b565b845160ff9081166000908152601760209081526040808320828a01518516845260188352818420828b0151861685526019845282852060608c015187168652601a855283862060808d015188168752601b865284872060a08e015189168852601c875285882060c08f01519099168852601d9096529386206001938401979284019691840195948401948c94908101938c939082019290910190601e908f6007602002015160ff1681526020019081526020016000206001016040516020018080701e39bb339034b21e93b63ab1b430b237b960791b8152506011018d805190602001908083835b60208310610b475780518252601f199092019160209182019101610b28565b6001836020036101000a03801982511681845116808217855250505050505090500180614f78603991396039018c805190602001908083835b60208310610b9f5780518252601f199092019160209182019101610b80565b6001836020036101000a038019825116818451168082178552505050505050905001807f3c6720636c6173733d276c756368612d62726561746865273e000000000000008152506019018b805460018160011615610100020316600290048015610c405780601f10610c1e576101008083540402835291820191610c40565b820191906000526020600020905b815481529060010190602001808311610c2c575b50508a805460018160011615610100020316600290048015610c995780601f10610c77576101008083540402835291820191610c99565b820191906000526020600020905b815481529060010190602001808311610c85575b505080614dfd60ad913960ad0189805460018160011615610100020316600290048015610cfd5780601f10610cdb576101008083540402835291820191610cfd565b820191906000526020600020905b815481529060010190602001808311610ce9575b505088805460018160011615610100020316600290048015610d565780601f10610d34576101008083540402835291820191610d56565b820191906000526020600020905b815481529060010190602001808311610d42575b5050875160208901908083835b60208310610d825780518252601f199092019160209182019101610d63565b6001836020036101000a03801982511681845116808217855250505050505090500180614bcc6072913960720180741e339031b630b9b99e93b63ab1b43096b0b63a139f60591b81525060150186805460018160011615610100020316600290048015610e265780601f10610e04576101008083540402835291820191610e26565b820191906000526020600020905b815481529060010190602001808311610e12575b505080631e17b39f60e11b81525060040185805190602001908083835b60208310610e625780518252601f199092019160209182019101610e43565b6001836020036101000a0380198251168184511680821785525050505050509050018061477960de913960de01602f614fb18239602f01603661465b823960360184805460018160011615610100020316600290048015610efa5780601f10610ed8576101008083540402835291820191610efa565b820191906000526020600020905b815481529060010190602001808311610ee6575b5050631e17b39f60e11b8152600401603f6148578239603f0160416148ee823960410183805460018160011615610100020316600290048015610f745780601f10610f52576101008083540402835291820191610f74565b820191906000526020600020905b815481529060010190602001808311610f60575b505080614b0b6049913960490182805460018160011615610100020316600290048015610fd85780601f10610fb6576101008083540402835291820191610fd8565b820191906000526020600020905b815481529060010190602001808311610fc4575b505080651e17b9bb339f60d11b8152506006019c505050505050505050505050506040516020818303038152906040529350505050919050565b60068054604080516020601f600260001961010060018816150201909516949094049384018190048102820181019092528281526060939092909183018282801561109e5780601f106110735761010080835404028352916020019161109e565b820191906000526020600020905b81548152906001019060200180831161108157829003601f168201915b5050505050905090565b60006110b382612cf5565b6110ee5760405162461bcd60e51b815260040180806020018281038252602c815260200180614adf602c913960400191505060405180910390fd5b506000908152600460205260409020546001600160a01b031690565b6000611115826118b5565b9050806001600160a01b0316836001600160a01b031614156111685760405162461bcd60e51b8152600401808060200182810382526021815260200180614dba6021913960400191505060405180910390fd5b806001600160a01b031661117a6132f5565b6001600160a01b0316148061119b575061119b816111966132f5565b612bb9565b6111d65760405162461bcd60e51b81526004018080602001828103825260388152602001806149a56038913960400191505060405180910390fd5b6111e083836132f9565b505050565b60006111f16002613367565b905090565b6112076112016132f5565b82613372565b6112425760405162461bcd60e51b8152600401808060200182810382526031815260200180614f476031913960400191505060405180910390fd5b6111e0838383613416565b6001600160a01b038216600090815260016020526040812061126f9083613562565b90505b92915050565b6112806132f5565b6001600160a01b0316611291611a67565b6001600160a01b0316146112da576040805162461bcd60e51b81526020600482018190526024820152600080516020614b54833981519152604482015290519081900360640190fd5b604051600090339047908381818185875af1925050503d806000811461131c576040519150601f19603f3d011682016040523d82523d6000602084013e611321565b606091505b505090508061136b576040805162461bcd60e51b815260206004820152601160248201527015da5d1a191c985dd85b0819985a5b1959607a1b604482015290519081900360640190fd5b50565b6111e083838360405180602001604052806000815250611c6c565b60008061139760028461356e565b509392505050565b6113a76132f5565b6001600160a01b03166113b8611a67565b6001600160a01b031614611401576040805162461bcd60e51b81526020600482018190526024820152600080516020614b54833981519152604482015290519081900360640190fd5b61140961358a565b565b6114136132f5565b6001600160a01b0316611424611a67565b6001600160a01b03161461146d576040805162461bcd60e51b81526020600482018190526024820152600080516020614b54833981519152604482015290519081900360640190fd5b61136b8161362a565b6002600b5414156114ce576040805162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015290519081900360640190fd5b6002600b556114db6118ac565b15611520576040805162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b604482015290519081900360640190fd5b61271061152d600d61363d565b1061157f576040805162461bcd60e51b815260206004820152601a60248201527f6d6178696d756d206c75636861646f7265732072656163686564000000000000604482015290519081900360640190fd5b6127108261158d600d61363d565b0111156115e1576040805162461bcd60e51b815260206004820181905260248201527f6d696e74207175616e746974792065786365656473206d617820737570706c79604482015290519081900360640190fd5b6000821180156115f2575060148211155b61162d5760405162461bcd60e51b8152600401808060200182810382526022815260200180614ddb6022913960400191505060405180910390fd5b6010546040805160028082526060808301845293860293926020830190803683375050600e54604080516315ab88c960e31b815290519394506001600160a01b039091169263ad5c464892506004808301926020929190829003018186803b15801561169857600080fd5b505afa1580156116ac573d6000803e3d6000fd5b505050506040513d60208110156116c257600080fd5b5051815182906000906116d157fe5b6001600160a01b0392831660209182029290920101526012548251911690829060019081106116fc57fe5b6001600160a01b03928316602091820292909201810191909152600e5460405163fb3bdb4160e01b815260048101868152306044830181905260648301899052608060248401908152875160848501528751949096169563fb3bdb419534958a958a958d949093909260a490920191878201910280838360005b8381101561178e578181015183820152602001611776565b50505050905001955050505050506000604051808303818588803b1580156117b557600080fd5b505af11580156117c9573d6000803e3d6000fd5b50505050506040513d6000823e601f3d908101601f1916820160405260208110156117f357600080fd5b810190808051604051939291908464010000000082111561181357600080fd5b90830190602082018581111561182857600080fd5b825186602082028301116401000000008211171561184557600080fd5b82525081516020918201928201910280838360005b8381101561187257818101518382015260200161185a565b505050509050016040525050505060005b848110156118a0576118984382900340613641565b600101611883565b50506001600b55505050565b600a5460ff1690565b600061127282604051806060016040528060298152602001614a076029913960029190613781565b60098054604080516020601f600260001961010060018816150201909516949094049384018190048102820181019092528281526060939092909183018282801561109e5780601f106110735761010080835404028352916020019161109e565b60006001600160a01b0382166119855760405162461bcd60e51b815260040180806020018281038252602a8152602001806149dd602a913960400191505060405180910390fd5b6001600160a01b038216600090815260016020526040902061127290613367565b6119ae6132f5565b6001600160a01b03166119bf611a67565b6001600160a01b031614611a08576040805162461bcd60e51b81526020600482018190526024820152600080516020614b54833981519152604482015290519081900360640190fd5b600a5460405160009161010090046001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600a8054610100600160a81b0319169055565b600e546001600160a01b031681565b600a5461010090046001600160a01b031690565b336001600160a01b037f000000000000000000000000f0d54349addcf704f77ae15b96510dea15cb79521614611af8576040805162461bcd60e51b815260206004820152601f60248201527f4f6e6c7920565246436f6f7264696e61746f722063616e2066756c66696c6c00604482015290519081900360640190fd5b611b02828261378e565b5050565b60078054604080516020601f600260001961010060018816150201909516949094049384018190048102820181019092528281526060939092909183018282801561109e5780601f106110735761010080835404028352916020019161109e565b611b6f6132f5565b6001600160a01b0316826001600160a01b03161415611bd5576040805162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c657200000000000000604482015290519081900360640190fd5b8060056000611be26132f5565b6001600160a01b03908116825260208083019390935260409182016000908120918716808252919093529120805460ff191692151592909217909155611c266132f5565b6001600160a01b03167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c318360405180821515815260200191505060405180910390a35050565b611c7d611c776132f5565b83613372565b611cb85760405162461bcd60e51b8152600401808060200182810382526031815260200180614f476031913960400191505060405180910390fd5b611cc4848484846137ea565b50505050565b611cd26132f5565b6001600160a01b0316611ce3611a67565b6001600160a01b031614611d2c576040805162461bcd60e51b81526020600482018190526024820152600080516020614b54833981519152604482015290519081900360640190fd5b61140961383c565b6060611d3f82612cf5565b611d7a5760405162461bcd60e51b815260040180806020018281038252602f815260200180614b9d602f913960400191505060405180910390fd5b6060611d846118dd565b90506000815111611da45760405180602001604052806000815250611e6e565b80611dae84612d50565b6040516020018083805190602001908083835b60208310611de05780518252601f199092019160209182019101611dc1565b51815160209384036101000a600019018019909216911617905285519190930192850191508083835b60208310611e285780518252601f199092019160209182019101611e09565b6001836020036101000a0380198251168184511680821785525050505050509050018064173539b7b760d91b815250600501925050506040516020818303038152906040525b9392505050565b611e7d6132f5565b6001600160a01b0316611e8e611a67565b6001600160a01b031614611ed7576040805162461bcd60e51b81526020600482018190526024820152600080516020614b54833981519152604482015290519081900360640190fd5b601055565b6060611ee782612cf5565b611f38576040805162461bcd60e51b815260206004820152601b60248201527f6d657461646174613a206e6f6e6578697374656e7420746f6b656e0000000000604482015290519081900360640190fd5b6000828152601f6020526040902054611f98576040805162461bcd60e51b815260206004820152601f60248201527f6d657461646174613a20646e61206e6f74207965742067656e65726174656400604482015290519081900360640190fd5b611fa0614518565b6000838152601f6020526040902054611fb890612d02565b9050611fc2614537565b60408051610100808201808452855160ff166000908152601760209081529085902061014085018652805460a01b6001600160a01b0319168352600180820180548851600293821615909702600019011691909104601f8101849004840286018401909752868552949586959394919361012087019390919083018282801561208c5780601f106120615761010080835404028352916020019161208c565b820191906000526020600020905b81548152906001019060200180831161206f57829003601f168201915b50505091909252505050815260208481015160ff1660009081526018825260409081902081518083018352815460a01b6001600160a01b0319168152600180830180548551600261010094831615949094026000190190911692909204601f810187900487028301870190955284825295850195919492938584019391929183018282801561215c5780601f106121315761010080835404028352916020019161215c565b820191906000526020600020905b81548152906001019060200180831161213f57829003601f168201915b50505091909252505050815260408481015160ff166000908152601960209081529082902082518084018452815460a01b6001600160a01b0319168152600180830180548651600261010094831615949094026000190190911692909204601f81018690048602830186019096528582529584019591949293858101939192919083018282801561222e5780601f106122035761010080835404028352916020019161222e565b820191906000526020600020905b81548152906001019060200180831161221157829003601f168201915b505050919092525050508152606084015160ff166000908152601a602090815260409182902082518084018452815460a01b6001600160a01b0319168152600180830180548651600261010094831615949094026000190190911692909204601f8101869004860283018601909652858252958401959194929385810193919291908301828280156123015780601f106122d657610100808354040283529160200191612301565b820191906000526020600020905b8154815290600101906020018083116122e457829003601f168201915b505050919092525050508152608084015160ff166000908152601b602090815260409182902082518084018452815460a01b6001600160a01b0319168152600180830180548651600261010094831615949094026000190190911692909204601f8101869004860283018601909652858252958401959194929385810193919291908301828280156123d45780601f106123a9576101008083540402835291602001916123d4565b820191906000526020600020905b8154815290600101906020018083116123b757829003601f168201915b50505091909252505050815260a08481015160ff166000908152601c602090815260409182902082518084018452815490941b6001600160a01b0319168452600180820180548551600261010094831615949094026000190190911692909204601f8101859004850283018501909552848252958301959193858401939192918301828280156124a55780601f1061247a576101008083540402835291602001916124a5565b820191906000526020600020905b81548152906001019060200180831161248857829003601f168201915b50505091909252505050815260c084015160ff166000908152601d602090815260409182902082518084018452815460a01b6001600160a01b0319168152600180830180548651600261010094831615949094026000190190911692909204601f8101869004860283018601909652858252958401959194929385810193919291908301828280156125785780601f1061254d57610100808354040283529160200191612578565b820191906000526020600020905b81548152906001019060200180831161255b57829003601f168201915b50505091909252505050815260e084015160ff166000908152601e602090815260409182902082518084018452815460a01b6001600160a01b0319168152600180830180548651600261010094831615949094026000190190911692909204601f81018690048602830186019096528582529584019591949293858101939192919083018282801561264b5780601f106126205761010080835404028352916020019161264b565b820191906000526020600020905b81548152906001019060200180831161262e57829003601f168201915b50505050508152505081525090506060612663614565565b506040805161014081018252600661010082019081526514dc1a5c9a5d60d21b6101208301528152815180830183526004808252634361706560e01b6020838101919091528084019290925283518085018552600580825264546f72736f60d81b8285015284860191909152845180860186528281526341726d7360e01b81850152606085015284518086018652918252634d61736b60e01b828401526080840191909152835180850185528181526409adeeae8d60db1b8184015260a0840152835180850185526007815266426f74746f6d7360c81b8184015260c08401528351808501909452835264426f6f747360d81b9083015260e081019190915260005b60088110156129a15783816008811061277a57fe5b6020020151516001600160a01b03191661279357612999565b8283516000146127be57604051806040016040528060038152602001622c207b60e81b8152506127d9565b604051806040016040528060018152602001607b60f81b8152505b8383600881106127e557fe5b60200201516128048785600881106127f957fe5b6020020151516138bf565b6040516020018085805190602001908083835b602083106128365780518252601f199092019160209182019101612817565b51815160209384036101000a600019018019909216911617905287519190930192870191508083835b6020831061287e5780518252601f19909201916020918201910161285f565b51815160209384036101000a60001901801990921691161790526e113a3930b4ba2fba3cb832911d101160891b919093019081528551600f90910192860191508083835b602083106128e15780518252601f1990920191602091820191016128c2565b51815160209384036101000a600019018019909216911617905261088b60f21b9190930190815269113b30b63ab2911d101160b11b60028201528451600c90910192850191508083835b6020831061294a5780518252601f19909201916020918201910161292b565b5181516020939093036101000a6000190180199091169216919091179052601160f91b920191825250607d60f81b600182015260408051808303601d1901815260029092019052975050505050505b600101612765565b506129ab86612d50565b6129b4876108b2565b6129bd88612d50565b604051607b60f81b602080830191825272226e616d65223a20224c75636861646f72202360681b602184015285518893603401918701908083835b60208310612a175780518252601f1990920191602091820191016129f8565b5181516020939093036101000a600019018019909116921691909117905261088b60f21b920191825250600201608d614a528239608d01806e1134b6b0b3b2afb230ba30911d101160891b815250600f0184805190602001908083835b60208310612a935780518252601f199092019160209182019101612a74565b5181516020939093036101000a600019018019909116921691909117905261088b60f21b9201918252506002016030614c3e823960300183805190602001908083835b60208310612af55780518252601f199092019160209182019101612ad6565b51815160209384036101000a600019018019909216911617905261088b60f21b919093019081526e2261747472696275746573223a205b60881b60028201528451601190910192850191508083835b60208310612b635780518252601f199092019160209182019101612b44565b5181516020939093036101000a6000190180199091169216919091179052605d60f81b920191825250607d60f81b600182015260408051808303601d19018152600290920190529b9a5050505050505050505050565b6001600160a01b03918216600090815260056020908152604080832093909416825291909152205460ff1690565b612bef6132f5565b6001600160a01b0316612c00611a67565b6001600160a01b031614612c49576040805162461bcd60e51b81526020600482018190526024820152600080516020614b54833981519152604482015290519081900360640190fd5b6001600160a01b038116612c8e5760405162461bcd60e51b81526004018080602001828103825260268152602001806148c86026913960400191505060405180910390fd5b600a546040516001600160a01b0380841692610100900416907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3600a80546001600160a01b0390921661010002610100600160a81b0319909216919091179055565b60006112726002836139c5565b612d0a614518565b612d12614518565b60005b600c811015612d4957600a84068282600c8110612d2e57fe5b60ff9092166020929092020152600a84049350600101612d15565b5092915050565b606081612d7557506040805180820190915260018152600360fc1b60208201526108ad565b8160005b8115612d8d57600101600a82049150612d79565b60608167ffffffffffffffff81118015612da657600080fd5b506040519080825280601f01601f191660200182016040528015612dd1576020820181803683370190505b50859350905060001982015b8315612e2257600a840660300160f81b82828060019003935081518110612e0057fe5b60200101906001600160f81b031916908160001a905350600a84049350612ddd565b50949350505050565b6060612e3683612d50565b6013836008602002015160ff1681548110612e4d57fe5b90600052602060002001612e6085612d50565b6014856009602002015160ff1681548110612e7757fe5b90600052602060002001612e8a87612d50565b601587600a602002015160ff1681548110612ea157fe5b90600052602060002001612eb489612d50565b601689600b602002015160ff1681548110612ecb57fe5b90600052602060002001612ede8b612d50565b60405160200180806f1e39ba3cb6329f11b63ab1b430b237b960811b8152506010018a805190602001908083835b60208310612f2b5780518252601f199092019160209182019101612f0c565b6001836020036101000a0380198251168184511680821785525050505050509050018075202e6c756368612d62617365207b2066696c6c3a202360501b81525060160189805460018160011615610100020316600290048015612fc55780601f10612fa3576101008083540402835291820191612fc5565b820191906000526020600020905b815481529060010190602001808311612fb1575b5050806c1d903e9011b63ab1b430b237b960991b815250600d0188805190602001908083835b6020831061300a5780518252601f199092019160209182019101612feb565b6001836020036101000a0380198251168184511680821785525050505050509050018074202e6c756368612d616c74207b2066696c6c3a202360581b815250601501878054600181600116156101000203166002900480156130a35780601f106130815761010080835404028352918201916130a3565b820191906000526020600020905b81548152906001019060200180831161308f575b5050806c1d903e9011b63ab1b430b237b960991b815250600d0186805190602001908083835b602083106130e85780518252601f1990920191602091820191016130c9565b6001836020036101000a0380198251168184511680821785525050505050509050018075202e6c756368612d65796573207b2066696c6c3a202360501b815250601601858054600181600116156101000203166002900480156131825780601f10613160576101008083540402835291820191613182565b820191906000526020600020905b81548152906001019060200180831161316e575b5050806c1d903e9011b63ab1b430b237b960991b815250600d0184805190602001908083835b602083106131c75780518252601f1990920191602091820191016131a8565b6001836020036101000a0380198251168184511680821785525050505050509050018075202e6c756368612d736b696e207b2066696c6c3a202360501b815250601601838054600181600116156101000203166002900480156132615780601f1061323f576101008083540402835291820191613261565b820191906000526020600020905b81548152906001019060200180831161324d575b5050806c1d903e9011b63ab1b430b237b960991b815250600d0182805190602001908083835b602083106132a65780518252601f199092019160209182019101613287565b6001836020036101000a038019825116818451168082178552505050505050905001806146bc60bd913960bd019950505050505050505050604051602081830303815290604052905092915050565b3390565b600081815260046020526040902080546001600160a01b0319166001600160a01b038416908117909155819061332e826118b5565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b60006112728261363d565b600061337d82612cf5565b6133b85760405162461bcd60e51b815260040180806020018281038252602c815260200180614979602c913960400191505060405180910390fd5b60006133c3836118b5565b9050806001600160a01b0316846001600160a01b031614806133fe5750836001600160a01b03166133f3846110a8565b6001600160a01b0316145b8061340e575061340e8185612bb9565b949350505050565b826001600160a01b0316613429826118b5565b6001600160a01b03161461346e5760405162461bcd60e51b8152600401808060200182810382526029815260200180614b746029913960400191505060405180910390fd5b6001600160a01b0382166134b35760405162461bcd60e51b815260040180806020018281038252602481526020018061492f6024913960400191505060405180910390fd5b6134be8383836139d1565b6134c96000826132f9565b6001600160a01b03831660009081526001602052604090206134eb9082613a20565b506001600160a01b038216600090815260016020526040902061350e9082613a2c565b5061351b60028284613a38565b5080826001600160a01b0316846001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4505050565b600061126f8383613a4e565b600080808061357d8686613ab2565b9097909650945050505050565b6135926118ac565b156135d7576040805162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b604482015290519081900360640190fd5b600a805460ff191660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a25861360d6132f5565b604080516001600160a01b039092168252519081900360200190a1565b8051611b0290600990602084019061458d565b5490565b601054604080516370a0823160e01b815230600482015290516001600160a01b037f000000000000000000000000514910771af9ca656af840dff83e8264ecf986ca16916370a08231916024808301926020929190829003018186803b1580156136aa57600080fd5b505afa1580156136be573d6000803e3d6000fd5b505050506040513d60208110156136d457600080fd5b50511015613729576040805162461bcd60e51b815260206004820152601f60248201527f4e6f7420656e6f756768204c494e4b202d2066696c6c20636f6e747261637400604482015290519081900360640190fd5b600061373a600f5460105484613b2d565b9050613746600d613ce0565b604051806020016040528061375b600d61363d565b90526000828152602080526040902090519055611b023361377c600d61363d565b613ce9565b600061340e848484613d03565b60008281526020808052604080832080548452601f83528184208590559285905281805291548251848152925190927f1d584699e20b45cf7fb70771dbd92bb407c244dd750faf0d3c3108aaae7d0e7292908290030190a25050565b6137f5848484613416565b61380184848484613dcd565b611cc45760405162461bcd60e51b81526004018080602001828103825260328152602001806148966032913960400191505060405180910390fd5b6138446118ac565b61388c576040805162461bcd60e51b815260206004820152601460248201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b604482015290519081900360640190fd5b600a805460ff191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa61360d6132f5565b606060005b600c8160ff161080156138f25750828160ff16600c81106138e157fe5b1a60f81b6001600160f81b03191615155b156138ff576001016138c4565b60608160ff1667ffffffffffffffff8111801561391b57600080fd5b506040519080825280601f01601f191660200182016040528015613946576020820181803683370190505b509050600091505b600c8260ff1610801561397c5750838260ff16600c811061396b57fe5b1a60f81b6001600160f81b03191615155b15611e6e57838260ff16600c811061399057fe5b1a60f81b818360ff16815181106139a357fe5b60200101906001600160f81b031916908160001a90535060019091019061394e565b600061126f8383613f35565b6139dc8383836111e0565b6139e46118ac565b156111e05760405162461bcd60e51b815260040180806020018281038252602b815260200180614691602b913960400191505060405180910390fd5b600061126f8383613f4d565b600061126f8383614013565b600061340e84846001600160a01b03851661405d565b81546000908210613a905760405162461bcd60e51b81526004018080602001828103825260228152602001806146396022913960400191505060405180910390fd5b826000018281548110613a9f57fe5b9060005260206000200154905092915050565b815460009081908310613af65760405162461bcd60e51b8152600401808060200182810382526022815260200180614a306022913960400191505060405180910390fd5b6000846000018481548110613b0757fe5b906000526020600020906002020190508060000154816001015492509250509250929050565b60007f000000000000000000000000514910771af9ca656af840dff83e8264ecf986ca6001600160a01b0316634000aea07f000000000000000000000000f0d54349addcf704f77ae15b96510dea15cb795285878660405160200180838152602001828152602001925050506040516020818303038152906040526040518463ffffffff1660e01b815260040180846001600160a01b0316815260200183815260200180602001828103825283818151815260200191508051906020019080838360005b83811015613c09578181015183820152602001613bf1565b50505050905090810190601f168015613c365780820380516001836020036101000a031916815260200191505b50945050505050602060405180830381600087803b158015613c5757600080fd5b505af1158015613c6b573d6000803e3d6000fd5b505050506040513d6020811015613c8157600080fd5b50506000848152600c6020526040812054613ca1908690859030906140f4565b6000868152600c6020526040902054909150613cbe90600161413b565b6000868152600c6020526040902055613cd78582614195565b95945050505050565b80546001019055565b611b028282604051806020016040528060008152506141c1565b60008281526001840160205260408120548281613d9e5760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015613d63578181015183820152602001613d4b565b50505050905090810190601f168015613d905780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b50846000016001820381548110613db157fe5b9060005260206000209060020201600101549150509392505050565b6000613de1846001600160a01b0316614213565b613ded5750600161340e565b6060613efb630a85bd0160e11b613e026132f5565b88878760405160240180856001600160a01b03168152602001846001600160a01b0316815260200183815260200180602001828103825283818151815260200191508051906020019080838360005b83811015613e69578181015183820152602001613e51565b50505050905090810190601f168015613e965780820380516001836020036101000a031916815260200191505b5095505050505050604051602081830303815290604052906001600160e01b0319166020820180516001600160e01b038381831617835250505050604051806060016040528060328152602001614896603291396001600160a01b0388169190614219565b90506000818060200190516020811015613f1457600080fd5b50516001600160e01b031916630a85bd0160e11b1492505050949350505050565b60009081526001919091016020526040902054151590565b600081815260018301602052604081205480156140095783546000198083019190810190600090879083908110613f8057fe5b9060005260206000200154905080876000018481548110613f9d57fe5b600091825260208083209091019290925582815260018981019092526040902090840190558654879080613fcd57fe5b60019003818190600052602060002001600090559055866001016000878152602001908152602001600020600090556001945050505050611272565b6000915050611272565b600061401f8383613f35565b61405557508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155611272565b506000611272565b6000828152600184016020526040812054806140c2575050604080518082018252838152602080820184815286546001818101895560008981528481209551600290930290950191825591519082015586548684528188019092529290912055611e6e565b828560000160018303815481106140d557fe5b9060005260206000209060020201600101819055506000915050611e6e565b60408051602080820196909652808201949094526001600160a01b039290921660608401526080808401919091528151808403909101815260a09092019052805191012090565b60008282018381101561126f576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b604080516020808201949094528082019290925280518083038201815260609092019052805191012090565b6141cb8383614228565b6141d86000848484613dcd565b6111e05760405162461bcd60e51b81526004018080602001828103825260328152602001806148966032913960400191505060405180910390fd5b3b151590565b606061340e8484600085614356565b6001600160a01b038216614283576040805162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f2061646472657373604482015290519081900360640190fd5b61428c81612cf5565b156142de576040805162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e74656400000000604482015290519081900360640190fd5b6142ea600083836139d1565b6001600160a01b038216600090815260016020526040902061430c9082613a2c565b5061431960028284613a38565b5060405181906001600160a01b038416906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b6060824710156143975760405162461bcd60e51b81526004018080602001828103825260268152602001806149536026913960400191505060405180910390fd5b6143a085614213565b6143f1576040805162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015290519081900360640190fd5b60006060866001600160a01b031685876040518082805190602001908083835b602083106144305780518252601f199092019160209182019101614411565b6001836020036101000a03801982511681845116808217855250505050505090500191505060006040518083038185875af1925050503d8060008114614492576040519150601f19603f3d011682016040523d82523d6000602084013e614497565b606091505b50915091506144a78282866144b2565b979650505050505050565b606083156144c1575081611e6e565b8251156144d15782518084602001fd5b60405162461bcd60e51b8152602060048201818152845160248401528451859391928392604401919085019080838360008315613d63578181015183820152602001613d4b565b604051806101800160405280600c906020820280368337509192915050565b6040518061010001604052806008905b61454f61460b565b8152602001906001900390816145475790505090565b6040518061010001604052806008905b60608152602001906001900390816145755790505090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106145ce57805160ff19168380011785556145fb565b828001600101855582156145fb579182015b828111156145fb5782518255916020019190600101906145e0565b50614607929150614623565b5090565b60408051808201909152600081526060602082015290565b5b80821115614607576000815560010161462456fe456e756d657261626c655365743a20696e646578206f7574206f6620626f756e64733c706174682066696c6c3d272330303027206f7061636974793d272e392720643d274d3133203131682d3376316834762d317a272f3e4552433732315061757361626c653a20746f6b656e207472616e73666572207768696c6520706175736564202e6c756368612d62726561746865207b20616e696d6174696f6e3a20302e3573206c756368612d6272656174686520696e66696e69746520616c7465726e61746520656173652d696e2d6f75743b207d20406b65796672616d6573206c756368612d62726561746865207b2066726f6d207b207472616e73666f726d3a207472616e736c6174655928307078293b207d20746f207b207472616e73666f726d3a207472616e736c61746559283125293b207d207d3c2f7374796c653e3c706174682066696c6c3d27234646462720643d274d39203648367633683456367a4d31372036682d337633683456367a272f3e3c7061746820636c6173733d276c756368612d657965732720643d274d31362036682d327633683356367a4d382036483776336833563648397a272f3e3c706174682066696c6c3d27234646462720643d274d3720366831763148377a4d3136203668317631682d317a27206f7061636974793d272e34272f3e3c706174682066696c6c3d27233030302720643d274d3135203768317631682d317a4d3820376831763148387a272f3e3c7061746820636c6173733d276c756368612d736b696e2720643d274d3136203233762d3648387636483776316834762d34683276346834762d317a272f3e4552433732313a207472616e7366657220746f206e6f6e20455243373231526563656976657220696d706c656d656e7465724f776e61626c653a206e6577206f776e657220697320746865207a65726f20616464726573733c7061746820636c6173733d276c756368612d626173652720643d274d31352031374838763168317631683276316832762d316832762d316831762d317a272f3e4552433732313a207472616e7366657220746f20746865207a65726f2061646472657373416464726573733a20696e73756666696369656e742062616c616e636520666f722063616c6c4552433732313a206f70657261746f7220717565727920666f72206e6f6e6578697374656e7420746f6b656e4552433732313a20617070726f76652063616c6c6572206973206e6f74206f776e6572206e6f7220617070726f76656420666f7220616c6c4552433732313a2062616c616e636520717565727920666f7220746865207a65726f20616464726573734552433732313a206f776e657220717565727920666f72206e6f6e6578697374656e7420746f6b656e456e756d657261626c654d61703a20696e646578206f7574206f6620626f756e6473226465736372697074696f6e223a20224c75636861646f726573206172652072616e646f6d6c792067656e657261746564207573696e6720436861696e6c696e6b2056524620616e6420686176652031303025206f6e2d636861696e2061727420616e64206d65746164617461202d204f6e6c792031303030302077696c6c206576657220657869737421222c4552433732313a20617070726f76656420717565727920666f72206e6f6e6578697374656e7420746f6b656e3c7061746820636c6173733d276c756368612d626173652720643d274d3920323148387632483776316834762d33682d317a4d3136203233762d32682d3376336834762d317a272f3e4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65724552433732313a207472616e73666572206f6620746f6b656e2074686174206973206e6f74206f776e4552433732314d657461646174613a2055524920717565727920666f72206e6f6e6578697374656e7420746f6b656e3c7061746820636c6173733d276c756368612d626173652720643d274d313820355633682d315632682d315631682d3156304839763148387631483776314836763248357635683176326831763168317631683176316836762d316831762d316831762d316831762d32683156357a272f3e2265787465726e616c5f75726c223a202268747470733a2f2f6c75636861646f7265732e696f2f6c75636861646f722f3c7061746820636c6173733d276c756368612d616c742720643d274d313820345633682d315632682d315631682d3156304839763148387631483776314836763248357635683156366831563568325634683156336834763168317631683276316831763468315635682d317a272f3e3c672066696c6c3d2723303030273e3c7061746820643d274d313820345633682d315632682d315631682d3156304839763148387631483776314836763248357635683156356831563468315633683156326836763168317631683176316831763568315635682d317a27206f7061636974793d272e32272f3e3c7061746820643d274d313620345633682d31563248397631483876314837763168325634683156336834763168317631683256347a4d3620356831763148367a4d3137203568317631682d317a27206f7061636974793d272e35272f3e3c2f673e4552433732313a20617070726f76616c20746f2063757272656e74206f776e65726d696e74207175616e74697479206d757374206265206265747765656e20312d32303c7061746820636c6173733d276c756368612d736b696e2720643d274d3232203132762d31682d31762d31682d315639682d315635682d315633682d315632682d315631682d3156304839763148387631483776314836763248357634483476314833763148327631483176386834762d316831762d324835762d336831763168317631683176326838762d326831762d316831762d3168317633682d317632683176316834762d387a272f3e3c7061746820636c6173733d276c756368612d616c742720643d274d32302031305639682d327631682d3176316834762d317a4d35203948347631483376316834762d31483656397a272f3e3c706174682066696c6c3d272330303027206f7061636974793d272e322720643d274d36203948347631483376316834762d3148367a4d32302031305639682d327631682d3176316834762d317a272f3e4552433732313a207472616e736665722063616c6c6572206973206e6f74206f776e6572206e6f7220617070726f7665642720786d6c6e733d27687474703a2f2f7777772e77332e6f72672f323030302f737667272076696577426f783d27302030203234203234273e3c7061746820636c6173733d276c756368612d736b696e2720643d274d3134203130483976336836762d337a272f3ea2646970667358221220f07ff78f47503188bddd1cb2cc6410513aab09c35bef87db8e84d77cf54338e964736f6c634300060c0033
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
[ Download: CSV Export ]
A token is a representation of an on-chain or off-chain asset. The token page shows information such as price, total supply, holders, transfers and social links. Learn more about this page in our Knowledge Base.