false
true
0

Contract Address Details

0xc2F76C723386e150AB0ad253a6D2c565BF0eF3E0

Contract Name
CowTipFarm
Creator
0x9341ae–067de7 at 0xe4f9b4–3313dc
Balance
0 PLS ( )
Tokens
Fetching tokens...
Transactions
61,522 Transactions
Transfers
0 Transfers
Gas Used
0
Last Balance Update
26152622
Warning! Contract bytecode has been changed and doesn't match the verified one. Therefore, interaction with this smart contract may be risky.
Contract name:
CowTipFarm




Optimization enabled
true
Compiler version
v0.8.19+commit.7dd6d404




Optimization runs
1000
EVM Version
paris




Verified at
2023-12-05T12:28:10.535324Z

Constructor Arguments

0x00000000000000000000000090732c0abc7b44f6e00c4cc90d29293d1dd01d8b000000000000000000000000ab9747b9ac5adc9c8ab282d96415284cb52308a70000000000000000000000005c42454748a8273c8381e24b87f0fec36d8499e300000000000000000000000000000000000000000000000000000000000003e800000000000000000000000000000000000000000000000000000000000003e800000000000000000000000000000000000000000000000029a2241af62c0000000000000000000000000000000000000000000000000000000000006570a890

Arg [0] (address) : 0x90732c0abc7b44f6e00c4cc90d29293d1dd01d8b
Arg [1] (address) : 0xab9747b9ac5adc9c8ab282d96415284cb52308a7
Arg [2] (address) : 0x5c42454748a8273c8381e24b87f0fec36d8499e3
Arg [3] (uint256) : 1000
Arg [4] (uint256) : 1000
Arg [5] (uint256) : 3000000000000000000
Arg [6] (uint256) : 1701882000

              

Contract source code

// Original license: SPDX_License_Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)

pragma solidity ^0.8.0;

/**
 * @dev Provides information about the current execution context, including the
 * sender of the transaction and its data. While these are generally available
 * via msg.sender and msg.data, they should not be accessed in such a direct
 * manner, since when dealing with meta-transactions the account sending and
 * paying for execution may not be the actual sender (as far as an application
 * is concerned).
 *
 * This contract is only required for intermediate, library-like contracts.
 */
abstract contract Context {
    function _msgSender() internal view virtual returns (address) {
        return msg.sender;
    }

    function _msgData() internal view virtual returns (bytes calldata) {
        return msg.data;
    }
}


// File @openzeppelin/contracts/access/Ownable.sol@v4.9.3

// Original license: SPDX_License_Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable.sol)

pragma solidity ^0.8.0;

/**
 * @dev Contract module which provides a basic access control mechanism, where
 * there is an account (an owner) that can be granted exclusive access to
 * specific functions.
 *
 * By default, the owner account will be the one that deploys the contract. This
 * can later be changed with {transferOwnership}.
 *
 * This module is used through inheritance. It will make available the modifier
 * `onlyOwner`, which can be applied to your functions to restrict their use to
 * the owner.
 */
abstract contract Ownable is Context {
    address private _owner;

    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);

    /**
     * @dev Initializes the contract setting the deployer as the initial owner.
     */
    constructor() {
        _transferOwnership(_msgSender());
    }

    /**
     * @dev 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 {
        require(owner() == _msgSender(), "Ownable: caller is not the owner");
    }

    /**
     * @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 {
        require(newOwner != address(0), "Ownable: new owner is the zero address");
        _transferOwnership(newOwner);
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Internal function without access restriction.
     */
    function _transferOwnership(address newOwner) internal virtual {
        address oldOwner = _owner;
        _owner = newOwner;
        emit OwnershipTransferred(oldOwner, newOwner);
    }
}


// File @openzeppelin/contracts/token/ERC20/extensions/IERC20Permit.sol@v4.9.3

// Original license: SPDX_License_Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/extensions/IERC20Permit.sol)

pragma solidity ^0.8.0;

/**
 * @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.
 */
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].
     */
    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);
}


// File @openzeppelin/contracts/token/ERC20/IERC20.sol@v4.9.3

// Original license: SPDX_License_Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol)

pragma solidity ^0.8.0;

/**
 * @dev Interface of the ERC20 standard as defined in the EIP.
 */
interface IERC20 {
    /**
     * @dev Emitted when `value` tokens are moved from one account (`from`) to
     * another (`to`).
     *
     * Note that `value` may be zero.
     */
    event Transfer(address indexed from, address indexed to, uint256 value);

    /**
     * @dev Emitted when the allowance of a `spender` for an `owner` is set by
     * a call to {approve}. `value` is the new allowance.
     */
    event Approval(address indexed owner, address indexed spender, uint256 value);

    /**
     * @dev Returns the amount of tokens in existence.
     */
    function totalSupply() external view returns (uint256);

    /**
     * @dev Returns the amount of tokens owned by `account`.
     */
    function balanceOf(address account) external view returns (uint256);

    /**
     * @dev Moves `amount` tokens from the caller's account to `to`.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transfer(address to, uint256 amount) external returns (bool);

    /**
     * @dev Returns the remaining number of tokens that `spender` will be
     * allowed to spend on behalf of `owner` through {transferFrom}. This is
     * zero by default.
     *
     * This value changes when {approve} or {transferFrom} are called.
     */
    function allowance(address owner, address spender) external view returns (uint256);

    /**
     * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * IMPORTANT: Beware that changing an allowance with this method brings the risk
     * that someone may use both the old and the new allowance by unfortunate
     * transaction ordering. One possible solution to mitigate this race
     * condition is to first reduce the spender's allowance to 0 and set the
     * desired value afterwards:
     * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
     *
     * Emits an {Approval} event.
     */
    function approve(address spender, uint256 amount) external returns (bool);

    /**
     * @dev Moves `amount` tokens from `from` to `to` using the
     * allowance mechanism. `amount` is then deducted from the caller's
     * allowance.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transferFrom(address from, address to, uint256 amount) external returns (bool);
}


// File @openzeppelin/contracts/utils/Address.sol@v4.9.3

// Original license: SPDX_License_Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)

pragma solidity ^0.8.1;

/**
 * @dev Collection of functions related to the address type
 */
library Address {
    /**
     * @dev Returns true if `account` is a contract.
     *
     * [IMPORTANT]
     * ====
     * It is unsafe to assume that an address for which this function returns
     * false is an externally-owned account (EOA) and not a contract.
     *
     * Among others, `isContract` will return false for the following
     * types of addresses:
     *
     *  - an externally-owned account
     *  - a contract in construction
     *  - an address where a contract will be created
     *  - an address where a contract lived, but was destroyed
     *
     * Furthermore, `isContract` will also return true if the target contract within
     * the same transaction is already scheduled for destruction by `SELFDESTRUCT`,
     * which only has an effect at the end of a transaction.
     * ====
     *
     * [IMPORTANT]
     * ====
     * You shouldn't rely on `isContract` to protect against flash loan attacks!
     *
     * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets
     * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract
     * constructor.
     * ====
     */
    function isContract(address account) internal view returns (bool) {
        // This method relies on extcodesize/address.code.length, which returns 0
        // for contracts in construction, since the code is only stored at the end
        // of the constructor execution.

        return account.code.length > 0;
    }

    /**
     * @dev Replacement for Solidity's `transfer`: sends `amount` wei to
     * `recipient`, forwarding all available gas and reverting on errors.
     *
     * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
     * of certain opcodes, possibly making contracts go over the 2300 gas limit
     * imposed by `transfer`, making them unable to receive funds via
     * `transfer`. {sendValue} removes this limitation.
     *
     * https://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.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
     */
    function sendValue(address payable recipient, uint256 amount) internal {
        require(address(this).balance >= amount, "Address: insufficient balance");

        (bool success, ) = recipient.call{value: amount}("");
        require(success, "Address: unable to send value, recipient may have reverted");
    }

    /**
     * @dev Performs a Solidity function call using a low level `call`. A
     * plain `call` is an unsafe replacement for a function call: use this
     * function instead.
     *
     * If `target` reverts with a revert reason, it is bubbled up by this
     * function (like regular Solidity function calls).
     *
     * Returns the raw returned data. To convert to the expected return value,
     * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].
     *
     * Requirements:
     *
     * - `target` must be a contract.
     * - calling `target` with `data` must not revert.
     *
     * _Available since v3.1._
     */
    function functionCall(address target, bytes memory data) internal returns (bytes memory) {
        return functionCallWithValue(target, data, 0, "Address: low-level call failed");
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with
     * `errorMessage` as a fallback revert reason when `target` reverts.
     *
     * _Available since v3.1._
     */
    function functionCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal returns (bytes memory) {
        return functionCallWithValue(target, data, 0, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but also transferring `value` wei to `target`.
     *
     * Requirements:
     *
     * - the calling contract must have an ETH balance of at least `value`.
     * - the called Solidity function must be `payable`.
     *
     * _Available since v3.1._
     */
    function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {
        return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
    }

    /**
     * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but
     * with `errorMessage` as a fallback revert reason when `target` reverts.
     *
     * _Available since v3.1._
     */
    function functionCallWithValue(
        address target,
        bytes memory data,
        uint256 value,
        string memory errorMessage
    ) internal returns (bytes memory) {
        require(address(this).balance >= value, "Address: insufficient balance for call");
        (bool success, bytes memory returndata) = target.call{value: value}(data);
        return verifyCallResultFromTarget(target, success, returndata, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but performing a static call.
     *
     * _Available since v3.3._
     */
    function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
        return functionStaticCall(target, data, "Address: low-level static call failed");
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
     * but performing a static call.
     *
     * _Available since v3.3._
     */
    function functionStaticCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal view returns (bytes memory) {
        (bool success, bytes memory returndata) = target.staticcall(data);
        return verifyCallResultFromTarget(target, success, returndata, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but performing a delegate call.
     *
     * _Available since v3.4._
     */
    function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
        return functionDelegateCall(target, data, "Address: low-level delegate call failed");
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
     * but performing a delegate call.
     *
     * _Available since v3.4._
     */
    function functionDelegateCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal returns (bytes memory) {
        (bool success, bytes memory returndata) = target.delegatecall(data);
        return verifyCallResultFromTarget(target, success, returndata, errorMessage);
    }

    /**
     * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling
     * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.
     *
     * _Available since v4.8._
     */
    function verifyCallResultFromTarget(
        address target,
        bool success,
        bytes memory returndata,
        string memory errorMessage
    ) internal view returns (bytes memory) {
        if (success) {
            if (returndata.length == 0) {
                // only check isContract if the call was successful and the return data is empty
                // otherwise we already know that it was a contract
                require(isContract(target), "Address: call to non-contract");
            }
            return returndata;
        } else {
            _revert(returndata, errorMessage);
        }
    }

    /**
     * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the
     * revert reason or using the provided one.
     *
     * _Available since v4.3._
     */
    function verifyCallResult(
        bool success,
        bytes memory returndata,
        string memory errorMessage
    ) internal pure returns (bytes memory) {
        if (success) {
            return returndata;
        } else {
            _revert(returndata, errorMessage);
        }
    }

    function _revert(bytes memory returndata, string memory errorMessage) 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(errorMessage);
        }
    }
}


// File @openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol@v4.9.3

// Original license: SPDX_License_Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.3) (token/ERC20/utils/SafeERC20.sol)

pragma solidity ^0.8.0;



/**
 * @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 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.encodeWithSelector(token.transfer.selector, 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.encodeWithSelector(token.transferFrom.selector, from, to, value));
    }

    /**
     * @dev Deprecated. This function has issues similar to the ones found in
     * {IERC20-approve}, and its usage is discouraged.
     *
     * Whenever possible, use {safeIncreaseAllowance} and
     * {safeDecreaseAllowance} instead.
     */
    function safeApprove(IERC20 token, address spender, uint256 value) internal {
        // safeApprove should only be called when setting an initial allowance,
        // or when resetting it to zero. To increase and decrease it, use
        // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'
        require(
            (value == 0) || (token.allowance(address(this), spender) == 0),
            "SafeERC20: approve from non-zero to non-zero allowance"
        );
        _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));
    }

    /**
     * @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);
        _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance + value));
    }

    /**
     * @dev Decrease the calling contract's allowance toward `spender` by `value`. If `token` returns no value,
     * non-reverting calls are assumed to be successful.
     */
    function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {
        unchecked {
            uint256 oldAllowance = token.allowance(address(this), spender);
            require(oldAllowance >= value, "SafeERC20: decreased allowance below zero");
            _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance - value));
        }
    }

    /**
     * @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.encodeWithSelector(token.approve.selector, spender, value);

        if (!_callOptionalReturnBool(token, approvalCall)) {
            _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, 0));
            _callOptionalReturn(token, approvalCall);
        }
    }

    /**
     * @dev Use a ERC-2612 signature to set the `owner` approval toward `spender` on `token`.
     * Revert on invalid signature.
     */
    function safePermit(
        IERC20Permit token,
        address owner,
        address spender,
        uint256 value,
        uint256 deadline,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) internal {
        uint256 nonceBefore = token.nonces(owner);
        token.permit(owner, spender, value, deadline, v, r, s);
        uint256 nonceAfter = token.nonces(owner);
        require(nonceAfter == nonceBefore + 1, "SafeERC20: permit did not succeed");
    }

    /**
     * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
     * on the return value: the return value is optional (but if data is returned, it must not be false).
     * @param token The token targeted by the call.
     * @param data The call data (encoded using abi.encode or one of its variants).
     */
    function _callOptionalReturn(IERC20 token, bytes memory data) private {
        // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since
        // we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that
        // the target address contains contract code and also asserts for success in the low-level call.

        bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed");
        require(returndata.length == 0 || abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed");
    }

    /**
     * @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.isContract(address(token));
    }
}


// File @openzeppelin/contracts/utils/Multicall.sol@v4.9.3

// Original license: SPDX_License_Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (utils/Multicall.sol)

pragma solidity ^0.8.0;

/**
 * @dev Provides a function to batch together multiple calls in a single external call.
 *
 * _Available since v4.1._
 */
abstract contract Multicall {
    /**
     * @dev Receives and executes a batch of function calls on this contract.
     * @custom:oz-upgrades-unsafe-allow-reachable delegatecall
     */
    function multicall(bytes[] calldata data) external virtual returns (bytes[] memory results) {
        results = new bytes[](data.length);
        for (uint256 i = 0; i < data.length; i++) {
            results[i] = Address.functionDelegateCall(address(this), data[i]);
        }
        return results;
    }
}


// File @openzeppelin/contracts/security/ReentrancyGuard.sol@v4.9.3

// Original license: SPDX_License_Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (security/ReentrancyGuard.sol)

pragma solidity ^0.8.0;

/**
 * @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;

    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
        require(_status != _ENTERED, "ReentrancyGuard: reentrant call");

        // 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;
    }
}


// File @openzeppelin/contracts/utils/math/SafeMath.sol@v4.9.3

// Original license: SPDX_License_Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (utils/math/SafeMath.sol)

pragma solidity ^0.8.0;

// CAUTION
// This version of SafeMath should only be used with Solidity 0.8 or later,
// because it relies on the compiler's built in overflow checks.

/**
 * @dev Wrappers over Solidity's arithmetic operations.
 *
 * NOTE: `SafeMath` is generally not needed starting with Solidity 0.8, since the compiler
 * now has built in overflow checking.
 */
library SafeMath {
    /**
     * @dev Returns the addition of two unsigned integers, with an overflow flag.
     *
     * _Available since v3.4._
     */
    function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            uint256 c = a + b;
            if (c < a) return (false, 0);
            return (true, c);
        }
    }

    /**
     * @dev Returns the subtraction of two unsigned integers, with an overflow flag.
     *
     * _Available since v3.4._
     */
    function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            if (b > a) return (false, 0);
            return (true, a - b);
        }
    }

    /**
     * @dev Returns the multiplication of two unsigned integers, with an overflow flag.
     *
     * _Available since v3.4._
     */
    function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            // Gas optimization: this is cheaper than requiring 'a' not being zero, but the
            // benefit is lost if 'b' is also tested.
            // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522
            if (a == 0) return (true, 0);
            uint256 c = a * b;
            if (c / a != b) return (false, 0);
            return (true, c);
        }
    }

    /**
     * @dev Returns the division of two unsigned integers, with a division by zero flag.
     *
     * _Available since v3.4._
     */
    function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            if (b == 0) return (false, 0);
            return (true, a / b);
        }
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag.
     *
     * _Available since v3.4._
     */
    function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            if (b == 0) return (false, 0);
            return (true, a % b);
        }
    }

    /**
     * @dev Returns the addition of two unsigned integers, reverting on
     * overflow.
     *
     * Counterpart to Solidity's `+` operator.
     *
     * Requirements:
     *
     * - Addition cannot overflow.
     */
    function add(uint256 a, uint256 b) internal pure returns (uint256) {
        return a + b;
    }

    /**
     * @dev Returns the subtraction of two unsigned integers, reverting on
     * overflow (when the result is negative).
     *
     * Counterpart to Solidity's `-` operator.
     *
     * Requirements:
     *
     * - Subtraction cannot overflow.
     */
    function sub(uint256 a, uint256 b) internal pure returns (uint256) {
        return a - b;
    }

    /**
     * @dev Returns the multiplication of two unsigned integers, reverting on
     * overflow.
     *
     * Counterpart to Solidity's `*` operator.
     *
     * Requirements:
     *
     * - Multiplication cannot overflow.
     */
    function mul(uint256 a, uint256 b) internal pure returns (uint256) {
        return a * b;
    }

    /**
     * @dev Returns the integer division of two unsigned integers, reverting on
     * division by zero. The result is rounded towards zero.
     *
     * Counterpart to Solidity's `/` operator.
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function div(uint256 a, uint256 b) internal pure returns (uint256) {
        return a / b;
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
     * reverting when dividing by zero.
     *
     * Counterpart to Solidity's `%` operator. This function uses a `revert`
     * opcode (which leaves remaining gas untouched) while Solidity uses an
     * invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function mod(uint256 a, uint256 b) internal pure returns (uint256) {
        return a % b;
    }

    /**
     * @dev Returns the subtraction of two unsigned integers, reverting with custom message on
     * overflow (when the result is negative).
     *
     * CAUTION: This function is deprecated because it requires allocating memory for the error
     * message unnecessarily. For custom revert reasons use {trySub}.
     *
     * Counterpart to Solidity's `-` operator.
     *
     * Requirements:
     *
     * - Subtraction cannot overflow.
     */
    function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
        unchecked {
            require(b <= a, errorMessage);
            return a - b;
        }
    }

    /**
     * @dev Returns the integer division of two unsigned integers, reverting with custom message on
     * division by zero. The result is rounded towards zero.
     *
     * Counterpart to Solidity's `/` operator. Note: this function uses a
     * `revert` opcode (which leaves remaining gas untouched) while Solidity
     * uses an invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
        unchecked {
            require(b > 0, errorMessage);
            return a / b;
        }
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
     * reverting with custom message when dividing by zero.
     *
     * CAUTION: This function is deprecated because it requires allocating memory for the error
     * message unnecessarily. For custom revert reasons use {tryMod}.
     *
     * Counterpart to Solidity's `%` operator. This function uses a `revert`
     * opcode (which leaves remaining gas untouched) while Solidity uses an
     * invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
        unchecked {
            require(b > 0, errorMessage);
            return a % b;
        }
    }
}


// File @openzeppelin/contracts/utils/structs/EnumerableSet.sol@v4.9.3

// Original license: SPDX_License_Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (utils/structs/EnumerableSet.sol)
// This file was procedurally generated from scripts/generate/templates/EnumerableSet.js.

pragma solidity ^0.8.0;

/**
 * @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 of the value in the `values` array, plus 1 because index 0
        // means a value is not in the set.
        mapping(bytes32 => uint256) _indexes;
    }

    /**
     * @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._indexes[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 read and store the value's index to prevent multiple reads from the same storage slot
        uint256 valueIndex = set._indexes[value];

        if (valueIndex != 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 toDeleteIndex = valueIndex - 1;
            uint256 lastIndex = set._values.length - 1;

            if (lastIndex != toDeleteIndex) {
                bytes32 lastValue = set._values[lastIndex];

                // Move the last value to the index where the value to delete is
                set._values[toDeleteIndex] = lastValue;
                // Update the index for the moved value
                set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex
            }

            // Delete the slot where the moved value was stored
            set._values.pop();

            // Delete the index for the deleted slot
            delete set._indexes[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._indexes[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;
    }
}


// File contracts/cowTipFarm.sol

// Original license: SPDX_License_Identifier: MIT

pragma solidity 0.8.19;
// import "hardhat/console.sol";

interface IMasterChef is IERC20 {
    struct UserInfo {
        uint256 amount;
        uint256 rewardDebt;
    }
    struct PoolInfo {
        IERC20 lpToken;
        uint256 allocPoint;
        uint256 lastRewardTime;
        uint256 accIncPerShare;
    }
    function poolLength() external view returns (uint256);
    function getMultiplier(uint256 _from, uint256 _to) external view returns (uint256);
    function pendingInc(uint256 _pid, address _user) external view returns (uint256);
    function deposit(uint256 _pid, uint256 _amount) external;
    function withdraw(uint256 _pid, uint256 _amount) external;
    function emergencyWithdraw(uint256 _pid) external;
    function poolInfo(uint256 pid) external view returns (IERC20 lpToken, uint256 allocPoint, uint256 lastRewardTime, uint256 accIncPerShare);
}

interface ICOWTIP is IERC20 {
    function mint(address account, uint256 amount) external;
}

interface IPair {
    function token0() external view returns (address);
    function token1() external view returns (address);
}

contract CowTipFarm is ReentrancyGuard, Ownable, Multicall {
    using SafeMath for uint256;
    using SafeERC20 for IERC20;
    using SafeERC20 for ICOWTIP;
    using EnumerableSet for EnumerableSet.AddressSet;

    // Info of each user.
    struct UserInfo {
        uint256 amount; // How many LP tokens the user has provided.
        uint256 rewardDebt; // Reward debt. See explanation below.
    }

    // Info of each pool.
    struct PoolInfo {
        IERC20 token; // Address of LP token contract.
        uint256 allocPoint; // How many allocation points assigned to this pool. CowTip to distribute per block.
        uint256 lastRewardTime; // Last time that cowTip distribution occurs.
        uint16 depositFeeBP; //depositfee
        uint16 withdrawFeeBP; //withdrawfee
        uint256 accTokensPerShare; // Accumulated cowTip per share, times 1e18. See below.
        bool isStarted; // if lastRewardTime has passed
        IMasterChef externalFarm; // Farm associated with the pool.
        uint256 lpBalance;
        uint256 externalPid;
    }

    struct PoolView {
        uint256 pid;
        address token;
        uint256 allocPoint;
        uint256 lastRewardTime;
        uint16 depositFeeBP;
        uint16 withdrawFeeBP;
        uint256 accTokensPerShare;
        bool isStarted;
        address externalFarm;
        uint256 lpBalance;
        uint256 rewardsPerSecond;
    }

    struct UserView {
        uint256 pid;
        uint256 stakedAmount;
        uint256 unclaimedRewards;
        uint256 lpBalance;
        uint256 allowance;
    }

    ICOWTIP public cowTip;

    IERC20 public constant INC = IERC20(0x2fa878Ab3F87CC1C9737Fc071108F904c0B0C95d);
    IMasterChef public constant PULSE_X_MASTERCHEF = IMasterChef(address(0xB2Ca4A66d3e57a5a9A12043B6bAD28249fE302d4));

    // Info of each pool.
    PoolInfo[] public poolInfo;
    EnumerableSet.AddressSet private lpTokens;

    // Info of each user that stakes LP tokens.
    mapping(uint256 => mapping(address => UserInfo)) public userInfo;

    // Total allocation points. Must be the sum of all allocation points in all pools.
    uint256 public totalAllocPoint = 0;

    // The time when cowTip mining starts.
    uint256 public poolStartTime;
    address public feeAddress;
    address public devAddress;
    uint256 public feePercent;
    uint256 public devPercent;
    uint256 public sharesPerSecond;
    uint256 public constant MAX_SHARES_PER_SECOND = 25 ether;
    uint256 public referralRate = 500;
    mapping(address => address) public referral; // referral => referrer
    mapping(address => uint256) public referralEarned; // for stats

    event Deposit(address indexed user, uint256 indexed pid, uint256 amount);
    event Withdraw(address indexed user, uint256 indexed pid, uint256 amount);
    event EmergencyWithdraw(
        address indexed user,
        uint256 indexed pid,
        uint256 amount
    );
    event RewardPaid(address indexed user, uint256 amount);

    constructor(
        ICOWTIP _cowTip,
        address _feeAddress,
        address _devAddress,
        uint256 _feePercent,
        uint256 _devPercent,
        uint256 _sharesPerSecond,
        uint256 _poolStartTime
    ) {
        require(_sharesPerSecond <= MAX_SHARES_PER_SECOND, "too high");
        require(block.timestamp < _poolStartTime, "CowTipFarm: late");
        require(
            _feeAddress != address(0) &&
                _devAddress != address(0) &&
                address(_cowTip) != address(0),
            "CowTipFarm: Zero address not allowed"
        );
        require(
            _devPercent <= 1000 && _feePercent <= 1000,
            "CowTipFarm: Invalid percentages"
        );
        cowTip = _cowTip;
        feeAddress = _feeAddress;
        devAddress = _devAddress;
        feePercent = _feePercent;
        devPercent = _devPercent;
        sharesPerSecond = _sharesPerSecond;
        poolStartTime = _poolStartTime;
    }

    function poolLength() external view returns (uint256) {
        return poolInfo.length;
    }

    // Add a new lp to the pool
    function add(
        uint256 _allocPoint,
        IERC20 _token,
        bool _withUpdate,
        uint256 _lastRewardTime,
        uint16 _depositFeeBP,
        uint16 _withdrawFeeBP,
        IMasterChef _externalFarm,
        uint256 _externalPid
    ) external onlyOwner {
        IPair pool_lp = IPair(address(_token));
        IERC20 token0 = IERC20(pool_lp.token0());
        IERC20 token1 = IERC20(pool_lp.token1());
        require(
            address(_externalFarm) == address(0) || _externalFarm == PULSE_X_MASTERCHEF, "incorrect farm"
        );
        require(
            address(token0) != address(0) && address(token1) != address(0),
            "CowTipFarm: Only LP tokens "
        );
        require(
            Address.isContract(address(_token)),
            "CowTipFarm: LP token must be a valid contract"
        );
        if (address(_externalFarm) != address(0)) {
             (IERC20 masterChefLpToken,,,) = _externalFarm.poolInfo(_externalPid);
            require(
                _token == masterChefLpToken,
                "CowTipFarm: farm is not valid"
            );
        }
        require(
            _depositFeeBP <= 400 && _withdrawFeeBP <= 400,
            "CowTipFarm: Invalid deposit or withdraw fee basis points"
        );
        require(
            !lpTokens.contains(address(_token)),
            "CowTipFarm: LP already added"
        );

        if (_withUpdate) {
            massUpdatePools();
        }

        if (block.timestamp < poolStartTime) {
            // chef is sleeping
            if (_lastRewardTime < poolStartTime) {
                _lastRewardTime = poolStartTime;
            }
        } else {
            // chef is cooking
            if (_lastRewardTime < block.timestamp) {
                _lastRewardTime = block.timestamp;
            }
        }
        bool _isStarted = (block.timestamp >= poolStartTime) &&
            (block.timestamp >= _lastRewardTime);
        poolInfo.push(
            PoolInfo({
                token: _token,
                allocPoint: _allocPoint,
                lastRewardTime: _lastRewardTime,
                accTokensPerShare: 0,
                isStarted: _isStarted,
                depositFeeBP: _depositFeeBP,
                withdrawFeeBP: _withdrawFeeBP,
                externalFarm: _externalFarm,
                lpBalance: 0,
                externalPid: _externalPid
            })
        );
        if (_isStarted) {
            totalAllocPoint = totalAllocPoint.add(_allocPoint);
        }

        lpTokens.add(address(_token));
    }

    // Update the given pool's cowTip allocation point. Can only be called by the owner.
    function set(
        uint256 _pid,
        uint256 _allocPoint,
        uint16 _depositFeeBP,
        uint16 _withdrawFeeBP
    ) external onlyOwner {
        require(
            _depositFeeBP <= 400 && _withdrawFeeBP <= 400,
            "CowTipFarm: Invalid deposit or withdraw fee basis points"
        );
        massUpdatePools();
        PoolInfo storage pool = poolInfo[_pid];
        if (pool.isStarted) {
            totalAllocPoint = totalAllocPoint.sub(pool.allocPoint).add(
                _allocPoint
            );
        }
        pool.allocPoint = _allocPoint;
        poolInfo[_pid].depositFeeBP = _depositFeeBP;
        poolInfo[_pid].withdrawFeeBP = _withdrawFeeBP;
    }

    // Return accumulate rewards over the given _from to _to block.
    function getMultiplier(
        uint256 _from,
        uint256 _to
    ) public view returns (uint256) {
        if (_from >= _to) return 0;
        if (_to <= poolStartTime) return 0;
        if (_from >= poolStartTime) {
            return _to.sub(_from);
        } else {
            return _to.sub(poolStartTime);
        }
    }

    // View function to see pending CowTip on frontend.
    function pendingShare(
        uint256 _pid,
        address _user
    ) public view returns (uint256) {
        PoolInfo storage pool = poolInfo[_pid];
        UserInfo storage user = userInfo[_pid][_user];
        uint256 accTokensPerShare = pool.accTokensPerShare;
        uint256 tokenSupply = pool.lpBalance;
        if (block.timestamp > pool.lastRewardTime && tokenSupply != 0) {
            uint256 multiplier = getMultiplier(
                pool.lastRewardTime,
                block.timestamp
            );
            uint256 lpPercent = 10000 - devPercent - feePercent;
            uint256 _generatedReward = multiplier.mul(sharesPerSecond);
            uint256 _cowTipReward = _generatedReward
                .mul(pool.allocPoint)
                .div(totalAllocPoint)
                .mul(lpPercent)
                .div(10000);
            accTokensPerShare = accTokensPerShare.add(
                _cowTipReward.mul(1e18).div(tokenSupply)
            );
        }
        return
            user.amount.mul(accTokensPerShare).div(1e18).sub(user.rewardDebt);
    }

    // Update reward variables for all pools. Be careful of gas spending!
    function massUpdatePools() public {
        uint256 length = poolInfo.length;
        for (uint256 pid = 0; pid < length; ++pid) {
            updatePool(pid);
        }
    }

    // Update reward variables of the given pool to be up-to-date.
    function updatePool(uint256 _pid) public {
        PoolInfo storage pool = poolInfo[_pid];
        if (block.timestamp <= pool.lastRewardTime) {
            return;
        }
        if (!pool.isStarted) {
            pool.isStarted = true;
            totalAllocPoint = totalAllocPoint.add(pool.allocPoint);
        }
        uint256 tokenSupply = pool.lpBalance;
        if (tokenSupply == 0) {
            pool.lastRewardTime = block.timestamp;
            return;
        }

        if (totalAllocPoint > 0) {
            uint256 multiplier = getMultiplier(
                pool.lastRewardTime,
                block.timestamp
            );
            uint256 _generatedReward = multiplier.mul(sharesPerSecond);
            uint256 _cowTipReward = _generatedReward
                .mul(pool.allocPoint)
                .div(totalAllocPoint);
            uint256 lpPercent = 10000 - devPercent - feePercent;
            cowTip.mint(
                devAddress,
                _cowTipReward.mul(devPercent).div(10000)
            );
            cowTip.mint(
                feeAddress,
                _cowTipReward.mul(feePercent).div(10000)
            );
            cowTip.mint(
                address(this),
                _cowTipReward.mul(lpPercent).div(10000) + _cowTipReward.mul(referralRate).div(10000)
            );

            pool.accTokensPerShare = pool.accTokensPerShare.add(
                _cowTipReward.mul(1e18).div(tokenSupply).mul(lpPercent).div(
                    10000
                )
            );
        }
        pool.lastRewardTime = block.timestamp;
    }

    function deposit(
        uint256 _pid,
        uint256 _amount,
        address _referrer
    ) external nonReentrant {
        address staker = _msgSender();
        _deposit(_pid, _amount, _referrer, staker);
    }

    function depositOnBehalfOf(
        uint256 _pid,
        uint256 _amount,
        address _referrer,
        address _staker
    ) external nonReentrant {
        _deposit(_pid, _amount, _referrer, _staker);
    }

    function withdraw(uint256 _pid, uint256 _amount) external nonReentrant {
        _withdraw(_pid, _amount);
    }

    function _deposit(
        uint256 _pid,
        uint256 _amount,
        address _referrer,
        address _staker
    ) private {
        if (referral[_staker] == address(0)) {
        require(
            _referrer != address(0) &&
                _referrer != _staker &&
                _referrer != address(this),
            "CowTipFarm: Invalid referrer"
        );
            referral[_staker] = _referrer;
        } else {
            _referrer = referral[_staker];
        }

        PoolInfo storage pool = poolInfo[_pid];
        UserInfo storage user = userInfo[_pid][_staker];
        updatePool(_pid);
        if (user.amount > 0) {
            uint256 _pending = user
                .amount
                .mul(pool.accTokensPerShare)
                .div(1e18)
                .sub(user.rewardDebt);
            if (_pending > 0) {
                uint256 referralAmount = ((_pending) * referralRate) / 10000;
                if (referralAmount > 0) {
                    referralEarned[_referrer] =
                        referralEarned[_referrer] +
                        referralAmount;
                    safeCowTipTransfer(_referrer, referralAmount);
                }
                safeCowTipTransfer(_staker, _pending);
                emit RewardPaid(_staker, _pending);
            }
        }
        if (_amount > 0) {
            pool.token.safeTransferFrom(_msgSender(), address(this), _amount);
        }
        if (pool.depositFeeBP > 0) {
            uint256 depositFee = _amount.mul(pool.depositFeeBP).div(10000);
            pool.token.safeTransfer(feeAddress, depositFee);
            user.amount = user.amount.add(_amount).sub(depositFee);
            pool.lpBalance = pool.lpBalance.add(_amount).sub(depositFee);
        } else {
            user.amount = user.amount.add(_amount);
            pool.lpBalance = pool.lpBalance.add(_amount);
        }

        user.rewardDebt = user.amount.mul(pool.accTokensPerShare).div(1e18);
        if (address(pool.externalFarm) != address(0)) {
            uint256 toDeposit = pool.token.balanceOf(address(this));
            address _externalFarm = address(pool.externalFarm);
            pool.token.approve(_externalFarm, toDeposit);
            pool.externalFarm.deposit(pool.externalPid,toDeposit);
        }
        emit Deposit(_staker, _pid, _amount);
    }

    function _withdraw(uint256 _pid, uint256 _amount) private {
        address _sender = _msgSender();
        PoolInfo storage pool = poolInfo[_pid];
        UserInfo storage user = userInfo[_pid][_sender];
        require(
            user.amount >= _amount,
            "CowTipFarm: User amount too low"
        );
        updatePool(_pid);
        address referrer = referral[_sender];
        uint256 _pending = user
            .amount
            .mul(pool.accTokensPerShare)
            .div(1e18)
            .sub(user.rewardDebt);

        if (_pending > 0) {
            uint256 referralAmount = ((_pending) * referralRate) / 10000;
            if (referralAmount > 0) {
                referralEarned[referrer] =
                    referralEarned[referrer] +
                    referralAmount;
                safeCowTipTransfer(referrer, referralAmount);
            }

            safeCowTipTransfer(_sender, _pending);
            emit RewardPaid(_sender, _pending);
        }
        if (_amount > 0) {
            user.amount = user.amount.sub(_amount);
            if (address(pool.externalFarm) != address(0)) {
                pool.externalFarm.withdraw(pool.externalPid,_amount);
            }
            if (pool.withdrawFeeBP > 0) {
                uint256 withdrawFee = _amount.mul(pool.withdrawFeeBP).div(
                    10000
                );
                pool.token.safeTransfer(feeAddress, withdrawFee);
                pool.token.safeTransfer(_sender, _amount.sub(withdrawFee));
            } else {
                pool.token.safeTransfer(_sender, _amount);
            }
        }
        user.rewardDebt = user.amount.mul(pool.accTokensPerShare).div(1e18);
        pool.lpBalance -= _amount;
        emit Withdraw(_sender, _pid, _amount);
    }

    // Withdraw without caring about rewards. EMERGENCY ONLY.
    function emergencyWithdraw(uint256 _pid) public nonReentrant {
        PoolInfo storage pool = poolInfo[_pid];
        UserInfo storage user = userInfo[_pid][_msgSender()];
        bool isExternalFarm = address(pool.externalFarm) != address(0);
        uint256 _amount = user.amount;
        require(_amount > 0, "CowTipFarm: User has no amount");
        user.amount = 0;
        user.rewardDebt = 0;
        if (isExternalFarm) {
            pool.externalFarm.withdraw(pool.externalPid,_amount);
        }
        if (pool.withdrawFeeBP > 0) {
            uint256 withdrawFee = _amount.mul(pool.withdrawFeeBP).div(10000);
            pool.token.safeTransfer(feeAddress, withdrawFee);
            pool.token.safeTransfer(_msgSender(), _amount.sub(withdrawFee));
        } else {
            pool.token.safeTransfer(_msgSender(), _amount);
        }
        pool.lpBalance -= _amount;
        emit EmergencyWithdraw(_msgSender(), _pid, _amount);
    }

    // Safe cowTip transfer function, just in case if rounding error causes pool to not have enough cowTip.
    function safeCowTipTransfer(address _to, uint256 _amount) internal {
        uint256 _cowTipBal = cowTip.balanceOf(address(this));
        if (_cowTipBal > 0) {
            if (_amount > _cowTipBal) {
                cowTip.safeTransfer(_to, _cowTipBal);
            } else {
                cowTip.safeTransfer(_to, _amount);
            }
        }
    }

    function getExternalReward(uint256 _pid) external onlyOwner {
        PoolInfo storage pool = poolInfo[_pid];
        bool isExternalFarm = address(pool.externalFarm) != address(0);
        require(isExternalFarm, "CowTipFarm: No externalFarm set");
        IERC20 rewardToken = INC;
        pool.externalFarm.deposit(pool.externalPid,0);
        uint256 amountToSend = rewardToken.balanceOf(address(this));
        rewardToken.safeTransfer(feeAddress, amountToSend);
    }

    // this will send the restaked tokens from pulseXmasterChef to cowTipFarm without caring of rewards
    // externalFarm is set to address(0) allowing users still being able to withdraw
    function removeExternalFarm(uint256 _pid) public onlyOwner nonReentrant {
        PoolInfo storage pool = poolInfo[_pid];
        bool isExternalFarm = address(pool.externalFarm) != address(0);
        require(isExternalFarm, "CowTipFarm: No externalFarm set");
        pool.externalFarm.emergencyWithdraw(pool.externalPid);
        pool.externalFarm = IMasterChef(address(0));
    }

    function setFeeAddress(address _feeAddress) external onlyOwner {
        require(
            _feeAddress != address(0),
            "CowTipFarm: Zero address not allowed"
        );
        feeAddress = _feeAddress;
    }

    function setFeePercent(uint256 _feePercent) external onlyOwner {
        require(
            _feePercent <= 1000,
            "CowTipFarm: invalid fee"
        );
        feePercent = _feePercent;
    }

    function setDevAddress(address _devAddress) external onlyOwner {
        require(
            _devAddress != address(0),
            "CowTipFarm: Invalid percentages"
        );
        devAddress = _devAddress;
    }

    function setDevPercent(uint256 _devPercent) external onlyOwner {
        require(
            _devPercent <= 1000,
            "CowTipFarm: Zero address not allowed"
        );
        devPercent = _devPercent;
    }

    function setReferralRate(uint256 _referralRate) external onlyOwner {
        require(_referralRate <= 500, "CowTipFarm: Too high");
        referralRate = _referralRate;
    }

    function updateEmissionRate(uint256 _sharesPerSecond) public onlyOwner {
        require(_sharesPerSecond <= MAX_SHARES_PER_SECOND, "too high");
        massUpdatePools();
        sharesPerSecond = _sharesPerSecond;
    }

    function getPoolView(uint256 pid) public view returns (PoolView memory) {
        require(pid < poolInfo.length, "CowTipFarm: pid out of range");
        PoolInfo memory pool = poolInfo[pid];
        uint256 lpPercent = 10000 - devPercent - feePercent;
        uint256 rewardsPerSecond;
        if(totalAllocPoint == 0){
        rewardsPerSecond = 0;
        }
        else {
        rewardsPerSecond = pool
            .allocPoint
            .mul(sharesPerSecond)
            .div(totalAllocPoint)
            .mul(lpPercent)
            .div(10000);
        }
        return
            PoolView({
                pid: pid,
                token: address(pool.token),
                allocPoint: pool.allocPoint,
                lastRewardTime: pool.lastRewardTime,
                depositFeeBP: pool.depositFeeBP,
                withdrawFeeBP: pool.withdrawFeeBP,
                accTokensPerShare: pool.accTokensPerShare,
                isStarted: pool.isStarted,
                externalFarm: address(pool.externalFarm),
                lpBalance: pool.lpBalance,
                rewardsPerSecond: rewardsPerSecond
            });
    }

    function getAllPoolViews() external view returns (PoolView[] memory) {
        PoolView[] memory views = new PoolView[](poolInfo.length);
        for (uint256 i = 0; i < poolInfo.length; i++) {
            views[i] = getPoolView(i);
        }
        return views;
    }

    function getUserView(
        uint256 pid,
        address account
    ) public view returns (UserView memory) {
        PoolInfo memory pool = poolInfo[pid];
        UserInfo memory user = userInfo[pid][account];
        uint256 unclaimedRewards = pendingShare(pid, account);
        uint256 lpBalance = pool.token.balanceOf(account);
        return
            UserView({
                pid: pid,
                stakedAmount: user.amount,
                unclaimedRewards: unclaimedRewards,
                lpBalance: lpBalance,
                allowance: pool.token.allowance(account, address(this))
            });
    }

    function getUserViews(
        address account
    ) external view returns (UserView[] memory) {
        UserView[] memory views = new UserView[](poolInfo.length);
        for (uint256 i = 0; i < poolInfo.length; i++) {
            views[i] = getUserView(i, account);
        }
        return views;
    }
}
        

Contract ABI

[{"type":"constructor","stateMutability":"nonpayable","inputs":[{"type":"address","name":"_cowTip","internalType":"contract ICOWTIP"},{"type":"address","name":"_feeAddress","internalType":"address"},{"type":"address","name":"_devAddress","internalType":"address"},{"type":"uint256","name":"_feePercent","internalType":"uint256"},{"type":"uint256","name":"_devPercent","internalType":"uint256"},{"type":"uint256","name":"_sharesPerSecond","internalType":"uint256"},{"type":"uint256","name":"_poolStartTime","internalType":"uint256"}]},{"type":"event","name":"Deposit","inputs":[{"type":"address","name":"user","internalType":"address","indexed":true},{"type":"uint256","name":"pid","internalType":"uint256","indexed":true},{"type":"uint256","name":"amount","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"EmergencyWithdraw","inputs":[{"type":"address","name":"user","internalType":"address","indexed":true},{"type":"uint256","name":"pid","internalType":"uint256","indexed":true},{"type":"uint256","name":"amount","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"OwnershipTransferred","inputs":[{"type":"address","name":"previousOwner","internalType":"address","indexed":true},{"type":"address","name":"newOwner","internalType":"address","indexed":true}],"anonymous":false},{"type":"event","name":"RewardPaid","inputs":[{"type":"address","name":"user","internalType":"address","indexed":true},{"type":"uint256","name":"amount","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"Withdraw","inputs":[{"type":"address","name":"user","internalType":"address","indexed":true},{"type":"uint256","name":"pid","internalType":"uint256","indexed":true},{"type":"uint256","name":"amount","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"contract IERC20"}],"name":"INC","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"MAX_SHARES_PER_SECOND","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"contract IMasterChef"}],"name":"PULSE_X_MASTERCHEF","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"add","inputs":[{"type":"uint256","name":"_allocPoint","internalType":"uint256"},{"type":"address","name":"_token","internalType":"contract IERC20"},{"type":"bool","name":"_withUpdate","internalType":"bool"},{"type":"uint256","name":"_lastRewardTime","internalType":"uint256"},{"type":"uint16","name":"_depositFeeBP","internalType":"uint16"},{"type":"uint16","name":"_withdrawFeeBP","internalType":"uint16"},{"type":"address","name":"_externalFarm","internalType":"contract IMasterChef"},{"type":"uint256","name":"_externalPid","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"contract ICOWTIP"}],"name":"cowTip","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"deposit","inputs":[{"type":"uint256","name":"_pid","internalType":"uint256"},{"type":"uint256","name":"_amount","internalType":"uint256"},{"type":"address","name":"_referrer","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"depositOnBehalfOf","inputs":[{"type":"uint256","name":"_pid","internalType":"uint256"},{"type":"uint256","name":"_amount","internalType":"uint256"},{"type":"address","name":"_referrer","internalType":"address"},{"type":"address","name":"_staker","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"devAddress","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"devPercent","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"emergencyWithdraw","inputs":[{"type":"uint256","name":"_pid","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"feeAddress","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"feePercent","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"tuple[]","name":"","internalType":"struct CowTipFarm.PoolView[]","components":[{"type":"uint256","name":"pid","internalType":"uint256"},{"type":"address","name":"token","internalType":"address"},{"type":"uint256","name":"allocPoint","internalType":"uint256"},{"type":"uint256","name":"lastRewardTime","internalType":"uint256"},{"type":"uint16","name":"depositFeeBP","internalType":"uint16"},{"type":"uint16","name":"withdrawFeeBP","internalType":"uint16"},{"type":"uint256","name":"accTokensPerShare","internalType":"uint256"},{"type":"bool","name":"isStarted","internalType":"bool"},{"type":"address","name":"externalFarm","internalType":"address"},{"type":"uint256","name":"lpBalance","internalType":"uint256"},{"type":"uint256","name":"rewardsPerSecond","internalType":"uint256"}]}],"name":"getAllPoolViews","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"getExternalReward","inputs":[{"type":"uint256","name":"_pid","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"getMultiplier","inputs":[{"type":"uint256","name":"_from","internalType":"uint256"},{"type":"uint256","name":"_to","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"tuple","name":"","internalType":"struct CowTipFarm.PoolView","components":[{"type":"uint256","name":"pid","internalType":"uint256"},{"type":"address","name":"token","internalType":"address"},{"type":"uint256","name":"allocPoint","internalType":"uint256"},{"type":"uint256","name":"lastRewardTime","internalType":"uint256"},{"type":"uint16","name":"depositFeeBP","internalType":"uint16"},{"type":"uint16","name":"withdrawFeeBP","internalType":"uint16"},{"type":"uint256","name":"accTokensPerShare","internalType":"uint256"},{"type":"bool","name":"isStarted","internalType":"bool"},{"type":"address","name":"externalFarm","internalType":"address"},{"type":"uint256","name":"lpBalance","internalType":"uint256"},{"type":"uint256","name":"rewardsPerSecond","internalType":"uint256"}]}],"name":"getPoolView","inputs":[{"type":"uint256","name":"pid","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"tuple","name":"","internalType":"struct CowTipFarm.UserView","components":[{"type":"uint256","name":"pid","internalType":"uint256"},{"type":"uint256","name":"stakedAmount","internalType":"uint256"},{"type":"uint256","name":"unclaimedRewards","internalType":"uint256"},{"type":"uint256","name":"lpBalance","internalType":"uint256"},{"type":"uint256","name":"allowance","internalType":"uint256"}]}],"name":"getUserView","inputs":[{"type":"uint256","name":"pid","internalType":"uint256"},{"type":"address","name":"account","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"tuple[]","name":"","internalType":"struct CowTipFarm.UserView[]","components":[{"type":"uint256","name":"pid","internalType":"uint256"},{"type":"uint256","name":"stakedAmount","internalType":"uint256"},{"type":"uint256","name":"unclaimedRewards","internalType":"uint256"},{"type":"uint256","name":"lpBalance","internalType":"uint256"},{"type":"uint256","name":"allowance","internalType":"uint256"}]}],"name":"getUserViews","inputs":[{"type":"address","name":"account","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"massUpdatePools","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"bytes[]","name":"results","internalType":"bytes[]"}],"name":"multicall","inputs":[{"type":"bytes[]","name":"data","internalType":"bytes[]"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"owner","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"pendingShare","inputs":[{"type":"uint256","name":"_pid","internalType":"uint256"},{"type":"address","name":"_user","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"token","internalType":"contract IERC20"},{"type":"uint256","name":"allocPoint","internalType":"uint256"},{"type":"uint256","name":"lastRewardTime","internalType":"uint256"},{"type":"uint16","name":"depositFeeBP","internalType":"uint16"},{"type":"uint16","name":"withdrawFeeBP","internalType":"uint16"},{"type":"uint256","name":"accTokensPerShare","internalType":"uint256"},{"type":"bool","name":"isStarted","internalType":"bool"},{"type":"address","name":"externalFarm","internalType":"contract IMasterChef"},{"type":"uint256","name":"lpBalance","internalType":"uint256"},{"type":"uint256","name":"externalPid","internalType":"uint256"}],"name":"poolInfo","inputs":[{"type":"uint256","name":"","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"poolLength","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"poolStartTime","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"referral","inputs":[{"type":"address","name":"","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"referralEarned","inputs":[{"type":"address","name":"","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"referralRate","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"removeExternalFarm","inputs":[{"type":"uint256","name":"_pid","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"renounceOwnership","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"set","inputs":[{"type":"uint256","name":"_pid","internalType":"uint256"},{"type":"uint256","name":"_allocPoint","internalType":"uint256"},{"type":"uint16","name":"_depositFeeBP","internalType":"uint16"},{"type":"uint16","name":"_withdrawFeeBP","internalType":"uint16"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setDevAddress","inputs":[{"type":"address","name":"_devAddress","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setDevPercent","inputs":[{"type":"uint256","name":"_devPercent","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setFeeAddress","inputs":[{"type":"address","name":"_feeAddress","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setFeePercent","inputs":[{"type":"uint256","name":"_feePercent","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setReferralRate","inputs":[{"type":"uint256","name":"_referralRate","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"sharesPerSecond","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"totalAllocPoint","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"transferOwnership","inputs":[{"type":"address","name":"newOwner","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"updateEmissionRate","inputs":[{"type":"uint256","name":"_sharesPerSecond","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"updatePool","inputs":[{"type":"uint256","name":"_pid","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"amount","internalType":"uint256"},{"type":"uint256","name":"rewardDebt","internalType":"uint256"}],"name":"userInfo","inputs":[{"type":"uint256","name":"","internalType":"uint256"},{"type":"address","name":"","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"withdraw","inputs":[{"type":"uint256","name":"_pid","internalType":"uint256"},{"type":"uint256","name":"_amount","internalType":"uint256"}]}]
              

Contract Creation Code

Verify & Publish
0x608060405260006007556101f4600e553480156200001c57600080fd5b5060405162003d9f38038062003d9f8339810160408190526200003f9162000291565b60016000556200004f3362000226565b68015af1d78b58c40000821115620000995760405162461bcd60e51b81526020600482015260086024820152670e8dede40d0d2ced60c31b60448201526064015b60405180910390fd5b804210620000dd5760405162461bcd60e51b815260206004820152601060248201526f436f775469704661726d3a206c61746560801b604482015260640162000090565b6001600160a01b03861615801590620000fe57506001600160a01b03851615155b80156200011357506001600160a01b03871615155b6200016d5760405162461bcd60e51b8152602060048201526024808201527f436f775469704661726d3a205a65726f2061646472657373206e6f7420616c6c6044820152631bddd95960e21b606482015260840162000090565b6103e883111580156200018257506103e88411155b620001d05760405162461bcd60e51b815260206004820152601f60248201527f436f775469704661726d3a20496e76616c69642070657263656e746167657300604482015260640162000090565b600280546001600160a01b03199081166001600160a01b03998a161790915560098054821697891697909717909655600a80549096169490961693909317909355600b55600c91909155600d556008556200030c565b600180546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6001600160a01b03811681146200028e57600080fd5b50565b600080600080600080600060e0888a031215620002ad57600080fd5b8751620002ba8162000278565b6020890151909750620002cd8162000278565b6040890151909650620002e08162000278565b80955050606088015193506080880151925060a0880151915060c0880151905092959891949750929550565b613a83806200031c6000396000f3fe608060405234801561001057600080fd5b50600436106102e95760003560e01c806377fffea011610191578063a053ce1f116100e3578063cf4b55cb11610097578063e4932abe11610071578063e4932abe146106b0578063f2fde38b146106cb578063fc3c28af146106de57600080fd5b8063cf4b55cb1461066a578063d0c9bb591461067d578063d0d41fe11461069d57600080fd5b8063ac9650d8116100c8578063ac9650d81461062e578063acfb24b71461064e578063ca4863fd1461065757600080fd5b8063a053ce1f14610612578063a327bde41461061b57600080fd5b80638b2738ad116101455780638dbdbe6d1161011f5780638dbdbe6d14610598578063900ea587146105ab57806393f1a40b146105cb57600080fd5b80638b2738ad146105645780638da5cb5b146105745780638dbb1e3a1461058557600080fd5b80637f00ca1a116101765780637f00ca1a1461052d5780637fd6f15c146105485780638705fcd41461055157600080fd5b806377fffea0146105075780637ce3489b1461051a57600080fd5b8063441a3e701161024a5780635f96dc11116101fe5780636eaddad2116101d85780636eaddad2146104c3578063715018a6146104d65780637247959a146104de57600080fd5b80635f96dc111461049d578063630b5ba1146104a657806364757332146104ae57600080fd5b806351eb05a61161022f57806351eb05a6146104645780635312ea8e14610477578063560cde911461048a57600080fd5b8063441a3e701461043e578063457b34371461045157600080fd5b8063225b87c4116102a157806331cd61791161028657806331cd6179146103e05780633ad10ef614610400578063412753581461042b57600080fd5b8063225b87c4146103ad5780632fe1bc1c146103cd57600080fd5b80630d336591116102d25780630d3365911461031a5780631526fe271461032d57806317caf6f1146103a457600080fd5b8063081e3eda146102ee5780630ba84cd214610305575b600080fd5b6003545b6040519081526020015b60405180910390f35b610318610313366004613375565b6106e7565b005b6103186103283660046133a3565b61075a565b61034061033b366004613375565b61077e565b604080516001600160a01b039b8c168152602081019a909a5289019790975261ffff958616606089015293909416608087015260a0860191909152151560c0850152931660e0830152610100820192909252610120810191909152610140016102fc565b6102f260075481565b6103c06103bb3660046133ed565b6107fa565b6040516102fc919061340a565b6103186103db366004613375565b6108cf565b6102f26103ee3660046133ed565b60106020526000908152604090205481565b600a54610413906001600160a01b031681565b6040516001600160a01b0390911681526020016102fc565b600954610413906001600160a01b031681565b61031861044c366004613483565b610a77565b61031861045f3660046134bc565b610a97565b610318610472366004613375565b610c1f565b610318610485366004613375565b610f2f565b600254610413906001600160a01b031681565b6102f260085481565b610318611166565b6104b661118d565b6040516102fc91906135aa565b6103186104d1366004613375565b6112a7565b610318611312565b6104136104ec3660046133ed565b600f602052600090815260409020546001600160a01b031681565b6103186105153660046135fb565b611326565b610318610528366004613375565b61194d565b61041373b2ca4a66d3e57a5a9a12043b6bad28249fe302d481565b6102f2600b5481565b61031861055f3660046133ed565b6119ac565b6102f268015af1d78b58c4000081565b6001546001600160a01b0316610413565b6102f2610593366004613483565b611a45565b6103186105a6366004613685565b611a95565b6105be6105b93660046136be565b611aba565b6040516102fc91906136ee565b6105fd6105d93660046136be565b60066020908152600092835260408084209091529082529020805460019091015482565b604080519283526020830191909152016102fc565b6102f2600e5481565b610318610629366004613375565b611d08565b61064161063c366004613727565b611e5d565b6040516102fc91906137ec565b6102f2600d5481565b610318610665366004613375565b611f4b565b6102f26106783660046136be565b611faa565b61069061068b366004613375565b6120f2565b6040516102fc919061384e565b6103186106ab3660046133ed565b61236a565b610413732fa878ab3f87cc1c9737fc071108f904c0b0c95d81565b6103186106d93660046133ed565b6123f7565b6102f2600c5481565b6106ef612484565b68015af1d78b58c4000081111561074d5760405162461bcd60e51b815260206004820152600860248201527f746f6f206869676800000000000000000000000000000000000000000000000060448201526064015b60405180910390fd5b610755611166565b600d55565b6107626124de565b61076e84848484612537565b6107786001600055565b50505050565b6003818154811061078e57600080fd5b6000918252602090912060089091020180546001820154600283015460038401546004850154600586015460068701546007909701546001600160a01b0396871698509496939561ffff80851696620100009095041694929360ff83169361010090930490911691908a565b60035460609060009067ffffffffffffffff81111561081b5761081b61385d565b60405190808252806020026020018201604052801561087e57816020015b61086b6040518060a0016040528060008152602001600081526020016000815260200160008152602001600081525090565b8152602001906001900390816108395790505b50905060005b6003548110156108c8576108988185611aba565b8282815181106108aa576108aa613873565b602002602001018190525080806108c09061389f565b915050610884565b5092915050565b6108d7612484565b6000600382815481106108ec576108ec613873565b6000918252602090912060056008909202019081015490915061010090046001600160a01b03161515806109625760405162461bcd60e51b815260206004820152601f60248201527f436f775469704661726d3a204e6f2065787465726e616c4661726d20736574006044820152606401610744565b60058201546007830154604051631c57762b60e31b8152600481019190915260006024820152732fa878ab3f87cc1c9737fc071108f904c0b0c95d9161010090046001600160a01b03169063e2bbb15890604401600060405180830381600087803b1580156109d057600080fd5b505af11580156109e4573d6000803e3d6000fd5b50506040516370a0823160e01b8152306004820152600092506001600160a01b03841691506370a0823190602401602060405180830381865afa158015610a2f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a5391906138b8565b600954909150610a70906001600160a01b03848116911683612a50565b5050505050565b610a7f6124de565b610a898282612ae1565b610a936001600055565b5050565b610a9f612484565b6101908261ffff1611158015610abb57506101908161ffff1611155b610b2d5760405162461bcd60e51b815260206004820152603860248201527f436f775469704661726d3a20496e76616c6964206465706f736974206f72207760448201527f697468647261772066656520626173697320706f696e747300000000000000006064820152608401610744565b610b35611166565b600060038581548110610b4a57610b4a613873565b60009182526020909120600890910201600581015490915060ff1615610b9157610b8d84610b878360010154600754612e3790919063ffffffff16565b90612e4a565b6007555b8381600101819055508260038681548110610bae57610bae613873565b906000526020600020906008020160030160006101000a81548161ffff021916908361ffff1602179055508160038681548110610bed57610bed613873565b906000526020600020906008020160030160026101000a81548161ffff021916908361ffff1602179055505050505050565b600060038281548110610c3457610c34613873565b9060005260206000209060080201905080600201544211610c53575050565b600581015460ff16610c845760058101805460ff19166001908117909155810154600754610c8091612e4a565b6007555b60068101546000819003610c9d57504260029091015550565b60075415610f24576000610cb5836002015442611a45565b90506000610cce600d5483612e5690919063ffffffff16565b90506000610cf5600754610cef876001015485612e5690919063ffffffff16565b90612e62565b90506000600b54600c54612710610d0c91906138d1565b610d1691906138d1565b600254600a54600c549293506001600160a01b03918216926340c10f199290911690610d4b9061271090610cef908890612e56565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401600060405180830381600087803b158015610d9157600080fd5b505af1158015610da5573d6000803e3d6000fd5b5050600254600954600b546001600160a01b0392831694506340c10f199350911690610dda9061271090610cef908890612e56565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401600060405180830381600087803b158015610e2057600080fd5b505af1158015610e34573d6000803e3d6000fd5b5050600254600e546001600160a01b0390911692506340c10f1991503090610e659061271090610cef908890612e56565b610e75612710610cef8888612e56565b610e7f91906138e4565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401600060405180830381600087803b158015610ec557600080fd5b505af1158015610ed9573d6000803e3d6000fd5b50505050610f1a610f0f612710610cef84610f098a610cef670de0b6b3a76400008a612e5690919063ffffffff16565b90612e56565b600488015490612e4a565b6004870155505050505b504260029091015550565b610f376124de565b600060038281548110610f4c57610f4c613873565b60009182526020808320858452600690915260408320600890920201925081610f723390565b6001600160a01b039081168252602082019290925260400160002060058401548154919350610100900490911615159080610fef5760405162461bcd60e51b815260206004820152601e60248201527f436f775469704661726d3a205573657220686173206e6f20616d6f756e7400006044820152606401610744565b6000808455600184015581156110715760058401546007850154604051630441a3e760e41b81526004810191909152602481018390526101009091046001600160a01b03169063441a3e7090604401600060405180830381600087803b15801561105857600080fd5b505af115801561106c573d6000803e3d6000fd5b505050505b600384015462010000900461ffff16156110ef5760038401546000906110aa9061271090610cef90859062010000900461ffff16612e56565b60095486549192506110c9916001600160a01b03908116911683612a50565b6110e9336110d78484612e37565b87546001600160a01b03169190612a50565b50611105565b6111053385546001600160a01b03169083612a50565b8084600601600082825461111991906138d1565b9091555050604051818152859033907fbb757047c2b5f3974fe26b7c10f732e7bce710b0952a71082702781e62ae05959060200160405180910390a3505050506111636001600055565b50565b60035460005b81811015610a935761117d81610c1f565b6111868161389f565b905061116c565b60035460609060009067ffffffffffffffff8111156111ae576111ae61385d565b60405190808252806020026020018201604052801561125857816020015b6112456040518061016001604052806000815260200160006001600160a01b031681526020016000815260200160008152602001600061ffff168152602001600061ffff1681526020016000815260200160001515815260200160006001600160a01b0316815260200160008152602001600081525090565b8152602001906001900390816111cc5790505b50905060005b6003548110156112a157611271816120f2565b82828151811061128357611283613873565b602002602001018190525080806112999061389f565b91505061125e565b50919050565b6112af612484565b6103e881111561130d5760405162461bcd60e51b8152602060048201526024808201527f436f775469704661726d3a205a65726f2061646472657373206e6f7420616c6c6044820152631bddd95960e21b6064820152608401610744565b600c55565b61131a612484565b6113246000612e6e565b565b61132e612484565b60008790506000816001600160a01b0316630dfe16816040518163ffffffff1660e01b8152600401602060405180830381865afa158015611373573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061139791906138f7565b90506000826001600160a01b031663d21220a76040518163ffffffff1660e01b8152600401602060405180830381865afa1580156113d9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113fd91906138f7565b90506001600160a01b038516158061143157506001600160a01b03851673b2ca4a66d3e57a5a9a12043b6bad28249fe302d4145b61147d5760405162461bcd60e51b815260206004820152600e60248201527f696e636f7272656374206661726d0000000000000000000000000000000000006044820152606401610744565b6001600160a01b0382161580159061149d57506001600160a01b03811615155b6114e95760405162461bcd60e51b815260206004820152601b60248201527f436f775469704661726d3a204f6e6c79204c5020746f6b656e732000000000006044820152606401610744565b6001600160a01b038a163b6115665760405162461bcd60e51b815260206004820152602d60248201527f436f775469704661726d3a204c5020746f6b656e206d7573742062652061207660448201527f616c696420636f6e7472616374000000000000000000000000000000000000006064820152608401610744565b6001600160a01b03851615611662576040517f1526fe27000000000000000000000000000000000000000000000000000000008152600481018590526000906001600160a01b03871690631526fe2790602401608060405180830381865afa1580156115d6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115fa9190613914565b5050509050806001600160a01b03168b6001600160a01b0316146116605760405162461bcd60e51b815260206004820152601d60248201527f436f775469704661726d3a206661726d206973206e6f742076616c69640000006044820152606401610744565b505b6101908761ffff161115801561167e57506101908661ffff1611155b6116f05760405162461bcd60e51b815260206004820152603860248201527f436f775469704661726d3a20496e76616c6964206465706f736974206f72207760448201527f697468647261772066656520626173697320706f696e747300000000000000006064820152608401610744565b6116fb60048b612ecd565b156117485760405162461bcd60e51b815260206004820152601c60248201527f436f775469704661726d3a204c5020616c7265616479206164646564000000006044820152606401610744565b881561175657611756611166565b600854421015611775576008548810156117705760085497505b611781565b42881015611781574297505b600060085442101580156117955750884210155b905060036040518061014001604052808d6001600160a01b031681526020018e81526020018b81526020018a61ffff1681526020018961ffff168152602001600081526020018315158152602001886001600160a01b031681526020016000815260200187815250908060018154018082558091505060019003906000526020600020906008020160009091909190915060008201518160000160006101000a8154816001600160a01b0302191690836001600160a01b03160217905550602082015181600101556040820151816002015560608201518160030160006101000a81548161ffff021916908361ffff16021790555060808201518160030160026101000a81548161ffff021916908361ffff16021790555060a0820151816004015560c08201518160050160006101000a81548160ff02191690831515021790555060e08201518160050160016101000a8154816001600160a01b0302191690836001600160a01b0316021790555061010082015181600601556101208201518160070155505080156119335760075461192f908d612e4a565b6007555b61193e60048c612eef565b50505050505050505050505050565b611955612484565b6103e88111156119a75760405162461bcd60e51b815260206004820152601760248201527f436f775469704661726d3a20696e76616c6964206665650000000000000000006044820152606401610744565b600b55565b6119b4612484565b6001600160a01b038116611a165760405162461bcd60e51b8152602060048201526024808201527f436f775469704661726d3a205a65726f2061646472657373206e6f7420616c6c6044820152631bddd95960e21b6064820152608401610744565b6009805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0392909216919091179055565b6000818310611a5657506000611a8f565b6008548211611a6757506000611a8f565b6008548310611a8157611a7a8284612e37565b9050611a8f565b600854611a7a908390612e37565b92915050565b611a9d6124de565b33611aaa84848484612537565b50611ab56001600055565b505050565b611aec6040518060a0016040528060008152602001600081526020016000815260200160008152602001600081525090565b600060038481548110611b0157611b01613873565b600091825260208083206040805161014081018252600890940290910180546001600160a01b03908116855260018083015486860152600283015486850152600383015461ffff808216606089015262010000909104166080870152600483015460a0870152600583015460ff8116151560c088015261010090819004831660e0880152600680850154918801919091526007909301546101208701528a87529184528286209089168652835281852082518084019093528054835201549181019190915290925090611bd48686611faa565b83516040516370a0823160e01b81526001600160a01b038881166004830152929350600092909116906370a0823190602401602060405180830381865afa158015611c23573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c4791906138b8565b6040805160a0810182528981528551602082015280820185905260608101839052865191517fdd62ed3e0000000000000000000000000000000000000000000000000000000081526001600160a01b038a8116600483015230602483015293945090926080840192169063dd62ed3e90604401602060405180830381865afa158015611cd7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611cfb91906138b8565b9052979650505050505050565b611d10612484565b611d186124de565b600060038281548110611d2d57611d2d613873565b6000918252602090912060056008909202019081015490915061010090046001600160a01b0316151580611da35760405162461bcd60e51b815260206004820152601f60248201527f436f775469704661726d3a204e6f2065787465726e616c4661726d20736574006044820152606401610744565b600582015460078301546040517f5312ea8e00000000000000000000000000000000000000000000000000000000815260048101919091526101009091046001600160a01b031690635312ea8e90602401600060405180830381600087803b158015611e0e57600080fd5b505af1158015611e22573d6000803e3d6000fd5b505050600590920180547fffffffffffffffffffffff0000000000000000000000000000000000000000ff1690555061116390506001600055565b60608167ffffffffffffffff811115611e7857611e7861385d565b604051908082528060200260200182016040528015611eab57816020015b6060815260200190600190039081611e965790505b50905060005b828110156108c857611f1b30858584818110611ecf57611ecf613873565b9050602002810190611ee19190613953565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250612f0492505050565b828281518110611f2d57611f2d613873565b60200260200101819052508080611f439061389f565b915050611eb1565b611f53612484565b6101f4811115611fa55760405162461bcd60e51b815260206004820152601460248201527f436f775469704661726d3a20546f6f20686967680000000000000000000000006044820152606401610744565b600e55565b60008060038481548110611fc057611fc0613873565b60009182526020808320878452600680835260408086206001600160a01b038a16875290935291909320600460089093029093019182015490820154600283015492945090914211801561201357508015155b156120b6576000612028856002015442611a45565b90506000600b54600c5461271061203f91906138d1565b61204991906138d1565b90506000612062600d5484612e5690919063ffffffff16565b9050600061208d612710610cef85610f09600754610cef8e6001015489612e5690919063ffffffff16565b90506120af6120a886610cef84670de0b6b3a7640000612e56565b8790612e4a565b9550505050505b6120e783600101546120e1670de0b6b3a7640000610cef868860000154612e5690919063ffffffff16565b90612e37565b979650505050505050565b61216b6040518061016001604052806000815260200160006001600160a01b031681526020016000815260200160008152602001600061ffff168152602001600061ffff1681526020016000815260200160001515815260200160006001600160a01b0316815260200160008152602001600081525090565b60035482106121bc5760405162461bcd60e51b815260206004820152601c60248201527f436f775469704661726d3a20706964206f7574206f662072616e6765000000006044820152606401610744565b6000600383815481106121d1576121d1613873565b600091825260208083206040805161014081018252600890940290910180546001600160a01b039081168552600182015493850193909352600281015491840191909152600381015461ffff808216606086015262010000909104166080840152600481015460a0840152600581015460ff8116151560c08501526101009081900490921660e084015260068101549183019190915260070154610120820152600b54600c5491935090612287906127106138d1565b61229191906138d1565b905060006007546000036122a7575060006122d3565b6122d0612710610cef84610f09600754610cef600d548a60200151612e5690919063ffffffff16565b90505b60405180610160016040528086815260200184600001516001600160a01b031681526020018460200151815260200184604001518152602001846060015161ffff168152602001846080015161ffff1681526020018460a0015181526020018460c00151151581526020018460e001516001600160a01b031681526020018461010001518152602001828152509350505050919050565b612372612484565b6001600160a01b0381166123c85760405162461bcd60e51b815260206004820152601f60248201527f436f775469704661726d3a20496e76616c69642070657263656e7461676573006044820152606401610744565b600a805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0392909216919091179055565b6123ff612484565b6001600160a01b03811661247b5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f64647265737300000000000000000000000000000000000000000000000000006064820152608401610744565b61116381612e6e565b6001546001600160a01b031633146113245760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610744565b6002600054036125305760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610744565b6002600055565b6001600160a01b038181166000908152600f602052604090205416612621576001600160a01b038216158015906125805750806001600160a01b0316826001600160a01b031614155b801561259557506001600160a01b0382163014155b6125e15760405162461bcd60e51b815260206004820152601c60248201527f436f775469704661726d3a20496e76616c6964207265666572726572000000006044820152606401610744565b6001600160a01b038181166000908152600f60205260409020805473ffffffffffffffffffffffffffffffffffffffff191691841691909117905561263f565b6001600160a01b038082166000908152600f60205260409020541691505b60006003858154811061265457612654613873565b600091825260208083208884526006825260408085206001600160a01b038816865290925292206008909102909101915061268e86610c1f565b80541561278b5760006126c682600101546120e1670de0b6b3a7640000610cef87600401548760000154612e5690919063ffffffff16565b90508015612789576000612710600e54836126e191906139a1565b6126eb91906139b8565b9050801561273a576001600160a01b0386166000908152601060205260409020546127179082906138e4565b6001600160a01b03871660009081526010602052604090205561273a8682612f29565b6127448583612f29565b846001600160a01b03167fe2403640ba68fed3a2f88b7557551d1993f84b99bb10ff833f0cf8db0c5e04868360405161277f91815260200190565b60405180910390a2505b505b84156127a8576127a83383546001600160a01b0316903088612fd4565b600382015461ffff16156128285760038201546000906127d59061271090610cef90899061ffff16612e56565b60095484549192506127f4916001600160a01b03908116911683612a50565b81546128069082906120e19089612e4a565b8255600683015461281d9082906120e19089612e4a565b60068401555061284b565b80546128349086612e4a565b815560068201546128459086612e4a565b60068301555b6004820154815461286991670de0b6b3a764000091610cef91612e56565b6001820155600582015461010090046001600160a01b031615612a045781546040516370a0823160e01b81523060048201526000916001600160a01b0316906370a0823190602401602060405180830381865afa1580156128ce573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128f291906138b8565b600584015484546040517f095ea7b30000000000000000000000000000000000000000000000000000000081526101009092046001600160a01b039081166004840181905260248401859052939450169063095ea7b3906044016020604051808303816000875af115801561296b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061298f91906139da565b5060058401546007850154604051631c57762b60e31b81526004810191909152602481018490526101009091046001600160a01b03169063e2bbb15890604401600060405180830381600087803b1580156129e957600080fd5b505af11580156129fd573d6000803e3d6000fd5b5050505050505b85836001600160a01b03167f90890809c654f11d6e72a28fa60149770a0d11ec6c92319d6ceb2bb0a4ea1a1587604051612a4091815260200190565b60405180910390a3505050505050565b6040516001600160a01b038316602482015260448101829052611ab59084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b60408051601f198184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff166001600160e01b031990931692909217909152613025565b6000339050600060038481548110612afb57612afb613873565b600091825260208083208784526006825260408085206001600160a01b03881686529092529220805460089092029092019250841115612b7d5760405162461bcd60e51b815260206004820152601f60248201527f436f775469704661726d3a205573657220616d6f756e7420746f6f206c6f77006044820152606401610744565b612b8685610c1f565b6001600160a01b038084166000908152600f60205260408120546001840154600486015485549290941693612bcc926120e191670de0b6b3a764000091610cef91612e56565b90508015612c8f576000612710600e5483612be791906139a1565b612bf191906139b8565b90508015612c40576001600160a01b038316600090815260106020526040902054612c1d9082906138e4565b6001600160a01b038416600090815260106020526040902055612c408382612f29565b612c4a8683612f29565b856001600160a01b03167fe2403640ba68fed3a2f88b7557551d1993f84b99bb10ff833f0cf8db0c5e048683604051612c8591815260200190565b60405180910390a2505b8515612daf578254612ca19087612e37565b8355600584015461010090046001600160a01b031615612d2d5760058401546007850154604051630441a3e760e41b81526004810191909152602481018890526101009091046001600160a01b03169063441a3e7090604401600060405180830381600087803b158015612d1457600080fd5b505af1158015612d28573d6000803e3d6000fd5b505050505b600384015462010000900461ffff1615612d99576003840154600090612d669061271090610cef908a9062010000900461ffff16612e56565b6009548654919250612d85916001600160a01b03908116911683612a50565b612d93866110d78984612e37565b50612daf565b8354612daf906001600160a01b03168688612a50565b60048401548354612dcd91670de0b6b3a764000091610cef91612e56565b836001018190555085846006016000828254612de991906138d1565b909155505060405186815287906001600160a01b038716907ff279e6a1f5e320cca91135676d9cb6e44ca8a08c0b88342bcdb1144f6511b5689060200160405180910390a350505050505050565b6000612e4382846138d1565b9392505050565b6000612e4382846138e4565b6000612e4382846139a1565b6000612e4382846139b8565b600180546001600160a01b0383811673ffffffffffffffffffffffffffffffffffffffff19831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6001600160a01b03811660009081526001830160205260408120541515612e43565b6000612e43836001600160a01b03841661310d565b6060612e438383604051806060016040528060278152602001613a276027913961315c565b6002546040516370a0823160e01b81523060048201526000916001600160a01b0316906370a0823190602401602060405180830381865afa158015612f72573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f9691906138b8565b90508015611ab55780821115612fbd57600254611ab5906001600160a01b03168483612a50565b600254611ab5906001600160a01b03168484612a50565b6040516001600160a01b03808516602483015283166044820152606481018290526107789085907f23b872dd0000000000000000000000000000000000000000000000000000000090608401612a95565b600061307a826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166131d49092919063ffffffff16565b905080516000148061309b57508080602001905181019061309b91906139da565b611ab55760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610744565b600081815260018301602052604081205461315457508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155611a8f565b506000611a8f565b6060600080856001600160a01b03168560405161317991906139f7565b600060405180830381855af49150503d80600081146131b4576040519150601f19603f3d011682016040523d82523d6000602084013e6131b9565b606091505b50915091506131ca868383876131eb565b9695505050505050565b60606131e38484600085613264565b949350505050565b6060831561325a578251600003613253576001600160a01b0385163b6132535760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610744565b50816131e3565b6131e3838361334b565b6060824710156132dc5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610744565b600080866001600160a01b031685876040516132f891906139f7565b60006040518083038185875af1925050503d8060008114613335576040519150601f19603f3d011682016040523d82523d6000602084013e61333a565b606091505b50915091506120e7878383876131eb565b81511561335b5781518083602001fd5b8060405162461bcd60e51b81526004016107449190613a13565b60006020828403121561338757600080fd5b5035919050565b6001600160a01b038116811461116357600080fd5b600080600080608085870312156133b957600080fd5b843593506020850135925060408501356133d28161338e565b915060608501356133e28161338e565b939692955090935050565b6000602082840312156133ff57600080fd5b8135612e438161338e565b6020808252825182820181905260009190848201906040850190845b818110156134775761346483855180518252602081015160208301526040810151604083015260608101516060830152608081015160808301525050565b9284019260a09290920191600101613426565b50909695505050505050565b6000806040838503121561349657600080fd5b50508035926020909101359150565b803561ffff811681146134b757600080fd5b919050565b600080600080608085870312156134d257600080fd5b84359350602085013592506134e9604086016134a5565b91506134f7606086016134a5565b905092959194509250565b80518252602081015161352060208401826001600160a01b03169052565b506040810151604083015260608101516060830152608081015161354a608084018261ffff169052565b5060a081015161356060a084018261ffff169052565b5060c081015160c083015260e081015161357e60e084018215159052565b50610100818101516001600160a01b031690830152610120808201519083015261014090810151910152565b6020808252825182820181905260009190848201906040850190845b81811015613477576135d9838551613502565b9284019261016092909201916001016135c6565b801515811461116357600080fd5b600080600080600080600080610100898b03121561361857600080fd5b88359750602089013561362a8161338e565b9650604089013561363a816135ed565b95506060890135945061364f60808a016134a5565b935061365d60a08a016134a5565b925060c089013561366d8161338e565b8092505060e089013590509295985092959890939650565b60008060006060848603121561369a57600080fd5b833592506020840135915060408401356136b38161338e565b809150509250925092565b600080604083850312156136d157600080fd5b8235915060208301356136e38161338e565b809150509250929050565b60a08101611a8f828480518252602081015160208301526040810151604083015260608101516060830152608081015160808301525050565b6000806020838503121561373a57600080fd5b823567ffffffffffffffff8082111561375257600080fd5b818501915085601f83011261376657600080fd5b81358181111561377557600080fd5b8660208260051b850101111561378a57600080fd5b60209290920196919550909350505050565b60005b838110156137b757818101518382015260200161379f565b50506000910152565b600081518084526137d881602086016020860161379c565b601f01601f19169290920160200192915050565b6000602080830181845280855180835260408601915060408160051b870101925083870160005b8281101561384157603f1988860301845261382f8583516137c0565b94509285019290850190600101613813565b5092979650505050505050565b6101608101611a8f8284613502565b634e487b7160e01b600052604160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b6000600182016138b1576138b1613889565b5060010190565b6000602082840312156138ca57600080fd5b5051919050565b81810381811115611a8f57611a8f613889565b80820180821115611a8f57611a8f613889565b60006020828403121561390957600080fd5b8151612e438161338e565b6000806000806080858703121561392a57600080fd5b84516139358161338e565b60208601516040870151606090970151919890975090945092505050565b6000808335601e1984360301811261396a57600080fd5b83018035915067ffffffffffffffff82111561398557600080fd5b60200191503681900382131561399a57600080fd5b9250929050565b8082028115828204841417611a8f57611a8f613889565b6000826139d557634e487b7160e01b600052601260045260246000fd5b500490565b6000602082840312156139ec57600080fd5b8151612e43816135ed565b60008251613a0981846020870161379c565b9190910192915050565b602081526000612e4360208301846137c056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a26469706673582212201f0f5ebe62b471e63651e73268042fadb21165a1fef2b3cebddda1a13afa122e64736f6c6343000813003300000000000000000000000090732c0abc7b44f6e00c4cc90d29293d1dd01d8b000000000000000000000000ab9747b9ac5adc9c8ab282d96415284cb52308a70000000000000000000000005c42454748a8273c8381e24b87f0fec36d8499e300000000000000000000000000000000000000000000000000000000000003e800000000000000000000000000000000000000000000000000000000000003e800000000000000000000000000000000000000000000000029a2241af62c0000000000000000000000000000000000000000000000000000000000006570a890

Deployed ByteCode

0x608060405234801561001057600080fd5b50600436106102e95760003560e01c806377fffea011610191578063a053ce1f116100e3578063cf4b55cb11610097578063e4932abe11610071578063e4932abe146106b0578063f2fde38b146106cb578063fc3c28af146106de57600080fd5b8063cf4b55cb1461066a578063d0c9bb591461067d578063d0d41fe11461069d57600080fd5b8063ac9650d8116100c8578063ac9650d81461062e578063acfb24b71461064e578063ca4863fd1461065757600080fd5b8063a053ce1f14610612578063a327bde41461061b57600080fd5b80638b2738ad116101455780638dbdbe6d1161011f5780638dbdbe6d14610598578063900ea587146105ab57806393f1a40b146105cb57600080fd5b80638b2738ad146105645780638da5cb5b146105745780638dbb1e3a1461058557600080fd5b80637f00ca1a116101765780637f00ca1a1461052d5780637fd6f15c146105485780638705fcd41461055157600080fd5b806377fffea0146105075780637ce3489b1461051a57600080fd5b8063441a3e701161024a5780635f96dc11116101fe5780636eaddad2116101d85780636eaddad2146104c3578063715018a6146104d65780637247959a146104de57600080fd5b80635f96dc111461049d578063630b5ba1146104a657806364757332146104ae57600080fd5b806351eb05a61161022f57806351eb05a6146104645780635312ea8e14610477578063560cde911461048a57600080fd5b8063441a3e701461043e578063457b34371461045157600080fd5b8063225b87c4116102a157806331cd61791161028657806331cd6179146103e05780633ad10ef614610400578063412753581461042b57600080fd5b8063225b87c4146103ad5780632fe1bc1c146103cd57600080fd5b80630d336591116102d25780630d3365911461031a5780631526fe271461032d57806317caf6f1146103a457600080fd5b8063081e3eda146102ee5780630ba84cd214610305575b600080fd5b6003545b6040519081526020015b60405180910390f35b610318610313366004613375565b6106e7565b005b6103186103283660046133a3565b61075a565b61034061033b366004613375565b61077e565b604080516001600160a01b039b8c168152602081019a909a5289019790975261ffff958616606089015293909416608087015260a0860191909152151560c0850152931660e0830152610100820192909252610120810191909152610140016102fc565b6102f260075481565b6103c06103bb3660046133ed565b6107fa565b6040516102fc919061340a565b6103186103db366004613375565b6108cf565b6102f26103ee3660046133ed565b60106020526000908152604090205481565b600a54610413906001600160a01b031681565b6040516001600160a01b0390911681526020016102fc565b600954610413906001600160a01b031681565b61031861044c366004613483565b610a77565b61031861045f3660046134bc565b610a97565b610318610472366004613375565b610c1f565b610318610485366004613375565b610f2f565b600254610413906001600160a01b031681565b6102f260085481565b610318611166565b6104b661118d565b6040516102fc91906135aa565b6103186104d1366004613375565b6112a7565b610318611312565b6104136104ec3660046133ed565b600f602052600090815260409020546001600160a01b031681565b6103186105153660046135fb565b611326565b610318610528366004613375565b61194d565b61041373b2ca4a66d3e57a5a9a12043b6bad28249fe302d481565b6102f2600b5481565b61031861055f3660046133ed565b6119ac565b6102f268015af1d78b58c4000081565b6001546001600160a01b0316610413565b6102f2610593366004613483565b611a45565b6103186105a6366004613685565b611a95565b6105be6105b93660046136be565b611aba565b6040516102fc91906136ee565b6105fd6105d93660046136be565b60066020908152600092835260408084209091529082529020805460019091015482565b604080519283526020830191909152016102fc565b6102f2600e5481565b610318610629366004613375565b611d08565b61064161063c366004613727565b611e5d565b6040516102fc91906137ec565b6102f2600d5481565b610318610665366004613375565b611f4b565b6102f26106783660046136be565b611faa565b61069061068b366004613375565b6120f2565b6040516102fc919061384e565b6103186106ab3660046133ed565b61236a565b610413732fa878ab3f87cc1c9737fc071108f904c0b0c95d81565b6103186106d93660046133ed565b6123f7565b6102f2600c5481565b6106ef612484565b68015af1d78b58c4000081111561074d5760405162461bcd60e51b815260206004820152600860248201527f746f6f206869676800000000000000000000000000000000000000000000000060448201526064015b60405180910390fd5b610755611166565b600d55565b6107626124de565b61076e84848484612537565b6107786001600055565b50505050565b6003818154811061078e57600080fd5b6000918252602090912060089091020180546001820154600283015460038401546004850154600586015460068701546007909701546001600160a01b0396871698509496939561ffff80851696620100009095041694929360ff83169361010090930490911691908a565b60035460609060009067ffffffffffffffff81111561081b5761081b61385d565b60405190808252806020026020018201604052801561087e57816020015b61086b6040518060a0016040528060008152602001600081526020016000815260200160008152602001600081525090565b8152602001906001900390816108395790505b50905060005b6003548110156108c8576108988185611aba565b8282815181106108aa576108aa613873565b602002602001018190525080806108c09061389f565b915050610884565b5092915050565b6108d7612484565b6000600382815481106108ec576108ec613873565b6000918252602090912060056008909202019081015490915061010090046001600160a01b03161515806109625760405162461bcd60e51b815260206004820152601f60248201527f436f775469704661726d3a204e6f2065787465726e616c4661726d20736574006044820152606401610744565b60058201546007830154604051631c57762b60e31b8152600481019190915260006024820152732fa878ab3f87cc1c9737fc071108f904c0b0c95d9161010090046001600160a01b03169063e2bbb15890604401600060405180830381600087803b1580156109d057600080fd5b505af11580156109e4573d6000803e3d6000fd5b50506040516370a0823160e01b8152306004820152600092506001600160a01b03841691506370a0823190602401602060405180830381865afa158015610a2f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a5391906138b8565b600954909150610a70906001600160a01b03848116911683612a50565b5050505050565b610a7f6124de565b610a898282612ae1565b610a936001600055565b5050565b610a9f612484565b6101908261ffff1611158015610abb57506101908161ffff1611155b610b2d5760405162461bcd60e51b815260206004820152603860248201527f436f775469704661726d3a20496e76616c6964206465706f736974206f72207760448201527f697468647261772066656520626173697320706f696e747300000000000000006064820152608401610744565b610b35611166565b600060038581548110610b4a57610b4a613873565b60009182526020909120600890910201600581015490915060ff1615610b9157610b8d84610b878360010154600754612e3790919063ffffffff16565b90612e4a565b6007555b8381600101819055508260038681548110610bae57610bae613873565b906000526020600020906008020160030160006101000a81548161ffff021916908361ffff1602179055508160038681548110610bed57610bed613873565b906000526020600020906008020160030160026101000a81548161ffff021916908361ffff1602179055505050505050565b600060038281548110610c3457610c34613873565b9060005260206000209060080201905080600201544211610c53575050565b600581015460ff16610c845760058101805460ff19166001908117909155810154600754610c8091612e4a565b6007555b60068101546000819003610c9d57504260029091015550565b60075415610f24576000610cb5836002015442611a45565b90506000610cce600d5483612e5690919063ffffffff16565b90506000610cf5600754610cef876001015485612e5690919063ffffffff16565b90612e62565b90506000600b54600c54612710610d0c91906138d1565b610d1691906138d1565b600254600a54600c549293506001600160a01b03918216926340c10f199290911690610d4b9061271090610cef908890612e56565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401600060405180830381600087803b158015610d9157600080fd5b505af1158015610da5573d6000803e3d6000fd5b5050600254600954600b546001600160a01b0392831694506340c10f199350911690610dda9061271090610cef908890612e56565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401600060405180830381600087803b158015610e2057600080fd5b505af1158015610e34573d6000803e3d6000fd5b5050600254600e546001600160a01b0390911692506340c10f1991503090610e659061271090610cef908890612e56565b610e75612710610cef8888612e56565b610e7f91906138e4565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401600060405180830381600087803b158015610ec557600080fd5b505af1158015610ed9573d6000803e3d6000fd5b50505050610f1a610f0f612710610cef84610f098a610cef670de0b6b3a76400008a612e5690919063ffffffff16565b90612e56565b600488015490612e4a565b6004870155505050505b504260029091015550565b610f376124de565b600060038281548110610f4c57610f4c613873565b60009182526020808320858452600690915260408320600890920201925081610f723390565b6001600160a01b039081168252602082019290925260400160002060058401548154919350610100900490911615159080610fef5760405162461bcd60e51b815260206004820152601e60248201527f436f775469704661726d3a205573657220686173206e6f20616d6f756e7400006044820152606401610744565b6000808455600184015581156110715760058401546007850154604051630441a3e760e41b81526004810191909152602481018390526101009091046001600160a01b03169063441a3e7090604401600060405180830381600087803b15801561105857600080fd5b505af115801561106c573d6000803e3d6000fd5b505050505b600384015462010000900461ffff16156110ef5760038401546000906110aa9061271090610cef90859062010000900461ffff16612e56565b60095486549192506110c9916001600160a01b03908116911683612a50565b6110e9336110d78484612e37565b87546001600160a01b03169190612a50565b50611105565b6111053385546001600160a01b03169083612a50565b8084600601600082825461111991906138d1565b9091555050604051818152859033907fbb757047c2b5f3974fe26b7c10f732e7bce710b0952a71082702781e62ae05959060200160405180910390a3505050506111636001600055565b50565b60035460005b81811015610a935761117d81610c1f565b6111868161389f565b905061116c565b60035460609060009067ffffffffffffffff8111156111ae576111ae61385d565b60405190808252806020026020018201604052801561125857816020015b6112456040518061016001604052806000815260200160006001600160a01b031681526020016000815260200160008152602001600061ffff168152602001600061ffff1681526020016000815260200160001515815260200160006001600160a01b0316815260200160008152602001600081525090565b8152602001906001900390816111cc5790505b50905060005b6003548110156112a157611271816120f2565b82828151811061128357611283613873565b602002602001018190525080806112999061389f565b91505061125e565b50919050565b6112af612484565b6103e881111561130d5760405162461bcd60e51b8152602060048201526024808201527f436f775469704661726d3a205a65726f2061646472657373206e6f7420616c6c6044820152631bddd95960e21b6064820152608401610744565b600c55565b61131a612484565b6113246000612e6e565b565b61132e612484565b60008790506000816001600160a01b0316630dfe16816040518163ffffffff1660e01b8152600401602060405180830381865afa158015611373573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061139791906138f7565b90506000826001600160a01b031663d21220a76040518163ffffffff1660e01b8152600401602060405180830381865afa1580156113d9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113fd91906138f7565b90506001600160a01b038516158061143157506001600160a01b03851673b2ca4a66d3e57a5a9a12043b6bad28249fe302d4145b61147d5760405162461bcd60e51b815260206004820152600e60248201527f696e636f7272656374206661726d0000000000000000000000000000000000006044820152606401610744565b6001600160a01b0382161580159061149d57506001600160a01b03811615155b6114e95760405162461bcd60e51b815260206004820152601b60248201527f436f775469704661726d3a204f6e6c79204c5020746f6b656e732000000000006044820152606401610744565b6001600160a01b038a163b6115665760405162461bcd60e51b815260206004820152602d60248201527f436f775469704661726d3a204c5020746f6b656e206d7573742062652061207660448201527f616c696420636f6e7472616374000000000000000000000000000000000000006064820152608401610744565b6001600160a01b03851615611662576040517f1526fe27000000000000000000000000000000000000000000000000000000008152600481018590526000906001600160a01b03871690631526fe2790602401608060405180830381865afa1580156115d6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115fa9190613914565b5050509050806001600160a01b03168b6001600160a01b0316146116605760405162461bcd60e51b815260206004820152601d60248201527f436f775469704661726d3a206661726d206973206e6f742076616c69640000006044820152606401610744565b505b6101908761ffff161115801561167e57506101908661ffff1611155b6116f05760405162461bcd60e51b815260206004820152603860248201527f436f775469704661726d3a20496e76616c6964206465706f736974206f72207760448201527f697468647261772066656520626173697320706f696e747300000000000000006064820152608401610744565b6116fb60048b612ecd565b156117485760405162461bcd60e51b815260206004820152601c60248201527f436f775469704661726d3a204c5020616c7265616479206164646564000000006044820152606401610744565b881561175657611756611166565b600854421015611775576008548810156117705760085497505b611781565b42881015611781574297505b600060085442101580156117955750884210155b905060036040518061014001604052808d6001600160a01b031681526020018e81526020018b81526020018a61ffff1681526020018961ffff168152602001600081526020018315158152602001886001600160a01b031681526020016000815260200187815250908060018154018082558091505060019003906000526020600020906008020160009091909190915060008201518160000160006101000a8154816001600160a01b0302191690836001600160a01b03160217905550602082015181600101556040820151816002015560608201518160030160006101000a81548161ffff021916908361ffff16021790555060808201518160030160026101000a81548161ffff021916908361ffff16021790555060a0820151816004015560c08201518160050160006101000a81548160ff02191690831515021790555060e08201518160050160016101000a8154816001600160a01b0302191690836001600160a01b0316021790555061010082015181600601556101208201518160070155505080156119335760075461192f908d612e4a565b6007555b61193e60048c612eef565b50505050505050505050505050565b611955612484565b6103e88111156119a75760405162461bcd60e51b815260206004820152601760248201527f436f775469704661726d3a20696e76616c6964206665650000000000000000006044820152606401610744565b600b55565b6119b4612484565b6001600160a01b038116611a165760405162461bcd60e51b8152602060048201526024808201527f436f775469704661726d3a205a65726f2061646472657373206e6f7420616c6c6044820152631bddd95960e21b6064820152608401610744565b6009805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0392909216919091179055565b6000818310611a5657506000611a8f565b6008548211611a6757506000611a8f565b6008548310611a8157611a7a8284612e37565b9050611a8f565b600854611a7a908390612e37565b92915050565b611a9d6124de565b33611aaa84848484612537565b50611ab56001600055565b505050565b611aec6040518060a0016040528060008152602001600081526020016000815260200160008152602001600081525090565b600060038481548110611b0157611b01613873565b600091825260208083206040805161014081018252600890940290910180546001600160a01b03908116855260018083015486860152600283015486850152600383015461ffff808216606089015262010000909104166080870152600483015460a0870152600583015460ff8116151560c088015261010090819004831660e0880152600680850154918801919091526007909301546101208701528a87529184528286209089168652835281852082518084019093528054835201549181019190915290925090611bd48686611faa565b83516040516370a0823160e01b81526001600160a01b038881166004830152929350600092909116906370a0823190602401602060405180830381865afa158015611c23573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c4791906138b8565b6040805160a0810182528981528551602082015280820185905260608101839052865191517fdd62ed3e0000000000000000000000000000000000000000000000000000000081526001600160a01b038a8116600483015230602483015293945090926080840192169063dd62ed3e90604401602060405180830381865afa158015611cd7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611cfb91906138b8565b9052979650505050505050565b611d10612484565b611d186124de565b600060038281548110611d2d57611d2d613873565b6000918252602090912060056008909202019081015490915061010090046001600160a01b0316151580611da35760405162461bcd60e51b815260206004820152601f60248201527f436f775469704661726d3a204e6f2065787465726e616c4661726d20736574006044820152606401610744565b600582015460078301546040517f5312ea8e00000000000000000000000000000000000000000000000000000000815260048101919091526101009091046001600160a01b031690635312ea8e90602401600060405180830381600087803b158015611e0e57600080fd5b505af1158015611e22573d6000803e3d6000fd5b505050600590920180547fffffffffffffffffffffff0000000000000000000000000000000000000000ff1690555061116390506001600055565b60608167ffffffffffffffff811115611e7857611e7861385d565b604051908082528060200260200182016040528015611eab57816020015b6060815260200190600190039081611e965790505b50905060005b828110156108c857611f1b30858584818110611ecf57611ecf613873565b9050602002810190611ee19190613953565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250612f0492505050565b828281518110611f2d57611f2d613873565b60200260200101819052508080611f439061389f565b915050611eb1565b611f53612484565b6101f4811115611fa55760405162461bcd60e51b815260206004820152601460248201527f436f775469704661726d3a20546f6f20686967680000000000000000000000006044820152606401610744565b600e55565b60008060038481548110611fc057611fc0613873565b60009182526020808320878452600680835260408086206001600160a01b038a16875290935291909320600460089093029093019182015490820154600283015492945090914211801561201357508015155b156120b6576000612028856002015442611a45565b90506000600b54600c5461271061203f91906138d1565b61204991906138d1565b90506000612062600d5484612e5690919063ffffffff16565b9050600061208d612710610cef85610f09600754610cef8e6001015489612e5690919063ffffffff16565b90506120af6120a886610cef84670de0b6b3a7640000612e56565b8790612e4a565b9550505050505b6120e783600101546120e1670de0b6b3a7640000610cef868860000154612e5690919063ffffffff16565b90612e37565b979650505050505050565b61216b6040518061016001604052806000815260200160006001600160a01b031681526020016000815260200160008152602001600061ffff168152602001600061ffff1681526020016000815260200160001515815260200160006001600160a01b0316815260200160008152602001600081525090565b60035482106121bc5760405162461bcd60e51b815260206004820152601c60248201527f436f775469704661726d3a20706964206f7574206f662072616e6765000000006044820152606401610744565b6000600383815481106121d1576121d1613873565b600091825260208083206040805161014081018252600890940290910180546001600160a01b039081168552600182015493850193909352600281015491840191909152600381015461ffff808216606086015262010000909104166080840152600481015460a0840152600581015460ff8116151560c08501526101009081900490921660e084015260068101549183019190915260070154610120820152600b54600c5491935090612287906127106138d1565b61229191906138d1565b905060006007546000036122a7575060006122d3565b6122d0612710610cef84610f09600754610cef600d548a60200151612e5690919063ffffffff16565b90505b60405180610160016040528086815260200184600001516001600160a01b031681526020018460200151815260200184604001518152602001846060015161ffff168152602001846080015161ffff1681526020018460a0015181526020018460c00151151581526020018460e001516001600160a01b031681526020018461010001518152602001828152509350505050919050565b612372612484565b6001600160a01b0381166123c85760405162461bcd60e51b815260206004820152601f60248201527f436f775469704661726d3a20496e76616c69642070657263656e7461676573006044820152606401610744565b600a805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0392909216919091179055565b6123ff612484565b6001600160a01b03811661247b5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f64647265737300000000000000000000000000000000000000000000000000006064820152608401610744565b61116381612e6e565b6001546001600160a01b031633146113245760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610744565b6002600054036125305760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610744565b6002600055565b6001600160a01b038181166000908152600f602052604090205416612621576001600160a01b038216158015906125805750806001600160a01b0316826001600160a01b031614155b801561259557506001600160a01b0382163014155b6125e15760405162461bcd60e51b815260206004820152601c60248201527f436f775469704661726d3a20496e76616c6964207265666572726572000000006044820152606401610744565b6001600160a01b038181166000908152600f60205260409020805473ffffffffffffffffffffffffffffffffffffffff191691841691909117905561263f565b6001600160a01b038082166000908152600f60205260409020541691505b60006003858154811061265457612654613873565b600091825260208083208884526006825260408085206001600160a01b038816865290925292206008909102909101915061268e86610c1f565b80541561278b5760006126c682600101546120e1670de0b6b3a7640000610cef87600401548760000154612e5690919063ffffffff16565b90508015612789576000612710600e54836126e191906139a1565b6126eb91906139b8565b9050801561273a576001600160a01b0386166000908152601060205260409020546127179082906138e4565b6001600160a01b03871660009081526010602052604090205561273a8682612f29565b6127448583612f29565b846001600160a01b03167fe2403640ba68fed3a2f88b7557551d1993f84b99bb10ff833f0cf8db0c5e04868360405161277f91815260200190565b60405180910390a2505b505b84156127a8576127a83383546001600160a01b0316903088612fd4565b600382015461ffff16156128285760038201546000906127d59061271090610cef90899061ffff16612e56565b60095484549192506127f4916001600160a01b03908116911683612a50565b81546128069082906120e19089612e4a565b8255600683015461281d9082906120e19089612e4a565b60068401555061284b565b80546128349086612e4a565b815560068201546128459086612e4a565b60068301555b6004820154815461286991670de0b6b3a764000091610cef91612e56565b6001820155600582015461010090046001600160a01b031615612a045781546040516370a0823160e01b81523060048201526000916001600160a01b0316906370a0823190602401602060405180830381865afa1580156128ce573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128f291906138b8565b600584015484546040517f095ea7b30000000000000000000000000000000000000000000000000000000081526101009092046001600160a01b039081166004840181905260248401859052939450169063095ea7b3906044016020604051808303816000875af115801561296b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061298f91906139da565b5060058401546007850154604051631c57762b60e31b81526004810191909152602481018490526101009091046001600160a01b03169063e2bbb15890604401600060405180830381600087803b1580156129e957600080fd5b505af11580156129fd573d6000803e3d6000fd5b5050505050505b85836001600160a01b03167f90890809c654f11d6e72a28fa60149770a0d11ec6c92319d6ceb2bb0a4ea1a1587604051612a4091815260200190565b60405180910390a3505050505050565b6040516001600160a01b038316602482015260448101829052611ab59084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b60408051601f198184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff166001600160e01b031990931692909217909152613025565b6000339050600060038481548110612afb57612afb613873565b600091825260208083208784526006825260408085206001600160a01b03881686529092529220805460089092029092019250841115612b7d5760405162461bcd60e51b815260206004820152601f60248201527f436f775469704661726d3a205573657220616d6f756e7420746f6f206c6f77006044820152606401610744565b612b8685610c1f565b6001600160a01b038084166000908152600f60205260408120546001840154600486015485549290941693612bcc926120e191670de0b6b3a764000091610cef91612e56565b90508015612c8f576000612710600e5483612be791906139a1565b612bf191906139b8565b90508015612c40576001600160a01b038316600090815260106020526040902054612c1d9082906138e4565b6001600160a01b038416600090815260106020526040902055612c408382612f29565b612c4a8683612f29565b856001600160a01b03167fe2403640ba68fed3a2f88b7557551d1993f84b99bb10ff833f0cf8db0c5e048683604051612c8591815260200190565b60405180910390a2505b8515612daf578254612ca19087612e37565b8355600584015461010090046001600160a01b031615612d2d5760058401546007850154604051630441a3e760e41b81526004810191909152602481018890526101009091046001600160a01b03169063441a3e7090604401600060405180830381600087803b158015612d1457600080fd5b505af1158015612d28573d6000803e3d6000fd5b505050505b600384015462010000900461ffff1615612d99576003840154600090612d669061271090610cef908a9062010000900461ffff16612e56565b6009548654919250612d85916001600160a01b03908116911683612a50565b612d93866110d78984612e37565b50612daf565b8354612daf906001600160a01b03168688612a50565b60048401548354612dcd91670de0b6b3a764000091610cef91612e56565b836001018190555085846006016000828254612de991906138d1565b909155505060405186815287906001600160a01b038716907ff279e6a1f5e320cca91135676d9cb6e44ca8a08c0b88342bcdb1144f6511b5689060200160405180910390a350505050505050565b6000612e4382846138d1565b9392505050565b6000612e4382846138e4565b6000612e4382846139a1565b6000612e4382846139b8565b600180546001600160a01b0383811673ffffffffffffffffffffffffffffffffffffffff19831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6001600160a01b03811660009081526001830160205260408120541515612e43565b6000612e43836001600160a01b03841661310d565b6060612e438383604051806060016040528060278152602001613a276027913961315c565b6002546040516370a0823160e01b81523060048201526000916001600160a01b0316906370a0823190602401602060405180830381865afa158015612f72573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f9691906138b8565b90508015611ab55780821115612fbd57600254611ab5906001600160a01b03168483612a50565b600254611ab5906001600160a01b03168484612a50565b6040516001600160a01b03808516602483015283166044820152606481018290526107789085907f23b872dd0000000000000000000000000000000000000000000000000000000090608401612a95565b600061307a826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166131d49092919063ffffffff16565b905080516000148061309b57508080602001905181019061309b91906139da565b611ab55760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610744565b600081815260018301602052604081205461315457508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155611a8f565b506000611a8f565b6060600080856001600160a01b03168560405161317991906139f7565b600060405180830381855af49150503d80600081146131b4576040519150601f19603f3d011682016040523d82523d6000602084013e6131b9565b606091505b50915091506131ca868383876131eb565b9695505050505050565b60606131e38484600085613264565b949350505050565b6060831561325a578251600003613253576001600160a01b0385163b6132535760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610744565b50816131e3565b6131e3838361334b565b6060824710156132dc5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610744565b600080866001600160a01b031685876040516132f891906139f7565b60006040518083038185875af1925050503d8060008114613335576040519150601f19603f3d011682016040523d82523d6000602084013e61333a565b606091505b50915091506120e7878383876131eb565b81511561335b5781518083602001fd5b8060405162461bcd60e51b81526004016107449190613a13565b60006020828403121561338757600080fd5b5035919050565b6001600160a01b038116811461116357600080fd5b600080600080608085870312156133b957600080fd5b843593506020850135925060408501356133d28161338e565b915060608501356133e28161338e565b939692955090935050565b6000602082840312156133ff57600080fd5b8135612e438161338e565b6020808252825182820181905260009190848201906040850190845b818110156134775761346483855180518252602081015160208301526040810151604083015260608101516060830152608081015160808301525050565b9284019260a09290920191600101613426565b50909695505050505050565b6000806040838503121561349657600080fd5b50508035926020909101359150565b803561ffff811681146134b757600080fd5b919050565b600080600080608085870312156134d257600080fd5b84359350602085013592506134e9604086016134a5565b91506134f7606086016134a5565b905092959194509250565b80518252602081015161352060208401826001600160a01b03169052565b506040810151604083015260608101516060830152608081015161354a608084018261ffff169052565b5060a081015161356060a084018261ffff169052565b5060c081015160c083015260e081015161357e60e084018215159052565b50610100818101516001600160a01b031690830152610120808201519083015261014090810151910152565b6020808252825182820181905260009190848201906040850190845b81811015613477576135d9838551613502565b9284019261016092909201916001016135c6565b801515811461116357600080fd5b600080600080600080600080610100898b03121561361857600080fd5b88359750602089013561362a8161338e565b9650604089013561363a816135ed565b95506060890135945061364f60808a016134a5565b935061365d60a08a016134a5565b925060c089013561366d8161338e565b8092505060e089013590509295985092959890939650565b60008060006060848603121561369a57600080fd5b833592506020840135915060408401356136b38161338e565b809150509250925092565b600080604083850312156136d157600080fd5b8235915060208301356136e38161338e565b809150509250929050565b60a08101611a8f828480518252602081015160208301526040810151604083015260608101516060830152608081015160808301525050565b6000806020838503121561373a57600080fd5b823567ffffffffffffffff8082111561375257600080fd5b818501915085601f83011261376657600080fd5b81358181111561377557600080fd5b8660208260051b850101111561378a57600080fd5b60209290920196919550909350505050565b60005b838110156137b757818101518382015260200161379f565b50506000910152565b600081518084526137d881602086016020860161379c565b601f01601f19169290920160200192915050565b6000602080830181845280855180835260408601915060408160051b870101925083870160005b8281101561384157603f1988860301845261382f8583516137c0565b94509285019290850190600101613813565b5092979650505050505050565b6101608101611a8f8284613502565b634e487b7160e01b600052604160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b6000600182016138b1576138b1613889565b5060010190565b6000602082840312156138ca57600080fd5b5051919050565b81810381811115611a8f57611a8f613889565b80820180821115611a8f57611a8f613889565b60006020828403121561390957600080fd5b8151612e438161338e565b6000806000806080858703121561392a57600080fd5b84516139358161338e565b60208601516040870151606090970151919890975090945092505050565b6000808335601e1984360301811261396a57600080fd5b83018035915067ffffffffffffffff82111561398557600080fd5b60200191503681900382131561399a57600080fd5b9250929050565b8082028115828204841417611a8f57611a8f613889565b6000826139d557634e487b7160e01b600052601260045260246000fd5b500490565b6000602082840312156139ec57600080fd5b8151612e43816135ed565b60008251613a0981846020870161379c565b9190910192915050565b602081526000612e4360208301846137c056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a26469706673582212201f0f5ebe62b471e63651e73268042fadb21165a1fef2b3cebddda1a13afa122e64736f6c63430008130033