ERC-721
Overview
Max Total Supply
6,556 FRNDS
Holders
833
Market
Volume (24H)
N/A
Min Price (24H)
N/A
Max Price (24H)
N/A
Other Info
Token Contract
Balance
1 FRNDSLoading...
Loading
Loading...
Loading
Loading...
Loading
# | Exchange | Pair | Price | 24H Volume | % Volume |
---|
Contract Name:
Frnds
Compiler Version
v0.8.7+commit.e28d00a7
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "@openzeppelin/contracts/access/Ownable.sol"; import "@openzeppelin/contracts/finance/PaymentSplitter.sol"; import "@openzeppelin/contracts/utils/cryptography/MerkleProof.sol"; import "erc721a/contracts/ERC721A.sol"; /// @author no-op.eth (nft-lab.xyz) /// @title Frnds Club contract Frnds is ERC721A, PaymentSplitter, Ownable { /** Maximum number of tokens per tx */ uint256 public constant MAX_TX = 10; /** Maximum amount of tokens in collection */ uint256 public constant MAX_SUPPLY = 6556; /** Price per token */ uint256 public cost = 0.038 ether; /** Base URI */ string public baseURI; /** Merkle tree for whitelist */ bytes32 public merkleRoot; /** Whitelist max per wallet */ uint256 public constant MAX_PER_WHITELIST = 5; /** Public sale state */ bool public saleActive = false; /** Presale state */ bool public presaleActive = false; /** Notify on sale state change */ event SaleStateChanged(bool _val); /** Notify on presale state change */ event PresaleStateChanged(bool _val); /** Notify on total supply change */ event TotalSupplyChanged(uint256 _val); constructor( string memory _name, string memory _symbol, address[] memory _shareholders, uint256[] memory _shares ) ERC721A(_name, _symbol) PaymentSplitter(_shareholders, _shares) {} /// @notice Returns the base URI function _baseURI() internal view virtual override returns (string memory) { return baseURI; } /// @notice Checks if an address is whitelisted /// @param _addr Address to check /// @param _proof Merkle proof function isWhitelisted(address _addr, bytes32[] calldata _proof) public view returns (bool) { bytes32 _leaf = keccak256(abi.encodePacked(_addr)); return MerkleProof.verify(_proof, merkleRoot, _leaf); } /// @notice Sets public sale state /// @param _val New sale state function setSaleState(bool _val) external onlyOwner { saleActive = _val; emit SaleStateChanged(_val); } /// @notice Sets presale state /// @param _val New presale state function setPresaleState(bool _val) external onlyOwner { presaleActive = _val; emit PresaleStateChanged(_val); } /// @notice Sets the whitelist /// @param _val Root function setWhitelist(bytes32 _val) external onlyOwner { merkleRoot = _val; } /// @notice Sets the price /// @param _val New price function setCost(uint256 _val) external onlyOwner { cost = _val; } /// @notice Sets the base metadata URI /// @param _val The new URI function setBaseURI(string calldata _val) external onlyOwner { baseURI = _val; } /// @notice Reserves a set of NFTs for collection owner (giveaways, etc) /// @param _amt The amount to reserve function reserve(uint256 _amt) external onlyOwner { _mint(msg.sender, _amt); emit TotalSupplyChanged(totalSupply()); } /// @notice Mints a new token in presale /// @param _amt The number of tokens to mint /// @param _proof Merkle proof /// @dev Must send cost * amt in ETH function preMint(uint256 _amt, bytes32[] calldata _proof) external payable { require(presaleActive, "Presale is not yet active."); require(isWhitelisted(msg.sender, _proof), "Address is not whitelisted."); require(_numberMinted(msg.sender) + _amt <= MAX_PER_WHITELIST, "Amount of tokens exceeds whitelist limit."); require(totalSupply() + _amt <= MAX_SUPPLY, "Amount exceeds supply."); require(cost * _amt == msg.value, "ETH sent not equal to cost."); _safeMint(msg.sender, _amt); emit TotalSupplyChanged(totalSupply()); } /// @notice Mints a new token in public sale /// @param _amt The number of tokens to mint /// @dev Must send cost * amt in ETH function mint(uint256 _amt) external payable { require(saleActive, "Sale is not yet active."); require(_amt <= MAX_TX, "Amount of tokens exceeds transaction limit."); require(totalSupply() + _amt <= MAX_SUPPLY, "Amount exceeds supply."); require(cost * _amt == msg.value, "ETH sent not equal to cost."); _safeMint(msg.sender, _amt); emit TotalSupplyChanged(totalSupply()); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (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.1 (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.1 (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.1 (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 (last updated v4.6.0) (token/ERC20/IERC20.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @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); /** * @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 `to`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address to, 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 `from` to `to` 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 from, address to, uint256 amount ) external returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol) pragma solidity ^0.8.1; /** * @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 * ==== * * [IMPORTANT] * ==== * You shouldn't rely on `isContract` to protect against flash loan attacks! * * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract * constructor. * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize/address.code.length, which returns 0 // for contracts in construction, since the code is only stored at the end // of the constructor execution. return account.code.length > 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 (last updated v4.6.0) (utils/cryptography/MerkleProof.sol) pragma solidity ^0.8.0; /** * @dev These functions deal with verification of Merkle Trees proofs. * * The proofs can be generated using the JavaScript library * https://github.com/miguelmota/merkletreejs[merkletreejs]. * Note: the hashing algorithm should be keccak256 and pair sorting should be enabled. * * See `test/utils/cryptography/MerkleProof.test.js` for some examples. * * WARNING: You should avoid using leaf values that are 64 bytes long prior to * hashing, or use a hash function other than keccak256 for hashing leaves. * This is because the concatenation of a sorted pair of internal nodes in * the merkle tree could be reinterpreted as a leaf value. */ library MerkleProof { /** * @dev Returns true if a `leaf` can be proved to be a part of a Merkle tree * defined by `root`. For this, a `proof` must be provided, containing * sibling hashes on the branch from the leaf to the root of the tree. Each * pair of leaves and each pair of pre-images are assumed to be sorted. */ function verify( bytes32[] memory proof, bytes32 root, bytes32 leaf ) internal pure returns (bool) { return processProof(proof, leaf) == root; } /** * @dev Returns the rebuilt hash obtained by traversing a Merkle tree up * from `leaf` using `proof`. A `proof` is valid if and only if the rebuilt * hash matches the root of the tree. When processing the proof, the pairs * of leafs & pre-images are assumed to be sorted. * * _Available since v4.4._ */ function processProof(bytes32[] memory proof, bytes32 leaf) internal pure returns (bytes32) { bytes32 computedHash = leaf; for (uint256 i = 0; i < proof.length; i++) { bytes32 proofElement = proof[i]; if (computedHash <= proofElement) { // Hash(current computed hash + current element of the proof) computedHash = _efficientHash(computedHash, proofElement); } else { // Hash(current element of the proof + current computed hash) computedHash = _efficientHash(proofElement, computedHash); } } return computedHash; } function _efficientHash(bytes32 a, bytes32 b) private pure returns (bytes32 value) { assembly { mstore(0x00, a) mstore(0x20, b) value := keccak256(0x00, 0x40) } } }
// SPDX-License-Identifier: MIT // ERC721A Contracts v4.0.0 // Creator: Chiru Labs pragma solidity ^0.8.4; import './IERC721A.sol'; /** * @dev ERC721 token receiver interface. */ interface ERC721A__IERC721Receiver { function onERC721Received( address operator, address from, uint256 tokenId, bytes calldata data ) external returns (bytes4); } /** * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including * the Metadata extension. Built to optimize for lower gas during batch mints. * * Assumes serials are sequentially minted starting at _startTokenId() (defaults to 0, e.g. 0, 1, 2, 3..). * * Assumes that an owner cannot have more than 2**64 - 1 (max value of uint64) of supply. * * Assumes that the maximum token id cannot exceed 2**256 - 1 (max value of uint256). */ contract ERC721A is IERC721A { // Mask of an entry in packed address data. uint256 private constant BITMASK_ADDRESS_DATA_ENTRY = (1 << 64) - 1; // The bit position of `numberMinted` in packed address data. uint256 private constant BITPOS_NUMBER_MINTED = 64; // The bit position of `numberBurned` in packed address data. uint256 private constant BITPOS_NUMBER_BURNED = 128; // The bit position of `aux` in packed address data. uint256 private constant BITPOS_AUX = 192; // Mask of all 256 bits in packed address data except the 64 bits for `aux`. uint256 private constant BITMASK_AUX_COMPLEMENT = (1 << 192) - 1; // The bit position of `startTimestamp` in packed ownership. uint256 private constant BITPOS_START_TIMESTAMP = 160; // The bit mask of the `burned` bit in packed ownership. uint256 private constant BITMASK_BURNED = 1 << 224; // The bit position of the `nextInitialized` bit in packed ownership. uint256 private constant BITPOS_NEXT_INITIALIZED = 225; // The bit mask of the `nextInitialized` bit in packed ownership. uint256 private constant BITMASK_NEXT_INITIALIZED = 1 << 225; // The tokenId of the next token to be minted. uint256 private _currentIndex; // The number of tokens burned. uint256 private _burnCounter; // Token name string private _name; // Token symbol string private _symbol; // Mapping from token ID to ownership details // An empty struct value does not necessarily mean the token is unowned. // See `_packedOwnershipOf` implementation for details. // // Bits Layout: // - [0..159] `addr` // - [160..223] `startTimestamp` // - [224] `burned` // - [225] `nextInitialized` mapping(uint256 => uint256) private _packedOwnerships; // Mapping owner address to address data. // // Bits Layout: // - [0..63] `balance` // - [64..127] `numberMinted` // - [128..191] `numberBurned` // - [192..255] `aux` mapping(address => uint256) private _packedAddressData; // 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; constructor(string memory name_, string memory symbol_) { _name = name_; _symbol = symbol_; _currentIndex = _startTokenId(); } /** * @dev Returns the starting token ID. * To change the starting token ID, please override this function. */ function _startTokenId() internal view virtual returns (uint256) { return 0; } /** * @dev Returns the next token ID to be minted. */ function _nextTokenId() internal view returns (uint256) { return _currentIndex; } /** * @dev Returns the total number of tokens in existence. * Burned tokens will reduce the count. * To get the total number of tokens minted, please see `_totalMinted`. */ function totalSupply() public view override returns (uint256) { // Counter underflow is impossible as _burnCounter cannot be incremented // more than `_currentIndex - _startTokenId()` times. unchecked { return _currentIndex - _burnCounter - _startTokenId(); } } /** * @dev Returns the total amount of tokens minted in the contract. */ function _totalMinted() internal view returns (uint256) { // Counter underflow is impossible as _currentIndex does not decrement, // and it is initialized to `_startTokenId()` unchecked { return _currentIndex - _startTokenId(); } } /** * @dev Returns the total number of tokens burned. */ function _totalBurned() internal view returns (uint256) { return _burnCounter; } /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { // The interface IDs are constants representing the first 4 bytes of the XOR of // all function selectors in the interface. See: https://eips.ethereum.org/EIPS/eip-165 // e.g. `bytes4(i.functionA.selector ^ i.functionB.selector ^ ...)` return interfaceId == 0x01ffc9a7 || // ERC165 interface ID for ERC165. interfaceId == 0x80ac58cd || // ERC165 interface ID for ERC721. interfaceId == 0x5b5e139f; // ERC165 interface ID for ERC721Metadata. } /** * @dev See {IERC721-balanceOf}. */ function balanceOf(address owner) public view override returns (uint256) { if (owner == address(0)) revert BalanceQueryForZeroAddress(); return _packedAddressData[owner] & BITMASK_ADDRESS_DATA_ENTRY; } /** * Returns the number of tokens minted by `owner`. */ function _numberMinted(address owner) internal view returns (uint256) { return (_packedAddressData[owner] >> BITPOS_NUMBER_MINTED) & BITMASK_ADDRESS_DATA_ENTRY; } /** * Returns the number of tokens burned by or on behalf of `owner`. */ function _numberBurned(address owner) internal view returns (uint256) { return (_packedAddressData[owner] >> BITPOS_NUMBER_BURNED) & BITMASK_ADDRESS_DATA_ENTRY; } /** * Returns the auxillary data for `owner`. (e.g. number of whitelist mint slots used). */ function _getAux(address owner) internal view returns (uint64) { return uint64(_packedAddressData[owner] >> BITPOS_AUX); } /** * Sets the auxillary data for `owner`. (e.g. number of whitelist mint slots used). * If there are multiple variables, please pack them into a uint64. */ function _setAux(address owner, uint64 aux) internal { uint256 packed = _packedAddressData[owner]; uint256 auxCasted; assembly { // Cast aux without masking. auxCasted := aux } packed = (packed & BITMASK_AUX_COMPLEMENT) | (auxCasted << BITPOS_AUX); _packedAddressData[owner] = packed; } /** * Returns the packed ownership data of `tokenId`. */ function _packedOwnershipOf(uint256 tokenId) private view returns (uint256) { uint256 curr = tokenId; unchecked { if (_startTokenId() <= curr) if (curr < _currentIndex) { uint256 packed = _packedOwnerships[curr]; // If not burned. if (packed & BITMASK_BURNED == 0) { // Invariant: // There will always be an ownership that has an address and is not burned // before an ownership that does not have an address and is not burned. // Hence, curr will not underflow. // // We can directly compare the packed value. // If the address is zero, packed is zero. while (packed == 0) { packed = _packedOwnerships[--curr]; } return packed; } } } revert OwnerQueryForNonexistentToken(); } /** * Returns the unpacked `TokenOwnership` struct from `packed`. */ function _unpackedOwnership(uint256 packed) private pure returns (TokenOwnership memory ownership) { ownership.addr = address(uint160(packed)); ownership.startTimestamp = uint64(packed >> BITPOS_START_TIMESTAMP); ownership.burned = packed & BITMASK_BURNED != 0; } /** * Returns the unpacked `TokenOwnership` struct at `index`. */ function _ownershipAt(uint256 index) internal view returns (TokenOwnership memory) { return _unpackedOwnership(_packedOwnerships[index]); } /** * @dev Initializes the ownership slot minted at `index` for efficiency purposes. */ function _initializeOwnershipAt(uint256 index) internal { if (_packedOwnerships[index] == 0) { _packedOwnerships[index] = _packedOwnershipOf(index); } } /** * Gas spent here starts off proportional to the maximum mint batch size. * It gradually moves to O(1) as tokens get transferred around in the collection over time. */ function _ownershipOf(uint256 tokenId) internal view returns (TokenOwnership memory) { return _unpackedOwnership(_packedOwnershipOf(tokenId)); } /** * @dev See {IERC721-ownerOf}. */ function ownerOf(uint256 tokenId) public view override returns (address) { return address(uint160(_packedOwnershipOf(tokenId))); } /** * @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) { if (!_exists(tokenId)) revert URIQueryForNonexistentToken(); string memory baseURI = _baseURI(); return bytes(baseURI).length != 0 ? string(abi.encodePacked(baseURI, _toString(tokenId))) : ''; } /** * @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 Casts the address to uint256 without masking. */ function _addressToUint256(address value) private pure returns (uint256 result) { assembly { result := value } } /** * @dev Casts the boolean to uint256 without branching. */ function _boolToUint256(bool value) private pure returns (uint256 result) { assembly { result := value } } /** * @dev See {IERC721-approve}. */ function approve(address to, uint256 tokenId) public override { address owner = address(uint160(_packedOwnershipOf(tokenId))); if (to == owner) revert ApprovalToCurrentOwner(); if (_msgSenderERC721A() != owner) if (!isApprovedForAll(owner, _msgSenderERC721A())) { revert ApprovalCallerNotOwnerNorApproved(); } _tokenApprovals[tokenId] = to; emit Approval(owner, to, tokenId); } /** * @dev See {IERC721-getApproved}. */ function getApproved(uint256 tokenId) public view override returns (address) { if (!_exists(tokenId)) revert ApprovalQueryForNonexistentToken(); return _tokenApprovals[tokenId]; } /** * @dev See {IERC721-setApprovalForAll}. */ function setApprovalForAll(address operator, bool approved) public virtual override { if (operator == _msgSenderERC721A()) revert ApproveToCaller(); _operatorApprovals[_msgSenderERC721A()][operator] = approved; emit ApprovalForAll(_msgSenderERC721A(), 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 { _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 { _transfer(from, to, tokenId); if (to.code.length != 0) if (!_checkContractOnERC721Received(from, to, tokenId, _data)) { revert TransferToNonERC721ReceiverImplementer(); } } /** * @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`), */ function _exists(uint256 tokenId) internal view returns (bool) { return _startTokenId() <= tokenId && tokenId < _currentIndex && // If within bounds, _packedOwnerships[tokenId] & BITMASK_BURNED == 0; // and not burned. } /** * @dev Equivalent to `_safeMint(to, quantity, '')`. */ function _safeMint(address to, uint256 quantity) internal { _safeMint(to, quantity, ''); } /** * @dev Safely mints `quantity` tokens and transfers them to `to`. * * Requirements: * * - If `to` refers to a smart contract, it must implement * {IERC721Receiver-onERC721Received}, which is called for each safe transfer. * - `quantity` must be greater than 0. * * Emits a {Transfer} event. */ function _safeMint( address to, uint256 quantity, bytes memory _data ) internal { uint256 startTokenId = _currentIndex; if (to == address(0)) revert MintToZeroAddress(); if (quantity == 0) revert MintZeroQuantity(); _beforeTokenTransfers(address(0), to, startTokenId, quantity); // Overflows are incredibly unrealistic. // balance or numberMinted overflow if current value of either + quantity > 1.8e19 (2**64) - 1 // updatedIndex overflows if _currentIndex + quantity > 1.2e77 (2**256) - 1 unchecked { // Updates: // - `balance += quantity`. // - `numberMinted += quantity`. // // We can directly add to the balance and number minted. _packedAddressData[to] += quantity * ((1 << BITPOS_NUMBER_MINTED) | 1); // Updates: // - `address` to the owner. // - `startTimestamp` to the timestamp of minting. // - `burned` to `false`. // - `nextInitialized` to `quantity == 1`. _packedOwnerships[startTokenId] = _addressToUint256(to) | (block.timestamp << BITPOS_START_TIMESTAMP) | (_boolToUint256(quantity == 1) << BITPOS_NEXT_INITIALIZED); uint256 updatedIndex = startTokenId; uint256 end = updatedIndex + quantity; if (to.code.length != 0) { do { emit Transfer(address(0), to, updatedIndex); if (!_checkContractOnERC721Received(address(0), to, updatedIndex++, _data)) { revert TransferToNonERC721ReceiverImplementer(); } } while (updatedIndex < end); // Reentrancy protection if (_currentIndex != startTokenId) revert(); } else { do { emit Transfer(address(0), to, updatedIndex++); } while (updatedIndex < end); } _currentIndex = updatedIndex; } _afterTokenTransfers(address(0), to, startTokenId, quantity); } /** * @dev Mints `quantity` tokens and transfers them to `to`. * * Requirements: * * - `to` cannot be the zero address. * - `quantity` must be greater than 0. * * Emits a {Transfer} event. */ function _mint(address to, uint256 quantity) internal { uint256 startTokenId = _currentIndex; if (to == address(0)) revert MintToZeroAddress(); if (quantity == 0) revert MintZeroQuantity(); _beforeTokenTransfers(address(0), to, startTokenId, quantity); // Overflows are incredibly unrealistic. // balance or numberMinted overflow if current value of either + quantity > 1.8e19 (2**64) - 1 // updatedIndex overflows if _currentIndex + quantity > 1.2e77 (2**256) - 1 unchecked { // Updates: // - `balance += quantity`. // - `numberMinted += quantity`. // // We can directly add to the balance and number minted. _packedAddressData[to] += quantity * ((1 << BITPOS_NUMBER_MINTED) | 1); // Updates: // - `address` to the owner. // - `startTimestamp` to the timestamp of minting. // - `burned` to `false`. // - `nextInitialized` to `quantity == 1`. _packedOwnerships[startTokenId] = _addressToUint256(to) | (block.timestamp << BITPOS_START_TIMESTAMP) | (_boolToUint256(quantity == 1) << BITPOS_NEXT_INITIALIZED); uint256 updatedIndex = startTokenId; uint256 end = updatedIndex + quantity; do { emit Transfer(address(0), to, updatedIndex++); } while (updatedIndex < end); _currentIndex = updatedIndex; } _afterTokenTransfers(address(0), to, startTokenId, quantity); } /** * @dev Transfers `tokenId` from `from` to `to`. * * 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 ) private { uint256 prevOwnershipPacked = _packedOwnershipOf(tokenId); if (address(uint160(prevOwnershipPacked)) != from) revert TransferFromIncorrectOwner(); bool isApprovedOrOwner = (_msgSenderERC721A() == from || isApprovedForAll(from, _msgSenderERC721A()) || getApproved(tokenId) == _msgSenderERC721A()); if (!isApprovedOrOwner) revert TransferCallerNotOwnerNorApproved(); if (to == address(0)) revert TransferToZeroAddress(); _beforeTokenTransfers(from, to, tokenId, 1); // Clear approvals from the previous owner. delete _tokenApprovals[tokenId]; // Underflow of the sender's balance is impossible because we check for // ownership above and the recipient's balance can't realistically overflow. // Counter overflow is incredibly unrealistic as tokenId would have to be 2**256. unchecked { // We can directly increment and decrement the balances. --_packedAddressData[from]; // Updates: `balance -= 1`. ++_packedAddressData[to]; // Updates: `balance += 1`. // Updates: // - `address` to the next owner. // - `startTimestamp` to the timestamp of transfering. // - `burned` to `false`. // - `nextInitialized` to `true`. _packedOwnerships[tokenId] = _addressToUint256(to) | (block.timestamp << BITPOS_START_TIMESTAMP) | BITMASK_NEXT_INITIALIZED; // If the next slot may not have been initialized (i.e. `nextInitialized == false`) . if (prevOwnershipPacked & BITMASK_NEXT_INITIALIZED == 0) { uint256 nextTokenId = tokenId + 1; // If the next slot's address is zero and not burned (i.e. packed value is zero). if (_packedOwnerships[nextTokenId] == 0) { // If the next slot is within bounds. if (nextTokenId != _currentIndex) { // Initialize the next slot to maintain correctness for `ownerOf(tokenId + 1)`. _packedOwnerships[nextTokenId] = prevOwnershipPacked; } } } } emit Transfer(from, to, tokenId); _afterTokenTransfers(from, to, tokenId, 1); } /** * @dev Equivalent to `_burn(tokenId, false)`. */ function _burn(uint256 tokenId) internal virtual { _burn(tokenId, false); } /** * @dev Destroys `tokenId`. * The approval is cleared when the token is burned. * * Requirements: * * - `tokenId` must exist. * * Emits a {Transfer} event. */ function _burn(uint256 tokenId, bool approvalCheck) internal virtual { uint256 prevOwnershipPacked = _packedOwnershipOf(tokenId); address from = address(uint160(prevOwnershipPacked)); if (approvalCheck) { bool isApprovedOrOwner = (_msgSenderERC721A() == from || isApprovedForAll(from, _msgSenderERC721A()) || getApproved(tokenId) == _msgSenderERC721A()); if (!isApprovedOrOwner) revert TransferCallerNotOwnerNorApproved(); } _beforeTokenTransfers(from, address(0), tokenId, 1); // Clear approvals from the previous owner. delete _tokenApprovals[tokenId]; // Underflow of the sender's balance is impossible because we check for // ownership above and the recipient's balance can't realistically overflow. // Counter overflow is incredibly unrealistic as tokenId would have to be 2**256. unchecked { // Updates: // - `balance -= 1`. // - `numberBurned += 1`. // // We can directly decrement the balance, and increment the number burned. // This is equivalent to `packed -= 1; packed += 1 << BITPOS_NUMBER_BURNED;`. _packedAddressData[from] += (1 << BITPOS_NUMBER_BURNED) - 1; // Updates: // - `address` to the last owner. // - `startTimestamp` to the timestamp of burning. // - `burned` to `true`. // - `nextInitialized` to `true`. _packedOwnerships[tokenId] = _addressToUint256(from) | (block.timestamp << BITPOS_START_TIMESTAMP) | BITMASK_BURNED | BITMASK_NEXT_INITIALIZED; // If the next slot may not have been initialized (i.e. `nextInitialized == false`) . if (prevOwnershipPacked & BITMASK_NEXT_INITIALIZED == 0) { uint256 nextTokenId = tokenId + 1; // If the next slot's address is zero and not burned (i.e. packed value is zero). if (_packedOwnerships[nextTokenId] == 0) { // If the next slot is within bounds. if (nextTokenId != _currentIndex) { // Initialize the next slot to maintain correctness for `ownerOf(tokenId + 1)`. _packedOwnerships[nextTokenId] = prevOwnershipPacked; } } } } emit Transfer(from, address(0), tokenId); _afterTokenTransfers(from, address(0), tokenId, 1); // Overflow not possible, as _burnCounter cannot be exceed _currentIndex times. unchecked { _burnCounter++; } } /** * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target 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 _checkContractOnERC721Received( address from, address to, uint256 tokenId, bytes memory _data ) private returns (bool) { try ERC721A__IERC721Receiver(to).onERC721Received(_msgSenderERC721A(), from, tokenId, _data) returns ( bytes4 retval ) { return retval == ERC721A__IERC721Receiver(to).onERC721Received.selector; } catch (bytes memory reason) { if (reason.length == 0) { revert TransferToNonERC721ReceiverImplementer(); } else { assembly { revert(add(32, reason), mload(reason)) } } } } /** * @dev Hook that is called before a set of serially-ordered token ids are about to be transferred. This includes minting. * And also called before burning one token. * * startTokenId - the first token id to be transferred * quantity - the amount to be transferred * * 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, `tokenId` will be burned by `from`. * - `from` and `to` are never both zero. */ function _beforeTokenTransfers( address from, address to, uint256 startTokenId, uint256 quantity ) internal virtual {} /** * @dev Hook that is called after a set of serially-ordered token ids have been transferred. This includes * minting. * And also called after one token has been burned. * * startTokenId - the first token id to be transferred * quantity - the amount to be transferred * * Calling conditions: * * - When `from` and `to` are both non-zero, `from`'s `tokenId` has been * transferred to `to`. * - When `from` is zero, `tokenId` has been minted for `to`. * - When `to` is zero, `tokenId` has been burned by `from`. * - `from` and `to` are never both zero. */ function _afterTokenTransfers( address from, address to, uint256 startTokenId, uint256 quantity ) internal virtual {} /** * @dev Returns the message sender (defaults to `msg.sender`). * * If you are writing GSN compatible contracts, you need to override this function. */ function _msgSenderERC721A() internal view virtual returns (address) { return msg.sender; } /** * @dev Converts a `uint256` to its ASCII `string` decimal representation. */ function _toString(uint256 value) internal pure returns (string memory ptr) { assembly { // The maximum value of a uint256 contains 78 digits (1 byte per digit), // but we allocate 128 bytes to keep the free memory pointer 32-byte word aliged. // We will need 1 32-byte word to store the length, // and 3 32-byte words to store a maximum of 78 digits. Total: 32 + 3 * 32 = 128. ptr := add(mload(0x40), 128) // Update the free memory pointer to allocate. mstore(0x40, ptr) // Cache the end of the memory to calculate the length later. let end := ptr // We write the string from the rightmost digit to the leftmost digit. // The following is essentially a do-while loop that also handles the zero case. // Costs a bit more than early returning for the zero case, // but cheaper in terms of deployment and overall runtime costs. for { // Initialize and perform the first pass without check. let temp := value // Move the pointer 1 byte leftwards to point to an empty character slot. ptr := sub(ptr, 1) // Write the character to the pointer. 48 is the ASCII index of '0'. mstore8(ptr, add(48, mod(temp, 10))) temp := div(temp, 10) } temp { // Keep dividing `temp` until zero. temp := div(temp, 10) } { // Body of the for loop. ptr := sub(ptr, 1) mstore8(ptr, add(48, mod(temp, 10))) } let length := sub(end, ptr) // Move the pointer 32 bytes leftwards to make room for the length. ptr := sub(ptr, 32) // Store the length. mstore(ptr, length) } } }
// SPDX-License-Identifier: MIT // ERC721A Contracts v4.0.0 // Creator: Chiru Labs pragma solidity ^0.8.4; /** * @dev Interface of an ERC721A compliant contract. */ interface IERC721A { /** * The caller must own the token or be an approved operator. */ error ApprovalCallerNotOwnerNorApproved(); /** * The token does not exist. */ error ApprovalQueryForNonexistentToken(); /** * The caller cannot approve to their own address. */ error ApproveToCaller(); /** * The caller cannot approve to the current owner. */ error ApprovalToCurrentOwner(); /** * Cannot query the balance for the zero address. */ error BalanceQueryForZeroAddress(); /** * Cannot mint to the zero address. */ error MintToZeroAddress(); /** * The quantity of tokens minted must be more than zero. */ error MintZeroQuantity(); /** * The token does not exist. */ error OwnerQueryForNonexistentToken(); /** * The caller must own the token or be an approved operator. */ error TransferCallerNotOwnerNorApproved(); /** * The token must be owned by `from`. */ error TransferFromIncorrectOwner(); /** * Cannot safely transfer to a contract that does not implement the ERC721Receiver interface. */ error TransferToNonERC721ReceiverImplementer(); /** * Cannot transfer to the zero address. */ error TransferToZeroAddress(); /** * The token does not exist. */ error URIQueryForNonexistentToken(); struct TokenOwnership { // The address of the owner. address addr; // Keeps track of the start time of ownership with minimal overhead for tokenomics. uint64 startTimestamp; // Whether the token has been burned. bool burned; } /** * @dev Returns the total amount of tokens stored by the contract. * * Burned tokens are calculated here, use `_totalMinted()` if you want to count just minted tokens. */ function totalSupply() external view returns (uint256); // ============================== // 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); // ============================== // IERC721 // ============================== /** * @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`. * * 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; /** * @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 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 the account approved for `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function getApproved(uint256 tokenId) external view returns (address operator); /** * @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); // ============================== // IERC721Metadata // ============================== /** * @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); }
{ "metadata": { "useLiteralContent": true }, "optimizer": { "enabled": true, "runs": 10000 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "abi" ] } } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"string","name":"_name","type":"string"},{"internalType":"string","name":"_symbol","type":"string"},{"internalType":"address[]","name":"_shareholders","type":"address[]"},{"internalType":"uint256[]","name":"_shares","type":"uint256[]"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"ApprovalCallerNotOwnerNorApproved","type":"error"},{"inputs":[],"name":"ApprovalQueryForNonexistentToken","type":"error"},{"inputs":[],"name":"ApprovalToCurrentOwner","type":"error"},{"inputs":[],"name":"ApproveToCaller","type":"error"},{"inputs":[],"name":"BalanceQueryForZeroAddress","type":"error"},{"inputs":[],"name":"MintToZeroAddress","type":"error"},{"inputs":[],"name":"MintZeroQuantity","type":"error"},{"inputs":[],"name":"OwnerQueryForNonexistentToken","type":"error"},{"inputs":[],"name":"TransferCallerNotOwnerNorApproved","type":"error"},{"inputs":[],"name":"TransferFromIncorrectOwner","type":"error"},{"inputs":[],"name":"TransferToNonERC721ReceiverImplementer","type":"error"},{"inputs":[],"name":"TransferToZeroAddress","type":"error"},{"inputs":[],"name":"URIQueryForNonexistentToken","type":"error"},{"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":false,"internalType":"bool","name":"_val","type":"bool"}],"name":"PresaleStateChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bool","name":"_val","type":"bool"}],"name":"SaleStateChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_val","type":"uint256"}],"name":"TotalSupplyChanged","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_PER_WHITELIST","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_SUPPLY","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_TX","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":"baseURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"cost","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_addr","type":"address"},{"internalType":"bytes32[]","name":"_proof","type":"bytes32[]"}],"name":"isWhitelisted","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"merkleRoot","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amt","type":"uint256"}],"name":"mint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"payee","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amt","type":"uint256"},{"internalType":"bytes32[]","name":"_proof","type":"bytes32[]"}],"name":"preMint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"presaleActive","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":[{"internalType":"uint256","name":"_amt","type":"uint256"}],"name":"reserve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"saleActive","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":"_val","type":"string"}],"name":"setBaseURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_val","type":"uint256"}],"name":"setCost","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_val","type":"bool"}],"name":"setPresaleState","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_val","type":"bool"}],"name":"setSaleState","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_val","type":"bytes32"}],"name":"setWhitelist","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":"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
6080604052668700cc757700006010556013805461ffff191690553480156200002757600080fd5b506040516200398e3803806200398e8339810160408190526200004a91620005d4565b818185858160029080519060200190620000669291906200041f565b5080516200007c9060039060208401906200041f565b506000805550508051825114620000f55760405162461bcd60e51b815260206004820152603260248201527f5061796d656e7453706c69747465723a2070617965657320616e6420736861726044820152710cae640d8cadccee8d040dad2e6dac2e8c6d60731b60648201526084015b60405180910390fd5b6000825111620001485760405162461bcd60e51b815260206004820152601a60248201527f5061796d656e7453706c69747465723a206e6f207061796565730000000000006044820152606401620000ec565b60005b8251811015620001b4576200019f8382815181106200016e576200016e620007e8565b60200260200101518383815181106200018b576200018b620007e8565b6020026020010151620001db60201b60201c565b80620001ab81620007b4565b9150506200014b565b505050620001d1620001cb620003c960201b60201c565b620003cd565b5050505062000814565b6001600160a01b038216620002485760405162461bcd60e51b815260206004820152602c60248201527f5061796d656e7453706c69747465723a206163636f756e74206973207468652060448201526b7a65726f206164647265737360a01b6064820152608401620000ec565b600081116200029a5760405162461bcd60e51b815260206004820152601d60248201527f5061796d656e7453706c69747465723a207368617265732061726520300000006044820152606401620000ec565b6001600160a01b0382166000908152600a602052604090205415620003165760405162461bcd60e51b815260206004820152602b60248201527f5061796d656e7453706c69747465723a206163636f756e7420616c726561647960448201526a206861732073686172657360a81b6064820152608401620000ec565b600c8054600181019091557fdf6966c971051c3d54ec59162606531493a51404a002842f56009d7e5cf4a8c70180546001600160a01b0319166001600160a01b0384169081179091556000908152600a60205260409020819055600854620003809082906200075c565b600855604080516001600160a01b0384168152602081018390527f40c340f65e17194d14ddddb073d3c9f888e3cb52b5aae0c6c7706b4fbc905fac910160405180910390a15050565b3390565b600f80546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b8280546200042d9062000777565b90600052602060002090601f0160209004810192826200045157600085556200049c565b82601f106200046c57805160ff19168380011785556200049c565b828001600101855582156200049c579182015b828111156200049c5782518255916020019190600101906200047f565b50620004aa929150620004ae565b5090565b5b80821115620004aa5760008155600101620004af565b600082601f830112620004d757600080fd5b81516020620004f0620004ea8362000736565b62000703565b80838252828201915082860187848660051b89010111156200051157600080fd5b60005b85811015620005325781518452928401929084019060010162000514565b5090979650505050505050565b600082601f8301126200055157600080fd5b81516001600160401b038111156200056d576200056d620007fe565b602062000583601f8301601f1916820162000703565b82815285828487010111156200059857600080fd5b60005b83811015620005b85785810183015182820184015282016200059b565b83811115620005ca5760008385840101525b5095945050505050565b60008060008060808587031215620005eb57600080fd5b84516001600160401b03808211156200060357600080fd5b62000611888389016200053f565b95506020915081870151818111156200062957600080fd5b6200063789828a016200053f565b9550506040870151818111156200064d57600080fd5b8701601f810189136200065f57600080fd5b805162000670620004ea8262000736565b8082825285820191508584018c878560051b87010111156200069157600080fd5b600094505b83851015620006cc5780516001600160a01b0381168114620006b757600080fd5b83526001949094019391860191860162000696565b5060608b0151909750945050505080821115620006e857600080fd5b50620006f787828801620004c5565b91505092959194509250565b604051601f8201601f191681016001600160401b03811182821017156200072e576200072e620007fe565b604052919050565b60006001600160401b03821115620007525762000752620007fe565b5060051b60200190565b60008219821115620007725762000772620007d2565b500190565b600181811c908216806200078c57607f821691505b60208210811415620007ae57634e487b7160e01b600052602260045260246000fd5b50919050565b6000600019821415620007cb57620007cb620007d2565b5060010190565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b61316a80620008246000396000f3fe6080604052600436106102e05760003560e01c80636352211e11610184578063a22cb465116100d6578063ce7c2ac21161008a578063e985e9c511610064578063e985e9c51461084b578063f2fde38b14610894578063f3b2db3f146108b457600080fd5b8063ce7c2ac2146107ca578063d79779b214610800578063e33b7de31461083657600080fd5b8063bce4d6ae116100bb578063bce4d6ae1461076a578063c4e370951461078a578063c87b56dd146107aa57600080fd5b8063a22cb4651461072a578063b88d4fde1461074a57600080fd5b8063819b25ba1161013857806395d89b411161011257806395d89b41146106cc5780639852595c146106e1578063a0712d681461071757600080fd5b8063819b25ba1461066e5780638b83209b1461068e5780638da5cb5b146106ae57600080fd5b80636c0360eb116101695780636c0360eb1461062457806370a0823114610639578063715018a61461065957600080fd5b80636352211e146105ea57806368428a1b1461060a57600080fd5b806332cb6b0c1161023d57806344a0d68a116101f157806355f804b3116101cb57806355f804b3146105975780635a23dd99146105b75780635a546223146105d757600080fd5b806344a0d68a1461053857806348b750441461055857806353135ca01461057857600080fd5b8063406072a911610222578063406072a9146104b257806342842e0e146104f8578063440bc7f31461051857600080fd5b806332cb6b0c146104875780633a98ef391461049d57600080fd5b806318160ddd1161029457806323b872dd1161027957806323b872dd1461043c5780632e0367681461045c5780632eb4a7ab1461047157600080fd5b806318160ddd14610403578063191655871461041c57600080fd5b8063081812fc116102c5578063081812fc14610385578063095ea7b3146103bd57806313faede6146103df57600080fd5b806301ffc9a71461032e57806306fdde031461036357600080fd5b36610329577f6ef95f06320e7a25a04a175ca677b7052bdd97131872c2192525a629f51be77033604080516001600160a01b0390921682523460208301520160405180910390a1005b600080fd5b34801561033a57600080fd5b5061034e610349366004612d1a565b6108c9565b60405190151581526020015b60405180910390f35b34801561036f57600080fd5b506103786109ae565b60405161035a9190612ee3565b34801561039157600080fd5b506103a56103a0366004612d01565b610a40565b6040516001600160a01b03909116815260200161035a565b3480156103c957600080fd5b506103dd6103d8366004612c9b565b610a9d565b005b3480156103eb57600080fd5b506103f560105481565b60405190815260200161035a565b34801561040f57600080fd5b50600154600054036103f5565b34801561042857600080fd5b506103dd610437366004612a83565b610bba565b34801561044857600080fd5b506103dd610457366004612ad9565b610d9a565b34801561046857600080fd5b506103f5600581565b34801561047d57600080fd5b506103f560125481565b34801561049357600080fd5b506103f561199c81565b3480156104a957600080fd5b506008546103f5565b3480156104be57600080fd5b506103f56104cd366004612aa0565b6001600160a01b039182166000908152600e6020908152604080832093909416825291909152205490565b34801561050457600080fd5b506103dd610513366004612ad9565b610daa565b34801561052457600080fd5b506103dd610533366004612d01565b610dc5565b34801561054457600080fd5b506103dd610553366004612d01565b610e24565b34801561056457600080fd5b506103dd610573366004612aa0565b610e83565b34801561058457600080fd5b5060135461034e90610100900460ff1681565b3480156105a357600080fd5b506103dd6105b2366004612d54565b611130565b3480156105c357600080fd5b5061034e6105d2366004612c18565b611196565b6103dd6105e5366004612ddf565b611231565b3480156105f657600080fd5b506103a5610605366004612d01565b611498565b34801561061657600080fd5b5060135461034e9060ff1681565b34801561063057600080fd5b506103786114a3565b34801561064557600080fd5b506103f5610654366004612a83565b611531565b34801561066557600080fd5b506103dd611599565b34801561067a57600080fd5b506103dd610689366004612d01565b6115ff565b34801561069a57600080fd5b506103a56106a9366004612d01565b6116a6565b3480156106ba57600080fd5b50600f546001600160a01b03166103a5565b3480156106d857600080fd5b506103786116d6565b3480156106ed57600080fd5b506103f56106fc366004612a83565b6001600160a01b03166000908152600b602052604090205490565b6103dd610725366004612d01565b6116e5565b34801561073657600080fd5b506103dd610745366004612c6d565b61187d565b34801561075657600080fd5b506103dd610765366004612b1a565b61194a565b34801561077657600080fd5b506103dd610785366004612cc7565b6119ad565b34801561079657600080fd5b506103dd6107a5366004612cc7565b611a6d565b3480156107b657600080fd5b506103786107c5366004612d01565b611b26565b3480156107d657600080fd5b506103f56107e5366004612a83565b6001600160a01b03166000908152600a602052604090205490565b34801561080c57600080fd5b506103f561081b366004612a83565b6001600160a01b03166000908152600d602052604090205490565b34801561084257600080fd5b506009546103f5565b34801561085757600080fd5b5061034e610866366004612aa0565b6001600160a01b03918216600090815260076020908152604080832093909416825291909152205460ff1690565b3480156108a057600080fd5b506103dd6108af366004612a83565b611bc3565b3480156108c057600080fd5b506103f5600a81565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316148061095c57507f80ac58cd000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316145b806109a857507f5b5e139f000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316145b92915050565b6060600280546109bd90612fc9565b80601f01602080910402602001604051908101604052809291908181526020018280546109e990612fc9565b8015610a365780601f10610a0b57610100808354040283529160200191610a36565b820191906000526020600020905b815481529060010190602001808311610a1957829003601f168201915b5050505050905090565b6000610a4b82611ca5565b610a81576040517fcf4700e400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b506000908152600660205260409020546001600160a01b031690565b6000610aa882611ce5565b9050806001600160a01b0316836001600160a01b03161415610af6576040517f943f7b8c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b336001600160a01b03821614610b4657610b108133610866565b610b46576040517fcfb3b94200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008281526006602052604080822080547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0387811691821790925591518593918516917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591a4505050565b6001600160a01b0381166000908152600a6020526040902054610c4a5760405162461bcd60e51b815260206004820152602660248201527f5061796d656e7453706c69747465723a206163636f756e7420686173206e6f2060448201527f736861726573000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b6000610c5560095490565b610c5f9047612ef6565b90506000610c8c8383610c87866001600160a01b03166000908152600b602052604090205490565b611d96565b905080610d015760405162461bcd60e51b815260206004820152602b60248201527f5061796d656e7453706c69747465723a206163636f756e74206973206e6f742060448201527f647565207061796d656e740000000000000000000000000000000000000000006064820152608401610c41565b6001600160a01b0383166000908152600b602052604081208054839290610d29908490612ef6565b925050819055508060096000828254610d429190612ef6565b90915550610d5290508382611ddc565b604080516001600160a01b0385168152602081018390527fdf20fd1e76bc69d672e4814fafb2c449bba3a5369d8359adf9e05e6fde87b05691015b60405180910390a1505050565b610da5838383611ef5565b505050565b610da58383836040518060200160405280600081525061194a565b600f546001600160a01b03163314610e1f5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610c41565b601255565b600f546001600160a01b03163314610e7e5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610c41565b601055565b6001600160a01b0381166000908152600a6020526040902054610f0e5760405162461bcd60e51b815260206004820152602660248201527f5061796d656e7453706c69747465723a206163636f756e7420686173206e6f2060448201527f73686172657300000000000000000000000000000000000000000000000000006064820152608401610c41565b6001600160a01b0382166000908152600d60205260408120546040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201526001600160a01b038516906370a082319060240160206040518083038186803b158015610f7f57600080fd5b505afa158015610f93573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fb79190612dc6565b610fc19190612ef6565b90506000610ffa8383610c8787876001600160a01b039182166000908152600e6020908152604080832093909416825291909152205490565b90508061106f5760405162461bcd60e51b815260206004820152602b60248201527f5061796d656e7453706c69747465723a206163636f756e74206973206e6f742060448201527f647565207061796d656e740000000000000000000000000000000000000000006064820152608401610c41565b6001600160a01b038085166000908152600e60209081526040808320938716835292905290812080548392906110a6908490612ef6565b90915550506001600160a01b0384166000908152600d6020526040812080548392906110d3908490612ef6565b909155506110e49050848483612133565b604080516001600160a01b038581168252602082018490528616917f3be5b7a71e84ed12875d241991c70855ac5817d847039e17a9d895c1ceb0f18a910160405180910390a250505050565b600f546001600160a01b0316331461118a5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610c41565b610da560118383612980565b6040517fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606085901b16602082015260009081906034016040516020818303038152906040528051906020012090506112268484808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152505060125491508490506121b3565b9150505b9392505050565b601354610100900460ff166112885760405162461bcd60e51b815260206004820152601a60248201527f50726573616c65206973206e6f7420796574206163746976652e0000000000006044820152606401610c41565b611293338383611196565b6112df5760405162461bcd60e51b815260206004820152601b60248201527f41646472657373206973206e6f742077686974656c69737465642e00000000006044820152606401610c41565b60058361130f336001600160a01b03166000908152600560205260409081902054901c67ffffffffffffffff1690565b6113199190612ef6565b111561138d5760405162461bcd60e51b815260206004820152602960248201527f416d6f756e74206f6620746f6b656e7320657863656564732077686974656c6960448201527f7374206c696d69742e00000000000000000000000000000000000000000000006064820152608401610c41565b61199c8361139e6001546000540390565b6113a89190612ef6565b11156113f65760405162461bcd60e51b815260206004820152601660248201527f416d6f756e74206578636565647320737570706c792e000000000000000000006044820152606401610c41565b34836010546114059190612f49565b146114525760405162461bcd60e51b815260206004820152601b60248201527f4554482073656e74206e6f7420657175616c20746f20636f73742e00000000006044820152606401610c41565b61145c33846121c9565b7fc8b17f75f53401f272e9ee7fa431e81ba33779363238896180425a422420c8f761148a6001546000540390565b604051908152602001610d8d565b60006109a882611ce5565b601180546114b090612fc9565b80601f01602080910402602001604051908101604052809291908181526020018280546114dc90612fc9565b80156115295780601f106114fe57610100808354040283529160200191611529565b820191906000526020600020905b81548152906001019060200180831161150c57829003601f168201915b505050505081565b60006001600160a01b038216611573576040517f8f4eb60400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b506001600160a01b031660009081526005602052604090205467ffffffffffffffff1690565b600f546001600160a01b031633146115f35760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610c41565b6115fd60006121e7565b565b600f546001600160a01b031633146116595760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610c41565b6116633382612251565b7fc8b17f75f53401f272e9ee7fa431e81ba33779363238896180425a422420c8f76116916001546000540390565b6040519081526020015b60405180910390a150565b6000600c82815481106116bb576116bb613085565b6000918252602090912001546001600160a01b031692915050565b6060600380546109bd90612fc9565b60135460ff166117375760405162461bcd60e51b815260206004820152601760248201527f53616c65206973206e6f7420796574206163746976652e0000000000000000006044820152606401610c41565b600a8111156117ae5760405162461bcd60e51b815260206004820152602b60248201527f416d6f756e74206f6620746f6b656e732065786365656473207472616e73616360448201527f74696f6e206c696d69742e0000000000000000000000000000000000000000006064820152608401610c41565b61199c816117bf6001546000540390565b6117c99190612ef6565b11156118175760405162461bcd60e51b815260206004820152601660248201527f416d6f756e74206578636565647320737570706c792e000000000000000000006044820152606401610c41565b34816010546118269190612f49565b146118735760405162461bcd60e51b815260206004820152601b60248201527f4554482073656e74206e6f7420657175616c20746f20636f73742e00000000006044820152606401610c41565b61166333826121c9565b6001600160a01b0382163314156118c0576040517fb06307db00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3360008181526007602090815260408083206001600160a01b0387168085529083529281902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b611955848484611ef5565b6001600160a01b0383163b156119a75761197184848484612362565b6119a7576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50505050565b600f546001600160a01b03163314611a075760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610c41565b60138054821515610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff9091161790556040517f1050112436208e776d9a33d97ca1981ed83303d2a93ccbd8c54f7a774c00f8149061169b90831515815260200190565b600f546001600160a01b03163314611ac75760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610c41565b601380547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00168215159081179091556040519081527fe333f8a36ee86e754548af2d6f50c73ff0d501e22e6c784662123dbbe493c6029060200161169b565b6060611b3182611ca5565b611b67576040517fa14c4b5000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000611b716124da565b9050805160001415611b92576040518060200160405280600081525061122a565b80611b9c846124e9565b604051602001611bad929190612e78565b6040516020818303038152906040529392505050565b600f546001600160a01b03163314611c1d5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610c41565b6001600160a01b038116611c995760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f64647265737300000000000000000000000000000000000000000000000000006064820152608401610c41565b611ca2816121e7565b50565b60008054821080156109a85750506000908152600460205260409020547c0100000000000000000000000000000000000000000000000000000000161590565b600081600054811015611d64576000818152600460205260409020547c01000000000000000000000000000000000000000000000000000000008116611d62575b8061122a57507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01600081815260046020526040902054611d26565b505b6040517fdf2d9b4200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6008546001600160a01b0384166000908152600a602052604081205490918391611dc09086612f49565b611dca9190612f0e565b611dd49190612f86565b949350505050565b80471015611e2c5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a20696e73756666696369656e742062616c616e63650000006044820152606401610c41565b6000826001600160a01b03168260405160006040518083038185875af1925050503d8060008114611e79576040519150601f19603f3d011682016040523d82523d6000602084013e611e7e565b606091505b5050905080610da55760405162461bcd60e51b815260206004820152603a60248201527f416464726573733a20756e61626c6520746f2073656e642076616c75652c207260448201527f6563697069656e74206d617920686176652072657665727465640000000000006064820152608401610c41565b6000611f0082611ce5565b9050836001600160a01b0316816001600160a01b031614611f4d576040517fa114810000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000336001600160a01b0386161480611f6b5750611f6b8533610866565b80611f86575033611f7b84610a40565b6001600160a01b0316145b905080611fbf576040517f59c896be00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001600160a01b038416611fff576040517fea553b3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600083815260066020908152604080832080547fffffffffffffffffffffffff00000000000000000000000000000000000000001690556001600160a01b0388811684526005835281842080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190558716835280832080546001019055858352600490915290207c02000000000000000000000000000000000000000000000000000000004260a01b8617811790915582166120eb57600183016000818152600460205260409020546120e95760005481146120e95760008181526004602052604090208390555b505b82846001600160a01b0316866001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a45050505050565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb00000000000000000000000000000000000000000000000000000000179052610da5908490612556565b6000826121c0858461263b565b14949350505050565b6121e38282604051806020016040528060008152506126af565b5050565b600f80546001600160a01b038381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6000546001600160a01b038316612294576040517f2e07630000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b816122cb576040517fb562e8dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001600160a01b03831660009081526005602090815260408083208054680100000000000000018702019055838352600490915290204260a01b84176001841460e11b179055808083015b6040516001830192906001600160a01b038716906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a48082106123165750600055505050565b6040517f150b7a020000000000000000000000000000000000000000000000000000000081526000906001600160a01b0385169063150b7a02906123b0903390899088908890600401612ea7565b602060405180830381600087803b1580156123ca57600080fd5b505af1925050508015612418575060408051601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016820190925261241591810190612d37565b60015b61248c573d808015612446576040519150601f19603f3d011682016040523d82523d6000602084013e61244b565b606091505b508051612484576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805181602001fd5b7fffffffff00000000000000000000000000000000000000000000000000000000167f150b7a0200000000000000000000000000000000000000000000000000000000149050949350505050565b6060601180546109bd90612fc9565b604080516080810191829052607f0190826030600a8206018353600a90045b801561252657600183039250600a81066030018353600a9004612508565b508190037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0909101908152919050565b60006125ab826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b031661286c9092919063ffffffff16565b805190915015610da557808060200190518101906125c99190612ce4565b610da55760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610c41565b600081815b84518110156126a757600085828151811061265d5761265d613085565b602002602001015190508083116126835760008381526020829052604090209250612694565b600081815260208490526040902092505b508061269f8161301d565b915050612640565b509392505050565b6000546001600160a01b0384166126f2576040517f2e07630000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b82612729576040517fb562e8dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001600160a01b03841660008181526005602090815260408083208054680100000000000000018902019055848352600490915290204260a01b86176001861460e11b1790558190818501903b15612817575b60405182906001600160a01b038816906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a46127c76000878480600101955087612362565b6127fd576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80821061277c57826000541461281257600080fd5b61285c565b5b6040516001830192906001600160a01b038816906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a4808210612818575b5060009081556119a79085838684565b6060611dd48484600085856001600160a01b0385163b6128ce5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610c41565b600080866001600160a01b031685876040516128ea9190612e5c565b60006040518083038185875af1925050503d8060008114612927576040519150601f19603f3d011682016040523d82523d6000602084013e61292c565b606091505b509150915061293c828286612947565b979650505050505050565b6060831561295657508161122a565b8251156129665782518084602001fd5b8160405162461bcd60e51b8152600401610c419190612ee3565b82805461298c90612fc9565b90600052602060002090601f0160209004810192826129ae5760008555612a12565b82601f106129e5578280017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00823516178555612a12565b82800160010185558215612a12579182015b82811115612a125782358255916020019190600101906129f7565b50612a1e929150612a22565b5090565b5b80821115612a1e5760008155600101612a23565b60008083601f840112612a4957600080fd5b50813567ffffffffffffffff811115612a6157600080fd5b6020830191508360208260051b8501011115612a7c57600080fd5b9250929050565b600060208284031215612a9557600080fd5b813561122a816130e3565b60008060408385031215612ab357600080fd5b8235612abe816130e3565b91506020830135612ace816130e3565b809150509250929050565b600080600060608486031215612aee57600080fd5b8335612af9816130e3565b92506020840135612b09816130e3565b929592945050506040919091013590565b60008060008060808587031215612b3057600080fd5b8435612b3b816130e3565b93506020850135612b4b816130e3565b925060408501359150606085013567ffffffffffffffff80821115612b6f57600080fd5b818701915087601f830112612b8357600080fd5b813581811115612b9557612b956130b4565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908382118183101715612bdb57612bdb6130b4565b816040528281528a6020848701011115612bf457600080fd5b82602086016020830137600060208483010152809550505050505092959194509250565b600080600060408486031215612c2d57600080fd5b8335612c38816130e3565b9250602084013567ffffffffffffffff811115612c5457600080fd5b612c6086828701612a37565b9497909650939450505050565b60008060408385031215612c8057600080fd5b8235612c8b816130e3565b91506020830135612ace816130f8565b60008060408385031215612cae57600080fd5b8235612cb9816130e3565b946020939093013593505050565b600060208284031215612cd957600080fd5b813561122a816130f8565b600060208284031215612cf657600080fd5b815161122a816130f8565b600060208284031215612d1357600080fd5b5035919050565b600060208284031215612d2c57600080fd5b813561122a81613106565b600060208284031215612d4957600080fd5b815161122a81613106565b60008060208385031215612d6757600080fd5b823567ffffffffffffffff80821115612d7f57600080fd5b818501915085601f830112612d9357600080fd5b813581811115612da257600080fd5b866020828501011115612db457600080fd5b60209290920196919550909350505050565b600060208284031215612dd857600080fd5b5051919050565b600080600060408486031215612df457600080fd5b83359250602084013567ffffffffffffffff811115612c5457600080fd5b60008151808452612e2a816020860160208601612f9d565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60008251612e6e818460208701612f9d565b9190910192915050565b60008351612e8a818460208801612f9d565b835190830190612e9e818360208801612f9d565b01949350505050565b60006001600160a01b03808716835280861660208401525083604083015260806060830152612ed96080830184612e12565b9695505050505050565b60208152600061122a6020830184612e12565b60008219821115612f0957612f09613056565b500190565b600082612f44577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615612f8157612f81613056565b500290565b600082821015612f9857612f98613056565b500390565b60005b83811015612fb8578181015183820152602001612fa0565b838111156119a75750506000910152565b600181811c90821680612fdd57607f821691505b60208210811415613017577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82141561304f5761304f613056565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6001600160a01b0381168114611ca257600080fd5b8015158114611ca257600080fd5b7fffffffff0000000000000000000000000000000000000000000000000000000081168114611ca257600080fdfea2646970667358221220c81c38ba5a636010f6fd88b4a9ec98932674dccb01dfa17898ddc80b6405a42564736f6c63430008070033000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001a0000000000000000000000000000000000000000000000000000000000000000a46726e647320436c756200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000546524e44530000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000c5d054620a396060fa28aa19cf30debd1c5d52840000000000000000000000006b99d2b10f3cc0ce6b871a9f5f94e1ecd6222f47000000000000000000000000ce419c6514045e6c7376cadabbd9a471ed7e30370000000000000000000000004a9a70f9f7127976fd892e122da07dccad8545b8000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000140000000000000000000000000000000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000000f000000000000000000000000000000000000000000000000000000000000002d
Deployed Bytecode
0x6080604052600436106102e05760003560e01c80636352211e11610184578063a22cb465116100d6578063ce7c2ac21161008a578063e985e9c511610064578063e985e9c51461084b578063f2fde38b14610894578063f3b2db3f146108b457600080fd5b8063ce7c2ac2146107ca578063d79779b214610800578063e33b7de31461083657600080fd5b8063bce4d6ae116100bb578063bce4d6ae1461076a578063c4e370951461078a578063c87b56dd146107aa57600080fd5b8063a22cb4651461072a578063b88d4fde1461074a57600080fd5b8063819b25ba1161013857806395d89b411161011257806395d89b41146106cc5780639852595c146106e1578063a0712d681461071757600080fd5b8063819b25ba1461066e5780638b83209b1461068e5780638da5cb5b146106ae57600080fd5b80636c0360eb116101695780636c0360eb1461062457806370a0823114610639578063715018a61461065957600080fd5b80636352211e146105ea57806368428a1b1461060a57600080fd5b806332cb6b0c1161023d57806344a0d68a116101f157806355f804b3116101cb57806355f804b3146105975780635a23dd99146105b75780635a546223146105d757600080fd5b806344a0d68a1461053857806348b750441461055857806353135ca01461057857600080fd5b8063406072a911610222578063406072a9146104b257806342842e0e146104f8578063440bc7f31461051857600080fd5b806332cb6b0c146104875780633a98ef391461049d57600080fd5b806318160ddd1161029457806323b872dd1161027957806323b872dd1461043c5780632e0367681461045c5780632eb4a7ab1461047157600080fd5b806318160ddd14610403578063191655871461041c57600080fd5b8063081812fc116102c5578063081812fc14610385578063095ea7b3146103bd57806313faede6146103df57600080fd5b806301ffc9a71461032e57806306fdde031461036357600080fd5b36610329577f6ef95f06320e7a25a04a175ca677b7052bdd97131872c2192525a629f51be77033604080516001600160a01b0390921682523460208301520160405180910390a1005b600080fd5b34801561033a57600080fd5b5061034e610349366004612d1a565b6108c9565b60405190151581526020015b60405180910390f35b34801561036f57600080fd5b506103786109ae565b60405161035a9190612ee3565b34801561039157600080fd5b506103a56103a0366004612d01565b610a40565b6040516001600160a01b03909116815260200161035a565b3480156103c957600080fd5b506103dd6103d8366004612c9b565b610a9d565b005b3480156103eb57600080fd5b506103f560105481565b60405190815260200161035a565b34801561040f57600080fd5b50600154600054036103f5565b34801561042857600080fd5b506103dd610437366004612a83565b610bba565b34801561044857600080fd5b506103dd610457366004612ad9565b610d9a565b34801561046857600080fd5b506103f5600581565b34801561047d57600080fd5b506103f560125481565b34801561049357600080fd5b506103f561199c81565b3480156104a957600080fd5b506008546103f5565b3480156104be57600080fd5b506103f56104cd366004612aa0565b6001600160a01b039182166000908152600e6020908152604080832093909416825291909152205490565b34801561050457600080fd5b506103dd610513366004612ad9565b610daa565b34801561052457600080fd5b506103dd610533366004612d01565b610dc5565b34801561054457600080fd5b506103dd610553366004612d01565b610e24565b34801561056457600080fd5b506103dd610573366004612aa0565b610e83565b34801561058457600080fd5b5060135461034e90610100900460ff1681565b3480156105a357600080fd5b506103dd6105b2366004612d54565b611130565b3480156105c357600080fd5b5061034e6105d2366004612c18565b611196565b6103dd6105e5366004612ddf565b611231565b3480156105f657600080fd5b506103a5610605366004612d01565b611498565b34801561061657600080fd5b5060135461034e9060ff1681565b34801561063057600080fd5b506103786114a3565b34801561064557600080fd5b506103f5610654366004612a83565b611531565b34801561066557600080fd5b506103dd611599565b34801561067a57600080fd5b506103dd610689366004612d01565b6115ff565b34801561069a57600080fd5b506103a56106a9366004612d01565b6116a6565b3480156106ba57600080fd5b50600f546001600160a01b03166103a5565b3480156106d857600080fd5b506103786116d6565b3480156106ed57600080fd5b506103f56106fc366004612a83565b6001600160a01b03166000908152600b602052604090205490565b6103dd610725366004612d01565b6116e5565b34801561073657600080fd5b506103dd610745366004612c6d565b61187d565b34801561075657600080fd5b506103dd610765366004612b1a565b61194a565b34801561077657600080fd5b506103dd610785366004612cc7565b6119ad565b34801561079657600080fd5b506103dd6107a5366004612cc7565b611a6d565b3480156107b657600080fd5b506103786107c5366004612d01565b611b26565b3480156107d657600080fd5b506103f56107e5366004612a83565b6001600160a01b03166000908152600a602052604090205490565b34801561080c57600080fd5b506103f561081b366004612a83565b6001600160a01b03166000908152600d602052604090205490565b34801561084257600080fd5b506009546103f5565b34801561085757600080fd5b5061034e610866366004612aa0565b6001600160a01b03918216600090815260076020908152604080832093909416825291909152205460ff1690565b3480156108a057600080fd5b506103dd6108af366004612a83565b611bc3565b3480156108c057600080fd5b506103f5600a81565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316148061095c57507f80ac58cd000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316145b806109a857507f5b5e139f000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316145b92915050565b6060600280546109bd90612fc9565b80601f01602080910402602001604051908101604052809291908181526020018280546109e990612fc9565b8015610a365780601f10610a0b57610100808354040283529160200191610a36565b820191906000526020600020905b815481529060010190602001808311610a1957829003601f168201915b5050505050905090565b6000610a4b82611ca5565b610a81576040517fcf4700e400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b506000908152600660205260409020546001600160a01b031690565b6000610aa882611ce5565b9050806001600160a01b0316836001600160a01b03161415610af6576040517f943f7b8c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b336001600160a01b03821614610b4657610b108133610866565b610b46576040517fcfb3b94200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008281526006602052604080822080547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0387811691821790925591518593918516917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591a4505050565b6001600160a01b0381166000908152600a6020526040902054610c4a5760405162461bcd60e51b815260206004820152602660248201527f5061796d656e7453706c69747465723a206163636f756e7420686173206e6f2060448201527f736861726573000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b6000610c5560095490565b610c5f9047612ef6565b90506000610c8c8383610c87866001600160a01b03166000908152600b602052604090205490565b611d96565b905080610d015760405162461bcd60e51b815260206004820152602b60248201527f5061796d656e7453706c69747465723a206163636f756e74206973206e6f742060448201527f647565207061796d656e740000000000000000000000000000000000000000006064820152608401610c41565b6001600160a01b0383166000908152600b602052604081208054839290610d29908490612ef6565b925050819055508060096000828254610d429190612ef6565b90915550610d5290508382611ddc565b604080516001600160a01b0385168152602081018390527fdf20fd1e76bc69d672e4814fafb2c449bba3a5369d8359adf9e05e6fde87b05691015b60405180910390a1505050565b610da5838383611ef5565b505050565b610da58383836040518060200160405280600081525061194a565b600f546001600160a01b03163314610e1f5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610c41565b601255565b600f546001600160a01b03163314610e7e5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610c41565b601055565b6001600160a01b0381166000908152600a6020526040902054610f0e5760405162461bcd60e51b815260206004820152602660248201527f5061796d656e7453706c69747465723a206163636f756e7420686173206e6f2060448201527f73686172657300000000000000000000000000000000000000000000000000006064820152608401610c41565b6001600160a01b0382166000908152600d60205260408120546040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201526001600160a01b038516906370a082319060240160206040518083038186803b158015610f7f57600080fd5b505afa158015610f93573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fb79190612dc6565b610fc19190612ef6565b90506000610ffa8383610c8787876001600160a01b039182166000908152600e6020908152604080832093909416825291909152205490565b90508061106f5760405162461bcd60e51b815260206004820152602b60248201527f5061796d656e7453706c69747465723a206163636f756e74206973206e6f742060448201527f647565207061796d656e740000000000000000000000000000000000000000006064820152608401610c41565b6001600160a01b038085166000908152600e60209081526040808320938716835292905290812080548392906110a6908490612ef6565b90915550506001600160a01b0384166000908152600d6020526040812080548392906110d3908490612ef6565b909155506110e49050848483612133565b604080516001600160a01b038581168252602082018490528616917f3be5b7a71e84ed12875d241991c70855ac5817d847039e17a9d895c1ceb0f18a910160405180910390a250505050565b600f546001600160a01b0316331461118a5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610c41565b610da560118383612980565b6040517fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606085901b16602082015260009081906034016040516020818303038152906040528051906020012090506112268484808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152505060125491508490506121b3565b9150505b9392505050565b601354610100900460ff166112885760405162461bcd60e51b815260206004820152601a60248201527f50726573616c65206973206e6f7420796574206163746976652e0000000000006044820152606401610c41565b611293338383611196565b6112df5760405162461bcd60e51b815260206004820152601b60248201527f41646472657373206973206e6f742077686974656c69737465642e00000000006044820152606401610c41565b60058361130f336001600160a01b03166000908152600560205260409081902054901c67ffffffffffffffff1690565b6113199190612ef6565b111561138d5760405162461bcd60e51b815260206004820152602960248201527f416d6f756e74206f6620746f6b656e7320657863656564732077686974656c6960448201527f7374206c696d69742e00000000000000000000000000000000000000000000006064820152608401610c41565b61199c8361139e6001546000540390565b6113a89190612ef6565b11156113f65760405162461bcd60e51b815260206004820152601660248201527f416d6f756e74206578636565647320737570706c792e000000000000000000006044820152606401610c41565b34836010546114059190612f49565b146114525760405162461bcd60e51b815260206004820152601b60248201527f4554482073656e74206e6f7420657175616c20746f20636f73742e00000000006044820152606401610c41565b61145c33846121c9565b7fc8b17f75f53401f272e9ee7fa431e81ba33779363238896180425a422420c8f761148a6001546000540390565b604051908152602001610d8d565b60006109a882611ce5565b601180546114b090612fc9565b80601f01602080910402602001604051908101604052809291908181526020018280546114dc90612fc9565b80156115295780601f106114fe57610100808354040283529160200191611529565b820191906000526020600020905b81548152906001019060200180831161150c57829003601f168201915b505050505081565b60006001600160a01b038216611573576040517f8f4eb60400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b506001600160a01b031660009081526005602052604090205467ffffffffffffffff1690565b600f546001600160a01b031633146115f35760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610c41565b6115fd60006121e7565b565b600f546001600160a01b031633146116595760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610c41565b6116633382612251565b7fc8b17f75f53401f272e9ee7fa431e81ba33779363238896180425a422420c8f76116916001546000540390565b6040519081526020015b60405180910390a150565b6000600c82815481106116bb576116bb613085565b6000918252602090912001546001600160a01b031692915050565b6060600380546109bd90612fc9565b60135460ff166117375760405162461bcd60e51b815260206004820152601760248201527f53616c65206973206e6f7420796574206163746976652e0000000000000000006044820152606401610c41565b600a8111156117ae5760405162461bcd60e51b815260206004820152602b60248201527f416d6f756e74206f6620746f6b656e732065786365656473207472616e73616360448201527f74696f6e206c696d69742e0000000000000000000000000000000000000000006064820152608401610c41565b61199c816117bf6001546000540390565b6117c99190612ef6565b11156118175760405162461bcd60e51b815260206004820152601660248201527f416d6f756e74206578636565647320737570706c792e000000000000000000006044820152606401610c41565b34816010546118269190612f49565b146118735760405162461bcd60e51b815260206004820152601b60248201527f4554482073656e74206e6f7420657175616c20746f20636f73742e00000000006044820152606401610c41565b61166333826121c9565b6001600160a01b0382163314156118c0576040517fb06307db00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3360008181526007602090815260408083206001600160a01b0387168085529083529281902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b611955848484611ef5565b6001600160a01b0383163b156119a75761197184848484612362565b6119a7576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50505050565b600f546001600160a01b03163314611a075760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610c41565b60138054821515610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff9091161790556040517f1050112436208e776d9a33d97ca1981ed83303d2a93ccbd8c54f7a774c00f8149061169b90831515815260200190565b600f546001600160a01b03163314611ac75760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610c41565b601380547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00168215159081179091556040519081527fe333f8a36ee86e754548af2d6f50c73ff0d501e22e6c784662123dbbe493c6029060200161169b565b6060611b3182611ca5565b611b67576040517fa14c4b5000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000611b716124da565b9050805160001415611b92576040518060200160405280600081525061122a565b80611b9c846124e9565b604051602001611bad929190612e78565b6040516020818303038152906040529392505050565b600f546001600160a01b03163314611c1d5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610c41565b6001600160a01b038116611c995760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f64647265737300000000000000000000000000000000000000000000000000006064820152608401610c41565b611ca2816121e7565b50565b60008054821080156109a85750506000908152600460205260409020547c0100000000000000000000000000000000000000000000000000000000161590565b600081600054811015611d64576000818152600460205260409020547c01000000000000000000000000000000000000000000000000000000008116611d62575b8061122a57507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01600081815260046020526040902054611d26565b505b6040517fdf2d9b4200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6008546001600160a01b0384166000908152600a602052604081205490918391611dc09086612f49565b611dca9190612f0e565b611dd49190612f86565b949350505050565b80471015611e2c5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a20696e73756666696369656e742062616c616e63650000006044820152606401610c41565b6000826001600160a01b03168260405160006040518083038185875af1925050503d8060008114611e79576040519150601f19603f3d011682016040523d82523d6000602084013e611e7e565b606091505b5050905080610da55760405162461bcd60e51b815260206004820152603a60248201527f416464726573733a20756e61626c6520746f2073656e642076616c75652c207260448201527f6563697069656e74206d617920686176652072657665727465640000000000006064820152608401610c41565b6000611f0082611ce5565b9050836001600160a01b0316816001600160a01b031614611f4d576040517fa114810000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000336001600160a01b0386161480611f6b5750611f6b8533610866565b80611f86575033611f7b84610a40565b6001600160a01b0316145b905080611fbf576040517f59c896be00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001600160a01b038416611fff576040517fea553b3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600083815260066020908152604080832080547fffffffffffffffffffffffff00000000000000000000000000000000000000001690556001600160a01b0388811684526005835281842080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190558716835280832080546001019055858352600490915290207c02000000000000000000000000000000000000000000000000000000004260a01b8617811790915582166120eb57600183016000818152600460205260409020546120e95760005481146120e95760008181526004602052604090208390555b505b82846001600160a01b0316866001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a45050505050565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb00000000000000000000000000000000000000000000000000000000179052610da5908490612556565b6000826121c0858461263b565b14949350505050565b6121e38282604051806020016040528060008152506126af565b5050565b600f80546001600160a01b038381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6000546001600160a01b038316612294576040517f2e07630000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b816122cb576040517fb562e8dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001600160a01b03831660009081526005602090815260408083208054680100000000000000018702019055838352600490915290204260a01b84176001841460e11b179055808083015b6040516001830192906001600160a01b038716906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a48082106123165750600055505050565b6040517f150b7a020000000000000000000000000000000000000000000000000000000081526000906001600160a01b0385169063150b7a02906123b0903390899088908890600401612ea7565b602060405180830381600087803b1580156123ca57600080fd5b505af1925050508015612418575060408051601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016820190925261241591810190612d37565b60015b61248c573d808015612446576040519150601f19603f3d011682016040523d82523d6000602084013e61244b565b606091505b508051612484576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805181602001fd5b7fffffffff00000000000000000000000000000000000000000000000000000000167f150b7a0200000000000000000000000000000000000000000000000000000000149050949350505050565b6060601180546109bd90612fc9565b604080516080810191829052607f0190826030600a8206018353600a90045b801561252657600183039250600a81066030018353600a9004612508565b508190037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0909101908152919050565b60006125ab826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b031661286c9092919063ffffffff16565b805190915015610da557808060200190518101906125c99190612ce4565b610da55760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610c41565b600081815b84518110156126a757600085828151811061265d5761265d613085565b602002602001015190508083116126835760008381526020829052604090209250612694565b600081815260208490526040902092505b508061269f8161301d565b915050612640565b509392505050565b6000546001600160a01b0384166126f2576040517f2e07630000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b82612729576040517fb562e8dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001600160a01b03841660008181526005602090815260408083208054680100000000000000018902019055848352600490915290204260a01b86176001861460e11b1790558190818501903b15612817575b60405182906001600160a01b038816906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a46127c76000878480600101955087612362565b6127fd576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80821061277c57826000541461281257600080fd5b61285c565b5b6040516001830192906001600160a01b038816906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a4808210612818575b5060009081556119a79085838684565b6060611dd48484600085856001600160a01b0385163b6128ce5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610c41565b600080866001600160a01b031685876040516128ea9190612e5c565b60006040518083038185875af1925050503d8060008114612927576040519150601f19603f3d011682016040523d82523d6000602084013e61292c565b606091505b509150915061293c828286612947565b979650505050505050565b6060831561295657508161122a565b8251156129665782518084602001fd5b8160405162461bcd60e51b8152600401610c419190612ee3565b82805461298c90612fc9565b90600052602060002090601f0160209004810192826129ae5760008555612a12565b82601f106129e5578280017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00823516178555612a12565b82800160010185558215612a12579182015b82811115612a125782358255916020019190600101906129f7565b50612a1e929150612a22565b5090565b5b80821115612a1e5760008155600101612a23565b60008083601f840112612a4957600080fd5b50813567ffffffffffffffff811115612a6157600080fd5b6020830191508360208260051b8501011115612a7c57600080fd5b9250929050565b600060208284031215612a9557600080fd5b813561122a816130e3565b60008060408385031215612ab357600080fd5b8235612abe816130e3565b91506020830135612ace816130e3565b809150509250929050565b600080600060608486031215612aee57600080fd5b8335612af9816130e3565b92506020840135612b09816130e3565b929592945050506040919091013590565b60008060008060808587031215612b3057600080fd5b8435612b3b816130e3565b93506020850135612b4b816130e3565b925060408501359150606085013567ffffffffffffffff80821115612b6f57600080fd5b818701915087601f830112612b8357600080fd5b813581811115612b9557612b956130b4565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908382118183101715612bdb57612bdb6130b4565b816040528281528a6020848701011115612bf457600080fd5b82602086016020830137600060208483010152809550505050505092959194509250565b600080600060408486031215612c2d57600080fd5b8335612c38816130e3565b9250602084013567ffffffffffffffff811115612c5457600080fd5b612c6086828701612a37565b9497909650939450505050565b60008060408385031215612c8057600080fd5b8235612c8b816130e3565b91506020830135612ace816130f8565b60008060408385031215612cae57600080fd5b8235612cb9816130e3565b946020939093013593505050565b600060208284031215612cd957600080fd5b813561122a816130f8565b600060208284031215612cf657600080fd5b815161122a816130f8565b600060208284031215612d1357600080fd5b5035919050565b600060208284031215612d2c57600080fd5b813561122a81613106565b600060208284031215612d4957600080fd5b815161122a81613106565b60008060208385031215612d6757600080fd5b823567ffffffffffffffff80821115612d7f57600080fd5b818501915085601f830112612d9357600080fd5b813581811115612da257600080fd5b866020828501011115612db457600080fd5b60209290920196919550909350505050565b600060208284031215612dd857600080fd5b5051919050565b600080600060408486031215612df457600080fd5b83359250602084013567ffffffffffffffff811115612c5457600080fd5b60008151808452612e2a816020860160208601612f9d565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60008251612e6e818460208701612f9d565b9190910192915050565b60008351612e8a818460208801612f9d565b835190830190612e9e818360208801612f9d565b01949350505050565b60006001600160a01b03808716835280861660208401525083604083015260806060830152612ed96080830184612e12565b9695505050505050565b60208152600061122a6020830184612e12565b60008219821115612f0957612f09613056565b500190565b600082612f44577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615612f8157612f81613056565b500290565b600082821015612f9857612f98613056565b500390565b60005b83811015612fb8578181015183820152602001612fa0565b838111156119a75750506000910152565b600181811c90821680612fdd57607f821691505b60208210811415613017577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82141561304f5761304f613056565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6001600160a01b0381168114611ca257600080fd5b8015158114611ca257600080fd5b7fffffffff0000000000000000000000000000000000000000000000000000000081168114611ca257600080fdfea2646970667358221220c81c38ba5a636010f6fd88b4a9ec98932674dccb01dfa17898ddc80b6405a42564736f6c63430008070033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001a0000000000000000000000000000000000000000000000000000000000000000a46726e647320436c756200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000546524e44530000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000c5d054620a396060fa28aa19cf30debd1c5d52840000000000000000000000006b99d2b10f3cc0ce6b871a9f5f94e1ecd6222f47000000000000000000000000ce419c6514045e6c7376cadabbd9a471ed7e30370000000000000000000000004a9a70f9f7127976fd892e122da07dccad8545b8000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000140000000000000000000000000000000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000000f000000000000000000000000000000000000000000000000000000000000002d
-----Decoded View---------------
Arg [0] : _name (string): Frnds Club
Arg [1] : _symbol (string): FRNDS
Arg [2] : _shareholders (address[]): 0xc5d054620A396060FA28aa19CF30deBd1C5D5284,0x6B99D2B10f3Cc0CE6b871A9F5f94e1ECD6222f47,0xCE419c6514045e6C7376CADABbd9A471eD7E3037,0x4A9A70F9F7127976Fd892E122DA07DCcAD8545b8
Arg [3] : _shares (uint256[]): 20,20,15,45
-----Encoded View---------------
18 Constructor Arguments found :
Arg [0] : 0000000000000000000000000000000000000000000000000000000000000080
Arg [1] : 00000000000000000000000000000000000000000000000000000000000000c0
Arg [2] : 0000000000000000000000000000000000000000000000000000000000000100
Arg [3] : 00000000000000000000000000000000000000000000000000000000000001a0
Arg [4] : 000000000000000000000000000000000000000000000000000000000000000a
Arg [5] : 46726e647320436c756200000000000000000000000000000000000000000000
Arg [6] : 0000000000000000000000000000000000000000000000000000000000000005
Arg [7] : 46524e4453000000000000000000000000000000000000000000000000000000
Arg [8] : 0000000000000000000000000000000000000000000000000000000000000004
Arg [9] : 000000000000000000000000c5d054620a396060fa28aa19cf30debd1c5d5284
Arg [10] : 0000000000000000000000006b99d2b10f3cc0ce6b871a9f5f94e1ecd6222f47
Arg [11] : 000000000000000000000000ce419c6514045e6c7376cadabbd9a471ed7e3037
Arg [12] : 0000000000000000000000004a9a70f9f7127976fd892e122da07dccad8545b8
Arg [13] : 0000000000000000000000000000000000000000000000000000000000000004
Arg [14] : 0000000000000000000000000000000000000000000000000000000000000014
Arg [15] : 0000000000000000000000000000000000000000000000000000000000000014
Arg [16] : 000000000000000000000000000000000000000000000000000000000000000f
Arg [17] : 000000000000000000000000000000000000000000000000000000000000002d
Deployed Bytecode Sourcemap
340:3845:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3249:40:2;719:10:6;3249:40:2;;;-1:-1:-1;;;;;9690:55:10;;;9672:74;;3279:9:2;9777:2:10;9762:18;;9755:34;9645:18;3249:40:2;;;;;;;340:3845:0;;;;;4880:607:8;;;;;;;;;;-1:-1:-1;4880:607:8;;;;;:::i;:::-;;:::i;:::-;;;10783:14:10;;10776:22;10758:41;;10746:2;10731:18;4880:607:8;;;;;;;;9768:98;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;11769:200::-;;;;;;;;;;-1:-1:-1;11769:200:8;;;;;:::i;:::-;;:::i;:::-;;;-1:-1:-1;;;;;9423:55:10;;;9405:74;;9393:2;9378:18;11769:200:8;9259:226:10;11245:463:8;;;;;;;;;;-1:-1:-1;11245:463:8;;;;;:::i;:::-;;:::i;:::-;;594:33:0;;;;;;;;;;;;;;;;;;;10956:25:10;;;10944:2;10929:18;594:33:0;10810:177:10;3963:309:8;;;;;;;;;;-1:-1:-1;4225:12:8;;4016:7;4209:13;:28;3963:309;;4977:553:2;;;;;;;;;;-1:-1:-1;4977:553:2;;;;;:::i;:::-;;:::i;12629:164:8:-;;;;;;;;;;-1:-1:-1;12629:164:8;;;;;:::i;:::-;;:::i;773:45:0:-;;;;;;;;;;;;817:1;773:45;;710:25;;;;;;;;;;;;;;;;524:41;;;;;;;;;;;;561:4;524:41;;3374:89:2;;;;;;;;;;-1:-1:-1;3444:12:2;;3374:89;;4466:133;;;;;;;;;;-1:-1:-1;4466:133:2;;;;;:::i;:::-;-1:-1:-1;;;;;4562:21:2;;;4536:7;4562:21;;;:14;:21;;;;;;;;:30;;;;;;;;;;;;;4466:133;12859:179:8;;;;;;;;;;-1:-1:-1;12859:179:8;;;;;:::i;:::-;;:::i;2299:83:0:-;;;;;;;;;;-1:-1:-1;2299:83:0;;;;;:::i;:::-;;:::i;2443:72::-;;;;;;;;;;-1:-1:-1;2443:72:0;;;;;:::i;:::-;;:::i;5791:628:2:-;;;;;;;;;;-1:-1:-1;5791:628:2;;;;;:::i;:::-;;:::i;907:33:0:-;;;;;;;;;;-1:-1:-1;907:33:0;;;;;;;;;;;2590:86;;;;;;;;;;-1:-1:-1;2590:86:0;;;;;:::i;:::-;;:::i;1646:211::-;;;;;;;;;;-1:-1:-1;1646:211:0;;;;;:::i;:::-;;:::i;3090:554::-;;;;;;:::i;:::-;;:::i;9564:142:8:-;;;;;;;;;;-1:-1:-1;9564:142:8;;;;;:::i;:::-;;:::i;850:30:0:-;;;;;;;;;;-1:-1:-1;850:30:0;;;;;;;;649:21;;;;;;;;;;;;;:::i;5546:221:8:-;;;;;;;;;;-1:-1:-1;5546:221:8;;;;;:::i;:::-;;:::i;1668:101:1:-;;;;;;;;;;;;;:::i;2795:129:0:-;;;;;;;;;;-1:-1:-1;2795:129:0;;;;;:::i;:::-;;:::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;;9930:102:8;;;;;;;;;;;;;:::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;3781:402:0;;;;;;:::i;:::-;;:::i;12036:303:8:-;;;;;;;;;;-1:-1:-1;12036:303:8;;;;;:::i;:::-;;:::i;13104:385::-;;;;;;;;;;-1:-1:-1;13104:385:8;;;;;:::i;:::-;;:::i;2117:122:0:-;;;;;;;;;;-1:-1:-1;2117:122:0;;;;;:::i;:::-;;:::i;1931:113::-;;;;;;;;;;-1:-1:-1;1931:113:0;;;;;:::i;:::-;;:::i;10098:313:8:-;;;;;;;;;;-1:-1:-1;10098:313:8;;;;;:::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;;12405:162:8;;;;;;;;;;-1:-1:-1;12405:162:8;;;;;:::i;:::-;-1:-1:-1;;;;;12525:25:8;;;12502:4;12525:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;;;12405:162;1918:198:1;;;;;;;;;;-1:-1:-1;1918:198:1;;;;;:::i;:::-;;:::i;437:35:0:-;;;;;;;;;;;;470:2;437:35;;4880:607:8;4965:4;5260:25;;;;;;:101;;-1:-1:-1;5336:25:8;;;;;5260:101;:177;;;-1:-1:-1;5412:25:8;;;;;5260:177;5241:196;4880:607;-1:-1:-1;;4880:607:8:o;9768:98::-;9822:13;9854:5;9847:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;9768:98;:::o;11769:200::-;11837:7;11861:16;11869:7;11861;:16::i;:::-;11856:64;;11886:34;;;;;;;;;;;;;;11856:64;-1:-1:-1;11938:24:8;;;;:15;:24;;;;;;-1:-1:-1;;;;;11938:24:8;;11769:200::o;11245:463::-;11317:13;11349:27;11368:7;11349:18;:27::i;:::-;11317:61;;11398:5;-1:-1:-1;;;;;11392:11:8;:2;-1:-1:-1;;;;;11392:11:8;;11388:48;;;11412:24;;;;;;;;;;;;;;11388:48;719:10:6;-1:-1:-1;;;;;11451:28:8;;;11447:172;;11498:44;11515:5;719:10:6;12405:162:8;:::i;11498:44::-;11493:126;;11569:35;;;;;;;;;;;;;;11493:126;11629:24;;;;:15;:24;;;;;;:29;;;;-1:-1:-1;;;;;11629:29:8;;;;;;;;;11673:28;;11629:24;;11673:28;;;;;;;11307:401;11245:463;;:::o;4977:553:2:-;-1:-1:-1;;;;;5052:16:2;;5071:1;5052:16;;;:7;:16;;;;;;5044:71;;;;-1:-1:-1;;;5044:71:2;;12591:2:10;5044:71:2;;;12573:21:10;12630:2;12610:18;;;12603:30;12669:34;12649:18;;;12642:62;12740:8;12720:18;;;12713:36;12766:19;;5044:71:2;;;;;;;;;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;;14190:2:10;5286:68:2;;;14172:21:10;14229:2;14209:18;;;14202:30;14268:34;14248:18;;;14241:62;14339:13;14319:18;;;14312:41;14370:19;;5286:68:2;13988:407:10;5286:68:2;-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;;;;;9690:55:10;;9672:74;;9777:2;9762:18;;9755:34;;;5490:33:2;;9645:18:10;5490:33:2;;;;;;;;5034:496;;4977:553;:::o;12629:164:8:-;12758:28;12768:4;12774:2;12778:7;12758:9;:28::i;:::-;12629:164;;;:::o;12859:179::-;12992:39;13009:4;13015:2;13019:7;12992:39;;;;;;;;;;;;:16;:39::i;2299:83:0:-;1108:6:1;;-1:-1:-1;;;;;1108:6:1;719:10:6;1248:23:1;1240:68;;;;-1:-1:-1;;;1240:68:1;;14953:2:10;1240:68:1;;;14935:21:10;;;14972:18;;;14965:30;15031:34;15011:18;;;15004:62;15083:18;;1240:68:1;14751:356:10;1240:68:1;2360:10:0::1;:17:::0;2299:83::o;2443:72::-;1108:6:1;;-1:-1:-1;;;;;1108:6:1;719:10:6;1248:23:1;1240:68;;;;-1:-1:-1;;;1240:68:1;;14953:2:10;1240:68:1;;;14935:21:10;;;14972:18;;;14965:30;15031:34;15011:18;;;15004:62;15083:18;;1240:68:1;14751:356:10;1240:68:1;2499:4:0::1;:11:::0;2443:72::o;5791:628:2:-;-1:-1:-1;;;;;5872:16:2;;5891:1;5872:16;;;:7;:16;;;;;;5864:71;;;;-1:-1:-1;;;5864:71:2;;12591:2:10;5864:71:2;;;12573:21:10;12630:2;12610:18;;;12603:30;12669:34;12649:18;;;12642:62;12740:8;12720:18;;;12713:36;12766:19;;5864:71:2;12389:402:10;5864:71:2;-1:-1:-1;;;;;3880:26:2;;5946:21;3880:26;;;:19;:26;;;;;;5970:30;;;;;5994:4;5970:30;;;9405:74:10;-1:-1:-1;;;;;5970:15:2;;;;;9378:18:10;;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;;14190:2:10;6127:68:2;;;14172:21:10;14229:2;14209:18;;;14202:30;14268:34;14248:18;;;14241:62;14339:13;14319:18;;;14312:41;14370:19;;6127:68:2;13988:407:10;6127:68:2;-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;;;;;9690:55:10;;;9672:74;;9777:2;9762:18;;9755:34;;;6367:45:2;;;;;9645:18:10;6367:45:2;;;;;;;5854:565;;5791:628;;:::o;2590:86:0:-;1108:6:1;;-1:-1:-1;;;;;1108:6:1;719:10:6;1248:23:1;1240:68;;;;-1:-1:-1;;;1240:68:1;;14953:2:10;1240:68:1;;;14935:21:10;;;14972:18;;;14965:30;15031:34;15011:18;;;15004:62;15083:18;;1240:68:1;14751:356:10;1240:68:1;2657:14:0::1;:7;2667:4:::0;;2657:14:::1;:::i;1646:211::-:0;1770:23;;8188:66:10;8175:2;8171:15;;;8167:88;1770:23:0;;;8155:101:10;1732:4:0;;;;8272:12:10;;1770:23:0;;;;;;;;;;;;1760:34;;;;;;1744:50;;1807:45;1826:6;;1807:45;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;1834:10:0;;;-1:-1:-1;1846:5:0;;-1:-1:-1;1807:18:0;:45::i;:::-;1800:52;;;1646:211;;;;;;:::o;3090:554::-;3179:13;;;;;;;3171:52;;;;-1:-1:-1;;;3171:52:0;;17203:2:10;3171:52:0;;;17185:21:10;17242:2;17222:18;;;17215:30;17281:28;17261:18;;;17254:56;17327:18;;3171:52:0;17001:350:10;3171:52:0;3237:33;3251:10;3263:6;;3237:13;:33::i;:::-;3229:73;;;;-1:-1:-1;;;3229:73:0;;15666:2:10;3229:73:0;;;15648:21:10;15705:2;15685:18;;;15678:30;15744:29;15724:18;;;15717:57;15791:18;;3229:73:0;15464:351:10;3229:73:0;817:1;3344:4;3316:25;3330:10;-1:-1:-1;;;;;5932:25:8;5905:7;5932:25;;;:18;:25;;1151:2;5932:25;;;;;:49;;1017:13;5931:80;;5844:174;3316:25:0;:32;;;;:::i;:::-;:53;;3308:107;;;;-1:-1:-1;;;3308:107:0;;11774:2:10;3308:107:0;;;11756:21:10;11813:2;11793:18;;;11786:30;11852:34;11832:18;;;11825:62;11923:11;11903:18;;;11896:39;11952:19;;3308:107:0;11572:405:10;3308:107:0;561:4;3445;3429:13;4225:12:8;;4016:7;4209:13;:28;;3963:309;3429:13:0;:20;;;;:::i;:::-;:34;;3421:69;;;;-1:-1:-1;;;3421:69:0;;14602:2:10;3421:69:0;;;14584:21:10;14641:2;14621:18;;;14614:30;14680:24;14660:18;;;14653:52;14722:18;;3421:69:0;14400:346:10;3421:69:0;3519:9;3511:4;3504;;:11;;;;:::i;:::-;:24;3496:64;;;;-1:-1:-1;;;3496:64:0;;11418:2:10;3496:64:0;;;11400:21:10;11457:2;11437:18;;;11430:30;11496:29;11476:18;;;11469:57;11543:18;;3496:64:0;11216:351:10;3496:64:0;3567:27;3577:10;3589:4;3567:9;:27::i;:::-;3606:33;3625:13;4225:12:8;;4016:7;4209:13;:28;;3963:309;3625:13:0;3606:33;;10956:25:10;;;10944:2;10929:18;3606:33:0;10810:177:10;9564:142:8;9628:7;9670:27;9689:7;9670:18;:27::i;649:21:0:-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;5546:221:8:-;5610:7;-1:-1:-1;;;;;5633:19:8;;5629:60;;5661:28;;;;;;;;;;;;;;5629:60;-1:-1:-1;;;;;;5706:25:8;;;;;:18;:25;;;;;;1017:13;5706:54;;5546:221::o;1668:101:1:-;1108:6;;-1:-1:-1;;;;;1108:6:1;719:10:6;1248:23:1;1240:68;;;;-1:-1:-1;;;1240:68:1;;14953:2:10;1240:68:1;;;14935:21:10;;;14972:18;;;14965:30;15031:34;15011:18;;;15004:62;15083:18;;1240:68:1;14751:356:10;1240:68:1;1732:30:::1;1759:1;1732:18;:30::i;:::-;1668:101::o:0;2795:129:0:-;1108:6:1;;-1:-1:-1;;;;;1108:6:1;719:10:6;1248:23:1;1240:68;;;;-1:-1:-1;;;1240:68:1;;14953:2:10;1240:68:1;;;14935:21:10;;;14972:18;;;14965:30;15031:34;15011:18;;;15004:62;15083:18;;1240:68:1;14751:356:10;1240:68:1;2851:23:0::1;2857:10;2869:4;2851:5;:23::i;:::-;2886:33;2905:13;4225:12:8::0;;4016:7;4209:13;:28;;3963:309;2905:13:0::1;2886:33;::::0;10956:25:10;;;10944:2;10929:18;2886:33:0::1;;;;;;;;2795:129:::0;:::o;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;9930:102:8:-;9986:13;10018:7;10011:14;;;;;:::i;3781:402:0:-;3840:10;;;;3832:46;;;;-1:-1:-1;;;3832:46:0;;15314:2:10;3832:46:0;;;15296:21:10;15353:2;15333:18;;;15326:30;15392:25;15372:18;;;15365:53;15435:18;;3832:46:0;15112:347:10;3832:46:0;470:2;3892:4;:14;;3884:70;;;;-1:-1:-1;;;3884:70:0;;16022:2:10;3884:70:0;;;16004:21:10;16061:2;16041:18;;;16034:30;16100:34;16080:18;;;16073:62;16171:13;16151:18;;;16144:41;16202:19;;3884:70:0;15820:407:10;3884:70:0;561:4;3984;3968:13;4225:12:8;;4016:7;4209:13;:28;;3963:309;3968:13:0;:20;;;;:::i;:::-;:34;;3960:69;;;;-1:-1:-1;;;3960:69:0;;14602:2:10;3960:69:0;;;14584:21:10;14641:2;14621:18;;;14614:30;14680:24;14660:18;;;14653:52;14722:18;;3960:69:0;14400:346:10;3960:69:0;4058:9;4050:4;4043;;:11;;;;:::i;:::-;:24;4035:64;;;;-1:-1:-1;;;4035:64:0;;11418:2:10;4035:64:0;;;11400:21:10;11457:2;11437:18;;;11430:30;11496:29;11476:18;;;11469:57;11543:18;;4035:64:0;11216:351:10;4035:64:0;4106:27;4116:10;4128:4;4106:9;:27::i;12036:303:8:-;-1:-1:-1;;;;;12134:31:8;;719:10:6;12134:31:8;12130:61;;;12174:17;;;;;;;;;;;;;;12130:61;719:10:6;12202:39:8;;;;:18;:39;;;;;;;;-1:-1:-1;;;;;12202:49:8;;;;;;;;;;;;:60;;;;;;;;;;;;;12277:55;;10758:41:10;;;12202:49:8;;719:10:6;12277:55:8;;10731:18:10;12277:55:8;;;;;;;12036:303;;:::o;13104:385::-;13265:28;13275:4;13281:2;13285:7;13265:9;:28::i;:::-;-1:-1:-1;;;;;13307:14:8;;;:19;13303:180;;13345:56;13376:4;13382:2;13386:7;13395:5;13345:30;:56::i;:::-;13340:143;;13428:40;;;;;;;;;;;;;;13340:143;13104:385;;;;:::o;2117:122:0:-;1108:6:1;;-1:-1:-1;;;;;1108:6:1;719:10:6;1248:23:1;1240:68;;;;-1:-1:-1;;;1240:68:1;;14953:2:10;1240:68:1;;;14935:21:10;;;14972:18;;;14965:30;15031:34;15011:18;;;15004:62;15083:18;;1240:68:1;14751:356:10;1240:68:1;2178:13:0::1;:20:::0;;;::::1;;;;::::0;;;::::1;;::::0;;2209:25:::1;::::0;::::1;::::0;::::1;::::0;2194:4;10783:14:10;10776:22;10758:41;;10746:2;10731:18;;10618:187;1931:113:0;1108:6:1;;-1:-1:-1;;;;;1108:6:1;719:10:6;1248:23:1;1240:68;;;;-1:-1:-1;;;1240:68:1;;14953:2:10;1240:68:1;;;14935:21:10;;;14972:18;;;14965:30;15031:34;15011:18;;;15004:62;15083:18;;1240:68:1;14751:356:10;1240:68:1;1989:10:0::1;:17:::0;;;::::1;::::0;::::1;;::::0;;::::1;::::0;;;2017:22:::1;::::0;10758:41:10;;;2017:22:0::1;::::0;10746:2:10;10731:18;2017:22:0::1;10618:187:10::0;10098:313:8;10171:13;10201:16;10209:7;10201;:16::i;:::-;10196:59;;10226:29;;;;;;;;;;;;;;10196:59;10266:21;10290:10;:8;:10::i;:::-;10266:34;;10323:7;10317:21;10342:1;10317:26;;:87;;;;;;;;;;;;;;;;;10370:7;10379:18;10389:7;10379:9;:18::i;:::-;10353:45;;;;;;;;;:::i;:::-;;;;;;;;;;;;;10310:94;10098:313;-1:-1:-1;;;10098:313:8:o;1918:198:1:-;1108:6;;-1:-1:-1;;;;;1108:6:1;719:10:6;1248:23:1;1240:68;;;;-1:-1:-1;;;1240:68:1;;14953:2:10;1240:68:1;;;14935:21:10;;;14972:18;;;14965:30;15031:34;15011:18;;;15004:62;15083:18;;1240:68:1;14751:356:10;1240:68:1;-1:-1:-1;;;;;2006:22:1;::::1;1998:73;;;::::0;-1:-1:-1;;;1998:73:1;;12184:2:10;1998:73:1::1;::::0;::::1;12166:21:10::0;12223:2;12203:18;;;12196:30;12262:34;12242:18;;;12235:62;12333:8;12313:18;;;12306:36;12359:19;;1998:73:1::1;11982:402:10::0;1998:73:1::1;2081:28;2100:8;2081:18;:28::i;:::-;1918:198:::0;:::o;13735:268:8:-;13792:4;13879:13;;13869:7;:23;13827:150;;;;-1:-1:-1;;13929:26:8;;;;:17;:26;;;;;;1769:8;13929:43;:48;;13735:268::o;7141:1105::-;7208:7;7242;7340:13;;7333:4;:20;7329:853;;;7377:14;7394:23;;;:17;:23;;;;;;1769:8;7481:23;;7477:687;;7992:111;7999:11;7992:111;;-1:-1:-1;8069:6:8;;8051:25;;;;:17;:25;;;;;;7992:111;;7477:687;7355:827;7329:853;8208:31;;;;;;;;;;;;;;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;-1:-1:-1;;;;6591:242:2:o;2412:312:5:-;2526:6;2501:21;:31;;2493:73;;;;-1:-1:-1;;;2493:73:5;;13425:2:10;2493:73:5;;;13407:21:10;13464:2;13444:18;;;13437:30;13503:31;13483:18;;;13476:59;13552:18;;2493:73:5;13223:353:10;2493:73:5;2578:12;2596:9;-1:-1:-1;;;;;2596:14:5;2618:6;2596:33;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2577:52;;;2647:7;2639:78;;;;-1:-1:-1;;;2639:78:5;;12998:2:10;2639:78:5;;;12980:21:10;13037:2;13017:18;;;13010:30;13076:34;13056:18;;;13049:62;13147:28;13127:18;;;13120:56;13193:19;;2639:78:5;12796:422:10;18835:2460:8;18945:27;18975;18994:7;18975:18;:27::i;:::-;18945:57;;19058:4;-1:-1:-1;;;;;19017:45:8;19033:19;-1:-1:-1;;;;;19017:45:8;;19013:86;;19071:28;;;;;;;;;;;;;;19013:86;19110:22;719:10:6;-1:-1:-1;;;;;19136:27:8;;;;:86;;-1:-1:-1;19179:43:8;19196:4;719:10:6;12405:162:8;:::i;19179:43::-;19136:145;;;-1:-1:-1;719:10:6;19238:20:8;19250:7;19238:11;:20::i;:::-;-1:-1:-1;;;;;19238:43:8;;19136:145;19110:172;;19298:17;19293:66;;19324:35;;;;;;;;;;;;;;19293:66;-1:-1:-1;;;;;19373:16:8;;19369:52;;19398:23;;;;;;;;;;;;;;19369:52;19545:24;;;;:15;:24;;;;;;;;19538:31;;;;;;-1:-1:-1;;;;;19930:24:8;;;;;:18;:24;;;;;19928:26;;;;;;19998:22;;;;;;;19996:24;;-1:-1:-1;19996:24:8;;;20284:26;;;:17;:26;;;;;2045:8;20370:15;1656:3;20370:41;20329:83;;:126;;20284:171;;;20572:46;;20568:616;;20675:1;20665:11;;20643:19;20796:30;;;:17;:30;;;;;;20792:378;;20932:13;;20917:11;:28;20913:239;;21077:30;;;;:17;:30;;;;;:52;;;20913:239;20625:559;20568:616;21228:7;21224:2;-1:-1:-1;;;;;21209:27:8;21218:4;-1:-1:-1;;;;;21209:27:8;;;;;;;;;;;18935:2360;;18835:2460;;;:::o;701:205:4:-;840:58;;;-1:-1:-1;;;;;9690:55:10;;840:58:4;;;9672:74:10;9762:18;;;;9755:34;;;840:58:4;;;;;;;;;;9645:18:10;;;;840:58:4;;;;;;;;;;863:23;840:58;;;813:86;;833:5;;813:19;:86::i;1154:184:7:-;1275:4;1327;1298:25;1311:5;1318:4;1298:12;:25::i;:::-;:33;;1154:184;-1:-1:-1;;;;1154:184:7:o;14082:102:8:-;14150:27;14160:2;14164:8;14150:27;;;;;;;;;;;;:9;:27::i;:::-;14082:102;;:::o;2270:187:1:-;2362:6;;;-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;16975:1618:8:-;17039:20;17062:13;-1:-1:-1;;;;;17089:16:8;;17085:48;;17114:19;;;;;;;;;;;;;;17085:48;17147:13;17143:44;;17169:18;;;;;;;;;;;;;;17143:44;-1:-1:-1;;;;;17723:22:8;;;;;;:18;:22;;;;1151:2;17723:22;;;:70;;17761:31;17749:44;;17723:70;;;18029:31;;;:17;:31;;;;;18120:15;1656:3;18120:41;18079:83;;-1:-1:-1;18197:13:8;;1913:3;18182:56;18079:160;18029:210;;:31;18317:23;;;18355:109;18381:40;;18406:14;;;;;-1:-1:-1;;;;;18381:40:8;;;18398:1;;18381:40;;18398:1;;18381:40;18459:3;18444:12;:18;18355:109;;-1:-1:-1;18478:13:8;:28;12629:164;;;:::o;24900:697::-;25078:88;;;;;25058:4;;-1:-1:-1;;;;;25078:45:8;;;;;:88;;719:10:6;;25145:4:8;;25151:7;;25160:5;;25078:88;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;25078:88:8;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;25074:517;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;25356:13:8;;25352:229;;25401:40;;;;;;;;;;;;;;25352:229;25541:6;25535:13;25526:6;25522:2;25518:15;25511:38;25074:517;25234:64;;25244:54;25234:64;;-1:-1:-1;24900:697:8;;;;;;:::o;1423:100:0:-;1483:13;1511:7;1504:14;;;;;:::i;27564:1920:8:-;28029:4;28023:11;;28036:3;28019:21;;28112:17;;;;28796:11;;;28677:5;28926:2;28940;28930:13;;28922:22;28796:11;28909:36;28980:2;28970:13;;28570:668;28998:4;28570:668;;;29169:1;29164:3;29160:11;29153:18;;29219:2;29213:4;29209:13;29205:2;29201:22;29196:3;29188:36;29092:2;29082:13;;28570:668;;;-1:-1:-1;29278:13:8;;;29391:12;;;;29449:19;;;29391:12;27564:1920;-1:-1:-1;27564:1920:8:o;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;;16792:2:10;3811:85:4;;;16774:21:10;16831:2;16811:18;;;16804:30;16870:34;16850:18;;;16843:62;16941:12;16921:18;;;16914:40;16971:19;;3811:85:4;16590:406:10;1689:662:7;1772:7;1814:4;1772:7;1828:488;1852:5;:12;1848:1;:16;1828:488;;;1885:20;1908:5;1914:1;1908:8;;;;;;;;:::i;:::-;;;;;;;1885:31;;1950:12;1934;:28;1930:376;;2425:13;2473:15;;;2508:4;2501:15;;;2554:4;2538:21;;2060:57;;1930:376;;;2425:13;2473:15;;;2508:4;2501:15;;;2554:4;2538:21;;2234:57;;1930:376;-1:-1:-1;1866:3:7;;;;:::i;:::-;;;;1828:488;;;-1:-1:-1;2332:12:7;1689:662;-1:-1:-1;;;1689:662:7:o;14544:2184:8:-;14662:20;14685:13;-1:-1:-1;;;;;14712:16:8;;14708:48;;14737:19;;;;;;;;;;;;;;14708:48;14770:13;14766:44;;14792:18;;;;;;;;;;;;;;14766:44;-1:-1:-1;;;;;15346:22:8;;;;;;:18;:22;;;;1151:2;15346:22;;;:70;;15384:31;15372:44;;15346:70;;;15652:31;;;:17;:31;;;;;15743:15;1656:3;15743:41;15702:83;;-1:-1:-1;15820:13:8;;1913:3;15805:56;15702:160;15652:210;;:31;;15940:23;;;;15982:14;:19;15978:622;;16021:308;16051:38;;16076:12;;-1:-1:-1;;;;;16051:38:8;;;16068:1;;16051:38;;16068:1;;16051:38;16116:69;16155:1;16159:2;16163:14;;;;;;16179:5;16116:30;:69::i;:::-;16111:172;;16220:40;;;;;;;;;;;;;;16111:172;16324:3;16309:12;:18;16021:308;;16408:12;16391:13;;:29;16387:43;;16422:8;;;16387:43;15978:622;;;16469:117;16499:40;;16524:14;;;;;-1:-1:-1;;;;;16499:40:8;;;16516:1;;16499:40;;16516:1;;16499:40;16581:3;16566:12;:18;16469:117;;15978:622;-1:-1:-1;16613:13:8;:28;;;16661:60;;16694:2;16698:12;16712:8;16661:60;:::i;3861:223:5:-;3994:12;4025:52;4047:6;4055:4;4061:1;4064:12;3994;-1:-1:-1;;;;;1465:19:5;;;5228:60;;;;-1:-1:-1;;;5228:60:5;;16434:2:10;5228:60:5;;;16416:21:10;16473:2;16453:18;;;16446:30;16512:31;16492:18;;;16485:59;16561:18;;5228:60:5;16232:353:10;5228:60:5;5300:12;5314:23;5341:6;-1:-1:-1;;;;;5341:11:5;5360:5;5367:4;5341:31;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5299:73;;;;5389:51;5406:7;5415:10;5427:12;5389:16;:51::i;:::-;5382:58;4948:499;-1:-1:-1;;;;;;;4948:499:5:o;7561:692::-;7707:12;7735:7;7731:516;;;-1:-1:-1;7765:10:5;7758:17;;7731:516;7876:17;;:21;7872:365;;8070:10;8064:17;8130:15;8117:10;8113:2;8109:19;8102:44;7872:365;8209:12;8202:20;;-1:-1:-1;;;8202:20:5;;;;;;;;:::i;-1:-1:-1:-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;14:367:10;77:8;87:6;141:3;134:4;126:6;122:17;118:27;108:55;;159:1;156;149:12;108:55;-1:-1:-1;182:20:10;;225:18;214:30;;211:50;;;257:1;254;247:12;211:50;294:4;286:6;282:17;270:29;;354:3;347:4;337:6;334:1;330:14;322:6;318:27;314:38;311:47;308:67;;;371:1;368;361:12;308:67;14:367;;;;;:::o;386:247::-;445:6;498:2;486:9;477:7;473:23;469:32;466:52;;;514:1;511;504:12;466:52;553:9;540:23;572:31;597:5;572:31;:::i;898:388::-;966:6;974;1027:2;1015:9;1006:7;1002:23;998:32;995:52;;;1043:1;1040;1033:12;995:52;1082:9;1069:23;1101:31;1126:5;1101:31;:::i;:::-;1151:5;-1:-1:-1;1208:2:10;1193:18;;1180:32;1221:33;1180:32;1221:33;:::i;:::-;1273:7;1263:17;;;898:388;;;;;:::o;1291:456::-;1368:6;1376;1384;1437:2;1425:9;1416:7;1412:23;1408:32;1405:52;;;1453:1;1450;1443:12;1405:52;1492:9;1479:23;1511:31;1536:5;1511:31;:::i;:::-;1561:5;-1:-1:-1;1618:2:10;1603:18;;1590:32;1631:33;1590:32;1631:33;:::i;:::-;1291:456;;1683:7;;-1:-1:-1;;;1737:2:10;1722:18;;;;1709:32;;1291:456::o;1752:1325::-;1847:6;1855;1863;1871;1924:3;1912:9;1903:7;1899:23;1895:33;1892:53;;;1941:1;1938;1931:12;1892:53;1980:9;1967:23;1999:31;2024:5;1999:31;:::i;:::-;2049:5;-1:-1:-1;2106:2:10;2091:18;;2078:32;2119:33;2078:32;2119:33;:::i;:::-;2171:7;-1:-1:-1;2225:2:10;2210:18;;2197:32;;-1:-1:-1;2280:2:10;2265:18;;2252:32;2303:18;2333:14;;;2330:34;;;2360:1;2357;2350:12;2330:34;2398:6;2387:9;2383:22;2373:32;;2443:7;2436:4;2432:2;2428:13;2424:27;2414:55;;2465:1;2462;2455:12;2414:55;2501:2;2488:16;2523:2;2519;2516:10;2513:36;;;2529:18;;:::i;:::-;2663:2;2657:9;2725:4;2717:13;;2568:66;2713:22;;;2737:2;2709:31;2705:40;2693:53;;;2761:18;;;2781:22;;;2758:46;2755:72;;;2807:18;;:::i;:::-;2847:10;2843:2;2836:22;2882:2;2874:6;2867:18;2922:7;2917:2;2912;2908;2904:11;2900:20;2897:33;2894:53;;;2943:1;2940;2933:12;2894:53;2999:2;2994;2990;2986:11;2981:2;2973:6;2969:15;2956:46;3044:1;3039:2;3034;3026:6;3022:15;3018:24;3011:35;3065:6;3055:16;;;;;;;1752:1325;;;;;;;:::o;3082:572::-;3177:6;3185;3193;3246:2;3234:9;3225:7;3221:23;3217:32;3214:52;;;3262:1;3259;3252:12;3214:52;3301:9;3288:23;3320:31;3345:5;3320:31;:::i;:::-;3370:5;-1:-1:-1;3426:2:10;3411:18;;3398:32;3453:18;3442:30;;3439:50;;;3485:1;3482;3475:12;3439:50;3524:70;3586:7;3577:6;3566:9;3562:22;3524:70;:::i;:::-;3082:572;;3613:8;;-1:-1:-1;3498:96:10;;-1:-1:-1;;;;3082:572:10:o;3659:382::-;3724:6;3732;3785:2;3773:9;3764:7;3760:23;3756:32;3753:52;;;3801:1;3798;3791:12;3753:52;3840:9;3827:23;3859:31;3884:5;3859:31;:::i;:::-;3909:5;-1:-1:-1;3966:2:10;3951:18;;3938:32;3979:30;3938:32;3979:30;:::i;4046:315::-;4114:6;4122;4175:2;4163:9;4154:7;4150:23;4146:32;4143:52;;;4191:1;4188;4181:12;4143:52;4230:9;4217:23;4249:31;4274:5;4249:31;:::i;:::-;4299:5;4351:2;4336:18;;;;4323:32;;-1:-1:-1;;;4046:315:10:o;4366:241::-;4422:6;4475:2;4463:9;4454:7;4450:23;4446:32;4443:52;;;4491:1;4488;4481:12;4443:52;4530:9;4517:23;4549:28;4571:5;4549:28;:::i;4612:245::-;4679:6;4732:2;4720:9;4711:7;4707:23;4703:32;4700:52;;;4748:1;4745;4738:12;4700:52;4780:9;4774:16;4799:28;4821:5;4799:28;:::i;4862:180::-;4921:6;4974:2;4962:9;4953:7;4949:23;4945:32;4942:52;;;4990:1;4987;4980:12;4942:52;-1:-1:-1;5013:23:10;;4862:180;-1:-1:-1;4862:180:10:o;5047:245::-;5105:6;5158:2;5146:9;5137:7;5133:23;5129:32;5126:52;;;5174:1;5171;5164:12;5126:52;5213:9;5200:23;5232:30;5256:5;5232:30;:::i;5297:249::-;5366:6;5419:2;5407:9;5398:7;5394:23;5390:32;5387:52;;;5435:1;5432;5425:12;5387:52;5467:9;5461:16;5486:30;5510:5;5486:30;:::i;6224:592::-;6295:6;6303;6356:2;6344:9;6335:7;6331:23;6327:32;6324:52;;;6372:1;6369;6362:12;6324:52;6412:9;6399:23;6441:18;6482:2;6474:6;6471:14;6468:34;;;6498:1;6495;6488:12;6468:34;6536:6;6525:9;6521:22;6511:32;;6581:7;6574:4;6570:2;6566:13;6562:27;6552:55;;6603:1;6600;6593:12;6552:55;6643:2;6630:16;6669:2;6661:6;6658:14;6655:34;;;6685:1;6682;6675:12;6655:34;6730:7;6725:2;6716:6;6712:2;6708:15;6704:24;6701:37;6698:57;;;6751:1;6748;6741:12;6698:57;6782:2;6774:11;;;;;6804:6;;-1:-1:-1;6224:592:10;;-1:-1:-1;;;;6224:592:10:o;7006:184::-;7076:6;7129:2;7117:9;7108:7;7104:23;7100:32;7097:52;;;7145:1;7142;7135:12;7097:52;-1:-1:-1;7168:16:10;;7006:184;-1:-1:-1;7006:184:10:o;7195:505::-;7290:6;7298;7306;7359:2;7347:9;7338:7;7334:23;7330:32;7327:52;;;7375:1;7372;7365:12;7327:52;7411:9;7398:23;7388:33;;7472:2;7461:9;7457:18;7444:32;7499:18;7491:6;7488:30;7485:50;;;7531:1;7528;7521:12;7705:316;7746:3;7784:5;7778:12;7811:6;7806:3;7799:19;7827:63;7883:6;7876:4;7871:3;7867:14;7860:4;7853:5;7849:16;7827:63;:::i;:::-;7935:2;7923:15;7940:66;7919:88;7910:98;;;;8010:4;7906:109;;7705:316;-1:-1:-1;;7705:316:10:o;8295:274::-;8424:3;8462:6;8456:13;8478:53;8524:6;8519:3;8512:4;8504:6;8500:17;8478:53;:::i;:::-;8547:16;;;;;8295:274;-1:-1:-1;;8295:274:10:o;8574:470::-;8753:3;8791:6;8785:13;8807:53;8853:6;8848:3;8841:4;8833:6;8829:17;8807:53;:::i;:::-;8923:13;;8882:16;;;;8945:57;8923:13;8882:16;8979:4;8967:17;;8945:57;:::i;:::-;9018:20;;8574:470;-1:-1:-1;;;;8574:470:10:o;9800:511::-;9994:4;-1:-1:-1;;;;;10104:2:10;10096:6;10092:15;10081:9;10074:34;10156:2;10148:6;10144:15;10139:2;10128:9;10124:18;10117:43;;10196:6;10191:2;10180:9;10176:18;10169:34;10239:3;10234:2;10223:9;10219:18;10212:31;10260:45;10300:3;10289:9;10285:19;10277:6;10260:45;:::i;:::-;10252:53;9800:511;-1:-1:-1;;;;;;9800:511:10:o;10992:219::-;11141:2;11130:9;11123:21;11104:4;11161:44;11201:2;11190:9;11186:18;11178:6;11161:44;:::i;17538:128::-;17578:3;17609:1;17605:6;17602:1;17599:13;17596:39;;;17615:18;;:::i;:::-;-1:-1:-1;17651:9:10;;17538:128::o;17671:274::-;17711:1;17737;17727:189;;17772:77;17769:1;17762:88;17873:4;17870:1;17863:15;17901:4;17898:1;17891:15;17727:189;-1:-1:-1;17930:9:10;;17671:274::o;17950:228::-;17990:7;18116:1;18048:66;18044:74;18041:1;18038:81;18033:1;18026:9;18019:17;18015:105;18012:131;;;18123:18;;:::i;:::-;-1:-1:-1;18163:9:10;;17950:228::o;18183:125::-;18223:4;18251:1;18248;18245:8;18242:34;;;18256:18;;:::i;:::-;-1:-1:-1;18293:9:10;;18183:125::o;18313:258::-;18385:1;18395:113;18409:6;18406:1;18403:13;18395:113;;;18485:11;;;18479:18;18466:11;;;18459:39;18431:2;18424:10;18395:113;;;18526:6;18523:1;18520:13;18517:48;;;-1:-1:-1;;18561:1:10;18543:16;;18536:27;18313:258::o;18576:437::-;18655:1;18651:12;;;;18698;;;18719:61;;18773:4;18765:6;18761:17;18751:27;;18719:61;18826:2;18818:6;18815:14;18795:18;18792:38;18789:218;;;18863:77;18860:1;18853:88;18964:4;18961:1;18954:15;18992:4;18989:1;18982:15;18789:218;;18576:437;;;:::o;19018:195::-;19057:3;19088:66;19081:5;19078:77;19075:103;;;19158:18;;:::i;:::-;-1:-1:-1;19205:1:10;19194:13;;19018:195::o;19218:184::-;19270:77;19267:1;19260:88;19367:4;19364:1;19357:15;19391:4;19388:1;19381:15;19407:184;19459:77;19456:1;19449:88;19556:4;19553:1;19546:15;19580:4;19577:1;19570:15;19596:184;19648:77;19645:1;19638:88;19745:4;19742:1;19735:15;19769:4;19766:1;19759:15;19785:154;-1:-1:-1;;;;;19864:5:10;19860:54;19853:5;19850:65;19840:93;;19929:1;19926;19919:12;19944:118;20030:5;20023:13;20016:21;20009:5;20006:32;19996:60;;20052:1;20049;20042:12;20067:177;20152:66;20145:5;20141:78;20134:5;20131:89;20121:117;;20234:1;20231;20224:12
Swarm Source
ipfs://c81c38ba5a636010f6fd88b4a9ec98932674dccb01dfa17898ddc80b6405a425
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
[ Download: CSV Export ]
A token is a representation of an on-chain or off-chain asset. The token page shows information such as price, total supply, holders, transfers and social links. Learn more about this page in our Knowledge Base.