ERC-20
Overview
Max Total Supply
10,000,000 KPAI
Holders
309
Market
Onchain Market Cap
$0.00
Circulating Supply Market Cap
-
Other Info
Token Contract (WITH 18 Decimals)
Balance
2,254.424967266051183102 KPAIValue
$0.00Loading...
Loading
Loading...
Loading
Loading...
Loading
# | Exchange | Pair | Price | 24H Volume | % Volume |
---|
Contract Source Code Verified (Exact Match)
Contract Name:
Kanpai
Compiler Version
v0.8.23+commit.f704f362
Contract Source Code (Solidity)
/** *Submitted for verification at Etherscan.io on 2024-01-12 */ // SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.23; // OpenZeppelin Contracts (last updated v5.0.0) (access/Ownable.sol) // OpenZeppelin Contracts (last updated v5.0.0) (utils/Context.sol) /** * @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; } } /** * @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. * * The initial owner is set to the address provided by the deployer. 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; /** * @dev The caller account is not authorized to perform an operation. */ error OwnableUnauthorizedAccount(address account); /** * @dev The owner is not a valid owner account. (eg. `address(0)`) */ error OwnableInvalidOwner(address owner); event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the address provided by the deployer as the initial owner. */ constructor(address initialOwner) { if (initialOwner == address(0)) { revert OwnableInvalidOwner(address(0)); } _transferOwnership(initialOwner); } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { _checkOwner(); _; } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if the sender is not the owner. */ function _checkOwner() internal view virtual { if (owner() != _msgSender()) { revert OwnableUnauthorizedAccount(_msgSender()); } } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby disabling 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 { if (newOwner == address(0)) { revert OwnableInvalidOwner(address(0)); } _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); } } // OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/ERC20.sol) // OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/IERC20.sol) /** * @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 value of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the value of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves a `value` amount of 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 value) 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 a `value` amount of tokens 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 value) external returns (bool); /** * @dev Moves a `value` amount of tokens from `from` to `to` using the * allowance mechanism. `value` 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 value) external returns (bool); } // OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/extensions/IERC20Metadata.sol) /** * @dev Interface for the optional metadata functions from the ERC20 standard. */ interface IERC20Metadata is IERC20 { /** * @dev Returns the name of the token. */ function name() external view returns (string memory); /** * @dev Returns the symbol of the token. */ function symbol() external view returns (string memory); /** * @dev Returns the decimals places of the token. */ function decimals() external view returns (uint8); } // OpenZeppelin Contracts (last updated v5.0.0) (interfaces/draft-IERC6093.sol) /** * @dev Standard ERC20 Errors * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC20 tokens. */ interface IERC20Errors { /** * @dev Indicates an error related to the current `balance` of a `sender`. Used in transfers. * @param sender Address whose tokens are being transferred. * @param balance Current balance for the interacting account. * @param needed Minimum amount required to perform a transfer. */ error ERC20InsufficientBalance(address sender, uint256 balance, uint256 needed); /** * @dev Indicates a failure with the token `sender`. Used in transfers. * @param sender Address whose tokens are being transferred. */ error ERC20InvalidSender(address sender); /** * @dev Indicates a failure with the token `receiver`. Used in transfers. * @param receiver Address to which tokens are being transferred. */ error ERC20InvalidReceiver(address receiver); /** * @dev Indicates a failure with the `spender`’s `allowance`. Used in transfers. * @param spender Address that may be allowed to operate on tokens without being their owner. * @param allowance Amount of tokens a `spender` is allowed to operate with. * @param needed Minimum amount required to perform a transfer. */ error ERC20InsufficientAllowance(address spender, uint256 allowance, uint256 needed); /** * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals. * @param approver Address initiating an approval operation. */ error ERC20InvalidApprover(address approver); /** * @dev Indicates a failure with the `spender` to be approved. Used in approvals. * @param spender Address that may be allowed to operate on tokens without being their owner. */ error ERC20InvalidSpender(address spender); } /** * @dev Standard ERC721 Errors * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC721 tokens. */ interface IERC721Errors { /** * @dev Indicates that an address can't be an owner. For example, `address(0)` is a forbidden owner in EIP-20. * Used in balance queries. * @param owner Address of the current owner of a token. */ error ERC721InvalidOwner(address owner); /** * @dev Indicates a `tokenId` whose `owner` is the zero address. * @param tokenId Identifier number of a token. */ error ERC721NonexistentToken(uint256 tokenId); /** * @dev Indicates an error related to the ownership over a particular token. Used in transfers. * @param sender Address whose tokens are being transferred. * @param tokenId Identifier number of a token. * @param owner Address of the current owner of a token. */ error ERC721IncorrectOwner(address sender, uint256 tokenId, address owner); /** * @dev Indicates a failure with the token `sender`. Used in transfers. * @param sender Address whose tokens are being transferred. */ error ERC721InvalidSender(address sender); /** * @dev Indicates a failure with the token `receiver`. Used in transfers. * @param receiver Address to which tokens are being transferred. */ error ERC721InvalidReceiver(address receiver); /** * @dev Indicates a failure with the `operator`’s approval. Used in transfers. * @param operator Address that may be allowed to operate on tokens without being their owner. * @param tokenId Identifier number of a token. */ error ERC721InsufficientApproval(address operator, uint256 tokenId); /** * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals. * @param approver Address initiating an approval operation. */ error ERC721InvalidApprover(address approver); /** * @dev Indicates a failure with the `operator` to be approved. Used in approvals. * @param operator Address that may be allowed to operate on tokens without being their owner. */ error ERC721InvalidOperator(address operator); } /** * @dev Standard ERC1155 Errors * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC1155 tokens. */ interface IERC1155Errors { /** * @dev Indicates an error related to the current `balance` of a `sender`. Used in transfers. * @param sender Address whose tokens are being transferred. * @param balance Current balance for the interacting account. * @param needed Minimum amount required to perform a transfer. * @param tokenId Identifier number of a token. */ error ERC1155InsufficientBalance(address sender, uint256 balance, uint256 needed, uint256 tokenId); /** * @dev Indicates a failure with the token `sender`. Used in transfers. * @param sender Address whose tokens are being transferred. */ error ERC1155InvalidSender(address sender); /** * @dev Indicates a failure with the token `receiver`. Used in transfers. * @param receiver Address to which tokens are being transferred. */ error ERC1155InvalidReceiver(address receiver); /** * @dev Indicates a failure with the `operator`’s approval. Used in transfers. * @param operator Address that may be allowed to operate on tokens without being their owner. * @param owner Address of the current owner of a token. */ error ERC1155MissingApprovalForAll(address operator, address owner); /** * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals. * @param approver Address initiating an approval operation. */ error ERC1155InvalidApprover(address approver); /** * @dev Indicates a failure with the `operator` to be approved. Used in approvals. * @param operator Address that may be allowed to operate on tokens without being their owner. */ error ERC1155InvalidOperator(address operator); /** * @dev Indicates an array length mismatch between ids and values in a safeBatchTransferFrom operation. * Used in batch transfers. * @param idsLength Length of the array of token identifiers * @param valuesLength Length of the array of token amounts */ error ERC1155InvalidArrayLength(uint256 idsLength, uint256 valuesLength); } /** * @dev Implementation of the {IERC20} interface. * * This implementation is agnostic to the way tokens are created. This means * that a supply mechanism has to be added in a derived contract using {_mint}. * * TIP: For a detailed writeup see our guide * https://forum.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226[How * to implement supply mechanisms]. * * The default value of {decimals} is 18. To change this, you should override * this function so it returns a different value. * * We have followed general OpenZeppelin Contracts guidelines: functions revert * instead returning `false` on failure. This behavior is nonetheless * conventional and does not conflict with the expectations of ERC20 * applications. * * Additionally, an {Approval} event is emitted on calls to {transferFrom}. * This allows applications to reconstruct the allowance for all accounts just * by listening to said events. Other implementations of the EIP may not emit * these events, as it isn't required by the specification. */ abstract contract ERC20 is Context, IERC20, IERC20Metadata, IERC20Errors { mapping(address account => uint256) private _balances; mapping(address account => mapping(address spender => uint256)) private _allowances; uint256 private _totalSupply; string private _name; string private _symbol; /** * @dev Sets the values for {name} and {symbol}. * * All two of these values are immutable: they can only be set once during * construction. */ constructor(string memory name_, string memory symbol_) { _name = name_; _symbol = symbol_; } /** * @dev Returns the name of the token. */ function name() public view virtual returns (string memory) { return _name; } /** * @dev Returns the symbol of the token, usually a shorter version of the * name. */ function symbol() public view virtual returns (string memory) { return _symbol; } /** * @dev Returns the number of decimals used to get its user representation. * For example, if `decimals` equals `2`, a balance of `505` tokens should * be displayed to a user as `5.05` (`505 / 10 ** 2`). * * Tokens usually opt for a value of 18, imitating the relationship between * Ether and Wei. This is the default value returned by this function, unless * it's overridden. * * NOTE: This information is only used for _display_ purposes: it in * no way affects any of the arithmetic of the contract, including * {IERC20-balanceOf} and {IERC20-transfer}. */ function decimals() public view virtual returns (uint8) { return 18; } /** * @dev See {IERC20-totalSupply}. */ function totalSupply() public view virtual returns (uint256) { return _totalSupply; } /** * @dev See {IERC20-balanceOf}. */ function balanceOf(address account) public view virtual returns (uint256) { return _balances[account]; } /** * @dev See {IERC20-transfer}. * * Requirements: * * - `to` cannot be the zero address. * - the caller must have a balance of at least `value`. */ function transfer(address to, uint256 value) public virtual returns (bool) { address owner = _msgSender(); _transfer(owner, to, value); return true; } /** * @dev See {IERC20-allowance}. */ function allowance(address owner, address spender) public view virtual returns (uint256) { return _allowances[owner][spender]; } /** * @dev See {IERC20-approve}. * * NOTE: If `value` is the maximum `uint256`, the allowance is not updated on * `transferFrom`. This is semantically equivalent to an infinite approval. * * Requirements: * * - `spender` cannot be the zero address. */ function approve(address spender, uint256 value) public virtual returns (bool) { address owner = _msgSender(); _approve(owner, spender, value); return true; } /** * @dev See {IERC20-transferFrom}. * * Emits an {Approval} event indicating the updated allowance. This is not * required by the EIP. See the note at the beginning of {ERC20}. * * NOTE: Does not update the allowance if the current allowance * is the maximum `uint256`. * * Requirements: * * - `from` and `to` cannot be the zero address. * - `from` must have a balance of at least `value`. * - the caller must have allowance for ``from``'s tokens of at least * `value`. */ function transferFrom(address from, address to, uint256 value) public virtual returns (bool) { address spender = _msgSender(); _spendAllowance(from, spender, value); _transfer(from, to, value); return true; } /** * @dev Moves a `value` amount of tokens from `from` to `to`. * * This internal function is equivalent to {transfer}, and can be used to * e.g. implement automatic token fees, slashing mechanisms, etc. * * Emits a {Transfer} event. * * NOTE: This function is not virtual, {_update} should be overridden instead. */ function _transfer(address from, address to, uint256 value) internal { if (from == address(0)) { revert ERC20InvalidSender(address(0)); } if (to == address(0)) { revert ERC20InvalidReceiver(address(0)); } _update(from, to, value); } /** * @dev Transfers a `value` amount of tokens from `from` to `to`, or alternatively mints (or burns) if `from` * (or `to`) is the zero address. All customizations to transfers, mints, and burns should be done by overriding * this function. * * Emits a {Transfer} event. */ function _update(address from, address to, uint256 value) internal virtual { if (from == address(0)) { // Overflow check required: The rest of the code assumes that totalSupply never overflows _totalSupply += value; } else { uint256 fromBalance = _balances[from]; if (fromBalance < value) { revert ERC20InsufficientBalance(from, fromBalance, value); } unchecked { // Overflow not possible: value <= fromBalance <= totalSupply. _balances[from] = fromBalance - value; } } if (to == address(0)) { unchecked { // Overflow not possible: value <= totalSupply or value <= fromBalance <= totalSupply. _totalSupply -= value; } } else { unchecked { // Overflow not possible: balance + value is at most totalSupply, which we know fits into a uint256. _balances[to] += value; } } emit Transfer(from, to, value); } /** * @dev Creates a `value` amount of tokens and assigns them to `account`, by transferring it from address(0). * Relies on the `_update` mechanism * * Emits a {Transfer} event with `from` set to the zero address. * * NOTE: This function is not virtual, {_update} should be overridden instead. */ function _mint(address account, uint256 value) internal { if (account == address(0)) { revert ERC20InvalidReceiver(address(0)); } _update(address(0), account, value); } /** * @dev Destroys a `value` amount of tokens from `account`, lowering the total supply. * Relies on the `_update` mechanism. * * Emits a {Transfer} event with `to` set to the zero address. * * NOTE: This function is not virtual, {_update} should be overridden instead */ function _burn(address account, uint256 value) internal { if (account == address(0)) { revert ERC20InvalidSender(address(0)); } _update(account, address(0), value); } /** * @dev Sets `value` as the allowance of `spender` over the `owner` s tokens. * * This internal function is equivalent to `approve`, and can be used to * e.g. set automatic allowances for certain subsystems, etc. * * Emits an {Approval} event. * * Requirements: * * - `owner` cannot be the zero address. * - `spender` cannot be the zero address. * * Overrides to this logic should be done to the variant with an additional `bool emitEvent` argument. */ function _approve(address owner, address spender, uint256 value) internal { _approve(owner, spender, value, true); } /** * @dev Variant of {_approve} with an optional flag to enable or disable the {Approval} event. * * By default (when calling {_approve}) the flag is set to true. On the other hand, approval changes made by * `_spendAllowance` during the `transferFrom` operation set the flag to false. This saves gas by not emitting any * `Approval` event during `transferFrom` operations. * * Anyone who wishes to continue emitting `Approval` events on the`transferFrom` operation can force the flag to * true using the following override: * ``` * function _approve(address owner, address spender, uint256 value, bool) internal virtual override { * super._approve(owner, spender, value, true); * } * ``` * * Requirements are the same as {_approve}. */ function _approve(address owner, address spender, uint256 value, bool emitEvent) internal virtual { if (owner == address(0)) { revert ERC20InvalidApprover(address(0)); } if (spender == address(0)) { revert ERC20InvalidSpender(address(0)); } _allowances[owner][spender] = value; if (emitEvent) { emit Approval(owner, spender, value); } } /** * @dev Updates `owner` s allowance for `spender` based on spent `value`. * * Does not update the allowance value in case of infinite allowance. * Revert if not enough allowance is available. * * Does not emit an {Approval} event. */ function _spendAllowance(address owner, address spender, uint256 value) internal virtual { uint256 currentAllowance = allowance(owner, spender); if (currentAllowance != type(uint256).max) { if (currentAllowance < value) { revert ERC20InsufficientAllowance(spender, currentAllowance, value); } unchecked { _approve(owner, spender, currentAllowance - value, false); } } } } // OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC20.sol) // OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC20Metadata.sol) // OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/utils/SafeERC20.sol) // OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/extensions/IERC20Permit.sol) /** * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612]. * * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't * need to send a transaction, and thus is not required to hold Ether at all. * * ==== Security Considerations * * There are two important considerations concerning the use of `permit`. The first is that a valid permit signature * expresses an allowance, and it should not be assumed to convey additional meaning. In particular, it should not be * considered as an intention to spend the allowance in any specific way. The second is that because permits have * built-in replay protection and can be submitted by anyone, they can be frontrun. A protocol that uses permits should * take this into consideration and allow a `permit` call to fail. Combining these two aspects, a pattern that may be * generally recommended is: * * ```solidity * function doThingWithPermit(..., uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s) public { * try token.permit(msg.sender, address(this), value, deadline, v, r, s) {} catch {} * doThing(..., value); * } * * function doThing(..., uint256 value) public { * token.safeTransferFrom(msg.sender, address(this), value); * ... * } * ``` * * Observe that: 1) `msg.sender` is used as the owner, leaving no ambiguity as to the signer intent, and 2) the use of * `try/catch` allows the permit to fail and makes the code tolerant to frontrunning. (See also * {SafeERC20-safeTransferFrom}). * * Additionally, note that smart contract wallets (such as Argent or Safe) are not able to produce permit signatures, so * contracts should have entry points that don't rely on permit. */ interface IERC20Permit { /** * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens, * given ``owner``'s signed approval. * * IMPORTANT: The same issues {IERC20-approve} has related to transaction * ordering also apply here. * * Emits an {Approval} event. * * Requirements: * * - `spender` cannot be the zero address. * - `deadline` must be a timestamp in the future. * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner` * over the EIP712-formatted function arguments. * - the signature must use ``owner``'s current nonce (see {nonces}). * * For more information on the signature format, see the * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP * section]. * * CAUTION: See Security Considerations above. */ function permit( address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) external; /** * @dev Returns the current nonce for `owner`. This value must be * included whenever a signature is generated for {permit}. * * Every successful call to {permit} increases ``owner``'s nonce by one. This * prevents a signature from being used multiple times. */ function nonces(address owner) external view returns (uint256); /** * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}. */ // solhint-disable-next-line func-name-mixedcase function DOMAIN_SEPARATOR() external view returns (bytes32); } // OpenZeppelin Contracts (last updated v5.0.0) (utils/Address.sol) /** * @dev Collection of functions related to the address type */ library Address { /** * @dev The ETH balance of the account is not enough to perform the operation. */ error AddressInsufficientBalance(address account); /** * @dev There's no code at `target` (it is not a contract). */ error AddressEmptyCode(address target); /** * @dev A call to an address target failed. The target may have reverted. */ error FailedInnerCall(); /** * @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://consensys.net/diligence/blog/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.8.20/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { if (address(this).balance < amount) { revert AddressInsufficientBalance(address(this)); } (bool success, ) = recipient.call{value: amount}(""); if (!success) { revert FailedInnerCall(); } } /** * @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 or custom error, it is bubbled * up by this function (like regular Solidity function calls). However, if * the call reverted with no returned reason, this function reverts with a * {FailedInnerCall} error. * * 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. */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCallWithValue(target, data, 0); } /** * @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`. */ function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) { if (address(this).balance < value) { revert AddressInsufficientBalance(address(this)); } (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResultFromTarget(target, success, returndata); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResultFromTarget(target, success, returndata); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResultFromTarget(target, success, returndata); } /** * @dev Tool to verify that a low level call to smart-contract was successful, and reverts if the target * was not a contract or bubbling up the revert reason (falling back to {FailedInnerCall}) in case of an * unsuccessful call. */ function verifyCallResultFromTarget( address target, bool success, bytes memory returndata ) internal view returns (bytes memory) { if (!success) { _revert(returndata); } else { // only check if target is a contract if the call was successful and the return data is empty // otherwise we already know that it was a contract if (returndata.length == 0 && target.code.length == 0) { revert AddressEmptyCode(target); } return returndata; } } /** * @dev Tool to verify that a low level call was successful, and reverts if it wasn't, either by bubbling the * revert reason or with a default {FailedInnerCall} error. */ function verifyCallResult(bool success, bytes memory returndata) internal pure returns (bytes memory) { if (!success) { _revert(returndata); } else { return returndata; } } /** * @dev Reverts with returndata if present. Otherwise reverts with {FailedInnerCall}. */ function _revert(bytes memory returndata) private pure { // 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 /// @solidity memory-safe-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert FailedInnerCall(); } } } /** * @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; /** * @dev An operation with an ERC20 token failed. */ error SafeERC20FailedOperation(address token); /** * @dev Indicates a failed `decreaseAllowance` request. */ error SafeERC20FailedDecreaseAllowance(address spender, uint256 currentAllowance, uint256 requestedDecrease); /** * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value, * non-reverting calls are assumed to be successful. */ function safeTransfer(IERC20 token, address to, uint256 value) internal { _callOptionalReturn(token, abi.encodeCall(token.transfer, (to, value))); } /** * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful. */ function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal { _callOptionalReturn(token, abi.encodeCall(token.transferFrom, (from, to, value))); } /** * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value, * non-reverting calls are assumed to be successful. */ function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal { uint256 oldAllowance = token.allowance(address(this), spender); forceApprove(token, spender, oldAllowance + value); } /** * @dev Decrease the calling contract's allowance toward `spender` by `requestedDecrease`. If `token` returns no * value, non-reverting calls are assumed to be successful. */ function safeDecreaseAllowance(IERC20 token, address spender, uint256 requestedDecrease) internal { unchecked { uint256 currentAllowance = token.allowance(address(this), spender); if (currentAllowance < requestedDecrease) { revert SafeERC20FailedDecreaseAllowance(spender, currentAllowance, requestedDecrease); } forceApprove(token, spender, currentAllowance - requestedDecrease); } } /** * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value, * non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval * to be set to zero before setting it to a non-zero value, such as USDT. */ function forceApprove(IERC20 token, address spender, uint256 value) internal { bytes memory approvalCall = abi.encodeCall(token.approve, (spender, value)); if (!_callOptionalReturnBool(token, approvalCall)) { _callOptionalReturn(token, abi.encodeCall(token.approve, (spender, 0))); _callOptionalReturn(token, approvalCall); } } /** * @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); if (returndata.length != 0 && !abi.decode(returndata, (bool))) { revert SafeERC20FailedOperation(address(token)); } } /** * @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). * * This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead. */ function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) { // 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 cannot use {Address-functionCall} here since this should return false // and not revert is the subcall reverts. (bool success, bytes memory returndata) = address(token).call(data); return success && (returndata.length == 0 || abi.decode(returndata, (bool))) && address(token).code.length > 0; } } // OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/extensions/ERC20Burnable.sol) /** * @dev Extension of {ERC20} that allows token holders to destroy both their own * tokens and those that they have an allowance for, in a way that can be * recognized off-chain (via event analysis). */ abstract contract ERC20Burnable is Context, ERC20 { /** * @dev Destroys a `value` amount of tokens from the caller. * * See {ERC20-_burn}. */ function burn(uint256 value) public virtual { _burn(_msgSender(), value); } /** * @dev Destroys a `value` amount of tokens from `account`, deducting from * the caller's allowance. * * See {ERC20-_burn} and {ERC20-allowance}. * * Requirements: * * - the caller must have allowance for ``accounts``'s tokens of at least * `value`. */ function burnFrom(address account, uint256 value) public virtual { _spendAllowance(account, _msgSender(), value); _burn(account, value); } } // OpenZeppelin Contracts (last updated v5.0.0) (utils/ReentrancyGuard.sol) /** * @dev Contract module that helps prevent reentrant calls to a function. * * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier * available, which can be applied to functions to make sure there are no nested * (reentrant) calls to them. * * Note that because there is a single `nonReentrant` guard, functions marked as * `nonReentrant` may not call one another. This can be worked around by making * those functions `private`, and then adding `external` `nonReentrant` entry * points to them. * * TIP: If you would like to learn more about reentrancy and alternative ways * to protect against it, check out our blog post * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul]. */ abstract contract ReentrancyGuard { // Booleans are more expensive than uint256 or any type that takes up a full // word because each write operation emits an extra SLOAD to first read the // slot's contents, replace the bits taken up by the boolean, and then write // back. This is the compiler's defense against contract upgrades and // pointer aliasing, and it cannot be disabled. // The values being non-zero value makes deployment a bit more expensive, // but in exchange the refund on every call to nonReentrant will be lower in // amount. Since refunds are capped to a percentage of the total // transaction's gas, it is best to keep them low in cases like this one, to // increase the likelihood of the full refund coming into effect. uint256 private constant NOT_ENTERED = 1; uint256 private constant ENTERED = 2; uint256 private _status; /** * @dev Unauthorized reentrant call. */ error ReentrancyGuardReentrantCall(); constructor() { _status = NOT_ENTERED; } /** * @dev Prevents a contract from calling itself, directly or indirectly. * Calling a `nonReentrant` function from another `nonReentrant` * function is not supported. It is possible to prevent this from happening * by making the `nonReentrant` function external, and making it call a * `private` function that does the actual work. */ modifier nonReentrant() { _nonReentrantBefore(); _; _nonReentrantAfter(); } function _nonReentrantBefore() private { // On the first call to nonReentrant, _status will be NOT_ENTERED if (_status == ENTERED) { revert ReentrancyGuardReentrantCall(); } // Any calls to nonReentrant after this point will fail _status = ENTERED; } function _nonReentrantAfter() private { // By storing the original value once again, a refund is triggered (see // https://eips.ethereum.org/EIPS/eip-2200) _status = NOT_ENTERED; } /** * @dev Returns true if the reentrancy guard is currently set to "entered", which indicates there is a * `nonReentrant` function in the call stack. */ function _reentrancyGuardEntered() internal view returns (bool) { return _status == ENTERED; } } // OpenZeppelin Contracts (last updated v5.0.0) (utils/structs/EnumerableSet.sol) // This file was procedurally generated from scripts/generate/templates/EnumerableSet.js. /** * @dev Library for managing * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive * types. * * Sets have the following properties: * * - Elements are added, removed, and checked for existence in constant time * (O(1)). * - Elements are enumerated in O(n). No guarantees are made on the ordering. * * ```solidity * contract Example { * // Add the library methods * using EnumerableSet for EnumerableSet.AddressSet; * * // Declare a set state variable * EnumerableSet.AddressSet private mySet; * } * ``` * * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`) * and `uint256` (`UintSet`) are supported. * * [WARNING] * ==== * Trying to delete such a structure from storage will likely result in data corruption, rendering the structure * unusable. * See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info. * * In order to clean an EnumerableSet, you can either remove all elements one by one or create a fresh instance using an * array of EnumerableSet. * ==== */ library EnumerableSet { // To implement this library for multiple types with as little code // repetition as possible, we write it in terms of a generic Set type with // bytes32 values. // The Set implementation uses private functions, and user-facing // implementations (such as AddressSet) are just wrappers around the // underlying Set. // This means that we can only create new EnumerableSets for types that fit // in bytes32. struct Set { // Storage of set values bytes32[] _values; // Position is the index of the value in the `values` array plus 1. // Position 0 is used to mean a value is not in the set. mapping(bytes32 value => uint256) _positions; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function _add(Set storage set, bytes32 value) private returns (bool) { if (!_contains(set, value)) { set._values.push(value); // The value is stored at length-1, but we add 1 to all indexes // and use 0 as a sentinel value set._positions[value] = set._values.length; return true; } else { return false; } } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function _remove(Set storage set, bytes32 value) private returns (bool) { // We cache the value's position to prevent multiple reads from the same storage slot uint256 position = set._positions[value]; if (position != 0) { // Equivalent to contains(set, value) // To delete an element from the _values array in O(1), we swap the element to delete with the last one in // the array, and then remove the last element (sometimes called as 'swap and pop'). // This modifies the order of the array, as noted in {at}. uint256 valueIndex = position - 1; uint256 lastIndex = set._values.length - 1; if (valueIndex != lastIndex) { bytes32 lastValue = set._values[lastIndex]; // Move the lastValue to the index where the value to delete is set._values[valueIndex] = lastValue; // Update the tracked position of the lastValue (that was just moved) set._positions[lastValue] = position; } // Delete the slot where the moved value was stored set._values.pop(); // Delete the tracked position for the deleted slot delete set._positions[value]; return true; } else { return false; } } /** * @dev Returns true if the value is in the set. O(1). */ function _contains(Set storage set, bytes32 value) private view returns (bool) { return set._positions[value] != 0; } /** * @dev Returns the number of values on the set. O(1). */ function _length(Set storage set) private view returns (uint256) { return set._values.length; } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function _at(Set storage set, uint256 index) private view returns (bytes32) { return set._values[index]; } /** * @dev Return the entire set in an array * * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that * this function has an unbounded cost, and using it as part of a state-changing function may render the function * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. */ function _values(Set storage set) private view returns (bytes32[] memory) { return set._values; } // Bytes32Set struct Bytes32Set { Set _inner; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function add(Bytes32Set storage set, bytes32 value) internal returns (bool) { return _add(set._inner, value); } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) { return _remove(set._inner, value); } /** * @dev Returns true if the value is in the set. O(1). */ function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) { return _contains(set._inner, value); } /** * @dev Returns the number of values in the set. O(1). */ function length(Bytes32Set storage set) internal view returns (uint256) { return _length(set._inner); } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) { return _at(set._inner, index); } /** * @dev Return the entire set in an array * * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that * this function has an unbounded cost, and using it as part of a state-changing function may render the function * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. */ function values(Bytes32Set storage set) internal view returns (bytes32[] memory) { bytes32[] memory store = _values(set._inner); bytes32[] memory result; /// @solidity memory-safe-assembly assembly { result := store } return result; } // AddressSet struct AddressSet { Set _inner; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function add(AddressSet storage set, address value) internal returns (bool) { return _add(set._inner, bytes32(uint256(uint160(value)))); } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function remove(AddressSet storage set, address value) internal returns (bool) { return _remove(set._inner, bytes32(uint256(uint160(value)))); } /** * @dev Returns true if the value is in the set. O(1). */ function contains(AddressSet storage set, address value) internal view returns (bool) { return _contains(set._inner, bytes32(uint256(uint160(value)))); } /** * @dev Returns the number of values in the set. O(1). */ function length(AddressSet storage set) internal view returns (uint256) { return _length(set._inner); } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(AddressSet storage set, uint256 index) internal view returns (address) { return address(uint160(uint256(_at(set._inner, index)))); } /** * @dev Return the entire set in an array * * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that * this function has an unbounded cost, and using it as part of a state-changing function may render the function * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. */ function values(AddressSet storage set) internal view returns (address[] memory) { bytes32[] memory store = _values(set._inner); address[] memory result; /// @solidity memory-safe-assembly assembly { result := store } return result; } // UintSet struct UintSet { Set _inner; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function add(UintSet storage set, uint256 value) internal returns (bool) { return _add(set._inner, bytes32(value)); } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function remove(UintSet storage set, uint256 value) internal returns (bool) { return _remove(set._inner, bytes32(value)); } /** * @dev Returns true if the value is in the set. O(1). */ function contains(UintSet storage set, uint256 value) internal view returns (bool) { return _contains(set._inner, bytes32(value)); } /** * @dev Returns the number of values in the set. O(1). */ function length(UintSet storage set) internal view returns (uint256) { return _length(set._inner); } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(UintSet storage set, uint256 index) internal view returns (uint256) { return uint256(_at(set._inner, index)); } /** * @dev Return the entire set in an array * * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that * this function has an unbounded cost, and using it as part of a state-changing function may render the function * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. */ function values(UintSet storage set) internal view returns (uint256[] memory) { bytes32[] memory store = _values(set._inner); uint256[] memory result; /// @solidity memory-safe-assembly assembly { result := store } return result; } } interface IUniswapV2Pair { event Approval(address indexed owner, address indexed spender, uint value); event Transfer(address indexed from, address indexed to, uint value); function name() external pure returns (string memory); function symbol() external pure returns (string memory); function decimals() external pure returns (uint8); function totalSupply() external view returns (uint); function balanceOf(address owner) external view returns (uint); function allowance(address owner, address spender) external view returns (uint); function approve(address spender, uint value) external returns (bool); function transfer(address to, uint value) external returns (bool); function transferFrom(address from, address to, uint value) external returns (bool); function DOMAIN_SEPARATOR() external view returns (bytes32); function PERMIT_TYPEHASH() external pure returns (bytes32); function nonces(address owner) external view returns (uint); function permit(address owner, address spender, uint value, uint deadline, uint8 v, bytes32 r, bytes32 s) external; event Mint(address indexed sender, uint amount0, uint amount1); event Burn(address indexed sender, uint amount0, uint amount1, address indexed to); event Swap( address indexed sender, uint amount0In, uint amount1In, uint amount0Out, uint amount1Out, address indexed to ); event Sync(uint112 reserve0, uint112 reserve1); function MINIMUM_LIQUIDITY() external pure returns (uint); function factory() external view returns (address); function token0() external view returns (address); function token1() external view returns (address); function getReserves() external view returns (uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast); function price0CumulativeLast() external view returns (uint); function price1CumulativeLast() external view returns (uint); function kLast() external view returns (uint); function mint(address to) external returns (uint liquidity); function burn(address to) external returns (uint amount0, uint amount1); function swap(uint amount0Out, uint amount1Out, address to, bytes calldata data) external; function skim(address to) external; function sync() external; function initialize(address, address) external; } interface IUniswapV2Factory { event PairCreated(address indexed token0, address indexed token1, address pair, uint); function feeTo() external view returns (address); function feeToSetter() external view returns (address); function getPair(address tokenA, address tokenB) external view returns (address pair); function allPairs(uint) external view returns (address pair); function allPairsLength() external view returns (uint); function createPair(address tokenA, address tokenB) external returns (address pair); function setFeeTo(address) external; function setFeeToSetter(address) external; } interface IUniswapV2Router01 { function factory() external pure returns (address); function WETH() external pure returns (address); function addLiquidity( address tokenA, address tokenB, uint amountADesired, uint amountBDesired, uint amountAMin, uint amountBMin, address to, uint deadline ) external returns (uint amountA, uint amountB, uint liquidity); function addLiquidityETH( address token, uint amountTokenDesired, uint amountTokenMin, uint amountETHMin, address to, uint deadline ) external payable returns (uint amountToken, uint amountETH, uint liquidity); function removeLiquidity( address tokenA, address tokenB, uint liquidity, uint amountAMin, uint amountBMin, address to, uint deadline ) external returns (uint amountA, uint amountB); function removeLiquidityETH( address token, uint liquidity, uint amountTokenMin, uint amountETHMin, address to, uint deadline ) external returns (uint amountToken, uint amountETH); function removeLiquidityWithPermit( address tokenA, address tokenB, uint liquidity, uint amountAMin, uint amountBMin, address to, uint deadline, bool approveMax, uint8 v, bytes32 r, bytes32 s ) external returns (uint amountA, uint amountB); function removeLiquidityETHWithPermit( address token, uint liquidity, uint amountTokenMin, uint amountETHMin, address to, uint deadline, bool approveMax, uint8 v, bytes32 r, bytes32 s ) external returns (uint amountToken, uint amountETH); function swapExactTokensForTokens( uint amountIn, uint amountOutMin, address[] calldata path, address to, uint deadline ) external returns (uint[] memory amounts); function swapTokensForExactTokens( uint amountOut, uint amountInMax, address[] calldata path, address to, uint deadline ) external returns (uint[] memory amounts); function swapExactETHForTokens(uint amountOutMin, address[] calldata path, address to, uint deadline) external payable returns (uint[] memory amounts); function swapTokensForExactETH(uint amountOut, uint amountInMax, address[] calldata path, address to, uint deadline) external returns (uint[] memory amounts); function swapExactTokensForETH(uint amountIn, uint amountOutMin, address[] calldata path, address to, uint deadline) external returns (uint[] memory amounts); function swapETHForExactTokens(uint amountOut, address[] calldata path, address to, uint deadline) external payable returns (uint[] memory amounts); function quote(uint amountA, uint reserveA, uint reserveB) external pure returns (uint amountB); function getAmountOut(uint amountIn, uint reserveIn, uint reserveOut) external pure returns (uint amountOut); function getAmountIn(uint amountOut, uint reserveIn, uint reserveOut) external pure returns (uint amountIn); function getAmountsOut(uint amountIn, address[] calldata path) external view returns (uint[] memory amounts); function getAmountsIn(uint amountOut, address[] calldata path) external view returns (uint[] memory amounts); } interface IUniswapV2Router02 is IUniswapV2Router01 { function removeLiquidityETHSupportingFeeOnTransferTokens( address token, uint liquidity, uint amountTokenMin, uint amountETHMin, address to, uint deadline ) external returns (uint amountETH); function removeLiquidityETHWithPermitSupportingFeeOnTransferTokens( address token, uint liquidity, uint amountTokenMin, uint amountETHMin, address to, uint deadline, bool approveMax, uint8 v, bytes32 r, bytes32 s ) external returns (uint amountETH); function swapExactTokensForTokensSupportingFeeOnTransferTokens( uint amountIn, uint amountOutMin, address[] calldata path, address to, uint deadline ) external; function swapExactETHForTokensSupportingFeeOnTransferTokens( uint amountOutMin, address[] calldata path, address to, uint deadline ) external payable; function swapExactTokensForETHSupportingFeeOnTransferTokens( uint amountIn, uint amountOutMin, address[] calldata path, address to, uint deadline ) external; } pragma abicoder v2; /// @title Callback for IUniswapV3PoolActions#swap /// @notice Any contract that calls IUniswapV3PoolActions#swap must implement this interface interface IUniswapV3SwapCallback { /// @notice Called to `msg.sender` after executing a swap via IUniswapV3Pool#swap. /// @dev In the implementation you must pay the pool tokens owed for the swap. /// The caller of this method must be checked to be a UniswapV3Pool deployed by the canonical UniswapV3Factory. /// amount0Delta and amount1Delta can both be 0 if no tokens were swapped. /// @param amount0Delta The amount of token0 that was sent (negative) or must be received (positive) by the pool by /// the end of the swap. If positive, the callback must send that amount of token0 to the pool. /// @param amount1Delta The amount of token1 that was sent (negative) or must be received (positive) by the pool by /// the end of the swap. If positive, the callback must send that amount of token1 to the pool. /// @param data Any data passed through by the caller via the IUniswapV3PoolActions#swap call function uniswapV3SwapCallback( int256 amount0Delta, int256 amount1Delta, bytes calldata data ) external; } /// @title Router token swapping functionality /// @notice Functions for swapping tokens via Uniswap V3 interface ISwapRouter is IUniswapV3SwapCallback { struct ExactInputSingleParams { address tokenIn; address tokenOut; uint24 fee; address recipient; uint256 deadline; uint256 amountIn; uint256 amountOutMinimum; uint160 sqrtPriceLimitX96; } /// @notice Swaps `amountIn` of one token for as much as possible of another token /// @param params The parameters necessary for the swap, encoded as `ExactInputSingleParams` in calldata /// @return amountOut The amount of the received token function exactInputSingle(ExactInputSingleParams calldata params) external payable returns (uint256 amountOut); struct ExactInputParams { bytes path; address recipient; uint256 deadline; uint256 amountIn; uint256 amountOutMinimum; } /// @notice Swaps `amountIn` of one token for as much as possible of another along the specified path /// @param params The parameters necessary for the multi-hop swap, encoded as `ExactInputParams` in calldata /// @return amountOut The amount of the received token function exactInput(ExactInputParams calldata params) external payable returns (uint256 amountOut); struct ExactOutputSingleParams { address tokenIn; address tokenOut; uint24 fee; address recipient; uint256 deadline; uint256 amountOut; uint256 amountInMaximum; uint160 sqrtPriceLimitX96; } /// @notice Swaps as little as possible of one token for `amountOut` of another token /// @param params The parameters necessary for the swap, encoded as `ExactOutputSingleParams` in calldata /// @return amountIn The amount of the input token function exactOutputSingle(ExactOutputSingleParams calldata params) external payable returns (uint256 amountIn); struct ExactOutputParams { bytes path; address recipient; uint256 deadline; uint256 amountOut; uint256 amountInMaximum; } /// @notice Swaps as little as possible of one token for `amountOut` of another along the specified path (reversed) /// @param params The parameters necessary for the multi-hop swap, encoded as `ExactOutputParams` in calldata /// @return amountIn The amount of the input token function exactOutput(ExactOutputParams calldata params) external payable returns (uint256 amountIn); } /// @title ERC20 rewards /// @author @niera26 /// @notice buy and sell tax on this token with rewardToken as rewards /// @notice source: https://github.com/niera26/erc20-rewards-contracts contract ERC20Rewards is Ownable, ERC20, ERC20Burnable, ReentrancyGuard { using SafeERC20 for IERC20; using SafeERC20 for IERC20Metadata; using EnumerableSet for EnumerableSet.AddressSet; // ========================================================================= // dependencies. // ========================================================================= ISwapRouter public constant swapRouter = ISwapRouter(0xE592427A0AEce92De3Edee1F18E0157C05861564); IUniswapV2Router02 public constant router = IUniswapV2Router02(0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D); IERC20Metadata public constant rewardToken = IERC20Metadata(0x6De037ef9aD2725EB40118Bb1702EBb27e4Aeb24); // RNDR // the amm pair where the tranfers from/to are taxed. // (populated with WETH/this token pair address in the constructor). IUniswapV2Pair public immutable pair; // ========================================================================= // rewards management. // ========================================================================= struct Share { uint256 amount; // recorded balance after last transfer. uint256 earned; // amount of tokens earned but not claimed yet. uint256 tokenPerShareLast; // token per share value of the last earn occurrence. } // numerator multiplier so tokenPerShare does not get rounded to 0. uint256 private constant PRECISION = 1e18; // scale factor so reward token scales to 18 decimals. uint256 private immutable SCALE_FACTOR; // total shares of this token. // (different from total supply because of addresses excluded from rewards). uint256 public totalShares; // shareholders record. // (addresses included to rewards are updated every time they send/receive tokens). mapping(address => Share) private shareholders; // the accumulated amount of reward token per share. uint256 private tokenPerShare; // total amount of reward tokens ever claimed. uint256 public totalRewardClaimed; // total amount of reward tokens ever distributed. uint256 public totalRewardDistributed; // contract addresses that opted in for rewards. mapping(address => bool) public isOptin; // ========================================================================= // reward donations. // ========================================================================= // the number of reward tokens to emit per block. uint256 public rewardTokenPerBlock; // the amount of reward tokens emitted on last emitting block update. uint256 public emittedRewardsCache; // last block reward tokens has been emitted. uint256 public lastEmittingBlock; // ========================================================================= // operator address. // ========================================================================= // the operator address receive marketing tax and can set non critical // settings. Allows to renounce ownership so critical settings can't be // updated anymore. It is the same as the owner by default and receive the // marketing tax. It can: // - update itself. // - remove max wallet limits. // - set uniswap V3 pool fee setting. // - set the reward token per block rate. address public operator; // ========================================================================= // anti-bot and limitations. // ========================================================================= EnumerableSet.AddressSet private blacklist; uint256 public maxWallet = type(uint256).max; // set to 1% in initialize uint256 public startBlock = 0; uint8 public deadBlocks = 1; // ========================================================================= // pool options. // ========================================================================= uint24 public poolFee = 10000; // works for RNDR // ========================================================================= // fees. // ========================================================================= uint24 public constant maxSwapFee = 3000; uint24 public constant maxMarketingFee = 10000; uint24 public constant feeDenominator = 10000; uint24 public buyFee = 2400; uint24 public sellFee = 2400; uint24 public marketingFee = 10000; // ========================================================================= // events. // ========================================================================= event OptIn(address addr); event OptOut(address addr); event AddToBlacklist(address addr); event RemoveFromBlacklist(address addr); event Claim(address indexed addr, address indexed to, uint256 amount); event Distribute(address indexed addr, uint256 amount); event Sweep(address indexed addr, address indexed token, uint256 amount); // ========================================================================= // modifiers. // ========================================================================= modifier onlyOperator() { require(msg.sender == operator, "!operator"); _; } // ========================================================================= // constructor. // ========================================================================= constructor(string memory name, string memory symbol, uint256 _totalSupply) Ownable(msg.sender) ERC20(name, symbol) { // operator is deployer by default. operator = msg.sender; // set the reward token scale factor. uint8 rewardTokenDecimals = rewardToken.decimals(); require(rewardTokenDecimals <= 18, "reward token decimals must be <= 18"); SCALE_FACTOR = 10 ** (18 - rewardTokenDecimals); // create an amm pair with WETH. // as a contract, pair is automatically excluded from rewards. IUniswapV2Factory factory = IUniswapV2Factory(router.factory()); pair = IUniswapV2Pair(factory.createPair(router.WETH(), address(this))); // mint total supply to itself. _mint(address(this), _totalSupply * 10 ** decimals()); } // ========================================================================= // exposed contract values. // ========================================================================= /** * Whether the given address is blacklisted or not. * * The only way an address can be blacklisted is by receiving tokens when * trading is not enabled. */ function isBlacklisted(address addr) public view returns (bool) { return blacklist.contains(addr); } /** * The circulating supply. * * It is the total supply minus the balances of all blacklisted addresses. * * Very gas intensive, should not be used in a state modifying function. */ function circulatingSupply() public view returns (uint256) { uint256 lockedSupply; uint256 length = blacklist.length(); for (uint256 i = 0; i < length; i++) { lockedSupply += super.balanceOf(blacklist.at(i)); } return totalSupply() - lockedSupply; } /** * Balance of the given account. * * 0 when trading is enabled and the account is blacklisted. */ function balanceOf(address account) public view override returns (uint256) { if (!isBlacklisted(account) || !_isTradingEnabled()) { return super.balanceOf(account); } return 0; } /** * Locked balance of the given account. * * 0 when the the account is not blacklisted. */ function lockedBalanceOf(address account) public view returns (uint256) { if (isBlacklisted(account)) { return super.balanceOf(account); } return 0; } /** * The remaining rewards to emit. */ function remainingRewards() public view returns (uint256) { return rewardBalance() - emittedRewards(); } /** * The reward balance (amount that can be emitted in total). * * It is this contract balance of reward tokens minus the amount remaining * to claim. */ function rewardBalance() public view returns (uint256) { uint256 amountToClaim = totalRewardDistributed - totalRewardClaimed; return rewardToken.balanceOf(address(this)) - amountToClaim; } /** * The amount of reward emitted since the last emitting block recorded, * according to the reward token per block. * * Emitting block is recorded when setting the reward tokens per block and * during an distribution occurrence. * * This value is capped by the reward balance. */ function emittedRewards() public view returns (uint256) { if (lastEmittingBlock == 0) return 0; if (rewardTokenPerBlock == 0) return 0; uint256 balance = rewardBalance(); if (balance == 0) return 0; uint256 emitted = emittedRewardsCache + (rewardTokenPerBlock * (block.number - lastEmittingBlock)); return emitted < balance ? emitted : balance; } /** * The amount of reward tokens the given address can claim. */ function pendingRewards(address addr) external view returns (uint256) { return _pendingRewards(shareholders[addr]); } // ========================================================================= // exposed user functions. // ========================================================================= /** * Claim reward tokens and send them to given address. */ function claim(address to) external nonReentrant { Share storage share = shareholders[msg.sender]; _earn(share); uint256 amountToClaim = share.earned; if (amountToClaim == 0) return; share.earned = 0; totalRewardClaimed += amountToClaim; rewardToken.safeTransfer(to, amountToClaim); emit Claim(msg.sender, to, amountToClaim); } /** * Optin for rewards when you are excluded from rewards (contracts). */ function rewardOptin() external { _includeToRewards(msg.sender); isOptin[msg.sender] = true; emit OptIn(msg.sender); } /** * Optout for rewards when you are included to rewards (contracts). */ function rewardOptout() external { _removeFromRewards(msg.sender); isOptin[msg.sender] = false; emit OptOut(msg.sender); } /** * Swap the collected tax to ETH. * * Pass minimal expected amount to prevent slippage/frontrun. */ function swapCollectedTax(uint256 amountOutMin) public { // return if no tax collected. uint256 amountIn = balanceOf(address(this)); if (amountIn == 0) return; // swap tax to eth. uint256 collectedEth = _swapTokenToETHV2(address(this), amountIn, amountOutMin); // collect marketing tax. uint256 marketingAmount = (collectedEth * marketingFee) / feeDenominator; if (marketingAmount > 0) { payable(operator).transfer(marketingAmount); } } /** * Distribute reward token. * * Pass minimal expected amount to prevent slippage/frontrun. */ function distribute(uint256 amountOutMinimum) public { if (totalShares == 0) return; // distribute the rewards that was emitted since last update. uint256 amountToDistribute = emittedRewards(); // swap eth balance to reward token and add it to amount to distribute. uint256 amountIn = address(this).balance; if (amountIn > 0) { amountToDistribute += _swapETHToRewardV3(address(this), amountIn, amountOutMinimum); } // stop when no rewards. if (amountToDistribute == 0) return; // distribute rewards. tokenPerShare += (amountToDistribute * SCALE_FACTOR * PRECISION) / totalShares; totalRewardDistributed += amountToDistribute; // reset emitted rewards. emittedRewardsCache = 0; lastEmittingBlock = block.number; emit Distribute(msg.sender, amountToDistribute); } /** * Sweep any other ERC20 mistakenly sent to this contract. */ function sweep(IERC20 otherToken) external { require(address(otherToken) != address(this), "!sweep"); require(address(otherToken) != address(rewardToken), "!sweep"); uint256 amount = otherToken.balanceOf(address(this)); otherToken.safeTransfer(msg.sender, amount); emit Sweep(msg.sender, address(otherToken), amount); } // ========================================================================= // exposed admin functions. // ========================================================================= /** * Send initial allocations before liquidity is initialized. */ function allocate(address to, uint256 amount) external onlyOwner { require(startBlock == 0, "!initialized"); this.transfer(to, amount); } /** * Set the fees. */ function setFee(uint24 _buyFee, uint24 _sellFee, uint24 _marketingFee) external onlyOwner { require(_buyFee <= maxSwapFee, "!buyFee"); require(_sellFee <= maxSwapFee, "!sellFee"); require(_marketingFee <= maxMarketingFee, "!marketingFee"); buyFee = _buyFee; sellFee = _sellFee; marketingFee = _marketingFee; } /** * Remove the given address from the blacklist. */ function removeFromBlacklist(address addr) external onlyOwner { _removeFromBlacklist(addr); } /** * Initialize the trading with the given eth and this contract balance. * * Starts trading, sets max wallet to 1% of the supply, create the uniswap V2 pair * with ETH, adds liquidity. * * LP tokens are sent to owner. */ function initialize() external payable onlyOwner { require(msg.value > 0, "!liquidity"); require(startBlock == 0, "!initialized"); // start deadblocks from there. startBlock = block.number; // init max wallet to 1%. maxWallet = totalSupply() / 100; // the all balance will be put in the LP. uint256 balance = balanceOf(address(this)); // approve router to use total balance. _approve(address(this), address(router), balance); // add liquidity and send LP to owner. router.addLiquidityETH{value: msg.value}(address(this), balance, 0, 0, msg.sender, block.timestamp); } // ========================================================================= // exposed operator functions. // ========================================================================= /** * Operator can update itself. */ function setOperator(address _operator) external onlyOperator { require(address(0) != _operator, "!address"); operator = _operator; } /** * Remove max wallet limits, one shoot. */ function removeMaxWallet() external onlyOperator { maxWallet = type(uint256).max; } /** * Set the uniswap V3 pool fee. */ function setPoolFee(uint24 _poolFee) external onlyOperator { poolFee = _poolFee; } /** * Set the reward token per block. Accumulates the emitted rewards until this * block before updating the value. */ function setRewardTokenPerBlock(uint256 _rewardTokenPerBlock) external onlyOperator { emittedRewardsCache = emittedRewards(); rewardTokenPerBlock = _rewardTokenPerBlock; lastEmittingBlock = block.number; } /** * Set the reward token per block without accumulating what has been * emitted. Fallback is case of an error. */ function setRewardTokenPerBlockUnsafe(uint256 _rewardTokenPerBlock) external onlyOperator { rewardTokenPerBlock = _rewardTokenPerBlock; } /** * Empty the emitted rewards. Fallback in case of error. */ function resetEmittedRewardsUnsafe() external onlyOperator { emittedRewardsCache = 0; } // ========================================================================= // internal functions. // ========================================================================= /** * Whether the trading is enabled or not. */ function _isTradingEnabled() private view returns (bool) { return block.number > startBlock + deadBlocks; } /** * Whether the given address can be blacklisted. * * Obviously this contract, the router and the pair can't be blacklisted. */ function _isExcludedFromBlacklist(address addr) private view returns (bool) { return address(this) == addr || address(router) == addr || address(pair) == addr; } /** * Whether the given address is excluded from max wallet limit. * * Blacklisted addresses are excluded too so they can buy as much as they want. */ function _isExcludedFromMaxWallet(address addr) private view returns (bool) { return address(this) == addr || address(router) == addr || address(pair) == addr || isBlacklisted(addr); } /** * Whether the given adress is excluded from taxes. */ function _isExcludedFromTaxes(address addr) private view returns (bool) { return address(this) == addr || address(router) == addr; } /** * Whether the given address is excluded from rewards. * * - blacklisted addresses. * - addresses of contracts that didn't opted in for rewards. * - zero address to save gas on mint/burn (its balance is always 0 so it would never get shares anyway). * - this contract address is removed too because address(this).code.length == 0 in the constructor. * - remove dead address because people are used to it. */ function _isExcludedFromRewards(address addr) private view returns (bool) { return address(0) == addr || address(this) == addr || (addr.code.length > 0 && !isOptin[addr]) || isBlacklisted(addr) || 0x000000000000000000000000000000000000dEaD == addr; } /** * Add the given address to blacklist. */ function _addToBlacklist(address addr) private { _removeFromRewards(addr); blacklist.add(addr); emit AddToBlacklist(addr); } /** * Remove the given address from blacklist. */ function _removeFromBlacklist(address addr) private { _includeToRewards(addr); blacklist.remove(addr); emit RemoveFromBlacklist(addr); } /** * Include the given address to rewards. Should only concern: * * - addresses of contracts opting in for rewards. * - addresses being removed from blacklist. */ function _includeToRewards(address addr) private { // ensure we dont update total shares twice. if (!_isExcludedFromRewards(addr)) return; // update total shares. uint256 balance = super.balanceOf(addr); totalShares += balance; // restart earning from now. Share storage share = shareholders[addr]; share.amount = balance; share.tokenPerShareLast = tokenPerShare; } /** * Remove the given address from rewards. Should only concern: * * - addresses of contracts opting out of rewards. * - addresses being added to blacklist. */ function _removeFromRewards(address addr) private { // ensure we dont update total shares twice. if (_isExcludedFromRewards(addr)) return; // update total shares. totalShares -= super.balanceOf(addr); // make sure pending rewards are earned and stop earning (share.amount = 0) Share storage share = shareholders[addr]; _earn(share); share.amount = 0; } /** * The pending rewards of the given share. * * The rewards earned since the last transfer are added to the already earned * rewards. */ function _pendingRewards(Share memory share) private view returns (uint256) { uint256 RDiff = tokenPerShare - share.tokenPerShareLast; uint256 earned = (share.amount * RDiff) / (SCALE_FACTOR * PRECISION); return share.earned + earned; } /** * Earn the rewards of the given share. */ function _earn(Share storage share) private { uint256 pending = _pendingRewards(share); share.earned = pending; share.tokenPerShareLast = tokenPerShare; } /** * Override the update method in order to take fee when the transfer is from/to * a registered amm pair. * * - transfers from a blacklisted address reverts. * - transfers from/to the amm pair are taxed. * - taxed tokens are sent to this very contract. * - on a taxed sell, the collected tax is swapped for eth. * - updates the shares of both the from and to addresses. * - addresses buying when trading is not enabled are blacklisted. * - prevents receiving address to get more than max wallet. */ function _update(address from, address to, uint256 amount) internal override { // check if trading is enabled. bool isTradingEnabled = _isTradingEnabled(); // check if it is a taxed buy/sell. bool isTaxedBuy = address(pair) == from && !_isExcludedFromTaxes(to); bool isTaxedSell = !_isExcludedFromTaxes(from) && address(pair) == to; // lock the blacklisted senders when trading is enabled. if (isTradingEnabled && isBlacklisted(from)) { revert("locked"); } // compute the fee of a taxed buy/sell. uint256 fee = (isTaxedBuy ? buyFee : 0) + (isTaxedSell ? sellFee : 0); uint256 taxAmount = (amount * fee) / feeDenominator; uint256 actualTransferAmount = amount - taxAmount; // transfer the tax to this contract. if (taxAmount > 0) { super._update(from, address(this), taxAmount); } // swaps the tax to eth when it is a sell. if (isTaxedSell) { swapCollectedTax(0); } // transfer the actual amount to receiving address. super._update(from, to, actualTransferAmount); // update shares of sending an receiving addresses. _updateShare(from); _updateShare(to); // any receiving address should be blacklisted when trading is not enabled. if (!isTradingEnabled && !_isExcludedFromBlacklist(to)) { _addToBlacklist(to); } // revert when the receiving address balance is above max wallet. if (!_isExcludedFromMaxWallet(to)) { require(balanceOf(to) <= maxWallet, "!maxWallet"); } } /** * Update the total shares and the shares of the given address if it is not * excluded from rewards. * * Earn first with his current share amount then update shares according to * its new balance. */ function _updateShare(address addr) private { if (_isExcludedFromRewards(addr)) return; uint256 balance = balanceOf(addr); Share storage share = shareholders[addr]; totalShares = totalShares - share.amount + balance; _earn(share); share.amount = balance; } /** * Swap amount of this token for ETH to address and return the amount received. */ function _swapTokenToETHV2(address to, uint256 amountIn, uint256 amountOutMin) private returns (uint256) { // return 0 if no amount given. if (amountIn == 0) return 0; // approve router to spend tokens. _approve(address(this), address(router), amountIn); // swap the whole amount to eth. address[] memory path = new address[](2); path[0] = address(this); path[1] = router.WETH(); uint256 originalETHbalance = address(this).balance; router.swapExactTokensForETHSupportingFeeOnTransferTokens(amountIn, amountOutMin, path, to, block.timestamp); return address(this).balance - originalETHbalance; } /** * Swap amount of ETH for reward tokens to address and return the amount received. */ function _swapETHToRewardV3(address to, uint256 amountIn, uint256 amountOutMinimum) private returns (uint256) { // return 0 if no amount given. if (amountIn == 0) return 0; // build the swap parameter. ISwapRouter.ExactInputSingleParams memory params = ISwapRouter.ExactInputSingleParams({ tokenIn: router.WETH(), tokenOut: address(rewardToken), fee: poolFee, recipient: to, deadline: block.timestamp, amountIn: amountIn, amountOutMinimum: amountOutMinimum, sqrtPriceLimitX96: 0 }); // execute the swap and return the number of received tokens. return swapRouter.exactInputSingle{value: amountIn}(params); } receive() external payable {} } /// @title Kanpai /// @author @niera26 /// @notice buy and sell tax on this token with RNDR as rewards /// @notice source: https://github.com/kanpairender/kanpai-contracts contract Kanpai is ERC20Rewards { constructor() ERC20Rewards("Kanpai", "KPAI", 10e6) {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"address","name":"target","type":"address"}],"name":"AddressEmptyCode","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"AddressInsufficientBalance","type":"error"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"allowance","type":"uint256"},{"internalType":"uint256","name":"needed","type":"uint256"}],"name":"ERC20InsufficientAllowance","type":"error"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"uint256","name":"balance","type":"uint256"},{"internalType":"uint256","name":"needed","type":"uint256"}],"name":"ERC20InsufficientBalance","type":"error"},{"inputs":[{"internalType":"address","name":"approver","type":"address"}],"name":"ERC20InvalidApprover","type":"error"},{"inputs":[{"internalType":"address","name":"receiver","type":"address"}],"name":"ERC20InvalidReceiver","type":"error"},{"inputs":[{"internalType":"address","name":"sender","type":"address"}],"name":"ERC20InvalidSender","type":"error"},{"inputs":[{"internalType":"address","name":"spender","type":"address"}],"name":"ERC20InvalidSpender","type":"error"},{"inputs":[],"name":"FailedInnerCall","type":"error"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"OwnableInvalidOwner","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"OwnableUnauthorizedAccount","type":"error"},{"inputs":[],"name":"ReentrancyGuardReentrantCall","type":"error"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"SafeERC20FailedOperation","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"addr","type":"address"}],"name":"AddToBlacklist","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"addr","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Claim","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"addr","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Distribute","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"addr","type":"address"}],"name":"OptIn","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"addr","type":"address"}],"name":"OptOut","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":"addr","type":"address"}],"name":"RemoveFromBlacklist","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"addr","type":"address"},{"indexed":true,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Sweep","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"allocate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"value","type":"uint256"}],"name":"burn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"burnFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"buyFee","outputs":[{"internalType":"uint24","name":"","type":"uint24"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"circulatingSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"}],"name":"claim","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"deadBlocks","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountOutMinimum","type":"uint256"}],"name":"distribute","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"emittedRewards","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"emittedRewardsCache","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"feeDenominator","outputs":[{"internalType":"uint24","name":"","type":"uint24"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"initialize","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"name":"isBlacklisted","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"isOptin","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lastEmittingBlock","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"lockedBalanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"marketingFee","outputs":[{"internalType":"uint24","name":"","type":"uint24"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxMarketingFee","outputs":[{"internalType":"uint24","name":"","type":"uint24"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxSwapFee","outputs":[{"internalType":"uint24","name":"","type":"uint24"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxWallet","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"operator","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pair","outputs":[{"internalType":"contract IUniswapV2Pair","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"name":"pendingRewards","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"poolFee","outputs":[{"internalType":"uint24","name":"","type":"uint24"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"remainingRewards","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"name":"removeFromBlacklist","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"removeMaxWallet","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"resetEmittedRewardsUnsafe","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"rewardBalance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"rewardOptin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"rewardOptout","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"rewardToken","outputs":[{"internalType":"contract IERC20Metadata","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"rewardTokenPerBlock","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"router","outputs":[{"internalType":"contract IUniswapV2Router02","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"sellFee","outputs":[{"internalType":"uint24","name":"","type":"uint24"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint24","name":"_buyFee","type":"uint24"},{"internalType":"uint24","name":"_sellFee","type":"uint24"},{"internalType":"uint24","name":"_marketingFee","type":"uint24"}],"name":"setFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_operator","type":"address"}],"name":"setOperator","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint24","name":"_poolFee","type":"uint24"}],"name":"setPoolFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_rewardTokenPerBlock","type":"uint256"}],"name":"setRewardTokenPerBlock","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_rewardTokenPerBlock","type":"uint256"}],"name":"setRewardTokenPerBlockUnsafe","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"startBlock","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountOutMin","type":"uint256"}],"name":"swapCollectedTax","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"swapRouter","outputs":[{"internalType":"contract ISwapRouter","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IERC20","name":"otherToken","type":"address"}],"name":"sweep","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalRewardClaimed","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalRewardDistributed","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":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"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
60c06040526000196013556000601455601580546001600160681b0319166b2710000960000960002710011790553480156200003a57600080fd5b5060408051808201825260068152654b616e70616960d01b602080830191909152825180840190935260048352634b50414960e01b90830152906298968082823380620000a257604051631e4fbdf760e01b8152600060048201526024015b60405180910390fd5b620000ad816200038f565b506004620000bc838262000fb9565b506005620000cb828262000fb9565b5050600160065550601080546001600160a01b031916331790556040805163313ce56760e01b81529051600091736de037ef9ad2725eb40118bb1702ebb27e4aeb249163313ce567916004808201926020929091908290030181865afa1580156200013a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000160919062001085565b905060128160ff161115620001c45760405162461bcd60e51b815260206004820152602360248201527f72657761726420746f6b656e20646563696d616c73206d757374206265203c3d60448201526204062760eb1b606482015260840162000099565b620001d1816012620010c0565b620001de90600a620011d9565b60a081815250506000600080516020620040eb8339815191526001600160a01b031663c45a01556040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000235573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200025b9190620011ea565b9050806001600160a01b031663c9c65396600080516020620040eb8339815191526001600160a01b031663ad5c46486040518163ffffffff1660e01b8152600401602060405180830381865afa158015620002ba573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620002e09190620011ea565b6040516001600160e01b031960e084901b1681526001600160a01b0390911660048201523060248201526044016020604051808303816000875af11580156200032d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620003539190620011ea565b6001600160a01b03166080526200038430620003726012600a620011d9565b6200037e908662001215565b620003df565b50505050506200132f565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6001600160a01b0382166200040b5760405163ec442f0560e01b81526000600482015260240162000099565b62000419600083836200041d565b5050565b60006200042962000634565b90506000846001600160a01b03166080516001600160a01b0316148015620004595750620004578462000655565b155b90506000620004688662000655565b158015620004895750846001600160a01b03166080516001600160a01b0316145b90508280156200049f57506200049f866200068c565b15620004d75760405162461bcd60e51b81526020600482015260066024820152651b1bd8dad95960d21b604482015260640162000099565b600081620004e7576000620004fb565b601554670100000000000000900462ffffff165b83620005095760006200051a565b601554640100000000900462ffffff165b6200052691906200122f565b62ffffff16905060006127106200053e838862001215565b6200054a919062001255565b905060006200055a828862001278565b905081156200057057620005708930846200069b565b83156200058357620005836000620007ce565b620005908989836200069b565b6200059b896200087d565b620005a6886200087d565b85158015620005bd5750620005bb88620008eb565b155b15620005ce57620005ce8862000938565b620005d98862000990565b6200062957601354620005ec89620009f2565b1115620006295760405162461bcd60e51b815260206004820152600a602482015269085b585e15d85b1b195d60b21b604482015260640162000099565b505050505050505050565b6015546014546000916200064e9160ff909116906200128e565b4311905090565b6000306001600160a01b0383161480620006865750600080516020620040eb8339815191526001600160a01b038316145b92915050565b60006200068660118362000a40565b6001600160a01b038316620006ca578060036000828254620006be91906200128e565b909155506200073e9050565b6001600160a01b038316600090815260016020526040902054818110156200071f5760405163391434e360e21b81526001600160a01b0385166004820152602481018290526044810183905260640162000099565b6001600160a01b03841660009081526001602052604090209082900390555b6001600160a01b0382166200075c576003805482900390556200077b565b6001600160a01b03821660009081526001602052604090208054820190555b816001600160a01b0316836001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef83604051620007c191815260200190565b60405180910390a3505050565b6000620007db30620009f2565b905080600003620007ea575050565b6000620007f930838562000a65565b6015549091506000906127109062000825906a0100000000000000000000900462ffffff168462001215565b62000831919062001255565b9050801562000877576010546040516001600160a01b039091169082156108fc029083906000818181858888f1935050505015801562000875573d6000803e3d6000fd5b505b50505050565b620008888162000c19565b15620008915750565b60006200089e82620009f2565b6001600160a01b0383166000908152600860205260409020805460075492935090918391620008cd9162001278565b620008d991906200128e565b600755620008e78162000c9f565b5550565b6000306001600160a01b03831614806200091c5750600080516020620040eb8339815191526001600160a01b038316145b80620006865750506080516001600160a01b0390811691161490565b620009438162000ce2565b6200095060118262000d51565b506040516001600160a01b03821681527f6b713f4f12b0a0860e4b6b54d27ef8de95da632b1250f5c12f8254fdedbc2ebd9060200160405180910390a150565b6000306001600160a01b0383161480620009c15750600080516020620040eb8339815191526001600160a01b038316145b80620009e05750816001600160a01b03166080516001600160a01b0316145b8062000686575062000686826200068c565b6000620009ff826200068c565b158062000a13575062000a1162000634565b155b1562000a38576001600160a01b03821660009081526001602052604090205462000686565b506000919050565b6001600160a01b038116600090815260018301602052604081205415155b9392505050565b60008260000362000a795750600062000a5e565b62000a9530600080516020620040eb8339815191528562000d68565b604080516002808252606082018352600092602083019080368337019050509050308160008151811062000acd5762000acd620012a4565b60200260200101906001600160a01b031690816001600160a01b031681525050600080516020620040eb8339815191526001600160a01b031663ad5c46486040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000b3b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000b619190620011ea565b8160018151811062000b775762000b77620012a4565b6001600160a01b039092166020928302919091019091015260405163791ac94760e01b81524790600080516020620040eb8339815191529063791ac9479062000bcd908890889087908c904290600401620012ba565b600060405180830381600087803b15801562000be857600080fd5b505af115801562000bfd573d6000803e3d6000fd5b50505050804762000c0f919062001278565b9695505050505050565b60006001600160a01b038216158062000c3a5750306001600160a01b038316145b8062000c7557506000826001600160a01b03163b11801562000c7557506001600160a01b0382166000908152600c602052604090205460ff16155b8062000c87575062000c87826200068c565b80620006865750506001600160a01b031661dead1490565b60408051606081018252825481526001830154602082015260028301549181019190915260009062000cd19062000d7c565b600183015550600954600290910155565b62000ced8162000c19565b1562000cf65750565b6001600160a01b0381166000908152600160205260409020546007600082825462000d22919062001278565b90915550506001600160a01b038116600090815260086020526040902062000d4a8162000c9f565b6000905550565b600062000a5e836001600160a01b03841662000de6565b62000d77838383600162000e38565b505050565b600080826040015160095462000d93919062001278565b90506000670de0b6b3a764000060a05162000daf919062001215565b845162000dbe90849062001215565b62000dca919062001255565b905080846020015162000dde91906200128e565b949350505050565b600081815260018301602052604081205462000e2f5750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915562000686565b50600062000686565b6001600160a01b03841662000e645760405163e602df0560e01b81526000600482015260240162000099565b6001600160a01b03831662000e9057604051634a1406b160e11b81526000600482015260240162000099565b6001600160a01b03808516600090815260026020908152604080832093871683529290522082905580156200087757826001600160a01b0316846001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9258460405162000f0591815260200190565b60405180910390a350505050565b634e487b7160e01b600052604160045260246000fd5b600181811c9082168062000f3e57607f821691505b60208210810362000f5f57634e487b7160e01b600052602260045260246000fd5b50919050565b601f82111562000d77576000816000526020600020601f850160051c8101602086101562000f905750805b601f850160051c820191505b8181101562000fb15782815560010162000f9c565b505050505050565b81516001600160401b0381111562000fd55762000fd562000f13565b62000fed8162000fe6845462000f29565b8462000f65565b602080601f8311600181146200102557600084156200100c5750858301515b600019600386901b1c1916600185901b17855562000fb1565b600085815260208120601f198616915b82811015620010565788860151825594840194600190910190840162001035565b5085821015620010755787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b6000602082840312156200109857600080fd5b815160ff8116811462000a5e57600080fd5b634e487b7160e01b600052601160045260246000fd5b60ff8281168282160390811115620006865762000686620010aa565b600181815b808511156200111d578160001904821115620011015762001101620010aa565b808516156200110f57918102915b93841c9390800290620010e1565b509250929050565b600082620011365750600162000686565b81620011455750600062000686565b81600181146200115e5760028114620011695762001189565b600191505062000686565b60ff8411156200117d576200117d620010aa565b50506001821b62000686565b5060208310610133831016604e8410600b8410161715620011ae575081810a62000686565b620011ba8383620010dc565b8060001904821115620011d157620011d1620010aa565b029392505050565b600062000a5e60ff84168362001125565b600060208284031215620011fd57600080fd5b81516001600160a01b038116811462000a5e57600080fd5b8082028115828204841417620006865762000686620010aa565b62ffffff8181168382160190808211156200124e576200124e620010aa565b5092915050565b6000826200127357634e487b7160e01b600052601260045260246000fd5b500490565b81810381811115620006865762000686620010aa565b80820180821115620006865762000686620010aa565b634e487b7160e01b600052603260045260246000fd5b600060a08201878352602087602085015260a0604085015281875180845260c08601915060208901935060005b818110156200130e5784516001600160a01b031683529383019391830191600101620012e7565b50506001600160a01b03969096166060850152505050608001529392505050565b60805160a051612d73620013786000396000818161115101526119b20152600081816107f80152818161210b01528181612167015281816125dc01526126a10152612d736000f3fe6080604052600436106103905760003560e01c806373dd250c116101dc578063c31c9c0711610102578063e7e3a24d116100a0578063f887ea401161006f578063f887ea4014610a29578063f8b45b0514610a51578063fabb0b4f14610a67578063fe575a8714610a8157600080fd5b8063e7e3a24d1461099c578063e7e82b69146109b1578063f2fde38b146109e1578063f7c618c114610a0157600080fd5b8063d7406965116100dc578063d740696514610901578063dbfa0bb514610921578063dc07b61714610941578063dd62ed3e1461095657600080fd5b8063c31c9c07146108a4578063c38ed941146108cc578063cebd7ae8146108ec57600080fd5b80639358928b1161017a578063aa5c3ab411610149578063aa5c3ab41461083a578063afb62e561461084f578063b3ab15fb14610864578063b78b52df1461088457600080fd5b80639358928b146107bc57806395d89b41146107d1578063a8aa1b31146107e6578063a9059cbb1461081a57600080fd5b80638da5cb5b116101b65780638da5cb5b14610754578063909921c71461077257806391c05b0b146107875780639266cc2a146107a757600080fd5b806373dd250c1461070c57806379cc67901461072c5780638129fc1c1461074c57600080fd5b80633a98ef39116102c1578063570ca7351161025f5780636b67c4df1161022e5780636b67c4df1461069e5780636f83f6a2146106c157806370a08231146106d7578063715018a6146106f757600080fd5b8063570ca7351461061057806359303a1114610648578063593557361461066857806366edecce1461068857600080fd5b806348cd4cb11161029b57806348cd4cb1146105ae578063537df3b6146105c45780635428c9cb146105e4578063554c798a146105fa57600080fd5b80633a98ef391461055457806342966c681461056a578063470624021461058a57600080fd5b80631e83409a1161032e5780632b14ca56116103085780632b14ca56146104d957806330188ee8146104fc578063313ce5671461051257806331d7a2621461053457600080fd5b80631e83409a146104835780632251c730146104a357806323b872dd146104b957600080fd5b806309094d661161036a57806309094d661461041e578063095ea7b314610434578063180b0d7e1461041e57806318160ddd1461046457600080fd5b806301681a621461039c57806306fdde03146103be578063089fe6aa146103e957600080fd5b3661039757005b600080fd5b3480156103a857600080fd5b506103bc6103b7366004612965565b610aa1565b005b3480156103ca57600080fd5b506103d3610c02565b6040516103e091906129a6565b60405180910390f35b3480156103f557600080fd5b5060155461040a90610100900462ffffff1681565b60405162ffffff90911681526020016103e0565b34801561042a57600080fd5b5061040a61271081565b34801561044057600080fd5b5061045461044f3660046129d9565b610c94565b60405190151581526020016103e0565b34801561047057600080fd5b506003545b6040519081526020016103e0565b34801561048f57600080fd5b506103bc61049e366004612965565b610cae565b3480156104af57600080fd5b50610475600f5481565b3480156104c557600080fd5b506104546104d4366004612a05565b610d74565b3480156104e557600080fd5b5060155461040a90600160381b900462ffffff1681565b34801561050857600080fd5b50610475600b5481565b34801561051e57600080fd5b5060125b60405160ff90911681526020016103e0565b34801561054057600080fd5b5061047561054f366004612965565b610d9a565b34801561056057600080fd5b5061047560075481565b34801561057657600080fd5b506103bc610585366004612a46565b610dde565b34801561059657600080fd5b5060155461040a90640100000000900462ffffff1681565b3480156105ba57600080fd5b5061047560145481565b3480156105d057600080fd5b506103bc6105df366004612965565b610de8565b3480156105f057600080fd5b50610475600e5481565b34801561060657600080fd5b50610475600d5481565b34801561061c57600080fd5b50601054610630906001600160a01b031681565b6040516001600160a01b0390911681526020016103e0565b34801561065457600080fd5b506103bc610663366004612a46565b610df9565b34801561067457600080fd5b50610475610683366004612965565b610e28565b34801561069457600080fd5b5061040a610bb881565b3480156106aa57600080fd5b5060155461040a90600160501b900462ffffff1681565b3480156106cd57600080fd5b50610475600a5481565b3480156106e357600080fd5b506104756106f2366004612965565b610e5e565b34801561070357600080fd5b506103bc610e9a565b34801561071857600080fd5b506103bc610727366004612a77565b610eae565b34801561073857600080fd5b506103bc6107473660046129d9565b610ef8565b6103bc610f11565b34801561076057600080fd5b506000546001600160a01b0316610630565b34801561077e57600080fd5b5061047561107b565b34801561079357600080fd5b506103bc6107a2366004612a46565b6110fb565b3480156107b357600080fd5b506103bc6111fc565b3480156107c857600080fd5b50610475611253565b3480156107dd57600080fd5b506103d36112c1565b3480156107f257600080fd5b506106307f000000000000000000000000000000000000000000000000000000000000000081565b34801561082657600080fd5b506104546108353660046129d9565b6112d0565b34801561084657600080fd5b506104756112de565b34801561085b57600080fd5b50610475611379565b34801561087057600080fd5b506103bc61087f366004612965565b61139a565b34801561089057600080fd5b506103bc61089f3660046129d9565b61142a565b3480156108b057600080fd5b5061063073e592427a0aece92de3edee1f18e0157c0586156481565b3480156108d857600080fd5b506103bc6108e7366004612a92565b6114e7565b3480156108f857600080fd5b506103bc611611565b34801561090d57600080fd5b506103bc61091c366004612a46565b611665565b34801561092d57600080fd5b506103bc61093c366004612a46565b6116a3565b34801561094d57600080fd5b506103bc61173f565b34801561096257600080fd5b50610475610971366004612ad5565b6001600160a01b03918216600090815260026020908152604080832093909416825291909152205490565b3480156109a857600080fd5b506103bc611771565b3480156109bd57600080fd5b506104546109cc366004612965565b600c6020526000908152604090205460ff1681565b3480156109ed57600080fd5b506103bc6109fc366004612965565b6117a2565b348015610a0d57600080fd5b50610630736de037ef9ad2725eb40118bb1702ebb27e4aeb2481565b348015610a3557600080fd5b50610630737a250d5630b4cf539739df2c5dacb4c659f2488d81565b348015610a5d57600080fd5b5061047560135481565b348015610a7357600080fd5b506015546105229060ff1681565b348015610a8d57600080fd5b50610454610a9c366004612965565b6117dd565b306001600160a01b03821603610ae75760405162461bcd60e51b815260206004820152600660248201526502173776565760d41b60448201526064015b60405180910390fd5b736de037ef9ad2725eb40118bb1702ebb27e4aeb23196001600160a01b03821601610b3d5760405162461bcd60e51b815260206004820152600660248201526502173776565760d41b6044820152606401610ade565b6040516370a0823160e01b81523060048201526000906001600160a01b038316906370a0823190602401602060405180830381865afa158015610b84573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ba89190612b0e565b9050610bbe6001600160a01b03831633836117ea565b6040518181526001600160a01b0383169033907fed679328aebf74ede77ae09efcf36e90244f83643dadac1c2d9f0b21a46f6ab79060200160405180910390a35050565b606060048054610c1190612b27565b80601f0160208091040260200160405190810160405280929190818152602001828054610c3d90612b27565b8015610c8a5780601f10610c5f57610100808354040283529160200191610c8a565b820191906000526020600020905b815481529060010190602001808311610c6d57829003601f168201915b5050505050905090565b600033610ca281858561183c565b60019150505b92915050565b610cb6611849565b336000908152600860205260409020610cce81611873565b60018101546000819003610ce3575050610d67565b6000826001018190555080600a6000828254610cff9190612b77565b90915550610d249050736de037ef9ad2725eb40118bb1702ebb27e4aeb2484836117ea565b6040518181526001600160a01b0384169033907f70eb43c4a8ae8c40502dcf22436c509c28d6ff421cf07c491be56984bd9870689060200160405180910390a350505b610d716001600655565b50565b600033610d828582856118b4565b610d8d85858561192c565b60019150505b9392505050565b6001600160a01b03811660009081526008602090815260408083208151606081018352815481526001820154938101939093526002015490820152610ca89061198b565b610d713382611a07565b610df0611a3d565b610d7181611a6a565b6010546001600160a01b03163314610e235760405162461bcd60e51b8152600401610ade90612b8a565b600d55565b6000610e33826117dd565b15610e56576001600160a01b038216600090815260016020526040902054610ca8565b506000919050565b6000610e69826117dd565b1580610e335750610e78611abf565b610e56576001600160a01b038216600090815260016020526040902054610ca8565b610ea2611a3d565b610eac6000611ade565b565b6010546001600160a01b03163314610ed85760405162461bcd60e51b8152600401610ade90612b8a565b6015805462ffffff9092166101000263ffffff0019909216919091179055565b610f038233836118b4565b610f0d8282611a07565b5050565b610f19611a3d565b60003411610f565760405162461bcd60e51b815260206004820152600a602482015269216c697175696469747960b01b6044820152606401610ade565b60145415610f955760405162461bcd60e51b815260206004820152600c60248201526b085a5b9a5d1a585b1a5e995960a21b6044820152606401610ade565b436014556064610fa460035490565b610fae9190612bad565b6013556000610fbc30610e5e565b9050610fdd30737a250d5630b4cf539739df2c5dacb4c659f2488d8361183c565b60405163f305d71960e01b81523060048201526024810182905260006044820181905260648201523360848201524260a4820152737a250d5630b4cf539739df2c5dacb4c659f2488d9063f305d71990349060c40160606040518083038185885af1158015611050573d6000803e3d6000fd5b50505050506040513d601f19601f820116820180604052508101906110759190612bcf565b50505050565b6000600f5460000361108d5750600090565b600d5460000361109d5750600090565b60006110a76112de565b9050806000036110b957600091505090565b6000600f54436110c99190612bfd565b600d546110d69190612c10565b600e546110e39190612b77565b90508181106110f257816110f4565b805b9250505090565b6007546000036111085750565b600061111261107b565b905047801561113357611126308285611b2e565b6111309083612b77565b91505b8160000361114057505050565b600754670de0b6b3a76400006111767f000000000000000000000000000000000000000000000000000000000000000085612c10565b6111809190612c10565b61118a9190612bad565b6009600082825461119b9190612b77565b9250508190555081600b60008282546111b49190612b77565b90915550506000600e5543600f5560405182815233907fc1d32ad5cca423e7dda2123dbf8c482f8e77d00b631c06e903a47f2cec1334df9060200160405180910390a2505050565b61120533611d00565b336000818152600c6020908152604091829020805460ff1916905590519182527f9d987f025241c15852f6fdf907bfad8c5c84f316a13b8855ba5185bf79a3f7bb91015b60405180910390a1565b60008060006112626011611d68565b905060005b818110156112ac5761129861127d601183611d72565b6001600160a01b031660009081526001602052604090205490565b6112a29084612b77565b9250600101611267565b50816112b760035490565b6110f49190612bfd565b606060058054610c1190612b27565b600033610ca281858561192c565b600080600a54600b546112f19190612bfd565b6040516370a0823160e01b81523060048201529091508190736de037ef9ad2725eb40118bb1702ebb27e4aeb24906370a0823190602401602060405180830381865afa158015611345573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113699190612b0e565b6113739190612bfd565b91505090565b600061138361107b565b61138b6112de565b6113959190612bfd565b905090565b6010546001600160a01b031633146113c45760405162461bcd60e51b8152600401610ade90612b8a565b6001600160a01b0381166000036114085760405162461bcd60e51b8152602060048201526008602482015267216164647265737360c01b6044820152606401610ade565b601080546001600160a01b0319166001600160a01b0392909216919091179055565b611432611a3d565b601454156114715760405162461bcd60e51b815260206004820152600c60248201526b085a5b9a5d1a585b1a5e995960a21b6044820152606401610ade565b60405163a9059cbb60e01b81526001600160a01b038316600482015260248101829052309063a9059cbb906044016020604051808303816000875af11580156114be573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114e29190612c27565b505050565b6114ef611a3d565b610bb862ffffff841611156115305760405162461bcd60e51b81526020600482015260076024820152662162757946656560c81b6044820152606401610ade565b610bb862ffffff831611156115725760405162461bcd60e51b81526020600482015260086024820152672173656c6c46656560c01b6044820152606401610ade565b61271062ffffff821611156115b95760405162461bcd60e51b815260206004820152600d60248201526c216d61726b6574696e6746656560981b6044820152606401610ade565b6015805469ffffffffffff00000000191664010000000062ffffff9586160269ffffff00000000000000191617600160381b938516939093029290921762ffffff60501b1916600160501b9190931602919091179055565b61161a33611d7e565b336000818152600c6020908152604091829020805460ff1916600117905590519182527f6d2f2ea0335c8c0e296412085b47e0ed0c1b67b6bde3f5739e7739ca804a75b19101611249565b6010546001600160a01b0316331461168f5760405162461bcd60e51b8152600401610ade90612b8a565b61169761107b565b600e55600d5543600f55565b60006116ae30610e5e565b9050806000036116bc575050565b60006116c9308385611de7565b601554909150600090612710906116ec90600160501b900462ffffff1684612c10565b6116f69190612bad565b90508015611075576010546040516001600160a01b039091169082156108fc029083906000818181858888f19350505050158015611738573d6000803e3d6000fd5b5050505050565b6010546001600160a01b031633146117695760405162461bcd60e51b8152600401610ade90612b8a565b600019601355565b6010546001600160a01b0316331461179b5760405162461bcd60e51b8152600401610ade90612b8a565b6000600e55565b6117aa611a3d565b6001600160a01b0381166117d457604051631e4fbdf760e01b815260006004820152602401610ade565b610d7181611ade565b6000610ca8601183611f97565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b1790526114e2908490611fb9565b6114e2838383600161201c565b60026006540361186c57604051633ee5aeb560e01b815260040160405180910390fd5b6002600655565b6040805160608101825282548152600183015460208201526002830154918101919091526000906118a39061198b565b600183015550600954600290910155565b6001600160a01b038381166000908152600260209081526040808320938616835292905220546000198114611075578181101561191d57604051637dc7a0d960e11b81526001600160a01b03841660048201526024810182905260448101839052606401610ade565b6110758484848403600061201c565b6001600160a01b03831661195657604051634b637e8f60e11b815260006004820152602401610ade565b6001600160a01b0382166119805760405163ec442f0560e01b815260006004820152602401610ade565b6114e28383836120f1565b60008082604001516009546119a09190612bfd565b905060006119d6670de0b6b3a76400007f0000000000000000000000000000000000000000000000000000000000000000612c10565b84516119e3908490612c10565b6119ed9190612bad565b90508084602001516119ff9190612b77565b949350505050565b6001600160a01b038216611a3157604051634b637e8f60e11b815260006004820152602401610ade565b610f0d826000836120f1565b6000546001600160a01b03163314610eac5760405163118cdaa760e01b8152336004820152602401610ade565b611a7381611d7e565b611a7e60118261230e565b506040516001600160a01b03821681527f3afada3900b4909463d8a846fbdc12d6b5c4e8030bd6bc1215822ecee62357ba906020015b60405180910390a150565b601554601454600091611ad79160ff90911690612b77565b4311905090565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b600082600003611b4057506000610d93565b6000604051806101000160405280737a250d5630b4cf539739df2c5dacb4c659f2488d6001600160a01b031663ad5c46486040518163ffffffff1660e01b8152600401602060405180830381865afa158015611ba0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611bc49190612c49565b6001600160a01b039081168252736de037ef9ad2725eb40118bb1702ebb27e4aeb24602080840191909152601554610100900462ffffff9081166040808601919091528a84166060808701919091524260808088019190915260a08088018d905260c08089018d9052600060e0998a0152845163414bf38960e01b81528a5189166004820152968a015188166024880152938901519094166044860152908701518516606485015286015160848401529085015160a483015284015160c4820152918301511660e482015290915073e592427a0aece92de3edee1f18e0157c058615649063414bf3899086906101040160206040518083038185885af1158015611cd2573d6000803e3d6000fd5b50505050506040513d601f19601f82011682018060405250810190611cf79190612b0e565b95945050505050565b611d0981612323565b15611d115750565b6001600160a01b03811660009081526001602052604090205460076000828254611d3b9190612bfd565b90915550506001600160a01b0381166000908152600860205260409020611d6181611873565b6000905550565b6000610ca8825490565b6000610d9383836123a2565b611d8781612323565b611d8e5750565b6001600160a01b03811660009081526001602052604081205490508060076000828254611dbb9190612b77565b90915550506001600160a01b039091166000908152600860205260409020908155600954600290910155565b600082600003611df957506000610d93565b611e1830737a250d5630b4cf539739df2c5dacb4c659f2488d8561183c565b6040805160028082526060820183526000926020830190803683370190505090503081600081518110611e4d57611e4d612c66565b60200260200101906001600160a01b031690816001600160a01b031681525050737a250d5630b4cf539739df2c5dacb4c659f2488d6001600160a01b031663ad5c46486040518163ffffffff1660e01b8152600401602060405180830381865afa158015611ebf573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ee39190612c49565b81600181518110611ef657611ef6612c66565b6001600160a01b039092166020928302919091019091015260405163791ac94760e01b81524790737a250d5630b4cf539739df2c5dacb4c659f2488d9063791ac94790611f4f908890889087908c904290600401612c7c565b600060405180830381600087803b158015611f6957600080fd5b505af1158015611f7d573d6000803e3d6000fd5b505050508047611f8d9190612bfd565b9695505050505050565b6001600160a01b03811660009081526001830160205260408120541515610d93565b6000611fce6001600160a01b038416836123cc565b90508051600014158015611ff3575080806020019051810190611ff19190612c27565b155b156114e257604051635274afe760e01b81526001600160a01b0384166004820152602401610ade565b6001600160a01b0384166120465760405163e602df0560e01b815260006004820152602401610ade565b6001600160a01b03831661207057604051634a1406b160e11b815260006004820152602401610ade565b6001600160a01b038085166000908152600260209081526040808320938716835292905220829055801561107557826001600160a01b0316846001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925846040516120e391815260200190565b60405180910390a350505050565b60006120fb611abf565b90506000846001600160a01b03167f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03161480156121465750612144846123da565b155b90506000612153866123da565b1580156121915750846001600160a01b03167f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316145b90508280156121a457506121a4866117dd565b156121da5760405162461bcd60e51b81526020600482015260066024820152651b1bd8dad95960d21b6044820152606401610ade565b6000816121e85760006121f8565b601554600160381b900462ffffff165b83612204576000612215565b601554640100000000900462ffffff165b61221f9190612cef565b62ffffff16905060006127106122358388612c10565b61223f9190612bad565b9050600061224d8288612bfd565b9050811561226057612260893084612411565b83156122705761227060006116a3565b61227b898983612411565b6122848961253b565b61228d8861253b565b851580156122a1575061229f8861259e565b155b156122af576122af8861260c565b6122b88861265a565b612303576013546122c889610e5e565b11156123035760405162461bcd60e51b815260206004820152600a602482015269085b585e15d85b1b195d60b21b6044820152606401610ade565b505050505050505050565b6000610d93836001600160a01b0384166126da565b60006001600160a01b03821615806123435750306001600160a01b038316145b8061237c57506000826001600160a01b03163b11801561237c57506001600160a01b0382166000908152600c602052604090205460ff16155b8061238b575061238b826117dd565b80610ca85750506001600160a01b031661dead1490565b60008260000182815481106123b9576123b9612c66565b9060005260206000200154905092915050565b6060610d93838360006127d4565b6000306001600160a01b0383161480610ca85750506001600160a01b0316737a250d5630b4cf539739df2c5dacb4c659f2488d1490565b6001600160a01b03831661243c5780600360008282546124319190612b77565b909155506124ae9050565b6001600160a01b0383166000908152600160205260409020548181101561248f5760405163391434e360e21b81526001600160a01b03851660048201526024810182905260448101839052606401610ade565b6001600160a01b03841660009081526001602052604090209082900390555b6001600160a01b0382166124ca576003805482900390556124e9565b6001600160a01b03821660009081526001602052604090208054820190555b816001600160a01b0316836001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8360405161252e91815260200190565b60405180910390a3505050565b61254481612323565b1561254c5750565b600061255782610e5e565b6001600160a01b038316600090815260086020526040902080546007549293509091839161258491612bfd565b61258e9190612b77565b60075561259a81611873565b5550565b6000306001600160a01b03831614806125d35750737a250d5630b4cf539739df2c5dacb4c659f2488d6001600160a01b038316145b80610ca85750507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0390811691161490565b61261581611d00565b612620601182612867565b506040516001600160a01b03821681527f6b713f4f12b0a0860e4b6b54d27ef8de95da632b1250f5c12f8254fdedbc2ebd90602001611ab4565b6000306001600160a01b038316148061268f5750737a250d5630b4cf539739df2c5dacb4c659f2488d6001600160a01b038316145b806126cb5750816001600160a01b03167f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316145b80610ca85750610ca8826117dd565b600081815260018301602052604081205480156127c35760006126fe600183612bfd565b855490915060009061271290600190612bfd565b905080821461277757600086600001828154811061273257612732612c66565b906000526020600020015490508087600001848154811061275557612755612c66565b6000918252602080832090910192909255918252600188019052604090208390555b855486908061278857612788612d0b565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610ca8565b6000915050610ca8565b5092915050565b6060814710156127f95760405163cd78605960e01b8152306004820152602401610ade565b600080856001600160a01b031684866040516128159190612d21565b60006040518083038185875af1925050503d8060008114612852576040519150601f19603f3d011682016040523d82523d6000602084013e612857565b606091505b5091509150611f8d86838361287c565b6000610d93836001600160a01b0384166128d8565b6060826128915761288c82612927565b610d93565b81511580156128a857506001600160a01b0384163b155b156128d157604051639996b31560e01b81526001600160a01b0385166004820152602401610ade565b5080610d93565b600081815260018301602052604081205461291f57508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610ca8565b506000610ca8565b8051156129375780518082602001fd5b604051630a12f52160e11b815260040160405180910390fd5b6001600160a01b0381168114610d7157600080fd5b60006020828403121561297757600080fd5b8135610d9381612950565b60005b8381101561299d578181015183820152602001612985565b50506000910152565b60208152600082518060208401526129c5816040850160208701612982565b601f01601f19169190910160400192915050565b600080604083850312156129ec57600080fd5b82356129f781612950565b946020939093013593505050565b600080600060608486031215612a1a57600080fd5b8335612a2581612950565b92506020840135612a3581612950565b929592945050506040919091013590565b600060208284031215612a5857600080fd5b5035919050565b803562ffffff81168114612a7257600080fd5b919050565b600060208284031215612a8957600080fd5b610d9382612a5f565b600080600060608486031215612aa757600080fd5b612ab084612a5f565b9250612abe60208501612a5f565b9150612acc60408501612a5f565b90509250925092565b60008060408385031215612ae857600080fd5b8235612af381612950565b91506020830135612b0381612950565b809150509250929050565b600060208284031215612b2057600080fd5b5051919050565b600181811c90821680612b3b57607f821691505b602082108103612b5b57634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052601160045260246000fd5b80820180821115610ca857610ca8612b61565b60208082526009908201526810b7b832b930ba37b960b91b604082015260600190565b600082612bca57634e487b7160e01b600052601260045260246000fd5b500490565b600080600060608486031215612be457600080fd5b8351925060208401519150604084015190509250925092565b81810381811115610ca857610ca8612b61565b8082028115828204841417610ca857610ca8612b61565b600060208284031215612c3957600080fd5b81518015158114610d9357600080fd5b600060208284031215612c5b57600080fd5b8151610d9381612950565b634e487b7160e01b600052603260045260246000fd5b600060a08201878352602087602085015260a0604085015281875180845260c08601915060208901935060005b81811015612cce5784516001600160a01b031683529383019391830191600101612ca9565b50506001600160a01b03969096166060850152505050608001529392505050565b62ffffff8181168382160190808211156127cd576127cd612b61565b634e487b7160e01b600052603160045260246000fd5b60008251612d33818460208701612982565b919091019291505056fea26469706673582212207a7a5a501753de715e3980387dd811393caf84f2158a1d2aea9f477f2bb162a464736f6c634300081700330000000000000000000000007a250d5630b4cf539739df2c5dacb4c659f2488d
Deployed Bytecode
0x6080604052600436106103905760003560e01c806373dd250c116101dc578063c31c9c0711610102578063e7e3a24d116100a0578063f887ea401161006f578063f887ea4014610a29578063f8b45b0514610a51578063fabb0b4f14610a67578063fe575a8714610a8157600080fd5b8063e7e3a24d1461099c578063e7e82b69146109b1578063f2fde38b146109e1578063f7c618c114610a0157600080fd5b8063d7406965116100dc578063d740696514610901578063dbfa0bb514610921578063dc07b61714610941578063dd62ed3e1461095657600080fd5b8063c31c9c07146108a4578063c38ed941146108cc578063cebd7ae8146108ec57600080fd5b80639358928b1161017a578063aa5c3ab411610149578063aa5c3ab41461083a578063afb62e561461084f578063b3ab15fb14610864578063b78b52df1461088457600080fd5b80639358928b146107bc57806395d89b41146107d1578063a8aa1b31146107e6578063a9059cbb1461081a57600080fd5b80638da5cb5b116101b65780638da5cb5b14610754578063909921c71461077257806391c05b0b146107875780639266cc2a146107a757600080fd5b806373dd250c1461070c57806379cc67901461072c5780638129fc1c1461074c57600080fd5b80633a98ef39116102c1578063570ca7351161025f5780636b67c4df1161022e5780636b67c4df1461069e5780636f83f6a2146106c157806370a08231146106d7578063715018a6146106f757600080fd5b8063570ca7351461061057806359303a1114610648578063593557361461066857806366edecce1461068857600080fd5b806348cd4cb11161029b57806348cd4cb1146105ae578063537df3b6146105c45780635428c9cb146105e4578063554c798a146105fa57600080fd5b80633a98ef391461055457806342966c681461056a578063470624021461058a57600080fd5b80631e83409a1161032e5780632b14ca56116103085780632b14ca56146104d957806330188ee8146104fc578063313ce5671461051257806331d7a2621461053457600080fd5b80631e83409a146104835780632251c730146104a357806323b872dd146104b957600080fd5b806309094d661161036a57806309094d661461041e578063095ea7b314610434578063180b0d7e1461041e57806318160ddd1461046457600080fd5b806301681a621461039c57806306fdde03146103be578063089fe6aa146103e957600080fd5b3661039757005b600080fd5b3480156103a857600080fd5b506103bc6103b7366004612965565b610aa1565b005b3480156103ca57600080fd5b506103d3610c02565b6040516103e091906129a6565b60405180910390f35b3480156103f557600080fd5b5060155461040a90610100900462ffffff1681565b60405162ffffff90911681526020016103e0565b34801561042a57600080fd5b5061040a61271081565b34801561044057600080fd5b5061045461044f3660046129d9565b610c94565b60405190151581526020016103e0565b34801561047057600080fd5b506003545b6040519081526020016103e0565b34801561048f57600080fd5b506103bc61049e366004612965565b610cae565b3480156104af57600080fd5b50610475600f5481565b3480156104c557600080fd5b506104546104d4366004612a05565b610d74565b3480156104e557600080fd5b5060155461040a90600160381b900462ffffff1681565b34801561050857600080fd5b50610475600b5481565b34801561051e57600080fd5b5060125b60405160ff90911681526020016103e0565b34801561054057600080fd5b5061047561054f366004612965565b610d9a565b34801561056057600080fd5b5061047560075481565b34801561057657600080fd5b506103bc610585366004612a46565b610dde565b34801561059657600080fd5b5060155461040a90640100000000900462ffffff1681565b3480156105ba57600080fd5b5061047560145481565b3480156105d057600080fd5b506103bc6105df366004612965565b610de8565b3480156105f057600080fd5b50610475600e5481565b34801561060657600080fd5b50610475600d5481565b34801561061c57600080fd5b50601054610630906001600160a01b031681565b6040516001600160a01b0390911681526020016103e0565b34801561065457600080fd5b506103bc610663366004612a46565b610df9565b34801561067457600080fd5b50610475610683366004612965565b610e28565b34801561069457600080fd5b5061040a610bb881565b3480156106aa57600080fd5b5060155461040a90600160501b900462ffffff1681565b3480156106cd57600080fd5b50610475600a5481565b3480156106e357600080fd5b506104756106f2366004612965565b610e5e565b34801561070357600080fd5b506103bc610e9a565b34801561071857600080fd5b506103bc610727366004612a77565b610eae565b34801561073857600080fd5b506103bc6107473660046129d9565b610ef8565b6103bc610f11565b34801561076057600080fd5b506000546001600160a01b0316610630565b34801561077e57600080fd5b5061047561107b565b34801561079357600080fd5b506103bc6107a2366004612a46565b6110fb565b3480156107b357600080fd5b506103bc6111fc565b3480156107c857600080fd5b50610475611253565b3480156107dd57600080fd5b506103d36112c1565b3480156107f257600080fd5b506106307f0000000000000000000000009a633671df5f36506fc513064eda0cdf83cb0c1381565b34801561082657600080fd5b506104546108353660046129d9565b6112d0565b34801561084657600080fd5b506104756112de565b34801561085b57600080fd5b50610475611379565b34801561087057600080fd5b506103bc61087f366004612965565b61139a565b34801561089057600080fd5b506103bc61089f3660046129d9565b61142a565b3480156108b057600080fd5b5061063073e592427a0aece92de3edee1f18e0157c0586156481565b3480156108d857600080fd5b506103bc6108e7366004612a92565b6114e7565b3480156108f857600080fd5b506103bc611611565b34801561090d57600080fd5b506103bc61091c366004612a46565b611665565b34801561092d57600080fd5b506103bc61093c366004612a46565b6116a3565b34801561094d57600080fd5b506103bc61173f565b34801561096257600080fd5b50610475610971366004612ad5565b6001600160a01b03918216600090815260026020908152604080832093909416825291909152205490565b3480156109a857600080fd5b506103bc611771565b3480156109bd57600080fd5b506104546109cc366004612965565b600c6020526000908152604090205460ff1681565b3480156109ed57600080fd5b506103bc6109fc366004612965565b6117a2565b348015610a0d57600080fd5b50610630736de037ef9ad2725eb40118bb1702ebb27e4aeb2481565b348015610a3557600080fd5b50610630737a250d5630b4cf539739df2c5dacb4c659f2488d81565b348015610a5d57600080fd5b5061047560135481565b348015610a7357600080fd5b506015546105229060ff1681565b348015610a8d57600080fd5b50610454610a9c366004612965565b6117dd565b306001600160a01b03821603610ae75760405162461bcd60e51b815260206004820152600660248201526502173776565760d41b60448201526064015b60405180910390fd5b736de037ef9ad2725eb40118bb1702ebb27e4aeb23196001600160a01b03821601610b3d5760405162461bcd60e51b815260206004820152600660248201526502173776565760d41b6044820152606401610ade565b6040516370a0823160e01b81523060048201526000906001600160a01b038316906370a0823190602401602060405180830381865afa158015610b84573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ba89190612b0e565b9050610bbe6001600160a01b03831633836117ea565b6040518181526001600160a01b0383169033907fed679328aebf74ede77ae09efcf36e90244f83643dadac1c2d9f0b21a46f6ab79060200160405180910390a35050565b606060048054610c1190612b27565b80601f0160208091040260200160405190810160405280929190818152602001828054610c3d90612b27565b8015610c8a5780601f10610c5f57610100808354040283529160200191610c8a565b820191906000526020600020905b815481529060010190602001808311610c6d57829003601f168201915b5050505050905090565b600033610ca281858561183c565b60019150505b92915050565b610cb6611849565b336000908152600860205260409020610cce81611873565b60018101546000819003610ce3575050610d67565b6000826001018190555080600a6000828254610cff9190612b77565b90915550610d249050736de037ef9ad2725eb40118bb1702ebb27e4aeb2484836117ea565b6040518181526001600160a01b0384169033907f70eb43c4a8ae8c40502dcf22436c509c28d6ff421cf07c491be56984bd9870689060200160405180910390a350505b610d716001600655565b50565b600033610d828582856118b4565b610d8d85858561192c565b60019150505b9392505050565b6001600160a01b03811660009081526008602090815260408083208151606081018352815481526001820154938101939093526002015490820152610ca89061198b565b610d713382611a07565b610df0611a3d565b610d7181611a6a565b6010546001600160a01b03163314610e235760405162461bcd60e51b8152600401610ade90612b8a565b600d55565b6000610e33826117dd565b15610e56576001600160a01b038216600090815260016020526040902054610ca8565b506000919050565b6000610e69826117dd565b1580610e335750610e78611abf565b610e56576001600160a01b038216600090815260016020526040902054610ca8565b610ea2611a3d565b610eac6000611ade565b565b6010546001600160a01b03163314610ed85760405162461bcd60e51b8152600401610ade90612b8a565b6015805462ffffff9092166101000263ffffff0019909216919091179055565b610f038233836118b4565b610f0d8282611a07565b5050565b610f19611a3d565b60003411610f565760405162461bcd60e51b815260206004820152600a602482015269216c697175696469747960b01b6044820152606401610ade565b60145415610f955760405162461bcd60e51b815260206004820152600c60248201526b085a5b9a5d1a585b1a5e995960a21b6044820152606401610ade565b436014556064610fa460035490565b610fae9190612bad565b6013556000610fbc30610e5e565b9050610fdd30737a250d5630b4cf539739df2c5dacb4c659f2488d8361183c565b60405163f305d71960e01b81523060048201526024810182905260006044820181905260648201523360848201524260a4820152737a250d5630b4cf539739df2c5dacb4c659f2488d9063f305d71990349060c40160606040518083038185885af1158015611050573d6000803e3d6000fd5b50505050506040513d601f19601f820116820180604052508101906110759190612bcf565b50505050565b6000600f5460000361108d5750600090565b600d5460000361109d5750600090565b60006110a76112de565b9050806000036110b957600091505090565b6000600f54436110c99190612bfd565b600d546110d69190612c10565b600e546110e39190612b77565b90508181106110f257816110f4565b805b9250505090565b6007546000036111085750565b600061111261107b565b905047801561113357611126308285611b2e565b6111309083612b77565b91505b8160000361114057505050565b600754670de0b6b3a76400006111767f000000000000000000000000000000000000000000000000000000000000000185612c10565b6111809190612c10565b61118a9190612bad565b6009600082825461119b9190612b77565b9250508190555081600b60008282546111b49190612b77565b90915550506000600e5543600f5560405182815233907fc1d32ad5cca423e7dda2123dbf8c482f8e77d00b631c06e903a47f2cec1334df9060200160405180910390a2505050565b61120533611d00565b336000818152600c6020908152604091829020805460ff1916905590519182527f9d987f025241c15852f6fdf907bfad8c5c84f316a13b8855ba5185bf79a3f7bb91015b60405180910390a1565b60008060006112626011611d68565b905060005b818110156112ac5761129861127d601183611d72565b6001600160a01b031660009081526001602052604090205490565b6112a29084612b77565b9250600101611267565b50816112b760035490565b6110f49190612bfd565b606060058054610c1190612b27565b600033610ca281858561192c565b600080600a54600b546112f19190612bfd565b6040516370a0823160e01b81523060048201529091508190736de037ef9ad2725eb40118bb1702ebb27e4aeb24906370a0823190602401602060405180830381865afa158015611345573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113699190612b0e565b6113739190612bfd565b91505090565b600061138361107b565b61138b6112de565b6113959190612bfd565b905090565b6010546001600160a01b031633146113c45760405162461bcd60e51b8152600401610ade90612b8a565b6001600160a01b0381166000036114085760405162461bcd60e51b8152602060048201526008602482015267216164647265737360c01b6044820152606401610ade565b601080546001600160a01b0319166001600160a01b0392909216919091179055565b611432611a3d565b601454156114715760405162461bcd60e51b815260206004820152600c60248201526b085a5b9a5d1a585b1a5e995960a21b6044820152606401610ade565b60405163a9059cbb60e01b81526001600160a01b038316600482015260248101829052309063a9059cbb906044016020604051808303816000875af11580156114be573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114e29190612c27565b505050565b6114ef611a3d565b610bb862ffffff841611156115305760405162461bcd60e51b81526020600482015260076024820152662162757946656560c81b6044820152606401610ade565b610bb862ffffff831611156115725760405162461bcd60e51b81526020600482015260086024820152672173656c6c46656560c01b6044820152606401610ade565b61271062ffffff821611156115b95760405162461bcd60e51b815260206004820152600d60248201526c216d61726b6574696e6746656560981b6044820152606401610ade565b6015805469ffffffffffff00000000191664010000000062ffffff9586160269ffffff00000000000000191617600160381b938516939093029290921762ffffff60501b1916600160501b9190931602919091179055565b61161a33611d7e565b336000818152600c6020908152604091829020805460ff1916600117905590519182527f6d2f2ea0335c8c0e296412085b47e0ed0c1b67b6bde3f5739e7739ca804a75b19101611249565b6010546001600160a01b0316331461168f5760405162461bcd60e51b8152600401610ade90612b8a565b61169761107b565b600e55600d5543600f55565b60006116ae30610e5e565b9050806000036116bc575050565b60006116c9308385611de7565b601554909150600090612710906116ec90600160501b900462ffffff1684612c10565b6116f69190612bad565b90508015611075576010546040516001600160a01b039091169082156108fc029083906000818181858888f19350505050158015611738573d6000803e3d6000fd5b5050505050565b6010546001600160a01b031633146117695760405162461bcd60e51b8152600401610ade90612b8a565b600019601355565b6010546001600160a01b0316331461179b5760405162461bcd60e51b8152600401610ade90612b8a565b6000600e55565b6117aa611a3d565b6001600160a01b0381166117d457604051631e4fbdf760e01b815260006004820152602401610ade565b610d7181611ade565b6000610ca8601183611f97565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b1790526114e2908490611fb9565b6114e2838383600161201c565b60026006540361186c57604051633ee5aeb560e01b815260040160405180910390fd5b6002600655565b6040805160608101825282548152600183015460208201526002830154918101919091526000906118a39061198b565b600183015550600954600290910155565b6001600160a01b038381166000908152600260209081526040808320938616835292905220546000198114611075578181101561191d57604051637dc7a0d960e11b81526001600160a01b03841660048201526024810182905260448101839052606401610ade565b6110758484848403600061201c565b6001600160a01b03831661195657604051634b637e8f60e11b815260006004820152602401610ade565b6001600160a01b0382166119805760405163ec442f0560e01b815260006004820152602401610ade565b6114e28383836120f1565b60008082604001516009546119a09190612bfd565b905060006119d6670de0b6b3a76400007f0000000000000000000000000000000000000000000000000000000000000001612c10565b84516119e3908490612c10565b6119ed9190612bad565b90508084602001516119ff9190612b77565b949350505050565b6001600160a01b038216611a3157604051634b637e8f60e11b815260006004820152602401610ade565b610f0d826000836120f1565b6000546001600160a01b03163314610eac5760405163118cdaa760e01b8152336004820152602401610ade565b611a7381611d7e565b611a7e60118261230e565b506040516001600160a01b03821681527f3afada3900b4909463d8a846fbdc12d6b5c4e8030bd6bc1215822ecee62357ba906020015b60405180910390a150565b601554601454600091611ad79160ff90911690612b77565b4311905090565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b600082600003611b4057506000610d93565b6000604051806101000160405280737a250d5630b4cf539739df2c5dacb4c659f2488d6001600160a01b031663ad5c46486040518163ffffffff1660e01b8152600401602060405180830381865afa158015611ba0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611bc49190612c49565b6001600160a01b039081168252736de037ef9ad2725eb40118bb1702ebb27e4aeb24602080840191909152601554610100900462ffffff9081166040808601919091528a84166060808701919091524260808088019190915260a08088018d905260c08089018d9052600060e0998a0152845163414bf38960e01b81528a5189166004820152968a015188166024880152938901519094166044860152908701518516606485015286015160848401529085015160a483015284015160c4820152918301511660e482015290915073e592427a0aece92de3edee1f18e0157c058615649063414bf3899086906101040160206040518083038185885af1158015611cd2573d6000803e3d6000fd5b50505050506040513d601f19601f82011682018060405250810190611cf79190612b0e565b95945050505050565b611d0981612323565b15611d115750565b6001600160a01b03811660009081526001602052604090205460076000828254611d3b9190612bfd565b90915550506001600160a01b0381166000908152600860205260409020611d6181611873565b6000905550565b6000610ca8825490565b6000610d9383836123a2565b611d8781612323565b611d8e5750565b6001600160a01b03811660009081526001602052604081205490508060076000828254611dbb9190612b77565b90915550506001600160a01b039091166000908152600860205260409020908155600954600290910155565b600082600003611df957506000610d93565b611e1830737a250d5630b4cf539739df2c5dacb4c659f2488d8561183c565b6040805160028082526060820183526000926020830190803683370190505090503081600081518110611e4d57611e4d612c66565b60200260200101906001600160a01b031690816001600160a01b031681525050737a250d5630b4cf539739df2c5dacb4c659f2488d6001600160a01b031663ad5c46486040518163ffffffff1660e01b8152600401602060405180830381865afa158015611ebf573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ee39190612c49565b81600181518110611ef657611ef6612c66565b6001600160a01b039092166020928302919091019091015260405163791ac94760e01b81524790737a250d5630b4cf539739df2c5dacb4c659f2488d9063791ac94790611f4f908890889087908c904290600401612c7c565b600060405180830381600087803b158015611f6957600080fd5b505af1158015611f7d573d6000803e3d6000fd5b505050508047611f8d9190612bfd565b9695505050505050565b6001600160a01b03811660009081526001830160205260408120541515610d93565b6000611fce6001600160a01b038416836123cc565b90508051600014158015611ff3575080806020019051810190611ff19190612c27565b155b156114e257604051635274afe760e01b81526001600160a01b0384166004820152602401610ade565b6001600160a01b0384166120465760405163e602df0560e01b815260006004820152602401610ade565b6001600160a01b03831661207057604051634a1406b160e11b815260006004820152602401610ade565b6001600160a01b038085166000908152600260209081526040808320938716835292905220829055801561107557826001600160a01b0316846001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925846040516120e391815260200190565b60405180910390a350505050565b60006120fb611abf565b90506000846001600160a01b03167f0000000000000000000000009a633671df5f36506fc513064eda0cdf83cb0c136001600160a01b03161480156121465750612144846123da565b155b90506000612153866123da565b1580156121915750846001600160a01b03167f0000000000000000000000009a633671df5f36506fc513064eda0cdf83cb0c136001600160a01b0316145b90508280156121a457506121a4866117dd565b156121da5760405162461bcd60e51b81526020600482015260066024820152651b1bd8dad95960d21b6044820152606401610ade565b6000816121e85760006121f8565b601554600160381b900462ffffff165b83612204576000612215565b601554640100000000900462ffffff165b61221f9190612cef565b62ffffff16905060006127106122358388612c10565b61223f9190612bad565b9050600061224d8288612bfd565b9050811561226057612260893084612411565b83156122705761227060006116a3565b61227b898983612411565b6122848961253b565b61228d8861253b565b851580156122a1575061229f8861259e565b155b156122af576122af8861260c565b6122b88861265a565b612303576013546122c889610e5e565b11156123035760405162461bcd60e51b815260206004820152600a602482015269085b585e15d85b1b195d60b21b6044820152606401610ade565b505050505050505050565b6000610d93836001600160a01b0384166126da565b60006001600160a01b03821615806123435750306001600160a01b038316145b8061237c57506000826001600160a01b03163b11801561237c57506001600160a01b0382166000908152600c602052604090205460ff16155b8061238b575061238b826117dd565b80610ca85750506001600160a01b031661dead1490565b60008260000182815481106123b9576123b9612c66565b9060005260206000200154905092915050565b6060610d93838360006127d4565b6000306001600160a01b0383161480610ca85750506001600160a01b0316737a250d5630b4cf539739df2c5dacb4c659f2488d1490565b6001600160a01b03831661243c5780600360008282546124319190612b77565b909155506124ae9050565b6001600160a01b0383166000908152600160205260409020548181101561248f5760405163391434e360e21b81526001600160a01b03851660048201526024810182905260448101839052606401610ade565b6001600160a01b03841660009081526001602052604090209082900390555b6001600160a01b0382166124ca576003805482900390556124e9565b6001600160a01b03821660009081526001602052604090208054820190555b816001600160a01b0316836001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8360405161252e91815260200190565b60405180910390a3505050565b61254481612323565b1561254c5750565b600061255782610e5e565b6001600160a01b038316600090815260086020526040902080546007549293509091839161258491612bfd565b61258e9190612b77565b60075561259a81611873565b5550565b6000306001600160a01b03831614806125d35750737a250d5630b4cf539739df2c5dacb4c659f2488d6001600160a01b038316145b80610ca85750507f0000000000000000000000009a633671df5f36506fc513064eda0cdf83cb0c136001600160a01b0390811691161490565b61261581611d00565b612620601182612867565b506040516001600160a01b03821681527f6b713f4f12b0a0860e4b6b54d27ef8de95da632b1250f5c12f8254fdedbc2ebd90602001611ab4565b6000306001600160a01b038316148061268f5750737a250d5630b4cf539739df2c5dacb4c659f2488d6001600160a01b038316145b806126cb5750816001600160a01b03167f0000000000000000000000009a633671df5f36506fc513064eda0cdf83cb0c136001600160a01b0316145b80610ca85750610ca8826117dd565b600081815260018301602052604081205480156127c35760006126fe600183612bfd565b855490915060009061271290600190612bfd565b905080821461277757600086600001828154811061273257612732612c66565b906000526020600020015490508087600001848154811061275557612755612c66565b6000918252602080832090910192909255918252600188019052604090208390555b855486908061278857612788612d0b565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610ca8565b6000915050610ca8565b5092915050565b6060814710156127f95760405163cd78605960e01b8152306004820152602401610ade565b600080856001600160a01b031684866040516128159190612d21565b60006040518083038185875af1925050503d8060008114612852576040519150601f19603f3d011682016040523d82523d6000602084013e612857565b606091505b5091509150611f8d86838361287c565b6000610d93836001600160a01b0384166128d8565b6060826128915761288c82612927565b610d93565b81511580156128a857506001600160a01b0384163b155b156128d157604051639996b31560e01b81526001600160a01b0385166004820152602401610ade565b5080610d93565b600081815260018301602052604081205461291f57508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610ca8565b506000610ca8565b8051156129375780518082602001fd5b604051630a12f52160e11b815260040160405180910390fd5b6001600160a01b0381168114610d7157600080fd5b60006020828403121561297757600080fd5b8135610d9381612950565b60005b8381101561299d578181015183820152602001612985565b50506000910152565b60208152600082518060208401526129c5816040850160208701612982565b601f01601f19169190910160400192915050565b600080604083850312156129ec57600080fd5b82356129f781612950565b946020939093013593505050565b600080600060608486031215612a1a57600080fd5b8335612a2581612950565b92506020840135612a3581612950565b929592945050506040919091013590565b600060208284031215612a5857600080fd5b5035919050565b803562ffffff81168114612a7257600080fd5b919050565b600060208284031215612a8957600080fd5b610d9382612a5f565b600080600060608486031215612aa757600080fd5b612ab084612a5f565b9250612abe60208501612a5f565b9150612acc60408501612a5f565b90509250925092565b60008060408385031215612ae857600080fd5b8235612af381612950565b91506020830135612b0381612950565b809150509250929050565b600060208284031215612b2057600080fd5b5051919050565b600181811c90821680612b3b57607f821691505b602082108103612b5b57634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052601160045260246000fd5b80820180821115610ca857610ca8612b61565b60208082526009908201526810b7b832b930ba37b960b91b604082015260600190565b600082612bca57634e487b7160e01b600052601260045260246000fd5b500490565b600080600060608486031215612be457600080fd5b8351925060208401519150604084015190509250925092565b81810381811115610ca857610ca8612b61565b8082028115828204841417610ca857610ca8612b61565b600060208284031215612c3957600080fd5b81518015158114610d9357600080fd5b600060208284031215612c5b57600080fd5b8151610d9381612950565b634e487b7160e01b600052603260045260246000fd5b600060a08201878352602087602085015260a0604085015281875180845260c08601915060208901935060005b81811015612cce5784516001600160a01b031683529383019391830191600101612ca9565b50506001600160a01b03969096166060850152505050608001529392505050565b62ffffff8181168382160190808211156127cd576127cd612b61565b634e487b7160e01b600052603160045260246000fd5b60008251612d33818460208701612982565b919091019291505056fea26469706673582212207a7a5a501753de715e3980387dd811393caf84f2158a1d2aea9f477f2bb162a464736f6c63430008170033
Deployed Bytecode Sourcemap
97130:95:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;83706:375;;;;;;;;;;-1:-1:-1;83706:375:0;;;;;:::i;:::-;;:::i;:::-;;15879:91;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;74930:29;;;;;;;;;;-1:-1:-1;74930:29:0;;;;;;;;;;;;;;1262:8:1;1250:21;;;1232:40;;1220:2;1205:18;74930:29:0;1088:190:1;75213:46:0;;;;;;;;;;;;75254:5;75213:46;;18172:190;;;;;;;;;;-1:-1:-1;18172:190:0;;;;;:::i;:::-;;:::i;:::-;;;1776:14:1;;1769:22;1751:41;;1739:2;1724:18;18172:190:0;1611:187:1;16981:99:0;;;;;;;;;;-1:-1:-1;17060:12:0;;16981:99;;;1949:25:1;;;1937:2;1922:18;16981:99:0;1803:177:1;80933:418:0;;;;;;;;;;-1:-1:-1;80933:418:0;;;;;:::i;:::-;;:::i;73661:32::-;;;;;;;;;;;;;;;;18940:249;;;;;;;;;;-1:-1:-1;18940:249:0;;;;;:::i;:::-;;:::i;75354:28::-;;;;;;;;;;-1:-1:-1;75354:28:0;;;;-1:-1:-1;;;75354:28:0;;;;;;73054:37;;;;;;;;;;;;;;;;16832:84;;;;;;;;;;-1:-1:-1;16906:2:0;16832:84;;;2894:4:1;2882:17;;;2864:36;;2852:2;2837:18;16832:84:0;2722:184:1;80518:131:0;;;;;;;;;;-1:-1:-1;80518:131:0;;;;;:::i;:::-;;:::i;72600:26::-;;;;;;;;;;;;;;;;41720:89;;;;;;;;;;-1:-1:-1;41720:89:0;;;;;:::i;:::-;;:::i;75320:27::-;;;;;;;;;;-1:-1:-1;75320:27:0;;;;;;;;;;;74670:29;;;;;;;;;;;;;;;;85031:107;;;;;;;;;;-1:-1:-1;85031:107:0;;;;;:::i;:::-;;:::i;73567:34::-;;;;;;;;;;;;;;;;73449;;;;;;;;;;;;;;;;74309:23;;;;;;;;;;-1:-1:-1;74309:23:0;;;;-1:-1:-1;;;;;74309:23:0;;;;;;-1:-1:-1;;;;;3260:32:1;;;3242:51;;3230:2;3215:18;74309:23:0;3096:203:1;87387:151:0;;;;;;;;;;-1:-1:-1;87387:151:0;;;;;:::i;:::-;;:::i;78880:197::-;;;;;;;;;;-1:-1:-1;78880:197:0;;;;;:::i;:::-;;:::i;75166:40::-;;;;;;;;;;;;75202:4;75166:40;;75389:34;;;;;;;;;;-1:-1:-1;75389:34:0;;;;-1:-1:-1;;;75389:34:0;;;;;;72956:33;;;;;;;;;;;;;;;;78525:225;;;;;;;;;;-1:-1:-1;78525:225:0;;;;;:::i;:::-;;:::i;3151:103::-;;;;;;;;;;;;;:::i;86757:96::-;;;;;;;;;;-1:-1:-1;86757:96:0;;;;;:::i;:::-;;:::i;42138:161::-;;;;;;;;;;-1:-1:-1;42138:161:0;;;;;:::i;:::-;;:::i;85416:690::-;;;:::i;2476:87::-;;;;;;;;;;-1:-1:-1;2522:7:0;2549:6;-1:-1:-1;;;;;2549:6:0;2476:87;;80014:413;;;;;;;;;;;;;:::i;82679:937::-;;;;;;;;;;-1:-1:-1;82679:937:0;;;;;:::i;:::-;;:::i;81704:158::-;;;;;;;;;;;;;:::i;78071:316::-;;;;;;;;;;;;;:::i;16089:95::-;;;;;;;;;;;;;:::i;71755:36::-;;;;;;;;;;;;;;;17466:182;;;;;;;;;;-1:-1:-1;17466:182:0;;;;;:::i;:::-;;:::i;79458:213::-;;;;;;;;;;;;;:::i;79142:118::-;;;;;;;;;;;;;:::i;86370:156::-;;;;;;;;;;-1:-1:-1;86370:156:0;;;;;:::i;:::-;;:::i;84372:162::-;;;;;;;;;;-1:-1:-1;84372:162:0;;;;;:::i;:::-;;:::i;71286:96::-;;;;;;;;;;;;71339:42;71286:96;;84582:370;;;;;;;;;;-1:-1:-1;84582:370:0;;;;;:::i;:::-;;:::i;81451:154::-;;;;;;;;;;;;;:::i;87003:237::-;;;;;;;;;;-1:-1:-1;87003:237:0;;;;;:::i;:::-;;:::i;82002:543::-;;;;;;;;;;-1:-1:-1;82002:543:0;;;;;:::i;:::-;;:::i;86597:97::-;;;;;;;;;;;;;:::i;17711:142::-;;;;;;;;;;-1:-1:-1;17711:142:0;;;;;:::i;:::-;-1:-1:-1;;;;;17818:18:0;;;17791:7;17818:18;;;:11;:18;;;;;;;;:27;;;;;;;;;;;;;17711:142;87626:101;;;;;;;;;;;;;:::i;73154:39::-;;;;;;;;;;-1:-1:-1;73154:39:0;;;;;:::i;:::-;;;;;;;;;;;;;;;;3409:220;;;;;;;;;;-1:-1:-1;3409:220:0;;;;;:::i;:::-;;:::i;71502:103::-;;;;;;;;;;;;71562:42;71502:103;;71389:106;;;;;;;;;;;;71452:42;71389:106;;74592:44;;;;;;;;;;;;;;;;74706:27;;;;;;;;;;-1:-1:-1;74706:27:0;;;;;;;;77725:114;;;;;;;;;;-1:-1:-1;77725:114:0;;;;;:::i;:::-;;:::i;83706:375::-;83799:4;-1:-1:-1;;;;;83768:36:0;;;83760:55;;;;-1:-1:-1;;;83760:55:0;;5527:2:1;83760:55:0;;;5509:21:1;5566:1;5546:18;;;5539:29;-1:-1:-1;;;5584:18:1;;;5577:36;5630:18;;83760:55:0;;;;;;;;;-1:-1:-1;;;;;;;83834:43:0;;;83826:62;;;;-1:-1:-1;;;83826:62:0;;5527:2:1;83826:62:0;;;5509:21:1;5566:1;5546:18;;;5539:29;-1:-1:-1;;;5584:18:1;;;5577:36;5630:18;;83826:62:0;5325:329:1;83826:62:0;83918:35;;-1:-1:-1;;;83918:35:0;;83947:4;83918:35;;;3242:51:1;83901:14:0;;-1:-1:-1;;;;;83918:20:0;;;;;3215:18:1;;83918:35:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;83901:52;-1:-1:-1;83966:43:0;-1:-1:-1;;;;;83966:23:0;;83990:10;83901:52;83966:23;:43::i;:::-;84027:46;;1949:25:1;;;-1:-1:-1;;;;;84027:46:0;;;84033:10;;84027:46;;1937:2:1;1922:18;84027:46:0;;;;;;;83749:332;83706:375;:::o;15879:91::-;15924:13;15957:5;15950:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;15879:91;:::o;18172:190::-;18245:4;831:10;18301:31;831:10;18317:7;18326:5;18301:8;:31::i;:::-;18350:4;18343:11;;;18172:190;;;;;:::o;80933:418::-;44656:21;:19;:21::i;:::-;81028:10:::1;80993:19;81015:24:::0;;;:12:::1;:24;::::0;;;;81052:12:::1;81015:24:::0;81052:5:::1;:12::i;:::-;81101;::::0;::::1;::::0;81077:21:::1;81130:18:::0;;;81126:31:::1;;81150:7;;;;81126:31;81184:1;81169:5;:12;;:16;;;;81220:13;81198:18;;:35;;;;;;;:::i;:::-;::::0;;;-1:-1:-1;81246:43:0::1;::::0;-1:-1:-1;71562:42:0::1;81271:2:::0;81275:13;81246:24:::1;:43::i;:::-;81307:36;::::0;1949:25:1;;;-1:-1:-1;;;;;81307:36:0;::::1;::::0;81313:10:::1;::::0;81307:36:::1;::::0;1937:2:1;1922:18;81307:36:0::1;;;;;;;80982:369;;44688:1;44700:20:::0;43991:1;45242:7;:21;45059:212;44700:20;80933:418;:::o;18940:249::-;19027:4;831:10;19085:37;19101:4;831:10;19116:5;19085:15;:37::i;:::-;19133:26;19143:4;19149:2;19153:5;19133:9;:26::i;:::-;19177:4;19170:11;;;18940:249;;;;;;:::o;80518:131::-;-1:-1:-1;;;;;80622:18:0;;80579:7;80622:18;;;:12;:18;;;;;;;;80606:35;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:15;:35::i;41720:89::-;41775:26;831:10;41795:5;41775;:26::i;85031:107::-;2362:13;:11;:13::i;:::-;85104:26:::1;85125:4;85104:20;:26::i;87387:151::-:0;76226:8;;-1:-1:-1;;;;;76226:8:0;76212:10;:22;76204:44;;;;-1:-1:-1;;;76204:44:0;;;;;;;:::i;:::-;87488:19:::1;:42:::0;87387:151::o;78880:197::-;78943:7;78967:22;78981:7;78967:13;:22::i;:::-;78963:86;;;-1:-1:-1;;;;;17235:18:0;;17208:7;17235:18;;;:9;:18;;;;;;79013:24;17143:118;78963:86;-1:-1:-1;79068:1:0;;78880:197;-1:-1:-1;78880:197:0:o;78525:225::-;78591:7;78616:22;78630:7;78616:13;:22::i;:::-;78615:23;:47;;;;78643:19;:17;:19::i;:::-;78611:111;;-1:-1:-1;;;;;17235:18:0;;17208:7;17235:18;;;:9;:18;;;;;;78686:24;17143:118;3151:103;2362:13;:11;:13::i;:::-;3216:30:::1;3243:1;3216:18;:30::i;:::-;3151:103::o:0;86757:96::-;76226:8;;-1:-1:-1;;;;;76226:8:0;76212:10;:22;76204:44;;;;-1:-1:-1;;;76204:44:0;;;;;;;:::i;:::-;86827:7:::1;:18:::0;;::::1;::::0;;::::1;;;-1:-1:-1::0;;86827:18:0;;::::1;::::0;;;::::1;::::0;;86757:96::o;42138:161::-;42214:45;42230:7;831:10;42253:5;42214:15;:45::i;:::-;42270:21;42276:7;42285:5;42270;:21::i;:::-;42138:161;;:::o;85416:690::-;2362:13;:11;:13::i;:::-;85496:1:::1;85484:9;:13;85476:36;;;::::0;-1:-1:-1;;;85476:36:0;;7034:2:1;85476:36:0::1;::::0;::::1;7016:21:1::0;7073:2;7053:18;;;7046:30;-1:-1:-1;;;7092:18:1;;;7085:40;7142:18;;85476:36:0::1;6832:334:1::0;85476:36:0::1;85531:10;::::0;:15;85523:40:::1;;;::::0;-1:-1:-1;;;85523:40:0;;7373:2:1;85523:40:0::1;::::0;::::1;7355:21:1::0;7412:2;7392:18;;;7385:30;-1:-1:-1;;;7431:18:1;;;7424:42;7483:18;;85523:40:0::1;7171:336:1::0;85523:40:0::1;85630:12;85617:10;:25:::0;85718:3:::1;85702:13;17060:12:::0;;;16981:99;85702:13:::1;:19;;;;:::i;:::-;85690:9;:31:::0;85785:15:::1;85803:24;85821:4;85803:9;:24::i;:::-;85785:42;;85889:49;85906:4;71452:42;85930:7;85889:8;:49::i;:::-;85999:99;::::0;-1:-1:-1;;;85999:99:0;;86048:4:::1;85999:99;::::0;::::1;8075:34:1::0;8125:18;;;8118:34;;;86064:1:0::1;8168:18:1::0;;;8161:34;;;8211:18;;;8204:34;86070:10:0::1;8254:19:1::0;;;8247:44;86082:15:0::1;8307:19:1::0;;;8300:35;71452:42:0::1;::::0;85999:22:::1;::::0;86029:9:::1;::::0;8009:19:1;;85999:99:0::1;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;85465:641;85416:690::o:0;80014:413::-;80061:7;80085:17;;80106:1;80085:22;80081:36;;-1:-1:-1;80116:1:0;;80014:413::o;80081:36::-;80132:19;;80155:1;80132:24;80128:38;;-1:-1:-1;80165:1:0;;80014:413::o;80128:38::-;80179:15;80197;:13;:15::i;:::-;80179:33;;80229:7;80240:1;80229:12;80225:26;;80250:1;80243:8;;;80014:413;:::o;80225:26::-;80264:15;80343:17;;80328:12;:32;;;;:::i;:::-;80305:19;;:56;;;;:::i;:::-;80282:19;;:80;;;;:::i;:::-;80264:98;;80392:7;80382;:17;:37;;80412:7;80382:37;;;80402:7;80382:37;80375:44;;;;80014:413;:::o;82679:937::-;82747:11;;82762:1;82747:16;82743:29;;82679:937;:::o;82743:29::-;82855:26;82884:16;:14;:16::i;:::-;82855:45;-1:-1:-1;83013:21:0;83051:12;;83047:128;;83102:61;83129:4;83136:8;83146:16;83102:18;:61::i;:::-;83080:83;;;;:::i;:::-;;;83047:128;83225:18;83247:1;83225:23;83221:36;;83250:7;;82679:937;:::o;83221:36::-;83368:11;;72362:4;83319:33;83340:12;83319:18;:33;:::i;:::-;:45;;;;:::i;:::-;83318:61;;;;:::i;:::-;83301:13;;:78;;;;;;;:::i;:::-;;;;;;;;83416:18;83390:22;;:44;;;;;;;:::i;:::-;;;;-1:-1:-1;;83504:1:0;83482:19;:23;83536:12;83516:17;:32;83566:42;;1949:25:1;;;83577:10:0;;83566:42;;1937:2:1;1922:18;83566:42:0;;;;;;;82732:884;;82679:937;:::o;81704:158::-;81748:30;81767:10;81748:18;:30::i;:::-;81799:10;81813:5;81791:19;;;:7;:19;;;;;;;;;:27;;-1:-1:-1;;81791:27:0;;;81836:18;;3242:51:1;;;81836:18:0;;3215::1;81836::0;;;;;;;;81704:158::o;78071:316::-;78121:7;78141:20;78172:14;78189:18;:9;:16;:18::i;:::-;78172:35;;78225:9;78220:112;78244:6;78240:1;:10;78220:112;;;78288:32;78304:15;:9;78317:1;78304:12;:15::i;:::-;-1:-1:-1;;;;;17235:18:0;17208:7;17235:18;;;:9;:18;;;;;;;17143:118;78288:32;78272:48;;;;:::i;:::-;;-1:-1:-1;78252:3:0;;78220:112;;;;78367:12;78351:13;17060:12;;;16981:99;78351:13;:28;;;;:::i;16089:95::-;16136:13;16169:7;16162:14;;;;;:::i;17466:182::-;17535:4;831:10;17591:27;831:10;17608:2;17612:5;17591:9;:27::i;79458:213::-;79504:7;79524:21;79573:18;;79548:22;;:43;;;;:::i;:::-;79611:36;;-1:-1:-1;;;79611:36:0;;79641:4;79611:36;;;3242:51:1;79524:67:0;;-1:-1:-1;79524:67:0;;71562:42;;79611:21;;3215:18:1;;79611:36:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:52;;;;:::i;:::-;79604:59;;;79458:213;:::o;79142:118::-;79191:7;79236:16;:14;:16::i;:::-;79218:15;:13;:15::i;:::-;:34;;;;:::i;:::-;79211:41;;79142:118;:::o;86370:156::-;76226:8;;-1:-1:-1;;;;;76226:8:0;76212:10;:22;76204:44;;;;-1:-1:-1;;;76204:44:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;86451:23:0;::::1;86459:1;86451:23:::0;86443:44:::1;;;::::0;-1:-1:-1;;;86443:44:0;;9165:2:1;86443:44:0::1;::::0;::::1;9147:21:1::0;9204:1;9184:18;;;9177:29;-1:-1:-1;;;9222:18:1;;;9215:38;9270:18;;86443:44:0::1;8963:331:1::0;86443:44:0::1;86498:8;:20:::0;;-1:-1:-1;;;;;;86498:20:0::1;-1:-1:-1::0;;;;;86498:20:0;;;::::1;::::0;;;::::1;::::0;;86370:156::o;84372:162::-;2362:13;:11;:13::i;:::-;84456:10:::1;::::0;:15;84448:40:::1;;;::::0;-1:-1:-1;;;84448:40:0;;7373:2:1;84448:40:0::1;::::0;::::1;7355:21:1::0;7412:2;7392:18;;;7385:30;-1:-1:-1;;;7431:18:1;;;7424:42;7483:18;;84448:40:0::1;7171:336:1::0;84448:40:0::1;84501:25;::::0;-1:-1:-1;;;84501:25:0;;-1:-1:-1;;;;;9491:32:1;;84501:25:0::1;::::0;::::1;9473:51:1::0;9540:18;;;9533:34;;;84501:4:0::1;::::0;:13:::1;::::0;9446:18:1;;84501:25:0::1;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;84372:162:::0;;:::o;84582:370::-;2362:13;:11;:13::i;:::-;75202:4:::1;84691:21;::::0;::::1;;;84683:41;;;::::0;-1:-1:-1;;;84683:41:0;;10062:2:1;84683:41:0::1;::::0;::::1;10044:21:1::0;10101:1;10081:18;;;10074:29;-1:-1:-1;;;10119:18:1;;;10112:37;10166:18;;84683:41:0::1;9860:330:1::0;84683:41:0::1;75202:4;84743:22;::::0;::::1;;;84735:43;;;::::0;-1:-1:-1;;;84735:43:0;;10397:2:1;84735:43:0::1;::::0;::::1;10379:21:1::0;10436:1;10416:18;;;10409:29;-1:-1:-1;;;10454:18:1;;;10447:38;10502:18;;84735:43:0::1;10195:331:1::0;84735:43:0::1;75254:5;84797:32;::::0;::::1;;;84789:58;;;::::0;-1:-1:-1;;;84789:58:0;;10733:2:1;84789:58:0::1;::::0;::::1;10715:21:1::0;10772:2;10752:18;;;10745:30;-1:-1:-1;;;10791:18:1;;;10784:43;10844:18;;84789:58:0::1;10531:337:1::0;84789:58:0::1;84860:6;:16:::0;;-1:-1:-1;;84887:18:0;84860:16;::::1;::::0;;::::1;;-1:-1:-1::0;;84887:18:0;;-1:-1:-1;;;84887:18:0;;::::1;::::0;;;::::1;::::0;;;::::1;-1:-1:-1::0;;;;84916:28:0::1;-1:-1:-1::0;;;84916:28:0;;;::::1;;::::0;;;::::1;::::0;;84582:370::o;81451:154::-;81494:29;81512:10;81494:17;:29::i;:::-;81544:10;81536:19;;;;:7;:19;;;;;;;;;:26;;-1:-1:-1;;81536:26:0;81558:4;81536:26;;;81580:17;;3242:51:1;;;81580:17:0;;3215:18:1;81580:17:0;3096:203:1;87003:237:0;76226:8;;-1:-1:-1;;;;;76226:8:0;76212:10;:22;76204:44;;;;-1:-1:-1;;;76204:44:0;;;;;;;:::i;:::-;87120:16:::1;:14;:16::i;:::-;87098:19;:38:::0;87147:19:::1;:42:::0;87220:12:::1;87200:17;:32:::0;87003:237::o;82002:543::-;82108:16;82127:24;82145:4;82127:9;:24::i;:::-;82108:43;;82168:8;82180:1;82168:13;82164:26;;82183:7;82002:543;:::o;82164:26::-;82231:20;82254:56;82280:4;82287:8;82297:12;82254:17;:56::i;:::-;82400:12;;82231:79;;-1:-1:-1;82358:23:0;;75306:5;;82385:27;;-1:-1:-1;;;82400:12:0;;82384:46;82400:12;82231:79;82385:27;:::i;:::-;82384:46;;;;:::i;:::-;82358:72;-1:-1:-1;82447:19:0;;82443:95;;82491:8;;82483:43;;-1:-1:-1;;;;;82491:8:0;;;;82483:43;;;;;82510:15;;82491:8;82483:43;82491:8;82483:43;82510:15;82491:8;82483:43;;;;;;;;;;;;;;;;;;;;;82057:488;;;82002:543;:::o;86597:97::-;76226:8;;-1:-1:-1;;;;;76226:8:0;76212:10;:22;76204:44;;;;-1:-1:-1;;;76204:44:0;;;;;;;:::i;:::-;-1:-1:-1;;86657:9:0::1;:29:::0;86597:97::o;87626:101::-;76226:8;;-1:-1:-1;;;;;76226:8:0;76212:10;:22;76204:44;;;;-1:-1:-1;;;76204:44:0;;;;;;;:::i;:::-;87718:1:::1;87696:19;:23:::0;87626:101::o;3409:220::-;2362:13;:11;:13::i;:::-;-1:-1:-1;;;;;3494:22:0;::::1;3490:93;;3540:31;::::0;-1:-1:-1;;;3540:31:0;;3568:1:::1;3540:31;::::0;::::1;3242:51:1::0;3215:18;;3540:31:0::1;3096:203:1::0;3490:93:0::1;3593:28;3612:8;3593:18;:28::i;77725:114::-:0;77783:4;77807:24;:9;77826:4;77807:18;:24::i;36684:162::-;36794:43;;;-1:-1:-1;;;;;9491:32:1;;36794:43:0;;;9473:51:1;9540:18;;;;9533:34;;;36794:43:0;;;;;;;;;;9446:18:1;;;;36794:43:0;;;;;;;;-1:-1:-1;;;;;36794:43:0;-1:-1:-1;;;36794:43:0;;;36767:71;;36787:5;;36767:19;:71::i;22999:130::-;23084:37;23093:5;23100:7;23109:5;23116:4;23084:8;:37::i;44736:315::-;44034:1;44865:7;;:18;44861:88;;44907:30;;-1:-1:-1;;;44907:30:0;;;;;;;;;;;44861:88;44034:1;45026:7;:17;44736:315::o;92128:188::-;92201:22;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;92183:15;;92201:22;;:15;:22::i;:::-;92236:12;;;:22;-1:-1:-1;92295:13:0;;92269:23;;;;:39;92128:188::o;24715:487::-;-1:-1:-1;;;;;17818:18:0;;;24815:24;17818:18;;;:11;:18;;;;;;;;:27;;;;;;;;;;-1:-1:-1;;24882:37:0;;24878:317;;24959:5;24940:16;:24;24936:132;;;24992:60;;-1:-1:-1;;;24992:60:0;;-1:-1:-1;;;;;11093:32:1;;24992:60:0;;;11075:51:1;11142:18;;;11135:34;;;11185:18;;;11178:34;;;11048:18;;24992:60:0;10873:345:1;24936:132:0;25111:57;25120:5;25127:7;25155:5;25136:16;:24;25162:5;25111:8;:57::i;19574:308::-;-1:-1:-1;;;;;19658:18:0;;19654:88;;19700:30;;-1:-1:-1;;;19700:30:0;;19727:1;19700:30;;;3242:51:1;3215:18;;19700:30:0;3096:203:1;19654:88:0;-1:-1:-1;;;;;19756:16:0;;19752:88;;19796:32;;-1:-1:-1;;;19796:32:0;;19825:1;19796:32;;;3242:51:1;3215:18;;19796:32:0;3096:203:1;19752:88:0;19850:24;19858:4;19864:2;19868:5;19850:7;:24::i;91787:270::-;91854:7;91874:13;91906:5;:23;;;91890:13;;:39;;;;:::i;:::-;91874:55;-1:-1:-1;91940:14:0;91983:24;72362:4;91983:12;:24;:::i;:::-;91958:12;;:20;;91973:5;;91958:20;:::i;:::-;91957:51;;;;:::i;:::-;91940:68;;92043:6;92028:5;:12;;;:21;;;;:::i;:::-;92021:28;91787:270;-1:-1:-1;;;;91787:270:0:o;22235:211::-;-1:-1:-1;;;;;22306:21:0;;22302:91;;22351:30;;-1:-1:-1;;;22351:30:0;;22378:1;22351:30;;;3242:51:1;3215:18;;22351:30:0;3096:203:1;22302:91:0;22403:35;22411:7;22428:1;22432:5;22403:7;:35::i;2641:166::-;2522:7;2549:6;-1:-1:-1;;;;;2549:6:0;831:10;2701:23;2697:103;;2748:40;;-1:-1:-1;;;2748:40:0;;831:10;2748:40;;;3242:51:1;3215:18;;2748:40:0;3096:203:1;90126:172:0;90189:23;90207:4;90189:17;:23::i;:::-;90225:22;:9;90242:4;90225:16;:22::i;:::-;-1:-1:-1;90265:25:0;;-1:-1:-1;;;;;3260:32:1;;3242:51;;90265:25:0;;3230:2:1;3215:18;90265:25:0;;;;;;;;90126:172;:::o;87994:121::-;88097:10;;88084;;88045:4;;88084:23;;88097:10;;;;;88084:23;:::i;:::-;88069:12;:38;88062:45;;87994:121;:::o;3789:191::-;3863:16;3882:6;;-1:-1:-1;;;;;3899:17:0;;;-1:-1:-1;;;;;;3899:17:0;;;;;;3932:40;;3882:6;;;;;;;3932:40;;3863:16;3932:40;3852:128;3789:191;:::o;96127:783::-;96228:7;96293:8;96305:1;96293:13;96289:27;;-1:-1:-1;96315:1:0;96308:8;;96289:27;96367:48;96418:341;;;;;;;;71452:42;-1:-1:-1;;;;;96477:11:0;;:13;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;96418:341:0;;;;;71562:42;96418:341;;;;;;;;96555:7;;;;;;;;;96418:341;;;;;;;;;;;;;;;;;;;96615:15;96418:341;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;96418:341:0;;;;;96850:52;;-1:-1:-1;;;96850:52:0;;11774:13:1;;11770:22;;96850:52:0;;;11752:41:1;11841:17;;;11835:24;11831:33;;11809:20;;;11802:63;11913:17;;;11907:24;11903:39;;;11881:20;;;11874:69;11991:17;;;11985:24;11981:33;;11959:20;;;11952:63;12059:17;;12053:24;12031:20;;;12024:54;12122:17;;;12116:24;12094:20;;;12087:54;12185:17;;12179:24;12157:20;;;12150:54;12252:17;;;12246:24;12242:33;12220:20;;;12213:63;96367:392:0;;-1:-1:-1;71339:42:0;;96850:27;;96418:341;;11686:19:1;;96850:52:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;96843:59;96127:783;-1:-1:-1;;;;;96127:783:0:o;91168:437::-;91287:28;91310:4;91287:22;:28::i;:::-;91283:41;;;91168:437;:::o;91283:41::-;-1:-1:-1;;;;;17235:18:0;;17208:7;17235:18;;;:9;:18;;;;;;91369:11;;:36;;;;;;;:::i;:::-;;;;-1:-1:-1;;;;;;;91525:18:0;;91503:19;91525:18;;;:12;:18;;;;;91556:12;91525:18;91556:5;:12::i;:::-;91596:1;91581:16;;-1:-1:-1;91168:437:0:o;54893:117::-;54956:7;54983:19;54991:3;50193:18;;50110:109;55364:158;55438:7;55489:22;55493:3;55505:5;55489:3;:22::i;90505:459::-;90624:28;90647:4;90624:22;:28::i;:::-;90619:42;;90505:459;:::o;90619:42::-;-1:-1:-1;;;;;17235:18:0;;90706:15;17235:18;;;:9;:18;;;;;;90706:39;;90773:7;90758:11;;:22;;;;;;;:::i;:::-;;;;-1:-1:-1;;;;;;;90853:18:0;;;90831:19;90853:18;;;:12;:18;;;;;90884:22;;;90943:13;;90917:23;;;;:39;90505:459::o;95305:708::-;95401:7;95466:8;95478:1;95466:13;95462:27;;-1:-1:-1;95488:1:0;95481:8;;95462:27;95546:50;95563:4;71452:42;95587:8;95546;:50::i;:::-;95675:16;;;95689:1;95675:16;;;;;;;;95651:21;;95675:16;;;;;;;;;;-1:-1:-1;95675:16:0;95651:40;;95720:4;95702;95707:1;95702:7;;;;;;;;:::i;:::-;;;;;;:23;-1:-1:-1;;;;;95702:23:0;;;-1:-1:-1;;;;;95702:23:0;;;;;71452:42;-1:-1:-1;;;;;95746:11:0;;:13;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;95736:4;95741:1;95736:7;;;;;;;;:::i;:::-;-1:-1:-1;;;;;95736:23:0;;;:7;;;;;;;;;;;:23;95835:108;;-1:-1:-1;;;95835:108:0;;95801:21;;71452:42;;95835:57;;:108;;95893:8;;95903:12;;95917:4;;95923:2;;95927:15;;95835:108;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;95987:18;95963:21;:42;;;;:::i;:::-;95956:49;95305:708;-1:-1:-1;;;;;;95305:708:0:o;54640:167::-;-1:-1:-1;;;;;54774:23:0;;54720:4;49990:21;;;:14;;;:21;;;;;;:26;;54744:55;49893:131;39495:638;39919:23;39945:33;-1:-1:-1;;;;;39945:27:0;;39973:4;39945:27;:33::i;:::-;39919:59;;39993:10;:17;40014:1;39993:22;;:57;;;;;40031:10;40020:30;;;;;;;;;;;;:::i;:::-;40019:31;39993:57;39989:137;;;40074:40;;-1:-1:-1;;;40074:40:0;;-1:-1:-1;;;;;3260:32:1;;40074:40:0;;;3242:51:1;3215:18;;40074:40:0;3096:203:1;23980:443:0;-1:-1:-1;;;;;24093:19:0;;24089:91;;24136:32;;-1:-1:-1;;;24136:32:0;;24165:1;24136:32;;;3242:51:1;3215:18;;24136:32:0;3096:203:1;24089:91:0;-1:-1:-1;;;;;24194:21:0;;24190:92;;24239:31;;-1:-1:-1;;;24239:31:0;;24267:1;24239:31;;;3242:51:1;3215:18;;24239:31:0;3096:203:1;24190:92:0;-1:-1:-1;;;;;24292:18:0;;;;;;;:11;:18;;;;;;;;:27;;;;;;;;;:35;;;24338:78;;;;24389:7;-1:-1:-1;;;;;24373:31:0;24382:5;-1:-1:-1;;;;;24373:31:0;;24398:5;24373:31;;;;1949:25:1;;1937:2;1922:18;;1803:177;24373:31:0;;;;;;;;23980:443;;;;:::o;92896:1721::-;93025:21;93049:19;:17;:19::i;:::-;93025:43;;93126:15;93161:4;-1:-1:-1;;;;;93144:21:0;93152:4;-1:-1:-1;;;;;93144:21:0;;:50;;;;;93170:24;93191:2;93170:20;:24::i;:::-;93169:25;93144:50;93126:68;;93205:16;93225:26;93246:4;93225:20;:26::i;:::-;93224:27;:50;;;;;93272:2;-1:-1:-1;;;;;93255:19:0;93263:4;-1:-1:-1;;;;;93255:19:0;;93224:50;93205:69;;93357:16;:39;;;;;93377:19;93391:4;93377:13;:19::i;:::-;93353:88;;;93413:16;;-1:-1:-1;;;93413:16:0;;13730:2:1;93413:16:0;;;13712:21:1;13769:1;13749:18;;;13742:29;-1:-1:-1;;;13787:18:1;;;13780:36;13833:18;;93413:16:0;13528:329:1;93353:88:0;93502:11;93545;:25;;93569:1;93545:25;;;93559:7;;-1:-1:-1;;;93559:7:0;;;;93545:25;93517:10;:23;;93539:1;93517:23;;;93530:6;;;;;;;93517:23;93516:55;;;;:::i;:::-;93502:69;;;-1:-1:-1;93584:17:0;75306:5;93605:12;93502:69;93605:6;:12;:::i;:::-;93604:31;;;;:::i;:::-;93584:51;-1:-1:-1;93648:28:0;93679:18;93584:51;93679:6;:18;:::i;:::-;93648:49;-1:-1:-1;93761:13:0;;93757:91;;93791:45;93805:4;93819;93826:9;93791:13;:45::i;:::-;93916:11;93912:63;;;93944:19;93961:1;93944:16;:19::i;:::-;94048:45;94062:4;94068:2;94072:20;94048:13;:45::i;:::-;94167:18;94180:4;94167:12;:18::i;:::-;94196:16;94209:2;94196:12;:16::i;:::-;94315;94314:17;:50;;;;;94336:28;94361:2;94336:24;:28::i;:::-;94335:29;94314:50;94310:102;;;94381:19;94397:2;94381:15;:19::i;:::-;94504:28;94529:2;94504:24;:28::i;:::-;94499:111;;94574:9;;94557:13;94567:2;94557:9;:13::i;:::-;:26;;94549:49;;;;-1:-1:-1;;;94549:49:0;;14239:2:1;94549:49:0;;;14221:21:1;14278:2;14258:18;;;14251:30;-1:-1:-1;;;14297:18:1;;;14290:40;14347:18;;94549:49:0;14037:334:1;94549:49:0;92973:1644;;;;;;92896:1721;;;:::o;54396:158::-;54469:4;54493:53;54501:3;-1:-1:-1;;;;;54521:23:0;;54493:7;:53::i;89544:277::-;89612:4;-1:-1:-1;;;;;89636:18:0;;;;:43;;-1:-1:-1;89666:4:0;-1:-1:-1;;;;;89658:21:0;;;89636:43;:87;;;;89703:1;89684:4;-1:-1:-1;;;;;89684:16:0;;:20;:38;;;;-1:-1:-1;;;;;;89709:13:0;;;;;;:7;:13;;;;;;;;89708:14;89684:38;89636:123;;;;89740:19;89754:4;89740:13;:19::i;:::-;89636:177;;;-1:-1:-1;;;;;;;89763:50:0;:42;:50;;89544:277::o;50573:120::-;50640:7;50667:3;:11;;50679:5;50667:18;;;;;;;;:::i;:::-;;;;;;;;;50660:25;;50573:120;;;;:::o;31999:153::-;32074:12;32106:38;32128:6;32136:4;32142:1;32106:21;:38::i;88926:146::-;88992:4;89024;-1:-1:-1;;;;;89016:21:0;;;;:48;;-1:-1:-1;;;;;;;89041:23:0;71452:42;89041:23;;88926:146::o;20206:1135::-;-1:-1:-1;;;;;20296:18:0;;20292:552;;20450:5;20434:12;;:21;;;;;;;:::i;:::-;;;;-1:-1:-1;20292:552:0;;-1:-1:-1;20292:552:0;;-1:-1:-1;;;;;20510:15:0;;20488:19;20510:15;;;:9;:15;;;;;;20544:19;;;20540:117;;;20591:50;;-1:-1:-1;;;20591:50:0;;-1:-1:-1;;;;;11093:32:1;;20591:50:0;;;11075:51:1;11142:18;;;11135:34;;;11185:18;;;11178:34;;;11048:18;;20591:50:0;10873:345:1;20540:117:0;-1:-1:-1;;;;;20780:15:0;;;;;;:9;:15;;;;;20798:19;;;;20780:37;;20292:552;-1:-1:-1;;;;;20860:16:0;;20856:435;;21026:12;:21;;;;;;;20856:435;;;-1:-1:-1;;;;;21242:13:0;;;;;;:9;:13;;;;;:22;;;;;;20856:435;21323:2;-1:-1:-1;;;;;21308:25:0;21317:4;-1:-1:-1;;;;;21308:25:0;;21327:5;21308:25;;;;1949::1;;1937:2;1922:18;;1803:177;21308:25:0;;;;;;;;20206:1135;;;:::o;94869:325::-;94928:28;94951:4;94928:22;:28::i;:::-;94924:41;;;94869:325;:::o;94924:41::-;94977:15;94995;95005:4;94995:9;:15::i;:::-;-1:-1:-1;;;;;95045:18:0;;95023:19;95045:18;;;:12;:18;;;;;95104:12;;95090:11;;94977:33;;-1:-1:-1;95045:18:0;;94977:33;;95090:26;;;:::i;:::-;:36;;;;:::i;:::-;95076:11;:50;95139:12;95145:5;95139;:12::i;:::-;95164:22;-1:-1:-1;94869:325:0:o;88282:175::-;88352:4;88384;-1:-1:-1;;;;;88376:21:0;;;;:48;;-1:-1:-1;71452:42:0;-1:-1:-1;;;;;88401:23:0;;;88376:48;:73;;;-1:-1:-1;;88436:4:0;-1:-1:-1;;;;;88428:21:0;;;;;;;88282:175::o;89891:160::-;89949:24;89968:4;89949:18;:24::i;:::-;89986:19;:9;90000:4;89986:13;:19::i;:::-;-1:-1:-1;90023:20:0;;-1:-1:-1;;;;;3260:32:1;;3242:51;;90023:20:0;;3230:2:1;3215:18;90023:20:0;3096:203:1;88645:198:0;88715:4;88747;-1:-1:-1;;;;;88739:21:0;;;;:48;;-1:-1:-1;71452:42:0;-1:-1:-1;;;;;88764:23:0;;;88739:48;:73;;;;88808:4;-1:-1:-1;;;;;88791:21:0;88799:4;-1:-1:-1;;;;;88791:21:0;;88739:73;:96;;;;88816:19;88830:4;88816:13;:19::i;48407:1400::-;48473:4;48604:21;;;:14;;;:21;;;;;;48642:13;;48638:1162;;49015:18;49036:12;49047:1;49036:8;:12;:::i;:::-;49083:18;;49015:33;;-1:-1:-1;49063:17:0;;49083:22;;49104:1;;49083:22;:::i;:::-;49063:42;;49140:9;49126:10;:23;49122:385;;49170:17;49190:3;:11;;49202:9;49190:22;;;;;;;;:::i;:::-;;;;;;;;;49170:42;;49340:9;49314:3;:11;;49326:10;49314:23;;;;;;;;:::i;:::-;;;;;;;;;;;;:35;;;;49455:25;;;:14;;;:25;;;;;:36;;;49122:385;49588:17;;:3;;:17;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;49694:3;:14;;:21;49709:5;49694:21;;;;;;;;;;;49687:28;;;49739:4;49732:11;;;;;;;48638:1162;49783:5;49776:12;;;;;48638:1162;48479:1328;48407:1400;;;;:::o;32487:398::-;32586:12;32639:5;32615:21;:29;32611:110;;;32668:41;;-1:-1:-1;;;32668:41:0;;32703:4;32668:41;;;3242:51:1;3215:18;;32668:41:0;3096:203:1;32611:110:0;32732:12;32746:23;32773:6;-1:-1:-1;;;;;32773:11:0;32792:5;32799:4;32773:31;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;32731:73;;;;32822:55;32849:6;32857:7;32866:10;32822:26;:55::i;54068:152::-;54138:4;54162:50;54167:3;-1:-1:-1;;;;;54187:23:0;;54162:4;:50::i;33963:597::-;34111:12;34141:7;34136:417;;34165:19;34173:10;34165:7;:19::i;:::-;34136:417;;;34393:17;;:22;:49;;;;-1:-1:-1;;;;;;34419:18:0;;;:23;34393:49;34389:121;;;34470:24;;-1:-1:-1;;;34470:24:0;;-1:-1:-1;;;;;3260:32:1;;34470:24:0;;;3242:51:1;3215:18;;34470:24:0;3096:203:1;34389:121:0;-1:-1:-1;34531:10:0;34524:17;;47815:416;47878:4;49990:21;;;:14;;;:21;;;;;;47895:329;;-1:-1:-1;47938:23:0;;;;;;;;:11;:23;;;;;;;;;;;;;48123:18;;48099:21;;;:14;;;:21;;;;;;:42;;;;48156:11;;47895:329;-1:-1:-1;48207:5:0;48200:12;;35113:528;35246:17;;:21;35242:392;;35478:10;35472:17;35535:15;35522:10;35518:2;35514:19;35507:44;35242:392;35605:17;;-1:-1:-1;;;35605:17:0;;;;;;;;;;;14:139:1;-1:-1:-1;;;;;97:31:1;;87:42;;77:70;;143:1;140;133:12;158:269;231:6;284:2;272:9;263:7;259:23;255:32;252:52;;;300:1;297;290:12;252:52;339:9;326:23;358:39;391:5;358:39;:::i;432:250::-;517:1;527:113;541:6;538:1;535:13;527:113;;;617:11;;;611:18;598:11;;;591:39;563:2;556:10;527:113;;;-1:-1:-1;;674:1:1;656:16;;649:27;432:250::o;687:396::-;836:2;825:9;818:21;799:4;868:6;862:13;911:6;906:2;895:9;891:18;884:34;927:79;999:6;994:2;983:9;979:18;974:2;966:6;962:15;927:79;:::i;:::-;1067:2;1046:15;-1:-1:-1;;1042:29:1;1027:45;;;;1074:2;1023:54;;687:396;-1:-1:-1;;687:396:1:o;1283:323::-;1351:6;1359;1412:2;1400:9;1391:7;1387:23;1383:32;1380:52;;;1428:1;1425;1418:12;1380:52;1467:9;1454:23;1486:39;1519:5;1486:39;:::i;:::-;1544:5;1596:2;1581:18;;;;1568:32;;-1:-1:-1;;;1283:323:1:o;2245:472::-;2322:6;2330;2338;2391:2;2379:9;2370:7;2366:23;2362:32;2359:52;;;2407:1;2404;2397:12;2359:52;2446:9;2433:23;2465:39;2498:5;2465:39;:::i;:::-;2523:5;-1:-1:-1;2580:2:1;2565:18;;2552:32;2593:41;2552:32;2593:41;:::i;:::-;2245:472;;2653:7;;-1:-1:-1;;;2707:2:1;2692:18;;;;2679:32;;2245:472::o;2911:180::-;2970:6;3023:2;3011:9;3002:7;2998:23;2994:32;2991:52;;;3039:1;3036;3029:12;2991:52;-1:-1:-1;3062:23:1;;2911:180;-1:-1:-1;2911:180:1:o;3304:161::-;3371:20;;3431:8;3420:20;;3410:31;;3400:59;;3455:1;3452;3445:12;3400:59;3304:161;;;:::o;3470:184::-;3528:6;3581:2;3569:9;3560:7;3556:23;3552:32;3549:52;;;3597:1;3594;3587:12;3549:52;3620:28;3638:9;3620:28;:::i;4118:328::-;4192:6;4200;4208;4261:2;4249:9;4240:7;4236:23;4232:32;4229:52;;;4277:1;4274;4267:12;4229:52;4300:28;4318:9;4300:28;:::i;:::-;4290:38;;4347:37;4380:2;4369:9;4365:18;4347:37;:::i;:::-;4337:47;;4403:37;4436:2;4425:9;4421:18;4403:37;:::i;:::-;4393:47;;4118:328;;;;;:::o;4451:404::-;4519:6;4527;4580:2;4568:9;4559:7;4555:23;4551:32;4548:52;;;4596:1;4593;4586:12;4548:52;4635:9;4622:23;4654:39;4687:5;4654:39;:::i;:::-;4712:5;-1:-1:-1;4769:2:1;4754:18;;4741:32;4782:41;4741:32;4782:41;:::i;:::-;4842:7;4832:17;;;4451:404;;;;;:::o;5659:184::-;5729:6;5782:2;5770:9;5761:7;5757:23;5753:32;5750:52;;;5798:1;5795;5788:12;5750:52;-1:-1:-1;5821:16:1;;5659:184;-1:-1:-1;5659:184:1:o;5848:380::-;5927:1;5923:12;;;;5970;;;5991:61;;6045:4;6037:6;6033:17;6023:27;;5991:61;6098:2;6090:6;6087:14;6067:18;6064:38;6061:161;;6144:10;6139:3;6135:20;6132:1;6125:31;6179:4;6176:1;6169:15;6207:4;6204:1;6197:15;6061:161;;5848:380;;;:::o;6233:127::-;6294:10;6289:3;6285:20;6282:1;6275:31;6325:4;6322:1;6315:15;6349:4;6346:1;6339:15;6365:125;6430:9;;;6451:10;;;6448:36;;;6464:18;;:::i;6495:332::-;6697:2;6679:21;;;6736:1;6716:18;;;6709:29;-1:-1:-1;;;6769:2:1;6754:18;;6747:39;6818:2;6803:18;;6495:332::o;7512:217::-;7552:1;7578;7568:132;;7622:10;7617:3;7613:20;7610:1;7603:31;7657:4;7654:1;7647:15;7685:4;7682:1;7675:15;7568:132;-1:-1:-1;7714:9:1;;7512:217::o;8346:306::-;8434:6;8442;8450;8503:2;8491:9;8482:7;8478:23;8474:32;8471:52;;;8519:1;8516;8509:12;8471:52;8548:9;8542:16;8532:26;;8598:2;8587:9;8583:18;8577:25;8567:35;;8642:2;8631:9;8627:18;8621:25;8611:35;;8346:306;;;;;:::o;8657:128::-;8724:9;;;8745:11;;;8742:37;;;8759:18;;:::i;8790:168::-;8863:9;;;8894;;8911:15;;;8905:22;;8891:37;8881:71;;8932:18;;:::i;9578:277::-;9645:6;9698:2;9686:9;9677:7;9673:23;9669:32;9666:52;;;9714:1;9711;9704:12;9666:52;9746:9;9740:16;9799:5;9792:13;9785:21;9778:5;9775:32;9765:60;;9821:1;9818;9811:12;11223:259;11293:6;11346:2;11334:9;11325:7;11321:23;11317:32;11314:52;;;11362:1;11359;11352:12;11314:52;11394:9;11388:16;11413:39;11446:5;11413:39;:::i;12419:127::-;12480:10;12475:3;12471:20;12468:1;12461:31;12511:4;12508:1;12501:15;12535:4;12532:1;12525:15;12551:972;12805:4;12853:3;12842:9;12838:19;12884:6;12873:9;12866:25;12910:2;12948:6;12943:2;12932:9;12928:18;12921:34;12991:3;12986:2;12975:9;12971:18;12964:31;13015:6;13050;13044:13;13081:6;13073;13066:22;13119:3;13108:9;13104:19;13097:26;;13158:2;13150:6;13146:15;13132:29;;13179:1;13189:195;13203:6;13200:1;13197:13;13189:195;;;13268:13;;-1:-1:-1;;;;;13264:39:1;13252:52;;13359:15;;;;13324:12;;;;13300:1;13218:9;13189:195;;;-1:-1:-1;;;;;;;13440:32:1;;;;13435:2;13420:18;;13413:60;-1:-1:-1;;;13504:3:1;13489:19;13482:35;13401:3;12551:972;-1:-1:-1;;;12551:972:1:o;13862:170::-;13929:8;13957:10;;;13969;;;13953:27;;13992:11;;;13989:37;;;14006:18;;:::i;14376:127::-;14437:10;14432:3;14428:20;14425:1;14418:31;14468:4;14465:1;14458:15;14492:4;14489:1;14482:15;14508:287;14637:3;14675:6;14669:13;14691:66;14750:6;14745:3;14738:4;14730:6;14726:17;14691:66;:::i;:::-;14773:16;;;;;14508:287;-1:-1:-1;;14508:287:1:o
Swarm Source
ipfs://7a7a5a501753de715e3980387dd811393caf84f2158a1d2aea9f477f2bb162a4
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.