Feature Tip: Add private address tag to any address under My Name Tag !
Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
Latest 1 from a total of 1 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
0x60a06040 | 18178644 | 335 days ago | IN | 0 ETH | 0.1332629 |
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:
DelegatorPool
Compiler Version
v0.8.15+commit.e14f2714
Contract Source Code (Solidity)
/** *Submitted for verification at Etherscan.io on 2023-09-20 */ // Sources flattened with hardhat v2.11.2 https://hardhat.org // File contracts/core/interfaces/IStakingAllowance.sol // SPDX-License-Identifier: GPL-3.0 pragma solidity 0.8.15; interface IStakingAllowance { function mint(address _account, uint256 _amount) external; function burn(uint256 _amount) external; function burnFrom(address account, uint256 amount) external; } // File @openzeppelin/contracts/token/ERC20/[email protected] // OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `to`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address to, uint256 amount) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 amount) external returns (bool); /** * @dev Moves `amount` tokens from `from` to `to` using the * allowance mechanism. `amount` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom( address from, address to, uint256 amount ) external returns (bool); } // File contracts/core/interfaces/IERC677.sol pragma solidity 0.8.15; interface IERC677 is IERC20 { function transferAndCall( address _to, uint256 _value, bytes calldata _data ) external returns (bool success); } // File contracts/core/interfaces/IRewardsPoolController.sol pragma solidity 0.8.15; interface IRewardsPoolController { /** * @notice returns an account's stake balance for use by reward pools * controlled by this contract * @return account's balance */ function staked(address _account) external view returns (uint256); /** * @notice returns the total staked amount for use by reward pools * controlled by this contract * @return total staked amount */ function totalStaked() external view returns (uint256); /** * @notice adds a new token * @param _token token to add * @param _rewardsPool token rewards pool to add **/ function addToken(address _token, address _rewardsPool) external; } // File @openzeppelin/contracts/utils/[email protected] // OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol) pragma solidity ^0.8.1; /** * @dev Collection of functions related to the address type */ library Address { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * ==== * * [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 functionCall(target, data, "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"); require(isContract(target), "Address: call to non-contract"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResult(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) { require(isContract(target), "Address: static call to non-contract"); (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { return functionDelegateCall(target, data, "Address: low-level delegate call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { require(isContract(target), "Address: delegate call to non-contract"); (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason 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 { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly /// @solidity memory-safe-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } } // File @openzeppelin/contracts/token/ERC20/extensions/[email protected] // OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-IERC20Permit.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612]. * * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't * need to send a transaction, and thus is not required to hold Ether at all. */ interface IERC20Permit { /** * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens, * given ``owner``'s signed approval. * * IMPORTANT: The same issues {IERC20-approve} has related to transaction * ordering also apply here. * * Emits an {Approval} event. * * Requirements: * * - `spender` cannot be the zero address. * - `deadline` must be a timestamp in the future. * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner` * over the EIP712-formatted function arguments. * - the signature must use ``owner``'s current nonce (see {nonces}). * * For more information on the signature format, see the * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP * section]. */ function permit( address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) external; /** * @dev Returns the current nonce for `owner`. This value must be * included whenever a signature is generated for {permit}. * * Every successful call to {permit} increases ``owner``'s nonce by one. This * prevents a signature from being used multiple times. */ function nonces(address owner) external view returns (uint256); /** * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}. */ // solhint-disable-next-line func-name-mixedcase function DOMAIN_SEPARATOR() external view returns (bytes32); } // File @openzeppelin/contracts/token/ERC20/utils/[email protected] // OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/utils/SafeERC20.sol) pragma solidity ^0.8.0; /** * @title SafeERC20 * @dev Wrappers around ERC20 operations that throw on failure (when the token * contract returns false). Tokens that return no value (and instead revert or * throw on failure) are also supported, non-reverting calls are assumed to be * successful. * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract, * which allows you to call the safe operations as `token.safeTransfer(...)`, etc. */ library SafeERC20 { using Address for address; function safeTransfer( IERC20 token, address to, uint256 value ) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value)); } function safeTransferFrom( IERC20 token, address from, address to, uint256 value ) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value)); } /** * @dev Deprecated. This function has issues similar to the ones found in * {IERC20-approve}, and its usage is discouraged. * * Whenever possible, use {safeIncreaseAllowance} and * {safeDecreaseAllowance} instead. */ function safeApprove( IERC20 token, address spender, uint256 value ) internal { // safeApprove should only be called when setting an initial allowance, // or when resetting it to zero. To increase and decrease it, use // 'safeIncreaseAllowance' and 'safeDecreaseAllowance' require( (value == 0) || (token.allowance(address(this), spender) == 0), "SafeERC20: approve from non-zero to non-zero allowance" ); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value)); } function safeIncreaseAllowance( IERC20 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( IERC20 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( IERC20Permit token, address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) internal { uint256 nonceBefore = token.nonces(owner); token.permit(owner, spender, value, deadline, v, r, s); uint256 nonceAfter = token.nonces(owner); require(nonceAfter == nonceBefore + 1, "SafeERC20: permit did not succeed"); } /** * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement * on the return value: the return value is optional (but if data is returned, it must not be false). * @param token The token targeted by the call. * @param data The call data (encoded using abi.encode or one of its variants). */ function _callOptionalReturn(IERC20 token, bytes memory data) private { // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that // the target address contains contract code and also asserts for success in the low-level call. bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed"); if (returndata.length > 0) { // Return data is optional require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed"); } } } // File contracts/core/RewardsPool.sol pragma solidity 0.8.15; /** * @title RewardsPool * @notice Handles reward distribution for a single asset * @dev rewards can only be positive (user balances can only increase) */ contract RewardsPool { using SafeERC20 for IERC677; IERC677 public immutable token; IRewardsPoolController public immutable controller; uint256 public rewardPerToken; uint256 public totalRewards; mapping(address => uint256) public userRewardPerTokenPaid; mapping(address => uint256) public userRewards; event Withdraw(address indexed account, uint256 amount); event DistributeRewards(address indexed sender, uint256 amountStaked, uint256 amount); constructor(address _controller, address _token) { controller = IRewardsPoolController(_controller); token = IERC677(_token); } /** * @notice returns an account's total withdrawable rewards (principal balance + newly earned rewards) * @param _account account address * @return account's total unclaimed rewards **/ function withdrawableRewards(address _account) public view virtual returns (uint256) { return (controller.staked(_account) * (rewardPerToken - userRewardPerTokenPaid[_account])) / 1e18 + userRewards[_account]; } /** * @notice withdraws an account's earned rewards **/ function withdraw() external { _withdraw(msg.sender); } /** * @notice withdraws an account's earned rewards * @dev used by RewardsPoolController * @param _account account to withdraw for **/ function withdraw(address _account) external { require(msg.sender == address(controller), "Controller only"); _withdraw(_account); } /** * @notice ERC677 implementation that proxies reward distribution **/ function onTokenTransfer( address, uint256, bytes calldata ) external { require(msg.sender == address(token), "Only callable by token"); distributeRewards(); } /** * @notice distributes new rewards that have been deposited **/ function distributeRewards() public virtual { require(controller.totalStaked() > 0, "Cannot distribute when nothing is staked"); uint256 toDistribute = token.balanceOf(address(this)) - totalRewards; totalRewards += toDistribute; _updateRewardPerToken(toDistribute); emit DistributeRewards(msg.sender, controller.totalStaked(), toDistribute); } /** * @notice updates an account's principal reward balance * @param _account account address **/ function updateReward(address _account) public virtual { uint256 newRewards = withdrawableRewards(_account) - userRewards[_account]; if (newRewards > 0) { userRewards[_account] += newRewards; } userRewardPerTokenPaid[_account] = rewardPerToken; } /** * @notice withdraws rewards for an account * @param _account account to withdraw for **/ function _withdraw(address _account) internal virtual { uint256 toWithdraw = withdrawableRewards(_account); if (toWithdraw > 0) { updateReward(_account); userRewards[_account] -= toWithdraw; totalRewards -= toWithdraw; token.safeTransfer(_account, toWithdraw); emit Withdraw(_account, toWithdraw); } } /** * @notice updates rewardPerToken * @param _reward deposited reward amount **/ function _updateRewardPerToken(uint256 _reward) internal { uint256 totalStaked = controller.totalStaked(); require(totalStaked > 0, "Staked amount must be > 0"); rewardPerToken += ((_reward * 1e18) / totalStaked); } } // File contracts/core/interfaces/IRewardsPool.sol pragma solidity 0.8.15; interface IRewardsPool { function updateReward(address _account) external; function withdraw(address _account) external; function distributeRewards() external; function withdrawableRewards(address _account) external view returns (uint256); } // File contracts/core/interfaces/IERC677Receiver.sol pragma solidity 0.8.15; interface IERC677Receiver { function onTokenTransfer( address _sender, uint256 _value, bytes calldata _data ) external; } // File @openzeppelin/contracts-upgradeable/utils/[email protected] // OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol) pragma solidity ^0.8.1; /** * @dev Collection of functions related to the address type */ library AddressUpgradeable { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * * Furthermore, `isContract` will also return true if the target contract within * the same transaction is already scheduled for destruction by `SELFDESTRUCT`, * which only has an effect at the end of a transaction. * ==== * * [IMPORTANT] * ==== * You shouldn't rely on `isContract` to protect against flash loan attacks! * * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract * constructor. * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize/address.code.length, which returns 0 // for contracts in construction, since the code is only stored at the end // of the constructor execution. return account.code.length > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); (bool success, ) = recipient.call{value: amount}(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain `call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value, string memory errorMessage ) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall( address target, bytes memory data, string memory errorMessage ) internal view returns (bytes memory) { (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { return functionDelegateCall(target, data, "Address: low-level delegate call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract. * * _Available since v4.8._ */ function verifyCallResultFromTarget( address target, bool success, bytes memory returndata, string memory errorMessage ) internal view returns (bytes memory) { if (success) { if (returndata.length == 0) { // only check isContract if the call was successful and the return data is empty // otherwise we already know that it was a contract require(isContract(target), "Address: call to non-contract"); } return returndata; } else { _revert(returndata, errorMessage); } } /** * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason or using the provided one. * * _Available since v4.3._ */ function verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) internal pure returns (bytes memory) { if (success) { return returndata; } else { _revert(returndata, errorMessage); } } function _revert(bytes memory returndata, string memory errorMessage) private pure { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly /// @solidity memory-safe-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } // File @openzeppelin/contracts-upgradeable/proxy/utils/[email protected] // OpenZeppelin Contracts (last updated v4.9.0) (proxy/utils/Initializable.sol) pragma solidity ^0.8.2; /** * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect. * * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be * reused. This mechanism prevents re-execution of each "step" but allows the creation of new initialization steps in * case an upgrade adds a module that needs to be initialized. * * For example: * * [.hljs-theme-light.nopadding] * ```solidity * contract MyToken is ERC20Upgradeable { * function initialize() initializer public { * __ERC20_init("MyToken", "MTK"); * } * } * * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable { * function initializeV2() reinitializer(2) public { * __ERC20Permit_init("MyToken"); * } * } * ``` * * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}. * * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity. * * [CAUTION] * ==== * Avoid leaving a contract uninitialized. * * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed: * * [.hljs-theme-light.nopadding] * ``` * /// @custom:oz-upgrades-unsafe-allow constructor * constructor() { * _disableInitializers(); * } * ``` * ==== */ abstract contract Initializable { /** * @dev 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; } } // File @openzeppelin/contracts-upgradeable/utils/[email protected] // OpenZeppelin Contracts v4.4.1 (utils/Context.sol) pragma solidity ^0.8.0; /** * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract 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; } // File @openzeppelin/contracts-upgradeable/token/ERC20/[email protected] // OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface 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); } // File @openzeppelin/contracts-upgradeable/token/ERC20/extensions/[email protected] // OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol) pragma solidity ^0.8.0; /** * @dev Interface for the optional metadata functions from the ERC20 standard. * * _Available since v4.1._ */ interface IERC20MetadataUpgradeable is IERC20Upgradeable { /** * @dev Returns the name of the token. */ function name() external view returns (string memory); /** * @dev Returns the symbol of the token. */ function symbol() external view returns (string memory); /** * @dev Returns the decimals places of the token. */ function decimals() external view returns (uint8); } // File @openzeppelin/contracts-upgradeable/token/ERC20/[email protected] // OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/ERC20.sol) pragma solidity ^0.8.0; /** * @dev Implementation of the {IERC20} interface. * * This implementation is agnostic to the way tokens are created. This means * that a supply mechanism has to be added in a derived contract using {_mint}. * For a generic mechanism see {ERC20PresetMinterPauser}. * * TIP: For a detailed writeup see our guide * https://forum.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226[How * to implement supply mechanisms]. * * The default value of {decimals} is 18. To change this, you should override * this function so it returns a different value. * * We have followed general OpenZeppelin Contracts guidelines: functions revert * instead returning `false` on failure. This behavior is nonetheless * conventional and does not conflict with the expectations of ERC20 * applications. * * Additionally, an {Approval} event is emitted on calls to {transferFrom}. * This allows applications to reconstruct the allowance for all accounts just * by listening to said events. Other implementations of the EIP may not emit * these events, as it isn't required by the specification. * * Finally, the non-standard {decreaseAllowance} and {increaseAllowance} * functions have been added to mitigate the well-known issues around setting * allowances. See {IERC20-approve}. */ contract ERC20Upgradeable is Initializable, ContextUpgradeable, IERC20Upgradeable, IERC20MetadataUpgradeable { mapping(address => uint256) private _balances; mapping(address => mapping(address => uint256)) private _allowances; uint256 private _totalSupply; string private _name; string private _symbol; /** * @dev Sets the values for {name} and {symbol}. * * All two of these values are immutable: they can only be set once during * construction. */ function __ERC20_init(string memory name_, string memory symbol_) internal onlyInitializing { __ERC20_init_unchained(name_, symbol_); } function __ERC20_init_unchained(string memory name_, string memory symbol_) internal onlyInitializing { _name = name_; _symbol = symbol_; } /** * @dev Returns the name of the token. */ function name() public view virtual override returns (string memory) { return _name; } /** * @dev Returns the symbol of the token, usually a shorter version of the * name. */ function symbol() public view virtual override returns (string memory) { return _symbol; } /** * @dev Returns the number of decimals used to get its user representation. * For example, if `decimals` equals `2`, a balance of `505` tokens should * be displayed to a user as `5.05` (`505 / 10 ** 2`). * * Tokens usually opt for a value of 18, imitating the relationship between * Ether and Wei. This is the default value returned by this function, unless * it's overridden. * * NOTE: This information is only used for _display_ purposes: it in * no way affects any of the arithmetic of the contract, including * {IERC20-balanceOf} and {IERC20-transfer}. */ function decimals() public view virtual override returns (uint8) { return 18; } /** * @dev See {IERC20-totalSupply}. */ function totalSupply() public view virtual override returns (uint256) { return _totalSupply; } /** * @dev See {IERC20-balanceOf}. */ function balanceOf(address account) public view virtual override returns (uint256) { return _balances[account]; } /** * @dev See {IERC20-transfer}. * * Requirements: * * - `to` cannot be the zero address. * - the caller must have a balance of at least `amount`. */ function transfer(address to, uint256 amount) public virtual override returns (bool) { address owner = _msgSender(); _transfer(owner, to, amount); return true; } /** * @dev See {IERC20-allowance}. */ function allowance(address owner, address spender) public view virtual override returns (uint256) { return _allowances[owner][spender]; } /** * @dev See {IERC20-approve}. * * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on * `transferFrom`. This is semantically equivalent to an infinite approval. * * Requirements: * * - `spender` cannot be the zero address. */ function approve(address spender, uint256 amount) public virtual override returns (bool) { address owner = _msgSender(); _approve(owner, spender, amount); return true; } /** * @dev See {IERC20-transferFrom}. * * Emits an {Approval} event indicating the updated allowance. This is not * required by the EIP. See the note at the beginning of {ERC20}. * * NOTE: Does not update the allowance if the current allowance * is the maximum `uint256`. * * Requirements: * * - `from` and `to` cannot be the zero address. * - `from` must have a balance of at least `amount`. * - the caller must have allowance for ``from``'s tokens of at least * `amount`. */ function transferFrom(address from, address to, uint256 amount) public virtual override returns (bool) { address spender = _msgSender(); _spendAllowance(from, spender, amount); _transfer(from, to, amount); return true; } /** * @dev Atomically increases the allowance granted to `spender` by the caller. * * This is an alternative to {approve} that can be used as a mitigation for * problems described in {IERC20-approve}. * * Emits an {Approval} event indicating the updated allowance. * * Requirements: * * - `spender` cannot be the zero address. */ function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) { address owner = _msgSender(); _approve(owner, spender, allowance(owner, spender) + addedValue); return true; } /** * @dev Atomically decreases the allowance granted to `spender` by the caller. * * This is an alternative to {approve} that can be used as a mitigation for * problems described in {IERC20-approve}. * * Emits an {Approval} event indicating the updated allowance. * * Requirements: * * - `spender` cannot be the zero address. * - `spender` must have allowance for the caller of at least * `subtractedValue`. */ function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) { address owner = _msgSender(); uint256 currentAllowance = allowance(owner, spender); require(currentAllowance >= subtractedValue, "ERC20: decreased allowance below zero"); unchecked { _approve(owner, spender, currentAllowance - subtractedValue); } return true; } /** * @dev Moves `amount` of tokens from `from` to `to`. * * This internal function is equivalent to {transfer}, and can be used to * e.g. implement automatic token fees, slashing mechanisms, etc. * * Emits a {Transfer} event. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `from` must have a balance of at least `amount`. */ function _transfer(address from, address to, uint256 amount) internal virtual { require(from != address(0), "ERC20: transfer from the zero address"); require(to != address(0), "ERC20: transfer to the zero address"); _beforeTokenTransfer(from, to, amount); uint256 fromBalance = _balances[from]; require(fromBalance >= amount, "ERC20: transfer amount exceeds balance"); unchecked { _balances[from] = fromBalance - amount; // Overflow not possible: the sum of all balances is capped by totalSupply, and the sum is preserved by // decrementing then incrementing. _balances[to] += amount; } emit Transfer(from, to, amount); _afterTokenTransfer(from, to, amount); } /** @dev Creates `amount` tokens and assigns them to `account`, increasing * the total supply. * * Emits a {Transfer} event with `from` set to the zero address. * * Requirements: * * - `account` cannot be the zero address. */ function _mint(address account, uint256 amount) internal virtual { require(account != address(0), "ERC20: mint to the zero address"); _beforeTokenTransfer(address(0), account, amount); _totalSupply += amount; unchecked { // Overflow not possible: balance + amount is at most totalSupply + amount, which is checked above. _balances[account] += amount; } emit Transfer(address(0), account, amount); _afterTokenTransfer(address(0), account, amount); } /** * @dev Destroys `amount` tokens from `account`, reducing the * total supply. * * Emits a {Transfer} event with `to` set to the zero address. * * Requirements: * * - `account` cannot be the zero address. * - `account` must have at least `amount` tokens. */ function _burn(address account, uint256 amount) internal virtual { require(account != address(0), "ERC20: burn from the zero address"); _beforeTokenTransfer(account, address(0), amount); uint256 accountBalance = _balances[account]; require(accountBalance >= amount, "ERC20: burn amount exceeds balance"); unchecked { _balances[account] = accountBalance - amount; // Overflow not possible: amount <= accountBalance <= totalSupply. _totalSupply -= amount; } emit Transfer(account, address(0), amount); _afterTokenTransfer(account, address(0), amount); } /** * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens. * * This internal function is equivalent to `approve`, and can be used to * e.g. set automatic allowances for certain subsystems, etc. * * Emits an {Approval} event. * * Requirements: * * - `owner` cannot be the zero address. * - `spender` cannot be the zero address. */ function _approve(address owner, address spender, uint256 amount) internal virtual { require(owner != address(0), "ERC20: approve from the zero address"); require(spender != address(0), "ERC20: approve to the zero address"); _allowances[owner][spender] = amount; emit Approval(owner, spender, amount); } /** * @dev Updates `owner` s allowance for `spender` based on spent `amount`. * * Does not update the allowance amount in case of infinite allowance. * Revert if not enough allowance is available. * * Might emit an {Approval} event. */ function _spendAllowance(address owner, address spender, uint256 amount) internal virtual { uint256 currentAllowance = allowance(owner, spender); if (currentAllowance != type(uint256).max) { require(currentAllowance >= amount, "ERC20: insufficient allowance"); unchecked { _approve(owner, spender, currentAllowance - amount); } } } /** * @dev Hook that is called before any transfer of tokens. This includes * minting and burning. * * Calling conditions: * * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens * will be transferred to `to`. * - when `from` is zero, `amount` tokens will be minted for `to`. * - when `to` is zero, `amount` of ``from``'s tokens will be burned. * - `from` and `to` are never both zero. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual {} /** * @dev Hook that is called after any transfer of tokens. This includes * minting and burning. * * Calling conditions: * * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens * has been transferred to `to`. * - when `from` is zero, `amount` tokens have been minted for `to`. * - when `to` is zero, `amount` of ``from``'s tokens have been burned. * - `from` and `to` are never both zero. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _afterTokenTransfer(address from, address to, uint256 amount) 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[45] private __gap; } // File contracts/core/tokens/base/ERC677Upgradeable.sol pragma solidity 0.8.15; contract ERC677Upgradeable is ERC20Upgradeable { function __ERC677_init( string memory _tokenName, string memory _tokenSymbol, uint256 _totalSupply ) public onlyInitializing { __ERC20_init(_tokenName, _tokenSymbol); _mint(msg.sender, _totalSupply * (10**uint256(decimals()))); } function transferAndCall( address _to, uint256 _value, bytes memory _data ) public returns (bool) { super.transfer(_to, _value); if (isContract(_to)) { contractFallback(msg.sender, _to, _value, _data); } return true; } function transferAndCallFrom( address _sender, address _to, uint256 _value, bytes memory _data ) internal returns (bool) { _transfer(_sender, _to, _value); if (isContract(_to)) { contractFallback(_sender, _to, _value, _data); } return true; } function contractFallback( address _sender, address _to, uint256 _value, bytes memory _data ) internal { IERC677Receiver receiver = IERC677Receiver(_to); receiver.onTokenTransfer(_sender, _value, _data); } function isContract(address _addr) internal view returns (bool hasCode) { uint256 length; assembly { length := extcodesize(_addr) } return length > 0; } } // File @openzeppelin/contracts-upgradeable/access/[email protected] // OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable.sol) pragma solidity ^0.8.0; /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * By default, the owner account will be the one that deploys the contract. This * can later be changed with {transferOwnership}. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ abstract contract OwnableUpgradeable is Initializable, ContextUpgradeable { address private _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the deployer as the initial owner. */ function __Ownable_init() internal onlyInitializing { __Ownable_init_unchained(); } function __Ownable_init_unchained() internal onlyInitializing { _transferOwnership(_msgSender()); } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { _checkOwner(); _; } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if the sender is not the owner. */ function _checkOwner() internal view virtual { require(owner() == _msgSender(), "Ownable: caller is not the owner"); } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby disabling any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { _transferOwnership(address(0)); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual onlyOwner { require(newOwner != address(0), "Ownable: new owner is the zero address"); _transferOwnership(newOwner); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Internal function without access restriction. */ function _transferOwnership(address newOwner) internal virtual { address oldOwner = _owner; _owner = newOwner; emit OwnershipTransferred(oldOwner, newOwner); } /** * @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; } // File @openzeppelin/contracts-upgradeable/interfaces/[email protected] // OpenZeppelin Contracts (last updated v4.5.0) (interfaces/draft-IERC1822.sol) pragma solidity ^0.8.0; /** * @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); } // File @openzeppelin/contracts-upgradeable/interfaces/[email protected] // OpenZeppelin Contracts (last updated v4.9.0) (interfaces/IERC1967.sol) pragma solidity ^0.8.0; /** * @dev ERC-1967: Proxy Storage Slots. This interface contains the events defined in the ERC. * * _Available since v4.8.3._ */ 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); } // File @openzeppelin/contracts-upgradeable/utils/[email protected] // OpenZeppelin Contracts (last updated v4.9.0) (utils/StorageSlot.sol) // This file was procedurally generated from scripts/generate/templates/StorageSlot.js. pragma solidity ^0.8.0; /** * @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: * ```solidity * 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`, `uint256`._ * _Available since v4.9 for `string`, `bytes`._ */ library StorageSlotUpgradeable { struct AddressSlot { address value; } struct BooleanSlot { bool value; } struct Bytes32Slot { bytes32 value; } struct Uint256Slot { uint256 value; } struct StringSlot { string value; } struct BytesSlot { bytes 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 } } /** * @dev Returns an `StringSlot` with member `value` located at `slot`. */ function getStringSlot(bytes32 slot) internal pure returns (StringSlot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } /** * @dev Returns an `StringSlot` representation of the string storage pointer `store`. */ function getStringSlot(string storage store) internal pure returns (StringSlot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := store.slot } } /** * @dev Returns an `BytesSlot` with member `value` located at `slot`. */ function getBytesSlot(bytes32 slot) internal pure returns (BytesSlot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } /** * @dev Returns an `BytesSlot` representation of the bytes storage pointer `store`. */ function getBytesSlot(bytes storage store) internal pure returns (BytesSlot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := store.slot } } } // File @openzeppelin/contracts-upgradeable/proxy/beacon/[email protected] // OpenZeppelin Contracts v4.4.1 (proxy/beacon/IBeacon.sol) pragma solidity ^0.8.0; /** * @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); } // File @openzeppelin/contracts-upgradeable/proxy/ERC1967/[email protected] // OpenZeppelin Contracts (last updated v4.9.0) (proxy/ERC1967/ERC1967Upgrade.sol) pragma solidity ^0.8.2; /** * @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._ */ 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) { AddressUpgradeable.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) { AddressUpgradeable.functionDelegateCall(IBeaconUpgradeable(newBeacon).implementation(), 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; } // File @openzeppelin/contracts-upgradeable/proxy/utils/[email protected] // OpenZeppelin Contracts (last updated v4.9.0) (proxy/utils/UUPSUpgradeable.sol) pragma solidity ^0.8.0; /** * @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. * * @custom:oz-upgrades-unsafe-allow-reachable delegatecall */ function upgradeTo(address newImplementation) public 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. * * @custom:oz-upgrades-unsafe-allow-reachable delegatecall */ function upgradeToAndCall(address newImplementation, bytes memory data) public 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; } // File @openzeppelin/contracts-upgradeable/token/ERC20/extensions/[email protected] // OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/extensions/IERC20Permit.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612]. * * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't * need to send a transaction, and thus is not required to hold Ether at all. */ interface 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); } // File @openzeppelin/contracts-upgradeable/token/ERC20/utils/[email protected] // OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/utils/SafeERC20.sol) pragma solidity ^0.8.0; /** * @title SafeERC20 * @dev Wrappers around ERC20 operations that throw on failure (when the token * contract returns false). Tokens that return no value (and instead revert or * throw on failure) are also supported, non-reverting calls are assumed to be * successful. * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract, * which allows you to call the safe operations as `token.safeTransfer(...)`, etc. */ library SafeERC20Upgradeable { using AddressUpgradeable for address; /** * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value, * non-reverting calls are assumed to be successful. */ function safeTransfer(IERC20Upgradeable token, address to, uint256 value) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value)); } /** * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful. */ function safeTransferFrom(IERC20Upgradeable token, address from, address to, uint256 value) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value)); } /** * @dev Deprecated. This function has issues similar to the ones found in * {IERC20-approve}, and its usage is discouraged. * * Whenever possible, use {safeIncreaseAllowance} and * {safeDecreaseAllowance} instead. */ function safeApprove(IERC20Upgradeable token, address spender, uint256 value) internal { // safeApprove should only be called when setting an initial allowance, // or when resetting it to zero. To increase and decrease it, use // 'safeIncreaseAllowance' and 'safeDecreaseAllowance' require( (value == 0) || (token.allowance(address(this), spender) == 0), "SafeERC20: approve from non-zero to non-zero allowance" ); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value)); } /** * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value, * non-reverting calls are assumed to be successful. */ function safeIncreaseAllowance(IERC20Upgradeable token, address spender, uint256 value) internal { uint256 oldAllowance = token.allowance(address(this), spender); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance + value)); } /** * @dev Decrease the calling contract's allowance toward `spender` by `value`. If `token` returns no value, * non-reverting calls are assumed to be successful. */ function safeDecreaseAllowance(IERC20Upgradeable token, address spender, uint256 value) internal { unchecked { uint256 oldAllowance = token.allowance(address(this), spender); require(oldAllowance >= value, "SafeERC20: decreased allowance below zero"); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance - value)); } } /** * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value, * non-reverting calls are assumed to be successful. Compatible with tokens that require the approval to be set to * 0 before setting it to a non-zero value. */ function forceApprove(IERC20Upgradeable token, address spender, uint256 value) internal { bytes memory approvalCall = abi.encodeWithSelector(token.approve.selector, spender, value); if (!_callOptionalReturnBool(token, approvalCall)) { _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, 0)); _callOptionalReturn(token, approvalCall); } } /** * @dev Use a ERC-2612 signature to set the `owner` approval toward `spender` on `token`. * Revert on invalid signature. */ function safePermit( IERC20PermitUpgradeable token, address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) internal { uint256 nonceBefore = token.nonces(owner); token.permit(owner, spender, value, deadline, v, r, s); uint256 nonceAfter = token.nonces(owner); require(nonceAfter == nonceBefore + 1, "SafeERC20: permit did not succeed"); } /** * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement * on the return value: the return value is optional (but if data is returned, it must not be false). * @param token The token targeted by the call. * @param data The call data (encoded using abi.encode or one of its variants). */ function _callOptionalReturn(IERC20Upgradeable token, bytes memory data) private { // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since // we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that // the target address contains contract code and also asserts for success in the low-level call. bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed"); require(returndata.length == 0 || abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed"); } /** * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement * on the return value: the return value is optional (but if data is returned, it must not be false). * @param token The token targeted by the call. * @param data The call data (encoded using abi.encode or one of its variants). * * This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead. */ function _callOptionalReturnBool(IERC20Upgradeable token, bytes memory data) private returns (bool) { // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since // we're implementing it ourselves. We cannot use {Address-functionCall} here since this should return false // and not revert is the subcall reverts. (bool success, bytes memory returndata) = address(token).call(data); return success && (returndata.length == 0 || abi.decode(returndata, (bool))) && AddressUpgradeable.isContract(address(token)); } } // File contracts/core/test/deprecated/RewardsPoolControllerV1.sol pragma solidity 0.8.15; /** * @title Rewards Pool Controller * @notice Acts as a proxy for any number of rewards pools */ abstract contract RewardsPoolControllerV1 is UUPSUpgradeable, OwnableUpgradeable, ERC677Upgradeable { using SafeERC20Upgradeable for IERC20Upgradeable; mapping(address => IRewardsPool) public tokenPools; address[] internal tokens; mapping(address => address) public rewardRedirects; // deprecated mapping(address => uint256) public redirectedStakes; // deprecated mapping(address => address) public redirectApprovals; // deprecated event WithdrawRewards(address indexed account); event AddToken(address indexed token, address rewardsPool); event RemoveToken(address indexed token, address rewardsPool); function __RewardsPoolController_init(string memory _derivativeTokenName, string memory _derivativeTokenSymbol) public onlyInitializing { __ERC677_init(_derivativeTokenName, _derivativeTokenSymbol, 0); __Ownable_init(); __UUPSUpgradeable_init(); } modifier updateRewards(address _account) { _updateRewards(_account); _; } /** * @notice returns a list of supported tokens * @return list of token addresses **/ function supportedTokens() external view returns (address[] memory) { return tokens; } /** * @notice returns true/false to whether a given token is supported * @param _token token address * @return is token supported **/ function isTokenSupported(address _token) public view returns (bool) { return address(tokenPools[_token]) != address(0) ? true : false; } /** * @notice returns balances of supported tokens within the controller * @return list of supported tokens * @return list of token balances **/ function tokenBalances() external view returns (address[] memory, uint256[] memory) { uint256[] memory balances = new uint256[](tokens.length); for (uint256 i = 0; i < tokens.length; i++) { balances[i] = IERC20Upgradeable(tokens[i]).balanceOf(address(this)); } return (tokens, balances); } /** * @notice ERC677 implementation to receive a token distribution **/ function onTokenTransfer( address, uint256, bytes calldata ) external virtual { if (isTokenSupported(msg.sender)) { distributeToken(msg.sender); } } /** * @notice returns an account's staked amount for use by reward pools * controlled by this contract * @param _account account address * @return account's staked amount */ function staked(address _account) external view virtual returns (uint256) { return balanceOf(_account); } /** * @notice returns the total staked amount for use by reward pools * controlled by this contract * @return total staked amount */ function totalStaked() external view virtual returns (uint256) { return totalSupply(); } /** * @dev updates the rewards of the sender and receiver * @param _from account sending from * @param _to account sending to * @param _amount amount being sent */ function _transfer( address _from, address _to, uint256 _amount ) internal virtual override updateRewards(_from) updateRewards(_to) { super._transfer(_from, _to, _amount); } /** * @notice distributes token balances to their respective rewards pools * @param _tokens list of token addresses */ function distributeTokens(address[] memory _tokens) public { for (uint256 i = 0; i < _tokens.length; i++) { distributeToken(_tokens[i]); } } /** * @notice distributes a token balance to its respective rewards pool * @param _token token address */ function distributeToken(address _token) public { require(isTokenSupported(_token), "Token not supported"); IERC20Upgradeable token = IERC20Upgradeable(_token); uint256 balance = token.balanceOf(address(this)); require(balance > 0, "Cannot distribute zero balance"); token.safeTransfer(address(tokenPools[_token]), balance); tokenPools[_token].distributeRewards(); } /** * @notice returns a list of withdrawable rewards for an account * @param _account account address * @return list of withdrawable reward amounts **/ function withdrawableRewards(address _account) external view returns (uint256[] memory) { uint256[] memory withdrawable = new uint256[](tokens.length); for (uint256 i = 0; i < tokens.length; i++) { withdrawable[i] = tokenPools[tokens[i]].withdrawableRewards(_account); } return withdrawable; } /** * @notice withdraws an account's earned rewards for a list of tokens * @param _tokens list of token addresses to withdraw rewards from **/ function withdrawRewards(address[] memory _tokens) public { for (uint256 i = 0; i < _tokens.length; i++) { tokenPools[_tokens[i]].withdraw(msg.sender); } emit WithdrawRewards(msg.sender); } /** * @notice adds a new token * @param _token token to add * @param _rewardsPool token rewards pool to add **/ function addToken(address _token, address _rewardsPool) public onlyOwner { require(!isTokenSupported(_token), "Token is already supported"); tokenPools[_token] = IRewardsPool(_rewardsPool); tokens.push(_token); if (IERC20Upgradeable(_token).balanceOf(address(this)) > 0) { distributeToken(_token); } emit AddToken(_token, _rewardsPool); } /** * @notice removes a supported token * @param _token address of token **/ function removeToken(address _token) external onlyOwner { require(isTokenSupported(_token), "Token is not supported"); IRewardsPool rewardsPool = tokenPools[_token]; delete (tokenPools[_token]); for (uint256 i = 0; i < tokens.length; i++) { if (tokens[i] == _token) { tokens[i] = tokens[tokens.length - 1]; tokens.pop(); break; } } emit RemoveToken(_token, address(rewardsPool)); } /** * @dev triggers a reward update for a given account * @param _account account to update rewards for */ function _updateRewards(address _account) internal { for (uint256 i = 0; i < tokens.length; i++) { tokenPools[tokens[i]].updateReward(_account); } } function _authorizeUpgrade(address) internal override onlyOwner {} } // File contracts/core/test/deprecated/DelegatorPool.sol pragma solidity 0.8.15; interface IPoolRouter { function isReservedMode() external view returns (bool); function getReservedMultiplier() external view returns (uint256); } interface ISDLPool { function migrate( address _account, uint256 _amount, uint64 _lockingDuration ) external; } /** * @title Delegator Pool * @notice Allows users to stake allowance tokens and receive a percentage of earned rewards */ contract DelegatorPool is RewardsPoolControllerV1 { using SafeERC20Upgradeable for IERC20Upgradeable; struct VestingSchedule { uint256 totalAmount; uint64 startTimestamp; uint64 durationSeconds; } IERC20Upgradeable public allowanceToken; IPoolRouter public poolRouter; address public feeCurve; // unused mapping(address => VestingSchedule) private vestingSchedules; // unused mapping(address => uint256) private lockedBalances; mapping(address => uint256) private lockedApprovals; mapping(address => bool) public communityPools; uint256 public totalLocked; address public sdlPool; event AllowanceStaked(address indexed user, uint256 amount); event AllowanceWithdrawn(address indexed user, uint256 amount); event Migration(address indexed user, uint256 amount); /// @custom:oz-upgrades-unsafe-allow constructor constructor() { _disableInitializers(); } function initialize( address _allowanceToken, string calldata _dTokenName, string calldata _dTokenSymbol, address[] calldata _vestingAddresses ) public reinitializer(2) { if (address(allowanceToken) == address(0)) { __RewardsPoolController_init(_dTokenName, _dTokenSymbol); allowanceToken = IERC20Upgradeable(_allowanceToken); } else { for (uint256 i = 0; i < _vestingAddresses.length; ++i) { address account = _vestingAddresses[i]; VestingSchedule memory vestingSchedule = vestingSchedules[account]; lockedBalances[account] += vestingSchedule.totalAmount; totalLocked += vestingSchedule.totalAmount; delete vestingSchedules[account]; } } } /** * @notice ERC677 implementation to stake allowance or distribute rewards * @param _sender of the stake * @param _value of the token transfer * @param _calldata encoded locked allowance amount if applicable **/ function onTokenTransfer( address _sender, uint256 _value, bytes calldata _calldata ) external override { require(sdlPool == address(0), "Deposits disabled"); require( msg.sender == address(allowanceToken) || isTokenSupported(msg.sender), "Sender must be allowance or rewards token" ); if (msg.sender == address(allowanceToken)) { _stakeAllowance(_sender, _value); if (_calldata.length != 0) { uint256 lockedAmount = abi.decode(_calldata, (uint256)); require(_value >= lockedAmount, "Cannot lock more than transferred value"); lockedBalances[_sender] += lockedAmount; totalLocked += lockedAmount; } } else { distributeToken(msg.sender); } } /** * @notice receipt tokens within the delegator pool cannot be transferred */ function _transfer( address, address, uint256 ) internal override { revert("Token cannot be transferred"); } /** * @notice returns an account's staked amount for use by reward pools * controlled by this contract * @dev excludes locked balances for community pools * @param _account account address * @return account's staked amount */ function staked(address _account) external view override returns (uint256) { return communityPools[msg.sender] ? balanceOf(_account) - lockedBalances[_account] : balanceOf(_account); } /** * @notice returns an accounts balance * @dev required for backwards compatability with the PoolRouter * @param _account account address * @return balance accounts balance */ function totalBalanceOf(address _account) external view returns (uint256) { return balanceOf(_account); } /** * @notice returns the total staked amount for use by reward pools * controlled by this contract * @return total staked amount */ function totalStaked() external view override returns (uint256) { return communityPools[msg.sender] ? totalSupply() - totalLocked : totalSupply(); } /** * @notice returns the available balance of an account, taking into account any locked and approved tokens * @param _account account address * @return available balance */ function availableBalanceOf(address _account) public view returns (uint256) { return balanceOf(_account) - lockedBalances[_account] + lockedApprovals[_account]; } /** * @notice returns the locked balance for a given account * @param _account account address * @return locked balance */ function lockedBalanceOf(address _account) public view returns (uint256) { return lockedBalances[_account] - lockedApprovals[_account]; } /** * @notice returns the approved locked balance for a given account * @param _account account address * @return approved locked balance */ function approvedLockedBalanceOf(address _account) external view returns (uint256) { return lockedApprovals[_account]; } /** * @notice withdraws allowance tokens if no pools are in reserve mode * @param _amount amount to withdraw **/ function withdrawAllowance(uint256 _amount) external updateRewards(msg.sender) { require(availableBalanceOf(msg.sender) >= _amount, "Withdrawal amount exceeds available balance"); uint256 unlockedBalance = balanceOf(msg.sender) - lockedBalances[msg.sender]; if (_amount > unlockedBalance) { uint256 approvedAmountToUnlock = _amount - unlockedBalance; lockedApprovals[msg.sender] -= approvedAmountToUnlock; lockedBalances[msg.sender] -= approvedAmountToUnlock; totalLocked -= approvedAmountToUnlock; } _burn(msg.sender, _amount); emit AllowanceWithdrawn(msg.sender, _amount); allowanceToken.safeTransfer(msg.sender, _amount); } /** * @notice approves an amount of locked balances to be withdrawn * @param _account account to approve locked balance * @param _amount account to approve */ function setLockedApproval(address _account, uint256 _amount) external onlyOwner { require(lockedBalances[_account] >= _amount, "Cannot approve more than locked balance"); lockedApprovals[_account] = _amount; } /** * @notice burns an amount of an accounts locked allowance token * @param _account account to burn tokens * @param _amount amount of tokens to burn */ function burnLockedBalance(address _account, uint256 _amount) external onlyOwner { require(lockedBalances[_account] >= _amount, "Cannot burn more than locked balance"); uint256 lockedApproval = lockedApprovals[_account]; if (lockedApproval != 0 && _amount >= lockedApproval) { delete lockedApprovals[_account]; } else if (lockedApproval != 0) { lockedApprovals[_account] -= _amount; } lockedBalances[_account] -= _amount; totalLocked -= _amount; _burn(_account, _amount); IStakingAllowance(address(allowanceToken)).burn(_amount); } /** * @notice sets the pool router address * @param _poolRouter pool router address **/ function setPoolRouter(address _poolRouter) external onlyOwner { require(address(poolRouter) == address(0), "pool router already set"); poolRouter = IPoolRouter(_poolRouter); } /** * @notice sets whether a given token pool is a community pool * @param _pool address of token pool * @param _isCommunityPool is community pool */ function setCommunityPool(address _pool, bool _isCommunityPool) external onlyOwner { require(address(tokenPools[_pool]) != address(0), "Token pool must exist"); communityPools[address(tokenPools[_pool])] = _isCommunityPool; } /** * @notice retires the contract * @param _lockedAddresses list of all operator addresses with a locked balance */ function retireDelegatorPool(address[] calldata _lockedAddresses, address _sdlPool) external onlyOwner { require(_sdlPool != address(0), "Invalid address"); allowanceToken.approve(_sdlPool, type(uint256).max); IRewardsPool rewardsPool = tokenPools[tokens[0]]; uint256 toBurn; for (uint256 i = 0; i < _lockedAddresses.length; ++i) { address account = _lockedAddresses[i]; uint256 unlockedBalance = availableBalanceOf(account); toBurn += lockedBalanceOf(account); rewardsPool.withdraw(account); _burn(account, balanceOf(account)); delete lockedBalances[account]; delete lockedApprovals[account]; if (unlockedBalance != 0) { ISDLPool(_sdlPool).migrate(account, unlockedBalance, 0); emit Migration(account, unlockedBalance); } } IStakingAllowance(address(allowanceToken)).burn(toBurn); totalLocked -= toBurn; sdlPool = _sdlPool; } /** * @notice migrates a stake to the new SDL pool * @param _amount amount of tokens to migrate * @param _lockingDuration duration of the lock in the SDL pool */ function migrate(uint256 _amount, uint64 _lockingDuration) external { require(sdlPool != address(0), "Cannot migrate until contract is retired"); require(_amount != 0, "Invalid amount"); require(_amount <= availableBalanceOf(msg.sender), "Insufficient balance"); tokenPools[tokens[0]].withdraw(msg.sender); _burn(msg.sender, _amount); ISDLPool(sdlPool).migrate(msg.sender, _amount, _lockingDuration); emit Migration(msg.sender, _amount); } /** * @notice stakes allowance tokens * @param _sender account to stake for * @param _amount amount to stake **/ function _stakeAllowance(address _sender, uint256 _amount) private updateRewards(_sender) { _mint(_sender, _amount); emit AllowanceStaked(_sender, _amount); } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"address","name":"rewardsPool","type":"address"}],"name":"AddToken","type":"event"},{"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":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"AllowanceStaked","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"AllowanceWithdrawn","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","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":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Migration","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"address","name":"rewardsPool","type":"address"}],"name":"RemoveToken","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"implementation","type":"address"}],"name":"Upgraded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"}],"name":"WithdrawRewards","type":"event"},{"inputs":[{"internalType":"string","name":"_tokenName","type":"string"},{"internalType":"string","name":"_tokenSymbol","type":"string"},{"internalType":"uint256","name":"_totalSupply","type":"uint256"}],"name":"__ERC677_init","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_derivativeTokenName","type":"string"},{"internalType":"string","name":"_derivativeTokenSymbol","type":"string"}],"name":"__RewardsPoolController_init","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"},{"internalType":"address","name":"_rewardsPool","type":"address"}],"name":"addToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"allowanceToken","outputs":[{"internalType":"contract IERC20Upgradeable","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_account","type":"address"}],"name":"approvedLockedBalanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_account","type":"address"}],"name":"availableBalanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_account","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"burnLockedBalance","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"communityPools","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"subtractedValue","type":"uint256"}],"name":"decreaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"}],"name":"distributeToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_tokens","type":"address[]"}],"name":"distributeTokens","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"feeCurve","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"addedValue","type":"uint256"}],"name":"increaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_allowanceToken","type":"address"},{"internalType":"string","name":"_dTokenName","type":"string"},{"internalType":"string","name":"_dTokenSymbol","type":"string"},{"internalType":"address[]","name":"_vestingAddresses","type":"address[]"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"}],"name":"isTokenSupported","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_account","type":"address"}],"name":"lockedBalanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"uint64","name":"_lockingDuration","type":"uint64"}],"name":"migrate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_sender","type":"address"},{"internalType":"uint256","name":"_value","type":"uint256"},{"internalType":"bytes","name":"_calldata","type":"bytes"}],"name":"onTokenTransfer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"poolRouter","outputs":[{"internalType":"contract IPoolRouter","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"proxiableUUID","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"redirectApprovals","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"redirectedStakes","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"}],"name":"removeToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_lockedAddresses","type":"address[]"},{"internalType":"address","name":"_sdlPool","type":"address"}],"name":"retireDelegatorPool","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"rewardRedirects","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"sdlPool","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_pool","type":"address"},{"internalType":"bool","name":"_isCommunityPool","type":"bool"}],"name":"setCommunityPool","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_account","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"setLockedApproval","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_poolRouter","type":"address"}],"name":"setPoolRouter","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_account","type":"address"}],"name":"staked","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"supportedTokens","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"tokenBalances","outputs":[{"internalType":"address[]","name":"","type":"address[]"},{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"tokenPools","outputs":[{"internalType":"contract IRewardsPool","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_account","type":"address"}],"name":"totalBalanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalLocked","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalStaked","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_value","type":"uint256"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"transferAndCall","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","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":"uint256","name":"_amount","type":"uint256"}],"name":"withdrawAllowance","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_tokens","type":"address[]"}],"name":"withdrawRewards","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_account","type":"address"}],"name":"withdrawableRewards","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"}]
Contract Creation Code
60a0604052306080523480156200001557600080fd5b506200002062000026565b620000e7565b600054610100900460ff1615620000935760405162461bcd60e51b815260206004820152602760248201527f496e697469616c697a61626c653a20636f6e747261637420697320696e697469604482015266616c697a696e6760c81b606482015260840160405180910390fd5b60005460ff90811614620000e5576000805460ff191660ff9081179091556040519081527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b565b6080516141b26200011f60003960008181610f0e01528181610f4e01528181611099015281816110d9015261120601526141b26000f3fe6080604052600436106103355760003560e01c8063628a0f55116101ab57806395d89b41116100f7578063b002249d11610095578063c3d2c3c11161006f578063c3d2c3c1146109dc578063d5d67d5114610a12578063dd62ed3e14610a33578063f2fde38b14610a5357600080fd5b8063b002249d14610979578063b63f46581461099b578063ba650f79146109bc57600080fd5b8063a3d69a1c116100d1578063a3d69a1c146108f9578063a457c2d714610919578063a4c0ed3614610939578063a9059cbb1461095957600080fd5b806395d89b41146108a457806398807d84146108b9578063a3ca91cc146108d957600080fd5b8063817b1cd21161016457806386d740371161013e57806386d740371461082657806388951352146108465780638d83d6cc146108665780638da5cb5b1461088657600080fd5b8063817b1cd2146107d0578063843cda00146107e5578063856695ea1461080557600080fd5b8063628a0f55146106fd57806362d76d061461072a57806370a082311461074a578063715018a61461076a57806375151b631461077f578063767e41a21461079f57600080fd5b80633a2e47cd116102855780635476bd72116102235780635a4d289d116101fd5780635a4d289d146106515780635b45fac4146106715780635fa7b584146106a7578063611fae02146106c757600080fd5b80635476bd72146105fa578063568914121461061a578063593557361461063157600080fd5b80634f1ef2861161025f5780634f1ef286146105795780635054d4e61461058c57806352d1902d146105ac5780635452b9ba146105c157600080fd5b80633a2e47cd146105195780634000aea0146105395780634b0ee02a1461055957600080fd5b806318160ddd116102f25780632b82d774116102cc5780632b82d7741461049d578063313ce567146104bd5780633659cfe6146104d957806339509351146104f957600080fd5b806318160ddd1461044857806323b872dd1461045d57806325d998bb1461047d57600080fd5b8063030a756b1461033a57806306fdde0314610384578063095ea7b3146103a65780630c8d9cc7146103d65780630e3bc974146103f85780630f14b4d61461041b575b600080fd5b34801561034657600080fd5b506103716103553660046135d8565b6001600160a01b03166000908152610105602052604090205490565b6040519081526020015b60405180910390f35b34801561039057600080fd5b50610399610a73565b60405161037b919061364b565b3480156103b257600080fd5b506103c66103c136600461365e565b610b05565b604051901515815260200161037b565b3480156103e257600080fd5b506103f66103f13660046135d8565b610b1f565b005b34801561040457600080fd5b5061040d610ba9565b60405161037b9291906136fc565b34801561042757600080fd5b5061043b6104363660046135d8565b610d24565b60405161037b919061372a565b34801561045457600080fd5b5060cb54610371565b34801561046957600080fd5b506103c661047836600461373d565b610e56565b34801561048957600080fd5b506103716104983660046135d8565b610e7a565b3480156104a957600080fd5b506103f66104b836600461382e565b610ebd565b3480156104c957600080fd5b506040516012815260200161037b565b3480156104e557600080fd5b506103f66104f43660046135d8565b610f04565b34801561050557600080fd5b506103c661051436600461365e565b610fe3565b34801561052557600080fd5b506103f6610534366004613891565b611005565b34801561054557600080fd5b506103c66105543660046138fd565b61105a565b34801561056557600080fd5b506103716105743660046135d8565b611084565b6103f6610587366004613953565b61108f565b34801561059857600080fd5b506103f66105a736600461365e565b61115b565b3480156105b857600080fd5b506103716111f9565b3480156105cd57600080fd5b50610101546105e2906001600160a01b031681565b6040516001600160a01b03909116815260200161037b565b34801561060657600080fd5b506103f6610615366004613996565b6112ac565b34801561062657600080fd5b506103716101075481565b34801561063d57600080fd5b5061037161064c3660046135d8565b611421565b34801561065d57600080fd5b506103f661066c3660046139c9565b611451565b34801561067d57600080fd5b506105e261068c3660046135d8565b60fd602052600090815260409020546001600160a01b031681565b3480156106b357600080fd5b506103f66106c23660046135d8565b61168e565b3480156106d357600080fd5b506105e26106e23660046135d8565b60ff602052600090815260409020546001600160a01b031681565b34801561070957600080fd5b506103716107183660046135d8565b60fe6020526000908152604090205481565b34801561073657600080fd5b506103f6610745366004613a05565b611855565b34801561075657600080fd5b506103716107653660046135d8565b611932565b34801561077657600080fd5b506103f661194d565b34801561078b57600080fd5b506103c661079a3660046135d8565b611961565b3480156107ab57600080fd5b506103c66107ba3660046135d8565b6101066020526000908152604090205460ff1681565b3480156107dc57600080fd5b50610371611991565b3480156107f157600080fd5b506103f661080036600461365e565b6119c6565b34801561081157600080fd5b50610102546105e2906001600160a01b031681565b34801561083257600080fd5b506103f66108413660046135d8565b611b7c565b34801561085257600080fd5b506103f6610861366004613a05565b611cff565b34801561087257600080fd5b506103f6610881366004613b3d565b611d3f565b34801561089257600080fd5b506097546001600160a01b03166105e2565b3480156108b057600080fd5b50610399611fd4565b3480156108c557600080fd5b506103716108d43660046135d8565b611fe3565b3480156108e557600080fd5b506103f66108f4366004613be7565b612036565b34801561090557600080fd5b506103f6610914366004613c48565b61239d565b34801561092557600080fd5b506103c661093436600461365e565b612440565b34801561094557600080fd5b506103f6610954366004613c74565b6124bb565b34801561096557600080fd5b506103c661097436600461365e565b612676565b34801561098557600080fd5b5061098e612684565b60405161037b9190613ccd565b3480156109a757600080fd5b50610108546105e2906001600160a01b031681565b3480156109c857600080fd5b506103f66109d7366004613ce0565b6126e5565b3480156109e857600080fd5b506105e26109f73660046135d8565b60fb602052600090815260409020546001600160a01b031681565b348015610a1e57600080fd5b50610100546105e2906001600160a01b031681565b348015610a3f57600080fd5b50610371610a4e366004613996565b612859565b348015610a5f57600080fd5b506103f6610a6e3660046135d8565b612884565b606060cc8054610a8290613cf9565b80601f0160208091040260200160405190810160405280929190818152602001828054610aae90613cf9565b8015610afb5780601f10610ad057610100808354040283529160200191610afb565b820191906000526020600020905b815481529060010190602001808311610ade57829003601f168201915b5050505050905090565b600033610b138185856128fa565b60019150505b92915050565b610b27612a1e565b610101546001600160a01b031615610b865760405162461bcd60e51b815260206004820152601760248201527f706f6f6c20726f7574657220616c72656164792073657400000000000000000060448201526064015b60405180910390fd5b61010180546001600160a01b0319166001600160a01b0392909216919091179055565b606080600060fc805490506001600160401b03811115610bcb57610bcb613779565b604051908082528060200260200182016040528015610bf4578160200160208202803683370190505b50905060005b60fc54811015610cbb5760fc8181548110610c1757610c17613d33565b6000918252602090912001546040516370a0823160e01b81523060048201526001600160a01b03909116906370a0823190602401602060405180830381865afa158015610c68573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c8c9190613d49565b828281518110610c9e57610c9e613d33565b602090810291909101015280610cb381613d78565b915050610bfa565b5060fc8181805480602002602001604051908101604052809291908181526020018280548015610d1457602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610cf6575b5050505050915092509250509091565b60fc546060906000906001600160401b03811115610d4457610d44613779565b604051908082528060200260200182016040528015610d6d578160200160208202803683370190505b50905060005b60fc54811015610e4f5760fb600060fc8381548110610d9457610d94613d33565b6000918252602080832091909101546001600160a01b039081168452908301939093526040918201902054905163078a5a6b60e11b81528683166004820152911690630f14b4d690602401602060405180830381865afa158015610dfc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e209190613d49565b828281518110610e3257610e32613d33565b602090810291909101015280610e4781613d78565b915050610d73565b5092915050565b600033610e64858285612a78565b610e6f858585612aec565b506001949350505050565b6001600160a01b03811660009081526101056020908152604080832054610104909252822054610ea984611932565b610eb39190613d91565b610b199190613da8565b600054610100900460ff16610ee45760405162461bcd60e51b8152600401610b7d90613dc0565b610ef082826000611005565b610ef8612b34565b610f00612b63565b5050565b6001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000163003610f4c5760405162461bcd60e51b8152600401610b7d90613e0b565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316610f95600080516020614136833981519152546001600160a01b031690565b6001600160a01b031614610fbb5760405162461bcd60e51b8152600401610b7d90613e57565b610fc481612b8a565b60408051600080825260208201909252610fe091839190612b92565b50565b600033610b13818585610ff68383612859565b6110009190613da8565b6128fa565b600054610100900460ff1661102c5760405162461bcd60e51b8152600401610b7d90613dc0565b6110368383612cfd565b611055336110466012600a613f87565b6110509084613f93565b612d2e565b505050565b60006110668484612676565b50833b1561107a5761107a33858585612def565b5060019392505050565b6000610b1982611932565b6001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001630036110d75760405162461bcd60e51b8152600401610b7d90613e0b565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316611120600080516020614136833981519152546001600160a01b031690565b6001600160a01b0316146111465760405162461bcd60e51b8152600401610b7d90613e57565b61114f82612b8a565b610f0082826001612b92565b611163612a1e565b6001600160a01b038216600090815261010460205260409020548111156111dc5760405162461bcd60e51b815260206004820152602760248201527f43616e6e6f7420617070726f7665206d6f7265207468616e206c6f636b65642060448201526662616c616e636560c81b6064820152608401610b7d565b6001600160a01b0390911660009081526101056020526040902055565b6000306001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146112995760405162461bcd60e51b815260206004820152603860248201527f555550535570677261646561626c653a206d757374206e6f742062652063616c60448201527f6c6564207468726f7567682064656c656761746563616c6c00000000000000006064820152608401610b7d565b5060008051602061413683398151915290565b6112b4612a1e565b6112bd82611961565b1561130a5760405162461bcd60e51b815260206004820152601a60248201527f546f6b656e20697320616c726561647920737570706f727465640000000000006044820152606401610b7d565b6001600160a01b03828116600081815260fb602052604080822080549486166001600160a01b031995861617905560fc80546001810182559083527f371f36870d18f32a11fea0f144b021c8b407bb50f8e0267c711123f454b963c0018054909416831790935591516370a0823160e01b81523060048201526370a0823190602401602060405180830381865afa1580156113a9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113cd9190613d49565b11156113dc576113dc82611b7c565b6040516001600160a01b0382811682528316907fdbf34b45b47a653cf4940cccbec765f72d4d63de3237306905bfc0ee28832362906020015b60405180910390a25050565b6001600160a01b03811660009081526101056020908152604080832054610104909252822054610b199190613d91565b610108546001600160a01b03166114bb5760405162461bcd60e51b815260206004820152602860248201527f43616e6e6f74206d69677261746520756e74696c20636f6e7472616374206973604482015267081c995d1a5c995960c21b6064820152608401610b7d565b816000036114fc5760405162461bcd60e51b815260206004820152600e60248201526d125b9d985b1a5908185b5bdd5b9d60921b6044820152606401610b7d565b61150533610e7a565b82111561154b5760405162461bcd60e51b8152602060048201526014602482015273496e73756666696369656e742062616c616e636560601b6044820152606401610b7d565b60fb600060fc60008154811061156357611563613d33565b6000918252602080832091909101546001600160a01b03908116845290830193909352604091820190205490516351cff8d960e01b81523360048201529116906351cff8d990602401600060405180830381600087803b1580156115c657600080fd5b505af11580156115da573d6000803e3d6000fd5b505050506115e83383612e5a565b610108546040516376a19e5b60e01b8152336004820152602481018490526001600160401b03831660448201526001600160a01b03909116906376a19e5b90606401600060405180830381600087803b15801561164457600080fd5b505af1158015611658573d6000803e3d6000fd5b50506040518481523392507f5c2da67751b5c2b8ffb1579ea16e70cf01e4b94068f0d42369de650adc07f6139150602001611415565b611696612a1e565b61169f81611961565b6116e45760405162461bcd60e51b8152602060048201526016602482015275151bdad95b881a5cc81b9bdd081cdd5c1c1bdc9d195960521b6044820152606401610b7d565b6001600160a01b03808216600090815260fb6020526040812080546001600160a01b03198116909155909116905b60fc5481101561181757826001600160a01b031660fc828154811061173957611739613d33565b6000918252602090912001546001600160a01b0316036118055760fc805461176390600190613d91565b8154811061177357611773613d33565b60009182526020909120015460fc80546001600160a01b03909216918390811061179f5761179f613d33565b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b0316021790555060fc8054806117de576117de613fb2565b600082815260209020810160001990810180546001600160a01b0319169055019055611817565b8061180f81613d78565b915050611712565b506040516001600160a01b0382811682528316907f39dcd754ec63af4b82c4c569ff1b6b4e55a8038e6545844747e54f2f2d4e8e5090602001611415565b60005b81518110156119035760fb600083838151811061187757611877613d33565b6020908102919091018101516001600160a01b0390811683529082019290925260409081016000205490516351cff8d960e01b81523360048201529116906351cff8d990602401600060405180830381600087803b1580156118d857600080fd5b505af11580156118ec573d6000803e3d6000fd5b5050505080806118fb90613d78565b915050611858565b5060405133907feeab3fd62be4cb59cbdc42d5b0f676a3597ff387b9a85e62330cc17c2a3603db90600090a250565b6001600160a01b0316600090815260c9602052604090205490565b611955612a1e565b61195f6000612f8e565b565b6001600160a01b03818116600090815260fb6020526040812054909116611989576000610b19565b600192915050565b336000908152610106602052604081205460ff166119b0575060cb5490565b6101075460cb546119c19190613d91565b905090565b6119ce612a1e565b6001600160a01b03821660009081526101046020526040902054811115611a435760405162461bcd60e51b8152602060048201526024808201527f43616e6e6f74206275726e206d6f7265207468616e206c6f636b65642062616c604482015263616e636560e01b6064820152608401610b7d565b6001600160a01b038216600090815261010560205260409020548015801590611a6c5750808210155b15611a90576001600160a01b03831660009081526101056020526040812055611ac5565b8015611ac5576001600160a01b0383166000908152610105602052604081208054849290611abf908490613d91565b90915550505b6001600160a01b0383166000908152610104602052604081208054849290611aee908490613d91565b92505081905550816101076000828254611b089190613d91565b90915550611b1890508383612e5a565b61010054604051630852cd8d60e31b8152600481018490526001600160a01b03909116906342966c6890602401600060405180830381600087803b158015611b5f57600080fd5b505af1158015611b73573d6000803e3d6000fd5b50505050505050565b611b8581611961565b611bc75760405162461bcd60e51b8152602060048201526013602482015272151bdad95b881b9bdd081cdd5c1c1bdc9d1959606a1b6044820152606401610b7d565b6040516370a0823160e01b815230600482015281906000906001600160a01b038316906370a0823190602401602060405180830381865afa158015611c10573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c349190613d49565b905060008111611c865760405162461bcd60e51b815260206004820152601e60248201527f43616e6e6f742064697374726962757465207a65726f2062616c616e636500006044820152606401610b7d565b6001600160a01b03808416600090815260fb6020526040902054611caf91848116911683612fe0565b6001600160a01b03808416600090815260fb60205260408082205481516306f4a2cd60e41b81529151931692636f4a2cd09260048084019391929182900301818387803b158015611b5f57600080fd5b60005b8151811015610f0057611d2d828281518110611d2057611d20613d33565b6020026020010151611b7c565b80611d3781613d78565b915050611d02565b600054600290610100900460ff16158015611d61575060005460ff8083169116105b611dc45760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401610b7d565b6000805461ffff191660ff831617610100908117909155546001600160a01b0316611e7d57611e5c87878080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080516020601f8b018190048102820181019092528981529250899150889081908401838280828437600092019190915250610ebd92505050565b61010080546001600160a01b0319166001600160a01b038a16179055611f89565b60005b82811015611f87576000848483818110611e9c57611e9c613d33565b9050602002016020810190611eb191906135d8565b6001600160a01b038116600081815261010360209081526040808320815160608101835281548082526001909201546001600160401b038082168387015268010000000000000000909104168184015294845261010490925282208054949550929390929190611f22908490613da8565b909155505080516101078054600090611f3c908490613da8565b9091555050506001600160a01b031660009081526101036020526040812090815560010180546fffffffffffffffffffffffffffffffff19169055611f8081613d78565b9050611e80565b505b6000805461ff001916905560405160ff821681527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15050505050505050565b606060cd8054610a8290613cf9565b336000908152610106602052604081205460ff166120095761200482611932565b610b19565b6001600160a01b0382166000908152610104602052604090205461202c83611932565b610b199190613d91565b61203e612a1e565b6001600160a01b0381166120865760405162461bcd60e51b815260206004820152600f60248201526e496e76616c6964206164647265737360881b6044820152606401610b7d565b6101005460405163095ea7b360e01b81526001600160a01b03838116600483015260001960248301529091169063095ea7b3906044016020604051808303816000875af11580156120db573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120ff9190613fc8565b50600060fb600060fc60008154811061211a5761211a613d33565b60009182526020808320909101546001600160a01b0390811684529083019390935260409091018120549091169150805b848110156122fd57600086868381811061216757612167613d33565b905060200201602081019061217c91906135d8565b9050600061218982610e7a565b905061219482611421565b61219e9085613da8565b6040516351cff8d960e01b81526001600160a01b038481166004830152919550908616906351cff8d990602401600060405180830381600087803b1580156121e557600080fd5b505af11580156121f9573d6000803e3d6000fd5b5050505061220f8261220a84611932565b612e5a565b6001600160a01b03821660009081526101046020908152604080832083905561010590915281205580156122ea576040516376a19e5b60e01b81526001600160a01b03838116600483015260248201839052600060448301528716906376a19e5b90606401600060405180830381600087803b15801561228e57600080fd5b505af11580156122a2573d6000803e3d6000fd5b50505050816001600160a01b03167f5c2da67751b5c2b8ffb1579ea16e70cf01e4b94068f0d42369de650adc07f613826040516122e191815260200190565b60405180910390a25b5050806122f690613d78565b905061214b565b5061010054604051630852cd8d60e31b8152600481018390526001600160a01b03909116906342966c6890602401600060405180830381600087803b15801561234557600080fd5b505af1158015612359573d6000803e3d6000fd5b505050508061010760008282546123709190613d91565b909155505061010880546001600160a01b0319166001600160a01b03949094169390931790925550505050565b6123a5612a1e565b6001600160a01b03828116600090815260fb6020526040902054166124045760405162461bcd60e51b8152602060048201526015602482015274151bdad95b881c1bdbdb081b5d5cdd08195e1a5cdd605a1b6044820152606401610b7d565b6001600160a01b03918216600090815260fb60209081526040808320549094168252610106905291909120805460ff1916911515919091179055565b6000338161244e8286612859565b9050838110156124ae5760405162461bcd60e51b815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f77604482015264207a65726f60d81b6064820152608401610b7d565b610e6f82868684036128fa565b610108546001600160a01b0316156125095760405162461bcd60e51b815260206004820152601160248201527011195c1bdcda5d1cc8191a5cd8589b1959607a1b6044820152606401610b7d565b610100546001600160a01b0316331480612527575061252733611961565b6125855760405162461bcd60e51b815260206004820152602960248201527f53656e646572206d75737420626520616c6c6f77616e6365206f722072657761604482015268393239903a37b5b2b760b91b6064820152608401610b7d565b610100546001600160a01b03163303612667576125a28484613032565b80156126625760006125b682840184613ce0565b9050808410156126185760405162461bcd60e51b815260206004820152602760248201527f43616e6e6f74206c6f636b206d6f7265207468616e207472616e736665727265604482015266642076616c756560c81b6064820152608401610b7d565b6001600160a01b0385166000908152610104602052604081208054839290612641908490613da8565b9250508190555080610107600082825461265b9190613da8565b9091555050505b612670565b61267033611b7c565b50505050565b600033610b13818585612aec565b606060fc805480602002602001604051908101604052809291908181526020018280548015610afb57602002820191906000526020600020905b81546001600160a01b031681526001909101906020018083116126be575050505050905090565b336126ef8161308e565b816126f933610e7a565b101561275b5760405162461bcd60e51b815260206004820152602b60248201527f5769746864726177616c20616d6f756e74206578636565647320617661696c6160448201526a626c652062616c616e636560a81b6064820152608401610b7d565b3360008181526101046020526040812054909161277790611932565b6127819190613d91565b9050808311156128025760006127978285613d91565b33600090815261010560205260408120805492935083929091906127bc908490613d91565b90915550503360009081526101046020526040812080548392906127e1908490613d91565b925050819055508061010760008282546127fb9190613d91565b9091555050505b61280c3384612e5a565b60405183815233907fcb4e4a5b4e544d9c587ec3ac0eead830ce8a4cccfe48b8dc331d447c481be8979060200160405180910390a261010054611055906001600160a01b03163385612fe0565b6001600160a01b03918216600090815260ca6020908152604080832093909416825291909152205490565b61288c612a1e565b6001600160a01b0381166128f15760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610b7d565b610fe081612f8e565b6001600160a01b03831661295c5760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f206164646044820152637265737360e01b6064820152608401610b7d565b6001600160a01b0382166129bd5760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f206164647265604482015261737360f01b6064820152608401610b7d565b6001600160a01b03838116600081815260ca602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050565b6097546001600160a01b0316331461195f5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610b7d565b6000612a848484612859565b905060001981146126705781811015612adf5760405162461bcd60e51b815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e63650000006044820152606401610b7d565b61267084848484036128fa565b60405162461bcd60e51b815260206004820152601b60248201527f546f6b656e2063616e6e6f74206265207472616e7366657272656400000000006044820152606401610b7d565b600054610100900460ff16612b5b5760405162461bcd60e51b8152600401610b7d90613dc0565b61195f613142565b600054610100900460ff1661195f5760405162461bcd60e51b8152600401610b7d90613dc0565b610fe0612a1e565b7f4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd91435460ff1615612bc55761105583613172565b826001600160a01b03166352d1902d6040518163ffffffff1660e01b8152600401602060405180830381865afa925050508015612c1f575060408051601f3d908101601f19168201909252612c1c91810190613d49565b60015b612c825760405162461bcd60e51b815260206004820152602e60248201527f45524331393637557067726164653a206e657720696d706c656d656e7461746960448201526d6f6e206973206e6f74205555505360901b6064820152608401610b7d565b6000805160206141368339815191528114612cf15760405162461bcd60e51b815260206004820152602960248201527f45524331393637557067726164653a20756e737570706f727465642070726f786044820152681a58589b195555525160ba1b6064820152608401610b7d565b5061105583838361320e565b600054610100900460ff16612d245760405162461bcd60e51b8152600401610b7d90613dc0565b610f008282613233565b6001600160a01b038216612d845760405162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f2061646472657373006044820152606401610b7d565b8060cb6000828254612d969190613da8565b90915550506001600160a01b038216600081815260c960209081526040808320805486019055518481527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a35050565b604051635260769b60e11b815283906001600160a01b0382169063a4c0ed3690612e2190889087908790600401613fe5565b600060405180830381600087803b158015612e3b57600080fd5b505af1158015612e4f573d6000803e3d6000fd5b505050505050505050565b6001600160a01b038216612eba5760405162461bcd60e51b815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f206164647265736044820152607360f81b6064820152608401610b7d565b6001600160a01b038216600090815260c9602052604090205481811015612f2e5760405162461bcd60e51b815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e604482015261636560f01b6064820152608401610b7d565b6001600160a01b038316600081815260c960209081526040808320868603905560cb80548790039055518581529192917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a3505050565b609780546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b179052611055908490613273565b8161303c8161308e565b6130468383612d2e565b826001600160a01b03167f60df8ac38837b0ae1b717d64eba4a631341a9365ed654aa2cb3ed7657d65acee8360405161308191815260200190565b60405180910390a2505050565b60005b60fc54811015610f005760fb600060fc83815481106130b2576130b2613d33565b6000918252602080832091909101546001600160a01b039081168452908301939093526040918201902054905163632447c960e01b8152848316600482015291169063632447c990602401600060405180830381600087803b15801561311757600080fd5b505af115801561312b573d6000803e3d6000fd5b50505050808061313a90613d78565b915050613091565b600054610100900460ff166131695760405162461bcd60e51b8152600401610b7d90613dc0565b61195f33612f8e565b6001600160a01b0381163b6131df5760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b6064820152608401610b7d565b60008051602061413683398151915280546001600160a01b0319166001600160a01b0392909216919091179055565b61321783613348565b6000825111806132245750805b15611055576126708383613388565b600054610100900460ff1661325a5760405162461bcd60e51b8152600401610b7d90613dc0565b60cc613266838261405a565b5060cd611055828261405a565b60006132c8826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166133b49092919063ffffffff16565b90508051600014806132e95750808060200190518101906132e99190613fc8565b6110555760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608401610b7d565b61335181613172565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b60606133ad8383604051806060016040528060278152602001614156602791396133cb565b9392505050565b60606133c38484600085613443565b949350505050565b6060600080856001600160a01b0316856040516133e89190614119565b600060405180830381855af49150503d8060008114613423576040519150601f19603f3d011682016040523d82523d6000602084013e613428565b606091505b50915091506134398683838761351e565b9695505050505050565b6060824710156134a45760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b6064820152608401610b7d565b600080866001600160a01b031685876040516134c09190614119565b60006040518083038185875af1925050503d80600081146134fd576040519150601f19603f3d011682016040523d82523d6000602084013e613502565b606091505b50915091506135138783838761351e565b979650505050505050565b6060831561358d578251600003613586576001600160a01b0385163b6135865760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610b7d565b50816133c3565b6133c383838151156135a25781518083602001fd5b8060405162461bcd60e51b8152600401610b7d919061364b565b80356001600160a01b03811681146135d357600080fd5b919050565b6000602082840312156135ea57600080fd5b6133ad826135bc565b60005b8381101561360e5781810151838201526020016135f6565b838111156126705750506000910152565b600081518084526136378160208601602086016135f3565b601f01601f19169290920160200192915050565b6020815260006133ad602083018461361f565b6000806040838503121561367157600080fd5b61367a836135bc565b946020939093013593505050565b600081518084526020808501945080840160005b838110156136c15781516001600160a01b03168752958201959082019060010161369c565b509495945050505050565b600081518084526020808501945080840160005b838110156136c1578151875295820195908201906001016136e0565b60408152600061370f6040830185613688565b828103602084015261372181856136cc565b95945050505050565b6020815260006133ad60208301846136cc565b60008060006060848603121561375257600080fd5b61375b846135bc565b9250613769602085016135bc565b9150604084013590509250925092565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f191681016001600160401b03811182821017156137b7576137b7613779565b604052919050565b600082601f8301126137d057600080fd5b81356001600160401b038111156137e9576137e9613779565b6137fc601f8201601f191660200161378f565b81815284602083860101111561381157600080fd5b816020850160208301376000918101602001919091529392505050565b6000806040838503121561384157600080fd5b82356001600160401b038082111561385857600080fd5b613864868387016137bf565b9350602085013591508082111561387a57600080fd5b50613887858286016137bf565b9150509250929050565b6000806000606084860312156138a657600080fd5b83356001600160401b03808211156138bd57600080fd5b6138c9878388016137bf565b945060208601359150808211156138df57600080fd5b506138ec868287016137bf565b925050604084013590509250925092565b60008060006060848603121561391257600080fd5b61391b846135bc565b92506020840135915060408401356001600160401b0381111561393d57600080fd5b613949868287016137bf565b9150509250925092565b6000806040838503121561396657600080fd5b61396f836135bc565b915060208301356001600160401b0381111561398a57600080fd5b613887858286016137bf565b600080604083850312156139a957600080fd5b6139b2836135bc565b91506139c0602084016135bc565b90509250929050565b600080604083850312156139dc57600080fd5b8235915060208301356001600160401b03811681146139fa57600080fd5b809150509250929050565b60006020808385031215613a1857600080fd5b82356001600160401b0380821115613a2f57600080fd5b818501915085601f830112613a4357600080fd5b813581811115613a5557613a55613779565b8060051b9150613a6684830161378f565b8181529183018401918481019088841115613a8057600080fd5b938501935b83851015613aa557613a96856135bc565b82529385019390850190613a85565b98975050505050505050565b60008083601f840112613ac357600080fd5b5081356001600160401b03811115613ada57600080fd5b602083019150836020828501011115613af257600080fd5b9250929050565b60008083601f840112613b0b57600080fd5b5081356001600160401b03811115613b2257600080fd5b6020830191508360208260051b8501011115613af257600080fd5b60008060008060008060006080888a031215613b5857600080fd5b613b61886135bc565b965060208801356001600160401b0380821115613b7d57600080fd5b613b898b838c01613ab1565b909850965060408a0135915080821115613ba257600080fd5b613bae8b838c01613ab1565b909650945060608a0135915080821115613bc757600080fd5b50613bd48a828b01613af9565b989b979a50959850939692959293505050565b600080600060408486031215613bfc57600080fd5b83356001600160401b03811115613c1257600080fd5b613c1e86828701613af9565b9094509250613c319050602085016135bc565b90509250925092565b8015158114610fe057600080fd5b60008060408385031215613c5b57600080fd5b613c64836135bc565b915060208301356139fa81613c3a565b60008060008060608587031215613c8a57600080fd5b613c93856135bc565b93506020850135925060408501356001600160401b03811115613cb557600080fd5b613cc187828801613ab1565b95989497509550505050565b6020815260006133ad6020830184613688565b600060208284031215613cf257600080fd5b5035919050565b600181811c90821680613d0d57607f821691505b602082108103613d2d57634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052603260045260246000fd5b600060208284031215613d5b57600080fd5b5051919050565b634e487b7160e01b600052601160045260246000fd5b600060018201613d8a57613d8a613d62565b5060010190565b600082821015613da357613da3613d62565b500390565b60008219821115613dbb57613dbb613d62565b500190565b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b606082015260800190565b6020808252602c908201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060408201526b19195b1959d85d1958d85b1b60a21b606082015260800190565b6020808252602c908201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060408201526b6163746976652070726f787960a01b606082015260800190565b600181815b80851115613ede578160001904821115613ec457613ec4613d62565b80851615613ed157918102915b93841c9390800290613ea8565b509250929050565b600082613ef557506001610b19565b81613f0257506000610b19565b8160018114613f185760028114613f2257613f3e565b6001915050610b19565b60ff841115613f3357613f33613d62565b50506001821b610b19565b5060208310610133831016604e8410600b8410161715613f61575081810a610b19565b613f6b8383613ea3565b8060001904821115613f7f57613f7f613d62565b029392505050565b60006133ad8383613ee6565b6000816000190483118215151615613fad57613fad613d62565b500290565b634e487b7160e01b600052603160045260246000fd5b600060208284031215613fda57600080fd5b81516133ad81613c3a565b60018060a01b0384168152826020820152606060408201526000613721606083018461361f565b601f82111561105557600081815260208120601f850160051c810160208610156140335750805b601f850160051c820191505b818110156140525782815560010161403f565b505050505050565b81516001600160401b0381111561407357614073613779565b614087816140818454613cf9565b8461400c565b602080601f8311600181146140bc57600084156140a45750858301515b600019600386901b1c1916600185901b178555614052565b600085815260208120601f198616915b828110156140eb578886015182559484019460019091019084016140cc565b50858210156141095787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b6000825161412b8184602087016135f3565b919091019291505056fe360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220afa15878e5d0f7ed19cc8dde4ac72d5905c7071c221a2be428c1c8489f5618d464736f6c634300080f0033
Deployed Bytecode
0x6080604052600436106103355760003560e01c8063628a0f55116101ab57806395d89b41116100f7578063b002249d11610095578063c3d2c3c11161006f578063c3d2c3c1146109dc578063d5d67d5114610a12578063dd62ed3e14610a33578063f2fde38b14610a5357600080fd5b8063b002249d14610979578063b63f46581461099b578063ba650f79146109bc57600080fd5b8063a3d69a1c116100d1578063a3d69a1c146108f9578063a457c2d714610919578063a4c0ed3614610939578063a9059cbb1461095957600080fd5b806395d89b41146108a457806398807d84146108b9578063a3ca91cc146108d957600080fd5b8063817b1cd21161016457806386d740371161013e57806386d740371461082657806388951352146108465780638d83d6cc146108665780638da5cb5b1461088657600080fd5b8063817b1cd2146107d0578063843cda00146107e5578063856695ea1461080557600080fd5b8063628a0f55146106fd57806362d76d061461072a57806370a082311461074a578063715018a61461076a57806375151b631461077f578063767e41a21461079f57600080fd5b80633a2e47cd116102855780635476bd72116102235780635a4d289d116101fd5780635a4d289d146106515780635b45fac4146106715780635fa7b584146106a7578063611fae02146106c757600080fd5b80635476bd72146105fa578063568914121461061a578063593557361461063157600080fd5b80634f1ef2861161025f5780634f1ef286146105795780635054d4e61461058c57806352d1902d146105ac5780635452b9ba146105c157600080fd5b80633a2e47cd146105195780634000aea0146105395780634b0ee02a1461055957600080fd5b806318160ddd116102f25780632b82d774116102cc5780632b82d7741461049d578063313ce567146104bd5780633659cfe6146104d957806339509351146104f957600080fd5b806318160ddd1461044857806323b872dd1461045d57806325d998bb1461047d57600080fd5b8063030a756b1461033a57806306fdde0314610384578063095ea7b3146103a65780630c8d9cc7146103d65780630e3bc974146103f85780630f14b4d61461041b575b600080fd5b34801561034657600080fd5b506103716103553660046135d8565b6001600160a01b03166000908152610105602052604090205490565b6040519081526020015b60405180910390f35b34801561039057600080fd5b50610399610a73565b60405161037b919061364b565b3480156103b257600080fd5b506103c66103c136600461365e565b610b05565b604051901515815260200161037b565b3480156103e257600080fd5b506103f66103f13660046135d8565b610b1f565b005b34801561040457600080fd5b5061040d610ba9565b60405161037b9291906136fc565b34801561042757600080fd5b5061043b6104363660046135d8565b610d24565b60405161037b919061372a565b34801561045457600080fd5b5060cb54610371565b34801561046957600080fd5b506103c661047836600461373d565b610e56565b34801561048957600080fd5b506103716104983660046135d8565b610e7a565b3480156104a957600080fd5b506103f66104b836600461382e565b610ebd565b3480156104c957600080fd5b506040516012815260200161037b565b3480156104e557600080fd5b506103f66104f43660046135d8565b610f04565b34801561050557600080fd5b506103c661051436600461365e565b610fe3565b34801561052557600080fd5b506103f6610534366004613891565b611005565b34801561054557600080fd5b506103c66105543660046138fd565b61105a565b34801561056557600080fd5b506103716105743660046135d8565b611084565b6103f6610587366004613953565b61108f565b34801561059857600080fd5b506103f66105a736600461365e565b61115b565b3480156105b857600080fd5b506103716111f9565b3480156105cd57600080fd5b50610101546105e2906001600160a01b031681565b6040516001600160a01b03909116815260200161037b565b34801561060657600080fd5b506103f6610615366004613996565b6112ac565b34801561062657600080fd5b506103716101075481565b34801561063d57600080fd5b5061037161064c3660046135d8565b611421565b34801561065d57600080fd5b506103f661066c3660046139c9565b611451565b34801561067d57600080fd5b506105e261068c3660046135d8565b60fd602052600090815260409020546001600160a01b031681565b3480156106b357600080fd5b506103f66106c23660046135d8565b61168e565b3480156106d357600080fd5b506105e26106e23660046135d8565b60ff602052600090815260409020546001600160a01b031681565b34801561070957600080fd5b506103716107183660046135d8565b60fe6020526000908152604090205481565b34801561073657600080fd5b506103f6610745366004613a05565b611855565b34801561075657600080fd5b506103716107653660046135d8565b611932565b34801561077657600080fd5b506103f661194d565b34801561078b57600080fd5b506103c661079a3660046135d8565b611961565b3480156107ab57600080fd5b506103c66107ba3660046135d8565b6101066020526000908152604090205460ff1681565b3480156107dc57600080fd5b50610371611991565b3480156107f157600080fd5b506103f661080036600461365e565b6119c6565b34801561081157600080fd5b50610102546105e2906001600160a01b031681565b34801561083257600080fd5b506103f66108413660046135d8565b611b7c565b34801561085257600080fd5b506103f6610861366004613a05565b611cff565b34801561087257600080fd5b506103f6610881366004613b3d565b611d3f565b34801561089257600080fd5b506097546001600160a01b03166105e2565b3480156108b057600080fd5b50610399611fd4565b3480156108c557600080fd5b506103716108d43660046135d8565b611fe3565b3480156108e557600080fd5b506103f66108f4366004613be7565b612036565b34801561090557600080fd5b506103f6610914366004613c48565b61239d565b34801561092557600080fd5b506103c661093436600461365e565b612440565b34801561094557600080fd5b506103f6610954366004613c74565b6124bb565b34801561096557600080fd5b506103c661097436600461365e565b612676565b34801561098557600080fd5b5061098e612684565b60405161037b9190613ccd565b3480156109a757600080fd5b50610108546105e2906001600160a01b031681565b3480156109c857600080fd5b506103f66109d7366004613ce0565b6126e5565b3480156109e857600080fd5b506105e26109f73660046135d8565b60fb602052600090815260409020546001600160a01b031681565b348015610a1e57600080fd5b50610100546105e2906001600160a01b031681565b348015610a3f57600080fd5b50610371610a4e366004613996565b612859565b348015610a5f57600080fd5b506103f6610a6e3660046135d8565b612884565b606060cc8054610a8290613cf9565b80601f0160208091040260200160405190810160405280929190818152602001828054610aae90613cf9565b8015610afb5780601f10610ad057610100808354040283529160200191610afb565b820191906000526020600020905b815481529060010190602001808311610ade57829003601f168201915b5050505050905090565b600033610b138185856128fa565b60019150505b92915050565b610b27612a1e565b610101546001600160a01b031615610b865760405162461bcd60e51b815260206004820152601760248201527f706f6f6c20726f7574657220616c72656164792073657400000000000000000060448201526064015b60405180910390fd5b61010180546001600160a01b0319166001600160a01b0392909216919091179055565b606080600060fc805490506001600160401b03811115610bcb57610bcb613779565b604051908082528060200260200182016040528015610bf4578160200160208202803683370190505b50905060005b60fc54811015610cbb5760fc8181548110610c1757610c17613d33565b6000918252602090912001546040516370a0823160e01b81523060048201526001600160a01b03909116906370a0823190602401602060405180830381865afa158015610c68573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c8c9190613d49565b828281518110610c9e57610c9e613d33565b602090810291909101015280610cb381613d78565b915050610bfa565b5060fc8181805480602002602001604051908101604052809291908181526020018280548015610d1457602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610cf6575b5050505050915092509250509091565b60fc546060906000906001600160401b03811115610d4457610d44613779565b604051908082528060200260200182016040528015610d6d578160200160208202803683370190505b50905060005b60fc54811015610e4f5760fb600060fc8381548110610d9457610d94613d33565b6000918252602080832091909101546001600160a01b039081168452908301939093526040918201902054905163078a5a6b60e11b81528683166004820152911690630f14b4d690602401602060405180830381865afa158015610dfc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e209190613d49565b828281518110610e3257610e32613d33565b602090810291909101015280610e4781613d78565b915050610d73565b5092915050565b600033610e64858285612a78565b610e6f858585612aec565b506001949350505050565b6001600160a01b03811660009081526101056020908152604080832054610104909252822054610ea984611932565b610eb39190613d91565b610b199190613da8565b600054610100900460ff16610ee45760405162461bcd60e51b8152600401610b7d90613dc0565b610ef082826000611005565b610ef8612b34565b610f00612b63565b5050565b6001600160a01b037f00000000000000000000000086637a9aba90204575db67451ba273b01cada2a3163003610f4c5760405162461bcd60e51b8152600401610b7d90613e0b565b7f00000000000000000000000086637a9aba90204575db67451ba273b01cada2a36001600160a01b0316610f95600080516020614136833981519152546001600160a01b031690565b6001600160a01b031614610fbb5760405162461bcd60e51b8152600401610b7d90613e57565b610fc481612b8a565b60408051600080825260208201909252610fe091839190612b92565b50565b600033610b13818585610ff68383612859565b6110009190613da8565b6128fa565b600054610100900460ff1661102c5760405162461bcd60e51b8152600401610b7d90613dc0565b6110368383612cfd565b611055336110466012600a613f87565b6110509084613f93565b612d2e565b505050565b60006110668484612676565b50833b1561107a5761107a33858585612def565b5060019392505050565b6000610b1982611932565b6001600160a01b037f00000000000000000000000086637a9aba90204575db67451ba273b01cada2a31630036110d75760405162461bcd60e51b8152600401610b7d90613e0b565b7f00000000000000000000000086637a9aba90204575db67451ba273b01cada2a36001600160a01b0316611120600080516020614136833981519152546001600160a01b031690565b6001600160a01b0316146111465760405162461bcd60e51b8152600401610b7d90613e57565b61114f82612b8a565b610f0082826001612b92565b611163612a1e565b6001600160a01b038216600090815261010460205260409020548111156111dc5760405162461bcd60e51b815260206004820152602760248201527f43616e6e6f7420617070726f7665206d6f7265207468616e206c6f636b65642060448201526662616c616e636560c81b6064820152608401610b7d565b6001600160a01b0390911660009081526101056020526040902055565b6000306001600160a01b037f00000000000000000000000086637a9aba90204575db67451ba273b01cada2a316146112995760405162461bcd60e51b815260206004820152603860248201527f555550535570677261646561626c653a206d757374206e6f742062652063616c60448201527f6c6564207468726f7567682064656c656761746563616c6c00000000000000006064820152608401610b7d565b5060008051602061413683398151915290565b6112b4612a1e565b6112bd82611961565b1561130a5760405162461bcd60e51b815260206004820152601a60248201527f546f6b656e20697320616c726561647920737570706f727465640000000000006044820152606401610b7d565b6001600160a01b03828116600081815260fb602052604080822080549486166001600160a01b031995861617905560fc80546001810182559083527f371f36870d18f32a11fea0f144b021c8b407bb50f8e0267c711123f454b963c0018054909416831790935591516370a0823160e01b81523060048201526370a0823190602401602060405180830381865afa1580156113a9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113cd9190613d49565b11156113dc576113dc82611b7c565b6040516001600160a01b0382811682528316907fdbf34b45b47a653cf4940cccbec765f72d4d63de3237306905bfc0ee28832362906020015b60405180910390a25050565b6001600160a01b03811660009081526101056020908152604080832054610104909252822054610b199190613d91565b610108546001600160a01b03166114bb5760405162461bcd60e51b815260206004820152602860248201527f43616e6e6f74206d69677261746520756e74696c20636f6e7472616374206973604482015267081c995d1a5c995960c21b6064820152608401610b7d565b816000036114fc5760405162461bcd60e51b815260206004820152600e60248201526d125b9d985b1a5908185b5bdd5b9d60921b6044820152606401610b7d565b61150533610e7a565b82111561154b5760405162461bcd60e51b8152602060048201526014602482015273496e73756666696369656e742062616c616e636560601b6044820152606401610b7d565b60fb600060fc60008154811061156357611563613d33565b6000918252602080832091909101546001600160a01b03908116845290830193909352604091820190205490516351cff8d960e01b81523360048201529116906351cff8d990602401600060405180830381600087803b1580156115c657600080fd5b505af11580156115da573d6000803e3d6000fd5b505050506115e83383612e5a565b610108546040516376a19e5b60e01b8152336004820152602481018490526001600160401b03831660448201526001600160a01b03909116906376a19e5b90606401600060405180830381600087803b15801561164457600080fd5b505af1158015611658573d6000803e3d6000fd5b50506040518481523392507f5c2da67751b5c2b8ffb1579ea16e70cf01e4b94068f0d42369de650adc07f6139150602001611415565b611696612a1e565b61169f81611961565b6116e45760405162461bcd60e51b8152602060048201526016602482015275151bdad95b881a5cc81b9bdd081cdd5c1c1bdc9d195960521b6044820152606401610b7d565b6001600160a01b03808216600090815260fb6020526040812080546001600160a01b03198116909155909116905b60fc5481101561181757826001600160a01b031660fc828154811061173957611739613d33565b6000918252602090912001546001600160a01b0316036118055760fc805461176390600190613d91565b8154811061177357611773613d33565b60009182526020909120015460fc80546001600160a01b03909216918390811061179f5761179f613d33565b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b0316021790555060fc8054806117de576117de613fb2565b600082815260209020810160001990810180546001600160a01b0319169055019055611817565b8061180f81613d78565b915050611712565b506040516001600160a01b0382811682528316907f39dcd754ec63af4b82c4c569ff1b6b4e55a8038e6545844747e54f2f2d4e8e5090602001611415565b60005b81518110156119035760fb600083838151811061187757611877613d33565b6020908102919091018101516001600160a01b0390811683529082019290925260409081016000205490516351cff8d960e01b81523360048201529116906351cff8d990602401600060405180830381600087803b1580156118d857600080fd5b505af11580156118ec573d6000803e3d6000fd5b5050505080806118fb90613d78565b915050611858565b5060405133907feeab3fd62be4cb59cbdc42d5b0f676a3597ff387b9a85e62330cc17c2a3603db90600090a250565b6001600160a01b0316600090815260c9602052604090205490565b611955612a1e565b61195f6000612f8e565b565b6001600160a01b03818116600090815260fb6020526040812054909116611989576000610b19565b600192915050565b336000908152610106602052604081205460ff166119b0575060cb5490565b6101075460cb546119c19190613d91565b905090565b6119ce612a1e565b6001600160a01b03821660009081526101046020526040902054811115611a435760405162461bcd60e51b8152602060048201526024808201527f43616e6e6f74206275726e206d6f7265207468616e206c6f636b65642062616c604482015263616e636560e01b6064820152608401610b7d565b6001600160a01b038216600090815261010560205260409020548015801590611a6c5750808210155b15611a90576001600160a01b03831660009081526101056020526040812055611ac5565b8015611ac5576001600160a01b0383166000908152610105602052604081208054849290611abf908490613d91565b90915550505b6001600160a01b0383166000908152610104602052604081208054849290611aee908490613d91565b92505081905550816101076000828254611b089190613d91565b90915550611b1890508383612e5a565b61010054604051630852cd8d60e31b8152600481018490526001600160a01b03909116906342966c6890602401600060405180830381600087803b158015611b5f57600080fd5b505af1158015611b73573d6000803e3d6000fd5b50505050505050565b611b8581611961565b611bc75760405162461bcd60e51b8152602060048201526013602482015272151bdad95b881b9bdd081cdd5c1c1bdc9d1959606a1b6044820152606401610b7d565b6040516370a0823160e01b815230600482015281906000906001600160a01b038316906370a0823190602401602060405180830381865afa158015611c10573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c349190613d49565b905060008111611c865760405162461bcd60e51b815260206004820152601e60248201527f43616e6e6f742064697374726962757465207a65726f2062616c616e636500006044820152606401610b7d565b6001600160a01b03808416600090815260fb6020526040902054611caf91848116911683612fe0565b6001600160a01b03808416600090815260fb60205260408082205481516306f4a2cd60e41b81529151931692636f4a2cd09260048084019391929182900301818387803b158015611b5f57600080fd5b60005b8151811015610f0057611d2d828281518110611d2057611d20613d33565b6020026020010151611b7c565b80611d3781613d78565b915050611d02565b600054600290610100900460ff16158015611d61575060005460ff8083169116105b611dc45760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401610b7d565b6000805461ffff191660ff831617610100908117909155546001600160a01b0316611e7d57611e5c87878080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080516020601f8b018190048102820181019092528981529250899150889081908401838280828437600092019190915250610ebd92505050565b61010080546001600160a01b0319166001600160a01b038a16179055611f89565b60005b82811015611f87576000848483818110611e9c57611e9c613d33565b9050602002016020810190611eb191906135d8565b6001600160a01b038116600081815261010360209081526040808320815160608101835281548082526001909201546001600160401b038082168387015268010000000000000000909104168184015294845261010490925282208054949550929390929190611f22908490613da8565b909155505080516101078054600090611f3c908490613da8565b9091555050506001600160a01b031660009081526101036020526040812090815560010180546fffffffffffffffffffffffffffffffff19169055611f8081613d78565b9050611e80565b505b6000805461ff001916905560405160ff821681527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15050505050505050565b606060cd8054610a8290613cf9565b336000908152610106602052604081205460ff166120095761200482611932565b610b19565b6001600160a01b0382166000908152610104602052604090205461202c83611932565b610b199190613d91565b61203e612a1e565b6001600160a01b0381166120865760405162461bcd60e51b815260206004820152600f60248201526e496e76616c6964206164647265737360881b6044820152606401610b7d565b6101005460405163095ea7b360e01b81526001600160a01b03838116600483015260001960248301529091169063095ea7b3906044016020604051808303816000875af11580156120db573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120ff9190613fc8565b50600060fb600060fc60008154811061211a5761211a613d33565b60009182526020808320909101546001600160a01b0390811684529083019390935260409091018120549091169150805b848110156122fd57600086868381811061216757612167613d33565b905060200201602081019061217c91906135d8565b9050600061218982610e7a565b905061219482611421565b61219e9085613da8565b6040516351cff8d960e01b81526001600160a01b038481166004830152919550908616906351cff8d990602401600060405180830381600087803b1580156121e557600080fd5b505af11580156121f9573d6000803e3d6000fd5b5050505061220f8261220a84611932565b612e5a565b6001600160a01b03821660009081526101046020908152604080832083905561010590915281205580156122ea576040516376a19e5b60e01b81526001600160a01b03838116600483015260248201839052600060448301528716906376a19e5b90606401600060405180830381600087803b15801561228e57600080fd5b505af11580156122a2573d6000803e3d6000fd5b50505050816001600160a01b03167f5c2da67751b5c2b8ffb1579ea16e70cf01e4b94068f0d42369de650adc07f613826040516122e191815260200190565b60405180910390a25b5050806122f690613d78565b905061214b565b5061010054604051630852cd8d60e31b8152600481018390526001600160a01b03909116906342966c6890602401600060405180830381600087803b15801561234557600080fd5b505af1158015612359573d6000803e3d6000fd5b505050508061010760008282546123709190613d91565b909155505061010880546001600160a01b0319166001600160a01b03949094169390931790925550505050565b6123a5612a1e565b6001600160a01b03828116600090815260fb6020526040902054166124045760405162461bcd60e51b8152602060048201526015602482015274151bdad95b881c1bdbdb081b5d5cdd08195e1a5cdd605a1b6044820152606401610b7d565b6001600160a01b03918216600090815260fb60209081526040808320549094168252610106905291909120805460ff1916911515919091179055565b6000338161244e8286612859565b9050838110156124ae5760405162461bcd60e51b815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f77604482015264207a65726f60d81b6064820152608401610b7d565b610e6f82868684036128fa565b610108546001600160a01b0316156125095760405162461bcd60e51b815260206004820152601160248201527011195c1bdcda5d1cc8191a5cd8589b1959607a1b6044820152606401610b7d565b610100546001600160a01b0316331480612527575061252733611961565b6125855760405162461bcd60e51b815260206004820152602960248201527f53656e646572206d75737420626520616c6c6f77616e6365206f722072657761604482015268393239903a37b5b2b760b91b6064820152608401610b7d565b610100546001600160a01b03163303612667576125a28484613032565b80156126625760006125b682840184613ce0565b9050808410156126185760405162461bcd60e51b815260206004820152602760248201527f43616e6e6f74206c6f636b206d6f7265207468616e207472616e736665727265604482015266642076616c756560c81b6064820152608401610b7d565b6001600160a01b0385166000908152610104602052604081208054839290612641908490613da8565b9250508190555080610107600082825461265b9190613da8565b9091555050505b612670565b61267033611b7c565b50505050565b600033610b13818585612aec565b606060fc805480602002602001604051908101604052809291908181526020018280548015610afb57602002820191906000526020600020905b81546001600160a01b031681526001909101906020018083116126be575050505050905090565b336126ef8161308e565b816126f933610e7a565b101561275b5760405162461bcd60e51b815260206004820152602b60248201527f5769746864726177616c20616d6f756e74206578636565647320617661696c6160448201526a626c652062616c616e636560a81b6064820152608401610b7d565b3360008181526101046020526040812054909161277790611932565b6127819190613d91565b9050808311156128025760006127978285613d91565b33600090815261010560205260408120805492935083929091906127bc908490613d91565b90915550503360009081526101046020526040812080548392906127e1908490613d91565b925050819055508061010760008282546127fb9190613d91565b9091555050505b61280c3384612e5a565b60405183815233907fcb4e4a5b4e544d9c587ec3ac0eead830ce8a4cccfe48b8dc331d447c481be8979060200160405180910390a261010054611055906001600160a01b03163385612fe0565b6001600160a01b03918216600090815260ca6020908152604080832093909416825291909152205490565b61288c612a1e565b6001600160a01b0381166128f15760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610b7d565b610fe081612f8e565b6001600160a01b03831661295c5760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f206164646044820152637265737360e01b6064820152608401610b7d565b6001600160a01b0382166129bd5760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f206164647265604482015261737360f01b6064820152608401610b7d565b6001600160a01b03838116600081815260ca602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050565b6097546001600160a01b0316331461195f5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610b7d565b6000612a848484612859565b905060001981146126705781811015612adf5760405162461bcd60e51b815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e63650000006044820152606401610b7d565b61267084848484036128fa565b60405162461bcd60e51b815260206004820152601b60248201527f546f6b656e2063616e6e6f74206265207472616e7366657272656400000000006044820152606401610b7d565b600054610100900460ff16612b5b5760405162461bcd60e51b8152600401610b7d90613dc0565b61195f613142565b600054610100900460ff1661195f5760405162461bcd60e51b8152600401610b7d90613dc0565b610fe0612a1e565b7f4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd91435460ff1615612bc55761105583613172565b826001600160a01b03166352d1902d6040518163ffffffff1660e01b8152600401602060405180830381865afa925050508015612c1f575060408051601f3d908101601f19168201909252612c1c91810190613d49565b60015b612c825760405162461bcd60e51b815260206004820152602e60248201527f45524331393637557067726164653a206e657720696d706c656d656e7461746960448201526d6f6e206973206e6f74205555505360901b6064820152608401610b7d565b6000805160206141368339815191528114612cf15760405162461bcd60e51b815260206004820152602960248201527f45524331393637557067726164653a20756e737570706f727465642070726f786044820152681a58589b195555525160ba1b6064820152608401610b7d565b5061105583838361320e565b600054610100900460ff16612d245760405162461bcd60e51b8152600401610b7d90613dc0565b610f008282613233565b6001600160a01b038216612d845760405162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f2061646472657373006044820152606401610b7d565b8060cb6000828254612d969190613da8565b90915550506001600160a01b038216600081815260c960209081526040808320805486019055518481527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a35050565b604051635260769b60e11b815283906001600160a01b0382169063a4c0ed3690612e2190889087908790600401613fe5565b600060405180830381600087803b158015612e3b57600080fd5b505af1158015612e4f573d6000803e3d6000fd5b505050505050505050565b6001600160a01b038216612eba5760405162461bcd60e51b815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f206164647265736044820152607360f81b6064820152608401610b7d565b6001600160a01b038216600090815260c9602052604090205481811015612f2e5760405162461bcd60e51b815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e604482015261636560f01b6064820152608401610b7d565b6001600160a01b038316600081815260c960209081526040808320868603905560cb80548790039055518581529192917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a3505050565b609780546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b179052611055908490613273565b8161303c8161308e565b6130468383612d2e565b826001600160a01b03167f60df8ac38837b0ae1b717d64eba4a631341a9365ed654aa2cb3ed7657d65acee8360405161308191815260200190565b60405180910390a2505050565b60005b60fc54811015610f005760fb600060fc83815481106130b2576130b2613d33565b6000918252602080832091909101546001600160a01b039081168452908301939093526040918201902054905163632447c960e01b8152848316600482015291169063632447c990602401600060405180830381600087803b15801561311757600080fd5b505af115801561312b573d6000803e3d6000fd5b50505050808061313a90613d78565b915050613091565b600054610100900460ff166131695760405162461bcd60e51b8152600401610b7d90613dc0565b61195f33612f8e565b6001600160a01b0381163b6131df5760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b6064820152608401610b7d565b60008051602061413683398151915280546001600160a01b0319166001600160a01b0392909216919091179055565b61321783613348565b6000825111806132245750805b15611055576126708383613388565b600054610100900460ff1661325a5760405162461bcd60e51b8152600401610b7d90613dc0565b60cc613266838261405a565b5060cd611055828261405a565b60006132c8826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166133b49092919063ffffffff16565b90508051600014806132e95750808060200190518101906132e99190613fc8565b6110555760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608401610b7d565b61335181613172565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b60606133ad8383604051806060016040528060278152602001614156602791396133cb565b9392505050565b60606133c38484600085613443565b949350505050565b6060600080856001600160a01b0316856040516133e89190614119565b600060405180830381855af49150503d8060008114613423576040519150601f19603f3d011682016040523d82523d6000602084013e613428565b606091505b50915091506134398683838761351e565b9695505050505050565b6060824710156134a45760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b6064820152608401610b7d565b600080866001600160a01b031685876040516134c09190614119565b60006040518083038185875af1925050503d80600081146134fd576040519150601f19603f3d011682016040523d82523d6000602084013e613502565b606091505b50915091506135138783838761351e565b979650505050505050565b6060831561358d578251600003613586576001600160a01b0385163b6135865760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610b7d565b50816133c3565b6133c383838151156135a25781518083602001fd5b8060405162461bcd60e51b8152600401610b7d919061364b565b80356001600160a01b03811681146135d357600080fd5b919050565b6000602082840312156135ea57600080fd5b6133ad826135bc565b60005b8381101561360e5781810151838201526020016135f6565b838111156126705750506000910152565b600081518084526136378160208601602086016135f3565b601f01601f19169290920160200192915050565b6020815260006133ad602083018461361f565b6000806040838503121561367157600080fd5b61367a836135bc565b946020939093013593505050565b600081518084526020808501945080840160005b838110156136c15781516001600160a01b03168752958201959082019060010161369c565b509495945050505050565b600081518084526020808501945080840160005b838110156136c1578151875295820195908201906001016136e0565b60408152600061370f6040830185613688565b828103602084015261372181856136cc565b95945050505050565b6020815260006133ad60208301846136cc565b60008060006060848603121561375257600080fd5b61375b846135bc565b9250613769602085016135bc565b9150604084013590509250925092565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f191681016001600160401b03811182821017156137b7576137b7613779565b604052919050565b600082601f8301126137d057600080fd5b81356001600160401b038111156137e9576137e9613779565b6137fc601f8201601f191660200161378f565b81815284602083860101111561381157600080fd5b816020850160208301376000918101602001919091529392505050565b6000806040838503121561384157600080fd5b82356001600160401b038082111561385857600080fd5b613864868387016137bf565b9350602085013591508082111561387a57600080fd5b50613887858286016137bf565b9150509250929050565b6000806000606084860312156138a657600080fd5b83356001600160401b03808211156138bd57600080fd5b6138c9878388016137bf565b945060208601359150808211156138df57600080fd5b506138ec868287016137bf565b925050604084013590509250925092565b60008060006060848603121561391257600080fd5b61391b846135bc565b92506020840135915060408401356001600160401b0381111561393d57600080fd5b613949868287016137bf565b9150509250925092565b6000806040838503121561396657600080fd5b61396f836135bc565b915060208301356001600160401b0381111561398a57600080fd5b613887858286016137bf565b600080604083850312156139a957600080fd5b6139b2836135bc565b91506139c0602084016135bc565b90509250929050565b600080604083850312156139dc57600080fd5b8235915060208301356001600160401b03811681146139fa57600080fd5b809150509250929050565b60006020808385031215613a1857600080fd5b82356001600160401b0380821115613a2f57600080fd5b818501915085601f830112613a4357600080fd5b813581811115613a5557613a55613779565b8060051b9150613a6684830161378f565b8181529183018401918481019088841115613a8057600080fd5b938501935b83851015613aa557613a96856135bc565b82529385019390850190613a85565b98975050505050505050565b60008083601f840112613ac357600080fd5b5081356001600160401b03811115613ada57600080fd5b602083019150836020828501011115613af257600080fd5b9250929050565b60008083601f840112613b0b57600080fd5b5081356001600160401b03811115613b2257600080fd5b6020830191508360208260051b8501011115613af257600080fd5b60008060008060008060006080888a031215613b5857600080fd5b613b61886135bc565b965060208801356001600160401b0380821115613b7d57600080fd5b613b898b838c01613ab1565b909850965060408a0135915080821115613ba257600080fd5b613bae8b838c01613ab1565b909650945060608a0135915080821115613bc757600080fd5b50613bd48a828b01613af9565b989b979a50959850939692959293505050565b600080600060408486031215613bfc57600080fd5b83356001600160401b03811115613c1257600080fd5b613c1e86828701613af9565b9094509250613c319050602085016135bc565b90509250925092565b8015158114610fe057600080fd5b60008060408385031215613c5b57600080fd5b613c64836135bc565b915060208301356139fa81613c3a565b60008060008060608587031215613c8a57600080fd5b613c93856135bc565b93506020850135925060408501356001600160401b03811115613cb557600080fd5b613cc187828801613ab1565b95989497509550505050565b6020815260006133ad6020830184613688565b600060208284031215613cf257600080fd5b5035919050565b600181811c90821680613d0d57607f821691505b602082108103613d2d57634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052603260045260246000fd5b600060208284031215613d5b57600080fd5b5051919050565b634e487b7160e01b600052601160045260246000fd5b600060018201613d8a57613d8a613d62565b5060010190565b600082821015613da357613da3613d62565b500390565b60008219821115613dbb57613dbb613d62565b500190565b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b606082015260800190565b6020808252602c908201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060408201526b19195b1959d85d1958d85b1b60a21b606082015260800190565b6020808252602c908201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060408201526b6163746976652070726f787960a01b606082015260800190565b600181815b80851115613ede578160001904821115613ec457613ec4613d62565b80851615613ed157918102915b93841c9390800290613ea8565b509250929050565b600082613ef557506001610b19565b81613f0257506000610b19565b8160018114613f185760028114613f2257613f3e565b6001915050610b19565b60ff841115613f3357613f33613d62565b50506001821b610b19565b5060208310610133831016604e8410600b8410161715613f61575081810a610b19565b613f6b8383613ea3565b8060001904821115613f7f57613f7f613d62565b029392505050565b60006133ad8383613ee6565b6000816000190483118215151615613fad57613fad613d62565b500290565b634e487b7160e01b600052603160045260246000fd5b600060208284031215613fda57600080fd5b81516133ad81613c3a565b60018060a01b0384168152826020820152606060408201526000613721606083018461361f565b601f82111561105557600081815260208120601f850160051c810160208610156140335750805b601f850160051c820191505b818110156140525782815560010161403f565b505050505050565b81516001600160401b0381111561407357614073613779565b614087816140818454613cf9565b8461400c565b602080601f8311600181146140bc57600084156140a45750858301515b600019600386901b1c1916600185901b178555614052565b600085815260208120601f198616915b828110156140eb578886015182559484019460019091019084016140cc565b50858210156141095787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b6000825161412b8184602087016135f3565b919091019291505056fe360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220afa15878e5d0f7ed19cc8dde4ac72d5905c7071c221a2be428c1c8489f5618d464736f6c634300080f0033
Deployed Bytecode Sourcemap
99984:10585:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;105250:134;;;;;;;;;;-1:-1:-1;105250:134:0;;;;;:::i;:::-;-1:-1:-1;;;;;105351:25:0;105324:7;105351:25;;;:15;:25;;;;;;;105250:134;;;;529:25:1;;;517:2;502:18;105250:134:0;;;;;;;;48390:100;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;50750:201::-;;;;;;;;;;-1:-1:-1;50750:201:0;;;;;:::i;:::-;;:::i;:::-;;;1740:14:1;;1733:22;1715:41;;1703:2;1688:18;50750:201:0;1575:187:1;107666:199:0;;;;;;;;;;-1:-1:-1;107666:199:0;;;;;:::i;:::-;;:::i;:::-;;94313:347;;;;;;;;;;;;;:::i;:::-;;;;;;;;:::i;97088:351::-;;;;;;;;;;-1:-1:-1;97088:351:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;49519:108::-;;;;;;;;;;-1:-1:-1;49607:12:0;;49519:108;;51531:261;;;;;;;;;;-1:-1:-1;51531:261:0;;;;;:::i;:::-;;:::i;104585:176::-;;;;;;;;;;-1:-1:-1;104585:176:0;;;;;:::i;:::-;;:::i;93185:302::-;;;;;;;;;;-1:-1:-1;93185:302:0;;;;;:::i;:::-;;:::i;49361:93::-;;;;;;;;;;-1:-1:-1;49361:93:0;;49444:2;5380:36:1;;5368:2;5353:18;49361:93:0;5238:184:1;81197:198:0;;;;;;;;;;-1:-1:-1;81197:198:0;;;;;:::i;:::-;;:::i;52201:238::-;;;;;;;;;;-1:-1:-1;52201:238:0;;;;;:::i;:::-;;:::i;59826:284::-;;;;;;;;;;-1:-1:-1;59826:284:0;;;;;:::i;:::-;;:::i;60118:304::-;;;;;;;;;;-1:-1:-1;60118:304:0;;;;;:::i;:::-;;:::i;103922:119::-;;;;;;;;;;-1:-1:-1;103922:119:0;;;;;:::i;:::-;;:::i;81726:223::-;;;;;;:::i;:::-;;:::i;106476:233::-;;;;;;;;;;-1:-1:-1;106476:233:0;;;;;:::i;:::-;;:::i;80803:133::-;;;;;;;;;;;;;:::i;100278:29::-;;;;;;;;;;-1:-1:-1;100278:29:0;;;;-1:-1:-1;;;;;100278:29:0;;;;;;-1:-1:-1;;;;;7277:32:1;;;7259:51;;7247:2;7232:18;100278:29:0;7093:223:1;97996:416:0;;;;;;;;;;-1:-1:-1;97996:416:0;;;;;:::i;:::-;;:::i;100603:26::-;;;;;;;;;;;;;;;;104921:151;;;;;;;;;;-1:-1:-1;104921:151:0;;;;;:::i;:::-;;:::i;109722:513::-;;;;;;;;;;-1:-1:-1;109722:513:0;;;;;:::i;:::-;;:::i;92779:50::-;;;;;;;;;;-1:-1:-1;92779:50:0;;;;;:::i;:::-;;;;;;;;;;;;-1:-1:-1;;;;;92779:50:0;;;98520:521;;;;;;;;;;-1:-1:-1;98520:521:0;;;;;:::i;:::-;;:::i;92922:52::-;;;;;;;;;;-1:-1:-1;92922:52:0;;;;;:::i;:::-;;;;;;;;;;;;-1:-1:-1;;;;;92922:52:0;;;92850:51;;;;;;;;;;-1:-1:-1;92850:51:0;;;;;:::i;:::-;;;;;;;;;;;;;;97613:234;;;;;;;;;;-1:-1:-1;97613:234:0;;;;;:::i;:::-;;:::i;49690:127::-;;;;;;;;;;-1:-1:-1;49690:127:0;;;;;:::i;:::-;;:::i;63362:103::-;;;;;;;;;;;;;:::i;93980:151::-;;;;;;;;;;-1:-1:-1;93980:151:0;;;;;:::i;:::-;;:::i;100550:46::-;;;;;;;;;;-1:-1:-1;100550:46:0;;;;;:::i;:::-;;;;;;;;;;;;;;;;104211:162;;;;;;;;;;;;;:::i;106900:647::-;;;;;;;;;;-1:-1:-1;106900:647:0;;;;;:::i;:::-;;:::i;100314:23::-;;;;;;;;;;-1:-1:-1;100314:23:0;;;;-1:-1:-1;;;;;100314:23:0;;;96470:429;;;;;;;;;;-1:-1:-1;96470:429:0;;;;;:::i;:::-;;:::i;96157:176::-;;;;;;;;;;-1:-1:-1;96157:176:0;;;;;:::i;:::-;;:::i;100983:850::-;;;;;;;;;;-1:-1:-1;100983:850:0;;;;;:::i;:::-;;:::i;62721:87::-;;;;;;;;;;-1:-1:-1;62794:6:0;;-1:-1:-1;;;;;62794:6:0;62721:87;;48609:104;;;;;;;;;;;;;:::i;103503:198::-;;;;;;;;;;-1:-1:-1;103503:198:0;;;;;:::i;:::-;;:::i;108448:1075::-;;;;;;;;;;-1:-1:-1;108448:1075:0;;;;;:::i;:::-;;:::i;108052:248::-;;;;;;;;;;-1:-1:-1;108052:248:0;;;;;:::i;:::-;;:::i;52942:436::-;;;;;;;;;;-1:-1:-1;52942:436:0;;;;;:::i;:::-;;:::i;102090:879::-;;;;;;;;;;-1:-1:-1;102090:879:0;;;;;:::i;:::-;;:::i;50023:193::-;;;;;;;;;;-1:-1:-1;50023:193:0;;;;;:::i;:::-;;:::i;93709:100::-;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;100638:22::-;;;;;;;;;;-1:-1:-1;100638:22:0;;;;-1:-1:-1;;;;;100638:22:0;;;105528:752;;;;;;;;;;-1:-1:-1;105528:752:0;;;;;:::i;:::-;;:::i;92688:50::-;;;;;;;;;;-1:-1:-1;92688:50:0;;;;;:::i;:::-;;;;;;;;;;;;-1:-1:-1;;;;;92688:50:0;;;100232:39;;;;;;;;;;-1:-1:-1;100232:39:0;;;;-1:-1:-1;;;;;100232:39:0;;;50279:151;;;;;;;;;;-1:-1:-1;50279:151:0;;;;;:::i;:::-;;:::i;63620:201::-;;;;;;;;;;-1:-1:-1;63620:201:0;;;;;:::i;:::-;;:::i;48390:100::-;48444:13;48477:5;48470:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;48390:100;:::o;50750:201::-;50833:4;41844:10;50889:32;41844:10;50905:7;50914:6;50889:8;:32::i;:::-;50939:4;50932:11;;;50750:201;;;;;:::o;107666:199::-;62607:13;:11;:13::i;:::-;107756:10:::1;::::0;-1:-1:-1;;;;;107756:10:0::1;107748:33:::0;107740:69:::1;;;::::0;-1:-1:-1;;;107740:69:0;;13966:2:1;107740:69:0::1;::::0;::::1;13948:21:1::0;14005:2;13985:18;;;13978:30;14044:25;14024:18;;;14017:53;14087:18;;107740:69:0::1;;;;;;;;;107820:10;:37:::0;;-1:-1:-1;;;;;;107820:37:0::1;-1:-1:-1::0;;;;;107820:37:0;;;::::1;::::0;;;::::1;::::0;;107666:199::o;94313:347::-;94361:16;94379;94408:25;94450:6;:13;;;;-1:-1:-1;;;;;94436:28:0;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;94436:28:0;;94408:56;;94482:9;94477:138;94501:6;:13;94497:17;;94477:138;;;94568:6;94575:1;94568:9;;;;;;;;:::i;:::-;;;;;;;;;;;94550:53;;-1:-1:-1;;;94550:53:0;;94597:4;94550:53;;;7259:51:1;-1:-1:-1;;;;;94568:9:0;;;;94550:38;;7232:18:1;;94550:53:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;94536:8;94545:1;94536:11;;;;;;;;:::i;:::-;;;;;;;;;;:67;94516:3;;;;:::i;:::-;;;;94477:138;;;;94635:6;94643:8;94627:25;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;94627:25:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;94313:347;;:::o;97088:351::-;97233:6;:13;97158:16;;97187:29;;-1:-1:-1;;;;;97219:28:0;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;97219:28:0;;97187:60;;97265:9;97260:140;97284:6;:13;97280:17;;97260:140;;;97337:10;:21;97348:6;97355:1;97348:9;;;;;;;;:::i;:::-;;;;;;;;;;;;;;-1:-1:-1;;;;;97348:9:0;;;97337:21;;;;;;;;;;;;;;;;:51;;-1:-1:-1;;;97337:51:0;;7277:32:1;;;97337:51:0;;;7259::1;97337:21:0;;;:41;;7232:18:1;;97337:51:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;97319:12;97332:1;97319:15;;;;;;;;:::i;:::-;;;;;;;;;;:69;97299:3;;;;:::i;:::-;;;;97260:140;;;-1:-1:-1;97419:12:0;97088:351;-1:-1:-1;;97088:351:0:o;51531:261::-;51628:4;41844:10;51686:38;51702:4;41844:10;51717:6;51686:15;:38::i;:::-;51735:27;51745:4;51751:2;51755:6;51735:9;:27::i;:::-;-1:-1:-1;51780:4:0;;51531:261;-1:-1:-1;;;;51531:261:0:o;104585:176::-;-1:-1:-1;;;;;104728:25:0;;104652:7;104728:25;;;:15;:25;;;;;;;;;104701:14;:24;;;;;;104679:19;104744:8;104679:9;:19::i;:::-;:46;;;;:::i;:::-;:74;;;;:::i;93185:302::-;39579:13;;;;;;;39571:69;;;;-1:-1:-1;;;39571:69:0;;;;;;;:::i;:::-;93355:62:::1;93369:20;93391:22;93415:1;93355:13;:62::i;:::-;93428:16;:14;:16::i;:::-;93455:24;:22;:24::i;:::-;93185:302:::0;;:::o;81197:198::-;-1:-1:-1;;;;;79673:6:0;79656:23;79664:4;79656:23;79648:80;;;;-1:-1:-1;;;79648:80:0;;;;;;;:::i;:::-;79771:6;-1:-1:-1;;;;;79747:30:0;:20;-1:-1:-1;;;;;;;;;;;72439:65:0;-1:-1:-1;;;;;72439:65:0;;72359:153;79747:20;-1:-1:-1;;;;;79747:30:0;;79739:87;;;;-1:-1:-1;;;79739:87:0;;;;;;;:::i;:::-;81279:36:::1;81297:17;81279;:36::i;:::-;81367:12;::::0;;81377:1:::1;81367:12:::0;;;::::1;::::0;::::1;::::0;;;81326:61:::1;::::0;81348:17;;81367:12;81326:21:::1;:61::i;:::-;81197:198:::0;:::o;52201:238::-;52289:4;41844:10;52345:64;41844:10;52361:7;52398:10;52370:25;41844:10;52361:7;52370:9;:25::i;:::-;:38;;;;:::i;:::-;52345:8;:64::i;59826:284::-;39579:13;;;;;;;39571:69;;;;-1:-1:-1;;;39571:69:0;;;;;;;:::i;:::-;59994:38:::1;60007:10;60019:12;59994;:38::i;:::-;60043:59;60049:10;60077:23;49444:2:::0;60077::::1;:23;:::i;:::-;60061:40;::::0;:12;:40:::1;:::i;:::-;60043:5;:59::i;:::-;59826:284:::0;;;:::o;60118:304::-;60242:4;60259:27;60274:3;60279:6;60259:14;:27::i;:::-;-1:-1:-1;61194:18:0;;61240:10;60297:96;;60333:48;60350:10;60362:3;60367:6;60375:5;60333:16;:48::i;:::-;-1:-1:-1;60410:4:0;60118:304;;;;;:::o;103922:119::-;103987:7;104014:19;104024:8;104014:9;:19::i;81726:223::-;-1:-1:-1;;;;;79673:6:0;79656:23;79664:4;79656:23;79648:80;;;;-1:-1:-1;;;79648:80:0;;;;;;;:::i;:::-;79771:6;-1:-1:-1;;;;;79747:30:0;:20;-1:-1:-1;;;;;;;;;;;72439:65:0;-1:-1:-1;;;;;72439:65:0;;72359:153;79747:20;-1:-1:-1;;;;;79747:30:0;;79739:87;;;;-1:-1:-1;;;79739:87:0;;;;;;;:::i;:::-;81842:36:::1;81860:17;81842;:36::i;:::-;81889:52;81911:17;81930:4;81936;81889:21;:52::i;106476:233::-:0;62607:13;:11;:13::i;:::-;-1:-1:-1;;;;;106576:24:0;::::1;;::::0;;;:14:::1;:24;::::0;;;;;:35;-1:-1:-1;106576:35:0::1;106568:87;;;::::0;-1:-1:-1;;;106568:87:0;;17959:2:1;106568:87:0::1;::::0;::::1;17941:21:1::0;17998:2;17978:18;;;17971:30;18037:34;18017:18;;;18010:62;-1:-1:-1;;;18088:18:1;;;18081:37;18135:19;;106568:87:0::1;17757:403:1::0;106568:87:0::1;-1:-1:-1::0;;;;;106666:25:0;;::::1;;::::0;;;:15:::1;:25;::::0;;;;:35;106476:233::o;80803:133::-;80881:7;80109:4;-1:-1:-1;;;;;80118:6:0;80101:23;;80093:92;;;;-1:-1:-1;;;80093:92:0;;18367:2:1;80093:92:0;;;18349:21:1;18406:2;18386:18;;;18379:30;18445:34;18425:18;;;18418:62;18516:26;18496:18;;;18489:54;18560:19;;80093:92:0;18165:420:1;80093:92:0;-1:-1:-1;;;;;;;;;;;;80803:133:0;:::o;97996:416::-;62607:13;:11;:13::i;:::-;98089:24:::1;98106:6;98089:16;:24::i;:::-;98088:25;98080:64;;;::::0;-1:-1:-1;;;98080:64:0;;18792:2:1;98080:64:0::1;::::0;::::1;18774:21:1::0;18831:2;18811:18;;;18804:30;18870:28;18850:18;;;18843:56;18916:18;;98080:64:0::1;18590:350:1::0;98080:64:0::1;-1:-1:-1::0;;;;;98157:18:0;;::::1;;::::0;;;:10:::1;:18;::::0;;;;;:47;;;;::::1;-1:-1:-1::0;;;;;;98157:47:0;;::::1;;::::0;;98215:6:::1;:19:::0;;-1:-1:-1;98215:19:0;::::1;::::0;;;;;;::::1;::::0;;;;::::1;::::0;::::1;::::0;;;98251:50;;-1:-1:-1;;;98251:50:0;;98295:4:::1;98251:50;::::0;::::1;7259:51:1::0;98251:35:0::1;::::0;7232:18:1;;98251:50:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:54;98247:110;;;98322:23;98338:6;98322:15;:23::i;:::-;98374:30;::::0;-1:-1:-1;;;;;7277:32:1;;;7259:51;;98374:30:0;::::1;::::0;::::1;::::0;7247:2:1;7232:18;98374:30:0::1;;;;;;;;97996:416:::0;;:::o;104921:151::-;-1:-1:-1;;;;;105039:25:0;;104985:7;105039:25;;;:15;:25;;;;;;;;;105012:14;:24;;;;;;:52;;105039:25;105012:52;:::i;109722:513::-;109809:7;;-1:-1:-1;;;;;109809:7:0;109801:74;;;;-1:-1:-1;;;109801:74:0;;19147:2:1;109801:74:0;;;19129:21:1;19186:2;19166:18;;;19159:30;19225:34;19205:18;;;19198:62;-1:-1:-1;;;19276:18:1;;;19269:38;19324:19;;109801:74:0;18945:404:1;109801:74:0;109894:7;109905:1;109894:12;109886:39;;;;-1:-1:-1;;;109886:39:0;;19556:2:1;109886:39:0;;;19538:21:1;19595:2;19575:18;;;19568:30;-1:-1:-1;;;19614:18:1;;;19607:44;19668:18;;109886:39:0;19354:338:1;109886:39:0;109955:30;109974:10;109955:18;:30::i;:::-;109944:7;:41;;109936:74;;;;-1:-1:-1;;;109936:74:0;;19899:2:1;109936:74:0;;;19881:21:1;19938:2;19918:18;;;19911:30;-1:-1:-1;;;19957:18:1;;;19950:50;20017:18;;109936:74:0;19697:344:1;109936:74:0;110023:10;:21;110034:6;110041:1;110034:9;;;;;;;;:::i;:::-;;;;;;;;;;;;;;-1:-1:-1;;;;;110034:9:0;;;110023:21;;;;;;;;;;;;;;;;:42;;-1:-1:-1;;;110023:42:0;;110054:10;110023:42;;;7259:51:1;110023:21:0;;;:30;;7232:18:1;;110023:42:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;110078:26;110084:10;110096:7;110078:5;:26::i;:::-;110124:7;;110115:64;;-1:-1:-1;;;110115:64:0;;110141:10;110115:64;;;20246:51:1;20313:18;;;20306:34;;;-1:-1:-1;;;;;20376:31:1;;20356:18;;;20349:59;-1:-1:-1;;;;;110124:7:0;;;;110115:25;;20219:18:1;;110115:64:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;110197:30:0;;529:25:1;;;110207:10:0;;-1:-1:-1;110197:30:0;;-1:-1:-1;517:2:1;502:18;110197:30:0;383:177:1;98520:521:0;62607:13;:11;:13::i;:::-;98595:24:::1;98612:6;98595:16;:24::i;:::-;98587:59;;;::::0;-1:-1:-1;;;98587:59:0;;20621:2:1;98587:59:0::1;::::0;::::1;20603:21:1::0;20660:2;20640:18;;;20633:30;-1:-1:-1;;;20679:18:1;;;20672:52;20741:18;;98587:59:0::1;20419:346:1::0;98587:59:0::1;-1:-1:-1::0;;;;;98686:18:0;;::::1;98659:24;98686:18:::0;;;:10:::1;:18;::::0;;;;;;-1:-1:-1;;;;;;98715:27:0;::::1;::::0;;;98686:18;;::::1;::::0;98753:222:::1;98777:6;:13:::0;98773:17;::::1;98753:222;;;98829:6;-1:-1:-1::0;;;;;98816:19:0::1;:6;98823:1;98816:9;;;;;;;;:::i;:::-;;::::0;;;::::1;::::0;;;::::1;::::0;-1:-1:-1;;;;;98816:9:0::1;:19:::0;98812:152:::1;;98868:6;98875:13:::0;;:17:::1;::::0;98891:1:::1;::::0;98875:17:::1;:::i;:::-;98868:25;;;;;;;;:::i;:::-;;::::0;;;::::1;::::0;;;::::1;::::0;98856:6:::1;:9:::0;;-1:-1:-1;;;;;98868:25:0;;::::1;::::0;98863:1;;98856:9;::::1;;;;;:::i;:::-;;;;;;;;;:37;;;;;-1:-1:-1::0;;;;;98856:37:0::1;;;;;-1:-1:-1::0;;;;;98856:37:0::1;;;;;;98912:6;:12;;;;;;;:::i;:::-;;::::0;;;::::1;::::0;;;;-1:-1:-1;;98912:12:0;;;;;-1:-1:-1;;;;;;98912:12:0::1;::::0;;;;;98943:5:::1;;98812:152;98792:3:::0;::::1;::::0;::::1;:::i;:::-;;;;98753:222;;;-1:-1:-1::0;98992:41:0::1;::::0;-1:-1:-1;;;;;7277:32:1;;;7259:51;;98992:41:0;::::1;::::0;::::1;::::0;7247:2:1;7232:18;98992:41:0::1;7093:223:1::0;97613:234:0;97687:9;97682:115;97706:7;:14;97702:1;:18;97682:115;;;97742:10;:22;97753:7;97761:1;97753:10;;;;;;;;:::i;:::-;;;;;;;;;;;;-1:-1:-1;;;;;97742:22:0;;;;;;;;;;;;;;;;-1:-1:-1;97742:22:0;;:43;;-1:-1:-1;;;97742:43:0;;97774:10;97742:43;;;7259:51:1;97742:22:0;;;:31;;7232:18:1;;97742:43:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;97722:3;;;;;:::i;:::-;;;;97682:115;;;-1:-1:-1;97812:27:0;;97828:10;;97812:27;;;;;97613:234;:::o;49690:127::-;-1:-1:-1;;;;;49791:18:0;49764:7;49791:18;;;:9;:18;;;;;;;49690:127::o;63362:103::-;62607:13;:11;:13::i;:::-;63427:30:::1;63454:1;63427:18;:30::i;:::-;63362:103::o:0;93980:151::-;-1:-1:-1;;;;;94075:18:0;;;94043:4;94075:18;;;:10;:18;;;;;;94043:4;;94075:18;94067:56;;94118:5;94067:56;;;94111:4;94060:63;93980:151;-1:-1:-1;;93980:151:0:o;104211:162::-;104308:10;104266:7;104293:26;;;:14;:26;;;;;;;;:72;;-1:-1:-1;49607:12:0;;;104211:162::o;104293:72::-;104338:11;;49607:12;;104322:27;;;;:::i;:::-;104286:79;;104211:162;:::o;106900:647::-;62607:13;:11;:13::i;:::-;-1:-1:-1;;;;;107000:24:0;::::1;;::::0;;;:14:::1;:24;::::0;;;;;:35;-1:-1:-1;107000:35:0::1;106992:84;;;::::0;-1:-1:-1;;;106992:84:0;;21104:2:1;106992:84:0::1;::::0;::::1;21086:21:1::0;21143:2;21123:18;;;21116:30;21182:34;21162:18;;;21155:62;-1:-1:-1;;;21233:18:1;;;21226:34;21277:19;;106992:84:0::1;20902:400:1::0;106992:84:0::1;-1:-1:-1::0;;;;;107114:25:0;::::1;107089:22;107114:25:::0;;;:15:::1;:25;::::0;;;;;107154:19;;;::::1;::::0;:48:::1;;;107188:14;107177:7;:25;;107154:48;107150:207;;;-1:-1:-1::0;;;;;107226:25:0;::::1;;::::0;;;:15:::1;:25;::::0;;;;107219:32;107150:207:::1;;;107273:19:::0;;107269:88:::1;;-1:-1:-1::0;;;;;107309:25:0;::::1;;::::0;;;:15:::1;:25;::::0;;;;:36;;107338:7;;107309:25;:36:::1;::::0;107338:7;;107309:36:::1;:::i;:::-;::::0;;;-1:-1:-1;;107269:88:0::1;-1:-1:-1::0;;;;;107367:24:0;::::1;;::::0;;;:14:::1;:24;::::0;;;;:35;;107395:7;;107367:24;:35:::1;::::0;107395:7;;107367:35:::1;:::i;:::-;;;;;;;;107428:7;107413:11;;:22;;;;;;;:::i;:::-;::::0;;;-1:-1:-1;107448:24:0::1;::::0;-1:-1:-1;107454:8:0;107464:7;107448:5:::1;:24::i;:::-;107509:14;::::0;107483:56:::1;::::0;-1:-1:-1;;;107483:56:0;;::::1;::::0;::::1;529:25:1::0;;;-1:-1:-1;;;;;107509:14:0;;::::1;::::0;107483:47:::1;::::0;502:18:1;;107483:56:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;106981:566;106900:647:::0;;:::o;96470:429::-;96537:24;96554:6;96537:16;:24::i;:::-;96529:56;;;;-1:-1:-1;;;96529:56:0;;21509:2:1;96529:56:0;;;21491:21:1;21548:2;21528:18;;;21521:30;-1:-1:-1;;;21567:18:1;;;21560:49;21626:18;;96529:56:0;21307:343:1;96529:56:0;96678:30;;-1:-1:-1;;;96678:30:0;;96702:4;96678:30;;;7259:51:1;96642:6:0;;96598:23;;-1:-1:-1;;;;;96678:15:0;;;;;7232:18:1;;96678:30:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;96660:48;;96737:1;96727:7;:11;96719:54;;;;-1:-1:-1;;;96719:54:0;;21857:2:1;96719:54:0;;;21839:21:1;21896:2;21876:18;;;21869:30;21935:32;21915:18;;;21908:60;21985:18;;96719:54:0;21655:354:1;96719:54:0;-1:-1:-1;;;;;96813:18:0;;;;;;;:10;:18;;;;;;96786:56;;:18;;;;96813;96834:7;96786:18;:56::i;:::-;-1:-1:-1;;;;;96853:18:0;;;;;;;:10;:18;;;;;;;:38;;-1:-1:-1;;;96853:38:0;;;;:18;;;:36;;:38;;;;;:18;;:38;;;;;;:18;;:38;;;;;;;;;;96157:176;96232:9;96227:99;96251:7;:14;96247:1;:18;96227:99;;;96287:27;96303:7;96311:1;96303:10;;;;;;;;:::i;:::-;;;;;;;96287:15;:27::i;:::-;96267:3;;;;:::i;:::-;;;;96227:99;;100983:850;39074:13;;101190:1;;39074:13;;;;;39073:14;:40;;;;-1:-1:-1;39091:12:0;;:22;;;;:12;;:22;39073:40;39065:99;;;;-1:-1:-1;;;39065:99:0;;22216:2:1;39065:99:0;;;22198:21:1;22255:2;22235:18;;;22228:30;22294:34;22274:18;;;22267:62;-1:-1:-1;;;22345:18:1;;;22338:44;22399:19;;39065:99:0;22014:410:1;39065:99:0;39175:12;:22;;-1:-1:-1;;39208:20:0;39175:22;;;39208:20;39175:22;39208:20;;;;;;101216:14;-1:-1:-1;;;;;101216:14:0::1;101204:622;;101262:56;101291:11;;101262:56;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;::::0;;;;-1:-1:-1;;101262:56:0::1;::::0;;::::1;;::::0;::::1;::::0;;::::1;::::0;::::1;::::0;;;;;;;;;;;-1:-1:-1;101304:13:0;;-1:-1:-1;101304:13:0;;;;101262:56;::::1;101304:13:::0;;;;101262:56;::::1;;::::0;::::1;::::0;;;;-1:-1:-1;101262:28:0::1;::::0;-1:-1:-1;;;101262:56:0:i:1;:::-;101333:14;:51:::0;;-1:-1:-1;;;;;;101333:51:0::1;-1:-1:-1::0;;;;;101333:51:0;::::1;;::::0;;101204:622:::1;;;101422:9;101417:398;101437:28:::0;;::::1;101417:398;;;101491:15;101509:17;;101527:1;101509:20;;;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;101589:25:0;::::1;101548:38;101589:25:::0;;;:16:::1;:25;::::0;;;;;;;101548:66;;::::1;::::0;::::1;::::0;;;;;;;::::1;::::0;;::::1;::::0;-1:-1:-1;;;;;101548:66:0;;::::1;::::0;;::::1;::::0;;;;::::1;;::::0;;;;101633:23;;;:14:::1;:23:::0;;;;;:54;;101491:38;;-1:-1:-1;101548:66:0;;;;101633:23;101548:38;101633:54:::1;::::0;101548:66;;101633:54:::1;:::i;:::-;::::0;;;-1:-1:-1;;101721:27:0;;101706:11:::1;:42:::0;;101721:27:::1;::::0;101706:42:::1;::::0;101721:27;;101706:42:::1;:::i;:::-;::::0;;;-1:-1:-1;;;;;;;;101774:25:0::1;;::::0;;;:16:::1;:25;::::0;;;;101767:32;;;::::1;;::::0;;-1:-1:-1;;101767:32:0;;;101467:3:::1;::::0;::::1;:::i;:::-;;;101417:398;;;;101204:622;39267:5:::0;39251:21;;-1:-1:-1;;39251:21:0;;;39288:20;;5410:4:1;5398:17;;5380:36;;39288:20:0;;5368:2:1;5353:18;39288:20:0;;;;;;;100983:850;;;;;;;;:::o;48609:104::-;48665:13;48698:7;48691:14;;;;;:::i;103503:198::-;103611:10;103569:7;103596:26;;;:14;:26;;;;;;;;:97;;103674:19;103684:8;103674:9;:19::i;:::-;103596:97;;;-1:-1:-1;;;;;103647:24:0;;;;;;:14;:24;;;;;;103625:19;103662:8;103625:9;:19::i;:::-;:46;;;;:::i;108448:1075::-;62607:13;:11;:13::i;:::-;-1:-1:-1;;;;;108570:22:0;::::1;108562:50;;;::::0;-1:-1:-1;;;108562:50:0;;22631:2:1;108562:50:0::1;::::0;::::1;22613:21:1::0;22670:2;22650:18;;;22643:30;-1:-1:-1;;;22689:18:1;;;22682:45;22744:18;;108562:50:0::1;22429:339:1::0;108562:50:0::1;108623:14;::::0;:51:::1;::::0;-1:-1:-1;;;108623:51:0;;-1:-1:-1;;;;;22965:32:1;;;108623:51:0::1;::::0;::::1;22947::1::0;-1:-1:-1;;23014:18:1;;;23007:34;108623:14:0;;::::1;::::0;:22:::1;::::0;22920:18:1;;108623:51:0::1;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;108687:24;108714:10;:21;108725:6;108732:1;108725:9;;;;;;;;:::i;:::-;;::::0;;;::::1;::::0;;;;;::::1;::::0;-1:-1:-1;;;;;108725:9:0;;::::1;108714:21:::0;;;;::::1;::::0;;;;;;;;;;;;;::::1;::::0;-1:-1:-1;108725:9:0;108773:614:::1;108793:27:::0;;::::1;108773:614;;;108842:15;108860:16;;108877:1;108860:19;;;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;108842:37;;108894:23;108920:27;108939:7;108920:18;:27::i;:::-;108894:53;;108972:24;108988:7;108972:15;:24::i;:::-;108962:34;::::0;;::::1;:::i;:::-;109013:29;::::0;-1:-1:-1;;;109013:29:0;;-1:-1:-1;;;;;7277:32:1;;;109013:29:0::1;::::0;::::1;7259:51:1::0;108962:34:0;;-1:-1:-1;109013:20:0;;::::1;::::0;::::1;::::0;7232:18:1;;109013:29:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;109059:34;109065:7;109074:18;109084:7;109074:9;:18::i;:::-;109059:5;:34::i;:::-;-1:-1:-1::0;;;;;109115:23:0;::::1;;::::0;;;:14:::1;:23;::::0;;;;;;;109108:30;;;109160:15:::1;:24:::0;;;;;109153:31;109205:20;;109201:175:::1;;109246:55;::::0;-1:-1:-1;;;109246:55:0;;-1:-1:-1;;;;;20264:32:1;;;109246:55:0::1;::::0;::::1;20246:51:1::0;20313:18;;;20306:34;;;109299:1:0::1;20356:18:1::0;;;20349:59;109246:26:0;::::1;::::0;::::1;::::0;20219:18:1;;109246:55:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;109335:7;-1:-1:-1::0;;;;;109325:35:0::1;;109344:15;109325:35;;;;529:25:1::0;;517:2;502:18;;383:177;109325:35:0::1;;;;;;;;109201:175;108827:560;;108822:3;;;;:::i;:::-;;;108773:614;;;-1:-1:-1::0;109425:14:0::1;::::0;109399:55:::1;::::0;-1:-1:-1;;;109399:55:0;;::::1;::::0;::::1;529:25:1::0;;;-1:-1:-1;;;;;109425:14:0;;::::1;::::0;109399:47:::1;::::0;502:18:1;;109399:55:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;109480:6;109465:11;;:21;;;;;;;:::i;:::-;::::0;;;-1:-1:-1;;109497:7:0::1;:18:::0;;-1:-1:-1;;;;;;109497:18:0::1;-1:-1:-1::0;;;;;109497:18:0;;;::::1;::::0;;;::::1;::::0;;;-1:-1:-1;;;;108448:1075:0:o;108052:248::-;62607:13;:11;:13::i;:::-;-1:-1:-1;;;;;108162:17:0;;::::1;108192:1;108162:17:::0;;;:10:::1;:17;::::0;;;;;::::1;108146:74;;;::::0;-1:-1:-1;;;108146:74:0;;23886:2:1;108146:74:0::1;::::0;::::1;23868:21:1::0;23925:2;23905:18;;;23898:30;-1:-1:-1;;;23944:18:1;;;23937:51;24005:18;;108146:74:0::1;23684:345:1::0;108146:74:0::1;-1:-1:-1::0;;;;;108254:17:0;;::::1;108231:42;108254:17:::0;;;:10:::1;:17;::::0;;;;;;;;;;::::1;108231:42:::0;;:14:::1;:42:::0;;;;;;:61;;-1:-1:-1;;108231:61:0::1;::::0;::::1;;::::0;;;::::1;::::0;;108052:248::o;52942:436::-;53035:4;41844:10;53035:4;53118:25;41844:10;53135:7;53118:9;:25::i;:::-;53091:52;;53182:15;53162:16;:35;;53154:85;;;;-1:-1:-1;;;53154:85:0;;24236:2:1;53154:85:0;;;24218:21:1;24275:2;24255:18;;;24248:30;24314:34;24294:18;;;24287:62;-1:-1:-1;;;24365:18:1;;;24358:35;24410:19;;53154:85:0;24034:401:1;53154:85:0;53275:60;53284:5;53291:7;53319:15;53300:16;:34;53275:8;:60::i;102090:879::-;102245:7;;-1:-1:-1;;;;;102245:7:0;:21;102237:51;;;;-1:-1:-1;;;102237:51:0;;24642:2:1;102237:51:0;;;24624:21:1;24681:2;24661:18;;;24654:30;-1:-1:-1;;;24700:18:1;;;24693:47;24757:18;;102237:51:0;24440:341:1;102237:51:0;102343:14;;-1:-1:-1;;;;;102343:14:0;102321:10;:37;;:69;;;102362:28;102379:10;102362:16;:28::i;:::-;102299:160;;;;-1:-1:-1;;;102299:160:0;;24988:2:1;102299:160:0;;;24970:21:1;25027:2;25007:18;;;25000:30;25066:34;25046:18;;;25039:62;-1:-1:-1;;;25117:18:1;;;25110:39;25166:19;;102299:160:0;24786:405:1;102299:160:0;102498:14;;-1:-1:-1;;;;;102498:14:0;102476:10;:37;102472:490;;102530:32;102546:7;102555:6;102530:15;:32::i;:::-;102581:21;;102577:314;;102623:20;102646:32;;;;102657:9;102646:32;:::i;:::-;102623:55;;102715:12;102705:6;:22;;102697:74;;;;-1:-1:-1;;;102697:74:0;;25398:2:1;102697:74:0;;;25380:21:1;25437:2;25417:18;;;25410:30;25476:34;25456:18;;;25449:62;-1:-1:-1;;;25527:18:1;;;25520:37;25574:19;;102697:74:0;25196:403:1;102697:74:0;-1:-1:-1;;;;;102790:23:0;;;;;;:14;:23;;;;;:39;;102817:12;;102790:23;:39;;102817:12;;102790:39;:::i;:::-;;;;;;;;102863:12;102848:11;;:27;;;;;;;:::i;:::-;;;;-1:-1:-1;;;102577:314:0;102472:490;;;102923:27;102939:10;102923:15;:27::i;:::-;102090:879;;;;:::o;50023:193::-;50102:4;41844:10;50158:28;41844:10;50175:2;50179:6;50158:9;:28::i;93709:100::-;93759:16;93795:6;93788:13;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;93788:13:0;;;;;;;;;;;;;;;;;;;;;;93709:100;:::o;105528:752::-;105595:10;93547:24;93562:8;93547:14;:24::i;:::-;105660:7:::1;105626:30;105645:10;105626:18;:30::i;:::-;:41;;105618:97;;;::::0;-1:-1:-1;;;105618:97:0;;25806:2:1;105618:97:0::1;::::0;::::1;25788:21:1::0;25845:2;25825:18;;;25818:30;25884:34;25864:18;;;25857:62;-1:-1:-1;;;25935:18:1;;;25928:41;25986:19;;105618:97:0::1;25604:407:1::0;105618:97:0::1;105793:10;105728:23;105778:26:::0;;;:14:::1;:26;::::0;;;;;105728:23;;105754:21:::1;::::0;:9:::1;:21::i;:::-;:50;;;;:::i;:::-;105728:76;;105829:15;105819:7;:25;105815:303;;;105861:30;105894:25;105904:15:::0;105894:7;:25:::1;:::i;:::-;105950:10;105934:27;::::0;;;:15:::1;:27;::::0;;;;:53;;105861:58;;-1:-1:-1;105861:58:0;;105934:27;;;:53:::1;::::0;105861:58;;105934:53:::1;:::i;:::-;::::0;;;-1:-1:-1;;106017:10:0::1;106002:26;::::0;;;:14:::1;:26;::::0;;;;:52;;106032:22;;106002:26;:52:::1;::::0;106032:22;;106002:52:::1;:::i;:::-;;;;;;;;106084:22;106069:11;;:37;;;;;;;:::i;:::-;::::0;;;-1:-1:-1;;;105815:303:0::1;106130:26;106136:10;106148:7;106130:5;:26::i;:::-;106172:39;::::0;529:25:1;;;106191:10:0::1;::::0;106172:39:::1;::::0;517:2:1;502:18;106172:39:0::1;;;;;;;106224:14;::::0;:48:::1;::::0;-1:-1:-1;;;;;106224:14:0::1;106252:10;106264:7:::0;106224:27:::1;:48::i;50279:151::-:0;-1:-1:-1;;;;;50395:18:0;;;50368:7;50395:18;;;:11;:18;;;;;;;;:27;;;;;;;;;;;;;50279:151::o;63620:201::-;62607:13;:11;:13::i;:::-;-1:-1:-1;;;;;63709:22:0;::::1;63701:73;;;::::0;-1:-1:-1;;;63701:73:0;;26218:2:1;63701:73:0::1;::::0;::::1;26200:21:1::0;26257:2;26237:18;;;26230:30;26296:34;26276:18;;;26269:62;-1:-1:-1;;;26347:18:1;;;26340:36;26393:19;;63701:73:0::1;26016:402:1::0;63701:73:0::1;63785:28;63804:8;63785:18;:28::i;56935:346::-:0;-1:-1:-1;;;;;57037:19:0;;57029:68;;;;-1:-1:-1;;;57029:68:0;;26625:2:1;57029:68:0;;;26607:21:1;26664:2;26644:18;;;26637:30;26703:34;26683:18;;;26676:62;-1:-1:-1;;;26754:18:1;;;26747:34;26798:19;;57029:68:0;26423:400:1;57029:68:0;-1:-1:-1;;;;;57116:21:0;;57108:68;;;;-1:-1:-1;;;57108:68:0;;27030:2:1;57108:68:0;;;27012:21:1;27069:2;27049:18;;;27042:30;27108:34;27088:18;;;27081:62;-1:-1:-1;;;27159:18:1;;;27152:32;27201:19;;57108:68:0;26828:398:1;57108:68:0;-1:-1:-1;;;;;57189:18:0;;;;;;;:11;:18;;;;;;;;:27;;;;;;;;;;;;;:36;;;57241:32;;529:25:1;;;57241:32:0;;502:18:1;57241:32:0;;;;;;;56935:346;;;:::o;62886:132::-;62794:6;;-1:-1:-1;;;;;62794:6:0;41844:10;62950:23;62942:68;;;;-1:-1:-1;;;62942:68:0;;27433:2:1;62942:68:0;;;27415:21:1;;;27452:18;;;27445:30;27511:34;27491:18;;;27484:62;27563:18;;62942:68:0;27231:356:1;57572:419:0;57673:24;57700:25;57710:5;57717:7;57700:9;:25::i;:::-;57673:52;;-1:-1:-1;;57740:16:0;:37;57736:248;;57822:6;57802:16;:26;;57794:68;;;;-1:-1:-1;;;57794:68:0;;27794:2:1;57794:68:0;;;27776:21:1;27833:2;27813:18;;;27806:30;27872:31;27852:18;;;27845:59;27921:18;;57794:68:0;27592:353:1;57794:68:0;57906:51;57915:5;57922:7;57950:6;57931:16;:25;57906:8;:51::i;103074:154::-;103183:37;;-1:-1:-1;;;103183:37:0;;28152:2:1;103183:37:0;;;28134:21:1;28191:2;28171:18;;;28164:30;28230:29;28210:18;;;28203:57;28277:18;;103183:37:0;27950:351:1;62264:97:0;39579:13;;;;;;;39571:69;;;;-1:-1:-1;;;39571:69:0;;;;;;;:::i;:::-;62327:26:::1;:24;:26::i;78801:68::-:0;39579:13;;;;;;;39571:69;;;;-1:-1:-1;;;39571:69:0;;;;;;;:::i;99371:66::-;62607:13;:11;:13::i;73761:958::-;71861:66;74181:59;;;74177:535;;;74257:37;74276:17;74257:18;:37::i;74177:535::-;74360:17;-1:-1:-1;;;;;74331:61:0;;:63;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;74331:63:0;;;;;;;;-1:-1:-1;;74331:63:0;;;;;;;;;;;;:::i;:::-;;;74327:306;;74561:56;;-1:-1:-1;;;74561:56:0;;28697:2:1;74561:56:0;;;28679:21:1;28736:2;28716:18;;;28709:30;28775:34;28755:18;;;28748:62;-1:-1:-1;;;28826:18:1;;;28819:44;28880:19;;74561:56:0;28495:410:1;74327:306:0;-1:-1:-1;;;;;;;;;;;74445:28:0;;74437:82;;;;-1:-1:-1;;;74437:82:0;;29112:2:1;74437:82:0;;;29094:21:1;29151:2;29131:18;;;29124:30;29190:34;29170:18;;;29163:62;-1:-1:-1;;;29241:18:1;;;29234:39;29290:19;;74437:82:0;28910:405:1;74437:82:0;74395:140;74647:53;74665:17;74684:4;74690:9;74647:17;:53::i;48001:149::-;39579:13;;;;;;;39571:69;;;;-1:-1:-1;;;39571:69:0;;;;;;;:::i;:::-;48104:38:::1;48127:5;48134:7;48104:22;:38::i;54941:548::-:0;-1:-1:-1;;;;;55025:21:0;;55017:65;;;;-1:-1:-1;;;55017:65:0;;29522:2:1;55017:65:0;;;29504:21:1;29561:2;29541:18;;;29534:30;29600:33;29580:18;;;29573:61;29651:18;;55017:65:0;29320:355:1;55017:65:0;55173:6;55157:12;;:22;;;;;;;:::i;:::-;;;;-1:-1:-1;;;;;;;55328:18:0;;;;;;:9;:18;;;;;;;;:28;;;;;;55383:37;529:25:1;;;55383:37:0;;502:18:1;55383:37:0;;;;;;;93185:302;;:::o;60775:269::-;60988:48;;-1:-1:-1;;;60988:48:0;;60973:3;;-1:-1:-1;;;;;60988:24:0;;;;;:48;;61013:7;;61022:6;;61030:5;;60988:48;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;60919:125;60775:269;;;;:::o;55822:675::-;-1:-1:-1;;;;;55906:21:0;;55898:67;;;;-1:-1:-1;;;55898:67:0;;30273:2:1;55898:67:0;;;30255:21:1;30312:2;30292:18;;;30285:30;30351:34;30331:18;;;30324:62;-1:-1:-1;;;30402:18:1;;;30395:31;30443:19;;55898:67:0;30071:397:1;55898:67:0;-1:-1:-1;;;;;56065:18:0;;56040:22;56065:18;;;:9;:18;;;;;;56102:24;;;;56094:71;;;;-1:-1:-1;;;56094:71:0;;30675:2:1;56094:71:0;;;30657:21:1;30714:2;30694:18;;;30687:30;30753:34;30733:18;;;30726:62;-1:-1:-1;;;30804:18:1;;;30797:32;30846:19;;56094:71:0;30473:398:1;56094:71:0;-1:-1:-1;;;;;56201:18:0;;;;;;:9;:18;;;;;;;;56222:23;;;56201:44;;56340:12;:22;;;;;;;56391:37;529:25:1;;;56201:18:0;;;56391:37;;502:18:1;56391:37:0;;;;;;;59826:284;;;:::o;63981:191::-;64074:6;;;-1:-1:-1;;;;;64091:17:0;;;-1:-1:-1;;;;;;64091:17:0;;;;;;;64124:40;;64074:6;;;64091:17;64074:6;;64124:40;;64055:16;;64124:40;64044:128;63981:191;:::o;86108:188::-;86229:58;;;-1:-1:-1;;;;;22965:32:1;;86229:58:0;;;22947:51:1;23014:18;;;;23007:34;;;86229:58:0;;;;;;;;;;22920:18:1;;;;86229:58:0;;;;;;;;-1:-1:-1;;;;;86229:58:0;-1:-1:-1;;;86229:58:0;;;86202:86;;86222:5;;86202:19;:86::i;110385:181::-;110466:7;93547:24;93562:8;93547:14;:24::i;:::-;110486:23:::1;110492:7;110501;110486:5;:23::i;:::-;110541:7;-1:-1:-1::0;;;;;110525:33:0::1;;110550:7;110525:33;;;;529:25:1::0;;517:2;502:18;;383:177;110525:33:0::1;;;;;;;;110385:181:::0;;;:::o;99179:184::-;99246:9;99241:115;99265:6;:13;99261:17;;99241:115;;;99300:10;:21;99311:6;99318:1;99311:9;;;;;;;;:::i;:::-;;;;;;;;;;;;;;-1:-1:-1;;;;;99311:9:0;;;99300:21;;;;;;;;;;;;;;;;:44;;-1:-1:-1;;;99300:44:0;;7277:32:1;;;99300:44:0;;;7259:51:1;99300:21:0;;;:34;;7232:18:1;;99300:44:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;99280:3;;;;;:::i;:::-;;;;99241:115;;62369:113;39579:13;;;;;;;39571:69;;;;-1:-1:-1;;;39571:69:0;;;;;;;:::i;:::-;62442:32:::1;41844:10:::0;62442:18:::1;:32::i;72608:284::-:0;-1:-1:-1;;;;;26202:19:0;;;72682:106;;;;-1:-1:-1;;;72682:106:0;;31078:2:1;72682:106:0;;;31060:21:1;31117:2;31097:18;;;31090:30;31156:34;31136:18;;;31129:62;-1:-1:-1;;;31207:18:1;;;31200:43;31260:19;;72682:106:0;30876:409:1;72682:106:0;-1:-1:-1;;;;;;;;;;;72799:85:0;;-1:-1:-1;;;;;;72799:85:0;-1:-1:-1;;;;;72799:85:0;;;;;;;;;;72608:284::o;73301:281::-;73410:29;73421:17;73410:10;:29::i;:::-;73468:1;73454:4;:11;:15;:28;;;;73473:9;73454:28;73450:125;;;73499:64;73539:17;73558:4;73499:39;:64::i;48158:162::-;39579:13;;;;;;;39571:69;;;;-1:-1:-1;;;39571:69:0;;;;;;;:::i;:::-;48271:5:::1;:13;48279:5:::0;48271;:13:::1;:::i;:::-;-1:-1:-1::0;48295:7:0::1;:17;48305:7:::0;48295;:17:::1;:::i;90508:660::-:0;90943:23;90969:69;90997:4;90969:69;;;;;;;;;;;;;;;;;90977:5;-1:-1:-1;;;;;90969:27:0;;;:69;;;;;:::i;:::-;90943:95;;91057:10;:17;91078:1;91057:22;:56;;;;91094:10;91083:30;;;;;;;;;;;;:::i;:::-;91049:111;;;;-1:-1:-1;;;91049:111:0;;33696:2:1;91049:111:0;;;33678:21:1;33735:2;33715:18;;;33708:30;33774:34;33754:18;;;33747:62;-1:-1:-1;;;33825:18:1;;;33818:40;33875:19;;91049:111:0;33494:406:1;73005:155:0;73072:37;73091:17;73072:18;:37::i;:::-;73125:27;;-1:-1:-1;;;;;73125:27:0;;;;;;;;73005:155;:::o;31299:200::-;31382:12;31414:77;31435:6;31443:4;31414:77;;;;;;;;;;;;;;;;;:20;:77::i;:::-;31407:84;31299:200;-1:-1:-1;;;31299:200:0:o;28662:229::-;28799:12;28831:52;28853:6;28861:4;28867:1;28870:12;28831:21;:52::i;:::-;28824:59;28662:229;-1:-1:-1;;;;28662:229:0:o;31693:332::-;31838:12;31864;31878:23;31905:6;-1:-1:-1;;;;;31905:19:0;31925:4;31905:25;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;31863:67;;;;31948:69;31975:6;31983:7;31992:10;32004:12;31948:26;:69::i;:::-;31941:76;31693:332;-1:-1:-1;;;;;;31693:332:0:o;29748:455::-;29918:12;29976:5;29951:21;:30;;29943:81;;;;-1:-1:-1;;;29943:81:0;;34386:2:1;29943:81:0;;;34368:21:1;34425:2;34405:18;;;34398:30;34464:34;34444:18;;;34437:62;-1:-1:-1;;;34515:18:1;;;34508:36;34561:19;;29943:81:0;34184:402:1;29943:81:0;30036:12;30050:23;30077:6;-1:-1:-1;;;;;30077:11:0;30096:5;30103:4;30077:31;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30035:73;;;;30126:69;30153:6;30161:7;30170:10;30182:12;30126:26;:69::i;:::-;30119:76;29748:455;-1:-1:-1;;;;;;;29748:455:0:o;32321:644::-;32506:12;32535:7;32531:427;;;32563:10;:17;32584:1;32563:22;32559:290;;-1:-1:-1;;;;;26202:19:0;;;32773:60;;;;-1:-1:-1;;;32773:60:0;;34793:2:1;32773:60:0;;;34775:21:1;34832:2;34812:18;;;34805:30;34871:31;34851:18;;;34844:59;34920:18;;32773:60:0;34591:353:1;32773:60:0;-1:-1:-1;32870:10:0;32863:17;;32531:427;32913:33;32921:10;32933:12;33668:17;;:21;33664:388;;33900:10;33894:17;33957:15;33944:10;33940:2;33936:19;33929:44;33664:388;34027:12;34020:20;;-1:-1:-1;;;34020:20:0;;;;;;;;:::i;14:173:1:-;82:20;;-1:-1:-1;;;;;131:31:1;;121:42;;111:70;;177:1;174;167:12;111:70;14:173;;;:::o;192:186::-;251:6;304:2;292:9;283:7;279:23;275:32;272:52;;;320:1;317;310:12;272:52;343:29;362:9;343:29;:::i;565:258::-;637:1;647:113;661:6;658:1;655:13;647:113;;;737:11;;;731:18;718:11;;;711:39;683:2;676:10;647:113;;;778:6;775:1;772:13;769:48;;;-1:-1:-1;;813:1:1;795:16;;788:27;565:258::o;828:::-;870:3;908:5;902:12;935:6;930:3;923:19;951:63;1007:6;1000:4;995:3;991:14;984:4;977:5;973:16;951:63;:::i;:::-;1068:2;1047:15;-1:-1:-1;;1043:29:1;1034:39;;;;1075:4;1030:50;;828:258;-1:-1:-1;;828:258:1:o;1091:220::-;1240:2;1229:9;1222:21;1203:4;1260:45;1301:2;1290:9;1286:18;1278:6;1260:45;:::i;1316:254::-;1384:6;1392;1445:2;1433:9;1424:7;1420:23;1416:32;1413:52;;;1461:1;1458;1451:12;1413:52;1484:29;1503:9;1484:29;:::i;:::-;1474:39;1560:2;1545:18;;;;1532:32;;-1:-1:-1;;;1316:254:1:o;1767:461::-;1820:3;1858:5;1852:12;1885:6;1880:3;1873:19;1911:4;1940:2;1935:3;1931:12;1924:19;;1977:2;1970:5;1966:14;1998:1;2008:195;2022:6;2019:1;2016:13;2008:195;;;2087:13;;-1:-1:-1;;;;;2083:39:1;2071:52;;2143:12;;;;2178:15;;;;2119:1;2037:9;2008:195;;;-1:-1:-1;2219:3:1;;1767:461;-1:-1:-1;;;;;1767:461:1:o;2233:435::-;2286:3;2324:5;2318:12;2351:6;2346:3;2339:19;2377:4;2406:2;2401:3;2397:12;2390:19;;2443:2;2436:5;2432:14;2464:1;2474:169;2488:6;2485:1;2482:13;2474:169;;;2549:13;;2537:26;;2583:12;;;;2618:15;;;;2510:1;2503:9;2474:169;;2673:465;2930:2;2919:9;2912:21;2893:4;2956:56;3008:2;2997:9;2993:18;2985:6;2956:56;:::i;:::-;3060:9;3052:6;3048:22;3043:2;3032:9;3028:18;3021:50;3088:44;3125:6;3117;3088:44;:::i;:::-;3080:52;2673:465;-1:-1:-1;;;;;2673:465:1:o;3143:261::-;3322:2;3311:9;3304:21;3285:4;3342:56;3394:2;3383:9;3379:18;3371:6;3342:56;:::i;3409:328::-;3486:6;3494;3502;3555:2;3543:9;3534:7;3530:23;3526:32;3523:52;;;3571:1;3568;3561:12;3523:52;3594:29;3613:9;3594:29;:::i;:::-;3584:39;;3642:38;3676:2;3665:9;3661:18;3642:38;:::i;:::-;3632:48;;3727:2;3716:9;3712:18;3699:32;3689:42;;3409:328;;;;;:::o;3742:127::-;3803:10;3798:3;3794:20;3791:1;3784:31;3834:4;3831:1;3824:15;3858:4;3855:1;3848:15;3874:275;3945:2;3939:9;4010:2;3991:13;;-1:-1:-1;;3987:27:1;3975:40;;-1:-1:-1;;;;;4030:34:1;;4066:22;;;4027:62;4024:88;;;4092:18;;:::i;:::-;4128:2;4121:22;3874:275;;-1:-1:-1;3874:275:1:o;4154:531::-;4197:5;4250:3;4243:4;4235:6;4231:17;4227:27;4217:55;;4268:1;4265;4258:12;4217:55;4304:6;4291:20;-1:-1:-1;;;;;4326:2:1;4323:26;4320:52;;;4352:18;;:::i;:::-;4396:55;4439:2;4420:13;;-1:-1:-1;;4416:27:1;4445:4;4412:38;4396:55;:::i;:::-;4476:2;4467:7;4460:19;4522:3;4515:4;4510:2;4502:6;4498:15;4494:26;4491:35;4488:55;;;4539:1;4536;4529:12;4488:55;4604:2;4597:4;4589:6;4585:17;4578:4;4569:7;4565:18;4552:55;4652:1;4627:16;;;4645:4;4623:27;4616:38;;;;4631:7;4154:531;-1:-1:-1;;;4154:531:1:o;4690:543::-;4778:6;4786;4839:2;4827:9;4818:7;4814:23;4810:32;4807:52;;;4855:1;4852;4845:12;4807:52;4895:9;4882:23;-1:-1:-1;;;;;4965:2:1;4957:6;4954:14;4951:34;;;4981:1;4978;4971:12;4951:34;5004:50;5046:7;5037:6;5026:9;5022:22;5004:50;:::i;:::-;4994:60;;5107:2;5096:9;5092:18;5079:32;5063:48;;5136:2;5126:8;5123:16;5120:36;;;5152:1;5149;5142:12;5120:36;;5175:52;5219:7;5208:8;5197:9;5193:24;5175:52;:::i;:::-;5165:62;;;4690:543;;;;;:::o;5427:611::-;5524:6;5532;5540;5593:2;5581:9;5572:7;5568:23;5564:32;5561:52;;;5609:1;5606;5599:12;5561:52;5649:9;5636:23;-1:-1:-1;;;;;5719:2:1;5711:6;5708:14;5705:34;;;5735:1;5732;5725:12;5705:34;5758:50;5800:7;5791:6;5780:9;5776:22;5758:50;:::i;:::-;5748:60;;5861:2;5850:9;5846:18;5833:32;5817:48;;5890:2;5880:8;5877:16;5874:36;;;5906:1;5903;5896:12;5874:36;;5929:52;5973:7;5962:8;5951:9;5947:24;5929:52;:::i;:::-;5919:62;;;6028:2;6017:9;6013:18;6000:32;5990:42;;5427:611;;;;;:::o;6043:463::-;6129:6;6137;6145;6198:2;6186:9;6177:7;6173:23;6169:32;6166:52;;;6214:1;6211;6204:12;6166:52;6237:29;6256:9;6237:29;:::i;:::-;6227:39;;6313:2;6302:9;6298:18;6285:32;6275:42;;6368:2;6357:9;6353:18;6340:32;-1:-1:-1;;;;;6387:6:1;6384:30;6381:50;;;6427:1;6424;6417:12;6381:50;6450;6492:7;6483:6;6472:9;6468:22;6450:50;:::i;:::-;6440:60;;;6043:463;;;;;:::o;6511:395::-;6588:6;6596;6649:2;6637:9;6628:7;6624:23;6620:32;6617:52;;;6665:1;6662;6655:12;6617:52;6688:29;6707:9;6688:29;:::i;:::-;6678:39;;6768:2;6757:9;6753:18;6740:32;-1:-1:-1;;;;;6787:6:1;6784:30;6781:50;;;6827:1;6824;6817:12;6781:50;6850;6892:7;6883:6;6872:9;6868:22;6850:50;:::i;7321:260::-;7389:6;7397;7450:2;7438:9;7429:7;7425:23;7421:32;7418:52;;;7466:1;7463;7456:12;7418:52;7489:29;7508:9;7489:29;:::i;:::-;7479:39;;7537:38;7571:2;7560:9;7556:18;7537:38;:::i;:::-;7527:48;;7321:260;;;;;:::o;7586:352::-;7653:6;7661;7714:2;7702:9;7693:7;7689:23;7685:32;7682:52;;;7730:1;7727;7720:12;7682:52;7766:9;7753:23;7743:33;;7826:2;7815:9;7811:18;7798:32;-1:-1:-1;;;;;7863:5:1;7859:30;7852:5;7849:41;7839:69;;7904:1;7901;7894:12;7839:69;7927:5;7917:15;;;7586:352;;;;;:::o;8151:952::-;8235:6;8266:2;8309;8297:9;8288:7;8284:23;8280:32;8277:52;;;8325:1;8322;8315:12;8277:52;8365:9;8352:23;-1:-1:-1;;;;;8435:2:1;8427:6;8424:14;8421:34;;;8451:1;8448;8441:12;8421:34;8489:6;8478:9;8474:22;8464:32;;8534:7;8527:4;8523:2;8519:13;8515:27;8505:55;;8556:1;8553;8546:12;8505:55;8592:2;8579:16;8614:2;8610;8607:10;8604:36;;;8620:18;;:::i;:::-;8666:2;8663:1;8659:10;8649:20;;8689:28;8713:2;8709;8705:11;8689:28;:::i;:::-;8751:15;;;8821:11;;;8817:20;;;8782:12;;;;8849:19;;;8846:39;;;8881:1;8878;8871:12;8846:39;8905:11;;;;8925:148;8941:6;8936:3;8933:15;8925:148;;;9007:23;9026:3;9007:23;:::i;:::-;8995:36;;8958:12;;;;9051;;;;8925:148;;;9092:5;8151:952;-1:-1:-1;;;;;;;;8151:952:1:o;9108:348::-;9160:8;9170:6;9224:3;9217:4;9209:6;9205:17;9201:27;9191:55;;9242:1;9239;9232:12;9191:55;-1:-1:-1;9265:20:1;;-1:-1:-1;;;;;9297:30:1;;9294:50;;;9340:1;9337;9330:12;9294:50;9377:4;9369:6;9365:17;9353:29;;9429:3;9422:4;9413:6;9405;9401:19;9397:30;9394:39;9391:59;;;9446:1;9443;9436:12;9391:59;9108:348;;;;;:::o;9461:367::-;9524:8;9534:6;9588:3;9581:4;9573:6;9569:17;9565:27;9555:55;;9606:1;9603;9596:12;9555:55;-1:-1:-1;9629:20:1;;-1:-1:-1;;;;;9661:30:1;;9658:50;;;9704:1;9701;9694:12;9658:50;9741:4;9733:6;9729:17;9717:29;;9801:3;9794:4;9784:6;9781:1;9777:14;9769:6;9765:27;9761:38;9758:47;9755:67;;;9818:1;9815;9808:12;9833:1111;9970:6;9978;9986;9994;10002;10010;10018;10071:3;10059:9;10050:7;10046:23;10042:33;10039:53;;;10088:1;10085;10078:12;10039:53;10111:29;10130:9;10111:29;:::i;:::-;10101:39;;10191:2;10180:9;10176:18;10163:32;-1:-1:-1;;;;;10255:2:1;10247:6;10244:14;10241:34;;;10271:1;10268;10261:12;10241:34;10310:59;10361:7;10352:6;10341:9;10337:22;10310:59;:::i;:::-;10388:8;;-1:-1:-1;10284:85:1;-1:-1:-1;10476:2:1;10461:18;;10448:32;;-1:-1:-1;10492:16:1;;;10489:36;;;10521:1;10518;10511:12;10489:36;10560:61;10613:7;10602:8;10591:9;10587:24;10560:61;:::i;:::-;10640:8;;-1:-1:-1;10534:87:1;-1:-1:-1;10728:2:1;10713:18;;10700:32;;-1:-1:-1;10744:16:1;;;10741:36;;;10773:1;10770;10763:12;10741:36;;10812:72;10876:7;10865:8;10854:9;10850:24;10812:72;:::i;:::-;9833:1111;;;;-1:-1:-1;9833:1111:1;;-1:-1:-1;9833:1111:1;;;;10786:98;;-1:-1:-1;;;9833:1111:1:o;10949:511::-;11044:6;11052;11060;11113:2;11101:9;11092:7;11088:23;11084:32;11081:52;;;11129:1;11126;11119:12;11081:52;11169:9;11156:23;-1:-1:-1;;;;;11194:6:1;11191:30;11188:50;;;11234:1;11231;11224:12;11188:50;11273:70;11335:7;11326:6;11315:9;11311:22;11273:70;:::i;:::-;11362:8;;-1:-1:-1;11247:96:1;-1:-1:-1;11416:38:1;;-1:-1:-1;11450:2:1;11435:18;;11416:38;:::i;:::-;11406:48;;10949:511;;;;;:::o;11465:118::-;11551:5;11544:13;11537:21;11530:5;11527:32;11517:60;;11573:1;11570;11563:12;11588:315;11653:6;11661;11714:2;11702:9;11693:7;11689:23;11685:32;11682:52;;;11730:1;11727;11720:12;11682:52;11753:29;11772:9;11753:29;:::i;:::-;11743:39;;11832:2;11821:9;11817:18;11804:32;11845:28;11867:5;11845:28;:::i;11908:552::-;11996:6;12004;12012;12020;12073:2;12061:9;12052:7;12048:23;12044:32;12041:52;;;12089:1;12086;12079:12;12041:52;12112:29;12131:9;12112:29;:::i;:::-;12102:39;;12188:2;12177:9;12173:18;12160:32;12150:42;;12243:2;12232:9;12228:18;12215:32;-1:-1:-1;;;;;12262:6:1;12259:30;12256:50;;;12302:1;12299;12292:12;12256:50;12341:59;12392:7;12383:6;12372:9;12368:22;12341:59;:::i;:::-;11908:552;;;;-1:-1:-1;12419:8:1;-1:-1:-1;;;;11908:552:1:o;12465:261::-;12644:2;12633:9;12626:21;12607:4;12664:56;12716:2;12705:9;12701:18;12693:6;12664:56;:::i;12731:180::-;12790:6;12843:2;12831:9;12822:7;12818:23;12814:32;12811:52;;;12859:1;12856;12849:12;12811:52;-1:-1:-1;12882:23:1;;12731:180;-1:-1:-1;12731:180:1:o;13379:380::-;13458:1;13454:12;;;;13501;;;13522:61;;13576:4;13568:6;13564:17;13554:27;;13522:61;13629:2;13621:6;13618:14;13598:18;13595:38;13592:161;;13675:10;13670:3;13666:20;13663:1;13656:31;13710:4;13707:1;13700:15;13738:4;13735:1;13728:15;13592:161;;13379:380;;;:::o;14116:127::-;14177:10;14172:3;14168:20;14165:1;14158:31;14208:4;14205:1;14198:15;14232:4;14229:1;14222:15;14248:184;14318:6;14371:2;14359:9;14350:7;14346:23;14342:32;14339:52;;;14387:1;14384;14377:12;14339:52;-1:-1:-1;14410:16:1;;14248:184;-1:-1:-1;14248:184:1:o;14437:127::-;14498:10;14493:3;14489:20;14486:1;14479:31;14529:4;14526:1;14519:15;14553:4;14550:1;14543:15;14569:135;14608:3;14629:17;;;14626:43;;14649:18;;:::i;:::-;-1:-1:-1;14696:1:1;14685:13;;14569:135::o;14709:125::-;14749:4;14777:1;14774;14771:8;14768:34;;;14782:18;;:::i;:::-;-1:-1:-1;14819:9:1;;14709:125::o;14839:128::-;14879:3;14910:1;14906:6;14903:1;14900:13;14897:39;;;14916:18;;:::i;:::-;-1:-1:-1;14952:9:1;;14839:128::o;14972:407::-;15174:2;15156:21;;;15213:2;15193:18;;;15186:30;15252:34;15247:2;15232:18;;15225:62;-1:-1:-1;;;15318:2:1;15303:18;;15296:41;15369:3;15354:19;;14972:407::o;15384:408::-;15586:2;15568:21;;;15625:2;15605:18;;;15598:30;15664:34;15659:2;15644:18;;15637:62;-1:-1:-1;;;15730:2:1;15715:18;;15708:42;15782:3;15767:19;;15384:408::o;15797:::-;15999:2;15981:21;;;16038:2;16018:18;;;16011:30;16077:34;16072:2;16057:18;;16050:62;-1:-1:-1;;;16143:2:1;16128:18;;16121:42;16195:3;16180:19;;15797:408::o;16210:422::-;16299:1;16342:5;16299:1;16356:270;16377:7;16367:8;16364:21;16356:270;;;16436:4;16432:1;16428:6;16424:17;16418:4;16415:27;16412:53;;;16445:18;;:::i;:::-;16495:7;16485:8;16481:22;16478:55;;;16515:16;;;;16478:55;16594:22;;;;16554:15;;;;16356:270;;;16360:3;16210:422;;;;;:::o;16637:806::-;16686:5;16716:8;16706:80;;-1:-1:-1;16757:1:1;16771:5;;16706:80;16805:4;16795:76;;-1:-1:-1;16842:1:1;16856:5;;16795:76;16887:4;16905:1;16900:59;;;;16973:1;16968:130;;;;16880:218;;16900:59;16930:1;16921:10;;16944:5;;;16968:130;17005:3;16995:8;16992:17;16989:43;;;17012:18;;:::i;:::-;-1:-1:-1;;17068:1:1;17054:16;;17083:5;;16880:218;;17182:2;17172:8;17169:16;17163:3;17157:4;17154:13;17150:36;17144:2;17134:8;17131:16;17126:2;17120:4;17117:12;17113:35;17110:77;17107:159;;;-1:-1:-1;17219:19:1;;;17251:5;;17107:159;17298:34;17323:8;17317:4;17298:34;:::i;:::-;17368:6;17364:1;17360:6;17356:19;17347:7;17344:32;17341:58;;;17379:18;;:::i;:::-;17417:20;;16637:806;-1:-1:-1;;;16637:806:1:o;17448:131::-;17508:5;17537:36;17564:8;17558:4;17537:36;:::i;17584:168::-;17624:7;17690:1;17686;17682:6;17678:14;17675:1;17672:21;17667:1;17660:9;17653:17;17649:45;17646:71;;;17697:18;;:::i;:::-;-1:-1:-1;17737:9:1;;17584:168::o;20770:127::-;20831:10;20826:3;20822:20;20819:1;20812:31;20862:4;20859:1;20852:15;20886:4;20883:1;20876:15;23052:245;23119:6;23172:2;23160:9;23151:7;23147:23;23143:32;23140:52;;;23188:1;23185;23178:12;23140:52;23220:9;23214:16;23239:28;23261:5;23239:28;:::i;29680:386::-;29912:1;29908;29903:3;29899:11;29895:19;29887:6;29883:32;29872:9;29865:51;29952:6;29947:2;29936:9;29932:18;29925:34;29995:2;29990;29979:9;29975:18;29968:30;29846:4;30015:45;30056:2;30045:9;30041:18;30033:6;30015:45;:::i;31416:545::-;31518:2;31513:3;31510:11;31507:448;;;31554:1;31579:5;31575:2;31568:17;31624:4;31620:2;31610:19;31694:2;31682:10;31678:19;31675:1;31671:27;31665:4;31661:38;31730:4;31718:10;31715:20;31712:47;;;-1:-1:-1;31753:4:1;31712:47;31808:2;31803:3;31799:12;31796:1;31792:20;31786:4;31782:31;31772:41;;31863:82;31881:2;31874:5;31871:13;31863:82;;;31926:17;;;31907:1;31896:13;31863:82;;;31867:3;;;31416:545;;;:::o;32137:1352::-;32263:3;32257:10;-1:-1:-1;;;;;32282:6:1;32279:30;32276:56;;;32312:18;;:::i;:::-;32341:97;32431:6;32391:38;32423:4;32417:11;32391:38;:::i;:::-;32385:4;32341:97;:::i;:::-;32493:4;;32557:2;32546:14;;32574:1;32569:663;;;;33276:1;33293:6;33290:89;;;-1:-1:-1;33345:19:1;;;33339:26;33290:89;-1:-1:-1;;32094:1:1;32090:11;;;32086:24;32082:29;32072:40;32118:1;32114:11;;;32069:57;33392:81;;32539:944;;32569:663;31363:1;31356:14;;;31400:4;31387:18;;-1:-1:-1;;32605:20:1;;;32723:236;32737:7;32734:1;32731:14;32723:236;;;32826:19;;;32820:26;32805:42;;32918:27;;;;32886:1;32874:14;;;;32753:19;;32723:236;;;32727:3;32987:6;32978:7;32975:19;32972:201;;;33048:19;;;33042:26;-1:-1:-1;;33131:1:1;33127:14;;;33143:3;33123:24;33119:37;33115:42;33100:58;33085:74;;32972:201;-1:-1:-1;;;;;33219:1:1;33203:14;;;33199:22;33186:36;;-1:-1:-1;32137:1352:1:o;33905:274::-;34034:3;34072:6;34066:13;34088:53;34134:6;34129:3;34122:4;34114:6;34110:17;34088:53;:::i;:::-;34157:16;;;;;33905:274;-1:-1:-1;;33905:274:1:o
Swarm Source
ipfs://afa15878e5d0f7ed19cc8dde4ac72d5905c7071c221a2be428c1c8489f5618d4
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 26 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
Loading...
Loading
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.