More Info
Private Name Tags
ContractCreator
Latest 25 from a total of 32,250 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Transfer Ownersh... | 14937429 | 975 days ago | IN | 0 ETH | 0.00260217 | ||||
Cancel | 11704678 | 1479 days ago | IN | 0 ETH | 0.00243924 | ||||
Buy | 11703349 | 1479 days ago | IN | 0.11275 ETH | 0.01779564 | ||||
Cancel | 11702840 | 1479 days ago | IN | 0 ETH | 0.0061709 | ||||
Cancel | 11701308 | 1479 days ago | IN | 0 ETH | 0.00235244 | ||||
Cancel | 11701105 | 1479 days ago | IN | 0 ETH | 0.00236967 | ||||
Buy | 11698151 | 1480 days ago | IN | 0.205 ETH | 0.01556477 | ||||
Buy | 11698061 | 1480 days ago | IN | 0.205 ETH | 0.0295836 | ||||
Cancel | 11696251 | 1480 days ago | IN | 0 ETH | 0.00257766 | ||||
Cancel | 11694842 | 1480 days ago | IN | 0 ETH | 0.00192597 | ||||
Buy | 11694447 | 1480 days ago | IN | 0.041 ETH | 0.01720377 | ||||
Cancel | 11694288 | 1480 days ago | IN | 0 ETH | 0.00175849 | ||||
Cancel | 11693530 | 1480 days ago | IN | 0 ETH | 0.0044406 | ||||
Buy | 11692396 | 1481 days ago | IN | 0.3075 ETH | 0.04665895 | ||||
Transfer | 11692105 | 1481 days ago | IN | 0.3 ETH | 0.00168368 | ||||
Transfer | 11691970 | 1481 days ago | IN | 0.3 ETH | 0.00269999 | ||||
Cancel | 11691533 | 1481 days ago | IN | 0 ETH | 0.00468889 | ||||
Cancel | 11691529 | 1481 days ago | IN | 0 ETH | 0.0046686 | ||||
Cancel | 11690907 | 1481 days ago | IN | 0 ETH | 0.00365214 | ||||
Cancel | 11690907 | 1481 days ago | IN | 0 ETH | 0.0036364 | ||||
Buy | 11690423 | 1481 days ago | IN | 0.01025 ETH | 0.01691096 | ||||
Cancel | 11689355 | 1481 days ago | IN | 0 ETH | 0.0030231 | ||||
Buy | 11687842 | 1481 days ago | IN | 0.205 ETH | 0.01918593 | ||||
Buy | 11683401 | 1482 days ago | IN | 0.09225 ETH | 0.01184695 | ||||
Cancel | 11682195 | 1482 days ago | IN | 0 ETH | 0.00246788 |
Latest 25 internal transactions (View All)
Advanced mode:
Parent Transaction Hash | Block |
From
|
To
|
|||
---|---|---|---|---|---|---|
11703349 | 1479 days ago | 0.09625 ETH | ||||
11703349 | 1479 days ago | 0.011 ETH | ||||
11703349 | 1479 days ago | 0.0055 ETH | ||||
11698151 | 1480 days ago | 0.2 ETH | ||||
11698151 | 1480 days ago | 0.005 ETH | ||||
11694447 | 1480 days ago | 0.039 ETH | ||||
11694447 | 1480 days ago | 0.002 ETH | ||||
11692396 | 1481 days ago | 0.2625 ETH | ||||
11692396 | 1481 days ago | 0.03 ETH | ||||
11692396 | 1481 days ago | 0.015 ETH | ||||
11690423 | 1481 days ago | 0.00875 ETH | ||||
11690423 | 1481 days ago | 0.001 ETH | ||||
11690423 | 1481 days ago | 0.0005 ETH | ||||
11687842 | 1481 days ago | 0.165 ETH | ||||
11687842 | 1481 days ago | 0.03 ETH | ||||
11687842 | 1481 days ago | 0.01 ETH | ||||
11683401 | 1482 days ago | 0.08775 ETH | ||||
11683401 | 1482 days ago | 0.0045 ETH | ||||
11675615 | 1483 days ago | 0.09907425 ETH | ||||
11675615 | 1483 days ago | 0.0180135 ETH | ||||
11675615 | 1483 days ago | 0.0060045 ETH | ||||
11673140 | 1484 days ago | 0.039 ETH | ||||
11673140 | 1484 days ago | 0.002 ETH | ||||
11672007 | 1484 days ago | 0.02625 ETH | ||||
11672007 | 1484 days ago | 0.003 ETH |
Loading...
Loading
Contract Source Code Verified (Exact Match)
Contract Name:
ERC721Sale
Compiler Version
v0.5.17+commit.d19bba13
Contract Source Code (Solidity)
/** *Submitted for verification at Etherscan.io on 2020-09-03 */ 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 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 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 { buyerFee = _buyerFee; } function setBeneficiary(address payable _beneficiary) public onlyOwner { beneficiary = _beneficiary; } function prepareMessage(address token, uint256 tokenId, uint256 price, uint256 fee, uint256 nonce) internal pure 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(10000)); 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(10000)); uint buyerFeeValue = total.mul(buyerFee).div(10000); 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; 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(10000); require(msg.value == price + buyerFeeValue, "msg.value is incorrect"); require(owner == prepareMessage(address(token), tokenId, price, sellerFee, nonce).recover(signature.v, signature.r, signature.s), "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":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
608060405260006001553480156200001657600080fd5b50604051620022f6380380620022f6833981016040819052620000399162000103565b8060006200004f6001600160e01b03620000df16565b600080546001600160a01b0319166001600160a01b0383169081178255604051929350917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a350600280546001600160a01b03199081166001600160a01b0393841617909155600380548216958316959095179094556004805490941692169190911790915550620001a2565b3390565b8051620000f0816200017d565b92915050565b8051620000f08162000197565b6000806000606084860312156200011957600080fd5b6000620001278686620000f6565b93505060206200013a86828701620000f6565b92505060406200014d86828701620000e3565b9150509250925092565b6000620000f08262000171565b6000620000f08262000157565b6001600160a01b031690565b620001888162000157565b81146200019457600080fd5b50565b620001888162000164565b61214480620001b26000396000f3fe6080604052600436106100c25760003560e01c8063715018a61161007f57806398590ef91161005957806398590ef9146101e6578063a4ddbaa614610206578063f2fde38b14610219578063fa7da19d14610239576100c2565b8063715018a61461019a5780638da5cb5b146101af5780638f32d59b146101c4576100c2565b8063150b7a02146100c75780631c31f710146100fd57806338af3eed1461011f57806341a259a6146101415780635de6c42f146101635780636e667db314610185575b600080fd5b3480156100d357600080fd5b506100e76100e2366004611a2b565b610259565b6040516100f49190611eb5565b60405180910390f35b34801561010957600080fd5b5061011d6101183660046119ef565b61026a565b005b34801561012b57600080fd5b506101346102b9565b6040516100f49190611e2e565b34801561014d57600080fd5b506101566102c8565b6040516100f49190611ec3565b34801561016f57600080fd5b506101786102d7565b6040516100f49190611fb0565b34801561019157600080fd5b506101566102dd565b3480156101a657600080fd5b5061011d6102ec565b3480156101bb57600080fd5b5061013461035a565b3480156101d057600080fd5b506101d9610369565b6040516100f49190611e8c565b3480156101f257600080fd5b5061011d610201366004611b2c565b61038d565b61011d610214366004611b66565b61056f565b34801561022557600080fd5b5061011d6102343660046119ef565b610852565b34801561024557600080fd5b5061011d610254366004611bdb565b610882565b630a85bd0160e11b5b949350505050565b610272610369565b6102975760405162461bcd60e51b815260040161028e90611f80565b60405180910390fd5b600280546001600160a01b0319166001600160a01b0392909216919091179055565b6002546001600160a01b031681565b6004546001600160a01b031681565b60015481565b6003546001600160a01b031681565b6102f4610369565b6103105760405162461bcd60e51b815260040161028e90611f80565b600080546040516001600160a01b03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600080546001600160a01b0319169055565b6000546001600160a01b031690565b600080546001600160a01b031661037e6108ab565b6001600160a01b031614905090565b6040516331a9108f60e11b81526000906001600160a01b03841690636352211e906103bc908590600401611fb0565b60206040518083038186803b1580156103d457600080fd5b505afa1580156103e8573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061040c9190810190611a0d565b90506001600160a01b03811633146104365760405162461bcd60e51b815260040161028e90611f90565b60048054604051638953580360e01b81526000926001600160a01b039092169163895358039161046a918891889101611ef9565b60206040518083038186803b15801561048257600080fd5b505afa158015610496573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506104ba9190810190611bf9565b6004805460405163e330a93560e01b815260019390930193506001600160a01b03169163e330a935916104f39188918891879101611f07565b600060405180830381600087803b15801561050d57600080fd5b505af1158015610521573d6000803e3d6000fd5b5050505082846001600160a01b03167fb8b7c5e8b8890227e1f8844a1b6bf94a9061b5ff6f8c75ae7db63926b22be27a8484604051610561929190611e71565b60405180910390a350505050565b6040516331a9108f60e11b81526000906001600160a01b03871690636352211e9061059e908890600401611fb0565b60206040518083038186803b1580156105b657600080fd5b505afa1580156105ca573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506105ee9190810190611a0d565b60048054604051638953580360e01b81529293506000926001600160a01b0390911691638953580391610625918b918b9101611ef9565b60206040518083038186803b15801561063d57600080fd5b505afa158015610651573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506106759190810190611bf9565b905060006106a0612710610694600154896108af90919063ffffffff16565b9063ffffffff6108f216565b905080860134146106c35760405162461bcd60e51b815260040161028e90611fa0565b6106f08460000151856020015186604001516106e28c8c8c8c8a610934565b92919063ffffffff610a2a16565b6001600160a01b0316836001600160a01b0316146107205760405162461bcd60e51b815260040161028e90611f60565b600354604051637b84dc8360e11b81526001600160a01b039091169063f709b90690610756908b90879033908d90600401611ed1565b600060405180830381600087803b15801561077057600080fd5b505af1158015610784573d6000803e3d6000fd5b505050506107958888858989610b07565b6004805460405163e330a93560e01b81526001600160a01b039091169163e330a935916107cb918c918c91600189019101611f07565b600060405180830381600087803b1580156107e557600080fd5b505af11580156107f9573d6000803e3d6000fd5b5050505086886001600160a01b03167f7a212d757c7290587e1c8f7100a01a3d09466d58945058b6f22a179013475a9085338a876001016040516108409493929190611e3c565b60405180910390a35050505050505050565b61085a610369565b6108765760405162461bcd60e51b815260040161028e90611f80565b61087f81610d9d565b50565b61088a610369565b6108a65760405162461bcd60e51b815260040161028e90611f80565b600155565b3390565b6000826108be575060006108ec565b828202828482816108cb57fe5b04146108e95760405162461bcd60e51b815260040161028e90611f70565b90505b92915050565b60006108e983836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250610e1e565b6060806109d461094c886001600160a01b0316610e57565b6040518060400160405280600b81526020016a017103a37b5b2b724b21d160ad1b81525061097989610fd5565b6040518060400160405280600981526020016801710383934b1b29d160bd1b8152506109a48a610fd5565b60405180604001604052806009815260200168017103737b731b29d160bd1b8152506109cf8a610fd5565b61108d565b90508315610a1e57610a1660405180604001604052806007815260200166017103332b29d160cd1b815250610a0886610fd5565b83919063ffffffff61133316565b915050610a21565b90505b95945050505050565b600060608590506060610aa36040518060400160405280601a81526020017f19457468657265756d205369676e6564204d6573736167653a0a000000000000815250610a768451610fd5565b60408051600080825260208201818152828401828152606084019283526080840190945288939091611487565b90506001818051906020012087878760405160008152602001604052604051610acf9493929190611e9a565b6020604051602081039080840390855afa158015610af1573d6000803e3d6000fd5b5050604051601f19015198975050505050505050565b6000610b13838361171e565b6040516301ffc9a760e01b81529091506001600160a01b038716906301ffc9a790610b4990632dde656160e21b90600401611eb5565b60206040518083038186803b158015610b6157600080fd5b505afa158015610b75573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610b999190810190611b0e565b15610d5e5760405163b9c4d9fb60e01b815286906060906001600160a01b0383169063b9c4d9fb90610bcf908a90600401611fb0565b60006040518083038186803b158015610be757600080fd5b505afa158015610bfb573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610c239190810190611aa4565b90506060826001600160a01b0316630ebd4c7f896040518263ffffffff1660e01b8152600401610c539190611fb0565b60006040518083038186803b158015610c6b57600080fd5b505afa158015610c7f573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610ca79190810190611ad9565b90508151815114610cb757600080fd5b60005b8151811015610d5957600080610cfb87610cf6612710610694888881518110610cdf57fe5b60200260200101518e6108af90919063ffffffff16565b6117c0565b91509150819650848381518110610d0e57fe5b60200260200101516001600160a01b03166108fc829081150290604051600060405180830381858888f19350505050158015610d4e573d6000803e3d6000fd5b505050600101610cba565b505050505b6040516001600160a01b0385169082156108fc029083906000818181858888f19350505050158015610d94573d6000803e3d6000fd5b50505050505050565b6001600160a01b038116610dc35760405162461bcd60e51b815260040161028e90611f40565b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b0319166001600160a01b0392909216919091179055565b60008183610e3f5760405162461bcd60e51b815260040161028e9190611f2f565b506000838581610e4b57fe5b049150505b9392505050565b604080518082018252601081526f181899199a1a9b1b9c1cb0b131b232b360811b60208201528151602a80825260608281019094526001600160a01b03851692918491602082018180388339019050509050600360fc1b81600081518110610ebb57fe5b60200101906001600160f81b031916908160001a905350600f60fb1b81600181518110610ee457fe5b60200101906001600160f81b031916908160001a90535060005b6014811015610fca578260048583600c0160208110610f1957fe5b1a60f81b6001600160f81b031916901c60f81c60ff1681518110610f3957fe5b602001015160f81c60f81b828260020260020181518110610f5657fe5b60200101906001600160f81b031916908160001a905350828482600c0160208110610f7d57fe5b825191901a600f16908110610f8e57fe5b602001015160f81c60f81b828260020260030181518110610fab57fe5b60200101906001600160f81b031916908160001a905350600101610efe565b50925050505b919050565b606081610ffa57506040805180820190915260018152600360fc1b6020820152610fd0565b8160005b811561101257600101600a82049150610ffe565b6060816040519080825280601f01601f19166020018201604052801561103f576020820181803883390190505b50905060001982015b8515610fca57600a860660300160f81b8282806001900393508151811061106b57fe5b60200101906001600160f81b031916908160001a905350600a86049550611048565b60608082518451865188518a518c518e510101010101016040519080825280601f01601f1916602001820160405280156110ce576020820181803883390190505b5090506000805b8a51811015611126578a81815181106110ea57fe5b602001015160f81c60f81b83838060010194508151811061110757fe5b60200101906001600160f81b031916908160001a9053506001016110d5565b5060005b895181101561117b5789818151811061113f57fe5b602001015160f81c60f81b83838060010194508151811061115c57fe5b60200101906001600160f81b031916908160001a90535060010161112a565b5060005b88518110156111d05788818151811061119457fe5b602001015160f81c60f81b8383806001019450815181106111b157fe5b60200101906001600160f81b031916908160001a90535060010161117f565b5060005b8751811015611225578781815181106111e957fe5b602001015160f81c60f81b83838060010194508151811061120657fe5b60200101906001600160f81b031916908160001a9053506001016111d4565b5060005b865181101561127a5786818151811061123e57fe5b602001015160f81c60f81b83838060010194508151811061125b57fe5b60200101906001600160f81b031916908160001a905350600101611229565b5060005b85518110156112cf5785818151811061129357fe5b602001015160f81c60f81b8383806001019450815181106112b057fe5b60200101906001600160f81b031916908160001a90535060010161127e565b5060005b8451811015611324578481815181106112e857fe5b602001015160f81c60f81b83838060010194508151811061130557fe5b60200101906001600160f81b031916908160001a9053506001016112d3565b50909998505050505050505050565b60608084905060608490506060849050606081518351855101016040519080825280601f01601f191660200182016040528015611377576020820181803883390190505b5090506000805b85518110156113cf5785818151811061139357fe5b602001015160f81c60f81b8383806001019450815181106113b057fe5b60200101906001600160f81b031916908160001a90535060010161137e565b5060005b8451811015611424578481815181106113e857fe5b602001015160f81c60f81b83838060010194508151811061140557fe5b60200101906001600160f81b031916908160001a9053506001016113d3565b5060005b83518110156114795783818151811061143d57fe5b602001015160f81c60f81b83838060010194508151811061145a57fe5b60200101906001600160f81b031916908160001a905350600101611428565b509098975050505050505050565b60608082518451865188518a518c518e510101010101016040519080825280601f01601f1916602001820160405280156114c8576020820181803883390190505b5090506000805b8a51811015611520578a81815181106114e457fe5b602001015160f81c60f81b83838060010194508151811061150157fe5b60200101906001600160f81b031916908160001a9053506001016114cf565b5060005b89518110156115755789818151811061153957fe5b602001015160f81c60f81b83838060010194508151811061155657fe5b60200101906001600160f81b031916908160001a905350600101611524565b5060005b88518110156115ca5788818151811061158e57fe5b602001015160f81c60f81b8383806001019450815181106115ab57fe5b60200101906001600160f81b031916908160001a905350600101611579565b5060005b875181101561161f578781815181106115e357fe5b602001015160f81c60f81b83838060010194508151811061160057fe5b60200101906001600160f81b031916908160001a9053506001016115ce565b5060005b86518110156116745786818151811061163857fe5b602001015160f81c60f81b83838060010194508151811061165557fe5b60200101906001600160f81b031916908160001a905350600101611623565b5060005b85518110156116c95785818151811061168d57fe5b602001015160f81c60f81b8383806001019450815181106116aa57fe5b60200101906001600160f81b031916908160001a905350600101611678565b5060005b8451811015611324578481815181106116e257fe5b602001015160f81c60f81b8383806001019450815181106116ff57fe5b60200101906001600160f81b031916908160001a9053506001016116cd565b6000808061173c85610cf6612710610694838963ffffffff6108af16565b91509150600061175d612710610694600154896108af90919063ffffffff16565b90506000611771828463ffffffff6117e416565b905080156117b5576002546040516001600160a01b039091169082156108fc029083906000818181858888f193505050501580156117b3573d6000803e3d6000fd5b505b509195945050505050565b600080828411156117d6575050808203816117dd565b5060009050825b9250929050565b6000828201838110156108e95760405162461bcd60e51b815260040161028e90611f50565b80356108ec816120c9565b80516108ec816120c9565b600082601f83011261183057600080fd5b815161184361183e82611fe5565b611fbe565b9150818183526020840193506020810190508385602084028201111561186857600080fd5b60005b83811015611894578161187e8882611814565b845250602092830192919091019060010161186b565b5050505092915050565b600082601f8301126118af57600080fd5b81516118bd61183e82611fe5565b915081818352602084019350602081019050838560208402820111156118e257600080fd5b60005b8381101561189457816118f888826119d9565b84525060209283019291909101906001016118e5565b80516108ec816120dd565b80356108ec816120e6565b600082601f83011261193557600080fd5b813561194361183e82612006565b9150808252602083016020830185838301111561195f57600080fd5b61196a838284612083565b50505092915050565b80356108ec816120ef565b60006060828403121561199057600080fd5b61199a6060611fbe565b905060006119a884846119e4565b82525060206119b984848301611919565b60208301525060406119cd84828501611919565b60408301525092915050565b80516108ec816120e6565b80356108ec816120f8565b600060208284031215611a0157600080fd5b60006102628484611809565b600060208284031215611a1f57600080fd5b60006102628484611814565b60008060008060808587031215611a4157600080fd5b6000611a4d8787611809565b9450506020611a5e87828801611809565b9350506040611a6f87828801611919565b925050606085013567ffffffffffffffff811115611a8c57600080fd5b611a9887828801611924565b91505092959194509250565b600060208284031215611ab657600080fd5b815167ffffffffffffffff811115611acd57600080fd5b6102628482850161181f565b600060208284031215611aeb57600080fd5b815167ffffffffffffffff811115611b0257600080fd5b6102628482850161189e565b600060208284031215611b2057600080fd5b6000610262848461190e565b60008060408385031215611b3f57600080fd5b6000611b4b8585611973565b9250506020611b5c85828601611919565b9150509250929050565b600080600080600060e08688031215611b7e57600080fd5b6000611b8a8888611973565b9550506020611b9b88828901611919565b9450506040611bac88828901611919565b9350506060611bbd88828901611919565b9250506080611bce8882890161197e565b9150509295509295909350565b600060208284031215611bed57600080fd5b60006102628484611919565b600060208284031215611c0b57600080fd5b600061026284846119d9565b611c2081612078565b82525050565b611c208161203b565b611c2081612046565b611c208161204b565b611c208161204e565b611c208161205b565b6000611c5e8261202e565b611c688185612032565b9350611c7881856020860161208f565b611c81816120bf565b9093019392505050565b6000611c98602683612032565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206181526564647265737360d01b602082015260400192915050565b6000611ce0601b83612032565b7f536166654d6174683a206164646974696f6e206f766572666c6f770000000000815260200192915050565b6000611d19602183612032565b7f6f776e65722073686f756c64207369676e20636f7272656374206d65737361678152606560f81b602082015260400192915050565b6000611d5c602183612032565b7f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f8152607760f81b602082015260400192915050565b6000611d9f602083612032565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572815260200192915050565b6000611dd8600c83612032565b6b3737ba1030b71037bbb732b960a11b815260200192915050565b6000611e00601683612032565b751b5cd9cb9d985b1d59481a5cc81a5b98dbdc9c9958dd60521b815260200192915050565b611c2081612072565b602081016108ec8284611c26565b60808101611e4a8287611c17565b611e576020830186611c17565b611e646040830185611c38565b610a216060830184611c38565b60408101611e7f8285611c26565b610e506020830184611c38565b602081016108ec8284611c2f565b60808101611ea88287611c38565b611e576020830186611e25565b602081016108ec8284611c41565b602081016108ec8284611c4a565b60808101611edf8287611c4a565b611eec6020830186611c17565b611e646040830185611c17565b60408101611e7f8285611c4a565b60608101611f158286611c4a565b611f226020830185611c38565b6102626040830184611c38565b602080825281016108e98184611c53565b602080825281016108ec81611c8b565b602080825281016108ec81611cd3565b602080825281016108ec81611d0c565b602080825281016108ec81611d4f565b602080825281016108ec81611d92565b602080825281016108ec81611dcb565b602080825281016108ec81611df3565b602081016108ec8284611c38565b60405181810167ffffffffffffffff81118282101715611fdd57600080fd5b604052919050565b600067ffffffffffffffff821115611ffc57600080fd5b5060209081020190565b600067ffffffffffffffff82111561201d57600080fd5b506020601f91909101601f19160190565b5190565b90815260200190565b60006108ec82612066565b151590565b90565b6001600160e01b03191690565b60006108ec8261203b565b6001600160a01b031690565b60ff1690565b60006108ec8261205b565b82818337506000910152565b60005b838110156120aa578181015183820152602001612092565b838111156120b9576000848401525b50505050565b601f01601f191690565b6120d28161203b565b811461087f57600080fd5b6120d281612046565b6120d28161204b565b6120d28161205b565b6120d28161207256fea365627a7a723158204c15ee64b8362b0f6d90892db19fa63f2d6b922d180468391e947cc53380603f6c6578706572696d656e74616cf564736f6c634300051100400000000000000000000000004fee7b061c97c9c496b01dbce9cdb10c02f0a0be000000000000000000000000efaefa82be8e827a15c9989417a19107ac9d54af000000000000000000000000256effcea2ab308d31e318728d2615545171d85b
Deployed Bytecode
0x6080604052600436106100c25760003560e01c8063715018a61161007f57806398590ef91161005957806398590ef9146101e6578063a4ddbaa614610206578063f2fde38b14610219578063fa7da19d14610239576100c2565b8063715018a61461019a5780638da5cb5b146101af5780638f32d59b146101c4576100c2565b8063150b7a02146100c75780631c31f710146100fd57806338af3eed1461011f57806341a259a6146101415780635de6c42f146101635780636e667db314610185575b600080fd5b3480156100d357600080fd5b506100e76100e2366004611a2b565b610259565b6040516100f49190611eb5565b60405180910390f35b34801561010957600080fd5b5061011d6101183660046119ef565b61026a565b005b34801561012b57600080fd5b506101346102b9565b6040516100f49190611e2e565b34801561014d57600080fd5b506101566102c8565b6040516100f49190611ec3565b34801561016f57600080fd5b506101786102d7565b6040516100f49190611fb0565b34801561019157600080fd5b506101566102dd565b3480156101a657600080fd5b5061011d6102ec565b3480156101bb57600080fd5b5061013461035a565b3480156101d057600080fd5b506101d9610369565b6040516100f49190611e8c565b3480156101f257600080fd5b5061011d610201366004611b2c565b61038d565b61011d610214366004611b66565b61056f565b34801561022557600080fd5b5061011d6102343660046119ef565b610852565b34801561024557600080fd5b5061011d610254366004611bdb565b610882565b630a85bd0160e11b5b949350505050565b610272610369565b6102975760405162461bcd60e51b815260040161028e90611f80565b60405180910390fd5b600280546001600160a01b0319166001600160a01b0392909216919091179055565b6002546001600160a01b031681565b6004546001600160a01b031681565b60015481565b6003546001600160a01b031681565b6102f4610369565b6103105760405162461bcd60e51b815260040161028e90611f80565b600080546040516001600160a01b03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600080546001600160a01b0319169055565b6000546001600160a01b031690565b600080546001600160a01b031661037e6108ab565b6001600160a01b031614905090565b6040516331a9108f60e11b81526000906001600160a01b03841690636352211e906103bc908590600401611fb0565b60206040518083038186803b1580156103d457600080fd5b505afa1580156103e8573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061040c9190810190611a0d565b90506001600160a01b03811633146104365760405162461bcd60e51b815260040161028e90611f90565b60048054604051638953580360e01b81526000926001600160a01b039092169163895358039161046a918891889101611ef9565b60206040518083038186803b15801561048257600080fd5b505afa158015610496573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506104ba9190810190611bf9565b6004805460405163e330a93560e01b815260019390930193506001600160a01b03169163e330a935916104f39188918891879101611f07565b600060405180830381600087803b15801561050d57600080fd5b505af1158015610521573d6000803e3d6000fd5b5050505082846001600160a01b03167fb8b7c5e8b8890227e1f8844a1b6bf94a9061b5ff6f8c75ae7db63926b22be27a8484604051610561929190611e71565b60405180910390a350505050565b6040516331a9108f60e11b81526000906001600160a01b03871690636352211e9061059e908890600401611fb0565b60206040518083038186803b1580156105b657600080fd5b505afa1580156105ca573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506105ee9190810190611a0d565b60048054604051638953580360e01b81529293506000926001600160a01b0390911691638953580391610625918b918b9101611ef9565b60206040518083038186803b15801561063d57600080fd5b505afa158015610651573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506106759190810190611bf9565b905060006106a0612710610694600154896108af90919063ffffffff16565b9063ffffffff6108f216565b905080860134146106c35760405162461bcd60e51b815260040161028e90611fa0565b6106f08460000151856020015186604001516106e28c8c8c8c8a610934565b92919063ffffffff610a2a16565b6001600160a01b0316836001600160a01b0316146107205760405162461bcd60e51b815260040161028e90611f60565b600354604051637b84dc8360e11b81526001600160a01b039091169063f709b90690610756908b90879033908d90600401611ed1565b600060405180830381600087803b15801561077057600080fd5b505af1158015610784573d6000803e3d6000fd5b505050506107958888858989610b07565b6004805460405163e330a93560e01b81526001600160a01b039091169163e330a935916107cb918c918c91600189019101611f07565b600060405180830381600087803b1580156107e557600080fd5b505af11580156107f9573d6000803e3d6000fd5b5050505086886001600160a01b03167f7a212d757c7290587e1c8f7100a01a3d09466d58945058b6f22a179013475a9085338a876001016040516108409493929190611e3c565b60405180910390a35050505050505050565b61085a610369565b6108765760405162461bcd60e51b815260040161028e90611f80565b61087f81610d9d565b50565b61088a610369565b6108a65760405162461bcd60e51b815260040161028e90611f80565b600155565b3390565b6000826108be575060006108ec565b828202828482816108cb57fe5b04146108e95760405162461bcd60e51b815260040161028e90611f70565b90505b92915050565b60006108e983836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250610e1e565b6060806109d461094c886001600160a01b0316610e57565b6040518060400160405280600b81526020016a017103a37b5b2b724b21d160ad1b81525061097989610fd5565b6040518060400160405280600981526020016801710383934b1b29d160bd1b8152506109a48a610fd5565b60405180604001604052806009815260200168017103737b731b29d160bd1b8152506109cf8a610fd5565b61108d565b90508315610a1e57610a1660405180604001604052806007815260200166017103332b29d160cd1b815250610a0886610fd5565b83919063ffffffff61133316565b915050610a21565b90505b95945050505050565b600060608590506060610aa36040518060400160405280601a81526020017f19457468657265756d205369676e6564204d6573736167653a0a000000000000815250610a768451610fd5565b60408051600080825260208201818152828401828152606084019283526080840190945288939091611487565b90506001818051906020012087878760405160008152602001604052604051610acf9493929190611e9a565b6020604051602081039080840390855afa158015610af1573d6000803e3d6000fd5b5050604051601f19015198975050505050505050565b6000610b13838361171e565b6040516301ffc9a760e01b81529091506001600160a01b038716906301ffc9a790610b4990632dde656160e21b90600401611eb5565b60206040518083038186803b158015610b6157600080fd5b505afa158015610b75573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610b999190810190611b0e565b15610d5e5760405163b9c4d9fb60e01b815286906060906001600160a01b0383169063b9c4d9fb90610bcf908a90600401611fb0565b60006040518083038186803b158015610be757600080fd5b505afa158015610bfb573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610c239190810190611aa4565b90506060826001600160a01b0316630ebd4c7f896040518263ffffffff1660e01b8152600401610c539190611fb0565b60006040518083038186803b158015610c6b57600080fd5b505afa158015610c7f573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610ca79190810190611ad9565b90508151815114610cb757600080fd5b60005b8151811015610d5957600080610cfb87610cf6612710610694888881518110610cdf57fe5b60200260200101518e6108af90919063ffffffff16565b6117c0565b91509150819650848381518110610d0e57fe5b60200260200101516001600160a01b03166108fc829081150290604051600060405180830381858888f19350505050158015610d4e573d6000803e3d6000fd5b505050600101610cba565b505050505b6040516001600160a01b0385169082156108fc029083906000818181858888f19350505050158015610d94573d6000803e3d6000fd5b50505050505050565b6001600160a01b038116610dc35760405162461bcd60e51b815260040161028e90611f40565b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b0319166001600160a01b0392909216919091179055565b60008183610e3f5760405162461bcd60e51b815260040161028e9190611f2f565b506000838581610e4b57fe5b049150505b9392505050565b604080518082018252601081526f181899199a1a9b1b9c1cb0b131b232b360811b60208201528151602a80825260608281019094526001600160a01b03851692918491602082018180388339019050509050600360fc1b81600081518110610ebb57fe5b60200101906001600160f81b031916908160001a905350600f60fb1b81600181518110610ee457fe5b60200101906001600160f81b031916908160001a90535060005b6014811015610fca578260048583600c0160208110610f1957fe5b1a60f81b6001600160f81b031916901c60f81c60ff1681518110610f3957fe5b602001015160f81c60f81b828260020260020181518110610f5657fe5b60200101906001600160f81b031916908160001a905350828482600c0160208110610f7d57fe5b825191901a600f16908110610f8e57fe5b602001015160f81c60f81b828260020260030181518110610fab57fe5b60200101906001600160f81b031916908160001a905350600101610efe565b50925050505b919050565b606081610ffa57506040805180820190915260018152600360fc1b6020820152610fd0565b8160005b811561101257600101600a82049150610ffe565b6060816040519080825280601f01601f19166020018201604052801561103f576020820181803883390190505b50905060001982015b8515610fca57600a860660300160f81b8282806001900393508151811061106b57fe5b60200101906001600160f81b031916908160001a905350600a86049550611048565b60608082518451865188518a518c518e510101010101016040519080825280601f01601f1916602001820160405280156110ce576020820181803883390190505b5090506000805b8a51811015611126578a81815181106110ea57fe5b602001015160f81c60f81b83838060010194508151811061110757fe5b60200101906001600160f81b031916908160001a9053506001016110d5565b5060005b895181101561117b5789818151811061113f57fe5b602001015160f81c60f81b83838060010194508151811061115c57fe5b60200101906001600160f81b031916908160001a90535060010161112a565b5060005b88518110156111d05788818151811061119457fe5b602001015160f81c60f81b8383806001019450815181106111b157fe5b60200101906001600160f81b031916908160001a90535060010161117f565b5060005b8751811015611225578781815181106111e957fe5b602001015160f81c60f81b83838060010194508151811061120657fe5b60200101906001600160f81b031916908160001a9053506001016111d4565b5060005b865181101561127a5786818151811061123e57fe5b602001015160f81c60f81b83838060010194508151811061125b57fe5b60200101906001600160f81b031916908160001a905350600101611229565b5060005b85518110156112cf5785818151811061129357fe5b602001015160f81c60f81b8383806001019450815181106112b057fe5b60200101906001600160f81b031916908160001a90535060010161127e565b5060005b8451811015611324578481815181106112e857fe5b602001015160f81c60f81b83838060010194508151811061130557fe5b60200101906001600160f81b031916908160001a9053506001016112d3565b50909998505050505050505050565b60608084905060608490506060849050606081518351855101016040519080825280601f01601f191660200182016040528015611377576020820181803883390190505b5090506000805b85518110156113cf5785818151811061139357fe5b602001015160f81c60f81b8383806001019450815181106113b057fe5b60200101906001600160f81b031916908160001a90535060010161137e565b5060005b8451811015611424578481815181106113e857fe5b602001015160f81c60f81b83838060010194508151811061140557fe5b60200101906001600160f81b031916908160001a9053506001016113d3565b5060005b83518110156114795783818151811061143d57fe5b602001015160f81c60f81b83838060010194508151811061145a57fe5b60200101906001600160f81b031916908160001a905350600101611428565b509098975050505050505050565b60608082518451865188518a518c518e510101010101016040519080825280601f01601f1916602001820160405280156114c8576020820181803883390190505b5090506000805b8a51811015611520578a81815181106114e457fe5b602001015160f81c60f81b83838060010194508151811061150157fe5b60200101906001600160f81b031916908160001a9053506001016114cf565b5060005b89518110156115755789818151811061153957fe5b602001015160f81c60f81b83838060010194508151811061155657fe5b60200101906001600160f81b031916908160001a905350600101611524565b5060005b88518110156115ca5788818151811061158e57fe5b602001015160f81c60f81b8383806001019450815181106115ab57fe5b60200101906001600160f81b031916908160001a905350600101611579565b5060005b875181101561161f578781815181106115e357fe5b602001015160f81c60f81b83838060010194508151811061160057fe5b60200101906001600160f81b031916908160001a9053506001016115ce565b5060005b86518110156116745786818151811061163857fe5b602001015160f81c60f81b83838060010194508151811061165557fe5b60200101906001600160f81b031916908160001a905350600101611623565b5060005b85518110156116c95785818151811061168d57fe5b602001015160f81c60f81b8383806001019450815181106116aa57fe5b60200101906001600160f81b031916908160001a905350600101611678565b5060005b8451811015611324578481815181106116e257fe5b602001015160f81c60f81b8383806001019450815181106116ff57fe5b60200101906001600160f81b031916908160001a9053506001016116cd565b6000808061173c85610cf6612710610694838963ffffffff6108af16565b91509150600061175d612710610694600154896108af90919063ffffffff16565b90506000611771828463ffffffff6117e416565b905080156117b5576002546040516001600160a01b039091169082156108fc029083906000818181858888f193505050501580156117b3573d6000803e3d6000fd5b505b509195945050505050565b600080828411156117d6575050808203816117dd565b5060009050825b9250929050565b6000828201838110156108e95760405162461bcd60e51b815260040161028e90611f50565b80356108ec816120c9565b80516108ec816120c9565b600082601f83011261183057600080fd5b815161184361183e82611fe5565b611fbe565b9150818183526020840193506020810190508385602084028201111561186857600080fd5b60005b83811015611894578161187e8882611814565b845250602092830192919091019060010161186b565b5050505092915050565b600082601f8301126118af57600080fd5b81516118bd61183e82611fe5565b915081818352602084019350602081019050838560208402820111156118e257600080fd5b60005b8381101561189457816118f888826119d9565b84525060209283019291909101906001016118e5565b80516108ec816120dd565b80356108ec816120e6565b600082601f83011261193557600080fd5b813561194361183e82612006565b9150808252602083016020830185838301111561195f57600080fd5b61196a838284612083565b50505092915050565b80356108ec816120ef565b60006060828403121561199057600080fd5b61199a6060611fbe565b905060006119a884846119e4565b82525060206119b984848301611919565b60208301525060406119cd84828501611919565b60408301525092915050565b80516108ec816120e6565b80356108ec816120f8565b600060208284031215611a0157600080fd5b60006102628484611809565b600060208284031215611a1f57600080fd5b60006102628484611814565b60008060008060808587031215611a4157600080fd5b6000611a4d8787611809565b9450506020611a5e87828801611809565b9350506040611a6f87828801611919565b925050606085013567ffffffffffffffff811115611a8c57600080fd5b611a9887828801611924565b91505092959194509250565b600060208284031215611ab657600080fd5b815167ffffffffffffffff811115611acd57600080fd5b6102628482850161181f565b600060208284031215611aeb57600080fd5b815167ffffffffffffffff811115611b0257600080fd5b6102628482850161189e565b600060208284031215611b2057600080fd5b6000610262848461190e565b60008060408385031215611b3f57600080fd5b6000611b4b8585611973565b9250506020611b5c85828601611919565b9150509250929050565b600080600080600060e08688031215611b7e57600080fd5b6000611b8a8888611973565b9550506020611b9b88828901611919565b9450506040611bac88828901611919565b9350506060611bbd88828901611919565b9250506080611bce8882890161197e565b9150509295509295909350565b600060208284031215611bed57600080fd5b60006102628484611919565b600060208284031215611c0b57600080fd5b600061026284846119d9565b611c2081612078565b82525050565b611c208161203b565b611c2081612046565b611c208161204b565b611c208161204e565b611c208161205b565b6000611c5e8261202e565b611c688185612032565b9350611c7881856020860161208f565b611c81816120bf565b9093019392505050565b6000611c98602683612032565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206181526564647265737360d01b602082015260400192915050565b6000611ce0601b83612032565b7f536166654d6174683a206164646974696f6e206f766572666c6f770000000000815260200192915050565b6000611d19602183612032565b7f6f776e65722073686f756c64207369676e20636f7272656374206d65737361678152606560f81b602082015260400192915050565b6000611d5c602183612032565b7f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f8152607760f81b602082015260400192915050565b6000611d9f602083612032565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572815260200192915050565b6000611dd8600c83612032565b6b3737ba1030b71037bbb732b960a11b815260200192915050565b6000611e00601683612032565b751b5cd9cb9d985b1d59481a5cc81a5b98dbdc9c9958dd60521b815260200192915050565b611c2081612072565b602081016108ec8284611c26565b60808101611e4a8287611c17565b611e576020830186611c17565b611e646040830185611c38565b610a216060830184611c38565b60408101611e7f8285611c26565b610e506020830184611c38565b602081016108ec8284611c2f565b60808101611ea88287611c38565b611e576020830186611e25565b602081016108ec8284611c41565b602081016108ec8284611c4a565b60808101611edf8287611c4a565b611eec6020830186611c17565b611e646040830185611c17565b60408101611e7f8285611c4a565b60608101611f158286611c4a565b611f226020830185611c38565b6102626040830184611c38565b602080825281016108e98184611c53565b602080825281016108ec81611c8b565b602080825281016108ec81611cd3565b602080825281016108ec81611d0c565b602080825281016108ec81611d4f565b602080825281016108ec81611d92565b602080825281016108ec81611dcb565b602080825281016108ec81611df3565b602081016108ec8284611c38565b60405181810167ffffffffffffffff81118282101715611fdd57600080fd5b604052919050565b600067ffffffffffffffff821115611ffc57600080fd5b5060209081020190565b600067ffffffffffffffff82111561201d57600080fd5b506020601f91909101601f19160190565b5190565b90815260200190565b60006108ec82612066565b151590565b90565b6001600160e01b03191690565b60006108ec8261203b565b6001600160a01b031690565b60ff1690565b60006108ec8261205b565b82818337506000910152565b60005b838110156120aa578181015183820152602001612092565b838111156120b9576000848401525b50505050565b601f01601f191690565b6120d28161203b565b811461087f57600080fd5b6120d281612046565b6120d28161204b565b6120d28161205b565b6120d28161207256fea365627a7a723158204c15ee64b8362b0f6d90892db19fa63f2d6b922d180468391e947cc53380603f6c6578706572696d656e74616cf564736f6c63430005110040
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
0000000000000000000000004fee7b061c97c9c496b01dbce9cdb10c02f0a0be000000000000000000000000efaefa82be8e827a15c9989417a19107ac9d54af000000000000000000000000256effcea2ab308d31e318728d2615545171d85b
-----Decoded View---------------
Arg [0] : _transferProxy (address): 0x4feE7B061C97C9c496b01DbcE9CDb10c02f0a0Be
Arg [1] : _nonceHolder (address): 0xefAefA82be8E827a15c9989417A19107aC9D54AF
Arg [2] : beneficiary (address): 0x256eFfCeA2ab308D31e318728D2615545171d85B
-----Encoded View---------------
3 Constructor Arguments found :
Arg [0] : 0000000000000000000000004fee7b061c97c9c496b01dbce9cdb10c02f0a0be
Arg [1] : 000000000000000000000000efaefa82be8e827a15c9989417a19107ac9d54af
Arg [2] : 000000000000000000000000256effcea2ab308d31e318728d2615545171d85b
Deployed Bytecode Sourcemap
71549:2116:0:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;73515:147;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;73515:147:0;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;57163:116;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;57163:116:0;;;;;;;;:::i;:::-;;56717:34;;8:9:-1;5:2;;;30:1;27;20:12;5:2;56717:34:0;;;:::i;:::-;;;;;;;;71997:40;;8:9:-1;5:2;;;30:1;27;20:12;5:2;71997:40:0;;;:::i;:::-;;;;;;;;56686:24;;8:9:-1;5:2;;;30:1;27;20:12;5:2;56686:24:0;;;:::i;:::-;;;;;;;;71956:34;;8:9:-1;5:2;;;30:1;27;20:12;5:2;71956: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;:::-;;;;;;;;72280:349;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;72280:349:0;;;;;;;;:::i;72637:870::-;;;;;;;;;:::i;7057:109::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;7057:109:0;;;;;;;;:::i;57059:96::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;57059:96:0;;;;;;;;:::i;73515:147::-;-1:-1:-1;;;73515:147:0;;;;;;;:::o;57163:116::-;6163:9;:7;:9::i;:::-;6155:54;;;;-1:-1:-1;;;6155:54:0;;;;;;;;;;;;;;;;;57245:11;:26;;-1:-1:-1;;;;;;57245:26:0;-1:-1:-1;;;;;57245:26:0;;;;;;;;;;57163:116::o;56717:34::-;;;-1:-1:-1;;;;;56717:34:0;;:::o;71997:40::-;;;-1:-1:-1;;;;;71997:40:0;;:::o;56686:24::-;;;;:::o;71956:34::-;;;-1:-1:-1;;;;;71956: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;72280:349::-;72362:22;;-1:-1:-1;;;72362:22:0;;72346:13;;-1:-1:-1;;;;;72362:13:0;;;;;:22;;72376:7;;72362:22;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;72362:22:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;72362: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;72362:22:0;;;;;;;;;72346:38;-1:-1:-1;;;;;;72403:19:0;;72412:10;72403:19;72395:44;;;;-1:-1:-1;;;72395:44:0;;;;;;;;;72466:11;;;:36;;-1:-1:-1;;;72466:36:0;;72450:13;;-1:-1:-1;;;;;72466:11:0;;;;:20;;:36;;72487:5;;72494:7;;72466:36;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;72466:36:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;72466: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;72466:36:0;;;;;;;;;72517:11;;;:43;;-1:-1:-1;;;72517:43:0;;72505:1;72466:40;;;;;-1:-1:-1;;;;;;72517:11:0;;:20;;:43;;72538:5;;72545:7;;72466:40;;72517:43;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;72517:43:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;72517:43:0;;;;72599:7;72591:5;-1:-1:-1;;;;;72576:45:0;;72608:5;72615;72576:45;;;;;;;;;;;;;;;;72280:349;;;;:::o;72637:870::-;72804:22;;-1:-1:-1;;;72804:22:0;;72764:21;;-1:-1:-1;;;;;72804:13:0;;;;;:22;;72818:7;;72804:22;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;72804:22:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;72804: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;72804:22:0;;;;;;;;;72855:11;;;:36;;-1:-1:-1;;;72855:36:0;;72764:64;;-1:-1:-1;72839:13:0;;-1:-1:-1;;;;;72855:11:0;;;;:20;;:36;;72876:5;;72883:7;;72855:36;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;72855:36:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;72855: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;72855:36:0;;;;;;;;;72839:52;;72902:21;72926:30;72950:5;72926:19;72936:8;;72926:5;:9;;:19;;;;:::i;:::-;:23;:30;:23;:30;:::i;:::-;72902:54;;72996:13;72988:5;:21;72975:9;:34;72967:69;;;;-1:-1:-1;;;72967:69:0;;;;;;;;;73064:111;73137:9;:11;;;73150:9;:11;;;73163:9;:11;;;73064:64;73087:5;73095:7;73104:5;73111:9;73122:5;73064:14;:64::i;:::-;:72;:111;;;:72;:111;:::i;:::-;-1:-1:-1;;;;;73055:120:0;:5;-1:-1:-1;;;;;73055:120:0;;73047:166;;;;-1:-1:-1;;;73047:166:0;;;;;;;;;73224:13;;:71;;-1:-1:-1;;;73224:71:0;;-1:-1:-1;;;;;73224:13:0;;;;:36;;:71;;73261:5;;73268;;73275:10;;73287:7;;73224:71;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;73224:71:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;73224:71:0;;;;73306:54;73320:5;73327:7;73336:5;73343;73350:9;73306:13;:54::i;:::-;73371:11;;;:47;;-1:-1:-1;;;73371:47:0;;-1:-1:-1;;;;;73371:11:0;;;;:20;;:47;;73392:5;;73399:7;;73371:11;73408:9;;;73371:47;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;73371:47:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;73371:47:0;;;;73454:7;73446:5;-1:-1:-1;;;;;73434:65:0;;73463:5;73470:10;73482:5;73489;73497:1;73489:9;73434:65;;;;;;;;;;;;;;;;;;72637:870;;;;;;;;:::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;57059:96::-;6163:9;:7;:9::i;:::-;6155:54;;;;-1:-1:-1;;;6155:54:0;;;;;;;;;57127:8;:20;57059:96::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;57287:638::-;57409:13;57435:20;57465:307;57499:16;:5;-1:-1:-1;;;;;57499:14:0;;:16::i;:::-;57535:20;;;;;;;;;;;;;-1:-1:-1;;;57535:20:0;;;57580:18;:7;:16;:18::i;:::-;57618;;;;;;;;;;;;;-1:-1:-1;;;57618:18:0;;;57661:16;:5;:14;:16::i;:::-;57697:18;;;;;;;;;;;;;-1:-1:-1;;;57697:18:0;;;57740:16;:5;:14;:16::i;:::-;57465:9;:307::i;:::-;57435:338;-1:-1:-1;57788:8:0;;57784:134;;57820:40;;;;;;;;;;;;;;-1:-1:-1;;;57820:40:0;;;57845:14;:3;:12;:14::i;:::-;57820:6;;:40;;:13;:40;:::i;:::-;57813:47;;;;;57784:134;57900:6;-1:-1:-1;57287:638:0;;;;;;;;:::o;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;58836:839::-;58968:10;58981:42;59006:5;59013:9;58981:24;:42::i;:::-;59038:43;;-1:-1:-1;;;59038:43:0;;58968:55;;-1:-1:-1;;;;;;59038:23:0;;;;;:43;;-1:-1:-1;;;59062:18:0;59038:43;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;59038:43:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;59038: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;59038:43:0;;;;;;;;;59034:602;;;59219:34;;-1:-1:-1;;;59219:34:0;;59159:5;;59181:35;;-1:-1:-1;;;;;59219:25:0;;;;;:34;;59245:7;;59219:34;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;59219:34:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;59219:34:0;;;;;;39:16:-1;36:1;17:17;2:54;101:4;59219:34:0;80:15:-1;;;-1:-1;;76:31;65:43;;120:4;113:20;59219:34:0;;;;;;;;;59181:72;;59268:18;59289:8;-1:-1:-1;;;;;59289:18:0;;59308:7;59289:27;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;59289:27:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;59289:27:0;;;;;;39:16:-1;36:1;17:17;2:54;101:4;59289:27:0;80:15:-1;;;-1:-1;;76:31;65:43;;120:4;113:20;59289:27:0;;;;;;;;;59268:48;;59354:10;:17;59339:4;:11;:32;59331:41;;;;;;59392:9;59387:238;59411:4;:11;59407:1;:15;59387:238;;;59449:13;59464:12;59480:44;59487:5;59494:29;59517:5;59494:18;59504:4;59509:1;59504:7;;;;;;;;;;;;;;59494:5;:9;;:18;;;;:::i;:29::-;59480:6;:44::i;:::-;59448:76;;;;59551:8;59543:16;;59578:10;59589:1;59578:13;;;;;;;;;;;;;;-1:-1:-1;;;;;59578:22:0;:31;59601:7;59578:31;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;-1:-1;;;59424:3:0;;59387:238;;;;59034:602;;;;59646:21;;-1:-1:-1;;;;;59646:14:0;;;:21;;;;;59661:5;;59646:21;;;;59661:5;59646:14;:21;;;;;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;59646:21:0;58836:839;;;;;;:::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;;;;;;;-1:-1:-1;;11696:345:0;;;;;;:::o;55945:483::-;56077:42;;;;;;;;;;;-1:-1:-1;;;56077:42:0;;;;56149:13;;56159:2;56149:13;;;56001;56149;;;;;;-1:-1:-1;;;;;56051:14:0;;;56077:42;56001:13;;56149;;;21:6:-1;;104:10;56149:13:0;87:34:-1;135:17;;-1:-1;56149:13:0;56130:32;;-1:-1:-1;;;56173:3:0;56177:1;56173:6;;;;;;;;;;;:12;-1:-1:-1;;;;;56173:12:0;;;;;;;;;-1:-1:-1;;;56196:3:0;56200:1;56196:6;;;;;;;;;;;:12;-1:-1:-1;;;;;56196:12:0;;;;;;;;-1:-1:-1;56224:9:0;56219:173;56243:2;56239:1;:6;56219:173;;;56280:8;56312:1;56295:5;56301:1;56305:2;56301:6;56295:13;;;;;;;;;;-1:-1:-1;;;;;56295:18:0;;;;56289:25;;56280:35;;;;;;;;;;;;;;;;;;56267:3;56273:1;56275;56273:3;56271:1;:5;56267:10;;;;;;;;;;;:48;-1:-1:-1;;;;;56267:48:0;;;;;;;;;56343:8;56358:5;56364:1;56368:2;56364:6;56358:13;;;;;;;56343:37;;56358:13;;;56374:4;56352:27;;56343:37;;;;;;;;;;;;;;56330:3;56336:1;56338;56336:3;56334:1;:5;56330:10;;;;;;;;;;;:50;-1:-1:-1;;;;;56330:50:0;;;;;;;;-1:-1:-1;56247:3:0;;56219:173;;;-1:-1:-1;56416:3:0;-1:-1:-1;;;55945: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;;57933:895;58101:12;58126:24;58241:3;:10;58228:3;:10;58215:3;:10;58202:3;:10;58189:3;:10;58176:3;:10;58163:3;:10;:23;:36;:49;:62;:75;:88;58153:99;;;;;;;;;;;;;;;;;;;;;;;;;21:6:-1;;104:10;58153:99:0;87:34:-1;135:17;;-1:-1;58153:99:0;-1:-1:-1;58126:126:0;-1:-1:-1;58263:6:0;;58284:63;58305:3;:10;58301:1;:14;58284:63;;;58341:3;58345:1;58341:6;;;;;;;;;;;;;;;;58322:11;58334:3;;;;;;58322:16;;;;;;;;;;;:25;-1:-1:-1;;;;;58322:25:0;;;;;;;;-1:-1:-1;58317:3:0;;58284:63;;;-1:-1:-1;58363:6:0;58358:63;58379:3;:10;58375:1;:14;58358:63;;;58415:3;58419:1;58415:6;;;;;;;;;;;;;;;;58396:11;58408:3;;;;;;58396:16;;;;;;;;;;;:25;-1:-1:-1;;;;;58396:25:0;;;;;;;;-1:-1:-1;58391:3:0;;58358:63;;;-1:-1:-1;58437:6:0;58432:63;58453:3;:10;58449:1;:14;58432:63;;;58489:3;58493:1;58489:6;;;;;;;;;;;;;;;;58470:11;58482:3;;;;;;58470:16;;;;;;;;;;;:25;-1:-1:-1;;;;;58470:25:0;;;;;;;;-1:-1:-1;58465:3:0;;58432:63;;;-1:-1:-1;58511:6:0;58506:63;58527:3;:10;58523:1;:14;58506:63;;;58563:3;58567:1;58563:6;;;;;;;;;;;;;;;;58544:11;58556:3;;;;;;58544:16;;;;;;;;;;;:25;-1:-1:-1;;;;;58544:25:0;;;;;;;;-1:-1:-1;58539:3:0;;58506:63;;;-1:-1:-1;58585:6:0;58580:63;58601:3;:10;58597:1;:14;58580:63;;;58637:3;58641:1;58637:6;;;;;;;;;;;;;;;;58618:11;58630:3;;;;;;58618:16;;;;;;;;;;;:25;-1:-1:-1;;;;;58618:25:0;;;;;;;;-1:-1:-1;58613:3:0;;58580:63;;;-1:-1:-1;58659:6:0;58654:63;58675:3;:10;58671:1;:14;58654:63;;;58711:3;58715:1;58711:6;;;;;;;;;;;;;;;;58692:11;58704:3;;;;;;58692:16;;;;;;;;;;;:25;-1:-1:-1;;;;;58692:25:0;;;;;;;;-1:-1:-1;58687:3:0;;58654:63;;;-1:-1:-1;58733:6:0;58728:63;58749:3;:10;58745:1;:14;58728:63;;;58785:3;58789:1;58785:6;;;;;;;;;;;;;;;;58766:11;58778:3;;;;;;58766:16;;;;;;;;;;;:25;-1:-1:-1;;;;;58766:25:0;;;;;;;;-1:-1:-1;58761:3:0;;58728:63;;;-1:-1:-1;58809:11:0;;57933:895;-1:-1:-1;;;;;;;;;57933: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;;46031:558;-1:-1:-1;;;;;;;;46031:558:0:o;47074:892::-;47239:12;47264:24;47379:3;:10;47366:3;:10;47353:3;:10;47340:3;:10;47327:3;:10;47314:3;:10;47301:3;:10;:23;:36;:49;:62;:75;:88;47291:99;;;;;;;;;;;;;;;;;;;;;;;;;21:6:-1;;104:10;47291:99:0;87:34:-1;135:17;;-1:-1;47291:99:0;-1:-1:-1;47264:126:0;-1:-1:-1;47401:6:0;;47422:63;47443:3;:10;47439:1;:14;47422:63;;;47479:3;47483:1;47479:6;;;;;;;;;;;;;;;;47460:11;47472:3;;;;;;47460:16;;;;;;;;;;;:25;-1:-1:-1;;;;;47460:25:0;;;;;;;;-1:-1:-1;47455:3:0;;47422:63;;;-1:-1:-1;47501:6:0;47496:63;47517:3;:10;47513:1;:14;47496:63;;;47553:3;47557:1;47553:6;;;;;;;;;;;;;;;;47534:11;47546:3;;;;;;47534:16;;;;;;;;;;;:25;-1:-1:-1;;;;;47534:25:0;;;;;;;;-1:-1:-1;47529:3:0;;47496:63;;;-1:-1:-1;47575:6:0;47570:63;47591:3;:10;47587:1;:14;47570:63;;;47627:3;47631:1;47627:6;;;;;;;;;;;;;;;;47608:11;47620:3;;;;;;47608:16;;;;;;;;;;;:25;-1:-1:-1;;;;;47608:25:0;;;;;;;;-1:-1:-1;47603:3:0;;47570:63;;;-1:-1:-1;47649:6:0;47644:63;47665:3;:10;47661:1;:14;47644:63;;;47701:3;47705:1;47701:6;;;;;;;;;;;;;;;;47682:11;47694:3;;;;;;47682:16;;;;;;;;;;;:25;-1:-1:-1;;;;;47682:25:0;;;;;;;;-1:-1:-1;47677:3:0;;47644:63;;;-1:-1:-1;47723:6:0;47718:63;47739:3;:10;47735:1;:14;47718:63;;;47775:3;47779:1;47775:6;;;;;;;;;;;;;;;;47756:11;47768:3;;;;;;47756:16;;;;;;;;;;;:25;-1:-1:-1;;;;;47756:25:0;;;;;;;;-1:-1:-1;47751:3:0;;47718:63;;;-1:-1:-1;47797:6:0;47792:63;47813:3;:10;47809:1;:14;47792:63;;;47849:3;47853:1;47849:6;;;;;;;;;;;;;;;;47830:11;47842:3;;;;;;47830:16;;;;;;;;;;;:25;-1:-1:-1;;;;;47830:25:0;;;;;;;;-1:-1:-1;47825:3:0;;47792:63;;;-1:-1:-1;47871:6:0;47866:63;47887:3;:10;47883:1;:14;47866:63;;;47923:3;47927:1;47923:6;;;;;;;;;;;;;;;;47904:11;47916:3;;;;;;47904:16;;;;;;;;;;;:25;-1:-1:-1;;;;;47904:25:0;;;;;;;;-1:-1:-1;47899:3:0;;47866:63;;59683:435;59763:4;;;59816:46;59823:5;59830:31;59855:5;59830:20;59823:5;59840:9;59830:20;:9;:20;:::i;59816:46::-;59780:82;;;;59873:18;59894:30;59918:5;59894:19;59904:8;;59894:5;:9;;:19;;;;:::i;:30::-;59873:51;-1:-1:-1;59935:19:0;59957:33;59873:51;59975:14;59957:33;:17;:33;:::i;:::-;59935:55;-1:-1:-1;60005:18:0;;60001:87;;60040:11;;:36;;-1:-1:-1;;;;;60040:11:0;;;;:36;;;;;60061:14;;60040:11;:36;:11;:36;60061:14;60040:11;:36;;;;;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;60040:36:0;60001:87;-1:-1:-1;60105:5:0;;59683:435;-1:-1:-1;;;;;59683:435:0:o;60126:277::-;60187:13;60202:12;60239:3;60231:5;:11;60227:169;;;-1:-1:-1;;60270:11:0;;;60278:3;60227:169;;;-1:-1:-1;60353:1:0;;-1:-1:-1;60379:5:0;60227:169;60126:277;;;;;:::o;8723:181::-;8781:7;8813:5;;;8837:6;;;;8829:46;;;;-1:-1:-1;;;8829:46:0;;;;;;;;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:408;;5711:2;5699:9;5690:7;5686:23;5682:32;5679:2;;;5727:1;5724;5717:12;5679:2;5762:24;;5806:18;5795:30;;5792:2;;;5838:1;5835;5828:12;5792:2;5858:97;5947:7;5938:6;5927:9;5923:22;5858:97;;5978:392;;6118:2;6106:9;6097:7;6093:23;6089:32;6086:2;;;6134:1;6131;6124:12;6086:2;6169:24;;6213:18;6202:30;;6199:2;;;6245:1;6242;6235:12;6199:2;6265:89;6346:7;6337:6;6326:9;6322:22;6265:89;;6377:257;;6489:2;6477:9;6468:7;6464:23;6460:32;6457:2;;;6505:1;6502;6495:12;6457:2;6540:1;6557:61;6610:7;6590:9;6557:61;;6641:396;;;6777:2;6765:9;6756:7;6752:23;6748:32;6745:2;;;6793:1;6790;6783:12;6745:2;6828:1;6845:68;6905:7;6885:9;6845:68;;;6835:78;;6807:112;6950:2;6968:53;7013:7;7004:6;6993:9;6989:22;6968:53;;;6958:63;;6929:98;6739:298;;;;;;7044:815;;;;;;7252:3;7240:9;7231:7;7227:23;7223:33;7220:2;;;7269:1;7266;7259:12;7220:2;7304:1;7321:68;7381:7;7361:9;7321:68;;;7311:78;;7283:112;7426:2;7444:53;7489:7;7480:6;7469:9;7465:22;7444:53;;;7434:63;;7405:98;7534:2;7552:53;7597:7;7588:6;7577:9;7573:22;7552:53;;;7542:63;;7513:98;7642:2;7660:53;7705:7;7696:6;7685:9;7681:22;7660:53;;;7650:63;;7621:98;7750:3;7769:74;7835:7;7826:6;7815:9;7811:22;7769:74;;;7759:84;;7729:120;7214:645;;;;;;;;;7866:241;;7970:2;7958:9;7949:7;7945:23;7941:32;7938:2;;;7986:1;7983;7976:12;7938:2;8021:1;8038:53;8083:7;8063:9;8038:53;;8114:263;;8229:2;8217:9;8208:7;8204:23;8200:32;8197:2;;;8245:1;8242;8235:12;8197:2;8280:1;8297:64;8353:7;8333:9;8297:64;;8384:142;8475:45;8514:5;8475:45;;;8470:3;8463:58;8457:69;;;8533:137;8632:32;8658:5;8632:32;;8797:104;8874:21;8889:5;8874:21;;8908:113;8991:24;9009:5;8991:24;;9028:110;9109:23;9126:5;9109:23;;9145:186;9258:67;9319:5;9258:67;;9678:347;;9790:39;9823:5;9790:39;;;9841:71;9905:6;9900:3;9841:71;;;9834:78;;9917:52;9962:6;9957:3;9950:4;9943:5;9939:16;9917:52;;;9990:29;10012:6;9990:29;;;9981:39;;;;9770:255;-1:-1;;;9770:255;10033:375;;10193:67;10257:2;10252:3;10193:67;;;10293:34;10273:55;;-1:-1;;;10357:2;10348:12;;10341:30;10399:2;10390:12;;10179:229;-1:-1;;10179:229;10417:327;;10577:67;10641:2;10636:3;10577:67;;;10677:29;10657:50;;10735:2;10726:12;;10563:181;-1:-1;;10563:181;10753:370;;10913:67;10977:2;10972:3;10913:67;;;11013:34;10993:55;;-1:-1;;;11077:2;11068:12;;11061:25;11114:2;11105:12;;10899:224;-1:-1;;10899:224;11132:370;;11292:67;11356:2;11351:3;11292:67;;;11392:34;11372:55;;-1:-1;;;11456:2;11447:12;;11440:25;11493:2;11484:12;;11278:224;-1:-1;;11278:224;11511:332;;11671:67;11735:2;11730:3;11671:67;;;11771:34;11751:55;;11834:2;11825:12;;11657:186;-1:-1;;11657:186;11852:312;;12012:67;12076:2;12071:3;12012:67;;;-1:-1;;;12092:35;;12155:2;12146:12;;11998:166;-1:-1;;11998:166;12173:322;;12333:67;12397:2;12392:3;12333:67;;;-1:-1;;;12413:45;;12486:2;12477:12;;12319:176;-1:-1;;12319:176;12623:107;12702:22;12718:5;12702:22;;12737:213;12855:2;12840:18;;12869:71;12844:9;12913:6;12869:71;;13209:579;13427:3;13412:19;;13442:79;13416:9;13494:6;13442:79;;;13532:80;13608:2;13597:9;13593:18;13584:6;13532:80;;;13623:72;13691:2;13680:9;13676:18;13667:6;13623:72;;;13706;13774:2;13763:9;13759:18;13750:6;13706:72;;13795:324;13941:2;13926:18;;13955:71;13930:9;13999:6;13955:71;;;14037:72;14105:2;14094:9;14090:18;14081:6;14037:72;;14126:201;14238:2;14223:18;;14252:65;14227:9;14290:6;14252:65;;14334:539;14532:3;14517:19;;14547:71;14521:9;14591:6;14547:71;;;14629:68;14693:2;14682:9;14678:18;14669:6;14629:68;;14880:209;14996:2;14981:18;;15010:69;14985:9;15052:6;15010:69;;15096:273;15244:2;15229:18;;15258:101;15233:9;15332:6;15258:101;;15376:609;15609:3;15594:19;;15624:86;15598:9;15683:6;15624:86;;;15721:80;15797:2;15786:9;15782:18;15773:6;15721:80;;;15812;15888:2;15877:9;15873:18;15864:6;15812:80;;15992:354;16153:2;16138:18;;16167:86;16142:9;16226:6;16167:86;;16353:465;16542:2;16527:18;;16556:86;16531:9;16615:6;16556:86;;;16653:72;16721:2;16710:9;16706:18;16697:6;16653:72;;;16736;16804:2;16793:9;16789:18;16780:6;16736:72;;17089:301;17227:2;17241:47;;;17212:18;;17302:78;17212:18;17366:6;17302:78;;17397:407;17588:2;17602:47;;;17573:18;;17663:131;17573:18;17663:131;;17811:407;18002:2;18016:47;;;17987:18;;18077:131;17987:18;18077:131;;18225:407;18416:2;18430:47;;;18401:18;;18491:131;18401:18;18491:131;;18639:407;18830:2;18844:47;;;18815:18;;18905:131;18815:18;18905:131;;19053:407;19244:2;19258:47;;;19229:18;;19319:131;19229:18;19319:131;;19467:407;19658:2;19672:47;;;19643:18;;19733:131;19643:18;19733:131;;19881:407;20072:2;20086:47;;;20057:18;;20147:131;20057:18;20147:131;;20295:213;20413:2;20398:18;;20427:71;20402:9;20471:6;20427:71;;20515:256;20577:2;20571:9;20603:17;;;20678:18;20663:34;;20699:22;;;20660:62;20657:2;;;20735:1;20732;20725:12;20657:2;20751;20744:22;20555:216;;-1:-1;20555:216;20778:312;;20945:18;20937:6;20934:30;20931:2;;;20977:1;20974;20967:12;20931:2;-1:-1;21012:4;21000:17;;;21065:15;;20868:222;21408:321;;21551:18;21543:6;21540:30;21537:2;;;21583:1;21580;21573:12;21537:2;-1:-1;21714:4;21650;21627:17;;;;-1:-1;;21623:33;21704:15;;21474:255;21736:122;21824:12;;21795:63;21866:163;21969:19;;;22018:4;22009:14;;21962:67;22037:91;;22099:24;22117:5;22099:24;;22241:85;22307:13;22300:21;;22283:43;22333:72;22395:5;22378:27;22412:144;-1:-1;;;;;;22473:78;;22456:100;22563:106;;22640:24;22658:5;22640:24;;22676:121;-1:-1;;;;;22738:54;;22721:76;22883:81;22954:4;22943:16;;22926:38;22971:129;;23058:37;23089:5;23058:37;;24281:145;24362:6;24357:3;24352;24339:30;-1:-1;24418:1;24400:16;;24393:27;24332:94;24435:268;24500:1;24507:101;24521:6;24518:1;24515:13;24507:101;;;24588:11;;;24582:18;24569:11;;;24562:39;24543:2;24536:10;24507:101;;;24623:6;24620:1;24617:13;24614:2;;;24688:1;24679:6;24674:3;24670:16;24663:27;24614:2;24484:219;;;;;24711:97;24799:2;24779:14;-1:-1;;24775:28;;24759:49;24816:117;24885:24;24903:5;24885:24;;;24878:5;24875:35;24865:2;;24924:1;24921;24914:12;25080:111;25146:21;25161:5;25146:21;;25198:117;25267:24;25285:5;25267:24;;25322:147;25406:39;25439:5;25406:39;;25600:113;25667:22;25683:5;25667:22;
Swarm Source
bzzr://4c15ee64b8362b0f6d90892db19fa63f2d6b922d180468391e947cc53380603f
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.