Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
This contract may be a proxy contract. Click on More Options and select Is this a proxy? to confirm and enable the "Read as Proxy" & "Write as Proxy" tabs.
Contract Name:
ClayMain
Compiler Version
v0.8.18+commit.87f61d96
Contract Source Code (Solidity)
/** *Submitted for verification at Etherscan.io on 2024-05-13 */ // SPDX-License-Identifier: UNLICENSED pragma solidity =0.8.18 ^0.8.0 ^0.8.1 ^0.8.2; // lib/openzeppelin-contracts-upgradeable/contracts/interfaces/IERC1967Upgradeable.sol // OpenZeppelin Contracts (last updated v4.8.3) (interfaces/IERC1967.sol) /** * @dev ERC-1967: Proxy Storage Slots. This interface contains the events defined in the ERC. * * _Available since v4.9._ */ interface IERC1967Upgradeable { /** * @dev Emitted when the implementation is upgraded. */ event Upgraded(address indexed implementation); /** * @dev Emitted when the admin account has changed. */ event AdminChanged(address previousAdmin, address newAdmin); /** * @dev Emitted when the beacon is changed. */ event BeaconUpgraded(address indexed beacon); } // lib/openzeppelin-contracts-upgradeable/contracts/interfaces/draft-IERC1822Upgradeable.sol // OpenZeppelin Contracts (last updated v4.5.0) (interfaces/draft-IERC1822.sol) /** * @dev ERC1822: Universal Upgradeable Proxy Standard (UUPS) documents a method for upgradeability through a simplified * proxy whose upgrades are fully controlled by the current implementation. */ interface IERC1822ProxiableUpgradeable { /** * @dev Returns the storage slot that the proxiable contract assumes is being used to store the implementation * address. * * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this * function revert if invoked through a proxy. */ function proxiableUUID() external view returns (bytes32); } // lib/openzeppelin-contracts-upgradeable/contracts/proxy/beacon/IBeaconUpgradeable.sol // OpenZeppelin Contracts v4.4.1 (proxy/beacon/IBeacon.sol) /** * @dev This is the interface that {BeaconProxy} expects of its beacon. */ interface IBeaconUpgradeable { /** * @dev Must return an address that can be used as a delegate call target. * * {BeaconProxy} will check that this address is a contract. */ function implementation() external view returns (address); } // lib/openzeppelin-contracts-upgradeable/contracts/token/ERC20/IERC20Upgradeable.sol // OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol) /** * @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); } // lib/openzeppelin-contracts-upgradeable/contracts/token/ERC20/extensions/draft-IERC20PermitUpgradeable.sol // OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-IERC20Permit.sol) /** * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612]. * * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't * need to send a transaction, and thus is not required to hold Ether at all. */ 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]. */ 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); } // lib/openzeppelin-contracts-upgradeable/contracts/utils/AddressUpgradeable.sol // OpenZeppelin Contracts (last updated v4.8.0) (utils/Address.sol) /** * @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 * ==== * * [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://diligence.consensys.net/posts/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.5.11/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 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); } } } // lib/openzeppelin-contracts-upgradeable/contracts/utils/StorageSlotUpgradeable.sol // OpenZeppelin Contracts (last updated v4.7.0) (utils/StorageSlot.sol) /** * @dev Library for reading and writing primitive types to specific storage slots. * * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts. * This library helps with reading and writing to such slots without the need for inline assembly. * * The functions in this library return Slot structs that contain a `value` member that can be used to read or write. * * Example usage to set ERC1967 implementation slot: * ``` * contract ERC1967 { * bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc; * * function _getImplementation() internal view returns (address) { * return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value; * } * * function _setImplementation(address newImplementation) internal { * require(Address.isContract(newImplementation), "ERC1967: new implementation is not a contract"); * StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation; * } * } * ``` * * _Available since v4.1 for `address`, `bool`, `bytes32`, and `uint256`._ */ library StorageSlotUpgradeable { struct AddressSlot { address value; } struct BooleanSlot { bool value; } struct Bytes32Slot { bytes32 value; } struct Uint256Slot { uint256 value; } /** * @dev Returns an `AddressSlot` with member `value` located at `slot`. */ function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } /** * @dev Returns an `BooleanSlot` with member `value` located at `slot`. */ function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } /** * @dev Returns an `Bytes32Slot` with member `value` located at `slot`. */ function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } /** * @dev Returns an `Uint256Slot` with member `value` located at `slot`. */ function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } } // src/interfaces/ICSToken.sol interface ICSToken { /// @notice Returns the amount of tokens in existence. function totalSupply() external view returns (uint256); /// @notice Returns the amount of tokens owned by `_account`. function balanceOf(address _account) external view returns (uint256); /// @notice Mints `_amount` of tokens `_to` user. function mint(address _to, uint256 _amount) external returns (bool); /// @notice Burns `_amount` of tokens `_from` user. function burn(address _from, uint256 _amount) external returns (bool); /// @notice Transfers `_amount` of tokens `_to` user. function transfer(address _to, uint256 _amount) external returns (bool); } // src/interfaces/INodeManager.sol interface INodeManager { /// @notice Event for Oracle reporting. /// @param reportBlockNumber : block number of report. /// @param amountRewards : Amounts of rewards. /// @param amountExited : Amounts exited on report. /// @param amountLiquid : Amounts liquid on report. event LogLiquidityTransfer( uint256 indexed reportBlockNumber, uint256 amountRewards, uint256 amountExited, uint256 amountLiquid ); /// @notice Event for Oracle reporting. /// @param reportBlockNumber : block number of report. /// @param validatorsCount : Number of validators. /// @param validatorsBalance : Total balance of validators. /// @param validatorsExited : Number of validators exited. event LogOracleReport( uint256 reportBlockNumber, uint256 validatorsCount, uint256 validatorsBalance, uint256 validatorsExited ); /// @notice Event for record of oracle participation /// @param reportBlockNumber : block number of report. /// @param oracle : Oracle address. event LogOracleVote(uint256 indexed reportBlockNumber, address indexed oracle); /// @notice Event for updating oracle whitelist. /// @param oracle : Oracle address. /// @param flag : boolean for addition or removal. event LogSetOracleWhitelist(address indexed oracle, bool indexed flag); /// @notice Event for updating autobalance registration whitelist. /// @param caller : autobalance caller address. /// @param flag : boolean for addition or removal. event LogSetAutoBalanceWhitelist(address indexed caller, bool indexed flag); /// @notice Event for validator deposit. /// @param validatorId : ID of the validator in Node Manager. /// @param publicKey : Public key of validator. /// @param validatorType : Type of validator. event LogDeposit(uint256 indexed validatorId, bytes indexed publicKey, uint256 validatorType); /// @notice Event for validator deposit. /// @param publicKey : Public key of validator. /// @param owner : Node operator address. event LogPreDeposit(bytes indexed publicKey, address indexed owner); /// @notice Event for validator deposit. /// @param validatorId : ID of the validator in Node Manager. /// @param publicKey : Public key of validator. /// @param owner : Node operator address. event LogPreDepositRefund(uint256 indexed validatorId, bytes indexed publicKey, address indexed owner); /// @notice Event for validator exit request. /// @param batchId : ID of the batch in Node Manager. /// @param withdrawCount : Number of validators exited. event LogWithdraw(uint256 indexed batchId, uint256 withdrawCount); /// @notice Event for new quorum. /// @param oldQuorum : Old oracle quorum. /// @param newQuorum : New oracle quorum. event LogSetOracleQuorum(uint256 oldQuorum, uint256 newQuorum); /// @notice Event for new node operator fee. /// @param oldFee : Old fee. /// @param newFee : New fee. event LogSetNodeOperatorFees(uint256 oldFee, uint256 newFee); /// @notice Event for setting claymain. /// @param newClaymain : Address of clayMain. event LogSetClayMain(address indexed newClaymain); /// @notice Event for setting nodeOperator. /// @param newNodeOperator : Address of nodeOperator. event LogSetNodeOperator(address indexed newNodeOperator); /// @notice Event for setting EigenLayer. /// @param eigenPodManager : Address of EigenPodManager. /// @param delayedWithdrawalRouter : Address of DelayedWithdrawalRouter. event LogSetEigenLayer(address indexed eigenPodManager, address indexed delayedWithdrawalRouter); /// @notice Event for unstaking from eigen layer. /// @param delayedWithdrawalIndex : Index of withdraw order. event LogWithdrawBeforeRestaking(uint256 indexed delayedWithdrawalIndex); /// @notice Event for claiming tokens from eigen layer. /// @param claimedAmount : Amount of tokens claimed. event LogClaimEigenLayer(uint256 claimedAmount); /// @notice Struct for validator data struct Validator { bytes publicKey; bytes signature; uint256 validatorType; } /// @notice Struct for validator view struct ValidatorView { uint256 id; bytes publicKey; uint256 validatorType; } /// @notice Deposits / Withdraws while registering validators with the specified parameters. /// @dev Anyone can call the function as long as no registration occurs ir order to close NetStaking batches. /// @param _publicKey The public key(s) of the validator. /// @param _signature The signature(s) of the validator. /// @param _deposit_data_root The deposit data root(s) of the validator. /// @param _validatorType The type of the validator code internally used. /// @return A boolean indicating whether the registration was successful. function autoBalance( bytes[] memory _publicKey, bytes[] memory _signature, bytes32[] memory _deposit_data_root, uint256[] memory _validatorType ) external returns (bool); /// @notice Returns the balance of the contract accounting for pending staking. function getBalance() external view returns (uint256); /// @notice Returns whether the address is a whitelisted autobalancer. function autobalanceWhitelist(address _caller) external view returns (bool); } // src/interfaces/IRoleManager.sol interface IRoleManager { /// @dev Returns a boolean value indicating whether `_account` has role `_roleName` or not. function checkRole(bytes32 _roleName, address _account) external view returns (bool); } // src/interfaces/IStrategiesManager.sol interface IStrategiesManager { /// @notice Event for new strategy deposit. /// @param user : Address of depositor. /// @param token : Address of Token deposited. /// @param amount : Amount of Token deposited. event LogStrategiesDeposit(address indexed user, address indexed token, uint256 amount); /// @notice Event for withdraw. /// @param user : Address of depositor. /// @param token : Address of token withdrawn. /// @param amountCs : Amount of csToken withdrawn. /// @param amount : Amount of token withdrawn. /// @param shares : Shares of token withdrawn. /// @param nonce : Nonce of withdrawal. /// @param startBlock : Start block of withdrawal. event LogStrategiesWithdraw( address indexed user, address indexed token, uint256 amountCs, uint256 amount, uint256 shares, uint256 nonce, uint256 startBlock ); /// @notice Event for transfer. /// @param user : Address of user transferring. /// @param token : Address of token transferred. /// @param amountCs : Amount of csToken minted. /// @param amount : Amount of token transferred. /// @param shares : Shares of token transferred. /// @param nonce : Nonce of withdrawal. /// @param startBlock : Start block of withdrawal. event LogStrategiesTransfer( address indexed user, address indexed token, uint256 amountCs, uint256 amount, uint256 shares, uint256 nonce, uint256 startBlock ); /// @notice Event for claim multiple withdrawals on single strategy. /// @param user : Address of user transferring. /// @param token : Address of token transferred. /// @param shares : Shares of token transferred. /// @param nonce : Nonce of withdrawal. /// @param startBlock : Start block of withdrawal. event LogStrategiesClaim( address indexed user, address indexed token, uint256 shares, uint256 nonce, uint256 startBlock ); /// @notice Event emitted when a strategy is updated. /// @param token The address of the token. /// @param strategy The address of the updated strategy. /// @param isActive Flag indicating whether the strategy is active or not. /// @param depositsActive Flag indicating whether deposits are active for the strategy. /// @param transfersActive Flag indicating whether transfers are active for the strategy. event LogUpdateStrategy( address indexed token, address strategy, bool isActive, bool depositsActive, bool transfersActive ); /// @notice Returns total balance of all EigenLayer holdings. function getBalance() external view returns (uint256 balance); } // lib/openzeppelin-contracts-upgradeable/contracts/proxy/utils/Initializable.sol // OpenZeppelin Contracts (last updated v4.8.1) (proxy/utils/Initializable.sol) /** * @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] * ``` * 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 Indicates that the contract has been initialized. * @custom:oz-retyped-from bool */ uint8 private _initialized; /** * @dev Indicates that the contract is in the process of being initialized. */ bool private _initializing; /** * @dev Triggered when the contract has been initialized or reinitialized. */ event Initialized(uint8 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 functions marked with `initializer` can be nested in the context of a * constructor. * * Emits an {Initialized} event. */ modifier initializer() { bool isTopLevelCall = !_initializing; require( (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1), "Initializable: contract is already initialized" ); _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 255 will prevent any future reinitialization. * * Emits an {Initialized} event. */ modifier reinitializer(uint8 version) { require(!_initializing && _initialized < version, "Initializable: contract is already initialized"); _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() { require(_initializing, "Initializable: contract is not initializing"); _; } /** * @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 { require(!_initializing, "Initializable: contract is initializing"); if (_initialized < type(uint8).max) { _initialized = type(uint8).max; emit Initialized(type(uint8).max); } } /** * @dev Returns the highest version that has been initialized. See {reinitializer}. */ function _getInitializedVersion() internal view returns (uint8) { return _initialized; } /** * @dev Returns `true` if the contract is currently initializing. See {onlyInitializing}. */ function _isInitializing() internal view returns (bool) { return _initializing; } } // src/interfaces/IClayMain.sol interface IClayMain { /// @notice Supported fee types. Matches fees ordering. enum SetFee { DepositFee, WithdrawFee, InstantWithdrawFee } /// @notice Struct used on ClayMatic fees struct Fees { uint256 depositFee; uint256 withdrawFee; uint256 instantWithdrawFee; } /// @notice Struct used on ClayMatic for returning user withdraw order struct UserWithdrawOrderInfo { uint256 orderId; uint256 amount; uint256 fee; uint256 claimableAt; bool isClaimable; } /// @notice Struct to track internal funds accounting /// @param currentDeposit : Total user deposits backing csETH /// @param withdrawQueue : Current amount of ETH waiting in the queue to be withdrawn by users /// @param stakedDeposit : Amount of ETH currently staked with validators without including exit requests /// @param unstakeExternal : Amount of ETH staked, yet in the process to be withdrawn due user withdraw requests /// @param unstakeInternal : Amount of ETH staked, yet in the process to be withdrawn due to protocol balancing /// @param withdrawQueueOpen : Amount of ETH to be claimed from withdrawals on open batches /// @param claimablePool : ETH balance reserved on contract for claims. struct Funds { uint256 currentDeposit; uint256 withdrawQueue; uint256 stakedDeposit; uint256 unstakeExternal; uint256 unstakeInternal; uint256 withdrawQueueOpen; uint256 claimablePool; } /// @notice WithdrawOrder struct /// @param amount : Total amount unstaked from from ethereum. /// @param fee : Fee percentage to be paid by the user at claim time. /// @param claimableAt timestamp when batch claims can be processed /// @param batchId : Id of the batch process to be sent to ethereum. struct WithdrawOrder { uint256 amount; uint256 fee; uint256 claimableAt; uint256 batchId; } /// @notice Information on batches for withdraws /// @param claimableAt timestamp when batch claims can be processed /// @param amount : Total amount unstaked from from ethereum. /// @param amountCs : Total amount of csToken burned on batch. /// @param multiplier : Multiplier for batch accounting for slashing struct BatchWithdraw { uint256 claimableAt; uint256 amount; uint256 amountCs; uint256 multiplier; } /// @notice Exchange rate allowed percentage deviation. /// @param exchangeDecreaseLimit - Max allowed rate decrease percentage based on last valid exchange rate /// @param exchangeIncreaseLimit - Max allowed rate increase percentage based on last valid exchange rate struct ExchangeDeviation { uint256 exchangeDecreaseLimit; uint256 exchangeIncreaseLimit; } /// @notice Event for new deposit. /// @param user : Address of depositor. /// @param amount : Amount of Token deposited. /// @param amountCs : Amount of csToken minted. /// @param fee : Fee paid by user on deposit in Token event LogDeposit(address indexed user, uint256 amount, uint256 amountCs, uint256 fee); /// @notice Event for new withdraw request. /// @param user : Address of user withdrawing. /// @param orderId : Withdraw order id. /// @param amountCs : Amount of csToken burned. /// @param amount : Amount of Token withdrawn. /// @param fee : Fee percentage to be paid by the user /// @param timestamp : Epoch at the moment of request event LogWithdraw( address indexed user, uint256 orderId, uint256 amountCs, uint256 amount, uint256 fee, uint256 timestamp ); /// @notice Event for withdraw claims by user. /// @param user : Address of user. /// @param orderId : Withdraw order id. /// @param amount : Amount of Token unstaked in order. /// @param received : Amount of Token received in order. /// @param fee : Fee paid by user. event LogClaim(address indexed user, uint256 orderId, uint256 amount, uint256 received, uint256 fee); /// @notice Event for instant withdraw. /// @param user : Address of user. /// @param amountCs : Amount of csToken burned. /// @param amount : Amount of Token withdrawn. /// @param fee : Fee paid by user on instant withdraw in Token event LogInstantWithdraw(address indexed user, uint256 amountCs, uint256 amount, uint256 fee); /// @notice Event for new deposit. /// @param updatedBy : Address of Updating entity. /// @param feeType : Fee type being updated. /// @param oldFee : Existing fee percent for given fee type. /// @param newFee : New fee percent for given fee type. event LogFeeUpdate(address indexed updatedBy, SetFee feeType, uint256 oldFee, uint256 newFee); /// @notice Event emitted when AutoBalance is run. /// @param batchId : Id of the current processed batch. /// @param isNetStaking : Flag denoting net tx type of batch. /// @param amount : Amount of Token to be deposited or expected at claim. event LogAutoBalance(uint256 indexed batchId, bool indexed isNetStaking, uint256 amount); /// @notice Event for rewards recognized. /// @param rewards : Amount of rewards recognized. event LogRewards(uint256 rewards); /// @notice Event for Donations recognized. /// @param amount : Amount of donations recognized. event LogDonation(uint256 amount); /// @notice Event for batch closed. /// @param batchId : Id of the current processed batch. /// @param amount : Amount of Token to be deposited or expected at claim. /// @param amountCs : Amount of csToken burned on batch. /// @param multiplier : Multiplier for batch accounting for slashing event LogBatchClosed(uint256 indexed batchId, uint256 amount, uint256 amountCs, uint256 multiplier); /// @notice Event for imposed penalties. /// @param penaltiesToHolders : Amount of penalties to cs holders. /// @param penaltiesToClaims : Amount of penalties to be claimed. event LogPenalties(uint256 indexed penaltiesToHolders, uint256 indexed penaltiesToClaims); /// @notice Event for updated value of exchange rate /// @param rate : Updated rate value. /// @param time : Timestamp on which info is updated. event LogUpdateExchangeRate(uint256 rate, uint256 time); /// @notice Event for updating minimum claim delay. /// @param newMinClaimSeconds : New claim delay. event LogSetMinClaimTime(uint256 indexed newMinClaimSeconds); /// @notice Event for updating withdrawals. /// @param flag : bool for enabling/disabling withdrawals. event LogSetWithdrawalsDisabled(bool indexed flag); /// @notice Event for updating change update limits. /// @param newDecreaseLimit : New fx change limit floor. /// @param newIncreaseLimit : New fx change limit ceil. event LogSetExchangeDeviation(uint256 indexed newDecreaseLimit, uint256 indexed newIncreaseLimit); /// @notice Event for new deposit with referral. /// @param user : Address of depositor. /// @param referral : Address of referral. /// @param amount : Amount of Token deposited. event LogDepositWithReferral(address indexed user, address indexed referral, uint256 amount); /// @notice Event for strategy manager set. /// @param strategiesManager : Address of strategy manager. event LogSetStrategiesManager(address strategiesManager); /// @notice Sends msg.value Token to ClayMain contract and mints csToken to msg.sender. function deposit() external payable returns (uint256); /// @notice Sends msg.value Token to ClayMain contract and mints csToken to `_delegatedTo`. function depositDelegate(address _delegatedTo) external payable returns (uint256); /// @notice Burns `_amountCs` csToken tokens from user and unstake respective amounts of Token tokens from node. function withdraw(uint256 _amountCs) external returns (uint256); /// @notice Allows user to claim unstaked tokens. function claim(uint256[] calldata _orderIds) external returns (bool); /// @notice Performs claiming of rewards & staking of Token tokens for ClayStack. function autoBalance( uint256 validatorCapacity ) external returns (uint256 currentBatchId, bool netStaking, uint256 validatorCount); /// @notice Exchange rate from csETH to ETH. function getExchangeRate() external view returns (uint256); /// @notice Returns amount of csTokens for given `_amountToken`. function exchangeToken(uint256 _amountToken) external view returns (uint256); /// @notice Returns amount of Tokens for given `_amountCsToken`. function exchangeCsToken(uint256 amountCsToken) external view returns (uint256); /// @notice Receives confirmation from NodeManager on batch finalization function closeBatches(uint256[] calldata _batchIds) external; /// @notice Receives liquidity from NodeManager for exits and rewards function receiveLiquidity(uint256 rewards, uint256 exited) external payable; /// @notice Returns instance of csToken function csToken() external returns (ICSToken); /// @notice enforceAndUpdateBalance public call function updateBalances() external; /// @notice Whether withdrawals & claims are disabled given slashing protection or other reasons function withdrawalsDisabled() external view returns (bool); /// @notice Disables withdrawals and claims function setWithdrawalsDisabled(bool _disabled) external; /// @notice Sends msg.value Token to ClayMain contract and mints csToken to msg.sender. /// And emits event for referral function depositWithReferral(address _referral) external payable returns (uint256); /// @notice Sends msg.value Token to ClayMain contract and mints csToken to `_delegatedTo`. /// And emits event for referral function depositDelegateWithReferral(address _delegatedTo, address _referral) external payable returns (uint256); /// @notice csToken to `_delegatedTo` with '_referral' on LST on StrategiesManager function internalDepositDelegate( uint256 amount, address _delegatedTo, address _referral ) external returns (uint256); /// @notice Burns csToken from user LST on StrategiesManager function internalWithdraw(uint256 _amountCs, address _user) external returns (uint256); } // lib/openzeppelin-contracts-upgradeable/contracts/security/ReentrancyGuardUpgradeable.sol // OpenZeppelin Contracts (last updated v4.8.0) (security/ReentrancyGuard.sol) /** * @dev Contract module that helps prevent reentrant calls to a function. * * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier * available, which can be applied to functions to make sure there are no nested * (reentrant) calls to them. * * Note that because there is a single `nonReentrant` guard, functions marked as * `nonReentrant` may not call one another. This can be worked around by making * those functions `private`, and then adding `external` `nonReentrant` entry * points to them. * * TIP: If you would like to learn more about reentrancy and alternative ways * to protect against it, check out our blog post * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul]. */ abstract contract 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 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; } // lib/openzeppelin-contracts-upgradeable/contracts/utils/ContextUpgradeable.sol // OpenZeppelin Contracts v4.4.1 (utils/Context.sol) /** * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract ContextUpgradeable is Initializable { function __Context_init() internal onlyInitializing { } function __Context_init_unchained() internal onlyInitializing { } function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } /** * @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[50] private __gap; } // lib/openzeppelin-contracts-upgradeable/contracts/security/PausableUpgradeable.sol // OpenZeppelin Contracts (last updated v4.7.0) (security/Pausable.sol) /** * @dev Contract module which allows children to implement an emergency stop * mechanism that can be triggered by an authorized account. * * This module is used through inheritance. It will make available the * modifiers `whenNotPaused` and `whenPaused`, which can be applied to * the functions of your contract. Note that they will not be pausable by * simply including this module, only once the modifiers are put in place. */ abstract contract PausableUpgradeable is Initializable, ContextUpgradeable { /** * @dev Emitted when the pause is triggered by `account`. */ event Paused(address account); /** * @dev Emitted when the pause is lifted by `account`. */ event Unpaused(address account); bool private _paused; /** * @dev Initializes the contract in unpaused state. */ function __Pausable_init() internal onlyInitializing { __Pausable_init_unchained(); } function __Pausable_init_unchained() internal onlyInitializing { _paused = false; } /** * @dev Modifier to make a function callable only when the contract is not paused. * * Requirements: * * - The contract must not be paused. */ modifier whenNotPaused() { _requireNotPaused(); _; } /** * @dev Modifier to make a function callable only when the contract is paused. * * Requirements: * * - The contract must be paused. */ modifier whenPaused() { _requirePaused(); _; } /** * @dev Returns true if the contract is paused, and false otherwise. */ function paused() public view virtual returns (bool) { return _paused; } /** * @dev Throws if the contract is paused. */ function _requireNotPaused() internal view virtual { require(!paused(), "Pausable: paused"); } /** * @dev Throws if the contract is not paused. */ function _requirePaused() internal view virtual { require(paused(), "Pausable: not paused"); } /** * @dev Triggers stopped state. * * Requirements: * * - The contract must not be paused. */ function _pause() internal virtual whenNotPaused { _paused = true; emit Paused(_msgSender()); } /** * @dev Returns to normal state. * * Requirements: * * - The contract must be paused. */ function _unpause() internal virtual whenPaused { _paused = false; emit Unpaused(_msgSender()); } /** * @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; } // lib/openzeppelin-contracts-upgradeable/contracts/token/ERC20/utils/SafeERC20Upgradeable.sol // OpenZeppelin Contracts (last updated v4.8.0) (token/ERC20/utils/SafeERC20.sol) /** * @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; function safeTransfer( IERC20Upgradeable token, address to, uint256 value ) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value)); } 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)); } function safeIncreaseAllowance( IERC20Upgradeable token, address spender, uint256 value ) internal { uint256 newAllowance = token.allowance(address(this), spender) + value; _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } 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"); uint256 newAllowance = oldAllowance - value; _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } } 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"); if (returndata.length > 0) { // Return data is optional require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed"); } } } // lib/openzeppelin-contracts-upgradeable/contracts/proxy/ERC1967/ERC1967UpgradeUpgradeable.sol // OpenZeppelin Contracts (last updated v4.8.3) (proxy/ERC1967/ERC1967Upgrade.sol) /** * @dev This abstract contract provides getters and event emitting update functions for * https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots. * * _Available since v4.1._ * * @custom:oz-upgrades-unsafe-allow delegatecall */ abstract contract ERC1967UpgradeUpgradeable is Initializable, IERC1967Upgradeable { function __ERC1967Upgrade_init() internal onlyInitializing { } function __ERC1967Upgrade_init_unchained() internal onlyInitializing { } // This is the keccak-256 hash of "eip1967.proxy.rollback" subtracted by 1 bytes32 private constant _ROLLBACK_SLOT = 0x4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143; /** * @dev Storage slot with the address of the current implementation. * This is the keccak-256 hash of "eip1967.proxy.implementation" subtracted by 1, and is * validated in the constructor. */ bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc; /** * @dev Returns the current implementation address. */ function _getImplementation() internal view returns (address) { return StorageSlotUpgradeable.getAddressSlot(_IMPLEMENTATION_SLOT).value; } /** * @dev Stores a new address in the EIP1967 implementation slot. */ function _setImplementation(address newImplementation) private { require(AddressUpgradeable.isContract(newImplementation), "ERC1967: new implementation is not a contract"); StorageSlotUpgradeable.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation; } /** * @dev Perform implementation upgrade * * Emits an {Upgraded} event. */ function _upgradeTo(address newImplementation) internal { _setImplementation(newImplementation); emit Upgraded(newImplementation); } /** * @dev Perform implementation upgrade with additional setup call. * * Emits an {Upgraded} event. */ function _upgradeToAndCall( address newImplementation, bytes memory data, bool forceCall ) internal { _upgradeTo(newImplementation); if (data.length > 0 || forceCall) { _functionDelegateCall(newImplementation, data); } } /** * @dev Perform implementation upgrade with security checks for UUPS proxies, and additional setup call. * * Emits an {Upgraded} event. */ function _upgradeToAndCallUUPS( address newImplementation, bytes memory data, bool forceCall ) internal { // Upgrades from old implementations will perform a rollback test. This test requires the new // implementation to upgrade back to the old, non-ERC1822 compliant, implementation. Removing // this special case will break upgrade paths from old UUPS implementation to new ones. if (StorageSlotUpgradeable.getBooleanSlot(_ROLLBACK_SLOT).value) { _setImplementation(newImplementation); } else { try IERC1822ProxiableUpgradeable(newImplementation).proxiableUUID() returns (bytes32 slot) { require(slot == _IMPLEMENTATION_SLOT, "ERC1967Upgrade: unsupported proxiableUUID"); } catch { revert("ERC1967Upgrade: new implementation is not UUPS"); } _upgradeToAndCall(newImplementation, data, forceCall); } } /** * @dev Storage slot with the admin of the contract. * This is the keccak-256 hash of "eip1967.proxy.admin" subtracted by 1, and is * validated in the constructor. */ bytes32 internal constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103; /** * @dev Returns the current admin. */ function _getAdmin() internal view returns (address) { return StorageSlotUpgradeable.getAddressSlot(_ADMIN_SLOT).value; } /** * @dev Stores a new address in the EIP1967 admin slot. */ function _setAdmin(address newAdmin) private { require(newAdmin != address(0), "ERC1967: new admin is the zero address"); StorageSlotUpgradeable.getAddressSlot(_ADMIN_SLOT).value = newAdmin; } /** * @dev Changes the admin of the proxy. * * Emits an {AdminChanged} event. */ function _changeAdmin(address newAdmin) internal { emit AdminChanged(_getAdmin(), newAdmin); _setAdmin(newAdmin); } /** * @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy. * This is bytes32(uint256(keccak256('eip1967.proxy.beacon')) - 1)) and is validated in the constructor. */ bytes32 internal constant _BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50; /** * @dev Returns the current beacon. */ function _getBeacon() internal view returns (address) { return StorageSlotUpgradeable.getAddressSlot(_BEACON_SLOT).value; } /** * @dev Stores a new beacon in the EIP1967 beacon slot. */ function _setBeacon(address newBeacon) private { require(AddressUpgradeable.isContract(newBeacon), "ERC1967: new beacon is not a contract"); require( AddressUpgradeable.isContract(IBeaconUpgradeable(newBeacon).implementation()), "ERC1967: beacon implementation is not a contract" ); StorageSlotUpgradeable.getAddressSlot(_BEACON_SLOT).value = newBeacon; } /** * @dev Perform beacon upgrade with additional setup call. Note: This upgrades the address of the beacon, it does * not upgrade the implementation contained in the beacon (see {UpgradeableBeacon-_setImplementation} for that). * * Emits a {BeaconUpgraded} event. */ function _upgradeBeaconToAndCall( address newBeacon, bytes memory data, bool forceCall ) internal { _setBeacon(newBeacon); emit BeaconUpgraded(newBeacon); if (data.length > 0 || forceCall) { _functionDelegateCall(IBeaconUpgradeable(newBeacon).implementation(), data); } } /** * @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) private returns (bytes memory) { require(AddressUpgradeable.isContract(target), "Address: delegate call to non-contract"); // solhint-disable-next-line avoid-low-level-calls (bool success, bytes memory returndata) = target.delegatecall(data); return AddressUpgradeable.verifyCallResult(success, returndata, "Address: low-level delegate call failed"); } /** * @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[50] private __gap; } // lib/openzeppelin-contracts-upgradeable/contracts/proxy/utils/UUPSUpgradeable.sol // OpenZeppelin Contracts (last updated v4.8.0) (proxy/utils/UUPSUpgradeable.sol) /** * @dev An upgradeability mechanism designed for UUPS proxies. The functions included here can perform an upgrade of an * {ERC1967Proxy}, when this contract is set as the implementation behind such a proxy. * * A security mechanism ensures that an upgrade does not turn off upgradeability accidentally, although this risk is * reinstated if the upgrade retains upgradeability but removes the security mechanism, e.g. by replacing * `UUPSUpgradeable` with a custom implementation of upgrades. * * The {_authorizeUpgrade} function must be overridden to include access restriction to the upgrade mechanism. * * _Available since v4.1._ */ abstract contract UUPSUpgradeable is Initializable, IERC1822ProxiableUpgradeable, ERC1967UpgradeUpgradeable { function __UUPSUpgradeable_init() internal onlyInitializing { } function __UUPSUpgradeable_init_unchained() internal onlyInitializing { } /// @custom:oz-upgrades-unsafe-allow state-variable-immutable state-variable-assignment address private immutable __self = address(this); /** * @dev Check that the execution is being performed through a delegatecall call and that the execution context is * a proxy contract with an implementation (as defined in ERC1967) pointing to self. This should only be the case * for UUPS and transparent proxies that are using the current contract as their implementation. Execution of a * function through ERC1167 minimal proxies (clones) would not normally pass this test, but is not guaranteed to * fail. */ modifier onlyProxy() { require(address(this) != __self, "Function must be called through delegatecall"); require(_getImplementation() == __self, "Function must be called through active proxy"); _; } /** * @dev Check that the execution is not being performed through a delegate call. This allows a function to be * callable on the implementing contract but not through proxies. */ modifier notDelegated() { require(address(this) == __self, "UUPSUpgradeable: must not be called through delegatecall"); _; } /** * @dev Implementation of the ERC1822 {proxiableUUID} function. This returns the storage slot used by the * implementation. It is used to validate the implementation's compatibility when performing an upgrade. * * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this * function revert if invoked through a proxy. This is guaranteed by the `notDelegated` modifier. */ function proxiableUUID() external view virtual override notDelegated returns (bytes32) { return _IMPLEMENTATION_SLOT; } /** * @dev Upgrade the implementation of the proxy to `newImplementation`. * * Calls {_authorizeUpgrade}. * * Emits an {Upgraded} event. */ function upgradeTo(address newImplementation) external virtual onlyProxy { _authorizeUpgrade(newImplementation); _upgradeToAndCallUUPS(newImplementation, new bytes(0), false); } /** * @dev Upgrade the implementation of the proxy to `newImplementation`, and subsequently execute the function call * encoded in `data`. * * Calls {_authorizeUpgrade}. * * Emits an {Upgraded} event. */ function upgradeToAndCall(address newImplementation, bytes memory data) external payable virtual onlyProxy { _authorizeUpgrade(newImplementation); _upgradeToAndCallUUPS(newImplementation, data, true); } /** * @dev Function that should revert when `msg.sender` is not authorized to upgrade the contract. Called by * {upgradeTo} and {upgradeToAndCall}. * * Normally, this function will use an xref:access.adoc[access control] modifier such as {Ownable-onlyOwner}. * * ```solidity * function _authorizeUpgrade(address) internal override onlyOwner {} * ``` */ function _authorizeUpgrade(address newImplementation) internal virtual; /** * @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[50] private __gap; } // src/ClayMain.sol /// @title ClayStack's main contract for user flows. /// @notice This contract is the main entry point for ClayStack's protocol. /// @dev This contract is upgradeable. /// @dev This contract is pausable. /// @dev This contract is reentrancy guarded. contract ClayMain is IClayMain, UUPSUpgradeable, PausableUpgradeable, ReentrancyGuardUpgradeable { using SafeERC20Upgradeable for IERC20Upgradeable; /// @notice ClayStack's default list of access-control roles. bytes32 private constant TIMELOCK_ROLE = keccak256("TIMELOCK_ROLE"); bytes32 private constant TIMELOCK_UPGRADES_ROLE = keccak256("TIMELOCK_UPGRADES_ROLE"); bytes32 private constant CS_SERVICE_ROLE = keccak256("CS_SERVICE_ROLE"); /// @notice Constants uint256 private constant DEPOSIT_SIZE = 32 ether; uint256 private constant MAX_DEPOSIT_FEE = 500; uint256 private constant MAX_WITHDRAW_FEE = 500; uint256 private constant MAX_INSTANT_WITHDRAW_FEE = 2000; uint256 private constant MAX_UNBONDING = 90 days; uint256 private constant PERCENTAGE_BASE = 10000; uint256 private constant PRECISION = 1e18; /// @notice Stores all fee info. Fees public fees; /// @notice RoleManager instance. IRoleManager private roleManager; /// @notice csToken instance. ICSToken public csToken; /// @notice Node manager handling deposits, withdrawals and rewards INodeManager private nodeManager; /// @notice Whether withdrawals & claims are disabled given slashing protection or other reasons bool public withdrawalsDisabled; /// @notice Mapping of all unstaking withdraw order by users. mapping(address => mapping(uint256 => WithdrawOrder)) public withdrawOrders; /// @notice maps id to Batch withdrawal structures mapping(uint256 => BatchWithdraw) public batchWithdrawOrders; /// @notice maps user to the list of claims they have mapping(address => uint256[]) public userWithdrawIds; /// @notice Stores all funds info. Funds public funds; /// @notice Whether there is a user withdrawal within unstaking tracking swaps bool public withdrawQueueActive; /// @notice Stores allowed deviation percentages. ExchangeDeviation public exchangeDeviation; /// @notice Active batch id uint256 public batchId; /// @notice Linear incremental order nonce. Increases by one after each withdraw request. uint256 orderNonce; /// @notice Minimum number of seconds to claim locally netted withdrawal orders uint256 public minClaimSeconds; /// @notice Last valid exchange rate uint256 public lastExchangeRate; /// @notice Last synced ETH balance of contract uint256 public ethBalance; /// @notice Last updated ETH balance on strategies manager uint256 public ethStrategiesManager; /// @notice Instance of strategies Manager contract IStrategiesManager public strategiesManager; /// @notice Check if the msg.sender has permission. /// @param _roleName : bytes32 hash of the role. modifier onlyRole(bytes32 _roleName) { _onlyRole(_roleName); _; } /// @notice Check if the msg.sender is StrategiesManager. modifier onlyStrategiesManager() { require(msg.sender == address(strategiesManager), "Auth Failed"); _; } /// @notice Initializes the contract's state vars. /// @param _csToken : Address of ClayStack's erc20 compliant synthetic token. /// @param _nodeManager : Address of ClayStack's node manager contract. /// @param _roleManager : Address of ClayStack's role manager contract. function initialize(address _csToken, address _nodeManager, address _roleManager) external initializer onlyProxy { require(_csToken != address(0), "Invalid csToken address"); require(_nodeManager != address(0), "Invalid NodeManager address"); require(_roleManager != address(0), "Invalid roleManager address"); __Pausable_init(); __ReentrancyGuard_init(); __UUPSUpgradeable_init(); csToken = ICSToken(_csToken); nodeManager = INodeManager(_nodeManager); roleManager = IRoleManager(_roleManager); // Default settings minClaimSeconds = 2 days; fees.instantWithdrawFee = 50; exchangeDeviation.exchangeIncreaseLimit = 1000; exchangeDeviation.exchangeDecreaseLimit = 1000; _updateExchangeRate(); // init rate 1:1 } /** USER OPERATIONS **/ /// @notice Sends Token to contract and mints csToken to msg.sender with '_referral'. /// @param _referral address of referral. /// @return Amount of csToken minted function depositWithReferral(address _referral) external payable whenNotPaused nonReentrant returns (uint256) { require(_referral != address(0), "Invalid referral"); uint256 amountCs = _deposit(msg.value, msg.sender, 0); emit LogDepositWithReferral(msg.sender, _referral, msg.value); return amountCs; } /// @notice Sends Token to contract and mints csToken to `_delegatedTo` with '_referral'. /// @param _delegatedTo Address of entity receiving csToken. /// @param _referral address of referral. /// @return Amount of csToken minted function depositDelegateWithReferral( address _delegatedTo, address _referral ) external payable whenNotPaused nonReentrant returns (uint256) { require(_delegatedTo != address(0), "Invalid delegatedTo"); require(_referral != address(0), "Invalid referral"); uint256 amountCs = _deposit(msg.value, _delegatedTo, 0); emit LogDepositWithReferral(_delegatedTo, _referral, msg.value); return amountCs; } /// @notice Sends Token to contract and mints csToken to msg.sender. /// @return Amount of csToken minted function deposit() external payable whenNotPaused nonReentrant returns (uint256) { return _deposit(msg.value, msg.sender, 0); } /// @notice Sends Token to contract and mints csToken to `_delegatedTo`. /// @param _delegatedTo Address of entity receiving csToken. /// @return Amount of csToken minted function depositDelegate( address _delegatedTo ) external payable override whenNotPaused nonReentrant returns (uint256) { require(_delegatedTo != address(0), "Invalid delegatedTo"); return _deposit(msg.value, _delegatedTo, 0); } /// @notice Internal for processing deposits /// @param _depositAmount Token to be deposited /// @param _delegatedTo Address of entity receiving csToken. /// @param _depositedStrategies Amount deposited on the StrategiesManager on the transaction /// @return Amount of csToken minted function _deposit( uint256 _depositAmount, address _delegatedTo, uint256 _depositedStrategies ) internal returns (uint256) { require(_depositAmount != 0, "Invalid deposit amount"); _updateBalance(); uint256 depositFee = (fees.depositFee * _depositAmount) / PERCENTAGE_BASE; uint256 amountToken = _depositAmount - depositFee; uint256 amountToMint = _exchangeToken(amountToken, funds.currentDeposit); funds.currentDeposit += _depositAmount; if (_depositedStrategies != 0) ethStrategiesManager += _depositedStrategies; require(csToken.mint(_delegatedTo, amountToMint), "Minting failed"); _updateClaimablePool(); _balanced(); emit LogDeposit(_delegatedTo, amountToken, amountToMint, depositFee); return amountToMint; } /// @notice Burns csToken from user and starts unstaking process from Ethereum /// @param _amountCs Amount of csToken to be withdrawn. /// @return Returns withdraw id. function withdraw(uint256 _amountCs) external override whenNotPaused nonReentrant returns (uint256) { require(!withdrawalsDisabled, "Withdrawals disabled"); require(_amountCs != 0, "Withdraw amount cannot be zero"); require(csToken.balanceOf(msg.sender) >= _amountCs, "Insufficient csToken user balance"); _updateBalance(); uint256 currentDeposit = funds.currentDeposit; uint256 amountTokenWithdraw = _exchangeCsToken(_amountCs, currentDeposit); require(amountTokenWithdraw != 0, "Invalid token amount"); require(amountTokenWithdraw <= currentDeposit - ethStrategiesManager, "Amount not available for withdrawal"); // Update funds withdrawQueueActive = true; funds.currentDeposit -= amountTokenWithdraw; funds.withdrawQueue += amountTokenWithdraw; funds.withdrawQueueOpen += amountTokenWithdraw; // Burn csToken require(csToken.burn(msg.sender, _amountCs), "Burn failed"); uint256 id = ++orderNonce; withdrawOrders[msg.sender][id] = WithdrawOrder({ amount: amountTokenWithdraw, fee: fees.withdrawFee, claimableAt: block.timestamp + minClaimSeconds, batchId: batchId }); // update batch amounts batchWithdrawOrders[batchId].amount += amountTokenWithdraw; batchWithdrawOrders[batchId].amountCs += _amountCs; userWithdrawIds[msg.sender].push(id); _updateClaimablePool(); _balanced(); emit LogWithdraw(msg.sender, id, _amountCs, amountTokenWithdraw, fees.withdrawFee, block.timestamp); return id; } /// @notice Allows the user to claim several orders at once. /// @param _orderIds - array of number of ids issued at withdraw() /// @return Bool confirmation of transaction function claim(uint256[] calldata _orderIds) external override whenNotPaused nonReentrant returns (bool) { require(!withdrawalsDisabled, "Withdrawals disabled"); uint256 orderLength = _orderIds.length; require(orderLength != 0, "Invalid order Id length"); _updateBalance(); uint256 amountsToUser = 0; uint256 ordersFees = 0; for (uint256 i = 0; i < _orderIds.length; i++) { (uint256 _amountsToUser, uint256 _orderFee) = _claim(_orderIds[i], msg.sender); amountsToUser += _amountsToUser; ordersFees += _orderFee; } require(amountsToUser != 0, "Invalid amount to user"); if (ordersFees != 0) { funds.currentDeposit += ordersFees; } // Transfer (bool success, ) = msg.sender.call{value: amountsToUser}(""); require(success, "Transfer of funds to user failed"); _updateClaimablePool(); _balanced(); return true; } /// @notice single claim implementation /// @param _orderId id issued at withdraw /// @param _user address of user /// @return amount claim, order fees function _claim(uint256 _orderId, address _user) internal returns (uint256, uint256) { WithdrawOrder memory order = withdrawOrders[_user][_orderId]; require(order.amount != 0, "Invalid Order"); BatchWithdraw memory batchOrder = batchWithdrawOrders[order.batchId]; require(batchOrder.claimableAt != 0 && batchOrder.claimableAt <= block.timestamp, "Order is not finalized"); (uint256 amount, uint256 orderFee) = _calculateOrderAmount(order, batchOrder); require(order.claimableAt <= block.timestamp && ethBalance >= amount, "Order is not claimable"); require(funds.claimablePool >= amount, "Amount exceeds funds.claimablePool"); emit LogClaim(_user, _orderId, order.amount, amount, orderFee); // Update balances withdrawOrders[_user][_orderId].amount = 0; funds.withdrawQueue -= amount; funds.claimablePool -= amount; ethBalance -= (amount - orderFee); return (amount - orderFee, orderFee); } /// @notice Checks whether order is claimable based on time and liquidity /// @param _order WithdrawOrder /// @return boolean of whether the order is claimable function _canClaim(WithdrawOrder memory _order) internal view returns (bool) { if (withdrawalsDisabled) { return false; } if (_order.amount == 0) { return false; } BatchWithdraw memory batchOrder = batchWithdrawOrders[_order.batchId]; if (batchOrder.claimableAt == 0 || batchOrder.claimableAt > block.timestamp) { return false; } if (_order.claimableAt > block.timestamp) { return false; } (uint256 amount, ) = _calculateOrderAmount(_order, batchOrder); if (ethBalance < amount) { return false; } if (funds.claimablePool < amount) { return false; } return true; } /// @notice Calculates order amount based on exchange rate and penalties/slashing /// @param _order WithdrawOrder /// @param _batchOrder BatchWithdraw /// @return amount - amount of Token to be returned to user /// @return orderFee - fee to be added to current deposits function _calculateOrderAmount( WithdrawOrder memory _order, BatchWithdraw memory _batchOrder ) internal view returns (uint256 amount, uint256 orderFee) { uint256 multiplier = _batchOrder.multiplier; // if not closed batch, calculate current multiplier if (_batchOrder.claimableAt == 0) { uint256 amountTokens = _exchangeCsToken(_batchOrder.amountCs, funds.currentDeposit); multiplier = (amountTokens * PRECISION) / _batchOrder.amount; } amount = multiplier > PRECISION ? _order.amount : (_order.amount * multiplier) / PRECISION; orderFee = (amount * _order.fee) / PERCENTAGE_BASE; } /// @notice Burns csToken from user and instantly returns Token to user. /// @param _amountCs Amount of csToken to be withdrawn. /// @return Bool confirmation of transaction function instantWithdraw(uint256 _amountCs) external whenNotPaused nonReentrant returns (bool) { require(!withdrawalsDisabled, "Withdrawals disabled"); require(_amountCs != 0, "Withdraw amount cannot be zero"); require(csToken.balanceOf(msg.sender) >= _amountCs, "Insufficient csToken user balance"); _updateBalance(); uint256 amountTokenWithdraw = _exchangeCsToken(_amountCs, funds.currentDeposit); require(amountTokenWithdraw != 0 && _getLiquidityToken() >= amountTokenWithdraw, "Invalid token amount"); funds.currentDeposit -= amountTokenWithdraw; // Payable fee uint256 payableFee = 0; if (fees.instantWithdrawFee != 0) { payableFee = (fees.instantWithdrawFee * amountTokenWithdraw) / PERCENTAGE_BASE; funds.currentDeposit += payableFee; } require(csToken.burn(msg.sender, _amountCs), "Burn failed"); uint256 amountTokenWithdrawToUser = amountTokenWithdraw - payableFee; ethBalance -= amountTokenWithdrawToUser; (bool success, ) = msg.sender.call{value: amountTokenWithdrawToUser}(""); require(success, "Transfer of funds to user failed"); _updateClaimablePool(); _balanced(); emit LogInstantWithdraw(msg.sender, _amountCs, amountTokenWithdrawToUser, payableFee); return true; } /** STRATEGIES OPERATIONS **/ /// @notice csToken to `_delegatedTo` with '_referral' on LST on StrategiesManager /// @param _amount Token to be deposited /// @param _delegatedTo Address of entity receiving csToken. /// @param _referral address of referral. /// @return Amount of csToken minted function internalDepositDelegate( uint256 _amount, address _delegatedTo, address _referral ) external whenNotPaused nonReentrant onlyStrategiesManager returns (uint256) { require(_amount != 0, "Invalid deposit amount"); require(_delegatedTo != address(0), "Invalid delegatedTo"); uint256 amountCs = _deposit(_amount, _delegatedTo, _amount); if (_referral != address(0)) { emit LogDepositWithReferral(_delegatedTo, _referral, _amount); } return amountCs; } /// @notice Burns csToken from user LST on StrategiesManager /// @dev Flow is similar to instantWithdraw to update accounts /// @param _amountCs : Amount of csToken to be withdrawn. /// @param _user : Account starting withdraw on Strategies Manager /// @return Amount ETH withdrawn function internalWithdraw( uint256 _amountCs, address _user ) external whenNotPaused nonReentrant onlyStrategiesManager returns (uint256) { require(!withdrawalsDisabled, "Withdrawals disabled"); require(_amountCs != 0, "Withdraw amount cannot be zero"); require(csToken.balanceOf(_user) >= _amountCs, "Insufficient csToken user balance"); _updateBalance(); uint256 currentDeposit = funds.currentDeposit; uint256 amountTokenWithdraw = _exchangeCsToken(_amountCs, currentDeposit); require(amountTokenWithdraw != 0, "Invalid token amount"); require(amountTokenWithdraw <= currentDeposit, "Amount not available for withdrawal"); require(amountTokenWithdraw <= ethStrategiesManager, "Amount exceeds available on strategies"); // Update funds funds.currentDeposit -= amountTokenWithdraw; ethStrategiesManager -= amountTokenWithdraw; // Burn csToken require(csToken.burn(_user, _amountCs), "Burn failed"); _balanced(); emit LogInstantWithdraw(_user, _amountCs, amountTokenWithdraw, 0); return amountTokenWithdraw; } /** VIEWS **/ /// @notice Returns the current exchange rate. /// @return Exchange Rate csToken to Token, Slashing occurred. function getExchangeRate() external view returns (uint256) { (uint256 currentDeposit, , , , ) = _calculateBalances(); return _exchangeCsToken(PRECISION, currentDeposit); } /// @notice Returns amount of csTokens for given `_amountsToken`. function exchangeToken(uint256 _amountsToken) external view returns (uint256) { (uint256 currentDeposit, , , , ) = _calculateBalances(); return _exchangeToken(_amountsToken, currentDeposit); } /// @notice Returns amount of Tokens for given `_amountCsToken`. function exchangeCsToken(uint256 _amountCsToken) external view returns (uint256) { (uint256 currentDeposit, , , , ) = _calculateBalances(); return _exchangeCsToken(_amountCsToken, currentDeposit); } /// @notice Returns amount of Token for given `_amountCs`. /// @param _amountCs : Amount of csToken. /// @param _currentDeposits : current deposits in contract. /// @return Amount of Tokens function _exchangeCsToken(uint256 _amountCs, uint256 _currentDeposits) internal view returns (uint256) { uint256 totalCsToken = csToken.totalSupply(); if (totalCsToken != _currentDeposits && totalCsToken != 0 && _currentDeposits != 0) { return (_amountCs * _currentDeposits) / totalCsToken; } else { return _amountCs; } } /// @notice Returns amount of csTokens for given `_amountsToken`. /// @param _amountsToken : Amount of Token. /// @param _currentDeposits : Protocol total current deposits. /// @return Amount of csTokens function _exchangeToken(uint256 _amountsToken, uint256 _currentDeposits) internal view returns (uint256) { uint256 totalCsToken = csToken.totalSupply(); if (totalCsToken != _currentDeposits && _currentDeposits != 0 && totalCsToken != 0) { return (_amountsToken * totalCsToken) / _currentDeposits; } else { return _amountsToken; } } /// @dev Returns liquidity of Token function _getLiquidityToken() internal view returns (uint256) { return ethBalance - funds.claimablePool; } /// @dev Returns total liquidity of csToken available for Instant Withdrawal. function getLiquidityCsToken() external view returns (uint256) { (uint256 currentDeposit, , , , ) = _calculateBalances(); uint256 amount = _getLiquidityToken(); return amount != 0 ? _exchangeToken(amount, currentDeposit) : 0; } /// @notice Returns the given page of the withdraw orders in descending order /// @dev Max 10 results starting at page 0 /// @param _user : Address of user. /// @param _page : Page to query. /// @return info Array for struct of user withdraw orders /// @return timeStamp current time of current chain /// @return totalPages supported for given user. function getUserOrders( address _user, uint256 _page ) external view returns (UserWithdrawOrderInfo[] memory, uint256, uint256) { UserWithdrawOrderInfo[] memory info = new UserWithdrawOrderInfo[](10); uint256 pageSize = 10; uint256 length = userWithdrawIds[_user].length; uint256 totalPages = length / pageSize; if (length > 0 && length % pageSize == 0) { totalPages--; } if (_page <= totalPages && length != 0) { for (uint256 i = 0; i < pageSize; i++) { uint256 index = length - _page * pageSize - i - 1; uint256 orderId = userWithdrawIds[_user][index]; WithdrawOrder memory order = withdrawOrders[_user][orderId]; BatchWithdraw memory batchOrder = batchWithdrawOrders[order.batchId]; (uint256 amount, uint256 orderFee) = _calculateOrderAmount(order, batchOrder); info[i] = UserWithdrawOrderInfo({ orderId: orderId, amount: amount - orderFee, fee: order.fee, claimableAt: order.claimableAt, isClaimable: _canClaim(order) }); if (index == 0) break; } } return (info, block.timestamp, totalPages); } /** CLAYSTACK STAKING **/ /// @notice Initiates transfer process to Ethereum /// @param _validatorCapacity Number of validators capacity /// @return currentBatchId - current batch id from autobalance /// @return netStaking - whether staking or unstaking /// @return validatorCount - number of validators to stake or unstake function autoBalance( uint256 _validatorCapacity ) external whenNotPaused nonReentrant returns (uint256 currentBatchId, bool netStaking, uint256 validatorCount) { require(msg.sender == address(nodeManager), "Send invalid, must be node manager"); _updateBalance(); currentBatchId = batchId; netStaking = false; validatorCount = 0; uint256 currentDeposit = funds.currentDeposit; uint256 stakedDeposit = funds.stakedDeposit; /** UNSTAKING **/ if (currentDeposit < stakedDeposit) { uint256 toUnStake = stakedDeposit - currentDeposit; validatorCount = toUnStake / DEPOSIT_SIZE; uint256 extra = toUnStake % DEPOSIT_SIZE; // increase unstake amount to unstake full validator if (extra != 0) { validatorCount += 1; toUnStake = _min(stakedDeposit, validatorCount * DEPOSIT_SIZE); } if (validatorCount != 0) { funds.stakedDeposit -= toUnStake; funds.unstakeInternal += toUnStake; } batchId++; emit LogAutoBalance(currentBatchId, netStaking, toUnStake); } /** STAKING **/ else if (currentDeposit >= stakedDeposit) { uint256 availableToStake = ethBalance - funds.claimablePool; uint256 toStake = _min(currentDeposit - stakedDeposit, availableToStake); validatorCount = _min(toStake / DEPOSIT_SIZE, _validatorCapacity); // Close batch if staked or if withdrawals within batch to unlock them if (validatorCount != 0 || withdrawQueueActive) { _closeBatch(currentBatchId); batchId++; withdrawQueueActive = false; } if (validatorCount != 0) { netStaking = true; toStake = validatorCount * DEPOSIT_SIZE; funds.stakedDeposit += toStake; ethBalance -= toStake; (bool success, ) = address(nodeManager).call{value: toStake}(""); require(success, "Transfer of funds to nodeManager failed"); emit LogAutoBalance(currentBatchId, netStaking, toStake); } } _updateClaimablePool(); _balanced(); } /// @notice Receives rewards and exits from NodeManager /// @dev Any extra amount sent additional to rewards and exited, are rewards previously reported /// @param _rewards receives as part of the total amount /// @param _exited exits as part of the total amount function receiveLiquidity(uint256 _rewards, uint256 _exited) external payable whenNotPaused nonReentrant { require(msg.sender == address(nodeManager), "Send invalid, must be node manager"); uint256 extraReceived = msg.value - _rewards - _exited; // update rewards if (_rewards != 0) { _reportRewards(_rewards); } // update staked reference sequentially if (_exited != 0) { _updateStakingAccounts(_exited); } // update contract reference if (extraReceived != 0) { funds.stakedDeposit -= extraReceived; } _updateBalance(); _updateClaimablePool(); _balanced(); } /// @notice updateBalance public call function updateBalances() external whenNotPaused nonReentrant { _updateBalance(); _updateClaimablePool(); _balanced(); } /// @notice Receives confirmation from NodeManager on batch finalization /// @param _batchIds list of claimed batches function closeBatches(uint256[] calldata _batchIds) external nonReentrant { require(msg.sender == address(nodeManager), "Send invalid, must be node manager"); for (uint256 i = 0; i < _batchIds.length; i++) { _closeBatch(_batchIds[i]); } } /// @notice Adjust the multiplier and updates the funds.withdrawQueueOpen /// @param _batchId batchId to close function _closeBatch(uint256 _batchId) internal { BatchWithdraw memory batchOrder = batchWithdrawOrders[_batchId]; require(batchOrder.claimableAt == 0, "batchId already processed"); batchWithdrawOrders[_batchId].claimableAt = block.timestamp; uint256 multiplier = 0; // adjust withdrawQueue if batch contains withdrawals if (batchOrder.amount != 0) { uint256 amountTokens = _exchangeCsToken(batchOrder.amountCs, funds.currentDeposit); multiplier = (amountTokens * PRECISION) / batchOrder.amount; batchWithdrawOrders[_batchId].multiplier = multiplier; amountTokens = amountTokens >= batchOrder.amount ? batchOrder.amount : amountTokens; if (amountTokens > funds.withdrawQueueOpen) { // The reduction may have been too conservative before // it will add back to withdrawQueue the difference uint256 extra = amountTokens - funds.withdrawQueueOpen; funds.withdrawQueue += extra; funds.currentDeposit -= extra; funds.withdrawQueueOpen = 0; } else { funds.withdrawQueueOpen -= amountTokens; } } emit LogBatchClosed(_batchId, batchOrder.amount, batchOrder.amountCs, multiplier); } /// @notice Used for receiving donations receive() external payable { uint256 donation = msg.value; ethBalance += donation; _reportRewards(donation); _updateExchangeRate(); emit LogDonation(donation); } /// @notice Updates the funds accounting and the claimable pool depending on the current state function _updateClaimablePool() internal { uint256 unstakeExternal = funds.unstakeExternal; // Unstake update swap given new withdrawals if (funds.unstakeInternal > 0) { uint256 swaps = _min( funds.withdrawQueue - funds.unstakeExternal - funds.claimablePool, funds.unstakeInternal ); unstakeExternal += swaps; funds.unstakeExternal = unstakeExternal; funds.unstakeInternal = funds.unstakeInternal - swaps; } /* @dev There are two cases where funds.claimablePool is updated: 1. Maximized reserves what is not accounted on external unstaking, but max to the liquidity 2. Or the current level, yet capped at the max withdraw queue. This changes due slashing */ funds.claimablePool = _max( _min(funds.claimablePool, funds.withdrawQueue), _min(funds.withdrawQueue - unstakeExternal, ethBalance) ); } /// @notice Updates balances and emits LogRewards function _updateBalance() internal { uint256 currentEthbalance = address(this).balance; uint256 txValue = msg.value; if (currentEthbalance == (ethBalance + txValue)) { ethBalance += txValue; } else if (currentEthbalance > ethBalance) { uint256 balanceDiff = currentEthbalance - (ethBalance + txValue); ethBalance = currentEthbalance; _reportRewards(balanceDiff); _updateExchangeRate(); emit LogDonation(balanceDiff); } ( , uint256 rewards, uint256 penalties, uint256 rewardsStrategies, uint256 penaltiesStrategies ) = _calculateBalances(); uint256 currentDeposit = funds.currentDeposit; if (rewards != 0) { _reportRewards(rewards); funds.stakedDeposit += rewards; // assumes all the rewards are in non-exit triggered nodes } else if (penalties != 0) { // penalties are distributed proportionally to holders and withdraw orders uint256 penaltiesToHolders = (penalties * currentDeposit) / (currentDeposit + funds.withdrawQueueOpen); currentDeposit -= penaltiesToHolders; funds.currentDeposit = currentDeposit; uint256 penaltiesToClaims = 0; if (funds.withdrawQueueOpen != 0) { penaltiesToClaims = penalties - penaltiesToHolders; funds.withdrawQueue -= penaltiesToClaims; funds.withdrawQueueOpen -= penaltiesToClaims; } emit LogPenalties(penaltiesToHolders, penaltiesToClaims); _updateStakingAccounts(penalties); } // Adjust for EigenLayer Strategies if (rewardsStrategies != 0) { _reportRewards(rewardsStrategies); ethStrategiesManager += rewardsStrategies; } else if (penaltiesStrategies != 0) { currentDeposit -= penaltiesStrategies; funds.currentDeposit = currentDeposit; ethStrategiesManager -= penaltiesStrategies; emit LogPenalties(penaltiesStrategies, 0); } } /// @notice Updates balances based on staking report, rewards, and penalties function _calculateBalances() internal view returns ( uint256 currentDeposit, uint256 rewards, uint256 penalties, uint256 rewardsStrategies, uint256 penaltiesStrategies ) { currentDeposit = funds.currentDeposit; rewards = 0; penalties = 0; rewardsStrategies = 0; penaltiesStrategies = 0; uint256 beaconBalance = nodeManager.getBalance(); uint256 previousBalance = funds.stakedDeposit + funds.unstakeExternal + funds.unstakeInternal; if (beaconBalance > previousBalance) { rewards = beaconBalance - previousBalance; currentDeposit += rewards; } else if (beaconBalance < previousBalance) { penalties = previousBalance - beaconBalance; uint256 penaltiesToHolders = (penalties * currentDeposit) / (currentDeposit + funds.withdrawQueueOpen); currentDeposit -= penaltiesToHolders; } // Adjust for EigenLayer Strategies uint256 strategiesBalance = address(strategiesManager) != address(0) ? strategiesManager.getBalance() : 0; uint256 previousStrategiesBalance = ethStrategiesManager; if (strategiesBalance > previousStrategiesBalance) { rewardsStrategies = strategiesBalance - previousStrategiesBalance; currentDeposit += rewardsStrategies; } else if (strategiesBalance < previousStrategiesBalance) { penaltiesStrategies = previousStrategiesBalance - strategiesBalance; currentDeposit -= penaltiesStrategies; } } /// @notice Updates rewards /// @param _rewards amount of rewards to update function _reportRewards(uint256 _rewards) internal { funds.currentDeposit += _rewards; emit LogRewards(_rewards); } /// @notice Updates accounting of staked assets /// @dev Assumes that penalties and exits are ordered as follows: external, internal, staked. /// If there are insufficient funds to cover penalties and exits, the orders can be fulfilled /// once the exits are finalized and amounts are known. The `receiveLiquidity` function will also be updated. /// @param _amount The amount of either exit value or penalty applied. function _updateStakingAccounts(uint256 _amount) internal { uint256 unstakeExternal = funds.unstakeExternal; if (unstakeExternal != 0) { uint256 amount = _min(_amount, unstakeExternal); funds.unstakeExternal -= amount; _amount -= amount; } uint256 unstakeInternal = funds.unstakeInternal; if (unstakeInternal != 0 && _amount != 0) { uint256 amounts = _min(_amount, unstakeInternal); funds.unstakeInternal -= amounts; _amount -= amounts; } uint256 stakedDeposit = funds.stakedDeposit; if (stakedDeposit != 0 && _amount != 0) { uint256 amount = _min(_amount, stakedDeposit); funds.stakedDeposit -= amount; _amount -= amount; } assert(_amount <= 0); } /// @notice Updates the exchange rate function _updateExchangeRate() internal { uint256 latest = _exchangeCsToken(1 ether, funds.currentDeposit); lastExchangeRate = latest; emit LogUpdateExchangeRate(latest, block.timestamp); } /// @notice Verifies rate is within bound otherwise pauses the contract function _exchangeRateProtection() internal { uint256 currentRate = _exchangeCsToken(1 ether, funds.currentDeposit); uint256 oldRate = lastExchangeRate; //slither-disable-next-line incorrect-equality if (oldRate == currentRate) return; uint256 currentDeviation = 0; uint256 allowedDeviation = 0; if (currentRate < oldRate) { // rate decrease currentDeviation = oldRate - currentRate; allowedDeviation = (oldRate * exchangeDeviation.exchangeDecreaseLimit) / PERCENTAGE_BASE; } else if (currentRate > oldRate) { // rate increase currentDeviation = currentRate - oldRate; allowedDeviation = (oldRate * exchangeDeviation.exchangeIncreaseLimit) / PERCENTAGE_BASE; } if (currentDeviation > allowedDeviation) { _pause(); } else { _updateExchangeRate(); } } // @dev Assures contract state remains balanced by comparing user flows deposits vs staking flows. function _balanced() internal { uint256 currentDeposit = funds.currentDeposit; require(currentDeposit > 0, "Current deposits cannot go to zero"); uint256 userFlow = (currentDeposit + funds.withdrawQueue) / 1e16; uint256 stakingFlow = (ethBalance + funds.stakedDeposit + funds.unstakeInternal + funds.unstakeExternal + ethStrategiesManager) / 1e16; require(stakingFlow <= userFlow + 1 && userFlow <= stakingFlow + 1, "Unbalanced contract"); _exchangeRateProtection(); } /** ADMIN **/ /// @notice Sets the minimum time for a claim tokens when netted locally. /// @param _seconds claim time function setMinClaimTime(uint256 _seconds) external onlyRole(TIMELOCK_ROLE) { require(_seconds <= MAX_UNBONDING, "Minimum claim time too high"); minClaimSeconds = _seconds; emit LogSetMinClaimTime(_seconds); } /// @notice Sets new fee percent for given `feeType_` to `fee_`. /// @param _feeType : Index of `feeType` to be updated. /// @param _fee : New fee percent. function setFee(SetFee _feeType, uint256 _fee) external onlyRole(TIMELOCK_ROLE) { require(_fee < PERCENTAGE_BASE, "Invalid fee"); uint256 oldFee = 0; if (_feeType == SetFee.DepositFee) { require(_fee <= MAX_DEPOSIT_FEE, "Invalid deposit fee"); oldFee = fees.depositFee; fees.depositFee = _fee; } else if (_feeType == SetFee.WithdrawFee) { oldFee = fees.withdrawFee; require(_fee <= MAX_WITHDRAW_FEE, "Invalid withdraw fee"); fees.withdrawFee = _fee; } else if (_feeType == SetFee.InstantWithdrawFee) { oldFee = fees.instantWithdrawFee; require(_fee <= MAX_INSTANT_WITHDRAW_FEE, "Instant Withdraw fee above max limit"); fees.instantWithdrawFee = _fee; } emit LogFeeUpdate(msg.sender, _feeType, oldFee, _fee); } /// @notice Disables withdrawals and claims /// @dev Can be called both by CS_SERVICE_ROLE or by the NodeManager /// @param _disabled : True to disable, false to enable function setWithdrawalsDisabled(bool _disabled) external { require( msg.sender == address(nodeManager) || roleManager.checkRole(CS_SERVICE_ROLE, msg.sender), "Auth Failed" ); withdrawalsDisabled = _disabled; emit LogSetWithdrawalsDisabled(_disabled); } /// @notice Updates Exchange rate allowed percentage deviation. /// @param _decreaseLimit - Max allowed rate decrease percentage based on last valid exchange rate /// @param _increaseLimit - Max allowed rate increase percentage based on last valid exchange rate function setExchangeDeviation(uint256 _decreaseLimit, uint256 _increaseLimit) external onlyRole(TIMELOCK_ROLE) { require(_decreaseLimit > 0 && _decreaseLimit <= PERCENTAGE_BASE, "Invalid decrease percent"); require(_increaseLimit > 0 && _increaseLimit <= PERCENTAGE_BASE, "Invalid increase percent"); ExchangeDeviation storage info = exchangeDeviation; info.exchangeDecreaseLimit = _decreaseLimit; info.exchangeIncreaseLimit = _increaseLimit; emit LogSetExchangeDeviation(_decreaseLimit, _increaseLimit); } /// @notice Sets StrategiesManager once /// @param _strategiesManager instance of _strategiesManager function setStrategiesManager(IStrategiesManager _strategiesManager) external onlyRole(TIMELOCK_ROLE) { require(address(strategiesManager) == address(0), "StrategiesManager already set"); require(address(_strategiesManager) != address(0), "StrategiesManager must be valid"); strategiesManager = _strategiesManager; emit LogSetStrategiesManager(address(_strategiesManager)); } /** SUPPORT **/ /// @dev returns the smaller number between a and b function _min(uint256 _a, uint256 _b) internal pure returns (uint256) { return _a > _b ? _b : _a; } /// @dev returns the bigger number between a and b function _max(uint256 _a, uint256 _b) internal pure returns (uint256) { return _a > _b ? _a : _b; } /// @notice Triggers stopped state. function pause() external onlyRole(CS_SERVICE_ROLE) whenNotPaused { _pause(); } /// @notice Returns to normal state. function unpause() external onlyRole(CS_SERVICE_ROLE) whenPaused { _updateExchangeRate(); _unpause(); } /// @notice Checks caller has the given `_roleName` or not. /// @param _roleName supported by RoleManager function _onlyRole(bytes32 _roleName) internal view { require(roleManager.checkRole(_roleName, msg.sender), "Auth Failed"); } /// @notice Upgrade the implementation of the proxy to `_newImplementation`. /// @param _newImplementation : Address of new implementation of the contract function upgradeTo( address _newImplementation ) external virtual override onlyRole(TIMELOCK_UPGRADES_ROLE) onlyProxy { _authorizeUpgrade(_newImplementation); _upgradeTo(_newImplementation); } /// @notice Function that should revert when `msg.sender` is not authorized to upgrade the contract or /// @param _newImplementation : Address of new implementation of the contract. function _authorizeUpgrade(address _newImplementation) internal virtual override onlyRole(TIMELOCK_UPGRADES_ROLE) { require(_newImplementation.code.length > 0, "!contract"); } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"previousAdmin","type":"address"},{"indexed":false,"internalType":"address","name":"newAdmin","type":"address"}],"name":"AdminChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"beacon","type":"address"}],"name":"BeaconUpgraded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint8","name":"version","type":"uint8"}],"name":"Initialized","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"batchId","type":"uint256"},{"indexed":true,"internalType":"bool","name":"isNetStaking","type":"bool"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"LogAutoBalance","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"batchId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amountCs","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"multiplier","type":"uint256"}],"name":"LogBatchClosed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"orderId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"received","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"fee","type":"uint256"}],"name":"LogClaim","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amountCs","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"fee","type":"uint256"}],"name":"LogDeposit","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"address","name":"referral","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"LogDepositWithReferral","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"LogDonation","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"updatedBy","type":"address"},{"indexed":false,"internalType":"enum IClayMain.SetFee","name":"feeType","type":"uint8"},{"indexed":false,"internalType":"uint256","name":"oldFee","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newFee","type":"uint256"}],"name":"LogFeeUpdate","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"amountCs","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"fee","type":"uint256"}],"name":"LogInstantWithdraw","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"penaltiesToHolders","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"penaltiesToClaims","type":"uint256"}],"name":"LogPenalties","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"rewards","type":"uint256"}],"name":"LogRewards","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"newDecreaseLimit","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"newIncreaseLimit","type":"uint256"}],"name":"LogSetExchangeDeviation","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"newMinClaimSeconds","type":"uint256"}],"name":"LogSetMinClaimTime","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"strategiesManager","type":"address"}],"name":"LogSetStrategiesManager","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bool","name":"flag","type":"bool"}],"name":"LogSetWithdrawalsDisabled","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"rate","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"time","type":"uint256"}],"name":"LogUpdateExchangeRate","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"orderId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amountCs","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"fee","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"LogWithdraw","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"implementation","type":"address"}],"name":"Upgraded","type":"event"},{"inputs":[{"internalType":"uint256","name":"_validatorCapacity","type":"uint256"}],"name":"autoBalance","outputs":[{"internalType":"uint256","name":"currentBatchId","type":"uint256"},{"internalType":"bool","name":"netStaking","type":"bool"},{"internalType":"uint256","name":"validatorCount","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"batchId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"batchWithdrawOrders","outputs":[{"internalType":"uint256","name":"claimableAt","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"amountCs","type":"uint256"},{"internalType":"uint256","name":"multiplier","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"_orderIds","type":"uint256[]"}],"name":"claim","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"_batchIds","type":"uint256[]"}],"name":"closeBatches","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"csToken","outputs":[{"internalType":"contract ICSToken","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"deposit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"_delegatedTo","type":"address"}],"name":"depositDelegate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"_delegatedTo","type":"address"},{"internalType":"address","name":"_referral","type":"address"}],"name":"depositDelegateWithReferral","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"_referral","type":"address"}],"name":"depositWithReferral","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"ethBalance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ethStrategiesManager","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amountCsToken","type":"uint256"}],"name":"exchangeCsToken","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"exchangeDeviation","outputs":[{"internalType":"uint256","name":"exchangeDecreaseLimit","type":"uint256"},{"internalType":"uint256","name":"exchangeIncreaseLimit","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amountsToken","type":"uint256"}],"name":"exchangeToken","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"fees","outputs":[{"internalType":"uint256","name":"depositFee","type":"uint256"},{"internalType":"uint256","name":"withdrawFee","type":"uint256"},{"internalType":"uint256","name":"instantWithdrawFee","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"funds","outputs":[{"internalType":"uint256","name":"currentDeposit","type":"uint256"},{"internalType":"uint256","name":"withdrawQueue","type":"uint256"},{"internalType":"uint256","name":"stakedDeposit","type":"uint256"},{"internalType":"uint256","name":"unstakeExternal","type":"uint256"},{"internalType":"uint256","name":"unstakeInternal","type":"uint256"},{"internalType":"uint256","name":"withdrawQueueOpen","type":"uint256"},{"internalType":"uint256","name":"claimablePool","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getExchangeRate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getLiquidityCsToken","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"},{"internalType":"uint256","name":"_page","type":"uint256"}],"name":"getUserOrders","outputs":[{"components":[{"internalType":"uint256","name":"orderId","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"fee","type":"uint256"},{"internalType":"uint256","name":"claimableAt","type":"uint256"},{"internalType":"bool","name":"isClaimable","type":"bool"}],"internalType":"struct IClayMain.UserWithdrawOrderInfo[]","name":"","type":"tuple[]"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_csToken","type":"address"},{"internalType":"address","name":"_nodeManager","type":"address"},{"internalType":"address","name":"_roleManager","type":"address"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amountCs","type":"uint256"}],"name":"instantWithdraw","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"address","name":"_delegatedTo","type":"address"},{"internalType":"address","name":"_referral","type":"address"}],"name":"internalDepositDelegate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amountCs","type":"uint256"},{"internalType":"address","name":"_user","type":"address"}],"name":"internalWithdraw","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"lastExchangeRate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"minClaimSeconds","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"proxiableUUID","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_rewards","type":"uint256"},{"internalType":"uint256","name":"_exited","type":"uint256"}],"name":"receiveLiquidity","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_decreaseLimit","type":"uint256"},{"internalType":"uint256","name":"_increaseLimit","type":"uint256"}],"name":"setExchangeDeviation","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"enum IClayMain.SetFee","name":"_feeType","type":"uint8"},{"internalType":"uint256","name":"_fee","type":"uint256"}],"name":"setFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_seconds","type":"uint256"}],"name":"setMinClaimTime","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IStrategiesManager","name":"_strategiesManager","type":"address"}],"name":"setStrategiesManager","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_disabled","type":"bool"}],"name":"setWithdrawalsDisabled","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"strategiesManager","outputs":[{"internalType":"contract IStrategiesManager","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"unpause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"updateBalances","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_newImplementation","type":"address"}],"name":"upgradeTo","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newImplementation","type":"address"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"upgradeToAndCall","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"userWithdrawIds","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amountCs","type":"uint256"}],"name":"withdraw","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"withdrawOrders","outputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"fee","type":"uint256"},{"internalType":"uint256","name":"claimableAt","type":"uint256"},{"internalType":"uint256","name":"batchId","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"withdrawQueueActive","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"withdrawalsDisabled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"stateMutability":"payable","type":"receive"}]
Contract Creation Code
60a06040523060805234801561001457600080fd5b50608051614ec861005a60003960008181611368015281816113a8015281816114ff0152818161153f015281816115b70152818161218201526121c20152614ec86000f3fe6080604052600436106102765760003560e01c80636f3fe4041161014f578063c18d7cb7116100c1578063e1c603f61161007a578063e1c603f614610829578063e6aa216c14610849578063e8e0da3e1461085e578063eba98b8a146108a1578063f18574a0146108c1578063fd92bff2146108e157600080fd5b8063c18d7cb714610737578063c483a33e1461074a578063c89f2ce414610783578063d0e30db0146107ee578063da26ec22146107f6578063e04605fd1461080957600080fd5b80638d0411db116101135780638d0411db1461066b5780638f78c3111461068b5780639764e249146106ab5780639af1d35a146106c25780639c705b47146106fc578063c0c53b8b1461071757600080fd5b80636f3fe404146105c45780637e70d9c5146105d95780638456cb591461061457806388ae7f2e146106295780638c6aa3f51461064b57600080fd5b80633f4ba83a116101e857806352d1902d116101ac57806352d1902d1461051d5780635c975abb146105325780635f1625b714610556578063693f0ca814610576578063695a1aea1461058d5780636ba4c138146105a457600080fd5b80633f4ba83a14610459578063466204161461046e5780634972134a146104dc5780634e6630b0146104f35780634f1ef2861461050a57600080fd5b80631c3c2e241161023a5780631c3c2e24146103a45780632951913c146103b95780632b8bb70c146103d95780632e1a7d4d146103f95780633659cfe6146104195780633b1908111461043957600080fd5b8063020fdae2146102e45780630e3d9cf11461031c57806314309fca1461033f5780631647f7e1146103525780631b18662f1461038457600080fd5b366102df576000349050806101126000828254610293919061462a565b909155506102a2905081610901565b6102aa610953565b6040518181527f7926e9adf71c42b63be07a89b069672dbe3702e8e42b5c1a246b82d1b37d4d1f9060200160405180910390a1005b600080fd5b3480156102f057600080fd5b506103046102ff366004614652565b6109ab565b6040516103139392919061467e565b60405180910390f35b34801561032857600080fd5b50610331610c2b565b604051908152602001610313565b61033161034d3660046146fb565b610c68565b34801561035e57600080fd5b5061010c5461010d5461036f919082565b60408051928352602083019190915201610313565b34801561039057600080fd5b5061033161039f366004614734565b610d61565b6103b76103b236600461474d565b610d83565b005b3480156103c557600080fd5b506103b76103d436600461477d565b610e3e565b3480156103e557600080fd5b506103316103f4366004614652565b610f4b565b34801561040557600080fd5b50610331610414366004614734565b610f7d565b34801561042557600080fd5b506103b761043436600461479a565b611334565b34801561044557600080fd5b506103b7610454366004614734565b611410565b34801561046557600080fd5b506103b76114b0565b34801561047a57600080fd5b506104bc610489366004614652565b61010160209081526000928352604080842090915290825290208054600182015460028301546003909301549192909184565b604080519485526020850193909352918301526060820152608001610313565b3480156104e857600080fd5b5061033161010e5481565b3480156104ff57600080fd5b506103316101125481565b6103b76105183660046147cd565b6114f5565b34801561052957600080fd5b506103316115aa565b34801561053e57600080fd5b5060975460ff165b6040519015158152602001610313565b34801561056257600080fd5b506103b761057136600461479a565b61165e565b34801561058257600080fd5b506103316101135481565b34801561059957600080fd5b506103316101105481565b3480156105b057600080fd5b506105466105bf366004614891565b61177c565b3480156105d057600080fd5b506103b761199e565b3480156105e557600080fd5b506105f96105f4366004614734565b6119d2565b60408051938452911515602084015290820152606001610313565b34801561062057600080fd5b506103b7611d3c565b34801561063557600080fd5b506101005461054690600160a01b900460ff1681565b34801561065757600080fd5b506103b7610666366004614906565b611d76565b34801561067757600080fd5b50610331610686366004614928565b611f79565b34801561069757600080fd5b506103316106a6366004614734565b61209d565b3480156106b757600080fd5b506103316101115481565b3480156106ce57600080fd5b5060fb5460fc5460fd546106e192919083565b60408051938452602084019290925290820152606001610313565b34801561070857600080fd5b5061010b546105469060ff1681565b34801561072357600080fd5b506103b761073236600461496a565b6120b8565b61033161074536600461479a565b6123de565b34801561075657600080fd5b506101145461076b906001600160a01b031681565b6040516001600160a01b039091168152602001610313565b34801561078f57600080fd5b5061010454610105546101065461010754610108546101095461010a546107b99695949392919087565b604080519788526020880196909652948601939093526060850191909152608084015260a083015260c082015260e001610313565b6103316124a2565b61033161080436600461479a565b6124cc565b34801561081557600080fd5b5060ff5461076b906001600160a01b031681565b34801561083557600080fd5b506103b7610844366004614891565b61251c565b34801561085557600080fd5b5061033161258d565b34801561086a57600080fd5b506104bc610879366004614734565b6101026020526000908152604090208054600182015460028301546003909301549192909184565b3480156108ad57600080fd5b506103316108bc36600461499a565b6125b6565b3480156108cd57600080fd5b506103b76108dc36600461474d565b6128ae565b3480156108ed57600080fd5b506105466108fc366004614734565b6129c1565b806101046000016000828254610917919061462a565b90915550506040518181527f872e90f6155f65f8bcd3c0ce902abd4e2cb622c9ab5d72c588a1a7ed98194c90906020015b60405180910390a150565b600061096d670de0b6b3a764000061010460000154612d09565b610111819055604080518281524260208201529192507fa21de314e188ba49fe0cc48414f955a0c3ba27013855d78d9ddcbce640504d409101610948565b60408051600a80825261016082019092526060916000918291829190816020015b610a006040518060a00160405280600081526020016000815260200160008152602001600081526020016000151581525090565b8152602001906001900390816109cc5750506001600160a01b03871660009081526101036020526040812054919250600a9190610a3d83836149d5565b9050600082118015610a565750610a5483836149e9565b155b15610a695780610a65816149fd565b9150505b808811158015610a7857508115155b15610c1a5760005b83811015610c18576000600182610a97878d614a14565b610aa19087614a2b565b610aab9190614a2b565b610ab59190614a2b565b6001600160a01b038c166000908152610103602052604081208054929350909183908110610ae557610ae5614a3e565b60009182526020808320909101546001600160a01b038f1683526101018252604080842082855283528084208151608080820184528254825260018084015483880152600280850154848701526003948501546060808601829052908a526101028952868a208751948501885280548552928301549884019890985281015494820194909452929091015493820193909352909350909180610b878484612dca565b915091506040518060a001604052808681526020018284610ba89190614a2b565b81526020018560200151815260200185604001518152602001610bca86612e7b565b15158152508b8881518110610be157610be1614a3e565b602002602001018190525085600003610bff57505050505050610c18565b5050505050508080610c1090614a54565b915050610a80565b505b929842985092965091945050505050565b600080610c36612f66565b5050505090506000610c46613165565b905080600003610c57576000610c61565b610c61818361317e565b9250505090565b6000610c72613224565b610c7a61326a565b6001600160a01b038316610ca95760405162461bcd60e51b8152600401610ca090614a6d565b60405180910390fd5b6001600160a01b038216610cf25760405162461bcd60e51b815260206004820152601060248201526f125b9d985b1a59081c9959995c9c985b60821b6044820152606401610ca0565b6000610d00348560006132c3565b9050826001600160a01b0316846001600160a01b03167f81fbde7da9aa460bc4230d1e4c27e6f5a95c773ae70f2abc3deb71fedd82e09234604051610d4791815260200190565b60405180910390a39050610d5b600160c955565b92915050565b600080610d6c612f66565b505050509050610d7c8382612d09565b9392505050565b610d8b613224565b610d9361326a565b610100546001600160a01b03163314610dbe5760405162461bcd60e51b8152600401610ca090614a9a565b600081610dcb8434614a2b565b610dd59190614a2b565b90508215610de657610de683610901565b8115610df557610df5826134b5565b8015610e1757806101046002016000828254610e119190614a2b565b90915550505b610e1f6135a3565b610e276137fb565b610e2f6138a1565b50610e3a600160c955565b5050565b610100546001600160a01b0316331480610ee5575060fe546040516312d9a6ad60e01b81527f70afc91226fba57efa6b459a2add00f29a9a7961e6eb3103074a44780ab8cdc860048201523360248201526001600160a01b03909116906312d9a6ad90604401602060405180830381865afa158015610ec1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ee59190614adc565b610f015760405162461bcd60e51b8152600401610ca090614af9565b610100805460ff60a01b1916600160a01b831515908102919091179091556040517fb90d13b85674cde408204dc341b2aa33c9cc1d514c87870836a213e74a6cf14b90600090a250565b6101036020528160005260406000208181548110610f6857600080fd5b90600052602060002001600091509150505481565b6000610f87613224565b610f8f61326a565b61010054600160a01b900460ff1615610fba5760405162461bcd60e51b8152600401610ca090614b1e565b81600003610fda5760405162461bcd60e51b8152600401610ca090614b4c565b60ff546040516370a0823160e01b815233600482015283916001600160a01b0316906370a0823190602401602060405180830381865afa158015611022573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110469190614b83565b10156110645760405162461bcd60e51b8152600401610ca090614b9c565b61106c6135a3565b61010454600061107c8483612d09565b90508060000361109e5760405162461bcd60e51b8152600401610ca090614bdd565b610113546110ac9083614a2b565b8111156110cb5760405162461bcd60e51b8152600401610ca090614c0b565b61010b805460ff1916600117905561010480548291906000906110ef908490614a2b565b9091555050610105805482919060009061110a90849061462a565b9091555050610109805482919060009061112590849061462a565b909155505060ff54604051632770a7eb60e21b8152336004820152602481018690526001600160a01b0390911690639dc29fac906044016020604051808303816000875af115801561117b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061119f9190614adc565b6111bb5760405162461bcd60e51b8152600401610ca090614c4e565b600061010f600081546111cd90614a54565b9190508190559050604051806080016040528083815260200160fb6001015481526020016101105442611200919061462a565b815261010e80546020928301523360009081526101018352604080822086835284528082208551815585850151600180830191909155868301516002830155606090960151600390910155915481526101029092528120909101805484929061126a90849061462a565b909155505061010e54600090815261010260205260408120600201805487929061129590849061462a565b909155505033600090815261010360209081526040822080546001810182559083529120018190556112c56137fb565b6112cd6138a1565b60fc546040805183815260208101889052908101849052606081019190915242608082015233907f0af70755b8d8f9e1aa3e6ff252c56885ef3b60f9f98c318a0df1502d10923d7a9060a00160405180910390a29250505061132f600160c955565b919050565b7fb8ea7c31de614c54f5b3938aa9732e87deb869a880ec52d4bb778c09789441b161135e816139ed565b6001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001630036113a65760405162461bcd60e51b8152600401610ca090614c73565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166113d8613a7c565b6001600160a01b0316146113fe5760405162461bcd60e51b8152600401610ca090614cbf565b61140782613a98565b610e3a82613b08565b600080516020614e2c833981519152611428816139ed565b6276a70082111561147b5760405162461bcd60e51b815260206004820152601b60248201527f4d696e696d756d20636c61696d2074696d6520746f6f206869676800000000006044820152606401610ca0565b61011082905560405182907f0c85bd8af73992514968a932f5ba7becbfb7965f14abceb3bf0d5bf08694646b90600090a25050565b7f70afc91226fba57efa6b459a2add00f29a9a7961e6eb3103074a44780ab8cdc86114da816139ed565b6114e2613b48565b6114ea610953565b6114f2613b91565b50565b6001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016300361153d5760405162461bcd60e51b8152600401610ca090614c73565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031661156f613a7c565b6001600160a01b0316146115955760405162461bcd60e51b8152600401610ca090614cbf565b61159e82613a98565b610e3a82826001613be3565b6000306001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000161461164a5760405162461bcd60e51b815260206004820152603860248201527f555550535570677261646561626c653a206d757374206e6f742062652063616c60448201527f6c6564207468726f7567682064656c656761746563616c6c00000000000000006064820152608401610ca0565b50600080516020614e4c8339815191525b90565b600080516020614e2c833981519152611676816139ed565b610114546001600160a01b0316156116d05760405162461bcd60e51b815260206004820152601d60248201527f537472617465676965734d616e6167657220616c7265616479207365740000006044820152606401610ca0565b6001600160a01b0382166117265760405162461bcd60e51b815260206004820152601f60248201527f537472617465676965734d616e61676572206d7573742062652076616c6964006044820152606401610ca0565b61011480546001600160a01b0319166001600160a01b0384169081179091556040519081527fc588eda4a659cb62d9f834c8c05ed21678af0b87f6a08926d98e0f16b00888a69060200160405180910390a15050565b6000611786613224565b61178e61326a565b61010054600160a01b900460ff16156117b95760405162461bcd60e51b8152600401610ca090614b1e565b81600081900361180b5760405162461bcd60e51b815260206004820152601760248201527f496e76616c6964206f72646572204964206c656e6774680000000000000000006044820152606401610ca0565b6118136135a3565b60008060005b858110156118785760008061184689898581811061183957611839614a3e565b9050602002013533613d4e565b9092509050611855828661462a565b9450611861818561462a565b93505050808061187090614a54565b915050611819565b50816000036118c25760405162461bcd60e51b815260206004820152601660248201527524b73b30b634b21030b6b7bab73a103a37903ab9b2b960511b6044820152606401610ca0565b80156118e4578061010460000160008282546118de919061462a565b90915550505b604051600090339084908381818185875af1925050503d8060008114611926576040519150601f19603f3d011682016040523d82523d6000602084013e61192b565b606091505b505090508061197c5760405162461bcd60e51b815260206004820181905260248201527f5472616e73666572206f662066756e647320746f2075736572206661696c65646044820152606401610ca0565b6119846137fb565b61198c6138a1565b6001945050505050610d5b600160c955565b6119a6613224565b6119ae61326a565b6119b66135a3565b6119be6137fb565b6119c66138a1565b6119d0600160c955565b565b60008060006119df613224565b6119e761326a565b610100546001600160a01b03163314611a125760405162461bcd60e51b8152600401610ca090614a9a565b611a1a6135a3565b505061010e54610104546101065491925060009182919080821015611b3c576000611a458383614a2b565b9050611a5a6801bc16d674ec800000826149d5565b93506000611a716801bc16d674ec800000836149e9565b90508015611aa557611a8460018661462a565b9450611aa283611a9d6801bc16d674ec80000088614a14565b614032565b91505b8415611ae257816101046002016000828254611ac19190614a2b565b90915550506101088054839190600090611adc90849061462a565b90915550505b61010e8054906000611af383614a54565b9190505550851515877feba6465416eefa23c736aaaef02a6f286d930650af93fb71e1ae6192e0a8704c84604051611b2d91815260200190565b60405180910390a35050611d19565b808210611d195761010a5461011254600091611b5791614a2b565b90506000611b6e611b688486614a2b565b83614032565b9050611b8c611b866801bc16d674ec800000836149d5565b89614032565b945084151580611b9f575061010b5460ff165b15611bcf57611bad87614047565b61010e8054906000611bbe83614a54565b909155505061010b805460ff191690555b8415611d165760019550611bec6801bc16d674ec80000086614a14565b9050806101046002016000828254611c04919061462a565b92505081905550806101126000828254611c1e9190614a2b565b9091555050610100546040516000916001600160a01b03169083908381818185875af1925050503d8060008114611c71576040519150601f19603f3d011682016040523d82523d6000602084013e611c76565b606091505b5050905080611cd75760405162461bcd60e51b815260206004820152602760248201527f5472616e73666572206f662066756e647320746f206e6f64654d616e616765726044820152660819985a5b195960ca1b6064820152608401610ca0565b861515887feba6465416eefa23c736aaaef02a6f286d930650af93fb71e1ae6192e0a8704c84604051611d0c91815260200190565b60405180910390a3505b50505b611d216137fb565b611d296138a1565b5050611d35600160c955565b9193909250565b7f70afc91226fba57efa6b459a2add00f29a9a7961e6eb3103074a44780ab8cdc8611d66816139ed565b611d6e613224565b6114f2614237565b600080516020614e2c833981519152611d8e816139ed565b6127108210611dcd5760405162461bcd60e51b815260206004820152600b60248201526a496e76616c69642066656560a81b6044820152606401610ca0565b600080846002811115611de257611de2614d0b565b03611e3d576101f4831115611e2f5760405162461bcd60e51b8152602060048201526013602482015272496e76616c6964206465706f7369742066656560681b6044820152606401610ca0565b5060fb805490839055611f2e565b6001846002811115611e5157611e51614d0b565b03611ead575060fc546101f4831115611ea35760405162461bcd60e51b8152602060048201526014602482015273496e76616c69642077697468647261772066656560601b6044820152606401610ca0565b60fc839055611f2e565b6002846002811115611ec157611ec1614d0b565b03611f2e575060fd546107d0831115611f285760405162461bcd60e51b8152602060048201526024808201527f496e7374616e74205769746864726177206665652061626f7665206d6178206c6044820152631a5b5a5d60e21b6064820152608401610ca0565b60fd8390555b336001600160a01b03167f45a6b8133c5ffadee20bcb60818497b9de860fb1e7f41778bb21b09232b98067858386604051611f6b93929190614d21565b60405180910390a250505050565b6000611f83613224565b611f8b61326a565b610114546001600160a01b03163314611fb65760405162461bcd60e51b8152600401610ca090614af9565b83600003611fff5760405162461bcd60e51b8152602060048201526016602482015275125b9d985b1a590819195c1bdcda5d08185b5bdd5b9d60521b6044820152606401610ca0565b6001600160a01b0383166120255760405162461bcd60e51b8152600401610ca090614a6d565b60006120328585876132c3565b90506001600160a01b0383161561209157826001600160a01b0316846001600160a01b03167f81fbde7da9aa460bc4230d1e4c27e6f5a95c773ae70f2abc3deb71fedd82e0928760405161208891815260200190565b60405180910390a35b9050610d7c600160c955565b6000806120a8612f66565b505050509050610d7c838261317e565b600054610100900460ff16158080156120d85750600054600160ff909116105b806120f25750303b1580156120f2575060005460ff166001145b6121555760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401610ca0565b6000805460ff191660011790558015612178576000805461ff0019166101001790555b6001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001630036121c05760405162461bcd60e51b8152600401610ca090614c73565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166121f2613a7c565b6001600160a01b0316146122185760405162461bcd60e51b8152600401610ca090614cbf565b6001600160a01b03841661226e5760405162461bcd60e51b815260206004820152601760248201527f496e76616c6964206373546f6b656e20616464726573730000000000000000006044820152606401610ca0565b6001600160a01b0383166122c45760405162461bcd60e51b815260206004820152601b60248201527f496e76616c6964204e6f64654d616e61676572206164647265737300000000006044820152606401610ca0565b6001600160a01b03821661231a5760405162461bcd60e51b815260206004820152601b60248201527f496e76616c696420726f6c654d616e61676572206164647265737300000000006044820152606401610ca0565b612322614274565b61232a6142a3565b6123326142d2565b60ff80546001600160a01b038087166001600160a01b031992831617909255610100805486841690831617905560fe8054928516929091169190911790556202a30061011055603260fd556103e861010d81905561010c55612392610953565b80156123d8576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50505050565b60006123e8613224565b6123f061326a565b6001600160a01b0382166124395760405162461bcd60e51b815260206004820152601060248201526f125b9d985b1a59081c9959995c9c985b60821b6044820152606401610ca0565b6000612447343360006132c3565b9050826001600160a01b0316336001600160a01b03167f81fbde7da9aa460bc4230d1e4c27e6f5a95c773ae70f2abc3deb71fedd82e0923460405161248e91815260200190565b60405180910390a3905061132f600160c955565b60006124ac613224565b6124b461326a565b6124c0343360006132c3565b905061165b600160c955565b60006124d6613224565b6124de61326a565b6001600160a01b0382166125045760405162461bcd60e51b8152600401610ca090614a6d565b612510348360006132c3565b905061132f600160c955565b61252461326a565b610100546001600160a01b0316331461254f5760405162461bcd60e51b8152600401610ca090614a9a565b60005b81811015610e2f5761257b83838381811061256f5761256f614a3e565b90506020020135614047565b8061258581614a54565b915050612552565b600080612598612f66565b5050505090506125b0670de0b6b3a764000082612d09565b91505090565b60006125c0613224565b6125c861326a565b610114546001600160a01b031633146125f35760405162461bcd60e51b8152600401610ca090614af9565b61010054600160a01b900460ff161561261e5760405162461bcd60e51b8152600401610ca090614b1e565b8260000361263e5760405162461bcd60e51b8152600401610ca090614b4c565b60ff546040516370a0823160e01b81526001600160a01b038481166004830152859216906370a0823190602401602060405180830381865afa158015612688573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126ac9190614b83565b10156126ca5760405162461bcd60e51b8152600401610ca090614b9c565b6126d26135a3565b6101045460006126e28583612d09565b9050806000036127045760405162461bcd60e51b8152600401610ca090614bdd565b818111156127245760405162461bcd60e51b8152600401610ca090614c0b565b610113548111156127865760405162461bcd60e51b815260206004820152602660248201527f416d6f756e74206578636565647320617661696c61626c65206f6e207374726160448201526574656769657360d01b6064820152608401610ca0565b80610104600001600082825461279c9190614a2b565b925050819055508061011360008282546127b69190614a2b565b909155505060ff54604051632770a7eb60e21b81526001600160a01b0386811660048301526024820188905290911690639dc29fac906044016020604051808303816000875af115801561280e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128329190614adc565b61284e5760405162461bcd60e51b8152600401610ca090614c4e565b6128566138a1565b604080518681526020810183905260008183015290516001600160a01b038616917e168c9e6995121888eee9b6d2c7566d846e3115a91cd4d27740443bc88a7bff919081900360600190a2915050610d5b600160c955565b600080516020614e2c8339815191526128c6816139ed565b6000831180156128d857506127108311155b6129245760405162461bcd60e51b815260206004820152601860248201527f496e76616c69642064656372656173652070657263656e7400000000000000006044820152606401610ca0565b60008211801561293657506127108211155b6129825760405162461bcd60e51b815260206004820152601860248201527f496e76616c696420696e6372656173652070657263656e7400000000000000006044820152606401610ca0565b61010c83815561010d839055604051839085907f6f5b5b24aad9445609bb96530a0ac641215ba77280befa9a9ad607ecfe08160c90600090a350505050565b60006129cb613224565b6129d361326a565b61010054600160a01b900460ff16156129fe5760405162461bcd60e51b8152600401610ca090614b1e565b81600003612a1e5760405162461bcd60e51b8152600401610ca090614b4c565b60ff546040516370a0823160e01b815233600482015283916001600160a01b0316906370a0823190602401602060405180830381865afa158015612a66573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a8a9190614b83565b1015612aa85760405162461bcd60e51b8152600401610ca090614b9c565b612ab06135a3565b6000612ac28361010460000154612d09565b90508015801590612ada575080612ad7613165565b10155b612af65760405162461bcd60e51b8152600401610ca090614bdd565b806101046000016000828254612b0c9190614a2b565b909155505060fd5460009015612b565760fd5461271090612b2e908490614a14565b612b3891906149d5565b9050806101046000016000828254612b50919061462a565b90915550505b60ff54604051632770a7eb60e21b8152336004820152602481018690526001600160a01b0390911690639dc29fac906044016020604051808303816000875af1158015612ba7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612bcb9190614adc565b612be75760405162461bcd60e51b8152600401610ca090614c4e565b6000612bf38284614a2b565b9050806101126000828254612c089190614a2b565b9091555050604051600090339083908381818185875af1925050503d8060008114612c4f576040519150601f19603f3d011682016040523d82523d6000602084013e612c54565b606091505b5050905080612ca55760405162461bcd60e51b815260206004820181905260248201527f5472616e73666572206f662066756e647320746f2075736572206661696c65646044820152606401610ca0565b612cad6137fb565b612cb56138a1565b604080518781526020810184905290810184905233907e168c9e6995121888eee9b6d2c7566d846e3115a91cd4d27740443bc88a7bff9060600160405180910390a2600194505050505061132f600160c955565b60008060ff60009054906101000a90046001600160a01b03166001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015612d5f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d839190614b83565b9050828114158015612d9457508015155b8015612d9f57508215155b15612dc15780612daf8486614a14565b612db991906149d5565b915050610d5b565b83915050610d5b565b6060810151815160009182918203612e1a576000612df2856040015161010460000154612d09565b6020860151909150612e0c670de0b6b3a764000083614a14565b612e1691906149d5565b9150505b670de0b6b3a76400008111612e4f578451670de0b6b3a764000090612e40908390614a14565b612e4a91906149d5565b612e52565b84515b9250612710856020015184612e679190614a14565b612e7191906149d5565b9150509250929050565b61010054600090600160a01b900460ff1615612e9957506000919050565b8151600003612eaa57506000919050565b60608083015160009081526101026020908152604091829020825160808101845281548082526001830154938201939093526002820154938101939093526003015492820192909252901580612f005750805142105b15612f0e5750600092915050565b4283604001511115612f235750600092915050565b6000612f2f8483612dca565b50905080610112541015612f47575060009392505050565b61010a54811115612f5c575060009392505050565b5060019392505050565b610104546101005460408051629032ff60e51b8152905160009283928392839283926001600160a01b03909116916312065fe0916004808201926020929091908290030181865afa158015612fbf573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612fe39190614b83565b610108546101075461010654929350600092612fff919061462a565b613009919061462a565b9050808211156130305761301d8183614a2b565b9550613029868861462a565b965061307a565b8082101561307a576130428282614a2b565b61010954909550600090613056908961462a565b6130608988614a14565b61306a91906149d5565b90506130768189614a2b565b9750505b610114546000906001600160a01b031661309557600061310d565b61011460009054906101000a90046001600160a01b03166001600160a01b03166312065fe06040518163ffffffff1660e01b8152600401602060405180830381865afa1580156130e9573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061310d9190614b83565b6101135490915080821115613139576131268183614a2b565b9550613132868a61462a565b985061315a565b8082101561315a5761314b8282614a2b565b9450613157858a614a2b565b98505b505050509091929394565b61010a546101125460009161317991614a2b565b905090565b60008060ff60009054906101000a90046001600160a01b03166001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156131d4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906131f89190614b83565b905082811415801561320957508215155b801561321457508015155b15612dc15782612daf8286614a14565b60975460ff16156119d05760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b6044820152606401610ca0565b600260c954036132bc5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610ca0565b600260c955565b60008360000361330e5760405162461bcd60e51b8152602060048201526016602482015275125b9d985b1a590819195c1bdcda5d08185b5bdd5b9d60521b6044820152606401610ca0565b6133166135a3565b60006127108560fb6000015461332c9190614a14565b61333691906149d5565b905060006133448287614a2b565b90506000613358826101046000015461317e565b9050866101046000016000828254613370919061462a565b909155505084156133945784610113600082825461338e919061462a565b90915550505b60ff546040516340c10f1960e01b81526001600160a01b03888116600483015260248201849052909116906340c10f19906044016020604051808303816000875af11580156133e7573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061340b9190614adc565b6134485760405162461bcd60e51b815260206004820152600e60248201526d135a5b9d1a5b99c819985a5b195960921b6044820152606401610ca0565b6134506137fb565b6134586138a1565b60408051838152602081018390529081018490526001600160a01b038716907f4b2bcb0ca50531683faa51870e1018aa0d7272c7f2acc5399389b0c0493865d99060600160405180910390a29695505050505050565b600160c955565b6101075480156134f75760006134cb8383614032565b90508061010460030160008282546134e39190614a2b565b909155506134f390508184614a2b565b9250505b61010854801580159061350957508215155b1561354657600061351a8483614032565b90508061010460040160008282546135329190614a2b565b9091555061354290508185614a2b565b9350505b61010654801580159061355857508315155b156135955760006135698583614032565b90508061010460020160008282546135819190614a2b565b9091555061359190508186614a2b565b9450505b83156123d8576123d8614d57565b61011254479034906135b690829061462a565b82036135da578061011260008282546135cf919061462a565b9091555061364e9050565b6101125482111561364e57600081610112546135f6919061462a565b6136009084614a2b565b610112849055905061361181610901565b613619610953565b6040518181527f7926e9adf71c42b63be07a89b069672dbe3702e8e42b5c1a246b82d1b37d4d1f9060200160405180910390a1505b60008060008061365c612f66565b61010454939850919650945092509050841561369c5761367b85610901565b846101046002016000828254613691919061462a565b909155506137649050565b831561376457610109546000906136b3908361462a565b6136bd8387614a14565b6136c791906149d5565b90506136d38183614a2b565b610104819055610109549092506000901561372b576136f28287614a2b565b905080610104600101600082825461370a9190614a2b565b90915550506101098054829190600090613725908490614a2b565b90915550505b604051819083907f0d2e0a4ccfc33a4f7fc640fadeca01848893f0680cd94a3ce360e9e1aa18581f90600090a3613761866134b5565b50505b82156137915761377383610901565b826101136000828254613786919061462a565b909155506137f29050565b81156137f2576137a18282614a2b565b610104819055610113805491925083916000906137bf908490614a2b565b909155505060405160009083907f0d2e0a4ccfc33a4f7fc640fadeca01848893f0680cd94a3ce360e9e1aa18581f908390a35b50505050505050565b6101075461010854156138645761010a54610107546101055460009261383a9290916138279190614a2b565b6138319190614a2b565b61010854614032565b9050613846818361462a565b6101078190556101085490925061385e908290614a2b565b61010855505b61010a546101055461389a9161387991614032565b610105546138959061388c908590614a2b565b61011254614032565b6142f9565b61010a5550565b61010454806138fd5760405162461bcd60e51b815260206004820152602260248201527f43757272656e74206465706f736974732063616e6e6f7420676f20746f207a65604482015261726f60f01b6064820152608401610ca0565b61010554600090662386f26fc1000090613917908461462a565b61392191906149d5565b6101135461010754610108546101065461011254949550600094662386f26fc10000949392916139509161462a565b61395a919061462a565b613964919061462a565b61396e919061462a565b61397891906149d5565b905061398582600161462a565b811115801561399e575061399a81600161462a565b8211155b6139e05760405162461bcd60e51b8152602060048201526013602482015272155b98985b185b98d9590818dbdb9d1c9858dd606a1b6044820152606401610ca0565b6139e861430f565b505050565b60fe546040516312d9a6ad60e01b8152600481018390523360248201526001600160a01b03909116906312d9a6ad90604401602060405180830381865afa158015613a3c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613a609190614adc565b6114f25760405162461bcd60e51b8152600401610ca090614af9565b600080516020614e4c833981519152546001600160a01b031690565b7fb8ea7c31de614c54f5b3938aa9732e87deb869a880ec52d4bb778c09789441b1613ac2816139ed565b6000826001600160a01b03163b11610e3a5760405162461bcd60e51b81526020600482015260096024820152680858dbdb9d1c9858dd60ba1b6044820152606401610ca0565b613b11816143c7565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b60975460ff166119d05760405162461bcd60e51b815260206004820152601460248201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b6044820152606401610ca0565b613b99613b48565b6097805460ff191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa335b6040516001600160a01b03909116815260200160405180910390a1565b7f4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd91435460ff1615613c16576139e8836143c7565b826001600160a01b03166352d1902d6040518163ffffffff1660e01b8152600401602060405180830381865afa925050508015613c70575060408051601f3d908101601f19168201909252613c6d91810190614b83565b60015b613cd35760405162461bcd60e51b815260206004820152602e60248201527f45524331393637557067726164653a206e657720696d706c656d656e7461746960448201526d6f6e206973206e6f74205555505360901b6064820152608401610ca0565b600080516020614e4c8339815191528114613d425760405162461bcd60e51b815260206004820152602960248201527f45524331393637557067726164653a20756e737570706f727465642070726f786044820152681a58589b195555525160ba1b6064820152608401610ca0565b506139e8838383614463565b6001600160a01b03811660009081526101016020908152604080832085845282528083208151608081018352815480825260018301549482019490945260028201549281019290925260030154606082015282918203613de05760405162461bcd60e51b815260206004820152600d60248201526c24b73b30b634b21027b93232b960991b6044820152606401610ca0565b606080820151600090815261010260209081526040918290208251608081018452815480825260018301549382019390935260028201549381019390935260030154928201929092529015801590613e39575080514210155b613e7e5760405162461bcd60e51b815260206004820152601660248201527513dc99195c881a5cc81b9bdd08199a5b985b1a5e995960521b6044820152606401610ca0565b600080613e8b8484612dca565b9150915042846040015111158015613ea65750816101125410155b613eeb5760405162461bcd60e51b81526020600482015260166024820152754f72646572206973206e6f7420636c61696d61626c6560501b6044820152606401610ca0565b61010a54821115613f495760405162461bcd60e51b815260206004820152602260248201527f416d6f756e7420657863656564732066756e64732e636c61696d61626c65506f6044820152611bdb60f21b6064820152608401610ca0565b8351604080518a815260208101929092528101839052606081018290526001600160a01b038816907f43236f0f39c52b337b0925119217c5e32cf752a69a2ae06b1e0a9652ec36a02e9060800160405180910390a26001600160a01b0387166000908152610101602090815260408083208b845290915281208190556101058054849290613fd8908490614a2b565b909155505061010a8054839190600090613ff3908490614a2b565b9091555061400390508183614a2b565b61011260008282546140159190614a2b565b9091555061402590508183614a2b565b9890975095505050505050565b60008183116140415782610d7c565b50919050565b6000818152610102602090815260409182902082516080810184528154808252600183015493820193909352600282015493810193909352600301546060830152156140d55760405162461bcd60e51b815260206004820152601960248201527f6261746368496420616c72656164792070726f636573736564000000000000006044820152606401610ca0565b6000828152610102602090815260408220429055820151156141dd576000614107836040015161010460000154612d09565b6020840151909150614121670de0b6b3a764000083614a14565b61412b91906149d5565b600085815261010260209081526040909120600301829055840151909250811015614156578061415c565b82602001515b610109549091508111156141bf576101095460009061417b9083614a2b565b9050806101046001016000828254614193919061462a565b909155505061010480548291906000906141ae908490614a2b565b9091555050600061010955506141db565b8061010460050160008282546141d59190614a2b565b90915550505b505b827f2f8e27901e927950b1278ec32324d1042109597c988544a4d8f85b19f2fd6419836020015184604001518460405161422a939291909283526020830191909152604082015260600190565b60405180910390a2505050565b61423f613224565b6097805460ff191660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258613bc63390565b600054610100900460ff1661429b5760405162461bcd60e51b8152600401610ca090614d6d565b6119d0614488565b600054610100900460ff166142ca5760405162461bcd60e51b8152600401610ca090614d6d565b6119d06144bb565b600054610100900460ff166119d05760405162461bcd60e51b8152600401610ca090614d6d565b60008183116143085781610d7c565b5090919050565b6000614329670de0b6b3a764000061010460000154612d09565b6101115490915081810361433b575050565b60008082841015614376576143508484614a2b565b61010c54909250612710906143659085614a14565b61436f91906149d5565b90506143aa565b828411156143aa576143888385614a2b565b61010d549092506127109061439d9085614a14565b6143a791906149d5565b90505b808211156143bf576143ba614237565b6123d8565b6123d8610953565b6001600160a01b0381163b6144345760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b6064820152608401610ca0565b600080516020614e4c83398151915280546001600160a01b0319166001600160a01b0392909216919091179055565b61446c83613b08565b6000825111806144795750805b156139e8576123d883836144e2565b600054610100900460ff166144af5760405162461bcd60e51b8152600401610ca090614d6d565b6097805460ff19169055565b600054610100900460ff166134ae5760405162461bcd60e51b8152600401610ca090614d6d565b60606001600160a01b0383163b61454a5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6044820152651b9d1c9858dd60d21b6064820152608401610ca0565b600080846001600160a01b0316846040516145659190614ddc565b600060405180830381855af49150503d80600081146145a0576040519150601f19603f3d011682016040523d82523d6000602084013e6145a5565b606091505b50915091506145cd8282604051806060016040528060278152602001614e6c602791396145d6565b95945050505050565b606083156145e5575081610d7c565b610d7c83838151156145fa5781518083602001fd5b8060405162461bcd60e51b8152600401610ca09190614df8565b634e487b7160e01b600052601160045260246000fd5b80820180821115610d5b57610d5b614614565b6001600160a01b03811681146114f257600080fd5b6000806040838503121561466557600080fd5b82356146708161463d565b946020939093013593505050565b6060808252845182820181905260009190608090818501906020808a01865b838110156146e057815180518652838101518487015260408082015190870152878101518887015286015115158686015260a0909401939082019060010161469d565b50508601979097526040909401949094525090949350505050565b6000806040838503121561470e57600080fd5b82356147198161463d565b915060208301356147298161463d565b809150509250929050565b60006020828403121561474657600080fd5b5035919050565b6000806040838503121561476057600080fd5b50508035926020909101359150565b80151581146114f257600080fd5b60006020828403121561478f57600080fd5b8135610d7c8161476f565b6000602082840312156147ac57600080fd5b8135610d7c8161463d565b634e487b7160e01b600052604160045260246000fd5b600080604083850312156147e057600080fd5b82356147eb8161463d565b9150602083013567ffffffffffffffff8082111561480857600080fd5b818501915085601f83011261481c57600080fd5b81358181111561482e5761482e6147b7565b604051601f8201601f19908116603f01168101908382118183101715614856576148566147b7565b8160405282815288602084870101111561486f57600080fd5b8260208601602083013760006020848301015280955050505050509250929050565b600080602083850312156148a457600080fd5b823567ffffffffffffffff808211156148bc57600080fd5b818501915085601f8301126148d057600080fd5b8135818111156148df57600080fd5b8660208260051b85010111156148f457600080fd5b60209290920196919550909350505050565b6000806040838503121561491957600080fd5b82356003811061467057600080fd5b60008060006060848603121561493d57600080fd5b83359250602084013561494f8161463d565b9150604084013561495f8161463d565b809150509250925092565b60008060006060848603121561497f57600080fd5b833561498a8161463d565b9250602084013561494f8161463d565b600080604083850312156149ad57600080fd5b8235915060208301356147298161463d565b634e487b7160e01b600052601260045260246000fd5b6000826149e4576149e46149bf565b500490565b6000826149f8576149f86149bf565b500690565b600081614a0c57614a0c614614565b506000190190565b8082028115828204841417610d5b57610d5b614614565b81810381811115610d5b57610d5b614614565b634e487b7160e01b600052603260045260246000fd5b600060018201614a6657614a66614614565b5060010190565b602080825260139082015272496e76616c69642064656c656761746564546f60681b604082015260600190565b60208082526022908201527f53656e6420696e76616c69642c206d757374206265206e6f6465206d616e616760408201526132b960f11b606082015260800190565b600060208284031215614aee57600080fd5b8151610d7c8161476f565b6020808252600b908201526a105d5d1a0811985a5b195960aa1b604082015260600190565b60208082526014908201527315da5d1a191c985dd85b1cc8191a5cd8589b195960621b604082015260600190565b6020808252601e908201527f576974686472617720616d6f756e742063616e6e6f74206265207a65726f0000604082015260600190565b600060208284031215614b9557600080fd5b5051919050565b60208082526021908201527f496e73756666696369656e74206373546f6b656e20757365722062616c616e636040820152606560f81b606082015260800190565b602080825260149082015273125b9d985b1a59081d1bdad95b88185b5bdd5b9d60621b604082015260600190565b60208082526023908201527f416d6f756e74206e6f7420617661696c61626c6520666f7220776974686472616040820152621dd85b60ea1b606082015260800190565b6020808252600b908201526a109d5c9b8819985a5b195960aa1b604082015260600190565b6020808252602c908201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060408201526b19195b1959d85d1958d85b1b60a21b606082015260800190565b6020808252602c908201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060408201526b6163746976652070726f787960a01b606082015260800190565b634e487b7160e01b600052602160045260246000fd5b6060810160038510614d4357634e487b7160e01b600052602160045260246000fd5b938152602081019290925260409091015290565b634e487b7160e01b600052600160045260246000fd5b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b606082015260800190565b60005b83811015614dd3578181015183820152602001614dbb565b50506000910152565b60008251614dee818460208701614db8565b9190910192915050565b6020815260008251806020840152614e17816040850160208701614db8565b601f01601f1916919091016040019291505056fef66846415d2bf9eabda9e84793ff9c0ea96d87f50fc41e66aa16469c6a442f05360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220bae85150d75515a911fdb7aeaac14fa4aeef1d461d73e44a4307c3fc7de5708a64736f6c63430008120033
Deployed Bytecode
0x6080604052600436106102765760003560e01c80636f3fe4041161014f578063c18d7cb7116100c1578063e1c603f61161007a578063e1c603f614610829578063e6aa216c14610849578063e8e0da3e1461085e578063eba98b8a146108a1578063f18574a0146108c1578063fd92bff2146108e157600080fd5b8063c18d7cb714610737578063c483a33e1461074a578063c89f2ce414610783578063d0e30db0146107ee578063da26ec22146107f6578063e04605fd1461080957600080fd5b80638d0411db116101135780638d0411db1461066b5780638f78c3111461068b5780639764e249146106ab5780639af1d35a146106c25780639c705b47146106fc578063c0c53b8b1461071757600080fd5b80636f3fe404146105c45780637e70d9c5146105d95780638456cb591461061457806388ae7f2e146106295780638c6aa3f51461064b57600080fd5b80633f4ba83a116101e857806352d1902d116101ac57806352d1902d1461051d5780635c975abb146105325780635f1625b714610556578063693f0ca814610576578063695a1aea1461058d5780636ba4c138146105a457600080fd5b80633f4ba83a14610459578063466204161461046e5780634972134a146104dc5780634e6630b0146104f35780634f1ef2861461050a57600080fd5b80631c3c2e241161023a5780631c3c2e24146103a45780632951913c146103b95780632b8bb70c146103d95780632e1a7d4d146103f95780633659cfe6146104195780633b1908111461043957600080fd5b8063020fdae2146102e45780630e3d9cf11461031c57806314309fca1461033f5780631647f7e1146103525780631b18662f1461038457600080fd5b366102df576000349050806101126000828254610293919061462a565b909155506102a2905081610901565b6102aa610953565b6040518181527f7926e9adf71c42b63be07a89b069672dbe3702e8e42b5c1a246b82d1b37d4d1f9060200160405180910390a1005b600080fd5b3480156102f057600080fd5b506103046102ff366004614652565b6109ab565b6040516103139392919061467e565b60405180910390f35b34801561032857600080fd5b50610331610c2b565b604051908152602001610313565b61033161034d3660046146fb565b610c68565b34801561035e57600080fd5b5061010c5461010d5461036f919082565b60408051928352602083019190915201610313565b34801561039057600080fd5b5061033161039f366004614734565b610d61565b6103b76103b236600461474d565b610d83565b005b3480156103c557600080fd5b506103b76103d436600461477d565b610e3e565b3480156103e557600080fd5b506103316103f4366004614652565b610f4b565b34801561040557600080fd5b50610331610414366004614734565b610f7d565b34801561042557600080fd5b506103b761043436600461479a565b611334565b34801561044557600080fd5b506103b7610454366004614734565b611410565b34801561046557600080fd5b506103b76114b0565b34801561047a57600080fd5b506104bc610489366004614652565b61010160209081526000928352604080842090915290825290208054600182015460028301546003909301549192909184565b604080519485526020850193909352918301526060820152608001610313565b3480156104e857600080fd5b5061033161010e5481565b3480156104ff57600080fd5b506103316101125481565b6103b76105183660046147cd565b6114f5565b34801561052957600080fd5b506103316115aa565b34801561053e57600080fd5b5060975460ff165b6040519015158152602001610313565b34801561056257600080fd5b506103b761057136600461479a565b61165e565b34801561058257600080fd5b506103316101135481565b34801561059957600080fd5b506103316101105481565b3480156105b057600080fd5b506105466105bf366004614891565b61177c565b3480156105d057600080fd5b506103b761199e565b3480156105e557600080fd5b506105f96105f4366004614734565b6119d2565b60408051938452911515602084015290820152606001610313565b34801561062057600080fd5b506103b7611d3c565b34801561063557600080fd5b506101005461054690600160a01b900460ff1681565b34801561065757600080fd5b506103b7610666366004614906565b611d76565b34801561067757600080fd5b50610331610686366004614928565b611f79565b34801561069757600080fd5b506103316106a6366004614734565b61209d565b3480156106b757600080fd5b506103316101115481565b3480156106ce57600080fd5b5060fb5460fc5460fd546106e192919083565b60408051938452602084019290925290820152606001610313565b34801561070857600080fd5b5061010b546105469060ff1681565b34801561072357600080fd5b506103b761073236600461496a565b6120b8565b61033161074536600461479a565b6123de565b34801561075657600080fd5b506101145461076b906001600160a01b031681565b6040516001600160a01b039091168152602001610313565b34801561078f57600080fd5b5061010454610105546101065461010754610108546101095461010a546107b99695949392919087565b604080519788526020880196909652948601939093526060850191909152608084015260a083015260c082015260e001610313565b6103316124a2565b61033161080436600461479a565b6124cc565b34801561081557600080fd5b5060ff5461076b906001600160a01b031681565b34801561083557600080fd5b506103b7610844366004614891565b61251c565b34801561085557600080fd5b5061033161258d565b34801561086a57600080fd5b506104bc610879366004614734565b6101026020526000908152604090208054600182015460028301546003909301549192909184565b3480156108ad57600080fd5b506103316108bc36600461499a565b6125b6565b3480156108cd57600080fd5b506103b76108dc36600461474d565b6128ae565b3480156108ed57600080fd5b506105466108fc366004614734565b6129c1565b806101046000016000828254610917919061462a565b90915550506040518181527f872e90f6155f65f8bcd3c0ce902abd4e2cb622c9ab5d72c588a1a7ed98194c90906020015b60405180910390a150565b600061096d670de0b6b3a764000061010460000154612d09565b610111819055604080518281524260208201529192507fa21de314e188ba49fe0cc48414f955a0c3ba27013855d78d9ddcbce640504d409101610948565b60408051600a80825261016082019092526060916000918291829190816020015b610a006040518060a00160405280600081526020016000815260200160008152602001600081526020016000151581525090565b8152602001906001900390816109cc5750506001600160a01b03871660009081526101036020526040812054919250600a9190610a3d83836149d5565b9050600082118015610a565750610a5483836149e9565b155b15610a695780610a65816149fd565b9150505b808811158015610a7857508115155b15610c1a5760005b83811015610c18576000600182610a97878d614a14565b610aa19087614a2b565b610aab9190614a2b565b610ab59190614a2b565b6001600160a01b038c166000908152610103602052604081208054929350909183908110610ae557610ae5614a3e565b60009182526020808320909101546001600160a01b038f1683526101018252604080842082855283528084208151608080820184528254825260018084015483880152600280850154848701526003948501546060808601829052908a526101028952868a208751948501885280548552928301549884019890985281015494820194909452929091015493820193909352909350909180610b878484612dca565b915091506040518060a001604052808681526020018284610ba89190614a2b565b81526020018560200151815260200185604001518152602001610bca86612e7b565b15158152508b8881518110610be157610be1614a3e565b602002602001018190525085600003610bff57505050505050610c18565b5050505050508080610c1090614a54565b915050610a80565b505b929842985092965091945050505050565b600080610c36612f66565b5050505090506000610c46613165565b905080600003610c57576000610c61565b610c61818361317e565b9250505090565b6000610c72613224565b610c7a61326a565b6001600160a01b038316610ca95760405162461bcd60e51b8152600401610ca090614a6d565b60405180910390fd5b6001600160a01b038216610cf25760405162461bcd60e51b815260206004820152601060248201526f125b9d985b1a59081c9959995c9c985b60821b6044820152606401610ca0565b6000610d00348560006132c3565b9050826001600160a01b0316846001600160a01b03167f81fbde7da9aa460bc4230d1e4c27e6f5a95c773ae70f2abc3deb71fedd82e09234604051610d4791815260200190565b60405180910390a39050610d5b600160c955565b92915050565b600080610d6c612f66565b505050509050610d7c8382612d09565b9392505050565b610d8b613224565b610d9361326a565b610100546001600160a01b03163314610dbe5760405162461bcd60e51b8152600401610ca090614a9a565b600081610dcb8434614a2b565b610dd59190614a2b565b90508215610de657610de683610901565b8115610df557610df5826134b5565b8015610e1757806101046002016000828254610e119190614a2b565b90915550505b610e1f6135a3565b610e276137fb565b610e2f6138a1565b50610e3a600160c955565b5050565b610100546001600160a01b0316331480610ee5575060fe546040516312d9a6ad60e01b81527f70afc91226fba57efa6b459a2add00f29a9a7961e6eb3103074a44780ab8cdc860048201523360248201526001600160a01b03909116906312d9a6ad90604401602060405180830381865afa158015610ec1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ee59190614adc565b610f015760405162461bcd60e51b8152600401610ca090614af9565b610100805460ff60a01b1916600160a01b831515908102919091179091556040517fb90d13b85674cde408204dc341b2aa33c9cc1d514c87870836a213e74a6cf14b90600090a250565b6101036020528160005260406000208181548110610f6857600080fd5b90600052602060002001600091509150505481565b6000610f87613224565b610f8f61326a565b61010054600160a01b900460ff1615610fba5760405162461bcd60e51b8152600401610ca090614b1e565b81600003610fda5760405162461bcd60e51b8152600401610ca090614b4c565b60ff546040516370a0823160e01b815233600482015283916001600160a01b0316906370a0823190602401602060405180830381865afa158015611022573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110469190614b83565b10156110645760405162461bcd60e51b8152600401610ca090614b9c565b61106c6135a3565b61010454600061107c8483612d09565b90508060000361109e5760405162461bcd60e51b8152600401610ca090614bdd565b610113546110ac9083614a2b565b8111156110cb5760405162461bcd60e51b8152600401610ca090614c0b565b61010b805460ff1916600117905561010480548291906000906110ef908490614a2b565b9091555050610105805482919060009061110a90849061462a565b9091555050610109805482919060009061112590849061462a565b909155505060ff54604051632770a7eb60e21b8152336004820152602481018690526001600160a01b0390911690639dc29fac906044016020604051808303816000875af115801561117b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061119f9190614adc565b6111bb5760405162461bcd60e51b8152600401610ca090614c4e565b600061010f600081546111cd90614a54565b9190508190559050604051806080016040528083815260200160fb6001015481526020016101105442611200919061462a565b815261010e80546020928301523360009081526101018352604080822086835284528082208551815585850151600180830191909155868301516002830155606090960151600390910155915481526101029092528120909101805484929061126a90849061462a565b909155505061010e54600090815261010260205260408120600201805487929061129590849061462a565b909155505033600090815261010360209081526040822080546001810182559083529120018190556112c56137fb565b6112cd6138a1565b60fc546040805183815260208101889052908101849052606081019190915242608082015233907f0af70755b8d8f9e1aa3e6ff252c56885ef3b60f9f98c318a0df1502d10923d7a9060a00160405180910390a29250505061132f600160c955565b919050565b7fb8ea7c31de614c54f5b3938aa9732e87deb869a880ec52d4bb778c09789441b161135e816139ed565b6001600160a01b037f00000000000000000000000041446668f264f493633aceebd811faa16605cb881630036113a65760405162461bcd60e51b8152600401610ca090614c73565b7f00000000000000000000000041446668f264f493633aceebd811faa16605cb886001600160a01b03166113d8613a7c565b6001600160a01b0316146113fe5760405162461bcd60e51b8152600401610ca090614cbf565b61140782613a98565b610e3a82613b08565b600080516020614e2c833981519152611428816139ed565b6276a70082111561147b5760405162461bcd60e51b815260206004820152601b60248201527f4d696e696d756d20636c61696d2074696d6520746f6f206869676800000000006044820152606401610ca0565b61011082905560405182907f0c85bd8af73992514968a932f5ba7becbfb7965f14abceb3bf0d5bf08694646b90600090a25050565b7f70afc91226fba57efa6b459a2add00f29a9a7961e6eb3103074a44780ab8cdc86114da816139ed565b6114e2613b48565b6114ea610953565b6114f2613b91565b50565b6001600160a01b037f00000000000000000000000041446668f264f493633aceebd811faa16605cb8816300361153d5760405162461bcd60e51b8152600401610ca090614c73565b7f00000000000000000000000041446668f264f493633aceebd811faa16605cb886001600160a01b031661156f613a7c565b6001600160a01b0316146115955760405162461bcd60e51b8152600401610ca090614cbf565b61159e82613a98565b610e3a82826001613be3565b6000306001600160a01b037f00000000000000000000000041446668f264f493633aceebd811faa16605cb88161461164a5760405162461bcd60e51b815260206004820152603860248201527f555550535570677261646561626c653a206d757374206e6f742062652063616c60448201527f6c6564207468726f7567682064656c656761746563616c6c00000000000000006064820152608401610ca0565b50600080516020614e4c8339815191525b90565b600080516020614e2c833981519152611676816139ed565b610114546001600160a01b0316156116d05760405162461bcd60e51b815260206004820152601d60248201527f537472617465676965734d616e6167657220616c7265616479207365740000006044820152606401610ca0565b6001600160a01b0382166117265760405162461bcd60e51b815260206004820152601f60248201527f537472617465676965734d616e61676572206d7573742062652076616c6964006044820152606401610ca0565b61011480546001600160a01b0319166001600160a01b0384169081179091556040519081527fc588eda4a659cb62d9f834c8c05ed21678af0b87f6a08926d98e0f16b00888a69060200160405180910390a15050565b6000611786613224565b61178e61326a565b61010054600160a01b900460ff16156117b95760405162461bcd60e51b8152600401610ca090614b1e565b81600081900361180b5760405162461bcd60e51b815260206004820152601760248201527f496e76616c6964206f72646572204964206c656e6774680000000000000000006044820152606401610ca0565b6118136135a3565b60008060005b858110156118785760008061184689898581811061183957611839614a3e565b9050602002013533613d4e565b9092509050611855828661462a565b9450611861818561462a565b93505050808061187090614a54565b915050611819565b50816000036118c25760405162461bcd60e51b815260206004820152601660248201527524b73b30b634b21030b6b7bab73a103a37903ab9b2b960511b6044820152606401610ca0565b80156118e4578061010460000160008282546118de919061462a565b90915550505b604051600090339084908381818185875af1925050503d8060008114611926576040519150601f19603f3d011682016040523d82523d6000602084013e61192b565b606091505b505090508061197c5760405162461bcd60e51b815260206004820181905260248201527f5472616e73666572206f662066756e647320746f2075736572206661696c65646044820152606401610ca0565b6119846137fb565b61198c6138a1565b6001945050505050610d5b600160c955565b6119a6613224565b6119ae61326a565b6119b66135a3565b6119be6137fb565b6119c66138a1565b6119d0600160c955565b565b60008060006119df613224565b6119e761326a565b610100546001600160a01b03163314611a125760405162461bcd60e51b8152600401610ca090614a9a565b611a1a6135a3565b505061010e54610104546101065491925060009182919080821015611b3c576000611a458383614a2b565b9050611a5a6801bc16d674ec800000826149d5565b93506000611a716801bc16d674ec800000836149e9565b90508015611aa557611a8460018661462a565b9450611aa283611a9d6801bc16d674ec80000088614a14565b614032565b91505b8415611ae257816101046002016000828254611ac19190614a2b565b90915550506101088054839190600090611adc90849061462a565b90915550505b61010e8054906000611af383614a54565b9190505550851515877feba6465416eefa23c736aaaef02a6f286d930650af93fb71e1ae6192e0a8704c84604051611b2d91815260200190565b60405180910390a35050611d19565b808210611d195761010a5461011254600091611b5791614a2b565b90506000611b6e611b688486614a2b565b83614032565b9050611b8c611b866801bc16d674ec800000836149d5565b89614032565b945084151580611b9f575061010b5460ff165b15611bcf57611bad87614047565b61010e8054906000611bbe83614a54565b909155505061010b805460ff191690555b8415611d165760019550611bec6801bc16d674ec80000086614a14565b9050806101046002016000828254611c04919061462a565b92505081905550806101126000828254611c1e9190614a2b565b9091555050610100546040516000916001600160a01b03169083908381818185875af1925050503d8060008114611c71576040519150601f19603f3d011682016040523d82523d6000602084013e611c76565b606091505b5050905080611cd75760405162461bcd60e51b815260206004820152602760248201527f5472616e73666572206f662066756e647320746f206e6f64654d616e616765726044820152660819985a5b195960ca1b6064820152608401610ca0565b861515887feba6465416eefa23c736aaaef02a6f286d930650af93fb71e1ae6192e0a8704c84604051611d0c91815260200190565b60405180910390a3505b50505b611d216137fb565b611d296138a1565b5050611d35600160c955565b9193909250565b7f70afc91226fba57efa6b459a2add00f29a9a7961e6eb3103074a44780ab8cdc8611d66816139ed565b611d6e613224565b6114f2614237565b600080516020614e2c833981519152611d8e816139ed565b6127108210611dcd5760405162461bcd60e51b815260206004820152600b60248201526a496e76616c69642066656560a81b6044820152606401610ca0565b600080846002811115611de257611de2614d0b565b03611e3d576101f4831115611e2f5760405162461bcd60e51b8152602060048201526013602482015272496e76616c6964206465706f7369742066656560681b6044820152606401610ca0565b5060fb805490839055611f2e565b6001846002811115611e5157611e51614d0b565b03611ead575060fc546101f4831115611ea35760405162461bcd60e51b8152602060048201526014602482015273496e76616c69642077697468647261772066656560601b6044820152606401610ca0565b60fc839055611f2e565b6002846002811115611ec157611ec1614d0b565b03611f2e575060fd546107d0831115611f285760405162461bcd60e51b8152602060048201526024808201527f496e7374616e74205769746864726177206665652061626f7665206d6178206c6044820152631a5b5a5d60e21b6064820152608401610ca0565b60fd8390555b336001600160a01b03167f45a6b8133c5ffadee20bcb60818497b9de860fb1e7f41778bb21b09232b98067858386604051611f6b93929190614d21565b60405180910390a250505050565b6000611f83613224565b611f8b61326a565b610114546001600160a01b03163314611fb65760405162461bcd60e51b8152600401610ca090614af9565b83600003611fff5760405162461bcd60e51b8152602060048201526016602482015275125b9d985b1a590819195c1bdcda5d08185b5bdd5b9d60521b6044820152606401610ca0565b6001600160a01b0383166120255760405162461bcd60e51b8152600401610ca090614a6d565b60006120328585876132c3565b90506001600160a01b0383161561209157826001600160a01b0316846001600160a01b03167f81fbde7da9aa460bc4230d1e4c27e6f5a95c773ae70f2abc3deb71fedd82e0928760405161208891815260200190565b60405180910390a35b9050610d7c600160c955565b6000806120a8612f66565b505050509050610d7c838261317e565b600054610100900460ff16158080156120d85750600054600160ff909116105b806120f25750303b1580156120f2575060005460ff166001145b6121555760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401610ca0565b6000805460ff191660011790558015612178576000805461ff0019166101001790555b6001600160a01b037f00000000000000000000000041446668f264f493633aceebd811faa16605cb881630036121c05760405162461bcd60e51b8152600401610ca090614c73565b7f00000000000000000000000041446668f264f493633aceebd811faa16605cb886001600160a01b03166121f2613a7c565b6001600160a01b0316146122185760405162461bcd60e51b8152600401610ca090614cbf565b6001600160a01b03841661226e5760405162461bcd60e51b815260206004820152601760248201527f496e76616c6964206373546f6b656e20616464726573730000000000000000006044820152606401610ca0565b6001600160a01b0383166122c45760405162461bcd60e51b815260206004820152601b60248201527f496e76616c6964204e6f64654d616e61676572206164647265737300000000006044820152606401610ca0565b6001600160a01b03821661231a5760405162461bcd60e51b815260206004820152601b60248201527f496e76616c696420726f6c654d616e61676572206164647265737300000000006044820152606401610ca0565b612322614274565b61232a6142a3565b6123326142d2565b60ff80546001600160a01b038087166001600160a01b031992831617909255610100805486841690831617905560fe8054928516929091169190911790556202a30061011055603260fd556103e861010d81905561010c55612392610953565b80156123d8576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50505050565b60006123e8613224565b6123f061326a565b6001600160a01b0382166124395760405162461bcd60e51b815260206004820152601060248201526f125b9d985b1a59081c9959995c9c985b60821b6044820152606401610ca0565b6000612447343360006132c3565b9050826001600160a01b0316336001600160a01b03167f81fbde7da9aa460bc4230d1e4c27e6f5a95c773ae70f2abc3deb71fedd82e0923460405161248e91815260200190565b60405180910390a3905061132f600160c955565b60006124ac613224565b6124b461326a565b6124c0343360006132c3565b905061165b600160c955565b60006124d6613224565b6124de61326a565b6001600160a01b0382166125045760405162461bcd60e51b8152600401610ca090614a6d565b612510348360006132c3565b905061132f600160c955565b61252461326a565b610100546001600160a01b0316331461254f5760405162461bcd60e51b8152600401610ca090614a9a565b60005b81811015610e2f5761257b83838381811061256f5761256f614a3e565b90506020020135614047565b8061258581614a54565b915050612552565b600080612598612f66565b5050505090506125b0670de0b6b3a764000082612d09565b91505090565b60006125c0613224565b6125c861326a565b610114546001600160a01b031633146125f35760405162461bcd60e51b8152600401610ca090614af9565b61010054600160a01b900460ff161561261e5760405162461bcd60e51b8152600401610ca090614b1e565b8260000361263e5760405162461bcd60e51b8152600401610ca090614b4c565b60ff546040516370a0823160e01b81526001600160a01b038481166004830152859216906370a0823190602401602060405180830381865afa158015612688573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126ac9190614b83565b10156126ca5760405162461bcd60e51b8152600401610ca090614b9c565b6126d26135a3565b6101045460006126e28583612d09565b9050806000036127045760405162461bcd60e51b8152600401610ca090614bdd565b818111156127245760405162461bcd60e51b8152600401610ca090614c0b565b610113548111156127865760405162461bcd60e51b815260206004820152602660248201527f416d6f756e74206578636565647320617661696c61626c65206f6e207374726160448201526574656769657360d01b6064820152608401610ca0565b80610104600001600082825461279c9190614a2b565b925050819055508061011360008282546127b69190614a2b565b909155505060ff54604051632770a7eb60e21b81526001600160a01b0386811660048301526024820188905290911690639dc29fac906044016020604051808303816000875af115801561280e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128329190614adc565b61284e5760405162461bcd60e51b8152600401610ca090614c4e565b6128566138a1565b604080518681526020810183905260008183015290516001600160a01b038616917e168c9e6995121888eee9b6d2c7566d846e3115a91cd4d27740443bc88a7bff919081900360600190a2915050610d5b600160c955565b600080516020614e2c8339815191526128c6816139ed565b6000831180156128d857506127108311155b6129245760405162461bcd60e51b815260206004820152601860248201527f496e76616c69642064656372656173652070657263656e7400000000000000006044820152606401610ca0565b60008211801561293657506127108211155b6129825760405162461bcd60e51b815260206004820152601860248201527f496e76616c696420696e6372656173652070657263656e7400000000000000006044820152606401610ca0565b61010c83815561010d839055604051839085907f6f5b5b24aad9445609bb96530a0ac641215ba77280befa9a9ad607ecfe08160c90600090a350505050565b60006129cb613224565b6129d361326a565b61010054600160a01b900460ff16156129fe5760405162461bcd60e51b8152600401610ca090614b1e565b81600003612a1e5760405162461bcd60e51b8152600401610ca090614b4c565b60ff546040516370a0823160e01b815233600482015283916001600160a01b0316906370a0823190602401602060405180830381865afa158015612a66573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a8a9190614b83565b1015612aa85760405162461bcd60e51b8152600401610ca090614b9c565b612ab06135a3565b6000612ac28361010460000154612d09565b90508015801590612ada575080612ad7613165565b10155b612af65760405162461bcd60e51b8152600401610ca090614bdd565b806101046000016000828254612b0c9190614a2b565b909155505060fd5460009015612b565760fd5461271090612b2e908490614a14565b612b3891906149d5565b9050806101046000016000828254612b50919061462a565b90915550505b60ff54604051632770a7eb60e21b8152336004820152602481018690526001600160a01b0390911690639dc29fac906044016020604051808303816000875af1158015612ba7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612bcb9190614adc565b612be75760405162461bcd60e51b8152600401610ca090614c4e565b6000612bf38284614a2b565b9050806101126000828254612c089190614a2b565b9091555050604051600090339083908381818185875af1925050503d8060008114612c4f576040519150601f19603f3d011682016040523d82523d6000602084013e612c54565b606091505b5050905080612ca55760405162461bcd60e51b815260206004820181905260248201527f5472616e73666572206f662066756e647320746f2075736572206661696c65646044820152606401610ca0565b612cad6137fb565b612cb56138a1565b604080518781526020810184905290810184905233907e168c9e6995121888eee9b6d2c7566d846e3115a91cd4d27740443bc88a7bff9060600160405180910390a2600194505050505061132f600160c955565b60008060ff60009054906101000a90046001600160a01b03166001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015612d5f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d839190614b83565b9050828114158015612d9457508015155b8015612d9f57508215155b15612dc15780612daf8486614a14565b612db991906149d5565b915050610d5b565b83915050610d5b565b6060810151815160009182918203612e1a576000612df2856040015161010460000154612d09565b6020860151909150612e0c670de0b6b3a764000083614a14565b612e1691906149d5565b9150505b670de0b6b3a76400008111612e4f578451670de0b6b3a764000090612e40908390614a14565b612e4a91906149d5565b612e52565b84515b9250612710856020015184612e679190614a14565b612e7191906149d5565b9150509250929050565b61010054600090600160a01b900460ff1615612e9957506000919050565b8151600003612eaa57506000919050565b60608083015160009081526101026020908152604091829020825160808101845281548082526001830154938201939093526002820154938101939093526003015492820192909252901580612f005750805142105b15612f0e5750600092915050565b4283604001511115612f235750600092915050565b6000612f2f8483612dca565b50905080610112541015612f47575060009392505050565b61010a54811115612f5c575060009392505050565b5060019392505050565b610104546101005460408051629032ff60e51b8152905160009283928392839283926001600160a01b03909116916312065fe0916004808201926020929091908290030181865afa158015612fbf573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612fe39190614b83565b610108546101075461010654929350600092612fff919061462a565b613009919061462a565b9050808211156130305761301d8183614a2b565b9550613029868861462a565b965061307a565b8082101561307a576130428282614a2b565b61010954909550600090613056908961462a565b6130608988614a14565b61306a91906149d5565b90506130768189614a2b565b9750505b610114546000906001600160a01b031661309557600061310d565b61011460009054906101000a90046001600160a01b03166001600160a01b03166312065fe06040518163ffffffff1660e01b8152600401602060405180830381865afa1580156130e9573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061310d9190614b83565b6101135490915080821115613139576131268183614a2b565b9550613132868a61462a565b985061315a565b8082101561315a5761314b8282614a2b565b9450613157858a614a2b565b98505b505050509091929394565b61010a546101125460009161317991614a2b565b905090565b60008060ff60009054906101000a90046001600160a01b03166001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156131d4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906131f89190614b83565b905082811415801561320957508215155b801561321457508015155b15612dc15782612daf8286614a14565b60975460ff16156119d05760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b6044820152606401610ca0565b600260c954036132bc5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610ca0565b600260c955565b60008360000361330e5760405162461bcd60e51b8152602060048201526016602482015275125b9d985b1a590819195c1bdcda5d08185b5bdd5b9d60521b6044820152606401610ca0565b6133166135a3565b60006127108560fb6000015461332c9190614a14565b61333691906149d5565b905060006133448287614a2b565b90506000613358826101046000015461317e565b9050866101046000016000828254613370919061462a565b909155505084156133945784610113600082825461338e919061462a565b90915550505b60ff546040516340c10f1960e01b81526001600160a01b03888116600483015260248201849052909116906340c10f19906044016020604051808303816000875af11580156133e7573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061340b9190614adc565b6134485760405162461bcd60e51b815260206004820152600e60248201526d135a5b9d1a5b99c819985a5b195960921b6044820152606401610ca0565b6134506137fb565b6134586138a1565b60408051838152602081018390529081018490526001600160a01b038716907f4b2bcb0ca50531683faa51870e1018aa0d7272c7f2acc5399389b0c0493865d99060600160405180910390a29695505050505050565b600160c955565b6101075480156134f75760006134cb8383614032565b90508061010460030160008282546134e39190614a2b565b909155506134f390508184614a2b565b9250505b61010854801580159061350957508215155b1561354657600061351a8483614032565b90508061010460040160008282546135329190614a2b565b9091555061354290508185614a2b565b9350505b61010654801580159061355857508315155b156135955760006135698583614032565b90508061010460020160008282546135819190614a2b565b9091555061359190508186614a2b565b9450505b83156123d8576123d8614d57565b61011254479034906135b690829061462a565b82036135da578061011260008282546135cf919061462a565b9091555061364e9050565b6101125482111561364e57600081610112546135f6919061462a565b6136009084614a2b565b610112849055905061361181610901565b613619610953565b6040518181527f7926e9adf71c42b63be07a89b069672dbe3702e8e42b5c1a246b82d1b37d4d1f9060200160405180910390a1505b60008060008061365c612f66565b61010454939850919650945092509050841561369c5761367b85610901565b846101046002016000828254613691919061462a565b909155506137649050565b831561376457610109546000906136b3908361462a565b6136bd8387614a14565b6136c791906149d5565b90506136d38183614a2b565b610104819055610109549092506000901561372b576136f28287614a2b565b905080610104600101600082825461370a9190614a2b565b90915550506101098054829190600090613725908490614a2b565b90915550505b604051819083907f0d2e0a4ccfc33a4f7fc640fadeca01848893f0680cd94a3ce360e9e1aa18581f90600090a3613761866134b5565b50505b82156137915761377383610901565b826101136000828254613786919061462a565b909155506137f29050565b81156137f2576137a18282614a2b565b610104819055610113805491925083916000906137bf908490614a2b565b909155505060405160009083907f0d2e0a4ccfc33a4f7fc640fadeca01848893f0680cd94a3ce360e9e1aa18581f908390a35b50505050505050565b6101075461010854156138645761010a54610107546101055460009261383a9290916138279190614a2b565b6138319190614a2b565b61010854614032565b9050613846818361462a565b6101078190556101085490925061385e908290614a2b565b61010855505b61010a546101055461389a9161387991614032565b610105546138959061388c908590614a2b565b61011254614032565b6142f9565b61010a5550565b61010454806138fd5760405162461bcd60e51b815260206004820152602260248201527f43757272656e74206465706f736974732063616e6e6f7420676f20746f207a65604482015261726f60f01b6064820152608401610ca0565b61010554600090662386f26fc1000090613917908461462a565b61392191906149d5565b6101135461010754610108546101065461011254949550600094662386f26fc10000949392916139509161462a565b61395a919061462a565b613964919061462a565b61396e919061462a565b61397891906149d5565b905061398582600161462a565b811115801561399e575061399a81600161462a565b8211155b6139e05760405162461bcd60e51b8152602060048201526013602482015272155b98985b185b98d9590818dbdb9d1c9858dd606a1b6044820152606401610ca0565b6139e861430f565b505050565b60fe546040516312d9a6ad60e01b8152600481018390523360248201526001600160a01b03909116906312d9a6ad90604401602060405180830381865afa158015613a3c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613a609190614adc565b6114f25760405162461bcd60e51b8152600401610ca090614af9565b600080516020614e4c833981519152546001600160a01b031690565b7fb8ea7c31de614c54f5b3938aa9732e87deb869a880ec52d4bb778c09789441b1613ac2816139ed565b6000826001600160a01b03163b11610e3a5760405162461bcd60e51b81526020600482015260096024820152680858dbdb9d1c9858dd60ba1b6044820152606401610ca0565b613b11816143c7565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b60975460ff166119d05760405162461bcd60e51b815260206004820152601460248201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b6044820152606401610ca0565b613b99613b48565b6097805460ff191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa335b6040516001600160a01b03909116815260200160405180910390a1565b7f4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd91435460ff1615613c16576139e8836143c7565b826001600160a01b03166352d1902d6040518163ffffffff1660e01b8152600401602060405180830381865afa925050508015613c70575060408051601f3d908101601f19168201909252613c6d91810190614b83565b60015b613cd35760405162461bcd60e51b815260206004820152602e60248201527f45524331393637557067726164653a206e657720696d706c656d656e7461746960448201526d6f6e206973206e6f74205555505360901b6064820152608401610ca0565b600080516020614e4c8339815191528114613d425760405162461bcd60e51b815260206004820152602960248201527f45524331393637557067726164653a20756e737570706f727465642070726f786044820152681a58589b195555525160ba1b6064820152608401610ca0565b506139e8838383614463565b6001600160a01b03811660009081526101016020908152604080832085845282528083208151608081018352815480825260018301549482019490945260028201549281019290925260030154606082015282918203613de05760405162461bcd60e51b815260206004820152600d60248201526c24b73b30b634b21027b93232b960991b6044820152606401610ca0565b606080820151600090815261010260209081526040918290208251608081018452815480825260018301549382019390935260028201549381019390935260030154928201929092529015801590613e39575080514210155b613e7e5760405162461bcd60e51b815260206004820152601660248201527513dc99195c881a5cc81b9bdd08199a5b985b1a5e995960521b6044820152606401610ca0565b600080613e8b8484612dca565b9150915042846040015111158015613ea65750816101125410155b613eeb5760405162461bcd60e51b81526020600482015260166024820152754f72646572206973206e6f7420636c61696d61626c6560501b6044820152606401610ca0565b61010a54821115613f495760405162461bcd60e51b815260206004820152602260248201527f416d6f756e7420657863656564732066756e64732e636c61696d61626c65506f6044820152611bdb60f21b6064820152608401610ca0565b8351604080518a815260208101929092528101839052606081018290526001600160a01b038816907f43236f0f39c52b337b0925119217c5e32cf752a69a2ae06b1e0a9652ec36a02e9060800160405180910390a26001600160a01b0387166000908152610101602090815260408083208b845290915281208190556101058054849290613fd8908490614a2b565b909155505061010a8054839190600090613ff3908490614a2b565b9091555061400390508183614a2b565b61011260008282546140159190614a2b565b9091555061402590508183614a2b565b9890975095505050505050565b60008183116140415782610d7c565b50919050565b6000818152610102602090815260409182902082516080810184528154808252600183015493820193909352600282015493810193909352600301546060830152156140d55760405162461bcd60e51b815260206004820152601960248201527f6261746368496420616c72656164792070726f636573736564000000000000006044820152606401610ca0565b6000828152610102602090815260408220429055820151156141dd576000614107836040015161010460000154612d09565b6020840151909150614121670de0b6b3a764000083614a14565b61412b91906149d5565b600085815261010260209081526040909120600301829055840151909250811015614156578061415c565b82602001515b610109549091508111156141bf576101095460009061417b9083614a2b565b9050806101046001016000828254614193919061462a565b909155505061010480548291906000906141ae908490614a2b565b9091555050600061010955506141db565b8061010460050160008282546141d59190614a2b565b90915550505b505b827f2f8e27901e927950b1278ec32324d1042109597c988544a4d8f85b19f2fd6419836020015184604001518460405161422a939291909283526020830191909152604082015260600190565b60405180910390a2505050565b61423f613224565b6097805460ff191660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258613bc63390565b600054610100900460ff1661429b5760405162461bcd60e51b8152600401610ca090614d6d565b6119d0614488565b600054610100900460ff166142ca5760405162461bcd60e51b8152600401610ca090614d6d565b6119d06144bb565b600054610100900460ff166119d05760405162461bcd60e51b8152600401610ca090614d6d565b60008183116143085781610d7c565b5090919050565b6000614329670de0b6b3a764000061010460000154612d09565b6101115490915081810361433b575050565b60008082841015614376576143508484614a2b565b61010c54909250612710906143659085614a14565b61436f91906149d5565b90506143aa565b828411156143aa576143888385614a2b565b61010d549092506127109061439d9085614a14565b6143a791906149d5565b90505b808211156143bf576143ba614237565b6123d8565b6123d8610953565b6001600160a01b0381163b6144345760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b6064820152608401610ca0565b600080516020614e4c83398151915280546001600160a01b0319166001600160a01b0392909216919091179055565b61446c83613b08565b6000825111806144795750805b156139e8576123d883836144e2565b600054610100900460ff166144af5760405162461bcd60e51b8152600401610ca090614d6d565b6097805460ff19169055565b600054610100900460ff166134ae5760405162461bcd60e51b8152600401610ca090614d6d565b60606001600160a01b0383163b61454a5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6044820152651b9d1c9858dd60d21b6064820152608401610ca0565b600080846001600160a01b0316846040516145659190614ddc565b600060405180830381855af49150503d80600081146145a0576040519150601f19603f3d011682016040523d82523d6000602084013e6145a5565b606091505b50915091506145cd8282604051806060016040528060278152602001614e6c602791396145d6565b95945050505050565b606083156145e5575081610d7c565b610d7c83838151156145fa5781518083602001fd5b8060405162461bcd60e51b8152600401610ca09190614df8565b634e487b7160e01b600052601160045260246000fd5b80820180821115610d5b57610d5b614614565b6001600160a01b03811681146114f257600080fd5b6000806040838503121561466557600080fd5b82356146708161463d565b946020939093013593505050565b6060808252845182820181905260009190608090818501906020808a01865b838110156146e057815180518652838101518487015260408082015190870152878101518887015286015115158686015260a0909401939082019060010161469d565b50508601979097526040909401949094525090949350505050565b6000806040838503121561470e57600080fd5b82356147198161463d565b915060208301356147298161463d565b809150509250929050565b60006020828403121561474657600080fd5b5035919050565b6000806040838503121561476057600080fd5b50508035926020909101359150565b80151581146114f257600080fd5b60006020828403121561478f57600080fd5b8135610d7c8161476f565b6000602082840312156147ac57600080fd5b8135610d7c8161463d565b634e487b7160e01b600052604160045260246000fd5b600080604083850312156147e057600080fd5b82356147eb8161463d565b9150602083013567ffffffffffffffff8082111561480857600080fd5b818501915085601f83011261481c57600080fd5b81358181111561482e5761482e6147b7565b604051601f8201601f19908116603f01168101908382118183101715614856576148566147b7565b8160405282815288602084870101111561486f57600080fd5b8260208601602083013760006020848301015280955050505050509250929050565b600080602083850312156148a457600080fd5b823567ffffffffffffffff808211156148bc57600080fd5b818501915085601f8301126148d057600080fd5b8135818111156148df57600080fd5b8660208260051b85010111156148f457600080fd5b60209290920196919550909350505050565b6000806040838503121561491957600080fd5b82356003811061467057600080fd5b60008060006060848603121561493d57600080fd5b83359250602084013561494f8161463d565b9150604084013561495f8161463d565b809150509250925092565b60008060006060848603121561497f57600080fd5b833561498a8161463d565b9250602084013561494f8161463d565b600080604083850312156149ad57600080fd5b8235915060208301356147298161463d565b634e487b7160e01b600052601260045260246000fd5b6000826149e4576149e46149bf565b500490565b6000826149f8576149f86149bf565b500690565b600081614a0c57614a0c614614565b506000190190565b8082028115828204841417610d5b57610d5b614614565b81810381811115610d5b57610d5b614614565b634e487b7160e01b600052603260045260246000fd5b600060018201614a6657614a66614614565b5060010190565b602080825260139082015272496e76616c69642064656c656761746564546f60681b604082015260600190565b60208082526022908201527f53656e6420696e76616c69642c206d757374206265206e6f6465206d616e616760408201526132b960f11b606082015260800190565b600060208284031215614aee57600080fd5b8151610d7c8161476f565b6020808252600b908201526a105d5d1a0811985a5b195960aa1b604082015260600190565b60208082526014908201527315da5d1a191c985dd85b1cc8191a5cd8589b195960621b604082015260600190565b6020808252601e908201527f576974686472617720616d6f756e742063616e6e6f74206265207a65726f0000604082015260600190565b600060208284031215614b9557600080fd5b5051919050565b60208082526021908201527f496e73756666696369656e74206373546f6b656e20757365722062616c616e636040820152606560f81b606082015260800190565b602080825260149082015273125b9d985b1a59081d1bdad95b88185b5bdd5b9d60621b604082015260600190565b60208082526023908201527f416d6f756e74206e6f7420617661696c61626c6520666f7220776974686472616040820152621dd85b60ea1b606082015260800190565b6020808252600b908201526a109d5c9b8819985a5b195960aa1b604082015260600190565b6020808252602c908201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060408201526b19195b1959d85d1958d85b1b60a21b606082015260800190565b6020808252602c908201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060408201526b6163746976652070726f787960a01b606082015260800190565b634e487b7160e01b600052602160045260246000fd5b6060810160038510614d4357634e487b7160e01b600052602160045260246000fd5b938152602081019290925260409091015290565b634e487b7160e01b600052600160045260246000fd5b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b606082015260800190565b60005b83811015614dd3578181015183820152602001614dbb565b50506000910152565b60008251614dee818460208701614db8565b9190910192915050565b6020815260008251806020840152614e17816040850160208701614db8565b601f01601f1916919091016040019291505056fef66846415d2bf9eabda9e84793ff9c0ea96d87f50fc41e66aa16469c6a442f05360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220bae85150d75515a911fdb7aeaac14fa4aeef1d461d73e44a4307c3fc7de5708a64736f6c63430008120033
Deployed Bytecode Sourcemap
71037:42370:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;99338:16;99357:9;99338:28;;99391:8;99377:10;;:22;;;;;;;:::i;:::-;;;;-1:-1:-1;99410:24:0;;-1:-1:-1;99425:8:0;99410:14;:24::i;:::-;99445:21;:19;:21::i;:::-;99482;;422:25:1;;;99482:21:0;;410:2:1;395:18;99482:21:0;;;;;;;99327:184;71037:42370;;;;91932:1391;;;;;;;;;;-1:-1:-1;91932:1391:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;;;:::i;:::-;;;;;;;;91280:259;;;;;;;;;;;;;:::i;:::-;;;422:25:1;;;410:2;395:18;91280:259:0;276:177:1;76152:471:0;;;;;;:::i;:::-;;:::i;73031:42::-;;;;;;;;;;-1:-1:-1;73031:42:0;;;;;;;;;;;;;2672:25:1;;;2728:2;2713:18;;2706:34;;;;2645:18;73031:42:0;2498:248:1;89563:221:0;;;;;;;;;;-1:-1:-1;89563:221:0;;;;;:::i;:::-;;:::i;96392:737::-;;;;;;:::i;:::-;;:::i;:::-;;109946:319;;;;;;;;;;-1:-1:-1;109946:319:0;;;;;:::i;:::-;;:::i;72724:52::-;;;;;;;;;;-1:-1:-1;72724:52:0;;;;;:::i;:::-;;:::i;78726:1703::-;;;;;;;;;;-1:-1:-1;78726:1703:0;;;;;:::i;:::-;;:::i;112786:229::-;;;;;;;;;;-1:-1:-1;112786:229:0;;;;;:::i;:::-;;:::i;108438:241::-;;;;;;;;;;-1:-1:-1;108438:241:0;;;;;:::i;:::-;;:::i;112224:126::-;;;;;;;;;;;;;:::i;72456:75::-;;;;;;;;;;-1:-1:-1;72456:75:0;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4041:25:1;;;4097:2;4082:18;;4075:34;;;;4125:18;;;4118:34;4183:2;4168:18;;4161:34;4028:3;4013:19;72456:75:0;3810:391:1;73115:22:0;;;;;;;;;;;;;;;;73527:25;;;;;;;;;;;;;;;;69738:225;;;;;;:::i;:::-;;:::i;68957:133::-;;;;;;;;;;;;;:::i;52651:86::-;;;;;;;;;;-1:-1:-1;52722:7:0;;;;52651:86;;;5746:14:1;;5739:22;5721:41;;5709:2;5694:18;52651:86:0;5581:187:1;111238:416:0;;;;;;;;;;-1:-1:-1;111238:416:0;;;;;:::i;:::-;;:::i;73625:35::-;;;;;;;;;;;;;;;;73353:30;;;;;;;;;;;;;;;;80625:1031;;;;;;;;;;-1:-1:-1;80625:1031:0;;;;;:::i;:::-;;:::i;97180:152::-;;;;;;;;;;;;;:::i;93687:2414::-;;;;;;;;;;-1:-1:-1;93687:2414:0;;;;;:::i;:::-;;:::i;:::-;;;;6867:25:1;;;6935:14;;6928:22;6923:2;6908:18;;6901:50;6967:18;;;6960:34;6855:2;6840:18;93687:2414:0;6671:329:1;112081:93:0;;;;;;;;;;;;;:::i;72349:31::-;;;;;;;;;;-1:-1:-1;72349:31:0;;;;-1:-1:-1;;;72349:31:0;;;;;;108858:896;;;;;;;;;;-1:-1:-1;108858:896:0;;;;;:::i;:::-;;:::i;86769:563::-;;;;;;;;;;-1:-1:-1;86769:563:0;;;;;:::i;:::-;;:::i;89270:215::-;;;;;;;;;;-1:-1:-1;89270:215:0;;;;;:::i;:::-;;:::i;73434:31::-;;;;;;;;;;;;;;;;71961:16;;;;;;;;;;-1:-1:-1;71961:16:0;;;;;;;;;;;;;;;;8007:25:1;;;8063:2;8048:18;;8041:34;;;;8091:18;;;8084:34;7995:2;7980:18;71961:16:0;7805:319:1;72936:31:0;;;;;;;;;;-1:-1:-1;72936:31:0;;;;;;;;74477:855;;;;;;;;;;-1:-1:-1;74477:855:0;;;;;:::i;:::-;;:::i;75551:343::-;;;;;;:::i;:::-;;:::i;73726:43::-;;;;;;;;;;-1:-1:-1;73726:43:0;;;;-1:-1:-1;;;;;73726:43:0;;;;;;-1:-1:-1;;;;;8853:32:1;;;8835:51;;8823:2;8808:18;73726:43:0;8663:229:1;72825:18:0;;;;;;;;;;-1:-1:-1;72825:18:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;9212:25:1;;;9268:2;9253:18;;9246:34;;;;9296:18;;;9289:34;;;;9354:2;9339:18;;9332:34;;;;9397:3;9382:19;;9375:35;9441:3;9426:19;;9419:35;9485:3;9470:19;;9463:35;9199:3;9184:19;72825:18:0;8897:607:1;76747:141:0;;;:::i;77082:265::-;;;;;;:::i;:::-;;:::i;72101:23::-;;;;;;;;;;-1:-1:-1;72101:23:0;;;;-1:-1:-1;;;;;72101:23:0;;;97468:283;;;;;;;;;;-1:-1:-1;97468:283:0;;;;;:::i;:::-;;:::i;88997:194::-;;;;;;;;;;;;;:::i;72596:60::-;;;;;;;;;;-1:-1:-1;72596:60:0;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;87647:1201;;;;;;;;;;-1:-1:-1;87647:1201:0;;;;;:::i;:::-;;:::i;110550:569::-;;;;;;;;;;-1:-1:-1;110550:569:0;;;;;:::i;:::-;;:::i;85024:1411::-;;;;;;;;;;-1:-1:-1;85024:1411:0;;;;;:::i;:::-;;:::i;104806:138::-;104892:8;104868:5;:20;;;:32;;;;;;;:::i;:::-;;;;-1:-1:-1;;104916:20:0;;422:25:1;;;104916:20:0;;410:2:1;395:18;104916:20:0;;;;;;;;104806:138;:::o;106321:221::-;106372:14;106389:47;106406:7;106415:5;:20;;;106389:16;:47::i;:::-;106447:16;:25;;;106488:46;;;2672:25:1;;;106518:15:0;2728:2:1;2713:18;;2706:34;106372:64:0;;-1:-1:-1;106488:46:0;;2645:18:1;106488:46:0;2498:248:1;91932:1391:0;92132:31;;;92160:2;92132:31;;;;;;;;;92033:30;;92065:7;;;;;;92132:31;;;;;;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;92132:31:0;;;;;;;;;;;;;-1:-1:-1;;;;;;;92223:22:0;;92174:16;92223:22;;;:15;:22;;;;;:29;92094:69;;-1:-1:-1;92193:2:0;;92223:29;92284:17;92193:2;92223:29;92284:17;:::i;:::-;92263:38;;92325:1;92316:6;:10;:36;;;;-1:-1:-1;92330:17:0;92339:8;92330:6;:17;:::i;:::-;:22;92316:36;92312:81;;;92369:12;;;;:::i;:::-;;;;92312:81;92416:10;92407:5;:19;;:34;;;;-1:-1:-1;92430:11:0;;;92407:34;92403:858;;;92463:9;92458:792;92482:8;92478:1;:12;92458:792;;;92516:13;92564:1;92560;92541:16;92549:8;92541:5;:16;:::i;:::-;92532:25;;:6;:25;:::i;:::-;:29;;;;:::i;:::-;:33;;;;:::i;:::-;-1:-1:-1;;;;;92602:22:0;;92584:15;92602:22;;;:15;:22;;;;;:29;;92516:49;;-1:-1:-1;92584:15:0;;92516:49;;92602:29;;;;;;:::i;:::-;;;;;;;;;;;;;-1:-1:-1;;;;;92679:21:0;;;;:14;:21;;;;;;:30;;;;;;;;92650:59;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;92762:34;;;:19;:34;;;;;92728:68;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;92602:29;;-1:-1:-1;92650:59:0;;92602:29;92852:40;92650:59;92728:68;92852:21;:40::i;:::-;92815:77;;;;92921:271;;;;;;;;92975:7;92921:271;;;;93022:8;93013:6;:17;;;;:::i;:::-;92921:271;;;;93058:5;:9;;;92921:271;;;;93103:5;:17;;;92921:271;;;;93156:16;93166:5;93156:9;:16::i;:::-;92921:271;;;;;92911:4;92916:1;92911:7;;;;;;;;:::i;:::-;;;;;;:281;;;;93217:5;93226:1;93217:10;93213:21;;93229:5;;;;;;;;93213:21;92497:753;;;;;;92492:3;;;;;:::i;:::-;;;;92458:792;;;;92403:858;93281:4;;93287:15;;-1:-1:-1;93281:4:0;;-1:-1:-1;91932:1391:0;;-1:-1:-1;;;;;91932:1391:0:o;91280:259::-;91334:7;91355:22;91389:20;:18;:20::i;:::-;91354:55;;;;;;91420:14;91437:20;:18;:20::i;:::-;91420:37;;91475:6;91485:1;91475:11;:56;;91530:1;91475:56;;;91489:38;91504:6;91512:14;91489;:38::i;:::-;91468:63;;;;91280:259;:::o;76152:471::-;76308:7;52256:19;:17;:19::i;:::-;48523:21:::1;:19;:21::i;:::-;-1:-1:-1::0;;;;;76336:26:0;::::2;76328:58;;;;-1:-1:-1::0;;;76328:58:0::2;;;;;;;:::i;:::-;;;;;;;;;-1:-1:-1::0;;;;;76405:23:0;::::2;76397:52;;;::::0;-1:-1:-1;;;76397:52:0;;11696:2:1;76397:52:0::2;::::0;::::2;11678:21:1::0;11735:2;11715:18;;;11708:30;-1:-1:-1;;;11754:18:1;;;11747:46;11810:18;;76397:52:0::2;11494:340:1::0;76397:52:0::2;76460:16;76479:36;76488:9;76499:12;76513:1;76479:8;:36::i;:::-;76460:55;;76568:9;-1:-1:-1::0;;;;;76531:58:0::2;76554:12;-1:-1:-1::0;;;;;76531:58:0::2;;76579:9;76531:58;;;;422:25:1::0;;410:2;395:18;;276:177;76531:58:0::2;;;;;;;;76607:8:::0;-1:-1:-1;48567:20:0::1;47784:1:::0;49087:7;:22;48904:213;48567:20:::1;76152:471:::0;;;;:::o;89563:221::-;89635:7;89656:22;89690:20;:18;:20::i;:::-;89655:55;;;;;;89728:48;89745:14;89761;89728:16;:48::i;:::-;89721:55;89563:221;-1:-1:-1;;;89563:221:0:o;96392:737::-;52256:19;:17;:19::i;:::-;48523:21:::1;:19;:21::i;:::-;96538:11:::2;::::0;-1:-1:-1;;;;;96538:11:0::2;96516:10;:34;96508:81;;;;-1:-1:-1::0;;;96508:81:0::2;;;;;;;:::i;:::-;96600:21;96647:7:::0;96624:20:::2;96636:8:::0;96624:9:::2;:20;:::i;:::-;:30;;;;:::i;:::-;96600:54:::0;-1:-1:-1;96698:13:0;;96694:70:::2;;96728:24;96743:8;96728:14;:24::i;:::-;96829:12:::0;;96825:76:::2;;96858:31;96881:7;96858:22;:31::i;:::-;96955:18:::0;;96951:87:::2;;97013:13;96990:5;:19;;;:36;;;;;;;:::i;:::-;::::0;;;-1:-1:-1;;96951:87:0::2;97050:16;:14;:16::i;:::-;97077:22;:20;:22::i;:::-;97110:11;:9;:11::i;:::-;96497:632;48567:20:::1;47784:1:::0;49087:7;:22;48904:213;48567:20:::1;96392:737:::0;;:::o;109946:319::-;110058:11;;-1:-1:-1;;;;;110058:11:0;110036:10;:34;;:88;;-1:-1:-1;110074:11:0;;:50;;-1:-1:-1;;;110074:50:0;;71474:28;110074:50;;;12416:25:1;110113:10:0;12457:18:1;;;12450:60;-1:-1:-1;;;;;110074:11:0;;;;:21;;12389:18:1;;110074:50:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;110014:149;;;;-1:-1:-1;;;110014:149:0;;;;;;;:::i;:::-;110174:19;:31;;-1:-1:-1;;;;110174:31:0;-1:-1:-1;;;110174:31:0;;;;;;;;;;;;;110221:36;;;;-1:-1:-1;;110221:36:0;109946:319;:::o;72724:52::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;78726:1703::-;78817:7;52256:19;:17;:19::i;:::-;48523:21:::1;:19;:21::i;:::-;78846:19:::2;::::0;-1:-1:-1;;;78846:19:0;::::2;;;78845:20;78837:53;;;;-1:-1:-1::0;;;78837:53:0::2;;;;;;;:::i;:::-;78909:9;78922:1;78909:14:::0;78901:57:::2;;;;-1:-1:-1::0;;;78901:57:0::2;;;;;;;:::i;:::-;78977:7;::::0;:29:::2;::::0;-1:-1:-1;;;78977:29:0;;78995:10:::2;78977:29;::::0;::::2;8835:51:1::0;79010:9:0;;-1:-1:-1;;;;;78977:7:0::2;::::0;:17:::2;::::0;8808:18:1;;78977:29:0::2;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:42;;78969:88;;;;-1:-1:-1::0;;;78969:88:0::2;;;;;;;:::i;:::-;79070:16;:14;:16::i;:::-;79124:5;:20:::0;79099:22:::2;79185:43;79202:9:::0;79124:20;79185:16:::2;:43::i;:::-;79155:73;;79247:19;79270:1;79247:24:::0;79239:57:::2;;;;-1:-1:-1::0;;;79239:57:0::2;;;;;;;:::i;:::-;79355:20;::::0;79338:37:::2;::::0;:14;:37:::2;:::i;:::-;79315:19;:60;;79307:108;;;;-1:-1:-1::0;;;79307:108:0::2;;;;;;;:::i;:::-;79453:19;:26:::0;;-1:-1:-1;;79453:26:0::2;79475:4;79453:26;::::0;;79490:5:::2;:43:::0;;79514:19;;79490:5;79453:19:::2;::::0;79490:43:::2;::::0;79514:19;;79490:43:::2;:::i;:::-;::::0;;;-1:-1:-1;;79544:19:0;:42;;79567:19;;79544;::::2;::::0;:42:::2;::::0;79567:19;;79544:42:::2;:::i;:::-;::::0;;;-1:-1:-1;;79597:23:0;:46;;79624:19;;79597:23;::::2;::::0;:46:::2;::::0;79624:19;;79597:46:::2;:::i;:::-;::::0;;;-1:-1:-1;;79689:7:0::2;::::0;:35:::2;::::0;-1:-1:-1;;;79689:35:0;;79702:10:::2;79689:35;::::0;::::2;15545:51:1::0;15612:18;;;15605:34;;;-1:-1:-1;;;;;79689:7:0;;::::2;::::0;:12:::2;::::0;15518:18:1;;79689:35:0::2;;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;79681:59;;;;-1:-1:-1::0;;;79681:59:0::2;;;;;;;:::i;:::-;79753:10;79768;;79766:12;;;;;:::i;:::-;;;;;;;79753:25;;79822:196;;;;;;;;79859:19;79822:196;;;;79898:4;:16;;;79822:196;;;;79960:15;;79942;:33;;;;:::i;:::-;79822:196:::0;;79999:7:::2;::::0;;79822:196:::2;::::0;;::::2;::::0;79804:10:::2;-1:-1:-1::0;79789:26:0;;;:14:::2;:26:::0;;;;;;:30;;;;;;;;:229;;;;;;::::2;::::0;::::2;::::0;;::::2;::::0;;;;;;::::2;::::0;::::2;::::0;::::2;::::0;::::2;::::0;;::::2;::::0;::::2;::::0;;::::2;::::0;80084:7;;80064:28;;:19:::2;:28:::0;;;;;:35;;::::2;:58:::0;;80103:19;;-1:-1:-1;80064:58:0::2;::::0;80103:19;;80064:58:::2;:::i;:::-;::::0;;;-1:-1:-1;;80153:7:0::2;::::0;80133:28:::2;::::0;;;:19:::2;:28;::::0;;;;:37:::2;;:50:::0;;80174:9;;80133:28;:50:::2;::::0;80174:9;;80133:50:::2;:::i;:::-;::::0;;;-1:-1:-1;;80212:10:0::2;80196:27;::::0;;;:15:::2;:27;::::0;;;;;;:36;;::::2;::::0;::::2;::::0;;;;;;;::::2;::::0;;;80245:22:::2;:20;:22::i;:::-;80278:11;:9;:11::i;:::-;80367:16:::0;;80307:94:::2;::::0;;16249:25:1;;;16305:2;16290:18;;16283:34;;;16333:18;;;16326:34;;;16391:2;16376:18;;16369:34;;;;80385:15:0::2;16434:3:1::0;16419:19;;16412:35;80319:10:0::2;::::0;80307:94:::2;::::0;16236:3:1;16221:19;80307:94:0::2;;;;;;;80419:2:::0;-1:-1:-1;;;48567:20:0::1;47784:1:::0;49087:7;:22;48904:213;48567:20:::1;78726:1703:::0;;;:::o;112786:229::-;71389:35;73937:20;73947:9;73937;:20::i;:::-;-1:-1:-1;;;;;67827:6:0::1;67810:23;67818:4;67810:23:::0;67802:80:::1;;;;-1:-1:-1::0;;;67802:80:0::1;;;;;;;:::i;:::-;67925:6;-1:-1:-1::0;;;;;67901:30:0::1;:20;:18;:20::i;:::-;-1:-1:-1::0;;;;;67901:30:0::1;;67893:87;;;;-1:-1:-1::0;;;67893:87:0::1;;;;;;;:::i;:::-;112929:37:::2;112947:18;112929:17;:37::i;:::-;112977:30;112988:18;112977:10;:30::i;108438:241::-:0;-1:-1:-1;;;;;;;;;;;73937:20:0;73947:9;73937;:20::i;:::-;71804:7:::1;108533:8;:25;;108525:65;;;::::0;-1:-1:-1;;;108525:65:0;;17486:2:1;108525:65:0::1;::::0;::::1;17468:21:1::0;17525:2;17505:18;;;17498:30;17564:29;17544:18;;;17537:57;17611:18;;108525:65:0::1;17284:351:1::0;108525:65:0::1;108601:15;:26:::0;;;108643:28:::1;::::0;108619:8;;108643:28:::1;::::0;;;::::1;108438:241:::0;;:::o;112224:126::-;71474:28;73937:20;73947:9;73937;:20::i;:::-;52515:16:::1;:14;:16::i;:::-;112300:21:::2;:19;:21::i;:::-;112332:10;:8;:10::i;:::-;112224:126:::0;:::o;69738:225::-;-1:-1:-1;;;;;67827:6:0;67810:23;67818:4;67810:23;67802:80;;;;-1:-1:-1;;;67802:80:0;;;;;;;:::i;:::-;67925:6;-1:-1:-1;;;;;67901:30:0;:20;:18;:20::i;:::-;-1:-1:-1;;;;;67901:30:0;;67893:87;;;;-1:-1:-1;;;67893:87:0;;;;;;;:::i;:::-;69856:36:::1;69874:17;69856;:36::i;:::-;69903:52;69925:17;69944:4;69950;69903:21;:52::i;68957:133::-:0;69035:7;68263:4;-1:-1:-1;;;;;68272:6:0;68255:23;;68247:92;;;;-1:-1:-1;;;68247:92:0;;17842:2:1;68247:92:0;;;17824:21:1;17881:2;17861:18;;;17854:30;17920:34;17900:18;;;17893:62;17991:26;17971:18;;;17964:54;18035:19;;68247:92:0;17640:420:1;68247:92:0;-1:-1:-1;;;;;;;;;;;;68350:1:0::1;68957:133:::0;:::o;111238:416::-;-1:-1:-1;;;;;;;;;;;73937:20:0;73947:9;73937;:20::i;:::-;111367:17:::1;::::0;-1:-1:-1;;;;;111367:17:0::1;111359:40:::0;111351:82:::1;;;::::0;-1:-1:-1;;;111351:82:0;;18267:2:1;111351:82:0::1;::::0;::::1;18249:21:1::0;18306:2;18286:18;;;18279:30;18345:31;18325:18;;;18318:59;18394:18;;111351:82:0::1;18065:353:1::0;111351:82:0::1;-1:-1:-1::0;;;;;111452:41:0;::::1;111444:85;;;::::0;-1:-1:-1;;;111444:85:0;;18625:2:1;111444:85:0::1;::::0;::::1;18607:21:1::0;18664:2;18644:18;;;18637:30;18703:33;18683:18;;;18676:61;18754:18;;111444:85:0::1;18423:355:1::0;111444:85:0::1;111540:17;:38:::0;;-1:-1:-1;;;;;;111540:38:0::1;-1:-1:-1::0;;;;;111540:38:0;::::1;::::0;;::::1;::::0;;;111594:52:::1;::::0;8835:51:1;;;111594:52:0::1;::::0;8823:2:1;8808:18;111594:52:0::1;;;;;;;111238:416:::0;;:::o;80625:1031::-;80724:4;52256:19;:17;:19::i;:::-;48523:21:::1;:19;:21::i;:::-;80750:19:::2;::::0;-1:-1:-1;;;80750:19:0;::::2;;;80749:20;80741:53;;;;-1:-1:-1::0;;;80741:53:0::2;;;;;;;:::i;:::-;80827:9:::0;80805:19:::2;80862:16:::0;;;80854:52:::2;;;::::0;-1:-1:-1;;;80854:52:0;;18985:2:1;80854:52:0::2;::::0;::::2;18967:21:1::0;19024:2;19004:18;;;18997:30;19063:25;19043:18;;;19036:53;19106:18;;80854:52:0::2;18783:347:1::0;80854:52:0::2;80919:16;:14;:16::i;:::-;80948:21;80984:18:::0;81022:9:::2;81017:236;81037:20:::0;;::::2;81017:236;;;81080:22;81104:17:::0;81125:32:::2;81132:9;;81142:1;81132:12;;;;;;;:::i;:::-;;;;;;;81146:10;81125:6;:32::i;:::-;81079:78:::0;;-1:-1:-1;81079:78:0;-1:-1:-1;81172:31:0::2;81079:78:::0;81172:31;::::2;:::i;:::-;::::0;-1:-1:-1;81218:23:0::2;81232:9:::0;81218:23;::::2;:::i;:::-;;;81064:189;;81059:3;;;;;:::i;:::-;;;;81017:236;;;;81271:13;81288:1;81271:18:::0;81263:53:::2;;;::::0;-1:-1:-1;;;81263:53:0;;19337:2:1;81263:53:0::2;::::0;::::2;19319:21:1::0;19376:2;19356:18;;;19349:30;-1:-1:-1;;;19395:18:1;;;19388:52;19457:18;;81263:53:0::2;19135:346:1::0;81263:53:0::2;81333:15:::0;;81329:82:::2;;81389:10;81365:5;:20;;;:34;;;;;;;:::i;:::-;::::0;;;-1:-1:-1;;81329:82:0::2;81463:41;::::0;81445:12:::2;::::0;81463:10:::2;::::0;81486:13;;81445:12;81463:41;81445:12;81463:41;81486:13;81463:10;:41:::2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;81444:60;;;81523:7;81515:52;;;::::0;-1:-1:-1;;;81515:52:0;;19898:2:1;81515:52:0::2;::::0;::::2;19880:21:1::0;;;19917:18;;;19910:30;19976:34;19956:18;;;19949:62;20028:18;;81515:52:0::2;19696:356:1::0;81515:52:0::2;81580:22;:20;:22::i;:::-;81613:11;:9;:11::i;:::-;81644:4;81637:11;;;;;;48567:20:::1;47784:1:::0;49087:7;:22;48904:213;97180:152;52256:19;:17;:19::i;:::-;48523:21:::1;:19;:21::i;:::-;97253:16:::2;:14;:16::i;:::-;97280:22;:20;:22::i;:::-;97313:11;:9;:11::i;:::-;48567:20:::1;47784:1:::0;49087:7;:22;48904:213;48567:20:::1;97180:152::o:0;93687:2414::-;93797:22;93821:15;93838:22;52256:19;:17;:19::i;:::-;48523:21:::1;:19;:21::i;:::-;93903:11:::2;::::0;-1:-1:-1;;;;;93903:11:0::2;93881:10;:34;93873:81;;;;-1:-1:-1::0;;;93873:81:0::2;;;;;;;:::i;:::-;93967:16;:14;:16::i;:::-;-1:-1:-1::0;;94013:7:0::2;::::0;94114:5:::2;:20:::0;94169:19;;94013:7;;-1:-1:-1;94044:5:0::2;::::0;;;94114:20;94232:30;;::::2;94228:1809;;;94279:17;94299:30;94315:14:::0;94299:13;:30:::2;:::i;:::-;94279:50:::0;-1:-1:-1;94361:24:0::2;71578:8;94279:50:::0;94361:24:::2;:::i;:::-;94344:41:::0;-1:-1:-1;94400:13:0::2;94416:24;71578:8;94416:9:::0;:24:::2;:::i;:::-;94400:40:::0;-1:-1:-1;94527:10:0;;94523:151:::2;;94558:19;94576:1;94558:19:::0;::::2;:::i;:::-;::::0;-1:-1:-1;94608:50:0::2;94613:13:::0;94628:29:::2;71578:8;94558:19:::0;94628:29:::2;:::i;:::-;94608:4;:50::i;:::-;94596:62;;94523:151;94694:19:::0;;94690:145:::2;;94757:9;94734:5;:19;;;:32;;;;;;;:::i;:::-;::::0;;;-1:-1:-1;;94785:21:0;:34;;94810:9;;94785:21;::::2;::::0;:34:::2;::::0;94810:9;;94785:34:::2;:::i;:::-;::::0;;;-1:-1:-1;;94690:145:0::2;94849:7;:9:::0;;;:7:::2;:9;::::0;::::2;:::i;:::-;;;;;;94911:10;94880:53;;94895:14;94880:53;94923:9;94880:53;;;;422:25:1::0;;410:2;395:18;;276:177;94880:53:0::2;;;;;;;;94264:681;;94228:1809;;;95007:13;94989:14;:31;94985:1052;;95077:19:::0;;95064:10:::2;::::0;95037:24:::2;::::0;95064:32:::2;::::0;::::2;:::i;:::-;95037:59:::0;-1:-1:-1;95111:15:0::2;95129:54;95134:30;95151:13:::0;95134:14;:30:::2;:::i;:::-;95166:16;95129:4;:54::i;:::-;95111:72:::0;-1:-1:-1;95215:48:0::2;95220:22;71578:8;95111:72:::0;95220:22:::2;:::i;:::-;95244:18;95215:4;:48::i;:::-;95198:65:::0;-1:-1:-1;95368:19:0;;::::2;::::0;:42:::2;;-1:-1:-1::0;95391:19:0::2;::::0;::::2;;95368:42;95364:184;;;95431:27;95443:14;95431:11;:27::i;:::-;95477:7;:9:::0;;;:7:::2;:9;::::0;::::2;:::i;:::-;::::0;;;-1:-1:-1;;95505:19:0::2;:27:::0;;-1:-1:-1;;95505:27:0::2;::::0;;95364:184:::2;95568:19:::0;;95564:462:::2;;95621:4;::::0;-1:-1:-1;95654:29:0::2;71578:8;95654:14:::0;:29:::2;:::i;:::-;95644:39;;95725:7;95702:5;:19;;;:30;;;;;;;:::i;:::-;;;;;;;;95765:7;95751:10;;:21;;;;;;;:::i;:::-;::::0;;;-1:-1:-1;;95820:11:0::2;::::0;95812:45:::2;::::0;95794:12:::2;::::0;-1:-1:-1;;;;;95820:11:0::2;::::0;95845:7;;95794:12;95812:45;95794:12;95812:45;95845:7;95820:11;95812:45:::2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;95793:64;;;95884:7;95876:59;;;::::0;-1:-1:-1;;;95876:59:0;;20259:2:1;95876:59:0::2;::::0;::::2;20241:21:1::0;20298:2;20278:18;;;20271:30;20337:34;20317:18;;;20310:62;-1:-1:-1;;;20388:18:1;;;20381:37;20435:19;;95876:59:0::2;20057:403:1::0;95876:59:0::2;95990:10;95959:51;;95974:14;95959:51;96002:7;95959:51;;;;422:25:1::0;;410:2;395:18;;276:177;95959:51:0::2;;;;;;;;95589:437;95564:462;95022:1015;;94985:1052;96049:22;:20;:22::i;:::-;96082:11;:9;:11::i;:::-;93862:2239;;48567:20:::1;47784:1:::0;49087:7;:22;48904:213;48567:20:::1;93687:2414:::0;;;;;:::o;112081:93::-;71474:28;73937:20;73947:9;73937;:20::i;:::-;52256:19:::1;:17;:19::i;:::-;112158:8:::2;:6;:8::i;108858:896::-:0;-1:-1:-1;;;;;;;;;;;73937:20:0;73947:9;73937;:20::i;:::-;71861:5:::1;108957:4;:22;108949:46;;;::::0;-1:-1:-1;;;108949:46:0;;20667:2:1;108949:46:0::1;::::0;::::1;20649:21:1::0;20706:2;20686:18;;;20679:30;-1:-1:-1;;;20725:18:1;;;20718:41;20776:18;;108949:46:0::1;20465:335:1::0;108949:46:0::1;109006:14;::::0;109039:8:::1;:29;;;;;;;;:::i;:::-;::::0;109035:646:::1;;71636:3;109093:4;:23;;109085:55;;;::::0;-1:-1:-1;;;109085:55:0;;21139:2:1;109085:55:0::1;::::0;::::1;21121:21:1::0;21178:2;21158:18;;;21151:30;-1:-1:-1;;;21197:18:1;;;21190:49;21256:18;;109085:55:0::1;20937:343:1::0;109085:55:0::1;-1:-1:-1::0;109164:4:0::1;:15:::0;;109194:22;;;;109035:646:::1;;;109250:18;109238:8;:30;;;;;;;;:::i;:::-;::::0;109234:447:::1;;-1:-1:-1::0;109294:16:0;;71690:3:::1;109333:24:::0;::::1;;109325:57;;;::::0;-1:-1:-1;;;109325:57:0;;21487:2:1;109325:57:0::1;::::0;::::1;21469:21:1::0;21526:2;21506:18;;;21499:30;-1:-1:-1;;;21545:18:1;;;21538:50;21605:18;;109325:57:0::1;21285:344:1::0;109325:57:0::1;109397:16:::0;:23;;;109234:447:::1;;;109454:25;109442:8;:37;;;;;;;;:::i;:::-;::::0;109438:243:::1;;-1:-1:-1::0;109505:23:0;;71752:4:::1;109551:32:::0;::::1;;109543:81;;;::::0;-1:-1:-1;;;109543:81:0;;21836:2:1;109543:81:0::1;::::0;::::1;21818:21:1::0;21875:2;21855:18;;;21848:30;21914:34;21894:18;;;21887:62;-1:-1:-1;;;21965:18:1;;;21958:34;22009:19;;109543:81:0::1;21634:400:1::0;109543:81:0::1;109639:23:::0;:30;;;109438:243:::1;109711:10;-1:-1:-1::0;;;;;109698:48:0::1;;109723:8;109733:6;109741:4;109698:48;;;;;;;;:::i;:::-;;;;;;;;108938:816;108858:896:::0;;;:::o;86769:563::-;86961:7;52256:19;:17;:19::i;:::-;48523:21:::1;:19;:21::i;:::-;74122:17:::2;::::0;-1:-1:-1;;;;;74122:17:0::2;74100:10;:40;74092:64;;;;-1:-1:-1::0;;;74092:64:0::2;;;;;;;:::i;:::-;86989:7:::3;87000:1;86989:12:::0;86981:47:::3;;;::::0;-1:-1:-1;;;86981:47:0;;22726:2:1;86981:47:0::3;::::0;::::3;22708:21:1::0;22765:2;22745:18;;;22738:30;-1:-1:-1;;;22784:18:1;;;22777:52;22846:18;;86981:47:0::3;22524:346:1::0;86981:47:0::3;-1:-1:-1::0;;;;;87047:26:0;::::3;87039:58;;;;-1:-1:-1::0;;;87039:58:0::3;;;;;;;:::i;:::-;87110:16;87129:40;87138:7;87147:12;87161:7;87129:8;:40::i;:::-;87110:59:::0;-1:-1:-1;;;;;;87186:23:0;::::3;::::0;87182:117:::3;;87268:9;-1:-1:-1::0;;;;;87231:56:0::3;87254:12;-1:-1:-1::0;;;;;87231:56:0::3;;87279:7;87231:56;;;;422:25:1::0;;410:2;395:18;;276:177;87231:56:0::3;;;;;;;;87182:117;87316:8:::0;-1:-1:-1;48567:20:0::1;47784:1:::0;49087:7;:22;48904:213;89270:215;89339:7;89360:22;89394:20;:18;:20::i;:::-;89359:55;;;;;;89432:45;89447:13;89462:14;89432;:45::i;74477:855::-;31757:19;31780:13;;;;;;31779:14;;31827:34;;;;-1:-1:-1;31845:12:0;;31860:1;31845:12;;;;:16;31827:34;31826:108;;;-1:-1:-1;31906:4:0;9089:19;:23;;;31867:66;;-1:-1:-1;31916:12:0;;;;;:17;31867:66;31804:204;;;;-1:-1:-1;;;31804:204:0;;23077:2:1;31804:204:0;;;23059:21:1;23116:2;23096:18;;;23089:30;23155:34;23135:18;;;23128:62;-1:-1:-1;;;23206:18:1;;;23199:44;23260:19;;31804:204:0;22875:410:1;31804:204:0;32019:12;:16;;-1:-1:-1;;32019:16:0;32034:1;32019:16;;;32046:67;;;;32081:13;:20;;-1:-1:-1;;32081:20:0;;;;;32046:67;-1:-1:-1;;;;;67827:6:0::1;67810:23;67818:4;67810:23:::0;67802:80:::1;;;;-1:-1:-1::0;;;67802:80:0::1;;;;;;;:::i;:::-;67925:6;-1:-1:-1::0;;;;;67901:30:0::1;:20;:18;:20::i;:::-;-1:-1:-1::0;;;;;67901:30:0::1;;67893:87;;;;-1:-1:-1::0;;;67893:87:0::1;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;74609:22:0;::::2;74601:58;;;::::0;-1:-1:-1;;;74601:58:0;;23492:2:1;74601:58:0::2;::::0;::::2;23474:21:1::0;23531:2;23511:18;;;23504:30;23570:25;23550:18;;;23543:53;23613:18;;74601:58:0::2;23290:347:1::0;74601:58:0::2;-1:-1:-1::0;;;;;74678:26:0;::::2;74670:66;;;::::0;-1:-1:-1;;;74670:66:0;;23844:2:1;74670:66:0::2;::::0;::::2;23826:21:1::0;23883:2;23863:18;;;23856:30;23922:29;23902:18;;;23895:57;23969:18;;74670:66:0::2;23642:351:1::0;74670:66:0::2;-1:-1:-1::0;;;;;74755:26:0;::::2;74747:66;;;::::0;-1:-1:-1;;;74747:66:0;;24200:2:1;74747:66:0::2;::::0;::::2;24182:21:1::0;24239:2;24219:18;;;24212:30;24278:29;24258:18;;;24251:57;24325:18;;74747:66:0::2;23998:351:1::0;74747:66:0::2;74826:17;:15;:17::i;:::-;74854:24;:22;:24::i;:::-;74889;:22;:24::i;:::-;74926:7;:28:::0;;-1:-1:-1;;;;;74926:28:0;;::::2;-1:-1:-1::0;;;;;;74926:28:0;;::::2;;::::0;;;::::2;74965:40:::0;;;;::::2;::::0;;::::2;;::::0;;75016:11:::2;:40:::0;;;;::::2;::::0;;;::::2;::::0;;;::::2;::::0;;75116:6:::2;75098:15;:24:::0;75159:2:::2;75133:23:::0;:28;75214:4:::2;75172:39:::0;:46;;;:17:::2;75229:46:::0;75286:21:::2;:19;:21::i;:::-;32139:14:::0;32135:102;;;32186:5;32170:21;;-1:-1:-1;;32170:21:0;;;32211:14;;-1:-1:-1;24506:36:1;;32211:14:0;;24494:2:1;24479:18;32211:14:0;;;;;;;32135:102;31746:498;74477:855;;;:::o;75551:343::-;75652:7;52256:19;:17;:19::i;:::-;48523:21:::1;:19;:21::i;:::-;-1:-1:-1::0;;;;;75680:23:0;::::2;75672:52;;;::::0;-1:-1:-1;;;75672:52:0;;11696:2:1;75672:52:0::2;::::0;::::2;11678:21:1::0;11735:2;11715:18;;;11708:30;-1:-1:-1;;;11754:18:1;;;11747:46;11810:18;;75672:52:0::2;11494:340:1::0;75672:52:0::2;75735:16;75754:34;75763:9;75774:10;75786:1;75754:8;:34::i;:::-;75735:53;;75839:9;-1:-1:-1::0;;;;;75804:56:0::2;75827:10;-1:-1:-1::0;;;;;75804:56:0::2;;75850:9;75804:56;;;;422:25:1::0;;410:2;395:18;;276:177;75804:56:0::2;;;;;;;;75878:8:::0;-1:-1:-1;48567:20:0::1;47784:1:::0;49087:7;:22;48904:213;76747:141;76819:7;52256:19;:17;:19::i;:::-;48523:21:::1;:19;:21::i;:::-;76846:34:::2;76855:9;76866:10;76878:1;76846:8;:34::i;:::-;76839:41;;48567:20:::1;47784:1:::0;49087:7;:22;48904:213;77082:265;77207:7;52256:19;:17;:19::i;:::-;48523:21:::1;:19;:21::i;:::-;-1:-1:-1::0;;;;;77235:26:0;::::2;77227:58;;;;-1:-1:-1::0;;;77227:58:0::2;;;;;;;:::i;:::-;77303:36;77312:9;77323:12;77337:1;77303:8;:36::i;:::-;77296:43;;48567:20:::1;47784:1:::0;49087:7;:22;48904:213;97468:283;48523:21;:19;:21::i;:::-;97583:11:::1;::::0;-1:-1:-1;;;;;97583:11:0::1;97561:10;:34;97553:81;;;;-1:-1:-1::0;;;97553:81:0::1;;;;;;;:::i;:::-;97650:9;97645:99;97665:20:::0;;::::1;97645:99;;;97707:25;97719:9;;97729:1;97719:12;;;;;;;:::i;:::-;;;;;;;97707:11;:25::i;:::-;97687:3:::0;::::1;::::0;::::1;:::i;:::-;;;;97645:99;;88997:194:::0;89047:7;89068:22;89102:20;:18;:20::i;:::-;89067:55;;;;;;89140:43;71910:4;89168:14;89140:16;:43::i;:::-;89133:50;;;88997:194;:::o;87647:1201::-;87799:7;52256:19;:17;:19::i;:::-;48523:21:::1;:19;:21::i;:::-;74122:17:::2;::::0;-1:-1:-1;;;;;74122:17:0::2;74100:10;:40;74092:64;;;;-1:-1:-1::0;;;74092:64:0::2;;;;;;;:::i;:::-;87828:19:::3;::::0;-1:-1:-1;;;87828:19:0;::::3;;;87827:20;87819:53;;;;-1:-1:-1::0;;;87819:53:0::3;;;;;;;:::i;:::-;87891:9;87904:1;87891:14:::0;87883:57:::3;;;;-1:-1:-1::0;;;87883:57:0::3;;;;;;;:::i;:::-;87959:7;::::0;:24:::3;::::0;-1:-1:-1;;;87959:24:0;;-1:-1:-1;;;;;8853:32:1;;;87959:24:0::3;::::0;::::3;8835:51:1::0;87987:9:0;;87959:7:::3;::::0;:17:::3;::::0;8808:18:1;;87959:24:0::3;;;;;;;;;;;;;;;;;::::0;::::3;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:37;;87951:83;;;;-1:-1:-1::0;;;87951:83:0::3;;;;;;;:::i;:::-;88047:16;:14;:16::i;:::-;88101:5;:20:::0;88076:22:::3;88162:43;88179:9:::0;88101:20;88162:16:::3;:43::i;:::-;88132:73;;88224:19;88247:1;88224:24:::0;88216:57:::3;;;;-1:-1:-1::0;;;88216:57:0::3;;;;;;;:::i;:::-;88315:14;88292:19;:37;;88284:85;;;;-1:-1:-1::0;;;88284:85:0::3;;;;;;;:::i;:::-;88411:20;;88388:19;:43;;88380:94;;;::::0;-1:-1:-1;;;88380:94:0;;24755:2:1;88380:94:0::3;::::0;::::3;24737:21:1::0;24794:2;24774:18;;;24767:30;24833:34;24813:18;;;24806:62;-1:-1:-1;;;24884:18:1;;;24877:36;24930:19;;88380:94:0::3;24553:402:1::0;88380:94:0::3;88536:19;88512:5;:20;;;:43;;;;;;;:::i;:::-;;;;;;;;88590:19;88566:20;;:43;;;;;;;:::i;:::-;::::0;;;-1:-1:-1;;88655:7:0::3;::::0;:30:::3;::::0;-1:-1:-1;;;88655:30:0;;-1:-1:-1;;;;;15563:32:1;;;88655:30:0::3;::::0;::::3;15545:51:1::0;15612:18;;;15605:34;;;88655:7:0;;::::3;::::0;:12:::3;::::0;15518:18:1;;88655:30:0::3;;;;;;;;;;;;;;;;;;::::0;::::3;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;88647:54;;;;-1:-1:-1::0;;;88647:54:0::3;;;;;;;:::i;:::-;88714:11;:9;:11::i;:::-;88743:60;::::0;;8007:25:1;;;8063:2;8048:18;;8041:34;;;-1:-1:-1;8091:18:1;;;8084:34;88743:60:0;;-1:-1:-1;;;;;88743:60:0;::::3;::::0;::::3;::::0;;;;;7995:2:1;88743:60:0;;::::3;88821:19:::0;-1:-1:-1;;48567:20:0::1;47784:1:::0;49087:7;:22;48904:213;110550:569;-1:-1:-1;;;;;;;;;;;73937:20:0;73947:9;73937;:20::i;:::-;110697:1:::1;110680:14;:18;:55;;;;;71861:5;110702:14;:33;;110680:55;110672:92;;;::::0;-1:-1:-1;;;110672:92:0;;25494:2:1;110672:92:0::1;::::0;::::1;25476:21:1::0;25533:2;25513:18;;;25506:30;25572:26;25552:18;;;25545:54;25616:18;;110672:92:0::1;25292:348:1::0;110672:92:0::1;110800:1;110783:14;:18;:55;;;;;71861:5;110805:14;:33;;110783:55;110775:92;;;::::0;-1:-1:-1;;;110775:92:0;;25847:2:1;110775:92:0::1;::::0;::::1;25829:21:1::0;25886:2;25866:18;;;25859:30;25925:26;25905:18;;;25898:54;25969:18;;110775:92:0::1;25645:348:1::0;110775:92:0::1;110913:17;110941:43:::0;;;110995:26;:43;;;111056:55:::1;::::0;111024:14;;110970;;111056:55:::1;::::0;110880:30:::1;::::0;111056:55:::1;110661:458;110550:569:::0;;;:::o;85024:1411::-;85113:4;52256:19;:17;:19::i;:::-;48523:21:::1;:19;:21::i;:::-;85139:19:::2;::::0;-1:-1:-1;;;85139:19:0;::::2;;;85138:20;85130:53;;;;-1:-1:-1::0;;;85130:53:0::2;;;;;;;:::i;:::-;85202:9;85215:1;85202:14:::0;85194:57:::2;;;;-1:-1:-1::0;;;85194:57:0::2;;;;;;;:::i;:::-;85270:7;::::0;:29:::2;::::0;-1:-1:-1;;;85270:29:0;;85288:10:::2;85270:29;::::0;::::2;8835:51:1::0;85303:9:0;;-1:-1:-1;;;;;85270:7:0::2;::::0;:17:::2;::::0;8808:18:1;;85270:29:0::2;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:42;;85262:88;;;;-1:-1:-1::0;;;85262:88:0::2;;;;;;;:::i;:::-;85363:16;:14;:16::i;:::-;85392:27;85422:49;85439:9;85450:5;:20;;;85422:16;:49::i;:::-;85392:79:::0;-1:-1:-1;85490:24:0;;;::::2;::::0;:71:::2;;;85542:19;85518:20;:18;:20::i;:::-;:43;;85490:71;85482:104;;;;-1:-1:-1::0;;;85482:104:0::2;;;;;;;:::i;:::-;85623:19;85599:5;:20;;;:43;;;;;;;:::i;:::-;::::0;;;-1:-1:-1;;85716:23:0;;85679:18:::2;::::0;85716:28;85712:188:::2;;85775:23:::0;;71861:5:::2;::::0;85775:45:::2;::::0;85801:19;;85775:45:::2;:::i;:::-;85774:65;;;;:::i;:::-;85761:78;;85878:10;85854:5;:20;;;:34;;;;;;;:::i;:::-;::::0;;;-1:-1:-1;;85712:188:0::2;85920:7;::::0;:35:::2;::::0;-1:-1:-1;;;85920:35:0;;85933:10:::2;85920:35;::::0;::::2;15545:51:1::0;15612:18;;;15605:34;;;-1:-1:-1;;;;;85920:7:0;;::::2;::::0;:12:::2;::::0;15518:18:1;;85920:35:0::2;;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;85912:59;;;;-1:-1:-1::0;;;85912:59:0::2;;;;;;;:::i;:::-;85984:33;86020:32;86042:10:::0;86020:19;:32:::2;:::i;:::-;85984:68;;86077:25;86063:10;;:39;;;;;;;:::i;:::-;::::0;;;-1:-1:-1;;86134:53:0::2;::::0;86116:12:::2;::::0;86134:10:::2;::::0;86157:25;;86116:12;86134:53;86116:12;86134:53;86157:25;86134:10;:53:::2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;86115:72;;;86206:7;86198:52;;;::::0;-1:-1:-1;;;86198:52:0;;19898:2:1;86198:52:0::2;::::0;::::2;19880:21:1::0;;;19917:18;;;19910:30;19976:34;19956:18;;;19949:62;20028:18;;86198:52:0::2;19696:356:1::0;86198:52:0::2;86263:22;:20;:22::i;:::-;86296:11;:9;:11::i;:::-;86325:80;::::0;;8007:25:1;;;8063:2;8048:18;;8041:34;;;8091:18;;;8084:34;;;86344:10:0::2;::::0;86325:80:::2;::::0;7995:2:1;7980:18;86325:80:0::2;;;;;;;86423:4;86416:11;;;;;;48567:20:::1;47784:1:::0;49087:7;:22;48904:213;90002:388;90096:7;90116:20;90139:7;;;;;;;;;-1:-1:-1;;;;;90139:7:0;-1:-1:-1;;;;;90139:19:0;;:21;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;90116:44;;90191:16;90175:12;:32;;:53;;;;-1:-1:-1;90211:17:0;;;90175:53;:78;;;;-1:-1:-1;90232:21:0;;;90175:78;90171:212;;;90310:12;90278:28;90290:16;90278:9;:28;:::i;:::-;90277:45;;;;:::i;:::-;90270:52;;;;;90171:212;90362:9;90355:16;;;;;84132:695;84340:22;;;;84441:23;;84274:14;;;;84441:28;;84437:219;;84486:20;84509:60;84526:11;:20;;;84548:5;:20;;;84509:16;:60::i;:::-;84626:18;;;;84486:83;;-1:-1:-1;84598:24:0;71910:4;84486:83;84598:24;:::i;:::-;84597:47;;;;:::i;:::-;84584:60;;84471:185;84437:219;71910:4;84677:10;:22;:81;;84719:13;;71910:4;;84719:26;;84735:10;;84719:26;:::i;:::-;84718:40;;;;:::i;:::-;84677:81;;;84702:13;;84677:81;84668:90;;71861:5;84790:6;:10;;;84781:6;:19;;;;:::i;:::-;84780:39;;;;:::i;:::-;84769:50;;84308:519;84132:695;;;;;:::o;83048:781::-;83140:19;;83119:4;;-1:-1:-1;;;83140:19:0;;;;83136:64;;;-1:-1:-1;83183:5:0;;83048:781;-1:-1:-1;83048:781:0:o;83136:64::-;83214:13;;;:18;83210:63;;-1:-1:-1;83256:5:0;;83048:781;-1:-1:-1;83048:781:0:o;83210:63::-;83337:14;;;;;83283:31;83317:35;;;:19;:35;;;;;;;;;83283:69;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;83367:27;;:71;;-1:-1:-1;83398:22:0;;83423:15;-1:-1:-1;83367:71:0;83363:116;;;-1:-1:-1;83462:5:0;;83048:781;-1:-1:-1;;83048:781:0:o;83363:116::-;83514:15;83493:6;:18;;;:36;83489:81;;;-1:-1:-1;83553:5:0;;83048:781;-1:-1:-1;;83048:781:0:o;83489:81::-;83581:14;83601:41;83623:6;83631:10;83601:21;:41::i;:::-;83580:62;;;83670:6;83657:10;;:19;83653:64;;;-1:-1:-1;83700:5:0;;83048:781;-1:-1:-1;;;83048:781:0:o;83653:64::-;83731:19;;:28;-1:-1:-1;83727:73:0;;;-1:-1:-1;83783:5:0;;83048:781;-1:-1:-1;;;83048:781:0:o;83727:73::-;-1:-1:-1;83817:4:0;;83048:781;-1:-1:-1;;;83048:781:0:o;103026:1686::-;103331:5;:20;103500:11;;:24;;;-1:-1:-1;;;103500:24:0;;;;103120:22;;;;;;;;;;-1:-1:-1;;;;;103500:11:0;;;;:22;;:24;;;;;;;;;;;;;;;:11;:24;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;103607:21;;103583;;103561:19;;103476:48;;-1:-1:-1;103535:23:0;;103561:43;;103583:21;103561:43;:::i;:::-;:67;;;;:::i;:::-;103535:93;;103661:15;103645:13;:31;103641:426;;;103703:31;103719:15;103703:13;:31;:::i;:::-;103693:41;-1:-1:-1;103749:25:0;103693:41;103749:25;;:::i;:::-;;;103641:426;;;103812:15;103796:13;:31;103792:275;;;103856:31;103874:13;103856:15;:31;:::i;:::-;103980:23;;103844:43;;-1:-1:-1;103902:26:0;;103963:40;;:14;:40;:::i;:::-;103932:26;103944:14;103932:9;:26;:::i;:::-;103931:73;;;;:::i;:::-;103902:102;-1:-1:-1;104019:36:0;103902:102;104019:36;;:::i;:::-;;;103829:238;103792:275;104160:17;;104124:25;;-1:-1:-1;;;;;104160:17:0;104152:77;;104228:1;104152:77;;;104195:17;;;;;;;;;-1:-1:-1;;;;;104195:17:0;-1:-1:-1;;;;;104195:28:0;;:30;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;104276:20;;104124:105;;-1:-1:-1;104313:45:0;;;104309:396;;;104395:45;104415:25;104395:17;:45;:::i;:::-;104375:65;-1:-1:-1;104455:35:0;104375:65;104455:35;;:::i;:::-;;;104309:396;;;104532:25;104512:17;:45;104508:197;;;104596:45;104624:17;104596:25;:45;:::i;:::-;104574:67;-1:-1:-1;104656:37:0;104574:67;104656:37;;:::i;:::-;;;104508:197;103303:1409;;;;103026:1686;;;;;:::o;91069:120::-;91162:19;;91149:10;;91122:7;;91149:32;;;:::i;:::-;91142:39;;91069:120;:::o;90622:398::-;90718:7;90738:20;90761:7;;;;;;;;;-1:-1:-1;;;;;90761:7:0;-1:-1:-1;;;;;90761:19:0;;:21;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;90738:44;;90813:16;90797:12;:32;;:57;;;;-1:-1:-1;90833:21:0;;;90797:57;:78;;;;-1:-1:-1;90858:17:0;;;90797:78;90793:220;;;90932:16;90900:28;90916:12;90900:13;:28;:::i;52810:108::-;52722:7;;;;52880:9;52872:38;;;;-1:-1:-1;;;52872:38:0;;26200:2:1;52872:38:0;;;26182:21:1;26239:2;26219:18;;;26212:30;-1:-1:-1;;;26258:18:1;;;26251:46;26314:18;;52872:38:0;25998:340:1;48603:293:0;47828:1;48737:7;;:19;48729:63;;;;-1:-1:-1;;;48729:63:0;;26545:2:1;48729:63:0;;;26527:21:1;26584:2;26564:18;;;26557:30;26623:33;26603:18;;;26596:61;26674:18;;48729:63:0;26343:355:1;48729:63:0;47828:1;48870:7;:18;48603:293::o;77664:871::-;77810:7;77838:14;77856:1;77838:19;77830:54;;;;-1:-1:-1;;;77830:54:0;;22726:2:1;77830:54:0;;;22708:21:1;22765:2;22745:18;;;22738:30;-1:-1:-1;;;22784:18:1;;;22777:52;22846:18;;77830:54:0;22524:346:1;77830:54:0;77895:16;:14;:16::i;:::-;77924:18;71861:5;77964:14;77946:4;:15;;;:32;;;;:::i;:::-;77945:52;;;;:::i;:::-;77924:73;-1:-1:-1;78008:19:0;78030:27;77924:73;78030:14;:27;:::i;:::-;78008:49;;78068:20;78091:49;78106:11;78119:5;:20;;;78091:14;:49::i;:::-;78068:72;;78177:14;78153:5;:20;;;:38;;;;;;;:::i;:::-;;;;-1:-1:-1;;78206:25:0;;78202:75;;78257:20;78233;;:44;;;;;;;:::i;:::-;;;;-1:-1:-1;;78202:75:0;78298:7;;:40;;-1:-1:-1;;;78298:40:0;;-1:-1:-1;;;;;15563:32:1;;;78298:40:0;;;15545:51:1;15612:18;;;15605:34;;;78298:7:0;;;;:12;;15518:18:1;;78298:40:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;78290:67;;;;-1:-1:-1;;;78290:67:0;;26905:2:1;78290:67:0;;;26887:21:1;26944:2;26924:18;;;26917:30;-1:-1:-1;;;26963:18:1;;;26956:44;27017:18;;78290:67:0;26703:338:1;78290:67:0;78370:22;:20;:22::i;:::-;78403:11;:9;:11::i;:::-;78432:63;;;8007:25:1;;;8063:2;8048:18;;8041:34;;;8091:18;;;8084:34;;;-1:-1:-1;;;;;78432:63:0;;;;;7995:2:1;7980:18;78432:63:0;;;;;;;78515:12;77664:871;-1:-1:-1;;;;;;77664:871:0:o;48904:213::-;47784:1;49087:7;:22;48904:213::o;105404:866::-;105499:21;;105535:20;;105531:178;;105572:14;105589:30;105594:7;105603:15;105589:4;:30::i;:::-;105572:47;;105659:6;105634:5;:21;;;:31;;;;;;;:::i;:::-;;;;-1:-1:-1;105680:17:0;;-1:-1:-1;105691:6:0;105680:17;;:::i;:::-;;;105557:152;105531:178;105747:21;;105783:20;;;;;:36;;-1:-1:-1;105807:12:0;;;105783:36;105779:197;;;105836:15;105854:30;105859:7;105868:15;105854:4;:30::i;:::-;105836:48;;105924:7;105899:5;:21;;;:32;;;;;;;:::i;:::-;;;;-1:-1:-1;105946:18:0;;-1:-1:-1;105957:7:0;105946:18;;:::i;:::-;;;105821:155;105779:197;106012:19;;106046:18;;;;;:34;;-1:-1:-1;106068:12:0;;;106046:34;106042:188;;;106097:14;106114:28;106119:7;106128:13;106114:4;:28::i;:::-;106097:45;;106180:6;106157:5;:19;;;:29;;;;;;;:::i;:::-;;;;-1:-1:-1;106201:17:0;;-1:-1:-1;106212:6:0;106201:17;;:::i;:::-;;;106082:148;106042:188;106249:12;;106242:20;;;;:::i;100709:2227::-;100881:10;;100783:21;;100833:9;;100881:20;;100833:9;;100881:20;:::i;:::-;100859:17;:43;100855:397;;100933:7;100919:10;;:21;;;;;;;:::i;:::-;;;;-1:-1:-1;100855:397:0;;-1:-1:-1;100855:397:0;;100982:10;;100962:17;:30;100958:294;;;101009:19;101065:7;101052:10;;:20;;;;:::i;:::-;101031:42;;:17;:42;:::i;:::-;101088:10;:30;;;101009:64;-1:-1:-1;101133:27:0;101009:64;101133:14;:27::i;:::-;101175:21;:19;:21::i;:::-;101216:24;;422:25:1;;;101216:24:0;;410:2:1;395:18;101216:24:0;;;;;;;100994:258;100958:294;101294:15;101324:17;101356:25;101396:27;101437:20;:18;:20::i;:::-;101493:5;:20;101264:193;;-1:-1:-1;101264:193:0;;-1:-1:-1;101264:193:0;-1:-1:-1;101264:193:0;-1:-1:-1;101493:20:0;-1:-1:-1;101530:12:0;;101526:936;;101559:23;101574:7;101559:14;:23::i;:::-;101620:7;101597:5;:19;;;:30;;;;;;;:::i;:::-;;;;-1:-1:-1;101526:936:0;;-1:-1:-1;101526:936:0;;101708:14;;101704:758;;101905:23;;101827:26;;101888:40;;:14;:40;:::i;:::-;101857:26;101869:14;101857:9;:26;:::i;:::-;101856:73;;;;:::i;:::-;101827:102;-1:-1:-1;101944:36:0;101827:102;101944:36;;:::i;:::-;101995:5;:37;;;102095:23;;101944:36;;-1:-1:-1;101995:20:0;;102095:28;102091:241;;102164:30;102176:18;102164:9;:30;:::i;:::-;102144:50;;102236:17;102213:5;:19;;;:40;;;;;;;:::i;:::-;;;;-1:-1:-1;;102272:23:0;:44;;102299:17;;102272:23;;;:44;;102299:17;;102272:44;:::i;:::-;;;;-1:-1:-1;;102091:241:0;102351:51;;102384:17;;102364:18;;102351:51;;;;;102417:33;102440:9;102417:22;:33::i;:::-;101724:738;;101704:758;102523:22;;102519:410;;102562:33;102577:17;102562:14;:33::i;:::-;102634:17;102610:20;;:41;;;;;;;:::i;:::-;;;;-1:-1:-1;102519:410:0;;-1:-1:-1;102519:410:0;;102673:24;;102669:260;;102714:37;102732:19;102714:37;;:::i;:::-;102766:5;:37;;;102818:20;:43;;102714:37;;-1:-1:-1;102842:19:0;;102766:20;;102818:43;;102842:19;;102818:43;:::i;:::-;;;;-1:-1:-1;;102881:36:0;;102915:1;;102894:19;;102881:36;;102915:1;;102881:36;102669:260;100744:2192;;;;;;;100709:2227::o;99619:1027::-;99697:21;;99789;;:25;99785:378;;99916:19;;99892:21;;99870:19;;99831:13;;99847:143;;99916:19;;99870:43;;99892:21;99870:43;:::i;:::-;:65;;;;:::i;:::-;99954:21;;99847:4;:143::i;:::-;99831:159;-1:-1:-1;100005:24:0;99831:159;100005:24;;:::i;:::-;100044:21;:39;;;100122:21;;100005:24;;-1:-1:-1;100122:29:0;;100146:5;;100122:29;:::i;:::-;100098:21;:53;-1:-1:-1;99785:378:0;100516:19;;100537;;100492:146;;100511:46;;:4;:46::i;:::-;100577:19;;100572:55;;100577:37;;100599:15;;100577:37;:::i;:::-;100616:10;;100572:4;:55::i;:::-;100492:4;:146::i;:::-;100470:19;:168;-1:-1:-1;99619:1027:0:o;107713:581::-;107779:5;:20;107818:18;107810:65;;;;-1:-1:-1;;;107810:65:0;;27380:2:1;107810:65:0;;;27362:21:1;27419:2;27399:18;;;27392:30;27458:34;27438:18;;;27431:62;-1:-1:-1;;;27509:18:1;;;27502:32;27551:19;;107810:65:0;27178:398:1;107810:65:0;107923:19;;107886:16;;107946:4;;107906:36;;:14;:36;:::i;:::-;107905:45;;;;:::i;:::-;108119:20;;108082:21;;108045;;108010:19;;107984:10;;107886:64;;-1:-1:-1;107961:19:0;;108143:4;;108119:20;108082:21;108045;107984:45;;;:::i;:::-;:82;;;;:::i;:::-;:119;;;;:::i;:::-;:155;;;;:::i;:::-;107983:164;;;;:::i;:::-;107961:186;-1:-1:-1;108181:12:0;:8;108192:1;108181:12;:::i;:::-;108166:11;:27;;:58;;;;-1:-1:-1;108209:15:0;:11;108223:1;108209:15;:::i;:::-;108197:8;:27;;108166:58;108158:90;;;;-1:-1:-1;;;108158:90:0;;27783:2:1;108158:90:0;;;27765:21:1;27822:2;27802:18;;;27795:30;-1:-1:-1;;;27841:18:1;;;27834:49;27900:18;;108158:90:0;27581:343:1;108158:90:0;108261:25;:23;:25::i;:::-;107743:551;;;107713:581::o;112474:139::-;112545:11;;:44;;-1:-1:-1;;;112545:44:0;;;;;12416:25:1;;;112578:10:0;12457:18:1;;;12450:60;-1:-1:-1;;;;;112545:11:0;;;;:21;;12389:18:1;;112545:44:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;112537:68;;;;-1:-1:-1;;;112537:68:0;;;;;;;:::i;59826:153::-;-1:-1:-1;;;;;;;;;;;59906:65:0;-1:-1:-1;;;;;59906:65:0;;59826:153::o;113215:189::-;71389:35;73937:20;73947:9;73937;:20::i;:::-;113381:1:::1;113348:18;-1:-1:-1::0;;;;;113348:30:0::1;;:34;113340:56;;;::::0;-1:-1:-1;;;113340:56:0;;28131:2:1;113340:56:0::1;::::0;::::1;28113:21:1::0;28170:1;28150:18;;;28143:29;-1:-1:-1;;;28188:18:1;;;28181:39;28237:18;;113340:56:0::1;27929:332:1::0;60472:155:0;60539:37;60558:17;60539:18;:37::i;:::-;60592:27;;-1:-1:-1;;;;;60592:27:0;;;;;;;;60472:155;:::o;52995:108::-;52722:7;;;;53054:41;;;;-1:-1:-1;;;53054:41:0;;28468:2:1;53054:41:0;;;28450:21:1;28507:2;28487:18;;;28480:30;-1:-1:-1;;;28526:18:1;;;28519:50;28586:18;;53054:41:0;28266:344:1;53506:120:0;52515:16;:14;:16::i;:::-;53565:7:::1;:15:::0;;-1:-1:-1;;53565:15:0::1;::::0;;53596:22:::1;50354:10:::0;53605:12:::1;53596:22;::::0;-1:-1:-1;;;;;8853:32:1;;;8835:51;;8823:2;8808:18;53596:22:0::1;;;;;;;53506:120::o:0;61244:992::-;59328:66;61698:59;;;61694:535;;;61774:37;61793:17;61774:18;:37::i;61694:535::-;61877:17;-1:-1:-1;;;;;61848:61:0;;:63;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;61848:63:0;;;;;;;;-1:-1:-1;;61848:63:0;;;;;;;;;;;;:::i;:::-;;;61844:306;;62078:56;;-1:-1:-1;;;62078:56:0;;29006:2:1;62078:56:0;;;28988:21:1;29045:2;29025:18;;;29018:30;29084:34;29064:18;;;29057:62;-1:-1:-1;;;29135:18:1;;;29128:44;29189:19;;62078:56:0;28804:410:1;61844:306:0;-1:-1:-1;;;;;;;;;;;61962:28:0;;61954:82;;;;-1:-1:-1;;;61954:82:0;;29421:2:1;61954:82:0;;;29403:21:1;29460:2;29440:18;;;29433:30;29499:34;29479:18;;;29472:62;-1:-1:-1;;;29550:18:1;;;29543:39;29599:19;;61954:82:0;29219:405:1;61954:82:0;61912:140;62164:53;62182:17;62201:4;62207:9;62164:17;:53::i;81836:1029::-;-1:-1:-1;;;;;81961:21:0;;81903:7;81961:21;;;:14;:21;;;;;;;;:31;;;;;;;;81932:60;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;81903:7;;82011:17;;82003:43;;;;-1:-1:-1;;;82003:43:0;;29831:2:1;82003:43:0;;;29813:21:1;29870:2;29850:18;;;29843:30;-1:-1:-1;;;29889:18:1;;;29882:43;29942:18;;82003:43:0;29629:337:1;82003:43:0;82113:13;;;;;82059:31;82093:34;;;:19;:34;;;;;;;;;82059:68;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;82146:27;;;;:72;;-1:-1:-1;82177:22:0;;82203:15;-1:-1:-1;82177:41:0;82146:72;82138:107;;;;-1:-1:-1;;;82138:107:0;;30173:2:1;82138:107:0;;;30155:21:1;30212:2;30192:18;;;30185:30;-1:-1:-1;;;30231:18:1;;;30224:52;30293:18;;82138:107:0;29971:346:1;82138:107:0;82259:14;82275:16;82295:40;82317:5;82324:10;82295:21;:40::i;:::-;82258:77;;;;82375:15;82354:5;:17;;;:36;;:60;;;;;82408:6;82394:10;;:20;;82354:60;82346:95;;;;-1:-1:-1;;;82346:95:0;;30524:2:1;82346:95:0;;;30506:21:1;30563:2;30543:18;;;30536:30;-1:-1:-1;;;30582:18:1;;;30575:52;30644:18;;82346:95:0;30322:346:1;82346:95:0;82460:19;;:29;-1:-1:-1;82460:29:0;82452:76;;;;-1:-1:-1;;;82452:76:0;;30875:2:1;82452:76:0;;;30857:21:1;30914:2;30894:18;;;30887:30;30953:34;30933:18;;;30926:62;-1:-1:-1;;;31004:18:1;;;30997:32;31046:19;;82452:76:0;30673:398:1;82452:76:0;82570:12;;82544:57;;;4041:25:1;;;4097:2;4082:18;;4075:34;;;;4125:18;;4118:34;;;4183:2;4168:18;;4161:34;;;-1:-1:-1;;;;;82544:57:0;;;;;4028:3:1;4013:19;82544:57:0;;;;;;;-1:-1:-1;;;;;82642:21:0;;82683:1;82642:21;;;:14;:21;;;;;;;;:31;;;;;;;;:42;;;82695:19;:29;;82718:6;;82683:1;82695:29;;82718:6;;82695:29;:::i;:::-;;;;-1:-1:-1;;82735:19:0;:29;;82758:6;;82735:19;;;:29;;82758:6;;82735:29;:::i;:::-;;;;-1:-1:-1;82790:17:0;;-1:-1:-1;82799:8:0;82790:6;:17;:::i;:::-;82775:10;;:33;;;;;;;:::i;:::-;;;;-1:-1:-1;82829:17:0;;-1:-1:-1;82838:8:0;82829:6;:17;:::i;:::-;82821:36;82848:8;;-1:-1:-1;81836:1029:0;-1:-1:-1;;;;;;81836:1029:0:o;111742:113::-;111803:7;111835:2;111830;:7;:17;;111845:2;111830:17;;;-1:-1:-1;111840:2:0;111823:24;-1:-1:-1;111742:113:0:o;97880:1366::-;97939:31;97973:29;;;:19;:29;;;;;;;;;97939:63;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;98021:27;98013:65;;;;-1:-1:-1;;;98013:65:0;;31278:2:1;98013:65:0;;;31260:21:1;31317:2;31297:18;;;31290:30;31356:27;31336:18;;;31329:55;31401:18;;98013:65:0;31076:349:1;98013:65:0;98091:29;;;;:19;:29;;;;;;;98135:15;98091:59;;98263:17;;;:22;98259:886;;98302:20;98325:59;98342:10;:19;;;98363:5;:20;;;98325:16;:59::i;:::-;98441:17;;;;98302:82;;-1:-1:-1;98413:24:0;71910:4;98302:82;98413:24;:::i;:::-;98412:46;;;;:::i;:::-;98473:29;;;;:19;:29;;;;;;;;:40;;:53;;;98572:17;;;98399:59;;-1:-1:-1;98556:33:0;;;:68;;98612:12;98556:68;;;98592:10;:17;;;98556:68;98658:23;;98541:83;;-1:-1:-1;98643:38:0;;98639:495;;;98874:23;;98843:13;;98859:38;;:12;:38;:::i;:::-;98843:54;;98939:5;98916;:19;;;:28;;;;;;;:::i;:::-;;;;-1:-1:-1;;98963:5:0;:29;;98987:5;;98963;:20;;:29;;98987:5;;98963:29;:::i;:::-;;;;-1:-1:-1;;99037:1:0;99011:23;:27;-1:-1:-1;98639:495:0;;;99106:12;99079:5;:23;;;:39;;;;;;;:::i;:::-;;;;-1:-1:-1;;98639:495:0;98287:858;98259:886;99177:8;99162:76;99187:10;:17;;;99206:10;:19;;;99227:10;99162:76;;;;;;;8007:25:1;;;8063:2;8048:18;;8041:34;;;;8106:2;8091:18;;8084:34;7995:2;7980:18;;7805:319;99162:76:0;;;;;;;;97928:1318;;97880:1366;:::o;53247:118::-;52256:19;:17;:19::i;:::-;53307:7:::1;:14:::0;;-1:-1:-1;;53307:14:0::1;53317:4;53307:14;::::0;;53337:20:::1;53344:12;50354:10:::0;;50274:98;51821:99;33900:13;;;;;;;33892:69;;;;-1:-1:-1;;;33892:69:0;;;;;;;:::i;:::-;51885:27:::1;:25;:27::i;47870:113::-:0;33900:13;;;;;;;33892:69;;;;-1:-1:-1;;;33892:69:0;;;;;;;:::i;:::-;47941:34:::1;:32;:34::i;66955:68::-:0;33900:13;;;;;;;33892:69;;;;-1:-1:-1;;;33892:69:0;;;;;;;:::i;111919:113::-;111980:7;112012:2;112007;:7;:17;;112022:2;112007:17;;;-1:-1:-1;112017:2:0;;111919:113;-1:-1:-1;111919:113:0:o;106627:974::-;106682:19;106704:47;106721:7;106730:5;:20;;;106704:16;:47::i;:::-;106780:16;;106682:69;;-1:-1:-1;106869:22:0;;;106865:35;;106893:7;;106627:974::o;106865:35::-;106912:24;106951;107010:7;106996:11;:21;106992:460;;;107083:21;107093:11;107083:7;:21;:::i;:::-;107149:17;:39;107064:40;;-1:-1:-1;71861:5:0;;107139:49;;:7;:49;:::i;:::-;107138:69;;;;:::i;:::-;107119:88;;106992:460;;;107243:7;107229:11;:21;107225:227;;;107316:21;107330:7;107316:11;:21;:::i;:::-;107382:39;;107297:40;;-1:-1:-1;71861:5:0;;107372:49;;:7;:49;:::i;:::-;107371:69;;;;:::i;:::-;107352:88;;107225:227;107487:16;107468;:35;107464:130;;;107520:8;:6;:8::i;:::-;107464:130;;;107561:21;:19;:21::i;60075:284::-;-1:-1:-1;;;;;9089:19:0;;;60149:106;;;;-1:-1:-1;;;60149:106:0;;32044:2:1;60149:106:0;;;32026:21:1;32083:2;32063:18;;;32056:30;32122:34;32102:18;;;32095:62;-1:-1:-1;;;32173:18:1;;;32166:43;32226:19;;60149:106:0;31842:409:1;60149:106:0;-1:-1:-1;;;;;;;;;;;60266:85:0;;-1:-1:-1;;;;;;60266:85:0;-1:-1:-1;;;;;60266:85:0;;;;;;;;;;60075:284::o;60768:297::-;60911:29;60922:17;60911:10;:29::i;:::-;60969:1;60955:4;:11;:15;:28;;;;60974:9;60955:28;60951:107;;;61000:46;61022:17;61041:4;61000:21;:46::i;51928:97::-;33900:13;;;;;;;33892:69;;;;-1:-1:-1;;;33892:69:0;;;;;;;:::i;:::-;52002:7:::1;:15:::0;;-1:-1:-1;;52002:15:0::1;::::0;;51928:97::o;47991:111::-;33900:13;;;;;;;33892:69;;;;-1:-1:-1;;;33892:69:0;;;;;;;:::i;65241:461::-;65324:12;-1:-1:-1;;;;;9089:19:0;;;65349:88;;;;-1:-1:-1;;;65349:88:0;;32458:2:1;65349:88:0;;;32440:21:1;32497:2;32477:18;;;32470:30;32536:34;32516:18;;;32509:62;-1:-1:-1;;;32587:18:1;;;32580:36;32633:19;;65349:88:0;32256:402:1;65349:88:0;65511:12;65525:23;65552:6;-1:-1:-1;;;;;65552:19:0;65572:4;65552:25;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;65510:67;;;;65595:99;65631:7;65640:10;65595:99;;;;;;;;;;;;;;;;;:35;:99::i;:::-;65588:106;65241:461;-1:-1:-1;;;;;65241:461:0:o;15204:305::-;15354:12;15383:7;15379:123;;;-1:-1:-1;15414:10:0;15407:17;;15379:123;15457:33;15465:10;15477:12;15678:17;;:21;15674:388;;15910:10;15904:17;15967:15;15954:10;15950:2;15946:19;15939:44;15674:388;16037:12;16030:20;;-1:-1:-1;;;16030:20:0;;;;;;;;:::i;14:127:1:-;75:10;70:3;66:20;63:1;56:31;106:4;103:1;96:15;130:4;127:1;120:15;146:125;211:9;;;232:10;;;229:36;;;245:18;;:::i;458:131::-;-1:-1:-1;;;;;533:31:1;;523:42;;513:70;;579:1;576;569:12;594:315;662:6;670;723:2;711:9;702:7;698:23;694:32;691:52;;;739:1;736;729:12;691:52;778:9;765:23;797:31;822:5;797:31;:::i;:::-;847:5;899:2;884:18;;;;871:32;;-1:-1:-1;;;594:315:1:o;914:1186::-;1217:2;1269:21;;;1339:13;;1242:18;;;1361:22;;;1188:4;;1217:2;1402:3;;1421:18;;;;1458:4;1485:15;;;1188:4;1528:458;1542:6;1539:1;1536:13;1528:458;;;1601:13;;1639:9;;1627:22;;1689:11;;;1683:18;1669:12;;;1662:40;1725:4;1769:11;;;1763:18;1749:12;;;1742:40;1822:11;;;1816:18;1802:12;;;1795:40;1889:11;;1883:18;1876:26;1869:34;1855:12;;;1848:56;1933:4;1924:14;;;;1961:15;;;;1564:1;1557:9;1528:458;;;-1:-1:-1;;2022:18:1;;2015:34;;;;2080:4;2065:20;;;2058:36;;;;-1:-1:-1;2003:3:1;;914:1186;-1:-1:-1;;;;914:1186:1:o;2105:388::-;2173:6;2181;2234:2;2222:9;2213:7;2209:23;2205:32;2202:52;;;2250:1;2247;2240:12;2202:52;2289:9;2276:23;2308:31;2333:5;2308:31;:::i;:::-;2358:5;-1:-1:-1;2415:2:1;2400:18;;2387:32;2428:33;2387:32;2428:33;:::i;:::-;2480:7;2470:17;;;2105:388;;;;;:::o;2751:180::-;2810:6;2863:2;2851:9;2842:7;2838:23;2834:32;2831:52;;;2879:1;2876;2869:12;2831:52;-1:-1:-1;2902:23:1;;2751:180;-1:-1:-1;2751:180:1:o;2936:248::-;3004:6;3012;3065:2;3053:9;3044:7;3040:23;3036:32;3033:52;;;3081:1;3078;3071:12;3033:52;-1:-1:-1;;3104:23:1;;;3174:2;3159:18;;;3146:32;;-1:-1:-1;2936:248:1:o;3189:118::-;3275:5;3268:13;3261:21;3254:5;3251:32;3241:60;;3297:1;3294;3287:12;3312:241;3368:6;3421:2;3409:9;3400:7;3396:23;3392:32;3389:52;;;3437:1;3434;3427:12;3389:52;3476:9;3463:23;3495:28;3517:5;3495:28;:::i;3558:247::-;3617:6;3670:2;3658:9;3649:7;3645:23;3641:32;3638:52;;;3686:1;3683;3676:12;3638:52;3725:9;3712:23;3744:31;3769:5;3744:31;:::i;4206:127::-;4267:10;4262:3;4258:20;4255:1;4248:31;4298:4;4295:1;4288:15;4322:4;4319:1;4312:15;4338:1056;4415:6;4423;4476:2;4464:9;4455:7;4451:23;4447:32;4444:52;;;4492:1;4489;4482:12;4444:52;4531:9;4518:23;4550:31;4575:5;4550:31;:::i;:::-;4600:5;-1:-1:-1;4656:2:1;4641:18;;4628:32;4679:18;4709:14;;;4706:34;;;4736:1;4733;4726:12;4706:34;4774:6;4763:9;4759:22;4749:32;;4819:7;4812:4;4808:2;4804:13;4800:27;4790:55;;4841:1;4838;4831:12;4790:55;4877:2;4864:16;4899:2;4895;4892:10;4889:36;;;4905:18;;:::i;:::-;4980:2;4974:9;4948:2;5034:13;;-1:-1:-1;;5030:22:1;;;5054:2;5026:31;5022:40;5010:53;;;5078:18;;;5098:22;;;5075:46;5072:72;;;5124:18;;:::i;:::-;5164:10;5160:2;5153:22;5199:2;5191:6;5184:18;5239:7;5234:2;5229;5225;5221:11;5217:20;5214:33;5211:53;;;5260:1;5257;5250:12;5211:53;5316:2;5311;5307;5303:11;5298:2;5290:6;5286:15;5273:46;5361:1;5356:2;5351;5343:6;5339:15;5335:24;5328:35;5382:6;5372:16;;;;;;;4338:1056;;;;;:::o;6051:615::-;6137:6;6145;6198:2;6186:9;6177:7;6173:23;6169:32;6166:52;;;6214:1;6211;6204:12;6166:52;6254:9;6241:23;6283:18;6324:2;6316:6;6313:14;6310:34;;;6340:1;6337;6330:12;6310:34;6378:6;6367:9;6363:22;6353:32;;6423:7;6416:4;6412:2;6408:13;6404:27;6394:55;;6445:1;6442;6435:12;6394:55;6485:2;6472:16;6511:2;6503:6;6500:14;6497:34;;;6527:1;6524;6517:12;6497:34;6580:7;6575:2;6565:6;6562:1;6558:14;6554:2;6550:23;6546:32;6543:45;6540:65;;;6601:1;6598;6591:12;6540:65;6632:2;6624:11;;;;;6654:6;;-1:-1:-1;6051:615:1;;-1:-1:-1;;;;6051:615:1:o;7005:334::-;7083:6;7091;7144:2;7132:9;7123:7;7119:23;7115:32;7112:52;;;7160:1;7157;7150:12;7112:52;7199:9;7186:23;7238:1;7231:5;7228:12;7218:40;;7254:1;7251;7244:12;7344:456;7421:6;7429;7437;7490:2;7478:9;7469:7;7465:23;7461:32;7458:52;;;7506:1;7503;7496:12;7458:52;7542:9;7529:23;7519:33;;7602:2;7591:9;7587:18;7574:32;7615:31;7640:5;7615:31;:::i;:::-;7665:5;-1:-1:-1;7722:2:1;7707:18;;7694:32;7735:33;7694:32;7735:33;:::i;:::-;7787:7;7777:17;;;7344:456;;;;;:::o;8129:529::-;8206:6;8214;8222;8275:2;8263:9;8254:7;8250:23;8246:32;8243:52;;;8291:1;8288;8281:12;8243:52;8330:9;8317:23;8349:31;8374:5;8349:31;:::i;:::-;8399:5;-1:-1:-1;8456:2:1;8441:18;;8428:32;8469:33;8428:32;8469:33;:::i;9733:315::-;9801:6;9809;9862:2;9850:9;9841:7;9837:23;9833:32;9830:52;;;9878:1;9875;9868:12;9830:52;9914:9;9901:23;9891:33;;9974:2;9963:9;9959:18;9946:32;9987:31;10012:5;9987:31;:::i;10053:127::-;10114:10;10109:3;10105:20;10102:1;10095:31;10145:4;10142:1;10135:15;10169:4;10166:1;10159:15;10185:120;10225:1;10251;10241:35;;10256:18;;:::i;:::-;-1:-1:-1;10290:9:1;;10185:120::o;10310:112::-;10342:1;10368;10358:35;;10373:18;;:::i;:::-;-1:-1:-1;10407:9:1;;10310:112::o;10427:136::-;10466:3;10494:5;10484:39;;10503:18;;:::i;:::-;-1:-1:-1;;;10539:18:1;;10427:136::o;10568:168::-;10641:9;;;10672;;10689:15;;;10683:22;;10669:37;10659:71;;10710:18;;:::i;10741:128::-;10808:9;;;10829:11;;;10826:37;;;10843:18;;:::i;10874:127::-;10935:10;10930:3;10926:20;10923:1;10916:31;10966:4;10963:1;10956:15;10990:4;10987:1;10980:15;11006:135;11045:3;11066:17;;;11063:43;;11086:18;;:::i;:::-;-1:-1:-1;11133:1:1;11122:13;;11006:135::o;11146:343::-;11348:2;11330:21;;;11387:2;11367:18;;;11360:30;-1:-1:-1;;;11421:2:1;11406:18;;11399:49;11480:2;11465:18;;11146:343::o;11839:398::-;12041:2;12023:21;;;12080:2;12060:18;;;12053:30;12119:34;12114:2;12099:18;;12092:62;-1:-1:-1;;;12185:2:1;12170:18;;12163:32;12227:3;12212:19;;11839:398::o;12521:245::-;12588:6;12641:2;12629:9;12620:7;12616:23;12612:32;12609:52;;;12657:1;12654;12647:12;12609:52;12689:9;12683:16;12708:28;12730:5;12708:28;:::i;12771:335::-;12973:2;12955:21;;;13012:2;12992:18;;;12985:30;-1:-1:-1;;;13046:2:1;13031:18;;13024:41;13097:2;13082:18;;12771:335::o;13111:344::-;13313:2;13295:21;;;13352:2;13332:18;;;13325:30;-1:-1:-1;;;13386:2:1;13371:18;;13364:50;13446:2;13431:18;;13111:344::o;13460:354::-;13662:2;13644:21;;;13701:2;13681:18;;;13674:30;13740:32;13735:2;13720:18;;13713:60;13805:2;13790:18;;13460:354::o;14027:184::-;14097:6;14150:2;14138:9;14129:7;14125:23;14121:32;14118:52;;;14166:1;14163;14156:12;14118:52;-1:-1:-1;14189:16:1;;14027:184;-1:-1:-1;14027:184:1:o;14216:397::-;14418:2;14400:21;;;14457:2;14437:18;;;14430:30;14496:34;14491:2;14476:18;;14469:62;-1:-1:-1;;;14562:2:1;14547:18;;14540:31;14603:3;14588:19;;14216:397::o;14618:344::-;14820:2;14802:21;;;14859:2;14839:18;;;14832:30;-1:-1:-1;;;14893:2:1;14878:18;;14871:50;14953:2;14938:18;;14618:344::o;14967:399::-;15169:2;15151:21;;;15208:2;15188:18;;;15181:30;15247:34;15242:2;15227:18;;15220:62;-1:-1:-1;;;15313:2:1;15298:18;;15291:33;15356:3;15341:19;;14967:399::o;15650:335::-;15852:2;15834:21;;;15891:2;15871:18;;;15864:30;-1:-1:-1;;;15925:2:1;15910:18;;15903:41;15976:2;15961:18;;15650:335::o;16458:408::-;16660:2;16642:21;;;16699:2;16679:18;;;16672:30;16738:34;16733:2;16718:18;;16711:62;-1:-1:-1;;;16804:2:1;16789:18;;16782:42;16856:3;16841:19;;16458:408::o;16871:::-;17073:2;17055:21;;;17112:2;17092:18;;;17085:30;17151:34;17146:2;17131:18;;17124:62;-1:-1:-1;;;17217:2:1;17202:18;;17195:42;17269:3;17254:19;;16871:408::o;20805:127::-;20866:10;20861:3;20857:20;20854:1;20847:31;20897:4;20894:1;20887:15;20921:4;20918:1;20911:15;22039:480;22237:2;22222:18;;22270:1;22259:13;;22249:144;;22315:10;22310:3;22306:20;22303:1;22296:31;22350:4;22347:1;22340:15;22378:4;22375:1;22368:15;22249:144;22402:25;;;22458:2;22443:18;;22436:34;;;;22501:2;22486:18;;;22479:34;22039:480;:::o;27046:127::-;27107:10;27102:3;27098:20;27095:1;27088:31;27138:4;27135:1;27128:15;27162:4;27159:1;27152:15;31430:407;31632:2;31614:21;;;31671:2;31651:18;;;31644:30;31710:34;31705:2;31690:18;;31683:62;-1:-1:-1;;;31776:2:1;31761:18;;31754:41;31827:3;31812:19;;31430:407::o;32663:250::-;32748:1;32758:113;32772:6;32769:1;32766:13;32758:113;;;32848:11;;;32842:18;32829:11;;;32822:39;32794:2;32787:10;32758:113;;;-1:-1:-1;;32905:1:1;32887:16;;32880:27;32663:250::o;32918:287::-;33047:3;33085:6;33079:13;33101:66;33160:6;33155:3;33148:4;33140:6;33136:17;33101:66;:::i;:::-;33183:16;;;;;32918:287;-1:-1:-1;;32918:287:1:o;33210:396::-;33359:2;33348:9;33341:21;33322:4;33391:6;33385:13;33434:6;33429:2;33418:9;33414:18;33407:34;33450:79;33522:6;33517:2;33506:9;33502:18;33497:2;33489:6;33485:15;33450:79;:::i;:::-;33590:2;33569:15;-1:-1:-1;;33565:29:1;33550:45;;;;33597:2;33546:54;;33210:396;-1:-1:-1;;33210:396:1:o
Swarm Source
ipfs://bae85150d75515a911fdb7aeaac14fa4aeef1d461d73e44a4307c3fc7de5708a
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
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.