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; 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 Divides current reward rate by PRECISION to fix precision scaling issue * @param _rewardsToken The token address with incorrect reward rate */ function fixRewardRate(address _rewardsToken) external onlyDistributor { if (!isRewardToken[_rewardsToken]) revert InvalidRewardToken(); Reward storage rewardInfo = rewardData[_rewardsToken]; // Only allow fixing if there's an active period if (block.timestamp >= rewardInfo.periodFinish) revert("No active period"); // Store current state uint256 oldRate = rewardInfo.rewardRate; // Update reward per token stored using the old rate up to this point rewardInfo.rewardPerVeTokenStored = _calculateRewardPerToken(_rewardsToken, rewardInfo.lastTotalSupply); // Fix precision issue by dividing by PRECISION rewardInfo.rewardRate = oldRate / PRECISION; // Ensure new rate is at least minimum if (rewardInfo.rewardRate < MINIMUM_RATE) { rewardInfo.rewardRate = MINIMUM_RATE; } // Reset start time to actual start time and adjust period finish uint256 startTime = 1743206488; rewardInfo.lastUpdateTime = startTime; rewardInfo.periodFinish = startTime + DURATION; // Fix userRewardPerTokenPaid for all tokens uint256 epoch = veSix.epoch(); for (uint256 i = 1; i <= epoch; i++) { try veSix.ownerOf(i) returns (address) { uint256 currentRewardPerToken = rewardInfo.rewardPerVeTokenStored; uint256 userPaid = userRewardPerTokenPaid[_rewardsToken][i]; // Only fix if userPaid is higher than currentRewardPerToken if (userPaid > currentRewardPerToken) { // Reset to the current value userRewardPerTokenPaid[_rewardsToken][i] = currentRewardPerToken; // Get farming power at the epoch timestamp uint32 epochTimestamp = uint32((rewardInfo.lastUpdateTime / 3600) * 3600); uint256 balance = veSix.getFarmingPower(i, epochTimestamp); // If we found a valid balance, calculate and add rewards if (balance > 0) { // Calculate reward delta using the reset userPaid value uint256 rewardDelta = currentRewardPerToken > userRewardPerTokenPaid[_rewardsToken][i] ? (currentRewardPerToken - userRewardPerTokenPaid[_rewardsToken][i]) : 0; // Calculate pending reward uint256 pendingReward = (balance * rewardDelta) / PRECISION; // Add to rewards rewards[_rewardsToken][i] += pendingReward; emit RewardFixed(i, _rewardsToken, pendingReward, balance); } } } catch { continue; } } } }
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":"_rewardsToken","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
6080604052348015600e575f5ffd5b5060156019565b60c9565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00805468010000000000000000900460ff161560685760405163f92ee8a960e01b815260040160405180910390fd5b80546001600160401b039081161460c65780546001600160401b0319166001600160401b0390811782556040519081527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b50565b6132b4806100d65f395ff3fe608060405234801561000f575f5ffd5b5060043610610195575f3560e01c80637abe18d2116100e0578063b2be1ef41161008f578063b2be1ef4146103fe578063b5fd73f814610408578063b66503cf1461043a578063b933ceac1461044d578063bc30a61814610477578063bfe109281461048a578063c4e41b221461049d578063c4f59f9b146104a5575f5ffd5b80637abe18d2146103625780637b167dfa1461036a5780637bb7bed11461038c57806386bc443e146103ac57806392815606146103cb578063aaf5eb68146103de578063ac4869f6146103ed575f5ffd5b80633d509c97116101475780633d509c97146102525780633e491d4714610265578063485cc9551461027857806348e5d9f81461028b5780635d0cde971461030a578063638634ee1461031257806364f78188146103255780636bc9b56114610338575f5ffd5b806304d0c2c5146101995780630a2976d5146101ae5780631be05289146101f95780631c03e6cc146102115780631e9b3a92146102245780632f2e36681461022c578063379607f51461023f575b5f5ffd5b6101ac6101a7366004612e43565b6104ba565b005b6101df6101bc366004612e43565b603a60209081525f92835260408084209091529082529020805460019091015482565b604080519283526020830191909152015b60405180910390f35b61020362093a8081565b6040519081526020016101f0565b6101ac61021f366004612e6d565b6106cd565b610203610703565b6101ac61023a366004612e6d565b6108e3565b6101ac61024d366004612e8f565b610d13565b6101ac610260366004612e6d565b6110cb565b610203610273366004612e43565b611494565b6101ac610286366004612ea6565b61167d565b6102d5610299366004612e6d565b60346020525f90815260409020805460018201546002830154600384015460048501546005860154600690960154949593949293919290919087565b604080519788526020880196909652948601939093526060850191909152608084015260a083015260c082015260e0016101f0565b610203603281565b610203610320366004612e6d565b6117f4565b6101ac610333366004612ef1565b611836565b610203610346366004612e43565b603860209081525f928352604080842090915290825290205481565b603754610203565b61037d610378366004612e8f565b6119c6565b6040516101f09392919061302c565b61039f61039a366004612e8f565b611d50565b6040516101f0919061306e565b6102036103ba366004612e6d565b60366020525f908152604090205481565b60325461039f906001600160a01b031681565b610203670de0b6b3a764000081565b61020369d3c21bcecceda100000081565b610203620f424081565b61042a610416366004612e6d565b60356020525f908152604090205460ff1681565b60405190151581526020016101f0565b6101ac610448366004612e43565b611d78565b61020361045b366004612e43565b603960209081525f928352604080842090915290825290205481565b6101ac610485366004612e6d565b61213a565b60335461039f906001600160a01b031681565b6102036121e1565b6104ad61225a565b6040516101f09190613082565b6033546001600160a01b031633146104e4576040516282b42960e81b815260040160405180910390fd5b6001600160a01b0382165f9081526035602052604090205460ff1661051c5760405163dfde867160e01b815260040160405180910390fd5b805f0361053c5760405163baf3f0f760e01b815260040160405180910390fd5b6040516370a0823160e01b81525f906001600160a01b038416906370a082319061056a90309060040161306e565b602060405180830381865afa158015610585573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906105a99190613094565b90506105c06001600160a01b0384163330856122ba565b5f81846001600160a01b03166370a08231306040518263ffffffff1660e01b81526004016105ee919061306e565b602060405180830381865afa158015610609573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061062d9190613094565b61063791906130bf565b6001600160a01b0385165f908152603460205260408120600401805492935083929091906106669084906130d2565b90915550506001600160a01b0384165f81815260346020908152604091829020600601548251938452908301849052908201527f09a4f557033a56cbe70db5ccef9534cbb73cbfe724512852e36e86e36d7a93b4906060015b60405180910390a150505050565b6033546001600160a01b031633146106f7576040516282b42960e81b815260040160405180910390fd5b6107008161232b565b50565b5f5f61070d61225a565b90505f5b81518110156108de575f82828151811061072d5761072d6130e5565b602002602001015190505f60325f9054906101000a90046001600160a01b03166001600160a01b031663900cf0cf6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610788573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906107ac9190613094565b905060015b8181116108d3576032546040516331a9108f60e11b8152600481018390526001600160a01b0390911690636352211e90602401602060405180830381865afa92505050801561081d575060408051601f3d908101601f1916820190925261081a918101906130f9565b60015b156108c1575f61082d8584611494565b905080156108425761083f81896130d2565b97505b6001600160a01b0385165f908152603a602090815260408083208684528252918290208251808401909352805480845260019091015491830191909152158015906108a957506001600160a01b0386165f9081526036602090815260409091205490820151105b156108bd5780516108ba908a6130d2565b98505b5050505b806108cb81613114565b9150506107b1565b505050600101610711565b505090565b6033546001600160a01b0316331461090d576040516282b42960e81b815260040160405180910390fd5b6001600160a01b0381165f9081526035602052604090205460ff166109455760405163dfde867160e01b815260040160405180910390fd5b6001600160a01b0381165f908152603460205260409020805442106109a45760405162461bcd60e51b815260206004820152601060248201526f139bc81858dd1a5d99481c195c9a5bd960821b60448201526064015b60405180910390fd5b600181015460058201546109b9908490612452565b60038301556109d0670de0b6b3a764000082613140565b60018301819055620f424011156109eb57620f424060018301555b6367e7385860028301819055610a0462093a80826130d2565b83556032546040805163900cf0cf60e01b815290515f926001600160a01b03169163900cf0cf9160048083019260209291908290030181865afa158015610a4d573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610a719190613094565b905060015b818111610d0b576032546040516331a9108f60e11b8152600481018390526001600160a01b0390911690636352211e90602401602060405180830381865afa925050508015610ae2575060408051601f3d908101601f19168201909252610adf918101906130f9565b60015b15610cf95760038601546001600160a01b0388165f90815260386020908152604080832086845290915290205481811115610cf5576001600160a01b0389165f90815260386020908152604080832087845290915281208390556002890154610b4e90610e1090613140565b610b5a90610e10613153565b603254604051636ed664a560e11b81526004810188905263ffffffff831660248201529192505f916001600160a01b039091169063ddacc94a90604401602060405180830381865afa158015610bb2573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610bd6919061316a565b6001600160801b031690508015610cf2576001600160a01b038b165f9081526038602090815260408083208984529091528120548511610c16575f610c43565b6001600160a01b038c165f9081526038602090815260408083208a8452909152902054610c4390866130bf565b90505f670de0b6b3a7640000610c598385613153565b610c639190613140565b6001600160a01b038e165f9081526039602090815260408083208c8452909152812080549293508392909190610c9a9084906130d2565b9091555050604080518981526001600160a01b038f166020820152908101829052606081018490527fdefe0aa5579373218fc5e22377d95459e6b9bbc450b520af03af84d0a9f2150a9060800160405180910390a150505b50505b5050505b80610d0381613114565b915050610a76565b505050505050565b610d1b61254c565b805f610d256121e1565b905080158015610d9d57506032546040805163900cf0cf60e01b815290515f926001600160a01b03169163900cf0cf9160048083019260209291908290030181865afa158015610d77573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610d9b9190613094565b115b15610dbb576040516318c8896960e11b815260040160405180910390fd5b5f5b603754811015610ee2575f60378281548110610ddb57610ddb6130e5565b5f9182526020808320909101546001600160a01b031680835260349091526040822060058101549193509190610e12908490612452565b600383018190559050610e24836117f4565b6002830155600582018590558515610ed75760038201546001600160a01b0384165f9081526038602090815260408083208a84529091529020541115610e8d5760038201546001600160a01b0384165f9081526038602090815260408083208a84529091529020555b610e978387611494565b6001600160a01b0384165f8181526039602090815260408083208b84528252808320949094556003860154928252603881528382208a8352905291909120555b505050600101610dbd565b506032546040516331a9108f60e11b81526004810185905233916001600160a01b031690636352211e90602401602060405180830381865afa158015610f2a573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610f4e91906130f9565b6001600160a01b031614610f74576040516282b42960e81b815260040160405180910390fd5b5f5f5f610f80866119c6565b92509250925082515f03610fa757604051630fec21fd60e21b815260040160405180910390fd5b5f5b83518110156110bc575f848281518110610fc557610fc56130e5565b602002602001015190505f848381518110610fe257610fe26130e5565b602002602001015190505f8111156110b2576001600160a01b0382165f9081526035602052604090205460ff1661102c5760405163dfde867160e01b815260040160405180910390fd5b6001600160a01b0382165f818152603460209081526040808320603983528184208e855283528184208490556003810154858552603884528285208f8652845282852055938352603a82528083208d845290915281205584516110b0908490339085908e908a908a9081106110a3576110a36130e5565b60200260200101516125a3565b505b5050600101610fa9565b50505050505061070060015f55565b6033546001600160a01b031633146110f5576040516282b42960e81b815260040160405180910390fd5b6001600160a01b0381165f9081526035602052604090205460ff1661112d5760405163dfde867160e01b815260040160405180910390fd5b6001600160a01b0381165f908152603460205260409020805442101561118d5760405162461bcd60e51b81526020600482015260156024820152741058dd1a5d99481c995dd85c991cc81c195c9a5bd9605a1b604482015260640161099b565b6004810154156111d15760405162461bcd60e51b815260206004820152600f60248201526e50656e64696e67207265776172647360881b604482015260640161099b565b6001600160a01b038083165f90815260366020908152604080832054603254825163900cf0cf60e01b815292519195169263900cf0cf92600480820193918290030181865afa158015611226573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061124a9190613094565b905060015b818111611327576032546040516331a9108f60e11b8152600481018390526001600160a01b0390911690636352211e90602401602060405180830381865afa9250505080156112bb575060408051601f3d908101601f191682019092526112b8918101906130f9565b60015b15611315575f6112cb8784611494565b905080156113125760408051808201825282815260208082018881526001600160a01b038b165f908152603a83528481208882529092529290209051815590516001909101555b50505b8061131f81613114565b91505061124f565b506001600160a01b0384165f908152603560205260409020805460ff191690556113528260016130d2565b6001600160a01b0385165f908152603660205260408120919091555b60375481101561146257846001600160a01b031660378281548110611395576113956130e5565b5f918252602090912001546001600160a01b03160361145a57603780546113be906001906130bf565b815481106113ce576113ce6130e5565b5f91825260209091200154603780546001600160a01b0390921691839081106113f9576113f96130e5565b905f5260205f20015f6101000a8154816001600160a01b0302191690836001600160a01b03160217905550603780548061143557611435613190565b5f8281526020902081015f1990810180546001600160a01b0319169055019055611462565b60010161136e565b507fbe0d2cc926911d1413d431090d31dd4a56de7770afb1245163f0e0ac7916db2184836040516106bf9291906131a4565b6001600160a01b038281165f9081526034602052604080822060325460028201549251636ed664a560e11b81526004810187905263ffffffff909316602484015292939092849291169063ddacc94a90604401602060405180830381865afa158015611502573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611526919061316a565b6001600160801b03169050805f03611542575f92505050611677565b5f8260020154611551876117f4565b11156115db575f8360020154611566886117f4565b61157091906130bf565b90505f8185600101546115839190613153565b90505f8560050154670de0b6b3a76400008361159f9190613153565b6115a99190613140565b9050801580156115b857505f83115b156115c1575060015b8086600301546115d191906130d2565b93505050506115e2565b5060038201545b6001600160a01b0386165f90815260386020908152604080832088845290915281205490818311611613575f61161d565b61161d82846130bf565b90505f670de0b6b3a76400006116338387613153565b61163d9190613140565b6001600160a01b038a165f9081526039602090815260408083208c845290915290205490915061166e9082906130d2565b96505050505050505b92915050565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a008054600160401b810460ff1615906001600160401b03165f811580156116c15750825b90505f826001600160401b031660011480156116dc5750303b155b9050811580156116ea575080155b156117085760405163f92ee8a960e01b815260040160405180910390fd5b845467ffffffffffffffff19166001178555831561173257845460ff60401b1916600160401b1785555b6001600160a01b038716158061174f57506001600160a01b038616155b1561176d5760405163d92e233d60e01b815260040160405180910390fd5b611775612b4b565b603280546001600160a01b03808a166001600160a01b031992831617909255603380549289169290911691909117905583156117eb57845460ff60401b19168555604051600181527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b50505050505050565b6001600160a01b0381165f90815260346020526040812054421061182f576001600160a01b0382165f90815260346020526040902054611677565b4292915050565b6033546001600160a01b03163314611860576040516282b42960e81b815260040160405180910390fd5b603281511115611883576040516303451c2960e21b815260040160405180910390fd5b603754156118d35760405162461bcd60e51b815260206004820152601a60248201527f546f6b656e7320616c726561647920696e697469616c697a6564000000000000604482015260640161099b565b5f5b815181101561198c575f6118ea8260016130d2565b90505b825181101561198357828181518110611908576119086130e5565b60200260200101516001600160a01b031683838151811061192b5761192b6130e5565b60200260200101516001600160a01b03160361197b5760405162461bcd60e51b815260206004820152600f60248201526e223ab83634b1b0ba32903a37b5b2b760891b604482015260640161099b565b6001016118ed565b506001016118d5565b505f5b81518110156119c2576119ba8282815181106119ad576119ad6130e5565b602002602001015161232b565b60010161198f565b5050565b6032546040516331a9108f60e11b815260048101839052606091829182915f916001600160a01b0390911690636352211e90602401602060405180830381865afa158015611a16573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611a3a91906130f9565b90506001600160a01b038116611a635760405163baf3f0f760e01b815260040160405180910390fd5b5f611a6c61225a565b905080516002611a7c9190613153565b6001600160401b03811115611a9357611a93612edd565b604051908082528060200260200182016040528015611abc578160200160208202803683370190505b50945080516002611acd9190613153565b6001600160401b03811115611ae457611ae4612edd565b604051908082528060200260200182016040528015611b0d578160200160208202803683370190505b50935080516002611b1e9190613153565b6001600160401b03811115611b3557611b35612edd565b604051908082528060200260200182016040528015611b5e578160200160208202803683370190505b5092505f805b8251811015611d3d575f838281518110611b8057611b806130e5565b602002602001015190505f611b95828b611494565b90508015611c415781898581518110611bb057611bb06130e5565b60200260200101906001600160a01b031690816001600160a01b03168152505080888581518110611be357611be36130e5565b60200260200101818152505060345f836001600160a01b03166001600160a01b031681526020019081526020015f2060060154878581518110611c2857611c286130e5565b602090810291909101015283611c3d81613114565b9450505b6001600160a01b0382165f908152603a602090815260408083208d8452825291829020825180840190935280548084526001909101549183019190915215801590611ca857506001600160a01b0383165f9081526036602090815260409091205490820151105b15611d3257828a8681518110611cc057611cc06130e5565b60200260200101906001600160a01b031690816001600160a01b031681525050805f0151898681518110611cf657611cf66130e5565b6020026020010181815250508060200151888681518110611d1957611d196130e5565b602090810291909101015284611d2e81613114565b9550505b505050600101611b64565b5080865280855283525092949193509150565b60378181548110611d5f575f80fd5b5f918252602090912001546001600160a01b0316905081565b6033546001600160a01b03163314611da2576040516282b42960e81b815260040160405180910390fd5b6001600160a01b0382165f9081526035602052604090205460ff16611dda5760405163dfde867160e01b815260040160405180910390fd5b805f03611dfa5760405163baf3f0f760e01b815260040160405180910390fd5b6040516370a0823160e01b81525f906001600160a01b038416906370a0823190611e2890309060040161306e565b602060405180830381865afa158015611e43573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611e679190613094565b905081811015611e8a57604051631e9acf1760e31b815260040160405180910390fd5b6001600160a01b0383165f9081526034602052604081206002810154909103611ee3576001600160a01b0384165f908152603660205260408120805491611ed083613114565b9190505550611edd6121e1565b60058201555b60028101545f9015801590611ef85750815442105b15611f0d578154611f0a9042906130bf565b90505b5f8115801590611f2057505f8360010154115b15611f7c57611f30825f19613140565b83600101541115611f5657611f4f8269d3c21bcecceda1000000613153565b9050611f7c565b670de0b6b3a7640000828460010154611f6f9190613153565b611f799190613140565b90505b60048301545f90611f8d83886130d2565b611f9791906130d2565b90508069d3c21bcecceda100000086821115611fb1578691505b80821115611fbd578091505b5f60048701819055821561205f575f62093a80611fe2670de0b6b3a764000086613153565b611fec9190613140565b90505f612003670de0b6b3a76400006103e8613153565b905080821115612011578091505b81925069d3c21bcecceda10000008311156120345769d3c21bcecceda100000092505b620f424083101561205857604051635cf4d02960e01b815260040160405180910390fd5b5050612078565b604051635cf4d02960e01b815260040160405180910390fd5b6001870181905542600288018190556120959062093a80906130d2565b87555f6120a06121e1565b9050670de0b6b3a764000081106120b757806120c1565b670de0b6b3a76400005b600589018190556120d3908c90612452565b60038901556006880154604080516001600160a01b038e168152602081018790528082018590526060810192909252517f0727302becd070529b3293f4ec8f553d9f6ae1773f638598db1205fbf89080839181900360800190a15050505050505050505050565b6033546001600160a01b03163314612164576040516282b42960e81b815260040160405180910390fd5b6001600160a01b03811661218b5760405163d92e233d60e01b815260040160405180910390fd5b603380546001600160a01b0319166001600160a01b0383161790556040517fc0ebb188f905d128bcd7e4282dd1f9cf24cd331b69071002e488349aca6a867b906121d690839061306e565b60405180910390a150565b6032546040805163268dc19960e01b815290515f926001600160a01b03169163268dc1999160048083019260209291908290030181865afa158015612228573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061224c919061316a565b6001600160801b0316905090565b606060378054806020026020016040519081016040528092919081815260200182805480156122b057602002820191905f5260205f20905b81546001600160a01b03168152600190910190602001808311612292575b5050505050905090565b6040516001600160a01b03808516602483015283166044820152606481018290526123259085906323b872dd60e01b906084015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152612b5d565b50505050565b6001600160a01b0381166123525760405163d92e233d60e01b815260040160405180910390fd5b6001600160a01b0381165f9081526035602052604090205460ff161561238b5760405163630b374b60e01b815260040160405180910390fd5b6037805460018082019092557f42a7b7dd785cd69714a189dffb3fd7d7174edc9ece837694ce50f7078f7c31ae0180546001600160a01b0319166001600160a01b0384169081179091555f908152603560209081526040808320805460ff1916851790556036808352818420948555603483528184206005810194909455909152915460068201819055915190917f68e3e9397770d9dfa88c0953a34e1a70a05416b3895957f5b689787a920791c4916124469185916131a4565b60405180910390a15050565b6001600160a01b0382165f90815260346020526040812082158061248e57506001600160a01b0384165f9081526035602052604090205460ff16155b1561249e57600301549050611677565b5f81600201546124ad866117f4565b6124b791906130bf565b9050805f036124cc5750600301549050611677565b670de0b6b3a76400008410156124e857670de0b6b3a764000093505b5f8183600101546124f99190613153565b90505f8561250f670de0b6b3a764000084613153565b6125199190613140565b90508015801561252857505f83115b15612531575060015b80846003015461254191906130d2565b979650505050505050565b60025f540361259d5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015260640161099b565b60025f55565b8215612b3e5760325f9054906101000a90046001600160a01b03166001600160a01b0316630f45cc816040518163ffffffff1660e01b8152600401602060405180830381865afa1580156125f9573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061261d91906130f9565b6001600160a01b0316856001600160a01b03160361293d576001600160801b0383111561267f5760405162461bcd60e51b815260206004820152601060248201526f416d6f756e7420746f6f206c6172676560801b604482015260640161099b565b603254604051638b25e8c160e01b8152600481018490525f916001600160a01b031690638b25e8c190602401602060405180830381865afa1580156126c6573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906126ea919061316a565b9050806001600160801b03165f036127395760405162461bcd60e51b815260206004820152601260248201527124b73b30b634b21036bab63a34b83634b2b960711b604482015260640161099b565b5f606461274783605f6131bd565b61275191906131e6565b60325460405163095ea7b360e01b81529192506001600160a01b03808a169263095ea7b39261278692169089906004016131a4565b6020604051808303815f875af11580156127a2573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906127c69190613214565b5060325460405163beb8310960e01b8152600481018690526001600160801b038088166024830152426044830152831660648201526001600160a01b039091169063beb83109906084015f604051808303815f87803b158015612827575f5ffd5b505af1925050508015612838575060015b6128f05760325460405163095ea7b360e01b81526001600160a01b038981169263095ea7b39261287092909116905f906004016131a4565b6020604051808303815f875af115801561288c573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906128b09190613214565b5060405162461bcd60e51b8152602060048201526014602482015273105d5d1bcb58dbdb5c1bdd5b990819985a5b195960621b604482015260640161099b565b60408051868152602081018590526001600160a01b0389169186917f85beda9bf1ef844bb2472cc053c13557032d6e187a546b4c640e86dcd8201e39910160405180910390a35050612b3e565b6040516370a0823160e01b81525f906001600160a01b038716906370a082319061296b90309060040161306e565b602060405180830381865afa158015612986573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906129aa9190613094565b9050838110156129cd57604051631e9acf1760e31b815260040160405180910390fd5b6040516370a0823160e01b81525f906001600160a01b038816906370a08231906129fb90899060040161306e565b602060405180830381865afa158015612a16573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612a3a9190613094565b9050612a506001600160a01b0388168787612c35565b6040516370a0823160e01b81525f906001600160a01b038916906370a0823190612a7e908a9060040161306e565b602060405180830381865afa158015612a99573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612abd9190613094565b9050818111612adf576040516312171d8360e31b815260040160405180910390fd5b5f612aea83836130bf565b9050886001600160a01b0316867f85beda9bf1ef844bb2472cc053c13557032d6e187a546b4c640e86dcd8201e398388604051612b31929190918252602082015260400190565b60405180910390a3505050505b5050505050565b60015f55565b612b53612c54565b612b5b612c9d565b565b5f612bb1826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316612ca59092919063ffffffff16565b905080515f1480612bd1575080806020019051810190612bd19190613214565b612c305760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b606482015260840161099b565b505050565b612c308363a9059cbb60e01b84846040516024016122ee9291906131a4565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a0054600160401b900460ff16612b5b57604051631afcd79f60e31b815260040160405180910390fd5b612b45612c54565b6060612cb384845f85612cbb565b949350505050565b606082471015612d1c5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b606482015260840161099b565b5f5f866001600160a01b03168587604051612d379190613233565b5f6040518083038185875af1925050503d805f8114612d71576040519150601f19603f3d011682016040523d82523d5f602084013e612d76565b606091505b50915091506125418783838760608315612df05782515f03612de9576001600160a01b0385163b612de95760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640161099b565b5081612cb3565b612cb38383815115612e055781518083602001fd5b8060405162461bcd60e51b815260040161099b9190613249565b6001600160a01b0381168114610700575f5ffd5b8035612e3e81612e1f565b919050565b5f5f60408385031215612e54575f5ffd5b8235612e5f81612e1f565b946020939093013593505050565b5f60208284031215612e7d575f5ffd5b8135612e8881612e1f565b9392505050565b5f60208284031215612e9f575f5ffd5b5035919050565b5f5f60408385031215612eb7575f5ffd5b8235612ec281612e1f565b91506020830135612ed281612e1f565b809150509250929050565b634e487b7160e01b5f52604160045260245ffd5b5f60208284031215612f01575f5ffd5b81356001600160401b03811115612f16575f5ffd5b8201601f81018413612f26575f5ffd5b80356001600160401b03811115612f3f57612f3f612edd565b8060051b604051601f19603f83011681018181106001600160401b0382111715612f6b57612f6b612edd565b604052918252602081840181019290810187841115612f88575f5ffd5b6020850194505b83851015612fae57612fa085612e33565b815260209485019401612f8f565b509695505050505050565b5f8151808452602084019350602083015f5b82811015612ff25781516001600160a01b0316865260209586019590910190600101612fcb565b5093949350505050565b5f8151808452602084019350602083015f5b82811015612ff257815186526020958601959091019060010161300e565b606081525f61303e6060830186612fb9565b82810360208401526130508186612ffc565b905082810360408401526130648185612ffc565b9695505050505050565b6001600160a01b0391909116815260200190565b602081525f612e886020830184612fb9565b5f602082840312156130a4575f5ffd5b5051919050565b634e487b7160e01b5f52601160045260245ffd5b81810381811115611677576116776130ab565b80820180821115611677576116776130ab565b634e487b7160e01b5f52603260045260245ffd5b5f60208284031215613109575f5ffd5b8151612e8881612e1f565b5f60018201613125576131256130ab565b5060010190565b634e487b7160e01b5f52601260045260245ffd5b5f8261314e5761314e61312c565b500490565b8082028115828204841417611677576116776130ab565b5f6020828403121561317a575f5ffd5b81516001600160801b0381168114612e88575f5ffd5b634e487b7160e01b5f52603160045260245ffd5b6001600160a01b03929092168252602082015260400190565b6001600160801b0381811683821602908116908181146131df576131df6130ab565b5092915050565b5f6001600160801b038316806131fe576131fe61312c565b6001600160801b03929092169190910492915050565b5f60208284031215613224575f5ffd5b81518015158114612e88575f5ffd5b5f82518060208501845e5f920191825250919050565b602081525f82518060208401528060208501604085015e5f604082850101526040601f19601f8301168401019150509291505056fea264697066735822122027f6dc952cc1b9fea92872f455eb2595333fc3485db421cd422d0a3dbfddfef164736f6c634300081b0033
Deployed Bytecode
0x608060405234801561000f575f5ffd5b5060043610610195575f3560e01c80637abe18d2116100e0578063b2be1ef41161008f578063b2be1ef4146103fe578063b5fd73f814610408578063b66503cf1461043a578063b933ceac1461044d578063bc30a61814610477578063bfe109281461048a578063c4e41b221461049d578063c4f59f9b146104a5575f5ffd5b80637abe18d2146103625780637b167dfa1461036a5780637bb7bed11461038c57806386bc443e146103ac57806392815606146103cb578063aaf5eb68146103de578063ac4869f6146103ed575f5ffd5b80633d509c97116101475780633d509c97146102525780633e491d4714610265578063485cc9551461027857806348e5d9f81461028b5780635d0cde971461030a578063638634ee1461031257806364f78188146103255780636bc9b56114610338575f5ffd5b806304d0c2c5146101995780630a2976d5146101ae5780631be05289146101f95780631c03e6cc146102115780631e9b3a92146102245780632f2e36681461022c578063379607f51461023f575b5f5ffd5b6101ac6101a7366004612e43565b6104ba565b005b6101df6101bc366004612e43565b603a60209081525f92835260408084209091529082529020805460019091015482565b604080519283526020830191909152015b60405180910390f35b61020362093a8081565b6040519081526020016101f0565b6101ac61021f366004612e6d565b6106cd565b610203610703565b6101ac61023a366004612e6d565b6108e3565b6101ac61024d366004612e8f565b610d13565b6101ac610260366004612e6d565b6110cb565b610203610273366004612e43565b611494565b6101ac610286366004612ea6565b61167d565b6102d5610299366004612e6d565b60346020525f90815260409020805460018201546002830154600384015460048501546005860154600690960154949593949293919290919087565b604080519788526020880196909652948601939093526060850191909152608084015260a083015260c082015260e0016101f0565b610203603281565b610203610320366004612e6d565b6117f4565b6101ac610333366004612ef1565b611836565b610203610346366004612e43565b603860209081525f928352604080842090915290825290205481565b603754610203565b61037d610378366004612e8f565b6119c6565b6040516101f09392919061302c565b61039f61039a366004612e8f565b611d50565b6040516101f0919061306e565b6102036103ba366004612e6d565b60366020525f908152604090205481565b60325461039f906001600160a01b031681565b610203670de0b6b3a764000081565b61020369d3c21bcecceda100000081565b610203620f424081565b61042a610416366004612e6d565b60356020525f908152604090205460ff1681565b60405190151581526020016101f0565b6101ac610448366004612e43565b611d78565b61020361045b366004612e43565b603960209081525f928352604080842090915290825290205481565b6101ac610485366004612e6d565b61213a565b60335461039f906001600160a01b031681565b6102036121e1565b6104ad61225a565b6040516101f09190613082565b6033546001600160a01b031633146104e4576040516282b42960e81b815260040160405180910390fd5b6001600160a01b0382165f9081526035602052604090205460ff1661051c5760405163dfde867160e01b815260040160405180910390fd5b805f0361053c5760405163baf3f0f760e01b815260040160405180910390fd5b6040516370a0823160e01b81525f906001600160a01b038416906370a082319061056a90309060040161306e565b602060405180830381865afa158015610585573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906105a99190613094565b90506105c06001600160a01b0384163330856122ba565b5f81846001600160a01b03166370a08231306040518263ffffffff1660e01b81526004016105ee919061306e565b602060405180830381865afa158015610609573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061062d9190613094565b61063791906130bf565b6001600160a01b0385165f908152603460205260408120600401805492935083929091906106669084906130d2565b90915550506001600160a01b0384165f81815260346020908152604091829020600601548251938452908301849052908201527f09a4f557033a56cbe70db5ccef9534cbb73cbfe724512852e36e86e36d7a93b4906060015b60405180910390a150505050565b6033546001600160a01b031633146106f7576040516282b42960e81b815260040160405180910390fd5b6107008161232b565b50565b5f5f61070d61225a565b90505f5b81518110156108de575f82828151811061072d5761072d6130e5565b602002602001015190505f60325f9054906101000a90046001600160a01b03166001600160a01b031663900cf0cf6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610788573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906107ac9190613094565b905060015b8181116108d3576032546040516331a9108f60e11b8152600481018390526001600160a01b0390911690636352211e90602401602060405180830381865afa92505050801561081d575060408051601f3d908101601f1916820190925261081a918101906130f9565b60015b156108c1575f61082d8584611494565b905080156108425761083f81896130d2565b97505b6001600160a01b0385165f908152603a602090815260408083208684528252918290208251808401909352805480845260019091015491830191909152158015906108a957506001600160a01b0386165f9081526036602090815260409091205490820151105b156108bd5780516108ba908a6130d2565b98505b5050505b806108cb81613114565b9150506107b1565b505050600101610711565b505090565b6033546001600160a01b0316331461090d576040516282b42960e81b815260040160405180910390fd5b6001600160a01b0381165f9081526035602052604090205460ff166109455760405163dfde867160e01b815260040160405180910390fd5b6001600160a01b0381165f908152603460205260409020805442106109a45760405162461bcd60e51b815260206004820152601060248201526f139bc81858dd1a5d99481c195c9a5bd960821b60448201526064015b60405180910390fd5b600181015460058201546109b9908490612452565b60038301556109d0670de0b6b3a764000082613140565b60018301819055620f424011156109eb57620f424060018301555b6367e7385860028301819055610a0462093a80826130d2565b83556032546040805163900cf0cf60e01b815290515f926001600160a01b03169163900cf0cf9160048083019260209291908290030181865afa158015610a4d573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610a719190613094565b905060015b818111610d0b576032546040516331a9108f60e11b8152600481018390526001600160a01b0390911690636352211e90602401602060405180830381865afa925050508015610ae2575060408051601f3d908101601f19168201909252610adf918101906130f9565b60015b15610cf95760038601546001600160a01b0388165f90815260386020908152604080832086845290915290205481811115610cf5576001600160a01b0389165f90815260386020908152604080832087845290915281208390556002890154610b4e90610e1090613140565b610b5a90610e10613153565b603254604051636ed664a560e11b81526004810188905263ffffffff831660248201529192505f916001600160a01b039091169063ddacc94a90604401602060405180830381865afa158015610bb2573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610bd6919061316a565b6001600160801b031690508015610cf2576001600160a01b038b165f9081526038602090815260408083208984529091528120548511610c16575f610c43565b6001600160a01b038c165f9081526038602090815260408083208a8452909152902054610c4390866130bf565b90505f670de0b6b3a7640000610c598385613153565b610c639190613140565b6001600160a01b038e165f9081526039602090815260408083208c8452909152812080549293508392909190610c9a9084906130d2565b9091555050604080518981526001600160a01b038f166020820152908101829052606081018490527fdefe0aa5579373218fc5e22377d95459e6b9bbc450b520af03af84d0a9f2150a9060800160405180910390a150505b50505b5050505b80610d0381613114565b915050610a76565b505050505050565b610d1b61254c565b805f610d256121e1565b905080158015610d9d57506032546040805163900cf0cf60e01b815290515f926001600160a01b03169163900cf0cf9160048083019260209291908290030181865afa158015610d77573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610d9b9190613094565b115b15610dbb576040516318c8896960e11b815260040160405180910390fd5b5f5b603754811015610ee2575f60378281548110610ddb57610ddb6130e5565b5f9182526020808320909101546001600160a01b031680835260349091526040822060058101549193509190610e12908490612452565b600383018190559050610e24836117f4565b6002830155600582018590558515610ed75760038201546001600160a01b0384165f9081526038602090815260408083208a84529091529020541115610e8d5760038201546001600160a01b0384165f9081526038602090815260408083208a84529091529020555b610e978387611494565b6001600160a01b0384165f8181526039602090815260408083208b84528252808320949094556003860154928252603881528382208a8352905291909120555b505050600101610dbd565b506032546040516331a9108f60e11b81526004810185905233916001600160a01b031690636352211e90602401602060405180830381865afa158015610f2a573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610f4e91906130f9565b6001600160a01b031614610f74576040516282b42960e81b815260040160405180910390fd5b5f5f5f610f80866119c6565b92509250925082515f03610fa757604051630fec21fd60e21b815260040160405180910390fd5b5f5b83518110156110bc575f848281518110610fc557610fc56130e5565b602002602001015190505f848381518110610fe257610fe26130e5565b602002602001015190505f8111156110b2576001600160a01b0382165f9081526035602052604090205460ff1661102c5760405163dfde867160e01b815260040160405180910390fd5b6001600160a01b0382165f818152603460209081526040808320603983528184208e855283528184208490556003810154858552603884528285208f8652845282852055938352603a82528083208d845290915281205584516110b0908490339085908e908a908a9081106110a3576110a36130e5565b60200260200101516125a3565b505b5050600101610fa9565b50505050505061070060015f55565b6033546001600160a01b031633146110f5576040516282b42960e81b815260040160405180910390fd5b6001600160a01b0381165f9081526035602052604090205460ff1661112d5760405163dfde867160e01b815260040160405180910390fd5b6001600160a01b0381165f908152603460205260409020805442101561118d5760405162461bcd60e51b81526020600482015260156024820152741058dd1a5d99481c995dd85c991cc81c195c9a5bd9605a1b604482015260640161099b565b6004810154156111d15760405162461bcd60e51b815260206004820152600f60248201526e50656e64696e67207265776172647360881b604482015260640161099b565b6001600160a01b038083165f90815260366020908152604080832054603254825163900cf0cf60e01b815292519195169263900cf0cf92600480820193918290030181865afa158015611226573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061124a9190613094565b905060015b818111611327576032546040516331a9108f60e11b8152600481018390526001600160a01b0390911690636352211e90602401602060405180830381865afa9250505080156112bb575060408051601f3d908101601f191682019092526112b8918101906130f9565b60015b15611315575f6112cb8784611494565b905080156113125760408051808201825282815260208082018881526001600160a01b038b165f908152603a83528481208882529092529290209051815590516001909101555b50505b8061131f81613114565b91505061124f565b506001600160a01b0384165f908152603560205260409020805460ff191690556113528260016130d2565b6001600160a01b0385165f908152603660205260408120919091555b60375481101561146257846001600160a01b031660378281548110611395576113956130e5565b5f918252602090912001546001600160a01b03160361145a57603780546113be906001906130bf565b815481106113ce576113ce6130e5565b5f91825260209091200154603780546001600160a01b0390921691839081106113f9576113f96130e5565b905f5260205f20015f6101000a8154816001600160a01b0302191690836001600160a01b03160217905550603780548061143557611435613190565b5f8281526020902081015f1990810180546001600160a01b0319169055019055611462565b60010161136e565b507fbe0d2cc926911d1413d431090d31dd4a56de7770afb1245163f0e0ac7916db2184836040516106bf9291906131a4565b6001600160a01b038281165f9081526034602052604080822060325460028201549251636ed664a560e11b81526004810187905263ffffffff909316602484015292939092849291169063ddacc94a90604401602060405180830381865afa158015611502573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611526919061316a565b6001600160801b03169050805f03611542575f92505050611677565b5f8260020154611551876117f4565b11156115db575f8360020154611566886117f4565b61157091906130bf565b90505f8185600101546115839190613153565b90505f8560050154670de0b6b3a76400008361159f9190613153565b6115a99190613140565b9050801580156115b857505f83115b156115c1575060015b8086600301546115d191906130d2565b93505050506115e2565b5060038201545b6001600160a01b0386165f90815260386020908152604080832088845290915281205490818311611613575f61161d565b61161d82846130bf565b90505f670de0b6b3a76400006116338387613153565b61163d9190613140565b6001600160a01b038a165f9081526039602090815260408083208c845290915290205490915061166e9082906130d2565b96505050505050505b92915050565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a008054600160401b810460ff1615906001600160401b03165f811580156116c15750825b90505f826001600160401b031660011480156116dc5750303b155b9050811580156116ea575080155b156117085760405163f92ee8a960e01b815260040160405180910390fd5b845467ffffffffffffffff19166001178555831561173257845460ff60401b1916600160401b1785555b6001600160a01b038716158061174f57506001600160a01b038616155b1561176d5760405163d92e233d60e01b815260040160405180910390fd5b611775612b4b565b603280546001600160a01b03808a166001600160a01b031992831617909255603380549289169290911691909117905583156117eb57845460ff60401b19168555604051600181527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b50505050505050565b6001600160a01b0381165f90815260346020526040812054421061182f576001600160a01b0382165f90815260346020526040902054611677565b4292915050565b6033546001600160a01b03163314611860576040516282b42960e81b815260040160405180910390fd5b603281511115611883576040516303451c2960e21b815260040160405180910390fd5b603754156118d35760405162461bcd60e51b815260206004820152601a60248201527f546f6b656e7320616c726561647920696e697469616c697a6564000000000000604482015260640161099b565b5f5b815181101561198c575f6118ea8260016130d2565b90505b825181101561198357828181518110611908576119086130e5565b60200260200101516001600160a01b031683838151811061192b5761192b6130e5565b60200260200101516001600160a01b03160361197b5760405162461bcd60e51b815260206004820152600f60248201526e223ab83634b1b0ba32903a37b5b2b760891b604482015260640161099b565b6001016118ed565b506001016118d5565b505f5b81518110156119c2576119ba8282815181106119ad576119ad6130e5565b602002602001015161232b565b60010161198f565b5050565b6032546040516331a9108f60e11b815260048101839052606091829182915f916001600160a01b0390911690636352211e90602401602060405180830381865afa158015611a16573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611a3a91906130f9565b90506001600160a01b038116611a635760405163baf3f0f760e01b815260040160405180910390fd5b5f611a6c61225a565b905080516002611a7c9190613153565b6001600160401b03811115611a9357611a93612edd565b604051908082528060200260200182016040528015611abc578160200160208202803683370190505b50945080516002611acd9190613153565b6001600160401b03811115611ae457611ae4612edd565b604051908082528060200260200182016040528015611b0d578160200160208202803683370190505b50935080516002611b1e9190613153565b6001600160401b03811115611b3557611b35612edd565b604051908082528060200260200182016040528015611b5e578160200160208202803683370190505b5092505f805b8251811015611d3d575f838281518110611b8057611b806130e5565b602002602001015190505f611b95828b611494565b90508015611c415781898581518110611bb057611bb06130e5565b60200260200101906001600160a01b031690816001600160a01b03168152505080888581518110611be357611be36130e5565b60200260200101818152505060345f836001600160a01b03166001600160a01b031681526020019081526020015f2060060154878581518110611c2857611c286130e5565b602090810291909101015283611c3d81613114565b9450505b6001600160a01b0382165f908152603a602090815260408083208d8452825291829020825180840190935280548084526001909101549183019190915215801590611ca857506001600160a01b0383165f9081526036602090815260409091205490820151105b15611d3257828a8681518110611cc057611cc06130e5565b60200260200101906001600160a01b031690816001600160a01b031681525050805f0151898681518110611cf657611cf66130e5565b6020026020010181815250508060200151888681518110611d1957611d196130e5565b602090810291909101015284611d2e81613114565b9550505b505050600101611b64565b5080865280855283525092949193509150565b60378181548110611d5f575f80fd5b5f918252602090912001546001600160a01b0316905081565b6033546001600160a01b03163314611da2576040516282b42960e81b815260040160405180910390fd5b6001600160a01b0382165f9081526035602052604090205460ff16611dda5760405163dfde867160e01b815260040160405180910390fd5b805f03611dfa5760405163baf3f0f760e01b815260040160405180910390fd5b6040516370a0823160e01b81525f906001600160a01b038416906370a0823190611e2890309060040161306e565b602060405180830381865afa158015611e43573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611e679190613094565b905081811015611e8a57604051631e9acf1760e31b815260040160405180910390fd5b6001600160a01b0383165f9081526034602052604081206002810154909103611ee3576001600160a01b0384165f908152603660205260408120805491611ed083613114565b9190505550611edd6121e1565b60058201555b60028101545f9015801590611ef85750815442105b15611f0d578154611f0a9042906130bf565b90505b5f8115801590611f2057505f8360010154115b15611f7c57611f30825f19613140565b83600101541115611f5657611f4f8269d3c21bcecceda1000000613153565b9050611f7c565b670de0b6b3a7640000828460010154611f6f9190613153565b611f799190613140565b90505b60048301545f90611f8d83886130d2565b611f9791906130d2565b90508069d3c21bcecceda100000086821115611fb1578691505b80821115611fbd578091505b5f60048701819055821561205f575f62093a80611fe2670de0b6b3a764000086613153565b611fec9190613140565b90505f612003670de0b6b3a76400006103e8613153565b905080821115612011578091505b81925069d3c21bcecceda10000008311156120345769d3c21bcecceda100000092505b620f424083101561205857604051635cf4d02960e01b815260040160405180910390fd5b5050612078565b604051635cf4d02960e01b815260040160405180910390fd5b6001870181905542600288018190556120959062093a80906130d2565b87555f6120a06121e1565b9050670de0b6b3a764000081106120b757806120c1565b670de0b6b3a76400005b600589018190556120d3908c90612452565b60038901556006880154604080516001600160a01b038e168152602081018790528082018590526060810192909252517f0727302becd070529b3293f4ec8f553d9f6ae1773f638598db1205fbf89080839181900360800190a15050505050505050505050565b6033546001600160a01b03163314612164576040516282b42960e81b815260040160405180910390fd5b6001600160a01b03811661218b5760405163d92e233d60e01b815260040160405180910390fd5b603380546001600160a01b0319166001600160a01b0383161790556040517fc0ebb188f905d128bcd7e4282dd1f9cf24cd331b69071002e488349aca6a867b906121d690839061306e565b60405180910390a150565b6032546040805163268dc19960e01b815290515f926001600160a01b03169163268dc1999160048083019260209291908290030181865afa158015612228573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061224c919061316a565b6001600160801b0316905090565b606060378054806020026020016040519081016040528092919081815260200182805480156122b057602002820191905f5260205f20905b81546001600160a01b03168152600190910190602001808311612292575b5050505050905090565b6040516001600160a01b03808516602483015283166044820152606481018290526123259085906323b872dd60e01b906084015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152612b5d565b50505050565b6001600160a01b0381166123525760405163d92e233d60e01b815260040160405180910390fd5b6001600160a01b0381165f9081526035602052604090205460ff161561238b5760405163630b374b60e01b815260040160405180910390fd5b6037805460018082019092557f42a7b7dd785cd69714a189dffb3fd7d7174edc9ece837694ce50f7078f7c31ae0180546001600160a01b0319166001600160a01b0384169081179091555f908152603560209081526040808320805460ff1916851790556036808352818420948555603483528184206005810194909455909152915460068201819055915190917f68e3e9397770d9dfa88c0953a34e1a70a05416b3895957f5b689787a920791c4916124469185916131a4565b60405180910390a15050565b6001600160a01b0382165f90815260346020526040812082158061248e57506001600160a01b0384165f9081526035602052604090205460ff16155b1561249e57600301549050611677565b5f81600201546124ad866117f4565b6124b791906130bf565b9050805f036124cc5750600301549050611677565b670de0b6b3a76400008410156124e857670de0b6b3a764000093505b5f8183600101546124f99190613153565b90505f8561250f670de0b6b3a764000084613153565b6125199190613140565b90508015801561252857505f83115b15612531575060015b80846003015461254191906130d2565b979650505050505050565b60025f540361259d5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015260640161099b565b60025f55565b8215612b3e5760325f9054906101000a90046001600160a01b03166001600160a01b0316630f45cc816040518163ffffffff1660e01b8152600401602060405180830381865afa1580156125f9573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061261d91906130f9565b6001600160a01b0316856001600160a01b03160361293d576001600160801b0383111561267f5760405162461bcd60e51b815260206004820152601060248201526f416d6f756e7420746f6f206c6172676560801b604482015260640161099b565b603254604051638b25e8c160e01b8152600481018490525f916001600160a01b031690638b25e8c190602401602060405180830381865afa1580156126c6573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906126ea919061316a565b9050806001600160801b03165f036127395760405162461bcd60e51b815260206004820152601260248201527124b73b30b634b21036bab63a34b83634b2b960711b604482015260640161099b565b5f606461274783605f6131bd565b61275191906131e6565b60325460405163095ea7b360e01b81529192506001600160a01b03808a169263095ea7b39261278692169089906004016131a4565b6020604051808303815f875af11580156127a2573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906127c69190613214565b5060325460405163beb8310960e01b8152600481018690526001600160801b038088166024830152426044830152831660648201526001600160a01b039091169063beb83109906084015f604051808303815f87803b158015612827575f5ffd5b505af1925050508015612838575060015b6128f05760325460405163095ea7b360e01b81526001600160a01b038981169263095ea7b39261287092909116905f906004016131a4565b6020604051808303815f875af115801561288c573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906128b09190613214565b5060405162461bcd60e51b8152602060048201526014602482015273105d5d1bcb58dbdb5c1bdd5b990819985a5b195960621b604482015260640161099b565b60408051868152602081018590526001600160a01b0389169186917f85beda9bf1ef844bb2472cc053c13557032d6e187a546b4c640e86dcd8201e39910160405180910390a35050612b3e565b6040516370a0823160e01b81525f906001600160a01b038716906370a082319061296b90309060040161306e565b602060405180830381865afa158015612986573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906129aa9190613094565b9050838110156129cd57604051631e9acf1760e31b815260040160405180910390fd5b6040516370a0823160e01b81525f906001600160a01b038816906370a08231906129fb90899060040161306e565b602060405180830381865afa158015612a16573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612a3a9190613094565b9050612a506001600160a01b0388168787612c35565b6040516370a0823160e01b81525f906001600160a01b038916906370a0823190612a7e908a9060040161306e565b602060405180830381865afa158015612a99573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612abd9190613094565b9050818111612adf576040516312171d8360e31b815260040160405180910390fd5b5f612aea83836130bf565b9050886001600160a01b0316867f85beda9bf1ef844bb2472cc053c13557032d6e187a546b4c640e86dcd8201e398388604051612b31929190918252602082015260400190565b60405180910390a3505050505b5050505050565b60015f55565b612b53612c54565b612b5b612c9d565b565b5f612bb1826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316612ca59092919063ffffffff16565b905080515f1480612bd1575080806020019051810190612bd19190613214565b612c305760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b606482015260840161099b565b505050565b612c308363a9059cbb60e01b84846040516024016122ee9291906131a4565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a0054600160401b900460ff16612b5b57604051631afcd79f60e31b815260040160405180910390fd5b612b45612c54565b6060612cb384845f85612cbb565b949350505050565b606082471015612d1c5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b606482015260840161099b565b5f5f866001600160a01b03168587604051612d379190613233565b5f6040518083038185875af1925050503d805f8114612d71576040519150601f19603f3d011682016040523d82523d5f602084013e612d76565b606091505b50915091506125418783838760608315612df05782515f03612de9576001600160a01b0385163b612de95760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640161099b565b5081612cb3565b612cb38383815115612e055781518083602001fd5b8060405162461bcd60e51b815260040161099b9190613249565b6001600160a01b0381168114610700575f5ffd5b8035612e3e81612e1f565b919050565b5f5f60408385031215612e54575f5ffd5b8235612e5f81612e1f565b946020939093013593505050565b5f60208284031215612e7d575f5ffd5b8135612e8881612e1f565b9392505050565b5f60208284031215612e9f575f5ffd5b5035919050565b5f5f60408385031215612eb7575f5ffd5b8235612ec281612e1f565b91506020830135612ed281612e1f565b809150509250929050565b634e487b7160e01b5f52604160045260245ffd5b5f60208284031215612f01575f5ffd5b81356001600160401b03811115612f16575f5ffd5b8201601f81018413612f26575f5ffd5b80356001600160401b03811115612f3f57612f3f612edd565b8060051b604051601f19603f83011681018181106001600160401b0382111715612f6b57612f6b612edd565b604052918252602081840181019290810187841115612f88575f5ffd5b6020850194505b83851015612fae57612fa085612e33565b815260209485019401612f8f565b509695505050505050565b5f8151808452602084019350602083015f5b82811015612ff25781516001600160a01b0316865260209586019590910190600101612fcb565b5093949350505050565b5f8151808452602084019350602083015f5b82811015612ff257815186526020958601959091019060010161300e565b606081525f61303e6060830186612fb9565b82810360208401526130508186612ffc565b905082810360408401526130648185612ffc565b9695505050505050565b6001600160a01b0391909116815260200190565b602081525f612e886020830184612fb9565b5f602082840312156130a4575f5ffd5b5051919050565b634e487b7160e01b5f52601160045260245ffd5b81810381811115611677576116776130ab565b80820180821115611677576116776130ab565b634e487b7160e01b5f52603260045260245ffd5b5f60208284031215613109575f5ffd5b8151612e8881612e1f565b5f60018201613125576131256130ab565b5060010190565b634e487b7160e01b5f52601260045260245ffd5b5f8261314e5761314e61312c565b500490565b8082028115828204841417611677576116776130ab565b5f6020828403121561317a575f5ffd5b81516001600160801b0381168114612e88575f5ffd5b634e487b7160e01b5f52603160045260245ffd5b6001600160a01b03929092168252602082015260400190565b6001600160801b0381811683821602908116908181146131df576131df6130ab565b5092915050565b5f6001600160801b038316806131fe576131fe61312c565b6001600160801b03929092169190910492915050565b5f60208284031215613224575f5ffd5b81518015158114612e88575f5ffd5b5f82518060208501845e5f920191825250919050565b602081525f82518060208401528060208501604085015e5f604082850101526040601f19601f8301168401019150509291505056fea264697066735822122027f6dc952cc1b9fea92872f455eb2595333fc3485db421cd422d0a3dbfddfef164736f6c634300081b0033
Deployed Bytecode Sourcemap
37190:25197:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;46117:684;;;;;;:::i;:::-;;:::i;:::-;;38098:81;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;835:25:1;;;891:2;876:18;;869:34;;;;808:18;38098:81:0;;;;;;;;38198:41;;38233:6;38198:41;;;;;1060:25:1;;;1048:2;1033:18;38198:41:0;914:177:1;40841:107:0;;;;;;:::i;:::-;;:::i;57715:1306::-;;;:::i;59281:3103::-;;;;;;:::i;:::-;;:::i;52506:1129::-;;;;;;:::i;:::-;;:::i;51003:1495::-;;;;;;:::i;:::-;;:::i;44312:1795::-;;;;;;:::i;:::-;;:::i;39610:324::-;;;;;;:::i;:::-;;:::i;37745: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;37745:44:0;1972:607:1;38392:46:0;;38436:2;38392:46;;42699:245;;;;;;:::i;:::-;;:::i;39942:641::-;;;;;;:::i;:::-;;:::i;37945:77::-;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;57430:109;57512:12;:19;57430:109;;55580:1726;;;;;;:::i;:::-;;:::i;:::-;;;;;;;;;:::i;37903:29::-;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;37848:48::-;;;;;;:::i;:::-;;;;;;;;;;;;;;37680:19;;;;;-1:-1:-1;;;;;37680:19:0;;;38345:40;;38381:4;38345:40;;38295:43;;38334:4;38295:43;;38246:42;;38285:3;38246:42;;37796:45;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;5994:14:1;;5987:22;5969:41;;5957:2;5942:18;37796:45:0;5829:187:1;46812:4183:0;;;;;;:::i;:::-;;:::i;38029:62::-;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;40591:242;;;;;;:::i;:::-;;:::i;37706:26::-;;;;;-1:-1:-1;;;;;37706:26:0;;;41477:109;;;:::i;57314:104::-;;;:::i;:::-;;;;;;;:::i;46117:684::-;39479:11;;-1:-1:-1;;;;;39479:11:0;39465:10;:25;39461:52;;39499:14;;-1:-1:-1;;;39499:14:0;;;;;;;;;;;39461:52;-1:-1:-1;;;;;46222:28:0;::::1;;::::0;;;:13:::1;:28;::::0;;;;;::::1;;46217:62;;46259:20;;-1:-1:-1::0;;;46259:20:0::1;;;;;;;;;;;46217:62;46294:6;46304:1;46294:11:::0;46290:38:::1;;46314:14;;-1:-1:-1::0;;;46314:14:0::1;;;;;;;;;;;46290:38;46370:57;::::0;-1:-1:-1;;;46370:57:0;;46349:18:::1;::::0;-1:-1:-1;;;;;46370:42:0;::::1;::::0;::::1;::::0;:57:::1;::::0;46421:4:::1;::::0;46370:57:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;46349:78:::0;-1:-1:-1;46438:84:0::1;-1:-1:-1::0;;;;;46438:49:0;::::1;46488:10;46508:4;46515:6:::0;46438:49:::1;:84::i;:::-;46533:16;46612:10;46570:13;-1:-1:-1::0;;;;;46552:42:0::1;;46603:4;46552:57;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:70;;;;:::i;:::-;-1:-1:-1::0;;;;;46643:25:0;::::1;;::::0;;;:10:::1;:25;::::0;;;;:39:::1;;:51:::0;;46533:89;;-1:-1:-1;46533:89:0;;46643:39;;:25;:51:::1;::::0;46533:89;;46643:51:::1;:::i;:::-;::::0;;;-1:-1:-1;;;;;;;46758:25:0;::::1;;::::0;;;:10:::1;:25;::::0;;;;;;;;:34:::1;;::::0;46720:73;;7073:51:1;;;7140:18;;;7133:34;;;7183:18;;;7176:34;46720:73:0::1;::::0;7061:2:1;7046:18;46720:73:0::1;;;;;;;;46206:595;;46117:684:::0;;:::o;40841:107::-;39479:11;;-1:-1:-1;;;;;39479:11:0;39465:10;:25;39461:52;;39499:14;;-1:-1:-1;;;39499:14:0;;;;;;;;;;;39461:52;40916:22:::1;40932:5;40916:15;:22::i;:::-;40841:107:::0;:::o;57715:1306::-;57772:20;57805:26;57834:17;:15;:17::i;:::-;57805:46;-1:-1:-1;57922:6:0;57918:1056;57938:9;:16;57934:1;:20;57918:1056;;;57976:13;57992:9;58002:1;57992:12;;;;;;;;:::i;:::-;;;;;;;57976:28;;58067:13;58083:5;;;;;;;;;-1:-1:-1;;;;;58083:5:0;-1:-1:-1;;;;;58083:11:0;;:13;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;58067:29;-1:-1:-1;58205:1:0;58188:775;58213:5;58208:1;:10;58188:775;;58248:5;;:16;;-1:-1:-1;;;58248:16:0;;;;;1060:25:1;;;-1:-1:-1;;;;;58248:5:0;;;;:13;;1033:18:1;;58248:16:0;;;;;;;;;;;;;;;;;;-1:-1:-1;58248:16:0;;;;;;;;-1:-1:-1;;58248:16:0;;;;;;;;;;;;:::i;:::-;;;58244:704;58920:8;58244:704;58349:20;58372:16;58379:5;58386:1;58372:6;:16::i;:::-;58349:39;-1:-1:-1;58415:16:0;;58411:101;;58460:28;58476:12;58460:28;;:::i;:::-;;;58411:101;-1:-1:-1;;;;;58646:24:0;;58603:40;58646:24;;;:17;:24;;;;;;;;:27;;;;;;;;;58603:70;;;;;;;;;;;;;;;;;;;;;;;;;58700:27;;;;:79;;-1:-1:-1;;;;;;58759:20:0;;;;;;:13;:20;;;;;;;;;58731:25;;;;:48;58700:79;58696:175;;;58824:23;;58808:39;;;;:::i;:::-;;;58696:175;58283:607;;58265:625;58244:704;58220:3;;;;:::i;:::-;;;;58188:775;;;-1:-1:-1;;;57956:3:0;;57918:1056;;;;58994:19;57715:1306;:::o;59281:3103::-;39479:11;;-1:-1:-1;;;;;39479:11:0;39465:10;:25;39461:52;;39499:14;;-1:-1:-1;;;39499:14:0;;;;;;;;;;;39461:52;-1:-1:-1;;;;;59368:28:0;::::1;;::::0;;;:13:::1;:28;::::0;;;;;::::1;;59363:62;;59405:20;;-1:-1:-1::0;;;59405:20:0::1;;;;;;;;;;;59363:62;-1:-1:-1::0;;;;;59474:25:0;::::1;59446;59474::::0;;;:10:::1;:25;::::0;;;;59601:23;;59582:15:::1;:42;59578:74;;59626:26;::::0;-1:-1:-1;;;59626:26:0;;7951:2:1;59626:26:0::1;::::0;::::1;7933:21:1::0;7990:2;7970:18;;;7963:30;-1:-1:-1;;;8009:18:1;;;8002:46;8065:18;;59626:26:0::1;;;;;;;;59578:74;59723:21;::::0;::::1;::::0;59920:26:::1;::::0;::::1;::::0;59880:67:::1;::::0;59905:13;;59880:24:::1;:67::i;:::-;59844:33;::::0;::::1;:103:::0;60049:19:::1;38381:4;60049:7:::0;:19:::1;:::i;:::-;60025:21;::::0;::::1;:43:::0;;;38285:3:::1;-1:-1:-1::0;60137:105:0::1;;;38285:3;60194:21;::::0;::::1;:36:::0;60137:105:::1;60357:10;60378:25;::::0;::::1;:37:::0;;;60452:20:::1;38233:6;60357:10:::0;60452:20:::1;:::i;:::-;60426:46:::0;;60563:5:::1;::::0;:13:::1;::::0;;-1:-1:-1;;;60563:13:0;;;;60426:23:::1;::::0;-1:-1:-1;;;;;60563:5:0::1;::::0;:11:::1;::::0;:13:::1;::::0;;::::1;::::0;::::1;::::0;;;;;;;;:5;:13:::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;60547:29:::0;-1:-1:-1;60604:1:0::1;60587:1780;60612:5;60607:1;:10;60587:1780;;60643:5;::::0;:16:::1;::::0;-1:-1:-1;;;60643:16:0;;::::1;::::0;::::1;1060:25:1::0;;;-1:-1:-1;;;;;60643:5:0;;::::1;::::0;:13:::1;::::0;1033:18:1;;60643:16:0::1;;;;;;;;;;;;;;;;;;-1:-1:-1::0;60643:16:0::1;::::0;;::::1;;::::0;;::::1;-1:-1:-1::0;;60643:16:0::1;::::0;::::1;::::0;;;::::1;::::0;;::::1;::::0;::::1;:::i;:::-;;;60639:1717:::0;62332:8:::1;60639:1717;60729:33;::::0;::::1;::::0;-1:-1:-1;;;;;60800:37:0;::::1;60697:29;60800:37:::0;;;:22:::1;:37;::::0;;;;;;;:40;;;;;;;;;60959:32;;::::1;60955:1336;;;-1:-1:-1::0;;;;;61067:37:0;::::1;;::::0;;;:22:::1;:37;::::0;;;;;;;:40;;;;;;;;:64;;;61273:25:::1;::::0;::::1;::::0;:32:::1;::::0;61301:4:::1;::::0;61273:32:::1;:::i;:::-;61272:41;::::0;61309:4:::1;61272:41;:::i;:::-;61355:5;::::0;:40:::1;::::0;-1:-1:-1;;;61355:40:0;;::::1;::::0;::::1;8696:25:1::0;;;8769:10;8757:23;;8737:18;;;8730:51;61241:73:0;;-1:-1:-1;61337:15:0::1;::::0;-1:-1:-1;;;;;61355:5:0;;::::1;::::0;:21:::1;::::0;8669:18:1;;61355:40:0::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;61337:58:0::1;::::0;-1:-1:-1;61523:11:0;;61519:753:::1;;-1:-1:-1::0;;;;;61691:37:0;::::1;61645:19;61691:37:::0;;;:22:::1;:37;::::0;;;;;;;:40;;;;;;;;;61667:64;::::1;:167;;61833:1;61667:167;;;-1:-1:-1::0;;;;;61789:37:0;::::1;;::::0;;;:22:::1;:37;::::0;;;;;;;:40;;;;;;;;;61765:64:::1;::::0;:21;:64:::1;:::i;:::-;61645:189:::0;-1:-1:-1;61940:21:0::1;38381:4;61965:21;61645:189:::0;61965:7;:21:::1;:::i;:::-;61964:35;;;;:::i;:::-;-1:-1:-1::0;;;;;62095:22:0;::::1;;::::0;;;:7:::1;:22;::::0;;;;;;;:25;;;;;;;;:42;;61940:59;;-1:-1:-1;61940:59:0;;62095:25;;:22;:42:::1;::::0;61940:59;;62095:42:::1;:::i;:::-;::::0;;;-1:-1:-1;;62195:53:0::1;::::0;;9318:25:1;;;-1:-1:-1;;;;;9379:32:1;;9374:2;9359:18;;9352:60;9428:18;;;9421:34;;;9486:2;9471:18;;9464:34;;;62195:53:0::1;::::0;9305:3:1;9290:19;62195:53:0::1;;;;;;;61536:736;;61519:753;60993:1298;;60955:1336;60678:1628;;60660:1646;60639:1717;60619:3:::0;::::1;::::0;::::1;:::i;:::-;;;;60587:1780;;;;59352:3032;;;;59281:3103:::0;:::o;52506:1129::-;34493:21;:19;:21::i;:::-;52571:7:::1;41639:16;41658;:14;:16::i;:::-;41639:35:::0;-1:-1:-1;41685:13:0;;:34;::::1;;;-1:-1:-1::0;41702:5:0::1;::::0;:13:::1;::::0;;-1:-1:-1;;;41702:13:0;;;;41718:1:::1;::::0;-1:-1:-1;;;;;41702:5:0::1;::::0;:11:::1;::::0;:13:::1;::::0;;::::1;::::0;::::1;::::0;;;;;;;;:5;:13:::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:17;41685:34;41681:64;;;41728:17;;-1:-1:-1::0;;;41728:17:0::1;;;;;;;;;;;41681:64;41762:6;41758:922;41778:12;:19:::0;41774:23;::::1;41758:922;;;41815:13;41831:12;41844:1;41831:15;;;;;;;;:::i;:::-;;::::0;;;::::1;::::0;;;;;::::1;::::0;-1:-1:-1;;;;;41831:15:0::1;41881:17:::0;;;:10:::1;:17:::0;;;;;;41989:22:::1;::::0;::::1;::::0;41831:15;;-1:-1:-1;41881:17:0;41831:15;41957:55:::1;::::0;41831:15;;41957:24:::1;:55::i;:::-;42023:29;::::0;::::1;:49:::0;;;41929:83;-1:-1:-1;42107:31:0::1;42132:5:::0;42107:24:::1;:31::i;:::-;42083:21;::::0;::::1;:55:::0;42149:22:::1;::::0;::::1;:33:::0;;;42207:12;;42203:470:::1;;42364:29;::::0;::::1;::::0;-1:-1:-1;;;;;42323:29:0;::::1;;::::0;;;:22:::1;:29;::::0;;;;;;;:38;;;;;;;;;:70:::1;42319:181;;;42455:29;::::0;::::1;::::0;-1:-1:-1;;;;;42414:29:0;::::1;;::::0;;;:22:::1;:29;::::0;;;;;;;:38;;;;;;;;:70;42319:181:::1;42554:22;42561:5;42568:7;42554:6;:22::i;:::-;-1:-1:-1::0;;;;;42528:14:0;::::1;;::::0;;;:7:::1;:14;::::0;;;;;;;:23;;;;;;;;:48;;;;42632:29:::1;::::0;::::1;::::0;42591;;;:22:::1;:29:::0;;;;;:38;;;;;;;;;:70;42203:470:::1;-1:-1:-1::0;;;41799:3:0::1;;41758:922;;;-1:-1:-1::0;52595:5:0::2;::::0;:22:::2;::::0;-1:-1:-1;;;52595:22:0;;::::2;::::0;::::2;1060:25:1::0;;;52621:10:0::2;::::0;-1:-1:-1;;;;;52595:5:0::2;::::0;:13:::2;::::0;1033:18:1;;52595:22:0::2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;52595:36:0::2;;52591:63;;52640:14;;-1:-1:-1::0;;;52640:14:0::2;;;;;;;;;;;52591:63;52676:23;52701:24;52727;52755:28;52775:7;52755:19;:28::i;:::-;52675:108;;;;;;52798:6;:13;52815:1;52798:18:::0;52794:42:::2;;52825:11;;-1:-1:-1::0;;;52825:11:0::2;;;;;;;;;;;52794:42;52861:6;52857:771;52877:6;:13;52873:1;:17;52857:771;;;52912:13;52928:6;52935:1;52928:9;;;;;;;;:::i;:::-;;;;;;;52912:25;;52952:14;52969:7;52977:1;52969:10;;;;;;;;:::i;:::-;;;;;;;52952:27;;53021:1;53012:6;:10;53008:609;;;-1:-1:-1::0;;;;;53064:20:0;::::2;;::::0;;;:13:::2;:20;::::0;;;;;::::2;;53059:54;;53093:20;;-1:-1:-1::0;;;53093:20:0::2;;;;;;;;;;;53059:54;-1:-1:-1::0;;;;;53192:17:0;::::2;53168:21;53192:17:::0;;;:10:::2;:17;::::0;;;;;;;53264:7:::2;:14:::0;;;;;:23;;;;;;;;:27;;;53351:29:::2;::::0;::::2;::::0;53310;;;:22:::2;:29:::0;;;;;:38;;;;;;;;:70;53435:24;;;:17:::2;:24:::0;;;;;:33;;;;;;;;:44;53590:10;;53534:67:::2;::::0;53203:5;;53561:10:::2;::::0;53573:6;;53279:7;;53590;;53598:1;;53590:10;::::2;;;;;:::i;:::-;;;;;;;53534:19;:67::i;:::-;53024:593;53008:609;-1:-1:-1::0;;52892:3:0::2;;52857:771;;;;52580:1055;;;41632:1059:::1;34525:1;34537:20:::0;33754:1;35057:7;:22;34874:213;51003:1495;39479:11;;-1:-1:-1;;;;;39479:11:0;39465:10;:25;39461:52;;39499:14;;-1:-1:-1;;;39499:14:0;;;;;;;;;;;39461:52;-1:-1:-1;;;;;51094:28:0;::::1;;::::0;;;:13:::1;:28;::::0;;;;;::::1;;51089:62;;51131:20;;-1:-1:-1::0;;;51131:20:0::1;;;;;;;;;;;51089:62;-1:-1:-1::0;;;;;51200:25:0;::::1;51172;51200::::0;;;:10:::1;:25;::::0;;;;51258:23;;51240:15:::1;:41;51236:78;;;51283:31;::::0;-1:-1:-1;;;51283:31:0;;9711:2:1;51283:31:0::1;::::0;::::1;9693:21:1::0;9750:2;9730:18;;;9723:30;-1:-1:-1;;;9769:18:1;;;9762:51;9830:18;;51283:31:0::1;9509:345:1::0;51236:78:0::1;51329:24;::::0;::::1;::::0;:28;51325:59:::1;;51359:25;::::0;-1:-1:-1;;;51359:25:0;;10061:2:1;51359:25:0::1;::::0;::::1;10043:21:1::0;10100:2;10080:18;;;10073:30;-1:-1:-1;;;10119:18:1;;;10112:45;10174:18;;51359:25:0::1;9859:339:1::0;51325:59:0::1;-1:-1:-1::0;;;;;51434:28:0;;::::1;51405:26;51434:28:::0;;;:13:::1;:28;::::0;;;;;;;;51499:5:::1;::::0;:13;;-1:-1:-1;;;51499:13:0;;;;51434:28;;51499:5:::1;::::0;:11:::1;::::0;:13:::1;::::0;;::::1;::::0;;;;;;;:5;:13:::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;51483:29:::0;-1:-1:-1;51540:1:0::1;51523:486;51548:5;51543:1;:10;51523:486;;51579:5;::::0;:16:::1;::::0;-1:-1:-1;;;51579:16:0;;::::1;::::0;::::1;1060:25:1::0;;;-1:-1:-1;;;;;51579:5:0;;::::1;::::0;:13:::1;::::0;1033:18:1;;51579:16:0::1;;;;;;;;;;;;;;;;;;-1:-1:-1::0;51579:16:0::1;::::0;;::::1;;::::0;;::::1;-1:-1:-1::0;;51579:16:0::1;::::0;::::1;::::0;;;::::1;::::0;;::::1;::::0;::::1;:::i;:::-;;;51575:423:::0;::::1;;51659:21;51683:24;51690:13;51705:1;51683:6;:24::i;:::-;51659:48:::0;-1:-1:-1;51730:17:0;;51726:248:::1;;51810:144;::::0;;;;::::1;::::0;;;;;::::1;::::0;;::::1;::::0;;;-1:-1:-1;;;;;51772:32:0;::::1;-1:-1:-1::0;51772:32:0;;;:17:::1;:32:::0;;;;;:35;;;;;;;;;:182;;;;;;::::1;::::0;;::::1;::::0;51726:248:::1;51614:375;51596:393;51575:423;51555:3:::0;::::1;::::0;::::1;:::i;:::-;;;;51523:486;;;-1:-1:-1::0;;;;;;52029:28:0;::::1;52060:5;52029:28:::0;;;:13:::1;:28;::::0;;;;:36;;-1:-1:-1;;52029:36:0::1;::::0;;52107:22:::1;:18:::0;52029:36;52107:22:::1;:::i;:::-;-1:-1:-1::0;;;;;52076:28:0;::::1;;::::0;;;:13:::1;:28;::::0;;;;:53;;;;52150:262:::1;52171:12;:19:::0;52167:23;::::1;52150:262;;;52235:13;-1:-1:-1::0;;;;;52216:32:0::1;:12;52229:1;52216:15;;;;;;;;:::i;:::-;;::::0;;;::::1;::::0;;;::::1;::::0;-1:-1:-1;;;;;52216:15:0::1;:32:::0;52212:189:::1;;52287:12;52300:19:::0;;:23:::1;::::0;52322:1:::1;::::0;52300:23:::1;:::i;:::-;52287:37;;;;;;;;:::i;:::-;;::::0;;;::::1;::::0;;;::::1;::::0;52269:12:::1;:15:::0;;-1:-1:-1;;;;;52287:37:0;;::::1;::::0;52282:1;;52269:15;::::1;;;;;:::i;:::-;;;;;;;;;:55;;;;;-1:-1:-1::0;;;;;52269:55:0::1;;;;;-1:-1:-1::0;;;;;52269:55:0::1;;;;;;52343:12;:18;;;;;;;:::i;:::-;;::::0;;;::::1;::::0;;;;-1:-1:-1;;52343:18:0;;;;;-1:-1:-1;;;;;;52343:18:0::1;::::0;;;;;52380:5:::1;;52212:189;52192:3;;52150:262;;;;52437:53;52456:13;52471:18;52437:53;;;;;;;:::i;44312:1795::-:0;-1:-1:-1;;;;;44433:25:0;;;44389:7;44433:25;;;:10;:25;;;;;;44557:5;;44595:21;;;;44557:61;;-1:-1:-1;;;44557:61:0;;;;;8696:25:1;;;8769:10;8757:23;;;8737:18;;;8730:51;44389:7:0;;44433:25;;44389:7;;44557:5;;;:21;;8669:18:1;;44557:61:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;44539:79:0;;;44633:7;44644:1;44633:12;44629:26;;44654:1;44647:8;;;;;;44629:26;44765:29;44936:6;:21;;;44894:39;44919:13;44894:24;:39::i;:::-;:63;44890:786;;;44978:17;45040:6;:21;;;44998:39;45023:13;44998:24;:39::i;:::-;:63;;;;:::i;:::-;44978:83;;45080:20;45123:9;45103:6;:17;;;:29;;;;:::i;:::-;45080:52;;45151:32;45215:6;:22;;;38381:4;45187:12;:24;;;;:::i;:::-;45186:51;;;;:::i;:::-;45151:86;-1:-1:-1;45331:29:0;;:46;;;;;45376:1;45364:9;:13;45331:46;45327:123;;;-1:-1:-1;45429:1:0;45327:123;45542:24;45510:6;:29;;;:56;;;;:::i;:::-;45486:80;;44959:623;;;44890:786;;;-1:-1:-1;45631:29:0;;;;44890:786;-1:-1:-1;;;;;45804:37:0;;45785:16;45804:37;;;:22;:37;;;;;;;;:46;;;;;;;;;;45883:32;;;:71;;45953:1;45883:71;;;45918:32;45942:8;45918:21;:32;:::i;:::-;45861:93;-1:-1:-1;45975:21:0;38381:4;46000:21;45861:93;46000:7;:21;:::i;:::-;45999:35;;;;:::i;:::-;-1:-1:-1;;;;;46052:22:0;;;;;;:7;:22;;;;;;;;:31;;;;;;;;;45975:59;;-1:-1:-1;46052:47:0;;45975:59;;46052:47;:::i;:::-;46045:54;;;;;;;;44312:1795;;;;;:::o;39610: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;;;;;39729:20:0;::::1;::::0;;:50:::1;;-1:-1:-1::0;;;;;;39753:26:0;::::1;::::0;39729:50:::1;39725:76;;;39788:13;;-1:-1:-1::0;;;39788:13:0::1;;;;;;;;;;;39725:76;39822:24;:22;:24::i;:::-;39867:5;:22:::0;;-1:-1:-1;;;;;39867:22:0;;::::1;-1:-1:-1::0;;;;;;39867:22:0;;::::1;;::::0;;;39900: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;10767:50:1;;28217:14:0;;10755:2:1;10740:18;28217:14:0;;;;;;;28139:104;27141:1109;;;;;39610:324;;:::o;42699:245::-;-1:-1:-1;;;;;42822:25:0;;42777:7;42822:25;;;:10;:25;;;;;:38;42804:15;:56;:132;;-1:-1:-1;;;;;42898:25:0;;;;;;:10;:25;;;;;:38;42804:132;;;42880:15;42797:139;42699:245;-1:-1:-1;;42699:245:0:o;39942:641::-;39479:11;;-1:-1:-1;;;;;39479:11:0;39465:10;:25;39461:52;;39499:14;;-1:-1:-1;;;39499:14:0;;;;;;;;;;;39461:52;38436:2:::1;40046:13;:20;:40;40042:74;;;40095:21;;-1:-1:-1::0;;;40095:21:0::1;;;;;;;;;;;40042:74;40131:12;:19:::0;:23;40127:65:::1;;40156:36;::::0;-1:-1:-1;;;40156:36:0;;11030:2:1;40156:36:0::1;::::0;::::1;11012:21:1::0;11069:2;11049:18;;;11042:30;11108:28;11088:18;;;11081:56;11154:18;;40156:36:0::1;10828:350:1::0;40127:65:0::1;40227:6;40223:226;40243:13;:20;40239:1;:24;40223:226;;;40289:6;40298:5;:1:::0;40302::::1;40298:5;:::i;:::-;40289:14;;40285:153;40309:13;:20;40305:1;:24;40285:153;;;40379:13;40393:1;40379:16;;;;;;;;:::i;:::-;;;;;;;-1:-1:-1::0;;;;;40359:36:0::1;:13;40373:1;40359:16;;;;;;;;:::i;:::-;;;;;;;-1:-1:-1::0;;;;;40359:36:0::1;::::0;40355:67:::1;;40397:25;::::0;-1:-1:-1;;;40397:25:0;;11385:2:1;40397:25:0::1;::::0;::::1;11367:21:1::0;11424:2;11404:18;;;11397:30;-1:-1:-1;;;11443:18:1;;;11436:45;11498:18;;40397:25:0::1;11183:339:1::0;40355:67:0::1;40331:3;;40285:153;;;-1:-1:-1::0;40265:3:0::1;;40223:226;;;-1:-1:-1::0;40473:6:0::1;40469:107;40489:13;:20;40485:1;:24;40469:107;;;40531:33;40547:13;40561:1;40547:16;;;;;;;;:::i;:::-;;;;;;;40531:15;:33::i;:::-;40511:3;;40469:107;;;;39942:641:::0;:::o;55580:1726::-;55841:5;;:22;;-1:-1:-1;;;55841:22:0;;;;;1060:25:1;;;55657:23:0;;;;;;55825:13;;-1:-1:-1;;;;;55841:5:0;;;;:13;;1033:18:1;;55841:22:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;55825:38;-1:-1:-1;;;;;;55878:19:0;;55874:46;;55906:14;;-1:-1:-1;;;55906:14:0;;;;;;;;;;;55874:46;55941:26;55970:17;:15;:17::i;:::-;55941:46;;56021:9;:16;56040:1;56021:20;;;;:::i;:::-;-1:-1:-1;;;;;56007:35:0;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;56007:35:0;;55998:44;;56109:9;:16;56128:1;56109:20;;;;:::i;:::-;-1:-1:-1;;;;;56095:35:0;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;56095:35:0;;56085:45;;56165:9;:16;56184:1;56165:20;;;;:::i;:::-;-1:-1:-1;;;;;56151:35:0;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;56151:35:0;-1:-1:-1;56141:45:0;-1:-1:-1;56207:13:0;;56231:872;56251:9;:16;56247:1;:20;56231:872;;;56289:13;56305:9;56315:1;56305:12;;;;;;;;:::i;:::-;;;;;;;56289:28;;56377:20;56400:22;56407:5;56414:7;56400:6;:22::i;:::-;56377:45;-1:-1:-1;56441:16:0;;56437:214;;56494:5;56478:6;56485:5;56478:13;;;;;;;;:::i;:::-;;;;;;:21;-1:-1:-1;;;;;56478:21:0;;;-1:-1:-1;;;;;56478:21:0;;;;;56535:12;56518:7;56526:5;56518:14;;;;;;;;:::i;:::-;;;;;;:29;;;;;56583:10;:17;56594:5;-1:-1:-1;;;;;56583:17:0;-1:-1:-1;;;;;56583:17:0;;;;;;;;;;;;:26;;;56566:7;56574:5;56566:14;;;;;;;;:::i;:::-;;;;;;;;;;:43;56628:7;;;;:::i;:::-;;;;56437:214;-1:-1:-1;;;;;56757:24:0;;56714:40;56757:24;;;:17;:24;;;;;;;;:33;;;;;;;;;56714:76;;;;;;;;;;;;;;;;;;;;;;;;;56809:27;;;;:79;;-1:-1:-1;;;;;;56868:20:0;;;;;;:13;:20;;;;;;;;;56840:25;;;;:48;56809:79;56805:287;;;56925:5;56909:6;56916:5;56909:13;;;;;;;;:::i;:::-;;;;;;:21;-1:-1:-1;;;;;56909:21:0;;;-1:-1:-1;;;;;56909:21:0;;;;;56966:16;:23;;;56949:7;56957:5;56949:14;;;;;;;;:::i;:::-;;;;;;:40;;;;;57025:16;:25;;;57008:7;57016:5;57008:14;;;;;;;;:::i;:::-;;;;;;;;;;:42;57069:7;;;;:::i;:::-;;;;56805:287;-1:-1:-1;;;56269:3:0;;56231:872;;;-1:-1:-1;57195:21:0;;;57230:22;;;57266;;-1:-1:-1;57202:6:0;;57237:7;;-1:-1:-1;57273:7:0;-1:-1:-1;55580:1726:0:o;37903:29::-;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;37903:29:0;;-1:-1:-1;37903:29:0;:::o;46812:4183::-;39479:11;;-1:-1:-1;;;;;39479:11:0;39465:10;:25;39461:52;;39499:14;;-1:-1:-1;;;39499:14:0;;;;;;;;;;;39461:52;-1:-1:-1;;;;;46920:28:0;::::1;;::::0;;;:13:::1;:28;::::0;;;;;::::1;;46915:62;;46957:20;;-1:-1:-1::0;;;46957:20:0::1;;;;;;;;;;;46915:62;46992:6;47002:1;46992:11:::0;46988:38:::1;;47012:14;;-1:-1:-1::0;;;47012:14:0::1;;;;;;;;;;;46988:38;47104:57;::::0;-1:-1:-1;;;47104:57:0;;47086:15:::1;::::0;-1:-1:-1;;;;;47104:42:0;::::1;::::0;::::1;::::0;:57:::1;::::0;47155:4:::1;::::0;47104:57:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;47086:75;;47186:6;47176:7;:16;47172:50;;;47201:21;;-1:-1:-1::0;;;47201:21:0::1;;;;;;;;;;;47172:50;-1:-1:-1::0;;;;;47271:25:0;::::1;47243;47271::::0;;;:10:::1;:25;::::0;;;;47395::::1;::::0;::::1;::::0;47271;;47395:30;47391:205:::1;;-1:-1:-1::0;;;;;47442:28:0;::::1;;::::0;;;:13:::1;:28;::::0;;;;:30;;;::::1;::::0;::::1;:::i;:::-;;;;;;47568:16;:14;:16::i;:::-;47539:26;::::0;::::1;:45:::0;47391:205:::1;47720:25;::::0;::::1;::::0;47685:16:::1;::::0;47720:29;;;;:74:::1;;-1:-1:-1::0;47753:23:0;;47779:15:::1;-1:-1:-1::0;47720:74:0::1;47716:159;;;47822:23:::0;;:41:::1;::::0;47848:15:::1;::::0;47822:41:::1;:::i;:::-;47811:52;;47716:159;47895:24;47938:12:::0;;;;;:41:::1;;;47978:1;47954:10;:21;;;:25;47938:41;47934:480;;;48094:28;48114:8:::0;-1:-1:-1;;48094:28:0::1;:::i;:::-;48070:10;:21;;;:52;48066:337;;;48162:23;48177:8:::0;38334:4:::1;48162:23;:::i;:::-;48143:42;;48066:337;;;38381:4;48366:8;48342:10;:21;;;:32;;;;:::i;:::-;48341:46;;;;:::i;:::-;48322:65;;48066:337;48540:24;::::0;::::1;::::0;48481:28:::1;::::0;48512:25:::1;48521:16:::0;48512:6;:25:::1;:::i;:::-;:52;;;;:::i;:::-;48481:83:::0;-1:-1:-1;48481:83:0;48751:18:::1;48818:22:::0;;::::1;48814:77;;;48872:7;48857:22;;48814:77;48920:20;48905:12;:35;48901:103;;;48972:20;48957:35;;48901:103;49084:1;49057:24;::::0;::::1;:28:::0;;;49265:16;;49261:1019:::1;;49498:23;38233:6;49525:24;38381:4;49525:12:::0;:24:::1;:::i;:::-;49524:37;;;;:::i;:::-;49498:63:::0;-1:-1:-1;49667:26:0::1;49696:16;38381:4;49696;:16;:::i;:::-;49667:45;;49749:18;49731:15;:36;49727:113;;;49806:18;49788:36;;49727:113;49954:15;49944:25;;38334:4;50040:7;:22;50036:85;;;38334:4;50083:22;;50036:85;38285:3;50139:7;:22;50135:82;;;50189:12;;-1:-1:-1::0;;;50189:12:0::1;;;;;;;;;;;50135:82;49283:945;;49261:1019;;;50256:12;;-1:-1:-1::0;;;50256:12:0::1;;;;;;;;;;;49261:1019;50331:21;::::0;::::1;:31:::0;;;50401:15:::1;50373:25;::::0;::::1;:43:::0;;;50453:26:::1;::::0;38233:6:::1;::::0;50453:26:::1;:::i;:::-;50427:52:::0;;:23:::1;50615:16;:14;:16::i;:::-;50591:40;;38381:4;50671:13;:25;:53;;50711:13;50671:53;;;38381:4;50671:53;50642:26;::::0;::::1;:82:::0;;;50824:67:::1;::::0;50849:13;;50824:24:::1;:67::i;:::-;50788:33;::::0;::::1;:103:::0;50967:19:::1;::::0;::::1;::::0;50917:70:::1;::::0;;-1:-1:-1;;;;;11776:32:1;;11758:51;;11840:2;11825:18;;11818:34;;;11868:18;;;11861:34;;;11926:2;11911:18;;11904:34;;;;50917:70:0;::::1;::::0;;;;11745:3:1;50917:70:0;;::::1;46904:4091;;;;;;;;;46812:4183:::0;;:::o;40591:242::-;39479:11;;-1:-1:-1;;;;;39479:11:0;39465:10;:25;39461:52;;39499:14;;-1:-1:-1;;;39499:14:0;;;;;;;;;;;39461:52;-1:-1:-1;;;;;40683:29:0;::::1;40679:55;;40721:13;;-1:-1:-1::0;;;40721:13:0::1;;;;;;;;;;;40679:55;40745:11;:29:::0;;-1:-1:-1;;;;;;40745:29:0::1;-1:-1:-1::0;;;;;40745:29:0;::::1;;::::0;;40790:35:::1;::::0;::::1;::::0;::::1;::::0;40745:29;;40790:35:::1;:::i;:::-;;;;;;;;40591:242:::0;:::o;41477:109::-;41551:5;;:27;;;-1:-1:-1;;;41551:27:0;;;;41524:7;;-1:-1:-1;;;;;41551:5:0;;:25;;:27;;;;;;;;;;;;;;:5;:27;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;41544:34:0;;;41477:109;:::o;57314:104::-;57362:16;57398:12;57391:19;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;57391:19:0;;;;;;;;;;;;;;;;;;;;;;;57314:104;:::o;17266:216::-;17405:68;;-1:-1:-1;;;;;12169:32:1;;;17405:68:0;;;12151:51:1;12238:32;;12218:18;;;12211:60;12287:18;;;12280:34;;;17378:96:0;;17398:5;;-1:-1:-1;;;17428:27:0;12124: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;40956:513::-;-1:-1:-1;;;;;41020:19:0;;41016:45;;41048:13;;-1:-1:-1;;;41048:13:0;;;;;;;;;;;41016:45;-1:-1:-1;;;;;41076:20:0;;;;;;:13;:20;;;;;;;;41072:52;;;41105:19;;-1:-1:-1;;;41105:19:0;;;;;;;;;;;41072:52;41145:12;:24;;;;;;;;;;;;;-1:-1:-1;;;;;;41145:24:0;-1:-1:-1;;;;;41145:24:0;;;;;;;;-1:-1:-1;41180:20:0;;;:13;41145:24;41180:20;;;;;;;:27;;-1:-1:-1;;41180:27:0;;;;;41218:13;:20;;;;;;:24;;;41287:10;:17;;;;;41315:22;;;:26;;;;41370:20;;;;;41352:15;;;:38;;;41416:45;;41287:17;;41416:45;;;;41145:24;;41416:45;:::i;:::-;;;;;;;;41005:464;40956:513;:::o;42953:1350::-;-1:-1:-1;;;;;43094:25:0;;43050:7;43094:25;;;:10;:25;;;;;43144:12;;;:45;;-1:-1:-1;;;;;;43161:28:0;;;;;;:13;:28;;;;;;;;43160:29;43144:45;43140:114;;;43213:29;;;;-1:-1:-1;43206:36:0;;43140:114;43326:17;43388:6;:21;;;43346:39;43371:13;43346:24;:39::i;:::-;:63;;;;:::i;:::-;43326:83;;43424:9;43437:1;43424:14;43420:56;;-1:-1:-1;43447:29:0;;;;-1:-1:-1;43440:36:0;;43420:56;38381:4;43570:7;:19;43566:71;;;38381:4;43606:19;;43566:71;43780:20;43823:9;43803:6;:17;;;:29;;;;:::i;:::-;43780:52;-1:-1:-1;43915:32:0;43979:7;43951:24;38381:4;43780:52;43951:24;:::i;:::-;43950:36;;;;:::i;:::-;43915:71;-1:-1:-1;44080:29:0;;:46;;;;;44125:1;44113:9;:13;44080:46;44076:136;;;-1:-1:-1;44170:1:0;44076:136;44271:24;44239:6;:29;;;:56;;;;:::i;:::-;44232:63;42953:1350;-1:-1:-1;;;;;;;42953:1350:0:o;34573:293::-;33798:1;34707:7;;:19;34699:63;;;;-1:-1:-1;;;34699:63:0;;12527:2:1;34699:63:0;;;12509:21:1;12566:2;12546:18;;;12539:30;12605:33;12585:18;;;12578:61;12656:18;;34699:63:0;12325:355:1;34699:63:0;33798:1;34840:7;:18;34573:293::o;53643:1929::-;53825:24;;53842:7;53825:24;53942:5;;;;;;;;;-1:-1:-1;;;;;53942:5:0;-1:-1:-1;;;;;53942:17:0;;:19;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;53933:28:0;:5;-1:-1:-1;;;;;53933:28:0;;53929:950;;-1:-1:-1;;;;;53982:26:0;;53978:58;;;54010:26;;-1:-1:-1;;;54010:26:0;;12887:2:1;54010:26:0;;;12869:21:1;12926:2;12906:18;;;12899:30;-1:-1:-1;;;12945:18:1;;;12938:46;13001:18;;54010:26:0;12685:340:1;53978:58:0;54079:5;;:35;;-1:-1:-1;;;54079:35:0;;;;;1060:25:1;;;54051::0;;-1:-1:-1;;;;;54079:5:0;;:26;;1033:18:1;;54079:35:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;54051:63;;54133:17;-1:-1:-1;;;;;54133:22:0;54154:1;54133:22;54129:56;;54157:28;;-1:-1:-1;;;54157:28:0;;13232:2:1;54157:28:0;;;13214:21:1;13271:2;13251:18;;;13244:30;-1:-1:-1;;;13290:18:1;;;13283:48;13348:18;;54157:28:0;13030:342:1;54129:56:0;54214:21;54263:3;54238:22;:17;54258:2;54238:22;:::i;:::-;:28;;;;:::i;:::-;54362:5;;54321:56;;-1:-1:-1;;;54321:56:0;;54214:52;;-1:-1:-1;;;;;;54321:32:0;;;;;;:56;;54362:5;;54370:6;;54321:56;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;54396:5:0;;:167;;-1:-1:-1;;;54396:167:0;;;;;14369:25:1;;;-1:-1:-1;;;;;14430:32:1;;;14410:18;;;14403:60;54501:15:0;14479:18:1;;;14472:34;14542:32;;14522:18;;;14515:60;-1:-1:-1;;;;;54396:5:0;;;;:24;;14341:19:1;;54396:167:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;54392:476;;54793:5;;54752:51;;-1:-1:-1;;;54752:51:0;;-1:-1:-1;;;;;54752:32:0;;;;;;:51;;54793:5;;;;;;54752:51;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;54822:30:0;;-1:-1:-1;;;54822:30:0;;15075:2:1;54822:30:0;;;15057:21:1;15114:2;15094:18;;;15087:30;-1:-1:-1;;;15133:18:1;;;15126:50;15193:18;;54822:30:0;14873:344:1;54392:476:0;54588:44;;;835:25:1;;;891:2;876:18;;869:34;;;-1:-1:-1;;;;;54588:44:0;;;54599:7;;54588:44;;808:18:1;54588:44:0;;;;;;;54651:7;;;;53929:950;54975:49;;-1:-1:-1;;;54975:49:0;;54954:18;;-1:-1:-1;;;;;54975:34:0;;;;;:49;;55018:4;;54975:49;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;54954:70;;55052:6;55039:10;:19;55035:53;;;55067:21;;-1:-1:-1;;;55067:21:0;;;;;;;;;;;55035:53;55139:38;;-1:-1:-1;;;55139:38:0;;55109:27;;-1:-1:-1;;;;;55139:34:0;;;;;:38;;55174:2;;55139:38;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;55109:68;-1:-1:-1;55198:49:0;-1:-1:-1;;;;;55198:37:0;;55236:2;55240:6;55198:37;:49::i;:::-;55299:38;;-1:-1:-1;;;55299:38:0;;55268:28;;-1:-1:-1;;;;;55299:34:0;;;;;:38;;55334:2;;55299:38;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;55268:69;;55376:19;55352:20;:43;55348:72;;55404:16;;-1:-1:-1;;;55404:16:0;;;;;;;;;;;55348:72;55441:16;55460:42;55483:19;55460:20;:42;:::i;:::-;55441:61;;55538:5;-1:-1:-1;;;;;55518:46:0;55529:7;55518:46;55545:8;55555;55518:46;;;;;;835:25:1;;;891:2;876:18;;869:34;823:2;808:18;;661:248;55518:46:0;;;;;;;;53814:1758;;;;53643: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;;15424:2:1;21797:111:0;;;15406:21:1;15463:2;15443:18;;;15436:30;15502:34;15482:18;;;15475:62;-1:-1:-1;;;15553:18:1;;;15546:40;15603:19;;21797:111:0;15222:406:1;21797:111:0;21337:579;21256:660;;:::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;;15835:2:1;11937:81:0;;;15817:21:1;15874:2;15854:18;;;15847:30;15913:34;15893:18;;;15886:62;-1:-1:-1;;;15964:18:1;;;15957:36;16010:19;;11937:81:0;15633: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;;16548:2:1;14767:60:0;;;16530:21:1;16587:2;16567:18;;;16560:30;16626:31;16606:18;;;16599:59;16675:18;;14767:60:0;16346: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;8094:127::-;8155:10;8150:3;8146:20;8143:1;8136:31;8186:4;8183:1;8176:15;8210:4;8207:1;8200:15;8226:120;8266:1;8292;8282:35;;8297:18;;:::i;:::-;-1:-1:-1;8331:9:1;;8226:120::o;8351:168::-;8424:9;;;8455;;8472:15;;;8466:22;;8452:37;8442:71;;8493:18;;:::i;8792:290::-;8862:6;8915:2;8903:9;8894:7;8890:23;8886:32;8883:52;;;8931:1;8928;8921:12;8883:52;8957:16;;-1:-1:-1;;;;;9002:31:1;;8992:42;;8982:70;;9048:1;9045;9038:12;10203:127;10264:10;10259:3;10255:20;10252:1;10245:31;10295:4;10292:1;10285:15;10319:4;10316:1;10309:15;10335:274;-1:-1:-1;;;;;10527:32:1;;;;10509:51;;10591:2;10576:18;;10569:34;10497:2;10482:18;;10335:274::o;13377:272::-;-1:-1:-1;;;;;13462:27:1;;;13491;;;13458:61;13539:37;;;;13595:24;;;13585:58;;13623:18;;:::i;:::-;13585:58;13377:272;;;;:::o;13654:197::-;13694:1;-1:-1:-1;;;;;13721:27:1;;;13757:37;;13774:18;;:::i;:::-;-1:-1:-1;;;;;13812:27:1;;;;13808:37;;;;;13654:197;-1:-1:-1;;13654:197:1:o;13856:277::-;13923:6;13976:2;13964:9;13955:7;13951:23;13947:32;13944:52;;;13992:1;13989;13982:12;13944:52;14024:9;14018:16;14077:5;14070:13;14063:21;14056:5;14053:32;14043:60;;14099:1;14096;14089:12;16040:301;16169:3;16207:6;16201:13;16253:6;16246:4;16238:6;16234:17;16229:3;16223:37;16315:1;16279:16;;16304:13;;;-1:-1:-1;16279:16:1;16040:301;-1:-1:-1;16040:301:1:o;16704:418::-;16853:2;16842:9;16835:21;16816:4;16885:6;16879:13;16928:6;16923:2;16912:9;16908:18;16901:34;16987:6;16982:2;16974:6;16970:15;16965:2;16954:9;16950:18;16944:50;17043:1;17038:2;17029:6;17018:9;17014:22;17010:31;17003:42;17113:2;17106;17102:7;17097:2;17089:6;17085:15;17081:29;17070:9;17066:45;17062:54;17054:62;;;16704:418;;;;:::o
Swarm Source
ipfs://27f6dc952cc1b9fea92872f455eb2595333fc3485db421cd422d0a3dbfddfef1
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.