Overview
ETH Balance
0.044 ETH
Eth Value
$152.46 (@ $3,465.04/ETH)More Info
Private Name Tags
ContractCreator
TokenTracker
Latest 25 from a total of 866 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Set Approval For... | 20202279 | 178 days ago | IN | 0 ETH | 0.00006973 | ||||
Set Approval For... | 19547262 | 269 days ago | IN | 0 ETH | 0.00090523 | ||||
Set Approval For... | 19381482 | 293 days ago | IN | 0 ETH | 0.00125128 | ||||
Set Approval For... | 18910362 | 359 days ago | IN | 0 ETH | 0.00046249 | ||||
Set Approval For... | 18909547 | 359 days ago | IN | 0 ETH | 0.00047635 | ||||
Set Approval For... | 17968737 | 491 days ago | IN | 0 ETH | 0.0007802 | ||||
Set Approval For... | 17964793 | 491 days ago | IN | 0 ETH | 0.00153393 | ||||
Set Approval For... | 17030702 | 623 days ago | IN | 0 ETH | 0.00100254 | ||||
Set Approval For... | 16692718 | 670 days ago | IN | 0 ETH | 0.00243191 | ||||
Set Approval For... | 16627651 | 679 days ago | IN | 0 ETH | 0.00057881 | ||||
Set Approval For... | 16613881 | 681 days ago | IN | 0 ETH | 0.00080448 | ||||
Set Approval For... | 16600372 | 683 days ago | IN | 0 ETH | 0.00103694 | ||||
Set Approval For... | 16600364 | 683 days ago | IN | 0 ETH | 0.00100212 | ||||
Set Approval For... | 16543608 | 691 days ago | IN | 0 ETH | 0.00139077 | ||||
Set Approval For... | 16426121 | 708 days ago | IN | 0 ETH | 0.00074739 | ||||
Set Approval For... | 16392797 | 712 days ago | IN | 0 ETH | 0.00140243 | ||||
Set Approval For... | 16391775 | 712 days ago | IN | 0 ETH | 0.00082494 | ||||
Set Approval For... | 16325686 | 722 days ago | IN | 0 ETH | 0.0007 | ||||
Set Approval For... | 16307282 | 724 days ago | IN | 0 ETH | 0.00080435 | ||||
Set Approval For... | 16306999 | 724 days ago | IN | 0 ETH | 0.00088607 | ||||
Set Approval For... | 16299520 | 725 days ago | IN | 0 ETH | 0.00072895 | ||||
Set Approval For... | 16297321 | 726 days ago | IN | 0 ETH | 0.00051068 | ||||
Set Approval For... | 16261524 | 731 days ago | IN | 0 ETH | 0.00063656 | ||||
Approve | 16235375 | 734 days ago | IN | 0 ETH | 0.00101311 | ||||
Set Approval For... | 16224926 | 736 days ago | IN | 0 ETH | 0.00059287 |
Loading...
Loading
Contract Name:
CabuCats
Compiler Version
v0.8.7+commit.e28d00a7
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: GPL-3.0 pragma solidity ^0.8.0; import "@openzeppelin/contracts/finance/PaymentSplitter.sol"; import "@openzeppelin/contracts/token/ERC721/ERC721.sol"; import "@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol"; import "@openzeppelin/contracts/access/Ownable.sol"; import "@openzeppelin/contracts/utils/cryptography/ECDSA.sol"; contract CabuCats is ERC721Enumerable, Ownable, PaymentSplitter { using Strings for uint256; using ECDSA for bytes32; uint256 public constant MAX_CATS = 8888; uint256 public RESERVED_CATS_AVAILABLE = 88; uint256 public constant PRESALE_CATS_PER_WALLET = 3; uint256 public constant MAX_PER_MINT = 7; uint256 public constant mintPrice = 0.04 ether; string private _tokenBaseURI; bool public presaleIsOpen = false; bool public saleIsOpen = false; bool public revealed = false; mapping (address => uint256) private _userPresaleMints; mapping(address => bool) private _isFreeMinted; address private _signer; constructor( address[] memory payees, uint256[] memory shares, string memory initBaseURI, address signerAddress ) ERC721("Cabu Cats", "CABU") PaymentSplitter(payees, shares) { _tokenBaseURI = initBaseURI; _signer = signerAddress; } function preSale(uint256 numberOfTokens, bytes32 hash, bytes memory signature) external payable { require(presaleIsOpen && !saleIsOpen, "Presale is not active"); require(numberOfTokens > 0, "Minimum minting amount is 1"); require(_userPresaleMints[msg.sender] + numberOfTokens <= PRESALE_CATS_PER_WALLET, "Max cats per wallet limit exceeded"); require(isValidSign(hash, signature), "Invalid signer"); require(hashTransaction(msg.sender, numberOfTokens) == hash, "Invalid hash"); if (_isFreeMinted[msg.sender]) { require(mintPrice * numberOfTokens <= msg.value, "Ether value sent is not correct"); } else { require(mintPrice * (numberOfTokens - 1) <= msg.value, "Ether value sent is not correct"); } for(uint256 i = 0; i < numberOfTokens; i++) { uint256 mintIndex = totalSupply() + 1; _safeMint(msg.sender, mintIndex); _userPresaleMints[msg.sender]++; } if (!_isFreeMinted[msg.sender]) { _isFreeMinted[msg.sender] = true; } } function mintCats(uint256 numberOfTokens) external payable { require(saleIsOpen, "Public mint is not active"); require(numberOfTokens <= MAX_PER_MINT, "Max cats per mint exceeded"); require(totalSupply() + numberOfTokens <= MAX_CATS - RESERVED_CATS_AVAILABLE, "Purchase would exceed max available cats"); require(mintPrice * numberOfTokens <= msg.value, "Ether value sent is not correct"); for(uint256 i = 0; i < numberOfTokens; i++) { uint256 mintIndex = totalSupply() + 1; _safeMint(msg.sender, mintIndex); } } function hashTransaction(address sender, uint256 qty) private pure returns(bytes32) { bytes32 hash = keccak256(abi.encodePacked( "\x19Ethereum Signed Message:\n32", keccak256(abi.encodePacked(sender, qty))) ); return hash; } function isValidSign(bytes32 hash, bytes memory signature) private view returns(bool) { return _signer == hash.recover(signature); } function gift(address to, uint256 numberOfTokens) external onlyOwner { require(RESERVED_CATS_AVAILABLE >= numberOfTokens, "Purchase would exceed reserved cats"); for(uint256 i = 0; i < numberOfTokens; i++) { uint256 mintIndex = totalSupply() + 1; _safeMint(to, mintIndex); RESERVED_CATS_AVAILABLE--; } } function flipPresaleState() external onlyOwner { presaleIsOpen = !presaleIsOpen; } function flipSaleState() external onlyOwner { saleIsOpen = !saleIsOpen; } function setBaseURI(string calldata newBaseURI) external onlyOwner { _tokenBaseURI = newBaseURI; } function setSigner(address _newSigner) external onlyOwner { _signer = _newSigner; } function reveal() external onlyOwner { revealed = true; } function tokenURI(uint256 tokenId) public view override(ERC721) returns (string memory) { require(_exists(tokenId), "ERC721Metadata: URI query for nonexistent token"); if(revealed == false) { return _tokenBaseURI; } else { return string(abi.encodePacked(_tokenBaseURI, tokenId.toString(), "")); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.0 (finance/PaymentSplitter.sol) pragma solidity ^0.8.0; import "../token/ERC20/utils/SafeERC20.sol"; import "../utils/Address.sol"; import "../utils/Context.sol"; /** * @title PaymentSplitter * @dev This contract allows to split Ether payments among a group of accounts. The sender does not need to be aware * that the Ether will be split in this way, since it is handled transparently by the contract. * * The split can be in equal parts or in any other arbitrary proportion. The way this is specified is by assigning each * account to a number of shares. Of all the Ether that this contract receives, each account will then be able to claim * an amount proportional to the percentage of total shares they were assigned. * * `PaymentSplitter` follows a _pull payment_ model. This means that payments are not automatically forwarded to the * accounts but kept in this contract, and the actual transfer is triggered as a separate step by calling the {release} * function. * * NOTE: This contract assumes that ERC20 tokens will behave similarly to native tokens (Ether). Rebasing tokens, and * tokens that apply fees during transfers, are likely to not be supported as expected. If in doubt, we encourage you * to run tests before sending real value to this contract. */ contract PaymentSplitter is Context { event PayeeAdded(address account, uint256 shares); event PaymentReleased(address to, uint256 amount); event ERC20PaymentReleased(IERC20 indexed token, address to, uint256 amount); event PaymentReceived(address from, uint256 amount); uint256 private _totalShares; uint256 private _totalReleased; mapping(address => uint256) private _shares; mapping(address => uint256) private _released; address[] private _payees; mapping(IERC20 => uint256) private _erc20TotalReleased; mapping(IERC20 => mapping(address => uint256)) private _erc20Released; /** * @dev Creates an instance of `PaymentSplitter` where each account in `payees` is assigned the number of shares at * the matching position in the `shares` array. * * All addresses in `payees` must be non-zero. Both arrays must have the same non-zero length, and there must be no * duplicates in `payees`. */ constructor(address[] memory payees, uint256[] memory shares_) payable { require(payees.length == shares_.length, "PaymentSplitter: payees and shares length mismatch"); require(payees.length > 0, "PaymentSplitter: no payees"); for (uint256 i = 0; i < payees.length; i++) { _addPayee(payees[i], shares_[i]); } } /** * @dev The Ether received will be logged with {PaymentReceived} events. Note that these events are not fully * reliable: it's possible for a contract to receive Ether without triggering this function. This only affects the * reliability of the events, and not the actual splitting of Ether. * * To learn more about this see the Solidity documentation for * https://solidity.readthedocs.io/en/latest/contracts.html#fallback-function[fallback * functions]. */ receive() external payable virtual { emit PaymentReceived(_msgSender(), msg.value); } /** * @dev Getter for the total shares held by payees. */ function totalShares() public view returns (uint256) { return _totalShares; } /** * @dev Getter for the total amount of Ether already released. */ function totalReleased() public view returns (uint256) { return _totalReleased; } /** * @dev Getter for the total amount of `token` already released. `token` should be the address of an IERC20 * contract. */ function totalReleased(IERC20 token) public view returns (uint256) { return _erc20TotalReleased[token]; } /** * @dev Getter for the amount of shares held by an account. */ function shares(address account) public view returns (uint256) { return _shares[account]; } /** * @dev Getter for the amount of Ether already released to a payee. */ function released(address account) public view returns (uint256) { return _released[account]; } /** * @dev Getter for the amount of `token` tokens already released to a payee. `token` should be the address of an * IERC20 contract. */ function released(IERC20 token, address account) public view returns (uint256) { return _erc20Released[token][account]; } /** * @dev Getter for the address of the payee number `index`. */ function payee(uint256 index) public view returns (address) { return _payees[index]; } /** * @dev Triggers a transfer to `account` of the amount of Ether they are owed, according to their percentage of the * total shares and their previous withdrawals. */ function release(address payable account) public virtual { require(_shares[account] > 0, "PaymentSplitter: account has no shares"); uint256 totalReceived = address(this).balance + totalReleased(); uint256 payment = _pendingPayment(account, totalReceived, released(account)); require(payment != 0, "PaymentSplitter: account is not due payment"); _released[account] += payment; _totalReleased += payment; Address.sendValue(account, payment); emit PaymentReleased(account, payment); } /** * @dev Triggers a transfer to `account` of the amount of `token` tokens they are owed, according to their * percentage of the total shares and their previous withdrawals. `token` must be the address of an IERC20 * contract. */ function release(IERC20 token, address account) public virtual { require(_shares[account] > 0, "PaymentSplitter: account has no shares"); uint256 totalReceived = token.balanceOf(address(this)) + totalReleased(token); uint256 payment = _pendingPayment(account, totalReceived, released(token, account)); require(payment != 0, "PaymentSplitter: account is not due payment"); _erc20Released[token][account] += payment; _erc20TotalReleased[token] += payment; SafeERC20.safeTransfer(token, account, payment); emit ERC20PaymentReleased(token, account, payment); } /** * @dev internal logic for computing the pending payment of an `account` given the token historical balances and * already released amounts. */ function _pendingPayment( address account, uint256 totalReceived, uint256 alreadyReleased ) private view returns (uint256) { return (totalReceived * _shares[account]) / _totalShares - alreadyReleased; } /** * @dev Add a new payee to the contract. * @param account The address of the payee to add. * @param shares_ The number of shares owned by the payee. */ function _addPayee(address account, uint256 shares_) private { require(account != address(0), "PaymentSplitter: account is the zero address"); require(shares_ > 0, "PaymentSplitter: shares are 0"); require(_shares[account] == 0, "PaymentSplitter: account already has shares"); _payees.push(account); _shares[account] = shares_; _totalShares = _totalShares + shares_; emit PayeeAdded(account, shares_); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.0 (token/ERC20/utils/SafeERC20.sol) pragma solidity ^0.8.0; import "../IERC20.sol"; import "../../../utils/Address.sol"; /** * @title SafeERC20 * @dev Wrappers around ERC20 operations that throw on failure (when the token * contract returns false). Tokens that return no value (and instead revert or * throw on failure) are also supported, non-reverting calls are assumed to be * successful. * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract, * which allows you to call the safe operations as `token.safeTransfer(...)`, etc. */ library SafeERC20 { using Address for address; function safeTransfer( IERC20 token, address to, uint256 value ) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value)); } function safeTransferFrom( IERC20 token, address from, address to, uint256 value ) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value)); } /** * @dev Deprecated. This function has issues similar to the ones found in * {IERC20-approve}, and its usage is discouraged. * * Whenever possible, use {safeIncreaseAllowance} and * {safeDecreaseAllowance} instead. */ function safeApprove( IERC20 token, address spender, uint256 value ) internal { // safeApprove should only be called when setting an initial allowance, // or when resetting it to zero. To increase and decrease it, use // 'safeIncreaseAllowance' and 'safeDecreaseAllowance' require( (value == 0) || (token.allowance(address(this), spender) == 0), "SafeERC20: approve from non-zero to non-zero allowance" ); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value)); } function safeIncreaseAllowance( IERC20 token, address spender, uint256 value ) internal { uint256 newAllowance = token.allowance(address(this), spender) + value; _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } function safeDecreaseAllowance( IERC20 token, address spender, uint256 value ) internal { unchecked { uint256 oldAllowance = token.allowance(address(this), spender); require(oldAllowance >= value, "SafeERC20: decreased allowance below zero"); uint256 newAllowance = oldAllowance - value; _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } } /** * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement * on the return value: the return value is optional (but if data is returned, it must not be false). * @param token The token targeted by the call. * @param data The call data (encoded using abi.encode or one of its variants). */ function _callOptionalReturn(IERC20 token, bytes memory data) private { // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that // the target address contains contract code and also asserts for success in the low-level call. bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed"); if (returndata.length > 0) { // Return data is optional require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed"); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.0 (token/ERC20/IERC20.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `recipient`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address recipient, uint256 amount) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 amount) external returns (bool); /** * @dev Moves `amount` tokens from `sender` to `recipient` using the * allowance mechanism. `amount` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom( address sender, address recipient, uint256 amount ) external returns (bool); /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.0 (utils/Address.sol) pragma solidity ^0.8.0; /** * @dev Collection of functions related to the address type */ library Address { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize, which returns 0 for contracts in // construction, since the code is only stored at the end of the // constructor execution. uint256 size; assembly { size := extcodesize(account) } return size > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); (bool success, ) = recipient.call{value: amount}(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain `call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCall(target, data, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value ) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value, string memory errorMessage ) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); require(isContract(target), "Address: call to non-contract"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall( address target, bytes memory data, string memory errorMessage ) internal view returns (bytes memory) { require(isContract(target), "Address: static call to non-contract"); (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { return functionDelegateCall(target, data, "Address: low-level delegate call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { require(isContract(target), "Address: delegate call to non-contract"); (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason using the provided one. * * _Available since v4.3._ */ function verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) internal pure returns (bytes memory) { if (success) { return returndata; } else { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.0 (utils/Context.sol) pragma solidity ^0.8.0; /** * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract Context { function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.0 (token/ERC721/ERC721.sol) pragma solidity ^0.8.0; import "./IERC721.sol"; import "./IERC721Receiver.sol"; import "./extensions/IERC721Metadata.sol"; import "../../utils/Address.sol"; import "../../utils/Context.sol"; import "../../utils/Strings.sol"; import "../../utils/introspection/ERC165.sol"; /** * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including * the Metadata extension, but not including the Enumerable extension, which is available separately as * {ERC721Enumerable}. */ contract ERC721 is Context, ERC165, IERC721, IERC721Metadata { using Address for address; using Strings for uint256; // Token name string private _name; // Token symbol string private _symbol; // Mapping from token ID to owner address mapping(uint256 => address) private _owners; // Mapping owner address to token count mapping(address => uint256) private _balances; // Mapping from token ID to approved address mapping(uint256 => address) private _tokenApprovals; // Mapping from owner to operator approvals mapping(address => mapping(address => bool)) private _operatorApprovals; /** * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection. */ constructor(string memory name_, string memory symbol_) { _name = name_; _symbol = symbol_; } /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) { return interfaceId == type(IERC721).interfaceId || interfaceId == type(IERC721Metadata).interfaceId || super.supportsInterface(interfaceId); } /** * @dev See {IERC721-balanceOf}. */ function balanceOf(address owner) public view virtual override returns (uint256) { require(owner != address(0), "ERC721: balance query for the zero address"); return _balances[owner]; } /** * @dev See {IERC721-ownerOf}. */ function ownerOf(uint256 tokenId) public view virtual override returns (address) { address owner = _owners[tokenId]; require(owner != address(0), "ERC721: owner query for nonexistent token"); return owner; } /** * @dev See {IERC721Metadata-name}. */ function name() public view virtual override returns (string memory) { return _name; } /** * @dev See {IERC721Metadata-symbol}. */ function symbol() public view virtual override returns (string memory) { return _symbol; } /** * @dev See {IERC721Metadata-tokenURI}. */ function tokenURI(uint256 tokenId) public view virtual override returns (string memory) { require(_exists(tokenId), "ERC721Metadata: URI query for nonexistent token"); string memory baseURI = _baseURI(); return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : ""; } /** * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each * token will be the concatenation of the `baseURI` and the `tokenId`. Empty * by default, can be overriden in child contracts. */ function _baseURI() internal view virtual returns (string memory) { return ""; } /** * @dev See {IERC721-approve}. */ function approve(address to, uint256 tokenId) public virtual override { address owner = ERC721.ownerOf(tokenId); require(to != owner, "ERC721: approval to current owner"); require( _msgSender() == owner || isApprovedForAll(owner, _msgSender()), "ERC721: approve caller is not owner nor approved for all" ); _approve(to, tokenId); } /** * @dev See {IERC721-getApproved}. */ function getApproved(uint256 tokenId) public view virtual override returns (address) { require(_exists(tokenId), "ERC721: approved query for nonexistent token"); return _tokenApprovals[tokenId]; } /** * @dev See {IERC721-setApprovalForAll}. */ function setApprovalForAll(address operator, bool approved) public virtual override { _setApprovalForAll(_msgSender(), operator, approved); } /** * @dev See {IERC721-isApprovedForAll}. */ function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) { return _operatorApprovals[owner][operator]; } /** * @dev See {IERC721-transferFrom}. */ function transferFrom( address from, address to, uint256 tokenId ) public virtual override { //solhint-disable-next-line max-line-length require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: transfer caller is not owner nor approved"); _transfer(from, to, tokenId); } /** * @dev See {IERC721-safeTransferFrom}. */ function safeTransferFrom( address from, address to, uint256 tokenId ) public virtual override { safeTransferFrom(from, to, tokenId, ""); } /** * @dev See {IERC721-safeTransferFrom}. */ function safeTransferFrom( address from, address to, uint256 tokenId, bytes memory _data ) public virtual override { require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: transfer caller is not owner nor approved"); _safeTransfer(from, to, tokenId, _data); } /** * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients * are aware of the ERC721 protocol to prevent tokens from being forever locked. * * `_data` is additional data, it has no specified format and it is sent in call to `to`. * * This internal function is equivalent to {safeTransferFrom}, and can be used to e.g. * implement alternative mechanisms to perform token transfer, such as signature-based. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function _safeTransfer( address from, address to, uint256 tokenId, bytes memory _data ) internal virtual { _transfer(from, to, tokenId); require(_checkOnERC721Received(from, to, tokenId, _data), "ERC721: transfer to non ERC721Receiver implementer"); } /** * @dev Returns whether `tokenId` exists. * * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}. * * Tokens start existing when they are minted (`_mint`), * and stop existing when they are burned (`_burn`). */ function _exists(uint256 tokenId) internal view virtual returns (bool) { return _owners[tokenId] != address(0); } /** * @dev Returns whether `spender` is allowed to manage `tokenId`. * * Requirements: * * - `tokenId` must exist. */ function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) { require(_exists(tokenId), "ERC721: operator query for nonexistent token"); address owner = ERC721.ownerOf(tokenId); return (spender == owner || getApproved(tokenId) == spender || isApprovedForAll(owner, spender)); } /** * @dev Safely mints `tokenId` and transfers it to `to`. * * Requirements: * * - `tokenId` must not exist. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function _safeMint(address to, uint256 tokenId) internal virtual { _safeMint(to, tokenId, ""); } /** * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is * forwarded in {IERC721Receiver-onERC721Received} to contract recipients. */ function _safeMint( address to, uint256 tokenId, bytes memory _data ) internal virtual { _mint(to, tokenId); require( _checkOnERC721Received(address(0), to, tokenId, _data), "ERC721: transfer to non ERC721Receiver implementer" ); } /** * @dev Mints `tokenId` and transfers it to `to`. * * WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible * * Requirements: * * - `tokenId` must not exist. * - `to` cannot be the zero address. * * Emits a {Transfer} event. */ function _mint(address to, uint256 tokenId) internal virtual { require(to != address(0), "ERC721: mint to the zero address"); require(!_exists(tokenId), "ERC721: token already minted"); _beforeTokenTransfer(address(0), to, tokenId); _balances[to] += 1; _owners[tokenId] = to; emit Transfer(address(0), to, tokenId); } /** * @dev Destroys `tokenId`. * The approval is cleared when the token is burned. * * Requirements: * * - `tokenId` must exist. * * Emits a {Transfer} event. */ function _burn(uint256 tokenId) internal virtual { address owner = ERC721.ownerOf(tokenId); _beforeTokenTransfer(owner, address(0), tokenId); // Clear approvals _approve(address(0), tokenId); _balances[owner] -= 1; delete _owners[tokenId]; emit Transfer(owner, address(0), tokenId); } /** * @dev Transfers `tokenId` from `from` to `to`. * As opposed to {transferFrom}, this imposes no restrictions on msg.sender. * * Requirements: * * - `to` cannot be the zero address. * - `tokenId` token must be owned by `from`. * * Emits a {Transfer} event. */ function _transfer( address from, address to, uint256 tokenId ) internal virtual { require(ERC721.ownerOf(tokenId) == from, "ERC721: transfer of token that is not own"); require(to != address(0), "ERC721: transfer to the zero address"); _beforeTokenTransfer(from, to, tokenId); // Clear approvals from the previous owner _approve(address(0), tokenId); _balances[from] -= 1; _balances[to] += 1; _owners[tokenId] = to; emit Transfer(from, to, tokenId); } /** * @dev Approve `to` to operate on `tokenId` * * Emits a {Approval} event. */ function _approve(address to, uint256 tokenId) internal virtual { _tokenApprovals[tokenId] = to; emit Approval(ERC721.ownerOf(tokenId), to, tokenId); } /** * @dev Approve `operator` to operate on all of `owner` tokens * * Emits a {ApprovalForAll} event. */ function _setApprovalForAll( address owner, address operator, bool approved ) internal virtual { require(owner != operator, "ERC721: approve to caller"); _operatorApprovals[owner][operator] = approved; emit ApprovalForAll(owner, operator, approved); } /** * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address. * The call is not executed if the target address is not a contract. * * @param from address representing the previous owner of the given token ID * @param to target address that will receive the tokens * @param tokenId uint256 ID of the token to be transferred * @param _data bytes optional data to send along with the call * @return bool whether the call correctly returned the expected magic value */ function _checkOnERC721Received( address from, address to, uint256 tokenId, bytes memory _data ) private returns (bool) { if (to.isContract()) { try IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, _data) returns (bytes4 retval) { return retval == IERC721Receiver.onERC721Received.selector; } catch (bytes memory reason) { if (reason.length == 0) { revert("ERC721: transfer to non ERC721Receiver implementer"); } else { assembly { revert(add(32, reason), mload(reason)) } } } } else { return true; } } /** * @dev Hook that is called before any token transfer. This includes minting * and burning. * * Calling conditions: * * - When `from` and `to` are both non-zero, ``from``'s `tokenId` will be * transferred to `to`. * - When `from` is zero, `tokenId` will be minted for `to`. * - When `to` is zero, ``from``'s `tokenId` will be burned. * - `from` and `to` are never both zero. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _beforeTokenTransfer( address from, address to, uint256 tokenId ) internal virtual {} }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.0 (token/ERC721/IERC721.sol) pragma solidity ^0.8.0; import "../../utils/introspection/IERC165.sol"; /** * @dev Required interface of an ERC721 compliant contract. */ interface IERC721 is IERC165 { /** * @dev Emitted when `tokenId` token is transferred from `from` to `to`. */ event Transfer(address indexed from, address indexed to, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token. */ event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets. */ event ApprovalForAll(address indexed owner, address indexed operator, bool approved); /** * @dev Returns the number of tokens in ``owner``'s account. */ function balanceOf(address owner) external view returns (uint256 balance); /** * @dev Returns the owner of the `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function ownerOf(uint256 tokenId) external view returns (address owner); /** * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients * are aware of the ERC721 protocol to prevent tokens from being forever locked. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must be have been allowed to move this token by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom( address from, address to, uint256 tokenId ) external; /** * @dev Transfers `tokenId` token from `from` to `to`. * * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must be owned by `from`. * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. * * Emits a {Transfer} event. */ function transferFrom( address from, address to, uint256 tokenId ) external; /** * @dev Gives permission to `to` to transfer `tokenId` token to another account. * The approval is cleared when the token is transferred. * * Only a single account can be approved at a time, so approving the zero address clears previous approvals. * * Requirements: * * - The caller must own the token or be an approved operator. * - `tokenId` must exist. * * Emits an {Approval} event. */ function approve(address to, uint256 tokenId) external; /** * @dev Returns the account approved for `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function getApproved(uint256 tokenId) external view returns (address operator); /** * @dev Approve or remove `operator` as an operator for the caller. * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller. * * Requirements: * * - The `operator` cannot be the caller. * * Emits an {ApprovalForAll} event. */ function setApprovalForAll(address operator, bool _approved) external; /** * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`. * * See {setApprovalForAll} */ function isApprovedForAll(address owner, address operator) external view returns (bool); /** * @dev Safely transfers `tokenId` token from `from` to `to`. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom( address from, address to, uint256 tokenId, bytes calldata data ) external; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.0 (utils/introspection/IERC165.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC165 standard, as defined in the * https://eips.ethereum.org/EIPS/eip-165[EIP]. * * Implementers can declare support of contract interfaces, which can then be * queried by others ({ERC165Checker}). * * For an implementation, see {ERC165}. */ interface IERC165 { /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] * to learn more about how these ids are created. * * This function call must use less than 30 000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.0 (token/ERC721/IERC721Receiver.sol) pragma solidity ^0.8.0; /** * @title ERC721 token receiver interface * @dev Interface for any contract that wants to support safeTransfers * from ERC721 asset contracts. */ interface IERC721Receiver { /** * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom} * by `operator` from `from`, this function is called. * * It must return its Solidity selector to confirm the token transfer. * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted. * * The selector can be obtained in Solidity with `IERC721.onERC721Received.selector`. */ function onERC721Received( address operator, address from, uint256 tokenId, bytes calldata data ) external returns (bytes4); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.0 (token/ERC721/extensions/IERC721Metadata.sol) pragma solidity ^0.8.0; import "../IERC721.sol"; /** * @title ERC-721 Non-Fungible Token Standard, optional metadata extension * @dev See https://eips.ethereum.org/EIPS/eip-721 */ interface IERC721Metadata is IERC721 { /** * @dev Returns the token collection name. */ function name() external view returns (string memory); /** * @dev Returns the token collection symbol. */ function symbol() external view returns (string memory); /** * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token. */ function tokenURI(uint256 tokenId) external view returns (string memory); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.0 (utils/Strings.sol) pragma solidity ^0.8.0; /** * @dev String operations. */ library Strings { bytes16 private constant _HEX_SYMBOLS = "0123456789abcdef"; /** * @dev Converts a `uint256` to its ASCII `string` decimal representation. */ function toString(uint256 value) internal pure returns (string memory) { // Inspired by OraclizeAPI's implementation - MIT licence // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol if (value == 0) { return "0"; } uint256 temp = value; uint256 digits; while (temp != 0) { digits++; temp /= 10; } bytes memory buffer = new bytes(digits); while (value != 0) { digits -= 1; buffer[digits] = bytes1(uint8(48 + uint256(value % 10))); value /= 10; } return string(buffer); } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation. */ function toHexString(uint256 value) internal pure returns (string memory) { if (value == 0) { return "0x00"; } uint256 temp = value; uint256 length = 0; while (temp != 0) { length++; temp >>= 8; } return toHexString(value, length); } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length. */ function toHexString(uint256 value, uint256 length) internal pure returns (string memory) { bytes memory buffer = new bytes(2 * length + 2); buffer[0] = "0"; buffer[1] = "x"; for (uint256 i = 2 * length + 1; i > 1; --i) { buffer[i] = _HEX_SYMBOLS[value & 0xf]; value >>= 4; } require(value == 0, "Strings: hex length insufficient"); return string(buffer); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.0 (utils/introspection/ERC165.sol) pragma solidity ^0.8.0; import "./IERC165.sol"; /** * @dev Implementation of the {IERC165} interface. * * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check * for the additional interface id that will be supported. For example: * * ```solidity * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId); * } * ``` * * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation. */ abstract contract ERC165 is IERC165 { /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { return interfaceId == type(IERC165).interfaceId; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.0 (token/ERC721/extensions/ERC721Enumerable.sol) pragma solidity ^0.8.0; import "../ERC721.sol"; import "./IERC721Enumerable.sol"; /** * @dev This implements an optional extension of {ERC721} defined in the EIP that adds * enumerability of all the token ids in the contract as well as all token ids owned by each * account. */ abstract contract ERC721Enumerable is ERC721, IERC721Enumerable { // Mapping from owner to list of owned token IDs mapping(address => mapping(uint256 => uint256)) private _ownedTokens; // Mapping from token ID to index of the owner tokens list mapping(uint256 => uint256) private _ownedTokensIndex; // Array with all token ids, used for enumeration uint256[] private _allTokens; // Mapping from token id to position in the allTokens array mapping(uint256 => uint256) private _allTokensIndex; /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165, ERC721) returns (bool) { return interfaceId == type(IERC721Enumerable).interfaceId || super.supportsInterface(interfaceId); } /** * @dev See {IERC721Enumerable-tokenOfOwnerByIndex}. */ function tokenOfOwnerByIndex(address owner, uint256 index) public view virtual override returns (uint256) { require(index < ERC721.balanceOf(owner), "ERC721Enumerable: owner index out of bounds"); return _ownedTokens[owner][index]; } /** * @dev See {IERC721Enumerable-totalSupply}. */ function totalSupply() public view virtual override returns (uint256) { return _allTokens.length; } /** * @dev See {IERC721Enumerable-tokenByIndex}. */ function tokenByIndex(uint256 index) public view virtual override returns (uint256) { require(index < ERC721Enumerable.totalSupply(), "ERC721Enumerable: global index out of bounds"); return _allTokens[index]; } /** * @dev Hook that is called before any token transfer. This includes minting * and burning. * * Calling conditions: * * - When `from` and `to` are both non-zero, ``from``'s `tokenId` will be * transferred to `to`. * - When `from` is zero, `tokenId` will be minted for `to`. * - When `to` is zero, ``from``'s `tokenId` will be burned. * - `from` cannot be the zero address. * - `to` cannot be the zero address. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _beforeTokenTransfer( address from, address to, uint256 tokenId ) internal virtual override { super._beforeTokenTransfer(from, to, tokenId); if (from == address(0)) { _addTokenToAllTokensEnumeration(tokenId); } else if (from != to) { _removeTokenFromOwnerEnumeration(from, tokenId); } if (to == address(0)) { _removeTokenFromAllTokensEnumeration(tokenId); } else if (to != from) { _addTokenToOwnerEnumeration(to, tokenId); } } /** * @dev Private function to add a token to this extension's ownership-tracking data structures. * @param to address representing the new owner of the given token ID * @param tokenId uint256 ID of the token to be added to the tokens list of the given address */ function _addTokenToOwnerEnumeration(address to, uint256 tokenId) private { uint256 length = ERC721.balanceOf(to); _ownedTokens[to][length] = tokenId; _ownedTokensIndex[tokenId] = length; } /** * @dev Private function to add a token to this extension's token tracking data structures. * @param tokenId uint256 ID of the token to be added to the tokens list */ function _addTokenToAllTokensEnumeration(uint256 tokenId) private { _allTokensIndex[tokenId] = _allTokens.length; _allTokens.push(tokenId); } /** * @dev Private function to remove a token from this extension's ownership-tracking data structures. Note that * while the token is not assigned a new owner, the `_ownedTokensIndex` mapping is _not_ updated: this allows for * gas optimizations e.g. when performing a transfer operation (avoiding double writes). * This has O(1) time complexity, but alters the order of the _ownedTokens array. * @param from address representing the previous owner of the given token ID * @param tokenId uint256 ID of the token to be removed from the tokens list of the given address */ function _removeTokenFromOwnerEnumeration(address from, uint256 tokenId) private { // To prevent a gap in from's tokens array, we store the last token in the index of the token to delete, and // then delete the last slot (swap and pop). uint256 lastTokenIndex = ERC721.balanceOf(from) - 1; uint256 tokenIndex = _ownedTokensIndex[tokenId]; // When the token to delete is the last token, the swap operation is unnecessary if (tokenIndex != lastTokenIndex) { uint256 lastTokenId = _ownedTokens[from][lastTokenIndex]; _ownedTokens[from][tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token _ownedTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index } // This also deletes the contents at the last position of the array delete _ownedTokensIndex[tokenId]; delete _ownedTokens[from][lastTokenIndex]; } /** * @dev Private function to remove a token from this extension's token tracking data structures. * This has O(1) time complexity, but alters the order of the _allTokens array. * @param tokenId uint256 ID of the token to be removed from the tokens list */ function _removeTokenFromAllTokensEnumeration(uint256 tokenId) private { // To prevent a gap in the tokens array, we store the last token in the index of the token to delete, and // then delete the last slot (swap and pop). uint256 lastTokenIndex = _allTokens.length - 1; uint256 tokenIndex = _allTokensIndex[tokenId]; // When the token to delete is the last token, the swap operation is unnecessary. However, since this occurs so // rarely (when the last minted token is burnt) that we still do the swap here to avoid the gas cost of adding // an 'if' statement (like in _removeTokenFromOwnerEnumeration) uint256 lastTokenId = _allTokens[lastTokenIndex]; _allTokens[tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token _allTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index // This also deletes the contents at the last position of the array delete _allTokensIndex[tokenId]; _allTokens.pop(); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.0 (token/ERC721/extensions/IERC721Enumerable.sol) pragma solidity ^0.8.0; import "../IERC721.sol"; /** * @title ERC-721 Non-Fungible Token Standard, optional enumeration extension * @dev See https://eips.ethereum.org/EIPS/eip-721 */ interface IERC721Enumerable is IERC721 { /** * @dev Returns the total amount of tokens stored by the contract. */ function totalSupply() external view returns (uint256); /** * @dev Returns a token ID owned by `owner` at a given `index` of its token list. * Use along with {balanceOf} to enumerate all of ``owner``'s tokens. */ function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256 tokenId); /** * @dev Returns a token ID at a given `index` of all the tokens stored by the contract. * Use along with {totalSupply} to enumerate all tokens. */ function tokenByIndex(uint256 index) external view returns (uint256); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.0 (access/Ownable.sol) pragma solidity ^0.8.0; import "../utils/Context.sol"; /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * By default, the owner account will be the one that deploys the contract. This * can later be changed with {transferOwnership}. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ abstract contract Ownable is Context { address private _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the deployer as the initial owner. */ constructor() { _transferOwnership(_msgSender()); } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { require(owner() == _msgSender(), "Ownable: caller is not the owner"); _; } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions anymore. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby removing any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { _transferOwnership(address(0)); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual onlyOwner { require(newOwner != address(0), "Ownable: new owner is the zero address"); _transferOwnership(newOwner); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Internal function without access restriction. */ function _transferOwnership(address newOwner) internal virtual { address oldOwner = _owner; _owner = newOwner; emit OwnershipTransferred(oldOwner, newOwner); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.0 (utils/cryptography/ECDSA.sol) pragma solidity ^0.8.0; import "../Strings.sol"; /** * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations. * * These functions can be used to verify that a message was signed by the holder * of the private keys of a given address. */ library ECDSA { enum RecoverError { NoError, InvalidSignature, InvalidSignatureLength, InvalidSignatureS, InvalidSignatureV } function _throwError(RecoverError error) private pure { if (error == RecoverError.NoError) { return; // no error: do nothing } else if (error == RecoverError.InvalidSignature) { revert("ECDSA: invalid signature"); } else if (error == RecoverError.InvalidSignatureLength) { revert("ECDSA: invalid signature length"); } else if (error == RecoverError.InvalidSignatureS) { revert("ECDSA: invalid signature 's' value"); } else if (error == RecoverError.InvalidSignatureV) { revert("ECDSA: invalid signature 'v' value"); } } /** * @dev Returns the address that signed a hashed message (`hash`) with * `signature` or error string. This address can then be used for verification purposes. * * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures: * this function rejects them by requiring the `s` value to be in the lower * half order, and the `v` value to be either 27 or 28. * * IMPORTANT: `hash` _must_ be the result of a hash operation for the * verification to be secure: it is possible to craft signatures that * recover to arbitrary addresses for non-hashed data. A safe way to ensure * this is by receiving a hash of the original message (which may otherwise * be too long), and then calling {toEthSignedMessageHash} on it. * * Documentation for signature generation: * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js] * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers] * * _Available since v4.3._ */ function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) { // Check the signature length // - case 65: r,s,v signature (standard) // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._ if (signature.length == 65) { bytes32 r; bytes32 s; uint8 v; // ecrecover takes the signature parameters, and the only way to get them // currently is to use assembly. assembly { r := mload(add(signature, 0x20)) s := mload(add(signature, 0x40)) v := byte(0, mload(add(signature, 0x60))) } return tryRecover(hash, v, r, s); } else if (signature.length == 64) { bytes32 r; bytes32 vs; // ecrecover takes the signature parameters, and the only way to get them // currently is to use assembly. assembly { r := mload(add(signature, 0x20)) vs := mload(add(signature, 0x40)) } return tryRecover(hash, r, vs); } else { return (address(0), RecoverError.InvalidSignatureLength); } } /** * @dev Returns the address that signed a hashed message (`hash`) with * `signature`. This address can then be used for verification purposes. * * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures: * this function rejects them by requiring the `s` value to be in the lower * half order, and the `v` value to be either 27 or 28. * * IMPORTANT: `hash` _must_ be the result of a hash operation for the * verification to be secure: it is possible to craft signatures that * recover to arbitrary addresses for non-hashed data. A safe way to ensure * this is by receiving a hash of the original message (which may otherwise * be too long), and then calling {toEthSignedMessageHash} on it. */ function recover(bytes32 hash, bytes memory signature) internal pure returns (address) { (address recovered, RecoverError error) = tryRecover(hash, signature); _throwError(error); return recovered; } /** * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately. * * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures] * * _Available since v4.3._ */ function tryRecover( bytes32 hash, bytes32 r, bytes32 vs ) internal pure returns (address, RecoverError) { bytes32 s; uint8 v; assembly { s := and(vs, 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) v := add(shr(255, vs), 27) } return tryRecover(hash, v, r, s); } /** * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately. * * _Available since v4.2._ */ function recover( bytes32 hash, bytes32 r, bytes32 vs ) internal pure returns (address) { (address recovered, RecoverError error) = tryRecover(hash, r, vs); _throwError(error); return recovered; } /** * @dev Overload of {ECDSA-tryRecover} that receives the `v`, * `r` and `s` signature fields separately. * * _Available since v4.3._ */ function tryRecover( bytes32 hash, uint8 v, bytes32 r, bytes32 s ) internal pure returns (address, RecoverError) { // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines // the valid range for s in (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most // signatures from current libraries generate a unique signature with an s-value in the lower half order. // // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept // these malleable signatures as well. if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) { return (address(0), RecoverError.InvalidSignatureS); } if (v != 27 && v != 28) { return (address(0), RecoverError.InvalidSignatureV); } // If the signature is valid (and not malleable), return the signer address address signer = ecrecover(hash, v, r, s); if (signer == address(0)) { return (address(0), RecoverError.InvalidSignature); } return (signer, RecoverError.NoError); } /** * @dev Overload of {ECDSA-recover} that receives the `v`, * `r` and `s` signature fields separately. */ function recover( bytes32 hash, uint8 v, bytes32 r, bytes32 s ) internal pure returns (address) { (address recovered, RecoverError error) = tryRecover(hash, v, r, s); _throwError(error); return recovered; } /** * @dev Returns an Ethereum Signed Message, created from a `hash`. This * produces hash corresponding to the one signed with the * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`] * JSON-RPC method as part of EIP-191. * * See {recover}. */ function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) { // 32 is the length in bytes of hash, // enforced by the type signature above return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", hash)); } /** * @dev Returns an Ethereum Signed Message, created from `s`. This * produces hash corresponding to the one signed with the * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`] * JSON-RPC method as part of EIP-191. * * See {recover}. */ function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) { return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n", Strings.toString(s.length), s)); } /** * @dev Returns an Ethereum Signed Typed Data, created from a * `domainSeparator` and a `structHash`. This produces hash corresponding * to the one signed with the * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`] * JSON-RPC method as part of EIP-712. * * See {recover}. */ function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) { return keccak256(abi.encodePacked("\x19\x01", domainSeparator, structHash)); } }
{ "metadata": { "useLiteralContent": true }, "optimizer": { "enabled": true, "runs": 200 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "abi" ] } } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"address[]","name":"payees","type":"address[]"},{"internalType":"uint256[]","name":"shares","type":"uint256[]"},{"internalType":"string","name":"initBaseURI","type":"string"},{"internalType":"address","name":"signerAddress","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"contract IERC20","name":"token","type":"address"},{"indexed":false,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"ERC20PaymentReleased","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"shares","type":"uint256"}],"name":"PayeeAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"from","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"PaymentReceived","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"PaymentReleased","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[],"name":"MAX_CATS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_PER_MINT","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PRESALE_CATS_PER_WALLET","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"RESERVED_CATS_AVAILABLE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"flipPresaleState","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"flipSaleState","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"numberOfTokens","type":"uint256"}],"name":"gift","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"numberOfTokens","type":"uint256"}],"name":"mintCats","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"mintPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"payee","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"numberOfTokens","type":"uint256"},{"internalType":"bytes32","name":"hash","type":"bytes32"},{"internalType":"bytes","name":"signature","type":"bytes"}],"name":"preSale","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"presaleIsOpen","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address payable","name":"account","type":"address"}],"name":"release","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IERC20","name":"token","type":"address"},{"internalType":"address","name":"account","type":"address"}],"name":"release","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IERC20","name":"token","type":"address"},{"internalType":"address","name":"account","type":"address"}],"name":"released","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"released","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"reveal","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"revealed","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"saleIsOpen","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"newBaseURI","type":"string"}],"name":"setBaseURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_newSigner","type":"address"}],"name":"setSigner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"shares","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenOfOwnerByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IERC20","name":"token","type":"address"}],"name":"totalReleased","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalReleased","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalShares","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]
Contract Creation Code
608060405260586012556014805462ffffff191690553480156200002257600080fd5b5060405162003d7e38038062003d7e833981016040819052620000459162000653565b604080518082018252600981526843616275204361747360b81b6020808301918252835180850190945260048452634341425560e01b90840152815187938793929091620000969160009162000481565b508051620000ac90600190602084019062000481565b505050620000c9620000c36200023d60201b60201c565b62000241565b80518251146200013b5760405162461bcd60e51b815260206004820152603260248201527f5061796d656e7453706c69747465723a2070617965657320616e6420736861726044820152710cae640d8cadccee8d040dad2e6dac2e8c6d60731b60648201526084015b60405180910390fd5b60008251116200018e5760405162461bcd60e51b815260206004820152601a60248201527f5061796d656e7453706c69747465723a206e6f20706179656573000000000000604482015260640162000132565b60005b8251811015620001fa57620001e5838281518110620001b457620001b462000849565b6020026020010151838381518110620001d157620001d162000849565b60200260200101516200029360201b60201c565b80620001f18162000815565b91505062000191565b50508251620002129150601390602085019062000481565b50601780546001600160a01b0319166001600160a01b03929092169190911790555062000875915050565b3390565b600a80546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6001600160a01b038216620003005760405162461bcd60e51b815260206004820152602c60248201527f5061796d656e7453706c69747465723a206163636f756e74206973207468652060448201526b7a65726f206164647265737360a01b606482015260840162000132565b60008111620003525760405162461bcd60e51b815260206004820152601d60248201527f5061796d656e7453706c69747465723a20736861726573206172652030000000604482015260640162000132565b6001600160a01b0382166000908152600d602052604090205415620003ce5760405162461bcd60e51b815260206004820152602b60248201527f5061796d656e7453706c69747465723a206163636f756e7420616c726561647960448201526a206861732073686172657360a81b606482015260840162000132565b600f8054600181019091557f8d1108e10bcb7c27dddfc02ed9d693a074039d026cf4ea4240b40f7d581ac8020180546001600160a01b0319166001600160a01b0384169081179091556000908152600d60205260409020819055600b5462000438908290620007bd565b600b55604080516001600160a01b0384168152602081018390527f40c340f65e17194d14ddddb073d3c9f888e3cb52b5aae0c6c7706b4fbc905fac910160405180910390a15050565b8280546200048f90620007d8565b90600052602060002090601f016020900481019282620004b35760008555620004fe565b82601f10620004ce57805160ff1916838001178555620004fe565b82800160010185558215620004fe579182015b82811115620004fe578251825591602001919060010190620004e1565b506200050c92915062000510565b5090565b5b808211156200050c576000815560010162000511565b80516001600160a01b03811681146200053f57600080fd5b919050565b600082601f8301126200055657600080fd5b815160206200056f620005698362000797565b62000764565b80838252828201915082860187848660051b89010111156200059057600080fd5b60005b85811015620005b15781518452928401929084019060010162000593565b5090979650505050505050565b600082601f830112620005d057600080fd5b81516001600160401b03811115620005ec57620005ec6200085f565b602062000602601f8301601f1916820162000764565b82815285828487010111156200061757600080fd5b60005b83811015620006375785810183015182820184015282016200061a565b83811115620006495760008385840101525b5095945050505050565b600080600080608085870312156200066a57600080fd5b84516001600160401b03808211156200068257600080fd5b818701915087601f8301126200069757600080fd5b81516020620006aa620005698362000797565b8083825282820191508286018c848660051b8901011115620006cb57600080fd5b600096505b84871015620006f957620006e48162000527565b835260019690960195918301918301620006d0565b50918a01519198509093505050808211156200071457600080fd5b620007228883890162000544565b945060408701519150808211156200073957600080fd5b506200074887828801620005be565b925050620007596060860162000527565b905092959194509250565b604051601f8201601f191681016001600160401b03811182821017156200078f576200078f6200085f565b604052919050565b60006001600160401b03821115620007b357620007b36200085f565b5060051b60200190565b60008219821115620007d357620007d362000833565b500190565b600181811c90821680620007ed57607f821691505b602082108114156200080f57634e487b7160e01b600052602260045260246000fd5b50919050565b60006000198214156200082c576200082c62000833565b5060010190565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6134f980620008856000396000f3fe60806040526004361061026b5760003560e01c80636352211e11610144578063a475b5dd116100b6578063ce7c2ac21161007a578063ce7c2ac214610760578063d79779b214610796578063e33b7de3146107cc578063e985e9c5146107e1578063f2fde38b1461082a578063f81227d41461084a57600080fd5b8063a475b5dd146106d6578063b88d4fde146106eb578063bc01c4661461070b578063c87b56dd14610720578063cbce4c971461074057600080fd5b80638b83209b116101085780638b83209b1461061a5780638da5cb5b1461063a5780639028f1351461065857806395d89b411461066b5780639852595c14610680578063a22cb465146106b657600080fd5b80636352211e1461058a5780636817c76c146105aa5780636c19e783146105c557806370a08231146105e5578063715018a61461060557600080fd5b80632cb25ecc116101dd578063406072a9116101a1578063406072a9146104a457806342842e0e146104ea57806348b750441461050a5780634f6ccce71461052a578063518302271461054a57806355f804b31461056a57600080fd5b80632cb25ecc1461042d5780632f745c591461044057806334918dfd146104605780633a98ef39146104755780633fab7bb11461048a57600080fd5b80631211b0761161022f5780631211b0761461038d57806318160ddd146103ac57806319165587146103c15780631ac6f91a146103e15780631e2fa5cd146103f757806323b872dd1461040d57600080fd5b806301ffc9a7146102b957806306fdde03146102ee578063081812fc14610310578063095ea7b31461034857806309d42b301461036a57600080fd5b366102b4577f6ef95f06320e7a25a04a175ca677b7052bdd97131872c2192525a629f51be77033604080516001600160a01b0390921682523460208301520160405180910390a1005b600080fd5b3480156102c557600080fd5b506102d96102d4366004612ece565b61085f565b60405190151581526020015b60405180910390f35b3480156102fa57600080fd5b5061030361088a565b6040516102e59190613144565b34801561031c57600080fd5b5061033061032b366004612f7a565b61091c565b6040516001600160a01b0390911681526020016102e5565b34801561035457600080fd5b50610368610363366004612e85565b6109b6565b005b34801561037657600080fd5b5061037f600781565b6040519081526020016102e5565b34801561039957600080fd5b506014546102d990610100900460ff1681565b3480156103b857600080fd5b5060085461037f565b3480156103cd57600080fd5b506103686103dc366004612d54565b610acc565b3480156103ed57600080fd5b5061037f60125481565b34801561040357600080fd5b5061037f6122b881565b34801561041957600080fd5b50610368610428366004612daa565b610bfa565b61036861043b366004612fac565b610c2b565b34801561044c57600080fd5b5061037f61045b366004612e85565b610f78565b34801561046c57600080fd5b5061036861100e565b34801561048157600080fd5b50600b5461037f565b34801561049657600080fd5b506014546102d99060ff1681565b3480156104b057600080fd5b5061037f6104bf366004612d71565b6001600160a01b03918216600090815260116020908152604080832093909416825291909152205490565b3480156104f657600080fd5b50610368610505366004612daa565b611055565b34801561051657600080fd5b50610368610525366004612d71565b611070565b34801561053657600080fd5b5061037f610545366004612f7a565b611258565b34801561055657600080fd5b506014546102d99062010000900460ff1681565b34801561057657600080fd5b50610368610585366004612f08565b6112eb565b34801561059657600080fd5b506103306105a5366004612f7a565b611321565b3480156105b657600080fd5b5061037f668e1bc9bf04000081565b3480156105d157600080fd5b506103686105e0366004612d54565b611398565b3480156105f157600080fd5b5061037f610600366004612d54565b6113e4565b34801561061157600080fd5b5061036861146b565b34801561062657600080fd5b50610330610635366004612f7a565b6114a1565b34801561064657600080fd5b50600a546001600160a01b0316610330565b610368610666366004612f7a565b6114d1565b34801561067757600080fd5b5061030361166f565b34801561068c57600080fd5b5061037f61069b366004612d54565b6001600160a01b03166000908152600e602052604090205490565b3480156106c257600080fd5b506103686106d1366004612e57565b61167e565b3480156106e257600080fd5b50610368611689565b3480156106f757600080fd5b50610368610706366004612deb565b6116c6565b34801561071757600080fd5b5061037f600381565b34801561072c57600080fd5b5061030361073b366004612f7a565b6116fe565b34801561074c57600080fd5b5061036861075b366004612e85565b611851565b34801561076c57600080fd5b5061037f61077b366004612d54565b6001600160a01b03166000908152600d602052604090205490565b3480156107a257600080fd5b5061037f6107b1366004612d54565b6001600160a01b031660009081526010602052604090205490565b3480156107d857600080fd5b50600c5461037f565b3480156107ed57600080fd5b506102d96107fc366004612d71565b6001600160a01b03918216600090815260056020908152604080832093909416825291909152205460ff1690565b34801561083657600080fd5b50610368610845366004612d54565b61192f565b34801561085657600080fd5b506103686119ca565b60006001600160e01b0319821663780e9d6360e01b1480610884575061088482611a08565b92915050565b6060600080546108999061339c565b80601f01602080910402602001604051908101604052809291908181526020018280546108c59061339c565b80156109125780601f106108e757610100808354040283529160200191610912565b820191906000526020600020905b8154815290600101906020018083116108f557829003601f168201915b5050505050905090565b6000818152600260205260408120546001600160a01b031661099a5760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b60648201526084015b60405180910390fd5b506000908152600460205260409020546001600160a01b031690565b60006109c182611321565b9050806001600160a01b0316836001600160a01b03161415610a2f5760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b6064820152608401610991565b336001600160a01b0382161480610a4b5750610a4b81336107fc565b610abd5760405162461bcd60e51b815260206004820152603860248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f7760448201527f6e6572206e6f7220617070726f76656420666f7220616c6c00000000000000006064820152608401610991565b610ac78383611a58565b505050565b6001600160a01b0381166000908152600d6020526040902054610b015760405162461bcd60e51b8152600401610991906131a9565b6000610b0c600c5490565b610b1690476132f7565b90506000610b438383610b3e866001600160a01b03166000908152600e602052604090205490565b611ac6565b905080610b625760405162461bcd60e51b815260040161099190613226565b6001600160a01b0383166000908152600e602052604081208054839290610b8a9084906132f7565b9250508190555080600c6000828254610ba391906132f7565b90915550610bb390508382611b0e565b604080516001600160a01b0385168152602081018390527fdf20fd1e76bc69d672e4814fafb2c449bba3a5369d8359adf9e05e6fde87b056910160405180910390a1505050565b610c043382611c27565b610c205760405162461bcd60e51b8152600401610991906132a6565b610ac7838383611d1e565b60145460ff168015610c455750601454610100900460ff16155b610c895760405162461bcd60e51b815260206004820152601560248201527450726573616c65206973206e6f742061637469766560581b6044820152606401610991565b60008311610cd95760405162461bcd60e51b815260206004820152601b60248201527f4d696e696d756d206d696e74696e6720616d6f756e74206973203100000000006044820152606401610991565b33600090815260156020526040902054600390610cf79085906132f7565b1115610d505760405162461bcd60e51b815260206004820152602260248201527f4d61782063617473207065722077616c6c6574206c696d697420657863656564604482015261195960f21b6064820152608401610991565b610d5a8282611ec9565b610d975760405162461bcd60e51b815260206004820152600e60248201526d24b73b30b634b21039b4b3b732b960911b6044820152606401610991565b604080513360601b6bffffffffffffffffffffffff19166020808301919091526034808301879052835180840390910181526054830184528051908201207f19457468657265756d205369676e6564204d6573736167653a0a33320000000060748401526090808401919091528351808403909101815260b090920190925280519101208214610e585760405162461bcd60e51b815260206004820152600c60248201526b092dcecc2d8d2c840d0c2e6d60a31b6044820152606401610991565b3360009081526016602052604090205460ff1615610ea55734610e8284668e1bc9bf040000613323565b1115610ea05760405162461bcd60e51b8152600401610991906131ef565b610ee0565b34610eb1600185613342565b610ec290668e1bc9bf040000613323565b1115610ee05760405162461bcd60e51b8152600401610991906131ef565b60005b83811015610f41576000610ef660085490565b610f019060016132f7565b9050610f0d3382611eed565b336000908152601560205260408120805491610f28836133d7565b9190505550508080610f39906133d7565b915050610ee3565b503360009081526016602052604090205460ff16610ac757336000908152601660205260409020805460ff19166001179055505050565b6000610f83836113e4565b8210610fe55760405162461bcd60e51b815260206004820152602b60248201527f455243373231456e756d657261626c653a206f776e657220696e646578206f7560448201526a74206f6620626f756e647360a81b6064820152608401610991565b506001600160a01b03919091166000908152600660209081526040808320938352929052205490565b600a546001600160a01b031633146110385760405162461bcd60e51b815260040161099190613271565b6014805461ff001981166101009182900460ff1615909102179055565b610ac7838383604051806020016040528060008152506116c6565b6001600160a01b0381166000908152600d60205260409020546110a55760405162461bcd60e51b8152600401610991906131a9565b6001600160a01b0382166000908152601060205260408120546040516370a0823160e01b81523060048201526001600160a01b038516906370a082319060240160206040518083038186803b1580156110fd57600080fd5b505afa158015611111573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111359190612f93565b61113f91906132f7565b905060006111788383610b3e87876001600160a01b03918216600090815260116020908152604080832093909416825291909152205490565b9050806111975760405162461bcd60e51b815260040161099190613226565b6001600160a01b038085166000908152601160209081526040808320938716835292905290812080548392906111ce9084906132f7565b90915550506001600160a01b038416600090815260106020526040812080548392906111fb9084906132f7565b9091555061120c9050848483611f07565b604080516001600160a01b038581168252602082018490528616917f3be5b7a71e84ed12875d241991c70855ac5817d847039e17a9d895c1ceb0f18a910160405180910390a250505050565b600061126360085490565b82106112c65760405162461bcd60e51b815260206004820152602c60248201527f455243373231456e756d657261626c653a20676c6f62616c20696e646578206f60448201526b7574206f6620626f756e647360a01b6064820152608401610991565b600882815481106112d9576112d961345e565b90600052602060002001549050919050565b600a546001600160a01b031633146113155760405162461bcd60e51b815260040161099190613271565b610ac760138383612c2e565b6000818152600260205260408120546001600160a01b0316806108845760405162461bcd60e51b815260206004820152602960248201527f4552433732313a206f776e657220717565727920666f72206e6f6e657869737460448201526832b73a103a37b5b2b760b91b6064820152608401610991565b600a546001600160a01b031633146113c25760405162461bcd60e51b815260040161099190613271565b601780546001600160a01b0319166001600160a01b0392909216919091179055565b60006001600160a01b03821661144f5760405162461bcd60e51b815260206004820152602a60248201527f4552433732313a2062616c616e636520717565727920666f7220746865207a65604482015269726f206164647265737360b01b6064820152608401610991565b506001600160a01b031660009081526003602052604090205490565b600a546001600160a01b031633146114955760405162461bcd60e51b815260040161099190613271565b61149f6000611f59565b565b6000600f82815481106114b6576114b661345e565b6000918252602090912001546001600160a01b031692915050565b601454610100900460ff166115285760405162461bcd60e51b815260206004820152601960248201527f5075626c6963206d696e74206973206e6f7420616374697665000000000000006044820152606401610991565b60078111156115795760405162461bcd60e51b815260206004820152601a60248201527f4d6178206361747320706572206d696e742065786365656465640000000000006044820152606401610991565b601254611588906122b8613342565b8161159260085490565b61159c91906132f7565b11156115fb5760405162461bcd60e51b815260206004820152602860248201527f507572636861736520776f756c6420657863656564206d617820617661696c61604482015267626c65206361747360c01b6064820152608401610991565b3461160d82668e1bc9bf040000613323565b111561162b5760405162461bcd60e51b8152600401610991906131ef565b60005b8181101561166b57600061164160085490565b61164c9060016132f7565b90506116583382611eed565b5080611663816133d7565b91505061162e565b5050565b6060600180546108999061339c565b61166b338383611fab565b600a546001600160a01b031633146116b35760405162461bcd60e51b815260040161099190613271565b6014805462ff0000191662010000179055565b6116d03383611c27565b6116ec5760405162461bcd60e51b8152600401610991906132a6565b6116f88484848461207a565b50505050565b6000818152600260205260409020546060906001600160a01b031661177d5760405162461bcd60e51b815260206004820152602f60248201527f4552433732314d657461646174613a2055524920717565727920666f72206e6f60448201526e3732bc34b9ba32b73a103a37b5b2b760891b6064820152608401610991565b60145462010000900460ff1661181f576013805461179a9061339c565b80601f01602080910402602001604051908101604052809291908181526020018280546117c69061339c565b80156118135780601f106117e857610100808354040283529160200191611813565b820191906000526020600020905b8154815290600101906020018083116117f657829003601f168201915b50505050509050919050565b601361182a836120ad565b60405160200161183b929190613060565b6040516020818303038152906040529050919050565b600a546001600160a01b0316331461187b5760405162461bcd60e51b815260040161099190613271565b8060125410156118d95760405162461bcd60e51b815260206004820152602360248201527f507572636861736520776f756c6420657863656564207265736572766564206360448201526261747360e81b6064820152608401610991565b60005b81811015610ac75760006118ef60085490565b6118fa9060016132f7565b90506119068482611eed565b6012805490600061191683613385565b9190505550508080611927906133d7565b9150506118dc565b600a546001600160a01b031633146119595760405162461bcd60e51b815260040161099190613271565b6001600160a01b0381166119be5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610991565b6119c781611f59565b50565b600a546001600160a01b031633146119f45760405162461bcd60e51b815260040161099190613271565b6014805460ff19811660ff90911615179055565b60006001600160e01b031982166380ac58cd60e01b1480611a3957506001600160e01b03198216635b5e139f60e01b145b8061088457506301ffc9a760e01b6001600160e01b0319831614610884565b600081815260046020526040902080546001600160a01b0319166001600160a01b0384169081179091558190611a8d82611321565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b600b546001600160a01b0384166000908152600d602052604081205490918391611af09086613323565b611afa919061330f565b611b049190613342565b90505b9392505050565b80471015611b5e5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a20696e73756666696369656e742062616c616e63650000006044820152606401610991565b6000826001600160a01b03168260405160006040518083038185875af1925050503d8060008114611bab576040519150601f19603f3d011682016040523d82523d6000602084013e611bb0565b606091505b5050905080610ac75760405162461bcd60e51b815260206004820152603a60248201527f416464726573733a20756e61626c6520746f2073656e642076616c75652c207260448201527f6563697069656e74206d617920686176652072657665727465640000000000006064820152608401610991565b6000818152600260205260408120546001600160a01b0316611ca05760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b6064820152608401610991565b6000611cab83611321565b9050806001600160a01b0316846001600160a01b03161480611ce65750836001600160a01b0316611cdb8461091c565b6001600160a01b0316145b80611d1657506001600160a01b0380821660009081526005602090815260408083209388168352929052205460ff165b949350505050565b826001600160a01b0316611d3182611321565b6001600160a01b031614611d995760405162461bcd60e51b815260206004820152602960248201527f4552433732313a207472616e73666572206f6620746f6b656e2074686174206960448201526839903737ba1037bbb760b91b6064820152608401610991565b6001600160a01b038216611dfb5760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b6064820152608401610991565b611e068383836121ab565b611e11600082611a58565b6001600160a01b0383166000908152600360205260408120805460019290611e3a908490613342565b90915550506001600160a01b0382166000908152600360205260408120805460019290611e689084906132f7565b909155505060008181526002602052604080822080546001600160a01b0319166001600160a01b0386811691821790925591518493918716917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b6000611ed58383612263565b6017546001600160a01b039182169116149392505050565b61166b828260405180602001604052806000815250612287565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b179052610ac79084906122ba565b600a80546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b816001600160a01b0316836001600160a01b0316141561200d5760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c6572000000000000006044820152606401610991565b6001600160a01b03838116600081815260056020908152604080832094871680845294825291829020805460ff191686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b612085848484611d1e565b6120918484848461238c565b6116f85760405162461bcd60e51b815260040161099190613157565b6060816120d15750506040805180820190915260018152600360fc1b602082015290565b8160005b81156120fb57806120e5816133d7565b91506120f49050600a8361330f565b91506120d5565b60008167ffffffffffffffff81111561211657612116613474565b6040519080825280601f01601f191660200182016040528015612140576020820181803683370190505b5090505b8415611d1657612155600183613342565b9150612162600a866133f2565b61216d9060306132f7565b60f81b8183815181106121825761218261345e565b60200101906001600160f81b031916908160001a9053506121a4600a8661330f565b9450612144565b6001600160a01b0383166122065761220181600880546000838152600960205260408120829055600182018355919091527ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee30155565b612229565b816001600160a01b0316836001600160a01b031614612229576122298382612499565b6001600160a01b03821661224057610ac781612536565b826001600160a01b0316826001600160a01b031614610ac757610ac782826125e5565b60008060006122728585612629565b9150915061227f81612699565b509392505050565b6122918383612854565b61229e600084848461238c565b610ac75760405162461bcd60e51b815260040161099190613157565b600061230f826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166129a29092919063ffffffff16565b805190915015610ac7578080602001905181019061232d9190612eb1565b610ac75760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608401610991565b60006001600160a01b0384163b1561248e57604051630a85bd0160e11b81526001600160a01b0385169063150b7a02906123d0903390899088908890600401613107565b602060405180830381600087803b1580156123ea57600080fd5b505af192505050801561241a575060408051601f3d908101601f1916820190925261241791810190612eeb565b60015b612474573d808015612448576040519150601f19603f3d011682016040523d82523d6000602084013e61244d565b606091505b50805161246c5760405162461bcd60e51b815260040161099190613157565b805181602001fd5b6001600160e01b031916630a85bd0160e11b149050611d16565b506001949350505050565b600060016124a6846113e4565b6124b09190613342565b600083815260076020526040902054909150808214612503576001600160a01b03841660009081526006602090815260408083208584528252808320548484528184208190558352600790915290208190555b5060009182526007602090815260408084208490556001600160a01b039094168352600681528383209183525290812055565b60085460009061254890600190613342565b600083815260096020526040812054600880549394509092849081106125705761257061345e565b9060005260206000200154905080600883815481106125915761259161345e565b60009182526020808320909101929092558281526009909152604080822084905585825281205560088054806125c9576125c9613448565b6001900381819060005260206000200160009055905550505050565b60006125f0836113e4565b6001600160a01b039093166000908152600660209081526040808320868452825280832085905593825260079052919091209190915550565b6000808251604114156126605760208301516040840151606085015160001a612654878285856129b1565b94509450505050612692565b82516040141561268a576020830151604084015161267f868383612a9e565b935093505050612692565b506000905060025b9250929050565b60008160048111156126ad576126ad613432565b14156126b65750565b60018160048111156126ca576126ca613432565b14156127185760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e617475726500000000000000006044820152606401610991565b600281600481111561272c5761272c613432565b141561277a5760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e677468006044820152606401610991565b600381600481111561278e5761278e613432565b14156127e75760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b6064820152608401610991565b60048160048111156127fb576127fb613432565b14156119c75760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c604482015261756560f01b6064820152608401610991565b6001600160a01b0382166128aa5760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f20616464726573736044820152606401610991565b6000818152600260205260409020546001600160a01b03161561290f5760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e746564000000006044820152606401610991565b61291b600083836121ab565b6001600160a01b03821660009081526003602052604081208054600192906129449084906132f7565b909155505060008181526002602052604080822080546001600160a01b0319166001600160a01b03861690811790915590518392907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b6060611b048484600085612acd565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a08311156129e85750600090506003612a95565b8460ff16601b14158015612a0057508460ff16601c14155b15612a115750600090506004612a95565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa158015612a65573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b038116612a8e57600060019250925050612a95565b9150600090505b94509492505050565b6000806001600160ff1b03831660ff84901c601b01612abf878288856129b1565b935093505050935093915050565b606082471015612b2e5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b6064820152608401610991565b843b612b7c5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610991565b600080866001600160a01b03168587604051612b989190613044565b60006040518083038185875af1925050503d8060008114612bd5576040519150601f19603f3d011682016040523d82523d6000602084013e612bda565b606091505b5091509150612bea828286612bf5565b979650505050505050565b60608315612c04575081611b07565b825115612c145782518084602001fd5b8160405162461bcd60e51b81526004016109919190613144565b828054612c3a9061339c565b90600052602060002090601f016020900481019282612c5c5760008555612ca2565b82601f10612c755782800160ff19823516178555612ca2565b82800160010185558215612ca2579182015b82811115612ca2578235825591602001919060010190612c87565b50612cae929150612cb2565b5090565b5b80821115612cae5760008155600101612cb3565b600082601f830112612cd857600080fd5b813567ffffffffffffffff80821115612cf357612cf3613474565b604051601f8301601f19908116603f01168101908282118183101715612d1b57612d1b613474565b81604052838152866020858801011115612d3457600080fd5b836020870160208301376000602085830101528094505050505092915050565b600060208284031215612d6657600080fd5b8135611b078161348a565b60008060408385031215612d8457600080fd5b8235612d8f8161348a565b91506020830135612d9f8161348a565b809150509250929050565b600080600060608486031215612dbf57600080fd5b8335612dca8161348a565b92506020840135612dda8161348a565b929592945050506040919091013590565b60008060008060808587031215612e0157600080fd5b8435612e0c8161348a565b93506020850135612e1c8161348a565b925060408501359150606085013567ffffffffffffffff811115612e3f57600080fd5b612e4b87828801612cc7565b91505092959194509250565b60008060408385031215612e6a57600080fd5b8235612e758161348a565b91506020830135612d9f8161349f565b60008060408385031215612e9857600080fd5b8235612ea38161348a565b946020939093013593505050565b600060208284031215612ec357600080fd5b8151611b078161349f565b600060208284031215612ee057600080fd5b8135611b07816134ad565b600060208284031215612efd57600080fd5b8151611b07816134ad565b60008060208385031215612f1b57600080fd5b823567ffffffffffffffff80821115612f3357600080fd5b818501915085601f830112612f4757600080fd5b813581811115612f5657600080fd5b866020828501011115612f6857600080fd5b60209290920196919550909350505050565b600060208284031215612f8c57600080fd5b5035919050565b600060208284031215612fa557600080fd5b5051919050565b600080600060608486031215612fc157600080fd5b8335925060208401359150604084013567ffffffffffffffff811115612fe657600080fd5b612ff286828701612cc7565b9150509250925092565b60008151808452613014816020860160208601613359565b601f01601f19169290920160200192915050565b6000815161303a818560208601613359565b9290920192915050565b60008251613056818460208701613359565b9190910192915050565b600080845481600182811c91508083168061307c57607f831692505b602080841082141561309c57634e487b7160e01b86526022600452602486fd5b8180156130b057600181146130c1576130ee565b60ff198616895284890196506130ee565b60008b81526020902060005b868110156130e65781548b8201529085019083016130cd565b505084890196505b5050505050506130fe8185613028565b95945050505050565b6001600160a01b038581168252841660208201526040810183905260806060820181905260009061313a90830184612ffc565b9695505050505050565b602081526000611b076020830184612ffc565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b60208082526026908201527f5061796d656e7453706c69747465723a206163636f756e7420686173206e6f2060408201526573686172657360d01b606082015260800190565b6020808252601f908201527f45746865722076616c75652073656e74206973206e6f7420636f727265637400604082015260600190565b6020808252602b908201527f5061796d656e7453706c69747465723a206163636f756e74206973206e6f742060408201526a191d59481c185e5b595b9d60aa1b606082015260800190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b60208082526031908201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f6040820152701ddb995c881b9bdc88185c1c1c9bdd9959607a1b606082015260800190565b6000821982111561330a5761330a613406565b500190565b60008261331e5761331e61341c565b500490565b600081600019048311821515161561333d5761333d613406565b500290565b60008282101561335457613354613406565b500390565b60005b8381101561337457818101518382015260200161335c565b838111156116f85750506000910152565b60008161339457613394613406565b506000190190565b600181811c908216806133b057607f821691505b602082108114156133d157634e487b7160e01b600052602260045260246000fd5b50919050565b60006000198214156133eb576133eb613406565b5060010190565b6000826134015761340161341c565b500690565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052602160045260246000fd5b634e487b7160e01b600052603160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160a01b03811681146119c757600080fd5b80151581146119c757600080fd5b6001600160e01b0319811681146119c757600080fdfea2646970667358221220271a3da421666ee8506c2b82019e2bb44793d15a9ec1b630c8d65a3fb664e89364736f6c63430008070033000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000140000000000000000000000000d5c4853eb42a7fbc4e3604088ab6acc3c396d7b30000000000000000000000000000000000000000000000000000000000000002000000000000000000000000a2c06202861105168e99da7f3ff5bc655ce16707000000000000000000000000ea14cdcd174257b3a6127e226ee145276e9cb8c00000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000005a000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000035697066733a2f2f516d5278686a7358446b763835324a3868526f746d5534414a643379525076766e78613941374e52794e707448630000000000000000000000
Deployed Bytecode
0x60806040526004361061026b5760003560e01c80636352211e11610144578063a475b5dd116100b6578063ce7c2ac21161007a578063ce7c2ac214610760578063d79779b214610796578063e33b7de3146107cc578063e985e9c5146107e1578063f2fde38b1461082a578063f81227d41461084a57600080fd5b8063a475b5dd146106d6578063b88d4fde146106eb578063bc01c4661461070b578063c87b56dd14610720578063cbce4c971461074057600080fd5b80638b83209b116101085780638b83209b1461061a5780638da5cb5b1461063a5780639028f1351461065857806395d89b411461066b5780639852595c14610680578063a22cb465146106b657600080fd5b80636352211e1461058a5780636817c76c146105aa5780636c19e783146105c557806370a08231146105e5578063715018a61461060557600080fd5b80632cb25ecc116101dd578063406072a9116101a1578063406072a9146104a457806342842e0e146104ea57806348b750441461050a5780634f6ccce71461052a578063518302271461054a57806355f804b31461056a57600080fd5b80632cb25ecc1461042d5780632f745c591461044057806334918dfd146104605780633a98ef39146104755780633fab7bb11461048a57600080fd5b80631211b0761161022f5780631211b0761461038d57806318160ddd146103ac57806319165587146103c15780631ac6f91a146103e15780631e2fa5cd146103f757806323b872dd1461040d57600080fd5b806301ffc9a7146102b957806306fdde03146102ee578063081812fc14610310578063095ea7b31461034857806309d42b301461036a57600080fd5b366102b4577f6ef95f06320e7a25a04a175ca677b7052bdd97131872c2192525a629f51be77033604080516001600160a01b0390921682523460208301520160405180910390a1005b600080fd5b3480156102c557600080fd5b506102d96102d4366004612ece565b61085f565b60405190151581526020015b60405180910390f35b3480156102fa57600080fd5b5061030361088a565b6040516102e59190613144565b34801561031c57600080fd5b5061033061032b366004612f7a565b61091c565b6040516001600160a01b0390911681526020016102e5565b34801561035457600080fd5b50610368610363366004612e85565b6109b6565b005b34801561037657600080fd5b5061037f600781565b6040519081526020016102e5565b34801561039957600080fd5b506014546102d990610100900460ff1681565b3480156103b857600080fd5b5060085461037f565b3480156103cd57600080fd5b506103686103dc366004612d54565b610acc565b3480156103ed57600080fd5b5061037f60125481565b34801561040357600080fd5b5061037f6122b881565b34801561041957600080fd5b50610368610428366004612daa565b610bfa565b61036861043b366004612fac565b610c2b565b34801561044c57600080fd5b5061037f61045b366004612e85565b610f78565b34801561046c57600080fd5b5061036861100e565b34801561048157600080fd5b50600b5461037f565b34801561049657600080fd5b506014546102d99060ff1681565b3480156104b057600080fd5b5061037f6104bf366004612d71565b6001600160a01b03918216600090815260116020908152604080832093909416825291909152205490565b3480156104f657600080fd5b50610368610505366004612daa565b611055565b34801561051657600080fd5b50610368610525366004612d71565b611070565b34801561053657600080fd5b5061037f610545366004612f7a565b611258565b34801561055657600080fd5b506014546102d99062010000900460ff1681565b34801561057657600080fd5b50610368610585366004612f08565b6112eb565b34801561059657600080fd5b506103306105a5366004612f7a565b611321565b3480156105b657600080fd5b5061037f668e1bc9bf04000081565b3480156105d157600080fd5b506103686105e0366004612d54565b611398565b3480156105f157600080fd5b5061037f610600366004612d54565b6113e4565b34801561061157600080fd5b5061036861146b565b34801561062657600080fd5b50610330610635366004612f7a565b6114a1565b34801561064657600080fd5b50600a546001600160a01b0316610330565b610368610666366004612f7a565b6114d1565b34801561067757600080fd5b5061030361166f565b34801561068c57600080fd5b5061037f61069b366004612d54565b6001600160a01b03166000908152600e602052604090205490565b3480156106c257600080fd5b506103686106d1366004612e57565b61167e565b3480156106e257600080fd5b50610368611689565b3480156106f757600080fd5b50610368610706366004612deb565b6116c6565b34801561071757600080fd5b5061037f600381565b34801561072c57600080fd5b5061030361073b366004612f7a565b6116fe565b34801561074c57600080fd5b5061036861075b366004612e85565b611851565b34801561076c57600080fd5b5061037f61077b366004612d54565b6001600160a01b03166000908152600d602052604090205490565b3480156107a257600080fd5b5061037f6107b1366004612d54565b6001600160a01b031660009081526010602052604090205490565b3480156107d857600080fd5b50600c5461037f565b3480156107ed57600080fd5b506102d96107fc366004612d71565b6001600160a01b03918216600090815260056020908152604080832093909416825291909152205460ff1690565b34801561083657600080fd5b50610368610845366004612d54565b61192f565b34801561085657600080fd5b506103686119ca565b60006001600160e01b0319821663780e9d6360e01b1480610884575061088482611a08565b92915050565b6060600080546108999061339c565b80601f01602080910402602001604051908101604052809291908181526020018280546108c59061339c565b80156109125780601f106108e757610100808354040283529160200191610912565b820191906000526020600020905b8154815290600101906020018083116108f557829003601f168201915b5050505050905090565b6000818152600260205260408120546001600160a01b031661099a5760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b60648201526084015b60405180910390fd5b506000908152600460205260409020546001600160a01b031690565b60006109c182611321565b9050806001600160a01b0316836001600160a01b03161415610a2f5760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b6064820152608401610991565b336001600160a01b0382161480610a4b5750610a4b81336107fc565b610abd5760405162461bcd60e51b815260206004820152603860248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f7760448201527f6e6572206e6f7220617070726f76656420666f7220616c6c00000000000000006064820152608401610991565b610ac78383611a58565b505050565b6001600160a01b0381166000908152600d6020526040902054610b015760405162461bcd60e51b8152600401610991906131a9565b6000610b0c600c5490565b610b1690476132f7565b90506000610b438383610b3e866001600160a01b03166000908152600e602052604090205490565b611ac6565b905080610b625760405162461bcd60e51b815260040161099190613226565b6001600160a01b0383166000908152600e602052604081208054839290610b8a9084906132f7565b9250508190555080600c6000828254610ba391906132f7565b90915550610bb390508382611b0e565b604080516001600160a01b0385168152602081018390527fdf20fd1e76bc69d672e4814fafb2c449bba3a5369d8359adf9e05e6fde87b056910160405180910390a1505050565b610c043382611c27565b610c205760405162461bcd60e51b8152600401610991906132a6565b610ac7838383611d1e565b60145460ff168015610c455750601454610100900460ff16155b610c895760405162461bcd60e51b815260206004820152601560248201527450726573616c65206973206e6f742061637469766560581b6044820152606401610991565b60008311610cd95760405162461bcd60e51b815260206004820152601b60248201527f4d696e696d756d206d696e74696e6720616d6f756e74206973203100000000006044820152606401610991565b33600090815260156020526040902054600390610cf79085906132f7565b1115610d505760405162461bcd60e51b815260206004820152602260248201527f4d61782063617473207065722077616c6c6574206c696d697420657863656564604482015261195960f21b6064820152608401610991565b610d5a8282611ec9565b610d975760405162461bcd60e51b815260206004820152600e60248201526d24b73b30b634b21039b4b3b732b960911b6044820152606401610991565b604080513360601b6bffffffffffffffffffffffff19166020808301919091526034808301879052835180840390910181526054830184528051908201207f19457468657265756d205369676e6564204d6573736167653a0a33320000000060748401526090808401919091528351808403909101815260b090920190925280519101208214610e585760405162461bcd60e51b815260206004820152600c60248201526b092dcecc2d8d2c840d0c2e6d60a31b6044820152606401610991565b3360009081526016602052604090205460ff1615610ea55734610e8284668e1bc9bf040000613323565b1115610ea05760405162461bcd60e51b8152600401610991906131ef565b610ee0565b34610eb1600185613342565b610ec290668e1bc9bf040000613323565b1115610ee05760405162461bcd60e51b8152600401610991906131ef565b60005b83811015610f41576000610ef660085490565b610f019060016132f7565b9050610f0d3382611eed565b336000908152601560205260408120805491610f28836133d7565b9190505550508080610f39906133d7565b915050610ee3565b503360009081526016602052604090205460ff16610ac757336000908152601660205260409020805460ff19166001179055505050565b6000610f83836113e4565b8210610fe55760405162461bcd60e51b815260206004820152602b60248201527f455243373231456e756d657261626c653a206f776e657220696e646578206f7560448201526a74206f6620626f756e647360a81b6064820152608401610991565b506001600160a01b03919091166000908152600660209081526040808320938352929052205490565b600a546001600160a01b031633146110385760405162461bcd60e51b815260040161099190613271565b6014805461ff001981166101009182900460ff1615909102179055565b610ac7838383604051806020016040528060008152506116c6565b6001600160a01b0381166000908152600d60205260409020546110a55760405162461bcd60e51b8152600401610991906131a9565b6001600160a01b0382166000908152601060205260408120546040516370a0823160e01b81523060048201526001600160a01b038516906370a082319060240160206040518083038186803b1580156110fd57600080fd5b505afa158015611111573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111359190612f93565b61113f91906132f7565b905060006111788383610b3e87876001600160a01b03918216600090815260116020908152604080832093909416825291909152205490565b9050806111975760405162461bcd60e51b815260040161099190613226565b6001600160a01b038085166000908152601160209081526040808320938716835292905290812080548392906111ce9084906132f7565b90915550506001600160a01b038416600090815260106020526040812080548392906111fb9084906132f7565b9091555061120c9050848483611f07565b604080516001600160a01b038581168252602082018490528616917f3be5b7a71e84ed12875d241991c70855ac5817d847039e17a9d895c1ceb0f18a910160405180910390a250505050565b600061126360085490565b82106112c65760405162461bcd60e51b815260206004820152602c60248201527f455243373231456e756d657261626c653a20676c6f62616c20696e646578206f60448201526b7574206f6620626f756e647360a01b6064820152608401610991565b600882815481106112d9576112d961345e565b90600052602060002001549050919050565b600a546001600160a01b031633146113155760405162461bcd60e51b815260040161099190613271565b610ac760138383612c2e565b6000818152600260205260408120546001600160a01b0316806108845760405162461bcd60e51b815260206004820152602960248201527f4552433732313a206f776e657220717565727920666f72206e6f6e657869737460448201526832b73a103a37b5b2b760b91b6064820152608401610991565b600a546001600160a01b031633146113c25760405162461bcd60e51b815260040161099190613271565b601780546001600160a01b0319166001600160a01b0392909216919091179055565b60006001600160a01b03821661144f5760405162461bcd60e51b815260206004820152602a60248201527f4552433732313a2062616c616e636520717565727920666f7220746865207a65604482015269726f206164647265737360b01b6064820152608401610991565b506001600160a01b031660009081526003602052604090205490565b600a546001600160a01b031633146114955760405162461bcd60e51b815260040161099190613271565b61149f6000611f59565b565b6000600f82815481106114b6576114b661345e565b6000918252602090912001546001600160a01b031692915050565b601454610100900460ff166115285760405162461bcd60e51b815260206004820152601960248201527f5075626c6963206d696e74206973206e6f7420616374697665000000000000006044820152606401610991565b60078111156115795760405162461bcd60e51b815260206004820152601a60248201527f4d6178206361747320706572206d696e742065786365656465640000000000006044820152606401610991565b601254611588906122b8613342565b8161159260085490565b61159c91906132f7565b11156115fb5760405162461bcd60e51b815260206004820152602860248201527f507572636861736520776f756c6420657863656564206d617820617661696c61604482015267626c65206361747360c01b6064820152608401610991565b3461160d82668e1bc9bf040000613323565b111561162b5760405162461bcd60e51b8152600401610991906131ef565b60005b8181101561166b57600061164160085490565b61164c9060016132f7565b90506116583382611eed565b5080611663816133d7565b91505061162e565b5050565b6060600180546108999061339c565b61166b338383611fab565b600a546001600160a01b031633146116b35760405162461bcd60e51b815260040161099190613271565b6014805462ff0000191662010000179055565b6116d03383611c27565b6116ec5760405162461bcd60e51b8152600401610991906132a6565b6116f88484848461207a565b50505050565b6000818152600260205260409020546060906001600160a01b031661177d5760405162461bcd60e51b815260206004820152602f60248201527f4552433732314d657461646174613a2055524920717565727920666f72206e6f60448201526e3732bc34b9ba32b73a103a37b5b2b760891b6064820152608401610991565b60145462010000900460ff1661181f576013805461179a9061339c565b80601f01602080910402602001604051908101604052809291908181526020018280546117c69061339c565b80156118135780601f106117e857610100808354040283529160200191611813565b820191906000526020600020905b8154815290600101906020018083116117f657829003601f168201915b50505050509050919050565b601361182a836120ad565b60405160200161183b929190613060565b6040516020818303038152906040529050919050565b600a546001600160a01b0316331461187b5760405162461bcd60e51b815260040161099190613271565b8060125410156118d95760405162461bcd60e51b815260206004820152602360248201527f507572636861736520776f756c6420657863656564207265736572766564206360448201526261747360e81b6064820152608401610991565b60005b81811015610ac75760006118ef60085490565b6118fa9060016132f7565b90506119068482611eed565b6012805490600061191683613385565b9190505550508080611927906133d7565b9150506118dc565b600a546001600160a01b031633146119595760405162461bcd60e51b815260040161099190613271565b6001600160a01b0381166119be5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610991565b6119c781611f59565b50565b600a546001600160a01b031633146119f45760405162461bcd60e51b815260040161099190613271565b6014805460ff19811660ff90911615179055565b60006001600160e01b031982166380ac58cd60e01b1480611a3957506001600160e01b03198216635b5e139f60e01b145b8061088457506301ffc9a760e01b6001600160e01b0319831614610884565b600081815260046020526040902080546001600160a01b0319166001600160a01b0384169081179091558190611a8d82611321565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b600b546001600160a01b0384166000908152600d602052604081205490918391611af09086613323565b611afa919061330f565b611b049190613342565b90505b9392505050565b80471015611b5e5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a20696e73756666696369656e742062616c616e63650000006044820152606401610991565b6000826001600160a01b03168260405160006040518083038185875af1925050503d8060008114611bab576040519150601f19603f3d011682016040523d82523d6000602084013e611bb0565b606091505b5050905080610ac75760405162461bcd60e51b815260206004820152603a60248201527f416464726573733a20756e61626c6520746f2073656e642076616c75652c207260448201527f6563697069656e74206d617920686176652072657665727465640000000000006064820152608401610991565b6000818152600260205260408120546001600160a01b0316611ca05760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b6064820152608401610991565b6000611cab83611321565b9050806001600160a01b0316846001600160a01b03161480611ce65750836001600160a01b0316611cdb8461091c565b6001600160a01b0316145b80611d1657506001600160a01b0380821660009081526005602090815260408083209388168352929052205460ff165b949350505050565b826001600160a01b0316611d3182611321565b6001600160a01b031614611d995760405162461bcd60e51b815260206004820152602960248201527f4552433732313a207472616e73666572206f6620746f6b656e2074686174206960448201526839903737ba1037bbb760b91b6064820152608401610991565b6001600160a01b038216611dfb5760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b6064820152608401610991565b611e068383836121ab565b611e11600082611a58565b6001600160a01b0383166000908152600360205260408120805460019290611e3a908490613342565b90915550506001600160a01b0382166000908152600360205260408120805460019290611e689084906132f7565b909155505060008181526002602052604080822080546001600160a01b0319166001600160a01b0386811691821790925591518493918716917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b6000611ed58383612263565b6017546001600160a01b039182169116149392505050565b61166b828260405180602001604052806000815250612287565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b179052610ac79084906122ba565b600a80546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b816001600160a01b0316836001600160a01b0316141561200d5760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c6572000000000000006044820152606401610991565b6001600160a01b03838116600081815260056020908152604080832094871680845294825291829020805460ff191686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b612085848484611d1e565b6120918484848461238c565b6116f85760405162461bcd60e51b815260040161099190613157565b6060816120d15750506040805180820190915260018152600360fc1b602082015290565b8160005b81156120fb57806120e5816133d7565b91506120f49050600a8361330f565b91506120d5565b60008167ffffffffffffffff81111561211657612116613474565b6040519080825280601f01601f191660200182016040528015612140576020820181803683370190505b5090505b8415611d1657612155600183613342565b9150612162600a866133f2565b61216d9060306132f7565b60f81b8183815181106121825761218261345e565b60200101906001600160f81b031916908160001a9053506121a4600a8661330f565b9450612144565b6001600160a01b0383166122065761220181600880546000838152600960205260408120829055600182018355919091527ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee30155565b612229565b816001600160a01b0316836001600160a01b031614612229576122298382612499565b6001600160a01b03821661224057610ac781612536565b826001600160a01b0316826001600160a01b031614610ac757610ac782826125e5565b60008060006122728585612629565b9150915061227f81612699565b509392505050565b6122918383612854565b61229e600084848461238c565b610ac75760405162461bcd60e51b815260040161099190613157565b600061230f826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166129a29092919063ffffffff16565b805190915015610ac7578080602001905181019061232d9190612eb1565b610ac75760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608401610991565b60006001600160a01b0384163b1561248e57604051630a85bd0160e11b81526001600160a01b0385169063150b7a02906123d0903390899088908890600401613107565b602060405180830381600087803b1580156123ea57600080fd5b505af192505050801561241a575060408051601f3d908101601f1916820190925261241791810190612eeb565b60015b612474573d808015612448576040519150601f19603f3d011682016040523d82523d6000602084013e61244d565b606091505b50805161246c5760405162461bcd60e51b815260040161099190613157565b805181602001fd5b6001600160e01b031916630a85bd0160e11b149050611d16565b506001949350505050565b600060016124a6846113e4565b6124b09190613342565b600083815260076020526040902054909150808214612503576001600160a01b03841660009081526006602090815260408083208584528252808320548484528184208190558352600790915290208190555b5060009182526007602090815260408084208490556001600160a01b039094168352600681528383209183525290812055565b60085460009061254890600190613342565b600083815260096020526040812054600880549394509092849081106125705761257061345e565b9060005260206000200154905080600883815481106125915761259161345e565b60009182526020808320909101929092558281526009909152604080822084905585825281205560088054806125c9576125c9613448565b6001900381819060005260206000200160009055905550505050565b60006125f0836113e4565b6001600160a01b039093166000908152600660209081526040808320868452825280832085905593825260079052919091209190915550565b6000808251604114156126605760208301516040840151606085015160001a612654878285856129b1565b94509450505050612692565b82516040141561268a576020830151604084015161267f868383612a9e565b935093505050612692565b506000905060025b9250929050565b60008160048111156126ad576126ad613432565b14156126b65750565b60018160048111156126ca576126ca613432565b14156127185760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e617475726500000000000000006044820152606401610991565b600281600481111561272c5761272c613432565b141561277a5760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e677468006044820152606401610991565b600381600481111561278e5761278e613432565b14156127e75760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b6064820152608401610991565b60048160048111156127fb576127fb613432565b14156119c75760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c604482015261756560f01b6064820152608401610991565b6001600160a01b0382166128aa5760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f20616464726573736044820152606401610991565b6000818152600260205260409020546001600160a01b03161561290f5760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e746564000000006044820152606401610991565b61291b600083836121ab565b6001600160a01b03821660009081526003602052604081208054600192906129449084906132f7565b909155505060008181526002602052604080822080546001600160a01b0319166001600160a01b03861690811790915590518392907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b6060611b048484600085612acd565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a08311156129e85750600090506003612a95565b8460ff16601b14158015612a0057508460ff16601c14155b15612a115750600090506004612a95565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa158015612a65573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b038116612a8e57600060019250925050612a95565b9150600090505b94509492505050565b6000806001600160ff1b03831660ff84901c601b01612abf878288856129b1565b935093505050935093915050565b606082471015612b2e5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b6064820152608401610991565b843b612b7c5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610991565b600080866001600160a01b03168587604051612b989190613044565b60006040518083038185875af1925050503d8060008114612bd5576040519150601f19603f3d011682016040523d82523d6000602084013e612bda565b606091505b5091509150612bea828286612bf5565b979650505050505050565b60608315612c04575081611b07565b825115612c145782518084602001fd5b8160405162461bcd60e51b81526004016109919190613144565b828054612c3a9061339c565b90600052602060002090601f016020900481019282612c5c5760008555612ca2565b82601f10612c755782800160ff19823516178555612ca2565b82800160010185558215612ca2579182015b82811115612ca2578235825591602001919060010190612c87565b50612cae929150612cb2565b5090565b5b80821115612cae5760008155600101612cb3565b600082601f830112612cd857600080fd5b813567ffffffffffffffff80821115612cf357612cf3613474565b604051601f8301601f19908116603f01168101908282118183101715612d1b57612d1b613474565b81604052838152866020858801011115612d3457600080fd5b836020870160208301376000602085830101528094505050505092915050565b600060208284031215612d6657600080fd5b8135611b078161348a565b60008060408385031215612d8457600080fd5b8235612d8f8161348a565b91506020830135612d9f8161348a565b809150509250929050565b600080600060608486031215612dbf57600080fd5b8335612dca8161348a565b92506020840135612dda8161348a565b929592945050506040919091013590565b60008060008060808587031215612e0157600080fd5b8435612e0c8161348a565b93506020850135612e1c8161348a565b925060408501359150606085013567ffffffffffffffff811115612e3f57600080fd5b612e4b87828801612cc7565b91505092959194509250565b60008060408385031215612e6a57600080fd5b8235612e758161348a565b91506020830135612d9f8161349f565b60008060408385031215612e9857600080fd5b8235612ea38161348a565b946020939093013593505050565b600060208284031215612ec357600080fd5b8151611b078161349f565b600060208284031215612ee057600080fd5b8135611b07816134ad565b600060208284031215612efd57600080fd5b8151611b07816134ad565b60008060208385031215612f1b57600080fd5b823567ffffffffffffffff80821115612f3357600080fd5b818501915085601f830112612f4757600080fd5b813581811115612f5657600080fd5b866020828501011115612f6857600080fd5b60209290920196919550909350505050565b600060208284031215612f8c57600080fd5b5035919050565b600060208284031215612fa557600080fd5b5051919050565b600080600060608486031215612fc157600080fd5b8335925060208401359150604084013567ffffffffffffffff811115612fe657600080fd5b612ff286828701612cc7565b9150509250925092565b60008151808452613014816020860160208601613359565b601f01601f19169290920160200192915050565b6000815161303a818560208601613359565b9290920192915050565b60008251613056818460208701613359565b9190910192915050565b600080845481600182811c91508083168061307c57607f831692505b602080841082141561309c57634e487b7160e01b86526022600452602486fd5b8180156130b057600181146130c1576130ee565b60ff198616895284890196506130ee565b60008b81526020902060005b868110156130e65781548b8201529085019083016130cd565b505084890196505b5050505050506130fe8185613028565b95945050505050565b6001600160a01b038581168252841660208201526040810183905260806060820181905260009061313a90830184612ffc565b9695505050505050565b602081526000611b076020830184612ffc565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b60208082526026908201527f5061796d656e7453706c69747465723a206163636f756e7420686173206e6f2060408201526573686172657360d01b606082015260800190565b6020808252601f908201527f45746865722076616c75652073656e74206973206e6f7420636f727265637400604082015260600190565b6020808252602b908201527f5061796d656e7453706c69747465723a206163636f756e74206973206e6f742060408201526a191d59481c185e5b595b9d60aa1b606082015260800190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b60208082526031908201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f6040820152701ddb995c881b9bdc88185c1c1c9bdd9959607a1b606082015260800190565b6000821982111561330a5761330a613406565b500190565b60008261331e5761331e61341c565b500490565b600081600019048311821515161561333d5761333d613406565b500290565b60008282101561335457613354613406565b500390565b60005b8381101561337457818101518382015260200161335c565b838111156116f85750506000910152565b60008161339457613394613406565b506000190190565b600181811c908216806133b057607f821691505b602082108114156133d157634e487b7160e01b600052602260045260246000fd5b50919050565b60006000198214156133eb576133eb613406565b5060010190565b6000826134015761340161341c565b500690565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052602160045260246000fd5b634e487b7160e01b600052603160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160a01b03811681146119c757600080fd5b80151581146119c757600080fd5b6001600160e01b0319811681146119c757600080fdfea2646970667358221220271a3da421666ee8506c2b82019e2bb44793d15a9ec1b630c8d65a3fb664e89364736f6c63430008070033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000140000000000000000000000000d5c4853eb42a7fbc4e3604088ab6acc3c396d7b30000000000000000000000000000000000000000000000000000000000000002000000000000000000000000a2c06202861105168e99da7f3ff5bc655ce16707000000000000000000000000ea14cdcd174257b3a6127e226ee145276e9cb8c00000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000005a000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000035697066733a2f2f516d5278686a7358446b763835324a3868526f746d5534414a643379525076766e78613941374e52794e707448630000000000000000000000
-----Decoded View---------------
Arg [0] : payees (address[]): 0xa2c06202861105168e99da7f3ff5Bc655ce16707,0xea14cdCd174257b3a6127E226EE145276e9cB8C0
Arg [1] : shares (uint256[]): 90,10
Arg [2] : initBaseURI (string): ipfs://QmRxhjsXDkv852J8hRotmU4AJd3yRPvvnxa9A7NRyNptHc
Arg [3] : signerAddress (address): 0xd5c4853eb42a7fBC4e3604088aB6AcC3C396d7b3
-----Encoded View---------------
13 Constructor Arguments found :
Arg [0] : 0000000000000000000000000000000000000000000000000000000000000080
Arg [1] : 00000000000000000000000000000000000000000000000000000000000000e0
Arg [2] : 0000000000000000000000000000000000000000000000000000000000000140
Arg [3] : 000000000000000000000000d5c4853eb42a7fbc4e3604088ab6acc3c396d7b3
Arg [4] : 0000000000000000000000000000000000000000000000000000000000000002
Arg [5] : 000000000000000000000000a2c06202861105168e99da7f3ff5bc655ce16707
Arg [6] : 000000000000000000000000ea14cdcd174257b3a6127e226ee145276e9cb8c0
Arg [7] : 0000000000000000000000000000000000000000000000000000000000000002
Arg [8] : 000000000000000000000000000000000000000000000000000000000000005a
Arg [9] : 000000000000000000000000000000000000000000000000000000000000000a
Arg [10] : 0000000000000000000000000000000000000000000000000000000000000035
Arg [11] : 697066733a2f2f516d5278686a7358446b763835324a3868526f746d5534414a
Arg [12] : 643379525076766e78613941374e52794e707448630000000000000000000000
Deployed Bytecode Sourcemap
378:4317:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3249:40:2;719:10:12;3249:40:2;;;-1:-1:-1;;;;;9663:32:17;;;9645:51;;3279:9:2;9727:2:17;9712:18;;9705:34;9618:18;3249:40:2;;;;;;;378:4317:0;;;;;990:222:8;;;;;;;;;;-1:-1:-1;990:222:8;;;;;:::i;:::-;;:::i;:::-;;;10698:14:17;;10691:22;10673:41;;10661:2;10646:18;990:222:8;;;;;;;;2473:98:5;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;3984:217::-;;;;;;;;;;-1:-1:-1;3984:217:5;;;;;:::i;:::-;;:::i;:::-;;;-1:-1:-1;;;;;9419:32:17;;;9401:51;;9389:2;9374:18;3984:217:5;9255:203:17;3522:401:5;;;;;;;;;;-1:-1:-1;3522:401:5;;;;;:::i;:::-;;:::i;:::-;;660:40:0;;;;;;;;;;;;699:1;660:40;;;;;26690:25:17;;;26678:2;26663:18;660:40:0;26544:177:17;833:30:0;;;;;;;;;;-1:-1:-1;833:30:0;;;;;;;;;;;1615:111:8;;;;;;;;;;-1:-1:-1;1702:10:8;:17;1615:111;;4977:553:2;;;;;;;;;;-1:-1:-1;4977:553:2;;;;;:::i;:::-;;:::i;554:43:0:-;;;;;;;;;;;;;;;;509:39;;;;;;;;;;;;544:4;509:39;;4711:330:5;;;;;;;;;;-1:-1:-1;4711:330:5;;;;;:::i;:::-;;:::i;1340:1101:0:-;;;;;;:::i;:::-;;:::i;1291:253:8:-;;;;;;;;;;-1:-1:-1;1291:253:8;;;;;:::i;:::-;;:::i;3951:85:0:-;;;;;;;;;;;;;:::i;3374:89:2:-;;;;;;;;;;-1:-1:-1;3444:12:2;;3374:89;;794:33:0;;;;;;;;;;-1:-1:-1;794:33:0;;;;;;;;4466:133:2;;;;;;;;;;-1:-1:-1;4466:133:2;;;;;:::i;:::-;-1:-1:-1;;;;;4562:21:2;;;4536:7;4562:21;;;:14;:21;;;;;;;;:30;;;;;;;;;;;;;4466:133;5107:179:5;;;;;;;;;;-1:-1:-1;5107:179:5;;;;;:::i;:::-;;:::i;5791:628:2:-;;;;;;;;;;-1:-1:-1;5791:628:2;;;;;:::i;:::-;;:::i;1798:230:8:-;;;;;;;;;;-1:-1:-1;1798:230:8;;;;;:::i;:::-;;:::i;869:28:0:-;;;;;;;;;;-1:-1:-1;869:28:0;;;;;;;;;;;4042:110;;;;;;;;;;-1:-1:-1;4042:110:0;;;;;:::i;:::-;;:::i;2176:235:5:-;;;;;;;;;;-1:-1:-1;2176:235:5;;;;;:::i;:::-;;:::i;706:46:0:-;;;;;;;;;;;;742:10;706:46;;4158:95;;;;;;;;;;-1:-1:-1;4158:95:0;;;;;:::i;:::-;;:::i;1914:205:5:-;;;;;;;;;;-1:-1:-1;1914:205:5;;;;;:::i;:::-;;:::i;1668:101:1:-;;;;;;;;;;;;;:::i;4685:98:2:-;;;;;;;;;;-1:-1:-1;4685:98:2;;;;;:::i;:::-;;:::i;1036:85:1:-;;;;;;;;;;-1:-1:-1;1108:6:1;;-1:-1:-1;;;;;1108:6:1;1036:85;;2447:590:0;;;;;;:::i;:::-;;:::i;2635:102:5:-;;;;;;;;;;;;;:::i;4196:107:2:-;;;;;;;;;;-1:-1:-1;4196:107:2;;;;;:::i;:::-;-1:-1:-1;;;;;4278:18:2;4252:7;4278:18;;;:9;:18;;;;;;;4196:107;4268:153:5;;;;;;;;;;-1:-1:-1;4268:153:5;;;;;:::i;:::-;;:::i;4259:69:0:-;;;;;;;;;;;;;:::i;5352:320:5:-;;;;;;;;;;-1:-1:-1;5352:320:5;;;;;:::i;:::-;;:::i;603:51:0:-;;;;;;;;;;;;653:1;603:51;;4334:359;;;;;;;;;;-1:-1:-1;4334:359:0;;;;;:::i;:::-;;:::i;3476:369::-;;;;;;;;;;-1:-1:-1;3476:369:0;;;;;:::i;:::-;;:::i;3999:103:2:-;;;;;;;;;;-1:-1:-1;3999:103:2;;;;;:::i;:::-;-1:-1:-1;;;;;4079:16:2;4053:7;4079:16;;;:7;:16;;;;;;;3999:103;3796:117;;;;;;;;;;-1:-1:-1;3796:117:2;;;;;:::i;:::-;-1:-1:-1;;;;;3880:26:2;3854:7;3880:26;;;:19;:26;;;;;;;3796:117;3552:93;;;;;;;;;;-1:-1:-1;3624:14:2;;3552:93;;4487:162:5;;;;;;;;;;-1:-1:-1;4487:162:5;;;;;:::i;:::-;-1:-1:-1;;;;;4607:25:5;;;4584:4;4607:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;;;4487:162;1918:198:1;;;;;;;;;;-1:-1:-1;1918:198:1;;;;;:::i;:::-;;:::i;3851:94:0:-;;;;;;;;;;;;;:::i;990:222:8:-;1092:4;-1:-1:-1;;;;;;1115:50:8;;-1:-1:-1;;;1115:50:8;;:90;;;1169:36;1193:11;1169:23;:36::i;:::-;1108:97;990:222;-1:-1:-1;;990:222:8:o;2473:98:5:-;2527:13;2559:5;2552:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2473:98;:::o;3984:217::-;4060:7;7232:16;;;:7;:16;;;;;;-1:-1:-1;;;;;7232:16:5;4079:73;;;;-1:-1:-1;;;4079:73:5;;21675:2:17;4079:73:5;;;21657:21:17;21714:2;21694:18;;;21687:30;21753:34;21733:18;;;21726:62;-1:-1:-1;;;21804:18:17;;;21797:42;21856:19;;4079:73:5;;;;;;;;;-1:-1:-1;4170:24:5;;;;:15;:24;;;;;;-1:-1:-1;;;;;4170:24:5;;3984:217::o;3522:401::-;3602:13;3618:23;3633:7;3618:14;:23::i;:::-;3602:39;;3665:5;-1:-1:-1;;;;;3659:11:5;:2;-1:-1:-1;;;;;3659:11:5;;;3651:57;;;;-1:-1:-1;;;3651:57:5;;23275:2:17;3651:57:5;;;23257:21:17;23314:2;23294:18;;;23287:30;23353:34;23333:18;;;23326:62;-1:-1:-1;;;23404:18:17;;;23397:31;23445:19;;3651:57:5;23073:397:17;3651:57:5;719:10:12;-1:-1:-1;;;;;3740:21:5;;;;:62;;-1:-1:-1;3765:37:5;3782:5;719:10:12;4487:162:5;:::i;3765:37::-;3719:165;;;;-1:-1:-1;;;3719:165:5;;19322:2:17;3719:165:5;;;19304:21:17;19361:2;19341:18;;;19334:30;19400:34;19380:18;;;19373:62;19471:26;19451:18;;;19444:54;19515:19;;3719:165:5;19120:420:17;3719:165:5;3895:21;3904:2;3908:7;3895:8;:21::i;:::-;3592:331;3522:401;;:::o;4977:553:2:-;-1:-1:-1;;;;;5052:16:2;;5071:1;5052:16;;;:7;:16;;;;;;5044:71;;;;-1:-1:-1;;;5044:71:2;;;;;;;:::i;:::-;5126:21;5174:15;3624:14;;;3552:93;5174:15;5150:39;;:21;:39;:::i;:::-;5126:63;;5199:15;5217:58;5233:7;5242:13;5257:17;5266:7;-1:-1:-1;;;;;4278:18:2;4252:7;4278:18;;;:9;:18;;;;;;;4196:107;5257:17;5217:15;:58::i;:::-;5199:76;-1:-1:-1;5294:12:2;5286:68;;;;-1:-1:-1;;;5286:68:2;;;;;;;:::i;:::-;-1:-1:-1;;;;;5365:18:2;;;;;;:9;:18;;;;;:29;;5387:7;;5365:18;:29;;5387:7;;5365:29;:::i;:::-;;;;;;;;5422:7;5404:14;;:25;;;;;;;:::i;:::-;;;;-1:-1:-1;5440:35:2;;-1:-1:-1;5458:7:2;5467;5440:17;:35::i;:::-;5490:33;;;-1:-1:-1;;;;;9663:32:17;;9645:51;;9727:2;9712:18;;9705:34;;;5490:33:2;;9618:18:17;5490:33:2;;;;;;;5034:496;;4977:553;:::o;4711:330:5:-;4900:41;719:10:12;4933:7:5;4900:18;:41::i;:::-;4892:103;;;;-1:-1:-1;;;4892:103:5;;;;;;;:::i;:::-;5006:28;5016:4;5022:2;5026:7;5006:9;:28::i;1340:1101:0:-;1454:13;;;;:28;;;;-1:-1:-1;1472:10:0;;;;;;;1471:11;1454:28;1446:62;;;;-1:-1:-1;;;1446:62:0;;25631:2:17;1446:62:0;;;25613:21:17;25670:2;25650:18;;;25643:30;-1:-1:-1;;;25689:18:17;;;25682:51;25750:18;;1446:62:0;25429:345:17;1446:62:0;1543:1;1526:14;:18;1518:58;;;;-1:-1:-1;;;1518:58:0;;23677:2:17;1518:58:0;;;23659:21:17;23716:2;23696:18;;;23689:30;23755:29;23735:18;;;23728:57;23802:18;;1518:58:0;23475:351:17;1518:58:0;1612:10;1594:29;;;;:17;:29;;;;;;653:1;;1594:46;;1626:14;;1594:46;:::i;:::-;:73;;1586:120;;;;-1:-1:-1;;;1586:120:0;;12677:2:17;1586:120:0;;;12659:21:17;12716:2;12696:18;;;12689:30;12755:34;12735:18;;;12728:62;-1:-1:-1;;;12806:18:17;;;12799:32;12848:19;;1586:120:0;12475:398:17;1586:120:0;1725:28;1737:4;1743:9;1725:11;:28::i;:::-;1717:55;;;;-1:-1:-1;;;1717:55:0;;21332:2:17;1717:55:0;;;21314:21:17;21371:2;21351:18;;;21344:30;-1:-1:-1;;;21390:18:17;;;21383:44;21444:18;;1717:55:0;21130:338:17;1717:55:0;3250:29;;;1806:10;6980:2:17;6976:15;-1:-1:-1;;6972:53:17;3250:29:0;;;;6960:66:17;;;;7042:12;;;;7035:28;;;3250:29:0;;;;;;;;;;7079:12:17;;;3250:29:0;;3240:40;;;;;;8902:66:17;3162:119:0;;;8890:79:17;8985:12;;;;8978:28;;;;3162:119:0;;;;;;;;;;9022:12:17;;;;3162:119:0;;;3152:139;;;;;1837:4;1790:51;1782:76;;;;-1:-1:-1;;;1782:76:0;;14271:2:17;1782:76:0;;;14253:21:17;14310:2;14290:18;;;14283:30;-1:-1:-1;;;14329:18:17;;;14322:42;14381:18;;1782:76:0;14069:336:17;1782:76:0;1887:10;1873:25;;;;:13;:25;;;;;;;;1869:259;;;1952:9;1922:26;1934:14;742:10;1922:26;:::i;:::-;:39;;1914:83;;;;-1:-1:-1;;;1914:83:0;;;;;;;:::i;:::-;1869:259;;;2072:9;2049:18;2066:1;2049:14;:18;:::i;:::-;2036:32;;742:10;2036:32;:::i;:::-;:45;;2028:89;;;;-1:-1:-1;;;2028:89:0;;;;;;;:::i;:::-;2142:9;2138:198;2162:14;2158:1;:18;2138:198;;;2197:17;2217:13;1702:10:8;:17;;1615:111;2217:13:0;:17;;2233:1;2217:17;:::i;:::-;2197:37;;2248:32;2258:10;2270:9;2248;:32::i;:::-;2312:10;2294:29;;;;:17;:29;;;;;:31;;;;;;:::i;:::-;;;;;;2183:153;2178:3;;;;;:::i;:::-;;;;2138:198;;;-1:-1:-1;2365:10:0;2351:25;;;;:13;:25;;;;;;;;2346:89;;2406:10;2392:25;;;;:13;:25;;;;;:32;;-1:-1:-1;;2392:32:0;2420:4;2392:32;;;1340:1101;;;:::o;1291:253:8:-;1388:7;1423:23;1440:5;1423:16;:23::i;:::-;1415:5;:31;1407:87;;;;-1:-1:-1;;;1407:87:8;;13440:2:17;1407:87:8;;;13422:21:17;13479:2;13459:18;;;13452:30;13518:34;13498:18;;;13491:62;-1:-1:-1;;;13569:18:17;;;13562:41;13620:19;;1407:87:8;13238:407:17;1407:87:8;-1:-1:-1;;;;;;1511:19:8;;;;;;;;:12;:19;;;;;;;;:26;;;;;;;;;1291:253::o;3951:85:0:-;1108:6:1;;-1:-1:-1;;;;;1108:6:1;719:10:12;1248:23:1;1240:68;;;;-1:-1:-1;;;1240:68:1;;;;;;;:::i;:::-;4019:10:0::1;::::0;;-1:-1:-1;;4005:24:0;::::1;4019:10;::::0;;;::::1;;;4018:11;4005:24:::0;;::::1;;::::0;;3951:85::o;5107:179:5:-;5240:39;5257:4;5263:2;5267:7;5240:39;;;;;;;;;;;;:16;:39::i;5791:628:2:-;-1:-1:-1;;;;;5872:16:2;;5891:1;5872:16;;;:7;:16;;;;;;5864:71;;;;-1:-1:-1;;;5864:71:2;;;;;;;:::i;:::-;-1:-1:-1;;;;;3880:26:2;;5946:21;3880:26;;;:19;:26;;;;;;5970:30;;-1:-1:-1;;;5970:30:2;;5994:4;5970:30;;;9401:51:17;-1:-1:-1;;;;;5970:15:2;;;;;9374:18:17;;5970:30:2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:53;;;;:::i;:::-;5946:77;;6033:15;6051:65;6067:7;6076:13;6091:24;6100:5;6107:7;-1:-1:-1;;;;;4562:21:2;;;4536:7;4562:21;;;:14;:21;;;;;;;;:30;;;;;;;;;;;;;4466:133;6051:65;6033:83;-1:-1:-1;6135:12:2;6127:68;;;;-1:-1:-1;;;6127:68:2;;;;;;;:::i;:::-;-1:-1:-1;;;;;6206:21:2;;;;;;;:14;:21;;;;;;;;:30;;;;;;;;;;;:41;;6240:7;;6206:21;:41;;6240:7;;6206:41;:::i;:::-;;;;-1:-1:-1;;;;;;;6257:26:2;;;;;;:19;:26;;;;;:37;;6287:7;;6257:26;:37;;6287:7;;6257:37;:::i;:::-;;;;-1:-1:-1;6305:47:2;;-1:-1:-1;6328:5:2;6335:7;6344;6305:22;:47::i;:::-;6367:45;;;-1:-1:-1;;;;;9663:32:17;;;9645:51;;9727:2;9712:18;;9705:34;;;6367:45:2;;;;;9618:18:17;6367:45:2;;;;;;;5854:565;;5791:628;;:::o;1798:230:8:-;1873:7;1908:30;1702:10;:17;;1615:111;1908:30;1900:5;:38;1892:95;;;;-1:-1:-1;;;1892:95:8;;25218:2:17;1892:95:8;;;25200:21:17;25257:2;25237:18;;;25230:30;25296:34;25276:18;;;25269:62;-1:-1:-1;;;25347:18:17;;;25340:42;25399:19;;1892:95:8;25016:408:17;1892:95:8;2004:10;2015:5;2004:17;;;;;;;;:::i;:::-;;;;;;;;;1997:24;;1798:230;;;:::o;4042:110:0:-;1108:6:1;;-1:-1:-1;;;;;1108:6:1;719:10:12;1248:23:1;1240:68;;;;-1:-1:-1;;;1240:68:1;;;;;;;:::i;:::-;4119:26:0::1;:13;4135:10:::0;;4119:26:::1;:::i;2176:235:5:-:0;2248:7;2283:16;;;:7;:16;;;;;;-1:-1:-1;;;;;2283:16:5;2317:19;2309:73;;;;-1:-1:-1;;;2309:73:5;;20158:2:17;2309:73:5;;;20140:21:17;20197:2;20177:18;;;20170:30;20236:34;20216:18;;;20209:62;-1:-1:-1;;;20287:18:17;;;20280:39;20336:19;;2309:73:5;19956:405:17;4158:95:0;1108:6:1;;-1:-1:-1;;;;;1108:6:1;719:10:12;1248:23:1;1240:68;;;;-1:-1:-1;;;1240:68:1;;;;;;;:::i;:::-;4226:7:0::1;:20:::0;;-1:-1:-1;;;;;;4226:20:0::1;-1:-1:-1::0;;;;;4226:20:0;;;::::1;::::0;;;::::1;::::0;;4158:95::o;1914:205:5:-;1986:7;-1:-1:-1;;;;;2013:19:5;;2005:74;;;;-1:-1:-1;;;2005:74:5;;19747:2:17;2005:74:5;;;19729:21:17;19786:2;19766:18;;;19759:30;19825:34;19805:18;;;19798:62;-1:-1:-1;;;19876:18:17;;;19869:40;19926:19;;2005:74:5;19545:406:17;2005:74:5;-1:-1:-1;;;;;;2096:16:5;;;;;:9;:16;;;;;;;1914:205::o;1668:101:1:-;1108:6;;-1:-1:-1;;;;;1108:6:1;719:10:12;1248:23:1;1240:68;;;;-1:-1:-1;;;1240:68:1;;;;;;;:::i;:::-;1732:30:::1;1759:1;1732:18;:30::i;:::-;1668:101::o:0;4685:98:2:-;4736:7;4762;4770:5;4762:14;;;;;;;;:::i;:::-;;;;;;;;;;;-1:-1:-1;;;;;4762:14:2;;4685:98;-1:-1:-1;;4685:98:2:o;2447:590:0:-;2524:10;;;;;;;2516:48;;;;-1:-1:-1;;;2516:48:0;;26392:2:17;2516:48:0;;;26374:21:17;26431:2;26411:18;;;26404:30;26470:27;26450:18;;;26443:55;26515:18;;2516:48:0;26190:349:17;2516:48:0;699:1;2582:14;:30;;2574:69;;;;-1:-1:-1;;;2574:69:0;;12322:2:17;2574:69:0;;;12304:21:17;12361:2;12341:18;;;12334:30;12400:28;12380:18;;;12373:56;12446:18;;2574:69:0;12120:350:17;2574:69:0;2706:23;;2695:34;;544:4;2695:34;:::i;:::-;2677:14;2661:13;1702:10:8;:17;;1615:111;2661:13:0;:30;;;;:::i;:::-;:68;;2653:121;;;;-1:-1:-1;;;2653:121:0;;24033:2:17;2653:121:0;;;24015:21:17;24072:2;24052:18;;;24045:30;24111:34;24091:18;;;24084:62;-1:-1:-1;;;24162:18:17;;;24155:38;24210:19;;2653:121:0;23831:404:17;2653:121:0;2822:9;2792:26;2804:14;742:10;2792:26;:::i;:::-;:39;;2784:83;;;;-1:-1:-1;;;2784:83:0;;;;;;;:::i;:::-;2882:9;2878:153;2902:14;2898:1;:18;2878:153;;;2937:17;2957:13;1702:10:8;:17;;1615:111;2957:13:0;:17;;2973:1;2957:17;:::i;:::-;2937:37;;2988:32;2998:10;3010:9;2988;:32::i;:::-;-1:-1:-1;2918:3:0;;;;:::i;:::-;;;;2878:153;;;;2447:590;:::o;2635:102:5:-;2691:13;2723:7;2716:14;;;;;:::i;4268:153::-;4362:52;719:10:12;4395:8:5;4405;4362:18;:52::i;4259:69:0:-;1108:6:1;;-1:-1:-1;;;;;1108:6:1;719:10:12;1248:23:1;1240:68;;;;-1:-1:-1;;;1240:68:1;;;;;;;:::i;:::-;4306:8:0::1;:15:::0;;-1:-1:-1;;4306:15:0::1;::::0;::::1;::::0;;4259:69::o;5352:320:5:-;5521:41;719:10:12;5554:7:5;5521:18;:41::i;:::-;5513:103;;;;-1:-1:-1;;;5513:103:5;;;;;;;:::i;:::-;5626:39;5640:4;5646:2;5650:7;5659:5;5626:13;:39::i;:::-;5352:320;;;;:::o;4334:359:0:-;7209:4:5;7232:16;;;:7;:16;;;;;;4407:13:0;;-1:-1:-1;;;;;7232:16:5;4432:76:0;;;;-1:-1:-1;;;4432:76:0;;22859:2:17;4432:76:0;;;22841:21:17;22898:2;22878:18;;;22871:30;22937:34;22917:18;;;22910:62;-1:-1:-1;;;22988:18:17;;;22981:45;23043:19;;4432:76:0;22657:411:17;4432:76:0;4522:8;;;;;;;4519:168;;4562:13;4555:20;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4334:359;;;:::o;4519:168::-;4637:13;4652:18;:7;:16;:18::i;:::-;4620:55;;;;;;;;;:::i;:::-;;;;;;;;;;;;;4606:70;;4334:359;;;:::o;3476:369::-;1108:6:1;;-1:-1:-1;;;;;1108:6:1;719:10:12;1248:23:1;1240:68;;;;-1:-1:-1;;;1240:68:1;;;;;;;:::i;:::-;3590:14:0::1;3563:23;;:41;;3555:89;;;::::0;-1:-1:-1;;;3555:89:0;;11918:2:17;3555:89:0::1;::::0;::::1;11900:21:17::0;11957:2;11937:18;;;11930:30;11996:34;11976:18;;;11969:62;-1:-1:-1;;;12047:18:17;;;12040:33;12090:19;;3555:89:0::1;11716:399:17::0;3555:89:0::1;3659:9;3655:184;3679:14;3675:1;:18;3655:184;;;3714:17;3734:13;1702:10:8::0;:17;;1615:111;3734:13:0::1;:17;::::0;3750:1:::1;3734:17;:::i;:::-;3714:37;;3765:24;3775:2;3779:9;3765;:24::i;:::-;3803:23;:25:::0;;;:23:::1;:25;::::0;::::1;:::i;:::-;;;;;;3700:139;3695:3;;;;;:::i;:::-;;;;3655:184;;1918:198:1::0;1108:6;;-1:-1:-1;;;;;1108:6:1;719:10:12;1248:23:1;1240:68;;;;-1:-1:-1;;;1240:68:1;;;;;;;:::i;:::-;-1:-1:-1;;;;;2006:22:1;::::1;1998:73;;;::::0;-1:-1:-1;;;1998:73:1;;14612:2:17;1998:73:1::1;::::0;::::1;14594:21:17::0;14651:2;14631:18;;;14624:30;14690:34;14670:18;;;14663:62;-1:-1:-1;;;14741:18:17;;;14734:36;14787:19;;1998:73:1::1;14410:402:17::0;1998:73:1::1;2081:28;2100:8;2081:18;:28::i;:::-;1918:198:::0;:::o;3851:94:0:-;1108:6:1;;-1:-1:-1;;;;;1108:6:1;719:10:12;1248:23:1;1240:68;;;;-1:-1:-1;;;1240:68:1;;;;;;;:::i;:::-;3925:13:0::1;::::0;;-1:-1:-1;;3908:30:0;::::1;3925:13;::::0;;::::1;3924:14;3908:30;::::0;;3851:94::o;1555:300:5:-;1657:4;-1:-1:-1;;;;;;1692:40:5;;-1:-1:-1;;;1692:40:5;;:104;;-1:-1:-1;;;;;;;1748:48:5;;-1:-1:-1;;;1748:48:5;1692:104;:156;;;-1:-1:-1;;;;;;;;;;937:40:15;;;1812:36:5;829:155:15;10995:171:5;11069:24;;;;:15;:24;;;;;:29;;-1:-1:-1;;;;;;11069:29:5;-1:-1:-1;;;;;11069:29:5;;;;;;;;:24;;11122:23;11069:24;11122:14;:23::i;:::-;-1:-1:-1;;;;;11113:46:5;;;;;;;;;;;10995:171;;:::o;6591:242:2:-;6796:12;;-1:-1:-1;;;;;6776:16:2;;6733:7;6776:16;;;:7;:16;;;;;;6733:7;;6811:15;;6760:32;;:13;:32;:::i;:::-;6759:49;;;;:::i;:::-;:67;;;;:::i;:::-;6752:74;;6591:242;;;;;;:::o;2065:312:11:-;2179:6;2154:21;:31;;2146:73;;;;-1:-1:-1;;;2146:73:11;;17732:2:17;2146:73:11;;;17714:21:17;17771:2;17751:18;;;17744:30;17810:31;17790:18;;;17783:59;17859:18;;2146:73:11;17530:353:17;2146:73:11;2231:12;2249:9;-1:-1:-1;;;;;2249:14:11;2271:6;2249:33;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2230:52;;;2300:7;2292:78;;;;-1:-1:-1;;;2292:78:11;;16902:2:17;2292:78:11;;;16884:21:17;16941:2;16921:18;;;16914:30;16980:34;16960:18;;;16953:62;17051:28;17031:18;;;17024:56;17097:19;;2292:78:11;16700:422:17;7427:344:5;7520:4;7232:16;;;:7;:16;;;;;;-1:-1:-1;;;;;7232:16:5;7536:73;;;;-1:-1:-1;;;7536:73:5;;18497:2:17;7536:73:5;;;18479:21:17;18536:2;18516:18;;;18509:30;18575:34;18555:18;;;18548:62;-1:-1:-1;;;18626:18:17;;;18619:42;18678:19;;7536:73:5;18295:408:17;7536:73:5;7619:13;7635:23;7650:7;7635:14;:23::i;:::-;7619:39;;7687:5;-1:-1:-1;;;;;7676:16:5;:7;-1:-1:-1;;;;;7676:16:5;;:51;;;;7720:7;-1:-1:-1;;;;;7696:31:5;:20;7708:7;7696:11;:20::i;:::-;-1:-1:-1;;;;;7696:31:5;;7676:51;:87;;;-1:-1:-1;;;;;;4607:25:5;;;4584:4;4607:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;7731:32;7668:96;7427:344;-1:-1:-1;;;;7427:344:5:o;10324:560::-;10478:4;-1:-1:-1;;;;;10451:31:5;:23;10466:7;10451:14;:23::i;:::-;-1:-1:-1;;;;;10451:31:5;;10443:85;;;;-1:-1:-1;;;10443:85:5;;22449:2:17;10443:85:5;;;22431:21:17;22488:2;22468:18;;;22461:30;22527:34;22507:18;;;22500:62;-1:-1:-1;;;22578:18:17;;;22571:39;22627:19;;10443:85:5;22247:405:17;10443:85:5;-1:-1:-1;;;;;10546:16:5;;10538:65;;;;-1:-1:-1;;;10538:65:5;;15783:2:17;10538:65:5;;;15765:21:17;15822:2;15802:18;;;15795:30;15861:34;15841:18;;;15834:62;-1:-1:-1;;;15912:18:17;;;15905:34;15956:19;;10538:65:5;15581:400:17;10538:65:5;10614:39;10635:4;10641:2;10645:7;10614:20;:39::i;:::-;10715:29;10732:1;10736:7;10715:8;:29::i;:::-;-1:-1:-1;;;;;10755:15:5;;;;;;:9;:15;;;;;:20;;10774:1;;10755:15;:20;;10774:1;;10755:20;:::i;:::-;;;;-1:-1:-1;;;;;;;10785:13:5;;;;;;:9;:13;;;;;:18;;10802:1;;10785:13;:18;;10802:1;;10785:18;:::i;:::-;;;;-1:-1:-1;;10813:16:5;;;;:7;:16;;;;;;:21;;-1:-1:-1;;;;;;10813:21:5;-1:-1:-1;;;;;10813:21:5;;;;;;;;;10850:27;;10813:16;;10850:27;;;;;;;10324:560;;;:::o;3326:144:0:-;3406:4;3440:23;:4;3453:9;3440:12;:23::i;:::-;3429:7;;-1:-1:-1;;;;;3429:34:0;;;:7;;:34;;3326:144;-1:-1:-1;;;3326:144:0:o;8101:108:5:-;8176:26;8186:2;8190:7;8176:26;;;;;;;;;;;;:9;:26::i;701:205:4:-;840:58;;;-1:-1:-1;;;;;9663:32:17;;840:58:4;;;9645:51:17;9712:18;;;;9705:34;;;840:58:4;;;;;;;;;;9618:18:17;;;;840:58:4;;;;;;;;-1:-1:-1;;;;;840:58:4;-1:-1:-1;;;840:58:4;;;813:86;;833:5;;813:19;:86::i;2270:187:1:-;2362:6;;;-1:-1:-1;;;;;2378:17:1;;;-1:-1:-1;;;;;;2378:17:1;;;;;;;2410:40;;2362:6;;;2378:17;2362:6;;2410:40;;2343:16;;2410:40;2333:124;2270:187;:::o;11301:307:5:-;11451:8;-1:-1:-1;;;;;11442:17:5;:5;-1:-1:-1;;;;;11442:17:5;;;11434:55;;;;-1:-1:-1;;;11434:55:5;;16188:2:17;11434:55:5;;;16170:21:17;16227:2;16207:18;;;16200:30;16266:27;16246:18;;;16239:55;16311:18;;11434:55:5;15986:349:17;11434:55:5;-1:-1:-1;;;;;11499:25:5;;;;;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;:46;;-1:-1:-1;;11499:46:5;;;;;;;;;;11560:41;;10673::17;;;11560::5;;10646:18:17;11560:41:5;;;;;;;11301:307;;;:::o;6534:::-;6685:28;6695:4;6701:2;6705:7;6685:9;:28::i;:::-;6731:48;6754:4;6760:2;6764:7;6773:5;6731:22;:48::i;:::-;6723:111;;;;-1:-1:-1;;;6723:111:5;;;;;;;:::i;328:703:13:-;384:13;601:10;597:51;;-1:-1:-1;;627:10:13;;;;;;;;;;;;-1:-1:-1;;;627:10:13;;;;;328:703::o;597:51::-;672:5;657:12;711:75;718:9;;711:75;;743:8;;;;:::i;:::-;;-1:-1:-1;765:10:13;;-1:-1:-1;773:2:13;765:10;;:::i;:::-;;;711:75;;;795:19;827:6;817:17;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;817:17:13;;795:39;;844:150;851:10;;844:150;;877:11;887:1;877:11;;:::i;:::-;;-1:-1:-1;945:10:13;953:2;945:5;:10;:::i;:::-;932:24;;:2;:24;:::i;:::-;919:39;;902:6;909;902:14;;;;;;;;:::i;:::-;;;;:56;-1:-1:-1;;;;;902:56:13;;;;;;;;-1:-1:-1;972:11:13;981:2;972:11;;:::i;:::-;;;844:150;;2624:572:8;-1:-1:-1;;;;;2823:18:8;;2819:183;;2857:40;2889:7;4005:10;:17;;3978:24;;;;:15;:24;;;;;:44;;;4032:24;;;;;;;;;;;;3902:161;2857:40;2819:183;;;2926:2;-1:-1:-1;;;;;2918:10:8;:4;-1:-1:-1;;;;;2918:10:8;;2914:88;;2944:47;2977:4;2983:7;2944:32;:47::i;:::-;-1:-1:-1;;;;;3015:16:8;;3011:179;;3047:45;3084:7;3047:36;:45::i;3011:179::-;3119:4;-1:-1:-1;;;;;3113:10:8;:2;-1:-1:-1;;;;;3113:10:8;;3109:81;;3139:40;3167:2;3171:7;3139:27;:40::i;4293:227:14:-;4371:7;4391:17;4410:18;4432:27;4443:4;4449:9;4432:10;:27::i;:::-;4390:69;;;;4469:18;4481:5;4469:11;:18::i;:::-;-1:-1:-1;4504:9:14;4293:227;-1:-1:-1;;;4293:227:14:o;8430:311:5:-;8555:18;8561:2;8565:7;8555:5;:18::i;:::-;8604:54;8635:1;8639:2;8643:7;8652:5;8604:22;:54::i;:::-;8583:151;;;;-1:-1:-1;;;8583:151:5;;;;;;;:::i;3207:706:4:-;3626:23;3652:69;3680:4;3652:69;;;;;;;;;;;;;;;;;3660:5;-1:-1:-1;;;;;3652:27:4;;;:69;;;;;:::i;:::-;3735:17;;3626:95;;-1:-1:-1;3735:21:4;3731:176;;3830:10;3819:30;;;;;;;;;;;;:::i;:::-;3811:85;;;;-1:-1:-1;;;3811:85:4;;25981:2:17;3811:85:4;;;25963:21:17;26020:2;26000:18;;;25993:30;26059:34;26039:18;;;26032:62;-1:-1:-1;;;26110:18:17;;;26103:40;26160:19;;3811:85:4;25779:406:17;12161:778:5;12311:4;-1:-1:-1;;;;;12331:13:5;;1087:20:11;1133:8;12327:606:5;;12366:72;;-1:-1:-1;;;12366:72:5;;-1:-1:-1;;;;;12366:36:5;;;;;:72;;719:10:12;;12417:4:5;;12423:7;;12432:5;;12366:72;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;12366:72:5;;;;;;;;-1:-1:-1;;12366:72:5;;;;;;;;;;;;:::i;:::-;;;12362:519;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;12605:13:5;;12601:266;;12647:60;;-1:-1:-1;;;12647:60:5;;;;;;;:::i;12601:266::-;12819:6;12813:13;12804:6;12800:2;12796:15;12789:38;12362:519;-1:-1:-1;;;;;;12488:51:5;-1:-1:-1;;;12488:51:5;;-1:-1:-1;12481:58:5;;12327:606;-1:-1:-1;12918:4:5;12161:778;;;;;;:::o;4680:970:8:-;4942:22;4992:1;4967:22;4984:4;4967:16;:22::i;:::-;:26;;;;:::i;:::-;5003:18;5024:26;;;:17;:26;;;;;;4942:51;;-1:-1:-1;5154:28:8;;;5150:323;;-1:-1:-1;;;;;5220:18:8;;5198:19;5220:18;;;:12;:18;;;;;;;;:34;;;;;;;;;5269:30;;;;;;:44;;;5385:30;;:17;:30;;;;;:43;;;5150:323;-1:-1:-1;5566:26:8;;;;:17;:26;;;;;;;;5559:33;;;-1:-1:-1;;;;;5609:18:8;;;;;:12;:18;;;;;:34;;;;;;;5602:41;4680:970::o;5938:1061::-;6212:10;:17;6187:22;;6212:21;;6232:1;;6212:21;:::i;:::-;6243:18;6264:24;;;:15;:24;;;;;;6632:10;:26;;6187:46;;-1:-1:-1;6264:24:8;;6187:46;;6632:26;;;;;;:::i;:::-;;;;;;;;;6610:48;;6694:11;6669:10;6680;6669:22;;;;;;;;:::i;:::-;;;;;;;;;;;;:36;;;;6773:28;;;:15;:28;;;;;;;:41;;;6942:24;;;;;6935:31;6976:10;:16;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;6009:990;;;5938:1061;:::o;3490:217::-;3574:14;3591:20;3608:2;3591:16;:20::i;:::-;-1:-1:-1;;;;;3621:16:8;;;;;;;:12;:16;;;;;;;;:24;;;;;;;;:34;;;3665:26;;;:17;:26;;;;;;:35;;;;-1:-1:-1;3490:217:8:o;2228:1279:14:-;2309:7;2318:12;2539:9;:16;2559:2;2539:22;2535:966;;;2828:4;2813:20;;2807:27;2877:4;2862:20;;2856:27;2934:4;2919:20;;2913:27;2577:9;2905:36;2975:25;2986:4;2905:36;2807:27;2856;2975:10;:25::i;:::-;2968:32;;;;;;;;;2535:966;3021:9;:16;3041:2;3021:22;3017:484;;;3290:4;3275:20;;3269:27;3340:4;3325:20;;3319:27;3380:23;3391:4;3269:27;3319;3380:10;:23::i;:::-;3373:30;;;;;;;;3017:484;-1:-1:-1;3450:1:14;;-1:-1:-1;3454:35:14;3017:484;2228:1279;;;;;:::o;533:631::-;610:20;601:5;:29;;;;;;;;:::i;:::-;;597:561;;;533:631;:::o;597:561::-;706:29;697:5;:38;;;;;;;;:::i;:::-;;693:465;;;751:34;;-1:-1:-1;;;751:34:14;;11565:2:17;751:34:14;;;11547:21:17;11604:2;11584:18;;;11577:30;11643:26;11623:18;;;11616:54;11687:18;;751:34:14;11363:348:17;693:465:14;815:35;806:5;:44;;;;;;;;:::i;:::-;;802:356;;;866:41;;-1:-1:-1;;;866:41:14;;13080:2:17;866:41:14;;;13062:21:17;13119:2;13099:18;;;13092:30;13158:33;13138:18;;;13131:61;13209:18;;866:41:14;12878:355:17;802:356:14;937:30;928:5;:39;;;;;;;;:::i;:::-;;924:234;;;983:44;;-1:-1:-1;;;983:44:14;;17329:2:17;983:44:14;;;17311:21:17;17368:2;17348:18;;;17341:30;17407:34;17387:18;;;17380:62;-1:-1:-1;;;17458:18:17;;;17451:32;17500:19;;983:44:14;17127:398:17;924:234:14;1057:30;1048:5;:39;;;;;;;;:::i;:::-;;1044:114;;;1103:44;;-1:-1:-1;;;1103:44:14;;20568:2:17;1103:44:14;;;20550:21:17;20607:2;20587:18;;;20580:30;20646:34;20626:18;;;20619:62;-1:-1:-1;;;20697:18:17;;;20690:32;20739:19;;1103:44:14;20366:398:17;9063:372:5;-1:-1:-1;;;;;9142:16:5;;9134:61;;;;-1:-1:-1;;;9134:61:5;;20971:2:17;9134:61:5;;;20953:21:17;;;20990:18;;;20983:30;21049:34;21029:18;;;21022:62;21101:18;;9134:61:5;20769:356:17;9134:61:5;7209:4;7232:16;;;:7;:16;;;;;;-1:-1:-1;;;;;7232:16:5;:30;9205:58;;;;-1:-1:-1;;;9205:58:5;;15019:2:17;9205:58:5;;;15001:21:17;15058:2;15038:18;;;15031:30;15097;15077:18;;;15070:58;15145:18;;9205:58:5;14817:352:17;9205:58:5;9274:45;9303:1;9307:2;9311:7;9274:20;:45::i;:::-;-1:-1:-1;;;;;9330:13:5;;;;;;:9;:13;;;;;:18;;9347:1;;9330:13;:18;;9347:1;;9330:18;:::i;:::-;;;;-1:-1:-1;;9358:16:5;;;;:7;:16;;;;;;:21;;-1:-1:-1;;;;;;9358:21:5;-1:-1:-1;;;;;9358:21:5;;;;;;;;9395:33;;9358:16;;;9395:33;;9358:16;;9395:33;9063:372;;:::o;3514:223:11:-;3647:12;3678:52;3700:6;3708:4;3714:1;3717:12;3678:21;:52::i;5744:1603:14:-;5870:7;;6794:66;6781:79;;6777:161;;;-1:-1:-1;6892:1:14;;-1:-1:-1;6896:30:14;6876:51;;6777:161;6951:1;:7;;6956:2;6951:7;;:18;;;;;6962:1;:7;;6967:2;6962:7;;6951:18;6947:100;;;-1:-1:-1;7001:1:14;;-1:-1:-1;7005:30:14;6985:51;;6947:100;7158:24;;;7141:14;7158:24;;;;;;;;;10952:25:17;;;11025:4;11013:17;;10993:18;;;10986:45;;;;11047:18;;;11040:34;;;11090:18;;;11083:34;;;7158:24:14;;10924:19:17;;7158:24:14;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;7158:24:14;;-1:-1:-1;;7158:24:14;;;-1:-1:-1;;;;;;;7196:20:14;;7192:101;;7248:1;7252:29;7232:50;;;;;;;7192:101;7311:6;-1:-1:-1;7319:20:14;;-1:-1:-1;5744:1603:14;;;;;;;;:::o;4774:379::-;4884:7;;-1:-1:-1;;;;;4981:75:14;;5082:3;5078:12;;;5092:2;5074:21;5121:25;5132:4;5074:21;5141:1;4981:75;5121:10;:25::i;:::-;5114:32;;;;;;4774:379;;;;;;:::o;4601:499:11:-;4766:12;4823:5;4798:21;:30;;4790:81;;;;-1:-1:-1;;;4790:81:11;;18090:2:17;4790:81:11;;;18072:21:17;18129:2;18109:18;;;18102:30;18168:34;18148:18;;;18141:62;-1:-1:-1;;;18219:18:17;;;18212:36;18265:19;;4790:81:11;17888:402:17;4790:81:11;1087:20;;4881:60;;;;-1:-1:-1;;;4881:60:11;;24860:2:17;4881:60:11;;;24842:21:17;24899:2;24879:18;;;24872:30;24938:31;24918:18;;;24911:59;24987:18;;4881:60:11;24658:353:17;4881:60:11;4953:12;4967:23;4994:6;-1:-1:-1;;;;;4994:11:11;5013:5;5020:4;4994:31;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4952:73;;;;5042:51;5059:7;5068:10;5080:12;5042:16;:51::i;:::-;5035:58;4601:499;-1:-1:-1;;;;;;;4601:499:11:o;7214:692::-;7360:12;7388:7;7384:516;;;-1:-1:-1;7418:10:11;7411:17;;7384:516;7529:17;;:21;7525:365;;7723:10;7717:17;7783:15;7770:10;7766:2;7762:19;7755:44;7525:365;7862:12;7855:20;;-1:-1:-1;;;7855:20:11;;;;;;;;:::i;-1:-1:-1:-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;14:718:17;56:5;109:3;102:4;94:6;90:17;86:27;76:55;;127:1;124;117:12;76:55;163:6;150:20;189:18;226:2;222;219:10;216:36;;;232:18;;:::i;:::-;307:2;301:9;275:2;361:13;;-1:-1:-1;;357:22:17;;;381:2;353:31;349:40;337:53;;;405:18;;;425:22;;;402:46;399:72;;;451:18;;:::i;:::-;491:10;487:2;480:22;526:2;518:6;511:18;572:3;565:4;560:2;552:6;548:15;544:26;541:35;538:55;;;589:1;586;579:12;538:55;653:2;646:4;638:6;634:17;627:4;619:6;615:17;602:54;700:1;693:4;688:2;680:6;676:15;672:26;665:37;720:6;711:15;;;;;;14:718;;;;:::o;737:247::-;796:6;849:2;837:9;828:7;824:23;820:32;817:52;;;865:1;862;855:12;817:52;904:9;891:23;923:31;948:5;923:31;:::i;1249:388::-;1317:6;1325;1378:2;1366:9;1357:7;1353:23;1349:32;1346:52;;;1394:1;1391;1384:12;1346:52;1433:9;1420:23;1452:31;1477:5;1452:31;:::i;:::-;1502:5;-1:-1:-1;1559:2:17;1544:18;;1531:32;1572:33;1531:32;1572:33;:::i;:::-;1624:7;1614:17;;;1249:388;;;;;:::o;1642:456::-;1719:6;1727;1735;1788:2;1776:9;1767:7;1763:23;1759:32;1756:52;;;1804:1;1801;1794:12;1756:52;1843:9;1830:23;1862:31;1887:5;1862:31;:::i;:::-;1912:5;-1:-1:-1;1969:2:17;1954:18;;1941:32;1982:33;1941:32;1982:33;:::i;:::-;1642:456;;2034:7;;-1:-1:-1;;;2088:2:17;2073:18;;;;2060:32;;1642:456::o;2103:665::-;2198:6;2206;2214;2222;2275:3;2263:9;2254:7;2250:23;2246:33;2243:53;;;2292:1;2289;2282:12;2243:53;2331:9;2318:23;2350:31;2375:5;2350:31;:::i;:::-;2400:5;-1:-1:-1;2457:2:17;2442:18;;2429:32;2470:33;2429:32;2470:33;:::i;:::-;2522:7;-1:-1:-1;2576:2:17;2561:18;;2548:32;;-1:-1:-1;2631:2:17;2616:18;;2603:32;2658:18;2647:30;;2644:50;;;2690:1;2687;2680:12;2644:50;2713:49;2754:7;2745:6;2734:9;2730:22;2713:49;:::i;:::-;2703:59;;;2103:665;;;;;;;:::o;2773:382::-;2838:6;2846;2899:2;2887:9;2878:7;2874:23;2870:32;2867:52;;;2915:1;2912;2905:12;2867:52;2954:9;2941:23;2973:31;2998:5;2973:31;:::i;:::-;3023:5;-1:-1:-1;3080:2:17;3065:18;;3052:32;3093:30;3052:32;3093:30;:::i;3160:315::-;3228:6;3236;3289:2;3277:9;3268:7;3264:23;3260:32;3257:52;;;3305:1;3302;3295:12;3257:52;3344:9;3331:23;3363:31;3388:5;3363:31;:::i;:::-;3413:5;3465:2;3450:18;;;;3437:32;;-1:-1:-1;;;3160:315:17:o;3480:245::-;3547:6;3600:2;3588:9;3579:7;3575:23;3571:32;3568:52;;;3616:1;3613;3606:12;3568:52;3648:9;3642:16;3667:28;3689:5;3667:28;:::i;3730:245::-;3788:6;3841:2;3829:9;3820:7;3816:23;3812:32;3809:52;;;3857:1;3854;3847:12;3809:52;3896:9;3883:23;3915:30;3939:5;3915:30;:::i;3980:249::-;4049:6;4102:2;4090:9;4081:7;4077:23;4073:32;4070:52;;;4118:1;4115;4108:12;4070:52;4150:9;4144:16;4169:30;4193:5;4169:30;:::i;4909:592::-;4980:6;4988;5041:2;5029:9;5020:7;5016:23;5012:32;5009:52;;;5057:1;5054;5047:12;5009:52;5097:9;5084:23;5126:18;5167:2;5159:6;5156:14;5153:34;;;5183:1;5180;5173:12;5153:34;5221:6;5210:9;5206:22;5196:32;;5266:7;5259:4;5255:2;5251:13;5247:27;5237:55;;5288:1;5285;5278:12;5237:55;5328:2;5315:16;5354:2;5346:6;5343:14;5340:34;;;5370:1;5367;5360:12;5340:34;5415:7;5410:2;5401:6;5397:2;5393:15;5389:24;5386:37;5383:57;;;5436:1;5433;5426:12;5383:57;5467:2;5459:11;;;;;5489:6;;-1:-1:-1;4909:592:17;;-1:-1:-1;;;;4909:592:17:o;5506:180::-;5565:6;5618:2;5606:9;5597:7;5593:23;5589:32;5586:52;;;5634:1;5631;5624:12;5586:52;-1:-1:-1;5657:23:17;;5506:180;-1:-1:-1;5506:180:17:o;5691:184::-;5761:6;5814:2;5802:9;5793:7;5789:23;5785:32;5782:52;;;5830:1;5827;5820:12;5782:52;-1:-1:-1;5853:16:17;;5691:184;-1:-1:-1;5691:184:17:o;5880:456::-;5966:6;5974;5982;6035:2;6023:9;6014:7;6010:23;6006:32;6003:52;;;6051:1;6048;6041:12;6003:52;6087:9;6074:23;6064:33;;6144:2;6133:9;6129:18;6116:32;6106:42;;6199:2;6188:9;6184:18;6171:32;6226:18;6218:6;6215:30;6212:50;;;6258:1;6255;6248:12;6212:50;6281:49;6322:7;6313:6;6302:9;6298:22;6281:49;:::i;:::-;6271:59;;;5880:456;;;;;:::o;6341:268::-;6393:3;6431:5;6425:12;6458:6;6453:3;6446:19;6474:63;6530:6;6523:4;6518:3;6514:14;6507:4;6500:5;6496:16;6474:63;:::i;:::-;6591:2;6570:15;-1:-1:-1;;6566:29:17;6557:39;;;;6598:4;6553:50;;6341:268;-1:-1:-1;;6341:268:17:o;6614:184::-;6655:3;6693:5;6687:12;6708:52;6753:6;6748:3;6741:4;6734:5;6730:16;6708:52;:::i;:::-;6776:16;;;;;6614:184;-1:-1:-1;;6614:184:17:o;7102:274::-;7231:3;7269:6;7263:13;7285:53;7331:6;7326:3;7319:4;7311:6;7307:17;7285:53;:::i;:::-;7354:16;;;;;7102:274;-1:-1:-1;;7102:274:17:o;7381:1274::-;7658:3;7687:1;7720:6;7714:13;7750:3;7772:1;7800:9;7796:2;7792:18;7782:28;;7860:2;7849:9;7845:18;7882;7872:61;;7926:4;7918:6;7914:17;7904:27;;7872:61;7952:2;8000;7992:6;7989:14;7969:18;7966:38;7963:165;;;-1:-1:-1;;;8027:33:17;;8083:4;8080:1;8073:15;8113:4;8034:3;8101:17;7963:165;8144:18;8171:104;;;;8289:1;8284:320;;;;8137:467;;8171:104;-1:-1:-1;;8204:24:17;;8192:37;;8249:16;;;;-1:-1:-1;8171:104:17;;8284:320;26799:1;26792:14;;;26836:4;26823:18;;8379:1;8393:165;8407:6;8404:1;8401:13;8393:165;;;8485:14;;8472:11;;;8465:35;8528:16;;;;8422:10;;8393:165;;;8397:3;;8587:6;8582:3;8578:16;8571:23;;8137:467;;;;;;;8620:29;8645:3;8637:6;8620:29;:::i;:::-;8613:36;7381:1274;-1:-1:-1;;;;;7381:1274:17:o;9750:499::-;-1:-1:-1;;;;;10019:15:17;;;10001:34;;10071:15;;10066:2;10051:18;;10044:43;10118:2;10103:18;;10096:34;;;10166:3;10161:2;10146:18;;10139:31;;;9944:4;;10187:56;;10223:19;;10215:6;10187:56;:::i;:::-;10179:64;9750:499;-1:-1:-1;;;;;;9750:499:17:o;11128:230::-;11277:2;11266:9;11259:21;11240:4;11297:55;11348:2;11337:9;11333:18;11325:6;11297:55;:::i;13650:414::-;13852:2;13834:21;;;13891:2;13871:18;;;13864:30;13930:34;13925:2;13910:18;;13903:62;-1:-1:-1;;;13996:2:17;13981:18;;13974:48;14054:3;14039:19;;13650:414::o;15174:402::-;15376:2;15358:21;;;15415:2;15395:18;;;15388:30;15454:34;15449:2;15434:18;;15427:62;-1:-1:-1;;;15520:2:17;15505:18;;15498:36;15566:3;15551:19;;15174:402::o;16340:355::-;16542:2;16524:21;;;16581:2;16561:18;;;16554:30;16620:33;16615:2;16600:18;;16593:61;16686:2;16671:18;;16340:355::o;18708:407::-;18910:2;18892:21;;;18949:2;18929:18;;;18922:30;18988:34;18983:2;18968:18;;18961:62;-1:-1:-1;;;19054:2:17;19039:18;;19032:41;19105:3;19090:19;;18708:407::o;21886:356::-;22088:2;22070:21;;;22107:18;;;22100:30;22166:34;22161:2;22146:18;;22139:62;22233:2;22218:18;;21886:356::o;24240:413::-;24442:2;24424:21;;;24481:2;24461:18;;;24454:30;24520:34;24515:2;24500:18;;24493:62;-1:-1:-1;;;24586:2:17;24571:18;;24564:47;24643:3;24628:19;;24240:413::o;26852:128::-;26892:3;26923:1;26919:6;26916:1;26913:13;26910:39;;;26929:18;;:::i;:::-;-1:-1:-1;26965:9:17;;26852:128::o;26985:120::-;27025:1;27051;27041:35;;27056:18;;:::i;:::-;-1:-1:-1;27090:9:17;;26985:120::o;27110:168::-;27150:7;27216:1;27212;27208:6;27204:14;27201:1;27198:21;27193:1;27186:9;27179:17;27175:45;27172:71;;;27223:18;;:::i;:::-;-1:-1:-1;27263:9:17;;27110:168::o;27283:125::-;27323:4;27351:1;27348;27345:8;27342:34;;;27356:18;;:::i;:::-;-1:-1:-1;27393:9:17;;27283:125::o;27413:258::-;27485:1;27495:113;27509:6;27506:1;27503:13;27495:113;;;27585:11;;;27579:18;27566:11;;;27559:39;27531:2;27524:10;27495:113;;;27626:6;27623:1;27620:13;27617:48;;;-1:-1:-1;;27661:1:17;27643:16;;27636:27;27413:258::o;27676:136::-;27715:3;27743:5;27733:39;;27752:18;;:::i;:::-;-1:-1:-1;;;27788:18:17;;27676:136::o;27817:380::-;27896:1;27892:12;;;;27939;;;27960:61;;28014:4;28006:6;28002:17;27992:27;;27960:61;28067:2;28059:6;28056:14;28036:18;28033:38;28030:161;;;28113:10;28108:3;28104:20;28101:1;28094:31;28148:4;28145:1;28138:15;28176:4;28173:1;28166:15;28030:161;;27817:380;;;:::o;28202:135::-;28241:3;-1:-1:-1;;28262:17:17;;28259:43;;;28282:18;;:::i;:::-;-1:-1:-1;28329:1:17;28318:13;;28202:135::o;28342:112::-;28374:1;28400;28390:35;;28405:18;;:::i;:::-;-1:-1:-1;28439:9:17;;28342:112::o;28459:127::-;28520:10;28515:3;28511:20;28508:1;28501:31;28551:4;28548:1;28541:15;28575:4;28572:1;28565:15;28591:127;28652:10;28647:3;28643:20;28640:1;28633:31;28683:4;28680:1;28673:15;28707:4;28704:1;28697:15;28723:127;28784:10;28779:3;28775:20;28772:1;28765:31;28815:4;28812:1;28805:15;28839:4;28836:1;28829:15;28855:127;28916:10;28911:3;28907:20;28904:1;28897:31;28947:4;28944:1;28937:15;28971:4;28968:1;28961:15;28987:127;29048:10;29043:3;29039:20;29036:1;29029:31;29079:4;29076:1;29069:15;29103:4;29100:1;29093:15;29119:127;29180:10;29175:3;29171:20;29168:1;29161:31;29211:4;29208:1;29201:15;29235:4;29232:1;29225:15;29251:131;-1:-1:-1;;;;;29326:31:17;;29316:42;;29306:70;;29372:1;29369;29362:12;29387:118;29473:5;29466:13;29459:21;29452:5;29449:32;29439:60;;29495:1;29492;29485:12;29510:131;-1:-1:-1;;;;;;29584:32:17;;29574:43;;29564:71;;29631:1;29628;29621:12
Swarm Source
ipfs://271a3da421666ee8506c2b82019e2bb44793d15a9ec1b630c8d65a3fb664e893
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|---|---|---|---|---|
ETH | Ether (ETH) | 100.00% | $3,465.04 | 0.044 | $152.46 |
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.