Feature Tip: Add private address tag to any address under My Name Tag !
Source Code
Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
TokenTracker
Latest 1 internal transaction
Advanced mode:
| Parent Transaction Hash | Method | Block |
From
|
|
To
|
||
|---|---|---|---|---|---|---|---|
| - | 13175739 | 1649 days ago | 0.3 ETH |
Loading...
Loading
Loading...
Loading
Cross-Chain Transactions
Loading...
Loading
This contract may be a proxy contract. Click on More Options and select Is this a proxy? to confirm and enable the "Read as Proxy" & "Write as Proxy" tabs.
Contract Name:
LootRock
Compiler Version
v0.8.0+commit.c7dfd78e
Contract Source Code (Solidity)
/**
*Submitted for verification at Etherscan.io on 2021-09-05
*/
// SPDX-License-Identifier: MIT
// File: @openzeppelin/contracts/utils/Context.sol
pragma solidity ^0.8.0;
/**
* @dev Provides information about the current execution context, including the
* sender of the transaction and its data. While these are generally available
* via msg.sender and msg.data, they should not be accessed in such a direct
* manner, since when dealing with meta-transactions the account sending and
* paying for execution may not be the actual sender (as far as an application
* is concerned).
*
* This contract is only required for intermediate, library-like contracts.
*/
abstract contract Context {
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
}
// File: libraries/HexStrings.sol
pragma solidity ^0.8.0;
library HexStrings {
bytes16 internal constant ALPHABET = '0123456789abcdef';
/// @notice Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.
/// @dev Credit to Open Zeppelin under MIT license https://github.com/OpenZeppelin/openzeppelin-contracts/blob/243adff49ce1700e0ecb99fe522fb16cff1d1ddc/contracts/utils/Strings.sol#L55
function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {
bytes memory buffer = new bytes(2 * length + 2);
buffer[0] = '0';
buffer[1] = 'x';
for (uint256 i = 2 * length + 1; i > 1; --i) {
buffer[i] = ALPHABET[value & 0xf];
value >>= 4;
}
require(value == 0, 'Strings: hex length insufficient');
return string(buffer);
}
function toHexStringNoPrefix(uint256 value, uint256 length) internal pure returns (string memory) {
bytes memory buffer = new bytes(2 * length);
for (uint256 i = buffer.length; i > 0; i--) {
buffer[i - 1] = ALPHABET[value & 0xf];
value >>= 4;
}
return string(buffer);
}
}
// File: libraries/NFTSVG.sol
pragma solidity >=0.7.6;
/// @title NFTSVG
library NFTSVG {
using Strings for uint256;
string constant curve = 'M93.388 40.430 C 84.339 42.524,78.632 48.186,78.151 55.546 C 78.051 57.067,77.824 57.700,75.822 62.028 C 74.601 64.666,72.465 69.308,71.075 72.344 C 69.684 75.381,68.307 78.245,68.015 78.709 C 62.572 87.337,59.165 96.003,58.444 103.054 C 57.915 108.218,57.292 110.335,53.667 119.293 C 49.280 130.136,49.501 128.260,49.500 154.655 C 49.499 173.381,49.454 176.143,49.132 177.048 C 48.516 178.781,48.113 181.045,46.889 189.629 C 44.967 203.110,43.968 207.086,41.678 210.371 C 37.704 216.071,36.003 223.922,33.815 246.671 C 33.382 251.172,32.683 254.375,30.292 262.817 C 29.430 265.863,28.304 270.106,27.791 272.245 C 27.278 274.384,26.597 277.036,26.279 278.138 C 25.308 281.503,25.225 282.091,24.979 287.331 C 24.548 296.500,24.161 298.393,22.157 301.143 C 21.509 302.032,20.976 302.921,20.974 303.118 C 20.962 304.005,18.674 308.693,15.728 313.867 C 7.892 327.625,7.059 334.546,12.600 339.866 L 14.143 341.348 13.076 344.046 C 10.860 349.649,10.505 352.355,10.496 363.701 L 10.489 372.540 11.724 376.141 C 14.557 384.400,18.936 391.854,23.772 396.652 C 30.882 403.706,34.662 413.693,38.286 435.003 C 40.157 446.003,42.050 450.984,52.421 472.194 C 57.209 481.986,60.546 484.297,74.619 487.569 C 86.502 490.332,89.391 491.773,93.225 496.851 C 101.551 507.877,115.203 515.355,126.930 515.311 C 130.099 515.299,130.955 515.392,135.180 516.210 C 145.726 518.252,151.435 519.152,176.900 522.786 C 195.221 525.400,203.087 526.640,210.843 528.134 L 215.085 528.951 232.528 529.169 C 242.121 529.290,258.282 529.392,268.440 529.396 L 286.909 529.405 287.625 530.007 C 291.832 533.547,304.137 534.373,317.973 532.043 L 320.448 531.627 323.159 532.419 C 328.345 533.935,328.532 533.967,330.326 533.670 C 332.601 533.294,334.674 532.230,336.665 530.417 C 343.181 524.485,355.346 518.798,361.520 518.798 C 361.780 518.798,363.411 518.431,365.145 517.983 C 366.879 517.535,370.876 516.578,374.028 515.857 C 382.387 513.943,385.752 512.999,390.021 511.369 L 392.417 510.453 392.850 508.320 C 393.940 502.945,393.397 495.298,391.250 485.798 C 390.737 483.530,389.953 480.057,389.507 478.080 C 389.061 476.104,388.494 474.088,388.246 473.602 C 385.956 469.100,384.635 462.763,382.559 446.317 C 381.181 435.401,381.162 435.286,379.025 424.396 C 376.431 411.178,376.511 412.021,377.136 404.560 C 377.772 396.967,377.826 390.773,377.279 388.214 C 377.071 387.242,376.901 385.406,376.901 384.133 C 376.900 377.611,376.434 371.419,375.744 368.768 C 374.867 365.396,374.540 362.149,374.308 354.508 C 374.116 348.147,373.706 344.137,372.841 340.130 C 372.193 337.133,371.929 328.351,371.937 310.122 C 371.944 295.458,371.819 293.193,370.780 289.130 C 369.208 282.982,365.784 278.175,361.020 275.427 C 351.825 270.124,349.290 262.012,350.524 241.839 C 350.663 239.570,350.778 234.903,350.780 231.467 C 350.782 228.032,350.880 224.766,350.999 224.210 C 352.812 215.704,350.484 204.781,345.235 197.171 C 344.520 196.134,343.542 194.630,343.062 193.828 C 342.582 193.026,341.796 191.961,341.317 191.462 C 340.838 190.964,340.003 189.672,339.462 188.591 C 336.456 182.584,332.890 180.211,322.575 177.351 C 318.216 176.142,318.436 176.307,317.773 173.750 C 316.479 168.768,314.730 166.317,305.724 156.865 C 299.846 150.697,299.227 150.012,292.467 142.191 C 289.014 138.197,288.722 137.784,288.134 136.072 C 286.368 130.929,282.534 125.153,273.773 114.437 C 271.296 111.407,270.520 110.279,267.290 104.999 C 260.477 93.868,256.427 89.515,250.593 87.052 C 247.628 85.801,245.036 84.349,240.674 81.492 C 230.845 75.055,227.838 74.156,220.631 75.499 C 215.106 76.528,211.782 76.294,210.160 74.761 C 209.471 74.111,209.202 74.042,205.539 73.580 C 201.695 73.096,201.609 73.072,198.114 71.536 C 193.529 69.520,187.197 66.969,184.166 65.917 C 182.847 65.459,180.649 64.432,179.282 63.634 C 174.626 60.918,170.065 59.340,158.199 56.339 C 146.824 53.463,141.586 51.102,137.065 46.814 L 135.651 45.473 132.115 45.000 C 130.171 44.739,124.867 43.900,120.330 43.134 C 109.928 41.379,106.200 40.864,101.473 40.532 C 99.399 40.386,97.518 40.170,97.293 40.051 C 96.705 39.741,96.117 39.798,93.388 40.430 M104.947 46.225 C 107.246 46.476,113.186 47.361,118.147 48.191 C 123.107 49.021,128.438 49.874,129.994 50.087 C 131.550 50.300,133.035 50.564,133.294 50.675 C 133.553 50.785,134.119 50.936,134.551 51.010 C 135.056 51.097,135.856 51.617,136.790 52.465 C 141.521 56.758,146.652 58.977,159.104 62.115 C 169.385 64.706,175.949 67.096,179.510 69.546 C 180.077 69.936,181.790 70.685,183.317 71.210 C 186.407 72.274,192.909 74.885,197.761 77.011 C 200.763 78.326,201.136 78.429,204.361 78.835 C 207.527 79.234,207.888 79.331,209.264 80.156 C 211.773 81.659,215.363 81.915,220.646 80.967 C 226.215 79.967,225.644 79.999,227.635 80.573 C 230.470 81.389,233.827 83.127,238.683 86.294 C 242.736 88.938,245.655 90.562,249.860 92.514 C 254.321 94.584,258.218 98.729,262.935 106.422 C 266.459 112.170,269.017 116.006,270.458 117.704 C 278.187 126.815,283.618 135.004,285.018 139.658 C 285.438 141.055,285.773 141.598,287.200 143.194 C 288.128 144.231,290.802 147.307,293.144 150.029 C 295.486 152.752,299.034 156.677,301.029 158.751 C 307.660 165.647,309.072 167.192,310.497 169.107 C 312.263 171.481,313.793 174.581,314.177 176.563 C 314.339 177.397,314.514 178.297,314.566 178.565 C 314.750 179.517,316.505 180.428,319.741 181.250 C 329.715 183.784,333.325 186.150,335.993 191.906 C 336.434 192.857,337.183 194.007,337.657 194.461 C 338.132 194.915,338.798 195.763,339.138 196.346 C 339.478 196.930,340.412 198.362,341.212 199.529 C 346.173 206.761,348.492 216.585,346.971 223.925 C 346.753 224.972,346.640 227.619,346.613 232.292 C 346.591 236.052,346.435 241.408,346.266 244.196 C 345.140 262.751,348.501 273.207,357.019 277.638 C 365.068 281.826,367.625 288.414,367.460 304.537 C 367.346 315.770,367.344 315.414,367.552 326.694 C 367.712 335.392,367.808 337.252,368.185 338.951 C 369.175 343.418,369.618 347.494,369.837 354.154 C 370.085 361.731,370.505 365.875,371.337 368.958 C 371.930 371.153,372.422 377.881,372.422 383.780 C 372.422 384.987,372.579 386.718,372.771 387.625 C 373.277 390.012,373.222 396.384,372.637 403.278 C 371.999 410.791,371.994 410.740,374.780 424.867 C 376.636 434.285,376.706 434.724,378.081 445.610 C 380.120 461.754,380.985 466.000,383.435 471.892 C 383.893 472.994,384.617 475.433,385.044 477.313 C 388.620 493.069,388.551 492.639,388.547 499.116 C 388.543 505.532,388.448 506.010,387.032 506.712 C 385.608 507.419,379.647 509.092,373.798 510.426 C 371.161 511.028,367.314 511.943,365.249 512.459 C 363.184 512.976,360.092 513.657,358.378 513.974 C 352.384 515.081,346.305 517.318,341.544 520.169 C 338.493 521.995,338.587 521.919,337.325 523.580 C 334.974 526.672,331.087 529.504,329.287 529.437 C 328.020 529.390,324.791 528.535,321.457 527.364 L 319.034 526.513 317.030 526.806 C 311.367 527.633,309.635 527.786,304.528 527.915 C 295.309 528.147,290.005 527.126,287.991 524.732 L 287.410 524.041 251.719 523.914 C 216.690 523.789,215.985 523.777,213.671 523.294 C 206.292 521.753,195.527 520.059,171.662 516.683 C 155.199 514.354,145.147 512.745,137.500 511.214 C 132.940 510.301,132.282 510.227,128.344 510.184 C 116.594 510.058,105.792 504.102,96.771 492.776 C 92.431 487.326,89.401 485.774,77.666 482.988 C 68.841 480.893,64.869 479.356,61.950 476.904 C 59.848 475.139,59.706 474.897,54.706 464.575 C 52.103 459.200,49.601 454.088,49.145 453.215 C 47.242 449.572,44.248 439.473,43.144 432.975 C 39.391 410.894,34.558 398.785,27.044 392.632 C 24.212 390.314,18.974 380.958,16.615 374.007 L 15.513 370.760 15.616 361.986 C 15.747 350.794,15.759 350.724,18.803 342.435 L 19.731 339.908 18.086 338.684 C 12.361 334.428,12.904 328.233,20.086 315.839 C 22.705 311.321,24.695 307.408,25.476 305.245 C 25.780 304.402,26.351 303.288,26.745 302.769 C 28.754 300.124,29.398 297.434,29.707 290.395 C 29.978 284.258,30.218 282.278,31.009 279.670 C 31.324 278.633,32.008 275.997,32.528 273.812 C 33.049 271.628,34.222 267.186,35.136 263.941 C 37.374 255.994,38.098 252.833,38.418 249.617 C 40.853 225.092,42.453 217.699,46.454 212.476 C 48.355 209.995,49.734 204.266,51.612 191.043 C 52.257 186.506,53.010 181.998,53.286 181.025 C 53.968 178.621,54.191 171.010,54.178 150.619 C 54.166 131.465,54.008 132.542,58.395 121.744 C 61.718 113.565,62.435 111.101,62.921 106.182 C 63.611 99.195,66.258 92.383,72.284 82.082 C 72.987 80.880,73.755 79.448,73.992 78.900 C 74.228 78.351,76.239 73.956,78.460 69.133 C 82.346 60.695,82.499 60.307,82.499 58.863 C 82.499 54.366,85.364 49.721,89.469 47.565 C 93.696 45.345,95.478 45.191,104.947 46.225';
struct SVGParams {
string color;
}
function generateSVG(SVGParams memory params) internal pure returns (string memory svg) {
return
string(
abi.encodePacked(
generateAll(params.color),
'</svg>'
)
);
}
function generateAll(string memory color) private pure returns (string memory svg) {
svg = string(
abi.encodePacked(
'<svg width="400" height="565.7041838538598" xmlns="http://www.w3.org/2000/svg" viewBox="0, 0, 400,565.7041838538598">',
'<g id="rock">',
'<path id="path0" d="',
curve,
'" stroke="none" fill="#',
color,
'" fill-rule="evenodd"></path>',
'</g>'
)
);
}
}
// File: libraries/base64.sol
pragma solidity ^0.8.0;
/// @title Base64
/// @author Brecht Devos - <brecht@loopring.org>
/// @notice Provides a function for encoding some bytes in base64
library Base64 {
string internal constant TABLE = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
function encode(bytes memory data) internal pure returns (string memory) {
if (data.length == 0) return '';
// load the table into memory
string memory table = TABLE;
// multiply by 4/3 rounded up
uint256 encodedLen = 4 * ((data.length + 2) / 3);
// add some extra buffer at the end required for the writing
string memory result = new string(encodedLen + 32);
assembly {
// set the actual output length
mstore(result, encodedLen)
// prepare the lookup table
let tablePtr := add(table, 1)
// input ptr
let dataPtr := data
let endPtr := add(dataPtr, mload(data))
// result ptr, jump over length
let resultPtr := add(result, 32)
// run over the input, 3 bytes at a time
for {} lt(dataPtr, endPtr) {}
{
dataPtr := add(dataPtr, 3)
// read 3 bytes
let input := mload(dataPtr)
// write 4 characters
mstore(resultPtr, shl(248, mload(add(tablePtr, and(shr(18, input), 0x3F)))))
resultPtr := add(resultPtr, 1)
mstore(resultPtr, shl(248, mload(add(tablePtr, and(shr(12, input), 0x3F)))))
resultPtr := add(resultPtr, 1)
mstore(resultPtr, shl(248, mload(add(tablePtr, and(shr( 6, input), 0x3F)))))
resultPtr := add(resultPtr, 1)
mstore(resultPtr, shl(248, mload(add(tablePtr, and( input, 0x3F)))))
resultPtr := add(resultPtr, 1)
}
// padding with '='
switch mod(mload(data), 3)
case 1 { mstore(sub(resultPtr, 2), shl(240, 0x3d3d)) }
case 2 { mstore(sub(resultPtr, 1), shl(248, 0x3d)) }
}
return result;
}
}
// File: libraries/NFTDescriptor.sol
pragma solidity ^0.8.0;
library NFTDescriptor {
using SafeMath for uint256;
using HexStrings for uint256;
struct ConstructTokenURIParams {
uint256 tokenId;
address owner;
bytes3 color;
}
function constructTokenURI(ConstructTokenURIParams memory params) public pure returns (string memory) {
string memory name = generateName(params.tokenId);
string memory description = generateDescription();
string memory image = Base64.encode(bytes(generateSVGImage(params)));
return
string(
abi.encodePacked(
'data:application/json;base64,',
Base64.encode(
bytes(
abi.encodePacked(
'{"name":"',
name,
'", "description":"',
description,
'", "image": "',
'data:image/svg+xml;base64,',
image,
'"}'
)
)
)
)
);
}
function generateDescription() private pure returns (string memory) {
return
string(
abi.encodePacked(
'Loot is randomized adventurer gear generated and stored on chain. '
'EtherRock was one of the first crypto collectible NFT-type projects on the Ethereum blockchain. '
'LootRock is the perfect collision of Loot and EtherRock.'
)
);
}
function generateName(uint256 tokenId)
private
pure
returns (string memory)
{
return
string(
abi.encodePacked(
'Rock #',
Strings.toString(tokenId)
)
);
}
function generateSVGImage(ConstructTokenURIParams memory params) internal pure returns (string memory svg) {
NFTSVG.SVGParams memory svgParams =
NFTSVG.SVGParams({
color: uint256(uint24(params.color)).toHexStringNoPrefix(3)
});
return NFTSVG.generateSVG(svgParams);
}
}
// File: @openzeppelin/contracts/access/Ownable.sol
pragma solidity ^0.8.0;
/**
* @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() {
_setOwner(_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 {
_setOwner(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");
_setOwner(newOwner);
}
function _setOwner(address newOwner) private {
address oldOwner = _owner;
_owner = newOwner;
emit OwnershipTransferred(oldOwner, newOwner);
}
}
// File: @openzeppelin/contracts/utils/Counters.sol
pragma solidity ^0.8.0;
/**
* @title Counters
* @author Matt Condon (@shrugs)
* @dev Provides counters that can only be incremented, decremented or reset. 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;`
*/
library Counters {
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 {
unchecked {
counter._value += 1;
}
}
function decrement(Counter storage counter) internal {
uint256 value = counter._value;
require(value > 0, "Counter: decrement overflow");
unchecked {
counter._value = value - 1;
}
}
function reset(Counter storage counter) internal {
counter._value = 0;
}
}
// File: @openzeppelin/contracts/utils/math/SafeMath.sol
pragma solidity ^0.8.0;
// CAUTION
// This version of SafeMath should only be used with Solidity 0.8 or later,
// because it relies on the compiler's built in overflow checks.
/**
* @dev Wrappers over Solidity's arithmetic operations.
*
* NOTE: `SafeMath` is no longer needed starting with Solidity 0.8. The compiler
* now has built in overflow checking.
*/
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) {
unchecked {
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) {
unchecked {
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) {
unchecked {
// 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) {
unchecked {
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) {
unchecked {
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) {
return a + b;
}
/**
* @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) {
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) {
return a * b;
}
/**
* @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.
*
* Requirements:
*
* - The divisor cannot be zero.
*/
function div(uint256 a, uint256 b) internal pure returns (uint256) {
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) {
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) {
unchecked {
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.
*
* 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) {
unchecked {
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) {
unchecked {
require(b > 0, errorMessage);
return a % b;
}
}
}
// File: @openzeppelin/contracts/token/ERC721/IERC721Receiver.sol
pragma solidity ^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);
}
// File: @openzeppelin/contracts/utils/introspection/IERC165.sol
pragma solidity ^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);
}
// File: @openzeppelin/contracts/token/ERC721/IERC721.sol
pragma solidity ^0.8.0;
/**
* @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;
}
// File: @openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol
pragma solidity ^0.8.0;
/**
* @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);
}
// File: @openzeppelin/contracts/utils/introspection/ERC165.sol
pragma solidity ^0.8.0;
/**
* @dev Implementation of the {IERC165} interface.
*
* Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check
* for the additional interface id that will be supported. For example:
*
* ```solidity
* function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
* return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);
* }
* ```
*
* Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.
*/
abstract contract ERC165 is IERC165 {
/**
* @dev See {IERC165-supportsInterface}.
*/
function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
return interfaceId == type(IERC165).interfaceId;
}
}
// File: @openzeppelin/contracts/token/ERC721/ERC721.sol
pragma solidity ^0.8.0;
/**
* @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including
* the Metadata extension, but not including the Enumerable extension, which is available separately as
* {ERC721Enumerable}.
*/
contract ERC721 is Context, ERC165, IERC721, IERC721Metadata {
using Address for address;
using Strings for uint256;
// Token name
string private _name;
// Token symbol
string private _symbol;
// Mapping from token ID to owner address
mapping(uint256 => address) private _owners;
// Mapping owner address to token count
mapping(address => uint256) private _balances;
// 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;
/**
* @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.
*/
constructor(string memory name_, string memory symbol_) {
_name = name_;
_symbol = symbol_;
}
/**
* @dev See {IERC165-supportsInterface}.
*/
function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {
return
interfaceId == type(IERC721).interfaceId ||
interfaceId == type(IERC721Metadata).interfaceId ||
super.supportsInterface(interfaceId);
}
/**
* @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 _balances[owner];
}
/**
* @dev See {IERC721-ownerOf}.
*/
function ownerOf(uint256 tokenId) public view virtual override returns (address) {
address owner = _owners[tokenId];
require(owner != address(0), "ERC721: owner query for nonexistent token");
return owner;
}
/**
* @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 baseURI = _baseURI();
return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : "";
}
/**
* @dev Base URI for computing {tokenURI}. If set, the resulting URI for each
* token will be the concatenation of the `baseURI` and the `tokenId`. Empty
* by default, can be overriden in child contracts.
*/
function _baseURI() internal view virtual returns (string memory) {
return "";
}
/**
* @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 || 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 _owners[tokenId] != address(0);
}
/**
* @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 || isApprovedForAll(owner, spender));
}
/**
* @dev Safely mints `tokenId` and transfers it to `to`.
*
* Requirements:
*
* - `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);
_balances[to] += 1;
_owners[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);
_beforeTokenTransfer(owner, address(0), tokenId);
// Clear approvals
_approve(address(0), tokenId);
_balances[owner] -= 1;
delete _owners[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");
require(to != address(0), "ERC721: transfer to the zero address");
_beforeTokenTransfer(from, to, tokenId);
// Clear approvals from the previous owner
_approve(address(0), tokenId);
_balances[from] -= 1;
_balances[to] += 1;
_owners[tokenId] = to;
emit Transfer(from, to, tokenId);
}
/**
* @dev Approve `to` to operate on `tokenId`
*
* Emits a {Approval} event.
*/
function _approve(address to, uint256 tokenId) internal virtual {
_tokenApprovals[tokenId] = to;
emit Approval(ERC721.ownerOf(tokenId), to, tokenId);
}
/**
* @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()) {
try IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, _data) returns (bytes4 retval) {
return retval == IERC721Receiver.onERC721Received.selector;
} catch (bytes memory reason) {
if (reason.length == 0) {
revert("ERC721: transfer to non ERC721Receiver implementer");
} else {
assembly {
revert(add(32, reason), mload(reason))
}
}
}
} else {
return true;
}
}
/**
* @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` and `to` are never both zero.
*
* 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 {}
}
// File: @openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol
pragma solidity ^0.8.0;
/**
* @dev ERC721 token with storage based token URI management.
*/
abstract contract ERC721URIStorage is ERC721 {
using Strings for uint256;
// Optional mapping for token URIs
mapping(uint256 => string) private _tokenURIs;
/**
* @dev See {IERC721Metadata-tokenURI}.
*/
function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {
require(_exists(tokenId), "ERC721URIStorage: 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));
}
return super.tokenURI(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), "ERC721URIStorage: URI set of nonexistent token");
_tokenURIs[tokenId] = _tokenURI;
}
/**
* @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 override {
super._burn(tokenId);
if (bytes(_tokenURIs[tokenId]).length != 0) {
delete _tokenURIs[tokenId];
}
}
}
// File: @openzeppelin/contracts/token/ERC721/extensions/IERC721Enumerable.sol
pragma solidity ^0.8.0;
/**
* @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);
}
// File: @openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol
pragma solidity ^0.8.0;
/**
* @dev This implements an optional extension of {ERC721} defined in the EIP that adds
* enumerability of all the token ids in the contract as well as all token ids owned by each
* account.
*/
abstract contract ERC721Enumerable is ERC721, IERC721Enumerable {
// Mapping from owner to list of owned token IDs
mapping(address => mapping(uint256 => uint256)) private _ownedTokens;
// Mapping from token ID to index of the owner tokens list
mapping(uint256 => uint256) private _ownedTokensIndex;
// Array with all token ids, used for enumeration
uint256[] private _allTokens;
// Mapping from token id to position in the allTokens array
mapping(uint256 => uint256) private _allTokensIndex;
/**
* @dev See {IERC165-supportsInterface}.
*/
function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165, ERC721) returns (bool) {
return interfaceId == type(IERC721Enumerable).interfaceId || super.supportsInterface(interfaceId);
}
/**
* @dev See {IERC721Enumerable-tokenOfOwnerByIndex}.
*/
function tokenOfOwnerByIndex(address owner, uint256 index) public view virtual override returns (uint256) {
require(index < ERC721.balanceOf(owner), "ERC721Enumerable: owner index out of bounds");
return _ownedTokens[owner][index];
}
/**
* @dev See {IERC721Enumerable-totalSupply}.
*/
function totalSupply() public view virtual override returns (uint256) {
return _allTokens.length;
}
/**
* @dev See {IERC721Enumerable-tokenByIndex}.
*/
function tokenByIndex(uint256 index) public view virtual override returns (uint256) {
require(index < ERC721Enumerable.totalSupply(), "ERC721Enumerable: global index out of bounds");
return _allTokens[index];
}
/**
* @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 override {
super._beforeTokenTransfer(from, to, tokenId);
if (from == address(0)) {
_addTokenToAllTokensEnumeration(tokenId);
} else if (from != to) {
_removeTokenFromOwnerEnumeration(from, tokenId);
}
if (to == address(0)) {
_removeTokenFromAllTokensEnumeration(tokenId);
} else if (to != from) {
_addTokenToOwnerEnumeration(to, tokenId);
}
}
/**
* @dev Private function to add a token to this extension's ownership-tracking data structures.
* @param to address representing the new owner of the given token ID
* @param tokenId uint256 ID of the token to be added to the tokens list of the given address
*/
function _addTokenToOwnerEnumeration(address to, uint256 tokenId) private {
uint256 length = ERC721.balanceOf(to);
_ownedTokens[to][length] = tokenId;
_ownedTokensIndex[tokenId] = length;
}
/**
* @dev Private function to add a token to this extension's token tracking data structures.
* @param tokenId uint256 ID of the token to be added to the tokens list
*/
function _addTokenToAllTokensEnumeration(uint256 tokenId) private {
_allTokensIndex[tokenId] = _allTokens.length;
_allTokens.push(tokenId);
}
/**
* @dev Private function to remove a token from this extension's ownership-tracking data structures. Note that
* while the token is not assigned a new owner, the `_ownedTokensIndex` mapping is _not_ updated: this allows for
* gas optimizations e.g. when performing a transfer operation (avoiding double writes).
* This has O(1) time complexity, but alters the order of the _ownedTokens array.
* @param from address representing the previous owner of the given token ID
* @param tokenId uint256 ID of the token to be removed from the tokens list of the given address
*/
function _removeTokenFromOwnerEnumeration(address from, uint256 tokenId) private {
// To prevent a gap in from's tokens array, we store the last token in the index of the token to delete, and
// then delete the last slot (swap and pop).
uint256 lastTokenIndex = ERC721.balanceOf(from) - 1;
uint256 tokenIndex = _ownedTokensIndex[tokenId];
// When the token to delete is the last token, the swap operation is unnecessary
if (tokenIndex != lastTokenIndex) {
uint256 lastTokenId = _ownedTokens[from][lastTokenIndex];
_ownedTokens[from][tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token
_ownedTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index
}
// This also deletes the contents at the last position of the array
delete _ownedTokensIndex[tokenId];
delete _ownedTokens[from][lastTokenIndex];
}
/**
* @dev Private function to remove a token from this extension's token tracking data structures.
* This has O(1) time complexity, but alters the order of the _allTokens array.
* @param tokenId uint256 ID of the token to be removed from the tokens list
*/
function _removeTokenFromAllTokensEnumeration(uint256 tokenId) private {
// To prevent a gap in the tokens array, we store the last token in the index of the token to delete, and
// then delete the last slot (swap and pop).
uint256 lastTokenIndex = _allTokens.length - 1;
uint256 tokenIndex = _allTokensIndex[tokenId];
// When the token to delete is the last token, the swap operation is unnecessary. However, since this occurs so
// rarely (when the last minted token is burnt) that we still do the swap here to avoid the gas cost of adding
// an 'if' statement (like in _removeTokenFromOwnerEnumeration)
uint256 lastTokenId = _allTokens[lastTokenIndex];
_allTokens[tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token
_allTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index
// This also deletes the contents at the last position of the array
delete _allTokensIndex[tokenId];
_allTokens.pop();
}
}
// File: @openzeppelin/contracts/utils/Strings.sol
pragma solidity ^0.8.0;
/**
* @dev String operations.
*/
library Strings {
bytes16 private constant _HEX_SYMBOLS = "0123456789abcdef";
/**
* @dev Converts a `uint256` to its ASCII `string` decimal 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);
while (value != 0) {
digits -= 1;
buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));
value /= 10;
}
return string(buffer);
}
/**
* @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.
*/
function toHexString(uint256 value) internal pure returns (string memory) {
if (value == 0) {
return "0x00";
}
uint256 temp = value;
uint256 length = 0;
while (temp != 0) {
length++;
temp >>= 8;
}
return toHexString(value, length);
}
/**
* @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.
*/
function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {
bytes memory buffer = new bytes(2 * length + 2);
buffer[0] = "0";
buffer[1] = "x";
for (uint256 i = 2 * length + 1; i > 1; --i) {
buffer[i] = _HEX_SYMBOLS[value & 0xf];
value >>= 4;
}
require(value == 0, "Strings: hex length insufficient");
return string(buffer);
}
}
// File: @openzeppelin/contracts/utils/Address.sol
pragma solidity ^0.8.0;
/**
* @dev Collection of functions related to the address type
*/
library Address {
/**
* @dev Returns true if `account` is a contract.
*
* [IMPORTANT]
* ====
* It is unsafe to assume that an address for which this function returns
* false is an externally-owned account (EOA) and not a contract.
*
* Among others, `isContract` will return false for the following
* types of addresses:
*
* - an externally-owned account
* - a contract in construction
* - an address where a contract will be created
* - an address where a contract lived, but was destroyed
* ====
*/
function isContract(address account) internal view returns (bool) {
// This method relies on extcodesize, which returns 0 for contracts in
// construction, since the code is only stored at the end of the
// constructor execution.
uint256 size;
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");
(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");
(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");
(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");
(bool success, bytes memory returndata) = target.delegatecall(data);
return verifyCallResult(success, returndata, errorMessage);
}
/**
* @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the
* revert reason using the provided one.
*
* _Available since v4.3._
*/
function verifyCallResult(
bool success,
bytes memory returndata,
string memory errorMessage
) internal pure returns (bytes memory) {
if (success) {
return returndata;
} else {
// 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
assembly {
let returndata_size := mload(returndata)
revert(add(32, returndata), returndata_size)
}
} else {
revert(errorMessage);
}
}
}
}
// File: LootRock.sol
pragma solidity ^0.8.0;
contract LootRock is ERC721, ERC721Enumerable, ERC721URIStorage, Ownable {
using SafeMath for uint256;
using Counters for Counters.Counter;
uint256 public constant MAX_SUPPLY = 1000;
uint256 public constant MAX_PURCHASE = 10;
uint256 public constant PRICE = 0.1 * 10 ** 18;
Counters.Counter private _tokenIdCounter;
mapping (uint256 => bytes3) public colors;
constructor() ERC721("LootRock", "ROCK") {}
function mint(uint256 amount) public payable {
require(totalSupply() < MAX_SUPPLY, "LootRock: Sale has ended");
require(amount > 0, "LootRock: Cannot buy 0");
require(amount <= MAX_PURCHASE, "LootRock: You may not buy that many NFTs at once");
require(totalSupply().add(amount) <= MAX_SUPPLY, "LootRock: Exceeds max supply");
require(PRICE.mul(amount) == msg.value, "LootRock: Ether value sent is not correct");
for (uint i = 0; i < amount; i++) {
uint256 tokenId = _tokenIdCounter.current();
_tokenIdCounter.increment();
_safeMint(msg.sender, tokenId);
bytes32 predictableRandom = keccak256(abi.encodePacked(blockhash(block.number), msg.sender, address(this), i));
colors[tokenId] = bytes2(predictableRandom[0]) | ( bytes2(predictableRandom[1]) >> 8 ) | ( bytes2(predictableRandom[2]) >> 16 );
}
}
function tokenURI(uint256 tokenId)
public view override(ERC721, ERC721URIStorage) returns (string memory)
{
address owner = ownerOf(tokenId);
bytes3 color = colors[tokenId];
return
NFTDescriptor.constructTokenURI(NFTDescriptor.ConstructTokenURIParams({
tokenId: tokenId,
owner: owner,
color: color
}));
}
function withdraw() public {
payable(owner()).transfer(address(this).balance);
}
// The following functions are overrides required by Solidity.
function _beforeTokenTransfer(address from, address to, uint256 tokenId)
internal
override(ERC721, ERC721Enumerable)
{
super._beforeTokenTransfer(from, to, tokenId);
}
function _burn(uint256 tokenId) internal override(ERC721, ERC721URIStorage) {
super._burn(tokenId);
}
function supportsInterface(bytes4 interfaceId)
public
view
override(ERC721, ERC721Enumerable)
returns (bool)
{
return super.supportsInterface(interfaceId);
}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"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":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","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"},{"inputs":[],"name":"MAX_PURCHASE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_SUPPLY","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PRICE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"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":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"colors","outputs":[{"internalType":"bytes3","name":"","type":"bytes3"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"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":"amount","type":"uint256"}],"name":"mint","outputs":[],"stateMutability":"payable","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":"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":"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":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]Contract Creation Code
60806040523480156200001157600080fd5b5060408051808201825260088152674c6f6f74526f636b60c01b602080830191825283518085019094526004845263524f434b60e01b9084015281519192916200005e91600091620000ed565b50805162000074906001906020840190620000ed565b505050620000916200008b6200009760201b60201c565b6200009b565b620001d0565b3390565b600b80546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b828054620000fb9062000193565b90600052602060002090601f0160209004810192826200011f57600085556200016a565b82601f106200013a57805160ff19168380011785556200016a565b828001600101855582156200016a579182015b828111156200016a5782518255916020019190600101906200014d565b50620001789291506200017c565b5090565b5b808211156200017857600081556001016200017d565b600281046001821680620001a857607f821691505b60208210811415620001ca57634e487b7160e01b600052602260045260246000fd5b50919050565b611fbc80620001e06000396000f3fe6080604052600436106101665760003560e01c806370a08231116100d1578063a0712d681161008a578063bd11f69d11610064578063bd11f69d146103da578063c87b56dd14610407578063e985e9c514610427578063f2fde38b1461044757610166565b8063a0712d6814610387578063a22cb4651461039a578063b88d4fde146103ba57610166565b806370a08231146102fe5780637146bd081461031e578063715018a6146103335780638d859f3e146103485780638da5cb5b1461035d57806395d89b411461037257610166565b80632f745c59116101235780632f745c591461025457806332cb6b0c146102745780633ccfd60b1461028957806342842e0e1461029e5780634f6ccce7146102be5780636352211e146102de57610166565b806301ffc9a71461016b57806306fdde03146101a1578063081812fc146101c3578063095ea7b3146101f057806318160ddd1461021257806323b872dd14610234575b600080fd5b34801561017757600080fd5b5061018b61018636600461165b565b610467565b60405161019891906117cd565b60405180910390f35b3480156101ad57600080fd5b506101b661047a565b60405161019891906117ed565b3480156101cf57600080fd5b506101e36101de366004611706565b61050c565b604051610198919061177c565b3480156101fc57600080fd5b5061021061020b366004611632565b610558565b005b34801561021e57600080fd5b506102276105f0565b6040516101989190611e19565b34801561024057600080fd5b5061021061024f36600461151a565b6105f6565b34801561026057600080fd5b5061022761026f366004611632565b61062e565b34801561028057600080fd5b50610227610680565b34801561029557600080fd5b50610210610686565b3480156102aa57600080fd5b506102106102b936600461151a565b6106c9565b3480156102ca57600080fd5b506102276102d9366004611706565b6106e4565b3480156102ea57600080fd5b506101e36102f9366004611706565b61073f565b34801561030a57600080fd5b506102276103193660046114ce565b610774565b34801561032a57600080fd5b506102276107b8565b34801561033f57600080fd5b506102106107bd565b34801561035457600080fd5b50610227610808565b34801561036957600080fd5b506101e3610814565b34801561037e57600080fd5b506101b6610823565b610210610395366004611706565b610832565b3480156103a657600080fd5b506102106103b53660046115f8565b6109ce565b3480156103c657600080fd5b506102106103d5366004611555565b610a9c565b3480156103e657600080fd5b506103fa6103f5366004611706565b610adb565b60405161019891906117d8565b34801561041357600080fd5b506101b6610422366004611706565b610af0565b34801561043357600080fd5b5061018b6104423660046114e8565b610bd4565b34801561045357600080fd5b506102106104623660046114ce565b610c02565b600061047282610c70565b90505b919050565b60606000805461048990611eee565b80601f01602080910402602001604051908101604052809291908181526020018280546104b590611eee565b80156105025780601f106104d757610100808354040283529160200191610502565b820191906000526020600020905b8154815290600101906020018083116104e557829003601f168201915b5050505050905090565b600061051782610c95565b61053c5760405162461bcd60e51b815260040161053390611c3d565b60405180910390fd5b506000908152600460205260409020546001600160a01b031690565b60006105638261073f565b9050806001600160a01b0316836001600160a01b031614156105975760405162461bcd60e51b815260040161053390611d07565b806001600160a01b03166105a9610cb2565b6001600160a01b031614806105c557506105c581610442610cb2565b6105e15760405162461bcd60e51b815260040161053390611ae1565b6105eb8383610cb6565b505050565b60085490565b610607610601610cb2565b82610d24565b6106235760405162461bcd60e51b815260040161053390611d48565b6105eb838383610da1565b600061063983610774565b82106106575760405162461bcd60e51b815260040161053390611849565b506001600160a01b03919091166000908152600660209081526040808320938352929052205490565b6103e881565b61068e610814565b6001600160a01b03166108fc479081150290604051600060405180830381858888f193505050501580156106c6573d6000803e3d6000fd5b50565b6105eb83838360405180602001604052806000815250610a9c565b60006106ee6105f0565b821061070c5760405162461bcd60e51b815260040161053390611d99565b6008828154811061072d57634e487b7160e01b600052603260045260246000fd5b90600052602060002001549050919050565b6000818152600260205260408120546001600160a01b0316806104725760405162461bcd60e51b815260040161053390611b88565b60006001600160a01b03821661079c5760405162461bcd60e51b815260040161053390611b3e565b506001600160a01b031660009081526003602052604090205490565b600a81565b6107c5610cb2565b6001600160a01b03166107d6610814565b6001600160a01b0316146107fc5760405162461bcd60e51b815260040161053390611c89565b6108066000610ece565b565b67016345785d8a000081565b600b546001600160a01b031690565b60606001805461048990611eee565b6103e861083d6105f0565b1061085a5760405162461bcd60e51b815260040161053390611963565b6000811161087a5760405162461bcd60e51b815260040161053390611ab1565b600a81111561089b5760405162461bcd60e51b81526004016105339061199a565b6103e86108b0826108aa6105f0565b90610f20565b11156108ce5760405162461bcd60e51b815260040161053390611bd1565b346108e167016345785d8a000083610f33565b146108fe5760405162461bcd60e51b815260040161053390611800565b60005b818110156109ca576000610915600c610f3f565b9050610921600c610f43565b61092b3382610f4c565b60004340333085604051602001610945949392919061174a565b60408051808303601f1901815291815281516020928301206000948552600d9092528320805462ffff009483901a60f81b6001600160f81b03191660ff60f01b600185901a60f01b161760ff60e81b60029490941a60e890811b949094161790921c9390931662ffffff199091161790915550806109c281611f29565b915050610901565b5050565b6109d6610cb2565b6001600160a01b0316826001600160a01b03161415610a075760405162461bcd60e51b815260040161053390611a2e565b8060056000610a14610cb2565b6001600160a01b03908116825260208083019390935260409182016000908120918716808252919093529120805460ff191692151592909217909155610a58610cb2565b6001600160a01b03167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3183604051610a9091906117cd565b60405180910390a35050565b610aad610aa7610cb2565b83610d24565b610ac95760405162461bcd60e51b815260040161053390611d48565b610ad584848484610f66565b50505050565b600d6020526000908152604090205460e81b81565b60606000610afd8361073f565b6000848152600d60209081526040918290205482516060810184528781526001600160a01b0385169281019290925260e81b6001600160e81b0319811682840152915163c49917d760e01b81529293509091739708af8bca083f1abfea3cdfc4049e54e5ca9ad49163c49917d791610b789190600401611de5565b60006040518083038186803b158015610b9057600080fd5b505af4158015610ba4573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610bcc9190810190611693565b949350505050565b6001600160a01b03918216600090815260056020908152604080832093909416825291909152205460ff1690565b610c0a610cb2565b6001600160a01b0316610c1b610814565b6001600160a01b031614610c415760405162461bcd60e51b815260040161053390611c89565b6001600160a01b038116610c675760405162461bcd60e51b8152600401610533906118e6565b6106c681610ece565b60006001600160e01b0319821663780e9d6360e01b1480610472575061047282610f99565b6000908152600260205260409020546001600160a01b0316151590565b3390565b600081815260046020526040902080546001600160a01b0319166001600160a01b0384169081179091558190610ceb8261073f565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b6000610d2f82610c95565b610d4b5760405162461bcd60e51b815260040161053390611a65565b6000610d568361073f565b9050806001600160a01b0316846001600160a01b03161480610d915750836001600160a01b0316610d868461050c565b6001600160a01b0316145b80610bcc5750610bcc8185610bd4565b826001600160a01b0316610db48261073f565b6001600160a01b031614610dda5760405162461bcd60e51b815260040161053390611cbe565b6001600160a01b038216610e005760405162461bcd60e51b8152600401610533906119ea565b610e0b838383610fd9565b610e16600082610cb6565b6001600160a01b0383166000908152600360205260408120805460019290610e3f908490611eab565b90915550506001600160a01b0382166000908152600360205260408120805460019290610e6d908490611e74565b909155505060008181526002602052604080822080546001600160a01b0319166001600160a01b0386811691821790925591518493918716917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b600b80546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6000610f2c8284611e74565b9392505050565b6000610f2c8284611e8c565b5490565b80546001019055565b6109ca828260405180602001604052806000815250610fe4565b610f71848484610da1565b610f7d84848484611017565b610ad55760405162461bcd60e51b815260040161053390611894565b60006001600160e01b031982166380ac58cd60e01b1480610fca57506001600160e01b03198216635b5e139f60e01b145b80610472575061047282611132565b6105eb83838361114b565b610fee83836111d4565b610ffb6000848484611017565b6105eb5760405162461bcd60e51b815260040161053390611894565b600061102b846001600160a01b03166112b3565b1561112757836001600160a01b031663150b7a02611047610cb2565b8786866040518563ffffffff1660e01b81526004016110699493929190611790565b602060405180830381600087803b15801561108357600080fd5b505af19250505080156110b3575060408051601f3d908101601f191682019092526110b091810190611677565b60015b61110d573d8080156110e1576040519150601f19603f3d011682016040523d82523d6000602084013e6110e6565b606091505b5080516111055760405162461bcd60e51b815260040161053390611894565b805181602001fd5b6001600160e01b031916630a85bd0160e11b149050610bcc565b506001949350505050565b6001600160e01b031981166301ffc9a760e01b14919050565b6111568383836105eb565b6001600160a01b0383166111725761116d816112b9565b611195565b816001600160a01b0316836001600160a01b0316146111955761119583826112fd565b6001600160a01b0382166111b1576111ac8161139a565b6105eb565b826001600160a01b0316826001600160a01b0316146105eb576105eb8282611473565b6001600160a01b0382166111fa5760405162461bcd60e51b815260040161053390611c08565b61120381610c95565b156112205760405162461bcd60e51b81526004016105339061192c565b61122c60008383610fd9565b6001600160a01b0382166000908152600360205260408120805460019290611255908490611e74565b909155505060008181526002602052604080822080546001600160a01b0319166001600160a01b03861690811790915590518392907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b3b151590565b600880546000838152600960205260408120829055600182018355919091527ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee30155565b6000600161130a84610774565b6113149190611eab565b600083815260076020526040902054909150808214611367576001600160a01b03841660009081526006602090815260408083208584528252808320548484528184208190558352600790915290208190555b5060009182526007602090815260408084208490556001600160a01b039094168352600681528383209183525290812055565b6008546000906113ac90600190611eab565b600083815260096020526040812054600880549394509092849081106113e257634e487b7160e01b600052603260045260246000fd5b90600052602060002001549050806008838154811061141157634e487b7160e01b600052603260045260246000fd5b600091825260208083209091019290925582815260099091526040808220849055858252812055600880548061145757634e487b7160e01b600052603160045260246000fd5b6001900381819060005260206000200160009055905550505050565b600061147e83610774565b6001600160a01b039093166000908152600660209081526040808320868452825280832085905593825260079052919091209190915550565b80356001600160a01b038116811461047557600080fd5b6000602082840312156114df578081fd5b610f2c826114b7565b600080604083850312156114fa578081fd5b611503836114b7565b9150611511602084016114b7565b90509250929050565b60008060006060848603121561152e578081fd5b611537846114b7565b9250611545602085016114b7565b9150604084013590509250925092565b6000806000806080858703121561156a578081fd5b611573856114b7565b9350611581602086016114b7565b925060408501359150606085013567ffffffffffffffff8111156115a3578182fd5b8501601f810187136115b3578182fd5b80356115c66115c182611e4c565b611e22565b8181528860208385010111156115da578384fd5b81602084016020830137908101602001929092525092959194509250565b6000806040838503121561160a578182fd5b611613836114b7565b915060208301358015158114611627578182fd5b809150509250929050565b60008060408385031215611644578182fd5b61164d836114b7565b946020939093013593505050565b60006020828403121561166c578081fd5b8135610f2c81611f70565b600060208284031215611688578081fd5b8151610f2c81611f70565b6000602082840312156116a4578081fd5b815167ffffffffffffffff8111156116ba578182fd5b8201601f810184136116ca578182fd5b80516116d86115c182611e4c565b8181528560208385010111156116ec578384fd5b6116fd826020830160208601611ec2565b95945050505050565b600060208284031215611717578081fd5b5035919050565b60008151808452611736816020860160208601611ec2565b601f01601f19169290920160200192915050565b9384526bffffffffffffffffffffffff19606093841b811660208601529190921b166034830152604882015260680190565b6001600160a01b0391909116815260200190565b6001600160a01b03858116825284166020820152604081018390526080606082018190526000906117c39083018461171e565b9695505050505050565b901515815260200190565b6001600160e81b031991909116815260200190565b600060208252610f2c602083018461171e565b60208082526029908201527f4c6f6f74526f636b3a2045746865722076616c75652073656e74206973206e6f6040820152681d0818dbdc9c9958dd60ba1b606082015260800190565b6020808252602b908201527f455243373231456e756d657261626c653a206f776e657220696e646578206f7560408201526a74206f6620626f756e647360a81b606082015260800190565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b60208082526026908201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160408201526564647265737360d01b606082015260800190565b6020808252601c908201527f4552433732313a20746f6b656e20616c7265616479206d696e74656400000000604082015260600190565b60208082526018908201527f4c6f6f74526f636b3a2053616c652068617320656e6465640000000000000000604082015260600190565b60208082526030908201527f4c6f6f74526f636b3a20596f75206d6179206e6f74206275792074686174206d60408201526f616e79204e465473206174206f6e636560801b606082015260800190565b60208082526024908201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646040820152637265737360e01b606082015260800190565b60208082526019908201527f4552433732313a20617070726f766520746f2063616c6c657200000000000000604082015260600190565b6020808252602c908201527f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860408201526b34b9ba32b73a103a37b5b2b760a11b606082015260800190565b60208082526016908201527504c6f6f74526f636b3a2043616e6e6f742062757920360541b604082015260600190565b60208082526038908201527f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f7760408201527f6e6572206e6f7220617070726f76656420666f7220616c6c0000000000000000606082015260800190565b6020808252602a908201527f4552433732313a2062616c616e636520717565727920666f7220746865207a65604082015269726f206164647265737360b01b606082015260800190565b60208082526029908201527f4552433732313a206f776e657220717565727920666f72206e6f6e657869737460408201526832b73a103a37b5b2b760b91b606082015260800190565b6020808252601c908201527f4c6f6f74526f636b3a2045786365656473206d617820737570706c7900000000604082015260600190565b6020808252818101527f4552433732313a206d696e7420746f20746865207a65726f2061646472657373604082015260600190565b6020808252602c908201527f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860408201526b34b9ba32b73a103a37b5b2b760a11b606082015260800190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b60208082526029908201527f4552433732313a207472616e73666572206f6620746f6b656e2074686174206960408201526839903737ba1037bbb760b91b606082015260800190565b60208082526021908201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656040820152603960f91b606082015260800190565b60208082526031908201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f6040820152701ddb995c881b9bdc88185c1c1c9bdd9959607a1b606082015260800190565b6020808252602c908201527f455243373231456e756d657261626c653a20676c6f62616c20696e646578206f60408201526b7574206f6620626f756e647360a01b606082015260800190565b815181526020808301516001600160a01b0316908201526040918201516001600160e81b0319169181019190915260600190565b90815260200190565b60405181810167ffffffffffffffff81118282101715611e4457611e44611f5a565b604052919050565b600067ffffffffffffffff821115611e6657611e66611f5a565b50601f01601f191660200190565b60008219821115611e8757611e87611f44565b500190565b6000816000190483118215151615611ea657611ea6611f44565b500290565b600082821015611ebd57611ebd611f44565b500390565b60005b83811015611edd578181015183820152602001611ec5565b83811115610ad55750506000910152565b600281046001821680611f0257607f821691505b60208210811415611f2357634e487b7160e01b600052602260045260246000fd5b50919050565b6000600019821415611f3d57611f3d611f44565b5060010190565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160e01b0319811681146106c657600080fdfea26469706673582212202774eec9994cccc35ff2b13f229ce1c085cf5ef82bcc2d5e58d8fb8e440d5f0564736f6c63430008000033
Deployed Bytecode
0x6080604052600436106101665760003560e01c806370a08231116100d1578063a0712d681161008a578063bd11f69d11610064578063bd11f69d146103da578063c87b56dd14610407578063e985e9c514610427578063f2fde38b1461044757610166565b8063a0712d6814610387578063a22cb4651461039a578063b88d4fde146103ba57610166565b806370a08231146102fe5780637146bd081461031e578063715018a6146103335780638d859f3e146103485780638da5cb5b1461035d57806395d89b411461037257610166565b80632f745c59116101235780632f745c591461025457806332cb6b0c146102745780633ccfd60b1461028957806342842e0e1461029e5780634f6ccce7146102be5780636352211e146102de57610166565b806301ffc9a71461016b57806306fdde03146101a1578063081812fc146101c3578063095ea7b3146101f057806318160ddd1461021257806323b872dd14610234575b600080fd5b34801561017757600080fd5b5061018b61018636600461165b565b610467565b60405161019891906117cd565b60405180910390f35b3480156101ad57600080fd5b506101b661047a565b60405161019891906117ed565b3480156101cf57600080fd5b506101e36101de366004611706565b61050c565b604051610198919061177c565b3480156101fc57600080fd5b5061021061020b366004611632565b610558565b005b34801561021e57600080fd5b506102276105f0565b6040516101989190611e19565b34801561024057600080fd5b5061021061024f36600461151a565b6105f6565b34801561026057600080fd5b5061022761026f366004611632565b61062e565b34801561028057600080fd5b50610227610680565b34801561029557600080fd5b50610210610686565b3480156102aa57600080fd5b506102106102b936600461151a565b6106c9565b3480156102ca57600080fd5b506102276102d9366004611706565b6106e4565b3480156102ea57600080fd5b506101e36102f9366004611706565b61073f565b34801561030a57600080fd5b506102276103193660046114ce565b610774565b34801561032a57600080fd5b506102276107b8565b34801561033f57600080fd5b506102106107bd565b34801561035457600080fd5b50610227610808565b34801561036957600080fd5b506101e3610814565b34801561037e57600080fd5b506101b6610823565b610210610395366004611706565b610832565b3480156103a657600080fd5b506102106103b53660046115f8565b6109ce565b3480156103c657600080fd5b506102106103d5366004611555565b610a9c565b3480156103e657600080fd5b506103fa6103f5366004611706565b610adb565b60405161019891906117d8565b34801561041357600080fd5b506101b6610422366004611706565b610af0565b34801561043357600080fd5b5061018b6104423660046114e8565b610bd4565b34801561045357600080fd5b506102106104623660046114ce565b610c02565b600061047282610c70565b90505b919050565b60606000805461048990611eee565b80601f01602080910402602001604051908101604052809291908181526020018280546104b590611eee565b80156105025780601f106104d757610100808354040283529160200191610502565b820191906000526020600020905b8154815290600101906020018083116104e557829003601f168201915b5050505050905090565b600061051782610c95565b61053c5760405162461bcd60e51b815260040161053390611c3d565b60405180910390fd5b506000908152600460205260409020546001600160a01b031690565b60006105638261073f565b9050806001600160a01b0316836001600160a01b031614156105975760405162461bcd60e51b815260040161053390611d07565b806001600160a01b03166105a9610cb2565b6001600160a01b031614806105c557506105c581610442610cb2565b6105e15760405162461bcd60e51b815260040161053390611ae1565b6105eb8383610cb6565b505050565b60085490565b610607610601610cb2565b82610d24565b6106235760405162461bcd60e51b815260040161053390611d48565b6105eb838383610da1565b600061063983610774565b82106106575760405162461bcd60e51b815260040161053390611849565b506001600160a01b03919091166000908152600660209081526040808320938352929052205490565b6103e881565b61068e610814565b6001600160a01b03166108fc479081150290604051600060405180830381858888f193505050501580156106c6573d6000803e3d6000fd5b50565b6105eb83838360405180602001604052806000815250610a9c565b60006106ee6105f0565b821061070c5760405162461bcd60e51b815260040161053390611d99565b6008828154811061072d57634e487b7160e01b600052603260045260246000fd5b90600052602060002001549050919050565b6000818152600260205260408120546001600160a01b0316806104725760405162461bcd60e51b815260040161053390611b88565b60006001600160a01b03821661079c5760405162461bcd60e51b815260040161053390611b3e565b506001600160a01b031660009081526003602052604090205490565b600a81565b6107c5610cb2565b6001600160a01b03166107d6610814565b6001600160a01b0316146107fc5760405162461bcd60e51b815260040161053390611c89565b6108066000610ece565b565b67016345785d8a000081565b600b546001600160a01b031690565b60606001805461048990611eee565b6103e861083d6105f0565b1061085a5760405162461bcd60e51b815260040161053390611963565b6000811161087a5760405162461bcd60e51b815260040161053390611ab1565b600a81111561089b5760405162461bcd60e51b81526004016105339061199a565b6103e86108b0826108aa6105f0565b90610f20565b11156108ce5760405162461bcd60e51b815260040161053390611bd1565b346108e167016345785d8a000083610f33565b146108fe5760405162461bcd60e51b815260040161053390611800565b60005b818110156109ca576000610915600c610f3f565b9050610921600c610f43565b61092b3382610f4c565b60004340333085604051602001610945949392919061174a565b60408051808303601f1901815291815281516020928301206000948552600d9092528320805462ffff009483901a60f81b6001600160f81b03191660ff60f01b600185901a60f01b161760ff60e81b60029490941a60e890811b949094161790921c9390931662ffffff199091161790915550806109c281611f29565b915050610901565b5050565b6109d6610cb2565b6001600160a01b0316826001600160a01b03161415610a075760405162461bcd60e51b815260040161053390611a2e565b8060056000610a14610cb2565b6001600160a01b03908116825260208083019390935260409182016000908120918716808252919093529120805460ff191692151592909217909155610a58610cb2565b6001600160a01b03167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3183604051610a9091906117cd565b60405180910390a35050565b610aad610aa7610cb2565b83610d24565b610ac95760405162461bcd60e51b815260040161053390611d48565b610ad584848484610f66565b50505050565b600d6020526000908152604090205460e81b81565b60606000610afd8361073f565b6000848152600d60209081526040918290205482516060810184528781526001600160a01b0385169281019290925260e81b6001600160e81b0319811682840152915163c49917d760e01b81529293509091739708af8bca083f1abfea3cdfc4049e54e5ca9ad49163c49917d791610b789190600401611de5565b60006040518083038186803b158015610b9057600080fd5b505af4158015610ba4573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610bcc9190810190611693565b949350505050565b6001600160a01b03918216600090815260056020908152604080832093909416825291909152205460ff1690565b610c0a610cb2565b6001600160a01b0316610c1b610814565b6001600160a01b031614610c415760405162461bcd60e51b815260040161053390611c89565b6001600160a01b038116610c675760405162461bcd60e51b8152600401610533906118e6565b6106c681610ece565b60006001600160e01b0319821663780e9d6360e01b1480610472575061047282610f99565b6000908152600260205260409020546001600160a01b0316151590565b3390565b600081815260046020526040902080546001600160a01b0319166001600160a01b0384169081179091558190610ceb8261073f565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b6000610d2f82610c95565b610d4b5760405162461bcd60e51b815260040161053390611a65565b6000610d568361073f565b9050806001600160a01b0316846001600160a01b03161480610d915750836001600160a01b0316610d868461050c565b6001600160a01b0316145b80610bcc5750610bcc8185610bd4565b826001600160a01b0316610db48261073f565b6001600160a01b031614610dda5760405162461bcd60e51b815260040161053390611cbe565b6001600160a01b038216610e005760405162461bcd60e51b8152600401610533906119ea565b610e0b838383610fd9565b610e16600082610cb6565b6001600160a01b0383166000908152600360205260408120805460019290610e3f908490611eab565b90915550506001600160a01b0382166000908152600360205260408120805460019290610e6d908490611e74565b909155505060008181526002602052604080822080546001600160a01b0319166001600160a01b0386811691821790925591518493918716917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b600b80546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6000610f2c8284611e74565b9392505050565b6000610f2c8284611e8c565b5490565b80546001019055565b6109ca828260405180602001604052806000815250610fe4565b610f71848484610da1565b610f7d84848484611017565b610ad55760405162461bcd60e51b815260040161053390611894565b60006001600160e01b031982166380ac58cd60e01b1480610fca57506001600160e01b03198216635b5e139f60e01b145b80610472575061047282611132565b6105eb83838361114b565b610fee83836111d4565b610ffb6000848484611017565b6105eb5760405162461bcd60e51b815260040161053390611894565b600061102b846001600160a01b03166112b3565b1561112757836001600160a01b031663150b7a02611047610cb2565b8786866040518563ffffffff1660e01b81526004016110699493929190611790565b602060405180830381600087803b15801561108357600080fd5b505af19250505080156110b3575060408051601f3d908101601f191682019092526110b091810190611677565b60015b61110d573d8080156110e1576040519150601f19603f3d011682016040523d82523d6000602084013e6110e6565b606091505b5080516111055760405162461bcd60e51b815260040161053390611894565b805181602001fd5b6001600160e01b031916630a85bd0160e11b149050610bcc565b506001949350505050565b6001600160e01b031981166301ffc9a760e01b14919050565b6111568383836105eb565b6001600160a01b0383166111725761116d816112b9565b611195565b816001600160a01b0316836001600160a01b0316146111955761119583826112fd565b6001600160a01b0382166111b1576111ac8161139a565b6105eb565b826001600160a01b0316826001600160a01b0316146105eb576105eb8282611473565b6001600160a01b0382166111fa5760405162461bcd60e51b815260040161053390611c08565b61120381610c95565b156112205760405162461bcd60e51b81526004016105339061192c565b61122c60008383610fd9565b6001600160a01b0382166000908152600360205260408120805460019290611255908490611e74565b909155505060008181526002602052604080822080546001600160a01b0319166001600160a01b03861690811790915590518392907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b3b151590565b600880546000838152600960205260408120829055600182018355919091527ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee30155565b6000600161130a84610774565b6113149190611eab565b600083815260076020526040902054909150808214611367576001600160a01b03841660009081526006602090815260408083208584528252808320548484528184208190558352600790915290208190555b5060009182526007602090815260408084208490556001600160a01b039094168352600681528383209183525290812055565b6008546000906113ac90600190611eab565b600083815260096020526040812054600880549394509092849081106113e257634e487b7160e01b600052603260045260246000fd5b90600052602060002001549050806008838154811061141157634e487b7160e01b600052603260045260246000fd5b600091825260208083209091019290925582815260099091526040808220849055858252812055600880548061145757634e487b7160e01b600052603160045260246000fd5b6001900381819060005260206000200160009055905550505050565b600061147e83610774565b6001600160a01b039093166000908152600660209081526040808320868452825280832085905593825260079052919091209190915550565b80356001600160a01b038116811461047557600080fd5b6000602082840312156114df578081fd5b610f2c826114b7565b600080604083850312156114fa578081fd5b611503836114b7565b9150611511602084016114b7565b90509250929050565b60008060006060848603121561152e578081fd5b611537846114b7565b9250611545602085016114b7565b9150604084013590509250925092565b6000806000806080858703121561156a578081fd5b611573856114b7565b9350611581602086016114b7565b925060408501359150606085013567ffffffffffffffff8111156115a3578182fd5b8501601f810187136115b3578182fd5b80356115c66115c182611e4c565b611e22565b8181528860208385010111156115da578384fd5b81602084016020830137908101602001929092525092959194509250565b6000806040838503121561160a578182fd5b611613836114b7565b915060208301358015158114611627578182fd5b809150509250929050565b60008060408385031215611644578182fd5b61164d836114b7565b946020939093013593505050565b60006020828403121561166c578081fd5b8135610f2c81611f70565b600060208284031215611688578081fd5b8151610f2c81611f70565b6000602082840312156116a4578081fd5b815167ffffffffffffffff8111156116ba578182fd5b8201601f810184136116ca578182fd5b80516116d86115c182611e4c565b8181528560208385010111156116ec578384fd5b6116fd826020830160208601611ec2565b95945050505050565b600060208284031215611717578081fd5b5035919050565b60008151808452611736816020860160208601611ec2565b601f01601f19169290920160200192915050565b9384526bffffffffffffffffffffffff19606093841b811660208601529190921b166034830152604882015260680190565b6001600160a01b0391909116815260200190565b6001600160a01b03858116825284166020820152604081018390526080606082018190526000906117c39083018461171e565b9695505050505050565b901515815260200190565b6001600160e81b031991909116815260200190565b600060208252610f2c602083018461171e565b60208082526029908201527f4c6f6f74526f636b3a2045746865722076616c75652073656e74206973206e6f6040820152681d0818dbdc9c9958dd60ba1b606082015260800190565b6020808252602b908201527f455243373231456e756d657261626c653a206f776e657220696e646578206f7560408201526a74206f6620626f756e647360a81b606082015260800190565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b60208082526026908201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160408201526564647265737360d01b606082015260800190565b6020808252601c908201527f4552433732313a20746f6b656e20616c7265616479206d696e74656400000000604082015260600190565b60208082526018908201527f4c6f6f74526f636b3a2053616c652068617320656e6465640000000000000000604082015260600190565b60208082526030908201527f4c6f6f74526f636b3a20596f75206d6179206e6f74206275792074686174206d60408201526f616e79204e465473206174206f6e636560801b606082015260800190565b60208082526024908201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646040820152637265737360e01b606082015260800190565b60208082526019908201527f4552433732313a20617070726f766520746f2063616c6c657200000000000000604082015260600190565b6020808252602c908201527f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860408201526b34b9ba32b73a103a37b5b2b760a11b606082015260800190565b60208082526016908201527504c6f6f74526f636b3a2043616e6e6f742062757920360541b604082015260600190565b60208082526038908201527f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f7760408201527f6e6572206e6f7220617070726f76656420666f7220616c6c0000000000000000606082015260800190565b6020808252602a908201527f4552433732313a2062616c616e636520717565727920666f7220746865207a65604082015269726f206164647265737360b01b606082015260800190565b60208082526029908201527f4552433732313a206f776e657220717565727920666f72206e6f6e657869737460408201526832b73a103a37b5b2b760b91b606082015260800190565b6020808252601c908201527f4c6f6f74526f636b3a2045786365656473206d617820737570706c7900000000604082015260600190565b6020808252818101527f4552433732313a206d696e7420746f20746865207a65726f2061646472657373604082015260600190565b6020808252602c908201527f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860408201526b34b9ba32b73a103a37b5b2b760a11b606082015260800190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b60208082526029908201527f4552433732313a207472616e73666572206f6620746f6b656e2074686174206960408201526839903737ba1037bbb760b91b606082015260800190565b60208082526021908201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656040820152603960f91b606082015260800190565b60208082526031908201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f6040820152701ddb995c881b9bdc88185c1c1c9bdd9959607a1b606082015260800190565b6020808252602c908201527f455243373231456e756d657261626c653a20676c6f62616c20696e646578206f60408201526b7574206f6620626f756e647360a01b606082015260800190565b815181526020808301516001600160a01b0316908201526040918201516001600160e81b0319169181019190915260600190565b90815260200190565b60405181810167ffffffffffffffff81118282101715611e4457611e44611f5a565b604052919050565b600067ffffffffffffffff821115611e6657611e66611f5a565b50601f01601f191660200190565b60008219821115611e8757611e87611f44565b500190565b6000816000190483118215151615611ea657611ea6611f44565b500290565b600082821015611ebd57611ebd611f44565b500390565b60005b83811015611edd578181015183820152602001611ec5565b83811115610ad55750506000910152565b600281046001821680611f0257607f821691505b60208210811415611f2357634e487b7160e01b600052602260045260246000fd5b50919050565b6000600019821415611f3d57611f3d611f44565b5060010190565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160e01b0319811681146106c657600080fdfea26469706673582212202774eec9994cccc35ff2b13f229ce1c085cf5ef82bcc2d5e58d8fb8e440d5f0564736f6c63430008000033
Deployed Bytecode Sourcemap
69199:2626:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;71610:212;;;;;;;;;;-1:-1:-1;71610:212:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;37787:100;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;39346:221::-;;;;;;;;;;-1:-1:-1;39346:221:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;38869:411::-;;;;;;;;;;-1:-1:-1;38869:411:0;;;;;:::i;:::-;;:::i;:::-;;53450:113;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;40236:339::-;;;;;;;;;;-1:-1:-1;40236:339:0;;;;;:::i;:::-;;:::i;53118:256::-;;;;;;;;;;-1:-1:-1;53118:256:0;;;;;:::i;:::-;;:::i;69360:41::-;;;;;;;;;;;;;:::i;71103:94::-;;;;;;;;;;;;;:::i;40646:185::-;;;;;;;;;;-1:-1:-1;40646:185:0;;;;;:::i;:::-;;:::i;53640:233::-;;;;;;;;;;-1:-1:-1;53640:233:0;;;;;:::i;:::-;;:::i;37481:239::-;;;;;;;;;;-1:-1:-1;37481:239:0;;;;;:::i;:::-;;:::i;37211:208::-;;;;;;;;;;-1:-1:-1;37211:208:0;;;;;:::i;:::-;;:::i;69408:41::-;;;;;;;;;;;;;:::i;18207:94::-;;;;;;;;;;;;;:::i;69456:46::-;;;;;;;;;;;;;:::i;17556:87::-;;;;;;;;;;;;;:::i;37956:104::-;;;;;;;;;;;;;:::i;69673:961::-;;;;;;:::i;:::-;;:::i;39639:295::-;;;;;;;;;;-1:-1:-1;39639:295:0;;;;;:::i;:::-;;:::i;40902:328::-;;;;;;;;;;-1:-1:-1;40902:328:0;;;;;:::i;:::-;;:::i;69568:41::-;;;;;;;;;;-1:-1:-1;69568:41:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;70646:445::-;;;;;;;;;;-1:-1:-1;70646:445:0;;;;;:::i;:::-;;:::i;40005:164::-;;;;;;;;;;-1:-1:-1;40005:164:0;;;;;:::i;:::-;;:::i;18456:192::-;;;;;;;;;;-1:-1:-1;18456:192:0;;;;;:::i;:::-;;:::i;71610:212::-;71749:4;71778:36;71802:11;71778:23;:36::i;:::-;71771:43;;71610:212;;;;:::o;37787:100::-;37841:13;37874:5;37867:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;37787:100;:::o;39346:221::-;39422:7;39450:16;39458:7;39450;:16::i;:::-;39442:73;;;;-1:-1:-1;;;39442:73:0;;;;;;;:::i;:::-;;;;;;;;;-1:-1:-1;39535:24:0;;;;:15;:24;;;;;;-1:-1:-1;;;;;39535:24:0;;39346:221::o;38869:411::-;38950:13;38966:23;38981:7;38966:14;:23::i;:::-;38950:39;;39014:5;-1:-1:-1;;;;;39008:11:0;:2;-1:-1:-1;;;;;39008:11:0;;;39000:57;;;;-1:-1:-1;;;39000:57:0;;;;;;;:::i;:::-;39108:5;-1:-1:-1;;;;;39092:21:0;:12;:10;:12::i;:::-;-1:-1:-1;;;;;39092:21:0;;:62;;;;39117:37;39134:5;39141:12;:10;:12::i;39117:37::-;39070:168;;;;-1:-1:-1;;;39070:168:0;;;;;;;:::i;:::-;39251:21;39260:2;39264:7;39251:8;:21::i;:::-;38869:411;;;:::o;53450:113::-;53538:10;:17;53450:113;:::o;40236:339::-;40431:41;40450:12;:10;:12::i;:::-;40464:7;40431:18;:41::i;:::-;40423:103;;;;-1:-1:-1;;;40423:103:0;;;;;;;:::i;:::-;40539:28;40549:4;40555:2;40559:7;40539:9;:28::i;53118:256::-;53215:7;53251:23;53268:5;53251:16;:23::i;:::-;53243:5;:31;53235:87;;;;-1:-1:-1;;;53235:87:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;;53340:19:0;;;;;;;;:12;:19;;;;;;;;:26;;;;;;;;;53118:256::o;69360:41::-;69397:4;69360:41;:::o;71103:94::-;71149:7;:5;:7::i;:::-;-1:-1:-1;;;;;71141:25:0;:48;71167:21;71141:48;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;71103:94::o;40646:185::-;40784:39;40801:4;40807:2;40811:7;40784:39;;;;;;;;;;;;:16;:39::i;53640:233::-;53715:7;53751:30;:28;:30::i;:::-;53743:5;:38;53735:95;;;;-1:-1:-1;;;53735:95:0;;;;;;;:::i;:::-;53848:10;53859:5;53848:17;;;;;;-1:-1:-1;;;53848:17:0;;;;;;;;;;;;;;;;;53841:24;;53640:233;;;:::o;37481:239::-;37553:7;37589:16;;;:7;:16;;;;;;-1:-1:-1;;;;;37589:16:0;37624:19;37616:73;;;;-1:-1:-1;;;37616:73:0;;;;;;;:::i;37211:208::-;37283:7;-1:-1:-1;;;;;37311:19:0;;37303:74;;;;-1:-1:-1;;;37303:74:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;;37395:16:0;;;;;:9;:16;;;;;;;37211:208::o;69408:41::-;69447:2;69408:41;:::o;18207:94::-;17787:12;:10;:12::i;:::-;-1:-1:-1;;;;;17776:23:0;:7;:5;:7::i;:::-;-1:-1:-1;;;;;17776:23:0;;17768:68;;;;-1:-1:-1;;;17768:68:0;;;;;;;:::i;:::-;18272:21:::1;18290:1;18272:9;:21::i;:::-;18207:94::o:0;69456:46::-;69488:14;69456:46;:::o;17556:87::-;17629:6;;-1:-1:-1;;;;;17629:6:0;17556:87;:::o;37956:104::-;38012:13;38045:7;38038:14;;;;;:::i;69673:961::-;69397:4;69737:13;:11;:13::i;:::-;:26;69729:63;;;;-1:-1:-1;;;69729:63:0;;;;;;;:::i;:::-;69820:1;69811:6;:10;69803:45;;;;-1:-1:-1;;;69803:45:0;;;;;;;:::i;:::-;69447:2;69867:6;:22;;69859:83;;;;-1:-1:-1;;;69859:83:0;;;;;;;:::i;:::-;69397:4;69961:25;69979:6;69961:13;:11;:13::i;:::-;:17;;:25::i;:::-;:39;;69953:80;;;;-1:-1:-1;;;69953:80:0;;;;;;;:::i;:::-;70073:9;70052:17;69488:14;70062:6;70052:9;:17::i;:::-;:30;70044:84;;;;-1:-1:-1;;;70044:84:0;;;;;;;:::i;:::-;70146:6;70141:486;70162:6;70158:1;:10;70141:486;;;70190:15;70208:25;:15;:23;:25::i;:::-;70190:43;;70248:27;:15;:25;:27::i;:::-;70304:30;70314:10;70326:7;70304:9;:30::i;:::-;70363:25;70428:12;70418:23;70443:10;70463:4;70470:1;70401:71;;;;;;;;;;;:::i;:::-;;;;;;;-1:-1:-1;;70401:71:0;;;;;;70391:82;;70401:71;70391:82;;;;70531:1;70488:15;;;:6;:15;;;;;:127;;;70513:20;;;;70586;70513;-1:-1:-1;;;;;;70506:28:0;-1:-1:-1;;;70564:1:0;70546:20;;;70539:33;;;70506:68;-1:-1:-1;;;70604:1:0;70586:20;;;;70579:34;;;;;;;;70506:109;70488:127;;;;;;;-1:-1:-1;;70488:127:0;;;;;;;-1:-1:-1;70170:3:0;;;;:::i;:::-;;;;70141:486;;;;69673:961;:::o;39639:295::-;39754:12;:10;:12::i;:::-;-1:-1:-1;;;;;39742:24:0;:8;-1:-1:-1;;;;;39742:24:0;;;39734:62;;;;-1:-1:-1;;;39734:62:0;;;;;;;:::i;:::-;39854:8;39809:18;:32;39828:12;:10;:12::i;:::-;-1:-1:-1;;;;;39809:32:0;;;;;;;;;;;;;;;;;-1:-1:-1;39809:32:0;;;:42;;;;;;;;;;;;:53;;-1:-1:-1;;39809:53:0;;;;;;;;;;;39893:12;:10;:12::i;:::-;-1:-1:-1;;;;;39878:48:0;;39917:8;39878:48;;;;;;:::i;:::-;;;;;;;;39639:295;;:::o;40902:328::-;41077:41;41096:12;:10;:12::i;:::-;41110:7;41077:18;:41::i;:::-;41069:103;;;;-1:-1:-1;;;41069:103:0;;;;;;;:::i;:::-;41183:39;41197:4;41203:2;41207:7;41216:5;41183:13;:39::i;:::-;40902:328;;;;:::o;69568:41::-;;;;;;;;;;;;;;;:::o;70646:445::-;70746:13;70777;70793:16;70801:7;70793;:16::i;:::-;70820:12;70835:15;;;:6;:15;;;;;;;;;;70915:167;;;;;;;;;;-1:-1:-1;;;;;70915:167:0;;;;;;;;;70835:15;;-1:-1:-1;;;;;;70915:167:0;;;;;;70883:200;;-1:-1:-1;;;70883:200:0;;70915:167;;-1:-1:-1;70835:15:0;;70883:13;;:31;;:200;;70915:167;70883:200;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;70883:200:0;;;;;;;;;;;;:::i;:::-;70863:220;70646:445;-1:-1:-1;;;;70646:445:0:o;40005:164::-;-1:-1:-1;;;;;40126:25:0;;;40102:4;40126:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;;;40005:164::o;18456:192::-;17787:12;:10;:12::i;:::-;-1:-1:-1;;;;;17776:23:0;:7;:5;:7::i;:::-;-1:-1:-1;;;;;17776:23:0;;17768:68;;;;-1:-1:-1;;;17768:68:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;18545:22:0;::::1;18537:73;;;;-1:-1:-1::0;;;18537:73:0::1;;;;;;;:::i;:::-;18621:19;18631:8;18621:9;:19::i;52810:224::-:0;52912:4;-1:-1:-1;;;;;;52936:50:0;;-1:-1:-1;;;52936:50:0;;:90;;;52990:36;53014:11;52990:23;:36::i;42740:127::-;42805:4;42829:16;;;:7;:16;;;;;;-1:-1:-1;;;;;42829:16:0;:30;;;42740:127::o;658:98::-;738:10;658:98;:::o;46722:174::-;46797:24;;;;:15;:24;;;;;:29;;-1:-1:-1;;;;;;46797:29:0;-1:-1:-1;;;;;46797:29:0;;;;;;;;:24;;46851:23;46797:24;46851:14;:23::i;:::-;-1:-1:-1;;;;;46842:46:0;;;;;;;;;;;46722:174;;:::o;43034:348::-;43127:4;43152:16;43160:7;43152;:16::i;:::-;43144:73;;;;-1:-1:-1;;;43144:73:0;;;;;;;:::i;:::-;43228:13;43244:23;43259:7;43244:14;:23::i;:::-;43228:39;;43297:5;-1:-1:-1;;;;;43286:16:0;:7;-1:-1:-1;;;;;43286:16:0;;:51;;;;43330:7;-1:-1:-1;;;;;43306:31:0;:20;43318:7;43306:11;:20::i;:::-;-1:-1:-1;;;;;43306:31:0;;43286:51;:87;;;;43341:32;43358:5;43365:7;43341:16;:32::i;46026:578::-;46185:4;-1:-1:-1;;;;;46158:31:0;:23;46173:7;46158:14;:23::i;:::-;-1:-1:-1;;;;;46158:31:0;;46150:85;;;;-1:-1:-1;;;46150:85:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;46254:16:0;;46246:65;;;;-1:-1:-1;;;46246:65:0;;;;;;;:::i;:::-;46324:39;46345:4;46351:2;46355:7;46324:20;:39::i;:::-;46428:29;46445:1;46449:7;46428:8;:29::i;:::-;-1:-1:-1;;;;;46470:15:0;;;;;;:9;:15;;;;;:20;;46489:1;;46470:15;:20;;46489:1;;46470:20;:::i;:::-;;;;-1:-1:-1;;;;;;;46501:13:0;;;;;;:9;:13;;;;;:18;;46518:1;;46501:13;:18;;46518:1;;46501:18;:::i;:::-;;;;-1:-1:-1;;46530:16:0;;;;:7;:16;;;;;;:21;;-1:-1:-1;;;;;;46530:21:0;-1:-1:-1;;;;;46530:21:0;;;;;;;;;46569:27;;46530:16;;46569:27;;;;;;;46026:578;;;:::o;18656:173::-;18731:6;;;-1:-1:-1;;;;;18748:17:0;;;-1:-1:-1;;;;;;18748:17:0;;;;;;;18781:40;;18731:6;;;18748:17;18731:6;;18781:40;;18712:16;;18781:40;18656:173;;:::o;23038:98::-;23096:7;23123:5;23127:1;23123;:5;:::i;:::-;23116:12;23038:98;-1:-1:-1;;;23038:98:0:o;23776:::-;23834:7;23861:5;23865:1;23861;:5;:::i;19653:114::-;19745:14;;19653:114::o;19775:127::-;19864:19;;19882:1;19864:19;;;19775:127::o;43724:110::-;43800:26;43810:2;43814:7;43800:26;;;;;;;;;;;;:9;:26::i;42112:315::-;42269:28;42279:4;42285:2;42289:7;42269:9;:28::i;:::-;42316:48;42339:4;42345:2;42349:7;42358:5;42316:22;:48::i;:::-;42308:111;;;;-1:-1:-1;;;42308:111:0;;;;;;;:::i;36842:305::-;36944:4;-1:-1:-1;;;;;;36981:40:0;;-1:-1:-1;;;36981:40:0;;:105;;-1:-1:-1;;;;;;;37038:48:0;;-1:-1:-1;;;37038:48:0;36981:105;:158;;;;37103:36;37127:11;37103:23;:36::i;71275:204::-;71426:45;71453:4;71459:2;71463:7;71426:26;:45::i;44061:321::-;44191:18;44197:2;44201:7;44191:5;:18::i;:::-;44242:54;44273:1;44277:2;44281:7;44290:5;44242:22;:54::i;:::-;44220:154;;;;-1:-1:-1;;;44220:154:0;;;;;;;:::i;47461:799::-;47616:4;47637:15;:2;-1:-1:-1;;;;;47637:13:0;;:15::i;:::-;47633:620;;;47689:2;-1:-1:-1;;;;;47673:36:0;;47710:12;:10;:12::i;:::-;47724:4;47730:7;47739:5;47673:72;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;47673:72:0;;;;;;;;-1:-1:-1;;47673:72:0;;;;;;;;;;;;:::i;:::-;;;47669:529;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;47915:13:0;;47911:272;;47958:60;;-1:-1:-1;;;47958:60:0;;;;;;;:::i;47911:272::-;48133:6;48127:13;48118:6;48114:2;48110:15;48103:38;47669:529;-1:-1:-1;;;;;;47796:51:0;-1:-1:-1;;;47796:51:0;;-1:-1:-1;47789:58:0;;47633:620;-1:-1:-1;48237:4:0;47461:799;;;;;;:::o;35346:157::-;-1:-1:-1;;;;;;35455:40:0;;-1:-1:-1;;;35455:40:0;35346:157;;;:::o;54486:589::-;54630:45;54657:4;54663:2;54667:7;54630:26;:45::i;:::-;-1:-1:-1;;;;;54692:18:0;;54688:187;;54727:40;54759:7;54727:31;:40::i;:::-;54688:187;;;54797:2;-1:-1:-1;;;;;54789:10:0;:4;-1:-1:-1;;;;;54789:10:0;;54785:90;;54816:47;54849:4;54855:7;54816:32;:47::i;:::-;-1:-1:-1;;;;;54889:16:0;;54885:183;;54922:45;54959:7;54922:36;:45::i;:::-;54885:183;;;54995:4;-1:-1:-1;;;;;54989:10:0;:2;-1:-1:-1;;;;;54989:10:0;;54985:83;;55016:40;55044:2;55048:7;55016:27;:40::i;44718:382::-;-1:-1:-1;;;;;44798:16:0;;44790:61;;;;-1:-1:-1;;;44790:61:0;;;;;;;:::i;:::-;44871:16;44879:7;44871;:16::i;:::-;44870:17;44862:58;;;;-1:-1:-1;;;44862:58:0;;;;;;;:::i;:::-;44933:45;44962:1;44966:2;44970:7;44933:20;:45::i;:::-;-1:-1:-1;;;;;44991:13:0;;;;;;:9;:13;;;;;:18;;45008:1;;44991:13;:18;;45008:1;;44991:18;:::i;:::-;;;;-1:-1:-1;;45020:16:0;;;;:7;:16;;;;;;:21;;-1:-1:-1;;;;;;45020:21:0;-1:-1:-1;;;;;45020:21:0;;;;;;;;45059:33;;45020:16;;;45059:33;;45020:16;;45059:33;44718:382;;:::o;61796:387::-;62119:20;62167:8;;;61796:387::o;55798:164::-;55902:10;:17;;55875:24;;;;:15;:24;;;;;:44;;;55930:24;;;;;;;;;;;;55798:164::o;56589:988::-;56855:22;56905:1;56880:22;56897:4;56880:16;:22::i;:::-;:26;;;;:::i;:::-;56917:18;56938:26;;;:17;:26;;;;;;56855:51;;-1:-1:-1;57071:28:0;;;57067:328;;-1:-1:-1;;;;;57138:18:0;;57116:19;57138:18;;;:12;:18;;;;;;;;:34;;;;;;;;;57189:30;;;;;;:44;;;57306:30;;:17;:30;;;;;:43;;;57067:328;-1:-1:-1;57491:26:0;;;;:17;:26;;;;;;;;57484:33;;;-1:-1:-1;;;;;57535:18:0;;;;;:12;:18;;;;;:34;;;;;;;57528:41;56589:988::o;57872:1079::-;58150:10;:17;58125:22;;58150:21;;58170:1;;58150:21;:::i;:::-;58182:18;58203:24;;;:15;:24;;;;;;58576:10;:26;;58125:46;;-1:-1:-1;58203:24:0;;58125:46;;58576:26;;;;-1:-1:-1;;;58576:26:0;;;;;;;;;;;;;;;;;58554:48;;58640:11;58615:10;58626;58615:22;;;;;;-1:-1:-1;;;58615:22:0;;;;;;;;;;;;;;;;;;;;:36;;;;58720:28;;;:15;:28;;;;;;;:41;;;58892:24;;;;;58885:31;58927:10;:16;;;;;-1:-1:-1;;;58927:16:0;;;;;;;;;;;;;;;;;;;;;;;;;;57872:1079;;;;:::o;55376:221::-;55461:14;55478:20;55495:2;55478:16;:20::i;:::-;-1:-1:-1;;;;;55509:16:0;;;;;;;:12;:16;;;;;;;;:24;;;;;;;;:34;;;55554:26;;;:17;:26;;;;;;:35;;;;-1:-1:-1;55376:221:0:o;14:175:1:-;84:20;;-1:-1:-1;;;;;133:31:1;;123:42;;113:2;;179:1;176;169:12;194:198;;306:2;294:9;285:7;281:23;277:32;274:2;;;327:6;319;312:22;274:2;355:31;376:9;355:31;:::i;397:274::-;;;526:2;514:9;505:7;501:23;497:32;494:2;;;547:6;539;532:22;494:2;575:31;596:9;575:31;:::i;:::-;565:41;;625:40;661:2;650:9;646:18;625:40;:::i;:::-;615:50;;484:187;;;;;:::o;676:342::-;;;;822:2;810:9;801:7;797:23;793:32;790:2;;;843:6;835;828:22;790:2;871:31;892:9;871:31;:::i;:::-;861:41;;921:40;957:2;946:9;942:18;921:40;:::i;:::-;911:50;;1008:2;997:9;993:18;980:32;970:42;;780:238;;;;;:::o;1023:938::-;;;;;1195:3;1183:9;1174:7;1170:23;1166:33;1163:2;;;1217:6;1209;1202:22;1163:2;1245:31;1266:9;1245:31;:::i;:::-;1235:41;;1295:40;1331:2;1320:9;1316:18;1295:40;:::i;:::-;1285:50;;1382:2;1371:9;1367:18;1354:32;1344:42;;1437:2;1426:9;1422:18;1409:32;1464:18;1456:6;1453:30;1450:2;;;1501:6;1493;1486:22;1450:2;1529:22;;1582:4;1574:13;;1570:27;-1:-1:-1;1560:2:1;;1616:6;1608;1601:22;1560:2;1657;1644:16;1682:49;1697:33;1727:2;1697:33;:::i;:::-;1682:49;:::i;:::-;1754:2;1747:5;1740:17;1794:7;1789:2;1784;1780;1776:11;1772:20;1769:33;1766:2;;;1820:6;1812;1805:22;1766:2;1880;1875;1871;1867:11;1862:2;1855:5;1851:14;1838:45;1903:14;;;1919:2;1899:23;1892:39;;;;-1:-1:-1;1153:808:1;;;;-1:-1:-1;1153:808:1;-1:-1:-1;1153:808:1:o;1966:369::-;;;2092:2;2080:9;2071:7;2067:23;2063:32;2060:2;;;2113:6;2105;2098:22;2060:2;2141:31;2162:9;2141:31;:::i;:::-;2131:41;;2222:2;2211:9;2207:18;2194:32;2269:5;2262:13;2255:21;2248:5;2245:32;2235:2;;2296:6;2288;2281:22;2235:2;2324:5;2314:15;;;2050:285;;;;;:::o;2340:266::-;;;2469:2;2457:9;2448:7;2444:23;2440:32;2437:2;;;2490:6;2482;2475:22;2437:2;2518:31;2539:9;2518:31;:::i;:::-;2508:41;2596:2;2581:18;;;;2568:32;;-1:-1:-1;;;2427:179:1:o;2611:257::-;;2722:2;2710:9;2701:7;2697:23;2693:32;2690:2;;;2743:6;2735;2728:22;2690:2;2787:9;2774:23;2806:32;2832:5;2806:32;:::i;2873:261::-;;2995:2;2983:9;2974:7;2970:23;2966:32;2963:2;;;3016:6;3008;3001:22;2963:2;3053:9;3047:16;3072:32;3098:5;3072:32;:::i;3139:676::-;;3272:2;3260:9;3251:7;3247:23;3243:32;3240:2;;;3293:6;3285;3278:22;3240:2;3331:9;3325:16;3364:18;3356:6;3353:30;3350:2;;;3401:6;3393;3386:22;3350:2;3429:22;;3482:4;3474:13;;3470:27;-1:-1:-1;3460:2:1;;3516:6;3508;3501:22;3460:2;3550;3544:9;3575:49;3590:33;3620:2;3590:33;:::i;3575:49::-;3647:2;3640:5;3633:17;3687:7;3682:2;3677;3673;3669:11;3665:20;3662:33;3659:2;;;3713:6;3705;3698:22;3659:2;3731:54;3782:2;3777;3770:5;3766:14;3761:2;3757;3753:11;3731:54;:::i;:::-;3804:5;3230:585;-1:-1:-1;;;;;3230:585:1:o;3820:190::-;;3932:2;3920:9;3911:7;3907:23;3903:32;3900:2;;;3953:6;3945;3938:22;3900:2;-1:-1:-1;3981:23:1;;3890:120;-1:-1:-1;3890:120:1:o;4015:259::-;;4096:5;4090:12;4123:6;4118:3;4111:19;4139:63;4195:6;4188:4;4183:3;4179:14;4172:4;4165:5;4161:16;4139:63;:::i;:::-;4256:2;4235:15;-1:-1:-1;;4231:29:1;4222:39;;;;4263:4;4218:50;;4066:208;-1:-1:-1;;4066:208:1:o;4279:464::-;4492:19;;;-1:-1:-1;;4599:2:1;4595:15;;;4591:24;;4586:2;4577:12;;4570:46;4650:15;;;;4646:24;4641:2;4632:12;;4625:46;4696:2;4687:12;;4680:28;4733:3;4724:13;;4482:261::o;4748:203::-;-1:-1:-1;;;;;4912:32:1;;;;4894:51;;4882:2;4867:18;;4849:102::o;4956:490::-;-1:-1:-1;;;;;5225:15:1;;;5207:34;;5277:15;;5272:2;5257:18;;5250:43;5324:2;5309:18;;5302:34;;;5372:3;5367:2;5352:18;;5345:31;;;4956:490;;5393:47;;5420:19;;5412:6;5393:47;:::i;:::-;5385:55;5159:287;-1:-1:-1;;;;;;5159:287:1:o;5451:187::-;5616:14;;5609:22;5591:41;;5579:2;5564:18;;5546:92::o;5643:200::-;-1:-1:-1;;;;;;5805:31:1;;;;5787:50;;5775:2;5760:18;;5742:101::o;5848:221::-;;5997:2;5986:9;5979:21;6017:46;6059:2;6048:9;6044:18;6036:6;6017:46;:::i;6074:405::-;6276:2;6258:21;;;6315:2;6295:18;;;6288:30;6354:34;6349:2;6334:18;;6327:62;-1:-1:-1;;;6420:2:1;6405:18;;6398:39;6469:3;6454:19;;6248:231::o;6484:407::-;6686:2;6668:21;;;6725:2;6705:18;;;6698:30;6764:34;6759:2;6744:18;;6737:62;-1:-1:-1;;;6830:2:1;6815:18;;6808:41;6881:3;6866:19;;6658:233::o;6896:414::-;7098:2;7080:21;;;7137:2;7117:18;;;7110:30;7176:34;7171:2;7156:18;;7149:62;-1:-1:-1;;;7242:2:1;7227:18;;7220:48;7300:3;7285:19;;7070:240::o;7315:402::-;7517:2;7499:21;;;7556:2;7536:18;;;7529:30;7595:34;7590:2;7575:18;;7568:62;-1:-1:-1;;;7661:2:1;7646:18;;7639:36;7707:3;7692:19;;7489:228::o;7722:352::-;7924:2;7906:21;;;7963:2;7943:18;;;7936:30;8002;7997:2;7982:18;;7975:58;8065:2;8050:18;;7896:178::o;8079:348::-;8281:2;8263:21;;;8320:2;8300:18;;;8293:30;8359:26;8354:2;8339:18;;8332:54;8418:2;8403:18;;8253:174::o;8432:412::-;8634:2;8616:21;;;8673:2;8653:18;;;8646:30;8712:34;8707:2;8692:18;;8685:62;-1:-1:-1;;;8778:2:1;8763:18;;8756:46;8834:3;8819:19;;8606:238::o;8849:400::-;9051:2;9033:21;;;9090:2;9070:18;;;9063:30;9129:34;9124:2;9109:18;;9102:62;-1:-1:-1;;;9195:2:1;9180:18;;9173:34;9239:3;9224:19;;9023:226::o;9254:349::-;9456:2;9438:21;;;9495:2;9475:18;;;9468:30;9534:27;9529:2;9514:18;;9507:55;9594:2;9579:18;;9428:175::o;9608:408::-;9810:2;9792:21;;;9849:2;9829:18;;;9822:30;9888:34;9883:2;9868:18;;9861:62;-1:-1:-1;;;9954:2:1;9939:18;;9932:42;10006:3;9991:19;;9782:234::o;10021:346::-;10223:2;10205:21;;;10262:2;10242:18;;;10235:30;-1:-1:-1;;;10296:2:1;10281:18;;10274:52;10358:2;10343:18;;10195:172::o;10372:420::-;10574:2;10556:21;;;10613:2;10593:18;;;10586:30;10652:34;10647:2;10632:18;;10625:62;10723:26;10718:2;10703:18;;10696:54;10782:3;10767:19;;10546:246::o;10797:406::-;10999:2;10981:21;;;11038:2;11018:18;;;11011:30;11077:34;11072:2;11057:18;;11050:62;-1:-1:-1;;;11143:2:1;11128:18;;11121:40;11193:3;11178:19;;10971:232::o;11208:405::-;11410:2;11392:21;;;11449:2;11429:18;;;11422:30;11488:34;11483:2;11468:18;;11461:62;-1:-1:-1;;;11554:2:1;11539:18;;11532:39;11603:3;11588:19;;11382:231::o;11618:352::-;11820:2;11802:21;;;11859:2;11839:18;;;11832:30;11898;11893:2;11878:18;;11871:58;11961:2;11946:18;;11792:178::o;11975:356::-;12177:2;12159:21;;;12196:18;;;12189:30;12255:34;12250:2;12235:18;;12228:62;12322:2;12307:18;;12149:182::o;12336:408::-;12538:2;12520:21;;;12577:2;12557:18;;;12550:30;12616:34;12611:2;12596:18;;12589:62;-1:-1:-1;;;12682:2:1;12667:18;;12660:42;12734:3;12719:19;;12510:234::o;12749:356::-;12951:2;12933:21;;;12970:18;;;12963:30;13029:34;13024:2;13009:18;;13002:62;13096:2;13081:18;;12923:182::o;13110:405::-;13312:2;13294:21;;;13351:2;13331:18;;;13324:30;13390:34;13385:2;13370:18;;13363:62;-1:-1:-1;;;13456:2:1;13441:18;;13434:39;13505:3;13490:19;;13284:231::o;13520:397::-;13722:2;13704:21;;;13761:2;13741:18;;;13734:30;13800:34;13795:2;13780:18;;13773:62;-1:-1:-1;;;13866:2:1;13851:18;;13844:31;13907:3;13892:19;;13694:223::o;13922:413::-;14124:2;14106:21;;;14163:2;14143:18;;;14136:30;14202:34;14197:2;14182:18;;14175:62;-1:-1:-1;;;14268:2:1;14253:18;;14246:47;14325:3;14310:19;;14096:239::o;14340:408::-;14542:2;14524:21;;;14581:2;14561:18;;;14554:30;14620:34;14615:2;14600:18;;14593:62;-1:-1:-1;;;14686:2:1;14671:18;;14664:42;14738:3;14723:19;;14514:234::o;14753:449::-;15005:13;;14987:32;;15079:4;15067:17;;;15061:24;-1:-1:-1;;;;;15057:50:1;15035:20;;;15028:80;15168:4;15156:17;;;15150:24;-1:-1:-1;;;;;;15146:49:1;15124:20;;;15117:79;;;;14975:2;14960:18;;14942:260::o;15207:177::-;15353:25;;;15341:2;15326:18;;15308:76::o;15389:251::-;15459:2;15453:9;15489:17;;;15536:18;15521:34;;15557:22;;;15518:62;15515:2;;;15583:18;;:::i;:::-;15619:2;15612:22;15433:207;;-1:-1:-1;15433:207:1:o;15645:190::-;;15728:18;15720:6;15717:30;15714:2;;;15750:18;;:::i;:::-;-1:-1:-1;15818:2:1;15795:17;-1:-1:-1;;15791:31:1;15824:4;15787:42;;15704:131::o;15840:128::-;;15911:1;15907:6;15904:1;15901:13;15898:2;;;15917:18;;:::i;:::-;-1:-1:-1;15953:9:1;;15888:80::o;15973:168::-;;16079:1;16075;16071:6;16067:14;16064:1;16061:21;16056:1;16049:9;16042:17;16038:45;16035:2;;;16086:18;;:::i;:::-;-1:-1:-1;16126:9:1;;16025:116::o;16146:125::-;;16214:1;16211;16208:8;16205:2;;;16219:18;;:::i;:::-;-1:-1:-1;16256:9:1;;16195:76::o;16276:258::-;16348:1;16358:113;16372:6;16369:1;16366:13;16358:113;;;16448:11;;;16442:18;16429:11;;;16422:39;16394:2;16387:10;16358:113;;;16489:6;16486:1;16483:13;16480:2;;;-1:-1:-1;;16524:1:1;16506:16;;16499:27;16329:205::o;16539:380::-;16624:1;16614:12;;16671:1;16661:12;;;16682:2;;16736:4;16728:6;16724:17;16714:27;;16682:2;16789;16781:6;16778:14;16758:18;16755:38;16752:2;;;16835:10;16830:3;16826:20;16823:1;16816:31;16870:4;16867:1;16860:15;16898:4;16895:1;16888:15;16752:2;;16594:325;;;:::o;16924:135::-;;-1:-1:-1;;16984:17:1;;16981:2;;;17004:18;;:::i;:::-;-1:-1:-1;17051:1:1;17040:13;;16971:88::o;17064:127::-;17125:10;17120:3;17116:20;17113:1;17106:31;17156:4;17153:1;17146:15;17180:4;17177:1;17170:15;17196:127;17257:10;17252:3;17248:20;17245:1;17238:31;17288:4;17285:1;17278:15;17312:4;17309:1;17302:15;17328:133;-1:-1:-1;;;;;;17404:32:1;;17394:43;;17384:2;;17451:1;17448;17441:12
Swarm Source
ipfs://2774eec9994cccc35ff2b13f229ce1c085cf5ef82bcc2d5e58d8fb8e440d5f05
Loading...
Loading
Loading...
Loading
Net Worth in USD
$0.00
Net Worth in ETH
0
Multichain Portfolio | 33 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.