Overview
S Balance
S Value
$0.00More Info
Private Name Tags
ContractCreator
Loading...
Loading
Contract Source Code Verified (Exact Match)
Contract Name:
VeSixRewardDistributor
Compiler Version
v0.8.27+commit.40a35a09
Contract Source Code (Solidity)
/** *Submitted for verification at SonicScan.org on 2025-03-29 */ // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20Upgradeable { /** * @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); } pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612]. * * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't * need to send a transaction, and thus is not required to hold Ether at all. * * ==== 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 IERC20PermitUpgradeable { /** * @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); } pragma solidity ^0.8.1; /** * @dev Collection of functions related to the address type */ library AddressUpgradeable { /** * @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); } } } pragma solidity ^0.8.0; /** * @title SafeERC20 * @dev Wrappers around ERC20 operations that throw on failure (when the token * contract returns false). Tokens that return no value (and instead revert or * throw on failure) are also supported, non-reverting calls are assumed to be * successful. * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract, * which allows you to call the safe operations as `token.safeTransfer(...)`, etc. */ library SafeERC20Upgradeable { using AddressUpgradeable 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(IERC20Upgradeable 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(IERC20Upgradeable 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(IERC20Upgradeable 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(IERC20Upgradeable 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(IERC20Upgradeable 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(IERC20Upgradeable 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( IERC20PermitUpgradeable 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(IERC20Upgradeable 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(IERC20Upgradeable 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))) && AddressUpgradeable.isContract(address(token)); } } pragma solidity ^0.8.20; /** * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect. * * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be * reused. This mechanism prevents re-execution of each "step" but allows the creation of new initialization steps in * case an upgrade adds a module that needs to be initialized. * * For example: * * [.hljs-theme-light.nopadding] * ```solidity * contract MyToken is ERC20Upgradeable { * function initialize() initializer public { * __ERC20_init("MyToken", "MTK"); * } * } * * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable { * function initializeV2() reinitializer(2) public { * __ERC20Permit_init("MyToken"); * } * } * ``` * * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}. * * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity. * * [CAUTION] * ==== * Avoid leaving a contract uninitialized. * * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed: * * [.hljs-theme-light.nopadding] * ``` * /// @custom:oz-upgrades-unsafe-allow constructor * constructor() { * _disableInitializers(); * } * ``` * ==== */ abstract contract Initializable { /** * @dev Storage of the initializable contract. * * It's implemented on a custom ERC-7201 namespace to reduce the risk of storage collisions * when using with upgradeable contracts. * * @custom:storage-location erc7201:openzeppelin.storage.Initializable */ struct InitializableStorage { /** * @dev Indicates that the contract has been initialized. */ uint64 _initialized; /** * @dev Indicates that the contract is in the process of being initialized. */ bool _initializing; } // keccak256(abi.encode(uint256(keccak256("openzeppelin.storage.Initializable")) - 1)) & ~bytes32(uint256(0xff)) bytes32 private constant INITIALIZABLE_STORAGE = 0xf0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00; /** * @dev The contract is already initialized. */ error InvalidInitialization(); /** * @dev The contract is not initializing. */ error NotInitializing(); /** * @dev Triggered when the contract has been initialized or reinitialized. */ event Initialized(uint64 version); /** * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope, * `onlyInitializing` functions can be used to initialize parent contracts. * * Similar to `reinitializer(1)`, except that in the context of a constructor an `initializer` may be invoked any * number of times. This behavior in the constructor can be useful during testing and is not expected to be used in * production. * * Emits an {Initialized} event. */ modifier initializer() { // solhint-disable-next-line var-name-mixedcase InitializableStorage storage $ = _getInitializableStorage(); // Cache values to avoid duplicated sloads bool isTopLevelCall = !$._initializing; uint64 initialized = $._initialized; // Allowed calls: // - initialSetup: the contract is not in the initializing state and no previous version was // initialized // - construction: the contract is initialized at version 1 (no reininitialization) and the // current contract is just being deployed bool initialSetup = initialized == 0 && isTopLevelCall; bool construction = initialized == 1 && address(this).code.length == 0; if (!initialSetup && !construction) { revert InvalidInitialization(); } $._initialized = 1; if (isTopLevelCall) { $._initializing = true; } _; if (isTopLevelCall) { $._initializing = false; emit Initialized(1); } } /** * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be * used to initialize parent contracts. * * A reinitializer may be used after the original initialization step. This is essential to configure modules that * are added through upgrades and that require initialization. * * When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer` * cannot be nested. If one is invoked in the context of another, execution will revert. * * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in * a contract, executing them in the right order is up to the developer or operator. * * WARNING: Setting the version to 2**64 - 1 will prevent any future reinitialization. * * Emits an {Initialized} event. */ modifier reinitializer(uint64 version) { // solhint-disable-next-line var-name-mixedcase InitializableStorage storage $ = _getInitializableStorage(); if ($._initializing || $._initialized >= version) { revert InvalidInitialization(); } $._initialized = version; $._initializing = true; _; $._initializing = false; emit Initialized(version); } /** * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the * {initializer} and {reinitializer} modifiers, directly or indirectly. */ modifier onlyInitializing() { _checkInitializing(); _; } /** * @dev Reverts if the contract is not in an initializing state. See {onlyInitializing}. */ function _checkInitializing() internal view virtual { if (!_isInitializing()) { revert NotInitializing(); } } /** * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call. * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized * to any version. It is recommended to use this to lock implementation contracts that are designed to be called * through proxies. * * Emits an {Initialized} event the first time it is successfully executed. */ function _disableInitializers() internal virtual { // solhint-disable-next-line var-name-mixedcase InitializableStorage storage $ = _getInitializableStorage(); if ($._initializing) { revert InvalidInitialization(); } if ($._initialized != type(uint64).max) { $._initialized = type(uint64).max; emit Initialized(type(uint64).max); } } /** * @dev Returns the highest version that has been initialized. See {reinitializer}. */ function _getInitializedVersion() internal view returns (uint64) { return _getInitializableStorage()._initialized; } /** * @dev Returns `true` if the contract is currently initializing. See {onlyInitializing}. */ function _isInitializing() internal view returns (bool) { return _getInitializableStorage()._initializing; } /** * @dev Returns a pointer to the storage namespace. */ // solhint-disable-next-line var-name-mixedcase function _getInitializableStorage() private pure returns (InitializableStorage storage $) { assembly { $.slot := INITIALIZABLE_STORAGE } } } 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 ReentrancyGuardUpgradeable is Initializable { // 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; function __ReentrancyGuard_init() internal onlyInitializing { __ReentrancyGuard_init_unchained(); } function __ReentrancyGuard_init_unchained() internal onlyInitializing { _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 This empty reserved space is put in place to allow future versions to add new * variables without shifting down storage in the inheritance chain. * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps */ uint256[49] private __gap; } pragma solidity 0.8.27; interface IVeSix { struct Point { int128 bias; int128 slope; uint256 ts; uint256 blk; } struct LockPosition { uint128 amount; uint128 slope; uint32 endTime; uint32 lastUpdate; } function balanceOfNFTAt(uint256 tokenId, uint256 timestamp) external view returns (uint256); function ownerOf(uint256 tokenId) external view returns (address); function isApprovedOrOwner(address spender, uint256 tokenId) external view returns (bool); function lockedToken() external view returns (address); function increaseLockAmount(uint256 tokenId, uint128 additionalAmount, uint256 deadline, uint128 minMultiplier) external; function _locks(uint256 tokenId) external view returns (LockPosition memory ) ; function getCurrentMultiplier(uint256 tokenId) external view returns (uint128); function totalWeightedSupply() external view returns (uint128); function getFarmingPower(uint256 tokenId, uint32 timestamp) external view returns (uint128); function point_history(uint256 epoch) external view returns (Point memory); function user_point_history(uint256 tokenId, uint256 loc) external view returns (Point memory); function epoch() external view returns (uint256); function userPointEpoch(uint256 tokenId) external view returns (uint256); function checkpoint() external; } pragma solidity 0.8.27; contract VeSixRewardDistributor is Initializable, ReentrancyGuardUpgradeable { using SafeERC20Upgradeable for IERC20Upgradeable; struct Reward { uint256 periodFinish; uint256 rewardRate; uint256 lastUpdateTime; uint256 rewardPerVeTokenStored; uint256 queuedRewards; uint256 lastTotalSupply; uint256 periodId; } struct HistoricalReward { uint256 amount; uint256 periodId; } IVeSix public veSix; address public distributor; mapping(address => Reward) public rewardData; mapping(address => bool) public isRewardToken; mapping(address => uint256) public currentPeriod; address[] public rewardTokens; mapping(address => mapping(uint256 => uint256)) public userRewardPerTokenPaid; mapping(address => mapping(uint256 => uint256)) public rewards; mapping(address => mapping(uint256 => HistoricalReward)) public historicalRewards; uint256 public constant DURATION = 7 days; uint256 public constant MINIMUM_RATE = 1e6; uint256 public constant MAXIMUM_RATE = 1e24; uint256 public constant PRECISION = 1e18; uint256 public constant MAX_REWARD_TOKENS = 50; uint256[49] private __gap; event RewardAdded(address token, uint256 reward, uint256 rewardRate, uint256 periodId); event RewardPaid(uint256 indexed tokenId, address indexed rewardsToken, uint256 reward, uint256 periodId); event RewardQueued(address token, uint256 amount, uint256 periodId); event RewardTokenAdded(address token, uint256 periodId); event RewardTokenRemoved(address token, uint256 periodId); event DistributorUpdated(address newDistributor); event RewardFixed(uint256 tokenId, address token, uint256 reward, uint256 balance); error InvalidRewardToken(); error InsufficientBalance(); error RateTooLow(); error RateTooHigh(); error Unauthorized(); error ZeroAddress(); error TokenAlreadyAdded(); error NoRewards(); error TooManyRewardTokens(); error InvalidVeSupply(); error ArithmeticError(); error TransferFailed(); error InvalidState(); modifier onlyDistributor() { if (msg.sender != distributor) revert Unauthorized(); _; } constructor() { _disableInitializers(); } function initialize( address _veSix, address _distributor ) external initializer { if (_veSix == address(0) || _distributor == address(0)) revert ZeroAddress(); __ReentrancyGuard_init(); veSix = IVeSix(_veSix); distributor = _distributor; } function addInitialRewardTokens(address[] memory _rewardTokens) external onlyDistributor { if (_rewardTokens.length > MAX_REWARD_TOKENS) revert TooManyRewardTokens(); if (rewardTokens.length > 0) revert("Tokens already initialized"); for(uint i = 0; i < _rewardTokens.length; i++) { for(uint j = i + 1; j < _rewardTokens.length; j++) { if (_rewardTokens[i] == _rewardTokens[j]) revert("Duplicate token"); } } for(uint i = 0; i < _rewardTokens.length; i++) { _addRewardToken(_rewardTokens[i]); } } function updateDistributor(address _newDistributor) external onlyDistributor { if (_newDistributor == address(0)) revert ZeroAddress(); distributor = _newDistributor; emit DistributorUpdated(_newDistributor); } function addRewardToken(address token) external onlyDistributor { _addRewardToken(token); } function _addRewardToken(address token) internal { if (token == address(0)) revert ZeroAddress(); if (isRewardToken[token]) revert TokenAlreadyAdded(); rewardTokens.push(token); isRewardToken[token] = true; currentPeriod[token] = 1; Reward storage reward = rewardData[token]; reward.lastTotalSupply = 0; reward.periodId = currentPeriod[token]; emit RewardTokenAdded(token, currentPeriod[token]); } function getTotalSupply() public view returns (uint256) { return veSix.totalWeightedSupply(); } modifier updateReward(uint256 tokenId) { uint256 veSupply = getTotalSupply(); if (veSupply == 0 && veSix.epoch() > 0) revert InvalidVeSupply(); for(uint i = 0; i < rewardTokens.length; i++) { address token = rewardTokens[i]; Reward storage reward = rewardData[token]; uint256 oldRewardPerToken = _calculateRewardPerToken(token, reward.lastTotalSupply); reward.rewardPerVeTokenStored = oldRewardPerToken; reward.lastUpdateTime = lastTimeRewardApplicable(token); reward.lastTotalSupply = veSupply; if (tokenId != 0) { // Ensure userRewardPerTokenPaid never exceeds rewardPerVeTokenStored if (userRewardPerTokenPaid[token][tokenId] > reward.rewardPerVeTokenStored) { userRewardPerTokenPaid[token][tokenId] = reward.rewardPerVeTokenStored; } rewards[token][tokenId] = earned(token, tokenId); userRewardPerTokenPaid[token][tokenId] = reward.rewardPerVeTokenStored; } } _; } function lastTimeRewardApplicable(address _rewardsToken) public view returns (uint256) { return block.timestamp < rewardData[_rewardsToken].periodFinish ? block.timestamp : rewardData[_rewardsToken].periodFinish; } function _calculateRewardPerToken(address _rewardsToken, uint256 _supply) internal view returns (uint256) { Reward storage reward = rewardData[_rewardsToken]; if (_supply == 0 || !isRewardToken[_rewardsToken]) { return reward.rewardPerVeTokenStored; } // Calculate new rewards since last update uint256 timeDelta = lastTimeRewardApplicable(_rewardsToken) - reward.lastUpdateTime; if (timeDelta == 0) return reward.rewardPerVeTokenStored; // Ensure _supply is at least 1 to prevent division by zero if (_supply < PRECISION) { _supply = PRECISION; } // Reward amount calculation with correct precision handling // rewardRate is already scaled by PRECISION uint256 rewardAmount = reward.rewardRate * timeDelta; // Multiply first, then divide to preserve precision uint256 additionalRewardPerToken = (rewardAmount * PRECISION) / _supply; // Ensure at least some minimum increase if time has passed if (additionalRewardPerToken == 0 && timeDelta > 0) { additionalRewardPerToken = 1; // Minimum non-zero increase } return reward.rewardPerVeTokenStored + additionalRewardPerToken; } function earned(address _rewardsToken, uint256 tokenId) public view returns (uint256) { Reward storage reward = rewardData[_rewardsToken]; // Get farming power at the exact last update time uint256 balance = veSix.getFarmingPower(tokenId, uint32(reward.lastUpdateTime)); if (balance == 0) return 0; // SIMULATE the updated rewardPerToken value that would be calculated right now uint256 currentRewardPerToken; { // Only recalculate if time has passed since last update if (lastTimeRewardApplicable(_rewardsToken) > reward.lastUpdateTime) { uint256 timeDelta = lastTimeRewardApplicable(_rewardsToken) - reward.lastUpdateTime; uint256 rewardAmount = (reward.rewardRate * timeDelta) / PRECISION; uint256 additionalRewardPerToken = (rewardAmount * PRECISION) / reward.lastTotalSupply; // Ensure at least minimum increase if (additionalRewardPerToken == 0 && timeDelta > 0) { additionalRewardPerToken = 1; } currentRewardPerToken = reward.rewardPerVeTokenStored + additionalRewardPerToken; } else { currentRewardPerToken = reward.rewardPerVeTokenStored; } } // Continue with normal reward calculation using the simulated value uint256 userPaid = userRewardPerTokenPaid[_rewardsToken][tokenId]; uint256 rewardDelta = currentRewardPerToken > userPaid ? currentRewardPerToken - userPaid : 0; uint256 pendingReward = (balance * rewardDelta) / PRECISION; return rewards[_rewardsToken][tokenId] + pendingReward; } function queueNewRewards(address _rewardsToken, uint256 amount) external onlyDistributor { if (!isRewardToken[_rewardsToken]) revert InvalidRewardToken(); if (amount == 0) revert InvalidState(); uint256 oldBalance = IERC20Upgradeable(_rewardsToken).balanceOf(address(this)); IERC20Upgradeable(_rewardsToken).safeTransferFrom(msg.sender, address(this), amount); uint256 received = IERC20Upgradeable(_rewardsToken).balanceOf(address(this)) - oldBalance; rewardData[_rewardsToken].queuedRewards += received; emit RewardQueued(_rewardsToken, received, rewardData[_rewardsToken].periodId); } function notifyRewardAmount(address _rewardsToken, uint256 reward) external onlyDistributor { if (!isRewardToken[_rewardsToken]) revert InvalidRewardToken(); if (reward == 0) revert InvalidState(); // Check actual token balance uint256 balance = IERC20Upgradeable(_rewardsToken).balanceOf(address(this)); if (balance < reward) revert InsufficientBalance(); Reward storage rewardInfo = rewardData[_rewardsToken]; // If this is the first reward for this token, start a new epoch if (rewardInfo.lastUpdateTime == 0) { currentPeriod[_rewardsToken]++; // Record farming power at epoch start rewardInfo.lastTotalSupply = getTotalSupply(); } // Calculate remaining rewards based on time left in current period uint256 timeLeft = 0; if (rewardInfo.lastUpdateTime > 0 && rewardInfo.periodFinish > block.timestamp) { timeLeft = rewardInfo.periodFinish - block.timestamp; } uint256 remainingRewards = 0; if (timeLeft > 0 && rewardInfo.rewardRate > 0) { // Cap remaining rewards calculation to prevent overflow if (rewardInfo.rewardRate > type(uint256).max / timeLeft) { remainingRewards = MAXIMUM_RATE * timeLeft; // Use a reasonable maximum } else { // Adjust for precision scaling in the stored rate remainingRewards = (rewardInfo.rewardRate * timeLeft) / PRECISION; } } // Calculate total rewards (uncapped) uint256 totalRewardsUncapped = reward + remainingRewards + rewardInfo.queuedRewards; // Cap total rewards to the contract's balance and a reasonable maximum uint256 totalRewards = totalRewardsUncapped; uint256 maxReasonableRewards = 1_000_000 * 10**18; // 1 billion tokens max if (totalRewards > balance) { totalRewards = balance; } if (totalRewards > maxReasonableRewards) { totalRewards = maxReasonableRewards; } // Reset queued rewards rewardInfo.queuedRewards = 0; // Calculate new rate with CORRECT precision scaling // We want the rate to be "tokens per second" * PRECISION uint256 newRate; if (totalRewards > 0) { // Ensure DURATION is non-zero to prevent division by zero if (DURATION == 0) revert InvalidState(); // Calculate rate properly: tokens per second uint256 tokensPerSecond = (totalRewards * PRECISION) / DURATION; // Cap tokensPerSecond to a reasonable amount (1000 tokens/sec) uint256 maxTokensPerSecond = 1000 * PRECISION; if (tokensPerSecond > maxTokensPerSecond) { tokensPerSecond = maxTokensPerSecond; } // No need to scale by PRECISION again since we already did it newRate = tokensPerSecond; // Final bounds checking if (newRate > MAXIMUM_RATE) { newRate = MAXIMUM_RATE; } if (newRate < MINIMUM_RATE) { revert RateTooLow(); } } else { revert RateTooLow(); } // Update reward data rewardInfo.rewardRate = newRate; rewardInfo.lastUpdateTime = block.timestamp; rewardInfo.periodFinish = block.timestamp + DURATION; // Ensure lastTotalSupply is at least PRECISION to prevent division by zero later uint256 currentSupply = getTotalSupply(); rewardInfo.lastTotalSupply = currentSupply < PRECISION ? PRECISION : currentSupply; // Update reward per token stored rewardInfo.rewardPerVeTokenStored = _calculateRewardPerToken(_rewardsToken, rewardInfo.lastTotalSupply); emit RewardAdded(_rewardsToken, totalRewards, newRate, rewardInfo.periodId); } function removeRewardToken(address _rewardsToken) external onlyDistributor { if (!isRewardToken[_rewardsToken]) revert InvalidRewardToken(); Reward storage rewardInfo = rewardData[_rewardsToken]; if (block.timestamp < rewardInfo.periodFinish) revert("Active rewards period"); if (rewardInfo.queuedRewards > 0) revert("Pending rewards"); uint256 currentTokenPeriod = currentPeriod[_rewardsToken]; uint256 epoch = veSix.epoch(); for (uint256 i = 1; i <= epoch; i++) { try veSix.ownerOf(i) returns (address) { // Check if token exists uint256 currentReward = earned(_rewardsToken, i); if (currentReward > 0) { historicalRewards[_rewardsToken][i] = HistoricalReward({ amount: currentReward, periodId: currentTokenPeriod }); } } catch {} } isRewardToken[_rewardsToken] = false; currentPeriod[_rewardsToken] = currentTokenPeriod + 1; for (uint i = 0; i < rewardTokens.length; i++) { if (rewardTokens[i] == _rewardsToken) { rewardTokens[i] = rewardTokens[rewardTokens.length - 1]; rewardTokens.pop(); break; } } emit RewardTokenRemoved(_rewardsToken, currentTokenPeriod); } function claim(uint256 tokenId) public nonReentrant updateReward(tokenId) { if (veSix.ownerOf(tokenId) != msg.sender) revert Unauthorized(); (address[] memory tokens, uint256[] memory amounts, uint256[] memory periods) = getClaimableRewards(tokenId); if (tokens.length == 0) revert NoRewards(); for(uint i = 0; i < tokens.length; i++) { address token = tokens[i]; uint256 amount = amounts[i]; if (amount > 0) { if (!isRewardToken[token]) revert InvalidRewardToken(); Reward storage reward = rewardData[token]; rewards[token][tokenId] = 0; userRewardPerTokenPaid[token][tokenId] = reward.rewardPerVeTokenStored; historicalRewards[token][tokenId].amount = 0; _safeTransferReward(token, msg.sender, amount, tokenId, periods[i]); } } } function _safeTransferReward( address token, address to, uint256 amount, uint256 tokenId, uint256 periodId ) internal { if (amount == 0) return; // If token is locked token, it is auto-compounded if (token == veSix.lockedToken()) { if (amount > type(uint128).max) revert("Amount too large"); uint128 currentMultiplier = veSix.getCurrentMultiplier(tokenId); if (currentMultiplier == 0) revert("Invalid multiplier"); uint128 minMultiplier = currentMultiplier * 95 / 100; // 5% slippage allowance IERC20Upgradeable(token).approve(address(veSix), amount); try veSix.increaseLockAmount( tokenId, uint128(amount), block.timestamp, minMultiplier ) { emit RewardPaid(tokenId, token, amount, periodId); return; } catch { // Clear approval if increase fails IERC20Upgradeable(token).approve(address(veSix), 0); revert("Auto-compound failed"); } } // For non-locked tokens, do regular transfer uint256 preBalance = IERC20Upgradeable(token).balanceOf(address(this)); if (preBalance < amount) revert InsufficientBalance(); uint256 recipientPreBalance = IERC20Upgradeable(token).balanceOf(to); IERC20Upgradeable(token).safeTransfer(to, amount); uint256 recipientPostBalance = IERC20Upgradeable(token).balanceOf(to); if (recipientPostBalance <= recipientPreBalance) revert TransferFailed(); uint256 received = recipientPostBalance - recipientPreBalance; emit RewardPaid(tokenId, token, received, periodId); } function getClaimableRewards(uint256 tokenId) public view returns ( address[] memory tokens, uint256[] memory amounts, uint256[] memory periods ) { // Check if token exists and has a valid owner address owner = veSix.ownerOf(tokenId); if (owner == address(0)) revert InvalidState(); address[] memory allTokens = getRewardTokens(); tokens = new address[](allTokens.length * 2); // *2 for active and historical amounts = new uint256[](allTokens.length * 2); periods = new uint256[](allTokens.length * 2); uint256 count; for(uint i = 0; i < allTokens.length; i++) { address token = allTokens[i]; // Active rewards uint256 activeReward = earned(token, tokenId); if (activeReward > 0) { tokens[count] = token; amounts[count] = activeReward; periods[count] = rewardData[token].periodId; count++; } // Historical rewards HistoricalReward memory historicalReward = historicalRewards[token][tokenId]; if (historicalReward.amount > 0 && historicalReward.periodId < currentPeriod[token]) { tokens[count] = token; amounts[count] = historicalReward.amount; periods[count] = historicalReward.periodId; count++; } } // Resize arrays to match actual count assembly { mstore(tokens, count) mstore(amounts, count) mstore(periods, count) } } function getRewardTokens() public view returns (address[] memory) { return rewardTokens; } function getRewardTokenLength() external view returns (uint256) { return rewardTokens.length; } /** * @notice Calculates total pending rewards across all tokens and reward tokens * @return totalRewards The total amount of pending rewards */ function getTotalPendingRewards() external view returns (uint256 totalRewards) { address[] memory allTokens = getRewardTokens(); // Iterate through all reward tokens for(uint i = 0; i < allTokens.length; i++) { address token = allTokens[i]; // Get current epoch uint256 epoch = veSix.epoch(); // Iterate through all tokens up to current epoch for (uint256 j = 1; j <= epoch; j++) { try veSix.ownerOf(j) returns (address) { // Add active rewards uint256 activeReward = earned(token, j); if (activeReward > 0) { totalRewards += activeReward; } // Add historical rewards HistoricalReward memory historicalReward = historicalRewards[token][j]; if (historicalReward.amount > 0 && historicalReward.periodId < currentPeriod[token]) { totalRewards += historicalReward.amount; } } catch { continue; } } } return totalRewards; } /** * @notice Emergency function to fix reward rate for active period * @dev Sets reward rate to exact value of 1.65343915343915 tokens per second * @param rewardToken The token address with incorrect reward rate */ function fixRewardRate(address rewardToken) external onlyDistributor { address _rewardToken = rewardToken; Reward storage reward = rewardData[_rewardToken]; reward.rewardRate = 1653439153439150000; // Update timestamps reward.lastUpdateTime = uint256(block.timestamp); reward.periodFinish = uint256(block.timestamp) + 7 days; // Calculate correct reward per token stored based on correct rate uint256 timeElapsed = block.timestamp - 1743206488; // Time since start uint256 correctRewardPerToken = (reward.rewardRate * timeElapsed) / reward.lastTotalSupply; reward.rewardPerVeTokenStored = correctRewardPerToken; // Calculate correct rewardPerVeTokenStored based on the correct rate timeElapsed = block.timestamp - reward.lastUpdateTime; uint256 rewardAmount = (reward.rewardRate * timeElapsed) / PRECISION; // Use the total supply from the start time uint256 startSupply = reward.lastTotalSupply; if (startSupply < PRECISION) { startSupply = PRECISION; } // Calculate the correct reward per token stored uint256 correctRewardPerTokenStored = (rewardAmount * PRECISION) / startSupply; // Set the correct reward per token stored reward.rewardPerVeTokenStored = correctRewardPerTokenStored; // Fix rewards for all tokens _fixRewardsForAllTokens(_rewardToken, reward); } /** * @notice Internal function to fix rewards for all tokens * @param _rewardsToken The reward token address * @param rewardInfo The reward info struct */ function _fixRewardsForAllTokens(address _rewardsToken, Reward storage rewardInfo) internal { uint256 epoch = veSix.epoch(); for (uint256 i = 1; i <= epoch; i++) { try veSix.ownerOf(i) returns (address) { _fixRewardForToken(_rewardsToken, i, rewardInfo); } catch { continue; } } } /** * @notice Internal function to fix reward for a single token * @param _rewardsToken The reward token address * @param tokenId The token ID * @param rewardInfo The reward info struct */ function _fixRewardForToken(address _rewardsToken, uint256 tokenId, Reward storage rewardInfo) internal { uint256 currentRewardPerToken = rewardInfo.rewardPerVeTokenStored; uint256 userPaid = userRewardPerTokenPaid[_rewardsToken][tokenId]; if (userPaid > currentRewardPerToken) { userRewardPerTokenPaid[_rewardsToken][tokenId] = currentRewardPerToken; uint32 epochTimestamp = uint32((rewardInfo.lastUpdateTime / 3600) * 3600); uint256 balance = veSix.getFarmingPower(tokenId, epochTimestamp); if (balance > 0) { uint256 rewardDelta = currentRewardPerToken > userRewardPerTokenPaid[_rewardsToken][tokenId] ? (currentRewardPerToken - userRewardPerTokenPaid[_rewardsToken][tokenId]) : 0; uint256 pendingReward = (balance * rewardDelta) / PRECISION; rewards[_rewardsToken][tokenId] += pendingReward; emit RewardFixed(tokenId, _rewardsToken, pendingReward, balance); } } } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"ArithmeticError","type":"error"},{"inputs":[],"name":"InsufficientBalance","type":"error"},{"inputs":[],"name":"InvalidInitialization","type":"error"},{"inputs":[],"name":"InvalidRewardToken","type":"error"},{"inputs":[],"name":"InvalidState","type":"error"},{"inputs":[],"name":"InvalidVeSupply","type":"error"},{"inputs":[],"name":"NoRewards","type":"error"},{"inputs":[],"name":"NotInitializing","type":"error"},{"inputs":[],"name":"RateTooHigh","type":"error"},{"inputs":[],"name":"RateTooLow","type":"error"},{"inputs":[],"name":"TokenAlreadyAdded","type":"error"},{"inputs":[],"name":"TooManyRewardTokens","type":"error"},{"inputs":[],"name":"TransferFailed","type":"error"},{"inputs":[],"name":"Unauthorized","type":"error"},{"inputs":[],"name":"ZeroAddress","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"newDistributor","type":"address"}],"name":"DistributorUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint64","name":"version","type":"uint64"}],"name":"Initialized","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"uint256","name":"reward","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"rewardRate","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"periodId","type":"uint256"}],"name":"RewardAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"uint256","name":"reward","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"balance","type":"uint256"}],"name":"RewardFixed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":true,"internalType":"address","name":"rewardsToken","type":"address"},{"indexed":false,"internalType":"uint256","name":"reward","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"periodId","type":"uint256"}],"name":"RewardPaid","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"periodId","type":"uint256"}],"name":"RewardQueued","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"uint256","name":"periodId","type":"uint256"}],"name":"RewardTokenAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"uint256","name":"periodId","type":"uint256"}],"name":"RewardTokenRemoved","type":"event"},{"inputs":[],"name":"DURATION","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAXIMUM_RATE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_REWARD_TOKENS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MINIMUM_RATE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PRECISION","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"_rewardTokens","type":"address[]"}],"name":"addInitialRewardTokens","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"addRewardToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"claim","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"currentPeriod","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"distributor","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_rewardsToken","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"earned","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"rewardToken","type":"address"}],"name":"fixRewardRate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getClaimableRewards","outputs":[{"internalType":"address[]","name":"tokens","type":"address[]"},{"internalType":"uint256[]","name":"amounts","type":"uint256[]"},{"internalType":"uint256[]","name":"periods","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getRewardTokenLength","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getRewardTokens","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getTotalPendingRewards","outputs":[{"internalType":"uint256","name":"totalRewards","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getTotalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"historicalRewards","outputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"periodId","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_veSix","type":"address"},{"internalType":"address","name":"_distributor","type":"address"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"isRewardToken","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_rewardsToken","type":"address"}],"name":"lastTimeRewardApplicable","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_rewardsToken","type":"address"},{"internalType":"uint256","name":"reward","type":"uint256"}],"name":"notifyRewardAmount","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_rewardsToken","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"queueNewRewards","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_rewardsToken","type":"address"}],"name":"removeRewardToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"rewardData","outputs":[{"internalType":"uint256","name":"periodFinish","type":"uint256"},{"internalType":"uint256","name":"rewardRate","type":"uint256"},{"internalType":"uint256","name":"lastUpdateTime","type":"uint256"},{"internalType":"uint256","name":"rewardPerVeTokenStored","type":"uint256"},{"internalType":"uint256","name":"queuedRewards","type":"uint256"},{"internalType":"uint256","name":"lastTotalSupply","type":"uint256"},{"internalType":"uint256","name":"periodId","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"rewardTokens","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"rewards","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_newDistributor","type":"address"}],"name":"updateDistributor","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"userRewardPerTokenPaid","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"veSix","outputs":[{"internalType":"contract IVeSix","name":"","type":"address"}],"stateMutability":"view","type":"function"}]
Contract Creation Code
6080604052348015600e575f5ffd5b5060156019565b60c9565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00805468010000000000000000900460ff161560685760405163f92ee8a960e01b815260040160405180910390fd5b80546001600160401b039081161460c65780546001600160401b0319166001600160401b0390811782556040519081527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b50565b6132e6806100d65f395ff3fe608060405234801561000f575f5ffd5b5060043610610195575f3560e01c80637abe18d2116100e0578063b2be1ef41161008f578063b2be1ef4146103fe578063b5fd73f814610408578063b66503cf1461043a578063b933ceac1461044d578063bc30a61814610477578063bfe109281461048a578063c4e41b221461049d578063c4f59f9b146104a5575f5ffd5b80637abe18d2146103625780637b167dfa1461036a5780637bb7bed11461038c57806386bc443e146103ac57806392815606146103cb578063aaf5eb68146103de578063ac4869f6146103ed575f5ffd5b80633d509c97116101475780633d509c97146102525780633e491d4714610265578063485cc9551461027857806348e5d9f81461028b5780635d0cde971461030a578063638634ee1461031257806364f78188146103255780636bc9b56114610338575f5ffd5b806304d0c2c5146101995780630a2976d5146101ae5780631be05289146101f95780631c03e6cc146102115780631e9b3a92146102245780632f2e36681461022c578063379607f51461023f575b5f5ffd5b6101ac6101a7366004612e75565b6104ba565b005b6101df6101bc366004612e75565b603a60209081525f92835260408084209091529082529020805460019091015482565b604080519283526020830191909152015b60405180910390f35b61020362093a8081565b6040519081526020016101f0565b6101ac61021f366004612e9f565b6106cd565b610203610703565b6101ac61023a366004612e9f565b6108e3565b6101ac61024d366004612ec1565b610a1a565b6101ac610260366004612e9f565b610dd2565b610203610273366004612e75565b6111a0565b6101ac610286366004612ed8565b61139c565b6102d5610299366004612e9f565b60346020525f90815260409020805460018201546002830154600384015460048501546005860154600690960154949593949293919290919087565b604080519788526020880196909652948601939093526060850191909152608084015260a083015260c082015260e0016101f0565b610203603281565b610203610320366004612e9f565b611513565b6101ac610333366004612f23565b611555565b610203610346366004612e75565b603860209081525f928352604080842090915290825290205481565b603754610203565b61037d610378366004612ec1565b6116e5565b6040516101f09392919061305e565b61039f61039a366004612ec1565b611a6f565b6040516101f091906130a0565b6102036103ba366004612e9f565b60366020525f908152604090205481565b60325461039f906001600160a01b031681565b610203670de0b6b3a764000081565b61020369d3c21bcecceda100000081565b610203620f424081565b61042a610416366004612e9f565b60356020525f908152604090205460ff1681565b60405190151581526020016101f0565b6101ac610448366004612e75565b611a97565b61020361045b366004612e75565b603960209081525f928352604080842090915290825290205481565b6101ac610485366004612e9f565b611e59565b60335461039f906001600160a01b031681565b610203611f00565b6104ad611f79565b6040516101f091906130b4565b6033546001600160a01b031633146104e4576040516282b42960e81b815260040160405180910390fd5b6001600160a01b0382165f9081526035602052604090205460ff1661051c5760405163dfde867160e01b815260040160405180910390fd5b805f0361053c5760405163baf3f0f760e01b815260040160405180910390fd5b6040516370a0823160e01b81525f906001600160a01b038416906370a082319061056a9030906004016130a0565b602060405180830381865afa158015610585573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906105a991906130c6565b90506105c06001600160a01b038416333085611fd9565b5f81846001600160a01b03166370a08231306040518263ffffffff1660e01b81526004016105ee91906130a0565b602060405180830381865afa158015610609573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061062d91906130c6565b61063791906130f1565b6001600160a01b0385165f90815260346020526040812060040180549293508392909190610666908490613104565b90915550506001600160a01b0384165f81815260346020908152604091829020600601548251938452908301849052908201527f09a4f557033a56cbe70db5ccef9534cbb73cbfe724512852e36e86e36d7a93b4906060015b60405180910390a150505050565b6033546001600160a01b031633146106f7576040516282b42960e81b815260040160405180910390fd5b6107008161204a565b50565b5f5f61070d611f79565b90505f5b81518110156108de575f82828151811061072d5761072d613117565b602002602001015190505f60325f9054906101000a90046001600160a01b03166001600160a01b031663900cf0cf6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610788573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906107ac91906130c6565b905060015b8181116108d3576032546040516331a9108f60e11b8152600481018390526001600160a01b0390911690636352211e90602401602060405180830381865afa92505050801561081d575060408051601f3d908101601f1916820190925261081a9181019061312b565b60015b156108c1575f61082d85846111a0565b905080156108425761083f8189613104565b97505b6001600160a01b0385165f908152603a602090815260408083208684528252918290208251808401909352805480845260019091015491830191909152158015906108a957506001600160a01b0386165f9081526036602090815260409091205490820151105b156108bd5780516108ba908a613104565b98505b5050505b806108cb81613146565b9150506107b1565b505050600101610711565b505090565b6033546001600160a01b0316331461090d576040516282b42960e81b815260040160405180910390fd5b6001600160a01b0381165f9081526034602052604090206716f2322656768fb06001820155426002820181905582919061094a9062093a80613104565b81555f61095b6367e73858426130f1565b90505f8260050154828460010154610973919061315e565b61097d9190613189565b60038401819055600284015490915061099690426130f1565b91505f670de0b6b3a76400008385600101546109b2919061315e565b6109bc9190613189565b6005850154909150670de0b6b3a76400008110156109df5750670de0b6b3a76400005b5f816109f3670de0b6b3a76400008561315e565b6109fd9190613189565b600387018190559050610a108787612171565b5050505050505050565b610a22612271565b805f610a2c611f00565b905080158015610aa457506032546040805163900cf0cf60e01b815290515f926001600160a01b03169163900cf0cf9160048083019260209291908290030181865afa158015610a7e573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610aa291906130c6565b115b15610ac2576040516318c8896960e11b815260040160405180910390fd5b5f5b603754811015610be9575f60378281548110610ae257610ae2613117565b5f9182526020808320909101546001600160a01b031680835260349091526040822060058101549193509190610b199084906122c8565b600383018190559050610b2b83611513565b6002830155600582018590558515610bde5760038201546001600160a01b0384165f9081526038602090815260408083208a84529091529020541115610b945760038201546001600160a01b0384165f9081526038602090815260408083208a84529091529020555b610b9e83876111a0565b6001600160a01b0384165f8181526039602090815260408083208b84528252808320949094556003860154928252603881528382208a8352905291909120555b505050600101610ac4565b506032546040516331a9108f60e11b81526004810185905233916001600160a01b031690636352211e90602401602060405180830381865afa158015610c31573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610c55919061312b565b6001600160a01b031614610c7b576040516282b42960e81b815260040160405180910390fd5b5f5f5f610c87866116e5565b92509250925082515f03610cae57604051630fec21fd60e21b815260040160405180910390fd5b5f5b8351811015610dc3575f848281518110610ccc57610ccc613117565b602002602001015190505f848381518110610ce957610ce9613117565b602002602001015190505f811115610db9576001600160a01b0382165f9081526035602052604090205460ff16610d335760405163dfde867160e01b815260040160405180910390fd5b6001600160a01b0382165f818152603460209081526040808320603983528184208e855283528184208490556003810154858552603884528285208f8652845282852055938352603a82528083208d84529091528120558451610db7908490339085908e908a908a908110610daa57610daa613117565b60200260200101516123c2565b505b5050600101610cb0565b50505050505061070060015f55565b6033546001600160a01b03163314610dfc576040516282b42960e81b815260040160405180910390fd5b6001600160a01b0381165f9081526035602052604090205460ff16610e345760405163dfde867160e01b815260040160405180910390fd5b6001600160a01b0381165f9081526034602052604090208054421015610e995760405162461bcd60e51b81526020600482015260156024820152741058dd1a5d99481c995dd85c991cc81c195c9a5bd9605a1b60448201526064015b60405180910390fd5b600481015415610edd5760405162461bcd60e51b815260206004820152600f60248201526e50656e64696e67207265776172647360881b6044820152606401610e90565b6001600160a01b038083165f90815260366020908152604080832054603254825163900cf0cf60e01b815292519195169263900cf0cf92600480820193918290030181865afa158015610f32573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610f5691906130c6565b905060015b818111611033576032546040516331a9108f60e11b8152600481018390526001600160a01b0390911690636352211e90602401602060405180830381865afa925050508015610fc7575060408051601f3d908101601f19168201909252610fc49181019061312b565b60015b15611021575f610fd787846111a0565b9050801561101e5760408051808201825282815260208082018881526001600160a01b038b165f908152603a83528481208882529092529290209051815590516001909101555b50505b8061102b81613146565b915050610f5b565b506001600160a01b0384165f908152603560205260409020805460ff1916905561105e826001613104565b6001600160a01b0385165f908152603660205260408120919091555b60375481101561116e57846001600160a01b0316603782815481106110a1576110a1613117565b5f918252602090912001546001600160a01b03160361116657603780546110ca906001906130f1565b815481106110da576110da613117565b5f91825260209091200154603780546001600160a01b03909216918390811061110557611105613117565b905f5260205f20015f6101000a8154816001600160a01b0302191690836001600160a01b0316021790555060378054806111415761114161319c565b5f8281526020902081015f1990810180546001600160a01b031916905501905561116e565b60010161107a565b507fbe0d2cc926911d1413d431090d31dd4a56de7770afb1245163f0e0ac7916db2184836040516106bf9291906131b0565b6001600160a01b038281165f9081526034602052604080822060325460028201549251636ed664a560e11b81526004810187905263ffffffff909316602484015292939092849291169063ddacc94a90604401602060405180830381865afa15801561120e573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061123291906131c9565b6001600160801b03169050805f0361124e575f92505050611396565b5f826002015461125d87611513565b11156112fa575f836002015461127288611513565b61127c91906130f1565b90505f670de0b6b3a7640000828660010154611298919061315e565b6112a29190613189565b90505f8560050154670de0b6b3a7640000836112be919061315e565b6112c89190613189565b9050801580156112d757505f83115b156112e0575060015b8086600301546112f09190613104565b9350505050611301565b5060038201545b6001600160a01b0386165f90815260386020908152604080832088845290915281205490818311611332575f61133c565b61133c82846130f1565b90505f670de0b6b3a7640000611352838761315e565b61135c9190613189565b6001600160a01b038a165f9081526039602090815260408083208c845290915290205490915061138d908290613104565b96505050505050505b92915050565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a008054600160401b810460ff1615906001600160401b03165f811580156113e05750825b90505f826001600160401b031660011480156113fb5750303b155b905081158015611409575080155b156114275760405163f92ee8a960e01b815260040160405180910390fd5b845467ffffffffffffffff19166001178555831561145157845460ff60401b1916600160401b1785555b6001600160a01b038716158061146e57506001600160a01b038616155b1561148c5760405163d92e233d60e01b815260040160405180910390fd5b61149461296a565b603280546001600160a01b03808a166001600160a01b0319928316179092556033805492891692909116919091179055831561150a57845460ff60401b19168555604051600181527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b50505050505050565b6001600160a01b0381165f90815260346020526040812054421061154e576001600160a01b0382165f90815260346020526040902054611396565b4292915050565b6033546001600160a01b0316331461157f576040516282b42960e81b815260040160405180910390fd5b6032815111156115a2576040516303451c2960e21b815260040160405180910390fd5b603754156115f25760405162461bcd60e51b815260206004820152601a60248201527f546f6b656e7320616c726561647920696e697469616c697a65640000000000006044820152606401610e90565b5f5b81518110156116ab575f611609826001613104565b90505b82518110156116a25782818151811061162757611627613117565b60200260200101516001600160a01b031683838151811061164a5761164a613117565b60200260200101516001600160a01b03160361169a5760405162461bcd60e51b815260206004820152600f60248201526e223ab83634b1b0ba32903a37b5b2b760891b6044820152606401610e90565b60010161160c565b506001016115f4565b505f5b81518110156116e1576116d98282815181106116cc576116cc613117565b602002602001015161204a565b6001016116ae565b5050565b6032546040516331a9108f60e11b815260048101839052606091829182915f916001600160a01b0390911690636352211e90602401602060405180830381865afa158015611735573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611759919061312b565b90506001600160a01b0381166117825760405163baf3f0f760e01b815260040160405180910390fd5b5f61178b611f79565b90508051600261179b919061315e565b6001600160401b038111156117b2576117b2612f0f565b6040519080825280602002602001820160405280156117db578160200160208202803683370190505b509450805160026117ec919061315e565b6001600160401b0381111561180357611803612f0f565b60405190808252806020026020018201604052801561182c578160200160208202803683370190505b5093508051600261183d919061315e565b6001600160401b0381111561185457611854612f0f565b60405190808252806020026020018201604052801561187d578160200160208202803683370190505b5092505f805b8251811015611a5c575f83828151811061189f5761189f613117565b602002602001015190505f6118b4828b6111a0565b9050801561196057818985815181106118cf576118cf613117565b60200260200101906001600160a01b031690816001600160a01b0316815250508088858151811061190257611902613117565b60200260200101818152505060345f836001600160a01b03166001600160a01b031681526020019081526020015f206006015487858151811061194757611947613117565b60209081029190910101528361195c81613146565b9450505b6001600160a01b0382165f908152603a602090815260408083208d84528252918290208251808401909352805480845260019091015491830191909152158015906119c757506001600160a01b0383165f9081526036602090815260409091205490820151105b15611a5157828a86815181106119df576119df613117565b60200260200101906001600160a01b031690816001600160a01b031681525050805f0151898681518110611a1557611a15613117565b6020026020010181815250508060200151888681518110611a3857611a38613117565b602090810291909101015284611a4d81613146565b9550505b505050600101611883565b5080865280855283525092949193509150565b60378181548110611a7e575f80fd5b5f918252602090912001546001600160a01b0316905081565b6033546001600160a01b03163314611ac1576040516282b42960e81b815260040160405180910390fd5b6001600160a01b0382165f9081526035602052604090205460ff16611af95760405163dfde867160e01b815260040160405180910390fd5b805f03611b195760405163baf3f0f760e01b815260040160405180910390fd5b6040516370a0823160e01b81525f906001600160a01b038416906370a0823190611b479030906004016130a0565b602060405180830381865afa158015611b62573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611b8691906130c6565b905081811015611ba957604051631e9acf1760e31b815260040160405180910390fd5b6001600160a01b0383165f9081526034602052604081206002810154909103611c02576001600160a01b0384165f908152603660205260408120805491611bef83613146565b9190505550611bfc611f00565b60058201555b60028101545f9015801590611c175750815442105b15611c2c578154611c299042906130f1565b90505b5f8115801590611c3f57505f8360010154115b15611c9b57611c4f825f19613189565b83600101541115611c7557611c6e8269d3c21bcecceda100000061315e565b9050611c9b565b670de0b6b3a7640000828460010154611c8e919061315e565b611c989190613189565b90505b60048301545f90611cac8388613104565b611cb69190613104565b90508069d3c21bcecceda100000086821115611cd0578691505b80821115611cdc578091505b5f600487018190558215611d7e575f62093a80611d01670de0b6b3a76400008661315e565b611d0b9190613189565b90505f611d22670de0b6b3a76400006103e861315e565b905080821115611d30578091505b81925069d3c21bcecceda1000000831115611d535769d3c21bcecceda100000092505b620f4240831015611d7757604051635cf4d02960e01b815260040160405180910390fd5b5050611d97565b604051635cf4d02960e01b815260040160405180910390fd5b600187018190554260028801819055611db49062093a8090613104565b87555f611dbf611f00565b9050670de0b6b3a76400008110611dd65780611de0565b670de0b6b3a76400005b60058901819055611df2908c906122c8565b60038901556006880154604080516001600160a01b038e168152602081018790528082018590526060810192909252517f0727302becd070529b3293f4ec8f553d9f6ae1773f638598db1205fbf89080839181900360800190a15050505050505050505050565b6033546001600160a01b03163314611e83576040516282b42960e81b815260040160405180910390fd5b6001600160a01b038116611eaa5760405163d92e233d60e01b815260040160405180910390fd5b603380546001600160a01b0319166001600160a01b0383161790556040517fc0ebb188f905d128bcd7e4282dd1f9cf24cd331b69071002e488349aca6a867b90611ef59083906130a0565b60405180910390a150565b6032546040805163268dc19960e01b815290515f926001600160a01b03169163268dc1999160048083019260209291908290030181865afa158015611f47573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611f6b91906131c9565b6001600160801b0316905090565b60606037805480602002602001604051908101604052809291908181526020018280548015611fcf57602002820191905f5260205f20905b81546001600160a01b03168152600190910190602001808311611fb1575b5050505050905090565b6040516001600160a01b03808516602483015283166044820152606481018290526120449085906323b872dd60e01b906084015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b03199093169290921790915261297c565b50505050565b6001600160a01b0381166120715760405163d92e233d60e01b815260040160405180910390fd5b6001600160a01b0381165f9081526035602052604090205460ff16156120aa5760405163630b374b60e01b815260040160405180910390fd5b6037805460018082019092557f42a7b7dd785cd69714a189dffb3fd7d7174edc9ece837694ce50f7078f7c31ae0180546001600160a01b0319166001600160a01b0384169081179091555f908152603560209081526040808320805460ff1916851790556036808352818420948555603483528184206005810194909455909152915460068201819055915190917f68e3e9397770d9dfa88c0953a34e1a70a05416b3895957f5b689787a920791c4916121659185916131b0565b60405180910390a15050565b6032546040805163900cf0cf60e01b815290515f926001600160a01b03169163900cf0cf9160048083019260209291908290030181865afa1580156121b8573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906121dc91906130c6565b905060015b818111612044576032546040516331a9108f60e11b8152600481018390526001600160a01b0390911690636352211e90602401602060405180830381865afa92505050801561224d575060408051601f3d908101601f1916820190925261224a9181019061312b565b60015b1561225f5761225d858386612a54565b505b8061226981613146565b9150506121e1565b60025f54036122c25760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610e90565b60025f55565b6001600160a01b0382165f90815260346020526040812082158061230457506001600160a01b0384165f9081526035602052604090205460ff16155b1561231457600301549050611396565b5f816002015461232386611513565b61232d91906130f1565b9050805f036123425750600301549050611396565b670de0b6b3a764000084101561235e57670de0b6b3a764000093505b5f81836001015461236f919061315e565b90505f85612385670de0b6b3a76400008461315e565b61238f9190613189565b90508015801561239e57505f83115b156123a7575060015b8084600301546123b79190613104565b979650505050505050565b821561295d5760325f9054906101000a90046001600160a01b03166001600160a01b0316630f45cc816040518163ffffffff1660e01b8152600401602060405180830381865afa158015612418573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061243c919061312b565b6001600160a01b0316856001600160a01b03160361275c576001600160801b0383111561249e5760405162461bcd60e51b815260206004820152601060248201526f416d6f756e7420746f6f206c6172676560801b6044820152606401610e90565b603254604051638b25e8c160e01b8152600481018490525f916001600160a01b031690638b25e8c190602401602060405180830381865afa1580156124e5573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061250991906131c9565b9050806001600160801b03165f036125585760405162461bcd60e51b815260206004820152601260248201527124b73b30b634b21036bab63a34b83634b2b960711b6044820152606401610e90565b5f606461256683605f6131ef565b6125709190613218565b60325460405163095ea7b360e01b81529192506001600160a01b03808a169263095ea7b3926125a592169089906004016131b0565b6020604051808303815f875af11580156125c1573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906125e59190613246565b5060325460405163beb8310960e01b8152600481018690526001600160801b038088166024830152426044830152831660648201526001600160a01b039091169063beb83109906084015f604051808303815f87803b158015612646575f5ffd5b505af1925050508015612657575060015b61270f5760325460405163095ea7b360e01b81526001600160a01b038981169263095ea7b39261268f92909116905f906004016131b0565b6020604051808303815f875af11580156126ab573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906126cf9190613246565b5060405162461bcd60e51b8152602060048201526014602482015273105d5d1bcb58dbdb5c1bdd5b990819985a5b195960621b6044820152606401610e90565b60408051868152602081018590526001600160a01b0389169186917f85beda9bf1ef844bb2472cc053c13557032d6e187a546b4c640e86dcd8201e39910160405180910390a3505061295d565b6040516370a0823160e01b81525f906001600160a01b038716906370a082319061278a9030906004016130a0565b602060405180830381865afa1580156127a5573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906127c991906130c6565b9050838110156127ec57604051631e9acf1760e31b815260040160405180910390fd5b6040516370a0823160e01b81525f906001600160a01b038816906370a082319061281a9089906004016130a0565b602060405180830381865afa158015612835573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061285991906130c6565b905061286f6001600160a01b0388168787612c67565b6040516370a0823160e01b81525f906001600160a01b038916906370a082319061289d908a906004016130a0565b602060405180830381865afa1580156128b8573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906128dc91906130c6565b90508181116128fe576040516312171d8360e31b815260040160405180910390fd5b5f61290983836130f1565b9050886001600160a01b0316867f85beda9bf1ef844bb2472cc053c13557032d6e187a546b4c640e86dcd8201e398388604051612950929190918252602082015260400190565b60405180910390a3505050505b5050505050565b60015f55565b612972612c86565b61297a612ccf565b565b5f6129d0826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316612cd79092919063ffffffff16565b905080515f14806129f05750808060200190518101906129f09190613246565b612a4f5760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608401610e90565b505050565b60038101546001600160a01b0384165f9081526038602090815260408083208684529091529020548181111561295d576001600160a01b0385165f90815260386020908152604080832087845290915281208390556002840154612abb90610e1090613189565b612ac790610e1061315e565b603254604051636ed664a560e11b81526004810188905263ffffffff831660248201529192505f916001600160a01b039091169063ddacc94a90604401602060405180830381865afa158015612b1f573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612b4391906131c9565b6001600160801b03169050801561150a576001600160a01b0387165f9081526038602090815260408083208984529091528120548511612b83575f612bb0565b6001600160a01b0388165f9081526038602090815260408083208a8452909152902054612bb090866130f1565b90505f670de0b6b3a7640000612bc6838561315e565b612bd09190613189565b6001600160a01b038a165f9081526039602090815260408083208c8452909152812080549293508392909190612c07908490613104565b9091555050604080518981526001600160a01b038b166020820152908101829052606081018490527fdefe0aa5579373218fc5e22377d95459e6b9bbc450b520af03af84d0a9f2150a9060800160405180910390a1505050505050505050565b612a4f8363a9059cbb60e01b848460405160240161200d9291906131b0565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a0054600160401b900460ff1661297a57604051631afcd79f60e31b815260040160405180910390fd5b612964612c86565b6060612ce584845f85612ced565b949350505050565b606082471015612d4e5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b6064820152608401610e90565b5f5f866001600160a01b03168587604051612d699190613265565b5f6040518083038185875af1925050503d805f8114612da3576040519150601f19603f3d011682016040523d82523d5f602084013e612da8565b606091505b50915091506123b78783838760608315612e225782515f03612e1b576001600160a01b0385163b612e1b5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610e90565b5081612ce5565b612ce58383815115612e375781518083602001fd5b8060405162461bcd60e51b8152600401610e90919061327b565b6001600160a01b0381168114610700575f5ffd5b8035612e7081612e51565b919050565b5f5f60408385031215612e86575f5ffd5b8235612e9181612e51565b946020939093013593505050565b5f60208284031215612eaf575f5ffd5b8135612eba81612e51565b9392505050565b5f60208284031215612ed1575f5ffd5b5035919050565b5f5f60408385031215612ee9575f5ffd5b8235612ef481612e51565b91506020830135612f0481612e51565b809150509250929050565b634e487b7160e01b5f52604160045260245ffd5b5f60208284031215612f33575f5ffd5b81356001600160401b03811115612f48575f5ffd5b8201601f81018413612f58575f5ffd5b80356001600160401b03811115612f7157612f71612f0f565b8060051b604051601f19603f83011681018181106001600160401b0382111715612f9d57612f9d612f0f565b604052918252602081840181019290810187841115612fba575f5ffd5b6020850194505b83851015612fe057612fd285612e65565b815260209485019401612fc1565b509695505050505050565b5f8151808452602084019350602083015f5b828110156130245781516001600160a01b0316865260209586019590910190600101612ffd565b5093949350505050565b5f8151808452602084019350602083015f5b82811015613024578151865260209586019590910190600101613040565b606081525f6130706060830186612feb565b8281036020840152613082818661302e565b90508281036040840152613096818561302e565b9695505050505050565b6001600160a01b0391909116815260200190565b602081525f612eba6020830184612feb565b5f602082840312156130d6575f5ffd5b5051919050565b634e487b7160e01b5f52601160045260245ffd5b81810381811115611396576113966130dd565b80820180821115611396576113966130dd565b634e487b7160e01b5f52603260045260245ffd5b5f6020828403121561313b575f5ffd5b8151612eba81612e51565b5f60018201613157576131576130dd565b5060010190565b8082028115828204841417611396576113966130dd565b634e487b7160e01b5f52601260045260245ffd5b5f8261319757613197613175565b500490565b634e487b7160e01b5f52603160045260245ffd5b6001600160a01b03929092168252602082015260400190565b5f602082840312156131d9575f5ffd5b81516001600160801b0381168114612eba575f5ffd5b6001600160801b038181168382160290811690818114613211576132116130dd565b5092915050565b5f6001600160801b0383168061323057613230613175565b6001600160801b03929092169190910492915050565b5f60208284031215613256575f5ffd5b81518015158114612eba575f5ffd5b5f82518060208501845e5f920191825250919050565b602081525f82518060208401528060208501604085015e5f604082850101526040601f19601f8301168401019150509291505056fea2646970667358221220e905059528afa3996c822be593cfea08d2ce664fb1775c978d38418496ecc25d64736f6c634300081b0033
Deployed Bytecode
0x608060405234801561000f575f5ffd5b5060043610610195575f3560e01c80637abe18d2116100e0578063b2be1ef41161008f578063b2be1ef4146103fe578063b5fd73f814610408578063b66503cf1461043a578063b933ceac1461044d578063bc30a61814610477578063bfe109281461048a578063c4e41b221461049d578063c4f59f9b146104a5575f5ffd5b80637abe18d2146103625780637b167dfa1461036a5780637bb7bed11461038c57806386bc443e146103ac57806392815606146103cb578063aaf5eb68146103de578063ac4869f6146103ed575f5ffd5b80633d509c97116101475780633d509c97146102525780633e491d4714610265578063485cc9551461027857806348e5d9f81461028b5780635d0cde971461030a578063638634ee1461031257806364f78188146103255780636bc9b56114610338575f5ffd5b806304d0c2c5146101995780630a2976d5146101ae5780631be05289146101f95780631c03e6cc146102115780631e9b3a92146102245780632f2e36681461022c578063379607f51461023f575b5f5ffd5b6101ac6101a7366004612e75565b6104ba565b005b6101df6101bc366004612e75565b603a60209081525f92835260408084209091529082529020805460019091015482565b604080519283526020830191909152015b60405180910390f35b61020362093a8081565b6040519081526020016101f0565b6101ac61021f366004612e9f565b6106cd565b610203610703565b6101ac61023a366004612e9f565b6108e3565b6101ac61024d366004612ec1565b610a1a565b6101ac610260366004612e9f565b610dd2565b610203610273366004612e75565b6111a0565b6101ac610286366004612ed8565b61139c565b6102d5610299366004612e9f565b60346020525f90815260409020805460018201546002830154600384015460048501546005860154600690960154949593949293919290919087565b604080519788526020880196909652948601939093526060850191909152608084015260a083015260c082015260e0016101f0565b610203603281565b610203610320366004612e9f565b611513565b6101ac610333366004612f23565b611555565b610203610346366004612e75565b603860209081525f928352604080842090915290825290205481565b603754610203565b61037d610378366004612ec1565b6116e5565b6040516101f09392919061305e565b61039f61039a366004612ec1565b611a6f565b6040516101f091906130a0565b6102036103ba366004612e9f565b60366020525f908152604090205481565b60325461039f906001600160a01b031681565b610203670de0b6b3a764000081565b61020369d3c21bcecceda100000081565b610203620f424081565b61042a610416366004612e9f565b60356020525f908152604090205460ff1681565b60405190151581526020016101f0565b6101ac610448366004612e75565b611a97565b61020361045b366004612e75565b603960209081525f928352604080842090915290825290205481565b6101ac610485366004612e9f565b611e59565b60335461039f906001600160a01b031681565b610203611f00565b6104ad611f79565b6040516101f091906130b4565b6033546001600160a01b031633146104e4576040516282b42960e81b815260040160405180910390fd5b6001600160a01b0382165f9081526035602052604090205460ff1661051c5760405163dfde867160e01b815260040160405180910390fd5b805f0361053c5760405163baf3f0f760e01b815260040160405180910390fd5b6040516370a0823160e01b81525f906001600160a01b038416906370a082319061056a9030906004016130a0565b602060405180830381865afa158015610585573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906105a991906130c6565b90506105c06001600160a01b038416333085611fd9565b5f81846001600160a01b03166370a08231306040518263ffffffff1660e01b81526004016105ee91906130a0565b602060405180830381865afa158015610609573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061062d91906130c6565b61063791906130f1565b6001600160a01b0385165f90815260346020526040812060040180549293508392909190610666908490613104565b90915550506001600160a01b0384165f81815260346020908152604091829020600601548251938452908301849052908201527f09a4f557033a56cbe70db5ccef9534cbb73cbfe724512852e36e86e36d7a93b4906060015b60405180910390a150505050565b6033546001600160a01b031633146106f7576040516282b42960e81b815260040160405180910390fd5b6107008161204a565b50565b5f5f61070d611f79565b90505f5b81518110156108de575f82828151811061072d5761072d613117565b602002602001015190505f60325f9054906101000a90046001600160a01b03166001600160a01b031663900cf0cf6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610788573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906107ac91906130c6565b905060015b8181116108d3576032546040516331a9108f60e11b8152600481018390526001600160a01b0390911690636352211e90602401602060405180830381865afa92505050801561081d575060408051601f3d908101601f1916820190925261081a9181019061312b565b60015b156108c1575f61082d85846111a0565b905080156108425761083f8189613104565b97505b6001600160a01b0385165f908152603a602090815260408083208684528252918290208251808401909352805480845260019091015491830191909152158015906108a957506001600160a01b0386165f9081526036602090815260409091205490820151105b156108bd5780516108ba908a613104565b98505b5050505b806108cb81613146565b9150506107b1565b505050600101610711565b505090565b6033546001600160a01b0316331461090d576040516282b42960e81b815260040160405180910390fd5b6001600160a01b0381165f9081526034602052604090206716f2322656768fb06001820155426002820181905582919061094a9062093a80613104565b81555f61095b6367e73858426130f1565b90505f8260050154828460010154610973919061315e565b61097d9190613189565b60038401819055600284015490915061099690426130f1565b91505f670de0b6b3a76400008385600101546109b2919061315e565b6109bc9190613189565b6005850154909150670de0b6b3a76400008110156109df5750670de0b6b3a76400005b5f816109f3670de0b6b3a76400008561315e565b6109fd9190613189565b600387018190559050610a108787612171565b5050505050505050565b610a22612271565b805f610a2c611f00565b905080158015610aa457506032546040805163900cf0cf60e01b815290515f926001600160a01b03169163900cf0cf9160048083019260209291908290030181865afa158015610a7e573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610aa291906130c6565b115b15610ac2576040516318c8896960e11b815260040160405180910390fd5b5f5b603754811015610be9575f60378281548110610ae257610ae2613117565b5f9182526020808320909101546001600160a01b031680835260349091526040822060058101549193509190610b199084906122c8565b600383018190559050610b2b83611513565b6002830155600582018590558515610bde5760038201546001600160a01b0384165f9081526038602090815260408083208a84529091529020541115610b945760038201546001600160a01b0384165f9081526038602090815260408083208a84529091529020555b610b9e83876111a0565b6001600160a01b0384165f8181526039602090815260408083208b84528252808320949094556003860154928252603881528382208a8352905291909120555b505050600101610ac4565b506032546040516331a9108f60e11b81526004810185905233916001600160a01b031690636352211e90602401602060405180830381865afa158015610c31573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610c55919061312b565b6001600160a01b031614610c7b576040516282b42960e81b815260040160405180910390fd5b5f5f5f610c87866116e5565b92509250925082515f03610cae57604051630fec21fd60e21b815260040160405180910390fd5b5f5b8351811015610dc3575f848281518110610ccc57610ccc613117565b602002602001015190505f848381518110610ce957610ce9613117565b602002602001015190505f811115610db9576001600160a01b0382165f9081526035602052604090205460ff16610d335760405163dfde867160e01b815260040160405180910390fd5b6001600160a01b0382165f818152603460209081526040808320603983528184208e855283528184208490556003810154858552603884528285208f8652845282852055938352603a82528083208d84529091528120558451610db7908490339085908e908a908a908110610daa57610daa613117565b60200260200101516123c2565b505b5050600101610cb0565b50505050505061070060015f55565b6033546001600160a01b03163314610dfc576040516282b42960e81b815260040160405180910390fd5b6001600160a01b0381165f9081526035602052604090205460ff16610e345760405163dfde867160e01b815260040160405180910390fd5b6001600160a01b0381165f9081526034602052604090208054421015610e995760405162461bcd60e51b81526020600482015260156024820152741058dd1a5d99481c995dd85c991cc81c195c9a5bd9605a1b60448201526064015b60405180910390fd5b600481015415610edd5760405162461bcd60e51b815260206004820152600f60248201526e50656e64696e67207265776172647360881b6044820152606401610e90565b6001600160a01b038083165f90815260366020908152604080832054603254825163900cf0cf60e01b815292519195169263900cf0cf92600480820193918290030181865afa158015610f32573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610f5691906130c6565b905060015b818111611033576032546040516331a9108f60e11b8152600481018390526001600160a01b0390911690636352211e90602401602060405180830381865afa925050508015610fc7575060408051601f3d908101601f19168201909252610fc49181019061312b565b60015b15611021575f610fd787846111a0565b9050801561101e5760408051808201825282815260208082018881526001600160a01b038b165f908152603a83528481208882529092529290209051815590516001909101555b50505b8061102b81613146565b915050610f5b565b506001600160a01b0384165f908152603560205260409020805460ff1916905561105e826001613104565b6001600160a01b0385165f908152603660205260408120919091555b60375481101561116e57846001600160a01b0316603782815481106110a1576110a1613117565b5f918252602090912001546001600160a01b03160361116657603780546110ca906001906130f1565b815481106110da576110da613117565b5f91825260209091200154603780546001600160a01b03909216918390811061110557611105613117565b905f5260205f20015f6101000a8154816001600160a01b0302191690836001600160a01b0316021790555060378054806111415761114161319c565b5f8281526020902081015f1990810180546001600160a01b031916905501905561116e565b60010161107a565b507fbe0d2cc926911d1413d431090d31dd4a56de7770afb1245163f0e0ac7916db2184836040516106bf9291906131b0565b6001600160a01b038281165f9081526034602052604080822060325460028201549251636ed664a560e11b81526004810187905263ffffffff909316602484015292939092849291169063ddacc94a90604401602060405180830381865afa15801561120e573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061123291906131c9565b6001600160801b03169050805f0361124e575f92505050611396565b5f826002015461125d87611513565b11156112fa575f836002015461127288611513565b61127c91906130f1565b90505f670de0b6b3a7640000828660010154611298919061315e565b6112a29190613189565b90505f8560050154670de0b6b3a7640000836112be919061315e565b6112c89190613189565b9050801580156112d757505f83115b156112e0575060015b8086600301546112f09190613104565b9350505050611301565b5060038201545b6001600160a01b0386165f90815260386020908152604080832088845290915281205490818311611332575f61133c565b61133c82846130f1565b90505f670de0b6b3a7640000611352838761315e565b61135c9190613189565b6001600160a01b038a165f9081526039602090815260408083208c845290915290205490915061138d908290613104565b96505050505050505b92915050565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a008054600160401b810460ff1615906001600160401b03165f811580156113e05750825b90505f826001600160401b031660011480156113fb5750303b155b905081158015611409575080155b156114275760405163f92ee8a960e01b815260040160405180910390fd5b845467ffffffffffffffff19166001178555831561145157845460ff60401b1916600160401b1785555b6001600160a01b038716158061146e57506001600160a01b038616155b1561148c5760405163d92e233d60e01b815260040160405180910390fd5b61149461296a565b603280546001600160a01b03808a166001600160a01b0319928316179092556033805492891692909116919091179055831561150a57845460ff60401b19168555604051600181527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b50505050505050565b6001600160a01b0381165f90815260346020526040812054421061154e576001600160a01b0382165f90815260346020526040902054611396565b4292915050565b6033546001600160a01b0316331461157f576040516282b42960e81b815260040160405180910390fd5b6032815111156115a2576040516303451c2960e21b815260040160405180910390fd5b603754156115f25760405162461bcd60e51b815260206004820152601a60248201527f546f6b656e7320616c726561647920696e697469616c697a65640000000000006044820152606401610e90565b5f5b81518110156116ab575f611609826001613104565b90505b82518110156116a25782818151811061162757611627613117565b60200260200101516001600160a01b031683838151811061164a5761164a613117565b60200260200101516001600160a01b03160361169a5760405162461bcd60e51b815260206004820152600f60248201526e223ab83634b1b0ba32903a37b5b2b760891b6044820152606401610e90565b60010161160c565b506001016115f4565b505f5b81518110156116e1576116d98282815181106116cc576116cc613117565b602002602001015161204a565b6001016116ae565b5050565b6032546040516331a9108f60e11b815260048101839052606091829182915f916001600160a01b0390911690636352211e90602401602060405180830381865afa158015611735573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611759919061312b565b90506001600160a01b0381166117825760405163baf3f0f760e01b815260040160405180910390fd5b5f61178b611f79565b90508051600261179b919061315e565b6001600160401b038111156117b2576117b2612f0f565b6040519080825280602002602001820160405280156117db578160200160208202803683370190505b509450805160026117ec919061315e565b6001600160401b0381111561180357611803612f0f565b60405190808252806020026020018201604052801561182c578160200160208202803683370190505b5093508051600261183d919061315e565b6001600160401b0381111561185457611854612f0f565b60405190808252806020026020018201604052801561187d578160200160208202803683370190505b5092505f805b8251811015611a5c575f83828151811061189f5761189f613117565b602002602001015190505f6118b4828b6111a0565b9050801561196057818985815181106118cf576118cf613117565b60200260200101906001600160a01b031690816001600160a01b0316815250508088858151811061190257611902613117565b60200260200101818152505060345f836001600160a01b03166001600160a01b031681526020019081526020015f206006015487858151811061194757611947613117565b60209081029190910101528361195c81613146565b9450505b6001600160a01b0382165f908152603a602090815260408083208d84528252918290208251808401909352805480845260019091015491830191909152158015906119c757506001600160a01b0383165f9081526036602090815260409091205490820151105b15611a5157828a86815181106119df576119df613117565b60200260200101906001600160a01b031690816001600160a01b031681525050805f0151898681518110611a1557611a15613117565b6020026020010181815250508060200151888681518110611a3857611a38613117565b602090810291909101015284611a4d81613146565b9550505b505050600101611883565b5080865280855283525092949193509150565b60378181548110611a7e575f80fd5b5f918252602090912001546001600160a01b0316905081565b6033546001600160a01b03163314611ac1576040516282b42960e81b815260040160405180910390fd5b6001600160a01b0382165f9081526035602052604090205460ff16611af95760405163dfde867160e01b815260040160405180910390fd5b805f03611b195760405163baf3f0f760e01b815260040160405180910390fd5b6040516370a0823160e01b81525f906001600160a01b038416906370a0823190611b479030906004016130a0565b602060405180830381865afa158015611b62573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611b8691906130c6565b905081811015611ba957604051631e9acf1760e31b815260040160405180910390fd5b6001600160a01b0383165f9081526034602052604081206002810154909103611c02576001600160a01b0384165f908152603660205260408120805491611bef83613146565b9190505550611bfc611f00565b60058201555b60028101545f9015801590611c175750815442105b15611c2c578154611c299042906130f1565b90505b5f8115801590611c3f57505f8360010154115b15611c9b57611c4f825f19613189565b83600101541115611c7557611c6e8269d3c21bcecceda100000061315e565b9050611c9b565b670de0b6b3a7640000828460010154611c8e919061315e565b611c989190613189565b90505b60048301545f90611cac8388613104565b611cb69190613104565b90508069d3c21bcecceda100000086821115611cd0578691505b80821115611cdc578091505b5f600487018190558215611d7e575f62093a80611d01670de0b6b3a76400008661315e565b611d0b9190613189565b90505f611d22670de0b6b3a76400006103e861315e565b905080821115611d30578091505b81925069d3c21bcecceda1000000831115611d535769d3c21bcecceda100000092505b620f4240831015611d7757604051635cf4d02960e01b815260040160405180910390fd5b5050611d97565b604051635cf4d02960e01b815260040160405180910390fd5b600187018190554260028801819055611db49062093a8090613104565b87555f611dbf611f00565b9050670de0b6b3a76400008110611dd65780611de0565b670de0b6b3a76400005b60058901819055611df2908c906122c8565b60038901556006880154604080516001600160a01b038e168152602081018790528082018590526060810192909252517f0727302becd070529b3293f4ec8f553d9f6ae1773f638598db1205fbf89080839181900360800190a15050505050505050505050565b6033546001600160a01b03163314611e83576040516282b42960e81b815260040160405180910390fd5b6001600160a01b038116611eaa5760405163d92e233d60e01b815260040160405180910390fd5b603380546001600160a01b0319166001600160a01b0383161790556040517fc0ebb188f905d128bcd7e4282dd1f9cf24cd331b69071002e488349aca6a867b90611ef59083906130a0565b60405180910390a150565b6032546040805163268dc19960e01b815290515f926001600160a01b03169163268dc1999160048083019260209291908290030181865afa158015611f47573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611f6b91906131c9565b6001600160801b0316905090565b60606037805480602002602001604051908101604052809291908181526020018280548015611fcf57602002820191905f5260205f20905b81546001600160a01b03168152600190910190602001808311611fb1575b5050505050905090565b6040516001600160a01b03808516602483015283166044820152606481018290526120449085906323b872dd60e01b906084015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b03199093169290921790915261297c565b50505050565b6001600160a01b0381166120715760405163d92e233d60e01b815260040160405180910390fd5b6001600160a01b0381165f9081526035602052604090205460ff16156120aa5760405163630b374b60e01b815260040160405180910390fd5b6037805460018082019092557f42a7b7dd785cd69714a189dffb3fd7d7174edc9ece837694ce50f7078f7c31ae0180546001600160a01b0319166001600160a01b0384169081179091555f908152603560209081526040808320805460ff1916851790556036808352818420948555603483528184206005810194909455909152915460068201819055915190917f68e3e9397770d9dfa88c0953a34e1a70a05416b3895957f5b689787a920791c4916121659185916131b0565b60405180910390a15050565b6032546040805163900cf0cf60e01b815290515f926001600160a01b03169163900cf0cf9160048083019260209291908290030181865afa1580156121b8573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906121dc91906130c6565b905060015b818111612044576032546040516331a9108f60e11b8152600481018390526001600160a01b0390911690636352211e90602401602060405180830381865afa92505050801561224d575060408051601f3d908101601f1916820190925261224a9181019061312b565b60015b1561225f5761225d858386612a54565b505b8061226981613146565b9150506121e1565b60025f54036122c25760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610e90565b60025f55565b6001600160a01b0382165f90815260346020526040812082158061230457506001600160a01b0384165f9081526035602052604090205460ff16155b1561231457600301549050611396565b5f816002015461232386611513565b61232d91906130f1565b9050805f036123425750600301549050611396565b670de0b6b3a764000084101561235e57670de0b6b3a764000093505b5f81836001015461236f919061315e565b90505f85612385670de0b6b3a76400008461315e565b61238f9190613189565b90508015801561239e57505f83115b156123a7575060015b8084600301546123b79190613104565b979650505050505050565b821561295d5760325f9054906101000a90046001600160a01b03166001600160a01b0316630f45cc816040518163ffffffff1660e01b8152600401602060405180830381865afa158015612418573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061243c919061312b565b6001600160a01b0316856001600160a01b03160361275c576001600160801b0383111561249e5760405162461bcd60e51b815260206004820152601060248201526f416d6f756e7420746f6f206c6172676560801b6044820152606401610e90565b603254604051638b25e8c160e01b8152600481018490525f916001600160a01b031690638b25e8c190602401602060405180830381865afa1580156124e5573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061250991906131c9565b9050806001600160801b03165f036125585760405162461bcd60e51b815260206004820152601260248201527124b73b30b634b21036bab63a34b83634b2b960711b6044820152606401610e90565b5f606461256683605f6131ef565b6125709190613218565b60325460405163095ea7b360e01b81529192506001600160a01b03808a169263095ea7b3926125a592169089906004016131b0565b6020604051808303815f875af11580156125c1573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906125e59190613246565b5060325460405163beb8310960e01b8152600481018690526001600160801b038088166024830152426044830152831660648201526001600160a01b039091169063beb83109906084015f604051808303815f87803b158015612646575f5ffd5b505af1925050508015612657575060015b61270f5760325460405163095ea7b360e01b81526001600160a01b038981169263095ea7b39261268f92909116905f906004016131b0565b6020604051808303815f875af11580156126ab573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906126cf9190613246565b5060405162461bcd60e51b8152602060048201526014602482015273105d5d1bcb58dbdb5c1bdd5b990819985a5b195960621b6044820152606401610e90565b60408051868152602081018590526001600160a01b0389169186917f85beda9bf1ef844bb2472cc053c13557032d6e187a546b4c640e86dcd8201e39910160405180910390a3505061295d565b6040516370a0823160e01b81525f906001600160a01b038716906370a082319061278a9030906004016130a0565b602060405180830381865afa1580156127a5573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906127c991906130c6565b9050838110156127ec57604051631e9acf1760e31b815260040160405180910390fd5b6040516370a0823160e01b81525f906001600160a01b038816906370a082319061281a9089906004016130a0565b602060405180830381865afa158015612835573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061285991906130c6565b905061286f6001600160a01b0388168787612c67565b6040516370a0823160e01b81525f906001600160a01b038916906370a082319061289d908a906004016130a0565b602060405180830381865afa1580156128b8573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906128dc91906130c6565b90508181116128fe576040516312171d8360e31b815260040160405180910390fd5b5f61290983836130f1565b9050886001600160a01b0316867f85beda9bf1ef844bb2472cc053c13557032d6e187a546b4c640e86dcd8201e398388604051612950929190918252602082015260400190565b60405180910390a3505050505b5050505050565b60015f55565b612972612c86565b61297a612ccf565b565b5f6129d0826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316612cd79092919063ffffffff16565b905080515f14806129f05750808060200190518101906129f09190613246565b612a4f5760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608401610e90565b505050565b60038101546001600160a01b0384165f9081526038602090815260408083208684529091529020548181111561295d576001600160a01b0385165f90815260386020908152604080832087845290915281208390556002840154612abb90610e1090613189565b612ac790610e1061315e565b603254604051636ed664a560e11b81526004810188905263ffffffff831660248201529192505f916001600160a01b039091169063ddacc94a90604401602060405180830381865afa158015612b1f573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612b4391906131c9565b6001600160801b03169050801561150a576001600160a01b0387165f9081526038602090815260408083208984529091528120548511612b83575f612bb0565b6001600160a01b0388165f9081526038602090815260408083208a8452909152902054612bb090866130f1565b90505f670de0b6b3a7640000612bc6838561315e565b612bd09190613189565b6001600160a01b038a165f9081526039602090815260408083208c8452909152812080549293508392909190612c07908490613104565b9091555050604080518981526001600160a01b038b166020820152908101829052606081018490527fdefe0aa5579373218fc5e22377d95459e6b9bbc450b520af03af84d0a9f2150a9060800160405180910390a1505050505050505050565b612a4f8363a9059cbb60e01b848460405160240161200d9291906131b0565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a0054600160401b900460ff1661297a57604051631afcd79f60e31b815260040160405180910390fd5b612964612c86565b6060612ce584845f85612ced565b949350505050565b606082471015612d4e5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b6064820152608401610e90565b5f5f866001600160a01b03168587604051612d699190613265565b5f6040518083038185875af1925050503d805f8114612da3576040519150601f19603f3d011682016040523d82523d5f602084013e612da8565b606091505b50915091506123b78783838760608315612e225782515f03612e1b576001600160a01b0385163b612e1b5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610e90565b5081612ce5565b612ce58383815115612e375781518083602001fd5b8060405162461bcd60e51b8152600401610e90919061327b565b6001600160a01b0381168114610700575f5ffd5b8035612e7081612e51565b919050565b5f5f60408385031215612e86575f5ffd5b8235612e9181612e51565b946020939093013593505050565b5f60208284031215612eaf575f5ffd5b8135612eba81612e51565b9392505050565b5f60208284031215612ed1575f5ffd5b5035919050565b5f5f60408385031215612ee9575f5ffd5b8235612ef481612e51565b91506020830135612f0481612e51565b809150509250929050565b634e487b7160e01b5f52604160045260245ffd5b5f60208284031215612f33575f5ffd5b81356001600160401b03811115612f48575f5ffd5b8201601f81018413612f58575f5ffd5b80356001600160401b03811115612f7157612f71612f0f565b8060051b604051601f19603f83011681018181106001600160401b0382111715612f9d57612f9d612f0f565b604052918252602081840181019290810187841115612fba575f5ffd5b6020850194505b83851015612fe057612fd285612e65565b815260209485019401612fc1565b509695505050505050565b5f8151808452602084019350602083015f5b828110156130245781516001600160a01b0316865260209586019590910190600101612ffd565b5093949350505050565b5f8151808452602084019350602083015f5b82811015613024578151865260209586019590910190600101613040565b606081525f6130706060830186612feb565b8281036020840152613082818661302e565b90508281036040840152613096818561302e565b9695505050505050565b6001600160a01b0391909116815260200190565b602081525f612eba6020830184612feb565b5f602082840312156130d6575f5ffd5b5051919050565b634e487b7160e01b5f52601160045260245ffd5b81810381811115611396576113966130dd565b80820180821115611396576113966130dd565b634e487b7160e01b5f52603260045260245ffd5b5f6020828403121561313b575f5ffd5b8151612eba81612e51565b5f60018201613157576131576130dd565b5060010190565b8082028115828204841417611396576113966130dd565b634e487b7160e01b5f52601260045260245ffd5b5f8261319757613197613175565b500490565b634e487b7160e01b5f52603160045260245ffd5b6001600160a01b03929092168252602082015260400190565b5f602082840312156131d9575f5ffd5b81516001600160801b0381168114612eba575f5ffd5b6001600160801b038181168382160290811690818114613211576132116130dd565b5092915050565b5f6001600160801b0383168061323057613230613175565b6001600160801b03929092169190910492915050565b5f60208284031215613256575f5ffd5b81518015158114612eba575f5ffd5b5f82518060208501845e5f920191825250919050565b602081525f82518060208401528060208501604085015e5f604082850101526040601f19601f8301168401019150509291505056fea2646970667358221220e905059528afa3996c822be593cfea08d2ce664fb1775c978d38418496ecc25d64736f6c634300081b0033
Deployed Bytecode Sourcemap
37202:25646:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;46145:684;;;;;;:::i;:::-;;:::i;:::-;;38110:81;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;835:25:1;;;891:2;876:18;;869:34;;;;808:18;38110:81:0;;;;;;;;38210:41;;38245:6;38210:41;;;;;1060:25:1;;;1048:2;1033:18;38210:41:0;914:177:1;40853:107:0;;;;;;:::i;:::-;;:::i;57743:1306::-;;;:::i;59315:1577::-;;;;;;:::i;:::-;;:::i;52534:1129::-;;;;;;:::i;:::-;;:::i;51031:1495::-;;;;;;:::i;:::-;;:::i;44326:1809::-;;;;;;:::i;:::-;;:::i;39622:324::-;;;;;;:::i;:::-;;:::i;37757:44::-;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2287:25:1;;;2343:2;2328:18;;2321:34;;;;2371:18;;;2364:34;;;;2429:2;2414:18;;2407:34;;;;2472:3;2457:19;;2450:35;2516:3;2501:19;;2494:35;2560:3;2545:19;;2538:35;2274:3;2259:19;37757:44:0;1972:607:1;38404:46:0;;38448:2;38404:46;;42711:245;;;;;;:::i;:::-;;:::i;39954:641::-;;;;;;:::i;:::-;;:::i;37957:77::-;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;57458:109;57540:12;:19;57458:109;;55608:1726;;;;;;:::i;:::-;;:::i;:::-;;;;;;;;;:::i;37915:29::-;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;37860:48::-;;;;;;:::i;:::-;;;;;;;;;;;;;;37692:19;;;;;-1:-1:-1;;;;;37692:19:0;;;38357:40;;38393:4;38357:40;;38307:43;;38346:4;38307:43;;38258:42;;38297:3;38258:42;;37808:45;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;5994:14:1;;5987:22;5969:41;;5957:2;5942:18;37808:45:0;5829:187:1;46840:4183:0;;;;;;:::i;:::-;;:::i;38041:62::-;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;40603:242;;;;;;:::i;:::-;;:::i;37718:26::-;;;;;-1:-1:-1;;;;;37718:26:0;;;41489:109;;;:::i;57342:104::-;;;:::i;:::-;;;;;;;:::i;46145:684::-;39491:11;;-1:-1:-1;;;;;39491:11:0;39477:10;:25;39473:52;;39511:14;;-1:-1:-1;;;39511:14:0;;;;;;;;;;;39473:52;-1:-1:-1;;;;;46250:28:0;::::1;;::::0;;;:13:::1;:28;::::0;;;;;::::1;;46245:62;;46287:20;;-1:-1:-1::0;;;46287:20:0::1;;;;;;;;;;;46245:62;46322:6;46332:1;46322:11:::0;46318:38:::1;;46342:14;;-1:-1:-1::0;;;46342:14:0::1;;;;;;;;;;;46318:38;46398:57;::::0;-1:-1:-1;;;46398:57:0;;46377:18:::1;::::0;-1:-1:-1;;;;;46398:42:0;::::1;::::0;::::1;::::0;:57:::1;::::0;46449:4:::1;::::0;46398:57:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;46377:78:::0;-1:-1:-1;46466:84:0::1;-1:-1:-1::0;;;;;46466:49:0;::::1;46516:10;46536:4;46543:6:::0;46466:49:::1;:84::i;:::-;46561:16;46640:10;46598:13;-1:-1:-1::0;;;;;46580:42:0::1;;46631:4;46580:57;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:70;;;;:::i;:::-;-1:-1:-1::0;;;;;46671:25:0;::::1;;::::0;;;:10:::1;:25;::::0;;;;:39:::1;;:51:::0;;46561:89;;-1:-1:-1;46561:89:0;;46671:39;;:25;:51:::1;::::0;46561:89;;46671:51:::1;:::i;:::-;::::0;;;-1:-1:-1;;;;;;;46786:25:0;::::1;;::::0;;;:10:::1;:25;::::0;;;;;;;;:34:::1;;::::0;46748:73;;7073:51:1;;;7140:18;;;7133:34;;;7183:18;;;7176:34;46748:73:0::1;::::0;7061:2:1;7046:18;46748:73:0::1;;;;;;;;46234:595;;46145:684:::0;;:::o;40853:107::-;39491:11;;-1:-1:-1;;;;;39491:11:0;39477:10;:25;39473:52;;39511:14;;-1:-1:-1;;;39511:14:0;;;;;;;;;;;39473:52;40928:22:::1;40944:5;40928:15;:22::i;:::-;40853:107:::0;:::o;57743:1306::-;57800:20;57833:26;57862:17;:15;:17::i;:::-;57833:46;-1:-1:-1;57950:6:0;57946:1056;57966:9;:16;57962:1;:20;57946:1056;;;58004:13;58020:9;58030:1;58020:12;;;;;;;;:::i;:::-;;;;;;;58004:28;;58095:13;58111:5;;;;;;;;;-1:-1:-1;;;;;58111:5:0;-1:-1:-1;;;;;58111:11:0;;:13;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;58095:29;-1:-1:-1;58233:1:0;58216:775;58241:5;58236:1;:10;58216:775;;58276:5;;:16;;-1:-1:-1;;;58276:16:0;;;;;1060:25:1;;;-1:-1:-1;;;;;58276:5:0;;;;:13;;1033:18:1;;58276:16:0;;;;;;;;;;;;;;;;;;-1:-1:-1;58276:16:0;;;;;;;;-1:-1:-1;;58276:16:0;;;;;;;;;;;;:::i;:::-;;;58272:704;58948:8;58272:704;58377:20;58400:16;58407:5;58414:1;58400:6;:16::i;:::-;58377:39;-1:-1:-1;58443:16:0;;58439:101;;58488:28;58504:12;58488:28;;:::i;:::-;;;58439:101;-1:-1:-1;;;;;58674:24:0;;58631:40;58674:24;;;:17;:24;;;;;;;;:27;;;;;;;;;58631:70;;;;;;;;;;;;;;;;;;;;;;;;;58728:27;;;;:79;;-1:-1:-1;;;;;;58787:20:0;;;;;;:13;:20;;;;;;;;;58759:25;;;;:48;58728:79;58724:175;;;58852:23;;58836:39;;;;:::i;:::-;;;58724:175;58311:607;;58293:625;58272:704;58248:3;;;;:::i;:::-;;;;58216:775;;;-1:-1:-1;;;57984:3:0;;57946:1056;;;;59022:19;57743:1306;:::o;59315:1577::-;39491:11;;-1:-1:-1;;;;;39491:11:0;39477:10;:25;39473:52;;39511:14;;-1:-1:-1;;;39511:14:0;;;;;;;;;;;39473:52;-1:-1:-1;;;;;59464:24:0;::::1;59395:20;59464:24:::0;;;:10:::1;:24;::::0;;;;59524:19:::1;59504:17;::::0;::::1;:39:::0;59627:15:::1;59595:21;::::0;::::1;:48:::0;;;59418:11;;59464:24;59676:33:::1;::::0;59703:6:::1;59676:33;:::i;:::-;59654:55:::0;;:19:::1;59828:28;59846:10;59828:15;:28;:::i;:::-;59806:50;;59887:29;59955:6;:22;;;59940:11;59920:6;:17;;;:31;;;;:::i;:::-;59919:58;;;;:::i;:::-;59988:29;::::0;::::1;:53:::0;;;60173:21:::1;::::0;::::1;::::0;59887:90;;-1:-1:-1;60155:39:0::1;::::0;:15:::1;:39;:::i;:::-;60141:53;;60205:20;38393:4;60249:11;60229:6;:17;;;:31;;;;:::i;:::-;60228:45;;;;:::i;:::-;60369:22;::::0;::::1;::::0;60205:68;;-1:-1:-1;38393:4:0::1;60406:23:::0;::::1;60402:79;;;-1:-1:-1::0;38393:4:0::1;60402:79;60559:35;60626:11:::0;60598:24:::1;38393:4;60598:12:::0;:24:::1;:::i;:::-;60597:40;;;;:::i;:::-;60710:29;::::0;::::1;:59:::0;;;60559:78;-1:-1:-1;60829:45:0::1;60853:12:::0;60710:6;60829:23:::1;:45::i;:::-;59384:1508;;;;;;;59315:1577:::0;:::o;52534:1129::-;34493:21;:19;:21::i;:::-;52599:7:::1;41651:16;41670;:14;:16::i;:::-;41651:35:::0;-1:-1:-1;41697:13:0;;:34;::::1;;;-1:-1:-1::0;41714:5:0::1;::::0;:13:::1;::::0;;-1:-1:-1;;;41714:13:0;;;;41730:1:::1;::::0;-1:-1:-1;;;;;41714:5:0::1;::::0;:11:::1;::::0;:13:::1;::::0;;::::1;::::0;::::1;::::0;;;;;;;;:5;:13:::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:17;41697:34;41693:64;;;41740:17;;-1:-1:-1::0;;;41740:17:0::1;;;;;;;;;;;41693:64;41774:6;41770:922;41790:12;:19:::0;41786:23;::::1;41770:922;;;41827:13;41843:12;41856:1;41843:15;;;;;;;;:::i;:::-;;::::0;;;::::1;::::0;;;;;::::1;::::0;-1:-1:-1;;;;;41843:15:0::1;41893:17:::0;;;:10:::1;:17:::0;;;;;;42001:22:::1;::::0;::::1;::::0;41843:15;;-1:-1:-1;41893:17:0;41843:15;41969:55:::1;::::0;41843:15;;41969:24:::1;:55::i;:::-;42035:29;::::0;::::1;:49:::0;;;41941:83;-1:-1:-1;42119:31:0::1;42144:5:::0;42119:24:::1;:31::i;:::-;42095:21;::::0;::::1;:55:::0;42161:22:::1;::::0;::::1;:33:::0;;;42219:12;;42215:470:::1;;42376:29;::::0;::::1;::::0;-1:-1:-1;;;;;42335:29:0;::::1;;::::0;;;:22:::1;:29;::::0;;;;;;;:38;;;;;;;;;:70:::1;42331:181;;;42467:29;::::0;::::1;::::0;-1:-1:-1;;;;;42426:29:0;::::1;;::::0;;;:22:::1;:29;::::0;;;;;;;:38;;;;;;;;:70;42331:181:::1;42566:22;42573:5;42580:7;42566:6;:22::i;:::-;-1:-1:-1::0;;;;;42540:14:0;::::1;;::::0;;;:7:::1;:14;::::0;;;;;;;:23;;;;;;;;:48;;;;42644:29:::1;::::0;::::1;::::0;42603;;;:22:::1;:29:::0;;;;;:38;;;;;;;;;:70;42215:470:::1;-1:-1:-1::0;;;41811:3:0::1;;41770:922;;;-1:-1:-1::0;52623:5:0::2;::::0;:22:::2;::::0;-1:-1:-1;;;52623:22:0;;::::2;::::0;::::2;1060:25:1::0;;;52649:10:0::2;::::0;-1:-1:-1;;;;;52623:5:0::2;::::0;:13:::2;::::0;1033:18:1;;52623:22:0::2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;52623:36:0::2;;52619:63;;52668:14;;-1:-1:-1::0;;;52668:14:0::2;;;;;;;;;;;52619:63;52704:23;52729:24;52755;52783:28;52803:7;52783:19;:28::i;:::-;52703:108;;;;;;52826:6;:13;52843:1;52826:18:::0;52822:42:::2;;52853:11;;-1:-1:-1::0;;;52853:11:0::2;;;;;;;;;;;52822:42;52889:6;52885:771;52905:6;:13;52901:1;:17;52885:771;;;52940:13;52956:6;52963:1;52956:9;;;;;;;;:::i;:::-;;;;;;;52940:25;;52980:14;52997:7;53005:1;52997:10;;;;;;;;:::i;:::-;;;;;;;52980:27;;53049:1;53040:6;:10;53036:609;;;-1:-1:-1::0;;;;;53092:20:0;::::2;;::::0;;;:13:::2;:20;::::0;;;;;::::2;;53087:54;;53121:20;;-1:-1:-1::0;;;53121:20:0::2;;;;;;;;;;;53087:54;-1:-1:-1::0;;;;;53220:17:0;::::2;53196:21;53220:17:::0;;;:10:::2;:17;::::0;;;;;;;53292:7:::2;:14:::0;;;;;:23;;;;;;;;:27;;;53379:29:::2;::::0;::::2;::::0;53338;;;:22:::2;:29:::0;;;;;:38;;;;;;;;:70;53463:24;;;:17:::2;:24:::0;;;;;:33;;;;;;;;:44;53618:10;;53562:67:::2;::::0;53231:5;;53589:10:::2;::::0;53601:6;;53307:7;;53618;;53626:1;;53618:10;::::2;;;;;:::i;:::-;;;;;;;53562:19;:67::i;:::-;53052:593;53036:609;-1:-1:-1::0;;52920:3:0::2;;52885:771;;;;52608:1055;;;41644:1059:::1;34525:1;34537:20:::0;33754:1;35057:7;:22;34874:213;51031:1495;39491:11;;-1:-1:-1;;;;;39491:11:0;39477:10;:25;39473:52;;39511:14;;-1:-1:-1;;;39511:14:0;;;;;;;;;;;39473:52;-1:-1:-1;;;;;51122:28:0;::::1;;::::0;;;:13:::1;:28;::::0;;;;;::::1;;51117:62;;51159:20;;-1:-1:-1::0;;;51159:20:0::1;;;;;;;;;;;51117:62;-1:-1:-1::0;;;;;51228:25:0;::::1;51200;51228::::0;;;:10:::1;:25;::::0;;;;51286:23;;51268:15:::1;:41;51264:78;;;51311:31;::::0;-1:-1:-1;;;51311:31:0;;8381:2:1;51311:31:0::1;::::0;::::1;8363:21:1::0;8420:2;8400:18;;;8393:30;-1:-1:-1;;;8439:18:1;;;8432:51;8500:18;;51311:31:0::1;;;;;;;;51264:78;51357:24;::::0;::::1;::::0;:28;51353:59:::1;;51387:25;::::0;-1:-1:-1;;;51387:25:0;;8731:2:1;51387:25:0::1;::::0;::::1;8713:21:1::0;8770:2;8750:18;;;8743:30;-1:-1:-1;;;8789:18:1;;;8782:45;8844:18;;51387:25:0::1;8529:339:1::0;51353:59:0::1;-1:-1:-1::0;;;;;51462:28:0;;::::1;51433:26;51462:28:::0;;;:13:::1;:28;::::0;;;;;;;;51527:5:::1;::::0;:13;;-1:-1:-1;;;51527:13:0;;;;51462:28;;51527:5:::1;::::0;:11:::1;::::0;:13:::1;::::0;;::::1;::::0;;;;;;;:5;:13:::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;51511:29:::0;-1:-1:-1;51568:1:0::1;51551:486;51576:5;51571:1;:10;51551:486;;51607:5;::::0;:16:::1;::::0;-1:-1:-1;;;51607:16:0;;::::1;::::0;::::1;1060:25:1::0;;;-1:-1:-1;;;;;51607:5:0;;::::1;::::0;:13:::1;::::0;1033:18:1;;51607:16:0::1;;;;;;;;;;;;;;;;;;-1:-1:-1::0;51607:16:0::1;::::0;;::::1;;::::0;;::::1;-1:-1:-1::0;;51607:16:0::1;::::0;::::1;::::0;;;::::1;::::0;;::::1;::::0;::::1;:::i;:::-;;;51603:423:::0;::::1;;51687:21;51711:24;51718:13;51733:1;51711:6;:24::i;:::-;51687:48:::0;-1:-1:-1;51758:17:0;;51754:248:::1;;51838:144;::::0;;;;::::1;::::0;;;;;::::1;::::0;;::::1;::::0;;;-1:-1:-1;;;;;51800:32:0;::::1;-1:-1:-1::0;51800:32:0;;;:17:::1;:32:::0;;;;;:35;;;;;;;;;:182;;;;;;::::1;::::0;;::::1;::::0;51754:248:::1;51642:375;51624:393;51603:423;51583:3:::0;::::1;::::0;::::1;:::i;:::-;;;;51551:486;;;-1:-1:-1::0;;;;;;52057:28:0;::::1;52088:5;52057:28:::0;;;:13:::1;:28;::::0;;;;:36;;-1:-1:-1;;52057:36:0::1;::::0;;52135:22:::1;:18:::0;52057:36;52135:22:::1;:::i;:::-;-1:-1:-1::0;;;;;52104:28:0;::::1;;::::0;;;:13:::1;:28;::::0;;;;:53;;;;52178:262:::1;52199:12;:19:::0;52195:23;::::1;52178:262;;;52263:13;-1:-1:-1::0;;;;;52244:32:0::1;:12;52257:1;52244:15;;;;;;;;:::i;:::-;;::::0;;;::::1;::::0;;;::::1;::::0;-1:-1:-1;;;;;52244:15:0::1;:32:::0;52240:189:::1;;52315:12;52328:19:::0;;:23:::1;::::0;52350:1:::1;::::0;52328:23:::1;:::i;:::-;52315:37;;;;;;;;:::i;:::-;;::::0;;;::::1;::::0;;;::::1;::::0;52297:12:::1;:15:::0;;-1:-1:-1;;;;;52315:37:0;;::::1;::::0;52310:1;;52297:15;::::1;;;;;:::i;:::-;;;;;;;;;:55;;;;;-1:-1:-1::0;;;;;52297:55:0::1;;;;;-1:-1:-1::0;;;;;52297:55:0::1;;;;;;52371:12;:18;;;;;;;:::i;:::-;;::::0;;;::::1;::::0;;;;-1:-1:-1;;52371:18:0;;;;;-1:-1:-1;;;;;;52371:18:0::1;::::0;;;;;52408:5:::1;;52240:189;52220:3;;52178:262;;;;52465:53;52484:13;52499:18;52465:53;;;;;;;:::i;44326:1809::-:0;-1:-1:-1;;;;;44447:25:0;;;44403:7;44447:25;;;:10;:25;;;;;;44571:5;;44609:21;;;;44571:61;;-1:-1:-1;;;44571:61:0;;;;;9456:25:1;;;9529:10;9517:23;;;9497:18;;;9490:51;44403:7:0;;44447:25;;44403:7;;44571:5;;;:21;;9429:18:1;;44571:61:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;44553:79:0;;;44647:7;44658:1;44647:12;44643:26;;44668:1;44661:8;;;;;;44643:26;44779:29;44950:6;:21;;;44908:39;44933:13;44908:24;:39::i;:::-;:63;44904:800;;;44992:17;45054:6;:21;;;45012:39;45037:13;45012:24;:39::i;:::-;:63;;;;:::i;:::-;44992:83;;45094:20;38393:4;45138:9;45118:6;:17;;;:29;;;;:::i;:::-;45117:43;;;;:::i;:::-;45094:66;;45179:32;45243:6;:22;;;38393:4;45215:12;:24;;;;:::i;:::-;45214:51;;;;:::i;:::-;45179:86;-1:-1:-1;45359:29:0;;:46;;;;;45404:1;45392:9;:13;45359:46;45355:123;;;-1:-1:-1;45457:1:0;45355:123;45570:24;45538:6;:29;;;:56;;;;:::i;:::-;45514:80;;44973:637;;;44904:800;;;-1:-1:-1;45659:29:0;;;;44904:800;-1:-1:-1;;;;;45832:37:0;;45813:16;45832:37;;;:22;:37;;;;;;;;:46;;;;;;;;;;45911:32;;;:71;;45981:1;45911:71;;;45946:32;45970:8;45946:21;:32;:::i;:::-;45889:93;-1:-1:-1;46003:21:0;38393:4;46028:21;45889:93;46028:7;:21;:::i;:::-;46027:35;;;;:::i;:::-;-1:-1:-1;;;;;46080:22:0;;;;;;:7;:22;;;;;;;;:31;;;;;;;;;46003:59;;-1:-1:-1;46080:47:0;;46003:59;;46080:47;:::i;:::-;46073:54;;;;;;;;44326:1809;;;;;:::o;39622:324::-;32040:21;27356:15;;-1:-1:-1;;;27356:15:0;;;;27355:16;;-1:-1:-1;;;;;27403:14:0;27209:30;27788:16;;:34;;;;;27808:14;27788:34;27768:54;;27833:17;27853:11;-1:-1:-1;;;;;27853:16:0;27868:1;27853:16;:50;;;;-1:-1:-1;27881:4:0;27873:25;:30;27853:50;27833:70;;27921:12;27920:13;:30;;;;;27938:12;27937:13;27920:30;27916:93;;;27974:23;;-1:-1:-1;;;27974:23:0;;;;;;;;;;;27916:93;28019:18;;-1:-1:-1;;28019:18:0;28036:1;28019:18;;;28048:69;;;;28083:22;;-1:-1:-1;;;;28083:22:0;-1:-1:-1;;;28083:22:0;;;28048:69;-1:-1:-1;;;;;39741:20:0;::::1;::::0;;:50:::1;;-1:-1:-1::0;;;;;;39765:26:0;::::1;::::0;39741:50:::1;39737:76;;;39800:13;;-1:-1:-1::0;;;39800:13:0::1;;;;;;;;;;;39737:76;39834:24;:22;:24::i;:::-;39879:5;:22:::0;;-1:-1:-1;;;;;39879:22:0;;::::1;-1:-1:-1::0;;;;;;39879:22:0;;::::1;;::::0;;;39912:11:::1;:26:::0;;;;::::1;::::0;;;::::1;::::0;;;::::1;::::0;;28139:104;;;;28174:23;;-1:-1:-1;;;;28174:23:0;;;28217:14;;-1:-1:-1;10000:50:1;;28217:14:0;;9988:2:1;9973:18;28217:14:0;;;;;;;28139:104;27141:1109;;;;;39622:324;;:::o;42711:245::-;-1:-1:-1;;;;;42834:25:0;;42789:7;42834:25;;;:10;:25;;;;;:38;42816:15;:56;:132;;-1:-1:-1;;;;;42910:25:0;;;;;;:10;:25;;;;;:38;42816:132;;;42892:15;42809:139;42711:245;-1:-1:-1;;42711:245:0:o;39954:641::-;39491:11;;-1:-1:-1;;;;;39491:11:0;39477:10;:25;39473:52;;39511:14;;-1:-1:-1;;;39511:14:0;;;;;;;;;;;39473:52;38448:2:::1;40058:13;:20;:40;40054:74;;;40107:21;;-1:-1:-1::0;;;40107:21:0::1;;;;;;;;;;;40054:74;40143:12;:19:::0;:23;40139:65:::1;;40168:36;::::0;-1:-1:-1;;;40168:36:0;;10263:2:1;40168:36:0::1;::::0;::::1;10245:21:1::0;10302:2;10282:18;;;10275:30;10341:28;10321:18;;;10314:56;10387:18;;40168:36:0::1;10061:350:1::0;40139:65:0::1;40239:6;40235:226;40255:13;:20;40251:1;:24;40235:226;;;40301:6;40310:5;:1:::0;40314::::1;40310:5;:::i;:::-;40301:14;;40297:153;40321:13;:20;40317:1;:24;40297:153;;;40391:13;40405:1;40391:16;;;;;;;;:::i;:::-;;;;;;;-1:-1:-1::0;;;;;40371:36:0::1;:13;40385:1;40371:16;;;;;;;;:::i;:::-;;;;;;;-1:-1:-1::0;;;;;40371:36:0::1;::::0;40367:67:::1;;40409:25;::::0;-1:-1:-1;;;40409:25:0;;10618:2:1;40409:25:0::1;::::0;::::1;10600:21:1::0;10657:2;10637:18;;;10630:30;-1:-1:-1;;;10676:18:1;;;10669:45;10731:18;;40409:25:0::1;10416:339:1::0;40367:67:0::1;40343:3;;40297:153;;;-1:-1:-1::0;40277:3:0::1;;40235:226;;;-1:-1:-1::0;40485:6:0::1;40481:107;40501:13;:20;40497:1;:24;40481:107;;;40543:33;40559:13;40573:1;40559:16;;;;;;;;:::i;:::-;;;;;;;40543:15;:33::i;:::-;40523:3;;40481:107;;;;39954:641:::0;:::o;55608:1726::-;55869:5;;:22;;-1:-1:-1;;;55869:22:0;;;;;1060:25:1;;;55685:23:0;;;;;;55853:13;;-1:-1:-1;;;;;55869:5:0;;;;:13;;1033:18:1;;55869:22:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;55853:38;-1:-1:-1;;;;;;55906:19:0;;55902:46;;55934:14;;-1:-1:-1;;;55934:14:0;;;;;;;;;;;55902:46;55969:26;55998:17;:15;:17::i;:::-;55969:46;;56049:9;:16;56068:1;56049:20;;;;:::i;:::-;-1:-1:-1;;;;;56035:35:0;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;56035:35:0;;56026:44;;56137:9;:16;56156:1;56137:20;;;;:::i;:::-;-1:-1:-1;;;;;56123:35:0;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;56123:35:0;;56113:45;;56193:9;:16;56212:1;56193:20;;;;:::i;:::-;-1:-1:-1;;;;;56179:35:0;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;56179:35:0;-1:-1:-1;56169:45:0;-1:-1:-1;56235:13:0;;56259:872;56279:9;:16;56275:1;:20;56259:872;;;56317:13;56333:9;56343:1;56333:12;;;;;;;;:::i;:::-;;;;;;;56317:28;;56405:20;56428:22;56435:5;56442:7;56428:6;:22::i;:::-;56405:45;-1:-1:-1;56469:16:0;;56465:214;;56522:5;56506:6;56513:5;56506:13;;;;;;;;:::i;:::-;;;;;;:21;-1:-1:-1;;;;;56506:21:0;;;-1:-1:-1;;;;;56506:21:0;;;;;56563:12;56546:7;56554:5;56546:14;;;;;;;;:::i;:::-;;;;;;:29;;;;;56611:10;:17;56622:5;-1:-1:-1;;;;;56611:17:0;-1:-1:-1;;;;;56611:17:0;;;;;;;;;;;;:26;;;56594:7;56602:5;56594:14;;;;;;;;:::i;:::-;;;;;;;;;;:43;56656:7;;;;:::i;:::-;;;;56465:214;-1:-1:-1;;;;;56785:24:0;;56742:40;56785:24;;;:17;:24;;;;;;;;:33;;;;;;;;;56742:76;;;;;;;;;;;;;;;;;;;;;;;;;56837:27;;;;:79;;-1:-1:-1;;;;;;56896:20:0;;;;;;:13;:20;;;;;;;;;56868:25;;;;:48;56837:79;56833:287;;;56953:5;56937:6;56944:5;56937:13;;;;;;;;:::i;:::-;;;;;;:21;-1:-1:-1;;;;;56937:21:0;;;-1:-1:-1;;;;;56937:21:0;;;;;56994:16;:23;;;56977:7;56985:5;56977:14;;;;;;;;:::i;:::-;;;;;;:40;;;;;57053:16;:25;;;57036:7;57044:5;57036:14;;;;;;;;:::i;:::-;;;;;;;;;;:42;57097:7;;;;:::i;:::-;;;;56833:287;-1:-1:-1;;;56297:3:0;;56259:872;;;-1:-1:-1;57223:21:0;;;57258:22;;;57294;;-1:-1:-1;57230:6:0;;57265:7;;-1:-1:-1;57301:7:0;-1:-1:-1;55608:1726:0:o;37915:29::-;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;37915:29:0;;-1:-1:-1;37915:29:0;:::o;46840:4183::-;39491:11;;-1:-1:-1;;;;;39491:11:0;39477:10;:25;39473:52;;39511:14;;-1:-1:-1;;;39511:14:0;;;;;;;;;;;39473:52;-1:-1:-1;;;;;46948:28:0;::::1;;::::0;;;:13:::1;:28;::::0;;;;;::::1;;46943:62;;46985:20;;-1:-1:-1::0;;;46985:20:0::1;;;;;;;;;;;46943:62;47020:6;47030:1;47020:11:::0;47016:38:::1;;47040:14;;-1:-1:-1::0;;;47040:14:0::1;;;;;;;;;;;47016:38;47132:57;::::0;-1:-1:-1;;;47132:57:0;;47114:15:::1;::::0;-1:-1:-1;;;;;47132:42:0;::::1;::::0;::::1;::::0;:57:::1;::::0;47183:4:::1;::::0;47132:57:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;47114:75;;47214:6;47204:7;:16;47200:50;;;47229:21;;-1:-1:-1::0;;;47229:21:0::1;;;;;;;;;;;47200:50;-1:-1:-1::0;;;;;47299:25:0;::::1;47271;47299::::0;;;:10:::1;:25;::::0;;;;47423::::1;::::0;::::1;::::0;47299;;47423:30;47419:205:::1;;-1:-1:-1::0;;;;;47470:28:0;::::1;;::::0;;;:13:::1;:28;::::0;;;;:30;;;::::1;::::0;::::1;:::i;:::-;;;;;;47596:16;:14;:16::i;:::-;47567:26;::::0;::::1;:45:::0;47419:205:::1;47748:25;::::0;::::1;::::0;47713:16:::1;::::0;47748:29;;;;:74:::1;;-1:-1:-1::0;47781:23:0;;47807:15:::1;-1:-1:-1::0;47748:74:0::1;47744:159;;;47850:23:::0;;:41:::1;::::0;47876:15:::1;::::0;47850:41:::1;:::i;:::-;47839:52;;47744:159;47923:24;47966:12:::0;;;;;:41:::1;;;48006:1;47982:10;:21;;;:25;47966:41;47962:480;;;48122:28;48142:8:::0;-1:-1:-1;;48122:28:0::1;:::i;:::-;48098:10;:21;;;:52;48094:337;;;48190:23;48205:8:::0;38346:4:::1;48190:23;:::i;:::-;48171:42;;48094:337;;;38393:4;48394:8;48370:10;:21;;;:32;;;;:::i;:::-;48369:46;;;;:::i;:::-;48350:65;;48094:337;48568:24;::::0;::::1;::::0;48509:28:::1;::::0;48540:25:::1;48549:16:::0;48540:6;:25:::1;:::i;:::-;:52;;;;:::i;:::-;48509:83:::0;-1:-1:-1;48509:83:0;48779:18:::1;48846:22:::0;;::::1;48842:77;;;48900:7;48885:22;;48842:77;48948:20;48933:12;:35;48929:103;;;49000:20;48985:35;;48929:103;49112:1;49085:24;::::0;::::1;:28:::0;;;49293:16;;49289:1019:::1;;49526:23;38245:6;49553:24;38393:4;49553:12:::0;:24:::1;:::i;:::-;49552:37;;;;:::i;:::-;49526:63:::0;-1:-1:-1;49695:26:0::1;49724:16;38393:4;49724;:16;:::i;:::-;49695:45;;49777:18;49759:15;:36;49755:113;;;49834:18;49816:36;;49755:113;49982:15;49972:25;;38346:4;50068:7;:22;50064:85;;;38346:4;50111:22;;50064:85;38297:3;50167:7;:22;50163:82;;;50217:12;;-1:-1:-1::0;;;50217:12:0::1;;;;;;;;;;;50163:82;49311:945;;49289:1019;;;50284:12;;-1:-1:-1::0;;;50284:12:0::1;;;;;;;;;;;49289:1019;50359:21;::::0;::::1;:31:::0;;;50429:15:::1;50401:25;::::0;::::1;:43:::0;;;50481:26:::1;::::0;38245:6:::1;::::0;50481:26:::1;:::i;:::-;50455:52:::0;;:23:::1;50643:16;:14;:16::i;:::-;50619:40;;38393:4;50699:13;:25;:53;;50739:13;50699:53;;;38393:4;50699:53;50670:26;::::0;::::1;:82:::0;;;50852:67:::1;::::0;50877:13;;50852:24:::1;:67::i;:::-;50816:33;::::0;::::1;:103:::0;50995:19:::1;::::0;::::1;::::0;50945:70:::1;::::0;;-1:-1:-1;;;;;11009:32:1;;10991:51;;11073:2;11058:18;;11051:34;;;11101:18;;;11094:34;;;11159:2;11144:18;;11137:34;;;;50945:70:0;::::1;::::0;;;;10978:3:1;50945:70:0;;::::1;46932:4091;;;;;;;;;46840:4183:::0;;:::o;40603:242::-;39491:11;;-1:-1:-1;;;;;39491:11:0;39477:10;:25;39473:52;;39511:14;;-1:-1:-1;;;39511:14:0;;;;;;;;;;;39473:52;-1:-1:-1;;;;;40695:29:0;::::1;40691:55;;40733:13;;-1:-1:-1::0;;;40733:13:0::1;;;;;;;;;;;40691:55;40757:11;:29:::0;;-1:-1:-1;;;;;;40757:29:0::1;-1:-1:-1::0;;;;;40757:29:0;::::1;;::::0;;40802:35:::1;::::0;::::1;::::0;::::1;::::0;40757:29;;40802:35:::1;:::i;:::-;;;;;;;;40603:242:::0;:::o;41489:109::-;41563:5;;:27;;;-1:-1:-1;;;41563:27:0;;;;41536:7;;-1:-1:-1;;;;;41563:5:0;;:25;;:27;;;;;;;;;;;;;;:5;:27;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;41556:34:0;;;41489:109;:::o;57342:104::-;57390:16;57426:12;57419:19;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;57419:19:0;;;;;;;;;;;;;;;;;;;;;;;57342:104;:::o;17266:216::-;17405:68;;-1:-1:-1;;;;;11402:32:1;;;17405:68:0;;;11384:51:1;11471:32;;11451:18;;;11444:60;11520:18;;;11513:34;;;17378:96:0;;17398:5;;-1:-1:-1;;;17428:27:0;11357:18:1;;17405:68:0;;;;-1:-1:-1;;17405:68:0;;;;;;;;;;;;;;-1:-1:-1;;;;;17405:68:0;-1:-1:-1;;;;;;17405:68:0;;;;;;;;;;17378:19;:96::i;:::-;17266:216;;;;:::o;40968:513::-;-1:-1:-1;;;;;41032:19:0;;41028:45;;41060:13;;-1:-1:-1;;;41060:13:0;;;;;;;;;;;41028:45;-1:-1:-1;;;;;41088:20:0;;;;;;:13;:20;;;;;;;;41084:52;;;41117:19;;-1:-1:-1;;;41117:19:0;;;;;;;;;;;41084:52;41157:12;:24;;;;;;;;;;;;;-1:-1:-1;;;;;;41157:24:0;-1:-1:-1;;;;;41157:24:0;;;;;;;;-1:-1:-1;41192:20:0;;;:13;41157:24;41192:20;;;;;;;:27;;-1:-1:-1;;41192:27:0;;;;;41230:13;:20;;;;;;:24;;;41299:10;:17;;;;;41327:22;;;:26;;;;41382:20;;;;;41364:15;;;:38;;;41428:45;;41299:17;;41428:45;;;;41157:24;;41428:45;:::i;:::-;;;;;;;;41017:464;40968:513;:::o;61085:385::-;61204:5;;:13;;;-1:-1:-1;;;61204:13:0;;;;61188;;-1:-1:-1;;;;;61204:5:0;;:11;;:13;;;;;;;;;;;;;;:5;:13;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;61188:29;-1:-1:-1;61245:1:0;61228:235;61253:5;61248:1;:10;61228:235;;61284:5;;:16;;-1:-1:-1;;;61284:16:0;;;;;1060:25:1;;;-1:-1:-1;;;;;61284:5:0;;;;:13;;1033:18:1;;61284:16:0;;;;;;;;;;;;;;;;;;-1:-1:-1;61284:16:0;;;;;;;;-1:-1:-1;;61284:16:0;;;;;;;;;;;;:::i;:::-;;;61280:172;61428:8;61280:172;61338:48;61357:13;61372:1;61375:10;61338:18;:48::i;:::-;61301:101;61280:172;61260:3;;;;:::i;:::-;;;;61228:235;;34573:293;33798:1;34707:7;;:19;34699:63;;;;-1:-1:-1;;;34699:63:0;;11760:2:1;34699:63:0;;;11742:21:1;11799:2;11779:18;;;11772:30;11838:33;11818:18;;;11811:61;11889:18;;34699:63:0;11558:355:1;34699:63:0;33798:1;34840:7;:18;34573:293::o;42965:1350::-;-1:-1:-1;;;;;43106:25:0;;43062:7;43106:25;;;:10;:25;;;;;43156:12;;;:45;;-1:-1:-1;;;;;;43173:28:0;;;;;;:13;:28;;;;;;;;43172:29;43156:45;43152:114;;;43225:29;;;;-1:-1:-1;43218:36:0;;43152:114;43338:17;43400:6;:21;;;43358:39;43383:13;43358:24;:39::i;:::-;:63;;;;:::i;:::-;43338:83;;43436:9;43449:1;43436:14;43432:56;;-1:-1:-1;43459:29:0;;;;-1:-1:-1;43452:36:0;;43432:56;38393:4;43582:7;:19;43578:71;;;38393:4;43618:19;;43578:71;43792:20;43835:9;43815:6;:17;;;:29;;;;:::i;:::-;43792:52;-1:-1:-1;43927:32:0;43991:7;43963:24;38393:4;43792:52;43963:24;:::i;:::-;43962:36;;;;:::i;:::-;43927:71;-1:-1:-1;44092:29:0;;:46;;;;;44137:1;44125:9;:13;44092:46;44088:136;;;-1:-1:-1;44182:1:0;44088:136;44283:24;44251:6;:29;;;:56;;;;:::i;:::-;44244:63;42965:1350;-1:-1:-1;;;;;;;42965:1350:0:o;53671:1929::-;53853:24;;53870:7;53853:24;53970:5;;;;;;;;;-1:-1:-1;;;;;53970:5:0;-1:-1:-1;;;;;53970:17:0;;:19;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;53961:28:0;:5;-1:-1:-1;;;;;53961:28:0;;53957:950;;-1:-1:-1;;;;;54010:26:0;;54006:58;;;54038:26;;-1:-1:-1;;;54038:26:0;;12120:2:1;54038:26:0;;;12102:21:1;12159:2;12139:18;;;12132:30;-1:-1:-1;;;12178:18:1;;;12171:46;12234:18;;54038:26:0;11918:340:1;54006:58:0;54107:5;;:35;;-1:-1:-1;;;54107:35:0;;;;;1060:25:1;;;54079::0;;-1:-1:-1;;;;;54107:5:0;;:26;;1033:18:1;;54107:35:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;54079:63;;54161:17;-1:-1:-1;;;;;54161:22:0;54182:1;54161:22;54157:56;;54185:28;;-1:-1:-1;;;54185:28:0;;12465:2:1;54185:28:0;;;12447:21:1;12504:2;12484:18;;;12477:30;-1:-1:-1;;;12523:18:1;;;12516:48;12581:18;;54185:28:0;12263:342:1;54157:56:0;54242:21;54291:3;54266:22;:17;54286:2;54266:22;:::i;:::-;:28;;;;:::i;:::-;54390:5;;54349:56;;-1:-1:-1;;;54349:56:0;;54242:52;;-1:-1:-1;;;;;;54349:32:0;;;;;;:56;;54390:5;;54398:6;;54349:56;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;54424:5:0;;:167;;-1:-1:-1;;;54424:167:0;;;;;13602:25:1;;;-1:-1:-1;;;;;13663:32:1;;;13643:18;;;13636:60;54529:15:0;13712:18:1;;;13705:34;13775:32;;13755:18;;;13748:60;-1:-1:-1;;;;;54424:5:0;;;;:24;;13574:19:1;;54424:167:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;54420:476;;54821:5;;54780:51;;-1:-1:-1;;;54780:51:0;;-1:-1:-1;;;;;54780:32:0;;;;;;:51;;54821:5;;;;;;54780:51;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;54850:30:0;;-1:-1:-1;;;54850:30:0;;14308:2:1;54850:30:0;;;14290:21:1;14347:2;14327:18;;;14320:30;-1:-1:-1;;;14366:18:1;;;14359:50;14426:18;;54850:30:0;14106:344:1;54420:476:0;54616:44;;;835:25:1;;;891:2;876:18;;869:34;;;-1:-1:-1;;;;;54616:44:0;;;54627:7;;54616:44;;808:18:1;54616:44:0;;;;;;;54679:7;;;;53957:950;55003:49;;-1:-1:-1;;;55003:49:0;;54982:18;;-1:-1:-1;;;;;55003:34:0;;;;;:49;;55046:4;;55003:49;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;54982:70;;55080:6;55067:10;:19;55063:53;;;55095:21;;-1:-1:-1;;;55095:21:0;;;;;;;;;;;55063:53;55167:38;;-1:-1:-1;;;55167:38:0;;55137:27;;-1:-1:-1;;;;;55167:34:0;;;;;:38;;55202:2;;55167:38;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;55137:68;-1:-1:-1;55226:49:0;-1:-1:-1;;;;;55226:37:0;;55264:2;55268:6;55226:37;:49::i;:::-;55327:38;;-1:-1:-1;;;55327:38:0;;55296:28;;-1:-1:-1;;;;;55327:34:0;;;;;:38;;55362:2;;55327:38;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;55296:69;;55404:19;55380:20;:43;55376:72;;55432:16;;-1:-1:-1;;;55432:16:0;;;;;;;;;;;55376:72;55469:16;55488:42;55511:19;55488:20;:42;:::i;:::-;55469:61;;55566:5;-1:-1:-1;;;;;55546:46:0;55557:7;55546:46;55573:8;55583;55546:46;;;;;;835:25:1;;;891:2;876:18;;869:34;823:2;808:18;;661:248;55546:46:0;;;;;;;;53842:1758;;;;53671:1929;;;;;;:::o;34874:213::-;33754:1;35057:7;:22;34874:213::o;33840:113::-;30047:20;:18;:20::i;:::-;33911:34:::1;:32;:34::i;:::-;33840:113::o:0;21256:660::-;21691:23;21717:69;21745:4;21717:69;;;;;;;;;;;;;;;;;21725:5;-1:-1:-1;;;;;21717:27:0;;;:69;;;;;:::i;:::-;21691:95;;21805:10;:17;21826:1;21805:22;:56;;;;21842:10;21831:30;;;;;;;;;;;;:::i;:::-;21797:111;;;;-1:-1:-1;;;21797:111:0;;14657:2:1;21797:111:0;;;14639:21:1;14696:2;14676:18;;;14669:30;14735:34;14715:18;;;14708:62;-1:-1:-1;;;14786:18:1;;;14779:40;14836:19;;21797:111:0;14455:406:1;21797:111:0;21337:579;21256:660;;:::o;61702:1137::-;61849:33;;;;-1:-1:-1;;;;;61912:37:0;;61817:29;61912:37;;;:22;:37;;;;;;;;:46;;;;;;;;;61983:32;;;61979:853;;;-1:-1:-1;;;;;62032:37:0;;;;;;:22;:37;;;;;;;;:46;;;;;;;;:70;;;62163:25;;;;:32;;62191:4;;62163:32;:::i;:::-;62162:41;;62199:4;62162:41;:::i;:::-;62237:5;;:46;;-1:-1:-1;;;62237:46:0;;;;;9456:25:1;;;9529:10;9517:23;;9497:18;;;9490:51;62131:73:0;;-1:-1:-1;62219:15:0;;-1:-1:-1;;;;;62237:5:0;;;;:21;;9429:18:1;;62237:46:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;62219:64:0;;-1:-1:-1;62316:11:0;;62312:509;;-1:-1:-1;;;;;62394:37:0;;62348:19;62394:37;;;:22;:37;;;;;;;;:46;;;;;;;;;62370:70;;:171;;62540:1;62370:171;;;-1:-1:-1;;;;;62490:37:0;;;;;;:22;:37;;;;;;;;:46;;;;;;;;;62466:70;;:21;:70;:::i;:::-;62348:193;-1:-1:-1;62578:21:0;38393:4;62603:21;62348:193;62603:7;:21;:::i;:::-;62602:35;;;;:::i;:::-;-1:-1:-1;;;;;62656:22:0;;;;;;:7;:22;;;;;;;;:31;;;;;;;;:48;;62578:59;;-1:-1:-1;62578:59:0;;62656:31;;:22;:48;;62578:59;;62656:48;:::i;:::-;;;;-1:-1:-1;;62746:59:0;;;15097:25:1;;;-1:-1:-1;;;;;15158:32:1;;15153:2;15138:18;;15131:60;15207:18;;;15200:34;;;15265:2;15250:18;;15243:34;;;62746:59:0;;15084:3:1;15069:19;62746:59:0;;;;;;;62329:492;;62017:815;;61806:1033;;61702:1137;;;:::o;16833:188::-;16927:86;16947:5;16977:23;;;17002:2;17006:5;16954:58;;;;;;;;;:::i;30207:145::-;32040:21;31721:40;-1:-1:-1;;;31721:40:0;;;;30270:75;;30316:17;;-1:-1:-1;;;30316:17:0;;;;;;;;;;;33961:111;30047:20;:18;:20::i;10656:229::-;10793:12;10825:52;10847:6;10855:4;10861:1;10864:12;10825:21;:52::i;:::-;10818:59;10656:229;-1:-1:-1;;;;10656:229:0:o;11742:455::-;11912:12;11970:5;11945:21;:30;;11937:81;;;;-1:-1:-1;;;11937:81:0;;15490:2:1;11937:81:0;;;15472:21:1;15529:2;15509:18;;;15502:30;15568:34;15548:18;;;15541:62;-1:-1:-1;;;15619:18:1;;;15612:36;15665:19;;11937:81:0;15288:402:1;11937:81:0;12030:12;12044:23;12071:6;-1:-1:-1;;;;;12071:11:0;12090:5;12097:4;12071:31;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;12029:73;;;;12120:69;12147:6;12155:7;12164:10;12176:12;14500;14529:7;14525:427;;;14557:10;:17;14578:1;14557:22;14553:290;;-1:-1:-1;;;;;8196:19:0;;;14767:60;;;;-1:-1:-1;;;14767:60:0;;16203:2:1;14767:60:0;;;16185:21:1;16242:2;16222:18;;;16215:30;16281:31;16261:18;;;16254:59;16330:18;;14767:60:0;16001:353:1;14767:60:0;-1:-1:-1;14864:10:0;14857:17;;14525:427;14907:33;14915:10;14927:12;15662:17;;:21;15658:388;;15894:10;15888:17;15951:15;15938:10;15934:2;15930:19;15923:44;15658:388;16021:12;16014:20;;-1:-1:-1;;;16014:20:0;;;;;;;;:::i;14:131:1:-;-1:-1:-1;;;;;89:31:1;;79:42;;69:70;;135:1;132;125:12;150:134;218:20;;247:31;218:20;247:31;:::i;:::-;150:134;;;:::o;289:367::-;357:6;365;418:2;406:9;397:7;393:23;389:32;386:52;;;434:1;431;424:12;386:52;473:9;460:23;492:31;517:5;492:31;:::i;:::-;542:5;620:2;605:18;;;;592:32;;-1:-1:-1;;;289:367:1:o;1096:247::-;1155:6;1208:2;1196:9;1187:7;1183:23;1179:32;1176:52;;;1224:1;1221;1214:12;1176:52;1263:9;1250:23;1282:31;1307:5;1282:31;:::i;:::-;1332:5;1096:247;-1:-1:-1;;;1096:247:1:o;1348:226::-;1407:6;1460:2;1448:9;1439:7;1435:23;1431:32;1428:52;;;1476:1;1473;1466:12;1428:52;-1:-1:-1;1521:23:1;;1348:226;-1:-1:-1;1348:226:1:o;1579:388::-;1647:6;1655;1708:2;1696:9;1687:7;1683:23;1679:32;1676:52;;;1724:1;1721;1714:12;1676:52;1763:9;1750:23;1782:31;1807:5;1782:31;:::i;:::-;1832:5;-1:-1:-1;1889:2:1;1874:18;;1861:32;1902:33;1861:32;1902:33;:::i;:::-;1954:7;1944:17;;;1579:388;;;;;:::o;2584:127::-;2645:10;2640:3;2636:20;2633:1;2626:31;2676:4;2673:1;2666:15;2700:4;2697:1;2690:15;2716:1127;2800:6;2853:2;2841:9;2832:7;2828:23;2824:32;2821:52;;;2869:1;2866;2859:12;2821:52;2909:9;2896:23;-1:-1:-1;;;;;2934:6:1;2931:30;2928:50;;;2974:1;2971;2964:12;2928:50;2997:22;;3050:4;3042:13;;3038:27;-1:-1:-1;3028:55:1;;3079:1;3076;3069:12;3028:55;3119:2;3106:16;-1:-1:-1;;;;;3137:6:1;3134:30;3131:56;;;3167:18;;:::i;:::-;3213:6;3210:1;3206:14;3249:2;3243:9;3312:2;3308:7;3303:2;3299;3295:11;3291:25;3283:6;3279:38;3383:6;3371:10;3368:22;-1:-1:-1;;;;;3335:10:1;3332:34;3329:62;3326:88;;;3394:18;;:::i;:::-;3430:2;3423:22;3480;;;3530:2;3560:11;;;3556:20;;;3480:22;3518:15;;3588:19;;;3585:39;;;3620:1;3617;3610:12;3585:39;3652:2;3648;3644:11;3633:22;;3664:148;3680:6;3675:3;3672:15;3664:148;;;3746:23;3765:3;3746:23;:::i;:::-;3734:36;;3799:2;3697:12;;;;3790;3664:148;;;-1:-1:-1;3831:6:1;2716:1127;-1:-1:-1;;;;;;2716:1127:1:o;3848:446::-;3901:3;3939:5;3933:12;3966:6;3961:3;3954:19;3998:4;3993:3;3989:14;3982:21;;4037:4;4030:5;4026:16;4060:1;4070:199;4084:6;4081:1;4078:13;4070:199;;;4149:13;;-1:-1:-1;;;;;4145:39:1;4133:52;;4214:4;4205:14;;;;4242:17;;;;4181:1;4099:9;4070:199;;;-1:-1:-1;4285:3:1;;3848:446;-1:-1:-1;;;;3848:446:1:o;4299:420::-;4352:3;4390:5;4384:12;4417:6;4412:3;4405:19;4449:4;4444:3;4440:14;4433:21;;4488:4;4481:5;4477:16;4511:1;4521:173;4535:6;4532:1;4529:13;4521:173;;;4596:13;;4584:26;;4639:4;4630:14;;;;4667:17;;;;4557:1;4550:9;4521:173;;4724:669;5059:2;5048:9;5041:21;5022:4;5085:56;5137:2;5126:9;5122:18;5114:6;5085:56;:::i;:::-;5189:9;5181:6;5177:22;5172:2;5161:9;5157:18;5150:50;5223:44;5260:6;5252;5223:44;:::i;:::-;5209:58;;5315:9;5307:6;5303:22;5298:2;5287:9;5283:18;5276:50;5343:44;5380:6;5372;5343:44;:::i;:::-;5335:52;4724:669;-1:-1:-1;;;;;;4724:669:1:o;5398:203::-;-1:-1:-1;;;;;5562:32:1;;;;5544:51;;5532:2;5517:18;;5398:203::o;6021:261::-;6200:2;6189:9;6182:21;6163:4;6220:56;6272:2;6261:9;6257:18;6249:6;6220:56;:::i;6287:184::-;6357:6;6410:2;6398:9;6389:7;6385:23;6381:32;6378:52;;;6426:1;6423;6416:12;6378:52;-1:-1:-1;6449:16:1;;6287:184;-1:-1:-1;6287:184:1:o;6476:127::-;6537:10;6532:3;6528:20;6525:1;6518:31;6568:4;6565:1;6558:15;6592:4;6589:1;6582:15;6608:128;6675:9;;;6696:11;;;6693:37;;;6710:18;;:::i;6741:125::-;6806:9;;;6827:10;;;6824:36;;;6840:18;;:::i;7221:127::-;7282:10;7277:3;7273:20;7270:1;7263:31;7313:4;7310:1;7303:15;7337:4;7334:1;7327:15;7353:251;7423:6;7476:2;7464:9;7455:7;7451:23;7447:32;7444:52;;;7492:1;7489;7482:12;7444:52;7524:9;7518:16;7543:31;7568:5;7543:31;:::i;7609:135::-;7648:3;7669:17;;;7666:43;;7689:18;;:::i;:::-;-1:-1:-1;7736:1:1;7725:13;;7609:135::o;7749:168::-;7822:9;;;7853;;7870:15;;;7864:22;;7850:37;7840:71;;7891:18;;:::i;7922:127::-;7983:10;7978:3;7974:20;7971:1;7964:31;8014:4;8011:1;8004:15;8038:4;8035:1;8028:15;8054:120;8094:1;8120;8110:35;;8125:18;;:::i;:::-;-1:-1:-1;8159:9:1;;8054:120::o;8873:127::-;8934:10;8929:3;8925:20;8922:1;8915:31;8965:4;8962:1;8955:15;8989:4;8986:1;8979:15;9005:274;-1:-1:-1;;;;;9197:32:1;;;;9179:51;;9261:2;9246:18;;9239:34;9167:2;9152:18;;9005:274::o;9552:290::-;9622:6;9675:2;9663:9;9654:7;9650:23;9646:32;9643:52;;;9691:1;9688;9681:12;9643:52;9717:16;;-1:-1:-1;;;;;9762:31:1;;9752:42;;9742:70;;9808:1;9805;9798:12;12610:272;-1:-1:-1;;;;;12695:27:1;;;12724;;;12691:61;12772:37;;;;12828:24;;;12818:58;;12856:18;;:::i;:::-;12818:58;12610:272;;;;:::o;12887:197::-;12927:1;-1:-1:-1;;;;;12954:27:1;;;12990:37;;13007:18;;:::i;:::-;-1:-1:-1;;;;;13045:27:1;;;;13041:37;;;;;12887:197;-1:-1:-1;;12887:197:1:o;13089:277::-;13156:6;13209:2;13197:9;13188:7;13184:23;13180:32;13177:52;;;13225:1;13222;13215:12;13177:52;13257:9;13251:16;13310:5;13303:13;13296:21;13289:5;13286:32;13276:60;;13332:1;13329;13322:12;15695:301;15824:3;15862:6;15856:13;15908:6;15901:4;15893:6;15889:17;15884:3;15878:37;15970:1;15934:16;;15959:13;;;-1:-1:-1;15934:16:1;15695:301;-1:-1:-1;15695:301:1:o;16359:418::-;16508:2;16497:9;16490:21;16471:4;16540:6;16534:13;16583:6;16578:2;16567:9;16563:18;16556:34;16642:6;16637:2;16629:6;16625:15;16620:2;16609:9;16605:18;16599:50;16698:1;16693:2;16684:6;16673:9;16669:22;16665:31;16658:42;16768:2;16761;16757:7;16752:2;16744:6;16740:15;16736:29;16725:9;16721:45;16717:54;16709:62;;;16359:418;;;;:::o
Swarm Source
ipfs://e905059528afa3996c822be593cfea08d2ce664fb1775c978d38418496ecc25d
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 35 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
Loading...
Loading
Loading...
Loading
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.