Source Code
Overview
ETH Balance
0 ETH
Eth Value
$0.00Latest 25 from a total of 242 transactions
| Transaction Hash |
Method
|
Block
|
From
|
|
To
|
||||
|---|---|---|---|---|---|---|---|---|---|
| Withdraw Balance | 14590056 | 1428 days ago | IN | 0 ETH | 0.00084144 | ||||
| Batch Buy Gen0Wi... | 14588362 | 1428 days ago | IN | 0 ETH | 0.06285638 | ||||
| Set Batch White ... | 14567863 | 1431 days ago | IN | 0 ETH | 0.00936748 | ||||
| Batch Buy Gen0Wi... | 14524867 | 1438 days ago | IN | 0 ETH | 0.01404805 | ||||
| Set Batch White ... | 14523153 | 1438 days ago | IN | 0 ETH | 0.01082289 | ||||
| Batch Buy Gen0 | 14517086 | 1439 days ago | IN | 0.08 ETH | 0.0114588 | ||||
| Batch Buy Gen0 | 14514801 | 1440 days ago | IN | 0.08 ETH | 0.01766113 | ||||
| Batch Buy Gen0 | 14440122 | 1451 days ago | IN | 0.08 ETH | 0.01500806 | ||||
| Batch Buy Gen0 | 14436857 | 1452 days ago | IN | 0.08 ETH | 0.01624458 | ||||
| Batch Buy Gen0Wi... | 14428305 | 1453 days ago | IN | 0 ETH | 0.01501664 | ||||
| Set White List | 14428297 | 1453 days ago | IN | 0 ETH | 0.00095909 | ||||
| Batch Buy Gen0 | 14385850 | 1460 days ago | IN | 0.08 ETH | 0.00871713 | ||||
| Batch Buy Gen0 | 14383905 | 1460 days ago | IN | 0.08 ETH | 0.00612714 | ||||
| Batch Buy Gen0Wi... | 14378025 | 1461 days ago | IN | 0.04 ETH | 0.00482568 | ||||
| Batch Buy Gen0 | 14377813 | 1461 days ago | IN | 0.08 ETH | 0.00446948 | ||||
| Set Batch White ... | 14377227 | 1461 days ago | IN | 0 ETH | 0.00199679 | ||||
| Batch Buy Gen0 | 14375672 | 1461 days ago | IN | 0.08 ETH | 0.00685366 | ||||
| Batch Buy Gen0 | 14373575 | 1462 days ago | IN | 0.08 ETH | 0.01156817 | ||||
| Batch Buy Gen0Wi... | 14373544 | 1462 days ago | IN | 0.04 ETH | 0.00950642 | ||||
| Batch Buy Gen0Wi... | 14370474 | 1462 days ago | IN | 0 ETH | 0.00743055 | ||||
| Set Batch White ... | 14369340 | 1462 days ago | IN | 0 ETH | 0.01056992 | ||||
| Set White List | 14358744 | 1464 days ago | IN | 0 ETH | 0.00159905 | ||||
| Set White List | 14358736 | 1464 days ago | IN | 0 ETH | 0.00167922 | ||||
| Set White List | 14356948 | 1464 days ago | IN | 0 ETH | 0.00348468 | ||||
| Set Batch White ... | 14356631 | 1464 days ago | IN | 0 ETH | 0.00347775 |
Latest 1 internal transaction
Advanced mode:
| Parent Transaction Hash | Method | Block |
From
|
|
To
|
||
|---|---|---|---|---|---|---|---|
| - | 14590056 | 1428 days ago | 15.37 ETH |
Loading...
Loading
Loading...
Loading
Cross-Chain Transactions
Loading...
Loading
Contract Name:
BunnyRouter
Compiler Version
v0.8.0+commit.c7dfd78e
Contract Source Code (Solidity)
/**
*Submitted for verification at Etherscan.io on 2021-12-31
*/
/**
*Submitted for verification at Etherscan.io on 2021-12-31
*/
/**
*Submitted for verification at Etherscan.io on 2021-12-24
*/
// File: contracts/libs/Initializable.sol
pragma solidity ^0.8.0;
library EnumerableSetUpgradeable {
// To implement this library for multiple types with as little code
// repetition as possible, we write it in terms of a generic Set type with
// bytes32 values.
// The Set implementation uses private functions, and user-facing
// implementations (such as AddressSet) are just wrappers around the
// underlying Set.
// This means that we can only create new EnumerableSets for types that fit
// in bytes32.
struct Set {
// Storage of set values
bytes32[] _values;
// Position of the value in the `values` array, plus 1 because index 0
// means a value is not in the set.
mapping (bytes32 => uint256) _indexes;
}
/**
* @dev Add a value to a set. O(1).
*
* Returns true if the value was added to the set, that is if it was not
* already present.
*/
function _add(Set storage set, bytes32 value) private returns (bool) {
if (!_contains(set, value)) {
set._values.push(value);
// The value is stored at length-1, but we add 1 to all indexes
// and use 0 as a sentinel value
set._indexes[value] = set._values.length;
return true;
} else {
return false;
}
}
/**
* @dev Removes a value from a set. O(1).
*
* Returns true if the value was removed from the set, that is if it was
* present.
*/
function _remove(Set storage set, bytes32 value) private returns (bool) {
// We read and store the value's index to prevent multiple reads from the same storage slot
uint256 valueIndex = set._indexes[value];
if (valueIndex != 0) { // Equivalent to contains(set, value)
// To delete an element from the _values array in O(1), we swap the element to delete with the last one in
// the array, and then remove the last element (sometimes called as 'swap and pop').
// This modifies the order of the array, as noted in {at}.
uint256 toDeleteIndex = valueIndex - 1;
uint256 lastIndex = set._values.length - 1;
// When the value to delete is the last one, the swap operation is unnecessary. However, since this occurs
// so rarely, we still do the swap anyway to avoid the gas cost of adding an 'if' statement.
bytes32 lastvalue = set._values[lastIndex];
// Move the last value to the index where the value to delete is
set._values[toDeleteIndex] = lastvalue;
// Update the index for the moved value
set._indexes[lastvalue] = toDeleteIndex + 1; // All indexes are 1-based
// Delete the slot where the moved value was stored
set._values.pop();
// Delete the index for the deleted slot
delete set._indexes[value];
return true;
} else {
return false;
}
}
/**
* @dev Returns true if the value is in the set. O(1).
*/
function _contains(Set storage set, bytes32 value) private view returns (bool) {
return set._indexes[value] != 0;
}
/**
* @dev Returns the number of values on the set. O(1).
*/
function _length(Set storage set) private view returns (uint256) {
return set._values.length;
}
/**
* @dev Returns the value stored at position `index` in the set. O(1).
*
* Note that there are no guarantees on the ordering of values inside the
* array, and it may change when more values are added or removed.
*
* Requirements:
*
* - `index` must be strictly less than {length}.
*/
function _at(Set storage set, uint256 index) private view returns (bytes32) {
require(set._values.length > index, "EnumerableSet: index out of bounds");
return set._values[index];
}
// Bytes32Set
struct Bytes32Set {
Set _inner;
}
/**
* @dev Add a value to a set. O(1).
*
* Returns true if the value was added to the set, that is if it was not
* already present.
*/
function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {
return _add(set._inner, value);
}
/**
* @dev Removes a value from a set. O(1).
*
* Returns true if the value was removed from the set, that is if it was
* present.
*/
function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {
return _remove(set._inner, value);
}
/**
* @dev Returns true if the value is in the set. O(1).
*/
function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {
return _contains(set._inner, value);
}
/**
* @dev Returns the number of values in the set. O(1).
*/
function length(Bytes32Set storage set) internal view returns (uint256) {
return _length(set._inner);
}
/**
* @dev Returns the value stored at position `index` in the set. O(1).
*
* Note that there are no guarantees on the ordering of values inside the
* array, and it may change when more values are added or removed.
*
* Requirements:
*
* - `index` must be strictly less than {length}.
*/
function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {
return _at(set._inner, index);
}
// AddressSet
struct AddressSet {
Set _inner;
}
/**
* @dev Add a value to a set. O(1).
*
* Returns true if the value was added to the set, that is if it was not
* already present.
*/
function add(AddressSet storage set, address value) internal returns (bool) {
return _add(set._inner, bytes32(uint256(uint160(value))));
}
/**
* @dev Removes a value from a set. O(1).
*
* Returns true if the value was removed from the set, that is if it was
* present.
*/
function remove(AddressSet storage set, address value) internal returns (bool) {
return _remove(set._inner, bytes32(uint256(uint160(value))));
}
/**
* @dev Returns true if the value is in the set. O(1).
*/
function contains(AddressSet storage set, address value) internal view returns (bool) {
return _contains(set._inner, bytes32(uint256(uint160(value))));
}
/**
* @dev Returns the number of values in the set. O(1).
*/
function length(AddressSet storage set) internal view returns (uint256) {
return _length(set._inner);
}
/**
* @dev Returns the value stored at position `index` in the set. O(1).
*
* Note that there are no guarantees on the ordering of values inside the
* array, and it may change when more values are added or removed.
*
* Requirements:
*
* - `index` must be strictly less than {length}.
*/
function at(AddressSet storage set, uint256 index) internal view returns (address) {
return address(uint160(uint256(_at(set._inner, index))));
}
// UintSet
struct UintSet {
Set _inner;
}
/**
* @dev Add a value to a set. O(1).
*
* Returns true if the value was added to the set, that is if it was not
* already present.
*/
function add(UintSet storage set, uint256 value) internal returns (bool) {
return _add(set._inner, bytes32(value));
}
/**
* @dev Removes a value from a set. O(1).
*
* Returns true if the value was removed from the set, that is if it was
* present.
*/
function remove(UintSet storage set, uint256 value) internal returns (bool) {
return _remove(set._inner, bytes32(value));
}
/**
* @dev Returns true if the value is in the set. O(1).
*/
function contains(UintSet storage set, uint256 value) internal view returns (bool) {
return _contains(set._inner, bytes32(value));
}
/**
* @dev Returns the number of values on the set. O(1).
*/
function length(UintSet storage set) internal view returns (uint256) {
return _length(set._inner);
}
/**
* @dev Returns the value stored at position `index` in the set. O(1).
*
* Note that there are no guarantees on the ordering of values inside the
* array, and it may change when more values are added or removed.
*
* Requirements:
*
* - `index` must be strictly less than {length}.
*/
function at(UintSet storage set, uint256 index) internal view returns (uint256) {
return uint256(_at(set._inner, index));
}
}
contract Initializable {
bool inited = false;
modifier initializer() {
require(!inited, "already inited");
_;
inited = true;
}
}
// File: contracts/libs/EIP712Base.sol
pragma solidity ^0.8.0;
contract EIP712Base is Initializable {
struct EIP712Domain {
string name;
string version;
address verifyingContract;
bytes32 salt;
}
string constant public ERC712_VERSION = "1";
bytes32 internal constant EIP712_DOMAIN_TYPEHASH = keccak256(
bytes(
"EIP712Domain(string name,string version,address verifyingContract,bytes32 salt)"
)
);
bytes32 internal domainSeperator;
// supposed to be called once while initializing.
// one of the contracts that inherits this contract follows proxy pattern
// so it is not possible to do this in a constructor
function _initializeEIP712(
string memory name
)
internal
initializer
{
_setDomainSeperator(name);
}
function _setDomainSeperator(string memory name) internal {
domainSeperator = keccak256(
abi.encode(
EIP712_DOMAIN_TYPEHASH,
keccak256(bytes(name)),
keccak256(bytes(ERC712_VERSION)),
address(this),
bytes32(getChainId())
)
);
}
function getDomainSeperator() public view returns (bytes32) {
return domainSeperator;
}
function getChainId() public view returns (uint256) {
uint256 id;
assembly {
id := chainid()
}
return id;
}
/**
* Accept message hash and returns hash message in EIP712 compatible form
* So that it can be used to recover signer from signature signed using EIP712 formatted data
* https://eips.ethereum.org/EIPS/eip-712
* "\\x19" makes the encoding deterministic
* "\\x01" is the version byte to make it compatible to EIP-191
*/
function toTypedMessageHash(bytes32 messageHash)
internal
view
returns (bytes32)
{
return
keccak256(
abi.encodePacked("\x19\x01", getDomainSeperator(), messageHash)
);
}
}
// File: contracts/libs/ContentMixin.sol
pragma solidity ^0.8.0;
abstract contract ContextMixin {
function msgSender()
internal
view
returns (address payable sender)
{
if (msg.sender == address(this)) {
bytes memory array = msg.data;
uint256 index = msg.data.length;
assembly {
// Load the 32 bytes word from memory with the address on the lower 20 bytes, and mask those.
sender := and(
mload(add(array, index)),
0xffffffffffffffffffffffffffffffffffffffff
)
}
} else {
sender = payable(msg.sender);
}
return sender;
}
}
// File: openzeppelin-solidity/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: contracts/libs/NativeMetaTransaction.sol
pragma solidity ^0.8.0;
contract NativeMetaTransaction is EIP712Base {
using SafeMath for uint256;
bytes32 private constant META_TRANSACTION_TYPEHASH = keccak256(
bytes(
"MetaTransaction(uint256 nonce,address from,bytes functionSignature)"
)
);
event MetaTransactionExecuted(
address userAddress,
address payable relayerAddress,
bytes functionSignature
);
mapping(address => uint256) nonces;
/*
* Meta transaction structure.
* No point of including value field here as if user is doing value transfer then he has the funds to pay for gas
* He should call the desired function directly in that case.
*/
struct MetaTransaction {
uint256 nonce;
address from;
bytes functionSignature;
}
function executeMetaTransaction(
address userAddress,
bytes memory functionSignature,
bytes32 sigR,
bytes32 sigS,
uint8 sigV
) public payable returns (bytes memory) {
MetaTransaction memory metaTx = MetaTransaction({
nonce: nonces[userAddress],
from: userAddress,
functionSignature: functionSignature
});
require(
verify(userAddress, metaTx, sigR, sigS, sigV),
"Signer and signature do not match"
);
// increase nonce for user (to avoid re-use)
nonces[userAddress] = nonces[userAddress].add(1);
emit MetaTransactionExecuted(
userAddress,
payable(msg.sender),
functionSignature
);
// Append userAddress and relayer address at the end to extract it from calling context
(bool success, bytes memory returnData) = address(this).call(
abi.encodePacked(functionSignature, userAddress)
);
require(success, "Function call not successful");
return returnData;
}
function hashMetaTransaction(MetaTransaction memory metaTx)
internal
pure
returns (bytes32)
{
return
keccak256(
abi.encode(
META_TRANSACTION_TYPEHASH,
metaTx.nonce,
metaTx.from,
keccak256(metaTx.functionSignature)
)
);
}
function getNonce(address user) public view returns (uint256 nonce) {
nonce = nonces[user];
}
function verify(
address signer,
MetaTransaction memory metaTx,
bytes32 sigR,
bytes32 sigS,
uint8 sigV
) internal view returns (bool) {
require(signer != address(0), "NativeMetaTransaction: INVALID_SIGNER");
return
signer ==
ecrecover(
toTypedMessageHash(hashMetaTransaction(metaTx)),
sigV,
sigR,
sigS
);
}
}
// File: openzeppelin-solidity/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-solidity/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: openzeppelin-solidity/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-solidity/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: openzeppelin-solidity/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-solidity/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-solidity/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-solidity/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-solidity/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-solidity/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-solidity/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-solidity/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 {
using EnumerableSetUpgradeable for EnumerableSetUpgradeable.UintSet;
// Mapping from owner to list of owned token IDs
mapping(address => mapping(uint256 => uint256)) private _ownedTokens;
// Mapping from holder address to their (enumerable) set of owned tokens
mapping (address => EnumerableSetUpgradeable.UintSet) _holderTokens;
// 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);
_holderTokens[to].add(tokenId);
_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];
_holderTokens[from].remove(tokenId);
}
/**
* @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: contracts/ERC721Tradable.sol
pragma solidity ^0.8.0;
contract OwnableDelegateProxy {}
contract ProxyRegistry {
mapping(address => OwnableDelegateProxy) public proxies;
}
/**
* @title ERC721Tradable
* ERC721Tradable - ERC721 contract that whitelists a trading address, and has minting functionality.
*/
abstract contract ERC721Tradable is ContextMixin, ERC721Enumerable, NativeMetaTransaction, Ownable {
using SafeMath for uint256;
bytes4 private constant _INTERFACE_ID_ERC721 = 0x80ac58cd;
bytes4 private constant _INTERFACE_ID_ERC721_METADATA = 0x5b5e139f;
bytes4 private constant _INTERFACE_ID_ERC721_ENUMERABLE = 0x780e9d63;
address proxyRegistryAddress;
address public routerAddress;
uint256 private _currentTokenId = 0;
modifier onlyRouter() {
require(msg.sender == routerAddress, "You are not Router");
_;
}
constructor(
string memory _name,
string memory _symbol,
address _proxyRegistryAddress
) ERC721(_name, _symbol) {
proxyRegistryAddress = _proxyRegistryAddress;
_initializeEIP712(_name);
}
/// @dev Assigns a new address to act as the Router. Only available to the current CEO.
/// @param _newRouter The address of the new Router
function setRouter(address _newRouter) external onlyOwner {
routerAddress = _newRouter;
}
/**
* @dev Mints a token to an address with a tokenURI.
* @param _to address of the future owner of the token
*/
function delegatedMintTo(address _to) public onlyRouter returns (uint256) {
uint256 newTokenId = _getNextTokenId();
_mint(_to, newTokenId);
_incrementTokenId();
return newTokenId;
}
/**
* @dev Mints a token to an address with a tokenURI.
* @param _to address of the future owner of the token
*/
function mintTo(address _to) public onlyOwner returns (uint256) {
uint256 newTokenId = _getNextTokenId();
_mint(_to, newTokenId);
_incrementTokenId();
return newTokenId;
}
/**
* @dev calculates the next token ID based on value of _currentTokenId
* @return uint256 for the next token ID
*/
function _getNextTokenId() private view returns (uint256) {
return _currentTokenId.add(1);
}
/**
* @dev increments the value of _currentTokenId
*/
function _incrementTokenId() private {
_currentTokenId++;
}
function baseTokenURI() virtual public view returns (string memory);
function tokenURI(uint256 _tokenId) override public view returns (string memory) {
return string(abi.encodePacked(baseTokenURI(), "api/token/", Strings.toString(_tokenId)));
}
/**
* Override isApprovedForAll to whitelist user's OpenSea proxy accounts to enable gas-less listings.
*/
function isApprovedForAll(address owner, address operator)
override
public
view
returns (bool)
{
// Whitelist OpenSea proxy contract for easy trading.
ProxyRegistry proxyRegistry = ProxyRegistry(proxyRegistryAddress);
if (address(proxyRegistry.proxies(owner)) == operator) {
return true;
}
return super.isApprovedForAll(owner, operator);
}
/**
* This is used instead of msg.sender as transactions won't be sent by the original token owner, but by OpenSea.
*/
function _msgSender()
internal
override
view
returns (address sender)
{
return ContextMixin.msgSender();
}
}
// File: contracts/MangaNft.sol
pragma solidity ^0.8.0;
/**
* @title Creature
* Creature - a contract for my non-fungible creatures.
*/
contract MangaNFT is ERC721Tradable {
event Birth(address owner, uint256 fadeAwayBunnyId, uint256 matronId, uint256 sireId, bytes32 genes);
struct FadeAwayBunny {
bytes32 genes;
uint64 birthTime;
uint32 matronId;
uint32 sireId;
uint16 generation;
}
string baseURI;
mapping(uint256 => FadeAwayBunny) public bunnies;
constructor(address _proxyRegistryAddress)
ERC721Tradable("FadeAwayBunny", "FABNFT", _proxyRegistryAddress)
{}
/// @dev Assigns a new address to act as the base URI. Only available to the current Owner.
/// @param _baseURI The address of the new base URI
function setBaseURI(string memory _baseURI) external onlyOwner {
baseURI = _baseURI;
}
function _createFadeAwayBunny(
uint256 _matronId,
uint256 _sireId,
uint256 _generation,
bytes32 _genes,
address _owner
)
internal
returns (uint256)
{
uint256 nextTokenId = delegatedMintTo(_owner);
bunnies[nextTokenId] = FadeAwayBunny({
genes: _genes,
birthTime: uint64(block.timestamp),
matronId: uint32(_matronId),
sireId: uint32(_sireId),
generation: uint16(_generation)
});
emit Birth(_owner, nextTokenId, _matronId, _sireId, _genes);
return nextTokenId;
}
function createFadeAwayBunny(
uint256 _matronId,
uint256 _sireId,
uint256 _generation,
bytes32 _genes,
address _owner
)
public onlyRouter returns (uint)
{
return _createFadeAwayBunny(_matronId, _sireId, _generation, _genes, _owner);
}
function baseTokenURI() override public view returns (string memory) {
return baseURI;
}
function contractURI() public view returns (string memory) {
return string(abi.encodePacked(baseTokenURI(), "api/contract"));
}
}
abstract contract GeneScienceInterface {
/// @dev simply a boolean to indicate this is the contract we expect to be
function isGeneScience() public pure virtual returns (bool);
/// @dev given genes of kitten 1 & 2, return a genetic combination - may have a random factor
/// @param genes1 genes of mom
/// @param genes2 genes of sire
/// @return the genes that are supposed to be passed down the child
function mixGenes(uint256 genes1, uint256 genes2, uint256 targetBlock) public virtual returns (bytes32);
function randomGenes(uint256 lastBlock) public virtual returns (bytes32);
}
contract BunnyRouter is Ownable {
using SafeMath for uint256;
// Counts the number of cats the contract owner has created.
uint256 public gen0CreatedCount;
uint256 public gen0Price = 8*1e15;
uint256 lastGen0Block;
mapping (address => uint8) public whitelist;
mapping (address => uint256) public whitelistPrice;
bool public canBuy = true;
GeneScienceInterface public geneScience;
MangaNFT public mangaNFT;
event CanBuy();
event CantBuy();
modifier whenCanBuy() {
require(canBuy, "can't buy");
_;
}
/// @dev Update the address of the genetic contract, can only be called by the Owner.
/// @param _address An address of a GeneScience contract instance to be used from this point forward.
function setGeneScienceAddress(address _address) external onlyOwner {
GeneScienceInterface candidateContract = GeneScienceInterface(_address);
require(candidateContract.isGeneScience());
// Set the new contract address
geneScience = candidateContract;
}
/// @dev Update the address of the nft contract, can only be called by the Owner.
/// @param _address An address of a NFT contract instance to be used from this point forward.
function setNFT(address _address) external onlyOwner {
MangaNFT newManga = MangaNFT(_address);
// Set the new contract address
mangaNFT = newManga;
}
function setCanBuy(bool _canBuy) external onlyOwner {
canBuy = _canBuy;
if (_canBuy) {
emit CanBuy();
} else {
emit CantBuy();
}
}
function setGen0Price(uint256 _price) external onlyOwner {
gen0Price = _price;
}
function setWhiteList(address _user, uint8 _number, uint256 _price) external onlyOwner {
whitelist[_user] = _number;
whitelistPrice[_user] = _price;
}
function setBatchWhiteList(address[] memory _users, uint8[] memory _numbers, uint256[] memory _prices) external onlyOwner {
require(_users.length == _numbers.length, "Array no match");
require(_users.length == _prices.length, "Array no match");
for (uint256 i = 0; i < _users.length; i++) {
whitelist[_users[i]] = _numbers[i];
whitelistPrice[_users[i]] = _prices[i];
}
}
function buyGen0() public payable whenCanBuy returns (uint256) {
require(msg.value >= gen0Price, "not enough money!");
bytes32 _genes = geneScience.randomGenes(lastGen0Block);
uint256 FadeAwayBunnyId = mangaNFT.createFadeAwayBunny(0, 0, 0, _genes, address(msg.sender));
gen0CreatedCount++;
lastGen0Block = block.number;
return FadeAwayBunnyId;
}
function batchBuyGen0(uint8 _number) public payable whenCanBuy {
require(msg.value >= (gen0Price * _number), "not enough money!");
for (uint8 index = 0; index < _number; index++) {
buyGen0();
}
}
function buyGen0WithVipPrice() public payable whenCanBuy returns (uint256) {
require(whitelist[msg.sender] > 0, "you not in whitelist!");
require(msg.value >= whitelistPrice[msg.sender], "wrong ammount of eth!");
bytes32 _genes = geneScience.randomGenes(lastGen0Block);
uint256 FadeAwayBunnyId = mangaNFT.createFadeAwayBunny(0, 0, 0, _genes, address(msg.sender));
gen0CreatedCount++;
whitelist[msg.sender] = whitelist[msg.sender] - 1;
lastGen0Block = block.number;
return FadeAwayBunnyId;
}
function batchBuyGen0WithVipPrice(uint8 _number) public payable whenCanBuy {
require(whitelist[msg.sender] >= _number, "not enough turn!");
require(msg.value >= whitelistPrice[msg.sender]*_number, "wrong ammount of eth!");
for (uint256 index = 0; index < _number; index++) {
buyGen0WithVipPrice();
}
}
// @dev Allows the Owner to capture the balance available to the contract.
function withdrawBalance() external onlyOwner {
uint256 balance = address(this).balance;
payable(owner()).transfer(balance);
}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"anonymous":false,"inputs":[],"name":"CanBuy","type":"event"},{"anonymous":false,"inputs":[],"name":"CantBuy","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"inputs":[{"internalType":"uint8","name":"_number","type":"uint8"}],"name":"batchBuyGen0","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint8","name":"_number","type":"uint8"}],"name":"batchBuyGen0WithVipPrice","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"buyGen0","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"buyGen0WithVipPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"canBuy","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"gen0CreatedCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"gen0Price","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"geneScience","outputs":[{"internalType":"contract GeneScienceInterface","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"mangaNFT","outputs":[{"internalType":"contract MangaNFT","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_users","type":"address[]"},{"internalType":"uint8[]","name":"_numbers","type":"uint8[]"},{"internalType":"uint256[]","name":"_prices","type":"uint256[]"}],"name":"setBatchWhiteList","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_canBuy","type":"bool"}],"name":"setCanBuy","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_price","type":"uint256"}],"name":"setGen0Price","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_address","type":"address"}],"name":"setGeneScienceAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_address","type":"address"}],"name":"setNFT","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"},{"internalType":"uint8","name":"_number","type":"uint8"},{"internalType":"uint256","name":"_price","type":"uint256"}],"name":"setWhiteList","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"whitelist","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"whitelistPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"withdrawBalance","outputs":[],"stateMutability":"nonpayable","type":"function"}]Contract Creation Code
6080604052661c6bf5263400006002556001600660006101000a81548160ff02191690831515021790555034801561003657600080fd5b5061005361004861005860201b60201c565b61006060201b60201c565b610124565b600033905090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b61248c80620001346000396000f3fe60806040526004361061012a5760003560e01c80637d9b6a15116100ab578063d6dbe28f1161006f578063d6dbe28f1461037b578063f1ca941014610399578063f2b47d52146103c4578063f2fde38b146103ef578063f56e9c6614610418578063ff65226c146104415761012a565b80637d9b6a15146102a15780638da5cb5b146102cc5780639b19251a146102f75780639b82df5c14610334578063c0011eec1461035d5761012a565b80635fd8c710116100f25780635fd8c71014610205578063715018a61461021c57806378927cd1146102335780637aef4c791461025c5780637bffa9da146102855761012a565b806315a2edd01461012f5780631cb37e8f1461014b5780631e05a0c91461017657806324e7a38a146101b35780632c06862b146101dc575b600080fd5b61014960048036038101906101449190611c49565b61046c565b005b34801561015757600080fd5b5061016061053f565b60405161016d9190611f61565b60405180910390f35b34801561018257600080fd5b5061019d60048036038101906101989190611a6d565b610565565b6040516101aa91906120cf565b60405180910390f35b3480156101bf57600080fd5b506101da60048036038101906101d59190611a6d565b61057d565b005b3480156101e857600080fd5b5061020360048036038101906101fe9190611b7c565b6106ca565b005b34801561021157600080fd5b5061021a6107c7565b005b34801561022857600080fd5b50610231610899565b005b34801561023f57600080fd5b5061025a60048036038101906102559190611bf7565b610921565b005b34801561026857600080fd5b50610283600480360381019061027e9190611ae5565b6109a7565b005b61029f600480360381019061029a9190611c49565b610c6c565b005b3480156102ad57600080fd5b506102b6610e0e565b6040516102c391906120cf565b60405180910390f35b3480156102d857600080fd5b506102e1610e14565b6040516102ee9190611f10565b60405180910390f35b34801561030357600080fd5b5061031e60048036038101906103199190611a6d565b610e3d565b60405161032b91906120ea565b60405180910390f35b34801561034057600080fd5b5061035b60048036038101906103569190611a96565b610e5d565b005b610365610f7a565b60405161037291906120cf565b60405180910390f35b6103836111a5565b60405161039091906120cf565b60405180910390f35b3480156103a557600080fd5b506103ae61154f565b6040516103bb91906120cf565b60405180910390f35b3480156103d057600080fd5b506103d9611555565b6040516103e69190611f46565b60405180910390f35b3480156103fb57600080fd5b5061041660048036038101906104119190611a6d565b61157b565b005b34801561042457600080fd5b5061043f600480360381019061043a9190611a6d565b611673565b005b34801561044d57600080fd5b50610456611739565b6040516104639190611f2b565b60405180910390f35b600660009054906101000a900460ff166104bb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104b290611fcf565b60405180910390fd5b8060ff166002546104cc91906121cb565b34101561050e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610505906120af565b60405180910390fd5b60005b8160ff168160ff16101561053b57610527610f7a565b5080806105339061235b565b915050610511565b5050565b600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60056020528060005260406000206000915090505481565b61058561174c565b73ffffffffffffffffffffffffffffffffffffffff166105a3610e14565b73ffffffffffffffffffffffffffffffffffffffff16146105f9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105f09061208f565b60405180910390fd5b60008190508073ffffffffffffffffffffffffffffffffffffffff166354c15b826040518163ffffffff1660e01b815260040160206040518083038186803b15801561064457600080fd5b505afa158015610658573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061067c9190611ba5565b61068557600080fd5b80600660016101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505050565b6106d261174c565b73ffffffffffffffffffffffffffffffffffffffff166106f0610e14565b73ffffffffffffffffffffffffffffffffffffffff1614610746576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161073d9061208f565b60405180910390fd5b80600660006101000a81548160ff0219169083151502179055508015610797577fd4c7f20c0d1113ce7122e09b22b5f2089f6702b31cb802495b115b1098726ead60405160405180910390a16107c4565b7f1ab7ae56f8c39285d884fe1d50c4027dbc90bad79bcaf0d1c4684aa4750403d560405160405180910390a15b50565b6107cf61174c565b73ffffffffffffffffffffffffffffffffffffffff166107ed610e14565b73ffffffffffffffffffffffffffffffffffffffff1614610843576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161083a9061208f565b60405180910390fd5b6000479050610850610e14565b73ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051600060405180830381858888f19350505050158015610895573d6000803e3d6000fd5b5050565b6108a161174c565b73ffffffffffffffffffffffffffffffffffffffff166108bf610e14565b73ffffffffffffffffffffffffffffffffffffffff1614610915576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161090c9061208f565b60405180910390fd5b61091f6000611754565b565b61092961174c565b73ffffffffffffffffffffffffffffffffffffffff16610947610e14565b73ffffffffffffffffffffffffffffffffffffffff161461099d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109949061208f565b60405180910390fd5b8060028190555050565b6109af61174c565b73ffffffffffffffffffffffffffffffffffffffff166109cd610e14565b73ffffffffffffffffffffffffffffffffffffffff1614610a23576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a1a9061208f565b60405180910390fd5b8151835114610a67576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a5e9061206f565b60405180910390fd5b8051835114610aab576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610aa29061206f565b60405180910390fd5b60005b8351811015610c6657828181518110610af0577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b602002602001015160046000868481518110610b35577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b602002602001015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908360ff160217905550818181518110610bc8577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b602002602001015160056000868481518110610c0d577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b602002602001015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508080610c5e90612312565b915050610aae565b50505050565b600660009054906101000a900460ff16610cbb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610cb290611fcf565b60405180910390fd5b8060ff16600460003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1660ff161015610d50576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d4790611fef565b60405180910390fd5b8060ff16600560003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054610d9e91906121cb565b341015610de0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610dd79061202f565b60405180910390fd5b60005b8160ff16811015610e0a57610df66111a5565b508080610e0290612312565b915050610de3565b5050565b60025481565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60046020528060005260406000206000915054906101000a900460ff1681565b610e6561174c565b73ffffffffffffffffffffffffffffffffffffffff16610e83610e14565b73ffffffffffffffffffffffffffffffffffffffff1614610ed9576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ed09061208f565b60405180910390fd5b81600460008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908360ff16021790555080600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550505050565b6000600660009054906101000a900460ff16610fcb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610fc290611fcf565b60405180910390fd5b600254341015611010576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611007906120af565b60405180910390fd5b6000600660019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166393508bb56003546040518263ffffffff1660e01b815260040161106f91906120cf565b602060405180830381600087803b15801561108957600080fd5b505af115801561109d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110c19190611bce565b90506000600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663fc7cf398600080600086336040518663ffffffff1660e01b815260040161112a959493929190611f7c565b602060405180830381600087803b15801561114457600080fd5b505af1158015611158573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061117c9190611c20565b90506001600081548092919061119190612312565b919050555043600381905550809250505090565b6000600660009054906101000a900460ff166111f6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111ed90611fcf565b60405180910390fd5b6000600460003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1660ff1611611288576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161127f9061204f565b60405180910390fd5b600560003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205434101561130a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113019061202f565b60405180910390fd5b6000600660019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166393508bb56003546040518263ffffffff1660e01b815260040161136991906120cf565b602060405180830381600087803b15801561138357600080fd5b505af1158015611397573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113bb9190611bce565b90506000600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663fc7cf398600080600086336040518663ffffffff1660e01b8152600401611424959493929190611f7c565b602060405180830381600087803b15801561143e57600080fd5b505af1158015611452573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114769190611c20565b90506001600081548092919061148b90612312565b91905055506001600460003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff166114e99190612225565b600460003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908360ff16021790555043600381905550809250505090565b60015481565b600660019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b61158361174c565b73ffffffffffffffffffffffffffffffffffffffff166115a1610e14565b73ffffffffffffffffffffffffffffffffffffffff16146115f7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016115ee9061208f565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415611667576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161165e9061200f565b60405180910390fd5b61167081611754565b50565b61167b61174c565b73ffffffffffffffffffffffffffffffffffffffff16611699610e14565b73ffffffffffffffffffffffffffffffffffffffff16146116ef576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116e69061208f565b60405180910390fd5b600081905080600760006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505050565b600660009054906101000a900460ff1681565b600033905090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b600061182b61182684612136565b612105565b9050808382526020820190508285602086028201111561184a57600080fd5b60005b8581101561187a5781611860888261195c565b84526020840193506020830192505060018101905061184d565b5050509392505050565b600061189761189284612162565b612105565b905080838252602082019050828560208602820111156118b657600080fd5b60005b858110156118e657816118cc8882611a2e565b8452602084019350602083019250506001810190506118b9565b5050509392505050565b60006119036118fe8461218e565b612105565b9050808382526020820190508285602086028201111561192257600080fd5b60005b8581101561195257816119388882611a58565b845260208401935060208301925050600181019050611925565b5050509392505050565b60008135905061196b816123e3565b92915050565b600082601f83011261198257600080fd5b8135611992848260208601611818565b91505092915050565b600082601f8301126119ac57600080fd5b81356119bc848260208601611884565b91505092915050565b600082601f8301126119d657600080fd5b81356119e68482602086016118f0565b91505092915050565b6000813590506119fe816123fa565b92915050565b600081519050611a13816123fa565b92915050565b600081519050611a2881612411565b92915050565b600081359050611a3d81612428565b92915050565b600081519050611a5281612428565b92915050565b600081359050611a678161243f565b92915050565b600060208284031215611a7f57600080fd5b6000611a8d8482850161195c565b91505092915050565b600080600060608486031215611aab57600080fd5b6000611ab98682870161195c565b9350506020611aca86828701611a58565b9250506040611adb86828701611a2e565b9150509250925092565b600080600060608486031215611afa57600080fd5b600084013567ffffffffffffffff811115611b1457600080fd5b611b2086828701611971565b935050602084013567ffffffffffffffff811115611b3d57600080fd5b611b49868287016119c5565b925050604084013567ffffffffffffffff811115611b6657600080fd5b611b728682870161199b565b9150509250925092565b600060208284031215611b8e57600080fd5b6000611b9c848285016119ef565b91505092915050565b600060208284031215611bb757600080fd5b6000611bc584828501611a04565b91505092915050565b600060208284031215611be057600080fd5b6000611bee84828501611a19565b91505092915050565b600060208284031215611c0957600080fd5b6000611c1784828501611a2e565b91505092915050565b600060208284031215611c3257600080fd5b6000611c4084828501611a43565b91505092915050565b600060208284031215611c5b57600080fd5b6000611c6984828501611a58565b91505092915050565b611c7b81612259565b82525050565b611c8a8161226b565b82525050565b611c9981612277565b82525050565b611ca8816122b8565b82525050565b611cb7816122dc565b82525050565b611cc681612300565b82525050565b6000611cd96009836121ba565b91507f63616e27742062757900000000000000000000000000000000000000000000006000830152602082019050919050565b6000611d196010836121ba565b91507f6e6f7420656e6f756768207475726e21000000000000000000000000000000006000830152602082019050919050565b6000611d596026836121ba565b91507f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008301527f64647265737300000000000000000000000000000000000000000000000000006020830152604082019050919050565b6000611dbf6015836121ba565b91507f77726f6e6720616d6d6f756e74206f66206574682100000000000000000000006000830152602082019050919050565b6000611dff6015836121ba565b91507f796f75206e6f7420696e2077686974656c6973742100000000000000000000006000830152602082019050919050565b6000611e3f600e836121ba565b91507f4172726179206e6f206d617463680000000000000000000000000000000000006000830152602082019050919050565b6000611e7f6020836121ba565b91507f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726000830152602082019050919050565b6000611ebf6011836121ba565b91507f6e6f7420656e6f756768206d6f6e6579210000000000000000000000000000006000830152602082019050919050565b611efb816122a1565b82525050565b611f0a816122ab565b82525050565b6000602082019050611f256000830184611c72565b92915050565b6000602082019050611f406000830184611c81565b92915050565b6000602082019050611f5b6000830184611c9f565b92915050565b6000602082019050611f766000830184611cae565b92915050565b600060a082019050611f916000830188611cbd565b611f9e6020830187611cbd565b611fab6040830186611cbd565b611fb86060830185611c90565b611fc56080830184611c72565b9695505050505050565b60006020820190508181036000830152611fe881611ccc565b9050919050565b6000602082019050818103600083015261200881611d0c565b9050919050565b6000602082019050818103600083015261202881611d4c565b9050919050565b6000602082019050818103600083015261204881611db2565b9050919050565b6000602082019050818103600083015261206881611df2565b9050919050565b6000602082019050818103600083015261208881611e32565b9050919050565b600060208201905081810360008301526120a881611e72565b9050919050565b600060208201905081810360008301526120c881611eb2565b9050919050565b60006020820190506120e46000830184611ef2565b92915050565b60006020820190506120ff6000830184611f01565b92915050565b6000604051905081810181811067ffffffffffffffff8211171561212c5761212b6123b4565b5b8060405250919050565b600067ffffffffffffffff821115612151576121506123b4565b5b602082029050602081019050919050565b600067ffffffffffffffff82111561217d5761217c6123b4565b5b602082029050602081019050919050565b600067ffffffffffffffff8211156121a9576121a86123b4565b5b602082029050602081019050919050565b600082825260208201905092915050565b60006121d6826122a1565b91506121e1836122a1565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048311821515161561221a57612219612385565b5b828202905092915050565b6000612230826122ab565b915061223b836122ab565b92508282101561224e5761224d612385565b5b828203905092915050565b600061226482612281565b9050919050565b60008115159050919050565b6000819050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b600060ff82169050919050565b60006122c3826122ca565b9050919050565b60006122d582612281565b9050919050565b60006122e7826122ee565b9050919050565b60006122f982612281565b9050919050565b600061230b826122a1565b9050919050565b600061231d826122a1565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8214156123505761234f612385565b5b600182019050919050565b6000612366826122ab565b915060ff82141561237a57612379612385565b5b600182019050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6123ec81612259565b81146123f757600080fd5b50565b6124038161226b565b811461240e57600080fd5b50565b61241a81612277565b811461242557600080fd5b50565b612431816122a1565b811461243c57600080fd5b50565b612448816122ab565b811461245357600080fd5b5056fea2646970667358221220ce08c9a4433ce1d65061b82c389dd320792c666fb7a75c7718105136bdeea38864736f6c63430008000033
Deployed Bytecode
0x60806040526004361061012a5760003560e01c80637d9b6a15116100ab578063d6dbe28f1161006f578063d6dbe28f1461037b578063f1ca941014610399578063f2b47d52146103c4578063f2fde38b146103ef578063f56e9c6614610418578063ff65226c146104415761012a565b80637d9b6a15146102a15780638da5cb5b146102cc5780639b19251a146102f75780639b82df5c14610334578063c0011eec1461035d5761012a565b80635fd8c710116100f25780635fd8c71014610205578063715018a61461021c57806378927cd1146102335780637aef4c791461025c5780637bffa9da146102855761012a565b806315a2edd01461012f5780631cb37e8f1461014b5780631e05a0c91461017657806324e7a38a146101b35780632c06862b146101dc575b600080fd5b61014960048036038101906101449190611c49565b61046c565b005b34801561015757600080fd5b5061016061053f565b60405161016d9190611f61565b60405180910390f35b34801561018257600080fd5b5061019d60048036038101906101989190611a6d565b610565565b6040516101aa91906120cf565b60405180910390f35b3480156101bf57600080fd5b506101da60048036038101906101d59190611a6d565b61057d565b005b3480156101e857600080fd5b5061020360048036038101906101fe9190611b7c565b6106ca565b005b34801561021157600080fd5b5061021a6107c7565b005b34801561022857600080fd5b50610231610899565b005b34801561023f57600080fd5b5061025a60048036038101906102559190611bf7565b610921565b005b34801561026857600080fd5b50610283600480360381019061027e9190611ae5565b6109a7565b005b61029f600480360381019061029a9190611c49565b610c6c565b005b3480156102ad57600080fd5b506102b6610e0e565b6040516102c391906120cf565b60405180910390f35b3480156102d857600080fd5b506102e1610e14565b6040516102ee9190611f10565b60405180910390f35b34801561030357600080fd5b5061031e60048036038101906103199190611a6d565b610e3d565b60405161032b91906120ea565b60405180910390f35b34801561034057600080fd5b5061035b60048036038101906103569190611a96565b610e5d565b005b610365610f7a565b60405161037291906120cf565b60405180910390f35b6103836111a5565b60405161039091906120cf565b60405180910390f35b3480156103a557600080fd5b506103ae61154f565b6040516103bb91906120cf565b60405180910390f35b3480156103d057600080fd5b506103d9611555565b6040516103e69190611f46565b60405180910390f35b3480156103fb57600080fd5b5061041660048036038101906104119190611a6d565b61157b565b005b34801561042457600080fd5b5061043f600480360381019061043a9190611a6d565b611673565b005b34801561044d57600080fd5b50610456611739565b6040516104639190611f2b565b60405180910390f35b600660009054906101000a900460ff166104bb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104b290611fcf565b60405180910390fd5b8060ff166002546104cc91906121cb565b34101561050e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610505906120af565b60405180910390fd5b60005b8160ff168160ff16101561053b57610527610f7a565b5080806105339061235b565b915050610511565b5050565b600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60056020528060005260406000206000915090505481565b61058561174c565b73ffffffffffffffffffffffffffffffffffffffff166105a3610e14565b73ffffffffffffffffffffffffffffffffffffffff16146105f9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105f09061208f565b60405180910390fd5b60008190508073ffffffffffffffffffffffffffffffffffffffff166354c15b826040518163ffffffff1660e01b815260040160206040518083038186803b15801561064457600080fd5b505afa158015610658573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061067c9190611ba5565b61068557600080fd5b80600660016101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505050565b6106d261174c565b73ffffffffffffffffffffffffffffffffffffffff166106f0610e14565b73ffffffffffffffffffffffffffffffffffffffff1614610746576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161073d9061208f565b60405180910390fd5b80600660006101000a81548160ff0219169083151502179055508015610797577fd4c7f20c0d1113ce7122e09b22b5f2089f6702b31cb802495b115b1098726ead60405160405180910390a16107c4565b7f1ab7ae56f8c39285d884fe1d50c4027dbc90bad79bcaf0d1c4684aa4750403d560405160405180910390a15b50565b6107cf61174c565b73ffffffffffffffffffffffffffffffffffffffff166107ed610e14565b73ffffffffffffffffffffffffffffffffffffffff1614610843576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161083a9061208f565b60405180910390fd5b6000479050610850610e14565b73ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051600060405180830381858888f19350505050158015610895573d6000803e3d6000fd5b5050565b6108a161174c565b73ffffffffffffffffffffffffffffffffffffffff166108bf610e14565b73ffffffffffffffffffffffffffffffffffffffff1614610915576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161090c9061208f565b60405180910390fd5b61091f6000611754565b565b61092961174c565b73ffffffffffffffffffffffffffffffffffffffff16610947610e14565b73ffffffffffffffffffffffffffffffffffffffff161461099d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109949061208f565b60405180910390fd5b8060028190555050565b6109af61174c565b73ffffffffffffffffffffffffffffffffffffffff166109cd610e14565b73ffffffffffffffffffffffffffffffffffffffff1614610a23576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a1a9061208f565b60405180910390fd5b8151835114610a67576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a5e9061206f565b60405180910390fd5b8051835114610aab576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610aa29061206f565b60405180910390fd5b60005b8351811015610c6657828181518110610af0577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b602002602001015160046000868481518110610b35577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b602002602001015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908360ff160217905550818181518110610bc8577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b602002602001015160056000868481518110610c0d577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b602002602001015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508080610c5e90612312565b915050610aae565b50505050565b600660009054906101000a900460ff16610cbb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610cb290611fcf565b60405180910390fd5b8060ff16600460003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1660ff161015610d50576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d4790611fef565b60405180910390fd5b8060ff16600560003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054610d9e91906121cb565b341015610de0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610dd79061202f565b60405180910390fd5b60005b8160ff16811015610e0a57610df66111a5565b508080610e0290612312565b915050610de3565b5050565b60025481565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60046020528060005260406000206000915054906101000a900460ff1681565b610e6561174c565b73ffffffffffffffffffffffffffffffffffffffff16610e83610e14565b73ffffffffffffffffffffffffffffffffffffffff1614610ed9576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ed09061208f565b60405180910390fd5b81600460008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908360ff16021790555080600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550505050565b6000600660009054906101000a900460ff16610fcb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610fc290611fcf565b60405180910390fd5b600254341015611010576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611007906120af565b60405180910390fd5b6000600660019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166393508bb56003546040518263ffffffff1660e01b815260040161106f91906120cf565b602060405180830381600087803b15801561108957600080fd5b505af115801561109d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110c19190611bce565b90506000600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663fc7cf398600080600086336040518663ffffffff1660e01b815260040161112a959493929190611f7c565b602060405180830381600087803b15801561114457600080fd5b505af1158015611158573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061117c9190611c20565b90506001600081548092919061119190612312565b919050555043600381905550809250505090565b6000600660009054906101000a900460ff166111f6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111ed90611fcf565b60405180910390fd5b6000600460003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1660ff1611611288576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161127f9061204f565b60405180910390fd5b600560003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205434101561130a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113019061202f565b60405180910390fd5b6000600660019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166393508bb56003546040518263ffffffff1660e01b815260040161136991906120cf565b602060405180830381600087803b15801561138357600080fd5b505af1158015611397573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113bb9190611bce565b90506000600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663fc7cf398600080600086336040518663ffffffff1660e01b8152600401611424959493929190611f7c565b602060405180830381600087803b15801561143e57600080fd5b505af1158015611452573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114769190611c20565b90506001600081548092919061148b90612312565b91905055506001600460003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff166114e99190612225565b600460003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908360ff16021790555043600381905550809250505090565b60015481565b600660019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b61158361174c565b73ffffffffffffffffffffffffffffffffffffffff166115a1610e14565b73ffffffffffffffffffffffffffffffffffffffff16146115f7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016115ee9061208f565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415611667576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161165e9061200f565b60405180910390fd5b61167081611754565b50565b61167b61174c565b73ffffffffffffffffffffffffffffffffffffffff16611699610e14565b73ffffffffffffffffffffffffffffffffffffffff16146116ef576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116e69061208f565b60405180910390fd5b600081905080600760006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505050565b600660009054906101000a900460ff1681565b600033905090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b600061182b61182684612136565b612105565b9050808382526020820190508285602086028201111561184a57600080fd5b60005b8581101561187a5781611860888261195c565b84526020840193506020830192505060018101905061184d565b5050509392505050565b600061189761189284612162565b612105565b905080838252602082019050828560208602820111156118b657600080fd5b60005b858110156118e657816118cc8882611a2e565b8452602084019350602083019250506001810190506118b9565b5050509392505050565b60006119036118fe8461218e565b612105565b9050808382526020820190508285602086028201111561192257600080fd5b60005b8581101561195257816119388882611a58565b845260208401935060208301925050600181019050611925565b5050509392505050565b60008135905061196b816123e3565b92915050565b600082601f83011261198257600080fd5b8135611992848260208601611818565b91505092915050565b600082601f8301126119ac57600080fd5b81356119bc848260208601611884565b91505092915050565b600082601f8301126119d657600080fd5b81356119e68482602086016118f0565b91505092915050565b6000813590506119fe816123fa565b92915050565b600081519050611a13816123fa565b92915050565b600081519050611a2881612411565b92915050565b600081359050611a3d81612428565b92915050565b600081519050611a5281612428565b92915050565b600081359050611a678161243f565b92915050565b600060208284031215611a7f57600080fd5b6000611a8d8482850161195c565b91505092915050565b600080600060608486031215611aab57600080fd5b6000611ab98682870161195c565b9350506020611aca86828701611a58565b9250506040611adb86828701611a2e565b9150509250925092565b600080600060608486031215611afa57600080fd5b600084013567ffffffffffffffff811115611b1457600080fd5b611b2086828701611971565b935050602084013567ffffffffffffffff811115611b3d57600080fd5b611b49868287016119c5565b925050604084013567ffffffffffffffff811115611b6657600080fd5b611b728682870161199b565b9150509250925092565b600060208284031215611b8e57600080fd5b6000611b9c848285016119ef565b91505092915050565b600060208284031215611bb757600080fd5b6000611bc584828501611a04565b91505092915050565b600060208284031215611be057600080fd5b6000611bee84828501611a19565b91505092915050565b600060208284031215611c0957600080fd5b6000611c1784828501611a2e565b91505092915050565b600060208284031215611c3257600080fd5b6000611c4084828501611a43565b91505092915050565b600060208284031215611c5b57600080fd5b6000611c6984828501611a58565b91505092915050565b611c7b81612259565b82525050565b611c8a8161226b565b82525050565b611c9981612277565b82525050565b611ca8816122b8565b82525050565b611cb7816122dc565b82525050565b611cc681612300565b82525050565b6000611cd96009836121ba565b91507f63616e27742062757900000000000000000000000000000000000000000000006000830152602082019050919050565b6000611d196010836121ba565b91507f6e6f7420656e6f756768207475726e21000000000000000000000000000000006000830152602082019050919050565b6000611d596026836121ba565b91507f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008301527f64647265737300000000000000000000000000000000000000000000000000006020830152604082019050919050565b6000611dbf6015836121ba565b91507f77726f6e6720616d6d6f756e74206f66206574682100000000000000000000006000830152602082019050919050565b6000611dff6015836121ba565b91507f796f75206e6f7420696e2077686974656c6973742100000000000000000000006000830152602082019050919050565b6000611e3f600e836121ba565b91507f4172726179206e6f206d617463680000000000000000000000000000000000006000830152602082019050919050565b6000611e7f6020836121ba565b91507f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726000830152602082019050919050565b6000611ebf6011836121ba565b91507f6e6f7420656e6f756768206d6f6e6579210000000000000000000000000000006000830152602082019050919050565b611efb816122a1565b82525050565b611f0a816122ab565b82525050565b6000602082019050611f256000830184611c72565b92915050565b6000602082019050611f406000830184611c81565b92915050565b6000602082019050611f5b6000830184611c9f565b92915050565b6000602082019050611f766000830184611cae565b92915050565b600060a082019050611f916000830188611cbd565b611f9e6020830187611cbd565b611fab6040830186611cbd565b611fb86060830185611c90565b611fc56080830184611c72565b9695505050505050565b60006020820190508181036000830152611fe881611ccc565b9050919050565b6000602082019050818103600083015261200881611d0c565b9050919050565b6000602082019050818103600083015261202881611d4c565b9050919050565b6000602082019050818103600083015261204881611db2565b9050919050565b6000602082019050818103600083015261206881611df2565b9050919050565b6000602082019050818103600083015261208881611e32565b9050919050565b600060208201905081810360008301526120a881611e72565b9050919050565b600060208201905081810360008301526120c881611eb2565b9050919050565b60006020820190506120e46000830184611ef2565b92915050565b60006020820190506120ff6000830184611f01565b92915050565b6000604051905081810181811067ffffffffffffffff8211171561212c5761212b6123b4565b5b8060405250919050565b600067ffffffffffffffff821115612151576121506123b4565b5b602082029050602081019050919050565b600067ffffffffffffffff82111561217d5761217c6123b4565b5b602082029050602081019050919050565b600067ffffffffffffffff8211156121a9576121a86123b4565b5b602082029050602081019050919050565b600082825260208201905092915050565b60006121d6826122a1565b91506121e1836122a1565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048311821515161561221a57612219612385565b5b828202905092915050565b6000612230826122ab565b915061223b836122ab565b92508282101561224e5761224d612385565b5b828203905092915050565b600061226482612281565b9050919050565b60008115159050919050565b6000819050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b600060ff82169050919050565b60006122c3826122ca565b9050919050565b60006122d582612281565b9050919050565b60006122e7826122ee565b9050919050565b60006122f982612281565b9050919050565b600061230b826122a1565b9050919050565b600061231d826122a1565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8214156123505761234f612385565b5b600182019050919050565b6000612366826122ab565b915060ff82141561237a57612379612385565b5b600182019050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6123ec81612259565b81146123f757600080fd5b50565b6124038161226b565b811461240e57600080fd5b50565b61241a81612277565b811461242557600080fd5b50565b612431816122a1565b811461243c57600080fd5b50565b612448816122ab565b811461245357600080fd5b5056fea2646970667358221220ce08c9a4433ce1d65061b82c389dd320792c666fb7a75c7718105136bdeea38864736f6c63430008000033
Deployed Bytecode Sourcemap
72374:4285:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;75217:242;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;72809:24;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;72672:50;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;73174:306;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;73865:197;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;76505:151;;;;;;;;;;;;;:::i;:::-;;26884:94;;;;;;;;;;;;;:::i;:::-;;74070;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;74355:439;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;76050:365;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;72552:33;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;26233:87;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;72622:43;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;74172:175;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;74802:407;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;75467:575;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;72514:31;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;72763:39;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;27133:192;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;73674:183;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;72731:25;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;75217:242;72928:6;;;;;;;;;;;72920:28;;;;;;;;;;;;:::i;:::-;;;;;;;;;75325:7:::1;75313:19;;:9;;:19;;;;:::i;:::-;75299:9;:34;;75291:64;;;;;;;;;;;;:::i;:::-;;;;;;;;;75373:11;75368:84;75398:7;75390:15;;:5;:15;;;75368:84;;;75431:9;:7;:9::i;:::-;;75407:7;;;;;:::i;:::-;;;;75368:84;;;;75217:242:::0;:::o;72809:24::-;;;;;;;;;;;;;:::o;72672:50::-;;;;;;;;;;;;;;;;;:::o;73174:306::-;26464:12;:10;:12::i;:::-;26453:23;;:7;:5;:7::i;:::-;:23;;;26445:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;73253:38:::1;73315:8;73253:71;;73353:17;:31;;;:33;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;73345:42;;;::::0;::::1;;73455:17;73441:11;;:31;;;;;;;;;;;;;;;;;;26524:1;73174:306:::0;:::o;73865:197::-;26464:12;:10;:12::i;:::-;26453:23;;:7;:5;:7::i;:::-;:23;;;26445:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;73937:7:::1;73928:6;;:16;;;;;;;;;;;;;;;;;;73959:7;73955:100;;;73988:8;;;;;;;;;;73955:100;;;74034:9;;;;;;;;;;73955:100;73865:197:::0;:::o;76505:151::-;26464:12;:10;:12::i;:::-;26453:23;;:7;:5;:7::i;:::-;:23;;;26445:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;76562:15:::1;76580:21;76562:39;;76622:7;:5;:7::i;:::-;76614:25;;:34;76640:7;76614:34;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;26524:1;76505:151::o:0;26884:94::-;26464:12;:10;:12::i;:::-;26453:23;;:7;:5;:7::i;:::-;:23;;;26445:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;26949:21:::1;26967:1;26949:9;:21::i;:::-;26884:94::o:0;74070:::-;26464:12;:10;:12::i;:::-;26453:23;;:7;:5;:7::i;:::-;:23;;;26445:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;74150:6:::1;74138:9;:18;;;;74070:94:::0;:::o;74355:439::-;26464:12;:10;:12::i;:::-;26453:23;;:7;:5;:7::i;:::-;:23;;;26445:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;74513:8:::1;:15;74496:6;:13;:32;74488:59;;;;;;;;;;;;:::i;:::-;;;;;;;;;74583:7;:14;74566:6;:13;:31;74558:58;;;;;;;;;;;;:::i;:::-;;;;;;;;;74634:9;74629:158;74653:6;:13;74649:1;:17;74629:158;;;74711:8;74720:1;74711:11;;;;;;;;;;;;;;;;;;;;;;74688:9;:20;74698:6;74705:1;74698:9;;;;;;;;;;;;;;;;;;;;;;74688:20;;;;;;;;;;;;;;;;:34;;;;;;;;;;;;;;;;;;74765:7;74773:1;74765:10;;;;;;;;;;;;;;;;;;;;;;74737:14;:25;74752:6;74759:1;74752:9;;;;;;;;;;;;;;;;;;;;;;74737:25;;;;;;;;;;;;;;;:38;;;;74668:3;;;;;:::i;:::-;;;;74629:158;;;;74355:439:::0;;;:::o;76050:365::-;72928:6;;;;;;;;;;;72920:28;;;;;;;;;;;;:::i;:::-;;;;;;;;;76169:7:::1;76144:32;;:9;:21;76154:10;76144:21;;;;;;;;;;;;;;;;;;;;;;;;;:32;;;;76136:61;;;;;;;;;;;;:::i;:::-;;;;;;;;;76256:7;76229:34;;:14;:26;76244:10;76229:26;;;;;;;;;;;;;;;;:34;;;;:::i;:::-;76216:9;:47;;76208:81;;;;;;;;;;;;:::i;:::-;;;;;;;;;76315:13;76310:98;76342:7;76334:15;;:5;:15;76310:98;;;76375:21;:19;:21::i;:::-;;76351:7;;;;;:::i;:::-;;;;76310:98;;;;76050:365:::0;:::o;72552:33::-;;;;:::o;26233:87::-;26279:7;26306:6;;;;;;;;;;;26299:13;;26233:87;:::o;72622:43::-;;;;;;;;;;;;;;;;;;;;;;:::o;74172:175::-;26464:12;:10;:12::i;:::-;26453:23;;:7;:5;:7::i;:::-;:23;;;26445:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;74289:7:::1;74270:9;:16;74280:5;74270:16;;;;;;;;;;;;;;;;:26;;;;;;;;;;;;;;;;;;74331:6;74307:14;:21;74322:5;74307:21;;;;;;;;;;;;;;;:30;;;;74172:175:::0;;;:::o;74802:407::-;74856:7;72928:6;;;;;;;;;;;72920:28;;;;;;;;;;;;:::i;:::-;;;;;;;;;74898:9:::1;;74885;:22;;74877:52;;;;;;;;;;;;:::i;:::-;;;;;;;;;74940:14;74957:11;;;;;;;;;;;:23;;;74981:13;;74957:38;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;74940:55;;75006:23;75032:8;;;;;;;;;;;:28;;;75061:1;75064::::0;75067::::1;75070:6;75086:10;75032:66;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;75006:92;;75109:16;;:18;;;;;;;;;:::i;:::-;;;;;;75154:12;75138:13;:28;;;;75186:15;75179:22;;;;74802:407:::0;:::o;75467:575::-;75533:7;72928:6;;;;;;;;;;;72920:28;;;;;;;;;;;;:::i;:::-;;;;;;;;;75587:1:::1;75563:9;:21;75573:10;75563:21;;;;;;;;;;;;;;;;;;;;;;;;;:25;;;75555:59;;;;;;;;;;;;:::i;:::-;;;;;;;;;75646:14;:26;75661:10;75646:26;;;;;;;;;;;;;;;;75633:9;:39;;75625:73;;;;;;;;;;;;:::i;:::-;;;;;;;;;75711:14;75728:11;;;;;;;;;;;:23;;;75752:13;;75728:38;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;75711:55;;75777:23;75803:8;;;;;;;;;;;:28;;;75832:1;75835::::0;75838::::1;75841:6;75857:10;75803:66;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;75777:92;;75882:16;;:18;;;;;;;;;:::i;:::-;;;;;;75959:1;75935:9;:21;75945:10;75935:21;;;;;;;;;;;;;;;;;;;;;;;;;:25;;;;:::i;:::-;75911:9;:21;75921:10;75911:21;;;;;;;;;;;;;;;;:49;;;;;;;;;;;;;;;;;;75987:12;75971:13;:28;;;;76019:15;76012:22;;;;75467:575:::0;:::o;72514:31::-;;;;:::o;72763:39::-;;;;;;;;;;;;;:::o;27133:192::-;26464:12;:10;:12::i;:::-;26453:23;;:7;:5;:7::i;:::-;:23;;;26445:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;27242:1:::1;27222:22;;:8;:22;;;;27214:73;;;;;;;;;;;;:::i;:::-;;;;;;;;;27298:19;27308:8;27298:9;:19::i;:::-;27133:192:::0;:::o;73674:183::-;26464:12;:10;:12::i;:::-;26453:23;;:7;:5;:7::i;:::-;:23;;;26445:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;73738:17:::1;73767:8;73738:38;;73841:8;73830;;:19;;;;;;;;;;;;;;;;;;26524:1;73674:183:::0;:::o;72731:25::-;;;;;;;;;;;;;:::o;25013:98::-;25066:7;25093:10;25086:17;;25013:98;:::o;27333:173::-;27389:16;27408:6;;;;;;;;;;;27389:25;;27434:8;27425:6;;:17;;;;;;;;;;;;;;;;;;27489:8;27458:40;;27479:8;27458:40;;;;;;;;;;;;27333:173;;:::o;24:622:1:-;;145:80;160:64;217:6;160:64;:::i;:::-;145:80;:::i;:::-;136:89;;245:5;273:6;266:5;259:21;299:4;292:5;288:16;281:23;;324:6;374:3;366:4;358:6;354:17;349:3;345:27;342:36;339:2;;;391:1;388;381:12;339:2;419:1;404:236;429:6;426:1;423:13;404:236;;;496:3;524:37;557:3;545:10;524:37;:::i;:::-;519:3;512:50;591:4;586:3;582:14;575:21;;625:4;620:3;616:14;609:21;;464:176;451:1;448;444:9;439:14;;404:236;;;408:14;126:520;;;;;;;:::o;669:622::-;;790:80;805:64;862:6;805:64;:::i;:::-;790:80;:::i;:::-;781:89;;890:5;918:6;911:5;904:21;944:4;937:5;933:16;926:23;;969:6;1019:3;1011:4;1003:6;999:17;994:3;990:27;987:36;984:2;;;1036:1;1033;1026:12;984:2;1064:1;1049:236;1074:6;1071:1;1068:13;1049:236;;;1141:3;1169:37;1202:3;1190:10;1169:37;:::i;:::-;1164:3;1157:50;1236:4;1231:3;1227:14;1220:21;;1270:4;1265:3;1261:14;1254:21;;1109:176;1096:1;1093;1089:9;1084:14;;1049:236;;;1053:14;771:520;;;;;;;:::o;1312:616::-;;1431:78;1446:62;1501:6;1446:62;:::i;:::-;1431:78;:::i;:::-;1422:87;;1529:5;1557:6;1550:5;1543:21;1583:4;1576:5;1572:16;1565:23;;1608:6;1658:3;1650:4;1642:6;1638:17;1633:3;1629:27;1626:36;1623:2;;;1675:1;1672;1665:12;1623:2;1703:1;1688:234;1713:6;1710:1;1707:13;1688:234;;;1780:3;1808:35;1839:3;1827:10;1808:35;:::i;:::-;1803:3;1796:48;1873:4;1868:3;1864:14;1857:21;;1907:4;1902:3;1898:14;1891:21;;1748:174;1735:1;1732;1728:9;1723:14;;1688:234;;;1692:14;1412:516;;;;;;;:::o;1934:139::-;;2018:6;2005:20;1996:29;;2034:33;2061:5;2034:33;:::i;:::-;1986:87;;;;:::o;2096:303::-;;2216:3;2209:4;2201:6;2197:17;2193:27;2183:2;;2234:1;2231;2224:12;2183:2;2274:6;2261:20;2299:94;2389:3;2381:6;2374:4;2366:6;2362:17;2299:94;:::i;:::-;2290:103;;2173:226;;;;;:::o;2422:303::-;;2542:3;2535:4;2527:6;2523:17;2519:27;2509:2;;2560:1;2557;2550:12;2509:2;2600:6;2587:20;2625:94;2715:3;2707:6;2700:4;2692:6;2688:17;2625:94;:::i;:::-;2616:103;;2499:226;;;;;:::o;2746:299::-;;2864:3;2857:4;2849:6;2845:17;2841:27;2831:2;;2882:1;2879;2872:12;2831:2;2922:6;2909:20;2947:92;3035:3;3027:6;3020:4;3012:6;3008:17;2947:92;:::i;:::-;2938:101;;2821:224;;;;;:::o;3051:133::-;;3132:6;3119:20;3110:29;;3148:30;3172:5;3148:30;:::i;:::-;3100:84;;;;:::o;3190:137::-;;3275:6;3269:13;3260:22;;3291:30;3315:5;3291:30;:::i;:::-;3250:77;;;;:::o;3333:143::-;;3421:6;3415:13;3406:22;;3437:33;3464:5;3437:33;:::i;:::-;3396:80;;;;:::o;3482:139::-;;3566:6;3553:20;3544:29;;3582:33;3609:5;3582:33;:::i;:::-;3534:87;;;;:::o;3627:143::-;;3715:6;3709:13;3700:22;;3731:33;3758:5;3731:33;:::i;:::-;3690:80;;;;:::o;3776:135::-;;3858:6;3845:20;3836:29;;3874:31;3899:5;3874:31;:::i;:::-;3826:85;;;;:::o;3917:262::-;;4025:2;4013:9;4004:7;4000:23;3996:32;3993:2;;;4041:1;4038;4031:12;3993:2;4084:1;4109:53;4154:7;4145:6;4134:9;4130:22;4109:53;:::i;:::-;4099:63;;4055:117;3983:196;;;;:::o;4185:548::-;;;;4325:2;4313:9;4304:7;4300:23;4296:32;4293:2;;;4341:1;4338;4331:12;4293:2;4384:1;4409:53;4454:7;4445:6;4434:9;4430:22;4409:53;:::i;:::-;4399:63;;4355:117;4511:2;4537:51;4580:7;4571:6;4560:9;4556:22;4537:51;:::i;:::-;4527:61;;4482:116;4637:2;4663:53;4708:7;4699:6;4688:9;4684:22;4663:53;:::i;:::-;4653:63;;4608:118;4283:450;;;;;:::o;4739:977::-;;;;4954:2;4942:9;4933:7;4929:23;4925:32;4922:2;;;4970:1;4967;4960:12;4922:2;5041:1;5030:9;5026:17;5013:31;5071:18;5063:6;5060:30;5057:2;;;5103:1;5100;5093:12;5057:2;5131:78;5201:7;5192:6;5181:9;5177:22;5131:78;:::i;:::-;5121:88;;4984:235;5286:2;5275:9;5271:18;5258:32;5317:18;5309:6;5306:30;5303:2;;;5349:1;5346;5339:12;5303:2;5377:76;5445:7;5436:6;5425:9;5421:22;5377:76;:::i;:::-;5367:86;;5229:234;5530:2;5519:9;5515:18;5502:32;5561:18;5553:6;5550:30;5547:2;;;5593:1;5590;5583:12;5547:2;5621:78;5691:7;5682:6;5671:9;5667:22;5621:78;:::i;:::-;5611:88;;5473:236;4912:804;;;;;:::o;5722:256::-;;5827:2;5815:9;5806:7;5802:23;5798:32;5795:2;;;5843:1;5840;5833:12;5795:2;5886:1;5911:50;5953:7;5944:6;5933:9;5929:22;5911:50;:::i;:::-;5901:60;;5857:114;5785:193;;;;:::o;5984:278::-;;6100:2;6088:9;6079:7;6075:23;6071:32;6068:2;;;6116:1;6113;6106:12;6068:2;6159:1;6184:61;6237:7;6228:6;6217:9;6213:22;6184:61;:::i;:::-;6174:71;;6130:125;6058:204;;;;:::o;6268:284::-;;6387:2;6375:9;6366:7;6362:23;6358:32;6355:2;;;6403:1;6400;6393:12;6355:2;6446:1;6471:64;6527:7;6518:6;6507:9;6503:22;6471:64;:::i;:::-;6461:74;;6417:128;6345:207;;;;:::o;6558:262::-;;6666:2;6654:9;6645:7;6641:23;6637:32;6634:2;;;6682:1;6679;6672:12;6634:2;6725:1;6750:53;6795:7;6786:6;6775:9;6771:22;6750:53;:::i;:::-;6740:63;;6696:117;6624:196;;;;:::o;6826:284::-;;6945:2;6933:9;6924:7;6920:23;6916:32;6913:2;;;6961:1;6958;6951:12;6913:2;7004:1;7029:64;7085:7;7076:6;7065:9;7061:22;7029:64;:::i;:::-;7019:74;;6975:128;6903:207;;;;:::o;7116:258::-;;7222:2;7210:9;7201:7;7197:23;7193:32;7190:2;;;7238:1;7235;7228:12;7190:2;7281:1;7306:51;7349:7;7340:6;7329:9;7325:22;7306:51;:::i;:::-;7296:61;;7252:115;7180:194;;;;:::o;7380:118::-;7467:24;7485:5;7467:24;:::i;:::-;7462:3;7455:37;7445:53;;:::o;7504:109::-;7585:21;7600:5;7585:21;:::i;:::-;7580:3;7573:34;7563:50;;:::o;7619:118::-;7706:24;7724:5;7706:24;:::i;:::-;7701:3;7694:37;7684:53;;:::o;7743:189::-;7859:66;7919:5;7859:66;:::i;:::-;7854:3;7847:79;7837:95;;:::o;7938:165::-;8042:54;8090:5;8042:54;:::i;:::-;8037:3;8030:67;8020:83;;:::o;8109:147::-;8204:45;8243:5;8204:45;:::i;:::-;8199:3;8192:58;8182:74;;:::o;8262:306::-;;8425:66;8489:1;8484:3;8425:66;:::i;:::-;8418:73;;8521:11;8517:1;8512:3;8508:11;8501:32;8559:2;8554:3;8550:12;8543:19;;8408:160;;;:::o;8574:314::-;;8737:67;8801:2;8796:3;8737:67;:::i;:::-;8730:74;;8834:18;8830:1;8825:3;8821:11;8814:39;8879:2;8874:3;8870:12;8863:19;;8720:168;;;:::o;8894:370::-;;9057:67;9121:2;9116:3;9057:67;:::i;:::-;9050:74;;9154:34;9150:1;9145:3;9141:11;9134:55;9220:8;9215:2;9210:3;9206:12;9199:30;9255:2;9250:3;9246:12;9239:19;;9040:224;;;:::o;9270:319::-;;9433:67;9497:2;9492:3;9433:67;:::i;:::-;9426:74;;9530:23;9526:1;9521:3;9517:11;9510:44;9580:2;9575:3;9571:12;9564:19;;9416:173;;;:::o;9595:319::-;;9758:67;9822:2;9817:3;9758:67;:::i;:::-;9751:74;;9855:23;9851:1;9846:3;9842:11;9835:44;9905:2;9900:3;9896:12;9889:19;;9741:173;;;:::o;9920:312::-;;10083:67;10147:2;10142:3;10083:67;:::i;:::-;10076:74;;10180:16;10176:1;10171:3;10167:11;10160:37;10223:2;10218:3;10214:12;10207:19;;10066:166;;;:::o;10238:330::-;;10401:67;10465:2;10460:3;10401:67;:::i;:::-;10394:74;;10498:34;10494:1;10489:3;10485:11;10478:55;10559:2;10554:3;10550:12;10543:19;;10384:184;;;:::o;10574:315::-;;10737:67;10801:2;10796:3;10737:67;:::i;:::-;10730:74;;10834:19;10830:1;10825:3;10821:11;10814:40;10880:2;10875:3;10871:12;10864:19;;10720:169;;;:::o;10895:118::-;10982:24;11000:5;10982:24;:::i;:::-;10977:3;10970:37;10960:53;;:::o;11019:112::-;11102:22;11118:5;11102:22;:::i;:::-;11097:3;11090:35;11080:51;;:::o;11137:222::-;;11268:2;11257:9;11253:18;11245:26;;11281:71;11349:1;11338:9;11334:17;11325:6;11281:71;:::i;:::-;11235:124;;;;:::o;11365:210::-;;11490:2;11479:9;11475:18;11467:26;;11503:65;11565:1;11554:9;11550:17;11541:6;11503:65;:::i;:::-;11457:118;;;;:::o;11581:280::-;;11741:2;11730:9;11726:18;11718:26;;11754:100;11851:1;11840:9;11836:17;11827:6;11754:100;:::i;:::-;11708:153;;;;:::o;11867:256::-;;12015:2;12004:9;12000:18;11992:26;;12028:88;12113:1;12102:9;12098:17;12089:6;12028:88;:::i;:::-;11982:141;;;;:::o;12129:712::-;;12396:3;12385:9;12381:19;12373:27;;12410:79;12486:1;12475:9;12471:17;12462:6;12410:79;:::i;:::-;12499:80;12575:2;12564:9;12560:18;12551:6;12499:80;:::i;:::-;12589;12665:2;12654:9;12650:18;12641:6;12589:80;:::i;:::-;12679:72;12747:2;12736:9;12732:18;12723:6;12679:72;:::i;:::-;12761:73;12829:3;12818:9;12814:19;12805:6;12761:73;:::i;:::-;12363:478;;;;;;;;:::o;12847:419::-;;13051:2;13040:9;13036:18;13028:26;;13100:9;13094:4;13090:20;13086:1;13075:9;13071:17;13064:47;13128:131;13254:4;13128:131;:::i;:::-;13120:139;;13018:248;;;:::o;13272:419::-;;13476:2;13465:9;13461:18;13453:26;;13525:9;13519:4;13515:20;13511:1;13500:9;13496:17;13489:47;13553:131;13679:4;13553:131;:::i;:::-;13545:139;;13443:248;;;:::o;13697:419::-;;13901:2;13890:9;13886:18;13878:26;;13950:9;13944:4;13940:20;13936:1;13925:9;13921:17;13914:47;13978:131;14104:4;13978:131;:::i;:::-;13970:139;;13868:248;;;:::o;14122:419::-;;14326:2;14315:9;14311:18;14303:26;;14375:9;14369:4;14365:20;14361:1;14350:9;14346:17;14339:47;14403:131;14529:4;14403:131;:::i;:::-;14395:139;;14293:248;;;:::o;14547:419::-;;14751:2;14740:9;14736:18;14728:26;;14800:9;14794:4;14790:20;14786:1;14775:9;14771:17;14764:47;14828:131;14954:4;14828:131;:::i;:::-;14820:139;;14718:248;;;:::o;14972:419::-;;15176:2;15165:9;15161:18;15153:26;;15225:9;15219:4;15215:20;15211:1;15200:9;15196:17;15189:47;15253:131;15379:4;15253:131;:::i;:::-;15245:139;;15143:248;;;:::o;15397:419::-;;15601:2;15590:9;15586:18;15578:26;;15650:9;15644:4;15640:20;15636:1;15625:9;15621:17;15614:47;15678:131;15804:4;15678:131;:::i;:::-;15670:139;;15568:248;;;:::o;15822:419::-;;16026:2;16015:9;16011:18;16003:26;;16075:9;16069:4;16065:20;16061:1;16050:9;16046:17;16039:47;16103:131;16229:4;16103:131;:::i;:::-;16095:139;;15993:248;;;:::o;16247:222::-;;16378:2;16367:9;16363:18;16355:26;;16391:71;16459:1;16448:9;16444:17;16435:6;16391:71;:::i;:::-;16345:124;;;;:::o;16475:214::-;;16602:2;16591:9;16587:18;16579:26;;16615:67;16679:1;16668:9;16664:17;16655:6;16615:67;:::i;:::-;16569:120;;;;:::o;16695:283::-;;16761:2;16755:9;16745:19;;16803:4;16795:6;16791:17;16910:6;16898:10;16895:22;16874:18;16862:10;16859:34;16856:62;16853:2;;;16921:18;;:::i;:::-;16853:2;16961:10;16957:2;16950:22;16735:243;;;;:::o;16984:311::-;;17151:18;17143:6;17140:30;17137:2;;;17173:18;;:::i;:::-;17137:2;17223:4;17215:6;17211:17;17203:25;;17283:4;17277;17273:15;17265:23;;17066:229;;;:::o;17301:311::-;;17468:18;17460:6;17457:30;17454:2;;;17490:18;;:::i;:::-;17454:2;17540:4;17532:6;17528:17;17520:25;;17600:4;17594;17590:15;17582:23;;17383:229;;;:::o;17618:309::-;;17783:18;17775:6;17772:30;17769:2;;;17805:18;;:::i;:::-;17769:2;17855:4;17847:6;17843:17;17835:25;;17915:4;17909;17905:15;17897:23;;17698:229;;;:::o;17933:169::-;;18051:6;18046:3;18039:19;18091:4;18086:3;18082:14;18067:29;;18029:73;;;;:::o;18108:348::-;;18171:20;18189:1;18171:20;:::i;:::-;18166:25;;18205:20;18223:1;18205:20;:::i;:::-;18200:25;;18393:1;18325:66;18321:74;18318:1;18315:81;18310:1;18303:9;18296:17;18292:105;18289:2;;;18400:18;;:::i;:::-;18289:2;18448:1;18445;18441:9;18430:20;;18156:300;;;;:::o;18462:185::-;;18520:18;18536:1;18520:18;:::i;:::-;18515:23;;18552:18;18568:1;18552:18;:::i;:::-;18547:23;;18589:1;18586;18583:8;18580:2;;;18594:18;;:::i;:::-;18580:2;18639:1;18636;18632:9;18624:17;;18505:142;;;;:::o;18653:96::-;;18719:24;18737:5;18719:24;:::i;:::-;18708:35;;18698:51;;;:::o;18755:90::-;;18832:5;18825:13;18818:21;18807:32;;18797:48;;;:::o;18851:77::-;;18917:5;18906:16;;18896:32;;;:::o;18934:126::-;;19011:42;19004:5;19000:54;18989:65;;18979:81;;;:::o;19066:77::-;;19132:5;19121:16;;19111:32;;;:::o;19149:86::-;;19224:4;19217:5;19213:16;19202:27;;19192:43;;;:::o;19241:184::-;;19353:66;19413:5;19353:66;:::i;:::-;19340:79;;19330:95;;;:::o;19431:142::-;;19543:24;19561:5;19543:24;:::i;:::-;19530:37;;19520:53;;;:::o;19579:160::-;;19679:54;19727:5;19679:54;:::i;:::-;19666:67;;19656:83;;;:::o;19745:130::-;;19845:24;19863:5;19845:24;:::i;:::-;19832:37;;19822:53;;;:::o;19881:121::-;;19972:24;19990:5;19972:24;:::i;:::-;19959:37;;19949:53;;;:::o;20008:233::-;;20070:24;20088:5;20070:24;:::i;:::-;20061:33;;20116:66;20109:5;20106:77;20103:2;;;20186:18;;:::i;:::-;20103:2;20233:1;20226:5;20222:13;20215:20;;20051:190;;;:::o;20247:167::-;;20307:22;20323:5;20307:22;:::i;:::-;20298:31;;20351:4;20344:5;20341:15;20338:2;;;20359:18;;:::i;:::-;20338:2;20406:1;20399:5;20395:13;20388:20;;20288:126;;;:::o;20420:180::-;20468:77;20465:1;20458:88;20565:4;20562:1;20555:15;20589:4;20586:1;20579:15;20606:180;20654:77;20651:1;20644:88;20751:4;20748:1;20741:15;20775:4;20772:1;20765:15;20792:122;20865:24;20883:5;20865:24;:::i;:::-;20858:5;20855:35;20845:2;;20904:1;20901;20894:12;20845:2;20835:79;:::o;20920:116::-;20990:21;21005:5;20990:21;:::i;:::-;20983:5;20980:32;20970:2;;21026:1;21023;21016:12;20970:2;20960:76;:::o;21042:122::-;21115:24;21133:5;21115:24;:::i;:::-;21108:5;21105:35;21095:2;;21154:1;21151;21144:12;21095:2;21085:79;:::o;21170:122::-;21243:24;21261:5;21243:24;:::i;:::-;21236:5;21233:35;21223:2;;21282:1;21279;21272:12;21223:2;21213:79;:::o;21298:118::-;21369:22;21385:5;21369:22;:::i;:::-;21362:5;21359:33;21349:2;;21406:1;21403;21396:12;21349:2;21339:77;:::o
Swarm Source
ipfs://ce08c9a4433ce1d65061b82c389dd320792c666fb7a75c7718105136bdeea388
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.