More Info
Private Name Tags
ContractCreator
Latest 22 from a total of 22 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Emergency Withdr... | 13142051 | 35 hrs ago | IN | 0 S | 0.0031167 | ||||
Harvest | 13134064 | 36 hrs ago | IN | 0.69631909 S | 0.00778281 | ||||
Deposit | 13127891 | 37 hrs ago | IN | 0 S | 0.00629903 | ||||
Deposit | 13122346 | 38 hrs ago | IN | 0 S | 0.00781219 | ||||
Deposit | 13120567 | 38 hrs ago | IN | 0 S | 0.00781219 | ||||
Withdraw | 13120488 | 38 hrs ago | IN | 0 S | 0.00490557 | ||||
Withdraw | 13120395 | 38 hrs ago | IN | 0 S | 0.00564743 | ||||
Withdraw | 13116449 | 39 hrs ago | IN | 0 S | 0.00478438 | ||||
Withdraw | 13116161 | 39 hrs ago | IN | 0 S | 0.00774749 | ||||
Withdraw | 13115207 | 39 hrs ago | IN | 0 S | 0.00698329 | ||||
Deposit | 12763171 | 3 days ago | IN | 0 S | 0.00961768 | ||||
Deposit | 12763081 | 3 days ago | IN | 0 S | 0.00666275 | ||||
Deposit | 12763047 | 3 days ago | IN | 0 S | 0.00666275 | ||||
Add | 12762888 | 3 days ago | IN | 0 S | 0.0173056 | ||||
Add | 12762822 | 3 days ago | IN | 0 S | 0.01620928 | ||||
Harvest | 12567364 | 4 days ago | IN | 1 S | 0.00778281 | ||||
Withdraw | 12550636 | 4 days ago | IN | 0 S | 0.00473894 | ||||
Deposit | 12550593 | 4 days ago | IN | 0 S | 0.00778402 | ||||
Set | 12546622 | 4 days ago | IN | 0 S | 0.00782148 | ||||
Withdraw | 12544907 | 4 days ago | IN | 0 S | 0.0069323 | ||||
Deposit | 12544361 | 4 days ago | IN | 0 S | 0.00663459 | ||||
Set S Hare Oracl... | 12524003 | 4 days ago | IN | 0 S | 0.00168033 |
Loading...
Loading
This contract may be a proxy contract. Click on More Options and select Is this a proxy? to confirm and enable the "Read as Proxy" & "Write as Proxy" tabs.
Contract Source Code Verified (Exact Match)
Contract Name:
ShareRewardPoolV3
Compiler Version
v0.8.28+commit.7893614a
Contract Source Code (Solidity)
/** *Submitted for verification at SonicScan.org on 2025-03-08 */ // 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; } } /** * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612]. * * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't * need to send a transaction, and thus is not required to hold Ether at all. * * ==== Security Considerations * * There are two important considerations concerning the use of `permit`. The first is that a valid permit signature * expresses an allowance, and it should not be assumed to convey additional meaning. In particular, it should not be * considered as an intention to spend the allowance in any specific way. The second is that because permits have * built-in replay protection and can be submitted by anyone, they can be frontrun. A protocol that uses permits should * take this into consideration and allow a `permit` call to fail. Combining these two aspects, a pattern that may be * generally recommended is: * * ```solidity * function doThingWithPermit(..., uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s) public { * try token.permit(msg.sender, address(this), value, deadline, v, r, s) {} catch {} * doThing(..., value); * } * * function doThing(..., uint256 value) public { * token.safeTransferFrom(msg.sender, address(this), value); * ... * } * ``` * * Observe that: 1) `msg.sender` is used as the owner, leaving no ambiguity as to the signer intent, and 2) the use of * `try/catch` allows the permit to fail and makes the code tolerant to frontrunning. (See also * {SafeERC20-safeTransferFrom}). * * Additionally, note that smart contract wallets (such as Argent or Safe) are not able to produce permit signatures, so * contracts should have entry points that don't rely on permit. */ interface IERC20Permit { /** * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens, * given ``owner``'s signed approval. * * IMPORTANT: The same issues {IERC20-approve} has related to transaction * ordering also apply here. * * Emits an {Approval} event. * * Requirements: * * - `spender` cannot be the zero address. * - `deadline` must be a timestamp in the future. * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner` * over the EIP712-formatted function arguments. * - the signature must use ``owner``'s current nonce (see {nonces}). * * For more information on the signature format, see the * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP * section]. * * CAUTION: See Security Considerations above. */ function permit( address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) external; /** * @dev Returns the current nonce for `owner`. This value must be * included whenever a signature is generated for {permit}. * * Every successful call to {permit} increases ``owner``'s nonce by one. This * prevents a signature from being used multiple times. */ function nonces(address owner) external view returns (uint256); /** * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}. */ // solhint-disable-next-line func-name-mixedcase function DOMAIN_SEPARATOR() external view returns (bytes32); } /** * @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); } /** * @dev Interface for the optional metadata functions from the ERC20 standard. * * _Available since v4.1._ */ interface IERC20Metadata is IERC20 { /** * @dev Returns the name of the token. */ function name() external view returns (string memory); /** * @dev Returns the symbol of the token. */ function symbol() external view returns (string memory); /** * @dev Returns the decimals places of the token. */ function decimals() external view returns (uint8); } /** * @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)); } } /** * @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); } } } // 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; } } } /** * @dev Interface of the ERC-4626 "Tokenized Vault Standard", as defined in * https://eips.ethereum.org/EIPS/eip-4626[ERC-4626]. */ interface IERC4626 is IERC20, IERC20Metadata { event Deposit(address indexed sender, address indexed owner, uint256 assets, uint256 shares); event Withdraw( address indexed sender, address indexed receiver, address indexed owner, uint256 assets, uint256 shares ); /** * @dev Returns the address of the underlying token used for the Vault for accounting, depositing, and withdrawing. * * - MUST be an ERC-20 token contract. * - MUST NOT revert. */ function asset() external view returns (address assetTokenAddress); /** * @dev Returns the total amount of the underlying asset that is “managed” by Vault. * * - SHOULD include any compounding that occurs from yield. * - MUST be inclusive of any fees that are charged against assets in the Vault. * - MUST NOT revert. */ function totalAssets() external view returns (uint256 totalManagedAssets); /** * @dev Returns the amount of shares that the Vault would exchange for the amount of assets provided, in an ideal * scenario where all the conditions are met. * * - MUST NOT be inclusive of any fees that are charged against assets in the Vault. * - MUST NOT show any variations depending on the caller. * - MUST NOT reflect slippage or other on-chain conditions, when performing the actual exchange. * - MUST NOT revert. * * NOTE: This calculation MAY NOT reflect the “per-user” price-per-share, and instead should reflect the * “average-user’s” price-per-share, meaning what the average user should expect to see when exchanging to and * from. */ function convertToShares(uint256 assets) external view returns (uint256 shares); /** * @dev Returns the amount of assets that the Vault would exchange for the amount of shares provided, in an ideal * scenario where all the conditions are met. * * - MUST NOT be inclusive of any fees that are charged against assets in the Vault. * - MUST NOT show any variations depending on the caller. * - MUST NOT reflect slippage or other on-chain conditions, when performing the actual exchange. * - MUST NOT revert. * * NOTE: This calculation MAY NOT reflect the “per-user” price-per-share, and instead should reflect the * “average-user’s” price-per-share, meaning what the average user should expect to see when exchanging to and * from. */ function convertToAssets(uint256 shares) external view returns (uint256 assets); /** * @dev Returns the maximum amount of the underlying asset that can be deposited into the Vault for the receiver, * through a deposit call. * * - MUST return a limited value if receiver is subject to some deposit limit. * - MUST return 2 ** 256 - 1 if there is no limit on the maximum amount of assets that may be deposited. * - MUST NOT revert. */ function maxDeposit(address receiver) external view returns (uint256 maxAssets); /** * @dev Allows an on-chain or off-chain user to simulate the effects of their deposit at the current block, given * current on-chain conditions. * * - MUST return as close to and no more than the exact amount of Vault shares that would be minted in a deposit * call in the same transaction. I.e. deposit should return the same or more shares as previewDeposit if called * in the same transaction. * - MUST NOT account for deposit limits like those returned from maxDeposit and should always act as though the * deposit would be accepted, regardless if the user has enough tokens approved, etc. * - MUST be inclusive of deposit fees. Integrators should be aware of the existence of deposit fees. * - MUST NOT revert. * * NOTE: any unfavorable discrepancy between convertToShares and previewDeposit SHOULD be considered slippage in * share price or some other type of condition, meaning the depositor will lose assets by depositing. */ function previewDeposit(uint256 assets) external view returns (uint256 shares); /** * @dev Mints shares Vault shares to receiver by depositing exactly amount of underlying tokens. * * - MUST emit the Deposit event. * - MAY support an additional flow in which the underlying tokens are owned by the Vault contract before the * deposit execution, and are accounted for during deposit. * - MUST revert if all of assets cannot be deposited (due to deposit limit being reached, slippage, the user not * approving enough underlying tokens to the Vault contract, etc). * * NOTE: most implementations will require pre-approval of the Vault with the Vault’s underlying asset token. */ function deposit(uint256 assets, address receiver) external returns (uint256 shares); /** * @dev Returns the maximum amount of the Vault shares that can be minted for the receiver, through a mint call. * - MUST return a limited value if receiver is subject to some mint limit. * - MUST return 2 ** 256 - 1 if there is no limit on the maximum amount of shares that may be minted. * - MUST NOT revert. */ function maxMint(address receiver) external view returns (uint256 maxShares); /** * @dev Allows an on-chain or off-chain user to simulate the effects of their mint at the current block, given * current on-chain conditions. * * - MUST return as close to and no fewer than the exact amount of assets that would be deposited in a mint call * in the same transaction. I.e. mint should return the same or fewer assets as previewMint if called in the * same transaction. * - MUST NOT account for mint limits like those returned from maxMint and should always act as though the mint * would be accepted, regardless if the user has enough tokens approved, etc. * - MUST be inclusive of deposit fees. Integrators should be aware of the existence of deposit fees. * - MUST NOT revert. * * NOTE: any unfavorable discrepancy between convertToAssets and previewMint SHOULD be considered slippage in * share price or some other type of condition, meaning the depositor will lose assets by minting. */ function previewMint(uint256 shares) external view returns (uint256 assets); /** * @dev Mints exactly shares Vault shares to receiver by depositing amount of underlying tokens. * * - MUST emit the Deposit event. * - MAY support an additional flow in which the underlying tokens are owned by the Vault contract before the mint * execution, and are accounted for during mint. * - MUST revert if all of shares cannot be minted (due to deposit limit being reached, slippage, the user not * approving enough underlying tokens to the Vault contract, etc). * * NOTE: most implementations will require pre-approval of the Vault with the Vault’s underlying asset token. */ function mint(uint256 shares, address receiver) external returns (uint256 assets); /** * @dev Returns the maximum amount of the underlying asset that can be withdrawn from the owner balance in the * Vault, through a withdraw call. * * - MUST return a limited value if owner is subject to some withdrawal limit or timelock. * - MUST NOT revert. */ function maxWithdraw(address owner) external view returns (uint256 maxAssets); /** * @dev Allows an on-chain or off-chain user to simulate the effects of their withdrawal at the current block, * given current on-chain conditions. * * - MUST return as close to and no fewer than the exact amount of Vault shares that would be burned in a withdraw * call in the same transaction. I.e. withdraw should return the same or fewer shares as previewWithdraw if * called * in the same transaction. * - MUST NOT account for withdrawal limits like those returned from maxWithdraw and should always act as though * the withdrawal would be accepted, regardless if the user has enough shares, etc. * - MUST be inclusive of withdrawal fees. Integrators should be aware of the existence of withdrawal fees. * - MUST NOT revert. * * NOTE: any unfavorable discrepancy between convertToShares and previewWithdraw SHOULD be considered slippage in * share price or some other type of condition, meaning the depositor will lose assets by depositing. */ function previewWithdraw(uint256 assets) external view returns (uint256 shares); /** * @dev Burns shares from owner and sends exactly assets of underlying tokens to receiver. * * - MUST emit the Withdraw event. * - MAY support an additional flow in which the underlying tokens are owned by the Vault contract before the * withdraw execution, and are accounted for during withdraw. * - MUST revert if all of assets cannot be withdrawn (due to withdrawal limit being reached, slippage, the owner * not having enough shares, etc). * * Note that some implementations will require pre-requesting to the Vault before a withdrawal may be performed. * Those methods should be performed separately. */ function withdraw(uint256 assets, address receiver, address owner) external returns (uint256 shares); /** * @dev Returns the maximum amount of Vault shares that can be redeemed from the owner balance in the Vault, * through a redeem call. * * - MUST return a limited value if owner is subject to some withdrawal limit or timelock. * - MUST return balanceOf(owner) if owner is not subject to any withdrawal limit or timelock. * - MUST NOT revert. */ function maxRedeem(address owner) external view returns (uint256 maxShares); /** * @dev Allows an on-chain or off-chain user to simulate the effects of their redeemption at the current block, * given current on-chain conditions. * * - MUST return as close to and no more than the exact amount of assets that would be withdrawn in a redeem call * in the same transaction. I.e. redeem should return the same or more assets as previewRedeem if called in the * same transaction. * - MUST NOT account for redemption limits like those returned from maxRedeem and should always act as though the * redemption would be accepted, regardless if the user has enough shares, etc. * - MUST be inclusive of withdrawal fees. Integrators should be aware of the existence of withdrawal fees. * - MUST NOT revert. * * NOTE: any unfavorable discrepancy between convertToAssets and previewRedeem SHOULD be considered slippage in * share price or some other type of condition, meaning the depositor will lose assets by redeeming. */ function previewRedeem(uint256 shares) external view returns (uint256 assets); /** * @dev Burns exactly shares from owner and sends assets of underlying tokens to receiver. * * - MUST emit the Withdraw event. * - MAY support an additional flow in which the underlying tokens are owned by the Vault contract before the * redeem execution, and are accounted for during redeem. * - MUST revert if all of shares cannot be redeemed (due to withdrawal limit being reached, slippage, the owner * not having enough shares, etc). * * NOTE: some implementations will require pre-requesting to the Vault before a withdrawal may be performed. * Those methods should be performed separately. */ function redeem(uint256 shares, address receiver, address owner) external returns (uint256 assets); } interface IShadowGauge { error ZERO_AMOUNT(); error CANT_NOTIFY_STAKE(); error REWARD_TOO_HIGH(); error NOT_GREATER_THAN_REMAINING(uint256 amount, uint256 remaining); error TOKEN_ERROR(address token); error NOT_WHITELISTED(); error NOT_AUTHORIZED(); event Deposit(address indexed from, uint256 amount); event Withdraw(address indexed from, uint256 amount); event NotifyReward( address indexed from, address indexed reward, uint256 amount ); event ClaimRewards( address indexed from, address indexed reward, uint256 amount ); event RewardWhitelisted(address indexed reward, bool whitelisted); /// @notice Get the amount of stakingToken deposited by an account function balanceOf(address) external view returns (uint256); /// @notice returns an array with all the addresses of the rewards /// @return _rewards array of addresses for rewards function rewardsList() external view returns (address[] memory _rewards); /// @notice number of different rewards the gauge has facilitated that are 'active' /// @return _length the number of individual rewards function rewardsListLength() external view returns (uint256 _length); /// @notice returns the last time the reward was modified or periodFinish if the reward has ended /// @param token address of the token /// @return ltra last time reward applicable function lastTimeRewardApplicable( address token ) external view returns (uint256 ltra); /// @notice displays the data struct of rewards for a token /// @param token the address of the token /// @return data rewards struct function rewardData( address token ) external view returns (Reward memory data); /// @notice calculates the amount of tokens earned for an address /// @param token address of the token to check /// @param account address to check /// @return _reward amount of token claimable function earned( address token, address account ) external view returns (uint256 _reward); /// @notice claims rewards (shadow + any external LP Incentives) /// @param account the address to claim for /// @param tokens an array of the tokens to claim function getReward(address account, address[] calldata tokens) external; /// @notice claims all rewards and instant exits xshadow into shadow function getRewardAndExit( address account, address[] calldata tokens ) external; /// @notice calculates the token amounts earned per lp token /// @param token address of the token to check /// @return rpt reward per token function rewardPerToken(address token) external view returns (uint256 rpt); /// @notice deposit all LP tokens from msg.sender's wallet to the gauge function depositAll() external; /// @param recipient the address of who to deposit on behalf of /// @param amount the amount of LP tokens to withdraw function depositFor(address recipient, uint256 amount) external; /// @notice deposit LP tokens to the gauge /// @param amount the amount of LP tokens to withdraw function deposit(uint256 amount) external; /// @notice withdraws all fungible LP tokens from legacy gauges function withdrawAll() external; /// @notice withdraws fungible LP tokens from legacy gauges /// @param amount the amount of LP tokens to withdraw function withdraw(uint256 amount) external; /// @notice calculates how many tokens are left to be distributed /// @dev reduces per second /// @param token the address of the token function left(address token) external view returns (uint256); /// @notice add a reward to the whitelist /// @param _reward address of the reward function whitelistReward(address _reward) external; /// @notice remove rewards from the whitelist /// @param _reward address of the reward function removeRewardWhitelist(address _reward) external; /** * @notice amount must be greater than left() for the token, this is to prevent griefing attacks * @notice notifying rewards is completely permissionless * @notice if nobody registers for a newly added reward for the period it will remain in the contract indefinitely */ function notifyRewardAmount(address token, uint256 amount) external; struct Reward { /// @dev tokens per second uint256 rewardRate; /// @dev 7 days after start uint256 periodFinish; uint256 lastUpdateTime; uint256 rewardPerTokenStored; } /// @notice checks if a reward is whitelisted /// @param reward the address of the reward /// @return true if the reward is whitelisted, false otherwise function isWhitelisted(address reward) external view returns (bool); } interface IShadowVoter { error ACTIVE_GAUGE(address gauge); error GAUGE_INACTIVE(address gauge); error ALREADY_WHITELISTED(address token); error NOT_AUTHORIZED(address caller); error NOT_WHITELISTED(); error NOT_POOL(); error NOT_INIT(); error LENGTH_MISMATCH(); error NO_GAUGE(); error ALREADY_DISTRIBUTED(address gauge, uint256 period); error ZERO_VOTE(address pool); error RATIO_TOO_HIGH(uint256 _xRatio); error VOTE_UNSUCCESSFUL(); event GaugeCreated( address indexed gauge, address creator, address feeDistributor, address indexed pool ); event GaugeKilled(address indexed gauge); event GaugeRevived(address indexed gauge); event Voted(address indexed owner, uint256 weight, address indexed pool); event Abstained(address indexed owner, uint256 weight); event Deposit( address indexed lp, address indexed gauge, address indexed owner, uint256 amount ); event Withdraw( address indexed lp, address indexed gauge, address indexed owner, uint256 amount ); event NotifyReward( address indexed sender, address indexed reward, uint256 amount ); event DistributeReward( address indexed sender, address indexed gauge, uint256 amount ); event EmissionsRatio( address indexed caller, uint256 oldRatio, uint256 newRatio ); event NewGovernor(address indexed sender, address indexed governor); event Whitelisted(address indexed whitelister, address indexed token); event WhitelistRevoked( address indexed forbidder, address indexed token, bool status ); event MainTickSpacingChanged( address indexed token0, address indexed token1, int24 indexed newMainTickSpacing ); event Poke(address indexed user); function initialize( address _shadow, address _legacyFactory, address _gauges, address _feeDistributorFactory, address _minter, address _msig, address _xShadow, address _clFactory, address _clGaugeFactory, address _nfpManager, address _feeRecipientFactory, address _voteModule, address _launcherPlugin ) external; /// @notice denominator basis function BASIS() external view returns (uint256); /// @notice ratio of xShadow emissions globally function xRatio() external view returns (uint256); /// @notice xShadow contract address function xShadow() external view returns (address); /// @notice legacy factory address (uni-v2/stableswap) function legacyFactory() external view returns (address); /// @notice concentrated liquidity factory function clFactory() external view returns (address); /// @notice gauge factory for CL function clGaugeFactory() external view returns (address); /// @notice legacy fee recipient factory function feeRecipientFactory() external view returns (address); /// @notice peripheral NFPManager contract function nfpManager() external view returns (address); /// @notice returns the address of the current governor /// @return _governor address of the governor function governor() external view returns (address _governor); /// @notice the address of the vote module /// @return _voteModule the vote module contract address function voteModule() external view returns (address _voteModule); /// @notice address of the central access Hub function accessHub() external view returns (address); /// @notice the address of the shadow launcher plugin to enable third party launchers /// @return _launcherPlugin the address of the plugin function launcherPlugin() external view returns (address _launcherPlugin); /// @notice distributes emissions from the minter to the voter /// @param amount the amount of tokens to notify function notifyRewardAmount(uint256 amount) external; /// @notice distributes the emissions for a specific gauge /// @param _gauge the gauge address function distribute(address _gauge) external; /// @notice returns the address of the gauge factory /// @param _gaugeFactory gauge factory address function gaugeFactory() external view returns (address _gaugeFactory); /// @notice returns the address of the feeDistributor factory /// @return _feeDistributorFactory feeDist factory address function feeDistributorFactory() external view returns (address _feeDistributorFactory); /// @notice returns the address of the minter contract /// @return _minter address of the minter function minter() external view returns (address _minter); /// @notice check if the gauge is active for governance use /// @param _gauge address of the gauge /// @return _trueOrFalse if the gauge is alive function isAlive(address _gauge) external view returns (bool _trueOrFalse); /// @notice allows the token to be paired with other whitelisted assets to participate in governance /// @param _token the address of the token function whitelist(address _token) external; /// @notice effectively disqualifies a token from governance /// @param _token the address of the token function revokeWhitelist(address _token) external; /// @notice returns if the address is a gauge /// @param gauge address of the gauge /// @return _trueOrFalse boolean if the address is a gauge function isGauge(address gauge) external view returns (bool _trueOrFalse); /// @notice disable a gauge from governance /// @param _gauge address of the gauge function killGauge(address _gauge) external; /// @notice re-activate a dead gauge /// @param _gauge address of the gauge function reviveGauge(address _gauge) external; /// @notice re-cast a tokenID's votes /// @param owner address of the owner function poke(address owner) external; /// @notice sets the main tickspacing of a token pairing /// @param tokenA address of tokenA /// @param tokenB address of tokenB /// @param tickSpacing the main tickspacing to set to function setMainTickSpacing( address tokenA, address tokenB, int24 tickSpacing ) external; /// @notice returns if the address is a fee distributor /// @param _feeDistributor address of the feeDist /// @return _trueOrFalse if the address is a fee distributor function isFeeDistributor( address _feeDistributor ) external view returns (bool _trueOrFalse); /// @notice returns the address of the emission's token /// @return _shadow emissions token contract address function shadow() external view returns (address _shadow); /// @notice returns the address of the pool's gauge, if any /// @param _pool pool address /// @return _gauge gauge address function gaugeForPool(address _pool) external view returns (address _gauge); /// @notice returns the address of the pool's feeDistributor, if any /// @param _gauge address of the gauge /// @return _feeDistributor address of the pool's feedist function feeDistributorForGauge( address _gauge ) external view returns (address _feeDistributor); /// @notice returns the new toPool that was redirected fromPool /// @param fromPool address of the original pool /// @return toPool the address of the redirected pool function poolRedirect( address fromPool ) external view returns (address toPool); /// @notice returns the gauge address of a CL pool /// @param tokenA address of token A in the pair /// @param tokenB address of token B in the pair /// @param tickSpacing tickspacing of the pool /// @return gauge address of the gauge function gaugeForClPool( address tokenA, address tokenB, int24 tickSpacing ) external view returns (address gauge); /// @notice returns the array of all tickspacings for the tokenA/tokenB combination /// @param tokenA address of token A in the pair /// @param tokenB address of token B in the pair /// @return _ts array of all the tickspacings function tickSpacingsForPair( address tokenA, address tokenB ) external view returns (int24[] memory _ts); /// @notice returns the main tickspacing used in the gauge/governance process /// @param tokenA address of token A in the pair /// @param tokenB address of token B in the pair /// @return _ts the main tickspacing function mainTickSpacingForPair( address tokenA, address tokenB ) external view returns (int24 _ts); /// @notice returns the block.timestamp divided by 1 week in seconds /// @return period the period used for gauges function getPeriod() external view returns (uint256 period); /// @notice cast a vote to direct emissions to gauges and earn incentives /// @param owner address of the owner /// @param _pools the list of pools to vote on /// @param _weights an arbitrary weight per pool which will be normalized to 100% regardless of numerical inputs function vote( address owner, address[] calldata _pools, uint256[] calldata _weights ) external; /// @notice reset the vote of an address /// @param owner address of the owner function reset(address owner) external; /// @notice set the governor address /// @param _governor the new governor address function setGovernor(address _governor) external; /// @notice recover stuck emissions /// @param _gauge the gauge address /// @param _period the period function stuckEmissionsRecovery(address _gauge, uint256 _period) external; /// @notice whitelists extra rewards for a gauge /// @param _gauge the gauge to whitelist rewards to /// @param _reward the reward to whitelist function whitelistGaugeRewards(address _gauge, address _reward) external; /// @notice removes a reward from the gauge whitelist /// @param _gauge the gauge to remove the whitelist from /// @param _reward the reward to remove from the whitelist function removeGaugeRewardWhitelist( address _gauge, address _reward ) external; /// @notice creates a legacy gauge for the pool /// @param _pool pool's address /// @return _gauge address of the new gauge function createGauge(address _pool) external returns (address _gauge); /// @notice create a concentrated liquidity gauge /// @param tokenA the address of tokenA /// @param tokenB the address of tokenB /// @param tickSpacing the tickspacing of the pool /// @return _clGauge address of the new gauge function createCLGauge( address tokenA, address tokenB, int24 tickSpacing ) external returns (address _clGauge); /// @notice claim concentrated liquidity gauge rewards for specific NFP token ids /// @param _gauges array of gauges /// @param _tokens two dimensional array for the tokens to claim /// @param _nfpTokenIds two dimensional array for the NFPs function claimClGaugeRewards( address[] calldata _gauges, address[][] calldata _tokens, uint256[][] calldata _nfpTokenIds ) external; /// @notice claim arbitrary rewards from specific feeDists /// @param owner address of the owner /// @param _feeDistributors address of the feeDists /// @param _tokens two dimensional array for the tokens to claim function claimIncentives( address owner, address[] calldata _feeDistributors, address[][] calldata _tokens ) external; /// @notice claim arbitrary rewards from specific gauges /// @param _gauges address of the gauges /// @param _tokens two dimensional array for the tokens to claim function claimRewards( address[] calldata _gauges, address[][] calldata _tokens ) external; /// @notice claim arbitrary rewards from specific legacy gauges, and exit to shadow /// @param _gauges address of the gauges /// @param _tokens two dimensional array for the tokens to claim function claimLegacyRewardsAndExit( address[] calldata _gauges, address[][] calldata _tokens ) external; /// @notice distribute emissions to a gauge for a specific period /// @param _gauge address of the gauge /// @param _period value of the period function distributeForPeriod(address _gauge, uint256 _period) external; /// @notice attempt distribution of emissions to all gauges function distributeAll() external; /// @notice distribute emissions to gauges by index /// @param startIndex start of the loop /// @param endIndex end of the loop function batchDistributeByIndex( uint256 startIndex, uint256 endIndex ) external; /// @notice returns the votes cast for a tokenID /// @param owner address of the owner /// @return votes an array of votes casted /// @return weights an array of the weights casted per pool function getVotes( address owner, uint256 period ) external view returns (address[] memory votes, uint256[] memory weights); /// @notice returns an array of all the gauges /// @return _gauges the array of gauges function getAllGauges() external view returns (address[] memory _gauges); /// @notice returns an array of all the feeDists /// @return _feeDistributors the array of feeDists function getAllFeeDistributors() external view returns (address[] memory _feeDistributors); /// @notice sets the xShadowRatio default function setGlobalRatio(uint256 _xRatio) external; /// @notice whether the token is whitelisted in governance function isWhitelisted(address _token) external view returns (bool _tf); /// @notice function for removing malicious or stuffed tokens function removeFeeDistributorReward( address _feeDist, address _token ) external; } interface ISwapxGauge { function notifyRewardAmount(address token, uint amount) external; // function getReward(address account, address[] memory tokens) external; function getReward(address account) external; function getReward() external; function deposit(uint256 amount) external; function withdraw(uint256 amount) external; function claimFees() external returns (uint claimed0, uint claimed1); function left(address token) external view returns (uint); function rewardRate(address _pair) external view returns (uint); function balanceOf(address _account) external view returns (uint); function isForPair() external view returns (bool); function totalSupply() external view returns (uint); function earned(address token, address account) external view returns (uint); } interface ISwapxVoter { function gauges(address _pool) external view returns (address); } interface IX33 is IERC20 { /// @dev parameters passed to the aggregator swap struct AggregatorParams { address aggregator; // address of the whitelisted aggregator address tokenIn; // token to swap from uint256 amountIn; // amount of tokenIn to swap uint256 minAmountOut; // minimum amount of tokenOut to receive bytes callData; // encoded swap calldata } /** * Error strings */ error ZERO(); error NOT_ENOUGH(); error NOT_CONFORMED_TO_SCALE(uint256); error NOT_ACCESSHUB(address); error LOCKED(); error REBASE_IN_PROGRESS(); error AGGREGATOR_REVERTED(bytes); error AMOUNT_OUT_TOO_LOW(uint256); error AGGREGATOR_NOT_WHITELISTED(address); error FORBIDDEN_TOKEN(address); event Entered(address indexed user, uint256 amount, uint256 ratioAtDeposit); event Exited(address indexed user, uint256 _outAmount, uint256 ratioAtWithdrawal); event NewOperator(address _oldOperator, address _newOperator); event Compounded(uint256 oldRatio, uint256 newRatio, uint256 amount); event SwappedBribe(address indexed operator, address indexed tokenIn, uint256 amountIn, uint256 amountOut); event Rebased(uint256 oldRatio, uint256 newRatio, uint256 amount); /// @notice Event emitted when an aggregator's whitelist status changes event AggregatorWhitelistUpdated(address aggregator, bool status); event Unlocked(uint256 _ts); event UpdatedIndex(uint256 _index); event ClaimedIncentives(address[] feeDistributors, address[][] tokens); /// @notice submits the optimized votes for the epoch function submitVotes(address[] calldata _pools, uint256[] calldata _weights) external; /// @notice swap function using aggregators to process rewards into SHADOW function swapIncentiveViaAggregator(AggregatorParams calldata _params) external; /// @notice claims the rebase accrued to x33 function claimRebase() external; /// @notice compounds any existing SHADOW within the contract function compound() external; /// @notice direct claim function claimIncentives(address[] calldata _feeDistributors, address[][] calldata _tokens) external; /// @notice rescue stuck tokens function rescue(address _token, uint256 _amount) external; /// @notice allows the operator to unlock the contract for the current period function unlock() external; /// @notice add or remove an aggregator from the whitelist (timelocked) /// @param _aggregator address of the aggregator to update /// @param _status new whitelist status function whitelistAggregator(address _aggregator, bool _status) external; /// @notice transfers the operator via accesshub function transferOperator(address _newOperator) external; /// @notice simple getPeriod call function getPeriod() external view returns (uint256 period); /// @notice if the contract is unlocked for deposits function isUnlocked() external view returns (bool); /// @notice determines whether the cooldown is active function isCooldownActive() external view returns (bool); /// @notice address of the current operator function operator() external view returns (address); /// @notice accessHub address function accessHub() external view returns (address); /// @notice returns the ratio of xShadow per X33 token function ratio() external view returns (uint256 _ratio); /// @notice the most recent active period the contract has interacted in function activePeriod() external view returns (uint256); /// @notice whether the periods are unlocked function periodUnlockStatus(uint256 _period) external view returns (bool unlocked); } interface IBasisAsset { function mint(address recipient, uint256 amount) external returns (bool); function burn(uint256 amount) external; function burnFrom(address from, uint256 amount) external; function isOperator() external returns (bool); function operator() external view returns (address); function transferOperator(address newOperator_) external; } interface IOracle { function update() external; function consult(address _token, uint256 _amountIn) external view returns (uint256 amountOut); function twap(address _token, uint256 _amountIn) external view returns (uint256 _amountOut); } contract ShareRewardPoolV3 is ReentrancyGuard { using SafeMath for uint256; using SafeERC20 for IERC20; enum GaugeDex { NONE, SHADOW, SWAPX } // governance address public operator; // Info of each user. struct UserInfo { uint256 amount; // How many LP tokens the user has provided. uint256 rewardDebt; // Reward debt. See explanation below. } struct GaugeInfo { bool isGauge; // If this is a gauge address gauge; // The gauge GaugeDex gaugeDex; // Dex of the gauge } // Info of each pool. struct PoolInfo { IERC20 token; // Address of LP token contract. uint256 depFee; // deposit fee that is applied to created pool. uint256 allocPoint; // How many allocation points assigned to this pool. SHAREs to distribute per block. uint256 lastRewardTime; // Last time that SHAREs distribution occurs. uint256 accSharePerShare; // Accumulated SHAREs per share, times 1e18. See below. bool isStarted; // if lastRewardTime has passed GaugeInfo gaugeInfo; // Gauge info (does this pool have a gauge and where is it) uint256 poolSharePerSec; // rewards per second for pool (acts as allocPoint) } IERC20 public share; IOracle public shareOracle; bool public claimGaugeRewardsOnUpdatePool = true; bool public pegStabilityModuleFeeEnabled = true; bool public mustConvertXShadow = true; uint256 public pegStabilityModuleFee = 300; // 15% uint256 public minClaimThreshold = 1e12; // 0.000001 SHARE IShadowVoter public shadowVoter; ISwapxVoter public swapxVoter; address public constant XSHADOW_TOKEN = 0x5050bc082FF4A74Fb6B0B04385dEfdDB114b2424; address public constant X33_TOKEN = 0x3333111A391cC08fa51353E9195526A70b333333; address public constant X33_WRAPPER = 0x9710E10A8f6FbA8C391606fee18614885684548d; address public constant SWAPX_TOKEN = 0xA04BC7140c26fc9BB1F36B1A604C7A5a88fb0E70; address public bribesSafe; address public msigWallet; // Info of each pool. PoolInfo[] public poolInfo; // Info of each user that stakes LP tokens. mapping(uint256 => mapping(address => UserInfo)) public userInfo; // Pending rewards for each user in each pool (pending rewards accrued since last deposit/withdrawal) mapping(uint256 => mapping(address => uint256)) public pendingRewards; // Total allocation points. Must be the sum of all allocation points in all pools. uint256 public totalAllocPoint = 0; // The time when SHARE mining starts. uint256 public poolStartTime; // The time when SHARE mining ends. uint256 public poolEndTime; uint256 public sharePerSecond = 0 ether; uint256 public runningTime = 100 days; 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( address _share, address _bribesSafe, uint256 _poolStartTime, address _shadowVoter, address _swapxVoter ) { require(block.timestamp < _poolStartTime, "pool cant be started in the past"); if (_share != address(0)) share = IERC20(_share); if(_bribesSafe != address(0)) bribesSafe = _bribesSafe; poolStartTime = _poolStartTime; poolEndTime = _poolStartTime + runningTime; operator = msg.sender; shadowVoter = IShadowVoter(_shadowVoter); swapxVoter = ISwapxVoter(_swapxVoter); bribesSafe = _bribesSafe; msigWallet = _bribesSafe; // create all the pools add(0.000578010052004059 ether, 0, IERC20(0x287c6882dE298665977787e268f3dba052A6e251), false, 0); // BILL-S add(0.000358399923896499 ether, 0, IERC20(0xb901D7316447C84f4417b8a8268E2822095051E6), false, 0); // SHARE-S add(0.000002893518518519 ether, 0, IERC20(0xF19748a0E269c6965a84f8C98ca8C47A064D4dd0), false, 0); // SHADOW-S add(0.000002893518518519 ether, 0, IERC20(0x039e2fB66102314Ce7b64Ce5Ce3E5183bc94aD38), false, 0); // Wrapped Sonic } modifier onlyOperator() { require(operator == msg.sender, "SHareRewardPool: caller is not the operator"); _; } function poolLength() external view returns (uint256) { return poolInfo.length; } function checkPoolDuplicate(IERC20 _token) internal view { uint256 length = poolInfo.length; for (uint256 pid = 0; pid < length; ++pid) { require(poolInfo[pid].token != _token, "SHareRewardPool: existing pool?"); } } // Add new lp to the pool. Can only be called by operator. function add( uint256 _allocPoint, uint256 _depFee, IERC20 _token, bool _withUpdate, uint256 _lastRewardTime ) public onlyOperator { checkPoolDuplicate(_token); if (_withUpdate) { massUpdatePools(); } if (block.timestamp < poolStartTime) { // chef is sleeping if (_lastRewardTime == 0) { _lastRewardTime = poolStartTime; } else { if (_lastRewardTime < poolStartTime) { _lastRewardTime = poolStartTime; } } } else { // chef is cooking if (_lastRewardTime == 0 || _lastRewardTime < block.timestamp) { _lastRewardTime = block.timestamp; } } bool _isStarted = (_lastRewardTime <= poolStartTime) || (_lastRewardTime <= block.timestamp); poolInfo.push(PoolInfo({ token: _token, depFee: _depFee, allocPoint: _allocPoint, poolSharePerSec: _allocPoint, lastRewardTime: _lastRewardTime, accSharePerShare: 0, isStarted: _isStarted, gaugeInfo: GaugeInfo(false, address(0), GaugeDex.NONE) })); // enableGauge(poolInfo.length - 1); if (_isStarted) { totalAllocPoint = totalAllocPoint.add(_allocPoint); sharePerSecond = sharePerSecond.add(_allocPoint); } } // Update the given pool's SHARE allocation point. Can only be called by the operator. function set(uint256 _pid, uint256 _allocPoint, uint256 _depFee) public onlyOperator { massUpdatePools(); PoolInfo storage pool = poolInfo[_pid]; require(_depFee < 200); // deposit fee cant be more than 2%; pool.depFee = _depFee; if (pool.isStarted) { totalAllocPoint = totalAllocPoint.sub(pool.allocPoint).add(_allocPoint); sharePerSecond = sharePerSecond.sub(pool.poolSharePerSec).add(_allocPoint); } pool.allocPoint = _allocPoint; pool.poolSharePerSec = _allocPoint; } function bulkSet(uint256[] calldata _pids, uint256[] calldata _allocPoints, uint256[] calldata _depFees) external onlyOperator { require(_pids.length == _allocPoints.length && _pids.length == _depFees.length, "SHareRewardPool: invalid length"); for (uint256 i = 0; i < _pids.length; i++) { set(_pids[i], _allocPoints[i], _depFees[i]); } } // Return accumulate rewards over the given _from to _to block. function getGeneratedReward(uint256 _fromTime, uint256 _toTime) public view returns (uint256) { if (_fromTime >= _toTime) return 0; if (_toTime >= poolEndTime) { if (_fromTime >= poolEndTime) return 0; if (_fromTime <= poolStartTime) return poolEndTime.sub(poolStartTime).mul(sharePerSecond); return poolEndTime.sub(_fromTime).mul(sharePerSecond); } else { if (_toTime <= poolStartTime) return 0; if (_fromTime <= poolStartTime) return _toTime.sub(poolStartTime).mul(sharePerSecond); return _toTime.sub(_fromTime).mul(sharePerSecond); } } // View function to see pending SHAREs on frontend. function pendingShare(uint256 _pid, address _user) public view returns (uint256) { PoolInfo storage pool = poolInfo[_pid]; UserInfo storage user = userInfo[_pid][_user]; uint256 accSharePerShare = pool.accSharePerShare; uint256 tokenSupply = pool.gaugeInfo.isGauge ? IShadowGauge(pool.gaugeInfo.gauge).balanceOf(address(this)) : pool.token.balanceOf(address(this)); if (block.timestamp > pool.lastRewardTime && tokenSupply != 0) { uint256 _generatedReward = getGeneratedReward(pool.lastRewardTime, block.timestamp); uint256 _shareReward = _generatedReward.mul(pool.allocPoint).div(totalAllocPoint); accSharePerShare = accSharePerShare.add(_shareReward.mul(1e18).div(tokenSupply)); } return user.amount.mul(accSharePerShare).div(1e18).sub(user.rewardDebt); } // View function to see pending SHAREs on frontend and any other pending rewards accumulated. function pendingShareAndPendingRewards(uint256 _pid, address _user) external view returns (uint256) { uint256 _pendingShare = pendingShare(_pid, _user); return _pendingShare.add(pendingRewards[_pid][_user]); } function massUpdatePools() public { uint256 length = poolInfo.length; for (uint256 pid = 0; pid < length; ++pid) { updatePool(pid); updatePoolWithGaugeDeposit(pid); } } // massUpdatePoolsInRange function massUpdatePoolsInRange(uint256 _fromPid, uint256 _toPid) public { require(_fromPid <= _toPid, "SHareRewardPool: invalid range"); for (uint256 pid = _fromPid; pid <= _toPid; ++pid) { updatePool(pid); updatePoolWithGaugeDeposit(pid); } } // Update reward variables of the given pool to be up-to-date. function updatePool(uint256 _pid) private { updatePoolWithGaugeDeposit(_pid); PoolInfo storage pool = poolInfo[_pid]; if (block.timestamp <= pool.lastRewardTime) { return; } uint256 tokenSupply = pool.gaugeInfo.isGauge ? IShadowGauge(pool.gaugeInfo.gauge).balanceOf(address(this)) : pool.token.balanceOf(address(this)); if (tokenSupply == 0) { pool.lastRewardTime = block.timestamp; return; } if (!pool.isStarted) { pool.isStarted = true; totalAllocPoint = totalAllocPoint.add(pool.allocPoint); sharePerSecond = sharePerSecond.add(pool.poolSharePerSec); } if (totalAllocPoint > 0) { uint256 _generatedReward = getGeneratedReward(pool.lastRewardTime, block.timestamp); uint256 _shareReward = _generatedReward.mul(pool.allocPoint).div(totalAllocPoint); pool.accSharePerShare = pool.accSharePerShare.add(_shareReward.mul(1e18).div(tokenSupply)); } pool.lastRewardTime = block.timestamp; if (claimGaugeRewardsOnUpdatePool) {claimGaugeRewards(_pid);} } // Deposit LP tokens to earn rewards function updatePoolWithGaugeDeposit(uint256 _pid) public { PoolInfo storage pool = poolInfo[_pid]; address gauge = pool.gaugeInfo.gauge; uint256 balance = pool.token.balanceOf(address(this)); // Do nothing if this pool doesn't have a gauge if (pool.gaugeInfo.isGauge) { // Do nothing if the LP token in the MC is empty if (balance > 0) { // Approve to the gauge if (pool.token.allowance(address(this), gauge) < balance ){ pool.token.approve(gauge, type(uint256).max); } // Deposit the LP in the gauge IShadowGauge(pool.gaugeInfo.gauge).deposit(balance); // NOTE: no need to check if gauge is shadow or swapx, because both have the same function } } } // Claim rewards to treasury function claimGaugeRewards(uint256 _pid) public { PoolInfo storage pool = poolInfo[_pid]; if (pool.gaugeInfo.isGauge) { if (pool.gaugeInfo.gaugeDex == GaugeDex.SHADOW) { _claimShadowRewards(_pid); } if (pool.gaugeInfo.gaugeDex == GaugeDex.SWAPX) { _claimSwapxRewards(_pid); } } } function claimAllFarmRewards() public onlyOperator { uint256 length = poolInfo.length; for (uint256 pid = 0; pid < length; ++pid) { claimGaugeRewards(pid); } } function _claimShadowRewards(uint256 _pid) internal { PoolInfo storage pool = poolInfo[_pid]; address[] memory gaugeRewardTokens = IShadowGauge(pool.gaugeInfo.gauge).rewardsList(); IShadowGauge(pool.gaugeInfo.gauge).getReward(address(this), gaugeRewardTokens); for (uint256 i = 0; i < gaugeRewardTokens.length; i++) { IERC20 rewardToken = IERC20(gaugeRewardTokens[i]); uint256 rewardAmount = rewardToken.balanceOf(address(this)); if (rewardAmount > 0) { if (address(rewardToken) == XSHADOW_TOKEN) { if (mustConvertXShadow) { _convertXShadow(rewardAmount); } } else { rewardToken.safeTransfer(bribesSafe, rewardAmount); } } } } function _convertXShadow(uint256 _amount) internal { IERC20(XSHADOW_TOKEN).approve(address(X33_TOKEN), _amount); // approve xshadow to x33 bool canMint = IX33(X33_TOKEN).isUnlocked(); if (canMint) { uint256 x33ReceivedAmount = IERC4626(X33_WRAPPER).deposit(_amount, address(this)); // mint x33 IERC20(X33_TOKEN).safeTransfer(bribesSafe, x33ReceivedAmount); // send x33 to bribesSafe } } function convertXShadowManual(uint256 _amount, bool _auto) public onlyOperator { IERC20(XSHADOW_TOKEN).approve(address(X33_TOKEN), _amount); // approve xshadow to x33 bool canMint = IX33(X33_TOKEN).isUnlocked(); if (canMint) { if (_auto) { uint256 x33ReceivedAmount = IERC4626(X33_WRAPPER).deposit(_amount, address(this)); // mint x33 IERC20(X33_TOKEN).safeTransfer(bribesSafe, x33ReceivedAmount); // send x33 to bribesSafe } else { IERC4626(X33_WRAPPER).deposit(_amount, address(this)); // mint x33 IERC20(X33_TOKEN).safeTransfer(bribesSafe, _amount); // send x33 to bribesSafe } } } function _claimSwapxRewards(uint256 _pid) internal { PoolInfo storage pool = poolInfo[_pid]; ISwapxGauge(pool.gaugeInfo.gauge).getReward(); // claim the swapx rewards IERC20 rewardToken = IERC20(SWAPX_TOKEN); uint256 rewardAmount = rewardToken.balanceOf(address(this)); if (rewardAmount > 0) { rewardToken.safeTransfer(bribesSafe, rewardAmount); } } // Add a gauge to a pool function enableGauge(uint256 _pid, GaugeDex _gaugeDex) public onlyOperator { if (_gaugeDex == GaugeDex.SHADOW) { _enableGaugeShadow(_pid); } if (_gaugeDex == GaugeDex.SWAPX) { _enableGaugeSwapX(_pid); } } function _enableGaugeShadow(uint256 _pid) internal { address gauge = shadowVoter.gaugeForPool(address(poolInfo[_pid].token)); if (gauge != address(0)) { poolInfo[_pid].gaugeInfo = GaugeInfo(true, gauge, GaugeDex.SHADOW); } } function _enableGaugeSwapX(uint256 _pid) internal { // Add the logic for swapx address gauge = swapxVoter.gauges(address(poolInfo[_pid].token)); if (gauge != address(0)) { poolInfo[_pid].gaugeInfo = GaugeInfo(true, gauge, GaugeDex.SWAPX); } } // Withdraw LP from the gauge function withdrawFromGauge(uint256 _pid, uint256 _amount) internal { PoolInfo storage pool = poolInfo[_pid]; // Do nothing if this pool doesn't have a gauge if (pool.gaugeInfo.isGauge) { // Withdraw from the gauge IShadowGauge(pool.gaugeInfo.gauge).withdraw(_amount); // NOTE: no need to check if gauge is shadow or swapx, because both have the same function } } // Deposit LP tokens. function deposit(uint256 _pid, uint256 _amount) public nonReentrant { address _sender = msg.sender; PoolInfo storage pool = poolInfo[_pid]; UserInfo storage user = userInfo[_pid][_sender]; updatePool(_pid); if (user.amount > 0) { uint256 _pending = user.amount.mul(pool.accSharePerShare).div(1e18).sub(user.rewardDebt); if (_pending > 0) { // safeShareTransfer(_sender, _pending); // emit RewardPaid(_sender, _pending); // accrue pending rewards to be claimed later pendingRewards[_pid][_sender] = pendingRewards[_pid][_sender].add(_pending); } } if (_amount > 0 ) { pool.token.safeTransferFrom(_sender, address(this), _amount); uint256 depositDebt = _amount.mul(pool.depFee).div(10000); user.amount = user.amount.add(_amount.sub(depositDebt)); pool.token.safeTransfer(bribesSafe, depositDebt); } updatePoolWithGaugeDeposit(_pid); user.rewardDebt = user.amount.mul(pool.accSharePerShare).div(1e18); emit Deposit(_sender, _pid, _amount); } // Withdraw LP tokens. function withdraw(uint256 _pid, uint256 _amount) public payable nonReentrant { address _sender = msg.sender; PoolInfo storage pool = poolInfo[_pid]; UserInfo storage user = userInfo[_pid][_sender]; require(user.amount >= _amount, "withdraw: not good"); updatePool(_pid); updatePoolWithGaugeDeposit(_pid); uint256 _pending = user.amount.mul(pool.accSharePerShare).div(1e18).sub(user.rewardDebt); if (_pending > 0) { // safeShareTransfer(_sender, _pending); // emit RewardPaid(_sender, _pending); // accrue pending rewards to be claimed later pendingRewards[_pid][_sender] = pendingRewards[_pid][_sender].add(_pending); } if (_amount > 0) { user.amount = user.amount.sub(_amount); withdrawFromGauge(_pid, _amount); pool.token.safeTransfer(_sender, _amount); } user.rewardDebt = user.amount.mul(pool.accSharePerShare).div(1e18); emit Withdraw(_sender, _pid, _amount); } function harvest(uint256 _pid) public payable nonReentrant { address _sender = msg.sender; PoolInfo storage pool = poolInfo[_pid]; UserInfo storage user = userInfo[_pid][_sender]; // Ensure rewards are updated updatePool(_pid); updatePoolWithGaugeDeposit(_pid); // Calculate the latest pending rewards uint256 _pending = user.amount.mul(pool.accSharePerShare).div(1e18).sub(user.rewardDebt); uint256 _accumulatedPending = pendingRewards[_pid][_sender]; uint256 _rewardsToClaim = _pending.add(_accumulatedPending); // Ensure that the user is claiming an amount above the minimum threshold require(_rewardsToClaim >= minClaimThreshold, "Claim amount below minimum threshold"); if (_rewardsToClaim > 0) { pendingRewards[_pid][_sender] = 0; uint256 amountSonicToPay = 0; if (pegStabilityModuleFeeEnabled) { uint256 currentSHAREPriceInSonic = shareOracle.twap(address(share), 1e18); amountSonicToPay = (currentSHAREPriceInSonic.mul(_rewardsToClaim).div(1e18)).mul(pegStabilityModuleFee).div(1000); require(msg.value >= amountSonicToPay, "insufficient sonic for PSM cost"); } else { require(msg.value == 0, "SHareRewardPool: invalid msg.value"); } safeShareTransfer(_sender, _rewardsToClaim); emit RewardPaid(_sender, _rewardsToClaim); // Refund any excess S if pegStabilityModuleFee is enabled if (pegStabilityModuleFeeEnabled && msg.value > amountSonicToPay) { uint256 refundAmount = msg.value - amountSonicToPay; (bool success, ) = _sender.call{value: refundAmount}(""); require(success, "Refund failed"); } } // Update the user’s reward debt user.rewardDebt = user.amount.mul(pool.accSharePerShare).div(1e18); } function harvestAll() public payable nonReentrant { address _sender = msg.sender; uint256 length = poolInfo.length; uint256 totalUserRewardsToClaim = 0; for (uint256 pid = 0; pid < length; ++pid) { PoolInfo storage pool = poolInfo[pid]; UserInfo storage user = userInfo[pid][_sender]; // Ensure rewards are updated updatePool(pid); updatePoolWithGaugeDeposit(pid); // Calculate the latest pending rewards uint256 _pending = user.amount.mul(pool.accSharePerShare).div(1e18).sub(user.rewardDebt); uint256 _accumulatedPending = pendingRewards[pid][_sender]; uint256 _rewardsToClaim = _pending.add(_accumulatedPending); if (_rewardsToClaim > 0) { pendingRewards[pid][_sender] = 0; totalUserRewardsToClaim = totalUserRewardsToClaim.add(_rewardsToClaim); } // Update the user’s reward debt user.rewardDebt = user.amount.mul(pool.accSharePerShare).div(1e18); } // Ensure that the user is claiming an amount above the minimum threshold require(totalUserRewardsToClaim >= minClaimThreshold, "Claim amount below minimum threshold"); if (totalUserRewardsToClaim > 0) { uint256 amountSonicToPay = 0; if (pegStabilityModuleFeeEnabled) { uint256 currentSHAREPriceInSonic = shareOracle.twap(address(share), 1e18); amountSonicToPay = (currentSHAREPriceInSonic.mul(totalUserRewardsToClaim).div(1e18)).mul(pegStabilityModuleFee).div(1000); require(msg.value >= amountSonicToPay, "insufficient sonic for PSM cost"); } else { require(msg.value == 0, "SHareRewardPool: invalid msg.value"); } safeShareTransfer(_sender, totalUserRewardsToClaim); emit RewardPaid(_sender, totalUserRewardsToClaim); // Refund any excess S if pegStabilityModuleFee is enabled if (pegStabilityModuleFeeEnabled && msg.value > amountSonicToPay) { uint256 refundAmount = msg.value - amountSonicToPay; (bool success, ) = _sender.call{value: refundAmount}(""); require(success, "Refund failed"); } } } // Withdraw without caring about rewards. EMERGENCY ONLY. function emergencyWithdraw(uint256 _pid) public nonReentrant { PoolInfo storage pool = poolInfo[_pid]; UserInfo storage user = userInfo[_pid][msg.sender]; uint256 _amount = user.amount; withdrawFromGauge(_pid, _amount); pendingRewards[_pid][msg.sender] = 0; user.amount = 0; user.rewardDebt = 0; pool.token.safeTransfer(msg.sender, _amount); emit EmergencyWithdraw(msg.sender, _pid, _amount); } // Safe share transfer function, just in case if rounding error causes pool to not have enough SHAREs. function safeShareTransfer(address _to, uint256 _amount) internal { uint256 _shareBal = share.balanceOf(address(this)); if (_shareBal > 0) { if (_amount > _shareBal) { share.safeTransfer(_to, _shareBal); } else { share.safeTransfer(_to, _amount); } } } function setOperator(address _operator) external onlyOperator { operator = _operator; } function setBribesSafe(address _bribesSafe) public onlyOperator { bribesSafe = _bribesSafe; } function setMsigWallet(address _msigWallet) public onlyOperator { msigWallet = _msigWallet; } function setPegStabilityModuleFee(uint256 _pegStabilityModuleFee) external onlyOperator { require(_pegStabilityModuleFee <= 500, "SHareRewardPool: invalid peg stability module fee"); // max 50% pegStabilityModuleFee = _pegStabilityModuleFee; } function setMustConvertXShadow(bool _mustConvertXShadow) external onlyOperator { mustConvertXShadow = _mustConvertXShadow; } function setSHareOracle(IOracle _shareOracle) external onlyOperator { shareOracle = _shareOracle; } function setPegStabilityModuleFeeEnabled(bool _enabled) external onlyOperator { pegStabilityModuleFeeEnabled = _enabled; } function setMinClaimThreshold(uint256 _minClaimThreshold) external onlyOperator { require(_minClaimThreshold >= 0, "SHareRewardPool: invalid min claim threshold"); require(_minClaimThreshold <= 1e18, "SHareRewardPool: invalid max claim threshold"); minClaimThreshold = _minClaimThreshold; } function setClaimGaugeRewardsOnUpdatePool(bool _claimGaugeRewardsOnUpdatePool) external onlyOperator { claimGaugeRewardsOnUpdatePool = _claimGaugeRewardsOnUpdatePool; } function governanceRecoverUnsupported(IERC20 _token, uint256 amount, address to) external onlyOperator { uint256 length = poolInfo.length; for (uint256 pid = 0; pid < length; ++pid) { PoolInfo storage pool = poolInfo[pid]; require(_token != pool.token, "ShareRewardPool: Token cannot be pool token"); } _token.safeTransfer(to, amount); } /** * @notice Collects the Sonic. * @param amount The amount of Sonic to collect */ function collectSonic(uint256 amount) public onlyOperator { (bool sent,) = bribesSafe.call{value: amount}(""); require(sent, "failed to send Sonic"); } function collectSonicMsig(uint256 amount) public onlyOperator { (bool sent,) = msigWallet.call{value: amount}(""); require(sent, "failed to send Sonic"); } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"address","name":"_share","type":"address"},{"internalType":"address","name":"_bribesSafe","type":"address"},{"internalType":"uint256","name":"_poolStartTime","type":"uint256"},{"internalType":"address","name":"_shadowVoter","type":"address"},{"internalType":"address","name":"_swapxVoter","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"uint256","name":"pid","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Deposit","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"uint256","name":"pid","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"EmergencyWithdraw","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"RewardPaid","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"uint256","name":"pid","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Withdraw","type":"event"},{"inputs":[],"name":"SWAPX_TOKEN","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"X33_TOKEN","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"X33_WRAPPER","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"XSHADOW_TOKEN","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_allocPoint","type":"uint256"},{"internalType":"uint256","name":"_depFee","type":"uint256"},{"internalType":"contract IERC20","name":"_token","type":"address"},{"internalType":"bool","name":"_withUpdate","type":"bool"},{"internalType":"uint256","name":"_lastRewardTime","type":"uint256"}],"name":"add","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"bribesSafe","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"_pids","type":"uint256[]"},{"internalType":"uint256[]","name":"_allocPoints","type":"uint256[]"},{"internalType":"uint256[]","name":"_depFees","type":"uint256[]"}],"name":"bulkSet","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"claimAllFarmRewards","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"}],"name":"claimGaugeRewards","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"claimGaugeRewardsOnUpdatePool","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"collectSonic","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"collectSonicMsig","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"bool","name":"_auto","type":"bool"}],"name":"convertXShadowManual","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"deposit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"}],"name":"emergencyWithdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"},{"internalType":"enum ShareRewardPoolV3.GaugeDex","name":"_gaugeDex","type":"uint8"}],"name":"enableGauge","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_fromTime","type":"uint256"},{"internalType":"uint256","name":"_toTime","type":"uint256"}],"name":"getGeneratedReward","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IERC20","name":"_token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"address","name":"to","type":"address"}],"name":"governanceRecoverUnsupported","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"}],"name":"harvest","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"harvestAll","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"massUpdatePools","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_fromPid","type":"uint256"},{"internalType":"uint256","name":"_toPid","type":"uint256"}],"name":"massUpdatePoolsInRange","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"minClaimThreshold","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"msigWallet","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"mustConvertXShadow","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"operator","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pegStabilityModuleFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pegStabilityModuleFeeEnabled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"address","name":"","type":"address"}],"name":"pendingRewards","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"},{"internalType":"address","name":"_user","type":"address"}],"name":"pendingShare","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"},{"internalType":"address","name":"_user","type":"address"}],"name":"pendingShareAndPendingRewards","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"poolEndTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"poolInfo","outputs":[{"internalType":"contract IERC20","name":"token","type":"address"},{"internalType":"uint256","name":"depFee","type":"uint256"},{"internalType":"uint256","name":"allocPoint","type":"uint256"},{"internalType":"uint256","name":"lastRewardTime","type":"uint256"},{"internalType":"uint256","name":"accSharePerShare","type":"uint256"},{"internalType":"bool","name":"isStarted","type":"bool"},{"components":[{"internalType":"bool","name":"isGauge","type":"bool"},{"internalType":"address","name":"gauge","type":"address"},{"internalType":"enum ShareRewardPoolV3.GaugeDex","name":"gaugeDex","type":"uint8"}],"internalType":"struct ShareRewardPoolV3.GaugeInfo","name":"gaugeInfo","type":"tuple"},{"internalType":"uint256","name":"poolSharePerSec","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"poolLength","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"poolStartTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"runningTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"},{"internalType":"uint256","name":"_allocPoint","type":"uint256"},{"internalType":"uint256","name":"_depFee","type":"uint256"}],"name":"set","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_bribesSafe","type":"address"}],"name":"setBribesSafe","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_claimGaugeRewardsOnUpdatePool","type":"bool"}],"name":"setClaimGaugeRewardsOnUpdatePool","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_minClaimThreshold","type":"uint256"}],"name":"setMinClaimThreshold","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_msigWallet","type":"address"}],"name":"setMsigWallet","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_mustConvertXShadow","type":"bool"}],"name":"setMustConvertXShadow","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_operator","type":"address"}],"name":"setOperator","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pegStabilityModuleFee","type":"uint256"}],"name":"setPegStabilityModuleFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_enabled","type":"bool"}],"name":"setPegStabilityModuleFeeEnabled","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IOracle","name":"_shareOracle","type":"address"}],"name":"setSHareOracle","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"shadowVoter","outputs":[{"internalType":"contract IShadowVoter","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"share","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"shareOracle","outputs":[{"internalType":"contract IOracle","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"sharePerSecond","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"swapxVoter","outputs":[{"internalType":"contract ISwapxVoter","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalAllocPoint","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"}],"name":"updatePoolWithGaugeDeposit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"address","name":"","type":"address"}],"name":"userInfo","outputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"rewardDebt","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"withdraw","outputs":[],"stateMutability":"payable","type":"function"}]
Contract Creation Code
60806040526003805462ffffff60a01b19166201010160a01b17905561012c60045564e8d4a510006005555f600d8190556010556283d600601155348015610045575f5ffd5b5060405161533738038061533783398101604081905261006491611298565b60015f554283116100bc5760405162461bcd60e51b815260206004820181905260248201527f706f6f6c2063616e74206265207374617274656420696e20746865207061737460448201526064015b60405180910390fd5b6001600160a01b038516156100e757600280546001600160a01b0319166001600160a01b0387161790555b6001600160a01b0384161561011257600880546001600160a01b0319166001600160a01b0386161790555b600e8390556011546101249084611307565b600f5560018054336001600160a01b0319918216179091556006805482166001600160a01b03858116919091179091556007805483168483161790556008805483169187169182179055600980549092161790556101a066020db273d388db5f73287c6882de298665977787e268f3dba052a6e2518180610220565b6101c8660145f67c26c0b35f73b901d7316447c84f4417b8a8268e2822095051e68180610220565b6101ef6502a1b324b8f75f73f19748a0e269c6965a84f8c98ca8c47a064d4dd08180610220565b6102166502a1b324b8f75f73039e2fb66102314ce7b64ce5ce3e5183bc94ad388180610220565b505050505061154f565b6001546001600160a01b0316331461028e5760405162461bcd60e51b815260206004820152602b60248201527f5348617265526577617264506f6f6c3a2063616c6c6572206973206e6f74207460448201526a34329037b832b930ba37b960a91b60648201526084016100b3565b610297836104a2565b81156102a5576102a561053f565b600e544210156102d357805f036102bf5750600e546102e7565b600e548110156102ce5750600e545b6102e7565b8015806102df57504281105b156102e75750425b5f600e54821115806102f95750428211155b9050600a604051806101000160405280866001600160a01b031681526020018781526020018881526020018481526020015f8152602001831515815260200160405180606001604052805f151581526020015f6001600160a01b031681526020015f600281111561036c5761036c61131a565b9052815260209081018990528254600181810185555f94855293829020835160089092020180546001600160a01b039283166001600160a01b03199091161781558383015194810194909455604080840151600280870191909155606085015160038701556080850151600487015560a085015160058701805491151560ff1990921691909117905560c085015180516006880180549683015190951661010002610100600160a81b0319911515919091166001600160a81b031990961695909517949094178084559184015194959491839160ff60a81b1990911690600160a81b9084908111156104605761046061131a565b0217905550505060e082015181600701555050801561049a57600d54610486908761056a565b600d55601054610496908761056a565b6010555b505050505050565b600a545f5b8181101561053a57826001600160a01b0316600a82815481106104cc576104cc61132e565b5f9182526020909120600890910201546001600160a01b0316036105325760405162461bcd60e51b815260206004820152601f60248201527f5348617265526577617264506f6f6c3a206578697374696e6720706f6f6c3f0060448201526064016100b3565b6001016104a7565b505050565b600a545f5b81811015610566576105558161057e565b61055e81610790565b600101610544565b5050565b5f6105758284611307565b90505b92915050565b61058781610790565b5f600a828154811061059b5761059b61132e565b905f5260205f2090600802019050806003015442116105b8575050565b60068101545f9060ff166106345781546040516370a0823160e01b81523060048201526001600160a01b03909116906370a0823190602401602060405180830381865afa15801561060b573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061062f9190611342565b6106a4565b60068201546040516370a0823160e01b81523060048201526101009091046001600160a01b0316906370a0823190602401602060405180830381865afa158015610680573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906106a49190611342565b9050805f036106b857504260039091015550565b600582015460ff166106fc5760058201805460ff191660011790556002820154600d546106e49161056a565b600d5560078201546010546106f89161056a565b6010555b600d541561076d575f61071983600301544261099660201b60201c565b90505f61073f600d54610739866002015485610a4160201b90919060201c565b90610a4c565b905061076561075a8461073984670de0b6b3a7640000610a41565b60048601549061056a565b600485015550505b4260038381019190915554600160a01b900460ff161561053a5761053a83610a57565b5f600a82815481106107a4576107a461132e565b5f9182526020822060089190910201600681015481546040516370a0823160e01b81523060048201529294506101009091046001600160a01b0390811693929116906370a0823190602401602060405180830381865afa15801561080a573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061082e9190611342565b600684015490915060ff1615610990578015610990578254604051636eb1769f60e11b81523060048201526001600160a01b0384811660248301528392169063dd62ed3e90604401602060405180830381865afa158015610891573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906108b59190611342565b101561093057825460405163095ea7b360e01b81526001600160a01b0384811660048301525f1960248301529091169063095ea7b3906044016020604051808303815f875af115801561090a573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061092e9190611359565b505b600683015460405163b6b55f2560e01b8152600481018390526101009091046001600160a01b03169063b6b55f25906024015f604051808303815f87803b158015610979575f5ffd5b505af115801561098b573d5f5f3e3d5ffd5b505050505b50505050565b5f8183106109a557505f610578565b600f548210610a0157600f5483106109be57505f610578565b600e5483116109ec57601054600e54600f546109e592916109df9190610aea565b90610a41565b9050610578565b601054600f546109e591906109df9086610aea565b600e548211610a1157505f610578565b600e548311610a3057601054600e546109e591906109df908590610aea565b6010546109e5906109df8486610aea565b5f610575828461137f565b5f6105758284611396565b5f600a8281548110610a6b57610a6b61132e565b5f9182526020909120600890910201600681015490915060ff16156105665760016006820154600160a81b900460ff166002811115610aac57610aac61131a565b03610aba57610aba82610af5565b60026006820154600160a81b900460ff166002811115610adc57610adc61131a565b036105665761056682610d00565b5f61057582846113b5565b5f600a8281548110610b0957610b0961132e565b905f5260205f20906008020190505f816006015f0160019054906101000a90046001600160a01b03166001600160a01b0316638003b6146040518163ffffffff1660e01b81526004015f60405180830381865afa158015610b6c573d5f5f3e3d5ffd5b505050506040513d5f823e601f3d908101601f19168201604052610b9391908101906113dc565b60068301546040516331279d3d60e01b815291925061010090046001600160a01b0316906331279d3d90610bcd90309085906004016114a6565b5f604051808303815f87803b158015610be4575f5ffd5b505af1158015610bf6573d5f5f3e3d5ffd5b505f925050505b8151811015610990575f828281518110610c1957610c1961132e565b60209081029190910101516040516370a0823160e01b81523060048201529091505f906001600160a01b038316906370a0823190602401602060405180830381865afa158015610c6b573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610c8f9190611342565b90508015610cf657735050bc082ff4a74fb6b0b04385defddb114b2423196001600160a01b03831601610cdc57600354600160b01b900460ff1615610cd757610cd781610e20565b610cf6565b600854610cf6906001600160a01b03848116911683610fd1565b5050600101610bfd565b5f600a8281548110610d1457610d1461132e565b905f5260205f2090600802019050806006015f0160019054906101000a90046001600160a01b03166001600160a01b0316633d18b9126040518163ffffffff1660e01b81526004015f604051808303815f87803b158015610d73575f5ffd5b505af1158015610d85573d5f5f3e3d5ffd5b50506040516370a0823160e01b815230600482015273a04bc7140c26fc9bb1f36b1a604c7a5a88fb0e7092505f915082906370a0823190602401602060405180830381865afa158015610dda573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610dfe9190611342565b9050801561099057600854610990906001600160a01b03848116911683610fd1565b60405163095ea7b360e01b8152733333111a391cc08fa51353e9195526a70b333333600482015260248101829052735050bc082ff4a74fb6b0b04385defddb114b24249063095ea7b3906044016020604051808303815f875af1158015610e89573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610ead9190611359565b505f733333111a391cc08fa51353e9195526a70b3333336001600160a01b0316638380edb76040518163ffffffff1660e01b8152600401602060405180830381865afa158015610eff573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610f239190611359565b9050801561056657604051636e553f6560e01b8152600481018390523060248201525f90739710e10a8f6fba8c391606fee18614885684548d90636e553f65906044016020604051808303815f875af1158015610f82573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610fa69190611342565b60085490915061053a90733333111a391cc08fa51353e9195526a70b333333906001600160a01b0316835b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b0390811663a9059cbb60e01b1790915261053a91859161102716565b6040805180820190915260208082527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564908201525f90611073906001600160a01b0385169084906110f2565b905080515f14806110935750808060200190518101906110939190611359565b61053a5760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b60648201526084016100b3565b606061110084845f85611108565b949350505050565b6060824710156111695760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b60648201526084016100b3565b5f5f866001600160a01b031685876040516111849190611504565b5f6040518083038185875af1925050503d805f81146111be576040519150601f19603f3d011682016040523d82523d5f602084013e6111c3565b606091505b5090925090506111d5878383876111e0565b979650505050505050565b6060831561124e5782515f03611247576001600160a01b0385163b6112475760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016100b3565b5081611100565b61110083838151156112635781518083602001fd5b8060405162461bcd60e51b81526004016100b3919061151a565b80516001600160a01b0381168114611293575f5ffd5b919050565b5f5f5f5f5f60a086880312156112ac575f5ffd5b6112b58661127d565b94506112c36020870161127d565b604087015190945092506112d96060870161127d565b91506112e76080870161127d565b90509295509295909350565b634e487b7160e01b5f52601160045260245ffd5b80820180821115610578576105786112f3565b634e487b7160e01b5f52602160045260245ffd5b634e487b7160e01b5f52603260045260245ffd5b5f60208284031215611352575f5ffd5b5051919050565b5f60208284031215611369575f5ffd5b81518015158114611378575f5ffd5b9392505050565b8082028115828204841417610578576105786112f3565b5f826113b057634e487b7160e01b5f52601260045260245ffd5b500490565b81810381811115610578576105786112f3565b634e487b7160e01b5f52604160045260245ffd5b5f602082840312156113ec575f5ffd5b81516001600160401b03811115611401575f5ffd5b8201601f81018413611411575f5ffd5b80516001600160401b0381111561142a5761142a6113c8565b604051600582901b90603f8201601f191681016001600160401b0381118282101715611458576114586113c8565b604052918252602081840181019290810187841115611475575f5ffd5b6020850194505b8385101561149b5761148d8561127d565b81526020948501940161147c565b509695505050505050565b6001600160a01b03831681526040602080830182905283519183018290525f91908401906060840190835b818110156114f85783516001600160a01b03168352602093840193909201916001016114d1565b50909695505050505050565b5f82518060208501845e5f920191825250919050565b602081525f82518060208401528060208501604085015e5f604082850101526040601f19601f83011684010191505092915050565b613ddb8061155c5f395ff3fe608060405260043610610340575f3560e01c806371747802116101bd578063ba44a45a116100f2578063d18df53c11610092578063de89c76c1161006d578063de89c76c1461098d578063dfbffa8c146109ac578063e2bbb158146109d3578063fddc298c146109f2575f5ffd5b8063d18df53c14610925578063da1165221461095b578063ddc632621461097a575f5ffd5b8063ce862f17116100cd578063ce862f17146108a9578063ced8a5d7146108c8578063cf4b55cb146108e7578063d02ade9414610906575f5ffd5b8063ba44a45a14610856578063c4c7fe691461086b578063c69c2c021461088a575f5ffd5b8063943f013d1161015d578063a8d5fd6511610138578063a8d5fd65146107da578063ad149a1e146107f9578063b3ab15fb14610818578063b947a88d14610837575f5ffd5b8063943f013d1461077f57806396f38bdb14610794578063a44a7432146107bb575f5ffd5b8063893d3f0f11610198578063893d3f0f146106e75780638ed955b91461070657806390c5ed6a1461070e57806393f1a40b1461072d575f5ffd5b8063717478021461068957806378e39d5d146106a95780637bd153e6146106c8575f5ffd5b806351637ba911610293578063605783691161023357806363eb04161161020e57806363eb0416146106175780636b2681c5146106365780636e142c8e146106555780636e271dd514610674575f5ffd5b806360578369146105c457806361e79f02146105e3578063630b5ba114610603575f5ffd5b8063549c278a1161026e578063549c278a14610554578063570ca7351461057b5780635752933a1461059a5780635f96dc11146105af575f5ffd5b806351637ba9146104f75780635312ea8e1461051657806354575af414610535575f5ffd5b80632df95ed7116102fe5780633aa158ee116102d95780633aa158ee146104815780633afb24f11461049557806343b0e8df146104c5578063441a3e70146104e4575f5ffd5b80632df95ed71461042e5780633202f6c11461044d5780633695dad11461046c575f5ffd5b8062c6b39114610344578063081e3eda146103885780631526fe27146103a657806317caf6f1146103d9578063231f0c6a146103ee57806329e63f7a1461040d575b5f5ffd5b34801561034f575f5ffd5b5061036b735050bc082ff4a74fb6b0b04385defddb114b242481565b6040516001600160a01b0390911681526020015b60405180910390f35b348015610393575f5ffd5b50600a545b60405190815260200161037f565b3480156103b1575f5ffd5b506103c56103c0366004613715565b610a11565b60405161037f989796959493929190613740565b3480156103e4575f5ffd5b50610398600d5481565b3480156103f9575f5ffd5b506103986104083660046137c8565b610ace565b348015610418575f5ffd5b5061042c6104273660046137fc565b610b8f565b005b348015610439575f5ffd5b5061042c610448366004613715565b610be4565b348015610458575f5ffd5b5060065461036b906001600160a01b031681565b348015610477575f5ffd5b5061039860055481565b34801561048c575f5ffd5b5061042c610dea565b3480156104a0575f5ffd5b506003546104b590600160a01b900460ff1681565b604051901515815260200161037f565b3480156104d0575f5ffd5b5061042c6104df366004613817565b610e36565b61042c6104f23660046137c8565b610efd565b348015610502575f5ffd5b5061042c610511366004613715565b6110db565b348015610521575f5ffd5b5061042c610530366004613715565b611177565b348015610540575f5ffd5b5061042c61054f366004613840565b61124a565b34801561055f575f5ffd5b5061036b733333111a391cc08fa51353e9195526a70b33333381565b348015610586575f5ffd5b5060015461036b906001600160a01b031681565b3480156105a5575f5ffd5b5061039860105481565b3480156105ba575f5ffd5b50610398600e5481565b3480156105cf575f5ffd5b5061042c6105de366004613715565b611336565b3480156105ee575f5ffd5b506003546104b590600160b01b900460ff1681565b34801561060e575f5ffd5b5061042c6113d1565b348015610622575f5ffd5b5061042c61063136600461388c565b6113f8565b348015610641575f5ffd5b506103986106503660046138a7565b611440565b348015610660575f5ffd5b5060075461036b906001600160a01b031681565b34801561067f575f5ffd5b50610398600f5481565b348015610694575f5ffd5b506003546104b590600160a81b900460ff1681565b3480156106b4575f5ffd5b5061042c6106c3366004613715565b611484565b3480156106d3575f5ffd5b5060035461036b906001600160a01b031681565b3480156106f2575f5ffd5b5061042c610701366004613715565b61154a565b61042c61158d565b348015610719575f5ffd5b5061042c6107283660046138d5565b61193b565b348015610738575f5ffd5b5061076a6107473660046138a7565b600b60209081525f92835260408084209091529082529020805460019091015482565b6040805192835260208301919091520161037f565b34801561078a575f5ffd5b5061039860115481565b34801561079f575f5ffd5b5061036b739710e10a8f6fba8c391606fee18614885684548d81565b3480156107c6575f5ffd5b5061042c6107d5366004613923565b611b79565b3480156107e5575f5ffd5b5060025461036b906001600160a01b031681565b348015610804575f5ffd5b5060095461036b906001600160a01b031681565b348015610823575f5ffd5b5061042c6108323660046137fc565b611e09565b348015610842575f5ffd5b5061042c6108513660046137c8565b611e55565b348015610861575f5ffd5b5061039860045481565b348015610876575f5ffd5b5061042c6108853660046137fc565b611ed0565b348015610895575f5ffd5b5061042c6108a436600461388c565b611f1c565b3480156108b4575f5ffd5b5061042c6108c3366004613946565b611f64565b3480156108d3575f5ffd5b5061042c6108e23660046137fc565b611fd2565b3480156108f2575f5ffd5b506103986109013660046138a7565b61201e565b348015610911575f5ffd5b5061042c610920366004613715565b6121fa565b348015610930575f5ffd5b5061039861093f3660046138a7565b600c60209081525f928352604080842090915290825290205481565b348015610966575f5ffd5b5061042c61097536600461388c565b61228d565b61042c610988366004613715565b6122d5565b348015610998575f5ffd5b5060085461036b906001600160a01b031681565b3480156109b7575f5ffd5b5061036b73a04bc7140c26fc9bb1f36b1a604c7a5a88fb0e7081565b3480156109de575f5ffd5b5061042c6109ed3660046137c8565b612654565b3480156109fd575f5ffd5b5061042c610a0c3660046139b4565b612826565b600a8181548110610a20575f80fd5b5f918252602091829020600890910201805460018201546002808401546003850154600486015460058701546040805160608101825260068a01805460ff8181161515845261010082046001600160a01b039081169e85019e909e529c909a169c50979a9599949893979286169694959094929391850192600160a81b9092041690811115610ab157610ab161372c565b6002811115610ac257610ac261372c565b90525060079091015488565b5f818310610add57505f610b89565b600f548210610b4457600f548310610af657505f610b89565b600e548311610b2957610b22601054610b1c600e54600f5461291890919063ffffffff16565b9061292a565b9050610b89565b610b22601054610b1c85600f5461291890919063ffffffff16565b600e548211610b5457505f610b89565b600e548311610b7857610b22601054610b1c600e548561291890919063ffffffff16565b601054610b2290610b1c8486612918565b92915050565b6001546001600160a01b03163314610bc25760405162461bcd60e51b8152600401610bb990613a53565b60405180910390fd5b600380546001600160a01b0319166001600160a01b0392909216919091179055565b5f600a8281548110610bf857610bf8613a9e565b5f9182526020822060089190910201600681015481546040516370a0823160e01b81523060048201529294506101009091046001600160a01b0390811693929116906370a0823190602401602060405180830381865afa158015610c5e573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610c829190613ab2565b600684015490915060ff1615610de4578015610de4578254604051636eb1769f60e11b81523060048201526001600160a01b0384811660248301528392169063dd62ed3e90604401602060405180830381865afa158015610ce5573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610d099190613ab2565b1015610d8457825460405163095ea7b360e01b81526001600160a01b0384811660048301525f1960248301529091169063095ea7b3906044016020604051808303815f875af1158015610d5e573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610d829190613ac9565b505b600683015460405163b6b55f2560e01b8152600481018390526101009091046001600160a01b03169063b6b55f25906024015f604051808303815f87803b158015610dcd575f5ffd5b505af1158015610ddf573d5f5f3e3d5ffd5b505050505b50505050565b6001546001600160a01b03163314610e145760405162461bcd60e51b8152600401610bb990613a53565b600a545f5b81811015610e3257610e2a816121fa565b600101610e19565b5050565b6001546001600160a01b03163314610e605760405162461bcd60e51b8152600401610bb990613a53565b610e686113d1565b5f600a8481548110610e7c57610e7c613a9e565b905f5260205f209060080201905060c88210610e96575f5ffd5b60018101829055600581015460ff1615610eeb57610ecd83610ec78360020154600d5461291890919063ffffffff16565b90612935565b600d556007810154601054610ee7918591610ec791612918565b6010555b60028101839055600701919091555050565b610f05612940565b5f3390505f600a8481548110610f1d57610f1d613a9e565b5f9182526020808320878452600b825260408085206001600160a01b03881686529092529220805460089092029092019250841115610f935760405162461bcd60e51b81526020600482015260126024820152711dda5d1a191c985dce881b9bdd0819dbdbd960721b6044820152606401610bb9565b610f9c85612997565b610fa585610be4565b5f610fe08260010154610fda670de0b6b3a7640000610fd48760040154875f015461292a90919063ffffffff16565b90612b9d565b90612918565b90508015611037575f868152600c602090815260408083206001600160a01b03881684529091529020546110149082612935565b5f878152600c602090815260408083206001600160a01b03891684529091529020555b841561106b5781546110499086612918565b82556110558686612ba8565b825461106b906001600160a01b03168587612c36565b6004830154825461108991670de0b6b3a764000091610fd49161292a565b600183015560405185815286906001600160a01b038616907ff279e6a1f5e320cca91135676d9cb6e44ca8a08c0b88342bcdb1144f6511b5689060200160405180910390a350505050610e3260015f55565b6001546001600160a01b031633146111055760405162461bcd60e51b8152600401610bb990613a53565b670de0b6b3a76400008111156111725760405162461bcd60e51b815260206004820152602c60248201527f5348617265526577617264506f6f6c3a20696e76616c6964206d617820636c6160448201526b1a5b481d1a1c995cda1bdb1960a21b6064820152608401610bb9565b600555565b61117f612940565b5f600a828154811061119357611193613a9e565b5f9182526020808320858452600b8252604080852033865290925292208054600890920290920192506111c68482612ba8565b5f848152600c60209081526040808320338085529252822082905581845560018401919091558354611204916001600160a01b039091169083612c36565b604051818152849033907fbb757047c2b5f3974fe26b7c10f732e7bce710b0952a71082702781e62ae05959060200160405180910390a350505061124760015f55565b50565b6001546001600160a01b031633146112745760405162461bcd60e51b8152600401610bb990613a53565b600a545f5b81811015611321575f600a828154811061129557611295613a9e565b5f918252602090912060089091020180549091506001600160a01b03908116908716036113185760405162461bcd60e51b815260206004820152602b60248201527f5368617265526577617264506f6f6c3a20546f6b656e2063616e6e6f7420626560448201526a103837b7b6103a37b5b2b760a91b6064820152608401610bb9565b50600101611279565b50610de46001600160a01b0385168385612c36565b6001546001600160a01b031633146113605760405162461bcd60e51b8152600401610bb990613a53565b6101f48111156113cc5760405162461bcd60e51b815260206004820152603160248201527f5348617265526577617264506f6f6c3a20696e76616c6964207065672073746160448201527062696c697479206d6f64756c652066656560781b6064820152608401610bb9565b600455565b600a545f5b81811015610e32576113e781612997565b6113f081610be4565b6001016113d6565b6001546001600160a01b031633146114225760405162461bcd60e51b8152600401610bb990613a53565b60038054911515600160a01b0260ff60a01b19909216919091179055565b5f5f61144c848461201e565b5f858152600c602090815260408083206001600160a01b038816845290915290205490915061147c908290612935565b949350505050565b6001546001600160a01b031633146114ae5760405162461bcd60e51b8152600401610bb990613a53565b6008546040515f916001600160a01b03169083905b5f6040518083038185875af1925050503d805f81146114fd576040519150601f19603f3d011682016040523d82523d5f602084013e611502565b606091505b5050905080610e325760405162461bcd60e51b81526020600482015260146024820152736661696c656420746f2073656e6420536f6e696360601b6044820152606401610bb9565b6001546001600160a01b031633146115745760405162461bcd60e51b8152600401610bb990613a53565b6009546040515f916001600160a01b03169083906114c3565b611595612940565b600a5433905f805b828110156116c2575f600a82815481106115b9576115b9613a9e565b5f9182526020808320858452600b825260408085206001600160a01b038b1686529092529220600890910290910191506115f283612997565b6115fb83610be4565b5f61162a8260010154610fda670de0b6b3a7640000610fd48760040154875f015461292a90919063ffffffff16565b5f858152600c602090815260408083206001600160a01b038c1684529091528120549192506116598383612935565b90508015611690575f868152600c602090815260408083206001600160a01b038d16845290915281205561168d8782612935565b96505b600485015484546116ae91670de0b6b3a764000091610fd49161292a565b60019485015550505091909101905061159d565b506005548110156116e55760405162461bcd60e51b8152600401610bb990613ae4565b801561192d576003545f90600160a81b900460ff161561180457600354600254604051630d01142560e31b81526001600160a01b039182166004820152670de0b6b3a764000060248201525f929190911690636808a12890604401602060405180830381865afa15801561175b573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061177f9190613ab2565b90506117ac6103e8610fd4600454610b1c670de0b6b3a7640000610fd4898861292a90919063ffffffff16565b9150813410156117fe5760405162461bcd60e51b815260206004820152601f60248201527f696e73756666696369656e7420736f6e696320666f722050534d20636f7374006044820152606401610bb9565b50611822565b34156118225760405162461bcd60e51b8152600401610bb990613b28565b61182c8483612c99565b836001600160a01b03167fe2403640ba68fed3a2f88b7557551d1993f84b99bb10ff833f0cf8db0c5e04868360405161186791815260200190565b60405180910390a2600354600160a81b900460ff16801561188757508034115b1561192b575f6118978234613b7e565b90505f856001600160a01b0316826040515f6040518083038185875af1925050503d805f81146118e2576040519150601f19603f3d011682016040523d82523d5f602084013e6118e7565b606091505b50509050806119285760405162461bcd60e51b815260206004820152600d60248201526c1499599d5b990819985a5b1959609a1b6044820152606401610bb9565b50505b505b50505061193960015f55565b565b6001546001600160a01b031633146119655760405162461bcd60e51b8152600401610bb990613a53565b61196e83612d41565b811561197c5761197c6113d1565b600e544210156119aa57805f036119965750600e546119be565b600e548110156119a55750600e545b6119be565b8015806119b657504281105b156119be5750425b5f600e54821115806119d05750428211155b9050600a604051806101000160405280866001600160a01b031681526020018781526020018881526020018481526020015f8152602001831515815260200160405180606001604052805f151581526020015f6001600160a01b031681526020015f6002811115611a4357611a4361372c565b9052815260209081018990528254600181810185555f94855293829020835160089092020180546001600160a01b039283166001600160a01b03199091161781558383015194810194909455604080840151600280870191909155606085015160038701556080850151600487015560a085015160058701805491151560ff1990921691909117905560c085015180516006880180549683015190951661010002610100600160a81b0319911515919091166001600160a81b031990961695909517949094178084559184015194959491839160ff60a81b1990911690600160a81b908490811115611b3757611b3761372c565b0217905550505060e0820151816007015550508015611b7157600d54611b5d9087612935565b600d55601054611b6d9087612935565b6010555b505050505050565b6001546001600160a01b03163314611ba35760405162461bcd60e51b8152600401610bb990613a53565b60405163095ea7b360e01b8152733333111a391cc08fa51353e9195526a70b333333600482015260248101839052735050bc082ff4a74fb6b0b04385defddb114b24249063095ea7b3906044016020604051808303815f875af1158015611c0c573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611c309190613ac9565b505f733333111a391cc08fa51353e9195526a70b3333336001600160a01b0316638380edb76040518163ffffffff1660e01b8152600401602060405180830381865afa158015611c82573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611ca69190613ac9565b90508015611e04578115611d5e57604051636e553f6560e01b8152600481018490523060248201525f90739710e10a8f6fba8c391606fee18614885684548d90636e553f65906044016020604051808303815f875af1158015611d0b573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611d2f9190613ab2565b600854909150610de490733333111a391cc08fa51353e9195526a70b333333906001600160a01b031683612c36565b604051636e553f6560e01b815260048101849052306024820152739710e10a8f6fba8c391606fee18614885684548d90636e553f65906044016020604051808303815f875af1158015611db3573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611dd79190613ab2565b50600854611e0490733333111a391cc08fa51353e9195526a70b333333906001600160a01b031685612c36565b505050565b6001546001600160a01b03163314611e335760405162461bcd60e51b8152600401610bb990613a53565b600180546001600160a01b0319166001600160a01b0392909216919091179055565b80821115611ea55760405162461bcd60e51b815260206004820152601e60248201527f5348617265526577617264506f6f6c3a20696e76616c69642072616e676500006044820152606401610bb9565b815b818111611e0457611eb781612997565b611ec081610be4565b611ec981613b91565b9050611ea7565b6001546001600160a01b03163314611efa5760405162461bcd60e51b8152600401610bb990613a53565b600980546001600160a01b0319166001600160a01b0392909216919091179055565b6001546001600160a01b03163314611f465760405162461bcd60e51b8152600401610bb990613a53565b60038054911515600160a81b0260ff60a81b19909216919091179055565b6001546001600160a01b03163314611f8e5760405162461bcd60e51b8152600401610bb990613a53565b6001816002811115611fa257611fa261372c565b03611fb057611fb082612dd9565b6002816002811115611fc457611fc461372c565b03610e3257610e3282612f46565b6001546001600160a01b03163314611ffc5760405162461bcd60e51b8152600401610bb990613a53565b600880546001600160a01b0319166001600160a01b0392909216919091179055565b5f5f600a848154811061203357612033613a9e565b5f9182526020808320878452600b825260408085206001600160a01b0389168652909252908320600892909202016004810154600682015491945091929060ff166120e65783546040516370a0823160e01b81523060048201526001600160a01b03909116906370a0823190602401602060405180830381865afa1580156120bd573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906120e19190613ab2565b612156565b60068401546040516370a0823160e01b81523060048201526101009091046001600160a01b0316906370a0823190602401602060405180830381865afa158015612132573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906121569190613ab2565b905083600301544211801561216a57508015155b156121c5575f61217e856003015442610ace565b90505f61219e600d54610fd488600201548561292a90919063ffffffff16565b90506121c06121b984610fd484670de0b6b3a764000061292a565b8590612935565b935050505b6121ef8360010154610fda670de0b6b3a7640000610fd486885f015461292a90919063ffffffff16565b979650505050505050565b5f600a828154811061220e5761220e613a9e565b5f9182526020909120600890910201600681015490915060ff1615610e325760016006820154600160a81b900460ff16600281111561224f5761224f61372c565b0361225d5761225d8261301d565b60026006820154600160a81b900460ff16600281111561227f5761227f61372c565b03610e3257610e3282613228565b6001546001600160a01b031633146122b75760405162461bcd60e51b8152600401610bb990613a53565b60038054911515600160b01b0260ff60b01b19909216919091179055565b6122dd612940565b5f3390505f600a83815481106122f5576122f5613a9e565b5f9182526020808320868452600b825260408085206001600160a01b038816865290925292206008909102909101915061232e84612997565b61233784610be4565b5f6123668260010154610fda670de0b6b3a7640000610fd48760040154875f015461292a90919063ffffffff16565b5f868152600c602090815260408083206001600160a01b03891684529091528120549192506123958383612935565b90506005548110156123b95760405162461bcd60e51b8152600401610bb990613ae4565b8015612623575f878152600c602090815260408083206001600160a01b038a1684529091528120819055600354600160a81b900460ff16156124fa57600354600254604051630d01142560e31b81526001600160a01b039182166004820152670de0b6b3a764000060248201525f929190911690636808a12890604401602060405180830381865afa158015612451573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906124759190613ab2565b90506124a26103e8610fd4600454610b1c670de0b6b3a7640000610fd4898861292a90919063ffffffff16565b9150813410156124f45760405162461bcd60e51b815260206004820152601f60248201527f696e73756666696369656e7420736f6e696320666f722050534d20636f7374006044820152606401610bb9565b50612518565b34156125185760405162461bcd60e51b8152600401610bb990613b28565b6125228783612c99565b866001600160a01b03167fe2403640ba68fed3a2f88b7557551d1993f84b99bb10ff833f0cf8db0c5e04868360405161255d91815260200190565b60405180910390a2600354600160a81b900460ff16801561257d57508034115b15612621575f61258d8234613b7e565b90505f886001600160a01b0316826040515f6040518083038185875af1925050503d805f81146125d8576040519150601f19603f3d011682016040523d82523d5f602084013e6125dd565b606091505b505090508061261e5760405162461bcd60e51b815260206004820152600d60248201526c1499599d5b990819985a5b1959609a1b6044820152606401610bb9565b50505b505b6004850154845461264191670de0b6b3a764000091610fd49161292a565b6001948501555050505f55506112479050565b61265c612940565b5f3390505f600a848154811061267457612674613a9e565b5f9182526020808320878452600b825260408085206001600160a01b03881686529092529220600890910290910191506126ad85612997565b80541561273c575f6126e38260010154610fda670de0b6b3a7640000610fd48760040154875f015461292a90919063ffffffff16565b9050801561273a575f868152600c602090815260408083206001600160a01b03881684529091529020546127179082612935565b5f878152600c602090815260408083206001600160a01b03891684529091529020555b505b83156127ae578154612759906001600160a01b0316843087613348565b5f612777612710610fd485600101548861292a90919063ffffffff16565b905061278e6127868683612918565b835490612935565b825560085483546127ac916001600160a01b03918216911683612c36565b505b6127b785610be4565b600482015481546127d591670de0b6b3a764000091610fd49161292a565b600182015560405184815285906001600160a01b038516907f90890809c654f11d6e72a28fa60149770a0d11ec6c92319d6ceb2bb0a4ea1a159060200160405180910390a3505050610e3260015f55565b6001546001600160a01b031633146128505760405162461bcd60e51b8152600401610bb990613a53565b848314801561285e57508481145b6128aa5760405162461bcd60e51b815260206004820152601f60248201527f5348617265526577617264506f6f6c3a20696e76616c6964206c656e677468006044820152606401610bb9565b5f5b8581101561290f576129078787838181106128c9576128c9613a9e565b905060200201358686848181106128e2576128e2613a9e565b905060200201358585858181106128fb576128fb613a9e565b90506020020135610e36565b6001016128ac565b50505050505050565b5f6129238284613b7e565b9392505050565b5f6129238284613ba9565b5f6129238284613bc0565b60025f54036129915760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610bb9565b60025f55565b6129a081610be4565b5f600a82815481106129b4576129b4613a9e565b905f5260205f2090600802019050806003015442116129d1575050565b60068101545f9060ff16612a4d5781546040516370a0823160e01b81523060048201526001600160a01b03909116906370a0823190602401602060405180830381865afa158015612a24573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612a489190613ab2565b612abd565b60068201546040516370a0823160e01b81523060048201526101009091046001600160a01b0316906370a0823190602401602060405180830381865afa158015612a99573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612abd9190613ab2565b9050805f03612ad157504260039091015550565b600582015460ff16612b155760058201805460ff191660011790556002820154600d54612afd91612935565b600d556007820154601054612b1191612935565b6010555b600d5415612b7a575f612b2c836003015442610ace565b90505f612b4c600d54610fd486600201548561292a90919063ffffffff16565b9050612b72612b6784610fd484670de0b6b3a764000061292a565b600486015490612935565b600485015550505b4260038381019190915554600160a01b900460ff1615611e0457611e04836121fa565b5f6129238284613bd3565b5f600a8381548110612bbc57612bbc613a9e565b5f9182526020909120600890910201600681015490915060ff1615611e04576006810154604051632e1a7d4d60e01b8152600481018490526101009091046001600160a01b031690632e1a7d4d906024015f604051808303815f87803b158015612c24575f5ffd5b505af115801561290f573d5f5f3e3d5ffd5b6040516001600160a01b038316602482015260448101829052611e0490849063a9059cbb60e01b906064015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152613380565b6002546040516370a0823160e01b81523060048201525f916001600160a01b0316906370a0823190602401602060405180830381865afa158015612cdf573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612d039190613ab2565b90508015611e045780821115612d2a57600254611e04906001600160a01b03168483612c36565b600254611e04906001600160a01b03168484612c36565b600a545f5b81811015611e0457826001600160a01b0316600a8281548110612d6b57612d6b613a9e565b5f9182526020909120600890910201546001600160a01b031603612dd15760405162461bcd60e51b815260206004820152601f60248201527f5348617265526577617264506f6f6c3a206578697374696e6720706f6f6c3f006044820152606401610bb9565b600101612d46565b600654600a80545f926001600160a01b031691632045be909185908110612e0257612e02613a9e565b5f91825260209091206008909102015460405160e083901b6001600160e01b03191681526001600160a01b039091166004820152602401602060405180830381865afa158015612e54573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612e789190613c02565b90506001600160a01b03811615610e32576040805160608101825260018082526001600160a01b038416602083015290918201905b815250600a8381548110612ec357612ec3613a9e565b5f918252602091829020835160066008909302909101919091018054928401516001600160a01b031661010002610100600160a81b0319921515929092166001600160a81b03199093169290921717808255604083015190829060ff60a81b1916600160a81b836002811115612f3b57612f3b61372c565b021790555050505050565b600754600a80545f926001600160a01b03169163b9a09fd59185908110612f6f57612f6f613a9e565b5f91825260209091206008909102015460405160e083901b6001600160e01b03191681526001600160a01b039091166004820152602401602060405180830381865afa158015612fc1573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612fe59190613c02565b90506001600160a01b03811615610e325760408051606081018252600181526001600160a01b03831660208201529081016002612ead565b5f600a828154811061303157613031613a9e565b905f5260205f20906008020190505f816006015f0160019054906101000a90046001600160a01b03166001600160a01b0316638003b6146040518163ffffffff1660e01b81526004015f60405180830381865afa158015613094573d5f5f3e3d5ffd5b505050506040513d5f823e601f3d908101601f191682016040526130bb9190810190613c31565b60068301546040516331279d3d60e01b815291925061010090046001600160a01b0316906331279d3d906130f59030908590600401613cfc565b5f604051808303815f87803b15801561310c575f5ffd5b505af115801561311e573d5f5f3e3d5ffd5b505f925050505b8151811015610de4575f82828151811061314157613141613a9e565b60209081029190910101516040516370a0823160e01b81523060048201529091505f906001600160a01b038316906370a0823190602401602060405180830381865afa158015613193573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906131b79190613ab2565b9050801561321e57735050bc082ff4a74fb6b0b04385defddb114b2423196001600160a01b0383160161320457600354600160b01b900460ff16156131ff576131ff81613453565b61321e565b60085461321e906001600160a01b03848116911683612c36565b5050600101613125565b5f600a828154811061323c5761323c613a9e565b905f5260205f2090600802019050806006015f0160019054906101000a90046001600160a01b03166001600160a01b0316633d18b9126040518163ffffffff1660e01b81526004015f604051808303815f87803b15801561329b575f5ffd5b505af11580156132ad573d5f5f3e3d5ffd5b50506040516370a0823160e01b815230600482015273a04bc7140c26fc9bb1f36b1a604c7a5a88fb0e7092505f915082906370a0823190602401602060405180830381865afa158015613302573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906133269190613ab2565b90508015610de457600854610de4906001600160a01b03848116911683612c36565b6040516001600160a01b0380851660248301528316604482015260648101829052610de49085906323b872dd60e01b90608401612c62565b5f6133d4826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166136089092919063ffffffff16565b905080515f14806133f45750808060200190518101906133f49190613ac9565b611e045760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608401610bb9565b60405163095ea7b360e01b8152733333111a391cc08fa51353e9195526a70b333333600482015260248101829052735050bc082ff4a74fb6b0b04385defddb114b24249063095ea7b3906044016020604051808303815f875af11580156134bc573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906134e09190613ac9565b505f733333111a391cc08fa51353e9195526a70b3333336001600160a01b0316638380edb76040518163ffffffff1660e01b8152600401602060405180830381865afa158015613532573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906135569190613ac9565b90508015610e3257604051636e553f6560e01b8152600481018390523060248201525f90739710e10a8f6fba8c391606fee18614885684548d90636e553f65906044016020604051808303815f875af11580156135b5573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906135d99190613ab2565b600854909150611e0490733333111a391cc08fa51353e9195526a70b333333906001600160a01b031683612c36565b606061147c84845f85855f5f866001600160a01b0316858760405161362d9190613d5a565b5f6040518083038185875af1925050503d805f8114613667576040519150601f19603f3d011682016040523d82523d5f602084013e61366c565b606091505b50915091506121ef87838387606083156136e65782515f036136df576001600160a01b0385163b6136df5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610bb9565b508161147c565b61147c83838151156136fb5781518083602001fd5b8060405162461bcd60e51b8152600401610bb99190613d70565b5f60208284031215613725575f5ffd5b5035919050565b634e487b7160e01b5f52602160045260245ffd5b6001600160a01b03898116825260208083018a905260408084018a9052606084018990526080840188905286151560a08501528551151560c08501529085015190911660e0830152830151610140820190600381106137ad57634e487b7160e01b5f52602160045260245ffd5b61010083015261012090910191909152979650505050505050565b5f5f604083850312156137d9575f5ffd5b50508035926020909101359150565b6001600160a01b0381168114611247575f5ffd5b5f6020828403121561380c575f5ffd5b8135612923816137e8565b5f5f5f60608486031215613829575f5ffd5b505081359360208301359350604090920135919050565b5f5f5f60608486031215613852575f5ffd5b833561385d816137e8565b9250602084013591506040840135613874816137e8565b809150509250925092565b8015158114611247575f5ffd5b5f6020828403121561389c575f5ffd5b81356129238161387f565b5f5f604083850312156138b8575f5ffd5b8235915060208301356138ca816137e8565b809150509250929050565b5f5f5f5f5f60a086880312156138e9575f5ffd5b85359450602086013593506040860135613902816137e8565b925060608601356139128161387f565b949793965091946080013592915050565b5f5f60408385031215613934575f5ffd5b8235915060208301356138ca8161387f565b5f5f60408385031215613957575f5ffd5b823591506020830135600381106138ca575f5ffd5b5f5f83601f84011261397c575f5ffd5b50813567ffffffffffffffff811115613993575f5ffd5b6020830191508360208260051b85010111156139ad575f5ffd5b9250929050565b5f5f5f5f5f5f606087890312156139c9575f5ffd5b863567ffffffffffffffff8111156139df575f5ffd5b6139eb89828a0161396c565b909750955050602087013567ffffffffffffffff811115613a0a575f5ffd5b613a1689828a0161396c565b909550935050604087013567ffffffffffffffff811115613a35575f5ffd5b613a4189828a0161396c565b979a9699509497509295939492505050565b6020808252602b908201527f5348617265526577617264506f6f6c3a2063616c6c6572206973206e6f74207460408201526a34329037b832b930ba37b960a91b606082015260800190565b634e487b7160e01b5f52603260045260245ffd5b5f60208284031215613ac2575f5ffd5b5051919050565b5f60208284031215613ad9575f5ffd5b81516129238161387f565b60208082526024908201527f436c61696d20616d6f756e742062656c6f77206d696e696d756d2074687265736040820152631a1bdb1960e21b606082015260800190565b60208082526022908201527f5348617265526577617264506f6f6c3a20696e76616c6964206d73672e76616c604082015261756560f01b606082015260800190565b634e487b7160e01b5f52601160045260245ffd5b81810381811115610b8957610b89613b6a565b5f60018201613ba257613ba2613b6a565b5060010190565b8082028115828204841417610b8957610b89613b6a565b80820180821115610b8957610b89613b6a565b5f82613bed57634e487b7160e01b5f52601260045260245ffd5b500490565b8051613bfd816137e8565b919050565b5f60208284031215613c12575f5ffd5b8151612923816137e8565b634e487b7160e01b5f52604160045260245ffd5b5f60208284031215613c41575f5ffd5b815167ffffffffffffffff811115613c57575f5ffd5b8201601f81018413613c67575f5ffd5b805167ffffffffffffffff811115613c8157613c81613c1d565b8060051b604051601f19603f830116810181811067ffffffffffffffff82111715613cae57613cae613c1d565b604052918252602081840181019290810187841115613ccb575f5ffd5b6020850194505b83851015613cf157613ce385613bf2565b815260209485019401613cd2565b509695505050505050565b6001600160a01b03831681526040602080830182905283519183018290525f91908401906060840190835b81811015613d4e5783516001600160a01b0316835260209384019390920191600101613d27565b50909695505050505050565b5f82518060208501845e5f920191825250919050565b602081525f82518060208401528060208501604085015e5f604082850101526040601f19601f8301168401019150509291505056fea2646970667358221220546019463008f930e7086dcc27b8ea4c441319f42813d3eace00544febff80b864736f6c634300081c003300000000000000000000000041e9bc85e6cd64852d9cb8cb22a69d26117f7448000000000000000000000000ef353f79d4368a26ee535a21763fa5ee2bd871710000000000000000000000000000000000000000000000000000000067ccbde00000000000000000000000009f59398d0a397b2eeb8a6123a6c7295cb0b0062d000000000000000000000000c1ae2779903cfb84cb9dee5c03eceac32dc407f2
Deployed Bytecode
0x608060405260043610610340575f3560e01c806371747802116101bd578063ba44a45a116100f2578063d18df53c11610092578063de89c76c1161006d578063de89c76c1461098d578063dfbffa8c146109ac578063e2bbb158146109d3578063fddc298c146109f2575f5ffd5b8063d18df53c14610925578063da1165221461095b578063ddc632621461097a575f5ffd5b8063ce862f17116100cd578063ce862f17146108a9578063ced8a5d7146108c8578063cf4b55cb146108e7578063d02ade9414610906575f5ffd5b8063ba44a45a14610856578063c4c7fe691461086b578063c69c2c021461088a575f5ffd5b8063943f013d1161015d578063a8d5fd6511610138578063a8d5fd65146107da578063ad149a1e146107f9578063b3ab15fb14610818578063b947a88d14610837575f5ffd5b8063943f013d1461077f57806396f38bdb14610794578063a44a7432146107bb575f5ffd5b8063893d3f0f11610198578063893d3f0f146106e75780638ed955b91461070657806390c5ed6a1461070e57806393f1a40b1461072d575f5ffd5b8063717478021461068957806378e39d5d146106a95780637bd153e6146106c8575f5ffd5b806351637ba911610293578063605783691161023357806363eb04161161020e57806363eb0416146106175780636b2681c5146106365780636e142c8e146106555780636e271dd514610674575f5ffd5b806360578369146105c457806361e79f02146105e3578063630b5ba114610603575f5ffd5b8063549c278a1161026e578063549c278a14610554578063570ca7351461057b5780635752933a1461059a5780635f96dc11146105af575f5ffd5b806351637ba9146104f75780635312ea8e1461051657806354575af414610535575f5ffd5b80632df95ed7116102fe5780633aa158ee116102d95780633aa158ee146104815780633afb24f11461049557806343b0e8df146104c5578063441a3e70146104e4575f5ffd5b80632df95ed71461042e5780633202f6c11461044d5780633695dad11461046c575f5ffd5b8062c6b39114610344578063081e3eda146103885780631526fe27146103a657806317caf6f1146103d9578063231f0c6a146103ee57806329e63f7a1461040d575b5f5ffd5b34801561034f575f5ffd5b5061036b735050bc082ff4a74fb6b0b04385defddb114b242481565b6040516001600160a01b0390911681526020015b60405180910390f35b348015610393575f5ffd5b50600a545b60405190815260200161037f565b3480156103b1575f5ffd5b506103c56103c0366004613715565b610a11565b60405161037f989796959493929190613740565b3480156103e4575f5ffd5b50610398600d5481565b3480156103f9575f5ffd5b506103986104083660046137c8565b610ace565b348015610418575f5ffd5b5061042c6104273660046137fc565b610b8f565b005b348015610439575f5ffd5b5061042c610448366004613715565b610be4565b348015610458575f5ffd5b5060065461036b906001600160a01b031681565b348015610477575f5ffd5b5061039860055481565b34801561048c575f5ffd5b5061042c610dea565b3480156104a0575f5ffd5b506003546104b590600160a01b900460ff1681565b604051901515815260200161037f565b3480156104d0575f5ffd5b5061042c6104df366004613817565b610e36565b61042c6104f23660046137c8565b610efd565b348015610502575f5ffd5b5061042c610511366004613715565b6110db565b348015610521575f5ffd5b5061042c610530366004613715565b611177565b348015610540575f5ffd5b5061042c61054f366004613840565b61124a565b34801561055f575f5ffd5b5061036b733333111a391cc08fa51353e9195526a70b33333381565b348015610586575f5ffd5b5060015461036b906001600160a01b031681565b3480156105a5575f5ffd5b5061039860105481565b3480156105ba575f5ffd5b50610398600e5481565b3480156105cf575f5ffd5b5061042c6105de366004613715565b611336565b3480156105ee575f5ffd5b506003546104b590600160b01b900460ff1681565b34801561060e575f5ffd5b5061042c6113d1565b348015610622575f5ffd5b5061042c61063136600461388c565b6113f8565b348015610641575f5ffd5b506103986106503660046138a7565b611440565b348015610660575f5ffd5b5060075461036b906001600160a01b031681565b34801561067f575f5ffd5b50610398600f5481565b348015610694575f5ffd5b506003546104b590600160a81b900460ff1681565b3480156106b4575f5ffd5b5061042c6106c3366004613715565b611484565b3480156106d3575f5ffd5b5060035461036b906001600160a01b031681565b3480156106f2575f5ffd5b5061042c610701366004613715565b61154a565b61042c61158d565b348015610719575f5ffd5b5061042c6107283660046138d5565b61193b565b348015610738575f5ffd5b5061076a6107473660046138a7565b600b60209081525f92835260408084209091529082529020805460019091015482565b6040805192835260208301919091520161037f565b34801561078a575f5ffd5b5061039860115481565b34801561079f575f5ffd5b5061036b739710e10a8f6fba8c391606fee18614885684548d81565b3480156107c6575f5ffd5b5061042c6107d5366004613923565b611b79565b3480156107e5575f5ffd5b5060025461036b906001600160a01b031681565b348015610804575f5ffd5b5060095461036b906001600160a01b031681565b348015610823575f5ffd5b5061042c6108323660046137fc565b611e09565b348015610842575f5ffd5b5061042c6108513660046137c8565b611e55565b348015610861575f5ffd5b5061039860045481565b348015610876575f5ffd5b5061042c6108853660046137fc565b611ed0565b348015610895575f5ffd5b5061042c6108a436600461388c565b611f1c565b3480156108b4575f5ffd5b5061042c6108c3366004613946565b611f64565b3480156108d3575f5ffd5b5061042c6108e23660046137fc565b611fd2565b3480156108f2575f5ffd5b506103986109013660046138a7565b61201e565b348015610911575f5ffd5b5061042c610920366004613715565b6121fa565b348015610930575f5ffd5b5061039861093f3660046138a7565b600c60209081525f928352604080842090915290825290205481565b348015610966575f5ffd5b5061042c61097536600461388c565b61228d565b61042c610988366004613715565b6122d5565b348015610998575f5ffd5b5060085461036b906001600160a01b031681565b3480156109b7575f5ffd5b5061036b73a04bc7140c26fc9bb1f36b1a604c7a5a88fb0e7081565b3480156109de575f5ffd5b5061042c6109ed3660046137c8565b612654565b3480156109fd575f5ffd5b5061042c610a0c3660046139b4565b612826565b600a8181548110610a20575f80fd5b5f918252602091829020600890910201805460018201546002808401546003850154600486015460058701546040805160608101825260068a01805460ff8181161515845261010082046001600160a01b039081169e85019e909e529c909a169c50979a9599949893979286169694959094929391850192600160a81b9092041690811115610ab157610ab161372c565b6002811115610ac257610ac261372c565b90525060079091015488565b5f818310610add57505f610b89565b600f548210610b4457600f548310610af657505f610b89565b600e548311610b2957610b22601054610b1c600e54600f5461291890919063ffffffff16565b9061292a565b9050610b89565b610b22601054610b1c85600f5461291890919063ffffffff16565b600e548211610b5457505f610b89565b600e548311610b7857610b22601054610b1c600e548561291890919063ffffffff16565b601054610b2290610b1c8486612918565b92915050565b6001546001600160a01b03163314610bc25760405162461bcd60e51b8152600401610bb990613a53565b60405180910390fd5b600380546001600160a01b0319166001600160a01b0392909216919091179055565b5f600a8281548110610bf857610bf8613a9e565b5f9182526020822060089190910201600681015481546040516370a0823160e01b81523060048201529294506101009091046001600160a01b0390811693929116906370a0823190602401602060405180830381865afa158015610c5e573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610c829190613ab2565b600684015490915060ff1615610de4578015610de4578254604051636eb1769f60e11b81523060048201526001600160a01b0384811660248301528392169063dd62ed3e90604401602060405180830381865afa158015610ce5573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610d099190613ab2565b1015610d8457825460405163095ea7b360e01b81526001600160a01b0384811660048301525f1960248301529091169063095ea7b3906044016020604051808303815f875af1158015610d5e573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610d829190613ac9565b505b600683015460405163b6b55f2560e01b8152600481018390526101009091046001600160a01b03169063b6b55f25906024015f604051808303815f87803b158015610dcd575f5ffd5b505af1158015610ddf573d5f5f3e3d5ffd5b505050505b50505050565b6001546001600160a01b03163314610e145760405162461bcd60e51b8152600401610bb990613a53565b600a545f5b81811015610e3257610e2a816121fa565b600101610e19565b5050565b6001546001600160a01b03163314610e605760405162461bcd60e51b8152600401610bb990613a53565b610e686113d1565b5f600a8481548110610e7c57610e7c613a9e565b905f5260205f209060080201905060c88210610e96575f5ffd5b60018101829055600581015460ff1615610eeb57610ecd83610ec78360020154600d5461291890919063ffffffff16565b90612935565b600d556007810154601054610ee7918591610ec791612918565b6010555b60028101839055600701919091555050565b610f05612940565b5f3390505f600a8481548110610f1d57610f1d613a9e565b5f9182526020808320878452600b825260408085206001600160a01b03881686529092529220805460089092029092019250841115610f935760405162461bcd60e51b81526020600482015260126024820152711dda5d1a191c985dce881b9bdd0819dbdbd960721b6044820152606401610bb9565b610f9c85612997565b610fa585610be4565b5f610fe08260010154610fda670de0b6b3a7640000610fd48760040154875f015461292a90919063ffffffff16565b90612b9d565b90612918565b90508015611037575f868152600c602090815260408083206001600160a01b03881684529091529020546110149082612935565b5f878152600c602090815260408083206001600160a01b03891684529091529020555b841561106b5781546110499086612918565b82556110558686612ba8565b825461106b906001600160a01b03168587612c36565b6004830154825461108991670de0b6b3a764000091610fd49161292a565b600183015560405185815286906001600160a01b038616907ff279e6a1f5e320cca91135676d9cb6e44ca8a08c0b88342bcdb1144f6511b5689060200160405180910390a350505050610e3260015f55565b6001546001600160a01b031633146111055760405162461bcd60e51b8152600401610bb990613a53565b670de0b6b3a76400008111156111725760405162461bcd60e51b815260206004820152602c60248201527f5348617265526577617264506f6f6c3a20696e76616c6964206d617820636c6160448201526b1a5b481d1a1c995cda1bdb1960a21b6064820152608401610bb9565b600555565b61117f612940565b5f600a828154811061119357611193613a9e565b5f9182526020808320858452600b8252604080852033865290925292208054600890920290920192506111c68482612ba8565b5f848152600c60209081526040808320338085529252822082905581845560018401919091558354611204916001600160a01b039091169083612c36565b604051818152849033907fbb757047c2b5f3974fe26b7c10f732e7bce710b0952a71082702781e62ae05959060200160405180910390a350505061124760015f55565b50565b6001546001600160a01b031633146112745760405162461bcd60e51b8152600401610bb990613a53565b600a545f5b81811015611321575f600a828154811061129557611295613a9e565b5f918252602090912060089091020180549091506001600160a01b03908116908716036113185760405162461bcd60e51b815260206004820152602b60248201527f5368617265526577617264506f6f6c3a20546f6b656e2063616e6e6f7420626560448201526a103837b7b6103a37b5b2b760a91b6064820152608401610bb9565b50600101611279565b50610de46001600160a01b0385168385612c36565b6001546001600160a01b031633146113605760405162461bcd60e51b8152600401610bb990613a53565b6101f48111156113cc5760405162461bcd60e51b815260206004820152603160248201527f5348617265526577617264506f6f6c3a20696e76616c6964207065672073746160448201527062696c697479206d6f64756c652066656560781b6064820152608401610bb9565b600455565b600a545f5b81811015610e32576113e781612997565b6113f081610be4565b6001016113d6565b6001546001600160a01b031633146114225760405162461bcd60e51b8152600401610bb990613a53565b60038054911515600160a01b0260ff60a01b19909216919091179055565b5f5f61144c848461201e565b5f858152600c602090815260408083206001600160a01b038816845290915290205490915061147c908290612935565b949350505050565b6001546001600160a01b031633146114ae5760405162461bcd60e51b8152600401610bb990613a53565b6008546040515f916001600160a01b03169083905b5f6040518083038185875af1925050503d805f81146114fd576040519150601f19603f3d011682016040523d82523d5f602084013e611502565b606091505b5050905080610e325760405162461bcd60e51b81526020600482015260146024820152736661696c656420746f2073656e6420536f6e696360601b6044820152606401610bb9565b6001546001600160a01b031633146115745760405162461bcd60e51b8152600401610bb990613a53565b6009546040515f916001600160a01b03169083906114c3565b611595612940565b600a5433905f805b828110156116c2575f600a82815481106115b9576115b9613a9e565b5f9182526020808320858452600b825260408085206001600160a01b038b1686529092529220600890910290910191506115f283612997565b6115fb83610be4565b5f61162a8260010154610fda670de0b6b3a7640000610fd48760040154875f015461292a90919063ffffffff16565b5f858152600c602090815260408083206001600160a01b038c1684529091528120549192506116598383612935565b90508015611690575f868152600c602090815260408083206001600160a01b038d16845290915281205561168d8782612935565b96505b600485015484546116ae91670de0b6b3a764000091610fd49161292a565b60019485015550505091909101905061159d565b506005548110156116e55760405162461bcd60e51b8152600401610bb990613ae4565b801561192d576003545f90600160a81b900460ff161561180457600354600254604051630d01142560e31b81526001600160a01b039182166004820152670de0b6b3a764000060248201525f929190911690636808a12890604401602060405180830381865afa15801561175b573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061177f9190613ab2565b90506117ac6103e8610fd4600454610b1c670de0b6b3a7640000610fd4898861292a90919063ffffffff16565b9150813410156117fe5760405162461bcd60e51b815260206004820152601f60248201527f696e73756666696369656e7420736f6e696320666f722050534d20636f7374006044820152606401610bb9565b50611822565b34156118225760405162461bcd60e51b8152600401610bb990613b28565b61182c8483612c99565b836001600160a01b03167fe2403640ba68fed3a2f88b7557551d1993f84b99bb10ff833f0cf8db0c5e04868360405161186791815260200190565b60405180910390a2600354600160a81b900460ff16801561188757508034115b1561192b575f6118978234613b7e565b90505f856001600160a01b0316826040515f6040518083038185875af1925050503d805f81146118e2576040519150601f19603f3d011682016040523d82523d5f602084013e6118e7565b606091505b50509050806119285760405162461bcd60e51b815260206004820152600d60248201526c1499599d5b990819985a5b1959609a1b6044820152606401610bb9565b50505b505b50505061193960015f55565b565b6001546001600160a01b031633146119655760405162461bcd60e51b8152600401610bb990613a53565b61196e83612d41565b811561197c5761197c6113d1565b600e544210156119aa57805f036119965750600e546119be565b600e548110156119a55750600e545b6119be565b8015806119b657504281105b156119be5750425b5f600e54821115806119d05750428211155b9050600a604051806101000160405280866001600160a01b031681526020018781526020018881526020018481526020015f8152602001831515815260200160405180606001604052805f151581526020015f6001600160a01b031681526020015f6002811115611a4357611a4361372c565b9052815260209081018990528254600181810185555f94855293829020835160089092020180546001600160a01b039283166001600160a01b03199091161781558383015194810194909455604080840151600280870191909155606085015160038701556080850151600487015560a085015160058701805491151560ff1990921691909117905560c085015180516006880180549683015190951661010002610100600160a81b0319911515919091166001600160a81b031990961695909517949094178084559184015194959491839160ff60a81b1990911690600160a81b908490811115611b3757611b3761372c565b0217905550505060e0820151816007015550508015611b7157600d54611b5d9087612935565b600d55601054611b6d9087612935565b6010555b505050505050565b6001546001600160a01b03163314611ba35760405162461bcd60e51b8152600401610bb990613a53565b60405163095ea7b360e01b8152733333111a391cc08fa51353e9195526a70b333333600482015260248101839052735050bc082ff4a74fb6b0b04385defddb114b24249063095ea7b3906044016020604051808303815f875af1158015611c0c573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611c309190613ac9565b505f733333111a391cc08fa51353e9195526a70b3333336001600160a01b0316638380edb76040518163ffffffff1660e01b8152600401602060405180830381865afa158015611c82573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611ca69190613ac9565b90508015611e04578115611d5e57604051636e553f6560e01b8152600481018490523060248201525f90739710e10a8f6fba8c391606fee18614885684548d90636e553f65906044016020604051808303815f875af1158015611d0b573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611d2f9190613ab2565b600854909150610de490733333111a391cc08fa51353e9195526a70b333333906001600160a01b031683612c36565b604051636e553f6560e01b815260048101849052306024820152739710e10a8f6fba8c391606fee18614885684548d90636e553f65906044016020604051808303815f875af1158015611db3573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611dd79190613ab2565b50600854611e0490733333111a391cc08fa51353e9195526a70b333333906001600160a01b031685612c36565b505050565b6001546001600160a01b03163314611e335760405162461bcd60e51b8152600401610bb990613a53565b600180546001600160a01b0319166001600160a01b0392909216919091179055565b80821115611ea55760405162461bcd60e51b815260206004820152601e60248201527f5348617265526577617264506f6f6c3a20696e76616c69642072616e676500006044820152606401610bb9565b815b818111611e0457611eb781612997565b611ec081610be4565b611ec981613b91565b9050611ea7565b6001546001600160a01b03163314611efa5760405162461bcd60e51b8152600401610bb990613a53565b600980546001600160a01b0319166001600160a01b0392909216919091179055565b6001546001600160a01b03163314611f465760405162461bcd60e51b8152600401610bb990613a53565b60038054911515600160a81b0260ff60a81b19909216919091179055565b6001546001600160a01b03163314611f8e5760405162461bcd60e51b8152600401610bb990613a53565b6001816002811115611fa257611fa261372c565b03611fb057611fb082612dd9565b6002816002811115611fc457611fc461372c565b03610e3257610e3282612f46565b6001546001600160a01b03163314611ffc5760405162461bcd60e51b8152600401610bb990613a53565b600880546001600160a01b0319166001600160a01b0392909216919091179055565b5f5f600a848154811061203357612033613a9e565b5f9182526020808320878452600b825260408085206001600160a01b0389168652909252908320600892909202016004810154600682015491945091929060ff166120e65783546040516370a0823160e01b81523060048201526001600160a01b03909116906370a0823190602401602060405180830381865afa1580156120bd573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906120e19190613ab2565b612156565b60068401546040516370a0823160e01b81523060048201526101009091046001600160a01b0316906370a0823190602401602060405180830381865afa158015612132573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906121569190613ab2565b905083600301544211801561216a57508015155b156121c5575f61217e856003015442610ace565b90505f61219e600d54610fd488600201548561292a90919063ffffffff16565b90506121c06121b984610fd484670de0b6b3a764000061292a565b8590612935565b935050505b6121ef8360010154610fda670de0b6b3a7640000610fd486885f015461292a90919063ffffffff16565b979650505050505050565b5f600a828154811061220e5761220e613a9e565b5f9182526020909120600890910201600681015490915060ff1615610e325760016006820154600160a81b900460ff16600281111561224f5761224f61372c565b0361225d5761225d8261301d565b60026006820154600160a81b900460ff16600281111561227f5761227f61372c565b03610e3257610e3282613228565b6001546001600160a01b031633146122b75760405162461bcd60e51b8152600401610bb990613a53565b60038054911515600160b01b0260ff60b01b19909216919091179055565b6122dd612940565b5f3390505f600a83815481106122f5576122f5613a9e565b5f9182526020808320868452600b825260408085206001600160a01b038816865290925292206008909102909101915061232e84612997565b61233784610be4565b5f6123668260010154610fda670de0b6b3a7640000610fd48760040154875f015461292a90919063ffffffff16565b5f868152600c602090815260408083206001600160a01b03891684529091528120549192506123958383612935565b90506005548110156123b95760405162461bcd60e51b8152600401610bb990613ae4565b8015612623575f878152600c602090815260408083206001600160a01b038a1684529091528120819055600354600160a81b900460ff16156124fa57600354600254604051630d01142560e31b81526001600160a01b039182166004820152670de0b6b3a764000060248201525f929190911690636808a12890604401602060405180830381865afa158015612451573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906124759190613ab2565b90506124a26103e8610fd4600454610b1c670de0b6b3a7640000610fd4898861292a90919063ffffffff16565b9150813410156124f45760405162461bcd60e51b815260206004820152601f60248201527f696e73756666696369656e7420736f6e696320666f722050534d20636f7374006044820152606401610bb9565b50612518565b34156125185760405162461bcd60e51b8152600401610bb990613b28565b6125228783612c99565b866001600160a01b03167fe2403640ba68fed3a2f88b7557551d1993f84b99bb10ff833f0cf8db0c5e04868360405161255d91815260200190565b60405180910390a2600354600160a81b900460ff16801561257d57508034115b15612621575f61258d8234613b7e565b90505f886001600160a01b0316826040515f6040518083038185875af1925050503d805f81146125d8576040519150601f19603f3d011682016040523d82523d5f602084013e6125dd565b606091505b505090508061261e5760405162461bcd60e51b815260206004820152600d60248201526c1499599d5b990819985a5b1959609a1b6044820152606401610bb9565b50505b505b6004850154845461264191670de0b6b3a764000091610fd49161292a565b6001948501555050505f55506112479050565b61265c612940565b5f3390505f600a848154811061267457612674613a9e565b5f9182526020808320878452600b825260408085206001600160a01b03881686529092529220600890910290910191506126ad85612997565b80541561273c575f6126e38260010154610fda670de0b6b3a7640000610fd48760040154875f015461292a90919063ffffffff16565b9050801561273a575f868152600c602090815260408083206001600160a01b03881684529091529020546127179082612935565b5f878152600c602090815260408083206001600160a01b03891684529091529020555b505b83156127ae578154612759906001600160a01b0316843087613348565b5f612777612710610fd485600101548861292a90919063ffffffff16565b905061278e6127868683612918565b835490612935565b825560085483546127ac916001600160a01b03918216911683612c36565b505b6127b785610be4565b600482015481546127d591670de0b6b3a764000091610fd49161292a565b600182015560405184815285906001600160a01b038516907f90890809c654f11d6e72a28fa60149770a0d11ec6c92319d6ceb2bb0a4ea1a159060200160405180910390a3505050610e3260015f55565b6001546001600160a01b031633146128505760405162461bcd60e51b8152600401610bb990613a53565b848314801561285e57508481145b6128aa5760405162461bcd60e51b815260206004820152601f60248201527f5348617265526577617264506f6f6c3a20696e76616c6964206c656e677468006044820152606401610bb9565b5f5b8581101561290f576129078787838181106128c9576128c9613a9e565b905060200201358686848181106128e2576128e2613a9e565b905060200201358585858181106128fb576128fb613a9e565b90506020020135610e36565b6001016128ac565b50505050505050565b5f6129238284613b7e565b9392505050565b5f6129238284613ba9565b5f6129238284613bc0565b60025f54036129915760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610bb9565b60025f55565b6129a081610be4565b5f600a82815481106129b4576129b4613a9e565b905f5260205f2090600802019050806003015442116129d1575050565b60068101545f9060ff16612a4d5781546040516370a0823160e01b81523060048201526001600160a01b03909116906370a0823190602401602060405180830381865afa158015612a24573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612a489190613ab2565b612abd565b60068201546040516370a0823160e01b81523060048201526101009091046001600160a01b0316906370a0823190602401602060405180830381865afa158015612a99573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612abd9190613ab2565b9050805f03612ad157504260039091015550565b600582015460ff16612b155760058201805460ff191660011790556002820154600d54612afd91612935565b600d556007820154601054612b1191612935565b6010555b600d5415612b7a575f612b2c836003015442610ace565b90505f612b4c600d54610fd486600201548561292a90919063ffffffff16565b9050612b72612b6784610fd484670de0b6b3a764000061292a565b600486015490612935565b600485015550505b4260038381019190915554600160a01b900460ff1615611e0457611e04836121fa565b5f6129238284613bd3565b5f600a8381548110612bbc57612bbc613a9e565b5f9182526020909120600890910201600681015490915060ff1615611e04576006810154604051632e1a7d4d60e01b8152600481018490526101009091046001600160a01b031690632e1a7d4d906024015f604051808303815f87803b158015612c24575f5ffd5b505af115801561290f573d5f5f3e3d5ffd5b6040516001600160a01b038316602482015260448101829052611e0490849063a9059cbb60e01b906064015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152613380565b6002546040516370a0823160e01b81523060048201525f916001600160a01b0316906370a0823190602401602060405180830381865afa158015612cdf573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612d039190613ab2565b90508015611e045780821115612d2a57600254611e04906001600160a01b03168483612c36565b600254611e04906001600160a01b03168484612c36565b600a545f5b81811015611e0457826001600160a01b0316600a8281548110612d6b57612d6b613a9e565b5f9182526020909120600890910201546001600160a01b031603612dd15760405162461bcd60e51b815260206004820152601f60248201527f5348617265526577617264506f6f6c3a206578697374696e6720706f6f6c3f006044820152606401610bb9565b600101612d46565b600654600a80545f926001600160a01b031691632045be909185908110612e0257612e02613a9e565b5f91825260209091206008909102015460405160e083901b6001600160e01b03191681526001600160a01b039091166004820152602401602060405180830381865afa158015612e54573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612e789190613c02565b90506001600160a01b03811615610e32576040805160608101825260018082526001600160a01b038416602083015290918201905b815250600a8381548110612ec357612ec3613a9e565b5f918252602091829020835160066008909302909101919091018054928401516001600160a01b031661010002610100600160a81b0319921515929092166001600160a81b03199093169290921717808255604083015190829060ff60a81b1916600160a81b836002811115612f3b57612f3b61372c565b021790555050505050565b600754600a80545f926001600160a01b03169163b9a09fd59185908110612f6f57612f6f613a9e565b5f91825260209091206008909102015460405160e083901b6001600160e01b03191681526001600160a01b039091166004820152602401602060405180830381865afa158015612fc1573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612fe59190613c02565b90506001600160a01b03811615610e325760408051606081018252600181526001600160a01b03831660208201529081016002612ead565b5f600a828154811061303157613031613a9e565b905f5260205f20906008020190505f816006015f0160019054906101000a90046001600160a01b03166001600160a01b0316638003b6146040518163ffffffff1660e01b81526004015f60405180830381865afa158015613094573d5f5f3e3d5ffd5b505050506040513d5f823e601f3d908101601f191682016040526130bb9190810190613c31565b60068301546040516331279d3d60e01b815291925061010090046001600160a01b0316906331279d3d906130f59030908590600401613cfc565b5f604051808303815f87803b15801561310c575f5ffd5b505af115801561311e573d5f5f3e3d5ffd5b505f925050505b8151811015610de4575f82828151811061314157613141613a9e565b60209081029190910101516040516370a0823160e01b81523060048201529091505f906001600160a01b038316906370a0823190602401602060405180830381865afa158015613193573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906131b79190613ab2565b9050801561321e57735050bc082ff4a74fb6b0b04385defddb114b2423196001600160a01b0383160161320457600354600160b01b900460ff16156131ff576131ff81613453565b61321e565b60085461321e906001600160a01b03848116911683612c36565b5050600101613125565b5f600a828154811061323c5761323c613a9e565b905f5260205f2090600802019050806006015f0160019054906101000a90046001600160a01b03166001600160a01b0316633d18b9126040518163ffffffff1660e01b81526004015f604051808303815f87803b15801561329b575f5ffd5b505af11580156132ad573d5f5f3e3d5ffd5b50506040516370a0823160e01b815230600482015273a04bc7140c26fc9bb1f36b1a604c7a5a88fb0e7092505f915082906370a0823190602401602060405180830381865afa158015613302573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906133269190613ab2565b90508015610de457600854610de4906001600160a01b03848116911683612c36565b6040516001600160a01b0380851660248301528316604482015260648101829052610de49085906323b872dd60e01b90608401612c62565b5f6133d4826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166136089092919063ffffffff16565b905080515f14806133f45750808060200190518101906133f49190613ac9565b611e045760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608401610bb9565b60405163095ea7b360e01b8152733333111a391cc08fa51353e9195526a70b333333600482015260248101829052735050bc082ff4a74fb6b0b04385defddb114b24249063095ea7b3906044016020604051808303815f875af11580156134bc573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906134e09190613ac9565b505f733333111a391cc08fa51353e9195526a70b3333336001600160a01b0316638380edb76040518163ffffffff1660e01b8152600401602060405180830381865afa158015613532573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906135569190613ac9565b90508015610e3257604051636e553f6560e01b8152600481018390523060248201525f90739710e10a8f6fba8c391606fee18614885684548d90636e553f65906044016020604051808303815f875af11580156135b5573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906135d99190613ab2565b600854909150611e0490733333111a391cc08fa51353e9195526a70b333333906001600160a01b031683612c36565b606061147c84845f85855f5f866001600160a01b0316858760405161362d9190613d5a565b5f6040518083038185875af1925050503d805f8114613667576040519150601f19603f3d011682016040523d82523d5f602084013e61366c565b606091505b50915091506121ef87838387606083156136e65782515f036136df576001600160a01b0385163b6136df5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610bb9565b508161147c565b61147c83838151156136fb5781518083602001fd5b8060405162461bcd60e51b8152600401610bb99190613d70565b5f60208284031215613725575f5ffd5b5035919050565b634e487b7160e01b5f52602160045260245ffd5b6001600160a01b03898116825260208083018a905260408084018a9052606084018990526080840188905286151560a08501528551151560c08501529085015190911660e0830152830151610140820190600381106137ad57634e487b7160e01b5f52602160045260245ffd5b61010083015261012090910191909152979650505050505050565b5f5f604083850312156137d9575f5ffd5b50508035926020909101359150565b6001600160a01b0381168114611247575f5ffd5b5f6020828403121561380c575f5ffd5b8135612923816137e8565b5f5f5f60608486031215613829575f5ffd5b505081359360208301359350604090920135919050565b5f5f5f60608486031215613852575f5ffd5b833561385d816137e8565b9250602084013591506040840135613874816137e8565b809150509250925092565b8015158114611247575f5ffd5b5f6020828403121561389c575f5ffd5b81356129238161387f565b5f5f604083850312156138b8575f5ffd5b8235915060208301356138ca816137e8565b809150509250929050565b5f5f5f5f5f60a086880312156138e9575f5ffd5b85359450602086013593506040860135613902816137e8565b925060608601356139128161387f565b949793965091946080013592915050565b5f5f60408385031215613934575f5ffd5b8235915060208301356138ca8161387f565b5f5f60408385031215613957575f5ffd5b823591506020830135600381106138ca575f5ffd5b5f5f83601f84011261397c575f5ffd5b50813567ffffffffffffffff811115613993575f5ffd5b6020830191508360208260051b85010111156139ad575f5ffd5b9250929050565b5f5f5f5f5f5f606087890312156139c9575f5ffd5b863567ffffffffffffffff8111156139df575f5ffd5b6139eb89828a0161396c565b909750955050602087013567ffffffffffffffff811115613a0a575f5ffd5b613a1689828a0161396c565b909550935050604087013567ffffffffffffffff811115613a35575f5ffd5b613a4189828a0161396c565b979a9699509497509295939492505050565b6020808252602b908201527f5348617265526577617264506f6f6c3a2063616c6c6572206973206e6f74207460408201526a34329037b832b930ba37b960a91b606082015260800190565b634e487b7160e01b5f52603260045260245ffd5b5f60208284031215613ac2575f5ffd5b5051919050565b5f60208284031215613ad9575f5ffd5b81516129238161387f565b60208082526024908201527f436c61696d20616d6f756e742062656c6f77206d696e696d756d2074687265736040820152631a1bdb1960e21b606082015260800190565b60208082526022908201527f5348617265526577617264506f6f6c3a20696e76616c6964206d73672e76616c604082015261756560f01b606082015260800190565b634e487b7160e01b5f52601160045260245ffd5b81810381811115610b8957610b89613b6a565b5f60018201613ba257613ba2613b6a565b5060010190565b8082028115828204841417610b8957610b89613b6a565b80820180821115610b8957610b89613b6a565b5f82613bed57634e487b7160e01b5f52601260045260245ffd5b500490565b8051613bfd816137e8565b919050565b5f60208284031215613c12575f5ffd5b8151612923816137e8565b634e487b7160e01b5f52604160045260245ffd5b5f60208284031215613c41575f5ffd5b815167ffffffffffffffff811115613c57575f5ffd5b8201601f81018413613c67575f5ffd5b805167ffffffffffffffff811115613c8157613c81613c1d565b8060051b604051601f19603f830116810181811067ffffffffffffffff82111715613cae57613cae613c1d565b604052918252602081840181019290810187841115613ccb575f5ffd5b6020850194505b83851015613cf157613ce385613bf2565b815260209485019401613cd2565b509695505050505050565b6001600160a01b03831681526040602080830182905283519183018290525f91908401906060840190835b81811015613d4e5783516001600160a01b0316835260209384019390920191600101613d27565b50909695505050505050565b5f82518060208501845e5f920191825250919050565b602081525f82518060208401528060208501604085015e5f604082850101526040601f19601f8301168401019150509291505056fea2646970667358221220546019463008f930e7086dcc27b8ea4c441319f42813d3eace00544febff80b864736f6c634300081c0033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
00000000000000000000000041e9bc85e6cd64852d9cb8cb22a69d26117f7448000000000000000000000000ef353f79d4368a26ee535a21763fa5ee2bd871710000000000000000000000000000000000000000000000000000000067ccbde00000000000000000000000009f59398d0a397b2eeb8a6123a6c7295cb0b0062d000000000000000000000000c1ae2779903cfb84cb9dee5c03eceac32dc407f2
-----Decoded View---------------
Arg [0] : _share (address): 0x41e9bc85e6CD64852D9Cb8Cb22a69d26117f7448
Arg [1] : _bribesSafe (address): 0xef353f79d4368A26eE535a21763fa5EE2bd87171
Arg [2] : _poolStartTime (uint256): 1741471200
Arg [3] : _shadowVoter (address): 0x9F59398D0a397b2EEB8a6123a6c7295cB0b0062D
Arg [4] : _swapxVoter (address): 0xC1AE2779903cfB84CB9DEe5c03EcEAc32dc407F2
-----Encoded View---------------
5 Constructor Arguments found :
Arg [0] : 00000000000000000000000041e9bc85e6cd64852d9cb8cb22a69d26117f7448
Arg [1] : 000000000000000000000000ef353f79d4368a26ee535a21763fa5ee2bd87171
Arg [2] : 0000000000000000000000000000000000000000000000000000000067ccbde0
Arg [3] : 0000000000000000000000009f59398d0a397b2eeb8a6123a6c7295cb0b0062d
Arg [4] : 000000000000000000000000c1ae2779903cfb84cb9dee5c03eceac32dc407f2
Deployed Bytecode Sourcemap
70563:27119:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;72288:82;;;;;;;;;;;;72328:42;72288:82;;;;;-1:-1:-1;;;;;178:32:1;;;160:51;;148:2;133:18;72288:82:0;;;;;;;;75106:95;;;;;;;;;;-1:-1:-1;75178:8:0;:15;75106:95;;;368:25:1;;;356:2;341:18;75106:95:0;222:177:1;72731:26:0;;;;;;;;;;-1:-1:-1;72731:26:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;;;;;;;;:::i;73159:34::-;;;;;;;;;;;;;;;;78236:657;;;;;;;;;;-1:-1:-1;78236:657:0;;;;;:::i;:::-;;:::i;96013:113::-;;;;;;;;;;-1:-1:-1;96013:113:0;;;;;:::i;:::-;;:::i;:::-;;82052:854;;;;;;;;;;-1:-1:-1;82052:854:0;;;;;:::i;:::-;;:::i;72214:31::-;;;;;;;;;;-1:-1:-1;72214:31:0;;;;-1:-1:-1;;;;;72214:31:0;;;72148:39;;;;;;;;;;;;;;;;83354:204;;;;;;;;;;;;;:::i;71939:48::-;;;;;;;;;;-1:-1:-1;71939:48:0;;;;-1:-1:-1;;;71939:48:0;;;;;;;;;3091:14:1;;3084:22;3066:41;;3054:2;3039:18;71939:48:0;2926:187:1;77189:579:0;;;;;;;;;;-1:-1:-1;77189:579:0;;;;;:::i;:::-;;:::i;88705:1081::-;;;;;;:::i;:::-;;:::i;96278:322::-;;;;;;;;;;-1:-1:-1;96278:322:0;;;;;:::i;:::-;;:::i;94293:480::-;;;;;;;;;;-1:-1:-1;94293:480:0;;;;;:::i;:::-;;:::i;96798:404::-;;;;;;;;;;-1:-1:-1;96798:404:0;;;;;:::i;:::-;;:::i;72377:78::-;;;;;;;;;;;;72413:42;72377:78;;70780:23;;;;;;;;;;-1:-1:-1;70780:23:0;;;;-1:-1:-1;;;;;70780:23:0;;;73356:39;;;;;;;;;;;;;;;;73245:28;;;;;;;;;;;;;;;;95593:266;;;;;;;;;;-1:-1:-1;95593:266:0;;;;;:::i;:::-;;:::i;72048:37::-;;;;;;;;;;-1:-1:-1;72048:37:0;;;;-1:-1:-1;;;72048:37:0;;;;;;80169:226;;;;;;;;;;;;;:::i;96608:182::-;;;;;;;;;;-1:-1:-1;96608:182:0;;;;;:::i;:::-;;:::i;79929:232::-;;;;;;;;;;-1:-1:-1;79929:232:0;;;;;:::i;:::-;;:::i;72252:29::-;;;;;;;;;;-1:-1:-1;72252:29:0;;;;-1:-1:-1;;;;;72252:29:0;;;73323:26;;;;;;;;;;;;;;;;71994:47;;;;;;;;;;-1:-1:-1;71994:47:0;;;;-1:-1:-1;;;71994:47:0;;;;;;97319:174;;;;;;;;;;-1:-1:-1;97319:174:0;;;;;:::i;:::-;;:::i;71906:26::-;;;;;;;;;;-1:-1:-1;71906:26:0;;;;-1:-1:-1;;;;;71906:26:0;;;97501:178;;;;;;;;;;-1:-1:-1;97501:178:0;;;;;:::i;:::-;;:::i;91826:2396::-;;;:::i;75542:1547::-;;;;;;;;;;-1:-1:-1;75542:1547:0;;;;;:::i;:::-;;:::i;72815:64::-;;;;;;;;;;-1:-1:-1;72815:64:0;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6282:25:1;;;6338:2;6323:18;;6316:34;;;;6255:18;72815:64:0;6108:248:1;73402:37:0;;;;;;;;;;;;;;;;72462:80;;;;;;;;;;;;72500:42;72462:80;;84906:732;;;;;;;;;;-1:-1:-1;84906:732:0;;;;;:::i;:::-;;:::i;71880:19::-;;;;;;;;;;-1:-1:-1;71880:19:0;;;;-1:-1:-1;;;;;71880:19:0;;;72670:25;;;;;;;;;;-1:-1:-1;72670:25:0;;;;-1:-1:-1;;;;;72670:25:0;;;95254:101;;;;;;;;;;-1:-1:-1;95254:101:0;;;;;:::i;:::-;;:::i;80434:302::-;;;;;;;;;;-1:-1:-1;80434:302:0;;;;;:::i;:::-;;:::i;72092:42::-;;;;;;;;;;;;;;;;95478:107;;;;;;;;;;-1:-1:-1;95478:107:0;;;;;:::i;:::-;;:::i;96134:136::-;;;;;;;;;;-1:-1:-1;96134:136:0;;;;;:::i;:::-;;:::i;86107:271::-;;;;;;;;;;-1:-1:-1;86107:271:0;;;;;:::i;:::-;;:::i;95363:107::-;;;;;;;;;;-1:-1:-1;95363:107:0;;;;;:::i;:::-;;:::i;78958:864::-;;;;;;;;;;-1:-1:-1;78958:864:0;;;;;:::i;:::-;;:::i;82948:398::-;;;;;;;;;;-1:-1:-1;82948:398:0;;;;;:::i;:::-;;:::i;72993:69::-;;;;;;;;;;-1:-1:-1;72993:69:0;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;95867:138;;;;;;;;;;-1:-1:-1;95867:138:0;;;;;:::i;:::-;;:::i;89794:2024::-;;;;;;:::i;:::-;;:::i;72638:25::-;;;;;;;;;;-1:-1:-1;72638:25:0;;;;-1:-1:-1;;;;;72638:25:0;;;72549:80;;;;;;;;;;;;72587:42;72549:80;;87466:1203;;;;;;;;;;-1:-1:-1;87466:1203:0;;;;;:::i;:::-;;:::i;77776:383::-;;;;;;;;;;-1:-1:-1;77776:383:0;;;;;:::i;:::-;;:::i;72731:26::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;72731:26:0;;;;;;;;;;;;;;;-1:-1:-1;72731:26:0;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;72731:26:0;;;;;;;;;;;;:::i;:::-;;;;;;;;;:::i;:::-;;;-1:-1:-1;72731:26:0;;;;;;:::o;78236:657::-;78321:7;78358;78345:9;:20;78341:34;;-1:-1:-1;78374:1:0;78367:8;;78341:34;78401:11;;78390:7;:22;78386:500;;78446:11;;78433:9;:24;78429:38;;-1:-1:-1;78466:1:0;78459:8;;78429:38;78499:13;;78486:9;:26;78482:89;;78521:50;78556:14;;78521:30;78537:13;;78521:11;;:15;;:30;;;;:::i;:::-;:34;;:50::i;:::-;78514:57;;;;78482:89;78593:46;78624:14;;78593:26;78609:9;78593:11;;:15;;:26;;;;:::i;78386:500::-;78687:13;;78676:7;:24;78672:38;;-1:-1:-1;78709:1:0;78702:8;;78672:38;78742:13;;78729:9;:26;78725:85;;78764:46;78795:14;;78764:26;78776:13;;78764:7;:11;;:26;;;;:::i;78725:85::-;78859:14;;78832:42;;:22;:7;78844:9;78832:11;:22::i;78386:500::-;78236:657;;;;:::o;96013:113::-;75008:8;;-1:-1:-1;;;;;75008:8:0;75020:10;75008:22;75000:78;;;;-1:-1:-1;;;75000:78:0;;;;;;;:::i;:::-;;;;;;;;;96092:11:::1;:26:::0;;-1:-1:-1;;;;;;96092:26:0::1;-1:-1:-1::0;;;;;96092:26:0;;;::::1;::::0;;;::::1;::::0;;96013:113::o;82052:854::-;82120:21;82144:8;82153:4;82144:14;;;;;;;;:::i;:::-;;;;;;;;;;;;;;82185;;;:20;82234:10;;:35;;-1:-1:-1;;;82234:35:0;;82263:4;82234:35;;;160:51:1;82144:14:0;;-1:-1:-1;82185:20:0;;;;-1:-1:-1;;;;;82185:20:0;;;;82144:14;82234:10;;;:20;;133:18:1;;82234:35:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;82341:14;;;:22;82216:53;;-1:-1:-1;82341:22:0;;82337:562;;;82446:11;;82442:446;;82523:10;;:42;;-1:-1:-1;;;82523:42:0;;82552:4;82523:42;;;9987:51:1;-1:-1:-1;;;;;10074:32:1;;;10054:18;;;10047:60;82568:7:0;;82523:10;;:20;;9960:18:1;;82523:42:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:52;82519:145;;;82600:10;;:44;;-1:-1:-1;;;82600:44:0;;-1:-1:-1;;;;;10310:32:1;;;82600:44:0;;;10292:51:1;-1:-1:-1;;10359:18:1;;;10352:34;82600:10:0;;;;:18;;10265::1;;82600:44:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;82519:145;82743:14;;;:20;82730:51;;-1:-1:-1;;;82730:51:0;;;;;368:25:1;;;82743:20:0;;;;-1:-1:-1;;;;;82743:20:0;;82730:42;;341:18:1;;82730:51:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;82442:446;82109:797;;;82052:854;:::o;83354:204::-;75008:8;;-1:-1:-1;;;;;75008:8:0;75020:10;75008:22;75000:78;;;;-1:-1:-1;;;75000:78:0;;;;;;;:::i;:::-;83433:8:::1;:15:::0;83416:14:::1;83459:92;83487:6;83481:3;:12;83459:92;;;83517:22;83535:3;83517:17;:22::i;:::-;83495:5;;83459:92;;;;83405:153;83354:204::o:0;77189:579::-;75008:8;;-1:-1:-1;;;;;75008:8:0;75020:10;75008:22;75000:78;;;;-1:-1:-1;;;75000:78:0;;;;;;;:::i;:::-;77285:17:::1;:15;:17::i;:::-;77315:21;77339:8;77348:4;77339:14;;;;;;;;:::i;:::-;;;;;;;;;;;77315:38;;77382:3;77372:7;:13;77364:22;;;;;;77435:11;::::0;::::1;:21:::0;;;77473:14:::1;::::0;::::1;::::0;::::1;;77469:207;;;77522:53;77563:11;77522:36;77542:4;:15;;;77522;;:19;;:36;;;;:::i;:::-;:40:::0;::::1;:53::i;:::-;77504:15;:71:::0;77626:20:::1;::::0;::::1;::::0;77607:14:::1;::::0;:57:::1;::::0;77652:11;;77607:40:::1;::::0;:18:::1;:40::i;:57::-;77590:14;:74:::0;77469:207:::1;77686:15;::::0;::::1;:29:::0;;;77726:20:::1;;:34:::0;;;;-1:-1:-1;;77189:579:0:o;88705:1081::-;2311:21;:19;:21::i;:::-;88793:15:::1;88811:10;88793:28;;88832:21;88856:8;88865:4;88856:14;;;;;;;;:::i;:::-;;::::0;;;::::1;::::0;;;88905;;;:8:::1;:14:::0;;;;;;-1:-1:-1;;;;;88905:23:0;::::1;::::0;;;;;;;88947:11;;88856:14:::1;::::0;;::::1;::::0;;::::1;::::0;-1:-1:-1;88947:22:0;-1:-1:-1;88947:22:0::1;88939:53;;;::::0;-1:-1:-1;;;88939:53:0;;10849:2:1;88939:53:0::1;::::0;::::1;10831:21:1::0;10888:2;10868:18;;;10861:30;-1:-1:-1;;;10907:18:1;;;10900:48;10965:18;;88939:53:0::1;10647:342:1::0;88939:53:0::1;89003:16;89014:4;89003:10;:16::i;:::-;89030:32;89057:4;89030:26;:32::i;:::-;89073:16;89092:69;89145:4;:15;;;89092:48;89135:4;89092:38;89108:4;:21;;;89092:4;:11;;;:15;;:38;;;;:::i;:::-;:42:::0;::::1;:48::i;:::-;:52:::0;::::1;:69::i;:::-;89073:88:::0;-1:-1:-1;89176:12:0;;89172:287:::1;;89404:20;::::0;;;:14:::1;:20;::::0;;;;;;;-1:-1:-1;;;;;89404:29:0;::::1;::::0;;;;;;;;:43:::1;::::0;89438:8;89404:33:::1;:43::i;:::-;89372:20;::::0;;;:14:::1;:20;::::0;;;;;;;-1:-1:-1;;;;;89372:29:0;::::1;::::0;;;;;;;:75;89172:287:::1;89473:11:::0;;89469:185:::1;;89515:11:::0;;:24:::1;::::0;89531:7;89515:15:::1;:24::i;:::-;89501:38:::0;;89554:32:::1;89572:4:::0;89578:7;89554:17:::1;:32::i;:::-;89601:10:::0;;:41:::1;::::0;-1:-1:-1;;;;;89601:10:0::1;89625:7:::0;89634;89601:23:::1;:41::i;:::-;89698:21;::::0;::::1;::::0;89682:11;;:48:::1;::::0;89725:4:::1;::::0;89682:38:::1;::::0;:15:::1;:38::i;:48::-;89664:15;::::0;::::1;:66:::0;89746:32:::1;::::0;368:25:1;;;89764:4:0;;-1:-1:-1;;;;;89746:32:0;::::1;::::0;::::1;::::0;356:2:1;341:18;89746:32:0::1;;;;;;;88782:1004;;;;2355:20:::0;1749:1;2875:7;:22;2692:213;96278:322;75008:8;;-1:-1:-1;;;;;75008:8:0;75020:10;75008:22;75000:78;;;;-1:-1:-1;;;75000:78:0;;;;;;;:::i;:::-;96490:4:::1;96468:18;:26;;96460:83;;;::::0;-1:-1:-1;;;96460:83:0;;11609:2:1;96460:83:0::1;::::0;::::1;11591:21:1::0;11648:2;11628:18;;;11621:30;11687:34;11667:18;;;11660:62;-1:-1:-1;;;11738:18:1;;;11731:42;11790:19;;96460:83:0::1;11407:408:1::0;96460:83:0::1;96554:17;:38:::0;96278:322::o;94293:480::-;2311:21;:19;:21::i;:::-;94365::::1;94389:8;94398:4;94389:14;;;;;;;;:::i;:::-;;::::0;;;::::1;::::0;;;94438;;;:8:::1;:14:::0;;;;;;94453:10:::1;94438:26:::0;;;;;;;94493:11;;94389:14:::1;::::0;;::::1;::::0;;::::1;::::0;-1:-1:-1;94515:32:0::1;94447:4:::0;94493:11;94515:17:::1;:32::i;:::-;94593:1;94558:20:::0;;;:14:::1;:20;::::0;;;;;;;94579:10:::1;94558:32:::0;;;;;;;:36;;;94605:15;;;94631::::1;::::0;::::1;:19:::0;;;;94661:10;;:44:::1;::::0;-1:-1:-1;;;;;94661:10:0;;::::1;::::0;94697:7;94661:23:::1;:44::i;:::-;94721;::::0;368:25:1;;;94751:4:0;;94739:10:::1;::::0;94721:44:::1;::::0;356:2:1;341:18;94721:44:0::1;;;;;;;94354:419;;;2355:20:::0;1749:1;2875:7;:22;2692:213;2355:20;94293:480;:::o;96798:404::-;75008:8;;-1:-1:-1;;;;;75008:8:0;75020:10;75008:22;75000:78;;;;-1:-1:-1;;;75000:78:0;;;;;;;:::i;:::-;96929:8:::1;:15:::0;96912:14:::1;96955:198;96983:6;96977:3;:12;96955:198;;;97013:21;97037:8;97046:3;97037:13;;;;;;;;:::i;:::-;;::::0;;;::::1;::::0;;;::::1;::::0;;::::1;;97083:10:::0;;97037:13;;-1:-1:-1;;;;;;97083:10:0;;::::1;97073:20:::0;;::::1;::::0;97065:76:::1;;;::::0;-1:-1:-1;;;97065:76:0;;12022:2:1;97065:76:0::1;::::0;::::1;12004:21:1::0;12061:2;12041:18;;;12034:30;12100:34;12080:18;;;12073:62;-1:-1:-1;;;12151:18:1;;;12144:41;12202:19;;97065:76:0::1;11820:407:1::0;97065:76:0::1;-1:-1:-1::0;96991:5:0::1;;96955:198;;;-1:-1:-1::0;97163:31:0::1;-1:-1:-1::0;;;;;97163:19:0;::::1;97183:2:::0;97187:6;97163:19:::1;:31::i;95593:266::-:0;75008:8;;-1:-1:-1;;;;;75008:8:0;75020:10;75008:22;75000:78;;;;-1:-1:-1;;;75000:78:0;;;;;;;:::i;:::-;95726:3:::1;95700:22;:29;;95692:91;;;::::0;-1:-1:-1;;;95692:91:0;;12434:2:1;95692:91:0::1;::::0;::::1;12416:21:1::0;12473:2;12453:18;;;12446:30;12512:34;12492:18;;;12485:62;-1:-1:-1;;;12563:18:1;;;12556:47;12620:19;;95692:91:0::1;12232:413:1::0;95692:91:0::1;95805:21;:46:::0;95593:266::o;80169:226::-;80231:8;:15;80214:14;80257:131;80285:6;80279:3;:12;80257:131;;;80315:15;80326:3;80315:10;:15::i;:::-;80345:31;80372:3;80345:26;:31::i;:::-;80293:5;;80257:131;;96608:182;75008:8;;-1:-1:-1;;;;;75008:8:0;75020:10;75008:22;75000:78;;;;-1:-1:-1;;;75000:78:0;;;;;;;:::i;:::-;96720:29:::1;:62:::0;;;::::1;;-1:-1:-1::0;;;96720:62:0::1;-1:-1:-1::0;;;;96720:62:0;;::::1;::::0;;;::::1;::::0;;96608:182::o;79929:232::-;80020:7;80040:21;80064:25;80077:4;80083:5;80064:12;:25::i;:::-;80125:20;;;;:14;:20;;;;;;;;-1:-1:-1;;;;;80125:27:0;;;;;;;;;;80040:49;;-1:-1:-1;80107:46:0;;80040:49;;80107:17;:46::i;:::-;80100:53;79929:232;-1:-1:-1;;;;79929:232:0:o;97319:174::-;75008:8;;-1:-1:-1;;;;;75008:8:0;75020:10;75008:22;75000:78;;;;-1:-1:-1;;;75000:78:0;;;;;;;:::i;:::-;97403:10:::1;::::0;:34:::1;::::0;97389:9:::1;::::0;-1:-1:-1;;;;;97403:10:0::1;::::0;97426:6;;97403:34:::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;97388:49;;;97456:4;97448:37;;;::::0;-1:-1:-1;;;97448:37:0;;13062:2:1;97448:37:0::1;::::0;::::1;13044:21:1::0;13101:2;13081:18;;;13074:30;-1:-1:-1;;;13120:18:1;;;13113:50;13180:18;;97448:37:0::1;12860:344:1::0;97501:178:0;75008:8;;-1:-1:-1;;;;;75008:8:0;75020:10;75008:22;75000:78;;;;-1:-1:-1;;;75000:78:0;;;;;;;:::i;:::-;97589:10:::1;::::0;:34:::1;::::0;97575:9:::1;::::0;-1:-1:-1;;;;;97589:10:0::1;::::0;97612:6;;97589:34:::1;12650:205:1::0;91826:2396:0;2311:21;:19;:21::i;:::-;91943:8:::1;:15:::0;91905:10:::1;::::0;91887:15:::1;::::0;92017:920:::1;92045:6;92039:3;:12;92017:920;;;92075:21;92099:8;92108:3;92099:13;;;;;;;;:::i;:::-;;::::0;;;::::1;::::0;;;92151;;;:8:::1;:13:::0;;;;;;-1:-1:-1;;;;;92151:22:0;::::1;::::0;;;;;;;92099:13:::1;::::0;;::::1;::::0;;::::1;::::0;-1:-1:-1;92233:15:0::1;92160:3:::0;92233:10:::1;:15::i;:::-;92263:31;92290:3;92263:26;:31::i;:::-;92364:16;92383:69;92436:4;:15;;;92383:48;92426:4;92383:38;92399:4;:21;;;92383:4;:11;;;:15;;:38;;;;:::i;:69::-;92467:27;92497:19:::0;;;:14:::1;:19;::::0;;;;;;;-1:-1:-1;;;;;92497:28:0;::::1;::::0;;;;;;;;92364:88;;-1:-1:-1;92566:33:0::1;92364:88:::0;92497:28;92566:12:::1;:33::i;:::-;92540:59:::0;-1:-1:-1;92620:19:0;;92616:181:::1;;92691:1;92660:19:::0;;;:14:::1;:19;::::0;;;;;;;-1:-1:-1;;;;;92660:28:0;::::1;::::0;;;;;;;:32;92737:44:::1;:23:::0;92765:15;92737:27:::1;:44::i;:::-;92711:70;;92616:181;92893:21;::::0;::::1;::::0;92877:11;;:48:::1;::::0;92920:4:::1;::::0;92877:38:::1;::::0;:15:::1;:38::i;:48::-;92859:15;::::0;;::::1;:66:::0;-1:-1:-1;;;92053:5:0;;;::::1;::::0;-1:-1:-1;92017:920:0::1;;;;93067:17;;93040:23;:44;;93032:93;;;;-1:-1:-1::0;;;93032:93:0::1;;;;;;;:::i;:::-;93142:27:::0;;93138:1077:::1;;93233:28;::::0;93186:24:::1;::::0;-1:-1:-1;;;93233:28:0;::::1;;;93229:476;;;93317:11;::::0;93342:5:::1;::::0;93317:38:::1;::::0;-1:-1:-1;;;93317:38:0;;-1:-1:-1;;;;;93342:5:0;;::::1;93317:38;::::0;::::1;10292:51:1::0;93350:4:0::1;10359:18:1::0;;;10352:34;93282:32:0::1;::::0;93317:11;;;::::1;::::0;:16:::1;::::0;10265:18:1;;93317:38:0::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;93282:73;;93393:102;93490:4;93393:92;93463:21;;93394:63;93452:4;93394:53;93423:23;93394:24;:28;;:53;;;;:::i;93393:102::-;93374:121;;93535:16;93522:9;:29;;93514:73;;;::::0;-1:-1:-1;;;93514:73:0;;14121:2:1;93514:73:0::1;::::0;::::1;14103:21:1::0;14160:2;14140:18;;;14133:30;14199:33;14179:18;;;14172:61;14250:18;;93514:73:0::1;13919:355:1::0;93514:73:0::1;93263:340;93229:476;;;93636:9;:14:::0;93628:61:::1;;;;-1:-1:-1::0;;;93628:61:0::1;;;;;;;:::i;:::-;93721:51;93739:7;93748:23;93721:17;:51::i;:::-;93803:7;-1:-1:-1::0;;;;;93792:44:0::1;;93812:23;93792:44;;;;368:25:1::0;;356:2;341:18;;222:177;93792:44:0::1;;;;;;;;93929:28;::::0;-1:-1:-1;;;93929:28:0;::::1;;;:60:::0;::::1;;;;93973:16;93961:9;:28;93929:60;93925:279;;;94010:20;94033:28;94045:16:::0;94033:9:::1;:28;:::i;:::-;94010:51;;94081:12;94099:7;-1:-1:-1::0;;;;;94099:12:0::1;94119;94099:37;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;94080:56;;;94163:7;94155:33;;;::::0;-1:-1:-1;;;94155:33:0;;15149:2:1;94155:33:0::1;::::0;::::1;15131:21:1::0;15188:2;15168:18;;;15161:30;-1:-1:-1;;;15207:18:1;;;15200:43;15260:18;;94155:33:0::1;14947:337:1::0;94155:33:0::1;93991:213;;93925:279;93171:1044;93138:1077;91876:2346;;;2355:20:::0;1749:1;2875:7;:22;2692:213;2355:20;91826:2396::o;75542:1547::-;75008:8;;-1:-1:-1;;;;;75008:8:0;75020:10;75008:22;75000:78;;;;-1:-1:-1;;;75000:78:0;;;;;;;:::i;:::-;75734:26:::1;75753:6;75734:18;:26::i;:::-;75775:11;75771:61;;;75803:17;:15;:17::i;:::-;75864:13;;75846:15;:31;75842:534;;;75931:15;75950:1;75931:20:::0;75927:243:::1;;-1:-1:-1::0;75990:13:0::1;::::0;75842:534:::1;;75927:243;76066:13;;76048:15;:31;76044:111;;;-1:-1:-1::0;76122:13:0::1;::::0;76044:111:::1;75842:534;;;76238:20:::0;;;:57:::1;;;76280:15;76262;:33;76238:57;76234:131;;;-1:-1:-1::0;76334:15:0::1;76234:131;76386:15;76424:13;;76405:15;:32;;76404:74;;;;76462:15;76443;:34;;76404:74;76386:92;;76489:8;76503:345;;;;;;;;76534:6;-1:-1:-1::0;;;;;76503:345:0::1;;;;;76563:7;76503:345;;;;76597:11;76503:345;;;;76682:15;76503:345;;;;76730:1;76503:345;;;;76757:10;76503:345;;;;;;76793:43;;;;;;;;76803:5;76793:43;;;;;;76818:1;-1:-1:-1::0;;;;;76793:43:0::1;;;;;76822:13;76793:43;;;;;;;;:::i;:::-;::::0;;76503:345;;::::1;::::0;;::::1;::::0;;;76489:360;;::::1;::::0;;::::1;::::0;;-1:-1:-1;76489:360:0;;;;;;;;;::::1;::::0;;::::1;;::::0;;-1:-1:-1;;;;;76489:360:0;;::::1;-1:-1:-1::0;;;;;;76489:360:0;;::::1;;::::0;;;;::::1;::::0;;;::::1;::::0;;;;::::1;::::0;;::::1;::::0;::::1;::::0;;::::1;::::0;;;;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;;;::::1;;-1:-1:-1::0;;76489:360:0;;::::1;::::0;;;::::1;::::0;;::::1;::::0;::::1;::::0;;;::::1;::::0;::::1;::::0;;;;::::1;::::0;;;::::1;;;-1:-1:-1::0;;;;;;76489:360:0;::::1;;::::0;;;;-1:-1:-1;;;;;;76489:360:0;;;;;;;;;;::::1;::::0;;;;;::::1;::::0;;;;;;;-1:-1:-1;;;;76489:360:0;;::::1;::::0;-1:-1:-1;;;76489:360:0;;;;::::1;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;76930:10;76926:156;;;76975:15;::::0;:32:::1;::::0;76995:11;76975:19:::1;:32::i;:::-;76957:15;:50:::0;77039:14:::1;::::0;:31:::1;::::0;77058:11;77039:18:::1;:31::i;:::-;77022:14;:48:::0;76926:156:::1;75723:1366;75542:1547:::0;;;;;:::o;84906:732::-;75008:8;;-1:-1:-1;;;;;75008:8:0;75020:10;75008:22;75000:78;;;;-1:-1:-1;;;75000:78:0;;;;;;;:::i;:::-;84996:58:::1;::::0;-1:-1:-1;;;84996:58:0;;72413:42:::1;84996:58;::::0;::::1;10292:51:1::0;10359:18;;;10352:34;;;72328:42:0::1;::::0;84996:29:::1;::::0;10265:18:1;;84996:58:0::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;85091:12;72413:42;-1:-1:-1::0;;;;;85106:26:0::1;;:28;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;85091:43;;85149:7;85145:486;;;85177:5;85173:447;;;85231:53;::::0;-1:-1:-1;;;85231:53:0;;::::1;::::0;::::1;15463:25:1::0;;;85278:4:0::1;15504:18:1::0;;;15497:60;85203:25:0::1;::::0;72500:42:::1;::::0;85231:29:::1;::::0;15436:18:1;;85231:53:0::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;85346:10;::::0;85203:81;;-1:-1:-1;85315:61:0::1;::::0;72413:42:::1;::::0;-1:-1:-1;;;;;85346:10:0::1;85203:81:::0;85315:30:::1;:61::i;85173:447::-;85443:53;::::0;-1:-1:-1;;;85443:53:0;;::::1;::::0;::::1;15463:25:1::0;;;85490:4:0::1;15504:18:1::0;;;15497:60;72500:42:0::1;::::0;85443:29:::1;::::0;15436:18:1;;85443:53:0::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;85558:10:0::1;::::0;85527:51:::1;::::0;72413:42:::1;::::0;-1:-1:-1;;;;;85558:10:0::1;85570:7:::0;85527:30:::1;:51::i;:::-;84985:653;84906:732:::0;;:::o;95254:101::-;75008:8;;-1:-1:-1;;;;;75008:8:0;75020:10;75008:22;75000:78;;;;-1:-1:-1;;;75000:78:0;;;;;;;:::i;:::-;95327:8:::1;:20:::0;;-1:-1:-1;;;;;;95327:20:0::1;-1:-1:-1::0;;;;;95327:20:0;;;::::1;::::0;;;::::1;::::0;;95254:101::o;80434:302::-;80538:6;80526:8;:18;;80518:61;;;;-1:-1:-1;;;80518:61:0;;15770:2:1;80518:61:0;;;15752:21:1;15809:2;15789:18;;;15782:30;15848:32;15828:18;;;15821:60;15898:18;;80518:61:0;15568:354:1;80518:61:0;80609:8;80590:139;80626:6;80619:3;:13;80590:139;;80656:15;80667:3;80656:10;:15::i;:::-;80686:31;80713:3;80686:26;:31::i;:::-;80634:5;;;:::i;:::-;;;80590:139;;95478:107;75008:8;;-1:-1:-1;;;;;75008:8:0;75020:10;75008:22;75000:78;;;;-1:-1:-1;;;75000:78:0;;;;;;;:::i;:::-;95553:10:::1;:24:::0;;-1:-1:-1;;;;;;95553:24:0::1;-1:-1:-1::0;;;;;95553:24:0;;;::::1;::::0;;;::::1;::::0;;95478:107::o;96134:136::-;75008:8;;-1:-1:-1;;;;;75008:8:0;75020:10;75008:22;75000:78;;;;-1:-1:-1;;;75000:78:0;;;;;;;:::i;:::-;96223:28:::1;:39:::0;;;::::1;;-1:-1:-1::0;;;96223:39:0::1;-1:-1:-1::0;;;;96223:39:0;;::::1;::::0;;;::::1;::::0;;96134:136::o;86107:271::-;75008:8;;-1:-1:-1;;;;;75008:8:0;75020:10;75008:22;75000:78;;;;-1:-1:-1;;;75000:78:0;;;;;;;:::i;:::-;86210:15:::1;86197:9;:28;;;;;;;;:::i;:::-;::::0;86193:85:::1;;86242:24;86261:4;86242:18;:24::i;:::-;86305:14;86292:9;:27;;;;;;;;:::i;:::-;::::0;86288:83:::1;;86336:23;86354:4;86336:17;:23::i;95363:107::-:0;75008:8;;-1:-1:-1;;;;;75008:8:0;75020:10;75008:22;75000:78;;;;-1:-1:-1;;;75000:78:0;;;;;;;:::i;:::-;95438:10:::1;:24:::0;;-1:-1:-1;;;;;;95438:24:0::1;-1:-1:-1::0;;;;;95438:24:0;;;::::1;::::0;;;::::1;::::0;;95363:107::o;78958:864::-;79030:7;79050:21;79074:8;79083:4;79074:14;;;;;;;;:::i;:::-;;;;;;;;;79123;;;:8;:14;;;;;;-1:-1:-1;;;;;79123:21:0;;;;;;;;;;79074:14;;;;;;79182:21;;;;79236:14;;;:22;79074:14;;-1:-1:-1;79123:21:0;;79074:14;79236:22;;:122;;79323:10;;:35;;-1:-1:-1;;;79323:35:0;;79352:4;79323:35;;;160:51:1;-1:-1:-1;;;;;79323:10:0;;;;:20;;133:18:1;;79323:35:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;79236:122;;;79274:14;;;:20;79261:59;;-1:-1:-1;;;79261:59:0;;79314:4;79261:59;;;160:51:1;79274:20:0;;;;-1:-1:-1;;;;;79274:20:0;;79261:44;;133:18:1;;79261:59:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;79214:144;;79391:4;:19;;;79373:15;:37;:57;;;;-1:-1:-1;79414:16:0;;;79373:57;79369:364;;;79447:24;79474:56;79493:4;:19;;;79514:15;79474:18;:56::i;:::-;79447:83;;79545:20;79568:58;79610:15;;79568:37;79589:4;:15;;;79568:16;:20;;:37;;;;:::i;:58::-;79545:81;-1:-1:-1;79660:61:0;79681:39;79708:11;79681:22;79545:81;79698:4;79681:16;:22::i;:39::-;79660:16;;:20;:61::i;:::-;79641:80;;79432:301;;79369:364;79750:64;79798:4;:15;;;79750:43;79788:4;79750:33;79766:16;79750:4;:11;;;:15;;:33;;;;:::i;:64::-;79743:71;78958:864;-1:-1:-1;;;;;;;78958:864:0:o;82948:398::-;83007:21;83031:8;83040:4;83031:14;;;;;;;;:::i;:::-;;;;;;;;;;;;;;83060;;;:22;83031:14;;-1:-1:-1;83060:22:0;;83056:283;;;83130:15;83103:14;;;:23;-1:-1:-1;;;83103:23:0;;;;:42;;;;;;;;:::i;:::-;;83099:108;;83166:25;83186:4;83166:19;:25::i;:::-;83252:14;83225;;;:23;-1:-1:-1;;;83225:23:0;;;;:41;;;;;;;;:::i;:::-;;83221:107;;83288:24;83307:4;83288:18;:24::i;95867:138::-;75008:8;;-1:-1:-1;;;;;75008:8:0;75020:10;75008:22;75000:78;;;;-1:-1:-1;;;75000:78:0;;;;;;;:::i;:::-;95957:18:::1;:40:::0;;;::::1;;-1:-1:-1::0;;;95957:40:0::1;-1:-1:-1::0;;;;95957:40:0;;::::1;::::0;;;::::1;::::0;;95867:138::o;89794:2024::-;2311:21;:19;:21::i;:::-;89865:15:::1;89883:10;89865:28;;89904:21;89928:8;89937:4;89928:14;;;;;;;;:::i;:::-;;::::0;;;::::1;::::0;;;89977;;;:8:::1;:14:::0;;;;;;-1:-1:-1;;;;;89977:23:0;::::1;::::0;;;;;;;89928:14:::1;::::0;;::::1;::::0;;::::1;::::0;-1:-1:-1;90052:16:0::1;89986:4:::0;90052:10:::1;:16::i;:::-;90079:32;90106:4;90079:26;:32::i;:::-;90173:16;90192:69;90245:4;:15;;;90192:48;90235:4;90192:38;90208:4;:21;;;90192:4;:11;;;:15;;:38;;;;:::i;:69::-;90272:27;90302:20:::0;;;:14:::1;:20;::::0;;;;;;;-1:-1:-1;;;;;90302:29:0;::::1;::::0;;;;;;;;90173:88;;-1:-1:-1;90368:33:0::1;90173:88:::0;90302:29;90368:12:::1;:33::i;:::-;90342:59;;90524:17;;90505:15;:36;;90497:85;;;;-1:-1:-1::0;;;90497:85:0::1;;;;;;;:::i;:::-;90599:19:::0;;90595:1095:::1;;90667:1;90635:20:::0;;;:14:::1;:20;::::0;;;;;;;-1:-1:-1;;;;;90635:29:0;::::1;::::0;;;;;;;:33;;;90732:28:::1;::::0;-1:-1:-1;;;90732:28:0;::::1;;;90728:468;;;90816:11;::::0;90841:5:::1;::::0;90816:38:::1;::::0;-1:-1:-1;;;90816:38:0;;-1:-1:-1;;;;;90841:5:0;;::::1;90816:38;::::0;::::1;10292:51:1::0;90849:4:0::1;10359:18:1::0;;;10352:34;90781:32:0::1;::::0;90816:11;;;::::1;::::0;:16:::1;::::0;10265:18:1;;90816:38:0::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;90781:73;;90892:94;90981:4;90892:84;90954:21;;90893:55;90943:4;90893:45;90922:15;90893:24;:28;;:45;;;;:::i;90892:94::-;90873:113;;91026:16;91013:9;:29;;91005:73;;;::::0;-1:-1:-1;;;91005:73:0;;14121:2:1;91005:73:0::1;::::0;::::1;14103:21:1::0;14160:2;14140:18;;;14133:30;14199:33;14179:18;;;14172:61;14250:18;;91005:73:0::1;13919:355:1::0;91005:73:0::1;90762:332;90728:468;;;91127:9;:14:::0;91119:61:::1;;;;-1:-1:-1::0;;;91119:61:0::1;;;;;;;:::i;:::-;91212:43;91230:7;91239:15;91212:17;:43::i;:::-;91286:7;-1:-1:-1::0;;;;;91275:36:0::1;;91295:15;91275:36;;;;368:25:1::0;;356:2;341:18;;222:177;91275:36:0::1;;;;;;;;91404:28;::::0;-1:-1:-1;;;91404:28:0;::::1;;;:60:::0;::::1;;;;91448:16;91436:9;:28;91404:60;91400:279;;;91485:20;91508:28;91520:16:::0;91508:9:::1;:28;:::i;:::-;91485:51;;91556:12;91574:7;-1:-1:-1::0;;;;;91574:12:0::1;91594;91574:37;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;91555:56;;;91638:7;91630:33;;;::::0;-1:-1:-1;;;91630:33:0;;15149:2:1;91630:33:0::1;::::0;::::1;15131:21:1::0;15188:2;15168:18;;;15161:30;-1:-1:-1;;;15207:18:1;;;15200:43;15260:18;;91630:33:0::1;14947:337:1::0;91630:33:0::1;91466:213;;91400:279;90620:1070;90595:1095;91778:21;::::0;::::1;::::0;91762:11;;:48:::1;::::0;91805:4:::1;::::0;91762:38:::1;::::0;:15:::1;:38::i;:48::-;91744:15;::::0;;::::1;:66:::0;-1:-1:-1;;;2875:7:0;:22;-1:-1:-1;2355:20:0;;-1:-1:-1;2692:213:0;87466:1203;2311:21;:19;:21::i;:::-;87545:15:::1;87563:10;87545:28;;87584:21;87608:8;87617:4;87608:14;;;;;;;;:::i;:::-;;::::0;;;::::1;::::0;;;87657;;;:8:::1;:14:::0;;;;;;-1:-1:-1;;;;;87657:23:0;::::1;::::0;;;;;;;87608:14:::1;::::0;;::::1;::::0;;::::1;::::0;-1:-1:-1;87691:16:0::1;87666:4:::0;87691:10:::1;:16::i;:::-;87722:11:::0;;:15;87718:457:::1;;87754:16;87773:69;87826:4;:15;;;87773:48;87816:4;87773:38;87789:4;:21;;;87773:4;:11;;;:15;;:38;;;;:::i;:69::-;87754:88:::0;-1:-1:-1;87861:12:0;;87857:307:::1;;88105:20;::::0;;;:14:::1;:20;::::0;;;;;;;-1:-1:-1;;;;;88105:29:0;::::1;::::0;;;;;;;;:43:::1;::::0;88139:8;88105:33:::1;:43::i;:::-;88073:20;::::0;;;:14:::1;:20;::::0;;;;;;;-1:-1:-1;;;;;88073:29:0;::::1;::::0;;;;;;;:75;87857:307:::1;87739:436;87718:457;88189:11:::0;;88185:310:::1;;88218:10:::0;;:60:::1;::::0;-1:-1:-1;;;;;88218:10:0::1;88246:7:::0;88263:4:::1;88270:7:::0;88218:27:::1;:60::i;:::-;88293:19;88315:35;88344:5;88315:24;88327:4;:11;;;88315:7;:11;;:24;;;;:::i;:35::-;88293:57:::0;-1:-1:-1;88379:41:0::1;88395:24;:7:::0;88293:57;88395:11:::1;:24::i;:::-;88379:11:::0;;;:15:::1;:41::i;:::-;88365:55:::0;;88459:10:::1;::::0;88435;;:48:::1;::::0;-1:-1:-1;;;;;88435:10:0;;::::1;::::0;88459::::1;88471:11:::0;88435:23:::1;:48::i;:::-;88203:292;88185:310;88505:32;88532:4;88505:26;:32::i;:::-;88582:21;::::0;::::1;::::0;88566:11;;:48:::1;::::0;88609:4:::1;::::0;88566:38:::1;::::0;:15:::1;:38::i;:48::-;88548:15;::::0;::::1;:66:::0;88630:31:::1;::::0;368:25:1;;;88647:4:0;;-1:-1:-1;;;;;88630:31:0;::::1;::::0;::::1;::::0;356:2:1;341:18;88630:31:0::1;;;;;;;87534:1135;;;2355:20:::0;1749:1;2875:7;:22;2692:213;77776:383;75008:8;;-1:-1:-1;;;;;75008:8:0;75020:10;75008:22;75000:78;;;;-1:-1:-1;;;75000:78:0;;;;;;;:::i;:::-;77922:35;;::::1;:70:::0;::::1;;;-1:-1:-1::0;77961:31:0;;::::1;77922:70;77914:114;;;::::0;-1:-1:-1;;;77914:114:0;;16269:2:1;77914:114:0::1;::::0;::::1;16251:21:1::0;16308:2;16288:18;;;16281:30;16347:33;16327:18;;;16320:61;16398:18;;77914:114:0::1;16067:355:1::0;77914:114:0::1;78044:9;78039:113;78059:16:::0;;::::1;78039:113;;;78097:43;78101:5;;78107:1;78101:8;;;;;;;:::i;:::-;;;;;;;78111:12;;78124:1;78111:15;;;;;;;:::i;:::-;;;;;;;78128:8;;78137:1;78128:11;;;;;;;:::i;:::-;;;;;;;78097:3;:43::i;:::-;78077:3;;78039:113;;;;77776:383:::0;;;;;;:::o;29583:98::-;29641:7;29668:5;29672:1;29668;:5;:::i;:::-;29661:12;29583:98;-1:-1:-1;;;29583:98:0:o;29940:::-;29998:7;30025:5;30029:1;30025;:5;:::i;29202:98::-;29260:7;29287:5;29291:1;29287;:5;:::i;2391:293::-;1793:1;2525:7;;:19;2517:63;;;;-1:-1:-1;;;2517:63:0;;16932:2:1;2517:63:0;;;16914:21:1;16971:2;16951:18;;;16944:30;17010:33;16990:18;;;16983:61;17061:18;;2517:63:0;16730:355:1;2517:63:0;1793:1;2658:7;:18;2391:293::o;80812:1186::-;80865:32;80892:4;80865:26;:32::i;:::-;80908:21;80932:8;80941:4;80932:14;;;;;;;;:::i;:::-;;;;;;;;;;;80908:38;;80980:4;:19;;;80961:15;:38;80957:77;;81016:7;80812:1186;:::o;80957:77::-;81066:14;;;:22;81044:19;;81066:22;;:122;;81153:10;;:35;;-1:-1:-1;;;81153:35:0;;81182:4;81153:35;;;160:51:1;-1:-1:-1;;;;;81153:10:0;;;;:20;;133:18:1;;81153:35:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;81066:122;;;81104:14;;;:20;81091:59;;-1:-1:-1;;;81091:59:0;;81144:4;81091:59;;;160:51:1;81104:20:0;;;;-1:-1:-1;;;;;81104:20:0;;81091:44;;133:18:1;;81091:59:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;81044:144;;81203:11;81218:1;81203:16;81199:107;;-1:-1:-1;81258:15:0;81236:19;;;;:37;-1:-1:-1;80812:1186:0:o;81199:107::-;81321:14;;;;;;81316:210;;81352:14;;;:21;;-1:-1:-1;;81352:21:0;81369:4;81352:21;;;81426:15;;;;81406;;:36;;:19;:36::i;:::-;81388:15;:54;81493:20;;;;81474:14;;:40;;:18;:40::i;:::-;81457:14;:57;81316:210;81540:15;;:19;81536:336;;81576:24;81603:56;81622:4;:19;;;81643:15;81603:18;:56::i;:::-;81576:83;;81674:20;81697:58;81739:15;;81697:37;81718:4;:15;;;81697:16;:20;;:37;;;;:::i;:58::-;81674:81;-1:-1:-1;81794:66:0;81820:39;81847:11;81820:22;81674:81;81837:4;81820:16;:22::i;:39::-;81794:21;;;;;:25;:66::i;:::-;81770:21;;;:90;-1:-1:-1;;81536:336:0;81904:15;81882:19;;;;:37;;;;81934:29;-1:-1:-1;;;81934:29:0;;;;81930:61;;;81966:23;81984:4;81966:17;:23::i;30339:98::-;30397:7;30424:5;30428:1;30424;:5;:::i;87002:429::-;87080:21;87104:8;87113:4;87104:14;;;;;;;;:::i;:::-;;;;;;;;;;;;;;87190;;;:22;87104:14;;-1:-1:-1;87190:22:0;;87186:238;;;87282:14;;;:20;87269:52;;-1:-1:-1;;;87269:52:0;;;;;368:25:1;;;87282:20:0;;;;-1:-1:-1;;;;;87282:20:0;;87269:43;;341:18:1;;87269:52:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;10894:177;11004:58;;-1:-1:-1;;;;;10310:32:1;;11004:58:0;;;10292:51:1;10359:18;;;10352:34;;;10977:86:0;;10997:5;;-1:-1:-1;;;11027:23:0;10265:18:1;;11004:58:0;;;;-1:-1:-1;;11004:58:0;;;;;;;;;;;;;;-1:-1:-1;;;;;11004:58:0;-1:-1:-1;;;;;;11004:58:0;;;;;;;;;;10977:19;:86::i;94889:357::-;94986:5;;:30;;-1:-1:-1;;;94986:30:0;;95010:4;94986:30;;;160:51:1;94966:17:0;;-1:-1:-1;;;;;94986:5:0;;:15;;133:18:1;;94986:30:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;94966:50;-1:-1:-1;95031:13:0;;95027:212;;95075:9;95065:7;:19;95061:167;;;95105:5;;:34;;-1:-1:-1;;;;;95105:5:0;95124:3;95129:9;95105:18;:34::i;95061:167::-;95180:5;;:32;;-1:-1:-1;;;;;95180:5:0;95199:3;95204:7;95180:18;:32::i;75209:261::-;75294:8;:15;75277:14;75320:143;75348:6;75342:3;:12;75320:143;;;75409:6;-1:-1:-1;;;;;75386:29:0;:8;75395:3;75386:13;;;;;;;;:::i;:::-;;;;;;;;;;;;;;:19;-1:-1:-1;;;;;75386:19:0;:29;75378:73;;;;-1:-1:-1;;;75378:73:0;;17514:2:1;75378:73:0;;;17496:21:1;17553:2;17533:18;;;17526:30;17592:33;17572:18;;;17565:61;17643:18;;75378:73:0;17312:355:1;75378:73:0;75356:5;;75320:143;;86386:269;86464:11;;86497:8;:14;;86448:13;;-1:-1:-1;;;;;86464:11:0;;:24;;86506:4;;86497:14;;;;;;:::i;:::-;;;;;;;;;;;;;;:20;86464:55;;;;;;-1:-1:-1;;;;;;86464:55:0;;;-1:-1:-1;;;;;86497:20:0;;;86464:55;;;160:51:1;133:18;;86464:55:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;86448:71;-1:-1:-1;;;;;;86534:19:0;;;86530:118;;86597:39;;;;;;;;86607:4;86597:39;;;-1:-1:-1;;;;;86597:39:0;;;;;;;;;;;;;;;86570:8;86579:4;86570:14;;;;;;;;:::i;:::-;;;;;;;;;;:66;;:24;:14;;;;;;;:24;;;;:66;;;;;;-1:-1:-1;;;;;86570:66:0;;;-1:-1:-1;;;;;;86570:66:0;;;;;;;-1:-1:-1;;;;;;86570:66:0;;;;;;;;;;;;;;;;:24;;-1:-1:-1;;;;86570:66:0;-1:-1:-1;;;86570:66:0;;;;;;;;;:::i;:::-;;;;;-1:-1:-1;;;86437:218:0;86386:269;:::o;86663:296::-;86776:10;;86802:8;:14;;86760:13;;-1:-1:-1;;;;;86776:10:0;;:17;;86811:4;;86802:14;;;;;;:::i;:::-;;;;;;;;;;;;;;:20;86776:48;;;;;;-1:-1:-1;;;;;;86776:48:0;;;-1:-1:-1;;;;;86802:20:0;;;86776:48;;;160:51:1;133:18;;86776:48:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;86760:64;-1:-1:-1;;;;;;86839:19:0;;;86835:117;;86902:38;;;;;;;;86912:4;86902:38;;-1:-1:-1;;;;;86902:38:0;;;;;;;;;86925:14;86902:38;;83566:871;83629:21;83653:8;83662:4;83653:14;;;;;;;;:::i;:::-;;;;;;;;;;;83629:38;;83678:34;83728:4;:14;;:20;;;;;;;;;;-1:-1:-1;;;;;83728:20:0;-1:-1:-1;;;;;83715:46:0;;:48;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;83715:48:0;;;;;;;;;;;;:::i;:::-;83787:14;;;:20;83774:78;;-1:-1:-1;;;83774:78:0;;83678:85;;-1:-1:-1;83787:20:0;;;-1:-1:-1;;;;;83787:20:0;;83774:44;;:78;;83827:4;;83678:85;;83774:78;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;83870:9:0;;-1:-1:-1;;;83865:565:0;83889:17;:24;83885:1;:28;83865:565;;;83935:18;83963:17;83981:1;83963:20;;;;;;;;:::i;:::-;;;;;;;;;;;84022:36;;-1:-1:-1;;;84022:36:0;;84052:4;84022:36;;;160:51:1;83963:20:0;;-1:-1:-1;83999:20:0;;-1:-1:-1;;;;;84022:21:0;;;;;133:18:1;;84022:36:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;83999:59;-1:-1:-1;84079:16:0;;84075:344;;-1:-1:-1;;;;;;;84120:37:0;;;84116:288;;84186:18;;-1:-1:-1;;;84186:18:0;;;;84182:104;;;84233:29;84249:12;84233:15;:29::i;:::-;84116:288;;;84359:10;;84334:50;;-1:-1:-1;;;;;84334:24:0;;;;84359:10;84371:12;84334:24;:50::i;:::-;-1:-1:-1;;83915:3:0;;83865:565;;85646:423;85708:21;85732:8;85741:4;85732:14;;;;;;;;:::i;:::-;;;;;;;;;;;85708:38;;85769:4;:14;;:20;;;;;;;;;;-1:-1:-1;;;;;85769:20:0;-1:-1:-1;;;;;85757:43:0;;:45;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;85916:36:0;;-1:-1:-1;;;85916:36:0;;85946:4;85916:36;;;160:51:1;72587:42:0;;-1:-1:-1;85842:18:0;;-1:-1:-1;72587:42:0;;85916:21;;133:18:1;;85916:36:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;85893:59;-1:-1:-1;85967:16:0;;85963:99;;86025:10;;86000:50;;-1:-1:-1;;;;;86000:24:0;;;;86025:10;86037:12;86000:24;:50::i;11316:205::-;11444:68;;-1:-1:-1;;;;;20320:32:1;;;11444:68:0;;;20302:51:1;20389:32;;20369:18;;;20362:60;20438:18;;;20431:34;;;11417:96:0;;11437:5;;-1:-1:-1;;;11467:27:0;20275:18:1;;11444:68:0;20100:371:1;15240:649:0;15664:23;15690:69;15718:4;15690:69;;;;;;;;;;;;;;;;;15698:5;-1:-1:-1;;;;;15690:27:0;;;:69;;;;;:::i;:::-;15664:95;;15778:10;:17;15799:1;15778:22;:56;;;;15815:10;15804:30;;;;;;;;;;;;:::i;:::-;15770:111;;;;-1:-1:-1;;;15770:111:0;;20678:2:1;15770:111:0;;;20660:21:1;20717:2;20697:18;;;20690:30;20756:34;20736:18;;;20729:62;-1:-1:-1;;;20807:18:1;;;20800:40;20857:19;;15770:111:0;20476:406:1;84445:453:0;84507:58;;-1:-1:-1;;;84507:58:0;;72413:42;84507:58;;;10292:51:1;10359:18;;;10352:34;;;72328:42:0;;84507:29;;10265:18:1;;84507:58:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;84602:12;72413:42;-1:-1:-1;;;;;84617:26:0;;:28;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;84602:43;;84660:7;84656:235;;;84712:53;;-1:-1:-1;;;84712:53:0;;;;;15463:25:1;;;84759:4:0;15504:18:1;;;15497:60;84684:25:0;;72500:42;;84712:29;;15436:18:1;;84712:53:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;84823:10;;84684:81;;-1:-1:-1;84792:61:0;;72413:42;;-1:-1:-1;;;;;84823:10:0;84684:81;84792:30;:61::i;21086:229::-;21223:12;21255:52;21277:6;21285:4;21291:1;21294:12;21223;22460;22474:23;22501:6;-1:-1:-1;;;;;22501:11:0;22520:5;22527:4;22501:31;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;22459:73;;;;22550:69;22577:6;22585:7;22594:10;22606:12;24930;24959:7;24955:427;;;24987:10;:17;25008:1;24987:22;24983:290;;-1:-1:-1;;;;;18626:19:0;;;25197:60;;;;-1:-1:-1;;;25197:60:0;;21802:2:1;25197:60:0;;;21784:21:1;21841:2;21821:18;;;21814:30;21880:31;21860:18;;;21853:59;21929:18;;25197:60:0;21600:353:1;25197:60:0;-1:-1:-1;25294:10:0;25287:17;;24955:427;25337:33;25345:10;25357:12;26092:17;;:21;26088:388;;26324:10;26318:17;26381:15;26368:10;26364:2;26360:19;26353:44;26088:388;26451:12;26444:20;;-1:-1:-1;;;26444:20:0;;;;;;;;:::i;404:226:1:-;463:6;516:2;504:9;495:7;491:23;487:32;484:52;;;532:1;529;522:12;484:52;-1:-1:-1;577:23:1;;404:226;-1:-1:-1;404:226:1:o;635:127::-;696:10;691:3;687:20;684:1;677:31;727:4;724:1;717:15;751:4;748:1;741:15;767:1152;-1:-1:-1;;;;;1190:32:1;;;1172:51;;1254:2;1239:18;;;1232:34;;;1297:2;1282:18;;;1275:34;;;1340:2;1325:18;;1318:34;;;1383:3;1368:19;;1361:35;;;1440:14;;1433:22;1210:3;1412:19;;1405:51;1507:13;;1500:21;1493:29;1487:3;1472:19;;1465:58;1570:15;;;1564:22;1560:48;;;1554:3;1539:19;;1532:77;1644:15;;1638:22;1159:3;1144:19;;;1696:1;1679:19;;1669:150;;1741:10;1736:3;1732:20;1729:1;1722:31;1776:4;1773:1;1766:15;1804:4;1801:1;1794:15;1669:150;1850:3;1835:19;;1828:41;1900:3;1885:19;;;1878:35;;;;767:1152;;-1:-1:-1;;;;;;;767:1152:1:o;1924:346::-;1992:6;2000;2053:2;2041:9;2032:7;2028:23;2024:32;2021:52;;;2069:1;2066;2059:12;2021:52;-1:-1:-1;;2114:23:1;;;2234:2;2219:18;;;2206:32;;-1:-1:-1;1924:346:1:o;2275:140::-;-1:-1:-1;;;;;2359:31:1;;2349:42;;2339:70;;2405:1;2402;2395:12;2420:272;2495:6;2548:2;2536:9;2527:7;2523:23;2519:32;2516:52;;;2564:1;2561;2554:12;2516:52;2603:9;2590:23;2622:40;2656:5;2622:40;:::i;3118:466::-;3195:6;3203;3211;3264:2;3252:9;3243:7;3239:23;3235:32;3232:52;;;3280:1;3277;3270:12;3232:52;-1:-1:-1;;3325:23:1;;;3445:2;3430:18;;3417:32;;-1:-1:-1;3548:2:1;3533:18;;;3520:32;;3118:466;-1:-1:-1;3118:466:1:o;3589:540::-;3680:6;3688;3696;3749:2;3737:9;3728:7;3724:23;3720:32;3717:52;;;3765:1;3762;3755:12;3717:52;3804:9;3791:23;3823:40;3857:5;3823:40;:::i;:::-;3882:5;-1:-1:-1;3960:2:1;3945:18;;3932:32;;-1:-1:-1;4042:2:1;4027:18;;4014:32;4055:42;4014:32;4055:42;:::i;:::-;4116:7;4106:17;;;3589:540;;;;;:::o;4134:118::-;4220:5;4213:13;4206:21;4199:5;4196:32;4186:60;;4242:1;4239;4232:12;4257:241;4313:6;4366:2;4354:9;4345:7;4341:23;4337:32;4334:52;;;4382:1;4379;4372:12;4334:52;4421:9;4408:23;4440:28;4462:5;4440:28;:::i;4503:376::-;4571:6;4579;4632:2;4620:9;4611:7;4607:23;4603:32;4600:52;;;4648:1;4645;4638:12;4600:52;4693:23;;;-1:-1:-1;4792:2:1;4777:18;;4764:32;4805:42;4764:32;4805:42;:::i;:::-;4866:7;4856:17;;;4503:376;;;;;:::o;5336:767::-;5442:6;5450;5458;5466;5474;5527:3;5515:9;5506:7;5502:23;5498:33;5495:53;;;5544:1;5541;5534:12;5495:53;5589:23;;;-1:-1:-1;5709:2:1;5694:18;;5681:32;;-1:-1:-1;5791:2:1;5776:18;;5763:32;5804:42;5763:32;5804:42;:::i;:::-;5865:7;-1:-1:-1;5924:2:1;5909:18;;5896:32;5937:30;5896:32;5937:30;:::i;:::-;5336:767;;;;-1:-1:-1;5336:767:1;;6066:3;6051:19;6038:33;;5336:767;-1:-1:-1;;5336:767:1:o;6361:361::-;6426:6;6434;6487:2;6475:9;6466:7;6462:23;6458:32;6455:52;;;6503:1;6500;6493:12;6455:52;6548:23;;;-1:-1:-1;6647:2:1;6632:18;;6619:32;6660:30;6619:32;6660:30;:::i;7210:389::-;7291:6;7299;7352:2;7340:9;7331:7;7327:23;7323:32;7320:52;;;7368:1;7365;7358:12;7320:52;7413:23;;;-1:-1:-1;7512:2:1;7497:18;;7484:32;7547:1;7535:14;;7525:42;;7563:1;7560;7553:12;7604:367;7667:8;7677:6;7731:3;7724:4;7716:6;7712:17;7708:27;7698:55;;7749:1;7746;7739:12;7698:55;-1:-1:-1;7772:20:1;;7815:18;7804:30;;7801:50;;;7847:1;7844;7837:12;7801:50;7884:4;7876:6;7872:17;7860:29;;7944:3;7937:4;7927:6;7924:1;7920:14;7912:6;7908:27;7904:38;7901:47;7898:67;;;7961:1;7958;7951:12;7898:67;7604:367;;;;;:::o;7976:1099::-;8134:6;8142;8150;8158;8166;8174;8227:2;8215:9;8206:7;8202:23;8198:32;8195:52;;;8243:1;8240;8233:12;8195:52;8283:9;8270:23;8316:18;8308:6;8305:30;8302:50;;;8348:1;8345;8338:12;8302:50;8387:70;8449:7;8440:6;8429:9;8425:22;8387:70;:::i;:::-;8476:8;;-1:-1:-1;8361:96:1;-1:-1:-1;;8564:2:1;8549:18;;8536:32;8593:18;8580:32;;8577:52;;;8625:1;8622;8615:12;8577:52;8664:72;8728:7;8717:8;8706:9;8702:24;8664:72;:::i;:::-;8755:8;;-1:-1:-1;8638:98:1;-1:-1:-1;;8843:2:1;8828:18;;8815:32;8872:18;8859:32;;8856:52;;;8904:1;8901;8894:12;8856:52;8943:72;9007:7;8996:8;8985:9;8981:24;8943:72;:::i;:::-;7976:1099;;;;-1:-1:-1;7976:1099:1;;-1:-1:-1;7976:1099:1;;9034:8;;7976:1099;-1:-1:-1;;;7976:1099:1:o;9080:407::-;9282:2;9264:21;;;9321:2;9301:18;;;9294:30;9360:34;9355:2;9340:18;;9333:62;-1:-1:-1;;;9426:2:1;9411:18;;9404:41;9477:3;9462:19;;9080:407::o;9492:127::-;9553:10;9548:3;9544:20;9541:1;9534:31;9584:4;9581:1;9574:15;9608:4;9605:1;9598:15;9624:184;9694:6;9747:2;9735:9;9726:7;9722:23;9718:32;9715:52;;;9763:1;9760;9753:12;9715:52;-1:-1:-1;9786:16:1;;9624:184;-1:-1:-1;9624:184:1:o;10397:245::-;10464:6;10517:2;10505:9;10496:7;10492:23;10488:32;10485:52;;;10533:1;10530;10523:12;10485:52;10565:9;10559:16;10584:28;10606:5;10584:28;:::i;13209:400::-;13411:2;13393:21;;;13450:2;13430:18;;;13423:30;13489:34;13484:2;13469:18;;13462:62;-1:-1:-1;;;13555:2:1;13540:18;;13533:34;13599:3;13584:19;;13209:400::o;14279:398::-;14481:2;14463:21;;;14520:2;14500:18;;;14493:30;14559:34;14554:2;14539:18;;14532:62;-1:-1:-1;;;14625:2:1;14610:18;;14603:32;14667:3;14652:19;;14279:398::o;14682:127::-;14743:10;14738:3;14734:20;14731:1;14724:31;14774:4;14771:1;14764:15;14798:4;14795:1;14788:15;14814:128;14881:9;;;14902:11;;;14899:37;;;14916:18;;:::i;15927:135::-;15966:3;15987:17;;;15984:43;;16007:18;;:::i;:::-;-1:-1:-1;16054:1:1;16043:13;;15927:135::o;16427:168::-;16500:9;;;16531;;16548:15;;;16542:22;;16528:37;16518:71;;16569:18;;:::i;16600:125::-;16665:9;;;16686:10;;;16683:36;;;16699:18;;:::i;17090:217::-;17130:1;17156;17146:132;;17200:10;17195:3;17191:20;17188:1;17181:31;17235:4;17232:1;17225:15;17263:4;17260:1;17253:15;17146:132;-1:-1:-1;17292:9:1;;17090:217::o;17672:147::-;17751:13;;17773:40;17751:13;17773:40;:::i;:::-;17672:147;;;:::o;17824:260::-;17894:6;17947:2;17935:9;17926:7;17922:23;17918:32;17915:52;;;17963:1;17960;17953:12;17915:52;17995:9;17989:16;18014:40;18048:5;18014:40;:::i;18089:127::-;18150:10;18145:3;18141:20;18138:1;18131:31;18181:4;18178:1;18171:15;18205:4;18202:1;18195:15;18221:1135;18316:6;18369:2;18357:9;18348:7;18344:23;18340:32;18337:52;;;18385:1;18382;18375:12;18337:52;18418:9;18412:16;18451:18;18443:6;18440:30;18437:50;;;18483:1;18480;18473:12;18437:50;18506:22;;18559:4;18551:13;;18547:27;-1:-1:-1;18537:55:1;;18588:1;18585;18578:12;18537:55;18621:2;18615:9;18647:18;18639:6;18636:30;18633:56;;;18669:18;;:::i;:::-;18715:6;18712:1;18708:14;18751:2;18745:9;18814:2;18810:7;18805:2;18801;18797:11;18793:25;18785:6;18781:38;18885:6;18873:10;18870:22;18849:18;18837:10;18834:34;18831:62;18828:88;;;18896:18;;:::i;:::-;18932:2;18925:22;18982;;;19032:2;19062:11;;;19058:20;;;18982:22;19020:15;;19090:19;;;19087:39;;;19122:1;19119;19112:12;19087:39;19154:2;19150;19146:11;19135:22;;19166:159;19182:6;19177:3;19174:15;19166:159;;;19248:34;19278:3;19248:34;:::i;:::-;19236:47;;19312:2;19199:12;;;;19303;19166:159;;;-1:-1:-1;19344:6:1;18221:1135;-1:-1:-1;;;;;;18221:1135:1:o;19361:734::-;-1:-1:-1;;;;;19609:32:1;;19591:51;;19579:2;19673;19658:18;;;19651:30;;;19730:13;;19564:18;;;19752:22;;;19531:4;;19831:15;;;;19805:2;19790:18;;;19531:4;19874:195;19888:6;19885:1;19882:13;19874:195;;;19953:13;;-1:-1:-1;;;;;19949:39:1;19937:52;;20018:2;20044:15;;;;20009:12;;;;19985:1;19903:9;19874:195;;;-1:-1:-1;20086:3:1;;19361:734;-1:-1:-1;;;;;;19361:734:1:o;21294:301::-;21423:3;21461:6;21455:13;21507:6;21500:4;21492:6;21488:17;21483:3;21477:37;21569:1;21533:16;;21558:13;;;-1:-1:-1;21533:16:1;21294:301;-1:-1:-1;21294:301:1:o;21958:418::-;22107:2;22096:9;22089:21;22070:4;22139:6;22133:13;22182:6;22177:2;22166:9;22162:18;22155:34;22241:6;22236:2;22228:6;22224:15;22219:2;22208:9;22204:18;22198:50;22297:1;22292:2;22283:6;22272:9;22268:22;22264:31;22257:42;22367:2;22360;22356:7;22351:2;22343:6;22339:15;22335:29;22324:9;22320:45;22316:54;22308:62;;;21958:418;;;;:::o
Swarm Source
ipfs://546019463008f930e7086dcc27b8ea4c441319f42813d3eace00544febff80b8
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.