Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
Latest 25 from a total of 177 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Cancel | 14875125 | 898 days ago | IN | 0 ETH | 0.00266606 | ||||
Cancel | 14875121 | 898 days ago | IN | 0 ETH | 0.00251574 | ||||
Cancel | 13970590 | 1040 days ago | IN | 0 ETH | 0.00798841 | ||||
Cancel | 13850453 | 1058 days ago | IN | 0 ETH | 0.00506599 | ||||
Cancel | 13850434 | 1058 days ago | IN | 0 ETH | 0.00458178 | ||||
Cancel | 13216788 | 1158 days ago | IN | 0 ETH | 0.00325236 | ||||
Cancel | 13189530 | 1162 days ago | IN | 0 ETH | 0.00543691 | ||||
Buy | 13117905 | 1173 days ago | IN | 0.0306 ETH | 0.01719211 | ||||
Buy | 13117905 | 1173 days ago | IN | 0.0306 ETH | 0.01576419 | ||||
Buy | 13117905 | 1173 days ago | IN | 0.0306 ETH | 0.01565486 | ||||
Buy | 13078584 | 1179 days ago | IN | 0.0051 ETH | 0.01115297 | ||||
Cancel | 13034030 | 1186 days ago | IN | 0 ETH | 0.00321923 | ||||
Cancel | 12996396 | 1192 days ago | IN | 0 ETH | 0.00292972 | ||||
Cancel | 12845603 | 1216 days ago | IN | 0 ETH | 0.00162762 | ||||
Buy | 12825133 | 1219 days ago | IN | 0.51 ETH | 0.00879549 | ||||
Buy | 12747547 | 1231 days ago | IN | 0.102 ETH | 0.00255962 | ||||
Cancel | 12701450 | 1238 days ago | IN | 0 ETH | 0.00065105 | ||||
Cancel | 12691150 | 1240 days ago | IN | 0 ETH | 0.00188804 | ||||
Buy | 12689542 | 1240 days ago | IN | 0.00102 ETH | 0.00234469 | ||||
Cancel | 12687740 | 1240 days ago | IN | 0 ETH | 0.00195315 | ||||
Cancel | 12662891 | 1244 days ago | IN | 0 ETH | 0.00065105 | ||||
Cancel | 12639122 | 1248 days ago | IN | 0 ETH | 0.00084636 | ||||
Cancel | 12639095 | 1248 days ago | IN | 0 ETH | 0.00078126 | ||||
Cancel | 12639037 | 1248 days ago | IN | 0 ETH | 0.00055038 | ||||
Cancel | 12639032 | 1248 days ago | IN | 0 ETH | 0.00071615 |
Latest 25 internal transactions (View All)
Advanced mode:
Parent Transaction Hash | Block | From | To | |||
---|---|---|---|---|---|---|
13117905 | 1173 days ago | 0.027 ETH | ||||
13117905 | 1173 days ago | 0.003 ETH | ||||
13117905 | 1173 days ago | 0.0006 ETH | ||||
13117905 | 1173 days ago | 0.027 ETH | ||||
13117905 | 1173 days ago | 0.003 ETH | ||||
13117905 | 1173 days ago | 0.0006 ETH | ||||
13117905 | 1173 days ago | 0.027 ETH | ||||
13117905 | 1173 days ago | 0.003 ETH | ||||
13117905 | 1173 days ago | 0.0006 ETH | ||||
13078584 | 1179 days ago | 0.0045 ETH | ||||
13078584 | 1179 days ago | 0.0005 ETH | ||||
13078584 | 1179 days ago | 0.0001 ETH | ||||
12825133 | 1219 days ago | 0.45 ETH | ||||
12825133 | 1219 days ago | 0.05 ETH | ||||
12825133 | 1219 days ago | 0.01 ETH | ||||
12747547 | 1231 days ago | 0.09 ETH | ||||
12747547 | 1231 days ago | 0.01 ETH | ||||
12747547 | 1231 days ago | 0.002 ETH | ||||
12689542 | 1240 days ago | 0.00085 ETH | ||||
12689542 | 1240 days ago | 0.00015 ETH | ||||
12689542 | 1240 days ago | 0.00002 ETH | ||||
12632433 | 1249 days ago | 0.0009 ETH | ||||
12632433 | 1249 days ago | 0.0001 ETH | ||||
12632433 | 1249 days ago | 0.00002 ETH | ||||
12615618 | 1251 days ago | 0.027 ETH |
Loading...
Loading
Contract Name:
ERC721Sale
Compiler Version
v0.5.16+commit.9c3226ce
Contract Source Code (Solidity)
/** *Submitted for verification at Etherscan.io on 2020-12-31 */ pragma solidity ^0.5.0; pragma experimental ABIEncoderV2; /** * @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); } /** * @dev Required interface of an ERC721 compliant contract. */ contract IERC721 is IERC165 { event Transfer(address indexed from, address indexed to, uint256 indexed tokenId); event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId); event ApprovalForAll(address indexed owner, address indexed operator, bool approved); /** * @dev Returns the number of NFTs in `owner`'s account. */ function balanceOf(address owner) public view returns (uint256 balance); /** * @dev Returns the owner of the NFT specified by `tokenId`. */ function ownerOf(uint256 tokenId) public view returns (address owner); /** * @dev Transfers a specific NFT (`tokenId`) from one account (`from`) to * another (`to`). * * * * Requirements: * - `from`, `to` cannot be zero. * - `tokenId` must be owned by `from`. * - If the caller is not `from`, it must be have been allowed to move this * NFT by either {approve} or {setApprovalForAll}. */ function safeTransferFrom(address from, address to, uint256 tokenId) public; /** * @dev Transfers a specific NFT (`tokenId`) from one account (`from`) to * another (`to`). * * Requirements: * - If the caller is not `from`, it must be approved to move this NFT by * either {approve} or {setApprovalForAll}. */ function transferFrom(address from, address to, uint256 tokenId) public; function approve(address to, uint256 tokenId) public; function getApproved(uint256 tokenId) public view returns (address operator); function setApprovalForAll(address operator, bool _approved) public; function isApprovedForAll(address owner, address operator) public view returns (bool); function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory data) public; } /** * @title ERC721 token receiver interface * @dev Interface for any contract that wants to support safeTransfers * from ERC721 asset contracts. */ contract IERC721Receiver { /** * @notice Handle the receipt of an NFT * @dev The ERC721 smart contract calls this function on the recipient * after a {IERC721-safeTransferFrom}. This function MUST return the function selector, * otherwise the caller will revert the transaction. The selector to be * returned can be obtained as `this.onERC721Received.selector`. This * function MAY throw to revert and reject the transfer. * Note: the ERC721 contract address is always the message sender. * @param operator The address which called `safeTransferFrom` function * @param from The address which previously owned the token * @param tokenId The NFT identifier which is being transferred * @param data Additional data with no specified format * @return bytes4 `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))` */ function onERC721Received(address operator, address from, uint256 tokenId, bytes memory data) public returns (bytes4); } /* * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with GSN meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ contract Context { // Empty internal constructor, to prevent people from mistakenly deploying // an instance of this contract, which should be used via inheritance. constructor () internal { } // solhint-disable-previous-line no-empty-blocks function _msgSender() internal view returns (address payable) { return msg.sender; } function _msgData() internal view returns (bytes memory) { this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691 return msg.data; } } /** * @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. * * 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. */ contract Ownable is Context { address private _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the deployer as the initial owner. */ constructor () internal { address msgSender = _msgSender(); _owner = msgSender; emit OwnershipTransferred(address(0), msgSender); } /** * @dev Returns the address of the current owner. */ function owner() public view returns (address) { return _owner; } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { require(isOwner(), "Ownable: caller is not the owner"); _; } /** * @dev Returns true if the caller is the current owner. */ function isOwner() public view returns (bool) { return _msgSender() == _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 onlyOwner { emit OwnershipTransferred(_owner, address(0)); _owner = address(0); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public onlyOwner { _transferOwnership(newOwner); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). */ function _transferOwnership(address newOwner) internal { require(newOwner != address(0), "Ownable: new owner is the zero address"); emit OwnershipTransferred(_owner, newOwner); _owner = newOwner; } } /** * @title ERC-721 Non-Fungible Token Standard, optional metadata extension * @dev See https://eips.ethereum.org/EIPS/eip-721 */ contract IERC721Metadata is IERC721 { function name() external view returns (string memory); function symbol() external view returns (string memory); function tokenURI(uint256 tokenId) external view returns (string memory); } /** * @dev Wrappers over Solidity's arithmetic operations with added overflow * checks. * * Arithmetic operations in Solidity wrap on overflow. This can easily result * in bugs, because programmers usually assume that an overflow raises an * error, which is the standard behavior in high level programming languages. * `SafeMath` restores this intuition by reverting the transaction when an * operation overflows. * * Using this library instead of the unchecked operations eliminates an entire * class of bugs, so it's recommended to use it always. */ library SafeMath { /** * @dev Returns the addition of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `+` operator. * * Requirements: * - Addition cannot overflow. */ function add(uint256 a, uint256 b) internal pure returns (uint256) { uint256 c = a + b; require(c >= a, "SafeMath: addition overflow"); return c; } /** * @dev Returns the subtraction of two unsigned integers, reverting on * overflow (when the result is negative). * * Counterpart to Solidity's `-` operator. * * Requirements: * - Subtraction cannot overflow. */ function sub(uint256 a, uint256 b) internal pure returns (uint256) { return sub(a, b, "SafeMath: subtraction overflow"); } /** * @dev Returns the subtraction of two unsigned integers, reverting with custom message on * overflow (when the result is negative). * * Counterpart to Solidity's `-` operator. * * Requirements: * - Subtraction cannot overflow. * * _Available since v2.4.0._ */ function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b <= a, errorMessage); uint256 c = a - b; return c; } /** * @dev Returns the multiplication of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `*` operator. * * Requirements: * - Multiplication cannot overflow. */ function mul(uint256 a, uint256 b) internal pure returns (uint256) { // Gas optimization: this is cheaper than requiring 'a' not being zero, but the // benefit is lost if 'b' is also tested. // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522 if (a == 0) { return 0; } uint256 c = a * b; require(c / a == b, "SafeMath: multiplication overflow"); return c; } /** * @dev Returns the integer division of two unsigned integers. Reverts on * division by zero. The result is rounded towards zero. * * Counterpart to Solidity's `/` operator. Note: this function uses a * `revert` opcode (which leaves remaining gas untouched) while Solidity * uses an invalid opcode to revert (consuming all remaining gas). * * Requirements: * - The divisor cannot be zero. */ function div(uint256 a, uint256 b) internal pure returns (uint256) { return div(a, b, "SafeMath: division by zero"); } /** * @dev Returns the integer division of two unsigned integers. Reverts 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. * * _Available since v2.4.0._ */ function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { // Solidity only automatically asserts when dividing by 0 require(b > 0, errorMessage); uint256 c = a / b; // assert(a == b * c + a % b); // There is no case in which this doesn't hold return c; } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * Reverts when dividing by zero. * * Counterpart to Solidity's `%` operator. This function uses a `revert` * opcode (which leaves remaining gas untouched) while Solidity uses an * invalid opcode to revert (consuming all remaining gas). * * Requirements: * - The divisor cannot be zero. */ function mod(uint256 a, uint256 b) internal pure returns (uint256) { return mod(a, b, "SafeMath: modulo by zero"); } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * Reverts with custom message 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. * * _Available since v2.4.0._ */ function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b != 0, errorMessage); return a % b; } } /** * @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) { // According to EIP-1052, 0x0 is the value returned for not-yet created accounts // and 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470 is returned // for accounts without code, i.e. `keccak256('')` bytes32 codehash; bytes32 accountHash = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470; // solhint-disable-next-line no-inline-assembly assembly { codehash := extcodehash(account) } return (codehash != accountHash && codehash != 0x0); } /** * @dev Converts an `address` into `address payable`. Note that this is * simply a type cast: the actual underlying value is not changed. * * _Available since v2.4.0._ */ function toPayable(address account) internal pure returns (address payable) { return address(uint160(account)); } /** * @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]. * * _Available since v2.4.0._ */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); // solhint-disable-next-line avoid-call-value (bool success, ) = recipient.call.value(amount)(""); require(success, "Address: unable to send value, recipient may have reverted"); } } /** * @title Counters * @author Matt Condon (@shrugs) * @dev Provides counters that can only be incremented or decremented by one. This can be used e.g. to track the number * of elements in a mapping, issuing ERC721 ids, or counting request ids. * * Include with `using Counters for Counters.Counter;` * Since it is not possible to overflow a 256 bit integer with increments of one, `increment` can skip the {SafeMath} * overflow check, thereby saving gas. This does assume however correct usage, in that the underlying `_value` is never * directly accessed. */ library Counters { using SafeMath for uint256; struct Counter { // This variable should never be directly accessed by users of the library: interactions must be restricted to // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add // this feature: see https://github.com/ethereum/solidity/issues/4637 uint256 _value; // default: 0 } function current(Counter storage counter) internal view returns (uint256) { return counter._value; } function increment(Counter storage counter) internal { // The {SafeMath} overflow check can be skipped here, see the comment at the top counter._value += 1; } function decrement(Counter storage counter) internal { counter._value = counter._value.sub(1); } } /** * @dev Implementation of the {IERC165} interface. * * Contracts may inherit from this and call {_registerInterface} to declare * their support of an interface. */ contract ERC165 is IERC165 { /* * bytes4(keccak256('supportsInterface(bytes4)')) == 0x01ffc9a7 */ bytes4 private constant _INTERFACE_ID_ERC165 = 0x01ffc9a7; /** * @dev Mapping of interface ids to whether or not it's supported. */ mapping(bytes4 => bool) private _supportedInterfaces; constructor () internal { // Derived contracts need only register support for their own interfaces, // we register support for ERC165 itself here _registerInterface(_INTERFACE_ID_ERC165); } /** * @dev See {IERC165-supportsInterface}. * * Time complexity O(1), guaranteed to always use less than 30 000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool) { return _supportedInterfaces[interfaceId]; } /** * @dev Registers the contract as an implementer of the interface defined by * `interfaceId`. Support of the actual ERC165 interface is automatic and * registering its interface id is not required. * * See {IERC165-supportsInterface}. * * Requirements: * * - `interfaceId` cannot be the ERC165 invalid interface (`0xffffffff`). */ function _registerInterface(bytes4 interfaceId) internal { require(interfaceId != 0xffffffff, "ERC165: invalid interface id"); _supportedInterfaces[interfaceId] = true; } } /** * @title ERC721 Non-Fungible Token Standard basic implementation * @dev see https://eips.ethereum.org/EIPS/eip-721 */ contract ERC721 is Context, ERC165, IERC721 { using SafeMath for uint256; using Address for address; using Counters for Counters.Counter; // Equals to `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))` // which can be also obtained as `IERC721Receiver(0).onERC721Received.selector` bytes4 private constant _ERC721_RECEIVED = 0x150b7a02; // Mapping from token ID to owner mapping (uint256 => address) private _tokenOwner; // Mapping from token ID to approved address mapping (uint256 => address) private _tokenApprovals; // Mapping from owner to number of owned token mapping (address => Counters.Counter) private _ownedTokensCount; // Mapping from owner to operator approvals mapping (address => mapping (address => bool)) private _operatorApprovals; /* * bytes4(keccak256('balanceOf(address)')) == 0x70a08231 * bytes4(keccak256('ownerOf(uint256)')) == 0x6352211e * bytes4(keccak256('approve(address,uint256)')) == 0x095ea7b3 * bytes4(keccak256('getApproved(uint256)')) == 0x081812fc * bytes4(keccak256('setApprovalForAll(address,bool)')) == 0xa22cb465 * bytes4(keccak256('isApprovedForAll(address,address)')) == 0xe985e9c5 * bytes4(keccak256('transferFrom(address,address,uint256)')) == 0x23b872dd * bytes4(keccak256('safeTransferFrom(address,address,uint256)')) == 0x42842e0e * bytes4(keccak256('safeTransferFrom(address,address,uint256,bytes)')) == 0xb88d4fde * * => 0x70a08231 ^ 0x6352211e ^ 0x095ea7b3 ^ 0x081812fc ^ * 0xa22cb465 ^ 0xe985e9c ^ 0x23b872dd ^ 0x42842e0e ^ 0xb88d4fde == 0x80ac58cd */ bytes4 private constant _INTERFACE_ID_ERC721 = 0x80ac58cd; constructor () public { // register the supported interfaces to conform to ERC721 via ERC165 _registerInterface(_INTERFACE_ID_ERC721); } /** * @dev Gets the balance of the specified address. * @param owner address to query the balance of * @return uint256 representing the amount owned by the passed address */ function balanceOf(address owner) public view returns (uint256) { require(owner != address(0), "ERC721: balance query for the zero address"); return _ownedTokensCount[owner].current(); } /** * @dev Gets the owner of the specified token ID. * @param tokenId uint256 ID of the token to query the owner of * @return address currently marked as the owner of the given token ID */ function ownerOf(uint256 tokenId) public view returns (address) { address owner = _tokenOwner[tokenId]; require(owner != address(0), "ERC721: owner query for nonexistent token"); return owner; } /** * @dev Approves another address to transfer the given token ID * The zero address indicates there is no approved address. * There can only be one approved address per token at a given time. * Can only be called by the token owner or an approved operator. * @param to address to be approved for the given token ID * @param tokenId uint256 ID of the token to be approved */ function approve(address to, uint256 tokenId) public { address owner = 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" ); _tokenApprovals[tokenId] = to; emit Approval(owner, to, tokenId); } /** * @dev Gets the approved address for a token ID, or zero if no address set * Reverts if the token ID does not exist. * @param tokenId uint256 ID of the token to query the approval of * @return address currently approved for the given token ID */ function getApproved(uint256 tokenId) public view returns (address) { require(_exists(tokenId), "ERC721: approved query for nonexistent token"); return _tokenApprovals[tokenId]; } /** * @dev Sets or unsets the approval of a given operator * An operator is allowed to transfer all tokens of the sender on their behalf. * @param to operator address to set the approval * @param approved representing the status of the approval to be set */ function setApprovalForAll(address to, bool approved) public { require(to != _msgSender(), "ERC721: approve to caller"); _operatorApprovals[_msgSender()][to] = approved; emit ApprovalForAll(_msgSender(), to, approved); } /** * @dev Tells whether an operator is approved by a given owner. * @param owner owner address which you want to query the approval of * @param operator operator address which you want to query the approval of * @return bool whether the given operator is approved by the given owner */ function isApprovedForAll(address owner, address operator) public view returns (bool) { return _operatorApprovals[owner][operator]; } /** * @dev Transfers the ownership of a given token ID to another address. * Usage of this method is discouraged, use {safeTransferFrom} whenever possible. * Requires the msg.sender to be the owner, approved, or operator. * @param from current owner of the token * @param to address to receive the ownership of the given token ID * @param tokenId uint256 ID of the token to be transferred */ function transferFrom(address from, address to, uint256 tokenId) public { //solhint-disable-next-line max-line-length require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: transfer caller is not owner nor approved"); _transferFrom(from, to, tokenId); } /** * @dev Safely transfers the ownership of a given token ID to another address * If the target address is a contract, it must implement {IERC721Receiver-onERC721Received}, * which is called upon a safe transfer, and return the magic value * `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`; otherwise, * the transfer is reverted. * Requires the msg.sender to be the owner, approved, or operator * @param from current owner of the token * @param to address to receive the ownership of the given token ID * @param tokenId uint256 ID of the token to be transferred */ function safeTransferFrom(address from, address to, uint256 tokenId) public { safeTransferFrom(from, to, tokenId, ""); } /** * @dev Safely transfers the ownership of a given token ID to another address * If the target address is a contract, it must implement {IERC721Receiver-onERC721Received}, * which is called upon a safe transfer, and return the magic value * `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`; otherwise, * the transfer is reverted. * Requires the _msgSender() to be the owner, approved, or operator * @param from current owner of the token * @param to address to receive the ownership of the given token ID * @param tokenId uint256 ID of the token to be transferred * @param _data bytes data to send along with a safe transfer check */ function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory _data) public { require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: transfer caller is not owner nor approved"); _safeTransferFrom(from, to, tokenId, _data); } /** * @dev Safely transfers the ownership of a given token ID to another address * If the target address is a contract, it must implement `onERC721Received`, * which is called upon a safe transfer, and return the magic value * `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`; otherwise, * the transfer is reverted. * Requires the msg.sender to be the owner, approved, or operator * @param from current owner of the token * @param to address to receive the ownership of the given token ID * @param tokenId uint256 ID of the token to be transferred * @param _data bytes data to send along with a safe transfer check */ function _safeTransferFrom(address from, address to, uint256 tokenId, bytes memory _data) internal { _transferFrom(from, to, tokenId); require(_checkOnERC721Received(from, to, tokenId, _data), "ERC721: transfer to non ERC721Receiver implementer"); } /** * @dev Returns whether the specified token exists. * @param tokenId uint256 ID of the token to query the existence of * @return bool whether the token exists */ function _exists(uint256 tokenId) internal view returns (bool) { address owner = _tokenOwner[tokenId]; return owner != address(0); } /** * @dev Returns whether the given spender can transfer a given token ID. * @param spender address of the spender to query * @param tokenId uint256 ID of the token to be transferred * @return bool whether the msg.sender is approved for the given token ID, * is an operator of the owner, or is the owner of the token */ function _isApprovedOrOwner(address spender, uint256 tokenId) internal view returns (bool) { require(_exists(tokenId), "ERC721: operator query for nonexistent token"); address owner = ownerOf(tokenId); return (spender == owner || getApproved(tokenId) == spender || isApprovedForAll(owner, spender)); } /** * @dev Internal function to safely mint a new token. * Reverts if the given token ID already exists. * If the target address is a contract, it must implement `onERC721Received`, * which is called upon a safe transfer, and return the magic value * `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`; otherwise, * the transfer is reverted. * @param to The address that will own the minted token * @param tokenId uint256 ID of the token to be minted */ function _safeMint(address to, uint256 tokenId) internal { _safeMint(to, tokenId, ""); } /** * @dev Internal function to safely mint a new token. * Reverts if the given token ID already exists. * If the target address is a contract, it must implement `onERC721Received`, * which is called upon a safe transfer, and return the magic value * `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`; otherwise, * the transfer is reverted. * @param to The address that will own the minted token * @param tokenId uint256 ID of the token to be minted * @param _data bytes data to send along with a safe transfer check */ function _safeMint(address to, uint256 tokenId, bytes memory _data) internal { _mint(to, tokenId); require(_checkOnERC721Received(address(0), to, tokenId, _data), "ERC721: transfer to non ERC721Receiver implementer"); } /** * @dev Internal function to mint a new token. * Reverts if the given token ID already exists. * @param to The address that will own the minted token * @param tokenId uint256 ID of the token to be minted */ function _mint(address to, uint256 tokenId) internal { require(to != address(0), "ERC721: mint to the zero address"); require(!_exists(tokenId), "ERC721: token already minted"); _tokenOwner[tokenId] = to; _ownedTokensCount[to].increment(); emit Transfer(address(0), to, tokenId); } /** * @dev Internal function to burn a specific token. * Reverts if the token does not exist. * Deprecated, use {_burn} instead. * @param owner owner of the token to burn * @param tokenId uint256 ID of the token being burned */ function _burn(address owner, uint256 tokenId) internal { require(ownerOf(tokenId) == owner, "ERC721: burn of token that is not own"); _clearApproval(tokenId); _ownedTokensCount[owner].decrement(); _tokenOwner[tokenId] = address(0); emit Transfer(owner, address(0), tokenId); } /** * @dev Internal function to burn a specific token. * Reverts if the token does not exist. * @param tokenId uint256 ID of the token being burned */ function _burn(uint256 tokenId) internal { _burn(ownerOf(tokenId), tokenId); } /** * @dev Internal function to transfer ownership of a given token ID to another address. * As opposed to {transferFrom}, this imposes no restrictions on msg.sender. * @param from current owner of the token * @param to address to receive the ownership of the given token ID * @param tokenId uint256 ID of the token to be transferred */ function _transferFrom(address from, address to, uint256 tokenId) internal { require(ownerOf(tokenId) == from, "ERC721: transfer of token that is not own"); require(to != address(0), "ERC721: transfer to the zero address"); _clearApproval(tokenId); _ownedTokensCount[from].decrement(); _ownedTokensCount[to].increment(); _tokenOwner[tokenId] = to; emit Transfer(from, 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. * * This is an internal detail of the `ERC721` contract and its use is deprecated. * @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) internal returns (bool) { if (!to.isContract()) { return true; } // solhint-disable-next-line avoid-low-level-calls (bool success, bytes memory returndata) = to.call(abi.encodeWithSelector( IERC721Receiver(to).onERC721Received.selector, _msgSender(), from, tokenId, _data )); if (!success) { if (returndata.length > 0) { // solhint-disable-next-line no-inline-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert("ERC721: transfer to non ERC721Receiver implementer"); } } else { bytes4 retval = abi.decode(returndata, (bytes4)); return (retval == _ERC721_RECEIVED); } } /** * @dev Private function to clear current approval of a given token ID. * @param tokenId uint256 ID of the token to be transferred */ function _clearApproval(uint256 tokenId) private { if (_tokenApprovals[tokenId] != address(0)) { _tokenApprovals[tokenId] = address(0); } } } /** * @title ERC721 Burnable Token * @dev ERC721 Token that can be irreversibly burned (destroyed). */ contract ERC721Burnable is Context, ERC721 { /** * @dev Burns a specific ERC721 token. * @param tokenId uint256 id of the ERC721 token to be burned. */ function burn(uint256 tokenId) public { //solhint-disable-next-line max-line-length require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721Burnable: caller is not owner nor approved"); _burn(tokenId); } } /** * @title ERC-721 Non-Fungible Token Standard, optional enumeration extension * @dev See https://eips.ethereum.org/EIPS/eip-721 */ contract IERC721Enumerable is IERC721 { function totalSupply() public view returns (uint256); function tokenOfOwnerByIndex(address owner, uint256 index) public view returns (uint256 tokenId); function tokenByIndex(uint256 index) public view returns (uint256); } /** * @title ERC-721 Non-Fungible Token with optional enumeration extension logic * @dev See https://eips.ethereum.org/EIPS/eip-721 */ contract ERC721Enumerable is Context, ERC165, ERC721, IERC721Enumerable { // Mapping from owner to list of owned token IDs mapping(address => uint256[]) private _ownedTokens; // Mapping from token ID to index of the owner tokens list mapping(uint256 => uint256) private _ownedTokensIndex; // Array with all token ids, used for enumeration uint256[] private _allTokens; // Mapping from token id to position in the allTokens array mapping(uint256 => uint256) private _allTokensIndex; /* * bytes4(keccak256('totalSupply()')) == 0x18160ddd * bytes4(keccak256('tokenOfOwnerByIndex(address,uint256)')) == 0x2f745c59 * bytes4(keccak256('tokenByIndex(uint256)')) == 0x4f6ccce7 * * => 0x18160ddd ^ 0x2f745c59 ^ 0x4f6ccce7 == 0x780e9d63 */ bytes4 private constant _INTERFACE_ID_ERC721_ENUMERABLE = 0x780e9d63; /** * @dev Constructor function. */ constructor () public { // register the supported interface to conform to ERC721Enumerable via ERC165 _registerInterface(_INTERFACE_ID_ERC721_ENUMERABLE); } /** * @dev Gets the token ID at a given index of the tokens list of the requested owner. * @param owner address owning the tokens list to be accessed * @param index uint256 representing the index to be accessed of the requested tokens list * @return uint256 token ID at the given index of the tokens list owned by the requested address */ function tokenOfOwnerByIndex(address owner, uint256 index) public view returns (uint256) { require(index < balanceOf(owner), "ERC721Enumerable: owner index out of bounds"); return _ownedTokens[owner][index]; } /** * @dev Gets the total amount of tokens stored by the contract. * @return uint256 representing the total amount of tokens */ function totalSupply() public view returns (uint256) { return _allTokens.length; } /** * @dev Gets the token ID at a given index of all the tokens in this contract * Reverts if the index is greater or equal to the total number of tokens. * @param index uint256 representing the index to be accessed of the tokens list * @return uint256 token ID at the given index of the tokens list */ function tokenByIndex(uint256 index) public view returns (uint256) { require(index < totalSupply(), "ERC721Enumerable: global index out of bounds"); return _allTokens[index]; } /** * @dev Internal function to transfer ownership of a given token ID to another address. * As opposed to transferFrom, this imposes no restrictions on msg.sender. * @param from current owner of the token * @param to address to receive the ownership of the given token ID * @param tokenId uint256 ID of the token to be transferred */ function _transferFrom(address from, address to, uint256 tokenId) internal { super._transferFrom(from, to, tokenId); _removeTokenFromOwnerEnumeration(from, tokenId); _addTokenToOwnerEnumeration(to, tokenId); } /** * @dev Internal function to mint a new token. * Reverts if the given token ID already exists. * @param to address the beneficiary that will own the minted token * @param tokenId uint256 ID of the token to be minted */ function _mint(address to, uint256 tokenId) internal { super._mint(to, tokenId); _addTokenToOwnerEnumeration(to, tokenId); _addTokenToAllTokensEnumeration(tokenId); } /** * @dev Internal function to burn a specific token. * Reverts if the token does not exist. * Deprecated, use {ERC721-_burn} instead. * @param owner owner of the token to burn * @param tokenId uint256 ID of the token being burned */ function _burn(address owner, uint256 tokenId) internal { super._burn(owner, tokenId); _removeTokenFromOwnerEnumeration(owner, tokenId); // Since tokenId will be deleted, we can clear its slot in _ownedTokensIndex to trigger a gas refund _ownedTokensIndex[tokenId] = 0; _removeTokenFromAllTokensEnumeration(tokenId); } /** * @dev Gets the list of token IDs of the requested owner. * @param owner address owning the tokens * @return uint256[] List of token IDs owned by the requested address */ function _tokensOfOwner(address owner) internal view returns (uint256[] storage) { return _ownedTokens[owner]; } /** * @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 { _ownedTokensIndex[tokenId] = _ownedTokens[to].length; _ownedTokens[to].push(tokenId); } /** * @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 = _ownedTokens[from].length.sub(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 _ownedTokens[from].length--; // Note that _ownedTokensIndex[tokenId] hasn't been cleared: it still points to the old slot (now occupied by // lastTokenId, or just over the end of the array if the token was the last one). } /** * @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.sub(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 _allTokens.length--; _allTokensIndex[tokenId] = 0; } } library UintLibrary { function toString(uint256 _i) internal pure returns (string memory) { if (_i == 0) { return "0"; } uint j = _i; uint len; while (j != 0) { len++; j /= 10; } bytes memory bstr = new bytes(len); uint k = len - 1; while (_i != 0) { bstr[k--] = byte(uint8(48 + _i % 10)); _i /= 10; } return string(bstr); } } library StringLibrary { using UintLibrary for uint256; function append(string memory _a, string memory _b) internal pure returns (string memory) { bytes memory _ba = bytes(_a); bytes memory _bb = bytes(_b); bytes memory bab = new bytes(_ba.length + _bb.length); uint k = 0; for (uint i = 0; i < _ba.length; i++) bab[k++] = _ba[i]; for (uint i = 0; i < _bb.length; i++) bab[k++] = _bb[i]; return string(bab); } function append(string memory _a, string memory _b, string memory _c) internal pure returns (string memory) { bytes memory _ba = bytes(_a); bytes memory _bb = bytes(_b); bytes memory _bc = bytes(_c); bytes memory bbb = new bytes(_ba.length + _bb.length + _bc.length); uint k = 0; for (uint i = 0; i < _ba.length; i++) bbb[k++] = _ba[i]; for (uint i = 0; i < _bb.length; i++) bbb[k++] = _bb[i]; for (uint i = 0; i < _bc.length; i++) bbb[k++] = _bc[i]; return string(bbb); } function recover(string memory message, uint8 v, bytes32 r, bytes32 s) internal pure returns (address) { bytes memory msgBytes = bytes(message); bytes memory fullMessage = concat( bytes("\x19Ethereum Signed Message:\n"), bytes(msgBytes.length.toString()), msgBytes, new bytes(0), new bytes(0), new bytes(0), new bytes(0) ); return ecrecover(keccak256(fullMessage), v, r, s); } function getAddress(bytes memory generatedBytes, uint8 v, bytes32 r, bytes32 s) internal pure returns (address) { bytes memory msgBytes = generatedBytes; bytes memory fullMessage = concat( bytes("\x19Ethereum Signed Message:\n"), bytes(msgBytes.length.toString()), msgBytes, new bytes(0), new bytes(0), new bytes(0), new bytes(0) ); return ecrecover(keccak256(fullMessage), v, r, s); } function concat(bytes memory _ba, bytes memory _bb, bytes memory _bc, bytes memory _bd, bytes memory _be, bytes memory _bf, bytes memory _bg) internal pure returns (bytes memory) { bytes memory resultBytes = new bytes(_ba.length + _bb.length + _bc.length + _bd.length + _be.length + _bf.length + _bg.length); uint k = 0; for (uint i = 0; i < _ba.length; i++) resultBytes[k++] = _ba[i]; for (uint i = 0; i < _bb.length; i++) resultBytes[k++] = _bb[i]; for (uint i = 0; i < _bc.length; i++) resultBytes[k++] = _bc[i]; for (uint i = 0; i < _bd.length; i++) resultBytes[k++] = _bd[i]; for (uint i = 0; i < _be.length; i++) resultBytes[k++] = _be[i]; for (uint i = 0; i < _bf.length; i++) resultBytes[k++] = _bf[i]; for (uint i = 0; i < _bg.length; i++) resultBytes[k++] = _bg[i]; return resultBytes; } } contract HasContractURI is ERC165 { string public contractURI; /* * bytes4(keccak256('contractURI()')) == 0xe8a3d485 */ bytes4 private constant _INTERFACE_ID_CONTRACT_URI = 0xe8a3d485; constructor(string memory _contractURI) public { contractURI = _contractURI; _registerInterface(_INTERFACE_ID_CONTRACT_URI); } /** * @dev Internal function to set the contract URI * @param _contractURI string URI prefix to assign */ function _setContractURI(string memory _contractURI) internal { contractURI = _contractURI; } } contract HasTokenURI { using StringLibrary for string; //Token URI prefix string public tokenURIPrefix; // Optional mapping for token URIs mapping(uint256 => string) private _tokenURIs; constructor(string memory _tokenURIPrefix) public { tokenURIPrefix = _tokenURIPrefix; } /** * @dev Returns an URI for a given token ID. * Throws if the token ID does not exist. May return an empty string. * @param tokenId uint256 ID of the token to query */ function _tokenURI(uint256 tokenId) internal view returns (string memory) { return tokenURIPrefix.append(_tokenURIs[tokenId]); } /** * @dev Internal function to set the token URI for a given token. * Reverts if the token ID does not exist. * @param tokenId uint256 ID of the token to set its URI * @param uri string URI to assign */ function _setTokenURI(uint256 tokenId, string memory uri) internal { _tokenURIs[tokenId] = uri; } /** * @dev Internal function to set the token URI prefix. * @param _tokenURIPrefix string URI prefix to assign */ function _setTokenURIPrefix(string memory _tokenURIPrefix) internal { tokenURIPrefix = _tokenURIPrefix; } function _clearTokenURI(uint256 tokenId) internal { if (bytes(_tokenURIs[tokenId]).length != 0) { delete _tokenURIs[tokenId]; } } } contract HasSecondarySaleFees is ERC165 { event SecondarySaleFees(uint256 tokenId, address[] recipients, uint[] bps); /* * bytes4(keccak256('getFeeBps(uint256)')) == 0x0ebd4c7f * bytes4(keccak256('getFeeRecipients(uint256)')) == 0xb9c4d9fb * * => 0x0ebd4c7f ^ 0xb9c4d9fb == 0xb7799584 */ bytes4 private constant _INTERFACE_ID_FEES = 0xb7799584; constructor() public { _registerInterface(_INTERFACE_ID_FEES); } function getFeeRecipients(uint256 id) public view returns (address payable[] memory); function getFeeBps(uint256 id) public view returns (uint[] memory); } /** * @title Full ERC721 Token with support for tokenURIPrefix * This implementation includes all the required and some optional functionality of the ERC721 standard * Moreover, it includes approve all functionality using operator terminology * @dev see https://eips.ethereum.org/EIPS/eip-721 */ contract ERC721Base is HasSecondarySaleFees, ERC721, HasContractURI, HasTokenURI, ERC721Enumerable { // Token name string public name; // Token symbol string public symbol; struct Fee { address payable recipient; uint256 value; } // id => fees mapping (uint256 => Fee[]) public fees; /* * bytes4(keccak256('name()')) == 0x06fdde03 * bytes4(keccak256('symbol()')) == 0x95d89b41 * bytes4(keccak256('tokenURI(uint256)')) == 0xc87b56dd * * => 0x06fdde03 ^ 0x95d89b41 ^ 0xc87b56dd == 0x5b5e139f */ bytes4 private constant _INTERFACE_ID_ERC721_METADATA = 0x5b5e139f; /** * @dev Constructor function */ constructor (string memory _name, string memory _symbol, string memory contractURI, string memory _tokenURIPrefix) HasContractURI(contractURI) HasTokenURI(_tokenURIPrefix) public { name = _name; symbol = _symbol; // register the supported interfaces to conform to ERC721 via ERC165 _registerInterface(_INTERFACE_ID_ERC721_METADATA); } function getFeeRecipients(uint256 id) public view returns (address payable[] memory) { Fee[] memory _fees = fees[id]; address payable[] memory result = new address payable[](_fees.length); for (uint i = 0; i < _fees.length; i++) { result[i] = _fees[i].recipient; } return result; } function getFeeBps(uint256 id) public view returns (uint[] memory) { Fee[] memory _fees = fees[id]; uint[] memory result = new uint[](_fees.length); for (uint i = 0; i < _fees.length; i++) { result[i] = _fees[i].value; } return result; } function _mint(address to, uint256 tokenId, Fee[] memory _fees) internal { _mint(to, tokenId); address[] memory recipients = new address[](_fees.length); uint[] memory bps = new uint[](_fees.length); for (uint i = 0; i < _fees.length; i++) { require(_fees[i].recipient != address(0x0), "Recipient should be present"); require(_fees[i].value != 0, "Fee value should be positive"); fees[tokenId].push(_fees[i]); recipients[i] = _fees[i].recipient; bps[i] = _fees[i].value; } if (_fees.length > 0) { emit SecondarySaleFees(tokenId, recipients, bps); } } /** * @dev Returns an URI for a given token ID. * Throws if the token ID does not exist. May return an empty string. * @param tokenId uint256 ID of the token to query */ function tokenURI(uint256 tokenId) external view returns (string memory) { require(_exists(tokenId), "ERC721Metadata: URI query for nonexistent token"); return super._tokenURI(tokenId); } /** * @dev Internal function to set the token URI for a given token. * Reverts if the token ID does not exist. * @param tokenId uint256 ID of the token to set its URI * @param uri string URI to assign */ function _setTokenURI(uint256 tokenId, string memory uri) internal { require(_exists(tokenId), "ERC721Metadata: URI set of nonexistent token"); super._setTokenURI(tokenId, uri); } /** * @dev Internal function to burn a specific token. * Reverts if the token does not exist. * Deprecated, use _burn(uint256) instead. * @param owner owner of the token to burn * @param tokenId uint256 ID of the token being burned by the msg.sender */ function _burn(address owner, uint256 tokenId) internal { super._burn(owner, tokenId); _clearTokenURI(tokenId); } } /** * @title MintableToken * @dev anyone can mint token. */ contract MintableToken is Ownable, IERC721, IERC721Metadata, ERC721Burnable, ERC721Base { constructor (string memory name, string memory symbol, address newOwner, string memory contractURI, string memory tokenURIPrefix) public ERC721Base(name, symbol, contractURI, tokenURIPrefix) { _registerInterface(bytes4(keccak256('MINT_WITH_ADDRESS'))); transferOwnership(newOwner); } function mint(uint256 tokenId, uint8 v, bytes32 r, bytes32 s, Fee[] memory _fees, string memory tokenURI) public { require(owner() == ecrecover(keccak256(abi.encodePacked(this, tokenId)), v, r, s), "owner should sign tokenId"); _mint(msg.sender, tokenId, _fees); _setTokenURI(tokenId, tokenURI); } function setTokenURIPrefix(string memory tokenURIPrefix) public onlyOwner { _setTokenURIPrefix(tokenURIPrefix); } function setContractURI(string memory contractURI) public onlyOwner { _setContractURI(contractURI); } } library AddressLibrary { function toString(address _addr) internal pure returns (string memory) { bytes32 value = bytes32(uint256(_addr)); bytes memory alphabet = "0123456789abcdef"; bytes memory str = new bytes(42); str[0] = '0'; str[1] = 'x'; for (uint256 i = 0; i < 20; i++) { str[2+i*2] = alphabet[uint8(value[i + 12] >> 4)]; str[3+i*2] = alphabet[uint8(value[i + 12] & 0x0f)]; } return string(str); } } contract AbstractSale is Ownable { using UintLibrary for uint256; using AddressLibrary for address; using StringLibrary for string; using SafeMath for uint256; bytes4 private constant _INTERFACE_ID_FEES = 0xb7799584; uint private constant maxBuyerFeePercentage = 10000; uint public buyerFee = 0; address payable public beneficiary; /* An ECDSA signature. */ struct Sig { /* v parameter */ uint8 v; /* r parameter */ bytes32 r; /* s parameter */ bytes32 s; } constructor(address payable _beneficiary) public { beneficiary = _beneficiary; } function setBuyerFee(uint256 _buyerFee) public onlyOwner { require(_buyerFee <= maxBuyerFeePercentage, "max buyer percentage can't be more than 10000"); buyerFee = _buyerFee; } function setBeneficiary(address payable _beneficiary) public onlyOwner { beneficiary = _beneficiary; } function prepareMessage(address token, uint256 tokenId, uint256 price, uint256 fee, uint256 nonce) public view returns (string memory) { string memory result = string(strConcat( bytes(token.toString()), bytes(". tokenId: "), bytes(tokenId.toString()), bytes(". price: "), bytes(price.toString()), bytes(". nonce: "), bytes(nonce.toString()) )); if (fee != 0) { return result.append(". fee: ", fee.toString()); } else { return result; } } function strConcat(bytes memory _ba, bytes memory _bb, bytes memory _bc, bytes memory _bd, bytes memory _be, bytes memory _bf, bytes memory _bg) internal pure returns (bytes memory) { bytes memory resultBytes = new bytes(_ba.length + _bb.length + _bc.length + _bd.length + _be.length + _bf.length + _bg.length); uint k = 0; for (uint i = 0; i < _ba.length; i++) resultBytes[k++] = _ba[i]; for (uint i = 0; i < _bb.length; i++) resultBytes[k++] = _bb[i]; for (uint i = 0; i < _bc.length; i++) resultBytes[k++] = _bc[i]; for (uint i = 0; i < _bd.length; i++) resultBytes[k++] = _bd[i]; for (uint i = 0; i < _be.length; i++) resultBytes[k++] = _be[i]; for (uint i = 0; i < _bf.length; i++) resultBytes[k++] = _bf[i]; for (uint i = 0; i < _bg.length; i++) resultBytes[k++] = _bg[i]; return resultBytes; } function transferEther(IERC165 token, uint256 tokenId, address payable owner, uint256 total, uint256 sellerFee) internal { uint value = transferFeeToBeneficiary(total, sellerFee); if (token.supportsInterface(_INTERFACE_ID_FEES)) { HasSecondarySaleFees withFees = HasSecondarySaleFees(address(token)); address payable[] memory recipients = withFees.getFeeRecipients(tokenId); uint[] memory fees = withFees.getFeeBps(tokenId); require(fees.length == recipients.length); for (uint256 i = 0; i < fees.length; i++) { (uint newValue, uint current) = subFee(value, total.mul(fees[i]).div(maxBuyerFeePercentage)); value = newValue; recipients[i].transfer(current); } } owner.transfer(value); } function transferFeeToBeneficiary(uint total, uint sellerFee) internal returns (uint) { (uint value, uint sellerFeeValue) = subFee(total, total.mul(sellerFee).div(maxBuyerFeePercentage)); uint buyerFeeValue = total.mul(buyerFee).div(maxBuyerFeePercentage); uint beneficiaryFee = buyerFeeValue.add(sellerFeeValue); if (beneficiaryFee > 0) { beneficiary.transfer(beneficiaryFee); } return value; } function subFee(uint value, uint fee) internal pure returns (uint newValue, uint realFee) { if (value > fee) { newValue = value - fee; realFee = fee; } else { newValue = 0; realFee = value; } } } /** @title ERC-1155 Multi Token Standard @dev See https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1155.md Note: The ERC-165 identifier for this interface is 0xd9b67a26. */ contract IERC1155 is IERC165 { /** @dev Either `TransferSingle` or `TransferBatch` MUST emit when tokens are transferred, including zero value transfers as well as minting or burning (see "Safe Transfer Rules" section of the standard). The `_operator` argument MUST be msg.sender. The `_from` argument MUST be the address of the holder whose balance is decreased. The `_to` argument MUST be the address of the recipient whose balance is increased. The `_id` argument MUST be the token type being transferred. The `_value` argument MUST be the number of tokens the holder balance is decreased by and match what the recipient balance is increased by. When minting/creating tokens, the `_from` argument MUST be set to `0x0` (i.e. zero address). When burning/destroying tokens, the `_to` argument MUST be set to `0x0` (i.e. zero address). */ event TransferSingle(address indexed _operator, address indexed _from, address indexed _to, uint256 _id, uint256 _value); /** @dev Either `TransferSingle` or `TransferBatch` MUST emit when tokens are transferred, including zero value transfers as well as minting or burning (see "Safe Transfer Rules" section of the standard). The `_operator` argument MUST be msg.sender. The `_from` argument MUST be the address of the holder whose balance is decreased. The `_to` argument MUST be the address of the recipient whose balance is increased. The `_ids` argument MUST be the list of tokens being transferred. The `_values` argument MUST be the list of number of tokens (matching the list and order of tokens specified in _ids) the holder balance is decreased by and match what the recipient balance is increased by. When minting/creating tokens, the `_from` argument MUST be set to `0x0` (i.e. zero address). When burning/destroying tokens, the `_to` argument MUST be set to `0x0` (i.e. zero address). */ event TransferBatch(address indexed _operator, address indexed _from, address indexed _to, uint256[] _ids, uint256[] _values); /** @dev MUST emit when approval for a second party/operator address to manage all tokens for an owner address is enabled or disabled (absense of an event assumes disabled). */ event ApprovalForAll(address indexed _owner, address indexed _operator, bool _approved); /** @dev MUST emit when the URI is updated for a token ID. URIs are defined in RFC 3986. The URI MUST point a JSON file that conforms to the "ERC-1155 Metadata URI JSON Schema". */ event URI(string _value, uint256 indexed _id); /** @notice Transfers `_value` amount of an `_id` from the `_from` address to the `_to` address specified (with safety call). @dev Caller must be approved to manage the tokens being transferred out of the `_from` account (see "Approval" section of the standard). MUST revert if `_to` is the zero address. MUST revert if balance of holder for token `_id` is lower than the `_value` sent. MUST revert on any other error. MUST emit the `TransferSingle` event to reflect the balance change (see "Safe Transfer Rules" section of the standard). After the above conditions are met, this function MUST check if `_to` is a smart contract (e.g. code size > 0). If so, it MUST call `onERC1155Received` on `_to` and act appropriately (see "Safe Transfer Rules" section of the standard). @param _from Source address @param _to Target address @param _id ID of the token type @param _value Transfer amount @param _data Additional data with no specified format, MUST be sent unaltered in call to `onERC1155Received` on `_to` */ function safeTransferFrom(address _from, address _to, uint256 _id, uint256 _value, bytes calldata _data) external; /** @notice Transfers `_values` amount(s) of `_ids` from the `_from` address to the `_to` address specified (with safety call). @dev Caller must be approved to manage the tokens being transferred out of the `_from` account (see "Approval" section of the standard). MUST revert if `_to` is the zero address. MUST revert if length of `_ids` is not the same as length of `_values`. MUST revert if any of the balance(s) of the holder(s) for token(s) in `_ids` is lower than the respective amount(s) in `_values` sent to the recipient. MUST revert on any other error. MUST emit `TransferSingle` or `TransferBatch` event(s) such that all the balance changes are reflected (see "Safe Transfer Rules" section of the standard). Balance changes and events MUST follow the ordering of the arrays (_ids[0]/_values[0] before _ids[1]/_values[1], etc). After the above conditions for the transfer(s) in the batch are met, this function MUST check if `_to` is a smart contract (e.g. code size > 0). If so, it MUST call the relevant `ERC1155TokenReceiver` hook(s) on `_to` and act appropriately (see "Safe Transfer Rules" section of the standard). @param _from Source address @param _to Target address @param _ids IDs of each token type (order and length must match _values array) @param _values Transfer amounts per token type (order and length must match _ids array) @param _data Additional data with no specified format, MUST be sent unaltered in call to the `ERC1155TokenReceiver` hook(s) on `_to` */ function safeBatchTransferFrom(address _from, address _to, uint256[] calldata _ids, uint256[] calldata _values, bytes calldata _data) external; /** @notice Get the balance of an account's Tokens. @param _owner The address of the token holder @param _id ID of the Token @return The _owner's balance of the Token type requested */ function balanceOf(address _owner, uint256 _id) external view returns (uint256); /** @notice Get the balance of multiple account/token pairs @param _owners The addresses of the token holders @param _ids ID of the Tokens @return The _owner's balance of the Token types requested (i.e. balance for each (owner, id) pair) */ function balanceOfBatch(address[] calldata _owners, uint256[] calldata _ids) external view returns (uint256[] memory); /** @notice Enable or disable approval for a third party ("operator") to manage all of the caller's tokens. @dev MUST emit the ApprovalForAll event on success. @param _operator Address to add to the set of authorized operators @param _approved True if the operator is approved, false to revoke approval */ function setApprovalForAll(address _operator, bool _approved) external; /** @notice Queries the approval status of an operator for a given owner. @param _owner The owner of the Tokens @param _operator Address of authorized operator @return True if the operator is approved, false if not */ function isApprovedForAll(address _owner, address _operator) external view returns (bool); } /** * @title Roles * @dev Library for managing addresses assigned to a Role. */ library Roles { struct Role { mapping (address => bool) bearer; } /** * @dev Give an account access to this role. */ function add(Role storage role, address account) internal { require(!has(role, account), "Roles: account already has role"); role.bearer[account] = true; } /** * @dev Remove an account's access to this role. */ function remove(Role storage role, address account) internal { require(has(role, account), "Roles: account does not have role"); role.bearer[account] = false; } /** * @dev Check if an account has this role. * @return bool */ function has(Role storage role, address account) internal view returns (bool) { require(account != address(0), "Roles: account is the zero address"); return role.bearer[account]; } } contract OperatorRole is Context { using Roles for Roles.Role; event OperatorAdded(address indexed account); event OperatorRemoved(address indexed account); Roles.Role private _operators; constructor () internal { } modifier onlyOperator() { require(isOperator(_msgSender()), "OperatorRole: caller does not have the Operator role"); _; } function isOperator(address account) public view returns (bool) { return _operators.has(account); } function _addOperator(address account) internal { _operators.add(account); emit OperatorAdded(account); } function _removeOperator(address account) internal { _operators.remove(account); emit OperatorRemoved(account); } } contract OwnableOperatorRole is Ownable, OperatorRole { function addOperator(address account) public onlyOwner { _addOperator(account); } function removeOperator(address account) public onlyOwner { _removeOperator(account); } } contract TransferProxy is OwnableOperatorRole { function erc721safeTransferFrom(IERC721 token, address from, address to, uint256 tokenId) external onlyOperator { token.safeTransferFrom(from, to, tokenId); } function erc1155safeTransferFrom(IERC1155 token, address _from, address _to, uint256 _id, uint256 _value, bytes calldata _data) external onlyOperator { token.safeTransferFrom(_from, _to, _id, _value, _data); } } contract IERC721Sale { function getNonce(IERC721 token, uint256 tokenId) view public returns (uint256); } contract ERC721SaleNonceHolder is OwnableOperatorRole { mapping(bytes32 => uint256) public nonces; IERC721Sale public previous; constructor(IERC721Sale _previous) public { previous = _previous; } function getNonce(IERC721 token, uint256 tokenId) view public returns (uint256) { uint256 newNonce = nonces[getPositionKey(token, tokenId)]; if (newNonce != 0) { return newNonce; } if (address(previous) == address(0x0)) { return 0; } return previous.getNonce(token, tokenId); } function setNonce(IERC721 token, uint256 tokenId, uint256 nonce) public onlyOperator { nonces[getPositionKey(token, tokenId)] = nonce; } function getPositionKey(IERC721 token, uint256 tokenId) pure public returns (bytes32) { return keccak256(abi.encodePacked(token, tokenId)); } } contract ERC721Sale is Ownable, IERC721Receiver, AbstractSale { using AddressLibrary for address; using UintLibrary for uint256; using StringLibrary for string; uint private constant maxBuyerFeePercentage = 10000; event Cancel(address indexed token, uint256 indexed tokenId, address owner, uint256 nonce); event Buy(address indexed token, uint256 indexed tokenId, address seller, address buyer, uint256 price, uint256 nonce); TransferProxy public transferProxy; ERC721SaleNonceHolder public nonceHolder; constructor(TransferProxy _transferProxy, ERC721SaleNonceHolder _nonceHolder, address payable beneficiary) AbstractSale(beneficiary) public { transferProxy = _transferProxy; nonceHolder = _nonceHolder; } function cancel(IERC721 token, uint256 tokenId) public { address owner = token.ownerOf(tokenId); require(owner == msg.sender, "not an owner"); uint256 nonce = nonceHolder.getNonce(token, tokenId) + 1; nonceHolder.setNonce(token, tokenId, nonce); emit Cancel(address(token), tokenId, owner, nonce); } function buy(IERC721 token, uint256 tokenId, uint256 price, uint256 sellerFee, Sig memory signature) public payable { address payable owner = address(uint160(token.ownerOf(tokenId))); uint256 nonce = nonceHolder.getNonce(token, tokenId); uint256 buyerFeeValue = price.mul(buyerFee).div(maxBuyerFeePercentage); require(msg.value == price.add(buyerFeeValue), "msg.value is incorrect" ); string memory messageSigned = prepareMessage(address(token), tokenId, price, sellerFee, nonce); address ownerOf = StringLibrary.recover(messageSigned, signature.v, signature.r, signature.s); require(owner == ownerOf, "owner should sign correct message"); transferProxy.erc721safeTransferFrom(token, owner, msg.sender, tokenId); transferEther(token, tokenId, owner, price, sellerFee); nonceHolder.setNonce(token, tokenId, nonce + 1); emit Buy(address(token), tokenId, owner, msg.sender, price, nonce + 1); } function onERC721Received(address, address, uint256, bytes memory) public returns (bytes4) { return this.onERC721Received.selector; } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"contract TransferProxy","name":"_transferProxy","type":"address"},{"internalType":"contract ERC721SaleNonceHolder","name":"_nonceHolder","type":"address"},{"internalType":"address payable","name":"beneficiary","type":"address"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"token","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"address","name":"seller","type":"address"},{"indexed":false,"internalType":"address","name":"buyer","type":"address"},{"indexed":false,"internalType":"uint256","name":"price","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"nonce","type":"uint256"}],"name":"Buy","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"token","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"address","name":"owner","type":"address"},{"indexed":false,"internalType":"uint256","name":"nonce","type":"uint256"}],"name":"Cancel","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"},{"constant":true,"inputs":[],"name":"beneficiary","outputs":[{"internalType":"address payable","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"contract IERC721","name":"token","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"price","type":"uint256"},{"internalType":"uint256","name":"sellerFee","type":"uint256"},{"components":[{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"internalType":"struct AbstractSale.Sig","name":"signature","type":"tuple"}],"name":"buy","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"constant":true,"inputs":[],"name":"buyerFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"contract IERC721","name":"token","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"cancel","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"isOwner","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"nonceHolder","outputs":[{"internalType":"contract ERC721SaleNonceHolder","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"onERC721Received","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"price","type":"uint256"},{"internalType":"uint256","name":"fee","type":"uint256"},{"internalType":"uint256","name":"nonce","type":"uint256"}],"name":"prepareMessage","outputs":[{"internalType":"string","name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"renounceOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address payable","name":"_beneficiary","type":"address"}],"name":"setBeneficiary","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"_buyerFee","type":"uint256"}],"name":"setBuyerFee","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"transferProxy","outputs":[{"internalType":"contract TransferProxy","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"}]
Contract Creation Code
608060405260006001553480156200001657600080fd5b506040516200243738038062002437833981016040819052620000399162000103565b8060006200004f6001600160e01b03620000df16565b600080546001600160a01b0319166001600160a01b0383169081178255604051929350917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a350600280546001600160a01b03199081166001600160a01b0393841617909155600380548216958316959095179094556004805490941692169190911790915550620001a2565b3390565b8051620000f0816200017d565b92915050565b8051620000f08162000197565b6000806000606084860312156200011957600080fd5b6000620001278686620000f6565b93505060206200013a86828701620000f6565b92505060406200014d86828701620000e3565b9150509250925092565b6000620000f08262000171565b6000620000f08262000157565b6001600160a01b031690565b620001888162000157565b81146200019457600080fd5b50565b620001888162000164565b61228580620001b26000396000f3fe6080604052600436106100dd5760003560e01c80638da5cb5b1161007f578063a4ddbaa611610059578063a4ddbaa614610221578063b899072e14610234578063f2fde38b14610261578063fa7da19d14610281576100dd565b80638da5cb5b146101ca5780638f32d59b146101df57806398590ef914610201576100dd565b806341a259a6116100bb57806341a259a61461015c5780635de6c42f1461017e5780636e667db3146101a0578063715018a6146101b5576100dd565b8063150b7a02146100e25780631c31f7101461011857806338af3eed1461013a575b600080fd5b3480156100ee57600080fd5b506101026100fd366004611aa5565b6102a1565b60405161010f9190611fe6565b60405180910390f35b34801561012457600080fd5b50610138610133366004611a69565b6102b2565b005b34801561014657600080fd5b5061014f610301565b60405161010f9190611f5f565b34801561016857600080fd5b50610171610310565b60405161010f9190611ff4565b34801561018a57600080fd5b5061019361031f565b60405161010f91906120f1565b3480156101ac57600080fd5b50610171610325565b3480156101c157600080fd5b50610138610334565b3480156101d657600080fd5b5061014f6103a2565b3480156101eb57600080fd5b506101f46103b1565b60405161010f9190611fbd565b34801561020d57600080fd5b5061013861021c366004611c1b565b6103d5565b61013861022f366004611c55565b6105b7565b34801561024057600080fd5b5061025461024f366004611b1e565b6108aa565b60405161010f9190612060565b34801561026d57600080fd5b5061013861027c366004611a69565b6109a0565b34801561028d57600080fd5b5061013861029c366004611cbd565b6109d0565b630a85bd0160e11b5b949350505050565b6102ba6103b1565b6102df5760405162461bcd60e51b81526004016102d6906120c1565b60405180910390fd5b600280546001600160a01b0319166001600160a01b0392909216919091179055565b6002546001600160a01b031681565b6004546001600160a01b031681565b60015481565b6003546001600160a01b031681565b61033c6103b1565b6103585760405162461bcd60e51b81526004016102d6906120c1565b600080546040516001600160a01b03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600080546001600160a01b0319169055565b6000546001600160a01b031690565b600080546001600160a01b03166103c6610a1b565b6001600160a01b031614905090565b6040516331a9108f60e11b81526000906001600160a01b03841690636352211e906104049085906004016120f1565b60206040518083038186803b15801561041c57600080fd5b505afa158015610430573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506104549190810190611a87565b90506001600160a01b038116331461047e5760405162461bcd60e51b81526004016102d6906120d1565b60048054604051638953580360e01b81526000926001600160a01b03909216916389535803916104b291889188910161202a565b60206040518083038186803b1580156104ca57600080fd5b505afa1580156104de573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506105029190810190611cdb565b6004805460405163e330a93560e01b815260019390930193506001600160a01b03169163e330a9359161053b9188918891879101612038565b600060405180830381600087803b15801561055557600080fd5b505af1158015610569573d6000803e3d6000fd5b5050505082846001600160a01b03167fb8b7c5e8b8890227e1f8844a1b6bf94a9061b5ff6f8c75ae7db63926b22be27a84846040516105a9929190611fa2565b60405180910390a350505050565b6040516331a9108f60e11b81526000906001600160a01b03871690636352211e906105e69088906004016120f1565b60206040518083038186803b1580156105fe57600080fd5b505afa158015610612573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506106369190810190611a87565b60048054604051638953580360e01b81529293506000926001600160a01b039091169163895358039161066d918b918b910161202a565b60206040518083038186803b15801561068557600080fd5b505afa158015610699573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506106bd9190810190611cdb565b905060006106e86127106106dc60015489610a1f90919063ffffffff16565b9063ffffffff610a6216565b90506106fa868263ffffffff610aa416565b34146107185760405162461bcd60e51b81526004016102d6906120e1565b606061072789898989876108aa565b9050600061074382876000015188602001518960400151610ac9565b9050806001600160a01b0316856001600160a01b0316146107765760405162461bcd60e51b81526004016102d6906120a1565b600354604051637b84dc8360e11b81526001600160a01b039091169063f709b906906107ac908d90899033908f90600401612002565b600060405180830381600087803b1580156107c657600080fd5b505af11580156107da573d6000803e3d6000fd5b505050506107eb8a8a878b8b610ba6565b6004805460405163e330a93560e01b81526001600160a01b039091169163e330a93591610821918e918e9160018b019101612038565b600060405180830381600087803b15801561083b57600080fd5b505af115801561084f573d6000803e3d6000fd5b50505050888a6001600160a01b03167f7a212d757c7290587e1c8f7100a01a3d09466d58945058b6f22a179013475a9087338c896001016040516108969493929190611f6d565b60405180910390a350505050505050505050565b60608061094a6108c2886001600160a01b0316610e3c565b6040518060400160405280600b81526020016a017103a37b5b2b724b21d160ad1b8152506108ef89610fba565b6040518060400160405280600981526020016801710383934b1b29d160bd1b81525061091a8a610fba565b60405180604001604052806009815260200168017103737b731b29d160bd1b8152506109458a610fba565b611072565b905083156109945761098c60405180604001604052806007815260200166017103332b29d160cd1b81525061097e86610fba565b83919063ffffffff61131816565b915050610997565b90505b95945050505050565b6109a86103b1565b6109c45760405162461bcd60e51b81526004016102d6906120c1565b6109cd8161146e565b50565b6109d86103b1565b6109f45760405162461bcd60e51b81526004016102d6906120c1565b612710811115610a165760405162461bcd60e51b81526004016102d690612071565b600155565b3390565b600082610a2e57506000610a5c565b82820282848281610a3b57fe5b0414610a595760405162461bcd60e51b81526004016102d6906120b1565b90505b92915050565b6000610a5983836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f0000000000008152506114ef565b600082820183811015610a595760405162461bcd60e51b81526004016102d690612091565b600060608590506060610b426040518060400160405280601a81526020017f19457468657265756d205369676e6564204d6573736167653a0a000000000000815250610b158451610fba565b60408051600080825260208201818152828401828152606084019283526080840190945288939091611526565b90506001818051906020012087878760405160008152602001604052604051610b6e9493929190611fcb565b6020604051602081039080840390855afa158015610b90573d6000803e3d6000fd5b5050604051601f19015198975050505050505050565b6000610bb283836117bd565b6040516301ffc9a760e01b81529091506001600160a01b038716906301ffc9a790610be890632dde656160e21b90600401611fe6565b60206040518083038186803b158015610c0057600080fd5b505afa158015610c14573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610c389190810190611bfd565b15610dfd5760405163b9c4d9fb60e01b815286906060906001600160a01b0383169063b9c4d9fb90610c6e908a906004016120f1565b60006040518083038186803b158015610c8657600080fd5b505afa158015610c9a573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610cc29190810190611b93565b90506060826001600160a01b0316630ebd4c7f896040518263ffffffff1660e01b8152600401610cf291906120f1565b60006040518083038186803b158015610d0a57600080fd5b505afa158015610d1e573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610d469190810190611bc8565b90508151815114610d5657600080fd5b60005b8151811015610df857600080610d9a87610d956127106106dc888881518110610d7e57fe5b60200260200101518e610a1f90919063ffffffff16565b61185f565b91509150819650848381518110610dad57fe5b60200260200101516001600160a01b03166108fc829081150290604051600060405180830381858888f19350505050158015610ded573d6000803e3d6000fd5b505050600101610d59565b505050505b6040516001600160a01b0385169082156108fc029083906000818181858888f19350505050158015610e33573d6000803e3d6000fd5b50505050505050565b604080518082018252601081526f181899199a1a9b1b9c1cb0b131b232b360811b60208201528151602a80825260608281019094526001600160a01b03851692918491602082018180388339019050509050600360fc1b81600081518110610ea057fe5b60200101906001600160f81b031916908160001a905350600f60fb1b81600181518110610ec957fe5b60200101906001600160f81b031916908160001a90535060005b6014811015610faf578260048583600c0160208110610efe57fe5b1a60f81b6001600160f81b031916901c60f81c60ff1681518110610f1e57fe5b602001015160f81c60f81b828260020260020181518110610f3b57fe5b60200101906001600160f81b031916908160001a905350828482600c0160208110610f6257fe5b825191901a600f16908110610f7357fe5b602001015160f81c60f81b828260020260030181518110610f9057fe5b60200101906001600160f81b031916908160001a905350600101610ee3565b50925050505b919050565b606081610fdf57506040805180820190915260018152600360fc1b6020820152610fb5565b8160005b8115610ff757600101600a82049150610fe3565b6060816040519080825280601f01601f191660200182016040528015611024576020820181803883390190505b50905060001982015b8515610faf57600a860660300160f81b8282806001900393508151811061105057fe5b60200101906001600160f81b031916908160001a905350600a8604955061102d565b60608082518451865188518a518c518e510101010101016040519080825280601f01601f1916602001820160405280156110b3576020820181803883390190505b5090506000805b8a5181101561110b578a81815181106110cf57fe5b602001015160f81c60f81b8383806001019450815181106110ec57fe5b60200101906001600160f81b031916908160001a9053506001016110ba565b5060005b89518110156111605789818151811061112457fe5b602001015160f81c60f81b83838060010194508151811061114157fe5b60200101906001600160f81b031916908160001a90535060010161110f565b5060005b88518110156111b55788818151811061117957fe5b602001015160f81c60f81b83838060010194508151811061119657fe5b60200101906001600160f81b031916908160001a905350600101611164565b5060005b875181101561120a578781815181106111ce57fe5b602001015160f81c60f81b8383806001019450815181106111eb57fe5b60200101906001600160f81b031916908160001a9053506001016111b9565b5060005b865181101561125f5786818151811061122357fe5b602001015160f81c60f81b83838060010194508151811061124057fe5b60200101906001600160f81b031916908160001a90535060010161120e565b5060005b85518110156112b45785818151811061127857fe5b602001015160f81c60f81b83838060010194508151811061129557fe5b60200101906001600160f81b031916908160001a905350600101611263565b5060005b8451811015611309578481815181106112cd57fe5b602001015160f81c60f81b8383806001019450815181106112ea57fe5b60200101906001600160f81b031916908160001a9053506001016112b8565b50909998505050505050505050565b60608084905060608490506060849050606081518351855101016040519080825280601f01601f19166020018201604052801561135c576020820181803883390190505b5090506000805b85518110156113b45785818151811061137857fe5b602001015160f81c60f81b83838060010194508151811061139557fe5b60200101906001600160f81b031916908160001a905350600101611363565b5060005b8451811015611409578481815181106113cd57fe5b602001015160f81c60f81b8383806001019450815181106113ea57fe5b60200101906001600160f81b031916908160001a9053506001016113b8565b5060005b835181101561145e5783818151811061142257fe5b602001015160f81c60f81b83838060010194508151811061143f57fe5b60200101906001600160f81b031916908160001a90535060010161140d565b50909450505050505b9392505050565b6001600160a01b0381166114945760405162461bcd60e51b81526004016102d690612081565b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b0319166001600160a01b0392909216919091179055565b600081836115105760405162461bcd60e51b81526004016102d69190612060565b50600083858161151c57fe5b0495945050505050565b60608082518451865188518a518c518e510101010101016040519080825280601f01601f191660200182016040528015611567576020820181803883390190505b5090506000805b8a518110156115bf578a818151811061158357fe5b602001015160f81c60f81b8383806001019450815181106115a057fe5b60200101906001600160f81b031916908160001a90535060010161156e565b5060005b8951811015611614578981815181106115d857fe5b602001015160f81c60f81b8383806001019450815181106115f557fe5b60200101906001600160f81b031916908160001a9053506001016115c3565b5060005b88518110156116695788818151811061162d57fe5b602001015160f81c60f81b83838060010194508151811061164a57fe5b60200101906001600160f81b031916908160001a905350600101611618565b5060005b87518110156116be5787818151811061168257fe5b602001015160f81c60f81b83838060010194508151811061169f57fe5b60200101906001600160f81b031916908160001a90535060010161166d565b5060005b8651811015611713578681815181106116d757fe5b602001015160f81c60f81b8383806001019450815181106116f457fe5b60200101906001600160f81b031916908160001a9053506001016116c2565b5060005b85518110156117685785818151811061172c57fe5b602001015160f81c60f81b83838060010194508151811061174957fe5b60200101906001600160f81b031916908160001a905350600101611717565b5060005b84518110156113095784818151811061178157fe5b602001015160f81c60f81b83838060010194508151811061179e57fe5b60200101906001600160f81b031916908160001a90535060010161176c565b600080806117db85610d956127106106dc838963ffffffff610a1f16565b9150915060006117fc6127106106dc60015489610a1f90919063ffffffff16565b90506000611810828463ffffffff610aa416565b90508015611854576002546040516001600160a01b039091169082156108fc029083906000818181858888f19350505050158015611852573d6000803e3d6000fd5b505b509195945050505050565b600080828411156118755750508082038161187c565b5060009050825b9250929050565b8035610a5c8161220a565b8051610a5c8161220a565b600082601f8301126118aa57600080fd5b81516118bd6118b882612126565b6120ff565b915081818352602084019350602081019050838560208402820111156118e257600080fd5b60005b8381101561190e57816118f8888261188e565b84525060209283019291909101906001016118e5565b5050505092915050565b600082601f83011261192957600080fd5b81516119376118b882612126565b9150818183526020840193506020810190508385602084028201111561195c57600080fd5b60005b8381101561190e57816119728882611a53565b845250602092830192919091019060010161195f565b8051610a5c8161221e565b8035610a5c81612227565b600082601f8301126119af57600080fd5b81356119bd6118b882612147565b915080825260208301602083018583830111156119d957600080fd5b6119e48382846121c4565b50505092915050565b8035610a5c81612230565b600060608284031215611a0a57600080fd5b611a1460606120ff565b90506000611a228484611a5e565b8252506020611a3384848301611993565b6020830152506040611a4784828501611993565b60408301525092915050565b8051610a5c81612227565b8035610a5c81612239565b600060208284031215611a7b57600080fd5b60006102aa8484611883565b600060208284031215611a9957600080fd5b60006102aa848461188e565b60008060008060808587031215611abb57600080fd5b6000611ac78787611883565b9450506020611ad887828801611883565b9350506040611ae987828801611993565b925050606085013567ffffffffffffffff811115611b0657600080fd5b611b128782880161199e565b91505092959194509250565b600080600080600060a08688031215611b3657600080fd5b6000611b428888611883565b9550506020611b5388828901611993565b9450506040611b6488828901611993565b9350506060611b7588828901611993565b9250506080611b8688828901611993565b9150509295509295909350565b600060208284031215611ba557600080fd5b815167ffffffffffffffff811115611bbc57600080fd5b6102aa84828501611899565b600060208284031215611bda57600080fd5b815167ffffffffffffffff811115611bf157600080fd5b6102aa84828501611918565b600060208284031215611c0f57600080fd5b60006102aa8484611988565b60008060408385031215611c2e57600080fd5b6000611c3a85856119ed565b9250506020611c4b85828601611993565b9150509250929050565b600080600080600060e08688031215611c6d57600080fd5b6000611c7988886119ed565b9550506020611c8a88828901611993565b9450506040611c9b88828901611993565b9350506060611cac88828901611993565b9250506080611b86888289016119f8565b600060208284031215611ccf57600080fd5b60006102aa8484611993565b600060208284031215611ced57600080fd5b60006102aa8484611a53565b611d02816121b9565b82525050565b611d028161217c565b611d0281612187565b611d028161218c565b611d028161218f565b611d028161219c565b6000611d408261216f565b611d4a8185612173565b9350611d5a8185602086016121d0565b611d6381612200565b9093019392505050565b6000611d7a602d83612173565b7f6d61782062757965722070657263656e746167652063616e2774206265206d6f81526c07265207468616e20313030303609c1b602082015260400192915050565b6000611dc9602683612173565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206181526564647265737360d01b602082015260400192915050565b6000611e11601b83612173565b7f536166654d6174683a206164646974696f6e206f766572666c6f770000000000815260200192915050565b6000611e4a602183612173565b7f6f776e65722073686f756c64207369676e20636f7272656374206d65737361678152606560f81b602082015260400192915050565b6000611e8d602183612173565b7f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f8152607760f81b602082015260400192915050565b6000611ed0602083612173565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572815260200192915050565b6000611f09600c83612173565b6b3737ba1030b71037bbb732b960a11b815260200192915050565b6000611f31601683612173565b751b5cd9cb9d985b1d59481a5cc81a5b98dbdc9c9958dd60521b815260200192915050565b611d02816121b3565b60208101610a5c8284611d08565b60808101611f7b8287611cf9565b611f886020830186611cf9565b611f956040830185611d1a565b6109976060830184611d1a565b60408101611fb08285611d08565b6114676020830184611d1a565b60208101610a5c8284611d11565b60808101611fd98287611d1a565b611f886020830186611f56565b60208101610a5c8284611d23565b60208101610a5c8284611d2c565b608081016120108287611d2c565b61201d6020830186611cf9565b611f956040830185611cf9565b60408101611fb08285611d2c565b606081016120468286611d2c565b6120536020830185611d1a565b6102aa6040830184611d1a565b60208082528101610a598184611d35565b60208082528101610a5c81611d6d565b60208082528101610a5c81611dbc565b60208082528101610a5c81611e04565b60208082528101610a5c81611e3d565b60208082528101610a5c81611e80565b60208082528101610a5c81611ec3565b60208082528101610a5c81611efc565b60208082528101610a5c81611f24565b60208101610a5c8284611d1a565b60405181810167ffffffffffffffff8111828210171561211e57600080fd5b604052919050565b600067ffffffffffffffff82111561213d57600080fd5b5060209081020190565b600067ffffffffffffffff82111561215e57600080fd5b506020601f91909101601f19160190565b5190565b90815260200190565b6000610a5c826121a7565b151590565b90565b6001600160e01b03191690565b6000610a5c8261217c565b6001600160a01b031690565b60ff1690565b6000610a5c8261219c565b82818337506000910152565b60005b838110156121eb5781810151838201526020016121d3565b838111156121fa576000848401525b50505050565b601f01601f191690565b6122138161217c565b81146109cd57600080fd5b61221381612187565b6122138161218c565b6122138161219c565b612213816121b356fea365627a7a723158206e3721fbccd7ecaaefc0adef69f6f3ac0162167a345e19435c599ee81d03136e6c6578706572696d656e74616cf564736f6c634300051000400000000000000000000000005192c67d94d4851bb22c6f9ce0e3d5c7df6928bc000000000000000000000000c1c029457699da42b588da9d91679f7e3d8ab349000000000000000000000000e8637989dfe98c60e26b49b62913ba776ef6ceb7
Deployed Bytecode
0x6080604052600436106100dd5760003560e01c80638da5cb5b1161007f578063a4ddbaa611610059578063a4ddbaa614610221578063b899072e14610234578063f2fde38b14610261578063fa7da19d14610281576100dd565b80638da5cb5b146101ca5780638f32d59b146101df57806398590ef914610201576100dd565b806341a259a6116100bb57806341a259a61461015c5780635de6c42f1461017e5780636e667db3146101a0578063715018a6146101b5576100dd565b8063150b7a02146100e25780631c31f7101461011857806338af3eed1461013a575b600080fd5b3480156100ee57600080fd5b506101026100fd366004611aa5565b6102a1565b60405161010f9190611fe6565b60405180910390f35b34801561012457600080fd5b50610138610133366004611a69565b6102b2565b005b34801561014657600080fd5b5061014f610301565b60405161010f9190611f5f565b34801561016857600080fd5b50610171610310565b60405161010f9190611ff4565b34801561018a57600080fd5b5061019361031f565b60405161010f91906120f1565b3480156101ac57600080fd5b50610171610325565b3480156101c157600080fd5b50610138610334565b3480156101d657600080fd5b5061014f6103a2565b3480156101eb57600080fd5b506101f46103b1565b60405161010f9190611fbd565b34801561020d57600080fd5b5061013861021c366004611c1b565b6103d5565b61013861022f366004611c55565b6105b7565b34801561024057600080fd5b5061025461024f366004611b1e565b6108aa565b60405161010f9190612060565b34801561026d57600080fd5b5061013861027c366004611a69565b6109a0565b34801561028d57600080fd5b5061013861029c366004611cbd565b6109d0565b630a85bd0160e11b5b949350505050565b6102ba6103b1565b6102df5760405162461bcd60e51b81526004016102d6906120c1565b60405180910390fd5b600280546001600160a01b0319166001600160a01b0392909216919091179055565b6002546001600160a01b031681565b6004546001600160a01b031681565b60015481565b6003546001600160a01b031681565b61033c6103b1565b6103585760405162461bcd60e51b81526004016102d6906120c1565b600080546040516001600160a01b03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600080546001600160a01b0319169055565b6000546001600160a01b031690565b600080546001600160a01b03166103c6610a1b565b6001600160a01b031614905090565b6040516331a9108f60e11b81526000906001600160a01b03841690636352211e906104049085906004016120f1565b60206040518083038186803b15801561041c57600080fd5b505afa158015610430573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506104549190810190611a87565b90506001600160a01b038116331461047e5760405162461bcd60e51b81526004016102d6906120d1565b60048054604051638953580360e01b81526000926001600160a01b03909216916389535803916104b291889188910161202a565b60206040518083038186803b1580156104ca57600080fd5b505afa1580156104de573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506105029190810190611cdb565b6004805460405163e330a93560e01b815260019390930193506001600160a01b03169163e330a9359161053b9188918891879101612038565b600060405180830381600087803b15801561055557600080fd5b505af1158015610569573d6000803e3d6000fd5b5050505082846001600160a01b03167fb8b7c5e8b8890227e1f8844a1b6bf94a9061b5ff6f8c75ae7db63926b22be27a84846040516105a9929190611fa2565b60405180910390a350505050565b6040516331a9108f60e11b81526000906001600160a01b03871690636352211e906105e69088906004016120f1565b60206040518083038186803b1580156105fe57600080fd5b505afa158015610612573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506106369190810190611a87565b60048054604051638953580360e01b81529293506000926001600160a01b039091169163895358039161066d918b918b910161202a565b60206040518083038186803b15801561068557600080fd5b505afa158015610699573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506106bd9190810190611cdb565b905060006106e86127106106dc60015489610a1f90919063ffffffff16565b9063ffffffff610a6216565b90506106fa868263ffffffff610aa416565b34146107185760405162461bcd60e51b81526004016102d6906120e1565b606061072789898989876108aa565b9050600061074382876000015188602001518960400151610ac9565b9050806001600160a01b0316856001600160a01b0316146107765760405162461bcd60e51b81526004016102d6906120a1565b600354604051637b84dc8360e11b81526001600160a01b039091169063f709b906906107ac908d90899033908f90600401612002565b600060405180830381600087803b1580156107c657600080fd5b505af11580156107da573d6000803e3d6000fd5b505050506107eb8a8a878b8b610ba6565b6004805460405163e330a93560e01b81526001600160a01b039091169163e330a93591610821918e918e9160018b019101612038565b600060405180830381600087803b15801561083b57600080fd5b505af115801561084f573d6000803e3d6000fd5b50505050888a6001600160a01b03167f7a212d757c7290587e1c8f7100a01a3d09466d58945058b6f22a179013475a9087338c896001016040516108969493929190611f6d565b60405180910390a350505050505050505050565b60608061094a6108c2886001600160a01b0316610e3c565b6040518060400160405280600b81526020016a017103a37b5b2b724b21d160ad1b8152506108ef89610fba565b6040518060400160405280600981526020016801710383934b1b29d160bd1b81525061091a8a610fba565b60405180604001604052806009815260200168017103737b731b29d160bd1b8152506109458a610fba565b611072565b905083156109945761098c60405180604001604052806007815260200166017103332b29d160cd1b81525061097e86610fba565b83919063ffffffff61131816565b915050610997565b90505b95945050505050565b6109a86103b1565b6109c45760405162461bcd60e51b81526004016102d6906120c1565b6109cd8161146e565b50565b6109d86103b1565b6109f45760405162461bcd60e51b81526004016102d6906120c1565b612710811115610a165760405162461bcd60e51b81526004016102d690612071565b600155565b3390565b600082610a2e57506000610a5c565b82820282848281610a3b57fe5b0414610a595760405162461bcd60e51b81526004016102d6906120b1565b90505b92915050565b6000610a5983836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f0000000000008152506114ef565b600082820183811015610a595760405162461bcd60e51b81526004016102d690612091565b600060608590506060610b426040518060400160405280601a81526020017f19457468657265756d205369676e6564204d6573736167653a0a000000000000815250610b158451610fba565b60408051600080825260208201818152828401828152606084019283526080840190945288939091611526565b90506001818051906020012087878760405160008152602001604052604051610b6e9493929190611fcb565b6020604051602081039080840390855afa158015610b90573d6000803e3d6000fd5b5050604051601f19015198975050505050505050565b6000610bb283836117bd565b6040516301ffc9a760e01b81529091506001600160a01b038716906301ffc9a790610be890632dde656160e21b90600401611fe6565b60206040518083038186803b158015610c0057600080fd5b505afa158015610c14573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610c389190810190611bfd565b15610dfd5760405163b9c4d9fb60e01b815286906060906001600160a01b0383169063b9c4d9fb90610c6e908a906004016120f1565b60006040518083038186803b158015610c8657600080fd5b505afa158015610c9a573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610cc29190810190611b93565b90506060826001600160a01b0316630ebd4c7f896040518263ffffffff1660e01b8152600401610cf291906120f1565b60006040518083038186803b158015610d0a57600080fd5b505afa158015610d1e573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610d469190810190611bc8565b90508151815114610d5657600080fd5b60005b8151811015610df857600080610d9a87610d956127106106dc888881518110610d7e57fe5b60200260200101518e610a1f90919063ffffffff16565b61185f565b91509150819650848381518110610dad57fe5b60200260200101516001600160a01b03166108fc829081150290604051600060405180830381858888f19350505050158015610ded573d6000803e3d6000fd5b505050600101610d59565b505050505b6040516001600160a01b0385169082156108fc029083906000818181858888f19350505050158015610e33573d6000803e3d6000fd5b50505050505050565b604080518082018252601081526f181899199a1a9b1b9c1cb0b131b232b360811b60208201528151602a80825260608281019094526001600160a01b03851692918491602082018180388339019050509050600360fc1b81600081518110610ea057fe5b60200101906001600160f81b031916908160001a905350600f60fb1b81600181518110610ec957fe5b60200101906001600160f81b031916908160001a90535060005b6014811015610faf578260048583600c0160208110610efe57fe5b1a60f81b6001600160f81b031916901c60f81c60ff1681518110610f1e57fe5b602001015160f81c60f81b828260020260020181518110610f3b57fe5b60200101906001600160f81b031916908160001a905350828482600c0160208110610f6257fe5b825191901a600f16908110610f7357fe5b602001015160f81c60f81b828260020260030181518110610f9057fe5b60200101906001600160f81b031916908160001a905350600101610ee3565b50925050505b919050565b606081610fdf57506040805180820190915260018152600360fc1b6020820152610fb5565b8160005b8115610ff757600101600a82049150610fe3565b6060816040519080825280601f01601f191660200182016040528015611024576020820181803883390190505b50905060001982015b8515610faf57600a860660300160f81b8282806001900393508151811061105057fe5b60200101906001600160f81b031916908160001a905350600a8604955061102d565b60608082518451865188518a518c518e510101010101016040519080825280601f01601f1916602001820160405280156110b3576020820181803883390190505b5090506000805b8a5181101561110b578a81815181106110cf57fe5b602001015160f81c60f81b8383806001019450815181106110ec57fe5b60200101906001600160f81b031916908160001a9053506001016110ba565b5060005b89518110156111605789818151811061112457fe5b602001015160f81c60f81b83838060010194508151811061114157fe5b60200101906001600160f81b031916908160001a90535060010161110f565b5060005b88518110156111b55788818151811061117957fe5b602001015160f81c60f81b83838060010194508151811061119657fe5b60200101906001600160f81b031916908160001a905350600101611164565b5060005b875181101561120a578781815181106111ce57fe5b602001015160f81c60f81b8383806001019450815181106111eb57fe5b60200101906001600160f81b031916908160001a9053506001016111b9565b5060005b865181101561125f5786818151811061122357fe5b602001015160f81c60f81b83838060010194508151811061124057fe5b60200101906001600160f81b031916908160001a90535060010161120e565b5060005b85518110156112b45785818151811061127857fe5b602001015160f81c60f81b83838060010194508151811061129557fe5b60200101906001600160f81b031916908160001a905350600101611263565b5060005b8451811015611309578481815181106112cd57fe5b602001015160f81c60f81b8383806001019450815181106112ea57fe5b60200101906001600160f81b031916908160001a9053506001016112b8565b50909998505050505050505050565b60608084905060608490506060849050606081518351855101016040519080825280601f01601f19166020018201604052801561135c576020820181803883390190505b5090506000805b85518110156113b45785818151811061137857fe5b602001015160f81c60f81b83838060010194508151811061139557fe5b60200101906001600160f81b031916908160001a905350600101611363565b5060005b8451811015611409578481815181106113cd57fe5b602001015160f81c60f81b8383806001019450815181106113ea57fe5b60200101906001600160f81b031916908160001a9053506001016113b8565b5060005b835181101561145e5783818151811061142257fe5b602001015160f81c60f81b83838060010194508151811061143f57fe5b60200101906001600160f81b031916908160001a90535060010161140d565b50909450505050505b9392505050565b6001600160a01b0381166114945760405162461bcd60e51b81526004016102d690612081565b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b0319166001600160a01b0392909216919091179055565b600081836115105760405162461bcd60e51b81526004016102d69190612060565b50600083858161151c57fe5b0495945050505050565b60608082518451865188518a518c518e510101010101016040519080825280601f01601f191660200182016040528015611567576020820181803883390190505b5090506000805b8a518110156115bf578a818151811061158357fe5b602001015160f81c60f81b8383806001019450815181106115a057fe5b60200101906001600160f81b031916908160001a90535060010161156e565b5060005b8951811015611614578981815181106115d857fe5b602001015160f81c60f81b8383806001019450815181106115f557fe5b60200101906001600160f81b031916908160001a9053506001016115c3565b5060005b88518110156116695788818151811061162d57fe5b602001015160f81c60f81b83838060010194508151811061164a57fe5b60200101906001600160f81b031916908160001a905350600101611618565b5060005b87518110156116be5787818151811061168257fe5b602001015160f81c60f81b83838060010194508151811061169f57fe5b60200101906001600160f81b031916908160001a90535060010161166d565b5060005b8651811015611713578681815181106116d757fe5b602001015160f81c60f81b8383806001019450815181106116f457fe5b60200101906001600160f81b031916908160001a9053506001016116c2565b5060005b85518110156117685785818151811061172c57fe5b602001015160f81c60f81b83838060010194508151811061174957fe5b60200101906001600160f81b031916908160001a905350600101611717565b5060005b84518110156113095784818151811061178157fe5b602001015160f81c60f81b83838060010194508151811061179e57fe5b60200101906001600160f81b031916908160001a90535060010161176c565b600080806117db85610d956127106106dc838963ffffffff610a1f16565b9150915060006117fc6127106106dc60015489610a1f90919063ffffffff16565b90506000611810828463ffffffff610aa416565b90508015611854576002546040516001600160a01b039091169082156108fc029083906000818181858888f19350505050158015611852573d6000803e3d6000fd5b505b509195945050505050565b600080828411156118755750508082038161187c565b5060009050825b9250929050565b8035610a5c8161220a565b8051610a5c8161220a565b600082601f8301126118aa57600080fd5b81516118bd6118b882612126565b6120ff565b915081818352602084019350602081019050838560208402820111156118e257600080fd5b60005b8381101561190e57816118f8888261188e565b84525060209283019291909101906001016118e5565b5050505092915050565b600082601f83011261192957600080fd5b81516119376118b882612126565b9150818183526020840193506020810190508385602084028201111561195c57600080fd5b60005b8381101561190e57816119728882611a53565b845250602092830192919091019060010161195f565b8051610a5c8161221e565b8035610a5c81612227565b600082601f8301126119af57600080fd5b81356119bd6118b882612147565b915080825260208301602083018583830111156119d957600080fd5b6119e48382846121c4565b50505092915050565b8035610a5c81612230565b600060608284031215611a0a57600080fd5b611a1460606120ff565b90506000611a228484611a5e565b8252506020611a3384848301611993565b6020830152506040611a4784828501611993565b60408301525092915050565b8051610a5c81612227565b8035610a5c81612239565b600060208284031215611a7b57600080fd5b60006102aa8484611883565b600060208284031215611a9957600080fd5b60006102aa848461188e565b60008060008060808587031215611abb57600080fd5b6000611ac78787611883565b9450506020611ad887828801611883565b9350506040611ae987828801611993565b925050606085013567ffffffffffffffff811115611b0657600080fd5b611b128782880161199e565b91505092959194509250565b600080600080600060a08688031215611b3657600080fd5b6000611b428888611883565b9550506020611b5388828901611993565b9450506040611b6488828901611993565b9350506060611b7588828901611993565b9250506080611b8688828901611993565b9150509295509295909350565b600060208284031215611ba557600080fd5b815167ffffffffffffffff811115611bbc57600080fd5b6102aa84828501611899565b600060208284031215611bda57600080fd5b815167ffffffffffffffff811115611bf157600080fd5b6102aa84828501611918565b600060208284031215611c0f57600080fd5b60006102aa8484611988565b60008060408385031215611c2e57600080fd5b6000611c3a85856119ed565b9250506020611c4b85828601611993565b9150509250929050565b600080600080600060e08688031215611c6d57600080fd5b6000611c7988886119ed565b9550506020611c8a88828901611993565b9450506040611c9b88828901611993565b9350506060611cac88828901611993565b9250506080611b86888289016119f8565b600060208284031215611ccf57600080fd5b60006102aa8484611993565b600060208284031215611ced57600080fd5b60006102aa8484611a53565b611d02816121b9565b82525050565b611d028161217c565b611d0281612187565b611d028161218c565b611d028161218f565b611d028161219c565b6000611d408261216f565b611d4a8185612173565b9350611d5a8185602086016121d0565b611d6381612200565b9093019392505050565b6000611d7a602d83612173565b7f6d61782062757965722070657263656e746167652063616e2774206265206d6f81526c07265207468616e20313030303609c1b602082015260400192915050565b6000611dc9602683612173565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206181526564647265737360d01b602082015260400192915050565b6000611e11601b83612173565b7f536166654d6174683a206164646974696f6e206f766572666c6f770000000000815260200192915050565b6000611e4a602183612173565b7f6f776e65722073686f756c64207369676e20636f7272656374206d65737361678152606560f81b602082015260400192915050565b6000611e8d602183612173565b7f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f8152607760f81b602082015260400192915050565b6000611ed0602083612173565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572815260200192915050565b6000611f09600c83612173565b6b3737ba1030b71037bbb732b960a11b815260200192915050565b6000611f31601683612173565b751b5cd9cb9d985b1d59481a5cc81a5b98dbdc9c9958dd60521b815260200192915050565b611d02816121b3565b60208101610a5c8284611d08565b60808101611f7b8287611cf9565b611f886020830186611cf9565b611f956040830185611d1a565b6109976060830184611d1a565b60408101611fb08285611d08565b6114676020830184611d1a565b60208101610a5c8284611d11565b60808101611fd98287611d1a565b611f886020830186611f56565b60208101610a5c8284611d23565b60208101610a5c8284611d2c565b608081016120108287611d2c565b61201d6020830186611cf9565b611f956040830185611cf9565b60408101611fb08285611d2c565b606081016120468286611d2c565b6120536020830185611d1a565b6102aa6040830184611d1a565b60208082528101610a598184611d35565b60208082528101610a5c81611d6d565b60208082528101610a5c81611dbc565b60208082528101610a5c81611e04565b60208082528101610a5c81611e3d565b60208082528101610a5c81611e80565b60208082528101610a5c81611ec3565b60208082528101610a5c81611efc565b60208082528101610a5c81611f24565b60208101610a5c8284611d1a565b60405181810167ffffffffffffffff8111828210171561211e57600080fd5b604052919050565b600067ffffffffffffffff82111561213d57600080fd5b5060209081020190565b600067ffffffffffffffff82111561215e57600080fd5b506020601f91909101601f19160190565b5190565b90815260200190565b6000610a5c826121a7565b151590565b90565b6001600160e01b03191690565b6000610a5c8261217c565b6001600160a01b031690565b60ff1690565b6000610a5c8261219c565b82818337506000910152565b60005b838110156121eb5781810151838201526020016121d3565b838111156121fa576000848401525b50505050565b601f01601f191690565b6122138161217c565b81146109cd57600080fd5b61221381612187565b6122138161218c565b6122138161219c565b612213816121b356fea365627a7a723158206e3721fbccd7ecaaefc0adef69f6f3ac0162167a345e19435c599ee81d03136e6c6578706572696d656e74616cf564736f6c63430005100040
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
0000000000000000000000005192c67d94d4851bb22c6f9ce0e3d5c7df6928bc000000000000000000000000c1c029457699da42b588da9d91679f7e3d8ab349000000000000000000000000e8637989dfe98c60e26b49b62913ba776ef6ceb7
-----Decoded View---------------
Arg [0] : _transferProxy (address): 0x5192c67d94D4851BB22C6f9Ce0E3D5c7Df6928bC
Arg [1] : _nonceHolder (address): 0xC1c029457699DA42B588da9D91679f7E3D8AB349
Arg [2] : beneficiary (address): 0xE8637989dFe98c60E26B49b62913Ba776eF6ceb7
-----Encoded View---------------
3 Constructor Arguments found :
Arg [0] : 0000000000000000000000005192c67d94d4851bb22c6f9ce0e3d5c7df6928bc
Arg [1] : 000000000000000000000000c1c029457699da42b588da9d91679f7e3d8ab349
Arg [2] : 000000000000000000000000e8637989dfe98c60e26b49b62913ba776ef6ceb7
Deployed Bytecode Sourcemap
72221:2299:0:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;74370:147;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;74370:147:0;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;57811:116;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;57811:116:0;;;;;;;;:::i;:::-;;57262:34;;8:9:-1;5:2;;;30:1;27;20:12;5:2;57262:34:0;;;:::i;:::-;;;;;;;;72727:40;;8:9:-1;5:2;;;30:1;27;20:12;5:2;72727:40:0;;;:::i;:::-;;;;;;;;57231:24;;8:9:-1;5:2;;;30:1;27;20:12;5:2;57231:24:0;;;:::i;:::-;;;;;;;;72686:34;;8:9:-1;5:2;;;30:1;27;20:12;5:2;72686:34:0;;;:::i;6762:140::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;6762:140:0;;;:::i;5951:79::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;5951:79:0;;;:::i;6317:94::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;6317:94:0;;;:::i;:::-;;;;;;;;73010:349;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;73010:349:0;;;;;;;;:::i;73367:995::-;;;;;;;;;:::i;57935:636::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;57935:636:0;;;;;;;;:::i;:::-;;;;;;;;7057:109;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;7057:109:0;;;;;;;;:::i;57604:199::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;57604:199:0;;;;;;;;:::i;74370:147::-;-1:-1:-1;;;74370:147:0;;;;;;;:::o;57811:116::-;6163:9;:7;:9::i;:::-;6155:54;;;;-1:-1:-1;;;6155:54:0;;;;;;;;;;;;;;;;;57893:11;:26;;-1:-1:-1;;;;;;57893:26:0;-1:-1:-1;;;;;57893:26:0;;;;;;;;;;57811:116::o;57262:34::-;;;-1:-1:-1;;;;;57262:34:0;;:::o;72727:40::-;;;-1:-1:-1;;;;;72727:40:0;;:::o;57231:24::-;;;;:::o;72686:34::-;;;-1:-1:-1;;;;;72686:34:0;;:::o;6762:140::-;6163:9;:7;:9::i;:::-;6155:54;;;;-1:-1:-1;;;6155:54:0;;;;;;;;;6861:1;6845:6;;6824:40;;-1:-1:-1;;;;;6845:6:0;;;;6824:40;;6861:1;;6824:40;6892:1;6875:19;;-1:-1:-1;;;;;;6875:19:0;;;6762:140::o;5951:79::-;5989:7;6016:6;-1:-1:-1;;;;;6016:6:0;5951:79;:::o;6317:94::-;6357:4;6397:6;;-1:-1:-1;;;;;6397:6:0;6381:12;:10;:12::i;:::-;-1:-1:-1;;;;;6381:22:0;;6374:29;;6317:94;:::o;73010:349::-;73092:22;;-1:-1:-1;;;73092:22:0;;73076:13;;-1:-1:-1;;;;;73092:13:0;;;;;:22;;73106:7;;73092:22;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;73092:22:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;73092:22:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;73092:22:0;;;;;;;;;73076:38;-1:-1:-1;;;;;;73133:19:0;;73142:10;73133:19;73125:44;;;;-1:-1:-1;;;73125:44:0;;;;;;;;;73196:11;;;:36;;-1:-1:-1;;;73196:36:0;;73180:13;;-1:-1:-1;;;;;73196:11:0;;;;:20;;:36;;73217:5;;73224:7;;73196:36;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;73196:36:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;73196:36:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;73196:36:0;;;;;;;;;73247:11;;;:43;;-1:-1:-1;;;73247:43:0;;73235:1;73196:40;;;;;-1:-1:-1;;;;;;73247:11:0;;:20;;:43;;73268:5;;73275:7;;73196:40;;73247:43;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;73247:43:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;73247:43:0;;;;73329:7;73321:5;-1:-1:-1;;;;;73306:45:0;;73338:5;73345;73306:45;;;;;;;;;;;;;;;;73010:349;;;;:::o;73367:995::-;73534:22;;-1:-1:-1;;;73534:22:0;;73494:21;;-1:-1:-1;;;;;73534:13:0;;;;;:22;;73548:7;;73534:22;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;73534:22:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;73534:22:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;73534:22:0;;;;;;;;;73585:11;;;:36;;-1:-1:-1;;;73585:36:0;;73494:64;;-1:-1:-1;73569:13:0;;-1:-1:-1;;;;;73585:11:0;;;;:20;;:36;;73606:5;;73613:7;;73585:36;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;73585:36:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;73585:36:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;73585:36:0;;;;;;;;;73569:52;;73632:21;73656:46;72448:5;73656:19;73666:8;;73656:5;:9;;:19;;;;:::i;:::-;:23;:46;:23;:46;:::i;:::-;73632:70;-1:-1:-1;73734:24:0;:5;73632:70;73734:24;:9;:24;:::i;:::-;73721:9;:37;73713:73;;;;-1:-1:-1;;;73713:73:0;;;;;;;;;73797:27;73827:64;73850:5;73858:7;73867:5;73874:9;73885:5;73827:14;:64::i;:::-;73797:94;;73902:15;73920:75;73942:13;73957:9;:11;;;73970:9;:11;;;73983:9;:11;;;73920:21;:75::i;:::-;73902:93;;74023:7;-1:-1:-1;;;;;74014:16:0;:5;-1:-1:-1;;;;;74014:16:0;;74006:62;;;;-1:-1:-1;;;74006:62:0;;;;;;;;;74079:13;;:71;;-1:-1:-1;;;74079:71:0;;-1:-1:-1;;;;;74079:13:0;;;;:36;;:71;;74116:5;;74123;;74130:10;;74142:7;;74079:71;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;74079:71:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;74079:71:0;;;;74161:54;74175:5;74182:7;74191:5;74198;74205:9;74161:13;:54::i;:::-;74226:11;;;:47;;-1:-1:-1;;;74226:47:0;;-1:-1:-1;;;;;74226:11:0;;;;:20;;:47;;74247:5;;74254:7;;74226:11;74263:9;;;74226:47;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;74226:47:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;74226:47:0;;;;74309:7;74301:5;-1:-1:-1;;;;;74289:65:0;;74318:5;74325:10;74337:5;74344;74352:1;74344:9;74289:65;;;;;;;;;;;;;;;;;;73367:995;;;;;;;;;;:::o;57935:636::-;58055:13;58081:20;58111:307;58145:16;:5;-1:-1:-1;;;;;58145:14:0;;:16::i;:::-;58181:20;;;;;;;;;;;;;-1:-1:-1;;;58181:20:0;;;58226:18;:7;:16;:18::i;:::-;58264;;;;;;;;;;;;;-1:-1:-1;;;58264:18:0;;;58307:16;:5;:14;:16::i;:::-;58343:18;;;;;;;;;;;;;-1:-1:-1;;;58343:18:0;;;58386:16;:5;:14;:16::i;:::-;58111:9;:307::i;:::-;58081:338;-1:-1:-1;58434:8:0;;58430:134;;58466:40;;;;;;;;;;;;;;-1:-1:-1;;;58466:40:0;;;58491:14;:3;:12;:14::i;:::-;58466:6;;:40;;:13;:40;:::i;:::-;58459:47;;;;;58430:134;58546:6;-1:-1:-1;57935:636:0;;;;;;;;:::o;7057:109::-;6163:9;:7;:9::i;:::-;6155:54;;;;-1:-1:-1;;;6155:54:0;;;;;;;;;7130:28;7149:8;7130:18;:28::i;:::-;7057:109;:::o;57604:199::-;6163:9;:7;:9::i;:::-;6155:54;;;;-1:-1:-1;;;6155:54:0;;;;;;;;;57216:5;57680:9;:34;;57672:92;;;;-1:-1:-1;;;57672:92:0;;;;;;;;;57775:8;:20;57604:199::o;4742:98::-;4822:10;4742:98;:::o;10095:471::-;10153:7;10398:6;10394:47;;-1:-1:-1;10428:1:0;10421:8;;10394:47;10465:5;;;10469:1;10465;:5;:1;10489:5;;;;;:10;10481:56;;;;-1:-1:-1;;;10481:56:0;;;;;;;;;10557:1;-1:-1:-1;10095:471:0;;;;;:::o;11034:132::-;11092:7;11119:39;11123:1;11126;11119:39;;;;;;;;;;;;;;;;;:3;:39::i;8723:181::-;8781:7;8813:5;;;8837:6;;;;8829:46;;;;-1:-1:-1;;;8829:46:0;;;;;;;;46597:469;46691:7;46711:21;46741:7;46711:38;;46760:24;46787:211;46808:39;;;;;;;;;;;;;;;;;46868:26;:8;:15;:24;:26::i;:::-;46933:12;;;46943:1;46933:12;;;;;;46947;;;;;;46961;;;;;;46975;;;;;;;;;46910:8;;46933:12;;46787:6;:211::i;:::-;46760:238;;47016:42;47036:11;47026:22;;;;;;47050:1;47053;47056;47016:42;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;-1:-1;;47016:42:0;;-1:-1:-1;;47016:42:0;;;46597:469;-1:-1:-1;;;;;;;;46597:469:0:o;59482:855::-;59614:10;59627:42;59652:5;59659:9;59627:24;:42::i;:::-;59684:43;;-1:-1:-1;;;59684:43:0;;59614:55;;-1:-1:-1;;;;;;59684:23:0;;;;;:43;;-1:-1:-1;;;59708:18:0;59684:43;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;59684:43:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;59684:43:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;59684:43:0;;;;;;;;;59680:618;;;59865:34;;-1:-1:-1;;;59865:34:0;;59805:5;;59827:35;;-1:-1:-1;;;;;59865:25:0;;;;;:34;;59891:7;;59865:34;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;59865:34:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;59865:34:0;;;;;;39:16:-1;36:1;17:17;2:54;101:4;59865:34:0;80:15:-1;;;-1:-1;;76:31;65:43;;120:4;113:20;59865:34:0;;;;;;;;;59827:72;;59914:18;59935:8;-1:-1:-1;;;;;59935:18:0;;59954:7;59935:27;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;59935:27:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;59935:27:0;;;;;;39:16:-1;36:1;17:17;2:54;101:4;59935:27:0;80:15:-1;;;-1:-1;;76:31;65:43;;120:4;113:20;59935:27:0;;;;;;;;;59914:48;;60000:10;:17;59985:4;:11;:32;59977:41;;;;;;60038:9;60033:254;60057:4;:11;60053:1;:15;60033:254;;;60095:13;60110:12;60126:60;60133:5;60140:45;57216:5;60140:18;60150:4;60155:1;60150:7;;;;;;;;;;;;;;60140:5;:9;;:18;;;;:::i;:45::-;60126:6;:60::i;:::-;60094:92;;;;60213:8;60205:16;;60240:10;60251:1;60240:13;;;;;;;;;;;;;;-1:-1:-1;;;;;60240:22:0;:31;60263:7;60240:31;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;-1:-1;;;60070:3:0;;60033:254;;;;59680:618;;;;60308:21;;-1:-1:-1;;;;;60308:14:0;;;:21;;;;;60323:5;;60308:21;;;;60323:5;60308:14;:21;;;;;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;60308:21:0;59482:855;;;;;;:::o;56431:483::-;56563:42;;;;;;;;;;;-1:-1:-1;;;56563:42:0;;;;56635:13;;56645:2;56635:13;;;56487;56635;;;;;;-1:-1:-1;;;;;56537:14:0;;;56563:42;56487:13;;56635;;;21:6:-1;;104:10;56635:13:0;87:34:-1;135:17;;-1:-1;56635:13:0;56616:32;;-1:-1:-1;;;56659:3:0;56663:1;56659:6;;;;;;;;;;;:12;-1:-1:-1;;;;;56659:12:0;;;;;;;;;-1:-1:-1;;;56682:3:0;56686:1;56682:6;;;;;;;;;;;:12;-1:-1:-1;;;;;56682:12:0;;;;;;;;-1:-1:-1;56710:9:0;56705:173;56729:2;56725:1;:6;56705:173;;;56766:8;56798:1;56781:5;56787:1;56791:2;56787:6;56781:13;;;;;;;;;;-1:-1:-1;;;;;56781:18:0;;;;56775:25;;56766:35;;;;;;;;;;;;;;;;;;56753:3;56759:1;56761;56759:3;56757:1;:5;56753:10;;;;;;;;;;;:48;-1:-1:-1;;;;;56753:48:0;;;;;;;;;56829:8;56844:5;56850:1;56854:2;56850:6;56844:13;;;;;;;56829:37;;56844:13;;;56860:4;56838:27;;56829:37;;;;;;;;;;;;;;56816:3;56822:1;56824;56822:3;56820:1;:5;56816:10;;;;;;;;;;;:50;-1:-1:-1;;;;;56816:50:0;;;;;;;;-1:-1:-1;56733:3:0;;56705:173;;;-1:-1:-1;56902:3:0;-1:-1:-1;;;56431:483:0;;;;:::o;45056:471::-;45109:13;45139:7;45135:50;;-1:-1:-1;45163:10:0;;;;;;;;;;;;-1:-1:-1;;;45163:10:0;;;;;;45135:50;45204:2;45195:6;45236:69;45243:6;;45236:69;;45266:5;;45291:2;45286:7;;;;45236:69;;;45315:17;45345:3;45335:14;;;;;;;;;;;;;;;;;;;;;;;;;21:6:-1;;104:10;45335:14:0;87:34:-1;135:17;;-1:-1;45335:14:0;-1:-1:-1;45315:34:0;-1:-1:-1;;;45369:7:0;;45387:103;45394:7;;45387:103;;45451:2;45446;:7;45441:2;:12;45430:25;;45418:4;45423:3;;;;;;;45418:9;;;;;;;;;;;:37;-1:-1:-1;;;;;45418:37:0;;;;;;;;-1:-1:-1;45476:2:0;45470:8;;;;45387:103;;58579:895;58747:12;58772:24;58887:3;:10;58874:3;:10;58861:3;:10;58848:3;:10;58835:3;:10;58822:3;:10;58809:3;:10;:23;:36;:49;:62;:75;:88;58799:99;;;;;;;;;;;;;;;;;;;;;;;;;21:6:-1;;104:10;58799:99:0;87:34:-1;135:17;;-1:-1;58799:99:0;-1:-1:-1;58772:126:0;-1:-1:-1;58909:6:0;;58930:63;58951:3;:10;58947:1;:14;58930:63;;;58987:3;58991:1;58987:6;;;;;;;;;;;;;;;;58968:11;58980:3;;;;;;58968:16;;;;;;;;;;;:25;-1:-1:-1;;;;;58968:25:0;;;;;;;;-1:-1:-1;58963:3:0;;58930:63;;;-1:-1:-1;59009:6:0;59004:63;59025:3;:10;59021:1;:14;59004:63;;;59061:3;59065:1;59061:6;;;;;;;;;;;;;;;;59042:11;59054:3;;;;;;59042:16;;;;;;;;;;;:25;-1:-1:-1;;;;;59042:25:0;;;;;;;;-1:-1:-1;59037:3:0;;59004:63;;;-1:-1:-1;59083:6:0;59078:63;59099:3;:10;59095:1;:14;59078:63;;;59135:3;59139:1;59135:6;;;;;;;;;;;;;;;;59116:11;59128:3;;;;;;59116:16;;;;;;;;;;;:25;-1:-1:-1;;;;;59116:25:0;;;;;;;;-1:-1:-1;59111:3:0;;59078:63;;;-1:-1:-1;59157:6:0;59152:63;59173:3;:10;59169:1;:14;59152:63;;;59209:3;59213:1;59209:6;;;;;;;;;;;;;;;;59190:11;59202:3;;;;;;59190:16;;;;;;;;;;;:25;-1:-1:-1;;;;;59190:25:0;;;;;;;;-1:-1:-1;59185:3:0;;59152:63;;;-1:-1:-1;59231:6:0;59226:63;59247:3;:10;59243:1;:14;59226:63;;;59283:3;59287:1;59283:6;;;;;;;;;;;;;;;;59264:11;59276:3;;;;;;59264:16;;;;;;;;;;;:25;-1:-1:-1;;;;;59264:25:0;;;;;;;;-1:-1:-1;59259:3:0;;59226:63;;;-1:-1:-1;59305:6:0;59300:63;59321:3;:10;59317:1;:14;59300:63;;;59357:3;59361:1;59357:6;;;;;;;;;;;;;;;;59338:11;59350:3;;;;;;59338:16;;;;;;;;;;;:25;-1:-1:-1;;;;;59338:25:0;;;;;;;;-1:-1:-1;59333:3:0;;59300:63;;;-1:-1:-1;59379:6:0;59374:63;59395:3;:10;59391:1;:14;59374:63;;;59431:3;59435:1;59431:6;;;;;;;;;;;;;;;;59412:11;59424:3;;;;;;59412:16;;;;;;;;;;;:25;-1:-1:-1;;;;;59412:25:0;;;;;;;;-1:-1:-1;59407:3:0;;59374:63;;;-1:-1:-1;59455:11:0;;58579:895;-1:-1:-1;;;;;;;;;58579:895:0:o;46031:558::-;46124:13;46150:16;46175:2;46150:28;;46189:16;46214:2;46189:28;;46228:16;46253:2;46228:28;;46267:16;46322:3;:10;46309:3;:10;46296:3;:10;:23;:36;46286:47;;;;;;;;;;;;;;;;;;;;;;;;;21:6:-1;;104:10;46286:47:0;87:34:-1;135:17;;-1:-1;46286:47:0;-1:-1:-1;46267:66:0;-1:-1:-1;46344:6:0;;46365:55;46386:3;:10;46382:1;:14;46365:55;;;46414:3;46418:1;46414:6;;;;;;;;;;;;;;;;46403:3;46407;;;;;;46403:8;;;;;;;;;;;:17;-1:-1:-1;;;;;46403:17:0;;;;;;;;-1:-1:-1;46398:3:0;;46365:55;;;-1:-1:-1;46436:6:0;46431:55;46452:3;:10;46448:1;:14;46431:55;;;46480:3;46484:1;46480:6;;;;;;;;;;;;;;;;46469:3;46473;;;;;;46469:8;;;;;;;;;;;:17;-1:-1:-1;;;;;46469:17:0;;;;;;;;-1:-1:-1;46464:3:0;;46431:55;;;-1:-1:-1;46502:6:0;46497:55;46518:3;:10;46514:1;:14;46497:55;;;46546:3;46550:1;46546:6;;;;;;;;;;;;;;;;46535:3;46539;;;;;;46535:8;;;;;;;;;;;:17;-1:-1:-1;;;;;46535:17:0;;;;;;;;-1:-1:-1;46530:3:0;;46497:55;;;-1:-1:-1;46577:3:0;;-1:-1:-1;;;;;46031:558:0;;;;;;:::o;7272:229::-;-1:-1:-1;;;;;7346:22:0;;7338:73;;;;-1:-1:-1;;;7338:73:0;;;;;;;;;7448:6;;;7427:38;;-1:-1:-1;;;;;7427:38:0;;;;7448:6;;;7427:38;;;7476:6;:17;;-1:-1:-1;;;;;;7476:17:0;-1:-1:-1;;;;;7476:17:0;;;;;;;;;;7272:229::o;11696:345::-;11782:7;11884:12;11877:5;11869:28;;;;-1:-1:-1;;;11869:28:0;;;;;;;;;;;11908:9;11924:1;11920;:5;;;;;;;11696:345;-1:-1:-1;;;;;11696:345:0:o;47560:892::-;47725:12;47750:24;47865:3;:10;47852:3;:10;47839:3;:10;47826:3;:10;47813:3;:10;47800:3;:10;47787:3;:10;:23;:36;:49;:62;:75;:88;47777:99;;;;;;;;;;;;;;;;;;;;;;;;;21:6:-1;;104:10;47777:99:0;87:34:-1;135:17;;-1:-1;47777:99:0;-1:-1:-1;47750:126:0;-1:-1:-1;47887:6:0;;47908:63;47929:3;:10;47925:1;:14;47908:63;;;47965:3;47969:1;47965:6;;;;;;;;;;;;;;;;47946:11;47958:3;;;;;;47946:16;;;;;;;;;;;:25;-1:-1:-1;;;;;47946:25:0;;;;;;;;-1:-1:-1;47941:3:0;;47908:63;;;-1:-1:-1;47987:6:0;47982:63;48003:3;:10;47999:1;:14;47982:63;;;48039:3;48043:1;48039:6;;;;;;;;;;;;;;;;48020:11;48032:3;;;;;;48020:16;;;;;;;;;;;:25;-1:-1:-1;;;;;48020:25:0;;;;;;;;-1:-1:-1;48015:3:0;;47982:63;;;-1:-1:-1;48061:6:0;48056:63;48077:3;:10;48073:1;:14;48056:63;;;48113:3;48117:1;48113:6;;;;;;;;;;;;;;;;48094:11;48106:3;;;;;;48094:16;;;;;;;;;;;:25;-1:-1:-1;;;;;48094:25:0;;;;;;;;-1:-1:-1;48089:3:0;;48056:63;;;-1:-1:-1;48135:6:0;48130:63;48151:3;:10;48147:1;:14;48130:63;;;48187:3;48191:1;48187:6;;;;;;;;;;;;;;;;48168:11;48180:3;;;;;;48168:16;;;;;;;;;;;:25;-1:-1:-1;;;;;48168:25:0;;;;;;;;-1:-1:-1;48163:3:0;;48130:63;;;-1:-1:-1;48209:6:0;48204:63;48225:3;:10;48221:1;:14;48204:63;;;48261:3;48265:1;48261:6;;;;;;;;;;;;;;;;48242:11;48254:3;;;;;;48242:16;;;;;;;;;;;:25;-1:-1:-1;;;;;48242:25:0;;;;;;;;-1:-1:-1;48237:3:0;;48204:63;;;-1:-1:-1;48283:6:0;48278:63;48299:3;:10;48295:1;:14;48278:63;;;48335:3;48339:1;48335:6;;;;;;;;;;;;;;;;48316:11;48328:3;;;;;;48316:16;;;;;;;;;;;:25;-1:-1:-1;;;;;48316:25:0;;;;;;;;-1:-1:-1;48311:3:0;;48278:63;;;-1:-1:-1;48357:6:0;48352:63;48373:3;:10;48369:1;:14;48352:63;;;48409:3;48413:1;48409:6;;;;;;;;;;;;;;;;48390:11;48402:3;;;;;;48390:16;;;;;;;;;;;:25;-1:-1:-1;;;;;48390:25:0;;;;;;;;-1:-1:-1;48385:3:0;;48352:63;;60345:467;60425:4;;;60478:62;60485:5;60492:47;57216:5;60492:20;60485:5;60502:9;60492:20;:9;:20;:::i;60478:62::-;60442:98;;;;60551:18;60572:46;57216:5;60572:19;60582:8;;60572:5;:9;;:19;;;;:::i;:46::-;60551:67;-1:-1:-1;60629:19:0;60651:33;60551:67;60669:14;60651:33;:17;:33;:::i;:::-;60629:55;-1:-1:-1;60699:18:0;;60695:87;;60734:11;;:36;;-1:-1:-1;;;;;60734:11:0;;;;:36;;;;;60755:14;;60734:11;:36;:11;:36;60755:14;60734:11;:36;;;;;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;60734:36:0;60695:87;-1:-1:-1;60799:5:0;;60345:467;-1:-1:-1;;;;;60345:467:0:o;60820:277::-;60881:13;60896:12;60933:3;60925:5;:11;60921:169;;;-1:-1:-1;;60964:11:0;;;60972:3;60921:169;;;-1:-1:-1;61047:1:0;;-1:-1:-1;61073:5:0;60921:169;60820:277;;;;;:::o;5:130:-1:-;72:20;;97:33;72:20;97:33;;142:134;220:13;;238:33;220:13;238:33;;619:746;;755:3;748:4;740:6;736:17;732:27;722:2;;773:1;770;763:12;722:2;803:6;797:13;825:88;840:72;905:6;840:72;;;825:88;;;816:97;;930:5;955:6;948:5;941:21;985:4;977:6;973:17;963:27;;1007:4;1002:3;998:14;991:21;;1060:6;1107:3;1099:4;1091:6;1087:17;1082:3;1078:27;1075:36;1072:2;;;1124:1;1121;1114:12;1072:2;1149:1;1134:225;1159:6;1156:1;1153:13;1134:225;;;1217:3;1239:56;1291:3;1279:10;1239:56;;;1227:69;;-1:-1;1319:4;1310:14;;;;1338;;;;;1181:1;1174:9;1134:225;;;1138:14;715:650;;;;;;;;1391:722;;1519:3;1512:4;1504:6;1500:17;1496:27;1486:2;;1537:1;1534;1527:12;1486:2;1567:6;1561:13;1589:80;1604:64;1661:6;1604:64;;1589:80;1580:89;;1686:5;1711:6;1704:5;1697:21;1741:4;1733:6;1729:17;1719:27;;1763:4;1758:3;1754:14;1747:21;;1816:6;1863:3;1855:4;1847:6;1843:17;1838:3;1834:27;1831:36;1828:2;;;1880:1;1877;1870:12;1828:2;1905:1;1890:217;1915:6;1912:1;1909:13;1890:217;;;1973:3;1995:48;2039:3;2027:10;1995:48;;;1983:61;;-1:-1;2067:4;2058:14;;;;2086;;;;;1937:1;1930:9;1890:217;;2121:128;2196:13;;2214:30;2196:13;2214:30;;2256:130;2323:20;;2348:33;2323:20;2348:33;;2394:440;;2495:3;2488:4;2480:6;2476:17;2472:27;2462:2;;2513:1;2510;2503:12;2462:2;2550:6;2537:20;2572:64;2587:48;2628:6;2587:48;;2572:64;2563:73;;2656:6;2649:5;2642:21;2692:4;2684:6;2680:17;2725:4;2718:5;2714:16;2760:3;2751:6;2746:3;2742:16;2739:25;2736:2;;;2777:1;2774;2767:12;2736:2;2787:41;2821:6;2816:3;2811;2787:41;;;2455:379;;;;;;;;2842:160;2924:20;;2949:48;2924:20;2949:48;;3039:596;;3149:4;3137:9;3132:3;3128:19;3124:30;3121:2;;;3167:1;3164;3157:12;3121:2;3185:20;3200:4;3185:20;;;3176:29;-1:-1;3252:1;3284:47;3327:3;3307:9;3284:47;;;3259:73;;-1:-1;3390:2;3423:49;3468:3;3444:22;;;3423:49;;;3416:4;3409:5;3405:16;3398:75;3353:131;3531:2;3564:49;3609:3;3600:6;3589:9;3585:22;3564:49;;;3557:4;3550:5;3546:16;3539:75;3494:131;3115:520;;;;;3779:134;3857:13;;3875:33;3857:13;3875:33;;3920:126;3985:20;;4010:31;3985:20;4010:31;;4053:241;;4157:2;4145:9;4136:7;4132:23;4128:32;4125:2;;;4173:1;4170;4163:12;4125:2;4208:1;4225:53;4270:7;4250:9;4225:53;;4301:263;;4416:2;4404:9;4395:7;4391:23;4387:32;4384:2;;;4432:1;4429;4422:12;4384:2;4467:1;4484:64;4540:7;4520:9;4484:64;;4835:721;;;;;4999:3;4987:9;4978:7;4974:23;4970:33;4967:2;;;5016:1;5013;5006:12;4967:2;5051:1;5068:53;5113:7;5093:9;5068:53;;;5058:63;;5030:97;5158:2;5176:53;5221:7;5212:6;5201:9;5197:22;5176:53;;;5166:63;;5137:98;5266:2;5284:53;5329:7;5320:6;5309:9;5305:22;5284:53;;;5274:63;;5245:98;5402:2;5391:9;5387:18;5374:32;5426:18;5418:6;5415:30;5412:2;;;5458:1;5455;5448:12;5412:2;5478:62;5532:7;5523:6;5512:9;5508:22;5478:62;;;5468:72;;5353:193;4961:595;;;;;;;;5563:743;;;;;;5735:3;5723:9;5714:7;5710:23;5706:33;5703:2;;;5752:1;5749;5742:12;5703:2;5787:1;5804:53;5849:7;5829:9;5804:53;;;5794:63;;5766:97;5894:2;5912:53;5957:7;5948:6;5937:9;5933:22;5912:53;;;5902:63;;5873:98;6002:2;6020:53;6065:7;6056:6;6045:9;6041:22;6020:53;;;6010:63;;5981:98;6110:2;6128:53;6173:7;6164:6;6153:9;6149:22;6128:53;;;6118:63;;6089:98;6218:3;6237:53;6282:7;6273:6;6262:9;6258:22;6237:53;;;6227:63;;6197:99;5697:609;;;;;;;;;6313:408;;6461:2;6449:9;6440:7;6436:23;6432:32;6429:2;;;6477:1;6474;6467:12;6429:2;6512:24;;6556:18;6545:30;;6542:2;;;6588:1;6585;6578:12;6542:2;6608:97;6697:7;6688:6;6677:9;6673:22;6608:97;;6728:392;;6868:2;6856:9;6847:7;6843:23;6839:32;6836:2;;;6884:1;6881;6874:12;6836:2;6919:24;;6963:18;6952:30;;6949:2;;;6995:1;6992;6985:12;6949:2;7015:89;7096:7;7087:6;7076:9;7072:22;7015:89;;7127:257;;7239:2;7227:9;7218:7;7214:23;7210:32;7207:2;;;7255:1;7252;7245:12;7207:2;7290:1;7307:61;7360:7;7340:9;7307:61;;7391:396;;;7527:2;7515:9;7506:7;7502:23;7498:32;7495:2;;;7543:1;7540;7533:12;7495:2;7578:1;7595:68;7655:7;7635:9;7595:68;;;7585:78;;7557:112;7700:2;7718:53;7763:7;7754:6;7743:9;7739:22;7718:53;;;7708:63;;7679:98;7489:298;;;;;;7794:815;;;;;;8002:3;7990:9;7981:7;7977:23;7973:33;7970:2;;;8019:1;8016;8009:12;7970:2;8054:1;8071:68;8131:7;8111:9;8071:68;;;8061:78;;8033:112;8176:2;8194:53;8239:7;8230:6;8219:9;8215:22;8194:53;;;8184:63;;8155:98;8284:2;8302:53;8347:7;8338:6;8327:9;8323:22;8302:53;;;8292:63;;8263:98;8392:2;8410:53;8455:7;8446:6;8435:9;8431:22;8410:53;;;8400:63;;8371:98;8500:3;8519:74;8585:7;8576:6;8565:9;8561:22;8519:74;;8616:241;;8720:2;8708:9;8699:7;8695:23;8691:32;8688:2;;;8736:1;8733;8726:12;8688:2;8771:1;8788:53;8833:7;8813:9;8788:53;;8864:263;;8979:2;8967:9;8958:7;8954:23;8950:32;8947:2;;;8995:1;8992;8985:12;8947:2;9030:1;9047:64;9103:7;9083:9;9047:64;;9134:142;9225:45;9264:5;9225:45;;;9220:3;9213:58;9207:69;;;9283:137;9382:32;9408:5;9382:32;;9547:104;9624:21;9639:5;9624:21;;9658:113;9741:24;9759:5;9741:24;;9778:110;9859:23;9876:5;9859:23;;9895:186;10008:67;10069:5;10008:67;;10428:347;;10540:39;10573:5;10540:39;;;10591:71;10655:6;10650:3;10591:71;;;10584:78;;10667:52;10712:6;10707:3;10700:4;10693:5;10689:16;10667:52;;;10740:29;10762:6;10740:29;;;10731:39;;;;10520:255;-1:-1;;;10520:255;10783:382;;10943:67;11007:2;11002:3;10943:67;;;11043:34;11023:55;;-1:-1;;;11107:2;11098:12;;11091:37;11156:2;11147:12;;10929:236;-1:-1;;10929:236;11174:375;;11334:67;11398:2;11393:3;11334:67;;;11434:34;11414:55;;-1:-1;;;11498:2;11489:12;;11482:30;11540:2;11531:12;;11320:229;-1:-1;;11320:229;11558:327;;11718:67;11782:2;11777:3;11718:67;;;11818:29;11798:50;;11876:2;11867:12;;11704:181;-1:-1;;11704:181;11894:370;;12054:67;12118:2;12113:3;12054:67;;;12154:34;12134:55;;-1:-1;;;12218:2;12209:12;;12202:25;12255:2;12246:12;;12040:224;-1:-1;;12040:224;12273:370;;12433:67;12497:2;12492:3;12433:67;;;12533:34;12513:55;;-1:-1;;;12597:2;12588:12;;12581:25;12634:2;12625:12;;12419:224;-1:-1;;12419:224;12652:332;;12812:67;12876:2;12871:3;12812:67;;;12912:34;12892:55;;12975:2;12966:12;;12798:186;-1:-1;;12798:186;12993:312;;13153:67;13217:2;13212:3;13153:67;;;-1:-1;;;13233:35;;13296:2;13287:12;;13139:166;-1:-1;;13139:166;13314:322;;13474:67;13538:2;13533:3;13474:67;;;-1:-1;;;13554:45;;13627:2;13618:12;;13460:176;-1:-1;;13460:176;13764:107;13843:22;13859:5;13843:22;;13878:213;13996:2;13981:18;;14010:71;13985:9;14054:6;14010:71;;14350:579;14568:3;14553:19;;14583:79;14557:9;14635:6;14583:79;;;14673:80;14749:2;14738:9;14734:18;14725:6;14673:80;;;14764:72;14832:2;14821:9;14817:18;14808:6;14764:72;;;14847;14915:2;14904:9;14900:18;14891:6;14847:72;;14936:324;15082:2;15067:18;;15096:71;15071:9;15140:6;15096:71;;;15178:72;15246:2;15235:9;15231:18;15222:6;15178:72;;15267:201;15379:2;15364:18;;15393:65;15368:9;15431:6;15393:65;;15475:539;15673:3;15658:19;;15688:71;15662:9;15732:6;15688:71;;;15770:68;15834:2;15823:9;15819:18;15810:6;15770:68;;16021:209;16137:2;16122:18;;16151:69;16126:9;16193:6;16151:69;;16237:273;16385:2;16370:18;;16399:101;16374:9;16473:6;16399:101;;16517:609;16750:3;16735:19;;16765:86;16739:9;16824:6;16765:86;;;16862:80;16938:2;16927:9;16923:18;16914:6;16862:80;;;16953;17029:2;17018:9;17014:18;17005:6;16953:80;;17133:354;17294:2;17279:18;;17308:86;17283:9;17367:6;17308:86;;17494:465;17683:2;17668:18;;17697:86;17672:9;17756:6;17697:86;;;17794:72;17862:2;17851:9;17847:18;17838:6;17794:72;;;17877;17945:2;17934:9;17930:18;17921:6;17877:72;;18230:301;18368:2;18382:47;;;18353:18;;18443:78;18353:18;18507:6;18443:78;;18538:407;18729:2;18743:47;;;18714:18;;18804:131;18714:18;18804:131;;18952:407;19143:2;19157:47;;;19128:18;;19218:131;19128:18;19218:131;;19366:407;19557:2;19571:47;;;19542:18;;19632:131;19542:18;19632:131;;19780:407;19971:2;19985:47;;;19956:18;;20046:131;19956:18;20046:131;;20194:407;20385:2;20399:47;;;20370:18;;20460:131;20370:18;20460:131;;20608:407;20799:2;20813:47;;;20784:18;;20874:131;20784:18;20874:131;;21022:407;21213:2;21227:47;;;21198:18;;21288:131;21198:18;21288:131;;21436:407;21627:2;21641:47;;;21612:18;;21702:131;21612:18;21702:131;;21850:213;21968:2;21953:18;;21982:71;21957:9;22026:6;21982:71;;22070:256;22132:2;22126:9;22158:17;;;22233:18;22218:34;;22254:22;;;22215:62;22212:2;;;22290:1;22287;22280:12;22212:2;22306;22299:22;22110:216;;-1:-1;22110:216;22333:312;;22500:18;22492:6;22489:30;22486:2;;;22532:1;22529;22522:12;22486:2;-1:-1;22567:4;22555:17;;;22620:15;;22423:222;22963:321;;23106:18;23098:6;23095:30;23092:2;;;23138:1;23135;23128:12;23092:2;-1:-1;23269:4;23205;23182:17;;;;-1:-1;;23178:33;23259:15;;23029:255;23291:122;23379:12;;23350:63;23421:163;23524:19;;;23573:4;23564:14;;23517:67;23592:91;;23654:24;23672:5;23654:24;;23796:85;23862:13;23855:21;;23838:43;23888:72;23950:5;23933:27;23967:144;-1:-1;;;;;;24028:78;;24011:100;24118:106;;24195:24;24213:5;24195:24;;24231:121;-1:-1;;;;;24293:54;;24276:76;24438:81;24509:4;24498:16;;24481:38;24526:129;;24613:37;24644:5;24613:37;;25836:145;25917:6;25912:3;25907;25894:30;-1:-1;25973:1;25955:16;;25948:27;25887:94;25990:268;26055:1;26062:101;26076:6;26073:1;26070:13;26062:101;;;26143:11;;;26137:18;26124:11;;;26117:39;26098:2;26091:10;26062:101;;;26178:6;26175:1;26172:13;26169:2;;;26243:1;26234:6;26229:3;26225:16;26218:27;26169:2;26039:219;;;;;26266:97;26354:2;26334:14;-1:-1;;26330:28;;26314:49;26371:117;26440:24;26458:5;26440:24;;;26433:5;26430:35;26420:2;;26479:1;26476;26469:12;26635:111;26701:21;26716:5;26701:21;;26753:117;26822:24;26840:5;26822:24;;26877:147;26961:39;26994:5;26961:39;;27155:113;27222:22;27238:5;27222:22;
Swarm Source
bzzr://6e3721fbccd7ecaaefc0adef69f6f3ac0162167a345e19435c599ee81d03136e
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
Loading...
Loading
[ Download: CSV Export ]
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.