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 | 17129452 | 507 days ago | IN | 0 ETH | 0.18701287 |
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:
LiquidityMining
Compiler Version
v0.8.17+commit.8df45f5f
Contract Source Code (Solidity)
/** *Submitted for verification at Etherscan.io on 2023-04-26 */ // SPDX-License-Identifier: BSD-3-Clause // File: @openzeppelin/contracts/token/ERC20/IERC20.sol // 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/interfaces/IStakedToken.sol pragma solidity 0.8.17; /// @title Interface of the Staked Token. interface IStakedToken is IERC20 { /** * @dev Contract id. * The keccak-256 hash of "io.ipor.IporToken" decreased by 1 */ function getContractId() external pure returns (bytes32); } // File: contracts/interfaces/types/PowerTokenTypes.sol pragma solidity 0.8.17; /// @title Struct used across Liquidity Mining. library PowerTokenTypes { struct PwTokenCooldown { // @dev The timestamp when the account can redeem Power Tokens uint256 endTimestamp; // @dev The amount of Power Tokens which can be redeemed without fee when the cooldown reaches `endTimestamp` uint256 pwTokenAmount; } } // File: contracts/interfaces/IPowerTokenInternal.sol pragma solidity 0.8.17; /// @title PowerToken smart contract interface interface IPowerTokenInternal { /// @notice Returns the current version of the PowerToken smart contract /// @return Current PowerToken smart contract version function getVersion() external pure returns (uint256); /// @notice Gets the total supply base amount /// @return total supply base amount, represented with 18 decimals function totalSupplyBase() external view returns (uint256); /// @notice Calculates the internal exchange rate between the Staked Token and total supply of a base amount /// @return Current exchange rate between the Staked Token and the total supply of a base amount, represented with 18 decimals. function calculateExchangeRate() external view returns (uint256); /// @notice Method for seting up the unstaking fee /// @param unstakeWithoutCooldownFee fee percentage, represented with 18 decimals. function setUnstakeWithoutCooldownFee(uint256 unstakeWithoutCooldownFee) external; /// @notice method allowing for claiming of the rewards /// @param account - address of user claiming rewards /// @param rewardsAmount - amount of rewards, represented with 18 decimals. function receiveRewardsFromLiquidityMining(address account, uint256 rewardsAmount) external; /// @notice method returning address of liquidity rewards contract - the LiquidityMining function getLiquidityMining() external view returns (address); /// @notice method returning address of the Staked Token function getStakedToken() external view returns (address); /// @notice Gets the Pause Manager's address /// @return Pause Manager's address function getPauseManager() external view returns (address); /// @notice method for setting up the address of LiquidityMining /// @param liquidityMining - the new address of the LiquidityMining contract function setLiquidityMining(address liquidityMining) external; /// @notice Sets the new Pause Manager address /// @param newPauseManagerAddr - new Pause Manager's address function setPauseManager(address newPauseManagerAddr) external; /// @notice Pauses the smart contract, it can only be executed by the Owner /// @dev Emits {Paused} event. function pause() external; /// @notice Unpauses the smart contract, it can only be executed by the Owner /// @dev Emits {Unpaused}. function unpause() external; /// @notice Emitted when the user receives rewards from the LiquidityMining /// @dev Receiving rewards does not change Internal Exchange Rate of Power Tokens in PowerToken smart contract. /// @param account address /// @param rewardsAmount amount of Power Tokens received from LiquidityMining event RewardsReceived(address account, uint256 rewardsAmount); /// @notice Emitted when the fee for immediate unstaking is modified. /// @param changedBy account address that changed the configuration /// @param oldFee old value of the fee, represented with 18 decimals /// @param newFee new value of the fee, represented with 18 decimals event UnstakeWithoutCooldownFeeChanged( address indexed changedBy, uint256 oldFee, uint256 newFee ); /// @notice Emmited when PauseManager's address had been changed by its owner. /// @param changedBy account address that has changed the LiquidityMining's address /// @param oldLiquidityMining PauseManager's old address /// @param newLiquidityMining PauseManager's new address event LiquidityMiningChanged( address indexed changedBy, address indexed oldLiquidityMining, address indexed newLiquidityMining ); /// @notice Emmited when the PauseManager's address is changed by its owner. /// @param changedBy account address that has changed the LiquidityMining's address /// @param oldPauseManager PauseManager's old address /// @param newPauseManager PauseManager's new address event PauseManagerChanged( address indexed changedBy, address indexed oldPauseManager, address indexed newPauseManager ); } // File: contracts/interfaces/IPowerToken.sol pragma solidity 0.8.17; /// @title The Interface for the interaction with the PowerToken - smart contract responsible /// for managing Power Token (pwToken), Swapping Staked Token for Power Tokens, and /// delegating Power Tokens to other components. interface IPowerToken { /// @notice Gets the name of the Power Token /// @return Returns the name of the Power Token. function name() external pure returns (string memory); /// @notice Contract ID. The keccak-256 hash of "io.ipor.PowerToken" decreased by 1 /// @return Returns the ID of the contract function getContractId() external pure returns (bytes32); /// @notice Gets the symbol of the Power Token. /// @return Returns the symbol of the Power Token. function symbol() external pure returns (string memory); /// @notice Returns the number of the decimals used by Power Token. By default it's 18 decimals. /// @return Returns the number of decimals: 18. function decimals() external pure returns (uint8); /// @notice Gets the total supply of the Power Token. /// @dev Value is calculated in runtime using baseTotalSupply and internal exchange rate. /// @return Total supply of Power tokens, represented with 18 decimals function totalSupply() external view returns (uint256); /// @notice Gets the balance of Power Tokens for a given account /// @param account account address for which the balance of Power Tokens is fetched /// @return Returns the amount of the Power Tokens owned by the `account`. function balanceOf(address account) external view returns (uint256); /// @notice Gets the delegated balance of the Power Tokens for a given account. /// Tokens are delegated from PowerToken to LiquidityMining smart contract (reponsible for rewards distribution). /// @param account account address for which the balance of delegated Power Tokens is checked /// @return Returns the amount of the Power Tokens owned by the `account` and delegated to the LiquidityMining contracts. function delegatedToLiquidityMiningBalanceOf(address account) external view returns (uint256); /// @notice Gets the rate of the fee from the configuration. This fee is applied when the owner of Power Tokens wants to unstake them immediately. /// @dev Fee value represented in as a percentage with 18 decimals /// @return value, a percentage represented with 18 decimal function getUnstakeWithoutCooldownFee() external view returns (uint256); /// @notice Gets the state of the active cooldown for the sender. /// @dev If PowerTokenTypes.PowerTokenCoolDown contains only zeros it represents no active cool down. /// Struct containing information on when the cooldown end and what is the quantity of the Power Tokens locked. /// @param account account address that owns Power Tokens in the cooldown /// @return Object PowerTokenTypes.PowerTokenCoolDown represents active cool down function getActiveCooldown(address account) external view returns (PowerTokenTypes.PwTokenCooldown memory); /// @notice Stakes [Staked] Tokens and mints Power Tokens (pwToken). /// @param stakedTokenAmount Tokens that sender staked to mint the Power Tokens function stake(uint256 stakedTokenAmount) external; /// @notice Unstakes Staked Tokens in the amount specified. /// @dev If the sender unstake tokens immediately (without the cooldown), then fee is applied by the PowerToken smart contract. See: `UnstakeWithoutCooldownFee`. /// @param pwTokenAmount Power Tokens amount which will be unstake or a given sender function unstake(uint256 pwTokenAmount) external; /// @notice Delegates the Power Tokens to the LiquidityMining /// @param lpTokens - list of lpTokens to which Power Tokens are delegated /// @param pwTokenAmounts - list of the amounts of Power Tokens delegated to corresponding lpTokens function delegateToLiquidityMining( address[] calldata lpTokens, uint256[] calldata pwTokenAmounts ) external; /// @notice Delegates Power Tokens and stakes lpTokens /// @dev Power Token amounts can equal zero. lpToken amounts can qual zero. /// @param lpTokens - list of lpTokens to which the sender delegates Power Tokens /// @param pwTokenAmounts - list of the amounts of Power Tokens delegated to correspondng lpTokens /// @param lpTokenAmounts - list of staked lpToken amounts function delegateAndStakeToLiquidityMining( address[] calldata lpTokens, uint256[] calldata pwTokenAmounts, uint256[] calldata lpTokenAmounts ) external; /// @notice Undelegates the Power Tokens from the LiquidityMining /// @dev Power Token amounts have to be higher than zero, otherwise transaction is reverted. /// @param lpTokens - list of the lpToken from which Power Tokens are undelegated /// @param pwTokenAmounts - list of the undelegated amounts of the Power Tokens function undelegateFromLiquidityMining( address[] calldata lpTokens, uint256[] calldata pwTokenAmounts ) external; /// @notice Resets the colldown of Power Tokens to the set duration of 2 weeks. /// @dev Power Tokens in cooldown cannot be unstaked without fee, /// when the cooldown is elapsed then Power Tokens can be unstaked without fee. /// Fee for immediate unstaking (without cooldown) is configured in param `_unstakeWithoutCooldownFee` /// Power Tokens can be redeemed for Staked Tokens in relation of 1:1. /// @param pwTokenAmount Power Token amount to be set in the cooldown function cooldown(uint256 pwTokenAmount) external; /// @notice Cancel the cooldown. /// @dev When this method is executed, all Power Tokens are released. function cancelCooldown() external; /// @notice The method allowing redemption of Power Tokens for the Staked Token after cooldown has passed. /// @dev Power Tokens are redeemable for Staked tokens at 1:1 ratio. /// @dev When the sender executes `redeem` method then the structure {PowerTokenTypes.PwTokenCoolDown} is cleared for a given sender in `_coolDowns` storage. function redeem() external; /// @notice Emitted when the account stakes [Staked] Tokens /// @param account account address that executed the staking /// @param stakedTokenAmount of Staked Token amount being staked into PowerToken contract /// @param internalExchangeRate internal exchange rate used to calculate the base amount /// @param baseAmount value calculated based on the stakedTokenAmount and the internalExchangeRate event Staked( address indexed account, uint256 stakedTokenAmount, uint256 internalExchangeRate, uint256 baseAmount ); /// @notice Emitted when the account unstakes the Power Tokens /// @param account address that executed the unstaking /// @param pwTokenAmount amount of Power Tokens that were unstaked /// @param internalExchangeRate which was used to calculate the base amount /// @param fee amount subtracted from the pwTokenAmount event Unstaked( address indexed account, uint256 pwTokenAmount, uint256 internalExchangeRate, uint256 fee ); /// @notice Emitted when the sender delegates the Power Tokens to the LiquidityMining contract /// @param account address delegating the Power Tokens /// @param lpTokens list of the tokens representing staking pools /// @param pwTokenAmounts amounts of Power Tokens delegated to respective lpTokens event ToLiquidityMiningDelegated( address indexed account, address[] lpTokens, uint256[] pwTokenAmounts ); /// @notice Emitted when the sender undelegates Power Tokens from the LiquidityMining /// @param account address undelegating Power Tokens /// @param lpTokens list of the tokens representing staking pools /// @param pwTokenAmounts amounts of Power Tokens undelegated form respective lpTokens event FromLiquidityMiningUndelegated( address indexed account, address[] lpTokens, uint256[] pwTokenAmounts ); /// @notice Emitted when the sender sets the cooldown on Power Tokens /// @param changedBy account address that has changed the cooldown rules /// @param pwTokenAmount amount of pwToken in cooldown /// @param endTimestamp end time of the cooldown event CooldownChanged(address indexed changedBy, uint256 pwTokenAmount, uint256 endTimestamp); /// @notice Emitted when the sender redeems the pwTokens after the cooldown /// @param account address that executed the redeem function /// @param pwTokenAmount amount of the pwTokens that was transferred to the Power Token owner's address event Redeem(address indexed account, uint256 pwTokenAmount); } // File: contracts/libraries/math/Math.sol pragma solidity 0.8.17; library Math { //@notice Division with the rounding up on last position, x, and y is with MD function division(uint256 x, uint256 y) internal pure returns (uint256 z) { z = (x + (y / 2)) / y; } } // File: contracts/libraries/Constants.sol pragma solidity 0.8.17; library Constants { uint256 public constant MAX_VALUE = type(uint256).max; uint256 public constant D10 = 1e10; uint256 public constant D17 = 1e17; uint256 public constant D18 = 1e18; uint256 public constant D19 = 1e19; uint256 public constant D45 = 1e45; } // File: @openzeppelin/contracts/utils/math/SafeCast.sol // OpenZeppelin Contracts (last updated v4.7.0) (utils/math/SafeCast.sol) pragma solidity ^0.8.0; /** * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow * checks. * * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can * easily result in undesired exploitation or bugs, since developers usually * assume that overflows raise errors. `SafeCast` restores this intuition by * reverting the transaction when such an operation overflows. * * Using this library instead of the unchecked operations eliminates an entire * class of bugs, so it's recommended to use it always. * * Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing * all math on `uint256` and `int256` and then downcasting. */ library SafeCast { /** * @dev Returns the downcasted uint248 from uint256, reverting on * overflow (when the input is greater than largest uint248). * * Counterpart to Solidity's `uint248` operator. * * Requirements: * * - input must fit into 248 bits * * _Available since v4.7._ */ function toUint248(uint256 value) internal pure returns (uint248) { require(value <= type(uint248).max, "SafeCast: value doesn't fit in 248 bits"); return uint248(value); } /** * @dev Returns the downcasted uint240 from uint256, reverting on * overflow (when the input is greater than largest uint240). * * Counterpart to Solidity's `uint240` operator. * * Requirements: * * - input must fit into 240 bits * * _Available since v4.7._ */ function toUint240(uint256 value) internal pure returns (uint240) { require(value <= type(uint240).max, "SafeCast: value doesn't fit in 240 bits"); return uint240(value); } /** * @dev Returns the downcasted uint232 from uint256, reverting on * overflow (when the input is greater than largest uint232). * * Counterpart to Solidity's `uint232` operator. * * Requirements: * * - input must fit into 232 bits * * _Available since v4.7._ */ function toUint232(uint256 value) internal pure returns (uint232) { require(value <= type(uint232).max, "SafeCast: value doesn't fit in 232 bits"); return uint232(value); } /** * @dev Returns the downcasted uint224 from uint256, reverting on * overflow (when the input is greater than largest uint224). * * Counterpart to Solidity's `uint224` operator. * * Requirements: * * - input must fit into 224 bits * * _Available since v4.2._ */ function toUint224(uint256 value) internal pure returns (uint224) { require(value <= type(uint224).max, "SafeCast: value doesn't fit in 224 bits"); return uint224(value); } /** * @dev Returns the downcasted uint216 from uint256, reverting on * overflow (when the input is greater than largest uint216). * * Counterpart to Solidity's `uint216` operator. * * Requirements: * * - input must fit into 216 bits * * _Available since v4.7._ */ function toUint216(uint256 value) internal pure returns (uint216) { require(value <= type(uint216).max, "SafeCast: value doesn't fit in 216 bits"); return uint216(value); } /** * @dev Returns the downcasted uint208 from uint256, reverting on * overflow (when the input is greater than largest uint208). * * Counterpart to Solidity's `uint208` operator. * * Requirements: * * - input must fit into 208 bits * * _Available since v4.7._ */ function toUint208(uint256 value) internal pure returns (uint208) { require(value <= type(uint208).max, "SafeCast: value doesn't fit in 208 bits"); return uint208(value); } /** * @dev Returns the downcasted uint200 from uint256, reverting on * overflow (when the input is greater than largest uint200). * * Counterpart to Solidity's `uint200` operator. * * Requirements: * * - input must fit into 200 bits * * _Available since v4.7._ */ function toUint200(uint256 value) internal pure returns (uint200) { require(value <= type(uint200).max, "SafeCast: value doesn't fit in 200 bits"); return uint200(value); } /** * @dev Returns the downcasted uint192 from uint256, reverting on * overflow (when the input is greater than largest uint192). * * Counterpart to Solidity's `uint192` operator. * * Requirements: * * - input must fit into 192 bits * * _Available since v4.7._ */ function toUint192(uint256 value) internal pure returns (uint192) { require(value <= type(uint192).max, "SafeCast: value doesn't fit in 192 bits"); return uint192(value); } /** * @dev Returns the downcasted uint184 from uint256, reverting on * overflow (when the input is greater than largest uint184). * * Counterpart to Solidity's `uint184` operator. * * Requirements: * * - input must fit into 184 bits * * _Available since v4.7._ */ function toUint184(uint256 value) internal pure returns (uint184) { require(value <= type(uint184).max, "SafeCast: value doesn't fit in 184 bits"); return uint184(value); } /** * @dev Returns the downcasted uint176 from uint256, reverting on * overflow (when the input is greater than largest uint176). * * Counterpart to Solidity's `uint176` operator. * * Requirements: * * - input must fit into 176 bits * * _Available since v4.7._ */ function toUint176(uint256 value) internal pure returns (uint176) { require(value <= type(uint176).max, "SafeCast: value doesn't fit in 176 bits"); return uint176(value); } /** * @dev Returns the downcasted uint168 from uint256, reverting on * overflow (when the input is greater than largest uint168). * * Counterpart to Solidity's `uint168` operator. * * Requirements: * * - input must fit into 168 bits * * _Available since v4.7._ */ function toUint168(uint256 value) internal pure returns (uint168) { require(value <= type(uint168).max, "SafeCast: value doesn't fit in 168 bits"); return uint168(value); } /** * @dev Returns the downcasted uint160 from uint256, reverting on * overflow (when the input is greater than largest uint160). * * Counterpart to Solidity's `uint160` operator. * * Requirements: * * - input must fit into 160 bits * * _Available since v4.7._ */ function toUint160(uint256 value) internal pure returns (uint160) { require(value <= type(uint160).max, "SafeCast: value doesn't fit in 160 bits"); return uint160(value); } /** * @dev Returns the downcasted uint152 from uint256, reverting on * overflow (when the input is greater than largest uint152). * * Counterpart to Solidity's `uint152` operator. * * Requirements: * * - input must fit into 152 bits * * _Available since v4.7._ */ function toUint152(uint256 value) internal pure returns (uint152) { require(value <= type(uint152).max, "SafeCast: value doesn't fit in 152 bits"); return uint152(value); } /** * @dev Returns the downcasted uint144 from uint256, reverting on * overflow (when the input is greater than largest uint144). * * Counterpart to Solidity's `uint144` operator. * * Requirements: * * - input must fit into 144 bits * * _Available since v4.7._ */ function toUint144(uint256 value) internal pure returns (uint144) { require(value <= type(uint144).max, "SafeCast: value doesn't fit in 144 bits"); return uint144(value); } /** * @dev Returns the downcasted uint136 from uint256, reverting on * overflow (when the input is greater than largest uint136). * * Counterpart to Solidity's `uint136` operator. * * Requirements: * * - input must fit into 136 bits * * _Available since v4.7._ */ function toUint136(uint256 value) internal pure returns (uint136) { require(value <= type(uint136).max, "SafeCast: value doesn't fit in 136 bits"); return uint136(value); } /** * @dev Returns the downcasted uint128 from uint256, reverting on * overflow (when the input is greater than largest uint128). * * Counterpart to Solidity's `uint128` operator. * * Requirements: * * - input must fit into 128 bits * * _Available since v2.5._ */ function toUint128(uint256 value) internal pure returns (uint128) { require(value <= type(uint128).max, "SafeCast: value doesn't fit in 128 bits"); return uint128(value); } /** * @dev Returns the downcasted uint120 from uint256, reverting on * overflow (when the input is greater than largest uint120). * * Counterpart to Solidity's `uint120` operator. * * Requirements: * * - input must fit into 120 bits * * _Available since v4.7._ */ function toUint120(uint256 value) internal pure returns (uint120) { require(value <= type(uint120).max, "SafeCast: value doesn't fit in 120 bits"); return uint120(value); } /** * @dev Returns the downcasted uint112 from uint256, reverting on * overflow (when the input is greater than largest uint112). * * Counterpart to Solidity's `uint112` operator. * * Requirements: * * - input must fit into 112 bits * * _Available since v4.7._ */ function toUint112(uint256 value) internal pure returns (uint112) { require(value <= type(uint112).max, "SafeCast: value doesn't fit in 112 bits"); return uint112(value); } /** * @dev Returns the downcasted uint104 from uint256, reverting on * overflow (when the input is greater than largest uint104). * * Counterpart to Solidity's `uint104` operator. * * Requirements: * * - input must fit into 104 bits * * _Available since v4.7._ */ function toUint104(uint256 value) internal pure returns (uint104) { require(value <= type(uint104).max, "SafeCast: value doesn't fit in 104 bits"); return uint104(value); } /** * @dev Returns the downcasted uint96 from uint256, reverting on * overflow (when the input is greater than largest uint96). * * Counterpart to Solidity's `uint96` operator. * * Requirements: * * - input must fit into 96 bits * * _Available since v4.2._ */ function toUint96(uint256 value) internal pure returns (uint96) { require(value <= type(uint96).max, "SafeCast: value doesn't fit in 96 bits"); return uint96(value); } /** * @dev Returns the downcasted uint88 from uint256, reverting on * overflow (when the input is greater than largest uint88). * * Counterpart to Solidity's `uint88` operator. * * Requirements: * * - input must fit into 88 bits * * _Available since v4.7._ */ function toUint88(uint256 value) internal pure returns (uint88) { require(value <= type(uint88).max, "SafeCast: value doesn't fit in 88 bits"); return uint88(value); } /** * @dev Returns the downcasted uint80 from uint256, reverting on * overflow (when the input is greater than largest uint80). * * Counterpart to Solidity's `uint80` operator. * * Requirements: * * - input must fit into 80 bits * * _Available since v4.7._ */ function toUint80(uint256 value) internal pure returns (uint80) { require(value <= type(uint80).max, "SafeCast: value doesn't fit in 80 bits"); return uint80(value); } /** * @dev Returns the downcasted uint72 from uint256, reverting on * overflow (when the input is greater than largest uint72). * * Counterpart to Solidity's `uint72` operator. * * Requirements: * * - input must fit into 72 bits * * _Available since v4.7._ */ function toUint72(uint256 value) internal pure returns (uint72) { require(value <= type(uint72).max, "SafeCast: value doesn't fit in 72 bits"); return uint72(value); } /** * @dev Returns the downcasted uint64 from uint256, reverting on * overflow (when the input is greater than largest uint64). * * Counterpart to Solidity's `uint64` operator. * * Requirements: * * - input must fit into 64 bits * * _Available since v2.5._ */ function toUint64(uint256 value) internal pure returns (uint64) { require(value <= type(uint64).max, "SafeCast: value doesn't fit in 64 bits"); return uint64(value); } /** * @dev Returns the downcasted uint56 from uint256, reverting on * overflow (when the input is greater than largest uint56). * * Counterpart to Solidity's `uint56` operator. * * Requirements: * * - input must fit into 56 bits * * _Available since v4.7._ */ function toUint56(uint256 value) internal pure returns (uint56) { require(value <= type(uint56).max, "SafeCast: value doesn't fit in 56 bits"); return uint56(value); } /** * @dev Returns the downcasted uint48 from uint256, reverting on * overflow (when the input is greater than largest uint48). * * Counterpart to Solidity's `uint48` operator. * * Requirements: * * - input must fit into 48 bits * * _Available since v4.7._ */ function toUint48(uint256 value) internal pure returns (uint48) { require(value <= type(uint48).max, "SafeCast: value doesn't fit in 48 bits"); return uint48(value); } /** * @dev Returns the downcasted uint40 from uint256, reverting on * overflow (when the input is greater than largest uint40). * * Counterpart to Solidity's `uint40` operator. * * Requirements: * * - input must fit into 40 bits * * _Available since v4.7._ */ function toUint40(uint256 value) internal pure returns (uint40) { require(value <= type(uint40).max, "SafeCast: value doesn't fit in 40 bits"); return uint40(value); } /** * @dev Returns the downcasted uint32 from uint256, reverting on * overflow (when the input is greater than largest uint32). * * Counterpart to Solidity's `uint32` operator. * * Requirements: * * - input must fit into 32 bits * * _Available since v2.5._ */ function toUint32(uint256 value) internal pure returns (uint32) { require(value <= type(uint32).max, "SafeCast: value doesn't fit in 32 bits"); return uint32(value); } /** * @dev Returns the downcasted uint24 from uint256, reverting on * overflow (when the input is greater than largest uint24). * * Counterpart to Solidity's `uint24` operator. * * Requirements: * * - input must fit into 24 bits * * _Available since v4.7._ */ function toUint24(uint256 value) internal pure returns (uint24) { require(value <= type(uint24).max, "SafeCast: value doesn't fit in 24 bits"); return uint24(value); } /** * @dev Returns the downcasted uint16 from uint256, reverting on * overflow (when the input is greater than largest uint16). * * Counterpart to Solidity's `uint16` operator. * * Requirements: * * - input must fit into 16 bits * * _Available since v2.5._ */ function toUint16(uint256 value) internal pure returns (uint16) { require(value <= type(uint16).max, "SafeCast: value doesn't fit in 16 bits"); return uint16(value); } /** * @dev Returns the downcasted uint8 from uint256, reverting on * overflow (when the input is greater than largest uint8). * * Counterpart to Solidity's `uint8` operator. * * Requirements: * * - input must fit into 8 bits * * _Available since v2.5._ */ function toUint8(uint256 value) internal pure returns (uint8) { require(value <= type(uint8).max, "SafeCast: value doesn't fit in 8 bits"); return uint8(value); } /** * @dev Converts a signed int256 into an unsigned uint256. * * Requirements: * * - input must be greater than or equal to 0. * * _Available since v3.0._ */ function toUint256(int256 value) internal pure returns (uint256) { require(value >= 0, "SafeCast: value must be positive"); return uint256(value); } /** * @dev Returns the downcasted int248 from int256, reverting on * overflow (when the input is less than smallest int248 or * greater than largest int248). * * Counterpart to Solidity's `int248` operator. * * Requirements: * * - input must fit into 248 bits * * _Available since v4.7._ */ function toInt248(int256 value) internal pure returns (int248) { require(value >= type(int248).min && value <= type(int248).max, "SafeCast: value doesn't fit in 248 bits"); return int248(value); } /** * @dev Returns the downcasted int240 from int256, reverting on * overflow (when the input is less than smallest int240 or * greater than largest int240). * * Counterpart to Solidity's `int240` operator. * * Requirements: * * - input must fit into 240 bits * * _Available since v4.7._ */ function toInt240(int256 value) internal pure returns (int240) { require(value >= type(int240).min && value <= type(int240).max, "SafeCast: value doesn't fit in 240 bits"); return int240(value); } /** * @dev Returns the downcasted int232 from int256, reverting on * overflow (when the input is less than smallest int232 or * greater than largest int232). * * Counterpart to Solidity's `int232` operator. * * Requirements: * * - input must fit into 232 bits * * _Available since v4.7._ */ function toInt232(int256 value) internal pure returns (int232) { require(value >= type(int232).min && value <= type(int232).max, "SafeCast: value doesn't fit in 232 bits"); return int232(value); } /** * @dev Returns the downcasted int224 from int256, reverting on * overflow (when the input is less than smallest int224 or * greater than largest int224). * * Counterpart to Solidity's `int224` operator. * * Requirements: * * - input must fit into 224 bits * * _Available since v4.7._ */ function toInt224(int256 value) internal pure returns (int224) { require(value >= type(int224).min && value <= type(int224).max, "SafeCast: value doesn't fit in 224 bits"); return int224(value); } /** * @dev Returns the downcasted int216 from int256, reverting on * overflow (when the input is less than smallest int216 or * greater than largest int216). * * Counterpart to Solidity's `int216` operator. * * Requirements: * * - input must fit into 216 bits * * _Available since v4.7._ */ function toInt216(int256 value) internal pure returns (int216) { require(value >= type(int216).min && value <= type(int216).max, "SafeCast: value doesn't fit in 216 bits"); return int216(value); } /** * @dev Returns the downcasted int208 from int256, reverting on * overflow (when the input is less than smallest int208 or * greater than largest int208). * * Counterpart to Solidity's `int208` operator. * * Requirements: * * - input must fit into 208 bits * * _Available since v4.7._ */ function toInt208(int256 value) internal pure returns (int208) { require(value >= type(int208).min && value <= type(int208).max, "SafeCast: value doesn't fit in 208 bits"); return int208(value); } /** * @dev Returns the downcasted int200 from int256, reverting on * overflow (when the input is less than smallest int200 or * greater than largest int200). * * Counterpart to Solidity's `int200` operator. * * Requirements: * * - input must fit into 200 bits * * _Available since v4.7._ */ function toInt200(int256 value) internal pure returns (int200) { require(value >= type(int200).min && value <= type(int200).max, "SafeCast: value doesn't fit in 200 bits"); return int200(value); } /** * @dev Returns the downcasted int192 from int256, reverting on * overflow (when the input is less than smallest int192 or * greater than largest int192). * * Counterpart to Solidity's `int192` operator. * * Requirements: * * - input must fit into 192 bits * * _Available since v4.7._ */ function toInt192(int256 value) internal pure returns (int192) { require(value >= type(int192).min && value <= type(int192).max, "SafeCast: value doesn't fit in 192 bits"); return int192(value); } /** * @dev Returns the downcasted int184 from int256, reverting on * overflow (when the input is less than smallest int184 or * greater than largest int184). * * Counterpart to Solidity's `int184` operator. * * Requirements: * * - input must fit into 184 bits * * _Available since v4.7._ */ function toInt184(int256 value) internal pure returns (int184) { require(value >= type(int184).min && value <= type(int184).max, "SafeCast: value doesn't fit in 184 bits"); return int184(value); } /** * @dev Returns the downcasted int176 from int256, reverting on * overflow (when the input is less than smallest int176 or * greater than largest int176). * * Counterpart to Solidity's `int176` operator. * * Requirements: * * - input must fit into 176 bits * * _Available since v4.7._ */ function toInt176(int256 value) internal pure returns (int176) { require(value >= type(int176).min && value <= type(int176).max, "SafeCast: value doesn't fit in 176 bits"); return int176(value); } /** * @dev Returns the downcasted int168 from int256, reverting on * overflow (when the input is less than smallest int168 or * greater than largest int168). * * Counterpart to Solidity's `int168` operator. * * Requirements: * * - input must fit into 168 bits * * _Available since v4.7._ */ function toInt168(int256 value) internal pure returns (int168) { require(value >= type(int168).min && value <= type(int168).max, "SafeCast: value doesn't fit in 168 bits"); return int168(value); } /** * @dev Returns the downcasted int160 from int256, reverting on * overflow (when the input is less than smallest int160 or * greater than largest int160). * * Counterpart to Solidity's `int160` operator. * * Requirements: * * - input must fit into 160 bits * * _Available since v4.7._ */ function toInt160(int256 value) internal pure returns (int160) { require(value >= type(int160).min && value <= type(int160).max, "SafeCast: value doesn't fit in 160 bits"); return int160(value); } /** * @dev Returns the downcasted int152 from int256, reverting on * overflow (when the input is less than smallest int152 or * greater than largest int152). * * Counterpart to Solidity's `int152` operator. * * Requirements: * * - input must fit into 152 bits * * _Available since v4.7._ */ function toInt152(int256 value) internal pure returns (int152) { require(value >= type(int152).min && value <= type(int152).max, "SafeCast: value doesn't fit in 152 bits"); return int152(value); } /** * @dev Returns the downcasted int144 from int256, reverting on * overflow (when the input is less than smallest int144 or * greater than largest int144). * * Counterpart to Solidity's `int144` operator. * * Requirements: * * - input must fit into 144 bits * * _Available since v4.7._ */ function toInt144(int256 value) internal pure returns (int144) { require(value >= type(int144).min && value <= type(int144).max, "SafeCast: value doesn't fit in 144 bits"); return int144(value); } /** * @dev Returns the downcasted int136 from int256, reverting on * overflow (when the input is less than smallest int136 or * greater than largest int136). * * Counterpart to Solidity's `int136` operator. * * Requirements: * * - input must fit into 136 bits * * _Available since v4.7._ */ function toInt136(int256 value) internal pure returns (int136) { require(value >= type(int136).min && value <= type(int136).max, "SafeCast: value doesn't fit in 136 bits"); return int136(value); } /** * @dev Returns the downcasted int128 from int256, reverting on * overflow (when the input is less than smallest int128 or * greater than largest int128). * * Counterpart to Solidity's `int128` operator. * * Requirements: * * - input must fit into 128 bits * * _Available since v3.1._ */ function toInt128(int256 value) internal pure returns (int128) { require(value >= type(int128).min && value <= type(int128).max, "SafeCast: value doesn't fit in 128 bits"); return int128(value); } /** * @dev Returns the downcasted int120 from int256, reverting on * overflow (when the input is less than smallest int120 or * greater than largest int120). * * Counterpart to Solidity's `int120` operator. * * Requirements: * * - input must fit into 120 bits * * _Available since v4.7._ */ function toInt120(int256 value) internal pure returns (int120) { require(value >= type(int120).min && value <= type(int120).max, "SafeCast: value doesn't fit in 120 bits"); return int120(value); } /** * @dev Returns the downcasted int112 from int256, reverting on * overflow (when the input is less than smallest int112 or * greater than largest int112). * * Counterpart to Solidity's `int112` operator. * * Requirements: * * - input must fit into 112 bits * * _Available since v4.7._ */ function toInt112(int256 value) internal pure returns (int112) { require(value >= type(int112).min && value <= type(int112).max, "SafeCast: value doesn't fit in 112 bits"); return int112(value); } /** * @dev Returns the downcasted int104 from int256, reverting on * overflow (when the input is less than smallest int104 or * greater than largest int104). * * Counterpart to Solidity's `int104` operator. * * Requirements: * * - input must fit into 104 bits * * _Available since v4.7._ */ function toInt104(int256 value) internal pure returns (int104) { require(value >= type(int104).min && value <= type(int104).max, "SafeCast: value doesn't fit in 104 bits"); return int104(value); } /** * @dev Returns the downcasted int96 from int256, reverting on * overflow (when the input is less than smallest int96 or * greater than largest int96). * * Counterpart to Solidity's `int96` operator. * * Requirements: * * - input must fit into 96 bits * * _Available since v4.7._ */ function toInt96(int256 value) internal pure returns (int96) { require(value >= type(int96).min && value <= type(int96).max, "SafeCast: value doesn't fit in 96 bits"); return int96(value); } /** * @dev Returns the downcasted int88 from int256, reverting on * overflow (when the input is less than smallest int88 or * greater than largest int88). * * Counterpart to Solidity's `int88` operator. * * Requirements: * * - input must fit into 88 bits * * _Available since v4.7._ */ function toInt88(int256 value) internal pure returns (int88) { require(value >= type(int88).min && value <= type(int88).max, "SafeCast: value doesn't fit in 88 bits"); return int88(value); } /** * @dev Returns the downcasted int80 from int256, reverting on * overflow (when the input is less than smallest int80 or * greater than largest int80). * * Counterpart to Solidity's `int80` operator. * * Requirements: * * - input must fit into 80 bits * * _Available since v4.7._ */ function toInt80(int256 value) internal pure returns (int80) { require(value >= type(int80).min && value <= type(int80).max, "SafeCast: value doesn't fit in 80 bits"); return int80(value); } /** * @dev Returns the downcasted int72 from int256, reverting on * overflow (when the input is less than smallest int72 or * greater than largest int72). * * Counterpart to Solidity's `int72` operator. * * Requirements: * * - input must fit into 72 bits * * _Available since v4.7._ */ function toInt72(int256 value) internal pure returns (int72) { require(value >= type(int72).min && value <= type(int72).max, "SafeCast: value doesn't fit in 72 bits"); return int72(value); } /** * @dev Returns the downcasted int64 from int256, reverting on * overflow (when the input is less than smallest int64 or * greater than largest int64). * * Counterpart to Solidity's `int64` operator. * * Requirements: * * - input must fit into 64 bits * * _Available since v3.1._ */ function toInt64(int256 value) internal pure returns (int64) { require(value >= type(int64).min && value <= type(int64).max, "SafeCast: value doesn't fit in 64 bits"); return int64(value); } /** * @dev Returns the downcasted int56 from int256, reverting on * overflow (when the input is less than smallest int56 or * greater than largest int56). * * Counterpart to Solidity's `int56` operator. * * Requirements: * * - input must fit into 56 bits * * _Available since v4.7._ */ function toInt56(int256 value) internal pure returns (int56) { require(value >= type(int56).min && value <= type(int56).max, "SafeCast: value doesn't fit in 56 bits"); return int56(value); } /** * @dev Returns the downcasted int48 from int256, reverting on * overflow (when the input is less than smallest int48 or * greater than largest int48). * * Counterpart to Solidity's `int48` operator. * * Requirements: * * - input must fit into 48 bits * * _Available since v4.7._ */ function toInt48(int256 value) internal pure returns (int48) { require(value >= type(int48).min && value <= type(int48).max, "SafeCast: value doesn't fit in 48 bits"); return int48(value); } /** * @dev Returns the downcasted int40 from int256, reverting on * overflow (when the input is less than smallest int40 or * greater than largest int40). * * Counterpart to Solidity's `int40` operator. * * Requirements: * * - input must fit into 40 bits * * _Available since v4.7._ */ function toInt40(int256 value) internal pure returns (int40) { require(value >= type(int40).min && value <= type(int40).max, "SafeCast: value doesn't fit in 40 bits"); return int40(value); } /** * @dev Returns the downcasted int32 from int256, reverting on * overflow (when the input is less than smallest int32 or * greater than largest int32). * * Counterpart to Solidity's `int32` operator. * * Requirements: * * - input must fit into 32 bits * * _Available since v3.1._ */ function toInt32(int256 value) internal pure returns (int32) { require(value >= type(int32).min && value <= type(int32).max, "SafeCast: value doesn't fit in 32 bits"); return int32(value); } /** * @dev Returns the downcasted int24 from int256, reverting on * overflow (when the input is less than smallest int24 or * greater than largest int24). * * Counterpart to Solidity's `int24` operator. * * Requirements: * * - input must fit into 24 bits * * _Available since v4.7._ */ function toInt24(int256 value) internal pure returns (int24) { require(value >= type(int24).min && value <= type(int24).max, "SafeCast: value doesn't fit in 24 bits"); return int24(value); } /** * @dev Returns the downcasted int16 from int256, reverting on * overflow (when the input is less than smallest int16 or * greater than largest int16). * * Counterpart to Solidity's `int16` operator. * * Requirements: * * - input must fit into 16 bits * * _Available since v3.1._ */ function toInt16(int256 value) internal pure returns (int16) { require(value >= type(int16).min && value <= type(int16).max, "SafeCast: value doesn't fit in 16 bits"); return int16(value); } /** * @dev Returns the downcasted int8 from int256, reverting on * overflow (when the input is less than smallest int8 or * greater than largest int8). * * Counterpart to Solidity's `int8` operator. * * Requirements: * * - input must fit into 8 bits * * _Available since v3.1._ */ function toInt8(int256 value) internal pure returns (int8) { require(value >= type(int8).min && value <= type(int8).max, "SafeCast: value doesn't fit in 8 bits"); return int8(value); } /** * @dev Converts an unsigned uint256 into a signed int256. * * Requirements: * * - input must be less than or equal to maxInt256. * * _Available since v3.0._ */ function toInt256(uint256 value) internal pure returns (int256) { // Note: Unsafe cast below is okay because `type(int256).max` is guaranteed to be positive require(value <= uint256(type(int256).max), "SafeCast: value doesn't fit in an int256"); return int256(value); } } // File: abdk-libraries-solidity/ABDKMathQuad.sol /* * ABDK Math Quad Smart Contract Library. Copyright © 2019 by ABDK Consulting. * Author: Mikhail Vladimirov <[email protected]> */ pragma solidity ^0.8.0; /** * Smart contract library of mathematical functions operating with IEEE 754 * quadruple-precision binary floating-point numbers (quadruple precision * numbers). As long as quadruple precision numbers are 16-bytes long, they are * represented by bytes16 type. */ library ABDKMathQuad { /* * 0. */ bytes16 private constant POSITIVE_ZERO = 0x00000000000000000000000000000000; /* * -0. */ bytes16 private constant NEGATIVE_ZERO = 0x80000000000000000000000000000000; /* * +Infinity. */ bytes16 private constant POSITIVE_INFINITY = 0x7FFF0000000000000000000000000000; /* * -Infinity. */ bytes16 private constant NEGATIVE_INFINITY = 0xFFFF0000000000000000000000000000; /* * Canonical NaN value. */ bytes16 private constant NaN = 0x7FFF8000000000000000000000000000; /** * Convert signed 256-bit integer number into quadruple precision number. * * @param x signed 256-bit integer number * @return quadruple precision number */ function fromInt (int256 x) internal pure returns (bytes16) { unchecked { if (x == 0) return bytes16 (0); else { // We rely on overflow behavior here uint256 result = uint256 (x > 0 ? x : -x); uint256 msb = mostSignificantBit (result); if (msb < 112) result <<= 112 - msb; else if (msb > 112) result >>= msb - 112; result = result & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF | 16383 + msb << 112; if (x < 0) result |= 0x80000000000000000000000000000000; return bytes16 (uint128 (result)); } } } /** * Convert quadruple precision number into signed 256-bit integer number * rounding towards zero. Revert on overflow. * * @param x quadruple precision number * @return signed 256-bit integer number */ function toInt (bytes16 x) internal pure returns (int256) { unchecked { uint256 exponent = uint128 (x) >> 112 & 0x7FFF; require (exponent <= 16638); // Overflow if (exponent < 16383) return 0; // Underflow uint256 result = uint256 (uint128 (x)) & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF | 0x10000000000000000000000000000; if (exponent < 16495) result >>= 16495 - exponent; else if (exponent > 16495) result <<= exponent - 16495; if (uint128 (x) >= 0x80000000000000000000000000000000) { // Negative require (result <= 0x8000000000000000000000000000000000000000000000000000000000000000); return -int256 (result); // We rely on overflow behavior here } else { require (result <= 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF); return int256 (result); } } } /** * Convert unsigned 256-bit integer number into quadruple precision number. * * @param x unsigned 256-bit integer number * @return quadruple precision number */ function fromUInt (uint256 x) internal pure returns (bytes16) { unchecked { if (x == 0) return bytes16 (0); else { uint256 result = x; uint256 msb = mostSignificantBit (result); if (msb < 112) result <<= 112 - msb; else if (msb > 112) result >>= msb - 112; result = result & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF | 16383 + msb << 112; return bytes16 (uint128 (result)); } } } /** * Convert quadruple precision number into unsigned 256-bit integer number * rounding towards zero. Revert on underflow. Note, that negative floating * point numbers in range (-1.0 .. 0.0) may be converted to unsigned integer * without error, because they are rounded to zero. * * @param x quadruple precision number * @return unsigned 256-bit integer number */ function toUInt (bytes16 x) internal pure returns (uint256) { unchecked { uint256 exponent = uint128 (x) >> 112 & 0x7FFF; if (exponent < 16383) return 0; // Underflow require (uint128 (x) < 0x80000000000000000000000000000000); // Negative require (exponent <= 16638); // Overflow uint256 result = uint256 (uint128 (x)) & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF | 0x10000000000000000000000000000; if (exponent < 16495) result >>= 16495 - exponent; else if (exponent > 16495) result <<= exponent - 16495; return result; } } /** * Convert signed 128.128 bit fixed point number into quadruple precision * number. * * @param x signed 128.128 bit fixed point number * @return quadruple precision number */ function from128x128 (int256 x) internal pure returns (bytes16) { unchecked { if (x == 0) return bytes16 (0); else { // We rely on overflow behavior here uint256 result = uint256 (x > 0 ? x : -x); uint256 msb = mostSignificantBit (result); if (msb < 112) result <<= 112 - msb; else if (msb > 112) result >>= msb - 112; result = result & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF | 16255 + msb << 112; if (x < 0) result |= 0x80000000000000000000000000000000; return bytes16 (uint128 (result)); } } } /** * Convert quadruple precision number into signed 128.128 bit fixed point * number. Revert on overflow. * * @param x quadruple precision number * @return signed 128.128 bit fixed point number */ function to128x128 (bytes16 x) internal pure returns (int256) { unchecked { uint256 exponent = uint128 (x) >> 112 & 0x7FFF; require (exponent <= 16510); // Overflow if (exponent < 16255) return 0; // Underflow uint256 result = uint256 (uint128 (x)) & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF | 0x10000000000000000000000000000; if (exponent < 16367) result >>= 16367 - exponent; else if (exponent > 16367) result <<= exponent - 16367; if (uint128 (x) >= 0x80000000000000000000000000000000) { // Negative require (result <= 0x8000000000000000000000000000000000000000000000000000000000000000); return -int256 (result); // We rely on overflow behavior here } else { require (result <= 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF); return int256 (result); } } } /** * Convert signed 64.64 bit fixed point number into quadruple precision * number. * * @param x signed 64.64 bit fixed point number * @return quadruple precision number */ function from64x64 (int128 x) internal pure returns (bytes16) { unchecked { if (x == 0) return bytes16 (0); else { // We rely on overflow behavior here uint256 result = uint128 (x > 0 ? x : -x); uint256 msb = mostSignificantBit (result); if (msb < 112) result <<= 112 - msb; else if (msb > 112) result >>= msb - 112; result = result & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF | 16319 + msb << 112; if (x < 0) result |= 0x80000000000000000000000000000000; return bytes16 (uint128 (result)); } } } /** * Convert quadruple precision number into signed 64.64 bit fixed point * number. Revert on overflow. * * @param x quadruple precision number * @return signed 64.64 bit fixed point number */ function to64x64 (bytes16 x) internal pure returns (int128) { unchecked { uint256 exponent = uint128 (x) >> 112 & 0x7FFF; require (exponent <= 16446); // Overflow if (exponent < 16319) return 0; // Underflow uint256 result = uint256 (uint128 (x)) & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF | 0x10000000000000000000000000000; if (exponent < 16431) result >>= 16431 - exponent; else if (exponent > 16431) result <<= exponent - 16431; if (uint128 (x) >= 0x80000000000000000000000000000000) { // Negative require (result <= 0x80000000000000000000000000000000); return -int128 (int256 (result)); // We rely on overflow behavior here } else { require (result <= 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF); return int128 (int256 (result)); } } } /** * Convert octuple precision number into quadruple precision number. * * @param x octuple precision number * @return quadruple precision number */ function fromOctuple (bytes32 x) internal pure returns (bytes16) { unchecked { bool negative = x & 0x8000000000000000000000000000000000000000000000000000000000000000 > 0; uint256 exponent = uint256 (x) >> 236 & 0x7FFFF; uint256 significand = uint256 (x) & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF; if (exponent == 0x7FFFF) { if (significand > 0) return NaN; else return negative ? NEGATIVE_INFINITY : POSITIVE_INFINITY; } if (exponent > 278526) return negative ? NEGATIVE_INFINITY : POSITIVE_INFINITY; else if (exponent < 245649) return negative ? NEGATIVE_ZERO : POSITIVE_ZERO; else if (exponent < 245761) { significand = (significand | 0x100000000000000000000000000000000000000000000000000000000000) >> 245885 - exponent; exponent = 0; } else { significand >>= 124; exponent -= 245760; } uint128 result = uint128 (significand | exponent << 112); if (negative) result |= 0x80000000000000000000000000000000; return bytes16 (result); } } /** * Convert quadruple precision number into octuple precision number. * * @param x quadruple precision number * @return octuple precision number */ function toOctuple (bytes16 x) internal pure returns (bytes32) { unchecked { uint256 exponent = uint128 (x) >> 112 & 0x7FFF; uint256 result = uint128 (x) & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF; if (exponent == 0x7FFF) exponent = 0x7FFFF; // Infinity or NaN else if (exponent == 0) { if (result > 0) { uint256 msb = mostSignificantBit (result); result = result << 236 - msb & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF; exponent = 245649 + msb; } } else { result <<= 124; exponent += 245760; } result |= exponent << 236; if (uint128 (x) >= 0x80000000000000000000000000000000) result |= 0x8000000000000000000000000000000000000000000000000000000000000000; return bytes32 (result); } } /** * Convert double precision number into quadruple precision number. * * @param x double precision number * @return quadruple precision number */ function fromDouble (bytes8 x) internal pure returns (bytes16) { unchecked { uint256 exponent = uint64 (x) >> 52 & 0x7FF; uint256 result = uint64 (x) & 0xFFFFFFFFFFFFF; if (exponent == 0x7FF) exponent = 0x7FFF; // Infinity or NaN else if (exponent == 0) { if (result > 0) { uint256 msb = mostSignificantBit (result); result = result << 112 - msb & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF; exponent = 15309 + msb; } } else { result <<= 60; exponent += 15360; } result |= exponent << 112; if (x & 0x8000000000000000 > 0) result |= 0x80000000000000000000000000000000; return bytes16 (uint128 (result)); } } /** * Convert quadruple precision number into double precision number. * * @param x quadruple precision number * @return double precision number */ function toDouble (bytes16 x) internal pure returns (bytes8) { unchecked { bool negative = uint128 (x) >= 0x80000000000000000000000000000000; uint256 exponent = uint128 (x) >> 112 & 0x7FFF; uint256 significand = uint128 (x) & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF; if (exponent == 0x7FFF) { if (significand > 0) return 0x7FF8000000000000; // NaN else return negative ? bytes8 (0xFFF0000000000000) : // -Infinity bytes8 (0x7FF0000000000000); // Infinity } if (exponent > 17406) return negative ? bytes8 (0xFFF0000000000000) : // -Infinity bytes8 (0x7FF0000000000000); // Infinity else if (exponent < 15309) return negative ? bytes8 (0x8000000000000000) : // -0 bytes8 (0x0000000000000000); // 0 else if (exponent < 15361) { significand = (significand | 0x10000000000000000000000000000) >> 15421 - exponent; exponent = 0; } else { significand >>= 60; exponent -= 15360; } uint64 result = uint64 (significand | exponent << 52); if (negative) result |= 0x8000000000000000; return bytes8 (result); } } /** * Test whether given quadruple precision number is NaN. * * @param x quadruple precision number * @return true if x is NaN, false otherwise */ function isNaN (bytes16 x) internal pure returns (bool) { unchecked { return uint128 (x) & 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF > 0x7FFF0000000000000000000000000000; } } /** * Test whether given quadruple precision number is positive or negative * infinity. * * @param x quadruple precision number * @return true if x is positive or negative infinity, false otherwise */ function isInfinity (bytes16 x) internal pure returns (bool) { unchecked { return uint128 (x) & 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF == 0x7FFF0000000000000000000000000000; } } /** * Calculate sign of x, i.e. -1 if x is negative, 0 if x if zero, and 1 if x * is positive. Note that sign (-0) is zero. Revert if x is NaN. * * @param x quadruple precision number * @return sign of x */ function sign (bytes16 x) internal pure returns (int8) { unchecked { uint128 absoluteX = uint128 (x) & 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF; require (absoluteX <= 0x7FFF0000000000000000000000000000); // Not NaN if (absoluteX == 0) return 0; else if (uint128 (x) >= 0x80000000000000000000000000000000) return -1; else return 1; } } /** * Calculate sign (x - y). Revert if either argument is NaN, or both * arguments are infinities of the same sign. * * @param x quadruple precision number * @param y quadruple precision number * @return sign (x - y) */ function cmp (bytes16 x, bytes16 y) internal pure returns (int8) { unchecked { uint128 absoluteX = uint128 (x) & 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF; require (absoluteX <= 0x7FFF0000000000000000000000000000); // Not NaN uint128 absoluteY = uint128 (y) & 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF; require (absoluteY <= 0x7FFF0000000000000000000000000000); // Not NaN // Not infinities of the same sign require (x != y || absoluteX < 0x7FFF0000000000000000000000000000); if (x == y) return 0; else { bool negativeX = uint128 (x) >= 0x80000000000000000000000000000000; bool negativeY = uint128 (y) >= 0x80000000000000000000000000000000; if (negativeX) { if (negativeY) return absoluteX > absoluteY ? -1 : int8 (1); else return -1; } else { if (negativeY) return 1; else return absoluteX > absoluteY ? int8 (1) : -1; } } } } /** * Test whether x equals y. NaN, infinity, and -infinity are not equal to * anything. * * @param x quadruple precision number * @param y quadruple precision number * @return true if x equals to y, false otherwise */ function eq (bytes16 x, bytes16 y) internal pure returns (bool) { unchecked { if (x == y) { return uint128 (x) & 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF < 0x7FFF0000000000000000000000000000; } else return false; } } /** * Calculate x + y. Special values behave in the following way: * * NaN + x = NaN for any x. * Infinity + x = Infinity for any finite x. * -Infinity + x = -Infinity for any finite x. * Infinity + Infinity = Infinity. * -Infinity + -Infinity = -Infinity. * Infinity + -Infinity = -Infinity + Infinity = NaN. * * @param x quadruple precision number * @param y quadruple precision number * @return quadruple precision number */ function add (bytes16 x, bytes16 y) internal pure returns (bytes16) { unchecked { uint256 xExponent = uint128 (x) >> 112 & 0x7FFF; uint256 yExponent = uint128 (y) >> 112 & 0x7FFF; if (xExponent == 0x7FFF) { if (yExponent == 0x7FFF) { if (x == y) return x; else return NaN; } else return x; } else if (yExponent == 0x7FFF) return y; else { bool xSign = uint128 (x) >= 0x80000000000000000000000000000000; uint256 xSignifier = uint128 (x) & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF; if (xExponent == 0) xExponent = 1; else xSignifier |= 0x10000000000000000000000000000; bool ySign = uint128 (y) >= 0x80000000000000000000000000000000; uint256 ySignifier = uint128 (y) & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF; if (yExponent == 0) yExponent = 1; else ySignifier |= 0x10000000000000000000000000000; if (xSignifier == 0) return y == NEGATIVE_ZERO ? POSITIVE_ZERO : y; else if (ySignifier == 0) return x == NEGATIVE_ZERO ? POSITIVE_ZERO : x; else { int256 delta = int256 (xExponent) - int256 (yExponent); if (xSign == ySign) { if (delta > 112) return x; else if (delta > 0) ySignifier >>= uint256 (delta); else if (delta < -112) return y; else if (delta < 0) { xSignifier >>= uint256 (-delta); xExponent = yExponent; } xSignifier += ySignifier; if (xSignifier >= 0x20000000000000000000000000000) { xSignifier >>= 1; xExponent += 1; } if (xExponent == 0x7FFF) return xSign ? NEGATIVE_INFINITY : POSITIVE_INFINITY; else { if (xSignifier < 0x10000000000000000000000000000) xExponent = 0; else xSignifier &= 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF; return bytes16 (uint128 ( (xSign ? 0x80000000000000000000000000000000 : 0) | (xExponent << 112) | xSignifier)); } } else { if (delta > 0) { xSignifier <<= 1; xExponent -= 1; } else if (delta < 0) { ySignifier <<= 1; xExponent = yExponent - 1; } if (delta > 112) ySignifier = 1; else if (delta > 1) ySignifier = (ySignifier - 1 >> uint256 (delta - 1)) + 1; else if (delta < -112) xSignifier = 1; else if (delta < -1) xSignifier = (xSignifier - 1 >> uint256 (-delta - 1)) + 1; if (xSignifier >= ySignifier) xSignifier -= ySignifier; else { xSignifier = ySignifier - xSignifier; xSign = ySign; } if (xSignifier == 0) return POSITIVE_ZERO; uint256 msb = mostSignificantBit (xSignifier); if (msb == 113) { xSignifier = xSignifier >> 1 & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF; xExponent += 1; } else if (msb < 112) { uint256 shift = 112 - msb; if (xExponent > shift) { xSignifier = xSignifier << shift & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF; xExponent -= shift; } else { xSignifier <<= xExponent - 1; xExponent = 0; } } else xSignifier &= 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF; if (xExponent == 0x7FFF) return xSign ? NEGATIVE_INFINITY : POSITIVE_INFINITY; else return bytes16 (uint128 ( (xSign ? 0x80000000000000000000000000000000 : 0) | (xExponent << 112) | xSignifier)); } } } } } /** * Calculate x - y. Special values behave in the following way: * * NaN - x = NaN for any x. * Infinity - x = Infinity for any finite x. * -Infinity - x = -Infinity for any finite x. * Infinity - -Infinity = Infinity. * -Infinity - Infinity = -Infinity. * Infinity - Infinity = -Infinity - -Infinity = NaN. * * @param x quadruple precision number * @param y quadruple precision number * @return quadruple precision number */ function sub (bytes16 x, bytes16 y) internal pure returns (bytes16) { unchecked { return add (x, y ^ 0x80000000000000000000000000000000); } } /** * Calculate x * y. Special values behave in the following way: * * NaN * x = NaN for any x. * Infinity * x = Infinity for any finite positive x. * Infinity * x = -Infinity for any finite negative x. * -Infinity * x = -Infinity for any finite positive x. * -Infinity * x = Infinity for any finite negative x. * Infinity * 0 = NaN. * -Infinity * 0 = NaN. * Infinity * Infinity = Infinity. * Infinity * -Infinity = -Infinity. * -Infinity * Infinity = -Infinity. * -Infinity * -Infinity = Infinity. * * @param x quadruple precision number * @param y quadruple precision number * @return quadruple precision number */ function mul (bytes16 x, bytes16 y) internal pure returns (bytes16) { unchecked { uint256 xExponent = uint128 (x) >> 112 & 0x7FFF; uint256 yExponent = uint128 (y) >> 112 & 0x7FFF; if (xExponent == 0x7FFF) { if (yExponent == 0x7FFF) { if (x == y) return x ^ y & 0x80000000000000000000000000000000; else if (x ^ y == 0x80000000000000000000000000000000) return x | y; else return NaN; } else { if (y & 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF == 0) return NaN; else return x ^ y & 0x80000000000000000000000000000000; } } else if (yExponent == 0x7FFF) { if (x & 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF == 0) return NaN; else return y ^ x & 0x80000000000000000000000000000000; } else { uint256 xSignifier = uint128 (x) & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF; if (xExponent == 0) xExponent = 1; else xSignifier |= 0x10000000000000000000000000000; uint256 ySignifier = uint128 (y) & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF; if (yExponent == 0) yExponent = 1; else ySignifier |= 0x10000000000000000000000000000; xSignifier *= ySignifier; if (xSignifier == 0) return (x ^ y) & 0x80000000000000000000000000000000 > 0 ? NEGATIVE_ZERO : POSITIVE_ZERO; xExponent += yExponent; uint256 msb = xSignifier >= 0x200000000000000000000000000000000000000000000000000000000 ? 225 : xSignifier >= 0x100000000000000000000000000000000000000000000000000000000 ? 224 : mostSignificantBit (xSignifier); if (xExponent + msb < 16496) { // Underflow xExponent = 0; xSignifier = 0; } else if (xExponent + msb < 16608) { // Subnormal if (xExponent < 16496) xSignifier >>= 16496 - xExponent; else if (xExponent > 16496) xSignifier <<= xExponent - 16496; xExponent = 0; } else if (xExponent + msb > 49373) { xExponent = 0x7FFF; xSignifier = 0; } else { if (msb > 112) xSignifier >>= msb - 112; else if (msb < 112) xSignifier <<= 112 - msb; xSignifier &= 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF; xExponent = xExponent + msb - 16607; } return bytes16 (uint128 (uint128 ((x ^ y) & 0x80000000000000000000000000000000) | xExponent << 112 | xSignifier)); } } } /** * Calculate x / y. Special values behave in the following way: * * NaN / x = NaN for any x. * x / NaN = NaN for any x. * Infinity / x = Infinity for any finite non-negative x. * Infinity / x = -Infinity for any finite negative x including -0. * -Infinity / x = -Infinity for any finite non-negative x. * -Infinity / x = Infinity for any finite negative x including -0. * x / Infinity = 0 for any finite non-negative x. * x / -Infinity = -0 for any finite non-negative x. * x / Infinity = -0 for any finite non-negative x including -0. * x / -Infinity = 0 for any finite non-negative x including -0. * * Infinity / Infinity = NaN. * Infinity / -Infinity = -NaN. * -Infinity / Infinity = -NaN. * -Infinity / -Infinity = NaN. * * Division by zero behaves in the following way: * * x / 0 = Infinity for any finite positive x. * x / -0 = -Infinity for any finite positive x. * x / 0 = -Infinity for any finite negative x. * x / -0 = Infinity for any finite negative x. * 0 / 0 = NaN. * 0 / -0 = NaN. * -0 / 0 = NaN. * -0 / -0 = NaN. * * @param x quadruple precision number * @param y quadruple precision number * @return quadruple precision number */ function div (bytes16 x, bytes16 y) internal pure returns (bytes16) { unchecked { uint256 xExponent = uint128 (x) >> 112 & 0x7FFF; uint256 yExponent = uint128 (y) >> 112 & 0x7FFF; if (xExponent == 0x7FFF) { if (yExponent == 0x7FFF) return NaN; else return x ^ y & 0x80000000000000000000000000000000; } else if (yExponent == 0x7FFF) { if (y & 0x0000FFFFFFFFFFFFFFFFFFFFFFFFFFFF != 0) return NaN; else return POSITIVE_ZERO | (x ^ y) & 0x80000000000000000000000000000000; } else if (y & 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF == 0) { if (x & 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF == 0) return NaN; else return POSITIVE_INFINITY | (x ^ y) & 0x80000000000000000000000000000000; } else { uint256 ySignifier = uint128 (y) & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF; if (yExponent == 0) yExponent = 1; else ySignifier |= 0x10000000000000000000000000000; uint256 xSignifier = uint128 (x) & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF; if (xExponent == 0) { if (xSignifier != 0) { uint shift = 226 - mostSignificantBit (xSignifier); xSignifier <<= shift; xExponent = 1; yExponent += shift - 114; } } else { xSignifier = (xSignifier | 0x10000000000000000000000000000) << 114; } xSignifier = xSignifier / ySignifier; if (xSignifier == 0) return (x ^ y) & 0x80000000000000000000000000000000 > 0 ? NEGATIVE_ZERO : POSITIVE_ZERO; assert (xSignifier >= 0x1000000000000000000000000000); uint256 msb = xSignifier >= 0x80000000000000000000000000000 ? mostSignificantBit (xSignifier) : xSignifier >= 0x40000000000000000000000000000 ? 114 : xSignifier >= 0x20000000000000000000000000000 ? 113 : 112; if (xExponent + msb > yExponent + 16497) { // Overflow xExponent = 0x7FFF; xSignifier = 0; } else if (xExponent + msb + 16380 < yExponent) { // Underflow xExponent = 0; xSignifier = 0; } else if (xExponent + msb + 16268 < yExponent) { // Subnormal if (xExponent + 16380 > yExponent) xSignifier <<= xExponent + 16380 - yExponent; else if (xExponent + 16380 < yExponent) xSignifier >>= yExponent - xExponent - 16380; xExponent = 0; } else { // Normal if (msb > 112) xSignifier >>= msb - 112; xSignifier &= 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF; xExponent = xExponent + msb + 16269 - yExponent; } return bytes16 (uint128 (uint128 ((x ^ y) & 0x80000000000000000000000000000000) | xExponent << 112 | xSignifier)); } } } /** * Calculate -x. * * @param x quadruple precision number * @return quadruple precision number */ function neg (bytes16 x) internal pure returns (bytes16) { unchecked { return x ^ 0x80000000000000000000000000000000; } } /** * Calculate |x|. * * @param x quadruple precision number * @return quadruple precision number */ function abs (bytes16 x) internal pure returns (bytes16) { unchecked { return x & 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF; } } /** * Calculate square root of x. Return NaN on negative x excluding -0. * * @param x quadruple precision number * @return quadruple precision number */ function sqrt (bytes16 x) internal pure returns (bytes16) { unchecked { if (uint128 (x) > 0x80000000000000000000000000000000) return NaN; else { uint256 xExponent = uint128 (x) >> 112 & 0x7FFF; if (xExponent == 0x7FFF) return x; else { uint256 xSignifier = uint128 (x) & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF; if (xExponent == 0) xExponent = 1; else xSignifier |= 0x10000000000000000000000000000; if (xSignifier == 0) return POSITIVE_ZERO; bool oddExponent = xExponent & 0x1 == 0; xExponent = xExponent + 16383 >> 1; if (oddExponent) { if (xSignifier >= 0x10000000000000000000000000000) xSignifier <<= 113; else { uint256 msb = mostSignificantBit (xSignifier); uint256 shift = (226 - msb) & 0xFE; xSignifier <<= shift; xExponent -= shift - 112 >> 1; } } else { if (xSignifier >= 0x10000000000000000000000000000) xSignifier <<= 112; else { uint256 msb = mostSignificantBit (xSignifier); uint256 shift = (225 - msb) & 0xFE; xSignifier <<= shift; xExponent -= shift - 112 >> 1; } } uint256 r = 0x10000000000000000000000000000; r = (r + xSignifier / r) >> 1; r = (r + xSignifier / r) >> 1; r = (r + xSignifier / r) >> 1; r = (r + xSignifier / r) >> 1; r = (r + xSignifier / r) >> 1; r = (r + xSignifier / r) >> 1; r = (r + xSignifier / r) >> 1; // Seven iterations should be enough uint256 r1 = xSignifier / r; if (r1 < r) r = r1; return bytes16 (uint128 (xExponent << 112 | r & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF)); } } } } /** * Calculate binary logarithm of x. Return NaN on negative x excluding -0. * * @param x quadruple precision number * @return quadruple precision number */ function log_2 (bytes16 x) internal pure returns (bytes16) { unchecked { if (uint128 (x) > 0x80000000000000000000000000000000) return NaN; else if (x == 0x3FFF0000000000000000000000000000) return POSITIVE_ZERO; else { uint256 xExponent = uint128 (x) >> 112 & 0x7FFF; if (xExponent == 0x7FFF) return x; else { uint256 xSignifier = uint128 (x) & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF; if (xExponent == 0) xExponent = 1; else xSignifier |= 0x10000000000000000000000000000; if (xSignifier == 0) return NEGATIVE_INFINITY; bool resultNegative; uint256 resultExponent = 16495; uint256 resultSignifier; if (xExponent >= 0x3FFF) { resultNegative = false; resultSignifier = xExponent - 0x3FFF; xSignifier <<= 15; } else { resultNegative = true; if (xSignifier >= 0x10000000000000000000000000000) { resultSignifier = 0x3FFE - xExponent; xSignifier <<= 15; } else { uint256 msb = mostSignificantBit (xSignifier); resultSignifier = 16493 - msb; xSignifier <<= 127 - msb; } } if (xSignifier == 0x80000000000000000000000000000000) { if (resultNegative) resultSignifier += 1; uint256 shift = 112 - mostSignificantBit (resultSignifier); resultSignifier <<= shift; resultExponent -= shift; } else { uint256 bb = resultNegative ? 1 : 0; while (resultSignifier < 0x10000000000000000000000000000) { resultSignifier <<= 1; resultExponent -= 1; xSignifier *= xSignifier; uint256 b = xSignifier >> 255; resultSignifier += b ^ bb; xSignifier >>= 127 + b; } } return bytes16 (uint128 ((resultNegative ? 0x80000000000000000000000000000000 : 0) | resultExponent << 112 | resultSignifier & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF)); } } } } /** * Calculate natural logarithm of x. Return NaN on negative x excluding -0. * * @param x quadruple precision number * @return quadruple precision number */ function ln (bytes16 x) internal pure returns (bytes16) { unchecked { return mul (log_2 (x), 0x3FFE62E42FEFA39EF35793C7673007E5); } } /** * Calculate 2^x. * * @param x quadruple precision number * @return quadruple precision number */ function pow_2 (bytes16 x) internal pure returns (bytes16) { unchecked { bool xNegative = uint128 (x) > 0x80000000000000000000000000000000; uint256 xExponent = uint128 (x) >> 112 & 0x7FFF; uint256 xSignifier = uint128 (x) & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF; if (xExponent == 0x7FFF && xSignifier != 0) return NaN; else if (xExponent > 16397) return xNegative ? POSITIVE_ZERO : POSITIVE_INFINITY; else if (xExponent < 16255) return 0x3FFF0000000000000000000000000000; else { if (xExponent == 0) xExponent = 1; else xSignifier |= 0x10000000000000000000000000000; if (xExponent > 16367) xSignifier <<= xExponent - 16367; else if (xExponent < 16367) xSignifier >>= 16367 - xExponent; if (xNegative && xSignifier > 0x406E00000000000000000000000000000000) return POSITIVE_ZERO; if (!xNegative && xSignifier > 0x3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) return POSITIVE_INFINITY; uint256 resultExponent = xSignifier >> 128; xSignifier &= 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF; if (xNegative && xSignifier != 0) { xSignifier = ~xSignifier; resultExponent += 1; } uint256 resultSignifier = 0x80000000000000000000000000000000; if (xSignifier & 0x80000000000000000000000000000000 > 0) resultSignifier = resultSignifier * 0x16A09E667F3BCC908B2FB1366EA957D3E >> 128; if (xSignifier & 0x40000000000000000000000000000000 > 0) resultSignifier = resultSignifier * 0x1306FE0A31B7152DE8D5A46305C85EDEC >> 128; if (xSignifier & 0x20000000000000000000000000000000 > 0) resultSignifier = resultSignifier * 0x1172B83C7D517ADCDF7C8C50EB14A791F >> 128; if (xSignifier & 0x10000000000000000000000000000000 > 0) resultSignifier = resultSignifier * 0x10B5586CF9890F6298B92B71842A98363 >> 128; if (xSignifier & 0x8000000000000000000000000000000 > 0) resultSignifier = resultSignifier * 0x1059B0D31585743AE7C548EB68CA417FD >> 128; if (xSignifier & 0x4000000000000000000000000000000 > 0) resultSignifier = resultSignifier * 0x102C9A3E778060EE6F7CACA4F7A29BDE8 >> 128; if (xSignifier & 0x2000000000000000000000000000000 > 0) resultSignifier = resultSignifier * 0x10163DA9FB33356D84A66AE336DCDFA3F >> 128; if (xSignifier & 0x1000000000000000000000000000000 > 0) resultSignifier = resultSignifier * 0x100B1AFA5ABCBED6129AB13EC11DC9543 >> 128; if (xSignifier & 0x800000000000000000000000000000 > 0) resultSignifier = resultSignifier * 0x10058C86DA1C09EA1FF19D294CF2F679B >> 128; if (xSignifier & 0x400000000000000000000000000000 > 0) resultSignifier = resultSignifier * 0x1002C605E2E8CEC506D21BFC89A23A00F >> 128; if (xSignifier & 0x200000000000000000000000000000 > 0) resultSignifier = resultSignifier * 0x100162F3904051FA128BCA9C55C31E5DF >> 128; if (xSignifier & 0x100000000000000000000000000000 > 0) resultSignifier = resultSignifier * 0x1000B175EFFDC76BA38E31671CA939725 >> 128; if (xSignifier & 0x80000000000000000000000000000 > 0) resultSignifier = resultSignifier * 0x100058BA01FB9F96D6CACD4B180917C3D >> 128; if (xSignifier & 0x40000000000000000000000000000 > 0) resultSignifier = resultSignifier * 0x10002C5CC37DA9491D0985C348C68E7B3 >> 128; if (xSignifier & 0x20000000000000000000000000000 > 0) resultSignifier = resultSignifier * 0x1000162E525EE054754457D5995292026 >> 128; if (xSignifier & 0x10000000000000000000000000000 > 0) resultSignifier = resultSignifier * 0x10000B17255775C040618BF4A4ADE83FC >> 128; if (xSignifier & 0x8000000000000000000000000000 > 0) resultSignifier = resultSignifier * 0x1000058B91B5BC9AE2EED81E9B7D4CFAB >> 128; if (xSignifier & 0x4000000000000000000000000000 > 0) resultSignifier = resultSignifier * 0x100002C5C89D5EC6CA4D7C8ACC017B7C9 >> 128; if (xSignifier & 0x2000000000000000000000000000 > 0) resultSignifier = resultSignifier * 0x10000162E43F4F831060E02D839A9D16D >> 128; if (xSignifier & 0x1000000000000000000000000000 > 0) resultSignifier = resultSignifier * 0x100000B1721BCFC99D9F890EA06911763 >> 128; if (xSignifier & 0x800000000000000000000000000 > 0) resultSignifier = resultSignifier * 0x10000058B90CF1E6D97F9CA14DBCC1628 >> 128; if (xSignifier & 0x400000000000000000000000000 > 0) resultSignifier = resultSignifier * 0x1000002C5C863B73F016468F6BAC5CA2B >> 128; if (xSignifier & 0x200000000000000000000000000 > 0) resultSignifier = resultSignifier * 0x100000162E430E5A18F6119E3C02282A5 >> 128; if (xSignifier & 0x100000000000000000000000000 > 0) resultSignifier = resultSignifier * 0x1000000B1721835514B86E6D96EFD1BFE >> 128; if (xSignifier & 0x80000000000000000000000000 > 0) resultSignifier = resultSignifier * 0x100000058B90C0B48C6BE5DF846C5B2EF >> 128; if (xSignifier & 0x40000000000000000000000000 > 0) resultSignifier = resultSignifier * 0x10000002C5C8601CC6B9E94213C72737A >> 128; if (xSignifier & 0x20000000000000000000000000 > 0) resultSignifier = resultSignifier * 0x1000000162E42FFF037DF38AA2B219F06 >> 128; if (xSignifier & 0x10000000000000000000000000 > 0) resultSignifier = resultSignifier * 0x10000000B17217FBA9C739AA5819F44F9 >> 128; if (xSignifier & 0x8000000000000000000000000 > 0) resultSignifier = resultSignifier * 0x1000000058B90BFCDEE5ACD3C1CEDC823 >> 128; if (xSignifier & 0x4000000000000000000000000 > 0) resultSignifier = resultSignifier * 0x100000002C5C85FE31F35A6A30DA1BE50 >> 128; if (xSignifier & 0x2000000000000000000000000 > 0) resultSignifier = resultSignifier * 0x10000000162E42FF0999CE3541B9FFFCF >> 128; if (xSignifier & 0x1000000000000000000000000 > 0) resultSignifier = resultSignifier * 0x100000000B17217F80F4EF5AADDA45554 >> 128; if (xSignifier & 0x800000000000000000000000 > 0) resultSignifier = resultSignifier * 0x10000000058B90BFBF8479BD5A81B51AD >> 128; if (xSignifier & 0x400000000000000000000000 > 0) resultSignifier = resultSignifier * 0x1000000002C5C85FDF84BD62AE30A74CC >> 128; if (xSignifier & 0x200000000000000000000000 > 0) resultSignifier = resultSignifier * 0x100000000162E42FEFB2FED257559BDAA >> 128; if (xSignifier & 0x100000000000000000000000 > 0) resultSignifier = resultSignifier * 0x1000000000B17217F7D5A7716BBA4A9AE >> 128; if (xSignifier & 0x80000000000000000000000 > 0) resultSignifier = resultSignifier * 0x100000000058B90BFBE9DDBAC5E109CCE >> 128; if (xSignifier & 0x40000000000000000000000 > 0) resultSignifier = resultSignifier * 0x10000000002C5C85FDF4B15DE6F17EB0D >> 128; if (xSignifier & 0x20000000000000000000000 > 0) resultSignifier = resultSignifier * 0x1000000000162E42FEFA494F1478FDE05 >> 128; if (xSignifier & 0x10000000000000000000000 > 0) resultSignifier = resultSignifier * 0x10000000000B17217F7D20CF927C8E94C >> 128; if (xSignifier & 0x8000000000000000000000 > 0) resultSignifier = resultSignifier * 0x1000000000058B90BFBE8F71CB4E4B33D >> 128; if (xSignifier & 0x4000000000000000000000 > 0) resultSignifier = resultSignifier * 0x100000000002C5C85FDF477B662B26945 >> 128; if (xSignifier & 0x2000000000000000000000 > 0) resultSignifier = resultSignifier * 0x10000000000162E42FEFA3AE53369388C >> 128; if (xSignifier & 0x1000000000000000000000 > 0) resultSignifier = resultSignifier * 0x100000000000B17217F7D1D351A389D40 >> 128; if (xSignifier & 0x800000000000000000000 > 0) resultSignifier = resultSignifier * 0x10000000000058B90BFBE8E8B2D3D4EDE >> 128; if (xSignifier & 0x400000000000000000000 > 0) resultSignifier = resultSignifier * 0x1000000000002C5C85FDF4741BEA6E77E >> 128; if (xSignifier & 0x200000000000000000000 > 0) resultSignifier = resultSignifier * 0x100000000000162E42FEFA39FE95583C2 >> 128; if (xSignifier & 0x100000000000000000000 > 0) resultSignifier = resultSignifier * 0x1000000000000B17217F7D1CFB72B45E1 >> 128; if (xSignifier & 0x80000000000000000000 > 0) resultSignifier = resultSignifier * 0x100000000000058B90BFBE8E7CC35C3F0 >> 128; if (xSignifier & 0x40000000000000000000 > 0) resultSignifier = resultSignifier * 0x10000000000002C5C85FDF473E242EA38 >> 128; if (xSignifier & 0x20000000000000000000 > 0) resultSignifier = resultSignifier * 0x1000000000000162E42FEFA39F02B772C >> 128; if (xSignifier & 0x10000000000000000000 > 0) resultSignifier = resultSignifier * 0x10000000000000B17217F7D1CF7D83C1A >> 128; if (xSignifier & 0x8000000000000000000 > 0) resultSignifier = resultSignifier * 0x1000000000000058B90BFBE8E7BDCBE2E >> 128; if (xSignifier & 0x4000000000000000000 > 0) resultSignifier = resultSignifier * 0x100000000000002C5C85FDF473DEA871F >> 128; if (xSignifier & 0x2000000000000000000 > 0) resultSignifier = resultSignifier * 0x10000000000000162E42FEFA39EF44D91 >> 128; if (xSignifier & 0x1000000000000000000 > 0) resultSignifier = resultSignifier * 0x100000000000000B17217F7D1CF79E949 >> 128; if (xSignifier & 0x800000000000000000 > 0) resultSignifier = resultSignifier * 0x10000000000000058B90BFBE8E7BCE544 >> 128; if (xSignifier & 0x400000000000000000 > 0) resultSignifier = resultSignifier * 0x1000000000000002C5C85FDF473DE6ECA >> 128; if (xSignifier & 0x200000000000000000 > 0) resultSignifier = resultSignifier * 0x100000000000000162E42FEFA39EF366F >> 128; if (xSignifier & 0x100000000000000000 > 0) resultSignifier = resultSignifier * 0x1000000000000000B17217F7D1CF79AFA >> 128; if (xSignifier & 0x80000000000000000 > 0) resultSignifier = resultSignifier * 0x100000000000000058B90BFBE8E7BCD6D >> 128; if (xSignifier & 0x40000000000000000 > 0) resultSignifier = resultSignifier * 0x10000000000000002C5C85FDF473DE6B2 >> 128; if (xSignifier & 0x20000000000000000 > 0) resultSignifier = resultSignifier * 0x1000000000000000162E42FEFA39EF358 >> 128; if (xSignifier & 0x10000000000000000 > 0) resultSignifier = resultSignifier * 0x10000000000000000B17217F7D1CF79AB >> 128; if (xSignifier & 0x8000000000000000 > 0) resultSignifier = resultSignifier * 0x1000000000000000058B90BFBE8E7BCD5 >> 128; if (xSignifier & 0x4000000000000000 > 0) resultSignifier = resultSignifier * 0x100000000000000002C5C85FDF473DE6A >> 128; if (xSignifier & 0x2000000000000000 > 0) resultSignifier = resultSignifier * 0x10000000000000000162E42FEFA39EF34 >> 128; if (xSignifier & 0x1000000000000000 > 0) resultSignifier = resultSignifier * 0x100000000000000000B17217F7D1CF799 >> 128; if (xSignifier & 0x800000000000000 > 0) resultSignifier = resultSignifier * 0x10000000000000000058B90BFBE8E7BCC >> 128; if (xSignifier & 0x400000000000000 > 0) resultSignifier = resultSignifier * 0x1000000000000000002C5C85FDF473DE5 >> 128; if (xSignifier & 0x200000000000000 > 0) resultSignifier = resultSignifier * 0x100000000000000000162E42FEFA39EF2 >> 128; if (xSignifier & 0x100000000000000 > 0) resultSignifier = resultSignifier * 0x1000000000000000000B17217F7D1CF78 >> 128; if (xSignifier & 0x80000000000000 > 0) resultSignifier = resultSignifier * 0x100000000000000000058B90BFBE8E7BB >> 128; if (xSignifier & 0x40000000000000 > 0) resultSignifier = resultSignifier * 0x10000000000000000002C5C85FDF473DD >> 128; if (xSignifier & 0x20000000000000 > 0) resultSignifier = resultSignifier * 0x1000000000000000000162E42FEFA39EE >> 128; if (xSignifier & 0x10000000000000 > 0) resultSignifier = resultSignifier * 0x10000000000000000000B17217F7D1CF6 >> 128; if (xSignifier & 0x8000000000000 > 0) resultSignifier = resultSignifier * 0x1000000000000000000058B90BFBE8E7A >> 128; if (xSignifier & 0x4000000000000 > 0) resultSignifier = resultSignifier * 0x100000000000000000002C5C85FDF473C >> 128; if (xSignifier & 0x2000000000000 > 0) resultSignifier = resultSignifier * 0x10000000000000000000162E42FEFA39D >> 128; if (xSignifier & 0x1000000000000 > 0) resultSignifier = resultSignifier * 0x100000000000000000000B17217F7D1CE >> 128; if (xSignifier & 0x800000000000 > 0) resultSignifier = resultSignifier * 0x10000000000000000000058B90BFBE8E6 >> 128; if (xSignifier & 0x400000000000 > 0) resultSignifier = resultSignifier * 0x1000000000000000000002C5C85FDF472 >> 128; if (xSignifier & 0x200000000000 > 0) resultSignifier = resultSignifier * 0x100000000000000000000162E42FEFA38 >> 128; if (xSignifier & 0x100000000000 > 0) resultSignifier = resultSignifier * 0x1000000000000000000000B17217F7D1B >> 128; if (xSignifier & 0x80000000000 > 0) resultSignifier = resultSignifier * 0x100000000000000000000058B90BFBE8D >> 128; if (xSignifier & 0x40000000000 > 0) resultSignifier = resultSignifier * 0x10000000000000000000002C5C85FDF46 >> 128; if (xSignifier & 0x20000000000 > 0) resultSignifier = resultSignifier * 0x1000000000000000000000162E42FEFA2 >> 128; if (xSignifier & 0x10000000000 > 0) resultSignifier = resultSignifier * 0x10000000000000000000000B17217F7D0 >> 128; if (xSignifier & 0x8000000000 > 0) resultSignifier = resultSignifier * 0x1000000000000000000000058B90BFBE7 >> 128; if (xSignifier & 0x4000000000 > 0) resultSignifier = resultSignifier * 0x100000000000000000000002C5C85FDF3 >> 128; if (xSignifier & 0x2000000000 > 0) resultSignifier = resultSignifier * 0x10000000000000000000000162E42FEF9 >> 128; if (xSignifier & 0x1000000000 > 0) resultSignifier = resultSignifier * 0x100000000000000000000000B17217F7C >> 128; if (xSignifier & 0x800000000 > 0) resultSignifier = resultSignifier * 0x10000000000000000000000058B90BFBD >> 128; if (xSignifier & 0x400000000 > 0) resultSignifier = resultSignifier * 0x1000000000000000000000002C5C85FDE >> 128; if (xSignifier & 0x200000000 > 0) resultSignifier = resultSignifier * 0x100000000000000000000000162E42FEE >> 128; if (xSignifier & 0x100000000 > 0) resultSignifier = resultSignifier * 0x1000000000000000000000000B17217F6 >> 128; if (xSignifier & 0x80000000 > 0) resultSignifier = resultSignifier * 0x100000000000000000000000058B90BFA >> 128; if (xSignifier & 0x40000000 > 0) resultSignifier = resultSignifier * 0x10000000000000000000000002C5C85FC >> 128; if (xSignifier & 0x20000000 > 0) resultSignifier = resultSignifier * 0x1000000000000000000000000162E42FD >> 128; if (xSignifier & 0x10000000 > 0) resultSignifier = resultSignifier * 0x10000000000000000000000000B17217E >> 128; if (xSignifier & 0x8000000 > 0) resultSignifier = resultSignifier * 0x1000000000000000000000000058B90BE >> 128; if (xSignifier & 0x4000000 > 0) resultSignifier = resultSignifier * 0x100000000000000000000000002C5C85E >> 128; if (xSignifier & 0x2000000 > 0) resultSignifier = resultSignifier * 0x10000000000000000000000000162E42E >> 128; if (xSignifier & 0x1000000 > 0) resultSignifier = resultSignifier * 0x100000000000000000000000000B17216 >> 128; if (xSignifier & 0x800000 > 0) resultSignifier = resultSignifier * 0x10000000000000000000000000058B90A >> 128; if (xSignifier & 0x400000 > 0) resultSignifier = resultSignifier * 0x1000000000000000000000000002C5C84 >> 128; if (xSignifier & 0x200000 > 0) resultSignifier = resultSignifier * 0x100000000000000000000000000162E41 >> 128; if (xSignifier & 0x100000 > 0) resultSignifier = resultSignifier * 0x1000000000000000000000000000B1720 >> 128; if (xSignifier & 0x80000 > 0) resultSignifier = resultSignifier * 0x100000000000000000000000000058B8F >> 128; if (xSignifier & 0x40000 > 0) resultSignifier = resultSignifier * 0x10000000000000000000000000002C5C7 >> 128; if (xSignifier & 0x20000 > 0) resultSignifier = resultSignifier * 0x1000000000000000000000000000162E3 >> 128; if (xSignifier & 0x10000 > 0) resultSignifier = resultSignifier * 0x10000000000000000000000000000B171 >> 128; if (xSignifier & 0x8000 > 0) resultSignifier = resultSignifier * 0x1000000000000000000000000000058B8 >> 128; if (xSignifier & 0x4000 > 0) resultSignifier = resultSignifier * 0x100000000000000000000000000002C5B >> 128; if (xSignifier & 0x2000 > 0) resultSignifier = resultSignifier * 0x10000000000000000000000000000162D >> 128; if (xSignifier & 0x1000 > 0) resultSignifier = resultSignifier * 0x100000000000000000000000000000B16 >> 128; if (xSignifier & 0x800 > 0) resultSignifier = resultSignifier * 0x10000000000000000000000000000058A >> 128; if (xSignifier & 0x400 > 0) resultSignifier = resultSignifier * 0x1000000000000000000000000000002C4 >> 128; if (xSignifier & 0x200 > 0) resultSignifier = resultSignifier * 0x100000000000000000000000000000161 >> 128; if (xSignifier & 0x100 > 0) resultSignifier = resultSignifier * 0x1000000000000000000000000000000B0 >> 128; if (xSignifier & 0x80 > 0) resultSignifier = resultSignifier * 0x100000000000000000000000000000057 >> 128; if (xSignifier & 0x40 > 0) resultSignifier = resultSignifier * 0x10000000000000000000000000000002B >> 128; if (xSignifier & 0x20 > 0) resultSignifier = resultSignifier * 0x100000000000000000000000000000015 >> 128; if (xSignifier & 0x10 > 0) resultSignifier = resultSignifier * 0x10000000000000000000000000000000A >> 128; if (xSignifier & 0x8 > 0) resultSignifier = resultSignifier * 0x100000000000000000000000000000004 >> 128; if (xSignifier & 0x4 > 0) resultSignifier = resultSignifier * 0x100000000000000000000000000000001 >> 128; if (!xNegative) { resultSignifier = resultSignifier >> 15 & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF; resultExponent += 0x3FFF; } else if (resultExponent <= 0x3FFE) { resultSignifier = resultSignifier >> 15 & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF; resultExponent = 0x3FFF - resultExponent; } else { resultSignifier = resultSignifier >> resultExponent - 16367; resultExponent = 0; } return bytes16 (uint128 (resultExponent << 112 | resultSignifier)); } } } /** * Calculate e^x. * * @param x quadruple precision number * @return quadruple precision number */ function exp (bytes16 x) internal pure returns (bytes16) { unchecked { return pow_2 (mul (x, 0x3FFF71547652B82FE1777D0FFDA0D23A)); } } /** * Get index of the most significant non-zero bit in binary representation of * x. Reverts if x is zero. * * @return index of the most significant non-zero bit in binary representation * of x */ function mostSignificantBit (uint256 x) private pure returns (uint256) { unchecked { require (x > 0); uint256 result = 0; if (x >= 0x100000000000000000000000000000000) { x >>= 128; result += 128; } if (x >= 0x10000000000000000) { x >>= 64; result += 64; } if (x >= 0x100000000) { x >>= 32; result += 32; } if (x >= 0x10000) { x >>= 16; result += 16; } if (x >= 0x100) { x >>= 8; result += 8; } if (x >= 0x10) { x >>= 4; result += 4; } if (x >= 0x4) { x >>= 2; result += 2; } if (x >= 0x2) result += 1; // No need to shift x anymore return result; } } } // File: contracts/libraries/errors/Errors.sol pragma solidity 0.8.17; library Errors { /// @notice Error thrown when the lpToken address is not supported /// @dev List of supported LpTokens are defined in {LiquidityMining._lpTokens} string public constant LP_TOKEN_NOT_SUPPORTED = "PT_701"; /// @notice Error thrown when the caller / msgSender is not a PowerToken smart contract string public constant CALLER_NOT_POWER_TOKEN = "PT_702"; /// @notice Error thrown when the caller / msgSender is not a LiquidityMining smart contract string public constant CALLER_NOT_LIQUIDITY_MINING = "PT_703"; /// @notice Error thrown when the caller / msgSender is not a Pause Manager address. /// @dev Pause Manager can be defined by smart contract's Onwer string public constant CALLER_NOT_PAUSE_MANAGER = "PT_704"; /// @notice Error thrown when the account's base balance is too low string public constant ACCOUNT_BASE_BALANCE_IS_TOO_LOW = "PT_705"; /// @notice Error thrown when the account's Lp Token balance is too low string public constant ACCOUNT_LP_TOKEN_BALANCE_IS_TOO_LOW = "PT_706"; /// @notice Error thrown when the account's delegated balance is too low string public constant ACC_DELEGATED_TO_LIQUIDITY_MINING_BALANCE_IS_TOO_LOW = "PT_707"; /// @notice Error thrown when the account's available Power Token balance is too low string public constant ACC_AVAILABLE_POWER_TOKEN_BALANCE_IS_TOO_LOW = "PT_708"; /// @notice Error thrown when the account doesn't have the rewards (Staked Tokens / Power Tokens) to claim string public constant NO_REWARDS_TO_CLAIM = "PT_709"; /// @notice Error thrown when the cooldown is not finished. string public constant COOL_DOWN_NOT_FINISH = "PT_710"; /// @notice Error thrown when the aggregate power up indicator is going to be negative during the calculation. string public constant AGGREGATE_POWER_UP_COULD_NOT_BE_NEGATIVE = "PT_711"; /// @notice Error thrown when the block number used in the function is lower than previous block number stored in the liquidity mining indicators. string public constant BLOCK_NUMBER_LOWER_THAN_PREVIOUS_BLOCK_NUMBER = "PT_712"; /// @notice Account Composite Multiplier indicator is greater or equal to Composit Multiplier indicator, but it should be lower or equal string public constant ACCOUNT_COMPOSITE_MULTIPLIER_GT_COMPOSITE_MULTIPLIER = "PT_713"; /// @notice The fee for unstacking of Power Tokens should be number between (0, 1e18) string public constant UNSTAKE_WITHOUT_COOLDOWN_FEE_IS_TO_HIGH = "PT_714"; /// @notice General problem, address is wrong string public constant WRONG_ADDRESS = "PT_715"; /// @notice General problem, contract is wrong string public constant WRONG_CONTRACT_ID = "PT_716"; /// @notice Value not greater than zero string public constant VALUE_NOT_GREATER_THAN_ZERO = "PT_717"; /// @notice Appeared when input of two arrays length mismatch string public constant INPUT_ARRAYS_LENGTH_MISMATCH = "PT_718"; /// @notice msg.sender is not an appointed owner, it cannot confirm their ownership string public constant SENDER_NOT_APPOINTED_OWNER = "PT_719"; } // File: contracts/libraries/math/MiningCalculation.sol pragma solidity 0.8.17; /// @title Library containing the core logic used in the Liquidity Mining module. library MiningCalculation { bytes16 constant N0_00 = 0x00000000000000000000000000000000; bytes16 constant N0_01 = 0x3ff847ae147ae147b74da9ca30cfea4b; //0.01 bytes16 constant N0_02 = 0x3ff947ae147ae147b2b11255bc3eff63; // 0.02 bytes16 constant N0_03 = 0x3ff9eb851eb851eb89bb4fc6601609a0; // 0.03 bytes16 constant N0_04 = 0x3ffa47ae147ae147b062c69b81f689ee; // 0.04 bytes16 constant N0_05 = 0x3ffa9999999999999be7e553d3e20f0d; // 0.05 bytes16 constant SLOPE_1 = 0x40024000000000000000000000000000; // 10.0 bytes16 constant BASE_1 = 0x3ffc9999999999999a2d2c88282bb6f6; // 0.2 bytes16 constant SLOPE_2 = 0x40010000000000000000000000000000; // 4.0 bytes16 constant BASE_2 = 0x3ffd0a3d70a3d70a3dba6d4e51867f52; // 0.26 bytes16 constant SLOPE_3 = 0x40008000000000000000000000000000; // 3.0 bytes16 constant BASE_3 = 0x3ffd1eb851eb851eb89bb4fc6601609a; // 0.28 bytes16 constant SLOPE_4 = 0x40000000000000000000000000000000; // 2.0 bytes16 constant BASE_4 = 0x3ffd3d70a3d70a3d70eda08184b9b285; // 0.31 bytes16 constant SLOPE_5 = 0x3fff0000000000000000000000000000; // 2.0 bytes16 constant BASE_5 = 0x3ffd66666666666666b02fddadaf7514; // 0.31 using SafeCast for uint256; using SafeCast for int256; /// @notice Calculases the Power-up indicator for a given account. /// @param accountPwTokenAmount account's Power Tokens amount /// @param accountLpTokenAmount account's lpTokens amount /// @param verticalShift preconfigured param, vertical shift used in equation calculating the account's power-up /// @param horizontalShift preconfigured param, horizontal shift used in equation calculating account's power-up /// @return power-up indicator of a given account function calculateAccountPowerUp( uint256 accountPwTokenAmount, uint256 accountLpTokenAmount, bytes16 verticalShift, bytes16 horizontalShift ) internal pure returns (uint256) { if (accountLpTokenAmount < Constants.D18) { return 0; } bytes16 accountPwTokenAmountQP = _toQuadruplePrecision(accountPwTokenAmount, Constants.D18); bytes16 lpTokenAmountQP = _toQuadruplePrecision(accountLpTokenAmount, Constants.D18); bytes16 ratio = ABDKMathQuad.div(accountPwTokenAmountQP, lpTokenAmountQP); bytes16 result; if (ABDKMathQuad.cmp(N0_05, ratio) >= 0) { result = accountPowerUpStepFunction(ratio); } else { bytes16 pwTokenAmountWithModifierQP = ABDKMathQuad.mul( _getPwTokenModifier(), accountPwTokenAmountQP ); bytes16 underLog = ABDKMathQuad.add( ABDKMathQuad.div(pwTokenAmountWithModifierQP, lpTokenAmountQP), horizontalShift ); result = ABDKMathQuad.add(verticalShift, ABDKMathQuad.log_2(underLog)); } bytes16 resultD18 = ABDKMathQuad.mul(result, ABDKMathQuad.fromUInt(Constants.D18)); return ABDKMathQuad.toUInt(resultD18); } /// @notice Calculates the aggreagated power-up. Aggregate power-up is a synthetic summary of all power-ups across all users. /// It's used to calculate the individual rewards in relation to the rest of the pool. /// @param accountPowerUp power up indicator is calculated for a given account /// @param accountLpTokenAmount lpToken amount for a given account /// @param previousAccountPowerUp previous power-up indicator for a given account /// @param previousAccountLpTokenAmount previous lpToken amount for a given account /// @param previousAggregatedPowerUp previous aggregated power-up indicator function calculateAggregatedPowerUp( uint256 accountPowerUp, uint256 accountLpTokenAmount, uint256 previousAccountPowerUp, uint256 previousAccountLpTokenAmount, uint256 previousAggregatedPowerUp ) internal pure returns (uint256) { int256 apu = accountPowerUp.toInt256() * accountLpTokenAmount.toInt256() - previousAccountPowerUp.toInt256() * previousAccountLpTokenAmount.toInt256(); uint256 newApu; if (apu < 0) { uint256 absApu = Math.division((-apu).toUint256(), Constants.D18); /// @dev the last unstaking of lpTokens can experience a rounding error if (previousAggregatedPowerUp < absApu && previousAggregatedPowerUp + 10000 >= absApu) { return 0; } require( previousAggregatedPowerUp >= absApu, Errors.AGGREGATE_POWER_UP_COULD_NOT_BE_NEGATIVE ); newApu = previousAggregatedPowerUp - absApu; } else { newApu = previousAggregatedPowerUp + Math.division(apu.toUint256(), Constants.D18); } if (newApu < 10000) { return 0; } return newApu; } /// @notice Calculates the rewards from last rebalancing including block number given as a param. /// @param blockNumber block number for which the rewards calculation is executed /// @param lastRebalanceBlockNumber block number when last rewards rebalance was executed /// @param rewardsPerBlock configuration param describing how many pwTokens are rewarded across all participants per one block, represendet with 8 decimals /// @param previousAccruedRewards number of previously cumulated/accrued rewards /// @return new accrued rewards, amount of Power Tokens accrued for given params function calculateAccruedRewards( uint256 blockNumber, uint256 lastRebalanceBlockNumber, uint256 rewardsPerBlock, uint256 previousAccruedRewards ) internal pure returns (uint256) { require( blockNumber >= lastRebalanceBlockNumber, Errors.BLOCK_NUMBER_LOWER_THAN_PREVIOUS_BLOCK_NUMBER ); uint256 newRewards = (blockNumber - lastRebalanceBlockNumber) * rewardsPerBlock * Constants.D10; return previousAccruedRewards + newRewards; } /// @notice Calculates the Composite Multiplier Indicator /// @param rewardsPerBlock config param, number of Power Token rewardes across all participants in one block, represented with 8 decimals /// @param aggregatedPowerUp Aggregated Power-up indicator, represented with 18 decimals /// @return composite multiplier, value represented with 27 decimals function calculateCompositeMultiplier(uint256 rewardsPerBlock, uint256 aggregatedPowerUp) internal pure returns (uint256) { if (aggregatedPowerUp == 0) { return 0; } /// @dev decimals: 8 + 18 + 19 - 18 = 27 return Math.division(rewardsPerBlock * Constants.D18 * Constants.D19, aggregatedPowerUp); } /// @notice calculates the account's rewards issued in pwTokens /// @param accountLpTokenAmount amount of lpTokens for a given account /// @param accountPowerUp value of power-up indicator for a given account /// @param accountCompMultiplierCumulativePrevBlock Account Composite Multiplier Cumulative for the Previous Block, value from last Account Indicator update of param Composite Multiplier Cumulative for a given account /// @param accruedCompMultiplierCumulativePrevBlock Accrued Composite Multiplier Cumulative for the Previous Block, accrued value (in a current block) of param Composite Multiplier Cumulative global /// @return rewards, amount of Staked Tokens (or Power Tokens because are in 1:1 relation with Staked Tokens), represented with 18 decimals function calculateAccountRewards( uint256 accountLpTokenAmount, uint256 accountPowerUp, uint256 accountCompMultiplierCumulativePrevBlock, uint256 accruedCompMultiplierCumulativePrevBlock ) internal pure returns (uint256) { require( accruedCompMultiplierCumulativePrevBlock >= accountCompMultiplierCumulativePrevBlock, Errors.ACCOUNT_COMPOSITE_MULTIPLIER_GT_COMPOSITE_MULTIPLIER ); uint256 accountStakedTokenRewards = accountLpTokenAmount * accountPowerUp * (accruedCompMultiplierCumulativePrevBlock - accountCompMultiplierCumulativePrevBlock); /// @dev decimals: 18 + 18 + 27 - 45 = 18 return Math.division(accountStakedTokenRewards, Constants.D45); } /// @notice Calculates the accrued Composite Multiplier Cumulative for the previous block /// @param currentBlockNumber Current block number /// @param globalIndBlockNumber Block number of the last update of the Global Indicators /// @param globalIndCompositeMultiplierInTheBlock Configuration param - Composite Multiplier for one block defined in Global Indicators /// @param globalIndCompositeMultiplierCumulativePrevBlock Compositne Multiplier Comulative for a previous block defined in Global Indicators structure. function calculateAccruedCompMultiplierCumulativePrevBlock( uint256 currentBlockNumber, uint256 globalIndBlockNumber, uint256 globalIndCompositeMultiplierInTheBlock, uint256 globalIndCompositeMultiplierCumulativePrevBlock ) internal pure returns (uint256) { return globalIndCompositeMultiplierCumulativePrevBlock + (currentBlockNumber - globalIndBlockNumber) * globalIndCompositeMultiplierInTheBlock; } function accountPowerUpStepFunction(bytes16 ratio) internal pure returns (bytes16) { if (ABDKMathQuad.cmp(N0_01, ratio) > 0) { return ABDKMathQuad.add(BASE_1, ABDKMathQuad.mul(SLOPE_1, ratio)); } else if (ABDKMathQuad.cmp(N0_02, ratio) > 0) { return ABDKMathQuad.add(BASE_2, ABDKMathQuad.mul(SLOPE_2, ratio)); } else if (ABDKMathQuad.cmp(N0_03, ratio) > 0) { return ABDKMathQuad.add(BASE_3, ABDKMathQuad.mul(SLOPE_3, ratio)); } else if (ABDKMathQuad.cmp(N0_04, ratio) > 0) { return ABDKMathQuad.add(BASE_4, ABDKMathQuad.mul(SLOPE_4, ratio)); } else { return ABDKMathQuad.add(BASE_5, ABDKMathQuad.mul(SLOPE_5, ratio)); } } /// @dev Quadruple precision, 128 bits function _toQuadruplePrecision(uint256 number, uint256 decimals) private pure returns (bytes16) { if (number % decimals > 0) { /// @dev during calculation this value is lost in the conversion number += 1; } bytes16 nominator = ABDKMathQuad.fromUInt(number); bytes16 denominator = ABDKMathQuad.fromUInt(decimals); bytes16 fraction = ABDKMathQuad.div(nominator, denominator); return fraction; } /// @dev Quadruple precision, 128 bits function _getPwTokenModifier() private pure returns (bytes16) { return ABDKMathQuad.fromUInt(2); } } // File: @openzeppelin/contracts-upgradeable/utils/StorageSlotUpgradeable.sol // OpenZeppelin Contracts (last updated v4.7.0) (utils/StorageSlot.sol) 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: * ``` * contract ERC1967 { * bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc; * * function _getImplementation() internal view returns (address) { * return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value; * } * * function _setImplementation(address newImplementation) internal { * require(Address.isContract(newImplementation), "ERC1967: new implementation is not a contract"); * StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation; * } * } * ``` * * _Available since v4.1 for `address`, `bool`, `bytes32`, and `uint256`._ */ library StorageSlotUpgradeable { struct AddressSlot { address value; } struct BooleanSlot { bool value; } struct Bytes32Slot { bytes32 value; } struct Uint256Slot { uint256 value; } /** * @dev Returns an `AddressSlot` with member `value` located at `slot`. */ function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } /** * @dev Returns an `BooleanSlot` with member `value` located at `slot`. */ function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } /** * @dev Returns an `Bytes32Slot` with member `value` located at `slot`. */ function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } /** * @dev Returns an `Uint256Slot` with member `value` located at `slot`. */ function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } } // File: @openzeppelin/contracts-upgradeable/proxy/beacon/IBeaconUpgradeable.sol // 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/interfaces/draft-IERC1822Upgradeable.sol // 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/utils/AddressUpgradeable.sol // 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 AddressUpgradeable { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * ==== * * [IMPORTANT] * ==== * You shouldn't rely on `isContract` to protect against flash loan attacks! * * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract * constructor. * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize/address.code.length, which returns 0 // for contracts in construction, since the code is only stored at the end // of the constructor execution. return account.code.length > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); (bool success, ) = recipient.call{value: amount}(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain `call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return 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 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-upgradeable/proxy/utils/Initializable.sol // OpenZeppelin Contracts (last updated v4.7.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] * ``` * 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. Equivalent to `reinitializer(1)`. */ 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. * * `initializer` is equivalent to `reinitializer(1)`, so 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. * * 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. */ 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. */ function _disableInitializers() internal virtual { require(!_initializing, "Initializable: contract is initializing"); if (_initialized < type(uint8).max) { _initialized = type(uint8).max; emit Initialized(type(uint8).max); } } } // File: @openzeppelin/contracts-upgradeable/proxy/ERC1967/ERC1967UpgradeUpgradeable.sol // OpenZeppelin Contracts (last updated v4.5.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._ * * @custom:oz-upgrades-unsafe-allow delegatecall */ abstract contract ERC1967UpgradeUpgradeable is Initializable { 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 Emitted when the implementation is upgraded. */ event Upgraded(address indexed implementation); /** * @dev Returns the current implementation address. */ function _getImplementation() internal view returns (address) { return StorageSlotUpgradeable.getAddressSlot(_IMPLEMENTATION_SLOT).value; } /** * @dev Stores a new address in the EIP1967 implementation slot. */ function _setImplementation(address newImplementation) private { require(AddressUpgradeable.isContract(newImplementation), "ERC1967: new implementation is not a contract"); StorageSlotUpgradeable.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation; } /** * @dev Perform implementation upgrade * * Emits an {Upgraded} event. */ function _upgradeTo(address newImplementation) internal { _setImplementation(newImplementation); emit Upgraded(newImplementation); } /** * @dev Perform implementation upgrade with additional setup call. * * Emits an {Upgraded} event. */ function _upgradeToAndCall( address newImplementation, bytes memory data, bool forceCall ) internal { _upgradeTo(newImplementation); if (data.length > 0 || forceCall) { _functionDelegateCall(newImplementation, data); } } /** * @dev Perform implementation upgrade with security checks for UUPS proxies, and additional setup call. * * Emits an {Upgraded} event. */ function _upgradeToAndCallUUPS( address newImplementation, bytes memory data, bool forceCall ) internal { // Upgrades from old implementations will perform a rollback test. This test requires the new // implementation to upgrade back to the old, non-ERC1822 compliant, implementation. Removing // this special case will break upgrade paths from old UUPS implementation to new ones. if (StorageSlotUpgradeable.getBooleanSlot(_ROLLBACK_SLOT).value) { _setImplementation(newImplementation); } else { try IERC1822ProxiableUpgradeable(newImplementation).proxiableUUID() returns (bytes32 slot) { require(slot == _IMPLEMENTATION_SLOT, "ERC1967Upgrade: unsupported proxiableUUID"); } catch { revert("ERC1967Upgrade: new implementation is not UUPS"); } _upgradeToAndCall(newImplementation, data, forceCall); } } /** * @dev Storage slot with the admin of the contract. * This is the keccak-256 hash of "eip1967.proxy.admin" subtracted by 1, and is * validated in the constructor. */ bytes32 internal constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103; /** * @dev Emitted when the admin account has changed. */ event AdminChanged(address previousAdmin, address newAdmin); /** * @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 Emitted when the beacon is upgraded. */ event BeaconUpgraded(address indexed beacon); /** * @dev Returns the current beacon. */ function _getBeacon() internal view returns (address) { return StorageSlotUpgradeable.getAddressSlot(_BEACON_SLOT).value; } /** * @dev Stores a new beacon in the EIP1967 beacon slot. */ function _setBeacon(address newBeacon) private { require(AddressUpgradeable.isContract(newBeacon), "ERC1967: new beacon is not a contract"); require( AddressUpgradeable.isContract(IBeaconUpgradeable(newBeacon).implementation()), "ERC1967: beacon implementation is not a contract" ); StorageSlotUpgradeable.getAddressSlot(_BEACON_SLOT).value = newBeacon; } /** * @dev Perform beacon upgrade with additional setup call. Note: This upgrades the address of the beacon, it does * not upgrade the implementation contained in the beacon (see {UpgradeableBeacon-_setImplementation} for that). * * Emits a {BeaconUpgraded} event. */ function _upgradeBeaconToAndCall( address newBeacon, bytes memory data, bool forceCall ) internal { _setBeacon(newBeacon); emit BeaconUpgraded(newBeacon); if (data.length > 0 || forceCall) { _functionDelegateCall(IBeaconUpgradeable(newBeacon).implementation(), data); } } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function _functionDelegateCall(address target, bytes memory data) private returns (bytes memory) { require(AddressUpgradeable.isContract(target), "Address: delegate call to non-contract"); // solhint-disable-next-line avoid-low-level-calls (bool success, bytes memory returndata) = target.delegatecall(data); return AddressUpgradeable.verifyCallResult(success, returndata, "Address: low-level delegate call failed"); } /** * @dev This empty reserved space is put in place to allow future versions to add new * variables without shifting down storage in the inheritance chain. * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps */ uint256[50] private __gap; } // File: @openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol // OpenZeppelin Contracts (last updated v4.5.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 that the this implementation remains valid after an upgrade. * * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this * function revert if invoked through a proxy. This is guaranteed by the `notDelegated` modifier. */ function proxiableUUID() external view virtual override notDelegated returns (bytes32) { return _IMPLEMENTATION_SLOT; } /** * @dev Upgrade the implementation of the proxy to `newImplementation`. * * Calls {_authorizeUpgrade}. * * Emits an {Upgraded} event. */ function upgradeTo(address newImplementation) external virtual onlyProxy { _authorizeUpgrade(newImplementation); _upgradeToAndCallUUPS(newImplementation, new bytes(0), false); } /** * @dev Upgrade the implementation of the proxy to `newImplementation`, and subsequently execute the function call * encoded in `data`. * * Calls {_authorizeUpgrade}. * * Emits an {Upgraded} event. */ function upgradeToAndCall(address newImplementation, bytes memory data) external payable virtual onlyProxy { _authorizeUpgrade(newImplementation); _upgradeToAndCallUUPS(newImplementation, data, true); } /** * @dev Function that should revert when `msg.sender` is not authorized to upgrade the contract. Called by * {upgradeTo} and {upgradeToAndCall}. * * Normally, this function will use an xref:access.adoc[access control] modifier such as {Ownable-onlyOwner}. * * ```solidity * function _authorizeUpgrade(address) internal override onlyOwner {} * ``` */ function _authorizeUpgrade(address newImplementation) internal virtual; /** * @dev This empty reserved space is put in place to allow future versions to add new * variables without shifting down storage in the inheritance chain. * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps */ uint256[50] private __gap; } // File: @openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol // OpenZeppelin Contracts v4.4.1 (security/ReentrancyGuard.sol) pragma solidity ^0.8.0; /** * @dev Contract module that helps prevent reentrant calls to a function. * * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier * available, which can be applied to functions to make sure there are no nested * (reentrant) calls to them. * * Note that because there is a single `nonReentrant` guard, functions marked as * `nonReentrant` may not call one another. This can be worked around by making * those functions `private`, and then adding `external` `nonReentrant` entry * points to them. * * TIP: If you would like to learn more about reentrancy and alternative ways * to protect against it, check out our blog post * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul]. */ abstract contract ReentrancyGuardUpgradeable is Initializable { // Booleans are more expensive than uint256 or any type that takes up a full // word because each write operation emits an extra SLOAD to first read the // slot's contents, replace the bits taken up by the boolean, and then write // back. This is the compiler's defense against contract upgrades and // pointer aliasing, and it cannot be disabled. // The values being non-zero value makes deployment a bit more expensive, // but in exchange the refund on every call to nonReentrant will be lower in // amount. Since refunds are capped to a percentage of the total // transaction's gas, it is best to keep them low in cases like this one, to // increase the likelihood of the full refund coming into effect. uint256 private constant _NOT_ENTERED = 1; uint256 private constant _ENTERED = 2; uint256 private _status; function __ReentrancyGuard_init() internal onlyInitializing { __ReentrancyGuard_init_unchained(); } function __ReentrancyGuard_init_unchained() internal onlyInitializing { _status = _NOT_ENTERED; } /** * @dev Prevents a contract from calling itself, directly or indirectly. * Calling a `nonReentrant` function from another `nonReentrant` * function is not supported. It is possible to prevent this from happening * by making the `nonReentrant` function external, and making it call a * `private` function that does the actual work. */ modifier nonReentrant() { // On the first call to nonReentrant, _notEntered will be true require(_status != _ENTERED, "ReentrancyGuard: reentrant call"); // Any calls to nonReentrant after this point will fail _status = _ENTERED; _; // By storing the original value once again, a refund is triggered (see // https://eips.ethereum.org/EIPS/eip-2200) _status = _NOT_ENTERED; } /** * @dev This empty reserved space is put in place to allow future versions to add new * variables without shifting down storage in the inheritance chain. * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps */ uint256[49] private __gap; } // File: @openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol // 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/access/OwnableUpgradeable.sol // OpenZeppelin Contracts (last updated v4.7.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 anymore. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby removing 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: contracts/security/MiningOwnableUpgradeable.sol pragma solidity 0.8.17; contract MiningOwnableUpgradeable is OwnableUpgradeable { address private _appointedOwner; event AppointedToTransferOwnership(address indexed appointedOwner); modifier onlyAppointedOwner() { require(_appointedOwner == _msgSender(), Errors.SENDER_NOT_APPOINTED_OWNER); _; } function transferOwnership(address appointedOwner) public override onlyOwner { require(appointedOwner != address(0), Errors.WRONG_ADDRESS); _appointedOwner = appointedOwner; emit AppointedToTransferOwnership(appointedOwner); } function confirmTransferOwnership() public onlyAppointedOwner { _appointedOwner = address(0); _transferOwnership(_msgSender()); } function renounceOwnership() public virtual override onlyOwner { _transferOwnership(address(0)); _appointedOwner = address(0); } } // File: @openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol // OpenZeppelin Contracts (last updated v4.7.0) (security/Pausable.sol) pragma solidity ^0.8.0; /** * @dev Contract module which allows children to implement an emergency stop * mechanism that can be triggered by an authorized account. * * This module is used through inheritance. It will make available the * modifiers `whenNotPaused` and `whenPaused`, which can be applied to * the functions of your contract. Note that they will not be pausable by * simply including this module, only once the modifiers are put in place. */ abstract contract PausableUpgradeable is Initializable, ContextUpgradeable { /** * @dev Emitted when the pause is triggered by `account`. */ event Paused(address account); /** * @dev Emitted when the pause is lifted by `account`. */ event Unpaused(address account); bool private _paused; /** * @dev Initializes the contract in unpaused state. */ function __Pausable_init() internal onlyInitializing { __Pausable_init_unchained(); } function __Pausable_init_unchained() internal onlyInitializing { _paused = false; } /** * @dev Modifier to make a function callable only when the contract is not paused. * * Requirements: * * - The contract must not be paused. */ modifier whenNotPaused() { _requireNotPaused(); _; } /** * @dev Modifier to make a function callable only when the contract is paused. * * Requirements: * * - The contract must be paused. */ modifier whenPaused() { _requirePaused(); _; } /** * @dev Returns true if the contract is paused, and false otherwise. */ function paused() public view virtual returns (bool) { return _paused; } /** * @dev Throws if the contract is paused. */ function _requireNotPaused() internal view virtual { require(!paused(), "Pausable: paused"); } /** * @dev Throws if the contract is not paused. */ function _requirePaused() internal view virtual { require(paused(), "Pausable: not paused"); } /** * @dev Triggers stopped state. * * Requirements: * * - The contract must not be paused. */ function _pause() internal virtual whenNotPaused { _paused = true; emit Paused(_msgSender()); } /** * @dev Returns to normal state. * * Requirements: * * - The contract must be paused. */ function _unpause() internal virtual whenPaused { _paused = false; emit Unpaused(_msgSender()); } /** * @dev This empty reserved space is put in place to allow future versions to add new * variables without shifting down storage in the inheritance chain. * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps */ uint256[49] private __gap; } // File: @openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol // 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 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/IERC20MetadataUpgradeable.sol // 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/ERC20Upgradeable.sol // OpenZeppelin Contracts (last updated v4.7.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.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How * to implement supply mechanisms]. * * 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}. * * The default value of {decimals} is 18. To select a different value for * {decimals} you should overload it. * * 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 value {ERC20} uses, unless this function is * 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; } _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; _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; } _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/interfaces/types/LiquidityMiningTypes.sol pragma solidity 0.8.17; /// @title Structures used in the LiquidityMining. library LiquidityMiningTypes { /// @title Struct pair representing delegated pwToken balance struct DelegatedPwTokenBalance { /// @notice lpToken address address lpToken; /// @notice The amount of Power Token delegated to lpToken staking pool /// @dev value represented in 18 decimals uint256 pwTokenAmount; } /// @title Global indicators used in rewards calculation. struct GlobalRewardsIndicators { /// @notice powerUp indicator aggregated /// @dev It can be changed many times during transaction, represended with 18 decimals uint256 aggregatedPowerUp; /// @notice composite multiplier in a block described in field blockNumber /// @dev It can be changed many times during transaction, represented with 27 decimals uint128 compositeMultiplierInTheBlock; /// @notice Composite multiplier updated in block {blockNumber} but calculated for PREVIOUS (!) block. /// @dev It can be changed once per block, represented with 27 decimals uint128 compositeMultiplierCumulativePrevBlock; /// @dev It can be changed once per block. Block number in which all other params of this structure are updated uint32 blockNumber; /// @notice value describing amount of rewards issued per block, /// @dev It can be changed at most once per block, represented with 8 decimals uint32 rewardsPerBlock; /// @notice amount of accrued rewards since inception /// @dev It can be changed at most once per block, represented with 8 decimals uint88 accruedRewards; } /// @title Params recorded for a given account. These params are used by the algorithm responsible for rewards distribution. /// @dev The structure in storage is updated when account interacts with the LiquidityMining smart contract (stake, unstake, delegate, undelegate, claim) struct AccountRewardsIndicators { /// @notice `composite multiplier cumulative` is calculated for previous block /// @dev represented in 27 decimals uint128 compositeMultiplierCumulativePrevBlock; /// @notice lpToken account's balance uint128 lpTokenBalance; /// @notive PowerUp is a result of logarithmic equastion, /// @dev powerUp < 100 *10^18 uint72 powerUp; /// @notice balance of Power Tokens delegated to LiquidityMining /// @dev delegatedPwTokenBalance < 10^26 < 2^87 uint96 delegatedPwTokenBalance; } } // File: contracts/interfaces/ILiquidityMiningInternal.sol pragma solidity 0.8.17; /// @title The interface for interaction with the LiquidityMining contract. Contains mainly technical methods or methods used by PowerToken smart contract. interface ILiquidityMiningInternal { /// @notice Returns the current version of the LiquidityMining contract /// @return Current LiquidityMining (Liquidity Rewards) version function getVersion() external pure returns (uint256); /// @notice Gets the Pause Manager's address /// @return Pause Manager's address function getPauseManager() external view returns (address); /// @notice Checks if lpToken is supported by the liquidity mining module. /// @param lpToken lpToken address /// @return returns true if lpToken is supported by the LiquidityMining, false otherwise function isLpTokenSupported(address lpToken) external view returns (bool); /// @notice Gets the global indicators for a given lpToken /// @param lpToken lpToken address /// @return {LiquidityMiningTypes.GlobalRewardsIndicators} structure with global indicators used in the rewards calculation. function getGlobalIndicators(address lpToken) external view returns (LiquidityMiningTypes.GlobalRewardsIndicators memory); /// @notice Gets the sender's rewards indicators for a given lpToken /// @param account account's address /// @param lpToken lpToken address /// @return {LiquidityMiningTypes.AccountRewardsIndicators} structure with the sender rewards indicators used in rewards calculation. function getAccountIndicators(address account, address lpToken) external view returns (LiquidityMiningTypes.AccountRewardsIndicators memory); /// @notice Delegates the Power Tokens of s given account to LiquidityMining smart contract. /// @param account account address delegating its Power Tokens to LiquidityMining /// @param lpTokens list of lpToken addresses to which Power Tokens are delegated /// @param pwTokenAmount list of Power Token amounts for delegated to given lpTokens, represented with 18 decimals function delegatePwToken( address account, address[] calldata lpTokens, uint256[] calldata pwTokenAmount ) external; /// @notice Delegates the Power Tokens an stakes lpTokens in LiquidityMining. /// @dev Power Token amounts can equal zero. lpToken amounts can equal zero. /// @param account account address delegating its Power Tokens and staking lpTokens in LiquidityMining /// @param lpTokens list of the lpToken addresses to which Power Tokens are delegated /// @param pwTokenAmounts list of the Power Token amounts delegated , represented with 18 decimals /// @param lpTokenAmounts list of the lpToken amounts to be staked in liquidityMining, represented with 18 decimals function delegatePwTokenAndStakeLpToken( address account, address[] calldata lpTokens, uint256[] calldata pwTokenAmounts, uint256[] calldata lpTokenAmounts ) external; /// @notice Undelegates the Power Tokens from the LiquidityMining /// @dev Power Token amounts can equal zero. /// @param account address undelegating Power Tokens /// @param lpTokens list of the lpTokens reprenseting staking pools from which to undelegate Power Tokens /// @param pwTokenAmounts list of the amounts of Power Tokens to be undelegated, represented with 18 decimals function undelegatePwToken( address account, address[] calldata lpTokens, uint256[] calldata pwTokenAmounts ) external; /// @notice Sets the global configuration indicator - rewardsPerBlock for a given lpToken /// @param lpToken address for which to setup `rewards per block` /// @param pwTokenAmount amount of the `rewards per block`, denominated in Power Token, represented with 8 decimals function setRewardsPerBlock(address lpToken, uint32 pwTokenAmount) external; /// @notice Adds LiquidityMining's support for a new lpToken /// @dev Can only be executed by the Owner /// @param lpToken address of the lpToken function addLpToken(address lpToken) external; /// @notice Removes lpToken from the list of tokens supported by the LiquidityMining contract /// @dev Can be executed only by the Owner. Note! That when lpToken is removed, the rewards cannot be claimed. To restore claiming, run function {addLpToken()} and {setRewardsPerBlock()} /// @param lpToken address of the lpToken function removeLpToken(address lpToken) external; /// @notice Sets the new Pause Manager address /// @param newPauseManagerAddr - new address of Pause Manager function setPauseManager(address newPauseManagerAddr) external; /// @notice Pauses current smart contract, it can only be executed by the Owner /// @dev Emits {Paused} event. function pause() external; /// @notice Unpauses current smart contract, it can only be executed by the Owner /// @dev Emits {Unpaused}. function unpause() external; /// @notice Emitted when the account unstakes lpTokens /// @param account account unstaking tokens /// @param lpToken address of lpToken being unstaked /// @param lpTokenAmount of lpTokens to unstake, represented with 18 decimals event LpTokensUnstaked(address account, address lpToken, uint256 lpTokenAmount); /// @notice Emitted when the LiquidityMining's Owner changes the `rewards per block` /// @param changedBy address of account executing changes /// @param oldPwTokenAmount old value of `rewards per block`, denominated in Power Token, represented in 8 decimals /// @param newPwTokenAmount new value of `rewards per block`, denominated in Power Token, represented in 8 decimals event RewardsPerBlockChanged( address indexed changedBy, uint256 oldPwTokenAmount, uint256 newPwTokenAmount ); /// @notice Emitted when the LiquidityMining's Owner adds support for lpToken /// @param account address of LiquidityMining's Owner /// @param lpToken address of newly supported lpToken event LpTokenAdded(address account, address lpToken); /// @notice Emitted when the LiquidityMining's Owner removes ssupport for lpToken /// @param account address of LiquidityMining's Owner /// @param lpToken address of dropped lpToken event LpTokenRemoved(address account, address lpToken); /// @notice Emitted when the account delegates Power Tokens to the LiquidityMining /// @param account performing delegation /// @param lpToken address of lpToken to which Power Token are delegated /// @param pwTokenAmount amount of Power Tokens delegated, represented with 18 decimals event PwTokenDelegated(address account, address lpToken, uint256 pwTokenAmount); /// @notice Emitted when the account delegates Power Tokens and stakes lpTokens to the LiquidityMining /// @param account account delegating Power Tokens and staking lpTokens /// @param lpToken address of lpToken staked /// @param pwTokenAmount of Power Token delegated, represented with 18 decimals /// @param lpTokenAmount of lpTokens to stake, represented with 18 decimals event PwTokenDelegatedAndLpTokenStaked( address account, address lpToken, uint256 pwTokenAmount, uint256 lpTokenAmount ); /// @notice Emitted when the account undelegates Power Tokens from the LiquidityMining /// @param account undelegating /// @param lpToken address of lpToken /// @param pwTokenAmount amount of Power Token undelegated, represented with 18 decimals event PwTokenUndelegated(address account, address lpToken, uint256 pwTokenAmount); /// @notice Emitted when the PauseManager's address is changed by its owner. /// @param changedBy account address that has changed LiquidityMining's address /// @param oldPauseManager PauseManager's old address /// @param newPauseManager PauseManager's new address event PauseManagerChanged( address indexed changedBy, address indexed oldPauseManager, address indexed newPauseManager ); } // File: contracts/interfaces/ILiquidityMining.sol pragma solidity 0.8.17; /// @title The interface for interaction with the LiquidityMining. /// LiquidityMining is responsible for the distribution of the Power Token rewards to accounts /// staking lpTokens and / or delegating Power Tokens to LiquidityMining. LpTokens can be staked directly to the LiquidityMining, /// Power Tokens are a staked version of the [Staked] Tokens minted by the PowerToken smart contract. interface ILiquidityMining { /// @notice Contract ID. The keccak-256 hash of "io.ipor.LiquidityMining" decreased by 1 /// @return Returns an ID of the contract function getContractId() external pure returns (bytes32); /// @notice Returns the balance of staked lpTokens /// @param account the account's address /// @param lpToken the address of lpToken /// @return balance of the lpTokens staked by the sender function balanceOf(address account, address lpToken) external view returns (uint256); /// @notice It returns the balance of delegated Power Tokens for a given `account` and the list of lpToken addresses. /// @param account address for which to fetch the information about balance of delegated Power Tokens /// @param lpTokens list of lpTokens addresses(lpTokens) /// @return balances list of {LiquidityMiningTypes.DelegatedPwTokenBalance} structure, with information how much Power Token is delegated per lpToken address. function balanceOfDelegatedPwToken(address account, address[] memory lpTokens) external view returns (LiquidityMiningTypes.DelegatedPwTokenBalance[] memory balances); /// @notice Gets the account's allocated rewards /// @param account The address for which to fetch information about balance of allocated Power Tokens /// @return allocatedPwTokens - The amount of the allocated rewards. function balanceOfAllocatedPwTokens(address account) external view returns (uint256 allocatedPwTokens); /// @notice Calculates the accrued rewards since the last rebalancing. /// @param lpToken the lpToken address /// @return rewards accrued since the last rebalancing, represented with 18 decimals. function calculateAccruedRewards(address lpToken) external view returns (uint256); /// @notice Calculates account's rewards based on the current state of the sender and global indicators. /// @dev Calculation does not consider rewards accrued for the current block /// @param account address for which the rewards are calculated /// @param lpToken address for which the rewards are calculated /// @return Sender's rewards, represented with 18 decimals. function calculateAccountRewards(address account, address lpToken) external view returns (uint256); /// @notice Stakes the lpToken amount into the LiquidityMining. /// @param lpToken address of the lpToken /// @param lpTokenAmount lpToken amount being staked, represented with 18 decimals function stake(address lpToken, uint256 lpTokenAmount) external; /// @notice Unstakes the lpToken amount from the LiquidityMining. /// @param lpToken address of the underlying asset /// @param lpTokenAmount lpToken amount being unstaked, represented with 18 decimals function unstake(address lpToken, uint256 lpTokenAmount) external; /// @notice Unstakes the lpToken amount from LiquidityMining and allocates the rewards into storage. /// This function can be used in the situation, when the are not enough rewards to cover claim and where /// regular unstake of lpTokens would not be possible. /// @param lpToken address of the underlying asset /// @param lpTokenAmount lpToken amount being unstaked, represented with 18 decimals function unstakeAndAllocatePwTokens(address lpToken, uint256 lpTokenAmount) external; /// @notice method allowing to claim the rewards per asset (lpToken) /// @param lpToken of the staking pool from which to claim the rewards function claim(address lpToken) external; /// @notice method allowed to claim the allocated rewards function claimAllocatedPwTokens() external; /// @notice method allowing to update the indicators per asset (lpToken). /// @param account of which we should update the indicators /// @param lpTokens of the staking pools to update the indicators function updateIndicators(address account, address[] calldata lpTokens) external; /// @notice Emitted when the account stakes the lpTokens /// @param account Account's address in the context of which the activities of staking of lpTokens are performed /// @param lpToken address of lpToken being staked /// @param lpTokenAmount of lpTokens to stake, represented with 18 decimals event LpTokensStaked(address account, address lpToken, uint256 lpTokenAmount); /// @notice Emitted when the account claims the rewards /// @param account Account's address in the context of which activities of claiming are performed /// @param lpToken The address of the lpToken /// @param rewardsAmount Reward amount denominated in pwToken, represented with 18 decimals event Claimed(address account, address lpToken, uint256 rewardsAmount); /// @notice Emitted when the account claims the allocated rewards /// @param account Account address in the context of which activities of claiming are performed /// @param allocatedRewards Reward amount denominated in pwToken, represented in 18 decimals event AllocatedTokensClaimed(address account, uint256 allocatedRewards); /// @notice Emitted when update was triggered for the account on the lpToken /// @param account Account address to which the update was triggered /// @param lpToken lpToken address to which the update was triggered event IndicatorsUpdated(address account, address lpToken); } // File: contracts/mining/LiquidityMiningInternal.sol pragma solidity 0.8.17; abstract contract LiquidityMiningInternal is Initializable, PausableUpgradeable, UUPSUpgradeable, MiningOwnableUpgradeable, ReentrancyGuardUpgradeable, ILiquidityMiningInternal { using SafeCast for uint256; using SafeCast for int256; bytes32 internal constant _STAKED_TOKEN_ID = 0xdba05ed67d0251facfcab8345f27ccd3e72b5a1da8cebfabbcccf4316e6d053c; bytes32 internal constant _POWER_TOKEN_ID = 0xbd22bf01cb7daed462db61de31bb111aabcdae27adc748450fb9a9ea1c419cce; address internal _powerToken; address internal _pauseManager; mapping(address => bool) internal _lpTokens; mapping(address => uint256) internal _allocatedPwTokens; mapping(address => LiquidityMiningTypes.GlobalRewardsIndicators) internal _globalIndicators; // account address => lpToken address => account params mapping(address => mapping(address => LiquidityMiningTypes.AccountRewardsIndicators)) internal _accountIndicators; modifier onlyPowerToken() { require(_msgSender() == _getPowerToken(), Errors.CALLER_NOT_POWER_TOKEN); _; } modifier onlyPauseManager() { require(_msgSender() == _pauseManager, Errors.CALLER_NOT_PAUSE_MANAGER); _; } /// @custom:oz-upgrades-unsafe-allow constructor constructor() { _disableInitializers(); } function initialize( address[] calldata lpTokens, address powerToken, address stakedToken ) public initializer { __Pausable_init_unchained(); __Ownable_init_unchained(); __UUPSUpgradeable_init_unchained(); require(powerToken != address(0), Errors.WRONG_ADDRESS); require( IPowerToken(powerToken).getContractId() == _POWER_TOKEN_ID, Errors.WRONG_CONTRACT_ID ); require(stakedToken != address(0), Errors.WRONG_ADDRESS); require( IStakedToken(stakedToken).getContractId() == _STAKED_TOKEN_ID, Errors.WRONG_CONTRACT_ID ); uint256 lpTokensLength = lpTokens.length; _powerToken = powerToken; _pauseManager = _msgSender(); IStakedToken(stakedToken).approve(powerToken, Constants.MAX_VALUE); for (uint256 i; i != lpTokensLength; ++i) { require(lpTokens[i] != address(0), Errors.WRONG_ADDRESS); _lpTokens[lpTokens[i]] = true; _globalIndicators[lpTokens[i]] = LiquidityMiningTypes.GlobalRewardsIndicators( 0, 0, 0, 0, 0, 0 ); } } function getVersion() external pure override returns (uint256) { return 3; } function getPauseManager() external view override returns (address) { return _pauseManager; } function isLpTokenSupported(address lpToken) external view override returns (bool) { return _lpTokens[lpToken]; } function getGlobalIndicators(address lpToken) external view override returns (LiquidityMiningTypes.GlobalRewardsIndicators memory) { return _globalIndicators[lpToken]; } function getAccountIndicators(address account, address lpToken) external view override returns (LiquidityMiningTypes.AccountRewardsIndicators memory) { return _accountIndicators[account][lpToken]; } function delegatePwToken( address account, address[] calldata lpTokens, uint256[] calldata pwTokenAmounts ) external override onlyPowerToken whenNotPaused { uint256 rewards; uint256 lpTokensLength = lpTokens.length; uint256 rewardsIteration; uint256 accruedCompMultiplierCumulativePrevBlock; LiquidityMiningTypes.AccountRewardsIndicators memory accountIndicators; LiquidityMiningTypes.GlobalRewardsIndicators memory globalIndicators; for (uint256 i; i != lpTokensLength; ++i) { require(_lpTokens[lpTokens[i]], Errors.LP_TOKEN_NOT_SUPPORTED); accountIndicators = _accountIndicators[account][lpTokens[i]]; globalIndicators = _globalIndicators[lpTokens[i]]; /// @dev when account not stake any IP Token then calculation rewards and rebalancing is redundant if (accountIndicators.lpTokenBalance == 0) { uint256 newBalance = accountIndicators.delegatedPwTokenBalance + pwTokenAmounts[i]; _accountIndicators[account][lpTokens[i]].delegatedPwTokenBalance = newBalance .toUint96(); emit PwTokenDelegated(account, lpTokens[i], pwTokenAmounts[i]); continue; } (rewardsIteration, accruedCompMultiplierCumulativePrevBlock) = _calculateAccountRewards( globalIndicators, accountIndicators ); rewards += rewardsIteration; _rebalanceIndicators( account, lpTokens[i], accruedCompMultiplierCumulativePrevBlock, globalIndicators, accountIndicators, accountIndicators.lpTokenBalance, accountIndicators.delegatedPwTokenBalance + pwTokenAmounts[i] ); emit PwTokenDelegated(account, lpTokens[i], pwTokenAmounts[i]); } if (rewards > 0) { _transferRewardsToPowerToken(account, rewards); } } function delegatePwTokenAndStakeLpToken( address account, address[] calldata lpTokens, uint256[] calldata pwTokenAmounts, uint256[] calldata lpTokenAmounts ) external override onlyPowerToken whenNotPaused { uint256 rewards; uint256 lpTokenAmount; uint256 pwTokenAmount; for (uint256 i; i != lpTokens.length; ++i) { require(_lpTokens[lpTokens[i]], Errors.LP_TOKEN_NOT_SUPPORTED); lpTokenAmount = lpTokenAmounts[i]; pwTokenAmount = pwTokenAmounts[i]; LiquidityMiningTypes.AccountRewardsIndicators memory accountIndicators = _accountIndicators[account][lpTokens[i]]; LiquidityMiningTypes.GlobalRewardsIndicators memory globalIndicators = _globalIndicators[lpTokens[i]]; /// @dev Order is important! First Stake, then Delegate. /// @dev Stake if (lpTokenAmount > 0) { IERC20Upgradeable(lpTokens[i]).transferFrom(account, address(this), lpTokenAmount); } /// @dev Delegate if (accountIndicators.lpTokenBalance == 0 && lpTokenAmount == 0) { _accountIndicators[account][lpTokens[i]] .delegatedPwTokenBalance = (accountIndicators.delegatedPwTokenBalance + pwTokenAmount).toUint96(); emit PwTokenDelegated(account, lpTokens[i], pwTokenAmount); continue; } ( uint256 rewardsIteration, uint256 accruedCompMultiplierCumulativePrevBlock ) = _calculateAccountRewards(globalIndicators, accountIndicators); rewards += rewardsIteration; _rebalanceIndicators( account, lpTokens[i], accruedCompMultiplierCumulativePrevBlock, globalIndicators, accountIndicators, accountIndicators.lpTokenBalance + lpTokenAmount, accountIndicators.delegatedPwTokenBalance + pwTokenAmount ); emit PwTokenDelegatedAndLpTokenStaked( account, lpTokens[i], pwTokenAmount, lpTokenAmount ); } if (rewards > 0) { _transferRewardsToPowerToken(account, rewards); } } function undelegatePwToken( address account, address[] calldata lpTokens, uint256[] calldata pwTokenAmounts ) external onlyPowerToken whenNotPaused { uint256 rewards; uint256 lpTokensLength = lpTokens.length; uint256 rewardsIteration; uint256 accruedCompMultiplierCumulativePrevBlock; LiquidityMiningTypes.AccountRewardsIndicators memory accountIndicators; LiquidityMiningTypes.GlobalRewardsIndicators memory globalIndicators; for (uint256 i; i != lpTokensLength; ++i) { require(_lpTokens[lpTokens[i]], Errors.LP_TOKEN_NOT_SUPPORTED); accountIndicators = _accountIndicators[account][lpTokens[i]]; require( accountIndicators.delegatedPwTokenBalance >= pwTokenAmounts[i], Errors.ACC_DELEGATED_TO_LIQUIDITY_MINING_BALANCE_IS_TOO_LOW ); globalIndicators = _globalIndicators[lpTokens[i]]; (rewardsIteration, accruedCompMultiplierCumulativePrevBlock) = _calculateAccountRewards( globalIndicators, accountIndicators ); rewards += rewardsIteration; _rebalanceIndicators( account, lpTokens[i], accruedCompMultiplierCumulativePrevBlock, globalIndicators, accountIndicators, accountIndicators.lpTokenBalance, accountIndicators.delegatedPwTokenBalance - pwTokenAmounts[i] ); emit PwTokenUndelegated(account, lpTokens[i], pwTokenAmounts[i]); } if (rewards > 0) { _transferRewardsToPowerToken(account, rewards); } } function setRewardsPerBlock(address lpToken, uint32 pwTokenAmount) external override onlyOwner { _setRewardsPerBlock(lpToken, pwTokenAmount); } function addLpToken(address lpToken) external onlyOwner { require(lpToken != address(0), Errors.WRONG_ADDRESS); _lpTokens[lpToken] = true; emit LpTokenAdded(_msgSender(), lpToken); } function removeLpToken(address lpToken) external override onlyOwner { require(lpToken != address(0), Errors.WRONG_ADDRESS); _setRewardsPerBlock(lpToken, 0); _lpTokens[lpToken] = false; emit LpTokenRemoved(_msgSender(), lpToken); } function setPauseManager(address newPauseManagerAddr) external override onlyOwner { require(newPauseManagerAddr != address(0), Errors.WRONG_ADDRESS); address oldPauseManagerAddr = _pauseManager; _pauseManager = newPauseManagerAddr; emit PauseManagerChanged(_msgSender(), oldPauseManagerAddr, newPauseManagerAddr); } function pause() external override onlyPauseManager { _pause(); } function unpause() external override onlyPauseManager { _unpause(); } function _unstake( address lpToken, uint256 lpTokenAmount, bool claimRewards ) internal { require(lpTokenAmount > 0, Errors.VALUE_NOT_GREATER_THAN_ZERO); address msgSender = _msgSender(); LiquidityMiningTypes.AccountRewardsIndicators memory accountIndicators = _accountIndicators[ msgSender ][lpToken]; require( accountIndicators.lpTokenBalance >= lpTokenAmount, Errors.ACCOUNT_LP_TOKEN_BALANCE_IS_TOO_LOW ); LiquidityMiningTypes.GlobalRewardsIndicators memory globalIndicators = _globalIndicators[ lpToken ]; ( uint256 rewardsAmount, uint256 accruedCompMultiplierCumulativePrevBlock ) = _calculateAccountRewards(globalIndicators, accountIndicators); _rebalanceIndicators( msgSender, lpToken, accruedCompMultiplierCumulativePrevBlock, globalIndicators, accountIndicators, accountIndicators.lpTokenBalance - lpTokenAmount, accountIndicators.delegatedPwTokenBalance ); if (rewardsAmount > 0) { if (claimRewards) { _transferRewardsToPowerToken(msgSender, rewardsAmount); } else { _allocatedPwTokens[msgSender] += rewardsAmount; } } IERC20Upgradeable(lpToken).transfer(msgSender, lpTokenAmount); emit LpTokensUnstaked(msgSender, lpToken, lpTokenAmount); } /// @dev Rebalance makes that rewards for account are reset in current block. function _rebalanceIndicators( address account, address lpToken, uint256 accruedCompMultiplierCumulativePrevBlock, LiquidityMiningTypes.GlobalRewardsIndicators memory globalIndicators, LiquidityMiningTypes.AccountRewardsIndicators memory accountIndicators, uint256 lpTokenBalance, uint256 delegatedPwTokenBalance ) internal { uint256 accountPowerUp = MiningCalculation.calculateAccountPowerUp( delegatedPwTokenBalance, lpTokenBalance, _getVerticalShift(), _getHorizontalShift() ); _accountIndicators[account][lpToken] = LiquidityMiningTypes.AccountRewardsIndicators( accruedCompMultiplierCumulativePrevBlock.toUint128(), lpTokenBalance.toUint128(), accountPowerUp.toUint72(), delegatedPwTokenBalance.toUint96() ); uint256 aggregatedPowerUp = MiningCalculation.calculateAggregatedPowerUp( accountPowerUp, lpTokenBalance, accountIndicators.powerUp, accountIndicators.lpTokenBalance, globalIndicators.aggregatedPowerUp ); uint256 accruedRewards; /// @dev check if we should update rewards, it should happened when at least one account stakes lpTokens if (globalIndicators.aggregatedPowerUp == 0) { accruedRewards = globalIndicators.accruedRewards; } else { accruedRewards = MiningCalculation.calculateAccruedRewards( block.number, globalIndicators.blockNumber, globalIndicators.rewardsPerBlock, globalIndicators.accruedRewards ); } uint256 compositeMultiplier = MiningCalculation.calculateCompositeMultiplier( globalIndicators.rewardsPerBlock, aggregatedPowerUp ); _globalIndicators[lpToken] = LiquidityMiningTypes.GlobalRewardsIndicators( aggregatedPowerUp, compositeMultiplier.toUint128(), accruedCompMultiplierCumulativePrevBlock.toUint128(), block.number.toUint32(), globalIndicators.rewardsPerBlock, accruedRewards.toUint88() ); } function _calculateAccountRewards( LiquidityMiningTypes.GlobalRewardsIndicators memory globalIndicators, LiquidityMiningTypes.AccountRewardsIndicators memory accountIndicators ) internal view returns (uint256 rewardsAmount, uint256 accruedCompMultiplierCumulativePrevBlock) { accruedCompMultiplierCumulativePrevBlock = MiningCalculation .calculateAccruedCompMultiplierCumulativePrevBlock( block.number, globalIndicators.blockNumber, globalIndicators.compositeMultiplierInTheBlock, globalIndicators.compositeMultiplierCumulativePrevBlock ); rewardsAmount = MiningCalculation.calculateAccountRewards( accountIndicators.lpTokenBalance, accountIndicators.powerUp, accountIndicators.compositeMultiplierCumulativePrevBlock, accruedCompMultiplierCumulativePrevBlock ); } function _setRewardsPerBlock(address lpToken, uint32 pwTokenAmount) internal { require(_lpTokens[lpToken], Errors.LP_TOKEN_NOT_SUPPORTED); LiquidityMiningTypes.GlobalRewardsIndicators memory globalIndicators = _globalIndicators[ lpToken ]; uint256 blockNumber = block.number; uint256 accruedCompositeMultiplierCumulativePrevBlock = MiningCalculation .calculateAccruedCompMultiplierCumulativePrevBlock( blockNumber, globalIndicators.blockNumber, globalIndicators.compositeMultiplierInTheBlock, globalIndicators.compositeMultiplierCumulativePrevBlock ); uint256 accruedRewards; if (globalIndicators.aggregatedPowerUp != 0) { accruedRewards = MiningCalculation.calculateAccruedRewards( blockNumber.toUint32(), globalIndicators.blockNumber, globalIndicators.rewardsPerBlock, globalIndicators.accruedRewards ); } else { accruedRewards = globalIndicators.accruedRewards; } uint256 compositeMultiplier = MiningCalculation.calculateCompositeMultiplier( pwTokenAmount, globalIndicators.aggregatedPowerUp ); _globalIndicators[lpToken] = LiquidityMiningTypes.GlobalRewardsIndicators( globalIndicators.aggregatedPowerUp, compositeMultiplier.toUint128(), accruedCompositeMultiplierCumulativePrevBlock.toUint128(), blockNumber.toUint32(), pwTokenAmount, accruedRewards.toUint88() ); emit RewardsPerBlockChanged(_msgSender(), globalIndicators.rewardsPerBlock, pwTokenAmount); } /// @dev Claim not changes Internal Exchange Rate of Power Tokens in PowerToken smart contract. function _transferRewardsToPowerToken(address account, uint256 rewardsAmount) internal { IPowerTokenInternal(_getPowerToken()).receiveRewardsFromLiquidityMining( account, rewardsAmount ); } /// @notice Gets Horizontal shift param used in Liquidity Mining equations. /// @dev To pre-calculate this value from uint256, use {MiningCalculation._toQuadruplePrecision()} method. /// @dev 0.5 = ABDKMathQuad.div(ABDKMathQuad.fromUInt(5), ABDKMathQuad.fromUInt(10)) /// @dev Notice! uint256 value before calculation has the following constraints: 0.5 <= Horizontal Shift <= 10^3 /// @return horizontal shift - value represented in bytes16, quadruple precision, 128 bits, it takes into consideration 18 decimals function _getHorizontalShift() internal pure virtual returns (bytes16) { return 0x3ffe0000000000000000000000000000; } /// @notice Gets vertical shift param used in Liquidity Mining equations. /// @dev To pre-calculate this value from uint256, use {MiningCalculation._toQuadruplePrecision()} method. /// @dev 1.4 = ABDKMathQuad.div(ABDKMathQuad.fromUInt(14), ABDKMathQuad.fromUInt(10)) /// @dev Notice! uint256 value before calculation has the following constraints: 10^(-4) <= Vertical Shift <= 3 /// @return vertical shift - value represented in bytes16, quadruple precision, 128 bits, it takes into consideration 18 decimals function _getVerticalShift() internal pure virtual returns (bytes16) { return 0x3fff6666666666666666666666666666; } function _getPowerToken() internal view returns (address) { return _powerToken; } //solhint-disable no-empty-blocks function _authorizeUpgrade(address) internal override onlyOwner {} } // File: contracts/mining/LiquidityMining.sol pragma solidity 0.8.17; /// @title Smart contract responsible for distribution of Power Token rewards across accounts contributing to Liquidity Mining /// by staking lpTokens and / or delegating Power Tokens. contract LiquidityMining is LiquidityMiningInternal, ILiquidityMining { using SafeCast for uint256; using SafeCast for int256; function getContractId() external pure returns (bytes32) { return 0x9b1f3aa590476fc9aa58d44ad1419ab53d34c344bd5ed46b12e4af7d27c38e06; } function balanceOf(address account, address lpToken) external view override returns (uint256) { return _accountIndicators[account][lpToken].lpTokenBalance; } function balanceOfDelegatedPwToken(address account, address[] calldata lpTokens) external view override returns (LiquidityMiningTypes.DelegatedPwTokenBalance[] memory balances) { uint256 lpTokensLength = lpTokens.length; balances = new LiquidityMiningTypes.DelegatedPwTokenBalance[](lpTokensLength); address lpToken; for (uint256 i; i != lpTokensLength; ++i) { lpToken = lpTokens[i]; require(_lpTokens[lpToken], Errors.LP_TOKEN_NOT_SUPPORTED); balances[i] = LiquidityMiningTypes.DelegatedPwTokenBalance( lpToken, _accountIndicators[account][lpToken].delegatedPwTokenBalance ); } } function balanceOfAllocatedPwTokens(address account) external view returns (uint256 allocatedPwTokens) { allocatedPwTokens = _allocatedPwTokens[account]; } function calculateAccruedRewards(address lpToken) external view override returns (uint256) { LiquidityMiningTypes.GlobalRewardsIndicators memory globalIndicators = _globalIndicators[ lpToken ]; if (globalIndicators.aggregatedPowerUp == 0) { return globalIndicators.accruedRewards; } return MiningCalculation.calculateAccruedRewards( block.number, globalIndicators.blockNumber, globalIndicators.rewardsPerBlock, globalIndicators.accruedRewards ); } function calculateAccountRewards(address account, address lpToken) external view override returns (uint256) { LiquidityMiningTypes.GlobalRewardsIndicators memory globalIndicators = _globalIndicators[ lpToken ]; LiquidityMiningTypes.AccountRewardsIndicators memory accountIndicators = _accountIndicators[ account ][lpToken]; (uint256 rewardsAmount, ) = _calculateAccountRewards(globalIndicators, accountIndicators); return rewardsAmount; } function updateIndicators(address account, address[] calldata lpTokens) external override nonReentrant whenNotPaused{ require(account != address(0), Errors.WRONG_ADDRESS); uint256 lpTokensLength = lpTokens.length; uint256 rewardsAmountToTransfer; for (uint256 i; i != lpTokensLength; ++i) { address lpToken = lpTokens[i]; LiquidityMiningTypes.AccountRewardsIndicators memory accountIndicators = _accountIndicators[account][lpToken]; LiquidityMiningTypes.GlobalRewardsIndicators memory globalIndicators = _globalIndicators[lpToken]; if (accountIndicators.lpTokenBalance == 0) { continue; } ( uint256 rewardsAmount, uint256 accruedCompMultiplierCumulativePrevBlock ) = _calculateAccountRewards(globalIndicators, accountIndicators); rewardsAmountToTransfer += rewardsAmount; _rebalanceIndicators( account, lpToken, accruedCompMultiplierCumulativePrevBlock, globalIndicators, accountIndicators, accountIndicators.lpTokenBalance, accountIndicators.delegatedPwTokenBalance ); emit IndicatorsUpdated(account, lpToken); } if (rewardsAmountToTransfer > 0) { _transferRewardsToPowerToken(account, rewardsAmountToTransfer); } } function stake(address lpToken, uint256 lpTokenAmount) external override nonReentrant whenNotPaused { require(lpTokenAmount > 0, Errors.VALUE_NOT_GREATER_THAN_ZERO); require(_lpTokens[lpToken], Errors.LP_TOKEN_NOT_SUPPORTED); address msgSender = _msgSender(); IERC20Upgradeable(lpToken).transferFrom(msgSender, address(this), lpTokenAmount); LiquidityMiningTypes.AccountRewardsIndicators memory accountIndicators = _accountIndicators[ msgSender ][lpToken]; LiquidityMiningTypes.GlobalRewardsIndicators memory globalIndicators = _globalIndicators[ lpToken ]; ( uint256 rewardsAmount, uint256 accruedCompMultiplierCumulativePrevBlock ) = _calculateAccountRewards(globalIndicators, accountIndicators); _rebalanceIndicators( msgSender, lpToken, accruedCompMultiplierCumulativePrevBlock, globalIndicators, accountIndicators, accountIndicators.lpTokenBalance + lpTokenAmount, accountIndicators.delegatedPwTokenBalance ); if (rewardsAmount > 0) { _transferRewardsToPowerToken(msgSender, rewardsAmount); } emit LpTokensStaked(msgSender, lpToken, lpTokenAmount); } function unstake(address lpToken, uint256 lpTokenAmount) external override nonReentrant whenNotPaused { _unstake(lpToken, lpTokenAmount, true); } function unstakeAndAllocatePwTokens(address lpToken, uint256 lpTokenAmount) external override nonReentrant whenNotPaused { _unstake(lpToken, lpTokenAmount, false); } function claim(address lpToken) external override whenNotPaused nonReentrant { address msgSender = _msgSender(); LiquidityMiningTypes.AccountRewardsIndicators memory accountIndicators = _accountIndicators[ msgSender ][lpToken]; LiquidityMiningTypes.GlobalRewardsIndicators memory globalIndicators = _globalIndicators[ lpToken ]; ( uint256 rewardsAmount, uint256 accruedCompMultiplierCumulativePrevBlock ) = _calculateAccountRewards(globalIndicators, accountIndicators); require(rewardsAmount > 0, Errors.NO_REWARDS_TO_CLAIM); _accountIndicators[msgSender][lpToken] = LiquidityMiningTypes.AccountRewardsIndicators( accruedCompMultiplierCumulativePrevBlock.toUint128(), accountIndicators.lpTokenBalance, accountIndicators.powerUp, accountIndicators.delegatedPwTokenBalance ); _transferRewardsToPowerToken(msgSender, rewardsAmount); emit Claimed(msgSender, lpToken, rewardsAmount); } function claimAllocatedPwTokens() external override whenNotPaused nonReentrant { address msgSender = _msgSender(); uint256 allocatedRewards = _allocatedPwTokens[msgSender]; require(allocatedRewards > 0, Errors.NO_REWARDS_TO_CLAIM); _allocatedPwTokens[msgSender] = 0; _transferRewardsToPowerToken(msgSender, allocatedRewards); emit AllocatedTokensClaimed(msgSender, allocatedRewards); } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"previousAdmin","type":"address"},{"indexed":false,"internalType":"address","name":"newAdmin","type":"address"}],"name":"AdminChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"allocatedRewards","type":"uint256"}],"name":"AllocatedTokensClaimed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"appointedOwner","type":"address"}],"name":"AppointedToTransferOwnership","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"beacon","type":"address"}],"name":"BeaconUpgraded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"address","name":"lpToken","type":"address"},{"indexed":false,"internalType":"uint256","name":"rewardsAmount","type":"uint256"}],"name":"Claimed","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"address","name":"lpToken","type":"address"}],"name":"IndicatorsUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint8","name":"version","type":"uint8"}],"name":"Initialized","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"address","name":"lpToken","type":"address"}],"name":"LpTokenAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"address","name":"lpToken","type":"address"}],"name":"LpTokenRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"address","name":"lpToken","type":"address"},{"indexed":false,"internalType":"uint256","name":"lpTokenAmount","type":"uint256"}],"name":"LpTokensStaked","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"address","name":"lpToken","type":"address"},{"indexed":false,"internalType":"uint256","name":"lpTokenAmount","type":"uint256"}],"name":"LpTokensUnstaked","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":"changedBy","type":"address"},{"indexed":true,"internalType":"address","name":"oldPauseManager","type":"address"},{"indexed":true,"internalType":"address","name":"newPauseManager","type":"address"}],"name":"PauseManagerChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"address","name":"lpToken","type":"address"},{"indexed":false,"internalType":"uint256","name":"pwTokenAmount","type":"uint256"}],"name":"PwTokenDelegated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"address","name":"lpToken","type":"address"},{"indexed":false,"internalType":"uint256","name":"pwTokenAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"lpTokenAmount","type":"uint256"}],"name":"PwTokenDelegatedAndLpTokenStaked","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"address","name":"lpToken","type":"address"},{"indexed":false,"internalType":"uint256","name":"pwTokenAmount","type":"uint256"}],"name":"PwTokenUndelegated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"changedBy","type":"address"},{"indexed":false,"internalType":"uint256","name":"oldPwTokenAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newPwTokenAmount","type":"uint256"}],"name":"RewardsPerBlockChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"implementation","type":"address"}],"name":"Upgraded","type":"event"},{"inputs":[{"internalType":"address","name":"lpToken","type":"address"}],"name":"addLpToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"address","name":"lpToken","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOfAllocatedPwTokens","outputs":[{"internalType":"uint256","name":"allocatedPwTokens","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"address[]","name":"lpTokens","type":"address[]"}],"name":"balanceOfDelegatedPwToken","outputs":[{"components":[{"internalType":"address","name":"lpToken","type":"address"},{"internalType":"uint256","name":"pwTokenAmount","type":"uint256"}],"internalType":"struct LiquidityMiningTypes.DelegatedPwTokenBalance[]","name":"balances","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"address","name":"lpToken","type":"address"}],"name":"calculateAccountRewards","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"lpToken","type":"address"}],"name":"calculateAccruedRewards","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"lpToken","type":"address"}],"name":"claim","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"claimAllocatedPwTokens","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"confirmTransferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"address[]","name":"lpTokens","type":"address[]"},{"internalType":"uint256[]","name":"pwTokenAmounts","type":"uint256[]"}],"name":"delegatePwToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"address[]","name":"lpTokens","type":"address[]"},{"internalType":"uint256[]","name":"pwTokenAmounts","type":"uint256[]"},{"internalType":"uint256[]","name":"lpTokenAmounts","type":"uint256[]"}],"name":"delegatePwTokenAndStakeLpToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"address","name":"lpToken","type":"address"}],"name":"getAccountIndicators","outputs":[{"components":[{"internalType":"uint128","name":"compositeMultiplierCumulativePrevBlock","type":"uint128"},{"internalType":"uint128","name":"lpTokenBalance","type":"uint128"},{"internalType":"uint72","name":"powerUp","type":"uint72"},{"internalType":"uint96","name":"delegatedPwTokenBalance","type":"uint96"}],"internalType":"struct LiquidityMiningTypes.AccountRewardsIndicators","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getContractId","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"lpToken","type":"address"}],"name":"getGlobalIndicators","outputs":[{"components":[{"internalType":"uint256","name":"aggregatedPowerUp","type":"uint256"},{"internalType":"uint128","name":"compositeMultiplierInTheBlock","type":"uint128"},{"internalType":"uint128","name":"compositeMultiplierCumulativePrevBlock","type":"uint128"},{"internalType":"uint32","name":"blockNumber","type":"uint32"},{"internalType":"uint32","name":"rewardsPerBlock","type":"uint32"},{"internalType":"uint88","name":"accruedRewards","type":"uint88"}],"internalType":"struct LiquidityMiningTypes.GlobalRewardsIndicators","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getPauseManager","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getVersion","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address[]","name":"lpTokens","type":"address[]"},{"internalType":"address","name":"powerToken","type":"address"},{"internalType":"address","name":"stakedToken","type":"address"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"lpToken","type":"address"}],"name":"isLpTokenSupported","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"proxiableUUID","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"lpToken","type":"address"}],"name":"removeLpToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newPauseManagerAddr","type":"address"}],"name":"setPauseManager","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"lpToken","type":"address"},{"internalType":"uint32","name":"pwTokenAmount","type":"uint32"}],"name":"setRewardsPerBlock","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"lpToken","type":"address"},{"internalType":"uint256","name":"lpTokenAmount","type":"uint256"}],"name":"stake","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"appointedOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"address[]","name":"lpTokens","type":"address[]"},{"internalType":"uint256[]","name":"pwTokenAmounts","type":"uint256[]"}],"name":"undelegatePwToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"unpause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"lpToken","type":"address"},{"internalType":"uint256","name":"lpTokenAmount","type":"uint256"}],"name":"unstake","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"lpToken","type":"address"},{"internalType":"uint256","name":"lpTokenAmount","type":"uint256"}],"name":"unstakeAndAllocatePwTokens","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"address[]","name":"lpTokens","type":"address[]"}],"name":"updateIndicators","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"}]
Contract Creation Code
60a0604052306080523480156200001557600080fd5b506200002062000026565b620000e8565b600054610100900460ff1615620000935760405162461bcd60e51b815260206004820152602760248201527f496e697469616c697a61626c653a20636f6e747261637420697320696e697469604482015266616c697a696e6760c81b606482015260840160405180910390fd5b60005460ff9081161015620000e6576000805460ff191660ff9081179091556040519081527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b565b608051615f2c6200012060003960008181610d6301528181610de801528181611436015281816114bb01526115a50152615f2c6000f3fe6080604052600436106102035760003560e01c8063658d9b5911610118578063b2cbc4b1116100a0578063cf4858b71161006f578063cf4858b7146107ec578063ef46e36b1461080c578063f2fde38b14610843578063f7888aec14610863578063fbb0b2b9146108ba57600080fd5b8063b2cbc4b114610777578063bbda182a14610797578063c2a672e0146107b7578063cc29516a146107d757600080fd5b80638456cb59116100e75780638456cb59146106e4578063890d4112146106f95780638da5cb5b1461071957806390482d7214610737578063adc9772e1461075757600080fd5b8063658d9b591461065a5780636a1c1e0414610687578063715018a61461069c578063769b81d6146106b157600080fd5b80633f4ba83a1161019b5780634f1ef2861161016a5780634f1ef286146105da57806352d1902d146105ed578063585d59f2146106025780635c975abb1461062257806364e57e421461063a57600080fd5b80633f4ba83a146105525780633f6e5394146105675780634788cabf146105875780634c1b9260146105ba57600080fd5b80631e9322c4116101d75780631e9322c4146102b75780632fafc3a4146103fd57806335a5ef711461041d5780633659cfe61461053257600080fd5b806214fde0146102085780630d8e6e2c1461025757806319092d9b146102755780631e83409a14610297575b600080fd5b34801561021457600080fd5b50610242610223366004615855565b6001600160a01b03166000908152610130602052604090205460ff1690565b60405190151581526020015b60405180910390f35b34801561026357600080fd5b5060035b60405190815260200161024e565b34801561028157600080fd5b50610295610290366004615855565b6108da565b005b3480156102a357600080fd5b506102956102b2366004615855565b6109a4565b3480156102c357600080fd5b5061038d6102d2366004615855565b6040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a0810191909152506001600160a01b031660009081526101326020908152604091829020825160c0810184528154815260018201546001600160801b0380821694830194909452600160801b90049092169282019290925260029091015463ffffffff8082166060840152600160201b8204166080830152600160401b90046001600160581b031660a082015290565b60405161024e9190600060c0820190508251825260208301516001600160801b0380821660208501528060408601511660408501525050606083015163ffffffff808216606085015280608086015116608085015250506001600160581b0360a08401511660a083015292915050565b34801561040957600080fd5b50610267610418366004615870565b610c55565b34801561042957600080fd5b506104db610438366004615870565b604080516080810182526000808252602082018190529181018290526060810191909152506001600160a01b03918216600090815261013360209081526040808320939094168252918252829020825160808101845281546001600160801b038082168352600160801b9091041692810192909252600101546001600160481b03811692820192909252600160481b9091046001600160601b0316606082015290565b60405161024e919060006080820190506001600160801b03808451168352806020850151166020840152506001600160481b0360408401511660408301526001600160601b03606084015116606083015292915050565b34801561053e57600080fd5b5061029561054d366004615855565b610d59565b34801561055e57600080fd5b50610295610ed4565b34801561057357600080fd5b506102956105823660046158ef565b610f34565b34801561059357600080fd5b507f9b1f3aa590476fc9aa58d44ad1419ab53d34c344bd5ed46b12e4af7d27c38e06610267565b3480156105c657600080fd5b506102956105d5366004615855565b611393565b6102956105e8366004615986565b61142c565b3480156105f957600080fd5b50610267611598565b34801561060e57600080fd5b5061026761061d366004615855565b61165d565b34801561062e57600080fd5b5060335460ff16610242565b34801561064657600080fd5b50610295610655366004615a48565b61172f565b34801561066657600080fd5b5061067a610675366004615a88565b611741565b60405161024e9190615adb565b34801561069357600080fd5b506102956118c0565b3480156106a857600080fd5b506102956119ce565b3480156106bd57600080fd5b5061012f546001600160a01b03165b6040516001600160a01b03909116815260200161024e565b3480156106f057600080fd5b506102956119f2565b34801561070557600080fd5b50610295610714366004615855565b611a50565b34801561072557600080fd5b5060c9546001600160a01b03166106cc565b34801561074357600080fd5b50610295610752366004615b33565b611b00565b34801561076357600080fd5b50610295610772366004615b98565b6120c8565b34801561078357600080fd5b506102956107923660046158ef565b6123c8565b3480156107a357600080fd5b506102956107b2366004615b98565b612913565b3480156107c357600080fd5b506102956107d2366004615b98565b612975565b3480156107e357600080fd5b506102956129ce565b3480156107f857600080fd5b50610295610807366004615bc2565b612a31565b34801561081857600080fd5b50610267610827366004615855565b6001600160a01b03166000908152610131602052604090205490565b34801561084f57600080fd5b5061029561085e366004615855565b612fcd565b34801561086f57600080fd5b5061026761087e366004615870565b6001600160a01b03918216600090815261013360209081526040808320939094168252919091522054600160801b90046001600160801b031690565b3480156108c657600080fd5b506102956108d5366004615a88565b613064565b6108e26132e8565b60408051808201909152600681526550545f37313560d01b60208201526001600160a01b03821661092f5760405162461bcd60e51b81526004016109269190615c91565b60405180910390fd5b5061093b816000613342565b6001600160a01b038116600090815261013060205260409020805460ff191690557f0ab1da102cf1f21b42dd087a1a4bd108313e4371052dffbc8445feba939209e3335b604080516001600160a01b03928316815291841660208301520160405180910390a150565b6109ac613634565b600260fc54036109ec5760405162461bcd60e51b815260206004820152601f6024820152600080516020615eb08339815191526044820152606401610926565b600260fc819055336000818152610133602090815260408083206001600160a01b03871680855290835281842082516080808201855282546001600160801b038082168452600160801b918290048116848901526001948501546001600160481b03811685890152600160481b90046001600160601b03166060808601919091529589526101328852868920875160c0810189528154815295810154808316998701999099529190970490961694830194909452939096015463ffffffff80821692880192909252600160201b810490911691860191909152600160401b90046001600160581b031660a085015291929080610ae8838561367a565b91509150600082116040518060400160405280600681526020016550545f37303960d01b81525090610b2d5760405162461bcd60e51b81526004016109269190615c91565b506040518060800160405280610b42836136eb565b6001600160801b0390811682526020878101518216818401526040808901516001600160481b03908116828601526060808b01516001600160601b03908116968201969096526001600160a01b03808d1660009081526101338652848120918f1681529085528390208751948801518616600160801b029490951693909317845590850151600190930180549590920151909316600160481b026001600160a81b03199094169190921617919091179055610bfd8583613758565b604080516001600160a01b038088168252881660208201529081018390527ff7a40077ff7a04c7e61f6f26fb13774259ddf1b6bce9ecf26a8276cdd39926839060600160405180910390a15050600160fc5550505050565b6001600160a01b03818116600081815261013260209081526040808320815160c081018352815481526001808301546001600160801b0380821684880152600160801b9182900481168487015260029094015463ffffffff808216606080870191909152600160201b8304909116608080870191909152600160401b9092046001600160581b031660a0860152998c16885261013387528588209888529786528487208551988901865280548086168a5291909104909316948701949094529201546001600160481b03811691850191909152600160481b90046001600160601b031693830193909352919082610d4c838361367a565b5093505050505b92915050565b6001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000163003610de65760405162461bcd60e51b815260206004820152602c60248201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060448201526b19195b1959d85d1958d85b1b60a21b6064820152608401610926565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316610e417f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc546001600160a01b031690565b6001600160a01b031614610eac5760405162461bcd60e51b815260206004820152602c60248201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060448201526b6163746976652070726f787960a01b6064820152608401610926565b610eb5816137cd565b60408051600080825260208201909252610ed1918391906137d5565b50565b61012f546001600160a01b0316336001600160a01b03161460405180604001604052806006815260200165141517cdcc0d60d21b81525090610f295760405162461bcd60e51b81526004016109269190615c91565b50610f32613957565b565b61012e54604080518082019091526006815265282a2f9b981960d11b6020820152906001600160a01b03163314610f7e5760405162461bcd60e51b81526004016109269190615c91565b50610f87613634565b6000838180610fb660408051608081018252600080825260208201819052918101829052606081019190915290565b6040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a08101829052905b8581146113755761013060008c8c8481811061100757611007615cc4565b905060200201602081019061101c9190615855565b6001600160a01b031681526020808201929092526040908101600020548151808301909252600682526550545f37303160d01b928201929092529060ff166110775760405162461bcd60e51b81526004016109269190615c91565b506001600160a01b038c16600090815261013360205260408120908c8c848181106110a4576110a4615cc4565b90506020020160208101906110b99190615855565b6001600160a01b031681526020808201929092526040908101600020815160808101835281546001600160801b038082168352600160801b9091041693810193909352600101546001600160481b03811691830191909152600160481b90046001600160601b03166060820152925088888281811061113a5761113a615cc4565b9050602002013583606001516001600160601b031610156040518060400160405280600681526020016550545f37303760d01b8152509061118e5760405162461bcd60e51b81526004016109269190615c91565b5061013260008c8c848181106111a6576111a6615cc4565b90506020020160208101906111bb9190615855565b6001600160a01b031681526020808201929092526040908101600020815160c0810183528154815260018201546001600160801b0380821695830195909552600160801b9004909316918301919091526002015463ffffffff8082166060840152600160201b8204166080830152600160401b90046001600160581b031660a0820152915061124a828461367a565b90955093506112598588615cf0565b96506112cd8c8c8c8481811061127157611271615cc4565b90506020020160208101906112869190615855565b86858788602001516001600160801b03168f8f898181106112a9576112a9615cc4565b905060200201358a606001516001600160601b03166112c89190615d03565b6139a9565b7f72ec23c86fe9e1a03ff3b69e7b455294b2581e363068c3d0e3ebf9b8c0fc736d8c8c8c8481811061130157611301615cc4565b90506020020160208101906113169190615855565b8b8b8581811061132857611328615cc4565b9050602002013560405161135d939291906001600160a01b039384168152919092166020820152604081019190915260600190565b60405180910390a161136e81615d16565b9050610fe9565b508515611386576113868b87613758565b5050505050505050505050565b61139b6132e8565b60408051808201909152600681526550545f37313560d01b60208201526001600160a01b0382166113df5760405162461bcd60e51b81526004016109269190615c91565b506001600160a01b038116600090815261013060205260409020805460ff191660011790557fa926f0878fdfbb99f575a83ab27b540cfa259857dd4da469b62ddff8905ebbac61097f3390565b6001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001630036114b95760405162461bcd60e51b815260206004820152602c60248201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060448201526b19195b1959d85d1958d85b1b60a21b6064820152608401610926565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166115147f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc546001600160a01b031690565b6001600160a01b03161461157f5760405162461bcd60e51b815260206004820152602c60248201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060448201526b6163746976652070726f787960a01b6064820152608401610926565b611588826137cd565b611594828260016137d5565b5050565b6000306001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146116385760405162461bcd60e51b815260206004820152603860248201527f555550535570677261646561626c653a206d757374206e6f742062652063616c60448201527f6c6564207468726f7567682064656c656761746563616c6c00000000000000006064820152608401610926565b507f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc90565b6001600160a01b038116600090815261013260209081526040808320815160c081018352815480825260018301546001600160801b0380821696840196909652600160801b9004909416928101929092526002015463ffffffff8082166060840152600160201b8204166080830152600160401b90046001600160581b031660a08201529082036116fb5760a001516001600160581b031692915050565b61172843826060015163ffffffff16836080015163ffffffff168460a001516001600160581b0316613c6d565b9392505050565b6117376132e8565b6115948282613342565b6060818067ffffffffffffffff81111561175d5761175d615970565b6040519080825280602002602001820160405280156117a257816020015b604080518082019091526000808252602082015281526020019060019003908161177b5790505b5091506000805b8281146118b6578585828181106117c2576117c2615cc4565b90506020020160208101906117d79190615855565b6001600160a01b03811660009081526101306020908152604091829020548251808401909352600683526550545f37303160d01b918301919091529193509060ff166118365760405162461bcd60e51b81526004016109269190615c91565b506040805180820182526001600160a01b03848116808352908a16600090815261013360209081528482209282529182529290922060010154600160481b90046001600160601b031691810191909152845185908390811061189a5761189a615cc4565b6020026020010181905250806118af90615d16565b90506117a9565b5050509392505050565b6118c8613634565b600260fc54036119085760405162461bcd60e51b815260206004820152601f6024820152600080516020615eb08339815191526044820152606401610926565b600260fc553360008181526101316020908152604091829020548251808401909352600683526550545f37303960d01b91830191909152908161195e5760405162461bcd60e51b81526004016109269190615c91565b506001600160a01b038216600090815261013160205260408120556119838282613758565b604080516001600160a01b0384168152602081018390527f54f95fe3d28f3e3aa8d8aecf94ed3edfe8a58ba281943414440d9fb92ce9646c910160405180910390a15050600160fc55565b6119d66132e8565b6119e06000613cf0565b60fb80546001600160a01b0319169055565b61012f546001600160a01b0316336001600160a01b03161460405180604001604052806006815260200165141517cdcc0d60d21b81525090611a475760405162461bcd60e51b81526004016109269190615c91565b50610f32613d42565b611a586132e8565b60408051808201909152600681526550545f37313560d01b60208201526001600160a01b038216611a9c5760405162461bcd60e51b81526004016109269190615c91565b5061012f80546001600160a01b038381166001600160a01b031983168117909355169081611ac73390565b6001600160a01b03167fb1f2133e27463d1f096faf22e79896b5ebbf2d047633dc7451139a1fe14854a960405160405180910390a45050565b600054610100900460ff1615808015611b205750600054600160ff909116105b80611b3a5750303b158015611b3a575060005460ff166001145b611b9d5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401610926565b6000805460ff191660011790558015611bc0576000805461ff0019166101001790555b611bc8613d7f565b611bd0613db2565b611bd8613de2565b60408051808201909152600681526550545f37313560d01b60208201526001600160a01b038416611c1c5760405162461bcd60e51b81526004016109269190615c91565b507fbd22bf01cb7daed462db61de31bb111aabcdae27adc748450fb9a9ea1c419cce60001b836001600160a01b0316634788cabf6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611c7f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ca39190615d2f565b1460405180604001604052806006815260200165282a2f9b989b60d11b81525090611ce15760405162461bcd60e51b81526004016109269190615c91565b5060408051808201909152600681526550545f37313560d01b60208201526001600160a01b038316611d265760405162461bcd60e51b81526004016109269190615c91565b507fdba05ed67d0251facfcab8345f27ccd3e72b5a1da8cebfabbcccf4316e6d053c60001b826001600160a01b0316634788cabf6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611d89573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611dad9190615d2f565b1460405180604001604052806006815260200165282a2f9b989b60d11b81525090611deb5760405162461bcd60e51b81526004016109269190615c91565b5061012e80546001600160a01b0319166001600160a01b038516179055833361012f80546001600160a01b0319166001600160a01b0392831617905560405163095ea7b360e01b8152858216600482015260001960248201529084169063095ea7b3906044016020604051808303816000875af1158015611e70573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e949190615d48565b5060005b818114612079576000878783818110611eb357611eb3615cc4565b9050602002016020810190611ec89190615855565b6001600160a01b031614156040518060400160405280600681526020016550545f37313560d01b81525090611f105760405162461bcd60e51b81526004016109269190615c91565b5060016101306000898985818110611f2a57611f2a615cc4565b9050602002016020810190611f3f9190615855565b6001600160a01b0316815260208082019290925260409081016000908120805460ff191694151594909417909355805160c0810182528381529182018390528101829052606081018290526080810182905260a081018290529061013290898985818110611faf57611faf615cc4565b9050602002016020810190611fc49190615855565b6001600160a01b0316815260208082019290925260409081016000208351815591830151908301516001600160801b03908116600160801b029116176001820155606082015160029091018054608084015160a0909401516001600160581b0316600160401b026affffffffffffffffffffff60401b1963ffffffff958616600160201b0267ffffffffffffffff199093169590941694909417179190911691909117905561207281615d16565b9050611e98565b505080156120c1576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b5050505050565b600260fc54036121085760405162461bcd60e51b815260206004820152601f6024820152600080516020615eb08339815191526044820152606401610926565b600260fc55612115613634565b60408051808201909152600681526550545f37313760d01b6020820152816121505760405162461bcd60e51b81526004016109269190615c91565b506001600160a01b03821660009081526101306020908152604091829020548251808401909352600683526550545f37303160d01b9183019190915260ff166121ac5760405162461bcd60e51b81526004016109269190615c91565b506000336040516323b872dd60e01b81526001600160a01b03808316600483015230602483015260448201859052919250908416906323b872dd906064016020604051808303816000875af1158015612209573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061222d9190615d48565b506001600160a01b0381811660009081526101336020908152604080832093871680845293825280832081516080808201845282546001600160801b038082168452600160801b918290048116848801526001948501546001600160481b03811685880152600160481b90046001600160601b03166060808601919091529888526101328752858820865160c081018852815481529581015480831698870198909852919096049095169383019390935260029093015463ffffffff80821696830196909652600160201b810490951691810191909152600160401b9093046001600160581b031660a0840152919080612327838561367a565b9150915061235f85888386888b8a602001516001600160801b031661234c9190615cf0565b8a606001516001600160601b03166139a9565b811561236f5761236f8583613758565b604080516001600160a01b038088168252891660208201529081018790527f0be61a5ceba15cd4c9c5deacde2110b0c5be6390bf9b3ee49aa96149b14543bc9060600160405180910390a15050600160fc555050505050565b61012e54604080518082019091526006815265282a2f9b981960d11b6020820152906001600160a01b031633146124125760405162461bcd60e51b81526004016109269190615c91565b5061241b613634565b600083818061244a60408051608081018252600080825260208201819052918101829052606081019190915290565b6040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a08101829052905b8581146113755761013060008c8c8481811061249b5761249b615cc4565b90506020020160208101906124b09190615855565b6001600160a01b031681526020808201929092526040908101600020548151808301909252600682526550545f37303160d01b928201929092529060ff1661250b5760405162461bcd60e51b81526004016109269190615c91565b506001600160a01b038c16600090815261013360205260408120908c8c8481811061253857612538615cc4565b905060200201602081019061254d9190615855565b6001600160a01b0316815260208082019290925260409081016000908120825160808101845281546001600160801b038082168352600160801b9091041694810194909452600101546001600160481b03811692840192909252600160481b9091046001600160601b03166060830152909350610132908c8c848181106125d6576125d6615cc4565b90506020020160208101906125eb9190615855565b6001600160a01b0316815260208082019290925260409081016000908120825160c0810184528154815260018201546001600160801b0380821683880152600160801b90910481169482019490945260029091015463ffffffff8082166060840152600160201b8204166080830152600160401b90046001600160581b031660a082015292860151929450911690036127e257600089898381811061269257612692615cc4565b9050602002013584606001516001600160601b03166126b19190615cf0565b90506126bc81613e09565b6001600160a01b038e16600090815261013360205260408120908e8e868181106126e8576126e8615cc4565b90506020020160208101906126fd9190615855565b6001600160a01b03166001600160a01b0316815260200190815260200160002060010160096101000a8154816001600160601b0302191690836001600160601b031602179055507f013627584e1896036670d60cab043cb12b9c822553ef971d0ca270c2857172fd8d8d8d8581811061277857612778615cc4565b905060200201602081019061278d9190615855565b8c8c8681811061279f5761279f615cc4565b905060200201356040516127d4939291906001600160a01b039384168152919092166020820152604081019190915260600190565b60405180910390a150612903565b6127ec828461367a565b90955093506127fb8588615cf0565b965061286a8c8c8c8481811061281357612813615cc4565b90506020020160208101906128289190615855565b86858788602001516001600160801b03168f8f8981811061284b5761284b615cc4565b905060200201358a606001516001600160601b03166112c89190615cf0565b7f013627584e1896036670d60cab043cb12b9c822553ef971d0ca270c2857172fd8c8c8c8481811061289e5761289e615cc4565b90506020020160208101906128b39190615855565b8b8b858181106128c5576128c5615cc4565b905060200201356040516128fa939291906001600160a01b039384168152919092166020820152604081019190915260600190565b60405180910390a15b61290c81615d16565b905061247d565b600260fc54036129535760405162461bcd60e51b815260206004820152601f6024820152600080516020615eb08339815191526044820152606401610926565b600260fc55612960613634565b61296c82826000613e71565b5050600160fc55565b600260fc54036129b55760405162461bcd60e51b815260206004820152601f6024820152600080516020615eb08339815191526044820152606401610926565b600260fc556129c2613634565b61296c82826001613e71565b60fb5460408051808201909152600681526550545f37313960d01b6020820152906001600160a01b03163314612a175760405162461bcd60e51b81526004016109269190615c91565b5060fb80546001600160a01b0319169055610f3233613cf0565b61012e54604080518082019091526006815265282a2f9b981960d11b6020820152906001600160a01b03163314612a7b5760405162461bcd60e51b81526004016109269190615c91565b50612a84613634565b6000806000805b808914612fb05761013060008b8b84818110612aa957612aa9615cc4565b9050602002016020810190612abe9190615855565b6001600160a01b031681526020808201929092526040908101600020548151808301909252600682526550545f37303160d01b928201929092529060ff16612b195760405162461bcd60e51b81526004016109269190615c91565b50858582818110612b2c57612b2c615cc4565b905060200201359250878782818110612b4757612b47615cc4565b6001600160a01b038e1660009081526101336020908152604082209202939093013594509050818c8c85818110612b8057612b80615cc4565b9050602002016020810190612b959190615855565b6001600160a01b0316815260208082019290925260409081016000908120825160808101845281546001600160801b038082168352600160801b9091041694810194909452600101546001600160481b03811692840192909252600160481b9091046001600160601b03166060830152909150610132818d8d86818110612c1e57612c1e615cc4565b9050602002016020810190612c339190615855565b6001600160a01b031681526020808201929092526040908101600020815160c0810183528154815260018201546001600160801b0380821695830195909552600160801b9004909316918301919091526002015463ffffffff8082166060840152600160201b8204166080830152600160401b90046001600160581b031660a082015290508415612d62578b8b84818110612cd057612cd0615cc4565b9050602002016020810190612ce59190615855565b6040516323b872dd60e01b81526001600160a01b038f811660048301523060248301526044820188905291909116906323b872dd906064016020604051808303816000875af1158015612d3c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d609190615d48565b505b60208201516001600160801b0316158015612d7b575084155b15612ea357612da18483606001516001600160601b0316612d9c9190615cf0565b613e09565b6001600160a01b038e16600090815261013360205260408120908e8e87818110612dcd57612dcd615cc4565b9050602002016020810190612de29190615855565b6001600160a01b03166001600160a01b0316815260200190815260200160002060010160096101000a8154816001600160601b0302191690836001600160601b031602179055507f013627584e1896036670d60cab043cb12b9c822553ef971d0ca270c2857172fd8d8d8d86818110612e5d57612e5d615cc4565b9050602002016020810190612e729190615855565b604080516001600160a01b039384168152929091166020830152810186905260600160405180910390a15050612fa0565b600080612eb0838561367a565b9092509050612ebf8289615cf0565b9750612f218f8f8f88818110612ed757612ed7615cc4565b9050602002016020810190612eec9190615855565b8386888c8a602001516001600160801b0316612f089190615cf0565b8c8b606001516001600160601b03166112c89190615cf0565b7ff0aaf972c9efcbddb73d7f97f05a673d7b2dcec839804b6f0839e88ed311e0b78f8f8f88818110612f5557612f55615cc4565b9050602002016020810190612f6a9190615855565b604080516001600160a01b03938416815292909116602083015281018890526060810189905260800160405180910390a1505050505b612fa981615d16565b9050612a8b565b508215612fc157612fc18a84613758565b50505050505050505050565b612fd56132e8565b60408051808201909152600681526550545f37313560d01b60208201526001600160a01b0382166130195760405162461bcd60e51b81526004016109269190615c91565b5060fb80546001600160a01b0319166001600160a01b0383169081179091556040517f3ec7bb1d452f3c36260fa8ef678a597fd97574d8ec42f6dc98ffce3dbc91228f90600090a250565b600260fc54036130a45760405162461bcd60e51b815260206004820152601f6024820152600080516020615eb08339815191526044820152606401610926565b600260fc556130b1613634565b60408051808201909152600681526550545f37313560d01b60208201526001600160a01b0384166130f55760405162461bcd60e51b81526004016109269190615c91565b50806000805b8281146132cb57600085858381811061311657613116615cc4565b905060200201602081019061312b9190615855565b6001600160a01b0388811660009081526101336020908152604080832093851680845293825280832081516080808201845282546001600160801b038082168452600160801b9182900481168488019081526001958601546001600160481b03811686890152600160481b90046001600160601b03166060808701919091529989526101328852868920875160c081018952815481529681015480841699880199909952929097048116958501959095526002015463ffffffff80821698850198909852600160201b810490971690830152600160401b9095046001600160581b031660a082015291519495509293909216900361322b575050506132bb565b600080613238838561367a565b90925090506132478288615cf0565b96506132728b8683868889602001516001600160801b03168a606001516001600160601b03166139a9565b604080516001600160a01b03808e168252871660208201527f510f627c13e7683adbb7033a1b06b83397772c9f84460303cb7f18d17fdec4bd910160405180910390a150505050505b6132c481615d16565b90506130fb565b5080156132dc576132dc8582613758565b5050600160fc55505050565b60c9546001600160a01b03163314610f325760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610926565b6001600160a01b03821660009081526101306020908152604091829020548251808401909352600683526550545f37303160d01b9183019190915260ff1661339d5760405162461bcd60e51b81526004016109269190615c91565b506001600160a01b038216600090815261013260209081526040808320815160c0810183528154815260018201546001600160801b03808216958301869052600160801b9091041692810183905260029091015463ffffffff80821660608401819052600160201b83049091166080840152600160401b9091046001600160581b031660a08301529093439390926134389285929091614129565b8351909150600090156134875761348061345184614153565b63ffffffff16856060015163ffffffff16866080015163ffffffff168760a001516001600160581b0316613c6d565b9050613497565b5060a08301516001600160581b03165b60006134ad8663ffffffff1686600001516141b8565b90506040518060c00160405280866000015181526020016134cd836136eb565b6001600160801b031681526020016134e4856136eb565b6001600160801b031681526020016134fb86614153565b63ffffffff1681526020018763ffffffff16815260200161351b846141f8565b6001600160581b039081169091526001600160a01b038916600090815261013260209081526040918290208451815590840151918401516001600160801b03908116600160801b029216919091176001820155606083015160029091018054608085015160a090950151909316600160401b026affffffffffffffffffffff60401b1963ffffffff958616600160201b0267ffffffffffffffff19909516959093169490941792909217169190911790556135d33390565b6001600160a01b03167fa92f31ffdefd5f39fe3e8b400639a2a60d1080fcd995d093dac1af68091e50ae86608001518860405161362392919063ffffffff92831681529116602082015260400190565b60405180910390a250505050505050565b60335460ff1615610f325760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b6044820152606401610926565b6000806136ad43856060015163ffffffff1686602001516001600160801b031687604001516001600160801b0316614129565b90506136e283602001516001600160801b031684604001516001600160481b031685600001516001600160801b031684614260565b91509250929050565b60006001600160801b038211156137545760405162461bcd60e51b815260206004820152602760248201527f53616665436173743a2076616c756520646f65736e27742066697420696e20316044820152663238206269747360c81b6064820152608401610926565b5090565b61012e546001600160a01b031660405163ec3c87c960e01b81526001600160a01b03848116600483015260248201849052919091169063ec3c87c990604401600060405180830381600087803b1580156137b157600080fd5b505af11580156137c5573d6000803e3d6000fd5b505050505050565b610ed16132e8565b7f4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd91435460ff161561380d57613808836142e3565b505050565b826001600160a01b03166352d1902d6040518163ffffffff1660e01b8152600401602060405180830381865afa925050508015613867575060408051601f3d908101601f1916820190925261386491810190615d2f565b60015b6138ca5760405162461bcd60e51b815260206004820152602e60248201527f45524331393637557067726164653a206e657720696d706c656d656e7461746960448201526d6f6e206973206e6f74205555505360901b6064820152608401610926565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc811461394b5760405162461bcd60e51b815260206004820152602960248201527f45524331393637557067726164653a20756e737570706f727465642070726f786044820152681a58589b195555525160ba1b6064820152608401610926565b50613808838383614391565b61395f6143bc565b6033805460ff191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa335b6040516001600160a01b03909116815260200160405180910390a1565b60006139cf82846f1fffb33333333333333333333333333360811b611fff60f11b61440e565b905060405180608001604052806139e5886136eb565b6001600160801b031681526020016139fc856136eb565b6001600160801b03168152602001613a1383614512565b6001600160481b03168152602001613a2a84613e09565b6001600160601b039081169091526001600160a01b03808b16600090815261013360209081526040808320938d1683529281528282208551868301516001600160801b03908116600160801b029181169190911782558685015160019092018054606090980151909616600160481b026001600160a81b03199097166001600160481b039283161796909617909455918801519188015189519194613ad99487948a949116929091169061457a565b905060008660000151600003613afd575060a08601516001600160581b0316613b2d565b613b2a43886060015163ffffffff16896080015163ffffffff168a60a001516001600160581b0316613c6d565b90505b6000613b43886080015163ffffffff16846141b8565b90506040518060c00160405280848152602001613b5f836136eb565b6001600160801b03168152602001613b768b6136eb565b6001600160801b03168152602001613b8d43614153565b63ffffffff168152602001896080015163ffffffff168152602001613bb1846141f8565b6001600160581b039081169091526001600160a01b03909b16600090815261013260209081526040918290208351815590830151918301516001600160801b03908116600160801b029216919091176001820155606082015160029091018054608084015160a090940151909d16600160401b026affffffffffffffffffffff60401b1963ffffffff948516600160201b0267ffffffffffffffff19909f1694909316939093179c909c17161790995550505050505050505050565b60008385101560405180604001604052806006815260200165282a2f9b989960d11b81525090613cb05760405162461bcd60e51b81526004016109269190615c91565b5060006402540be40084613cc48789615d03565b613cce9190615d6a565b613cd89190615d6a565b9050613ce48184615cf0565b9150505b949350505050565b60c980546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b613d4a613634565b6033805460ff191660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a25861398c3390565b600054610100900460ff16613da65760405162461bcd60e51b815260040161092690615d81565b6033805460ff19169055565b600054610100900460ff16613dd95760405162461bcd60e51b815260040161092690615d81565b610f3233613cf0565b600054610100900460ff16610f325760405162461bcd60e51b815260040161092690615d81565b60006001600160601b038211156137545760405162461bcd60e51b815260206004820152602660248201527f53616665436173743a2076616c756520646f65736e27742066697420696e203960448201526536206269747360d01b6064820152608401610926565b60408051808201909152600681526550545f37313760d01b602082015282613eac5760405162461bcd60e51b81526004016109269190615c91565b50336000818152610133602090815260408083206001600160a01b0388168452825291829020825160808101845281546001600160801b038082168352600160801b909104168184018190526001909201546001600160481b03811682860152600160481b90046001600160601b0316606082015283518085019094526006845265282a2f9b981b60d11b92840192909252909190851115613f615760405162461bcd60e51b81526004016109269190615c91565b506001600160a01b038516600090815261013260209081526040808320815160c0810183528154815260018201546001600160801b0380821695830195909552600160801b9004909316918301919091526002015463ffffffff8082166060840152600160201b8204166080830152600160401b90046001600160581b031660a08201529080613ff1838561367a565b9150915061401685898386888c8a602001516001600160801b031661234c9190615d03565b81156140605785156140315761402c8583613758565b614060565b6001600160a01b038516600090815261013160205260408120805484929061405a908490615cf0565b90915550505b60405163a9059cbb60e01b81526001600160a01b0386811660048301526024820189905289169063a9059cbb906044016020604051808303816000875af11580156140af573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906140d39190615d48565b50604080516001600160a01b0380881682528a1660208201529081018890527f820d19e507b9188a561dd1270049c35fd21a7289cdbf5230d13ba5b42609d7dc9060600160405180910390a15050505050505050565b6000826141368587615d03565b6141409190615d6a565b61414a9083615cf0565b95945050505050565b600063ffffffff8211156137545760405162461bcd60e51b815260206004820152602660248201527f53616665436173743a2076616c756520646f65736e27742066697420696e203360448201526532206269747360d01b6064820152608401610926565b6000816000036141ca57506000610d53565b611728678ac7230489e800006141e8670de0b6b3a764000086615d6a565b6141f29190615d6a565b836146a6565b60006001600160581b038211156137545760405162461bcd60e51b815260206004820152602660248201527f53616665436173743a2076616c756520646f65736e27742066697420696e203860448201526538206269747360d01b6064820152608401610926565b6000828210156040518060400160405280600681526020016550545f37313360d01b815250906142a35760405162461bcd60e51b81526004016109269190615c91565b5060006142b08484615d03565b6142ba8688615d6a565b6142c49190615d6a565b9050613ce481722cd76fe086b93ce2f768a00b22a000000000006146a6565b6001600160a01b0381163b6143505760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b6064820152608401610926565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc80546001600160a01b0319166001600160a01b0392909216919091179055565b61439a836146c8565b6000825111806143a75750805b15613808576143b68383614708565b50505050565b60335460ff16610f325760405162461bcd60e51b815260206004820152601460248201527f5061757361626c653a206e6f74207061757365640000000000000000000000006044820152606401610926565b6000670de0b6b3a764000084101561442857506000613ce8565b600061443c86670de0b6b3a76400006147f3565b9050600061445286670de0b6b3a76400006147f3565b905060006144608383614844565b90506000806144826f3ffa9999999999999be7e553d3e20f0d60801b84614b2b565b60000b1261449a5761449382614c62565b90506144dd565b60006144ad6144a7614dc6565b86614dd7565b905060006144c46144be8387614844565b89615040565b90506144d8896144d38361540a565b615040565b925050505b60006144f9826144f4670de0b6b3a76400006155c2565b614dd7565b905061450481615629565b9a9950505050505050505050565b60006001600160481b038211156137545760405162461bcd60e51b815260206004820152602660248201527f53616665436173743a2076616c756520646f65736e27742066697420696e203760448201526532206269747360d01b6064820152608401610926565b600080614586846156ac565b61458f866156ac565b6145999190615dcc565b6145a2876156ac565b6145ab896156ac565b6145b59190615dcc565b6145bf9190615dfc565b905060008082121561466d5760006145ef6145e16145dc85615e23565b615716565b670de0b6b3a76400006146a6565b9050808510801561460b57508061460886612710615cf0565b10155b1561461c576000935050505061414a565b60408051808201909152600681526550545f37313160d01b60208201528186101561465a5760405162461bcd60e51b81526004016109269190615c91565b506146658186615d03565b915050614686565b6146796145e183615716565b6146839085615cf0565b90505b61271081101561469b5760009250505061414a565b979650505050505050565b6000816146b4600282615e55565b6146be9085615cf0565b6117289190615e55565b6146d1816142e3565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b60606001600160a01b0383163b6147705760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6044820152651b9d1c9858dd60d21b6064820152608401610926565b600080846001600160a01b03168460405161478b9190615e69565b600060405180830381855af49150503d80600081146147c6576040519150601f19603f3d011682016040523d82523d6000602084013e6147cb565b606091505b509150915061414a8282604051806060016040528060278152602001615ed060279139615768565b6000806148008385615e85565b111561481457614811600184615cf0565b92505b600061481f846155c2565b9050600061482c846155c2565b9050600061483a8383614844565b9695505050505050565b6000617fff60f084811c8216919084901c8116908290036148895780617fff03614878575061ffff60ef1b9150610d539050565b505050600160ff1b81168218610d53565b80617fff036148cc576dffffffffffffffffffffffffffff60801b8416156148bb575061ffff60ef1b9150610d539050565b505050808218600160ff1b16610d53565b600160801b600160ff1b03841660000361491c57600160801b600160ff1b038516600003614904575061ffff60ef1b9150610d539050565b505050808218600160ff1b16617fff60f01b17610d53565b6001600160701b03608085901c16600082900361493c5760019150614943565b600160701b175b6001600160701b03608087901c16600084900361498657801561498157600061496b826157a1565b6001955060e20393840160711901939190911b90505b614990565b600160701b1760721b5b81818161499f5761499f615e3f565b049050806000036149cf57600160ff1b878718166149be5760006149c4565b600160ff1b5b945050505050610d53565b6d10000000000000000000000000008110156149ed576149ed615e99565b60006e080000000000000000000000000000821015614a42576e040000000000000000000000000000821015614a3757600160711b821015614a30576070614a3a565b6071614a3a565b60725b60ff16614a4b565b614a4b826157a1565b905083614071018186011115614a6957617fff945060009150614afc565b83818601613ffc011015614a84576000945060009150614afc565b83818601613f8c011015614ad1578385613ffc011115614aaf578385613ffc010382901b9150614ac8565b8385613ffc011015614ac857613ffc8585030382901c91505b60009450614afc565b6070811115614ae4576070810382901c91505b6001600160701b038216915083818601613f8d010394505b81607086901b888a186001607f1b60801b1660801c6001600160801b0316171760801b95505050505050610d53565b60006f7fffffffffffffffffffffffffffffff608084901c16617fff60701b811115614b5657600080fd5b6f7fffffffffffffffffffffffffffffff608084901c16617fff60701b811115614b7f57600080fd5b6001600160801b0319858116908516141580614ba85750617fff60701b826001600160801b0316105b614bb157600080fd5b6001600160801b031980851690861603614bd057600092505050610d53565b6001607f1b608086811c82118015929187901c919091101590614c21578015614c1357826001600160801b0316846001600160801b031611614c135760016149c4565b600019945050505050610d53565b8015614c34576001945050505050610d53565b826001600160801b0316846001600160801b031611614c55576000196149c4565b6001945050505050610d53565b600080614c826f3ff847ae147ae147b74da9ca30cfea4b60801b84614b2b565b60000b1315614cb257610d536f1ffe4ccccccccccccd1696441415db7b60811b6144d36201000960ee1b85614dd7565b6000614cd16f3ff947ae147ae147b2b11255bc3eff6360801b84614b2b565b60000b1315614d0057610d536f1ffe851eb851eb851edd36a728c33fa960811b6144d361400160f01b85614dd7565b6000614d1f6f01ffcf5c28f5c28f5c4dda7e3300b04d60851b84614b2b565b60000b1315614d4e57610d536f1ffe8f5c28f5c28f5c4dda7e3300b04d60811b6144d361800160ef1b85614dd7565b6000614d6d6f1ffd23d70a3d70a3d831634dc0fb44f760811b84614b2b565b60000b1315614d9b57610d536f3ffd3d70a3d70a3d70eda08184b9b28560801b6144d3600160fe1b85614dd7565b610d536f0fff59999999999999ac0bf76b6bdd4560821b6144d3613fff60f01b85614dd7565b919050565b6000614dd260026155c2565b905090565b6000617fff60f084811c8216919084901c811690829003614e765780617fff03614e52576001600160801b031980851690861603614e2057505050600160ff1b81168218610d53565b6001600160801b031985851816600160ff1b03614e4257505050818117610d53565b5061ffff60ef1b9150610d539050565b600160801b600160ff1b038416600003614878575061ffff60ef1b9150610d539050565b80617fff03614eb457600160801b600160ff1b038516600003614ea3575061ffff60ef1b9150610d539050565b505050600160ff1b82168118610d53565b6001600160701b03608086901c166000839003614ed45760019250614edb565b600160701b175b6001600160701b03608086901c166000839003614efb5760019250614f02565b600160701b175b808202915081600003614f2357600160ff1b878718166149be5760006149c4565b928201926000600160e11b831015614f5657600160e01b831015614f4f57614f4a836157a1565b614f59565b60e0614f59565b60e15b90506140708186011015614f74576000945060009250615011565b6140e08186011015614fb757614070851015614f9957846140700383901c9250614fae565b614070851115614fae57614070850383901b92505b60009450615011565b61c0dd8186011115614fd157617fff945060009250615011565b6070811115614fe8576070810383901c9250614ffb565b6070811015614ffb578060700383901b92505b6001600160701b03831692506140df8186010394505b82607086901b888a186001607f1b60801b1660801c6001600160801b0316171760801b95505050505050610d53565b6000617fff60f084811c8216919084901c81169082900361508c5780617fff03615082576001600160801b031980851690861603614e42578492505050610d53565b8492505050610d53565b80617fff0361509f578392505050610d53565b6001607f1b608086901c90811015906001600160701b031660008490036150c957600193506150d0565b600160701b175b6001607f1b608087901c90811015906001600160701b031660008590036150fa5760019450615101565b600160701b175b82600003615134576001600160801b03198816600160ff1b146151245787615127565b60005b9650505050505050610d53565b80600003615157576001600160801b03198916600160ff1b146151245788615127565b8486038215158515150361526057607081131561517d5789975050505050505050610d53565b600081131561518f5790811c906151be565b606f198112156151a85788975050505050505050610d53565b60008112156151be578060000384901c93508596505b92810192600160711b84106151d9576001968701969390931c925b86617fff0361520a57846151f257617fff60f01b6151fc565b6001600160f01b03195b975050505050505050610d53565b600160701b84101561521f576000965061522c565b6001600160701b03841693505b83607088901b8661523e576000615244565b6001607f1b5b6001600160801b0316171760801b975050505050505050610d53565b600081131561527b57600184901b9350600187039650615292565b600081121561529257600182901b91506001860396505b60708113156152a457600191506152f1565b60018113156152c1576001810360018303901c60010191506152f1565b606f198112156152d457600193506152f1565b6000198112156152f1576001816000030360018503901c60010193505b81841061530257818403935061530b565b83820393508294505b83600003615324575060009650610d5395505050505050565b600061532f856157a1565b90508060710361535457600185901c6001600160701b031694506001880197506153a3565b607081101561539657607081900380891115615383578086901b6001600160701b031695508089039850615390565b600098600019019590951b945b506153a3565b6001600160701b03851694505b87617fff036153d557856153bc57617fff60f01b6153c6565b6001600160f01b03195b98505050505050505050610d53565b84607089901b876153e75760006153ed565b6001607f1b5b6001600160801b0316171760801b98505050505050505050610d53565b60006001607f1b608083901c1115615428575061ffff60ef1b919050565b6001600160801b03198216613fff60f01b0361544657506000919050565b617fff60f083901c81169081900361545f575090919050565b6001600160701b03608084901c16600082900361547f5760019150615486565b600160701b175b8060000361549f57506001600160f01b03199392505050565b600061406f81613fff85106154c55750600f9290921b9160009150613ffe198401615504565b60019250600160701b84106154e75784613ffe039050600f84901b9350615504565b60006154f2856157a1565b607f8190039590951b9461406d039150505b836001607f1b0361553a578215615519576001015b6000615524826157a1565b60700390508082901b9150808303925050615588565b60008361554857600061554b565b60015b60ff1690505b600160701b8210156155865793800260ff81901c607f81019190911c94600019939093019260019290921b9082180190615551565b505b806001600160701b0316607083901b846155a35760006155a9565b6001607f1b5b6001600160801b0316171760801b979650505050505050565b6000816000036155d457506000919050565b8160006155e0826157a1565b905060708110156155f9578060700382901b915061560c565b607081111561560c576070810382901c91505b613fff0160701b6001600160701b03919091161760801b92915050565b6000617fff60f083901c16613fff8110156156475750600092915050565b6001607f1b608084901c1061565b57600080fd5b6140fe81111561566a57600080fd5b600160701b6001600160701b03608085901c161761406f8210156156945761406f8290031c611728565b61406f8211156117285761406e1982011b9392505050565b60006001600160ff1b038211156137545760405162461bcd60e51b815260206004820152602860248201527f53616665436173743a2076616c756520646f65736e27742066697420696e2061604482015267371034b73a191a9b60c11b6064820152608401610926565b6000808212156137545760405162461bcd60e51b815260206004820181905260248201527f53616665436173743a2076616c7565206d75737420626520706f7369746976656044820152606401610926565b60608315615777575081611728565b8251156157875782518084602001fd5b8160405162461bcd60e51b81526004016109269190615c91565b60008082116157af57600080fd5b6000600160801b83106157c457608092831c92015b600160401b83106157d757604092831c92015b600160201b83106157ea57602092831c92015b6201000083106157fc57601092831c92015b610100831061580d57600892831c92015b6010831061581d57600492831c92015b6004831061582d57600292831c92015b60028310610d535760010192915050565b80356001600160a01b0381168114614dc157600080fd5b60006020828403121561586757600080fd5b6117288261583e565b6000806040838503121561588357600080fd5b61588c8361583e565b915061589a6020840161583e565b90509250929050565b60008083601f8401126158b557600080fd5b50813567ffffffffffffffff8111156158cd57600080fd5b6020830191508360208260051b85010111156158e857600080fd5b9250929050565b60008060008060006060868803121561590757600080fd5b6159108661583e565b9450602086013567ffffffffffffffff8082111561592d57600080fd5b61593989838a016158a3565b9096509450604088013591508082111561595257600080fd5b5061595f888289016158a3565b969995985093965092949392505050565b634e487b7160e01b600052604160045260246000fd5b6000806040838503121561599957600080fd5b6159a28361583e565b9150602083013567ffffffffffffffff808211156159bf57600080fd5b818501915085601f8301126159d357600080fd5b8135818111156159e5576159e5615970565b604051601f8201601f19908116603f01168101908382118183101715615a0d57615a0d615970565b81604052828152886020848701011115615a2657600080fd5b8260208601602083013760006020848301015280955050505050509250929050565b60008060408385031215615a5b57600080fd5b615a648361583e565b9150602083013563ffffffff81168114615a7d57600080fd5b809150509250929050565b600080600060408486031215615a9d57600080fd5b615aa68461583e565b9250602084013567ffffffffffffffff811115615ac257600080fd5b615ace868287016158a3565b9497909650939450505050565b602080825282518282018190526000919060409081850190868401855b82811015615b2657815180516001600160a01b03168552860151868501529284019290850190600101615af8565b5091979650505050505050565b60008060008060608587031215615b4957600080fd5b843567ffffffffffffffff811115615b6057600080fd5b615b6c878288016158a3565b9095509350615b7f90506020860161583e565b9150615b8d6040860161583e565b905092959194509250565b60008060408385031215615bab57600080fd5b615bb48361583e565b946020939093013593505050565b60008060008060008060006080888a031215615bdd57600080fd5b615be68861583e565b9650602088013567ffffffffffffffff80821115615c0357600080fd5b615c0f8b838c016158a3565b909850965060408a0135915080821115615c2857600080fd5b615c348b838c016158a3565b909650945060608a0135915080821115615c4d57600080fd5b50615c5a8a828b016158a3565b989b979a50959850939692959293505050565b60005b83811015615c88578181015183820152602001615c70565b50506000910152565b6020815260008251806020840152615cb0816040850160208701615c6d565b601f01601f19169190910160400192915050565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b80820180821115610d5357610d53615cda565b81810381811115610d5357610d53615cda565b600060018201615d2857615d28615cda565b5060010190565b600060208284031215615d4157600080fd5b5051919050565b600060208284031215615d5a57600080fd5b8151801515811461172857600080fd5b8082028115828204841417610d5357610d53615cda565b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b606082015260800190565b80820260008212600160ff1b84141615615de857615de8615cda565b8181058314821517610d5357610d53615cda565b8181036000831280158383131683831282161715615e1c57615e1c615cda565b5092915050565b6000600160ff1b8201615e3857615e38615cda565b5060000390565b634e487b7160e01b600052601260045260246000fd5b600082615e6457615e64615e3f565b500490565b60008251615e7b818460208701615c6d565b9190910192915050565b600082615e9457615e94615e3f565b500690565b634e487b7160e01b600052600160045260246000fdfe5265656e7472616e637947756172643a207265656e7472616e742063616c6c00416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a26469706673582212203fe110dbac2afce103aa95e536ddfc1246e465bc92c902d21e96eadd872e766164736f6c63430008110033
Deployed Bytecode
0x6080604052600436106102035760003560e01c8063658d9b5911610118578063b2cbc4b1116100a0578063cf4858b71161006f578063cf4858b7146107ec578063ef46e36b1461080c578063f2fde38b14610843578063f7888aec14610863578063fbb0b2b9146108ba57600080fd5b8063b2cbc4b114610777578063bbda182a14610797578063c2a672e0146107b7578063cc29516a146107d757600080fd5b80638456cb59116100e75780638456cb59146106e4578063890d4112146106f95780638da5cb5b1461071957806390482d7214610737578063adc9772e1461075757600080fd5b8063658d9b591461065a5780636a1c1e0414610687578063715018a61461069c578063769b81d6146106b157600080fd5b80633f4ba83a1161019b5780634f1ef2861161016a5780634f1ef286146105da57806352d1902d146105ed578063585d59f2146106025780635c975abb1461062257806364e57e421461063a57600080fd5b80633f4ba83a146105525780633f6e5394146105675780634788cabf146105875780634c1b9260146105ba57600080fd5b80631e9322c4116101d75780631e9322c4146102b75780632fafc3a4146103fd57806335a5ef711461041d5780633659cfe61461053257600080fd5b806214fde0146102085780630d8e6e2c1461025757806319092d9b146102755780631e83409a14610297575b600080fd5b34801561021457600080fd5b50610242610223366004615855565b6001600160a01b03166000908152610130602052604090205460ff1690565b60405190151581526020015b60405180910390f35b34801561026357600080fd5b5060035b60405190815260200161024e565b34801561028157600080fd5b50610295610290366004615855565b6108da565b005b3480156102a357600080fd5b506102956102b2366004615855565b6109a4565b3480156102c357600080fd5b5061038d6102d2366004615855565b6040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a0810191909152506001600160a01b031660009081526101326020908152604091829020825160c0810184528154815260018201546001600160801b0380821694830194909452600160801b90049092169282019290925260029091015463ffffffff8082166060840152600160201b8204166080830152600160401b90046001600160581b031660a082015290565b60405161024e9190600060c0820190508251825260208301516001600160801b0380821660208501528060408601511660408501525050606083015163ffffffff808216606085015280608086015116608085015250506001600160581b0360a08401511660a083015292915050565b34801561040957600080fd5b50610267610418366004615870565b610c55565b34801561042957600080fd5b506104db610438366004615870565b604080516080810182526000808252602082018190529181018290526060810191909152506001600160a01b03918216600090815261013360209081526040808320939094168252918252829020825160808101845281546001600160801b038082168352600160801b9091041692810192909252600101546001600160481b03811692820192909252600160481b9091046001600160601b0316606082015290565b60405161024e919060006080820190506001600160801b03808451168352806020850151166020840152506001600160481b0360408401511660408301526001600160601b03606084015116606083015292915050565b34801561053e57600080fd5b5061029561054d366004615855565b610d59565b34801561055e57600080fd5b50610295610ed4565b34801561057357600080fd5b506102956105823660046158ef565b610f34565b34801561059357600080fd5b507f9b1f3aa590476fc9aa58d44ad1419ab53d34c344bd5ed46b12e4af7d27c38e06610267565b3480156105c657600080fd5b506102956105d5366004615855565b611393565b6102956105e8366004615986565b61142c565b3480156105f957600080fd5b50610267611598565b34801561060e57600080fd5b5061026761061d366004615855565b61165d565b34801561062e57600080fd5b5060335460ff16610242565b34801561064657600080fd5b50610295610655366004615a48565b61172f565b34801561066657600080fd5b5061067a610675366004615a88565b611741565b60405161024e9190615adb565b34801561069357600080fd5b506102956118c0565b3480156106a857600080fd5b506102956119ce565b3480156106bd57600080fd5b5061012f546001600160a01b03165b6040516001600160a01b03909116815260200161024e565b3480156106f057600080fd5b506102956119f2565b34801561070557600080fd5b50610295610714366004615855565b611a50565b34801561072557600080fd5b5060c9546001600160a01b03166106cc565b34801561074357600080fd5b50610295610752366004615b33565b611b00565b34801561076357600080fd5b50610295610772366004615b98565b6120c8565b34801561078357600080fd5b506102956107923660046158ef565b6123c8565b3480156107a357600080fd5b506102956107b2366004615b98565b612913565b3480156107c357600080fd5b506102956107d2366004615b98565b612975565b3480156107e357600080fd5b506102956129ce565b3480156107f857600080fd5b50610295610807366004615bc2565b612a31565b34801561081857600080fd5b50610267610827366004615855565b6001600160a01b03166000908152610131602052604090205490565b34801561084f57600080fd5b5061029561085e366004615855565b612fcd565b34801561086f57600080fd5b5061026761087e366004615870565b6001600160a01b03918216600090815261013360209081526040808320939094168252919091522054600160801b90046001600160801b031690565b3480156108c657600080fd5b506102956108d5366004615a88565b613064565b6108e26132e8565b60408051808201909152600681526550545f37313560d01b60208201526001600160a01b03821661092f5760405162461bcd60e51b81526004016109269190615c91565b60405180910390fd5b5061093b816000613342565b6001600160a01b038116600090815261013060205260409020805460ff191690557f0ab1da102cf1f21b42dd087a1a4bd108313e4371052dffbc8445feba939209e3335b604080516001600160a01b03928316815291841660208301520160405180910390a150565b6109ac613634565b600260fc54036109ec5760405162461bcd60e51b815260206004820152601f6024820152600080516020615eb08339815191526044820152606401610926565b600260fc819055336000818152610133602090815260408083206001600160a01b03871680855290835281842082516080808201855282546001600160801b038082168452600160801b918290048116848901526001948501546001600160481b03811685890152600160481b90046001600160601b03166060808601919091529589526101328852868920875160c0810189528154815295810154808316998701999099529190970490961694830194909452939096015463ffffffff80821692880192909252600160201b810490911691860191909152600160401b90046001600160581b031660a085015291929080610ae8838561367a565b91509150600082116040518060400160405280600681526020016550545f37303960d01b81525090610b2d5760405162461bcd60e51b81526004016109269190615c91565b506040518060800160405280610b42836136eb565b6001600160801b0390811682526020878101518216818401526040808901516001600160481b03908116828601526060808b01516001600160601b03908116968201969096526001600160a01b03808d1660009081526101338652848120918f1681529085528390208751948801518616600160801b029490951693909317845590850151600190930180549590920151909316600160481b026001600160a81b03199094169190921617919091179055610bfd8583613758565b604080516001600160a01b038088168252881660208201529081018390527ff7a40077ff7a04c7e61f6f26fb13774259ddf1b6bce9ecf26a8276cdd39926839060600160405180910390a15050600160fc5550505050565b6001600160a01b03818116600081815261013260209081526040808320815160c081018352815481526001808301546001600160801b0380821684880152600160801b9182900481168487015260029094015463ffffffff808216606080870191909152600160201b8304909116608080870191909152600160401b9092046001600160581b031660a0860152998c16885261013387528588209888529786528487208551988901865280548086168a5291909104909316948701949094529201546001600160481b03811691850191909152600160481b90046001600160601b031693830193909352919082610d4c838361367a565b5093505050505b92915050565b6001600160a01b037f000000000000000000000000ac0dcbe1296ae5ae69351a05e6b5803c3eab644e163003610de65760405162461bcd60e51b815260206004820152602c60248201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060448201526b19195b1959d85d1958d85b1b60a21b6064820152608401610926565b7f000000000000000000000000ac0dcbe1296ae5ae69351a05e6b5803c3eab644e6001600160a01b0316610e417f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc546001600160a01b031690565b6001600160a01b031614610eac5760405162461bcd60e51b815260206004820152602c60248201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060448201526b6163746976652070726f787960a01b6064820152608401610926565b610eb5816137cd565b60408051600080825260208201909252610ed1918391906137d5565b50565b61012f546001600160a01b0316336001600160a01b03161460405180604001604052806006815260200165141517cdcc0d60d21b81525090610f295760405162461bcd60e51b81526004016109269190615c91565b50610f32613957565b565b61012e54604080518082019091526006815265282a2f9b981960d11b6020820152906001600160a01b03163314610f7e5760405162461bcd60e51b81526004016109269190615c91565b50610f87613634565b6000838180610fb660408051608081018252600080825260208201819052918101829052606081019190915290565b6040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a08101829052905b8581146113755761013060008c8c8481811061100757611007615cc4565b905060200201602081019061101c9190615855565b6001600160a01b031681526020808201929092526040908101600020548151808301909252600682526550545f37303160d01b928201929092529060ff166110775760405162461bcd60e51b81526004016109269190615c91565b506001600160a01b038c16600090815261013360205260408120908c8c848181106110a4576110a4615cc4565b90506020020160208101906110b99190615855565b6001600160a01b031681526020808201929092526040908101600020815160808101835281546001600160801b038082168352600160801b9091041693810193909352600101546001600160481b03811691830191909152600160481b90046001600160601b03166060820152925088888281811061113a5761113a615cc4565b9050602002013583606001516001600160601b031610156040518060400160405280600681526020016550545f37303760d01b8152509061118e5760405162461bcd60e51b81526004016109269190615c91565b5061013260008c8c848181106111a6576111a6615cc4565b90506020020160208101906111bb9190615855565b6001600160a01b031681526020808201929092526040908101600020815160c0810183528154815260018201546001600160801b0380821695830195909552600160801b9004909316918301919091526002015463ffffffff8082166060840152600160201b8204166080830152600160401b90046001600160581b031660a0820152915061124a828461367a565b90955093506112598588615cf0565b96506112cd8c8c8c8481811061127157611271615cc4565b90506020020160208101906112869190615855565b86858788602001516001600160801b03168f8f898181106112a9576112a9615cc4565b905060200201358a606001516001600160601b03166112c89190615d03565b6139a9565b7f72ec23c86fe9e1a03ff3b69e7b455294b2581e363068c3d0e3ebf9b8c0fc736d8c8c8c8481811061130157611301615cc4565b90506020020160208101906113169190615855565b8b8b8581811061132857611328615cc4565b9050602002013560405161135d939291906001600160a01b039384168152919092166020820152604081019190915260600190565b60405180910390a161136e81615d16565b9050610fe9565b508515611386576113868b87613758565b5050505050505050505050565b61139b6132e8565b60408051808201909152600681526550545f37313560d01b60208201526001600160a01b0382166113df5760405162461bcd60e51b81526004016109269190615c91565b506001600160a01b038116600090815261013060205260409020805460ff191660011790557fa926f0878fdfbb99f575a83ab27b540cfa259857dd4da469b62ddff8905ebbac61097f3390565b6001600160a01b037f000000000000000000000000ac0dcbe1296ae5ae69351a05e6b5803c3eab644e1630036114b95760405162461bcd60e51b815260206004820152602c60248201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060448201526b19195b1959d85d1958d85b1b60a21b6064820152608401610926565b7f000000000000000000000000ac0dcbe1296ae5ae69351a05e6b5803c3eab644e6001600160a01b03166115147f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc546001600160a01b031690565b6001600160a01b03161461157f5760405162461bcd60e51b815260206004820152602c60248201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060448201526b6163746976652070726f787960a01b6064820152608401610926565b611588826137cd565b611594828260016137d5565b5050565b6000306001600160a01b037f000000000000000000000000ac0dcbe1296ae5ae69351a05e6b5803c3eab644e16146116385760405162461bcd60e51b815260206004820152603860248201527f555550535570677261646561626c653a206d757374206e6f742062652063616c60448201527f6c6564207468726f7567682064656c656761746563616c6c00000000000000006064820152608401610926565b507f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc90565b6001600160a01b038116600090815261013260209081526040808320815160c081018352815480825260018301546001600160801b0380821696840196909652600160801b9004909416928101929092526002015463ffffffff8082166060840152600160201b8204166080830152600160401b90046001600160581b031660a08201529082036116fb5760a001516001600160581b031692915050565b61172843826060015163ffffffff16836080015163ffffffff168460a001516001600160581b0316613c6d565b9392505050565b6117376132e8565b6115948282613342565b6060818067ffffffffffffffff81111561175d5761175d615970565b6040519080825280602002602001820160405280156117a257816020015b604080518082019091526000808252602082015281526020019060019003908161177b5790505b5091506000805b8281146118b6578585828181106117c2576117c2615cc4565b90506020020160208101906117d79190615855565b6001600160a01b03811660009081526101306020908152604091829020548251808401909352600683526550545f37303160d01b918301919091529193509060ff166118365760405162461bcd60e51b81526004016109269190615c91565b506040805180820182526001600160a01b03848116808352908a16600090815261013360209081528482209282529182529290922060010154600160481b90046001600160601b031691810191909152845185908390811061189a5761189a615cc4565b6020026020010181905250806118af90615d16565b90506117a9565b5050509392505050565b6118c8613634565b600260fc54036119085760405162461bcd60e51b815260206004820152601f6024820152600080516020615eb08339815191526044820152606401610926565b600260fc553360008181526101316020908152604091829020548251808401909352600683526550545f37303960d01b91830191909152908161195e5760405162461bcd60e51b81526004016109269190615c91565b506001600160a01b038216600090815261013160205260408120556119838282613758565b604080516001600160a01b0384168152602081018390527f54f95fe3d28f3e3aa8d8aecf94ed3edfe8a58ba281943414440d9fb92ce9646c910160405180910390a15050600160fc55565b6119d66132e8565b6119e06000613cf0565b60fb80546001600160a01b0319169055565b61012f546001600160a01b0316336001600160a01b03161460405180604001604052806006815260200165141517cdcc0d60d21b81525090611a475760405162461bcd60e51b81526004016109269190615c91565b50610f32613d42565b611a586132e8565b60408051808201909152600681526550545f37313560d01b60208201526001600160a01b038216611a9c5760405162461bcd60e51b81526004016109269190615c91565b5061012f80546001600160a01b038381166001600160a01b031983168117909355169081611ac73390565b6001600160a01b03167fb1f2133e27463d1f096faf22e79896b5ebbf2d047633dc7451139a1fe14854a960405160405180910390a45050565b600054610100900460ff1615808015611b205750600054600160ff909116105b80611b3a5750303b158015611b3a575060005460ff166001145b611b9d5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401610926565b6000805460ff191660011790558015611bc0576000805461ff0019166101001790555b611bc8613d7f565b611bd0613db2565b611bd8613de2565b60408051808201909152600681526550545f37313560d01b60208201526001600160a01b038416611c1c5760405162461bcd60e51b81526004016109269190615c91565b507fbd22bf01cb7daed462db61de31bb111aabcdae27adc748450fb9a9ea1c419cce60001b836001600160a01b0316634788cabf6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611c7f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ca39190615d2f565b1460405180604001604052806006815260200165282a2f9b989b60d11b81525090611ce15760405162461bcd60e51b81526004016109269190615c91565b5060408051808201909152600681526550545f37313560d01b60208201526001600160a01b038316611d265760405162461bcd60e51b81526004016109269190615c91565b507fdba05ed67d0251facfcab8345f27ccd3e72b5a1da8cebfabbcccf4316e6d053c60001b826001600160a01b0316634788cabf6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611d89573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611dad9190615d2f565b1460405180604001604052806006815260200165282a2f9b989b60d11b81525090611deb5760405162461bcd60e51b81526004016109269190615c91565b5061012e80546001600160a01b0319166001600160a01b038516179055833361012f80546001600160a01b0319166001600160a01b0392831617905560405163095ea7b360e01b8152858216600482015260001960248201529084169063095ea7b3906044016020604051808303816000875af1158015611e70573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e949190615d48565b5060005b818114612079576000878783818110611eb357611eb3615cc4565b9050602002016020810190611ec89190615855565b6001600160a01b031614156040518060400160405280600681526020016550545f37313560d01b81525090611f105760405162461bcd60e51b81526004016109269190615c91565b5060016101306000898985818110611f2a57611f2a615cc4565b9050602002016020810190611f3f9190615855565b6001600160a01b0316815260208082019290925260409081016000908120805460ff191694151594909417909355805160c0810182528381529182018390528101829052606081018290526080810182905260a081018290529061013290898985818110611faf57611faf615cc4565b9050602002016020810190611fc49190615855565b6001600160a01b0316815260208082019290925260409081016000208351815591830151908301516001600160801b03908116600160801b029116176001820155606082015160029091018054608084015160a0909401516001600160581b0316600160401b026affffffffffffffffffffff60401b1963ffffffff958616600160201b0267ffffffffffffffff199093169590941694909417179190911691909117905561207281615d16565b9050611e98565b505080156120c1576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b5050505050565b600260fc54036121085760405162461bcd60e51b815260206004820152601f6024820152600080516020615eb08339815191526044820152606401610926565b600260fc55612115613634565b60408051808201909152600681526550545f37313760d01b6020820152816121505760405162461bcd60e51b81526004016109269190615c91565b506001600160a01b03821660009081526101306020908152604091829020548251808401909352600683526550545f37303160d01b9183019190915260ff166121ac5760405162461bcd60e51b81526004016109269190615c91565b506000336040516323b872dd60e01b81526001600160a01b03808316600483015230602483015260448201859052919250908416906323b872dd906064016020604051808303816000875af1158015612209573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061222d9190615d48565b506001600160a01b0381811660009081526101336020908152604080832093871680845293825280832081516080808201845282546001600160801b038082168452600160801b918290048116848801526001948501546001600160481b03811685880152600160481b90046001600160601b03166060808601919091529888526101328752858820865160c081018852815481529581015480831698870198909852919096049095169383019390935260029093015463ffffffff80821696830196909652600160201b810490951691810191909152600160401b9093046001600160581b031660a0840152919080612327838561367a565b9150915061235f85888386888b8a602001516001600160801b031661234c9190615cf0565b8a606001516001600160601b03166139a9565b811561236f5761236f8583613758565b604080516001600160a01b038088168252891660208201529081018790527f0be61a5ceba15cd4c9c5deacde2110b0c5be6390bf9b3ee49aa96149b14543bc9060600160405180910390a15050600160fc555050505050565b61012e54604080518082019091526006815265282a2f9b981960d11b6020820152906001600160a01b031633146124125760405162461bcd60e51b81526004016109269190615c91565b5061241b613634565b600083818061244a60408051608081018252600080825260208201819052918101829052606081019190915290565b6040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a08101829052905b8581146113755761013060008c8c8481811061249b5761249b615cc4565b90506020020160208101906124b09190615855565b6001600160a01b031681526020808201929092526040908101600020548151808301909252600682526550545f37303160d01b928201929092529060ff1661250b5760405162461bcd60e51b81526004016109269190615c91565b506001600160a01b038c16600090815261013360205260408120908c8c8481811061253857612538615cc4565b905060200201602081019061254d9190615855565b6001600160a01b0316815260208082019290925260409081016000908120825160808101845281546001600160801b038082168352600160801b9091041694810194909452600101546001600160481b03811692840192909252600160481b9091046001600160601b03166060830152909350610132908c8c848181106125d6576125d6615cc4565b90506020020160208101906125eb9190615855565b6001600160a01b0316815260208082019290925260409081016000908120825160c0810184528154815260018201546001600160801b0380821683880152600160801b90910481169482019490945260029091015463ffffffff8082166060840152600160201b8204166080830152600160401b90046001600160581b031660a082015292860151929450911690036127e257600089898381811061269257612692615cc4565b9050602002013584606001516001600160601b03166126b19190615cf0565b90506126bc81613e09565b6001600160a01b038e16600090815261013360205260408120908e8e868181106126e8576126e8615cc4565b90506020020160208101906126fd9190615855565b6001600160a01b03166001600160a01b0316815260200190815260200160002060010160096101000a8154816001600160601b0302191690836001600160601b031602179055507f013627584e1896036670d60cab043cb12b9c822553ef971d0ca270c2857172fd8d8d8d8581811061277857612778615cc4565b905060200201602081019061278d9190615855565b8c8c8681811061279f5761279f615cc4565b905060200201356040516127d4939291906001600160a01b039384168152919092166020820152604081019190915260600190565b60405180910390a150612903565b6127ec828461367a565b90955093506127fb8588615cf0565b965061286a8c8c8c8481811061281357612813615cc4565b90506020020160208101906128289190615855565b86858788602001516001600160801b03168f8f8981811061284b5761284b615cc4565b905060200201358a606001516001600160601b03166112c89190615cf0565b7f013627584e1896036670d60cab043cb12b9c822553ef971d0ca270c2857172fd8c8c8c8481811061289e5761289e615cc4565b90506020020160208101906128b39190615855565b8b8b858181106128c5576128c5615cc4565b905060200201356040516128fa939291906001600160a01b039384168152919092166020820152604081019190915260600190565b60405180910390a15b61290c81615d16565b905061247d565b600260fc54036129535760405162461bcd60e51b815260206004820152601f6024820152600080516020615eb08339815191526044820152606401610926565b600260fc55612960613634565b61296c82826000613e71565b5050600160fc55565b600260fc54036129b55760405162461bcd60e51b815260206004820152601f6024820152600080516020615eb08339815191526044820152606401610926565b600260fc556129c2613634565b61296c82826001613e71565b60fb5460408051808201909152600681526550545f37313960d01b6020820152906001600160a01b03163314612a175760405162461bcd60e51b81526004016109269190615c91565b5060fb80546001600160a01b0319169055610f3233613cf0565b61012e54604080518082019091526006815265282a2f9b981960d11b6020820152906001600160a01b03163314612a7b5760405162461bcd60e51b81526004016109269190615c91565b50612a84613634565b6000806000805b808914612fb05761013060008b8b84818110612aa957612aa9615cc4565b9050602002016020810190612abe9190615855565b6001600160a01b031681526020808201929092526040908101600020548151808301909252600682526550545f37303160d01b928201929092529060ff16612b195760405162461bcd60e51b81526004016109269190615c91565b50858582818110612b2c57612b2c615cc4565b905060200201359250878782818110612b4757612b47615cc4565b6001600160a01b038e1660009081526101336020908152604082209202939093013594509050818c8c85818110612b8057612b80615cc4565b9050602002016020810190612b959190615855565b6001600160a01b0316815260208082019290925260409081016000908120825160808101845281546001600160801b038082168352600160801b9091041694810194909452600101546001600160481b03811692840192909252600160481b9091046001600160601b03166060830152909150610132818d8d86818110612c1e57612c1e615cc4565b9050602002016020810190612c339190615855565b6001600160a01b031681526020808201929092526040908101600020815160c0810183528154815260018201546001600160801b0380821695830195909552600160801b9004909316918301919091526002015463ffffffff8082166060840152600160201b8204166080830152600160401b90046001600160581b031660a082015290508415612d62578b8b84818110612cd057612cd0615cc4565b9050602002016020810190612ce59190615855565b6040516323b872dd60e01b81526001600160a01b038f811660048301523060248301526044820188905291909116906323b872dd906064016020604051808303816000875af1158015612d3c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d609190615d48565b505b60208201516001600160801b0316158015612d7b575084155b15612ea357612da18483606001516001600160601b0316612d9c9190615cf0565b613e09565b6001600160a01b038e16600090815261013360205260408120908e8e87818110612dcd57612dcd615cc4565b9050602002016020810190612de29190615855565b6001600160a01b03166001600160a01b0316815260200190815260200160002060010160096101000a8154816001600160601b0302191690836001600160601b031602179055507f013627584e1896036670d60cab043cb12b9c822553ef971d0ca270c2857172fd8d8d8d86818110612e5d57612e5d615cc4565b9050602002016020810190612e729190615855565b604080516001600160a01b039384168152929091166020830152810186905260600160405180910390a15050612fa0565b600080612eb0838561367a565b9092509050612ebf8289615cf0565b9750612f218f8f8f88818110612ed757612ed7615cc4565b9050602002016020810190612eec9190615855565b8386888c8a602001516001600160801b0316612f089190615cf0565b8c8b606001516001600160601b03166112c89190615cf0565b7ff0aaf972c9efcbddb73d7f97f05a673d7b2dcec839804b6f0839e88ed311e0b78f8f8f88818110612f5557612f55615cc4565b9050602002016020810190612f6a9190615855565b604080516001600160a01b03938416815292909116602083015281018890526060810189905260800160405180910390a1505050505b612fa981615d16565b9050612a8b565b508215612fc157612fc18a84613758565b50505050505050505050565b612fd56132e8565b60408051808201909152600681526550545f37313560d01b60208201526001600160a01b0382166130195760405162461bcd60e51b81526004016109269190615c91565b5060fb80546001600160a01b0319166001600160a01b0383169081179091556040517f3ec7bb1d452f3c36260fa8ef678a597fd97574d8ec42f6dc98ffce3dbc91228f90600090a250565b600260fc54036130a45760405162461bcd60e51b815260206004820152601f6024820152600080516020615eb08339815191526044820152606401610926565b600260fc556130b1613634565b60408051808201909152600681526550545f37313560d01b60208201526001600160a01b0384166130f55760405162461bcd60e51b81526004016109269190615c91565b50806000805b8281146132cb57600085858381811061311657613116615cc4565b905060200201602081019061312b9190615855565b6001600160a01b0388811660009081526101336020908152604080832093851680845293825280832081516080808201845282546001600160801b038082168452600160801b9182900481168488019081526001958601546001600160481b03811686890152600160481b90046001600160601b03166060808701919091529989526101328852868920875160c081018952815481529681015480841699880199909952929097048116958501959095526002015463ffffffff80821698850198909852600160201b810490971690830152600160401b9095046001600160581b031660a082015291519495509293909216900361322b575050506132bb565b600080613238838561367a565b90925090506132478288615cf0565b96506132728b8683868889602001516001600160801b03168a606001516001600160601b03166139a9565b604080516001600160a01b03808e168252871660208201527f510f627c13e7683adbb7033a1b06b83397772c9f84460303cb7f18d17fdec4bd910160405180910390a150505050505b6132c481615d16565b90506130fb565b5080156132dc576132dc8582613758565b5050600160fc55505050565b60c9546001600160a01b03163314610f325760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610926565b6001600160a01b03821660009081526101306020908152604091829020548251808401909352600683526550545f37303160d01b9183019190915260ff1661339d5760405162461bcd60e51b81526004016109269190615c91565b506001600160a01b038216600090815261013260209081526040808320815160c0810183528154815260018201546001600160801b03808216958301869052600160801b9091041692810183905260029091015463ffffffff80821660608401819052600160201b83049091166080840152600160401b9091046001600160581b031660a08301529093439390926134389285929091614129565b8351909150600090156134875761348061345184614153565b63ffffffff16856060015163ffffffff16866080015163ffffffff168760a001516001600160581b0316613c6d565b9050613497565b5060a08301516001600160581b03165b60006134ad8663ffffffff1686600001516141b8565b90506040518060c00160405280866000015181526020016134cd836136eb565b6001600160801b031681526020016134e4856136eb565b6001600160801b031681526020016134fb86614153565b63ffffffff1681526020018763ffffffff16815260200161351b846141f8565b6001600160581b039081169091526001600160a01b038916600090815261013260209081526040918290208451815590840151918401516001600160801b03908116600160801b029216919091176001820155606083015160029091018054608085015160a090950151909316600160401b026affffffffffffffffffffff60401b1963ffffffff958616600160201b0267ffffffffffffffff19909516959093169490941792909217169190911790556135d33390565b6001600160a01b03167fa92f31ffdefd5f39fe3e8b400639a2a60d1080fcd995d093dac1af68091e50ae86608001518860405161362392919063ffffffff92831681529116602082015260400190565b60405180910390a250505050505050565b60335460ff1615610f325760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b6044820152606401610926565b6000806136ad43856060015163ffffffff1686602001516001600160801b031687604001516001600160801b0316614129565b90506136e283602001516001600160801b031684604001516001600160481b031685600001516001600160801b031684614260565b91509250929050565b60006001600160801b038211156137545760405162461bcd60e51b815260206004820152602760248201527f53616665436173743a2076616c756520646f65736e27742066697420696e20316044820152663238206269747360c81b6064820152608401610926565b5090565b61012e546001600160a01b031660405163ec3c87c960e01b81526001600160a01b03848116600483015260248201849052919091169063ec3c87c990604401600060405180830381600087803b1580156137b157600080fd5b505af11580156137c5573d6000803e3d6000fd5b505050505050565b610ed16132e8565b7f4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd91435460ff161561380d57613808836142e3565b505050565b826001600160a01b03166352d1902d6040518163ffffffff1660e01b8152600401602060405180830381865afa925050508015613867575060408051601f3d908101601f1916820190925261386491810190615d2f565b60015b6138ca5760405162461bcd60e51b815260206004820152602e60248201527f45524331393637557067726164653a206e657720696d706c656d656e7461746960448201526d6f6e206973206e6f74205555505360901b6064820152608401610926565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc811461394b5760405162461bcd60e51b815260206004820152602960248201527f45524331393637557067726164653a20756e737570706f727465642070726f786044820152681a58589b195555525160ba1b6064820152608401610926565b50613808838383614391565b61395f6143bc565b6033805460ff191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa335b6040516001600160a01b03909116815260200160405180910390a1565b60006139cf82846f1fffb33333333333333333333333333360811b611fff60f11b61440e565b905060405180608001604052806139e5886136eb565b6001600160801b031681526020016139fc856136eb565b6001600160801b03168152602001613a1383614512565b6001600160481b03168152602001613a2a84613e09565b6001600160601b039081169091526001600160a01b03808b16600090815261013360209081526040808320938d1683529281528282208551868301516001600160801b03908116600160801b029181169190911782558685015160019092018054606090980151909616600160481b026001600160a81b03199097166001600160481b039283161796909617909455918801519188015189519194613ad99487948a949116929091169061457a565b905060008660000151600003613afd575060a08601516001600160581b0316613b2d565b613b2a43886060015163ffffffff16896080015163ffffffff168a60a001516001600160581b0316613c6d565b90505b6000613b43886080015163ffffffff16846141b8565b90506040518060c00160405280848152602001613b5f836136eb565b6001600160801b03168152602001613b768b6136eb565b6001600160801b03168152602001613b8d43614153565b63ffffffff168152602001896080015163ffffffff168152602001613bb1846141f8565b6001600160581b039081169091526001600160a01b03909b16600090815261013260209081526040918290208351815590830151918301516001600160801b03908116600160801b029216919091176001820155606082015160029091018054608084015160a090940151909d16600160401b026affffffffffffffffffffff60401b1963ffffffff948516600160201b0267ffffffffffffffff19909f1694909316939093179c909c17161790995550505050505050505050565b60008385101560405180604001604052806006815260200165282a2f9b989960d11b81525090613cb05760405162461bcd60e51b81526004016109269190615c91565b5060006402540be40084613cc48789615d03565b613cce9190615d6a565b613cd89190615d6a565b9050613ce48184615cf0565b9150505b949350505050565b60c980546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b613d4a613634565b6033805460ff191660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a25861398c3390565b600054610100900460ff16613da65760405162461bcd60e51b815260040161092690615d81565b6033805460ff19169055565b600054610100900460ff16613dd95760405162461bcd60e51b815260040161092690615d81565b610f3233613cf0565b600054610100900460ff16610f325760405162461bcd60e51b815260040161092690615d81565b60006001600160601b038211156137545760405162461bcd60e51b815260206004820152602660248201527f53616665436173743a2076616c756520646f65736e27742066697420696e203960448201526536206269747360d01b6064820152608401610926565b60408051808201909152600681526550545f37313760d01b602082015282613eac5760405162461bcd60e51b81526004016109269190615c91565b50336000818152610133602090815260408083206001600160a01b0388168452825291829020825160808101845281546001600160801b038082168352600160801b909104168184018190526001909201546001600160481b03811682860152600160481b90046001600160601b0316606082015283518085019094526006845265282a2f9b981b60d11b92840192909252909190851115613f615760405162461bcd60e51b81526004016109269190615c91565b506001600160a01b038516600090815261013260209081526040808320815160c0810183528154815260018201546001600160801b0380821695830195909552600160801b9004909316918301919091526002015463ffffffff8082166060840152600160201b8204166080830152600160401b90046001600160581b031660a08201529080613ff1838561367a565b9150915061401685898386888c8a602001516001600160801b031661234c9190615d03565b81156140605785156140315761402c8583613758565b614060565b6001600160a01b038516600090815261013160205260408120805484929061405a908490615cf0565b90915550505b60405163a9059cbb60e01b81526001600160a01b0386811660048301526024820189905289169063a9059cbb906044016020604051808303816000875af11580156140af573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906140d39190615d48565b50604080516001600160a01b0380881682528a1660208201529081018890527f820d19e507b9188a561dd1270049c35fd21a7289cdbf5230d13ba5b42609d7dc9060600160405180910390a15050505050505050565b6000826141368587615d03565b6141409190615d6a565b61414a9083615cf0565b95945050505050565b600063ffffffff8211156137545760405162461bcd60e51b815260206004820152602660248201527f53616665436173743a2076616c756520646f65736e27742066697420696e203360448201526532206269747360d01b6064820152608401610926565b6000816000036141ca57506000610d53565b611728678ac7230489e800006141e8670de0b6b3a764000086615d6a565b6141f29190615d6a565b836146a6565b60006001600160581b038211156137545760405162461bcd60e51b815260206004820152602660248201527f53616665436173743a2076616c756520646f65736e27742066697420696e203860448201526538206269747360d01b6064820152608401610926565b6000828210156040518060400160405280600681526020016550545f37313360d01b815250906142a35760405162461bcd60e51b81526004016109269190615c91565b5060006142b08484615d03565b6142ba8688615d6a565b6142c49190615d6a565b9050613ce481722cd76fe086b93ce2f768a00b22a000000000006146a6565b6001600160a01b0381163b6143505760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b6064820152608401610926565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc80546001600160a01b0319166001600160a01b0392909216919091179055565b61439a836146c8565b6000825111806143a75750805b15613808576143b68383614708565b50505050565b60335460ff16610f325760405162461bcd60e51b815260206004820152601460248201527f5061757361626c653a206e6f74207061757365640000000000000000000000006044820152606401610926565b6000670de0b6b3a764000084101561442857506000613ce8565b600061443c86670de0b6b3a76400006147f3565b9050600061445286670de0b6b3a76400006147f3565b905060006144608383614844565b90506000806144826f3ffa9999999999999be7e553d3e20f0d60801b84614b2b565b60000b1261449a5761449382614c62565b90506144dd565b60006144ad6144a7614dc6565b86614dd7565b905060006144c46144be8387614844565b89615040565b90506144d8896144d38361540a565b615040565b925050505b60006144f9826144f4670de0b6b3a76400006155c2565b614dd7565b905061450481615629565b9a9950505050505050505050565b60006001600160481b038211156137545760405162461bcd60e51b815260206004820152602660248201527f53616665436173743a2076616c756520646f65736e27742066697420696e203760448201526532206269747360d01b6064820152608401610926565b600080614586846156ac565b61458f866156ac565b6145999190615dcc565b6145a2876156ac565b6145ab896156ac565b6145b59190615dcc565b6145bf9190615dfc565b905060008082121561466d5760006145ef6145e16145dc85615e23565b615716565b670de0b6b3a76400006146a6565b9050808510801561460b57508061460886612710615cf0565b10155b1561461c576000935050505061414a565b60408051808201909152600681526550545f37313160d01b60208201528186101561465a5760405162461bcd60e51b81526004016109269190615c91565b506146658186615d03565b915050614686565b6146796145e183615716565b6146839085615cf0565b90505b61271081101561469b5760009250505061414a565b979650505050505050565b6000816146b4600282615e55565b6146be9085615cf0565b6117289190615e55565b6146d1816142e3565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b60606001600160a01b0383163b6147705760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6044820152651b9d1c9858dd60d21b6064820152608401610926565b600080846001600160a01b03168460405161478b9190615e69565b600060405180830381855af49150503d80600081146147c6576040519150601f19603f3d011682016040523d82523d6000602084013e6147cb565b606091505b509150915061414a8282604051806060016040528060278152602001615ed060279139615768565b6000806148008385615e85565b111561481457614811600184615cf0565b92505b600061481f846155c2565b9050600061482c846155c2565b9050600061483a8383614844565b9695505050505050565b6000617fff60f084811c8216919084901c8116908290036148895780617fff03614878575061ffff60ef1b9150610d539050565b505050600160ff1b81168218610d53565b80617fff036148cc576dffffffffffffffffffffffffffff60801b8416156148bb575061ffff60ef1b9150610d539050565b505050808218600160ff1b16610d53565b600160801b600160ff1b03841660000361491c57600160801b600160ff1b038516600003614904575061ffff60ef1b9150610d539050565b505050808218600160ff1b16617fff60f01b17610d53565b6001600160701b03608085901c16600082900361493c5760019150614943565b600160701b175b6001600160701b03608087901c16600084900361498657801561498157600061496b826157a1565b6001955060e20393840160711901939190911b90505b614990565b600160701b1760721b5b81818161499f5761499f615e3f565b049050806000036149cf57600160ff1b878718166149be5760006149c4565b600160ff1b5b945050505050610d53565b6d10000000000000000000000000008110156149ed576149ed615e99565b60006e080000000000000000000000000000821015614a42576e040000000000000000000000000000821015614a3757600160711b821015614a30576070614a3a565b6071614a3a565b60725b60ff16614a4b565b614a4b826157a1565b905083614071018186011115614a6957617fff945060009150614afc565b83818601613ffc011015614a84576000945060009150614afc565b83818601613f8c011015614ad1578385613ffc011115614aaf578385613ffc010382901b9150614ac8565b8385613ffc011015614ac857613ffc8585030382901c91505b60009450614afc565b6070811115614ae4576070810382901c91505b6001600160701b038216915083818601613f8d010394505b81607086901b888a186001607f1b60801b1660801c6001600160801b0316171760801b95505050505050610d53565b60006f7fffffffffffffffffffffffffffffff608084901c16617fff60701b811115614b5657600080fd5b6f7fffffffffffffffffffffffffffffff608084901c16617fff60701b811115614b7f57600080fd5b6001600160801b0319858116908516141580614ba85750617fff60701b826001600160801b0316105b614bb157600080fd5b6001600160801b031980851690861603614bd057600092505050610d53565b6001607f1b608086811c82118015929187901c919091101590614c21578015614c1357826001600160801b0316846001600160801b031611614c135760016149c4565b600019945050505050610d53565b8015614c34576001945050505050610d53565b826001600160801b0316846001600160801b031611614c55576000196149c4565b6001945050505050610d53565b600080614c826f3ff847ae147ae147b74da9ca30cfea4b60801b84614b2b565b60000b1315614cb257610d536f1ffe4ccccccccccccd1696441415db7b60811b6144d36201000960ee1b85614dd7565b6000614cd16f3ff947ae147ae147b2b11255bc3eff6360801b84614b2b565b60000b1315614d0057610d536f1ffe851eb851eb851edd36a728c33fa960811b6144d361400160f01b85614dd7565b6000614d1f6f01ffcf5c28f5c28f5c4dda7e3300b04d60851b84614b2b565b60000b1315614d4e57610d536f1ffe8f5c28f5c28f5c4dda7e3300b04d60811b6144d361800160ef1b85614dd7565b6000614d6d6f1ffd23d70a3d70a3d831634dc0fb44f760811b84614b2b565b60000b1315614d9b57610d536f3ffd3d70a3d70a3d70eda08184b9b28560801b6144d3600160fe1b85614dd7565b610d536f0fff59999999999999ac0bf76b6bdd4560821b6144d3613fff60f01b85614dd7565b919050565b6000614dd260026155c2565b905090565b6000617fff60f084811c8216919084901c811690829003614e765780617fff03614e52576001600160801b031980851690861603614e2057505050600160ff1b81168218610d53565b6001600160801b031985851816600160ff1b03614e4257505050818117610d53565b5061ffff60ef1b9150610d539050565b600160801b600160ff1b038416600003614878575061ffff60ef1b9150610d539050565b80617fff03614eb457600160801b600160ff1b038516600003614ea3575061ffff60ef1b9150610d539050565b505050600160ff1b82168118610d53565b6001600160701b03608086901c166000839003614ed45760019250614edb565b600160701b175b6001600160701b03608086901c166000839003614efb5760019250614f02565b600160701b175b808202915081600003614f2357600160ff1b878718166149be5760006149c4565b928201926000600160e11b831015614f5657600160e01b831015614f4f57614f4a836157a1565b614f59565b60e0614f59565b60e15b90506140708186011015614f74576000945060009250615011565b6140e08186011015614fb757614070851015614f9957846140700383901c9250614fae565b614070851115614fae57614070850383901b92505b60009450615011565b61c0dd8186011115614fd157617fff945060009250615011565b6070811115614fe8576070810383901c9250614ffb565b6070811015614ffb578060700383901b92505b6001600160701b03831692506140df8186010394505b82607086901b888a186001607f1b60801b1660801c6001600160801b0316171760801b95505050505050610d53565b6000617fff60f084811c8216919084901c81169082900361508c5780617fff03615082576001600160801b031980851690861603614e42578492505050610d53565b8492505050610d53565b80617fff0361509f578392505050610d53565b6001607f1b608086901c90811015906001600160701b031660008490036150c957600193506150d0565b600160701b175b6001607f1b608087901c90811015906001600160701b031660008590036150fa5760019450615101565b600160701b175b82600003615134576001600160801b03198816600160ff1b146151245787615127565b60005b9650505050505050610d53565b80600003615157576001600160801b03198916600160ff1b146151245788615127565b8486038215158515150361526057607081131561517d5789975050505050505050610d53565b600081131561518f5790811c906151be565b606f198112156151a85788975050505050505050610d53565b60008112156151be578060000384901c93508596505b92810192600160711b84106151d9576001968701969390931c925b86617fff0361520a57846151f257617fff60f01b6151fc565b6001600160f01b03195b975050505050505050610d53565b600160701b84101561521f576000965061522c565b6001600160701b03841693505b83607088901b8661523e576000615244565b6001607f1b5b6001600160801b0316171760801b975050505050505050610d53565b600081131561527b57600184901b9350600187039650615292565b600081121561529257600182901b91506001860396505b60708113156152a457600191506152f1565b60018113156152c1576001810360018303901c60010191506152f1565b606f198112156152d457600193506152f1565b6000198112156152f1576001816000030360018503901c60010193505b81841061530257818403935061530b565b83820393508294505b83600003615324575060009650610d5395505050505050565b600061532f856157a1565b90508060710361535457600185901c6001600160701b031694506001880197506153a3565b607081101561539657607081900380891115615383578086901b6001600160701b031695508089039850615390565b600098600019019590951b945b506153a3565b6001600160701b03851694505b87617fff036153d557856153bc57617fff60f01b6153c6565b6001600160f01b03195b98505050505050505050610d53565b84607089901b876153e75760006153ed565b6001607f1b5b6001600160801b0316171760801b98505050505050505050610d53565b60006001607f1b608083901c1115615428575061ffff60ef1b919050565b6001600160801b03198216613fff60f01b0361544657506000919050565b617fff60f083901c81169081900361545f575090919050565b6001600160701b03608084901c16600082900361547f5760019150615486565b600160701b175b8060000361549f57506001600160f01b03199392505050565b600061406f81613fff85106154c55750600f9290921b9160009150613ffe198401615504565b60019250600160701b84106154e75784613ffe039050600f84901b9350615504565b60006154f2856157a1565b607f8190039590951b9461406d039150505b836001607f1b0361553a578215615519576001015b6000615524826157a1565b60700390508082901b9150808303925050615588565b60008361554857600061554b565b60015b60ff1690505b600160701b8210156155865793800260ff81901c607f81019190911c94600019939093019260019290921b9082180190615551565b505b806001600160701b0316607083901b846155a35760006155a9565b6001607f1b5b6001600160801b0316171760801b979650505050505050565b6000816000036155d457506000919050565b8160006155e0826157a1565b905060708110156155f9578060700382901b915061560c565b607081111561560c576070810382901c91505b613fff0160701b6001600160701b03919091161760801b92915050565b6000617fff60f083901c16613fff8110156156475750600092915050565b6001607f1b608084901c1061565b57600080fd5b6140fe81111561566a57600080fd5b600160701b6001600160701b03608085901c161761406f8210156156945761406f8290031c611728565b61406f8211156117285761406e1982011b9392505050565b60006001600160ff1b038211156137545760405162461bcd60e51b815260206004820152602860248201527f53616665436173743a2076616c756520646f65736e27742066697420696e2061604482015267371034b73a191a9b60c11b6064820152608401610926565b6000808212156137545760405162461bcd60e51b815260206004820181905260248201527f53616665436173743a2076616c7565206d75737420626520706f7369746976656044820152606401610926565b60608315615777575081611728565b8251156157875782518084602001fd5b8160405162461bcd60e51b81526004016109269190615c91565b60008082116157af57600080fd5b6000600160801b83106157c457608092831c92015b600160401b83106157d757604092831c92015b600160201b83106157ea57602092831c92015b6201000083106157fc57601092831c92015b610100831061580d57600892831c92015b6010831061581d57600492831c92015b6004831061582d57600292831c92015b60028310610d535760010192915050565b80356001600160a01b0381168114614dc157600080fd5b60006020828403121561586757600080fd5b6117288261583e565b6000806040838503121561588357600080fd5b61588c8361583e565b915061589a6020840161583e565b90509250929050565b60008083601f8401126158b557600080fd5b50813567ffffffffffffffff8111156158cd57600080fd5b6020830191508360208260051b85010111156158e857600080fd5b9250929050565b60008060008060006060868803121561590757600080fd5b6159108661583e565b9450602086013567ffffffffffffffff8082111561592d57600080fd5b61593989838a016158a3565b9096509450604088013591508082111561595257600080fd5b5061595f888289016158a3565b969995985093965092949392505050565b634e487b7160e01b600052604160045260246000fd5b6000806040838503121561599957600080fd5b6159a28361583e565b9150602083013567ffffffffffffffff808211156159bf57600080fd5b818501915085601f8301126159d357600080fd5b8135818111156159e5576159e5615970565b604051601f8201601f19908116603f01168101908382118183101715615a0d57615a0d615970565b81604052828152886020848701011115615a2657600080fd5b8260208601602083013760006020848301015280955050505050509250929050565b60008060408385031215615a5b57600080fd5b615a648361583e565b9150602083013563ffffffff81168114615a7d57600080fd5b809150509250929050565b600080600060408486031215615a9d57600080fd5b615aa68461583e565b9250602084013567ffffffffffffffff811115615ac257600080fd5b615ace868287016158a3565b9497909650939450505050565b602080825282518282018190526000919060409081850190868401855b82811015615b2657815180516001600160a01b03168552860151868501529284019290850190600101615af8565b5091979650505050505050565b60008060008060608587031215615b4957600080fd5b843567ffffffffffffffff811115615b6057600080fd5b615b6c878288016158a3565b9095509350615b7f90506020860161583e565b9150615b8d6040860161583e565b905092959194509250565b60008060408385031215615bab57600080fd5b615bb48361583e565b946020939093013593505050565b60008060008060008060006080888a031215615bdd57600080fd5b615be68861583e565b9650602088013567ffffffffffffffff80821115615c0357600080fd5b615c0f8b838c016158a3565b909850965060408a0135915080821115615c2857600080fd5b615c348b838c016158a3565b909650945060608a0135915080821115615c4d57600080fd5b50615c5a8a828b016158a3565b989b979a50959850939692959293505050565b60005b83811015615c88578181015183820152602001615c70565b50506000910152565b6020815260008251806020840152615cb0816040850160208701615c6d565b601f01601f19169190910160400192915050565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b80820180821115610d5357610d53615cda565b81810381811115610d5357610d53615cda565b600060018201615d2857615d28615cda565b5060010190565b600060208284031215615d4157600080fd5b5051919050565b600060208284031215615d5a57600080fd5b8151801515811461172857600080fd5b8082028115828204841417610d5357610d53615cda565b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b606082015260800190565b80820260008212600160ff1b84141615615de857615de8615cda565b8181058314821517610d5357610d53615cda565b8181036000831280158383131683831282161715615e1c57615e1c615cda565b5092915050565b6000600160ff1b8201615e3857615e38615cda565b5060000390565b634e487b7160e01b600052601260045260246000fd5b600082615e6457615e64615e3f565b500490565b60008251615e7b818460208701615c6d565b9190910192915050565b600082615e9457615e94615e3f565b500690565b634e487b7160e01b600052600160045260246000fdfe5265656e7472616e637947756172643a207265656e7472616e742063616c6c00416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a26469706673582212203fe110dbac2afce103aa95e536ddfc1246e465bc92c902d21e96eadd872e766164736f6c63430008110033
Deployed Bytecode Sourcemap
220221:7627:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;202945:127;;;;;;;;;;-1:-1:-1;202945:127:0;;;;;:::i;:::-;-1:-1:-1;;;;;203046:18:0;203022:4;203046:18;;;:9;:18;;;;;;;;;202945:127;;;;571:14:1;;564:22;546:41;;534:2;519:18;202945:127:0;;;;;;;;202732:90;;;;;;;;;;-1:-1:-1;202813:1:0;202732:90;;;744:25:1;;;732:2;717:18;202732:90:0;598:177:1;210361:271:0;;;;;;;;;;-1:-1:-1;210361:271:0;;;;;:::i;:::-;;:::i;:::-;;226284:1109;;;;;;;;;;-1:-1:-1;226284:1109:0;;;;;:::i;:::-;;:::i;203080:224::-;;;;;;;;;;-1:-1:-1;203080:224:0;;;;;:::i;:::-;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;203270:26:0;;;;;:17;:26;;;;;;;;;203263:33;;;;;;;;;;;;;;;-1:-1:-1;;;;;203263:33:0;;;;;;;;;;-1:-1:-1;;;203263:33:0;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;203263:33:0;;;;;;;-1:-1:-1;;;203263:33:0;;-1:-1:-1;;;;;203263:33:0;;;;;;203080:224;;;;;;;956:4:1;998:3;987:9;983:19;975:27;;1035:6;1029:13;1018:9;1011:32;1090:4;1082:6;1078:17;1072:24;-1:-1:-1;;;;;1205:2:1;1191:12;1187:21;1180:4;1169:9;1165:20;1158:51;1277:2;1269:4;1261:6;1257:17;1251:24;1247:33;1240:4;1229:9;1225:20;1218:63;;;1330:4;1322:6;1318:17;1312:24;1355:10;1423:2;1407:14;1403:23;1396:4;1385:9;1381:20;1374:53;1495:2;1487:4;1479:6;1475:17;1469:24;1465:33;1458:4;1447:9;1443:20;1436:63;;;-1:-1:-1;;;;;1559:4:1;1551:6;1547:17;1541:24;1537:55;1530:4;1519:9;1515:20;1508:85;780:819;;;;;222302:568:0;;;;;;;;;;-1:-1:-1;222302:568:0;;;;;:::i;:::-;;:::i;203312:253::-;;;;;;;;;;-1:-1:-1;203312:253:0;;;;;:::i;:::-;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;203521:27:0;;;;;;;:18;:27;;;;;;;;:36;;;;;;;;;;;;203514:43;;;;;;;;;-1:-1:-1;;;;;203514:43:0;;;;;-1:-1:-1;;;203514:43:0;;;;;;;;;;;;;;-1:-1:-1;;;;;203514:43:0;;;;;;;;;-1:-1:-1;;;203514:43:0;;;-1:-1:-1;;;;;203514:43:0;;;;;;203312:253;;;;;;;2047:4:1;2089:3;2078:9;2074:19;2066:27;;-1:-1:-1;;;;;2192:2:1;2183:6;2177:13;2173:22;2162:9;2155:41;2264:2;2256:4;2248:6;2244:17;2238:24;2234:33;2227:4;2216:9;2212:20;2205:63;;-1:-1:-1;;;;;2328:4:1;2320:6;2316:17;2310:24;2306:51;2299:4;2288:9;2284:20;2277:81;-1:-1:-1;;;;;2418:4:1;2410:6;2406:17;2400:24;2396:57;2389:4;2378:9;2374:20;2367:87;1869:591;;;;;152000:200:0;;;;;;;;;;-1:-1:-1;152000:200:0;;;;;:::i;:::-;;:::i;211091:83::-;;;;;;;;;;;;;:::i;208175:1789::-;;;;;;;;;;-1:-1:-1;208175:1789:0;;;;;:::i;:::-;;:::i;220365:149::-;;;;;;;;;;-1:-1:-1;220440:66:0;220365:149;;210137:216;;;;;;;;;;-1:-1:-1;210137:216:0;;;;;:::i;:::-;;:::i;152459:225::-;;;;;;:::i;:::-;;:::i;151678:133::-;;;;;;;;;;;;;:::i;221677:617::-;;;;;;;;;;-1:-1:-1;221677:617:0;;;;;:::i;:::-;;:::i;164258:86::-;;;;;;;;;;-1:-1:-1;164329:7:0;;;;164258:86;;209972:157;;;;;;;;;;-1:-1:-1;209972:157:0;;;;;:::i;:::-;;:::i;220701:759::-;;;;;;;;;;-1:-1:-1;220701:759:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;227401:444::-;;;;;;;;;;;;;:::i;162209:151::-;;;;;;;;;;;;;:::i;202830:107::-;;;;;;;;;;-1:-1:-1;202916:13:0;;-1:-1:-1;;;;;202916:13:0;202830:107;;;-1:-1:-1;;;;;6914:55:1;;;6896:74;;6884:2;6869:18;202830:107:0;6750:226:1;211004:79:0;;;;;;;;;;;;;:::i;210640:356::-;;;;;;;;;;-1:-1:-1;210640:356:0;;;;;:::i;:::-;;:::i;159605:87::-;;;;;;;;;;-1:-1:-1;159678:6:0;;-1:-1:-1;;;;;159678:6:0;159605:87;;201413:1311;;;;;;;;;;-1:-1:-1;201413:1311:0;;;;;:::i;:::-;;:::i;224434:1406::-;;;;;;;;;;-1:-1:-1;224434:1406:0;;;;;:::i;:::-;;:::i;203573:2117::-;;;;;;;;;;-1:-1:-1;203573:2117:0;;;;;:::i;:::-;;:::i;226056:220::-;;;;;;;;;;-1:-1:-1;226056:220:0;;;;;:::i;:::-;;:::i;225848:200::-;;;;;;;;;;-1:-1:-1;225848:200:0;;;;;:::i;:::-;;:::i;162049:152::-;;;;;;;;;;;;;:::i;205698:2469::-;;;;;;;;;;-1:-1:-1;205698:2469:0;;;;;:::i;:::-;;:::i;221468:201::-;;;;;;;;;;-1:-1:-1;221468:201:0;;;;;:::i;:::-;-1:-1:-1;;;;;221634:27:0;221571:25;221634:27;;;:18;:27;;;;;;;221468:201;161783:258;;;;;;;;;;-1:-1:-1;161783:258:0;;;;;:::i;:::-;;:::i;220522:171::-;;;;;;;;;;-1:-1:-1;220522:171:0;;;;;:::i;:::-;-1:-1:-1;;;;;220634:27:0;;;220607:7;220634:27;;;:18;:27;;;;;;;;:36;;;;;;;;;;;:51;-1:-1:-1;;;220634:51:0;;-1:-1:-1;;;;;220634:51:0;;220522:171;222878:1548;;;;;;;;;;-1:-1:-1;222878:1548:0;;;;;:::i;:::-;;:::i;210361:271::-;159491:13;:11;:13::i;:::-;210471:20:::1;::::0;;;;::::1;::::0;;;::::1;::::0;;-1:-1:-1;;;210471:20:0::1;::::0;::::1;::::0;-1:-1:-1;;;;;210448:21:0;::::1;210440:52;;;;-1:-1:-1::0;;;210440:52:0::1;;;;;;;;:::i;:::-;;;;;;;;;;210503:31;210523:7;210532:1;210503:19;:31::i;:::-;-1:-1:-1::0;;;;;210545:18:0;::::1;210566:5;210545:18:::0;;;:9:::1;:18;::::0;;;;:26;;-1:-1:-1;;210545:26:0::1;::::0;;210587:37:::1;157723:10:::0;210602:12:::1;210587:37;::::0;;-1:-1:-1;;;;;9907:15:1;;;9889:34;;9959:15;;;9954:2;9939:18;;9932:43;9801:18;210587:37:0::1;;;;;;;210361:271:::0;:::o;226284:1109::-;163863:19;:17;:19::i;:::-;155345:1:::1;156120:7;;:19:::0;156112:63:::1;;;::::0;-1:-1:-1;;;156112:63:0;;10188:2:1;156112:63:0::1;::::0;::::1;10170:21:1::0;10227:2;10207:18;;;10200:30;-1:-1:-1;;;;;;;;;;;10246:18:1;;;10239:61;10317:18;;156112:63:0::1;9986:355:1::0;156112:63:0::1;155345:1;156253:7;:18:::0;;;157723:10;226372:17:::2;226490:53:::0;;;:18:::2;:53;::::0;;;;;;;-1:-1:-1;;;;;226490:62:0;::::2;::::0;;;;;;;;;226417:135;;::::2;::::0;;::::2;::::0;;;;-1:-1:-1;;;;;226417:135:0;;::::2;::::0;;-1:-1:-1;;;226417:135:0;;;::::2;::::0;::::2;::::0;;::::2;::::0;;;;::::2;::::0;-1:-1:-1;;;;;226417:135:0;::::2;::::0;;;;-1:-1:-1;;;226417:135:0;::::2;-1:-1:-1::0;;;;;226417:135:0::2;::::0;;;;;;;;226634:50;;;:17:::2;:50:::0;;;;;226563:121;;::::2;::::0;::::2;::::0;;;;;;;;::::2;::::0;;;::::2;::::0;;::::2;::::0;;;;;;;::::2;::::0;;::::2;::::0;;;;;;;;;;::::2;::::0;::::2;::::0;;::::2;::::0;;;;;;;-1:-1:-1;;;226563:121:0;::::2;::::0;;::::2;::::0;;;;;;;-1:-1:-1;;;226563:121:0;::::2;-1:-1:-1::0;;;;;226563:121:0::2;::::0;;;;157723:10;;226563:121;226372:17;226810:61:::2;226563:121:::0;226417:135;226810:24:::2;:61::i;:::-;226697:174;;;;226908:1;226892:13;:17;226911:26;;;;;;;;;;;;;-1:-1:-1::0;;;226911:26:0::2;;::::0;226884:54:::2;;;;;-1:-1:-1::0;;;226884:54:0::2;;;;;;;;:::i;:::-;;226992:266;;;;;;;;227052:52;:40;:50;:52::i;:::-;-1:-1:-1::0;;;;;226992:266:0;;::::2;::::0;;::::2;227119:32:::0;;::::2;::::0;226992:266;::::2;::::0;;::::2;::::0;;227166:25;;::::2;::::0;-1:-1:-1;;;;;226992:266:0;;::::2;::::0;;;;;227206:41;;::::2;::::0;-1:-1:-1;;;;;226992:266:0;;::::2;::::0;;;;;;;-1:-1:-1;;;;;226951:29:0;;::::2;-1:-1:-1::0;226951:29:0;;;:18:::2;:29:::0;;;;;:38;;::::2;::::0;;;;;;;;:307;;;;::::2;::::0;;::::2;-1:-1:-1::0;;;226951:307:0::2;::::0;;;::::2;::::0;;;::::2;::::0;;;;::::2;::::0;;;;::::2;::::0;;;;;::::2;::::0;;;::::2;-1:-1:-1::0;;;226951:307:0::2;-1:-1:-1::0;;;;;;226951:307:0;;;;;;::::2;::::0;;;;::::2;::::0;;227271:54:::2;226970:9:::0;227311:13;227271:28:::2;:54::i;:::-;227343:42;::::0;;-1:-1:-1;;;;;10627:15:1;;;10609:34;;10679:15;;10674:2;10659:18;;10652:43;10711:18;;;10704:34;;;227343:42:0::2;::::0;10536:2:1;10521:18;227343:42:0::2;;;;;;;-1:-1:-1::0;;155301:1:0::1;156432:7;:22:::0;-1:-1:-1;;;;226284:1109:0:o;222302:568::-;-1:-1:-1;;;;;222533:50:0;;;222437:7;222533:50;;;:17;:50;;;;;;;;222462:121;;;;;;;;;;;;;;;;-1:-1:-1;;;;;222462:121:0;;;;;;;-1:-1:-1;;;222462:121:0;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;222462:121:0;;;;;;;;;;;;;-1:-1:-1;;;222462:121:0;;;-1:-1:-1;;;;;222462:121:0;;;;;222667:51;;;;;:18;:51;;;;;:60;;;;;;;;;222594:133;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;222594:133:0;;;;;;;;;-1:-1:-1;;;222594:133:0;;-1:-1:-1;;;;;222594:133:0;;;;;;;;222437:7;222462:121;222437:7;222768:61;222462:121;222594:133;222768:24;:61::i;:::-;-1:-1:-1;222740:89:0;-1:-1:-1;;;;222302:568:0;;;;;:::o;152000:200::-;-1:-1:-1;;;;;150550:6:0;150533:23;150541:4;150533:23;150525:80;;;;-1:-1:-1;;;150525:80:0;;10951:2:1;150525:80:0;;;10933:21:1;10990:2;10970:18;;;10963:30;11029:34;11009:18;;;11002:62;-1:-1:-1;;;11080:18:1;;;11073:42;11132:19;;150525:80:0;10749:408:1;150525:80:0;150648:6;-1:-1:-1;;;;;150624:30:0;:20;141976:66;142337:65;-1:-1:-1;;;;;142337:65:0;;142257:153;150624:20;-1:-1:-1;;;;;150624:30:0;;150616:87;;;;-1:-1:-1;;;150616:87:0;;11364:2:1;150616:87:0;;;11346:21:1;11403:2;11383:18;;;11376:30;11442:34;11422:18;;;11415:62;-1:-1:-1;;;11493:18:1;;;11486:42;11545:19;;150616:87:0;11162:408:1;150616:87:0;152084:36:::1;152102:17;152084;:36::i;:::-;152172:12;::::0;;152182:1:::1;152172:12:::0;;;::::1;::::0;::::1;::::0;;;152131:61:::1;::::0;152153:17;;152172:12;152131:21:::1;:61::i;:::-;152000:200:::0;:::o;211091:83::-;201221:13;;-1:-1:-1;;;;;201221:13:0;157723:10;-1:-1:-1;;;;;201205:29:0;;201236:31;;;;;;;;;;;;;-1:-1:-1;;;201236:31:0;;;201197:71;;;;;-1:-1:-1;;;201197:71:0;;;;;;;;:::i;:::-;;211156:10:::1;:8;:10::i;:::-;211091:83::o:0;208175:1789::-;219813:11;;201100:29;;;;;;;;;;;;-1:-1:-1;;;201100:29:0;;;;;-1:-1:-1;;;;;219813:11:0;157723:10;201066:32;201058:72;;;;-1:-1:-1;;;201058:72:0;;;;;;;;:::i;:::-;;163863:19:::1;:17;:19::i;:::-;208366:15:::2;208417:8:::0;208366:15;;208537:70:::2;-1:-1:-1::0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;208537:70:0::2;-1:-1:-1::0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;208699:1156:0::2;208720:14;208715:1;:19;208699:1156;;208764:9;:22;208774:8;;208783:1;208774:11;;;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;208764:22:0::2;::::0;;::::2;::::0;;::::2;::::0;;;;;;;;-1:-1:-1;208764:22:0;;208788:29;;;;::::2;::::0;;;::::2;::::0;;-1:-1:-1;;;208788:29:0;;::::2;::::0;;;;;208764:22:::2;;208756:62;;;;-1:-1:-1::0;;;208756:62:0::2;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;;208855:27:0;::::2;;::::0;;;:18:::2;:27;::::0;;;;;208883:8;;208892:1;208883:11;;::::2;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;208855:40:0::2;::::0;;::::2;::::0;;::::2;::::0;;;;;;;;-1:-1:-1;208855:40:0;208835:60;;::::2;::::0;::::2;::::0;;;;-1:-1:-1;;;;;208835:60:0;;::::2;::::0;;-1:-1:-1;;;208835:60:0;;::::2;;::::0;;::::2;::::0;;;;;::::2;::::0;-1:-1:-1;;;;;208835:60:0;::::2;::::0;;;;;;;-1:-1:-1;;;208835:60:0;::::2;-1:-1:-1::0;;;;;208835:60:0::2;::::0;;;;;-1:-1:-1;208983:14:0;;208998:1;208983:17;;::::2;;;;;:::i;:::-;;;;;;;208938;:41;;;-1:-1:-1::0;;;;;208938:62:0::2;;;209019:59;;;;;;;;;;;;;-1:-1:-1::0;;;209019:59:0::2;;::::0;208912:181:::2;;;;;-1:-1:-1::0;;;208912:181:0::2;;;;;;;;:::i;:::-;;209129:17;:30;209147:8;;209156:1;209147:11;;;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;209129:30:0::2;::::0;;::::2;::::0;;::::2;::::0;;;;;;;;-1:-1:-1;209129:30:0;209110:49;;::::2;::::0;::::2;::::0;;;;;;::::2;::::0;::::2;::::0;-1:-1:-1;;;;;209110:49:0;;::::2;::::0;;::::2;::::0;;;;-1:-1:-1;;;209110:49:0;::::2;::::0;;::::2;::::0;;;;;;;::::2;;::::0;::::2;::::0;;::::2;::::0;;;;-1:-1:-1;;;209110:49:0;::::2;;::::0;;;;-1:-1:-1;;;209110:49:0;::::2;-1:-1:-1::0;;;;;209110:49:0::2;::::0;;;;;-1:-1:-1;209239:110:0::2;209110:49:::0;209317:17;209239:24:::2;:110::i;:::-;209176:173:::0;;-1:-1:-1;209176:173:0;-1:-1:-1;209366:27:0::2;209176:173:::0;209366:27;::::2;:::i;:::-;;;209410:352;209449:7;209475:8;;209484:1;209475:11;;;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;209505:40;209564:16;209599:17;209635;:32;;;-1:-1:-1::0;;;;;209410:352:0::2;209730:14;;209745:1;209730:17;;;;;;;:::i;:::-;;;;;;;209686;:41;;;-1:-1:-1::0;;;;;209686:61:0::2;;;;;:::i;:::-;209410:20;:352::i;:::-;209784:59;209803:7;209812:8;;209821:1;209812:11;;;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;209825:14;;209840:1;209825:17;;;;;;;:::i;:::-;;;;;;;209784:59;;;;;;;-1:-1:-1::0;;;;;10627:15:1;;;10609:34;;10679:15;;;;10674:2;10659:18;;10652:43;10726:2;10711:18;;10704:34;;;;10536:2;10521:18;;10346:398;209784:59:0::2;;;;;;;;208736:3;::::0;::::2;:::i;:::-;;;208699:1156;;;-1:-1:-1::0;209871:11:0;;209867:90:::2;;209899:46;209928:7;209937;209899:28;:46::i;:::-;208355:1609;;;;;;208175:1789:::0;;;;;:::o;210137:216::-;159491:13;:11;:13::i;:::-;210235:20:::1;::::0;;;;::::1;::::0;;;::::1;::::0;;-1:-1:-1;;;210235:20:0::1;::::0;::::1;::::0;-1:-1:-1;;;;;210212:21:0;::::1;210204:52;;;;-1:-1:-1::0;;;210204:52:0::1;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;;210267:18:0;::::1;;::::0;;;:9:::1;:18;::::0;;;;:25;;-1:-1:-1;;210267:25:0::1;210288:4;210267:25;::::0;;210310:35:::1;210323:12;157723:10:::0;;157643:98;152459:225;-1:-1:-1;;;;;150550:6:0;150533:23;150541:4;150533:23;150525:80;;;;-1:-1:-1;;;150525:80:0;;10951:2:1;150525:80:0;;;10933:21:1;10990:2;10970:18;;;10963:30;11029:34;11009:18;;;11002:62;-1:-1:-1;;;11080:18:1;;;11073:42;11132:19;;150525:80:0;10749:408:1;150525:80:0;150648:6;-1:-1:-1;;;;;150624:30:0;:20;141976:66;142337:65;-1:-1:-1;;;;;142337:65:0;;142257:153;150624:20;-1:-1:-1;;;;;150624:30:0;;150616:87;;;;-1:-1:-1;;;150616:87:0;;11364:2:1;150616:87:0;;;11346:21:1;11403:2;11383:18;;;11376:30;11442:34;11422:18;;;11415:62;-1:-1:-1;;;11493:18:1;;;11486:42;11545:19;;150616:87:0;11162:408:1;150616:87:0;152577:36:::1;152595:17;152577;:36::i;:::-;152624:52;152646:17;152665:4;152671;152624:21;:52::i;:::-;152459:225:::0;;:::o;151678:133::-;151756:7;150986:4;-1:-1:-1;;;;;150995:6:0;150978:23;;150970:92;;;;-1:-1:-1;;;150970:92:0;;12444:2:1;150970:92:0;;;12426:21:1;12483:2;12463:18;;;12456:30;12522:34;12502:18;;;12495:62;12593:26;12573:18;;;12566:54;12637:19;;150970:92:0;12242:420:1;150970:92:0;-1:-1:-1;141976:66:0::1;151678:133:::0;:::o;221677:617::-;-1:-1:-1;;;;;221850:50:0;;221759:7;221850:50;;;:17;:50;;;;;;;;221779:121;;;;;;;;;;;;;;;;-1:-1:-1;;;;;221779:121:0;;;;;;;;;;-1:-1:-1;;;221779:121:0;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;221779:121:0;;;;;;;-1:-1:-1;;;221779:121:0;;-1:-1:-1;;;;;221779:121:0;;;;;;221915:39;;221911:110;;221978:31;;;-1:-1:-1;;;;;221971:38:0;;221677:617;-1:-1:-1;;221677:617:0:o;221911:110::-;222051:235;222111:12;222142:16;:28;;;222051:235;;222189:16;:32;;;222051:235;;222240:16;:31;;;-1:-1:-1;;;;;222051:235:0;:41;:235::i;:::-;222031:255;221677:617;-1:-1:-1;;;221677:617:0:o;209972:157::-;159491:13;:11;:13::i;:::-;210078:43:::1;210098:7;210107:13;210078:19;:43::i;220701:759::-:0;220850:62;220955:8;;220992:66;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;;;;;;;220992:66:0;;;;;;;;;;;;;;;;220981:77;;221069:15;221102:9;221097:356;221118:14;221113:1;:19;221097:356;;221164:8;;221173:1;221164:11;;;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;221198:18:0;;;;;;:9;:18;;;;;;;;;;221218:29;;;;;;;;;;;-1:-1:-1;;;221218:29:0;;;;;;;221154:21;;-1:-1:-1;221218:29:0;221198:18;;221190:58;;;;-1:-1:-1;;;221190:58:0;;;;;;;;:::i;:::-;-1:-1:-1;221277:164:0;;;;;;;;-1:-1:-1;;;;;221277:164:0;;;;;;221366:27;;;-1:-1:-1;221366:27:0;;;:18;221277:164;221366:27;;;;;;:36;;;;;;;;;;:60;;;-1:-1:-1;;;221366:60:0;;-1:-1:-1;;;;;221366:60:0;221277:164;;;;;;;221263:11;;;;221272:1;;221263:11;;;;;;:::i;:::-;;;;;;:178;;;;221134:3;;;;:::i;:::-;;;221097:356;;;;220919:541;;220701:759;;;;;:::o;227401:444::-;163863:19;:17;:19::i;:::-;155345:1:::1;156120:7;;:19:::0;156112:63:::1;;;::::0;-1:-1:-1;;;156112:63:0;;10188:2:1;156112:63:0::1;::::0;::::1;10170:21:1::0;10227:2;10207:18;;;10200:30;-1:-1:-1;;;;;;;;;;;10246:18:1;;;10239:61;10317:18;;156112:63:0::1;9986:355:1::0;156112:63:0::1;155345:1;156253:7;:18:::0;157723:10;227491:17:::2;227561:29:::0;;;:18:::2;:29;::::0;;;;;;;;;227631:26;;;;::::2;::::0;;;::::2;::::0;;-1:-1:-1;;;227631:26:0;;::::2;::::0;;;;227561:29;;227601:57:::2;;;;-1:-1:-1::0;;;227601:57:0::2;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;;227669:29:0;::::2;227701:1;227669:29:::0;;;:18:::2;:29;::::0;;;;:33;227713:57:::2;227688:9:::0;227753:16;227713:28:::2;:57::i;:::-;227786:51;::::0;;-1:-1:-1;;;;;12859:55:1;;12841:74;;12946:2;12931:18;;12924:34;;;227786:51:0::2;::::0;12814:18:1;227786:51:0::2;;;;;;;-1:-1:-1::0;;155301:1:0::1;156432:7;:22:::0;227401:444::o;162209:151::-;159491:13;:11;:13::i;:::-;162283:30:::1;162310:1;162283:18;:30::i;:::-;162324:15;:28:::0;;-1:-1:-1;;;;;;162324:28:0::1;::::0;;162209:151::o;211004:79::-;201221:13;;-1:-1:-1;;;;;201221:13:0;157723:10;-1:-1:-1;;;;;201205:29:0;;201236:31;;;;;;;;;;;;;-1:-1:-1;;;201236:31:0;;;201197:71;;;;;-1:-1:-1;;;201197:71:0;;;;;;;;:::i;:::-;;211067:8:::1;:6;:8::i;210640:356::-:0;159491:13;:11;:13::i;:::-;210776:20:::1;::::0;;;;::::1;::::0;;;::::1;::::0;;-1:-1:-1;;;210776:20:0::1;::::0;::::1;::::0;-1:-1:-1;;;;;210741:33:0;::::1;210733:64;;;;-1:-1:-1::0;;;210733:64:0::1;;;;;;;;:::i;:::-;-1:-1:-1::0;210838:13:0::1;::::0;;-1:-1:-1;;;;;210862:35:0;;::::1;-1:-1:-1::0;;;;;;210862:35:0;::::1;::::0;::::1;::::0;;;210838:13:::1;::::0;;210933:12:::1;157723:10:::0;;157643:98;210933:12:::1;-1:-1:-1::0;;;;;210913:75:0::1;;;;;;;;;;;210722:274;210640:356:::0;:::o;201413:1311::-;138197:19;138220:13;;;;;;138219:14;;138267:34;;;;-1:-1:-1;138285:12:0;;138300:1;138285:12;;;;:16;138267:34;138266:108;;;-1:-1:-1;138346:4:0;128959:19;:23;;;138307:66;;-1:-1:-1;138356:12:0;;;;;:17;138307:66;138244:204;;;;-1:-1:-1;;;138244:204:0;;13171:2:1;138244:204:0;;;13153:21:1;13210:2;13190:18;;;13183:30;13249:34;13229:18;;;13222:62;-1:-1:-1;;;13300:18:1;;;13293:44;13354:19;;138244:204:0;12969:410:1;138244:204:0;138459:12;:16;;-1:-1:-1;;138459:16:0;138474:1;138459:16;;;138486:67;;;;138521:13;:20;;-1:-1:-1;;138521:20:0;;;;;138486:67;201567:27:::1;:25;:27::i;:::-;201605:26;:24;:26::i;:::-;201642:34;:32;:34::i;:::-;201723:20;::::0;;;;::::1;::::0;;;::::1;::::0;;-1:-1:-1;;;201723:20:0::1;::::0;::::1;::::0;-1:-1:-1;;;;;201697:24:0;::::1;201689:55;;;;-1:-1:-1::0;;;201689:55:0::1;;;;;;;;:::i;:::-;;200467:66;201820:15;;201789:10;-1:-1:-1::0;;;;;201777:37:0::1;;:39;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:58;201850:24;;;;;;;;;;;;;-1:-1:-1::0;;;201850:24:0::1;;::::0;201755:130:::1;;;;;-1:-1:-1::0;;;201755:130:0::1;;;;;;;;:::i;:::-;-1:-1:-1::0;201931:20:0::1;::::0;;;;::::1;::::0;;;::::1;::::0;;-1:-1:-1;;;201931:20:0::1;::::0;::::1;::::0;-1:-1:-1;;;;;201904:25:0;::::1;201896:56;;;;-1:-1:-1::0;;;201896:56:0::1;;;;;;;;:::i;:::-;;200341:66;202030:16;;201998:11;-1:-1:-1::0;;;;;201985:39:0::1;;:41;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:61;202061:24;;;;;;;;;;;;;-1:-1:-1::0;;;202061:24:0::1;;::::0;201963:133:::1;;;;;-1:-1:-1::0;;;201963:133:0::1;;;;;;;;:::i;:::-;-1:-1:-1::0;202162:11:0::1;:24:::0;;-1:-1:-1;;;;;;202162:24:0::1;-1:-1:-1::0;;;;;202162:24:0;::::1;;::::0;;202134:8;157723:10;202197:13:::1;:28:::0;;-1:-1:-1;;;;;;202197:28:0::1;-1:-1:-1::0;;;;;202197:28:0;;::::1;;::::0;;202238:66:::1;::::0;-1:-1:-1;;;202238:66:0;;12859:55:1;;;202238:66:0::1;::::0;::::1;12841:74:1::0;-1:-1:-1;;12931:18:1;;;12924:34;202238:33:0;;::::1;::::0;::::1;::::0;12814:18:1;;202238:66:0::1;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;202322:9;202317:400;202338:14;202333:1;:19;202317:400;;202405:1;202382:8:::0;;202391:1;202382:11;;::::1;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;202382:25:0::1;;;202409:20;;;;;;;;;;;;;-1:-1:-1::0;;;202409:20:0::1;;::::0;202374:56:::1;;;;;-1:-1:-1::0;;;202374:56:0::1;;;;;;;;:::i;:::-;;202472:4;202447:9;:22;202457:8;;202466:1;202457:11;;;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;202447:22:0::1;::::0;;::::1;::::0;;::::1;::::0;;;;;;;;-1:-1:-1;202447:22:0;;;:29;;-1:-1:-1;;202447:29:0::1;::::0;::::1;;::::0;;;::::1;::::0;;;202526:179;;::::1;::::0;::::1;::::0;;;;;;;::::1;::::0;;;;;;;;;;;;;;;;;;;;;;;;;;;202493:17:::1;::::0;202511:8;;202520:1;202511:11;;::::1;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;202493:30:0::1;::::0;;::::1;::::0;;::::1;::::0;;;;;;;;-1:-1:-1;202493:30:0;:212;;;;;;::::1;::::0;;;::::1;::::0;-1:-1:-1;;;;;202493:212:0;;::::1;-1:-1:-1::0;;;202493:212:0::1;::::0;::::1;;;::::0;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;;::::1;::::0;;::::1;::::0;::::1;::::0;::::1;::::0;;::::1;::::0;-1:-1:-1;;;;;202493:212:0::1;-1:-1:-1::0;;;202493:212:0::1;-1:-1:-1::0;;;;202493:212:0::1;::::0;;::::1;-1:-1:-1::0;;;202493:212:0::1;-1:-1:-1::0;;202493:212:0;;;;;;::::1;::::0;;;;::::1;::::0;;;::::1;::::0;;;::::1;::::0;;202354:3:::1;::::0;::::1;:::i;:::-;;;202317:400;;;;201556:1168;138579:14:::0;138575:102;;;138626:5;138610:21;;-1:-1:-1;;138610:21:0;;;138651:14;;-1:-1:-1;14007:36:1;;138651:14:0;;13995:2:1;13980:18;138651:14:0;;;;;;;138575:102;138186:498;201413:1311;;;;:::o;224434:1406::-;155345:1;156120:7;;:19;156112:63;;;;-1:-1:-1;;;156112:63:0;;10188:2:1;156112:63:0;;;10170:21:1;10227:2;10207:18;;;10200:30;-1:-1:-1;;;;;;;;;;;10246:18:1;;;10239:61;10317:18;;156112:63:0;9986:355:1;156112:63:0;155345:1;156253:7;:18;163863:19:::1;:17;:19::i;:::-;224613:34:::2;::::0;;;;::::2;::::0;;;::::2;::::0;;-1:-1:-1;;;224613:34:0::2;::::0;::::2;::::0;224594:17;224586:62:::2;;;;-1:-1:-1::0;;;224586:62:0::2;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;;224667:18:0;::::2;;::::0;;;:9:::2;:18;::::0;;;;;;;;;224687:29;;;;::::2;::::0;;;::::2;::::0;;-1:-1:-1;;;224687:29:0;;::::2;::::0;;;;224667:18:::2;;224659:58;;;;-1:-1:-1::0;;;224659:58:0::2;;;;;;;;:::i;:::-;-1:-1:-1::0;224730:17:0::2;157723:10:::0;224775:80:::2;::::0;-1:-1:-1;;;224775:80:0;;-1:-1:-1;;;;;10627:15:1;;;224775:80:0::2;::::0;::::2;10609:34:1::0;224834:4:0::2;10659:18:1::0;;;10652:43;10711:18;;;10704:34;;;224730:32:0;;-1:-1:-1;224775:39:0;;::::2;::::0;::::2;::::0;10521:18:1;;224775:80:0::2;;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;;224941:53:0;;::::2;224868:70;224941:53:::0;;;:18:::2;:53;::::0;;;;;;;:62;;::::2;::::0;;;;;;;;;224868:135;;::::2;::::0;;::::2;::::0;;;;-1:-1:-1;;;;;224868:135:0;;::::2;::::0;;-1:-1:-1;;;224868:135:0;;;::::2;::::0;::::2;::::0;;::::2;::::0;;;;::::2;::::0;-1:-1:-1;;;;;224868:135:0;::::2;::::0;;;;-1:-1:-1;;;224868:135:0;::::2;-1:-1:-1::0;;;;;224868:135:0::2;::::0;;;;;;;;225085:50;;;:17:::2;:50:::0;;;;;225014:121;;::::2;::::0;::::2;::::0;;;;;;;;::::2;::::0;;;::::2;::::0;;::::2;::::0;;;;;;;::::2;::::0;;::::2;::::0;;;;;;;::::2;::::0;;::::2;::::0;::::2;::::0;;::::2;::::0;;;;;;;-1:-1:-1;;;225014:121:0;::::2;::::0;;::::2;::::0;;;;;;;-1:-1:-1;;;225014:121:0;;::::2;-1:-1:-1::0;;;;;225014:121:0::2;::::0;;;;224868:135;225014:121;224868:70;225261:61:::2;225014:121:::0;224868:135;225261:24:::2;:61::i;:::-;225148:174;;;;225335:314;225370:9;225394:7;225416:40;225471:16;225502:17;225569:13;225534:17;:32;;;-1:-1:-1::0;;;;;225534:48:0::2;;;;;:::i;:::-;225597:17;:41;;;-1:-1:-1::0;;;;;225335:314:0::2;:20;:314::i;:::-;225666:17:::0;;225662:104:::2;;225700:54;225729:9;225740:13;225700:28;:54::i;:::-;225783:49;::::0;;-1:-1:-1;;;;;10627:15:1;;;10609:34;;10679:15;;10674:2;10659:18;;10652:43;10711:18;;;10704:34;;;225783:49:0::2;::::0;10536:2:1;10521:18;225783:49:0::2;;;;;;;-1:-1:-1::0;;155301:1:0;156432:7;:22;-1:-1:-1;;;;;224434:1406:0:o;203573:2117::-;219813:11;;201100:29;;;;;;;;;;;;-1:-1:-1;;;201100:29:0;;;;;-1:-1:-1;;;;;219813:11:0;157723:10;201066:32;201058:72;;;;-1:-1:-1;;;201058:72:0;;;;;;;;:::i;:::-;;163863:19:::1;:17;:19::i;:::-;203771:15:::2;203822:8:::0;203771:15;;203942:70:::2;-1:-1:-1::0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;203942:70:0::2;-1:-1:-1::0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;204104:1477:0::2;204125:14;204120:1;:19;204104:1477;;204169:9;:22;204179:8;;204188:1;204179:11;;;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;204169:22:0::2;::::0;;::::2;::::0;;::::2;::::0;;;;;;;;-1:-1:-1;204169:22:0;;204193:29;;;;::::2;::::0;;;::::2;::::0;;-1:-1:-1;;;204193:29:0;;::::2;::::0;;;;;204169:22:::2;;204161:62;;;;-1:-1:-1::0;;;204161:62:0::2;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;;204260:27:0;::::2;;::::0;;;:18:::2;:27;::::0;;;;;204288:8;;204297:1;204288:11;;::::2;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;204260:40:0::2;::::0;;::::2;::::0;;::::2;::::0;;;;;;;;-1:-1:-1;204260:40:0;;;204240:60;;::::2;::::0;::::2;::::0;;;;-1:-1:-1;;;;;204240:60:0;;::::2;::::0;;-1:-1:-1;;;204240:60:0;;::::2;;::::0;;::::2;::::0;;;;;::::2;::::0;-1:-1:-1;;;;;204240:60:0;::::2;::::0;;;;;;;-1:-1:-1;;;204240:60:0;;::::2;-1:-1:-1::0;;;;;204240:60:0::2;::::0;;;;;;-1:-1:-1;204334:17:0::2;::::0;204352:8;;204361:1;204352:11;;::::2;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;204334:30:0::2;::::0;;::::2;::::0;;::::2;::::0;;;;;;;;-1:-1:-1;204334:30:0;;;204315:49;;::::2;::::0;::::2;::::0;;;;;;::::2;::::0;::::2;::::0;-1:-1:-1;;;;;204315:49:0;;::::2;::::0;;::::2;::::0;-1:-1:-1;;;204315:49:0;;::::2;::::0;::::2;::::0;;;;;;;::::2;::::0;;::::2;::::0;::::2;::::0;;::::2;::::0;;;;-1:-1:-1;;;204315:49:0;::::2;;::::0;;;;-1:-1:-1;;;204315:49:0;::::2;-1:-1:-1::0;;;;;204315:49:0::2;::::0;;;;204497:32;;::::2;::::0;204315:49;;-1:-1:-1;204497:37:0;::::2;::::0;;204493:397:::2;;204555:18;204620:14;;204635:1;204620:17;;;;;;;:::i;:::-;;;;;;;204576;:41;;;-1:-1:-1::0;;;;;204576:61:0::2;;;;;:::i;:::-;204555:82;;204723:43;:10;:41;:43::i;:::-;-1:-1:-1::0;;;;;204656:27:0;::::2;;::::0;;;:18:::2;:27;::::0;;;;;204684:8;;204693:1;204684:11;;::::2;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;204656:40:0::2;-1:-1:-1::0;;;;;204656:40:0::2;;;;;;;;;;;;:64;;;:110;;;;;-1:-1:-1::0;;;;;204656:110:0::2;;;;;-1:-1:-1::0;;;;;204656:110:0::2;;;;;;204790:57;204807:7;204816:8;;204825:1;204816:11;;;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;204829:14;;204844:1;204829:17;;;;;;;:::i;:::-;;;;;;;204790:57;;;;;;;-1:-1:-1::0;;;;;10627:15:1;;;10609:34;;10679:15;;;;10674:2;10659:18;;10652:43;10726:2;10711:18;;10704:34;;;;10536:2;10521:18;;10346:398;204790:57:0::2;;;;;;;;204866:8;;;204493:397;204969:110;205012:16;205047:17;204969:24;:110::i;:::-;204906:173:::0;;-1:-1:-1;204906:173:0;-1:-1:-1;205096:27:0::2;204906:173:::0;205096:27;::::2;:::i;:::-;;;205140:352;205179:7;205205:8;;205214:1;205205:11;;;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;205235:40;205294:16;205329:17;205365;:32;;;-1:-1:-1::0;;;;;205140:352:0::2;205460:14;;205475:1;205460:17;;;;;;;:::i;:::-;;;;;;;205416;:41;;;-1:-1:-1::0;;;;;205416:61:0::2;;;;;:::i;205140:352::-;205512:57;205529:7;205538:8;;205547:1;205538:11;;;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;205551:14;;205566:1;205551:17;;;;;;;:::i;:::-;;;;;;;205512:57;;;;;;;-1:-1:-1::0;;;;;10627:15:1;;;10609:34;;10679:15;;;;10674:2;10659:18;;10652:43;10726:2;10711:18;;10704:34;;;;10536:2;10521:18;;10346:398;205512:57:0::2;;;;;;;;204104:1477;204141:3;::::0;::::2;:::i;:::-;;;204104:1477;;226056:220:::0;155345:1;156120:7;;:19;156112:63;;;;-1:-1:-1;;;156112:63:0;;10188:2:1;156112:63:0;;;10170:21:1;10227:2;10207:18;;;10200:30;-1:-1:-1;;;;;;;;;;;10246:18:1;;;10239:61;10317:18;;156112:63:0;9986:355:1;156112:63:0;155345:1;156253:7;:18;163863:19:::1;:17;:19::i;:::-;226229:39:::2;226238:7;226247:13;226262:5;226229:8;:39::i;:::-;-1:-1:-1::0;;155301:1:0;156432:7;:22;226056:220::o;225848:200::-;155345:1;156120:7;;:19;156112:63;;;;-1:-1:-1;;;156112:63:0;;10188:2:1;156112:63:0;;;10170:21:1;10227:2;10207:18;;;10200:30;-1:-1:-1;;;;;;;;;;;10246:18:1;;;10239:61;10317:18;;156112:63:0;9986:355:1;156112:63:0;155345:1;156253:7;:18;163863:19:::1;:17;:19::i;:::-;226002:38:::2;226011:7;226020:13;226035:4;226002:8;:38::i;162049:152::-:0;161688:15;;161721:33;;;;;;;;;;;;-1:-1:-1;;;161721:33:0;;;;;-1:-1:-1;;;;;161688:15:0;157723:10;161688:31;161680:75;;;;-1:-1:-1;;;161680:75:0;;;;;;;;:::i;:::-;-1:-1:-1;162122:15:0::1;:28:::0;;-1:-1:-1;;;;;;162122:28:0::1;::::0;;162161:32:::1;157723:10:::0;162161:18:::1;:32::i;205698:2469::-:0;219813:11;;201100:29;;;;;;;;;;;;-1:-1:-1;;;201100:29:0;;;;;-1:-1:-1;;;;;219813:11:0;157723:10;201066:32;201058:72;;;;-1:-1:-1;;;201058:72:0;;;;;;;;:::i;:::-;;163863:19:::1;:17;:19::i;:::-;205955:15:::2;205981:21:::0;206013::::2;206052:9:::0;206047:2011:::2;206063:20:::0;;::::2;206047:2011;;206113:9;:22;206123:8;;206132:1;206123:11;;;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;206113:22:0::2;::::0;;::::2;::::0;;::::2;::::0;;;;;;;;-1:-1:-1;206113:22:0;;206137:29;;;;::::2;::::0;;;::::2;::::0;;-1:-1:-1;;;206137:29:0;;::::2;::::0;;;;;206113:22:::2;;206105:62;;;;-1:-1:-1::0;;;206105:62:0::2;;;;;;;;:::i;:::-;;206198:14;;206213:1;206198:17;;;;;;;:::i;:::-;;;;;;;206182:33;;206246:14;;206261:1;206246:17;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;206370:27:0;::::2;206280:87;206370:27:::0;;;:18:::2;206246:17;206370:27:::0;;;;;;206246:17;::::2;::::0;;;::::2;;::::0;-1:-1:-1;206370:27:0;-1:-1:-1;206280:87:0;206398:8;;206407:1;206398:11;;::::2;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;206370:40:0::2;::::0;;::::2;::::0;;::::2;::::0;;;;;;;;-1:-1:-1;206370:40:0;;;206280:130;;::::2;::::0;::::2;::::0;;;;-1:-1:-1;;;;;206280:130:0;;::::2;::::0;;-1:-1:-1;;;206280:130:0;;::::2;;::::0;;::::2;::::0;;;;;::::2;::::0;-1:-1:-1;;;;;206280:130:0;::::2;::::0;;;;;;;-1:-1:-1;;;206280:130:0;;::::2;-1:-1:-1::0;;;;;206280:130:0::2;::::0;;;;;;-1:-1:-1;206513:17:0::2;-1:-1:-1::0;206531:8:0;;206540:1;206531:11;;::::2;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;206513:30:0::2;::::0;;::::2;::::0;;::::2;::::0;;;;;;;;-1:-1:-1;206513:30:0;206425:118;;::::2;::::0;::::2;::::0;;;;;;::::2;::::0;::::2;::::0;-1:-1:-1;;;;;206425:118:0;;::::2;::::0;;::::2;::::0;;;;-1:-1:-1;;;206425:118:0;::::2;::::0;;::::2;::::0;;;;;;;::::2;;::::0;::::2;::::0;;::::2;::::0;;;;-1:-1:-1;;;206425:118:0;::::2;;::::0;;;;-1:-1:-1;;;206425:118:0;::::2;-1:-1:-1::0;;;;;206425:118:0::2;::::0;;;;;-1:-1:-1;206662:17:0;;206658:140:::2;;206718:8;;206727:1;206718:11;;;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;206700:82;::::0;-1:-1:-1;;;206700:82:0;;-1:-1:-1;;;;;10627:15:1;;;206700:82:0::2;::::0;::::2;10609:34:1::0;206761:4:0::2;10659:18:1::0;;;10652:43;10711:18;;;10704:34;;;206700:43:0;;;::::2;::::0;::::2;::::0;10521:18:1;;206700:82:0::2;;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;206658:140;206849:32;::::0;::::2;::::0;-1:-1:-1;;;;;206849:37:0::2;::::0;:59;::::2;;;-1:-1:-1::0;206890:18:0;;206849:59:::2;206845:384;;;207018:91;207084:13;207019:17;:41;;;-1:-1:-1::0;;;;;207019:78:0::2;;;;;:::i;:::-;207018:89;:91::i;:::-;-1:-1:-1::0;;;;;206929:27:0;::::2;;::::0;;;:18:::2;:27;::::0;;;;;206957:8;;206966:1;206957:11;;::::2;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;206929:40:0::2;-1:-1:-1::0;;;;;206929:40:0::2;;;;;;;;;;;;:86;;;:180;;;;;-1:-1:-1::0;;;;;206929:180:0::2;;;;;-1:-1:-1::0;;;;;206929:180:0::2;;;;;;207133:53;207150:7;207159:8;;207168:1;207159:11;;;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;207133:53;::::0;;-1:-1:-1;;;;;10627:15:1;;;10609:34;;10679:15;;;;10674:2;10659:18;;10652:43;10711:18;;10704:34;;;10536:2;10521:18;207133:53:0::2;;;;;;;207205:8;;;;206845:384;207264:24;207307:48:::0;207373:61:::2;207398:16;207416:17;207373:24;:61::i;:::-;207245:189:::0;;-1:-1:-1;207245:189:0;-1:-1:-1;207451:27:0::2;207245:189:::0;207451:27;::::2;:::i;:::-;;;207495:364;207534:7;207560:8;;207569:1;207560:11;;;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;207590:40;207649:16;207684:17;207755:13;207720:17;:32;;;-1:-1:-1::0;;;;;207720:48:0::2;;;;;:::i;:::-;207831:13;207787:17;:41;;;-1:-1:-1::0;;;;;207787:57:0::2;;;;;:::i;207495:364::-;207879:167;207930:7;207956:8;;207965:1;207956:11;;;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;207879:167;::::0;;-1:-1:-1;;;;;14364:15:1;;;14346:34;;14416:15;;;;14411:2;14396:18;;14389:43;14448:18;;14441:34;;;14506:2;14491:18;;14484:34;;;14272:3;14257:19;207879:167:0::2;;;;;;;206090:1968;;;;206047:2011;206085:3;::::0;::::2;:::i;:::-;;;206047:2011;;;-1:-1:-1::0;208074:11:0;;208070:90:::2;;208102:46;208131:7;208140;208102:28;:46::i;:::-;205944:2223;;;205698:2469:::0;;;;;;;:::o;161783:258::-;159491:13;:11;:13::i;:::-;161909:20:::1;::::0;;;;::::1;::::0;;;::::1;::::0;;-1:-1:-1;;;161909:20:0::1;::::0;::::1;::::0;-1:-1:-1;;;;;161879:28:0;::::1;161871:59;;;;-1:-1:-1::0;;;161871:59:0::1;;;;;;;;:::i;:::-;-1:-1:-1::0;161941:15:0::1;:32:::0;;-1:-1:-1;;;;;;161941:32:0::1;-1:-1:-1::0;;;;;161941:32:0;::::1;::::0;;::::1;::::0;;;161989:44:::1;::::0;::::1;::::0;-1:-1:-1;;161989:44:0::1;161783:258:::0;:::o;222878:1548::-;155345:1;156120:7;;:19;156112:63;;;;-1:-1:-1;;;156112:63:0;;10188:2:1;156112:63:0;;;10170:21:1;10227:2;10207:18;;;10200:30;-1:-1:-1;;;;;;;;;;;10246:18:1;;;10239:61;10317:18;;156112:63:0;9986:355:1;156112:63:0;155345:1;156253:7;:18;163863:19:::1;:17;:19::i;:::-;223036:20:::2;::::0;;;;::::2;::::0;;;::::2;::::0;;-1:-1:-1;;;223036:20:0::2;::::0;::::2;::::0;-1:-1:-1;;;;;223013:21:0;::::2;223005:52;;;;-1:-1:-1::0;;;223005:52:0::2;;;;;;;;:::i;:::-;-1:-1:-1::0;223093:8:0;223068:22:::2;::::0;223161:1126:::2;223182:14;223177:1;:19;223161:1126;;223218:15;223236:8;;223245:1;223236:11;;;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;223352:27:0;;::::2;223262:87;223352:27:::0;;;:18:::2;:27;::::0;;;;;;;:36;;::::2;::::0;;;;;;;;;223262:126;;::::2;::::0;;::::2;::::0;;;;-1:-1:-1;;;;;223262:126:0;;::::2;::::0;;-1:-1:-1;;;223262:126:0;;;::::2;::::0;::::2;::::0;;::::2;::::0;;;;;;::::2;::::0;-1:-1:-1;;;;;223262:126:0;::::2;::::0;;;;-1:-1:-1;;;223262:126:0;::::2;-1:-1:-1::0;;;;;223262:126:0::2;::::0;;;;;;;;223491:26;;;:17:::2;:26:::0;;;;;223403:114;;::::2;::::0;::::2;::::0;;;;;;;;::::2;::::0;;;::::2;::::0;;::::2;::::0;;;;;;;::::2;::::0;::::2;::::0;;;;;;;::::2;;::::0;::::2;::::0;;::::2;::::0;;;;;;;-1:-1:-1;;;223403:114:0;::::2;::::0;;::::2;::::0;;;;-1:-1:-1;;;223403:114:0;;::::2;-1:-1:-1::0;;;;;223403:114:0::2;::::0;;;;223538:32;;223352:36;;-1:-1:-1;223262:126:0;;223403:114;;223538:37:::2;::::0;;223534:86:::2;;223596:8;;;;;223534:86;223655:21;223695:48:::0;223761:61:::2;223786:16;223804:17;223761:24;:61::i;:::-;223636:186:::0;;-1:-1:-1;223636:186:0;-1:-1:-1;223837:40:0::2;223636:186:::0;223837:40;::::2;:::i;:::-;;;223892:328;223931:7;223957;223983:40;224042:16;224077:17;224113;:32;;;-1:-1:-1::0;;;;;223892:328:0::2;224164:17;:41;;;-1:-1:-1::0;;;;;223892:328:0::2;:20;:328::i;:::-;224240:35;::::0;;-1:-1:-1;;;;;9907:15:1;;;9889:34;;9959:15;;9954:2;9939:18;;9932:43;224240:35:0::2;::::0;9801:18:1;224240:35:0::2;;;;;;;223203:1084;;;;;223161:1126;223198:3;::::0;::::2;:::i;:::-;;;223161:1126;;;-1:-1:-1::0;224301:27:0;;224297:122:::2;;224345:62;224374:7;224383:23;224345:28;:62::i;:::-;-1:-1:-1::0;;155301:1:0;156432:7;:22;-1:-1:-1;;;222878:1548:0:o;159770:132::-;159678:6;;-1:-1:-1;;;;;159678:6:0;157723:10;159834:23;159826:68;;;;-1:-1:-1;;;159826:68:0;;14731:2:1;159826:68:0;;;14713:21:1;;;14750:18;;;14743:30;14809:34;14789:18;;;14782:62;14861:18;;159826:68:0;14529:356:1;216211:1823:0;-1:-1:-1;;;;;216307:18:0;;;;;;:9;:18;;;;;;;;;;216327:29;;;;;;;;;;;-1:-1:-1;;;216327:29:0;;;;;;;216307:18;;216299:58;;;;-1:-1:-1;;;216299:58:0;;;;;;;;:::i;:::-;-1:-1:-1;;;;;;216441:50:0;;216370:68;216441:50;;;:17;:50;;;;;;;;216370:121;;;;;;;;;;;;;;;-1:-1:-1;;;;;216370:121:0;;;;;;;;;-1:-1:-1;;;216370:121:0;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;216370:121:0;;;;;;;;;-1:-1:-1;;;216370:121:0;;;-1:-1:-1;;;;;216370:121:0;;;;;;;216524:12;;216370:68;;216605:312;;216524:12;;216370:121;;216605:81;:312::i;:::-;216967:34;;216549:368;;-1:-1:-1;216930:22:0;;216967:39;216963:415;;217040:245;217100:22;:11;:20;:22::i;:::-;217040:245;;217141:16;:28;;;217040:245;;217188:16;:32;;;217040:245;;217239:16;:31;;;-1:-1:-1;;;;;217040:245:0;:41;:245::i;:::-;217023:262;;216963:415;;;-1:-1:-1;217335:31:0;;;;-1:-1:-1;;;;;217318:48:0;216963:415;217390:27;217420:134;217481:13;217420:134;;217509:16;:34;;;217420:46;:134::i;:::-;217390:164;;217596:327;;;;;;;;217655:16;:34;;;217596:327;;;;217704:31;:19;:29;:31::i;:::-;-1:-1:-1;;;;;217596:327:0;;;;;217750:57;:45;:55;:57::i;:::-;-1:-1:-1;;;;;217596:327:0;;;;;217822:22;:11;:20;:22::i;:::-;217596:327;;;;;;217859:13;217596:327;;;;;;217887:25;:14;:23;:25::i;:::-;-1:-1:-1;;;;;217596:327:0;;;;;;-1:-1:-1;;;;;217567:26:0;;;;;;:17;:26;;;;;;;;;:356;;;;;;;;;;;;-1:-1:-1;;;;;217567:356:0;;;-1:-1:-1;;;217567:356:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;217567:356:0;-1:-1:-1;;;;217567:356:0;;;;-1:-1:-1;;;217567:356:0;-1:-1:-1;;217567:356:0;;;;;;;;;;;;;;;;;;;;;;217964:12;157723:10;;157643:98;217964:12;-1:-1:-1;;;;;217941:85:0;;217978:16;:32;;;218012:13;217941:85;;;;;;15072:10:1;15109:15;;;15091:34;;15161:15;;15156:2;15141:18;;15134:43;15050:2;15035:18;;14890:293;217941:85:0;;;;;;;;216288:1746;;;;;216211:1823;;:::o;164417:108::-;164329:7;;;;164487:9;164479:38;;;;-1:-1:-1;;;164479:38:0;;15390:2:1;164479:38:0;;;15372:21:1;15429:2;15409:18;;;15402:30;-1:-1:-1;;;15448:18:1;;;15441:46;15504:18;;164479:38:0;15188:340:1;215205:998:0;215456:21;215479:48;215588:313;215688:12;215719:16;:28;;;215588:313;;215766:16;:46;;;-1:-1:-1;;;;;215588:313:0;215831:16;:55;;;-1:-1:-1;;;;;215588:313:0;:81;:313::i;:::-;215545:356;;215930:265;215986:17;:32;;;-1:-1:-1;;;;;215930:265:0;216033:17;:25;;;-1:-1:-1;;;;;215930:265:0;216073:17;:56;;;-1:-1:-1;;;;;215930:265:0;216144:40;215930:41;:265::i;:::-;215914:281;;215205:998;;;;;:::o;27097:195::-;27154:7;-1:-1:-1;;;;;27182:26:0;;;27174:78;;;;-1:-1:-1;;;27174:78:0;;15735:2:1;27174:78:0;;;15717:21:1;15774:2;15754:18;;;15747:30;15813:34;15793:18;;;15786:62;-1:-1:-1;;;15864:18:1;;;15857:37;15911:19;;27174:78:0;15533:403:1;27174:78:0;-1:-1:-1;27278:5:0;27097:195::o;218143:238::-;219813:11;;-1:-1:-1;;;;;219813:11:0;218241:132;;-1:-1:-1;;;218241:132:0;;-1:-1:-1;;;;;12859:55:1;;;218241:132:0;;;12841:74:1;12931:18;;;12924:34;;;218241:71:0;;;;;;;12814:18:1;;218241:132:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;218143:238;;:::o;219879:66::-;159491:13;:11;:13::i;143675:992::-;141628:66;144129:59;;;144125:535;;;144205:37;144224:17;144205:18;:37::i;:::-;143675:992;;;:::o;144125:535::-;144308:17;-1:-1:-1;;;;;144279:61:0;;:63;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;144279:63:0;;;;;;;;-1:-1:-1;;144279:63:0;;;;;;;;;;;;:::i;:::-;;;144275:306;;144509:56;;-1:-1:-1;;;144509:56:0;;16143:2:1;144509:56:0;;;16125:21:1;16182:2;16162:18;;;16155:30;16221:34;16201:18;;;16194:62;-1:-1:-1;;;16272:18:1;;;16265:44;16326:19;;144509:56:0;15941:410:1;144275:306:0;141976:66;144393:28;;144385:82;;;;-1:-1:-1;;;144385:82:0;;16558:2:1;144385:82:0;;;16540:21:1;16597:2;16577:18;;;16570:30;16636:34;16616:18;;;16609:62;-1:-1:-1;;;16687:18:1;;;16680:39;16736:19;;144385:82:0;16356:405:1;144385:82:0;144343:140;144595:53;144613:17;144632:4;144638:9;144595:17;:53::i;165113:120::-;164122:16;:14;:16::i;:::-;165172:7:::1;:15:::0;;-1:-1:-1;;165172:15:0::1;::::0;;165203:22:::1;157723:10:::0;165212:12:::1;165203:22;::::0;-1:-1:-1;;;;;6914:55:1;;;6896:74;;6884:2;6869:18;165203:22:0::1;;;;;;;165113:120::o:0;212865:2332::-;213268:22;213293:189;213349:23;213387:14;-1:-1:-1;;;;;;213293:41:0;:189::i;:::-;213268:214;;213534:253;;;;;;;;213594:52;:40;:50;:52::i;:::-;-1:-1:-1;;;;;213534:253:0;;;;;213661:26;:14;:24;:26::i;:::-;-1:-1:-1;;;;;213534:253:0;;;;;213702:25;:14;:23;:25::i;:::-;-1:-1:-1;;;;;213534:253:0;;;;;213742:34;:23;:32;:34::i;:::-;-1:-1:-1;;;;;213534:253:0;;;;;;-1:-1:-1;;;;;213495:27:0;;;;;;;:18;:27;;;;;;;;:36;;;;;;;;;;;:292;;;;;;-1:-1:-1;;;;;213495:292:0;;;-1:-1:-1;;;213495:292:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;213495:292:0;-1:-1:-1;;;;;;213495:292:0;;;-1:-1:-1;;;;;213495:292:0;;;;;;;;;;;213945:25;;;;213985:32;;;;214032:34;;213495:27;;213828:249;;213887:14;;213916;;213828:249;;;;;;;:44;:249::i;:::-;213800:277;;214090:22;214243:16;:34;;;214281:1;214243:39;214239:405;;-1:-1:-1;214316:31:0;;;;-1:-1:-1;;;;;214299:48:0;214239:405;;;214397:235;214457:12;214488:16;:28;;;214397:235;;214535:16;:32;;;214397:235;;214586:16;:31;;;-1:-1:-1;;;;;214397:235:0;:41;:235::i;:::-;214380:252;;214239:405;214656:27;214686:136;214747:16;:32;;;214686:136;;214794:17;214686:46;:136::i;:::-;214656:166;;214864:325;;;;;;;;214923:17;214864:325;;;;214955:31;:19;:29;:31::i;:::-;-1:-1:-1;;;;;214864:325:0;;;;;215001:52;:40;:50;:52::i;:::-;-1:-1:-1;;;;;214864:325:0;;;;;215068:23;:12;:21;:23::i;:::-;214864:325;;;;;;215106:16;:32;;;214864:325;;;;;;215153:25;:14;:23;:25::i;:::-;-1:-1:-1;;;;;214864:325:0;;;;;;-1:-1:-1;;;;;214835:26:0;;;;;;;:17;:26;;;;;;;;;:354;;;;;;;;;;;;-1:-1:-1;;;;;214835:354:0;;;-1:-1:-1;;;214835:354:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;214835:354:0;-1:-1:-1;;;;214835:354:0;;;;-1:-1:-1;;;214835:354:0;-1:-1:-1;;214835:354:0;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;212865:2332:0:o;117608:563::-;117819:7;117876:24;117861:11;:39;;117915:52;;;;;;;;;;;;;-1:-1:-1;;;117915:52:0;;;117839:139;;;;;-1:-1:-1;;;117839:139:0;;;;;;;;:::i;:::-;-1:-1:-1;117989:18:0;17601:4;118066:15;118011:38;118025:24;118011:11;:38;:::i;:::-;118010:71;;;;:::i;:::-;:100;;;;:::i;:::-;117989:121;-1:-1:-1;118128:35:0;117989:121;118128:22;:35;:::i;:::-;118121:42;;;117608:563;;;;;;;:::o;160872:191::-;160965:6;;;-1:-1:-1;;;;;160982:17:0;;;-1:-1:-1;;;;;;160982:17:0;;;;;;;161015:40;;160965:6;;;160982:17;160965:6;;161015:40;;160946:16;;161015:40;160935:128;160872:191;:::o;164854:118::-;163863:19;:17;:19::i;:::-;164914:7:::1;:14:::0;;-1:-1:-1;;164914:14:0::1;164924:4;164914:14;::::0;;164944:20:::1;164951:12;157723:10:::0;;157643:98;163535:97;140038:13;;;;;;;140030:69;;;;-1:-1:-1;;;140030:69:0;;;;;;;:::i;:::-;163609:7:::1;:15:::0;;-1:-1:-1;;163609:15:0::1;::::0;;163535:97::o;159253:113::-;140038:13;;;;;;;140030:69;;;;-1:-1:-1;;;140030:69:0;;;;;;;:::i;:::-;159326:32:::1;157723:10:::0;162161:18:::1;:32::i;149754:78::-:0;140038:13;;;;;;;140030:69;;;;-1:-1:-1;;;140030:69:0;;;;;;;:::i;29245:190::-;29301:6;-1:-1:-1;;;;;29328:25:0;;;29320:76;;;;-1:-1:-1;;;29320:76:0;;17553:2:1;29320:76:0;;;17535:21:1;17592:2;17572:18;;;17565:30;17631:34;17611:18;;;17604:62;-1:-1:-1;;;17682:18:1;;;17675:36;17728:19;;29320:76:0;17351:402:1;211182:1592:0;211340:34;;;;;;;;;;;;-1:-1:-1;;;211340:34:0;;;;211321:17;211313:62;;;;-1:-1:-1;;;211313:62:0;;;;;;;;:::i;:::-;-1:-1:-1;157723:10:0;211388:17;211506:53;;;:18;:53;;;;;;;;-1:-1:-1;;;;;211506:62:0;;;;;;;;;;211433:135;;;;;;;;;-1:-1:-1;;;;;211433:135:0;;;;;-1:-1:-1;;;211433:135:0;;;;;;;;;;;;;;;-1:-1:-1;;;;;211433:135:0;;;;;;-1:-1:-1;;;211433:135:0;;-1:-1:-1;;;;;211433:135:0;;;;;211667:42;;;;;;;;;;;-1:-1:-1;;;211667:42:0;;;;;;;211433:135;;211667:42;-1:-1:-1;;211603:49:0;211581:139;;;;-1:-1:-1;;;211581:139:0;;;;;;;;:::i;:::-;-1:-1:-1;;;;;;211804:50:0;;211733:68;211804:50;;;:17;:50;;;;;;;;211733:121;;;;;;;;;;;;;;;-1:-1:-1;;;;;211733:121:0;;;;;;;;;;-1:-1:-1;;;211733:121:0;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;211733:121:0;;;;;;;-1:-1:-1;;;211733:121:0;;-1:-1:-1;;;;;211733:121:0;;;;;;:68;211980:61;211733:121;212023:17;211980:24;:61::i;:::-;211867:174;;;;212054:314;212089:9;212113:7;212135:40;212190:16;212221:17;212288:13;212253:17;:32;;;-1:-1:-1;;;;;212253:48:0;;;;;:::i;212054:314::-;212385:17;;212381:243;;212423:12;212419:194;;;212456:54;212485:9;212496:13;212456:28;:54::i;:::-;212419:194;;;-1:-1:-1;;;;;212551:29:0;;;;;;:18;:29;;;;;:46;;212584:13;;212551:29;:46;;212584:13;;212551:46;:::i;:::-;;;;-1:-1:-1;;212419:194:0;212636:61;;-1:-1:-1;;;212636:61:0;;-1:-1:-1;;;;;12859:55:1;;;212636:61:0;;;12841:74:1;12931:18;;;12924:34;;;212636:35:0;;;;;12814:18:1;;212636:61:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;212715:51:0;;;-1:-1:-1;;;;;10627:15:1;;;10609:34;;10679:15;;10674:2;10659:18;;10652:43;10711:18;;;10704:34;;;212715:51:0;;10536:2:1;10521:18;212715:51:0;;;;;;;211302:1472;;;;;211182:1592;;;:::o;121092:496::-;121380:7;121542:38;121484:41;121505:20;121484:18;:41;:::i;:::-;121483:97;;;;:::i;:::-;121420:160;;:47;:160;:::i;:::-;121400:180;121092:496;-1:-1:-1;;;;;121092:496:0:o;33477:190::-;33533:6;33569:16;33560:25;;;33552:76;;;;-1:-1:-1;;;33552:76:0;;17960:2:1;33552:76:0;;;17942:21:1;17999:2;17979:18;;;17972:30;18038:34;18018:18;;;18011:62;-1:-1:-1;;;18089:18:1;;;18082:36;18135:19;;33552:76:0;17758:402:1;118553:384:0;118693:7;118722:17;118743:1;118722:22;118718:63;;-1:-1:-1;118768:1:0;118761:8;;118718:63;118848:81;17724:4;118862:31;17683:4;118862:15;:31;:::i;:::-;:47;;;;:::i;:::-;118911:17;118848:13;:81::i;29774:190::-;29830:6;-1:-1:-1;;;;;29857:25:0;;;29849:76;;;;-1:-1:-1;;;29849:76:0;;18367:2:1;29849:76:0;;;18349:21:1;18406:2;18386:18;;;18379:30;18445:34;18425:18;;;18418:62;-1:-1:-1;;;18496:18:1;;;18489:36;18542:19;;29849:76:0;18165:402:1;119741:799:0;119994:7;120080:40;120036;:84;;120135:59;;;;;;;;;;;;;-1:-1:-1;;;120135:59:0;;;120014:191;;;;;-1:-1:-1;;;120014:191:0;;;;;;;;:::i;:::-;-1:-1:-1;120218:33:0;120321:83;120364:40;120321;:83;:::i;:::-;120254:50;120290:14;120254:20;:50;:::i;:::-;:151;;;;:::i;:::-;120218:187;;120477:55;120491:25;17765:4;120477:13;:55::i;142506:284::-;-1:-1:-1;;;;;128959:19:0;;;142580:106;;;;-1:-1:-1;;;142580:106:0;;18774:2:1;142580:106:0;;;18756:21:1;18813:2;18793:18;;;18786:30;18852:34;18832:18;;;18825:62;-1:-1:-1;;;18903:18:1;;;18896:43;18956:19;;142580:106:0;18572:409:1;142580:106:0;141976:66;142697:85;;-1:-1:-1;;;;;;142697:85:0;-1:-1:-1;;;;;142697:85:0;;;;;;;;;;142506:284::o;143199:297::-;143342:29;143353:17;143342:10;:29::i;:::-;143400:1;143386:4;:11;:15;:28;;;;143405:9;143386:28;143382:107;;;143431:46;143453:17;143472:4;143431:21;:46::i;:::-;;143199:297;;;:::o;164602:108::-;164329:7;;;;164661:41;;;;-1:-1:-1;;;164661:41:0;;19188:2:1;164661:41:0;;;19170:21:1;19227:2;19207:18;;;19200:30;19266:22;19246:18;;;19239:50;19306:18;;164661:41:0;18986:344:1;113715:1336:0;113922:7;17683:4;113946:20;:36;113942:77;;;-1:-1:-1;114006:1:0;113999:8;;113942:77;114031:30;114064:58;114086:20;17683:4;114064:21;:58::i;:::-;114031:91;;114133:23;114159:58;114181:20;17683:4;114159:21;:58::i;:::-;114133:84;;114228:13;114244:57;114261:22;114285:15;114244:16;:57::i;:::-;114228:73;-1:-1:-1;114314:14:0;;114343:30;-1:-1:-1;;;114228:73:0;114343:16;:30::i;:::-;:35;;;114339:562;;114404:33;114431:5;114404:26;:33::i;:::-;114395:42;;114339:562;;;114470:35;114508:112;114543:21;:19;:21::i;:::-;114583:22;114508:16;:112::i;:::-;114470:150;;114637:16;114656:146;114691:62;114708:27;114737:15;114691:16;:62::i;:::-;114772:15;114656:16;:146::i;:::-;114637:165;;114828:61;114845:13;114860:28;114879:8;114860:18;:28::i;:::-;114828:16;:61::i;:::-;114819:70;;114455:446;;114339:562;114911:17;114931:62;114948:6;114956:36;17683:4;114956:21;:36::i;:::-;114931:16;:62::i;:::-;114911:82;;115013:30;115033:9;115013:19;:30::i;:::-;115006:37;113715:1336;-1:-1:-1;;;;;;;;;;113715:1336:0:o;30832:190::-;30888:6;-1:-1:-1;;;;;30915:25:0;;;30907:76;;;;-1:-1:-1;;;30907:76:0;;19537:2:1;30907:76:0;;;19519:21:1;19576:2;19556:18;;;19549:30;19615:34;19595:18;;;19588:62;-1:-1:-1;;;19666:18:1;;;19659:36;19712:19;;30907:76:0;19335:402:1;115695:1287:0;115965:7;115985:10;116135:39;:28;:37;:39::i;:::-;116086:33;:22;:31;:33::i;:::-;:88;;;;:::i;:::-;116039:31;:20;:29;:31::i;:::-;115998:25;:14;:23;:25::i;:::-;:72;;;;:::i;:::-;:176;;;;:::i;:::-;115985:189;;116187:14;116224:1;116218:3;:7;116214:670;;;116242:14;116259:48;116273:18;116274:4;116275:3;116274:4;:::i;:::-;116273:16;:18::i;:::-;17683:4;116259:13;:48::i;:::-;116242:65;;116441:6;116413:25;:34;:81;;;;-1:-1:-1;116488:6:0;116451:33;:25;116479:5;116451:33;:::i;:::-;:43;;116413:81;116409:130;;;116522:1;116515:8;;;;;;;116409:130;116635:47;;;;;;;;;;;;-1:-1:-1;;;116635:47:0;;;;116581:35;;;;116555:142;;;;-1:-1:-1;;;116555:142:0;;;;;;;;:::i;:::-;-1:-1:-1;116723:34:0;116751:6;116723:25;:34;:::i;:::-;116714:43;;116227:542;116214:670;;;116827:45;116841:15;:3;:13;:15::i;116827:45::-;116799:73;;:25;:73;:::i;:::-;116790:82;;116214:670;116909:5;116900:6;:14;116896:55;;;116938:1;116931:8;;;;;;116896:55;116968:6;115695:1287;-1:-1:-1;;;;;;;115695:1287:0:o;17290:114::-;17353:9;17395:1;17385:5;17389:1;17395;17385:5;:::i;:::-;17380:11;;:1;:11;:::i;:::-;17379:17;;;;:::i;142903:155::-;142970:37;142989:17;142970:18;:37::i;:::-;143023:27;;-1:-1:-1;;;;;143023:27:0;;;;;;;;142903:155;:::o;147936:461::-;148019:12;-1:-1:-1;;;;;128959:19:0;;;148044:88;;;;-1:-1:-1;;;148044:88:0;;20789:2:1;148044:88:0;;;20771:21:1;20828:2;20808:18;;;20801:30;20867:34;20847:18;;;20840:62;-1:-1:-1;;;20918:18:1;;;20911:36;20964:19;;148044:88:0;20587:402:1;148044:88:0;148206:12;148220:23;148247:6;-1:-1:-1;;;;;148247:19:0;148267:4;148247:25;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;148205:67;;;;148290:99;148326:7;148335:10;148290:99;;;;;;;;;;;;;;;;;:35;:99::i;122393:509::-;122507:7;;122536:17;122545:8;122536:6;:17;:::i;:::-;:21;122532:143;;;122652:11;122662:1;122652:11;;:::i;:::-;;;122532:143;122685:17;122705:29;122727:6;122705:21;:29::i;:::-;122685:49;;122745:19;122767:31;122789:8;122767:21;:31::i;:::-;122745:53;;122809:16;122828:40;122845:9;122856:11;122828:16;:40::i;:::-;122809:59;122393:509;-1:-1:-1;;;;;;122393:509:0:o;80482:2866::-;80541:7;80617:6;80596:18;;;;:27;;;80652:18;;;;:27;;;80694:19;;;80690:2646;;80730:9;80743:6;80730:19;80726:100;;-1:-1:-1;;;;80758:3:0;-1:-1:-1;80751:10:0;;-1:-1:-1;80751:10:0;80726:100;-1:-1:-1;;;;;;80788:38:0;;80784:42;;80777:49;;80690:2646;80846:9;80859:6;80846:19;80842:2494;;-1:-1:-1;;;80882:38:0;;:43;80878:142;;-1:-1:-1;;;;80934:3:0;-1:-1:-1;80927:10:0;;-1:-1:-1;80927:10:0;80878:142;-1:-1:-1;;;80977:5:0;;;-1:-1:-1;;;80976:44:0;80953:67;;80842:2494;-1:-1:-1;;;;;;;81040:38:0;;81082:1;81040:43;81036:2300;;-1:-1:-1;;;;;;;81100:38:0;;81142:1;81100:43;81096:146;;-1:-1:-1;;;;81152:3:0;-1:-1:-1;81145:10:0;;-1:-1:-1;81145:10:0;81096:146;-1:-1:-1;;;81199:5:0;;;-1:-1:-1;;;81198:44:0;-1:-1:-1;;;81178:64:0;81171:71;;81036:2300;-1:-1:-1;;;;;81290:11:0;;;;:44;81269:18;81349:14;;;81345:94;;81377:1;81365:13;;81345:94;;;-1:-1:-1;;;81394:45:0;81345:94;-1:-1:-1;;;;;81473:11:0;;;;:44;81452:18;81532:14;;;81528:356;;81565:15;;81561:206;;81597:10;81616:31;81636:10;81616:18;:31::i;:::-;81713:1;;-1:-1:-1;81610:3:0;:37;81729:24;;;-1:-1:-1;;81729:24:0;;81664:20;;;;;-1:-1:-1;81561:206:0;81528:356;;;-1:-1:-1;;;81820:44:0;81869:3;81819:53;81528:356;81922:10;81909;:23;;;;;:::i;:::-;;81896:36;;81947:10;81961:1;81947:15;81943:134;;-1:-1:-1;;;81983:5:0;;;81982:44;:95;;55072:34;81982:95;;;-1:-1:-1;;;81982:95:0;81975:102;;;;;;;;81943:134;82112:30;82098:10;:44;;82090:53;;;;:::i;:::-;82156:11;82195:31;82181:10;:45;;:215;;82288:31;82274:10;:45;;:122;;-1:-1:-1;;;82339:10:0;:45;;:57;;82393:3;82274:122;;82339:57;82387:3;82274:122;;;82322:3;82274:122;82181:215;;;;;82229:31;82249:10;82229:18;:31::i;:::-;82156:240;;82431:9;82443:5;82431:17;82425:3;82413:9;:15;:35;82409:779;;;82487:6;82475:18;;82519:1;82506:14;;82409:779;;;82569:9;82554:3;82542:9;:15;82560:5;82542:23;:36;82538:650;;;82618:1;82606:13;;82645:1;82632:14;;82538:650;;;82695:9;82680:3;82668:9;:15;82686:5;82668:23;:36;82664:524;;;82756:9;82736;82748:5;82736:17;:29;82732:202;;;82815:9;82795;82807:5;82795:17;:29;82780:44;;;;;82732:202;;;82866:9;82846;82858:5;82846:17;:29;82842:92;;;82929:5;82917:9;82905;:21;:29;82890:44;;;;;82842:92;82961:1;82949:13;;82664:524;;;83013:3;83007;:9;83003:52;;;83052:3;83046;:9;83031:24;;;;;83003:52;-1:-1:-1;;;;;83070:44:0;;;;83167:9;83153:3;83141:9;:15;83159:5;83141:23;:35;83129:47;;82664:524;83314:10;83308:3;83295:9;:16;;83239:1;83235;:5;-1:-1:-1;;;83234:44:0;;;83225:54;;-1:-1:-1;;;;;83225:86:0;;:99;83207:119;;83200:126;;;;;;;;;69368:991;69427:4;69493:34;69479:11;;;;:48;-1:-1:-1;;;69547:47:0;;;69538:57;;;;;;69651:34;69637:11;;;;:48;-1:-1:-1;;;69705:47:0;;;69696:57;;;;;;-1:-1:-1;;;;;;69826:6:0;;;;;;;;;:56;;;-1:-1:-1;;;69836:9:0;-1:-1:-1;;;;;69836:46:0;;69826:56;69817:66;;;;;;-1:-1:-1;;;;;;69898:6:0;;;;;;;69894:453;;69913:1;69906:8;;;;;;69894:453;-1:-1:-1;;;69956:11:0;;;;:49;-1:-1:-1;69956:49:0;;;70033:11;;;;:49;;;;;;70095:243;;70127:9;70123:86;;;70157:9;-1:-1:-1;;;;;70145:21:0;:9;-1:-1:-1;;;;;70145:21:0;;:37;;70180:1;70145:37;;;-1:-1:-1;;70138:44:0;;;;;;;;70095:243;70245:9;70241:85;;;70263:1;70256:8;;;;;;;;70241:85;70301:9;-1:-1:-1;;;;;70289:21:0;:9;-1:-1:-1;;;;;70289:21:0;;:37;;-1:-1:-1;;70289:37:0;;;70319:1;70282:44;;;;;;;;121596:745;121670:7;;121694:30;-1:-1:-1;;;121718:5:0;121694:16;:30::i;:::-;:34;;;121690:644;;;121752:58;-1:-1:-1;;;121777:32:0;-1:-1:-1;;;121803:5:0;121777:16;:32::i;121690:644::-;121865:1;121832:30;-1:-1:-1;;;121856:5:0;121832:16;:30::i;:::-;:34;;;121828:506;;;121890:58;-1:-1:-1;;;121915:32:0;-1:-1:-1;;;121941:5:0;121915:16;:32::i;121828:506::-;122003:1;121970:30;-1:-1:-1;;;121994:5:0;121970:16;:30::i;:::-;:34;;;121966:368;;;122028:58;-1:-1:-1;;;122053:32:0;-1:-1:-1;;;122079:5:0;122053:16;:32::i;121966:368::-;122141:1;122108:30;-1:-1:-1;;;122132:5:0;122108:16;:30::i;:::-;:34;;;122104:230;;;122166:58;-1:-1:-1;;;122191:32:0;-1:-1:-1;;;122217:5:0;122191:16;:32::i;122104:230::-;122264:58;-1:-1:-1;;;122289:32:0;-1:-1:-1;;;122315:5:0;122289:16;:32::i;122104:230::-;121596:745;;;:::o;122954:112::-;123007:7;123034:24;123056:1;123034:21;:24::i;:::-;123027:31;;122954:112;:::o;76639:2550::-;76698:7;76774:6;76753:18;;;;:27;;;76809:18;;;;:27;;;76851:19;;;76847:2330;;76887:9;76900:6;76887:19;76883:375;;-1:-1:-1;;;;;;76925:6:0;;;;;;;76921:168;;-1:-1:-1;;;;;;76944:38:0;;76940:42;;76933:49;;76921:168;-1:-1:-1;;;;;;77004:5:0;;;:43;-1:-1:-1;;;77004:43:0;77000:89;;-1:-1:-1;;;77056:5:0;;;77049:12;;77000:89;-1:-1:-1;;;;77086:3:0;-1:-1:-1;77079:10:0;;-1:-1:-1;77079:10:0;76883:375;-1:-1:-1;;;;;;;77124:38:0;;77166:1;77124:43;77120:126;;-1:-1:-1;;;;77176:3:0;-1:-1:-1;77169:10:0;;-1:-1:-1;77169:10:0;76847:2330;77277:9;77290:6;77277:19;77273:1904;;-1:-1:-1;;;;;;;77315:38:0;;77357:1;77315:43;77311:126;;-1:-1:-1;;;;77367:3:0;-1:-1:-1;77360:10:0;;-1:-1:-1;77360:10:0;77311:126;-1:-1:-1;;;;;;77399:38:0;;77395:42;;77388:49;;77273:1904;-1:-1:-1;;;;;77485:11:0;;;;:44;77464:18;77544:14;;;77540:94;;77572:1;77560:13;;77540:94;;;-1:-1:-1;;;77589:45:0;77540:94;-1:-1:-1;;;;;77668:11:0;;;;:44;77647:18;77727:14;;;77723:94;;77755:1;77743:13;;77723:94;;;-1:-1:-1;;;77772:45:0;77723:94;77844:10;77830:24;;;;77869:10;77883:1;77869:15;77865:134;;-1:-1:-1;;;77905:5:0;;;77904:44;:95;;55072:34;77904:95;;77865:134;78012:22;;;;78047:11;-1:-1:-1;;;78072:73:0;;;:217;;-1:-1:-1;;;78165:10:0;:73;;:124;;78258:31;78278:10;78258:18;:31::i;:::-;78072:217;;78165:124;78241:3;78072:217;;;78148:3;78072:217;78047:242;;78324:5;78318:3;78306:9;:15;:23;78302:727;;;78369:1;78357:13;;78396:1;78383:14;;78302:727;;;78437:5;78431:3;78419:9;:15;:23;78415:614;;;78486:5;78474:9;:17;78470:154;;;78529:9;78521:5;:17;78506:32;;;;;78470:154;;;78572:5;78560:9;:17;78556:68;;;78619:5;78607:9;:17;78592:32;;;;;78556:68;78649:1;78637:13;;78415:614;;;78690:5;78684:3;78672:9;:15;:23;78668:361;;;78722:6;78710:18;;78754:1;78741:14;;78668:361;;;78796:3;78790;:9;78786:122;;;78835:3;78829;:9;78814:24;;;;;78786:122;;;78866:3;78860;:9;78856:52;;;78905:3;78899;:9;78884:24;;;;;78856:52;-1:-1:-1;;;;;78923:44:0;;;;79012:5;79006:3;78994:9;:15;:23;78982:35;;78668:361;79155:10;79149:3;79136:9;:16;;79080:1;79076;:5;-1:-1:-1;;;79075:44:0;;;79066:54;;-1:-1:-1;;;;;79066:86:0;;:99;79048:119;;79041:126;;;;;;;;;71364:3925;71423:7;71499:6;71478:18;;;;:27;;;71534:18;;;;:27;;;71576:19;;;71572:3705;;71612:9;71625:6;71612:19;71608:113;;-1:-1:-1;;;;;;71651:6:0;;;;;;;71647:48;;71666:1;71659:8;;;;;;71608:113;71720:1;71713:8;;;;;;71572:3705;71742:9;71755:6;71742:19;71738:3539;;71770:1;71763:8;;;;;;71738:3539;-1:-1:-1;;;71809:11:0;;;;:49;;;;;-1:-1:-1;;;;;71890:44:0;71796:10;71949:14;;;71945:94;;71977:1;71965:13;;71945:94;;;-1:-1:-1;;;71994:45:0;71945:94;-1:-1:-1;;;72065:11:0;;;;:49;;;;;-1:-1:-1;;;;;72146:44:0;72052:10;72205:14;;;72201:94;;72233:1;72221:13;;72201:94;;;-1:-1:-1;;;72250:45:0;72201:94;72312:10;72326:1;72312:15;72308:2960;;-1:-1:-1;;;;;;72336:18:0;;-1:-1:-1;;;72336:18:0;:38;;72373:1;72336:38;;;55072:34;72336:38;72329:45;;;;;;;;;;72308:2960;72394:10;72408:1;72394:15;72390:2878;;-1:-1:-1;;;;;;72418:18:0;;-1:-1:-1;;;72418:18:0;:38;;72455:1;72418:38;;72390:2878;72500:39;;;72560:14;;;;;;;72556:2701;;72603:3;72595:5;:11;72591:273;;;72615:1;72608:8;;;;;;;;;;;72591:273;72648:1;72640:5;:9;72636:228;;;72651:30;;;;72636:228;;;-1:-1:-1;;72705:5:0;:12;72701:163;;;72726:1;72719:8;;;;;;;;;;;72701:163;72759:1;72751:5;:9;72747:117;;;72804:5;72803:6;;72779:31;;;;;72839:9;72827:21;;72747:117;72882:24;;;;-1:-1:-1;;;72929:45:0;;72925:131;;73008:1;73026:14;;;;72993:16;;;;;72925:131;73078:9;73091:6;73078:19;73074:463;;73121:5;:45;;-1:-1:-1;;;73121:45:0;;;-1:-1:-1;;;;;;73121:45:0;73114:52;;;;;;;;;;;73074:463;-1:-1:-1;;;73207:10:0;:44;73203:129;;;73265:1;73253:13;;73203:129;;;-1:-1:-1;;;;;73288:44:0;;;;73203:129;73508:10;73482:3;73469:9;:16;;73399:5;:46;;73444:1;73399:46;;;-1:-1:-1;;;73399:46:0;-1:-1:-1;;;;;73398:88:0;;:120;73360:160;;73353:167;;;;;;;;;;;72556:2701;73583:1;73575:5;:9;73571:207;;;73618:1;73603:16;;;;;73649:1;73636:14;;;;73571:207;;;73684:1;73676:5;:9;73672:106;;;73719:1;73704:16;;;;;73761:1;73749:9;:13;73737:25;;73672:106;73806:3;73798:5;:11;73794:267;;;73824:1;73811:14;;73794:267;;;73857:1;73849:5;:9;73845:216;;;73909:1;73901:5;:9;73887:1;73874:10;:14;:37;;73915:1;73873:43;73860:56;;73845:216;;;-1:-1:-1;;73940:5:0;:12;73936:125;;;73967:1;73954:14;;73936:125;;;-1:-1:-1;;73992:5:0;:10;73988:73;;;74054:1;74046:5;74045:6;;:10;74031:1;74018:10;:14;:38;;74060:1;74017:44;74004:57;;73988:73;74096:10;74082;:24;74078:173;;74122:10;74108:24;;;;74078:173;;;74195:10;74182;:23;74169:36;;74230:5;74222:13;;74078:173;74271:10;74285:1;74271:15;74267:56;;-1:-1:-1;55072:34:0;;-1:-1:-1;74303:20:0;;-1:-1:-1;;;;;;74303:20:0;74267:56;74340:11;74354:31;74374:10;74354:18;:31::i;:::-;74340:45;;74406:3;74413;74406:10;74402:551;;74462:1;74448:10;:15;;-1:-1:-1;;;;;74448:48:0;74435:61;;74526:1;74513:14;;;;74402:551;;;74559:3;74553;:9;74549:404;;;74597:3;:9;;;74627:17;;;74623:265;;;74692:5;74678:10;:19;;-1:-1:-1;;;;;74678:52:0;74665:65;;74762:5;74749:18;;;;74623:265;;;74869:1;;-1:-1:-1;;74825:13:0;74810:28;;;;;74623:265;74564:339;74549:404;;;-1:-1:-1;;;;;74909:44:0;;;;74549:404;74974:9;74987:6;74974:19;74970:273;;75017:5;:45;;-1:-1:-1;;;75017:45:0;;;-1:-1:-1;;;;;;75017:45:0;75010:52;;;;;;;;;;;;74970:273;75231:10;75207:3;75194:9;:16;;75126:5;:46;;75171:1;75126:46;;;-1:-1:-1;;;75126:46:0;-1:-1:-1;;;;;75125:86:0;;:116;75089:154;;75082:161;;;;;;;;;;;;86198:2203;86248:7;-1:-1:-1;;;86287:11:0;;;;:48;86283:2106;;;-1:-1:-1;;;;86344:3:0;86198:2203;-1:-1:-1;86198:2203:0:o;86283:2106::-;-1:-1:-1;;;;;;86365:39:0;;-1:-1:-1;;;86365:39:0;86361:2028;;-1:-1:-1;55072:34:0;;86198:2203;-1:-1:-1;86198:2203:0:o;86361:2028::-;86493:6;86472:18;;;;:27;;;86514:19;;;86510:1870;;-1:-1:-1;86542:1:0;;86198:2203;-1:-1:-1;86198:2203:0:o;86510:1870::-;-1:-1:-1;;;;;86593:11:0;;;;:44;86572:18;86654:14;;;86650:96;;86682:1;86670:13;;86650:96;;;-1:-1:-1;;;86701:45:0;86650:96;86765:10;86779:1;86765:15;86761:45;;-1:-1:-1;;;;;;;86789:17:0;86198:2203;-1:-1:-1;;;86198:2203:0:o;86761:45::-;86821:19;86878:5;86821:19;86951:6;86938:19;;86934:554;;-1:-1:-1;87077:2:0;87062:17;;;;;86991:5;;-1:-1:-1;;;87029:18:0;;86934:554;;;87131:4;87114:21;;-1:-1:-1;;;87154:10:0;:45;87150:325;;87245:9;87236:6;:18;87218:36;;87286:2;87271:17;;;;;87150:325;;;87327:11;87341:31;87361:10;87341:18;:31::i;:::-;87450:3;:9;;;87435:24;;;;;87407:5;:11;;-1:-1:-1;;87150:325:0;87506:10;-1:-1:-1;;;87506:48:0;87502:678;;87575:14;87571:40;;;87610:1;87591:20;87571:40;87626:13;87648:36;87668:15;87648:18;:36::i;:::-;87642:3;:42;87626:58;;87719:5;87699:25;;;;;87757:5;87739:23;;;;87556:220;87502:678;;;87797:10;87810:14;:22;;87831:1;87810:22;;;87827:1;87810:22;87797:35;;;;87847:320;-1:-1:-1;;;87854:15:0;:49;87847:320;;;88000:24;;;88067:3;88053:17;;;88144:3;:7;;88129:22;;;;;-1:-1:-1;;87960:19:0;;;;;87942:1;87922:21;;;;88106:6;;;88087:25;;87847:320;;;87782:398;87502:678;88318:15;-1:-1:-1;;;;;88318:48:0;88312:3;88294:14;:21;;88220:14;:55;;88274:1;88220:55;;;-1:-1:-1;;;88220:55:0;-1:-1:-1;;;;;88219:96:0;;:147;88201:167;;;86198:2203;-1:-1:-1;;;;;;;86198:2203:0:o;57665:462::-;57718:7;57757:1;57762;57757:6;57753:362;;-1:-1:-1;57781:1:0;;57665:462;-1:-1:-1;57665:462:0:o;57753:362::-;57825:1;57808:14;57853:27;57825:1;57853:18;:27::i;:::-;57839:41;;57901:3;57895;:9;57891:86;;;57923:3;57917;:9;57906:20;;;;;57891:86;;;57952:3;57946;:9;57942:35;;;57974:3;57968;:9;57957:20;;;;;57942:35;58041:5;:11;58056:3;58041:18;-1:-1:-1;;;;;57999:39:0;;;;:60;58079:26;;;;-1:-1:-1;;57665:462:0:o;58535:600::-;58586:7;58661:6;58640:18;;;;:27;58693:5;58682:16;;58678:30;;;-1:-1:-1;58707:1:0;;58535:600;-1:-1:-1;;58535:600:0:o;58678:30::-;-1:-1:-1;;;58741:11:0;;;;:48;58732:58;;;;;;58834:5;58822:8;:17;;58813:27;;;;;;-1:-1:-1;;;;;;;;58887:11:0;;;;58878:54;:97;59001:5;58990:16;;58986:112;;;59019:5;:16;;;59008:27;58986:112;;;59064:5;59053:8;:16;59049:49;;;-1:-1:-1;;59082:16:0;;59071:27;59116:6;58535:600;-1:-1:-1;;;58535:600:0:o;54163:301::-;54219:6;-1:-1:-1;;;;;54346:5:0;:34;;54338:87;;;;-1:-1:-1;;;54338:87:0;;21737:2:1;54338:87:0;;;21719:21:1;21776:2;21756:18;;;21749:30;21815:34;21795:18;;;21788:62;-1:-1:-1;;;21866:18:1;;;21859:38;21914:19;;54338:87:0;21535:404:1;35465:171:0;35521:7;35558:1;35549:5;:10;;35541:55;;;;-1:-1:-1;;;35541:55:0;;22146:2:1;35541:55:0;;;22128:21:1;;;22165:18;;;22158:30;22224:34;22204:18;;;22197:62;22276:18;;35541:55:0;21944:356:1;134238:762:0;134388:12;134417:7;134413:580;;;-1:-1:-1;134448:10:0;134441:17;;134413:580;134562:17;;:21;134558:424;;134810:10;134804:17;134871:15;134858:10;134854:2;134850:19;134843:44;134558:424;134953:12;134946:20;;-1:-1:-1;;;134946:20:0;;;;;;;;:::i;107796:646::-;107858:7;107906:1;107902;:5;107893:15;;;;;;107919:14;-1:-1:-1;;;107952:1:0;:40;107948:75;;108002:3;107996:9;;;;108007:13;107948:75;-1:-1:-1;;;108035:1:0;:24;108031:57;;108069:2;108063:8;;;;108073:12;108031:57;-1:-1:-1;;;108100:1:0;:16;108096:49;;108126:2;108120:8;;;;108130:12;108096:49;108162:7;108157:1;:12;108153:45;;108179:2;108173:8;;;;108183:12;108153:45;108215:5;108210:1;:10;108206:41;;108230:1;108224:7;;;;108233:11;108206:41;108264:4;108259:1;:9;108255:40;;108278:1;108272:7;;;;108281:11;108255:40;108312:3;108307:1;:8;108303:39;;108325:1;108319:7;;;;108328:11;108303:39;108359:3;108354:1;:8;108350:25;;108374:1;108364:11;108423:6;107796:646;-1:-1:-1;;107796:646:0:o;14:196:1:-;82:20;;-1:-1:-1;;;;;131:54:1;;121:65;;111:93;;200:1;197;190:12;215:186;274:6;327:2;315:9;306:7;302:23;298:32;295:52;;;343:1;340;333:12;295:52;366:29;385:9;366:29;:::i;1604:260::-;1672:6;1680;1733:2;1721:9;1712:7;1708:23;1704:32;1701:52;;;1749:1;1746;1739:12;1701:52;1772:29;1791:9;1772:29;:::i;:::-;1762:39;;1820:38;1854:2;1843:9;1839:18;1820:38;:::i;:::-;1810:48;;1604:260;;;;;:::o;2465:367::-;2528:8;2538:6;2592:3;2585:4;2577:6;2573:17;2569:27;2559:55;;2610:1;2607;2600:12;2559:55;-1:-1:-1;2633:20:1;;2676:18;2665:30;;2662:50;;;2708:1;2705;2698:12;2662:50;2745:4;2737:6;2733:17;2721:29;;2805:3;2798:4;2788:6;2785:1;2781:14;2773:6;2769:27;2765:38;2762:47;2759:67;;;2822:1;2819;2812:12;2759:67;2465:367;;;;;:::o;2837:847::-;2968:6;2976;2984;2992;3000;3053:2;3041:9;3032:7;3028:23;3024:32;3021:52;;;3069:1;3066;3059:12;3021:52;3092:29;3111:9;3092:29;:::i;:::-;3082:39;;3172:2;3161:9;3157:18;3144:32;3195:18;3236:2;3228:6;3225:14;3222:34;;;3252:1;3249;3242:12;3222:34;3291:70;3353:7;3344:6;3333:9;3329:22;3291:70;:::i;:::-;3380:8;;-1:-1:-1;3265:96:1;-1:-1:-1;3468:2:1;3453:18;;3440:32;;-1:-1:-1;3484:16:1;;;3481:36;;;3513:1;3510;3503:12;3481:36;;3552:72;3616:7;3605:8;3594:9;3590:24;3552:72;:::i;:::-;2837:847;;;;-1:-1:-1;2837:847:1;;-1:-1:-1;3643:8:1;;3526:98;2837:847;-1:-1:-1;;;2837:847:1:o;3871:127::-;3932:10;3927:3;3923:20;3920:1;3913:31;3963:4;3960:1;3953:15;3987:4;3984:1;3977:15;4003:995;4080:6;4088;4141:2;4129:9;4120:7;4116:23;4112:32;4109:52;;;4157:1;4154;4147:12;4109:52;4180:29;4199:9;4180:29;:::i;:::-;4170:39;;4260:2;4249:9;4245:18;4232:32;4283:18;4324:2;4316:6;4313:14;4310:34;;;4340:1;4337;4330:12;4310:34;4378:6;4367:9;4363:22;4353:32;;4423:7;4416:4;4412:2;4408:13;4404:27;4394:55;;4445:1;4442;4435:12;4394:55;4481:2;4468:16;4503:2;4499;4496:10;4493:36;;;4509:18;;:::i;:::-;4584:2;4578:9;4552:2;4638:13;;-1:-1:-1;;4634:22:1;;;4658:2;4630:31;4626:40;4614:53;;;4682:18;;;4702:22;;;4679:46;4676:72;;;4728:18;;:::i;:::-;4768:10;4764:2;4757:22;4803:2;4795:6;4788:18;4843:7;4838:2;4833;4829;4825:11;4821:20;4818:33;4815:53;;;4864:1;4861;4854:12;4815:53;4920:2;4915;4911;4907:11;4902:2;4894:6;4890:15;4877:46;4965:1;4960:2;4955;4947:6;4943:15;4939:24;4932:35;4986:6;4976:16;;;;;;;4003:995;;;;;:::o;5003:350::-;5070:6;5078;5131:2;5119:9;5110:7;5106:23;5102:32;5099:52;;;5147:1;5144;5137:12;5099:52;5170:29;5189:9;5170:29;:::i;:::-;5160:39;;5249:2;5238:9;5234:18;5221:32;5293:10;5286:5;5282:22;5275:5;5272:33;5262:61;;5319:1;5316;5309:12;5262:61;5342:5;5332:15;;;5003:350;;;;;:::o;5358:511::-;5453:6;5461;5469;5522:2;5510:9;5501:7;5497:23;5493:32;5490:52;;;5538:1;5535;5528:12;5490:52;5561:29;5580:9;5561:29;:::i;:::-;5551:39;;5641:2;5630:9;5626:18;5613:32;5668:18;5660:6;5657:30;5654:50;;;5700:1;5697;5690:12;5654:50;5739:70;5801:7;5792:6;5781:9;5777:22;5739:70;:::i;:::-;5358:511;;5828:8;;-1:-1:-1;5713:96:1;;-1:-1:-1;;;;5358:511:1:o;5874:871::-;6129:2;6181:21;;;6251:13;;6154:18;;;6273:22;;;6100:4;;6129:2;6314;;6332:18;;;;6373:15;;;6100:4;6416:303;6430:6;6427:1;6424:13;6416:303;;;6489:13;;6531:9;;-1:-1:-1;;;;;6527:58:1;6515:71;;6626:11;;6620:18;6606:12;;;6599:40;6659:12;;;;6694:15;;;;6452:1;6445:9;6416:303;;;-1:-1:-1;6736:3:1;;5874:871;-1:-1:-1;;;;;;;5874:871:1:o;6981:585::-;7085:6;7093;7101;7109;7162:2;7150:9;7141:7;7137:23;7133:32;7130:52;;;7178:1;7175;7168:12;7130:52;7218:9;7205:23;7251:18;7243:6;7240:30;7237:50;;;7283:1;7280;7273:12;7237:50;7322:70;7384:7;7375:6;7364:9;7360:22;7322:70;:::i;:::-;7411:8;;-1:-1:-1;7296:96:1;-1:-1:-1;7465:38:1;;-1:-1:-1;7499:2:1;7484:18;;7465:38;:::i;:::-;7455:48;;7522:38;7556:2;7545:9;7541:18;7522:38;:::i;:::-;7512:48;;6981:585;;;;;;;:::o;7571:254::-;7639:6;7647;7700:2;7688:9;7679:7;7675:23;7671:32;7668:52;;;7716:1;7713;7706:12;7668:52;7739:29;7758:9;7739:29;:::i;:::-;7729:39;7815:2;7800:18;;;;7787:32;;-1:-1:-1;;;7571:254:1:o;7830:1163::-;7997:6;8005;8013;8021;8029;8037;8045;8098:3;8086:9;8077:7;8073:23;8069:33;8066:53;;;8115:1;8112;8105:12;8066:53;8138:29;8157:9;8138:29;:::i;:::-;8128:39;;8218:2;8207:9;8203:18;8190:32;8241:18;8282:2;8274:6;8271:14;8268:34;;;8298:1;8295;8288:12;8268:34;8337:70;8399:7;8390:6;8379:9;8375:22;8337:70;:::i;:::-;8426:8;;-1:-1:-1;8311:96:1;-1:-1:-1;8514:2:1;8499:18;;8486:32;;-1:-1:-1;8530:16:1;;;8527:36;;;8559:1;8556;8549:12;8527:36;8598:72;8662:7;8651:8;8640:9;8636:24;8598:72;:::i;:::-;8689:8;;-1:-1:-1;8572:98:1;-1:-1:-1;8777:2:1;8762:18;;8749:32;;-1:-1:-1;8793:16:1;;;8790:36;;;8822:1;8819;8812:12;8790:36;;8861:72;8925:7;8914:8;8903:9;8899:24;8861:72;:::i;:::-;7830:1163;;;;-1:-1:-1;7830:1163:1;;-1:-1:-1;7830:1163:1;;;;8835:98;;-1:-1:-1;;;7830:1163:1:o;8998:250::-;9083:1;9093:113;9107:6;9104:1;9101:13;9093:113;;;9183:11;;;9177:18;9164:11;;;9157:39;9129:2;9122:10;9093:113;;;-1:-1:-1;;9240:1:1;9222:16;;9215:27;8998:250::o;9253:396::-;9402:2;9391:9;9384:21;9365:4;9434:6;9428:13;9477:6;9472:2;9461:9;9457:18;9450:34;9493:79;9565:6;9560:2;9549:9;9545:18;9540:2;9532:6;9528:15;9493:79;:::i;:::-;9633:2;9612:15;-1:-1:-1;;9608:29:1;9593:45;;;;9640:2;9589:54;;9253:396;-1:-1:-1;;9253:396:1:o;11575:127::-;11636:10;11631:3;11627:20;11624:1;11617:31;11667:4;11664:1;11657:15;11691:4;11688:1;11681:15;11707:127;11768:10;11763:3;11759:20;11756:1;11749:31;11799:4;11796:1;11789:15;11823:4;11820:1;11813:15;11839:125;11904:9;;;11925:10;;;11922:36;;;11938:18;;:::i;11969:128::-;12036:9;;;12057:11;;;12054:37;;;12071:18;;:::i;12102:135::-;12141:3;12162:17;;;12159:43;;12182:18;;:::i;:::-;-1:-1:-1;12229:1:1;12218:13;;12102:135::o;13384:184::-;13454:6;13507:2;13495:9;13486:7;13482:23;13478:32;13475:52;;;13523:1;13520;13513:12;13475:52;-1:-1:-1;13546:16:1;;13384:184;-1:-1:-1;13384:184:1:o;13573:277::-;13640:6;13693:2;13681:9;13672:7;13668:23;13664:32;13661:52;;;13709:1;13706;13699:12;13661:52;13741:9;13735:16;13794:5;13787:13;13780:21;13773:5;13770:32;13760:60;;13816:1;13813;13806:12;16766:168;16839:9;;;16870;;16887:15;;;16881:22;;16867:37;16857:71;;16908:18;;:::i;16939:407::-;17141:2;17123:21;;;17180:2;17160:18;;;17153:30;17219:34;17214:2;17199:18;;17192:62;-1:-1:-1;;;17285:2:1;17270:18;;17263:41;17336:3;17321:19;;16939:407::o;19742:237::-;19814:9;;;19781:7;19839:9;;-1:-1:-1;;;19850:18:1;;19835:34;19832:60;;;19872:18;;:::i;:::-;19945:1;19936:7;19931:16;19928:1;19925:23;19921:1;19914:9;19911:38;19901:72;;19953:18;;:::i;19984:200::-;20050:9;;;20023:4;20078:9;;20106:10;;20118:12;;;20102:29;20141:12;;;20133:21;;20099:56;20096:82;;;20158:18;;:::i;:::-;20096:82;19984:200;;;;:::o;20189:136::-;20224:3;-1:-1:-1;;;20245:22:1;;20242:48;;20270:18;;:::i;:::-;-1:-1:-1;20310:1:1;20306:13;;20189:136::o;20330:127::-;20391:10;20386:3;20382:20;20379:1;20372:31;20422:4;20419:1;20412:15;20446:4;20443:1;20436:15;20462:120;20502:1;20528;20518:35;;20533:18;;:::i;:::-;-1:-1:-1;20567:9:1;;20462:120::o;20994:287::-;21123:3;21161:6;21155:13;21177:66;21236:6;21231:3;21224:4;21216:6;21212:17;21177:66;:::i;:::-;21259:16;;;;;20994:287;-1:-1:-1;;20994:287:1:o;21286:112::-;21318:1;21344;21334:35;;21349:18;;:::i;:::-;-1:-1:-1;21383:9:1;;21286:112::o;21403:127::-;21464:10;21459:3;21455:20;21452:1;21445:31;21495:4;21492:1;21485:15;21519:4;21516:1;21509:15
Swarm Source
ipfs://3fe110dbac2afce103aa95e536ddfc1246e465bc92c902d21e96eadd872e7661
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.