Contract
0xd22b04395705144Fd12AfFD854248427A2776194
1
My Name Tag:
Not Available, login to update
[ Download CSV Export ]
Contract Name:
TroveManager
Compiler Version
v0.6.11+commit.5ef660b1
Contract Source Code (Solidity)
/** *Submitted for verification at snowtrace.io on 2021-11-03 */ // Sources flattened with hardhat v2.1.1 https://hardhat.org // File contracts/Interfaces/IPriceFeed.sol // SPDX-License-Identifier: MIT pragma solidity 0.6.11; interface IPriceFeed { // --- Events --- event LastGoodPriceUpdated(uint _lastGoodPrice); // --- Function --- function fetchPrice() external returns (uint); } // File contracts/Interfaces/ILiquityBase.sol pragma solidity 0.6.11; interface ILiquityBase { function priceFeed() external view returns (IPriceFeed); } // File contracts/Interfaces/IStabilityPool.sol pragma solidity 0.6.11; /* * The Stability Pool holds LUSD tokens deposited by Stability Pool depositors. * * When a trove is liquidated, then depending on system conditions, some of its LUSD debt gets offset with * LUSD in the Stability Pool: that is, the offset debt evaporates, and an equal amount of LUSD tokens in the Stability Pool is burned. * * Thus, a liquidation causes each depositor to receive a LUSD loss, in proportion to their deposit as a share of total deposits. * They also receive an ETH gain, as the ETH collateral of the liquidated trove is distributed among Stability depositors, * in the same proportion. * * When a liquidation occurs, it depletes every deposit by the same fraction: for example, a liquidation that depletes 40% * of the total LUSD in the Stability Pool, depletes 40% of each deposit. * * A deposit that has experienced a series of liquidations is termed a "compounded deposit": each liquidation depletes the deposit, * multiplying it by some factor in range ]0,1[ * * Please see the implementation spec in the proof document, which closely follows on from the compounded deposit / ETH gain derivations: * https://github.com/liquity/liquity/blob/master/papers/Scalable_Reward_Distribution_with_Compounding_Stakes.pdf * * --- LQTY ISSUANCE TO STABILITY POOL DEPOSITORS --- * * An LQTY issuance event occurs at every deposit operation, and every liquidation. * * Each deposit is tagged with the address of the front end through which it was made. * * All deposits earn a share of the issued LQTY in proportion to the deposit as a share of total deposits. The LQTY earned * by a given deposit, is split between the depositor and the front end through which the deposit was made, based on the front end's kickbackRate. * * Please see the system Readme for an overview: * https://github.com/liquity/dev/blob/main/README.md#lqty-issuance-to-stability-providers */ interface IStabilityPool { // --- Events --- event StabilityPoolETHBalanceUpdated(uint _newBalance); event StabilityPoolLUSDBalanceUpdated(uint _newBalance); event BorrowerOperationsAddressChanged(address _newBorrowerOperationsAddress); event TroveManagerAddressChanged(address _newTroveManagerAddress); event ActivePoolAddressChanged(address _newActivePoolAddress); event DefaultPoolAddressChanged(address _newDefaultPoolAddress); event LUSDTokenAddressChanged(address _newLUSDTokenAddress); event SortedTrovesAddressChanged(address _newSortedTrovesAddress); event PriceFeedAddressChanged(address _newPriceFeedAddress); event CommunityIssuanceAddressChanged(address _newCommunityIssuanceAddress); event P_Updated(uint _P); event S_Updated(uint _S, uint128 _epoch, uint128 _scale); event G_Updated(uint _G, uint128 _epoch, uint128 _scale); event EpochUpdated(uint128 _currentEpoch); event ScaleUpdated(uint128 _currentScale); event FrontEndRegistered(address indexed _frontEnd, uint _kickbackRate); event FrontEndTagSet(address indexed _depositor, address indexed _frontEnd); event DepositSnapshotUpdated(address indexed _depositor, uint _P, uint _S, uint _G); event FrontEndSnapshotUpdated(address indexed _frontEnd, uint _P, uint _G); event UserDepositChanged(address indexed _depositor, uint _newDeposit); event FrontEndStakeChanged(address indexed _frontEnd, uint _newFrontEndStake, address _depositor); event ETHGainWithdrawn(address indexed _depositor, uint _ETH, uint _LUSDLoss); event LQTYPaidToDepositor(address indexed _depositor, uint _LQTY); event LQTYPaidToFrontEnd(address indexed _frontEnd, uint _LQTY); event EtherSent(address _to, uint _amount); // --- Functions --- /* * Called only once on init, to set addresses of other Liquity contracts * Callable only by owner, renounces ownership at the end */ function setAddresses( address _borrowerOperationsAddress, address _troveManagerAddress, address _activePoolAddress, address _lusdTokenAddress, address _sortedTrovesAddress, address _priceFeedAddress, address _communityIssuanceAddress ) external; /* * Initial checks: * - Frontend is registered or zero address * - Sender is not a registered frontend * - _amount is not zero * --- * - Triggers a LQTY issuance, based on time passed since the last issuance. The LQTY issuance is shared between *all* depositors and front ends * - Tags the deposit with the provided front end tag param, if it's a new deposit * - Sends depositor's accumulated gains (LQTY, ETH) to depositor * - Sends the tagged front end's accumulated LQTY gains to the tagged front end * - Increases deposit and tagged front end's stake, and takes new snapshots for each. */ function provideToSP(uint _amount, address _frontEndTag) external; /* * Initial checks: * - _amount is zero or there are no under collateralized troves left in the system * - User has a non zero deposit * --- * - Triggers a LQTY issuance, based on time passed since the last issuance. The LQTY issuance is shared between *all* depositors and front ends * - Removes the deposit's front end tag if it is a full withdrawal * - Sends all depositor's accumulated gains (LQTY, ETH) to depositor * - Sends the tagged front end's accumulated LQTY gains to the tagged front end * - Decreases deposit and tagged front end's stake, and takes new snapshots for each. * * If _amount > userDeposit, the user withdraws all of their compounded deposit. */ function withdrawFromSP(uint _amount) external; /* * Initial checks: * - User has a non zero deposit * - User has an open trove * - User has some ETH gain * --- * - Triggers a LQTY issuance, based on time passed since the last issuance. The LQTY issuance is shared between *all* depositors and front ends * - Sends all depositor's LQTY gain to depositor * - Sends all tagged front end's LQTY gain to the tagged front end * - Transfers the depositor's entire ETH gain from the Stability Pool to the caller's trove * - Leaves their compounded deposit in the Stability Pool * - Updates snapshots for deposit and tagged front end stake */ function withdrawETHGainToTrove(address _upperHint, address _lowerHint) external; /* * Initial checks: * - Frontend (sender) not already registered * - User (sender) has no deposit * - _kickbackRate is in the range [0, 100%] * --- * Front end makes a one-time selection of kickback rate upon registering */ function registerFrontEnd(uint _kickbackRate) external; /* * Initial checks: * - Caller is TroveManager * --- * Cancels out the specified debt against the LUSD contained in the Stability Pool (as far as possible) * and transfers the Trove's ETH collateral from ActivePool to StabilityPool. * Only called by liquidation functions in the TroveManager. */ function offset(uint _debt, uint _coll) external; /* * Returns the total amount of ETH held by the pool, accounted in an internal variable instead of `balance`, * to exclude edge cases like ETH received from a self-destruct. */ function getETH() external view returns (uint); /* * Returns LUSD held in the pool. Changes when users deposit/withdraw, and when Trove debt is offset. */ function getTotalLUSDDeposits() external view returns (uint); /* * Calculates the ETH gain earned by the deposit since its last snapshots were taken. */ function getDepositorETHGain(address _depositor) external view returns (uint); /* * Calculate the LQTY gain earned by a deposit since its last snapshots were taken. * If not tagged with a front end, the depositor gets a 100% cut of what their deposit earned. * Otherwise, their cut of the deposit's earnings is equal to the kickbackRate, set by the front end through * which they made their deposit. */ function getDepositorLQTYGain(address _depositor) external view returns (uint); /* * Return the LQTY gain earned by the front end. */ function getFrontEndLQTYGain(address _frontEnd) external view returns (uint); /* * Return the user's compounded deposit. */ function getCompoundedLUSDDeposit(address _depositor) external view returns (uint); /* * Return the front end's compounded stake. * * The front end's compounded stake is equal to the sum of its depositors' compounded deposits. */ function getCompoundedFrontEndStake(address _frontEnd) external view returns (uint); /* * Fallback function * Only callable by Active Pool, it just accounts for ETH received * receive() external payable; */ } // File contracts/Dependencies/IERC20.sol pragma solidity 0.6.11; /** * Based on the OpenZeppelin IER20 interface: * https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/IERC20.sol * * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @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 `recipient`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address recipient, 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); function increaseAllowance(address spender, uint256 addedValue) external returns (bool); function decreaseAllowance(address spender, uint256 subtractedValue) external returns (bool); /** * @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 `sender` to `recipient` 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 sender, address recipient, uint256 amount) external returns (bool); function name() external view returns (string memory); function symbol() external view returns (string memory); function decimals() external view returns (uint8); /** * @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); } // File contracts/Dependencies/IERC2612.sol pragma solidity 0.6.11; /** * @dev Interface of the ERC2612 standard as defined in the EIP. * * Adds the {permit} method, which can be used to change one's * {IERC20-allowance} without having to send a transaction, by signing a * message. This allows users to spend tokens without having to hold Ether. * * See https://eips.ethereum.org/EIPS/eip-2612. * * Code adapted from https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2237/ */ interface IERC2612 { /** * @dev Sets `amount` as the allowance of `spender` over `owner`'s tokens, * given `owner`'s signed approval. * * IMPORTANT: The same issues {IERC20-approve} has related to transaction * ordering also apply here. * * Emits an {Approval} event. * * Requirements: * * - `owner` cannot be the zero address. * - `spender` cannot be the zero address. * - `deadline` must be a timestamp in the future. * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner` * over the EIP712-formatted function arguments. * - the signature must use ``owner``'s current nonce (see {nonces}). * * For more information on the signature format, see the * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP * section]. */ function permit(address owner, address spender, uint256 amount, uint256 deadline, uint8 v, bytes32 r, bytes32 s) external; /** * @dev Returns the current ERC2612 nonce for `owner`. This value must be * included whenever a signature is generated for {permit}. * * Every successful call to {permit} increases `owner`'s nonce by one. This * prevents a signature from being used multiple times. * * `owner` can limit the time a Permit is valid for by setting `deadline` to * a value in the near future. The deadline argument can be set to uint(-1) to * create Permits that effectively never expire. */ function nonces(address owner) external view returns (uint256); function version() external view returns (string memory); function permitTypeHash() external view returns (bytes32); function domainSeparator() external view returns (bytes32); } // File contracts/Interfaces/ILUSDToken.sol pragma solidity 0.6.11; interface ILUSDToken is IERC20, IERC2612 { // --- Events --- event TroveManagerAddressChanged(address _troveManagerAddress); event StabilityPoolAddressChanged(address _newStabilityPoolAddress); event BorrowerOperationsAddressChanged(address _newBorrowerOperationsAddress); event LUSDTokenBalanceUpdated(address _user, uint _amount); // --- Functions --- function mint(address _account, uint256 _amount) external; function burn(address _account, uint256 _amount) external; function sendToPool(address _sender, address poolAddress, uint256 _amount) external; function returnFromPool(address poolAddress, address user, uint256 _amount ) external; } // File contracts/Interfaces/ILQTYToken.sol pragma solidity 0.6.11; interface ILQTYToken is IERC20, IERC2612 { // --- Events --- event CommunityIssuanceAddressSet(address _communityIssuanceAddress); event LQTYStakingAddressSet(address _lqtyStakingAddress); event LockupContractFactoryAddressSet(address _lockupContractFactoryAddress); // --- Functions --- function sendToLQTYStaking(address _sender, uint256 _amount) external; function getDeploymentStartTime() external view returns (uint256); function getLpRewardsEntitlement() external view returns (uint256); } // File contracts/Interfaces/ILQTYStaking.sol pragma solidity 0.6.11; interface ILQTYStaking { // --- Events -- event LQTYTokenAddressSet(address _lqtyTokenAddress); event LUSDTokenAddressSet(address _lusdTokenAddress); event TroveManagerAddressSet(address _troveManager); event BorrowerOperationsAddressSet(address _borrowerOperationsAddress); event ActivePoolAddressSet(address _activePoolAddress); event StakeChanged(address indexed staker, uint newStake); event StakingGainsWithdrawn(address indexed staker, uint LUSDGain, uint ETHGain); event F_ETHUpdated(uint _F_ETH); event F_LUSDUpdated(uint _F_LUSD); event TotalLQTYStakedUpdated(uint _totalLQTYStaked); event EtherSent(address _account, uint _amount); event StakerSnapshotsUpdated(address _staker, uint _F_ETH, uint _F_LUSD); // --- Functions --- function setAddresses ( address _lqtyTokenAddress, address _lusdTokenAddress, address _troveManagerAddress, address _borrowerOperationsAddress, address _activePoolAddress ) external; function stake(uint _LQTYamount) external; function unstake(uint _LQTYamount) external; function increaseF_ETH(uint _ETHFee) external; function increaseF_LUSD(uint _LQTYFee) external; function getPendingETHGain(address _user) external view returns (uint); function getPendingLUSDGain(address _user) external view returns (uint); } // File contracts/Interfaces/ITroveManager.sol pragma solidity 0.6.11; // Common interface for the Trove Manager. interface ITroveManager is ILiquityBase { // --- Events --- event BorrowerOperationsAddressChanged(address _newBorrowerOperationsAddress); event PriceFeedAddressChanged(address _newPriceFeedAddress); event LUSDTokenAddressChanged(address _newLUSDTokenAddress); event ActivePoolAddressChanged(address _activePoolAddress); event DefaultPoolAddressChanged(address _defaultPoolAddress); event StabilityPoolAddressChanged(address _stabilityPoolAddress); event GasPoolAddressChanged(address _gasPoolAddress); event CollSurplusPoolAddressChanged(address _collSurplusPoolAddress); event SortedTrovesAddressChanged(address _sortedTrovesAddress); event LQTYTokenAddressChanged(address _lqtyTokenAddress); event LQTYStakingAddressChanged(address _lqtyStakingAddress); event Liquidation(uint _liquidatedDebt, uint _liquidatedColl, uint _collGasCompensation, uint _LUSDGasCompensation); event Redemption(uint _attemptedLUSDAmount, uint _actualLUSDAmount, uint _ETHSent, uint _ETHFee); event TroveUpdated(address indexed _borrower, uint _debt, uint _coll, uint stake, uint8 operation); event TroveLiquidated(address indexed _borrower, uint _debt, uint _coll, uint8 operation); event BaseRateUpdated(uint _baseRate); event LastFeeOpTimeUpdated(uint _lastFeeOpTime); event TotalStakesUpdated(uint _newTotalStakes); event SystemSnapshotsUpdated(uint _totalStakesSnapshot, uint _totalCollateralSnapshot); event LTermsUpdated(uint _L_ETH, uint _L_LUSDDebt); event TroveSnapshotsUpdated(uint _L_ETH, uint _L_LUSDDebt); event TroveIndexUpdated(address _borrower, uint _newIndex); // --- Functions --- function setAddresses( address _borrowerOperationsAddress, address _activePoolAddress, address _defaultPoolAddress, address _stabilityPoolAddress, address _gasPoolAddress, address _collSurplusPoolAddress, address _priceFeedAddress, address _lusdTokenAddress, address _sortedTrovesAddress, address _lqtyTokenAddress, address _lqtyStakingAddress ) external; function stabilityPool() external view returns (IStabilityPool); function lusdToken() external view returns (ILUSDToken); function lqtyToken() external view returns (ILQTYToken); function lqtyStaking() external view returns (ILQTYStaking); function getTroveOwnersCount() external view returns (uint); function getTroveFromTroveOwnersArray(uint _index) external view returns (address); function getNominalICR(address _borrower) external view returns (uint); function getCurrentICR(address _borrower, uint _price) external view returns (uint); function liquidate(address _borrower) external; function liquidateTroves(uint _n) external; function batchLiquidateTroves(address[] calldata _troveArray) external; function redeemCollateral( uint _LUSDAmount, address _firstRedemptionHint, address _upperPartialRedemptionHint, address _lowerPartialRedemptionHint, uint _partialRedemptionHintNICR, uint _maxIterations, uint _maxFee ) external; function updateStakeAndTotalStakes(address _borrower) external returns (uint); function updateTroveRewardSnapshots(address _borrower) external; function addTroveOwnerToArray(address _borrower) external returns (uint index); function applyPendingRewards(address _borrower) external; function getPendingETHReward(address _borrower) external view returns (uint); function getPendingLUSDDebtReward(address _borrower) external view returns (uint); function hasPendingRewards(address _borrower) external view returns (bool); function getEntireDebtAndColl(address _borrower) external view returns ( uint debt, uint coll, uint pendingLUSDDebtReward, uint pendingETHReward ); function closeTrove(address _borrower) external; function removeStake(address _borrower) external; function getRedemptionRate() external view returns (uint); function getRedemptionRateWithDecay() external view returns (uint); function getRedemptionFeeWithDecay(uint _ETHDrawn) external view returns (uint); function getBorrowingRate() external view returns (uint); function getBorrowingRateWithDecay() external view returns (uint); function getBorrowingFee(uint LUSDDebt) external view returns (uint); function getBorrowingFeeWithDecay(uint _LUSDDebt) external view returns (uint); function decayBaseRateFromBorrowing() external; function getTroveStatus(address _borrower) external view returns (uint); function getTroveStake(address _borrower) external view returns (uint); function getTroveDebt(address _borrower) external view returns (uint); function getTroveColl(address _borrower) external view returns (uint); function setTroveStatus(address _borrower, uint num) external; function increaseTroveColl(address _borrower, uint _collIncrease) external returns (uint); function decreaseTroveColl(address _borrower, uint _collDecrease) external returns (uint); function increaseTroveDebt(address _borrower, uint _debtIncrease) external returns (uint); function decreaseTroveDebt(address _borrower, uint _collDecrease) external returns (uint); function getTCR(uint _price) external view returns (uint); function checkRecoveryMode(uint _price) external view returns (bool); } // File contracts/Interfaces/ICollSurplusPool.sol pragma solidity 0.6.11; interface ICollSurplusPool { // --- Events --- event BorrowerOperationsAddressChanged(address _newBorrowerOperationsAddress); event TroveManagerAddressChanged(address _newTroveManagerAddress); event ActivePoolAddressChanged(address _newActivePoolAddress); event CollBalanceUpdated(address indexed _account, uint _newBalance); event EtherSent(address _to, uint _amount); // --- Contract setters --- function setAddresses( address _borrowerOperationsAddress, address _troveManagerAddress, address _activePoolAddress ) external; function getETH() external view returns (uint); function getCollateral(address _account) external view returns (uint); function accountSurplus(address _account, uint _amount) external; function claimColl(address _account) external; } // File contracts/Interfaces/ISortedTroves.sol pragma solidity 0.6.11; // Common interface for the SortedTroves Doubly Linked List. interface ISortedTroves { // --- Events --- event SortedTrovesAddressChanged(address _sortedDoublyLLAddress); event BorrowerOperationsAddressChanged(address _borrowerOperationsAddress); event NodeAdded(address _id, uint _NICR); event NodeRemoved(address _id); // --- Functions --- function setParams(uint256 _size, address _TroveManagerAddress, address _borrowerOperationsAddress) external; function insert(address _id, uint256 _ICR, address _prevId, address _nextId) external; function remove(address _id) external; function reInsert(address _id, uint256 _newICR, address _prevId, address _nextId) external; function contains(address _id) external view returns (bool); function isFull() external view returns (bool); function isEmpty() external view returns (bool); function getSize() external view returns (uint256); function getMaxSize() external view returns (uint256); function getFirst() external view returns (address); function getLast() external view returns (address); function getNext(address _id) external view returns (address); function getPrev(address _id) external view returns (address); function validInsertPosition(uint256 _ICR, address _prevId, address _nextId) external view returns (bool); function findInsertPosition(uint256 _ICR, address _prevId, address _nextId) external view returns (address, address); } // File contracts/Dependencies/BaseMath.sol pragma solidity 0.6.11; contract BaseMath { uint constant public DECIMAL_PRECISION = 1e18; } // File contracts/Dependencies/SafeMath.sol pragma solidity 0.6.11; /** * Based on OpenZeppelin's SafeMath: * https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/math/SafeMath.sol * * @dev Wrappers over Solidity's arithmetic operations with added overflow * checks. * * Arithmetic operations in Solidity wrap on overflow. This can easily result * in bugs, because programmers usually assume that an overflow raises an * error, which is the standard behavior in high level programming languages. * `SafeMath` restores this intuition by reverting the transaction when 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. */ library SafeMath { /** * @dev Returns the addition of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `+` operator. * * Requirements: * - Addition cannot overflow. */ function add(uint256 a, uint256 b) internal pure returns (uint256) { uint256 c = a + b; require(c >= a, "SafeMath: addition overflow"); return c; } /** * @dev Returns the subtraction of two unsigned integers, reverting on * overflow (when the result is negative). * * Counterpart to Solidity's `-` operator. * * Requirements: * - Subtraction cannot overflow. */ function sub(uint256 a, uint256 b) internal pure returns (uint256) { return sub(a, b, "SafeMath: subtraction overflow"); } /** * @dev Returns the subtraction of two unsigned integers, reverting with custom message on * overflow (when the result is negative). * * Counterpart to Solidity's `-` operator. * * Requirements: * - Subtraction cannot overflow. * * _Available since v2.4.0._ */ function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b <= a, errorMessage); uint256 c = a - b; return c; } /** * @dev Returns the multiplication of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `*` operator. * * Requirements: * - Multiplication cannot overflow. */ function mul(uint256 a, uint256 b) internal pure returns (uint256) { // Gas optimization: this is cheaper than requiring 'a' not being zero, but the // benefit is lost if 'b' is also tested. // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522 if (a == 0) { return 0; } uint256 c = a * b; require(c / a == b, "SafeMath: multiplication overflow"); return c; } /** * @dev Returns the integer division of two unsigned integers. Reverts on * division by zero. The result is rounded towards zero. * * Counterpart to Solidity's `/` operator. Note: this function uses a * `revert` opcode (which leaves remaining gas untouched) while Solidity * uses an invalid opcode to revert (consuming all remaining gas). * * Requirements: * - The divisor cannot be zero. */ function div(uint256 a, uint256 b) internal pure returns (uint256) { return div(a, b, "SafeMath: division by zero"); } /** * @dev Returns the integer division of two unsigned integers. Reverts with custom message on * division by zero. The result is rounded towards zero. * * Counterpart to Solidity's `/` operator. Note: this function uses a * `revert` opcode (which leaves remaining gas untouched) while Solidity * uses an invalid opcode to revert (consuming all remaining gas). * * Requirements: * - The divisor cannot be zero. * * _Available since v2.4.0._ */ function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { // Solidity only automatically asserts when dividing by 0 require(b > 0, errorMessage); uint256 c = a / b; // assert(a == b * c + a % b); // There is no case in which this doesn't hold return c; } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * Reverts when dividing by zero. * * Counterpart to Solidity's `%` operator. This function uses a `revert` * opcode (which leaves remaining gas untouched) while Solidity uses an * invalid opcode to revert (consuming all remaining gas). * * Requirements: * - The divisor cannot be zero. */ function mod(uint256 a, uint256 b) internal pure returns (uint256) { return mod(a, b, "SafeMath: modulo by zero"); } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * Reverts with custom message when dividing by zero. * * Counterpart to Solidity's `%` operator. This function uses a `revert` * opcode (which leaves remaining gas untouched) while Solidity uses an * invalid opcode to revert (consuming all remaining gas). * * Requirements: * - The divisor cannot be zero. * * _Available since v2.4.0._ */ function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b != 0, errorMessage); return a % b; } } // File contracts/Dependencies/console.sol pragma solidity 0.6.11; // Buidler's helper contract for console logging library console { address constant CONSOLE_ADDRESS = address(0x000000000000000000636F6e736F6c652e6c6f67); function log() internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log()")); ignored; } function logInt(int p0) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(int)", p0)); ignored; } function logUint(uint p0) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(uint)", p0)); ignored; } function logString(string memory p0) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(string)", p0)); ignored; } function logBool(bool p0) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bool)", p0)); ignored; } function logAddress(address p0) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(address)", p0)); ignored; } function logBytes(bytes memory p0) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bytes)", p0)); ignored; } function logByte(byte p0) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(byte)", p0)); ignored; } function logBytes1(bytes1 p0) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bytes1)", p0)); ignored; } function logBytes2(bytes2 p0) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bytes2)", p0)); ignored; } function logBytes3(bytes3 p0) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bytes3)", p0)); ignored; } function logBytes4(bytes4 p0) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bytes4)", p0)); ignored; } function logBytes5(bytes5 p0) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bytes5)", p0)); ignored; } function logBytes6(bytes6 p0) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bytes6)", p0)); ignored; } function logBytes7(bytes7 p0) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bytes7)", p0)); ignored; } function logBytes8(bytes8 p0) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bytes8)", p0)); ignored; } function logBytes9(bytes9 p0) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bytes9)", p0)); ignored; } function logBytes10(bytes10 p0) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bytes10)", p0)); ignored; } function logBytes11(bytes11 p0) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bytes11)", p0)); ignored; } function logBytes12(bytes12 p0) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bytes12)", p0)); ignored; } function logBytes13(bytes13 p0) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bytes13)", p0)); ignored; } function logBytes14(bytes14 p0) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bytes14)", p0)); ignored; } function logBytes15(bytes15 p0) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bytes15)", p0)); ignored; } function logBytes16(bytes16 p0) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bytes16)", p0)); ignored; } function logBytes17(bytes17 p0) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bytes17)", p0)); ignored; } function logBytes18(bytes18 p0) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bytes18)", p0)); ignored; } function logBytes19(bytes19 p0) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bytes19)", p0)); ignored; } function logBytes20(bytes20 p0) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bytes20)", p0)); ignored; } function logBytes21(bytes21 p0) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bytes21)", p0)); ignored; } function logBytes22(bytes22 p0) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bytes22)", p0)); ignored; } function logBytes23(bytes23 p0) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bytes23)", p0)); ignored; } function logBytes24(bytes24 p0) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bytes24)", p0)); ignored; } function logBytes25(bytes25 p0) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bytes25)", p0)); ignored; } function logBytes26(bytes26 p0) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bytes26)", p0)); ignored; } function logBytes27(bytes27 p0) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bytes27)", p0)); ignored; } function logBytes28(bytes28 p0) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bytes28)", p0)); ignored; } function logBytes29(bytes29 p0) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bytes29)", p0)); ignored; } function logBytes30(bytes30 p0) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bytes30)", p0)); ignored; } function logBytes31(bytes31 p0) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bytes31)", p0)); ignored; } function logBytes32(bytes32 p0) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bytes32)", p0)); ignored; } function log(uint p0) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(uint)", p0)); ignored; } function log(string memory p0) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(string)", p0)); ignored; } function log(bool p0) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bool)", p0)); ignored; } function log(address p0) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(address)", p0)); ignored; } function log(uint p0, uint p1) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(uint,uint)", p0, p1)); ignored; } function log(uint p0, string memory p1) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(uint,string)", p0, p1)); ignored; } function log(uint p0, bool p1) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(uint,bool)", p0, p1)); ignored; } function log(uint p0, address p1) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(uint,address)", p0, p1)); ignored; } function log(string memory p0, uint p1) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(string,uint)", p0, p1)); ignored; } function log(string memory p0, string memory p1) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(string,string)", p0, p1)); ignored; } function log(string memory p0, bool p1) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(string,bool)", p0, p1)); ignored; } function log(string memory p0, address p1) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(string,address)", p0, p1)); ignored; } function log(bool p0, uint p1) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bool,uint)", p0, p1)); ignored; } function log(bool p0, string memory p1) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bool,string)", p0, p1)); ignored; } function log(bool p0, bool p1) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bool,bool)", p0, p1)); ignored; } function log(bool p0, address p1) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bool,address)", p0, p1)); ignored; } function log(address p0, uint p1) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(address,uint)", p0, p1)); ignored; } function log(address p0, string memory p1) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(address,string)", p0, p1)); ignored; } function log(address p0, bool p1) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(address,bool)", p0, p1)); ignored; } function log(address p0, address p1) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(address,address)", p0, p1)); ignored; } function log(uint p0, uint p1, uint p2) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(uint,uint,uint)", p0, p1, p2)); ignored; } function log(uint p0, uint p1, string memory p2) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(uint,uint,string)", p0, p1, p2)); ignored; } function log(uint p0, uint p1, bool p2) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(uint,uint,bool)", p0, p1, p2)); ignored; } function log(uint p0, uint p1, address p2) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(uint,uint,address)", p0, p1, p2)); ignored; } function log(uint p0, string memory p1, uint p2) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(uint,string,uint)", p0, p1, p2)); ignored; } function log(uint p0, string memory p1, string memory p2) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(uint,string,string)", p0, p1, p2)); ignored; } function log(uint p0, string memory p1, bool p2) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(uint,string,bool)", p0, p1, p2)); ignored; } function log(uint p0, string memory p1, address p2) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(uint,string,address)", p0, p1, p2)); ignored; } function log(uint p0, bool p1, uint p2) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(uint,bool,uint)", p0, p1, p2)); ignored; } function log(uint p0, bool p1, string memory p2) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(uint,bool,string)", p0, p1, p2)); ignored; } function log(uint p0, bool p1, bool p2) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(uint,bool,bool)", p0, p1, p2)); ignored; } function log(uint p0, bool p1, address p2) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(uint,bool,address)", p0, p1, p2)); ignored; } function log(uint p0, address p1, uint p2) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(uint,address,uint)", p0, p1, p2)); ignored; } function log(uint p0, address p1, string memory p2) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(uint,address,string)", p0, p1, p2)); ignored; } function log(uint p0, address p1, bool p2) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(uint,address,bool)", p0, p1, p2)); ignored; } function log(uint p0, address p1, address p2) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(uint,address,address)", p0, p1, p2)); ignored; } function log(string memory p0, uint p1, uint p2) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(string,uint,uint)", p0, p1, p2)); ignored; } function log(string memory p0, uint p1, string memory p2) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(string,uint,string)", p0, p1, p2)); ignored; } function log(string memory p0, uint p1, bool p2) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(string,uint,bool)", p0, p1, p2)); ignored; } function log(string memory p0, uint p1, address p2) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(string,uint,address)", p0, p1, p2)); ignored; } function log(string memory p0, string memory p1, uint p2) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(string,string,uint)", p0, p1, p2)); ignored; } function log(string memory p0, string memory p1, string memory p2) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(string,string,string)", p0, p1, p2)); ignored; } function log(string memory p0, string memory p1, bool p2) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(string,string,bool)", p0, p1, p2)); ignored; } function log(string memory p0, string memory p1, address p2) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(string,string,address)", p0, p1, p2)); ignored; } function log(string memory p0, bool p1, uint p2) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(string,bool,uint)", p0, p1, p2)); ignored; } function log(string memory p0, bool p1, string memory p2) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(string,bool,string)", p0, p1, p2)); ignored; } function log(string memory p0, bool p1, bool p2) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(string,bool,bool)", p0, p1, p2)); ignored; } function log(string memory p0, bool p1, address p2) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(string,bool,address)", p0, p1, p2)); ignored; } function log(string memory p0, address p1, uint p2) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(string,address,uint)", p0, p1, p2)); ignored; } function log(string memory p0, address p1, string memory p2) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(string,address,string)", p0, p1, p2)); ignored; } function log(string memory p0, address p1, bool p2) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(string,address,bool)", p0, p1, p2)); ignored; } function log(string memory p0, address p1, address p2) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(string,address,address)", p0, p1, p2)); ignored; } function log(bool p0, uint p1, uint p2) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bool,uint,uint)", p0, p1, p2)); ignored; } function log(bool p0, uint p1, string memory p2) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bool,uint,string)", p0, p1, p2)); ignored; } function log(bool p0, uint p1, bool p2) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bool,uint,bool)", p0, p1, p2)); ignored; } function log(bool p0, uint p1, address p2) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bool,uint,address)", p0, p1, p2)); ignored; } function log(bool p0, string memory p1, uint p2) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bool,string,uint)", p0, p1, p2)); ignored; } function log(bool p0, string memory p1, string memory p2) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bool,string,string)", p0, p1, p2)); ignored; } function log(bool p0, string memory p1, bool p2) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bool,string,bool)", p0, p1, p2)); ignored; } function log(bool p0, string memory p1, address p2) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bool,string,address)", p0, p1, p2)); ignored; } function log(bool p0, bool p1, uint p2) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bool,bool,uint)", p0, p1, p2)); ignored; } function log(bool p0, bool p1, string memory p2) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bool,bool,string)", p0, p1, p2)); ignored; } function log(bool p0, bool p1, bool p2) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bool,bool,bool)", p0, p1, p2)); ignored; } function log(bool p0, bool p1, address p2) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bool,bool,address)", p0, p1, p2)); ignored; } function log(bool p0, address p1, uint p2) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bool,address,uint)", p0, p1, p2)); ignored; } function log(bool p0, address p1, string memory p2) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bool,address,string)", p0, p1, p2)); ignored; } function log(bool p0, address p1, bool p2) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bool,address,bool)", p0, p1, p2)); ignored; } function log(bool p0, address p1, address p2) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bool,address,address)", p0, p1, p2)); ignored; } function log(address p0, uint p1, uint p2) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(address,uint,uint)", p0, p1, p2)); ignored; } function log(address p0, uint p1, string memory p2) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(address,uint,string)", p0, p1, p2)); ignored; } function log(address p0, uint p1, bool p2) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(address,uint,bool)", p0, p1, p2)); ignored; } function log(address p0, uint p1, address p2) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(address,uint,address)", p0, p1, p2)); ignored; } function log(address p0, string memory p1, uint p2) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(address,string,uint)", p0, p1, p2)); ignored; } function log(address p0, string memory p1, string memory p2) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(address,string,string)", p0, p1, p2)); ignored; } function log(address p0, string memory p1, bool p2) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(address,string,bool)", p0, p1, p2)); ignored; } function log(address p0, string memory p1, address p2) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(address,string,address)", p0, p1, p2)); ignored; } function log(address p0, bool p1, uint p2) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(address,bool,uint)", p0, p1, p2)); ignored; } function log(address p0, bool p1, string memory p2) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(address,bool,string)", p0, p1, p2)); ignored; } function log(address p0, bool p1, bool p2) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(address,bool,bool)", p0, p1, p2)); ignored; } function log(address p0, bool p1, address p2) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(address,bool,address)", p0, p1, p2)); ignored; } function log(address p0, address p1, uint p2) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(address,address,uint)", p0, p1, p2)); ignored; } function log(address p0, address p1, string memory p2) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(address,address,string)", p0, p1, p2)); ignored; } function log(address p0, address p1, bool p2) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(address,address,bool)", p0, p1, p2)); ignored; } function log(address p0, address p1, address p2) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(address,address,address)", p0, p1, p2)); ignored; } function log(uint p0, uint p1, uint p2, uint p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(uint,uint,uint,uint)", p0, p1, p2, p3)); ignored; } function log(uint p0, uint p1, uint p2, string memory p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(uint,uint,uint,string)", p0, p1, p2, p3)); ignored; } function log(uint p0, uint p1, uint p2, bool p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(uint,uint,uint,bool)", p0, p1, p2, p3)); ignored; } function log(uint p0, uint p1, uint p2, address p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(uint,uint,uint,address)", p0, p1, p2, p3)); ignored; } function log(uint p0, uint p1, string memory p2, uint p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(uint,uint,string,uint)", p0, p1, p2, p3)); ignored; } function log(uint p0, uint p1, string memory p2, string memory p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(uint,uint,string,string)", p0, p1, p2, p3)); ignored; } function log(uint p0, uint p1, string memory p2, bool p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(uint,uint,string,bool)", p0, p1, p2, p3)); ignored; } function log(uint p0, uint p1, string memory p2, address p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(uint,uint,string,address)", p0, p1, p2, p3)); ignored; } function log(uint p0, uint p1, bool p2, uint p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(uint,uint,bool,uint)", p0, p1, p2, p3)); ignored; } function log(uint p0, uint p1, bool p2, string memory p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(uint,uint,bool,string)", p0, p1, p2, p3)); ignored; } function log(uint p0, uint p1, bool p2, bool p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(uint,uint,bool,bool)", p0, p1, p2, p3)); ignored; } function log(uint p0, uint p1, bool p2, address p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(uint,uint,bool,address)", p0, p1, p2, p3)); ignored; } function log(uint p0, uint p1, address p2, uint p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(uint,uint,address,uint)", p0, p1, p2, p3)); ignored; } function log(uint p0, uint p1, address p2, string memory p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(uint,uint,address,string)", p0, p1, p2, p3)); ignored; } function log(uint p0, uint p1, address p2, bool p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(uint,uint,address,bool)", p0, p1, p2, p3)); ignored; } function log(uint p0, uint p1, address p2, address p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(uint,uint,address,address)", p0, p1, p2, p3)); ignored; } function log(uint p0, string memory p1, uint p2, uint p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(uint,string,uint,uint)", p0, p1, p2, p3)); ignored; } function log(uint p0, string memory p1, uint p2, string memory p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(uint,string,uint,string)", p0, p1, p2, p3)); ignored; } function log(uint p0, string memory p1, uint p2, bool p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(uint,string,uint,bool)", p0, p1, p2, p3)); ignored; } function log(uint p0, string memory p1, uint p2, address p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(uint,string,uint,address)", p0, p1, p2, p3)); ignored; } function log(uint p0, string memory p1, string memory p2, uint p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(uint,string,string,uint)", p0, p1, p2, p3)); ignored; } function log(uint p0, string memory p1, string memory p2, string memory p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(uint,string,string,string)", p0, p1, p2, p3)); ignored; } function log(uint p0, string memory p1, string memory p2, bool p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(uint,string,string,bool)", p0, p1, p2, p3)); ignored; } function log(uint p0, string memory p1, string memory p2, address p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(uint,string,string,address)", p0, p1, p2, p3)); ignored; } function log(uint p0, string memory p1, bool p2, uint p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(uint,string,bool,uint)", p0, p1, p2, p3)); ignored; } function log(uint p0, string memory p1, bool p2, string memory p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(uint,string,bool,string)", p0, p1, p2, p3)); ignored; } function log(uint p0, string memory p1, bool p2, bool p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(uint,string,bool,bool)", p0, p1, p2, p3)); ignored; } function log(uint p0, string memory p1, bool p2, address p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(uint,string,bool,address)", p0, p1, p2, p3)); ignored; } function log(uint p0, string memory p1, address p2, uint p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(uint,string,address,uint)", p0, p1, p2, p3)); ignored; } function log(uint p0, string memory p1, address p2, string memory p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(uint,string,address,string)", p0, p1, p2, p3)); ignored; } function log(uint p0, string memory p1, address p2, bool p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(uint,string,address,bool)", p0, p1, p2, p3)); ignored; } function log(uint p0, string memory p1, address p2, address p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(uint,string,address,address)", p0, p1, p2, p3)); ignored; } function log(uint p0, bool p1, uint p2, uint p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(uint,bool,uint,uint)", p0, p1, p2, p3)); ignored; } function log(uint p0, bool p1, uint p2, string memory p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(uint,bool,uint,string)", p0, p1, p2, p3)); ignored; } function log(uint p0, bool p1, uint p2, bool p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(uint,bool,uint,bool)", p0, p1, p2, p3)); ignored; } function log(uint p0, bool p1, uint p2, address p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(uint,bool,uint,address)", p0, p1, p2, p3)); ignored; } function log(uint p0, bool p1, string memory p2, uint p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(uint,bool,string,uint)", p0, p1, p2, p3)); ignored; } function log(uint p0, bool p1, string memory p2, string memory p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(uint,bool,string,string)", p0, p1, p2, p3)); ignored; } function log(uint p0, bool p1, string memory p2, bool p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(uint,bool,string,bool)", p0, p1, p2, p3)); ignored; } function log(uint p0, bool p1, string memory p2, address p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(uint,bool,string,address)", p0, p1, p2, p3)); ignored; } function log(uint p0, bool p1, bool p2, uint p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(uint,bool,bool,uint)", p0, p1, p2, p3)); ignored; } function log(uint p0, bool p1, bool p2, string memory p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(uint,bool,bool,string)", p0, p1, p2, p3)); ignored; } function log(uint p0, bool p1, bool p2, bool p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(uint,bool,bool,bool)", p0, p1, p2, p3)); ignored; } function log(uint p0, bool p1, bool p2, address p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(uint,bool,bool,address)", p0, p1, p2, p3)); ignored; } function log(uint p0, bool p1, address p2, uint p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(uint,bool,address,uint)", p0, p1, p2, p3)); ignored; } function log(uint p0, bool p1, address p2, string memory p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(uint,bool,address,string)", p0, p1, p2, p3)); ignored; } function log(uint p0, bool p1, address p2, bool p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(uint,bool,address,bool)", p0, p1, p2, p3)); ignored; } function log(uint p0, bool p1, address p2, address p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(uint,bool,address,address)", p0, p1, p2, p3)); ignored; } function log(uint p0, address p1, uint p2, uint p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(uint,address,uint,uint)", p0, p1, p2, p3)); ignored; } function log(uint p0, address p1, uint p2, string memory p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(uint,address,uint,string)", p0, p1, p2, p3)); ignored; } function log(uint p0, address p1, uint p2, bool p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(uint,address,uint,bool)", p0, p1, p2, p3)); ignored; } function log(uint p0, address p1, uint p2, address p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(uint,address,uint,address)", p0, p1, p2, p3)); ignored; } function log(uint p0, address p1, string memory p2, uint p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(uint,address,string,uint)", p0, p1, p2, p3)); ignored; } function log(uint p0, address p1, string memory p2, string memory p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(uint,address,string,string)", p0, p1, p2, p3)); ignored; } function log(uint p0, address p1, string memory p2, bool p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(uint,address,string,bool)", p0, p1, p2, p3)); ignored; } function log(uint p0, address p1, string memory p2, address p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(uint,address,string,address)", p0, p1, p2, p3)); ignored; } function log(uint p0, address p1, bool p2, uint p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(uint,address,bool,uint)", p0, p1, p2, p3)); ignored; } function log(uint p0, address p1, bool p2, string memory p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(uint,address,bool,string)", p0, p1, p2, p3)); ignored; } function log(uint p0, address p1, bool p2, bool p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(uint,address,bool,bool)", p0, p1, p2, p3)); ignored; } function log(uint p0, address p1, bool p2, address p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(uint,address,bool,address)", p0, p1, p2, p3)); ignored; } function log(uint p0, address p1, address p2, uint p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(uint,address,address,uint)", p0, p1, p2, p3)); ignored; } function log(uint p0, address p1, address p2, string memory p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(uint,address,address,string)", p0, p1, p2, p3)); ignored; } function log(uint p0, address p1, address p2, bool p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(uint,address,address,bool)", p0, p1, p2, p3)); ignored; } function log(uint p0, address p1, address p2, address p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(uint,address,address,address)", p0, p1, p2, p3)); ignored; } function log(string memory p0, uint p1, uint p2, uint p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(string,uint,uint,uint)", p0, p1, p2, p3)); ignored; } function log(string memory p0, uint p1, uint p2, string memory p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(string,uint,uint,string)", p0, p1, p2, p3)); ignored; } function log(string memory p0, uint p1, uint p2, bool p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(string,uint,uint,bool)", p0, p1, p2, p3)); ignored; } function log(string memory p0, uint p1, uint p2, address p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(string,uint,uint,address)", p0, p1, p2, p3)); ignored; } function log(string memory p0, uint p1, string memory p2, uint p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(string,uint,string,uint)", p0, p1, p2, p3)); ignored; } function log(string memory p0, uint p1, string memory p2, string memory p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(string,uint,string,string)", p0, p1, p2, p3)); ignored; } function log(string memory p0, uint p1, string memory p2, bool p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(string,uint,string,bool)", p0, p1, p2, p3)); ignored; } function log(string memory p0, uint p1, string memory p2, address p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(string,uint,string,address)", p0, p1, p2, p3)); ignored; } function log(string memory p0, uint p1, bool p2, uint p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(string,uint,bool,uint)", p0, p1, p2, p3)); ignored; } function log(string memory p0, uint p1, bool p2, string memory p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(string,uint,bool,string)", p0, p1, p2, p3)); ignored; } function log(string memory p0, uint p1, bool p2, bool p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(string,uint,bool,bool)", p0, p1, p2, p3)); ignored; } function log(string memory p0, uint p1, bool p2, address p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(string,uint,bool,address)", p0, p1, p2, p3)); ignored; } function log(string memory p0, uint p1, address p2, uint p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(string,uint,address,uint)", p0, p1, p2, p3)); ignored; } function log(string memory p0, uint p1, address p2, string memory p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(string,uint,address,string)", p0, p1, p2, p3)); ignored; } function log(string memory p0, uint p1, address p2, bool p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(string,uint,address,bool)", p0, p1, p2, p3)); ignored; } function log(string memory p0, uint p1, address p2, address p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(string,uint,address,address)", p0, p1, p2, p3)); ignored; } function log(string memory p0, string memory p1, uint p2, uint p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(string,string,uint,uint)", p0, p1, p2, p3)); ignored; } function log(string memory p0, string memory p1, uint p2, string memory p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(string,string,uint,string)", p0, p1, p2, p3)); ignored; } function log(string memory p0, string memory p1, uint p2, bool p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(string,string,uint,bool)", p0, p1, p2, p3)); ignored; } function log(string memory p0, string memory p1, uint p2, address p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(string,string,uint,address)", p0, p1, p2, p3)); ignored; } function log(string memory p0, string memory p1, string memory p2, uint p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(string,string,string,uint)", p0, p1, p2, p3)); ignored; } function log(string memory p0, string memory p1, string memory p2, string memory p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(string,string,string,string)", p0, p1, p2, p3)); ignored; } function log(string memory p0, string memory p1, string memory p2, bool p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(string,string,string,bool)", p0, p1, p2, p3)); ignored; } function log(string memory p0, string memory p1, string memory p2, address p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(string,string,string,address)", p0, p1, p2, p3)); ignored; } function log(string memory p0, string memory p1, bool p2, uint p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(string,string,bool,uint)", p0, p1, p2, p3)); ignored; } function log(string memory p0, string memory p1, bool p2, string memory p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(string,string,bool,string)", p0, p1, p2, p3)); ignored; } function log(string memory p0, string memory p1, bool p2, bool p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(string,string,bool,bool)", p0, p1, p2, p3)); ignored; } function log(string memory p0, string memory p1, bool p2, address p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(string,string,bool,address)", p0, p1, p2, p3)); ignored; } function log(string memory p0, string memory p1, address p2, uint p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(string,string,address,uint)", p0, p1, p2, p3)); ignored; } function log(string memory p0, string memory p1, address p2, string memory p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(string,string,address,string)", p0, p1, p2, p3)); ignored; } function log(string memory p0, string memory p1, address p2, bool p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(string,string,address,bool)", p0, p1, p2, p3)); ignored; } function log(string memory p0, string memory p1, address p2, address p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(string,string,address,address)", p0, p1, p2, p3)); ignored; } function log(string memory p0, bool p1, uint p2, uint p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(string,bool,uint,uint)", p0, p1, p2, p3)); ignored; } function log(string memory p0, bool p1, uint p2, string memory p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(string,bool,uint,string)", p0, p1, p2, p3)); ignored; } function log(string memory p0, bool p1, uint p2, bool p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(string,bool,uint,bool)", p0, p1, p2, p3)); ignored; } function log(string memory p0, bool p1, uint p2, address p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(string,bool,uint,address)", p0, p1, p2, p3)); ignored; } function log(string memory p0, bool p1, string memory p2, uint p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(string,bool,string,uint)", p0, p1, p2, p3)); ignored; } function log(string memory p0, bool p1, string memory p2, string memory p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(string,bool,string,string)", p0, p1, p2, p3)); ignored; } function log(string memory p0, bool p1, string memory p2, bool p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(string,bool,string,bool)", p0, p1, p2, p3)); ignored; } function log(string memory p0, bool p1, string memory p2, address p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(string,bool,string,address)", p0, p1, p2, p3)); ignored; } function log(string memory p0, bool p1, bool p2, uint p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(string,bool,bool,uint)", p0, p1, p2, p3)); ignored; } function log(string memory p0, bool p1, bool p2, string memory p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(string,bool,bool,string)", p0, p1, p2, p3)); ignored; } function log(string memory p0, bool p1, bool p2, bool p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(string,bool,bool,bool)", p0, p1, p2, p3)); ignored; } function log(string memory p0, bool p1, bool p2, address p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(string,bool,bool,address)", p0, p1, p2, p3)); ignored; } function log(string memory p0, bool p1, address p2, uint p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(string,bool,address,uint)", p0, p1, p2, p3)); ignored; } function log(string memory p0, bool p1, address p2, string memory p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(string,bool,address,string)", p0, p1, p2, p3)); ignored; } function log(string memory p0, bool p1, address p2, bool p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(string,bool,address,bool)", p0, p1, p2, p3)); ignored; } function log(string memory p0, bool p1, address p2, address p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(string,bool,address,address)", p0, p1, p2, p3)); ignored; } function log(string memory p0, address p1, uint p2, uint p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(string,address,uint,uint)", p0, p1, p2, p3)); ignored; } function log(string memory p0, address p1, uint p2, string memory p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(string,address,uint,string)", p0, p1, p2, p3)); ignored; } function log(string memory p0, address p1, uint p2, bool p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(string,address,uint,bool)", p0, p1, p2, p3)); ignored; } function log(string memory p0, address p1, uint p2, address p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(string,address,uint,address)", p0, p1, p2, p3)); ignored; } function log(string memory p0, address p1, string memory p2, uint p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(string,address,string,uint)", p0, p1, p2, p3)); ignored; } function log(string memory p0, address p1, string memory p2, string memory p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(string,address,string,string)", p0, p1, p2, p3)); ignored; } function log(string memory p0, address p1, string memory p2, bool p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(string,address,string,bool)", p0, p1, p2, p3)); ignored; } function log(string memory p0, address p1, string memory p2, address p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(string,address,string,address)", p0, p1, p2, p3)); ignored; } function log(string memory p0, address p1, bool p2, uint p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(string,address,bool,uint)", p0, p1, p2, p3)); ignored; } function log(string memory p0, address p1, bool p2, string memory p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(string,address,bool,string)", p0, p1, p2, p3)); ignored; } function log(string memory p0, address p1, bool p2, bool p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(string,address,bool,bool)", p0, p1, p2, p3)); ignored; } function log(string memory p0, address p1, bool p2, address p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(string,address,bool,address)", p0, p1, p2, p3)); ignored; } function log(string memory p0, address p1, address p2, uint p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(string,address,address,uint)", p0, p1, p2, p3)); ignored; } function log(string memory p0, address p1, address p2, string memory p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(string,address,address,string)", p0, p1, p2, p3)); ignored; } function log(string memory p0, address p1, address p2, bool p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(string,address,address,bool)", p0, p1, p2, p3)); ignored; } function log(string memory p0, address p1, address p2, address p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(string,address,address,address)", p0, p1, p2, p3)); ignored; } function log(bool p0, uint p1, uint p2, uint p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bool,uint,uint,uint)", p0, p1, p2, p3)); ignored; } function log(bool p0, uint p1, uint p2, string memory p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bool,uint,uint,string)", p0, p1, p2, p3)); ignored; } function log(bool p0, uint p1, uint p2, bool p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bool,uint,uint,bool)", p0, p1, p2, p3)); ignored; } function log(bool p0, uint p1, uint p2, address p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bool,uint,uint,address)", p0, p1, p2, p3)); ignored; } function log(bool p0, uint p1, string memory p2, uint p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bool,uint,string,uint)", p0, p1, p2, p3)); ignored; } function log(bool p0, uint p1, string memory p2, string memory p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bool,uint,string,string)", p0, p1, p2, p3)); ignored; } function log(bool p0, uint p1, string memory p2, bool p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bool,uint,string,bool)", p0, p1, p2, p3)); ignored; } function log(bool p0, uint p1, string memory p2, address p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bool,uint,string,address)", p0, p1, p2, p3)); ignored; } function log(bool p0, uint p1, bool p2, uint p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bool,uint,bool,uint)", p0, p1, p2, p3)); ignored; } function log(bool p0, uint p1, bool p2, string memory p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bool,uint,bool,string)", p0, p1, p2, p3)); ignored; } function log(bool p0, uint p1, bool p2, bool p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bool,uint,bool,bool)", p0, p1, p2, p3)); ignored; } function log(bool p0, uint p1, bool p2, address p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bool,uint,bool,address)", p0, p1, p2, p3)); ignored; } function log(bool p0, uint p1, address p2, uint p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bool,uint,address,uint)", p0, p1, p2, p3)); ignored; } function log(bool p0, uint p1, address p2, string memory p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bool,uint,address,string)", p0, p1, p2, p3)); ignored; } function log(bool p0, uint p1, address p2, bool p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bool,uint,address,bool)", p0, p1, p2, p3)); ignored; } function log(bool p0, uint p1, address p2, address p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bool,uint,address,address)", p0, p1, p2, p3)); ignored; } function log(bool p0, string memory p1, uint p2, uint p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bool,string,uint,uint)", p0, p1, p2, p3)); ignored; } function log(bool p0, string memory p1, uint p2, string memory p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bool,string,uint,string)", p0, p1, p2, p3)); ignored; } function log(bool p0, string memory p1, uint p2, bool p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bool,string,uint,bool)", p0, p1, p2, p3)); ignored; } function log(bool p0, string memory p1, uint p2, address p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bool,string,uint,address)", p0, p1, p2, p3)); ignored; } function log(bool p0, string memory p1, string memory p2, uint p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bool,string,string,uint)", p0, p1, p2, p3)); ignored; } function log(bool p0, string memory p1, string memory p2, string memory p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bool,string,string,string)", p0, p1, p2, p3)); ignored; } function log(bool p0, string memory p1, string memory p2, bool p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bool,string,string,bool)", p0, p1, p2, p3)); ignored; } function log(bool p0, string memory p1, string memory p2, address p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bool,string,string,address)", p0, p1, p2, p3)); ignored; } function log(bool p0, string memory p1, bool p2, uint p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bool,string,bool,uint)", p0, p1, p2, p3)); ignored; } function log(bool p0, string memory p1, bool p2, string memory p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bool,string,bool,string)", p0, p1, p2, p3)); ignored; } function log(bool p0, string memory p1, bool p2, bool p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bool,string,bool,bool)", p0, p1, p2, p3)); ignored; } function log(bool p0, string memory p1, bool p2, address p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bool,string,bool,address)", p0, p1, p2, p3)); ignored; } function log(bool p0, string memory p1, address p2, uint p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bool,string,address,uint)", p0, p1, p2, p3)); ignored; } function log(bool p0, string memory p1, address p2, string memory p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bool,string,address,string)", p0, p1, p2, p3)); ignored; } function log(bool p0, string memory p1, address p2, bool p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bool,string,address,bool)", p0, p1, p2, p3)); ignored; } function log(bool p0, string memory p1, address p2, address p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bool,string,address,address)", p0, p1, p2, p3)); ignored; } function log(bool p0, bool p1, uint p2, uint p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bool,bool,uint,uint)", p0, p1, p2, p3)); ignored; } function log(bool p0, bool p1, uint p2, string memory p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bool,bool,uint,string)", p0, p1, p2, p3)); ignored; } function log(bool p0, bool p1, uint p2, bool p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bool,bool,uint,bool)", p0, p1, p2, p3)); ignored; } function log(bool p0, bool p1, uint p2, address p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bool,bool,uint,address)", p0, p1, p2, p3)); ignored; } function log(bool p0, bool p1, string memory p2, uint p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bool,bool,string,uint)", p0, p1, p2, p3)); ignored; } function log(bool p0, bool p1, string memory p2, string memory p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bool,bool,string,string)", p0, p1, p2, p3)); ignored; } function log(bool p0, bool p1, string memory p2, bool p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bool,bool,string,bool)", p0, p1, p2, p3)); ignored; } function log(bool p0, bool p1, string memory p2, address p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bool,bool,string,address)", p0, p1, p2, p3)); ignored; } function log(bool p0, bool p1, bool p2, uint p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bool,bool,bool,uint)", p0, p1, p2, p3)); ignored; } function log(bool p0, bool p1, bool p2, string memory p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bool,bool,bool,string)", p0, p1, p2, p3)); ignored; } function log(bool p0, bool p1, bool p2, bool p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bool,bool,bool,bool)", p0, p1, p2, p3)); ignored; } function log(bool p0, bool p1, bool p2, address p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bool,bool,bool,address)", p0, p1, p2, p3)); ignored; } function log(bool p0, bool p1, address p2, uint p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bool,bool,address,uint)", p0, p1, p2, p3)); ignored; } function log(bool p0, bool p1, address p2, string memory p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bool,bool,address,string)", p0, p1, p2, p3)); ignored; } function log(bool p0, bool p1, address p2, bool p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bool,bool,address,bool)", p0, p1, p2, p3)); ignored; } function log(bool p0, bool p1, address p2, address p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bool,bool,address,address)", p0, p1, p2, p3)); ignored; } function log(bool p0, address p1, uint p2, uint p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bool,address,uint,uint)", p0, p1, p2, p3)); ignored; } function log(bool p0, address p1, uint p2, string memory p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bool,address,uint,string)", p0, p1, p2, p3)); ignored; } function log(bool p0, address p1, uint p2, bool p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bool,address,uint,bool)", p0, p1, p2, p3)); ignored; } function log(bool p0, address p1, uint p2, address p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bool,address,uint,address)", p0, p1, p2, p3)); ignored; } function log(bool p0, address p1, string memory p2, uint p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bool,address,string,uint)", p0, p1, p2, p3)); ignored; } function log(bool p0, address p1, string memory p2, string memory p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bool,address,string,string)", p0, p1, p2, p3)); ignored; } function log(bool p0, address p1, string memory p2, bool p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bool,address,string,bool)", p0, p1, p2, p3)); ignored; } function log(bool p0, address p1, string memory p2, address p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bool,address,string,address)", p0, p1, p2, p3)); ignored; } function log(bool p0, address p1, bool p2, uint p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bool,address,bool,uint)", p0, p1, p2, p3)); ignored; } function log(bool p0, address p1, bool p2, string memory p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bool,address,bool,string)", p0, p1, p2, p3)); ignored; } function log(bool p0, address p1, bool p2, bool p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bool,address,bool,bool)", p0, p1, p2, p3)); ignored; } function log(bool p0, address p1, bool p2, address p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bool,address,bool,address)", p0, p1, p2, p3)); ignored; } function log(bool p0, address p1, address p2, uint p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bool,address,address,uint)", p0, p1, p2, p3)); ignored; } function log(bool p0, address p1, address p2, string memory p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bool,address,address,string)", p0, p1, p2, p3)); ignored; } function log(bool p0, address p1, address p2, bool p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bool,address,address,bool)", p0, p1, p2, p3)); ignored; } function log(bool p0, address p1, address p2, address p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bool,address,address,address)", p0, p1, p2, p3)); ignored; } function log(address p0, uint p1, uint p2, uint p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(address,uint,uint,uint)", p0, p1, p2, p3)); ignored; } function log(address p0, uint p1, uint p2, string memory p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(address,uint,uint,string)", p0, p1, p2, p3)); ignored; } function log(address p0, uint p1, uint p2, bool p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(address,uint,uint,bool)", p0, p1, p2, p3)); ignored; } function log(address p0, uint p1, uint p2, address p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(address,uint,uint,address)", p0, p1, p2, p3)); ignored; } function log(address p0, uint p1, string memory p2, uint p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(address,uint,string,uint)", p0, p1, p2, p3)); ignored; } function log(address p0, uint p1, string memory p2, string memory p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(address,uint,string,string)", p0, p1, p2, p3)); ignored; } function log(address p0, uint p1, string memory p2, bool p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(address,uint,string,bool)", p0, p1, p2, p3)); ignored; } function log(address p0, uint p1, string memory p2, address p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(address,uint,string,address)", p0, p1, p2, p3)); ignored; } function log(address p0, uint p1, bool p2, uint p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(address,uint,bool,uint)", p0, p1, p2, p3)); ignored; } function log(address p0, uint p1, bool p2, string memory p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(address,uint,bool,string)", p0, p1, p2, p3)); ignored; } function log(address p0, uint p1, bool p2, bool p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(address,uint,bool,bool)", p0, p1, p2, p3)); ignored; } function log(address p0, uint p1, bool p2, address p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(address,uint,bool,address)", p0, p1, p2, p3)); ignored; } function log(address p0, uint p1, address p2, uint p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(address,uint,address,uint)", p0, p1, p2, p3)); ignored; } function log(address p0, uint p1, address p2, string memory p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(address,uint,address,string)", p0, p1, p2, p3)); ignored; } function log(address p0, uint p1, address p2, bool p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(address,uint,address,bool)", p0, p1, p2, p3)); ignored; } function log(address p0, uint p1, address p2, address p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(address,uint,address,address)", p0, p1, p2, p3)); ignored; } function log(address p0, string memory p1, uint p2, uint p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(address,string,uint,uint)", p0, p1, p2, p3)); ignored; } function log(address p0, string memory p1, uint p2, string memory p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(address,string,uint,string)", p0, p1, p2, p3)); ignored; } function log(address p0, string memory p1, uint p2, bool p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(address,string,uint,bool)", p0, p1, p2, p3)); ignored; } function log(address p0, string memory p1, uint p2, address p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(address,string,uint,address)", p0, p1, p2, p3)); ignored; } function log(address p0, string memory p1, string memory p2, uint p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(address,string,string,uint)", p0, p1, p2, p3)); ignored; } function log(address p0, string memory p1, string memory p2, string memory p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(address,string,string,string)", p0, p1, p2, p3)); ignored; } function log(address p0, string memory p1, string memory p2, bool p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(address,string,string,bool)", p0, p1, p2, p3)); ignored; } function log(address p0, string memory p1, string memory p2, address p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(address,string,string,address)", p0, p1, p2, p3)); ignored; } function log(address p0, string memory p1, bool p2, uint p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(address,string,bool,uint)", p0, p1, p2, p3)); ignored; } function log(address p0, string memory p1, bool p2, string memory p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(address,string,bool,string)", p0, p1, p2, p3)); ignored; } function log(address p0, string memory p1, bool p2, bool p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(address,string,bool,bool)", p0, p1, p2, p3)); ignored; } function log(address p0, string memory p1, bool p2, address p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(address,string,bool,address)", p0, p1, p2, p3)); ignored; } function log(address p0, string memory p1, address p2, uint p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(address,string,address,uint)", p0, p1, p2, p3)); ignored; } function log(address p0, string memory p1, address p2, string memory p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(address,string,address,string)", p0, p1, p2, p3)); ignored; } function log(address p0, string memory p1, address p2, bool p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(address,string,address,bool)", p0, p1, p2, p3)); ignored; } function log(address p0, string memory p1, address p2, address p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(address,string,address,address)", p0, p1, p2, p3)); ignored; } function log(address p0, bool p1, uint p2, uint p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(address,bool,uint,uint)", p0, p1, p2, p3)); ignored; } function log(address p0, bool p1, uint p2, string memory p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(address,bool,uint,string)", p0, p1, p2, p3)); ignored; } function log(address p0, bool p1, uint p2, bool p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(address,bool,uint,bool)", p0, p1, p2, p3)); ignored; } function log(address p0, bool p1, uint p2, address p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(address,bool,uint,address)", p0, p1, p2, p3)); ignored; } function log(address p0, bool p1, string memory p2, uint p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(address,bool,string,uint)", p0, p1, p2, p3)); ignored; } function log(address p0, bool p1, string memory p2, string memory p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(address,bool,string,string)", p0, p1, p2, p3)); ignored; } function log(address p0, bool p1, string memory p2, bool p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(address,bool,string,bool)", p0, p1, p2, p3)); ignored; } function log(address p0, bool p1, string memory p2, address p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(address,bool,string,address)", p0, p1, p2, p3)); ignored; } function log(address p0, bool p1, bool p2, uint p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(address,bool,bool,uint)", p0, p1, p2, p3)); ignored; } function log(address p0, bool p1, bool p2, string memory p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(address,bool,bool,string)", p0, p1, p2, p3)); ignored; } function log(address p0, bool p1, bool p2, bool p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(address,bool,bool,bool)", p0, p1, p2, p3)); ignored; } function log(address p0, bool p1, bool p2, address p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(address,bool,bool,address)", p0, p1, p2, p3)); ignored; } function log(address p0, bool p1, address p2, uint p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(address,bool,address,uint)", p0, p1, p2, p3)); ignored; } function log(address p0, bool p1, address p2, string memory p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(address,bool,address,string)", p0, p1, p2, p3)); ignored; } function log(address p0, bool p1, address p2, bool p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(address,bool,address,bool)", p0, p1, p2, p3)); ignored; } function log(address p0, bool p1, address p2, address p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(address,bool,address,address)", p0, p1, p2, p3)); ignored; } function log(address p0, address p1, uint p2, uint p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(address,address,uint,uint)", p0, p1, p2, p3)); ignored; } function log(address p0, address p1, uint p2, string memory p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(address,address,uint,string)", p0, p1, p2, p3)); ignored; } function log(address p0, address p1, uint p2, bool p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(address,address,uint,bool)", p0, p1, p2, p3)); ignored; } function log(address p0, address p1, uint p2, address p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(address,address,uint,address)", p0, p1, p2, p3)); ignored; } function log(address p0, address p1, string memory p2, uint p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(address,address,string,uint)", p0, p1, p2, p3)); ignored; } function log(address p0, address p1, string memory p2, string memory p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(address,address,string,string)", p0, p1, p2, p3)); ignored; } function log(address p0, address p1, string memory p2, bool p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(address,address,string,bool)", p0, p1, p2, p3)); ignored; } function log(address p0, address p1, string memory p2, address p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(address,address,string,address)", p0, p1, p2, p3)); ignored; } function log(address p0, address p1, bool p2, uint p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(address,address,bool,uint)", p0, p1, p2, p3)); ignored; } function log(address p0, address p1, bool p2, string memory p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(address,address,bool,string)", p0, p1, p2, p3)); ignored; } function log(address p0, address p1, bool p2, bool p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(address,address,bool,bool)", p0, p1, p2, p3)); ignored; } function log(address p0, address p1, bool p2, address p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(address,address,bool,address)", p0, p1, p2, p3)); ignored; } function log(address p0, address p1, address p2, uint p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(address,address,address,uint)", p0, p1, p2, p3)); ignored; } function log(address p0, address p1, address p2, string memory p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(address,address,address,string)", p0, p1, p2, p3)); ignored; } function log(address p0, address p1, address p2, bool p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(address,address,address,bool)", p0, p1, p2, p3)); ignored; } function log(address p0, address p1, address p2, address p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(address,address,address,address)", p0, p1, p2, p3)); ignored; } } // File contracts/Dependencies/LiquityMath.sol pragma solidity 0.6.11; library LiquityMath { using SafeMath for uint; uint internal constant DECIMAL_PRECISION = 1e18; /* Precision for Nominal ICR (independent of price). Rationale for the value: * * - Making it “too high” could lead to overflows. * - Making it “too low” could lead to an ICR equal to zero, due to truncation from Solidity floor division. * * This value of 1e20 is chosen for safety: the NICR will only overflow for numerator > ~1e39 ETH, * and will only truncate to 0 if the denominator is at least 1e20 times greater than the numerator. * */ uint internal constant NICR_PRECISION = 1e20; function _min(uint _a, uint _b) internal pure returns (uint) { return (_a < _b) ? _a : _b; } function _max(uint _a, uint _b) internal pure returns (uint) { return (_a >= _b) ? _a : _b; } /* * Multiply two decimal numbers and use normal rounding rules: * -round product up if 19'th mantissa digit >= 5 * -round product down if 19'th mantissa digit < 5 * * Used only inside the exponentiation, _decPow(). */ function decMul(uint x, uint y) internal pure returns (uint decProd) { uint prod_xy = x.mul(y); decProd = prod_xy.add(DECIMAL_PRECISION / 2).div(DECIMAL_PRECISION); } /* * _decPow: Exponentiation function for 18-digit decimal base, and integer exponent n. * * Uses the efficient "exponentiation by squaring" algorithm. O(log(n)) complexity. * * Called by two functions that represent time in units of minutes: * 1) TroveManager._calcDecayedBaseRate * 2) CommunityIssuance._getCumulativeIssuanceFraction * * The exponent is capped to avoid reverting due to overflow. The cap 525600000 equals * "minutes in 1000 years": 60 * 24 * 365 * 1000 * * If a period of > 1000 years is ever used as an exponent in either of the above functions, the result will be * negligibly different from just passing the cap, since: * * In function 1), the decayed base rate will be 0 for 1000 years or > 1000 years * In function 2), the difference in tokens issued at 1000 years and any time > 1000 years, will be negligible */ function _decPow(uint _base, uint _minutes) internal pure returns (uint) { if (_minutes > 525600000) {_minutes = 525600000;} // cap to avoid overflow if (_minutes == 0) {return DECIMAL_PRECISION;} uint y = DECIMAL_PRECISION; uint x = _base; uint n = _minutes; // Exponentiation-by-squaring while (n > 1) { if (n % 2 == 0) { x = decMul(x, x); n = n.div(2); } else { // if (n % 2 != 0) y = decMul(x, y); x = decMul(x, x); n = (n.sub(1)).div(2); } } return decMul(x, y); } function _getAbsoluteDifference(uint _a, uint _b) internal pure returns (uint) { return (_a >= _b) ? _a.sub(_b) : _b.sub(_a); } function _computeNominalCR(uint _coll, uint _debt) internal pure returns (uint) { if (_debt > 0) { return _coll.mul(NICR_PRECISION).div(_debt); } // Return the maximal value for uint256 if the Trove has a debt of 0. Represents "infinite" CR. else { // if (_debt == 0) return 2**256 - 1; } } function _computeCR(uint _coll, uint _debt, uint _price) internal pure returns (uint) { if (_debt > 0) { uint newCollRatio = _coll.mul(_price).div(_debt); return newCollRatio; } // Return the maximal value for uint256 if the Trove has a debt of 0. Represents "infinite" CR. else { // if (_debt == 0) return 2**256 - 1; } } } // File contracts/Interfaces/IPool.sol pragma solidity 0.6.11; // Common interface for the Pools. interface IPool { // --- Events --- event ETHBalanceUpdated(uint _newBalance); event LUSDBalanceUpdated(uint _newBalance); event ActivePoolAddressChanged(address _newActivePoolAddress); event DefaultPoolAddressChanged(address _newDefaultPoolAddress); event StabilityPoolAddressChanged(address _newStabilityPoolAddress); event EtherSent(address _to, uint _amount); // --- Functions --- function getETH() external view returns (uint); function getLUSDDebt() external view returns (uint); function increaseLUSDDebt(uint _amount) external; function decreaseLUSDDebt(uint _amount) external; } // File contracts/Interfaces/IActivePool.sol pragma solidity 0.6.11; interface IActivePool is IPool { // --- Events --- event BorrowerOperationsAddressChanged(address _newBorrowerOperationsAddress); event TroveManagerAddressChanged(address _newTroveManagerAddress); event ActivePoolLUSDDebtUpdated(uint _LUSDDebt); event ActivePoolETHBalanceUpdated(uint _ETH); // --- Functions --- function sendETH(address _account, uint _amount) external; } // File contracts/Interfaces/IDefaultPool.sol pragma solidity 0.6.11; interface IDefaultPool is IPool { // --- Events --- event TroveManagerAddressChanged(address _newTroveManagerAddress); event DefaultPoolLUSDDebtUpdated(uint _LUSDDebt); event DefaultPoolETHBalanceUpdated(uint _ETH); // --- Functions --- function sendETHToActivePool(uint _amount) external; } // File contracts/Dependencies/LiquityBase.sol pragma solidity 0.6.11; /* * Base contract for TroveManager, BorrowerOperations and StabilityPool. Contains global system constants and * common functions. */ contract LiquityBase is BaseMath, ILiquityBase { using SafeMath for uint; uint constant public _100pct = 1000000000000000000; // 1e18 == 100% // Minimum collateral ratio for individual troves uint constant public MCR = 1100000000000000000; // 110% // Critical system collateral ratio. If the system's total collateral ratio (TCR) falls below the CCR, Recovery Mode is triggered. uint constant public CCR = 1500000000000000000; // 150% // Amount of LUSD to be locked in gas pool on opening troves uint constant public LUSD_GAS_COMPENSATION = 200e18; // Minimum amount of net LUSD debt a trove must have uint constant public MIN_NET_DEBT = 1800e18; // uint constant public MIN_NET_DEBT = 0; uint constant public PERCENT_DIVISOR = 200; // dividing by 200 yields 0.5% uint constant public BORROWING_FEE_FLOOR = DECIMAL_PRECISION / 1000 * 5; // 0.5% IActivePool public activePool; IDefaultPool public defaultPool; IPriceFeed public override priceFeed; // --- Gas compensation functions --- // Returns the composite debt (drawn debt + gas compensation) of a trove, for the purpose of ICR calculation function _getCompositeDebt(uint _debt) internal pure returns (uint) { return _debt.add(LUSD_GAS_COMPENSATION); } function _getNetDebt(uint _debt) internal pure returns (uint) { return _debt.sub(LUSD_GAS_COMPENSATION); } // Return the amount of ETH to be drawn from a trove's collateral and sent as gas compensation. function _getCollGasCompensation(uint _entireColl) internal pure returns (uint) { return _entireColl / PERCENT_DIVISOR; } function getEntireSystemColl() public view returns (uint entireSystemColl) { uint activeColl = activePool.getETH(); uint liquidatedColl = defaultPool.getETH(); return activeColl.add(liquidatedColl); } function getEntireSystemDebt() public view returns (uint entireSystemDebt) { uint activeDebt = activePool.getLUSDDebt(); uint closedDebt = defaultPool.getLUSDDebt(); return activeDebt.add(closedDebt); } function _getTCR(uint _price) internal view returns (uint TCR) { uint entireSystemColl = getEntireSystemColl(); uint entireSystemDebt = getEntireSystemDebt(); TCR = LiquityMath._computeCR(entireSystemColl, entireSystemDebt, _price); return TCR; } function _checkRecoveryMode(uint _price) internal view returns (bool) { uint TCR = _getTCR(_price); return TCR < CCR; } function _requireUserAcceptsFee(uint _fee, uint _amount, uint _maxFeePercentage) internal pure { uint feePercentage = _fee.mul(DECIMAL_PRECISION).div(_amount); require(feePercentage <= _maxFeePercentage, "Fee exceeded provided maximum"); } } // File contracts/Dependencies/Ownable.sol pragma solidity 0.6.11; /** * Based on OpenZeppelin's Ownable contract: * https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/access/Ownable.sol * * @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. * * 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. */ contract Ownable { address private _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the deployer as the initial owner. */ constructor () internal { _owner = msg.sender; emit OwnershipTransferred(address(0), msg.sender); } /** * @dev Returns the address of the current owner. */ function owner() public view returns (address) { return _owner; } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { require(isOwner(), "Ownable: caller is not the owner"); _; } /** * @dev Returns true if the caller is the current owner. */ function isOwner() public view returns (bool) { return msg.sender == _owner; } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions anymore. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby removing any functionality that is only available to the owner. * * NOTE: This function is not safe, as it doesn’t check owner is calling it. * Make sure you check it before calling it. */ function _renounceOwnership() internal { emit OwnershipTransferred(_owner, address(0)); _owner = address(0); } } // File contracts/Dependencies/CheckContract.sol pragma solidity 0.6.11; contract CheckContract { /** * Check that the account is an already deployed non-destroyed contract. * See: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/Address.sol#L12 */ function checkContract(address _account) internal view { require(_account != address(0), "Account cannot be zero address"); uint256 size; // solhint-disable-next-line no-inline-assembly assembly { size := extcodesize(_account) } require(size > 0, "Account code size cannot be zero"); } } // File contracts/TroveManager.sol pragma solidity 0.6.11; contract TroveManager is LiquityBase, Ownable, CheckContract, ITroveManager { string constant public NAME = "TroveManager"; // --- Connected contract declarations --- address public borrowerOperationsAddress; IStabilityPool public override stabilityPool; address gasPoolAddress; ICollSurplusPool collSurplusPool; ILUSDToken public override lusdToken; ILQTYToken public override lqtyToken; ILQTYStaking public override lqtyStaking; // A doubly linked list of Troves, sorted by their sorted by their collateral ratios ISortedTroves public sortedTroves; // --- Data structures --- uint constant public SECONDS_IN_ONE_MINUTE = 60; /* * Half-life of 12h. 12h = 720 min * (1/2) = d^720 => d = (1/2)^(1/720) */ uint constant public MINUTE_DECAY_FACTOR = 999037758833783000; uint constant public REDEMPTION_FEE_FLOOR = DECIMAL_PRECISION / 1000 * 5; // 0.5% uint constant public MAX_BORROWING_FEE = DECIMAL_PRECISION / 100 * 5; // 5% // During bootsrap period redemptions are not allowed uint constant public BOOTSTRAP_PERIOD = 14 days; /* * BETA: 18 digit decimal. Parameter by which to divide the redeemed fraction, in order to calc the new base rate from a redemption. * Corresponds to (1 / ALPHA) in the white paper. */ uint constant public BETA = 2; uint public baseRate; // The timestamp of the latest fee operation (redemption or new LUSD issuance) uint public lastFeeOperationTime; enum Status { nonExistent, active, closedByOwner, closedByLiquidation, closedByRedemption } // Store the necessary data for a trove struct Trove { uint debt; uint coll; uint stake; Status status; uint128 arrayIndex; } mapping (address => Trove) public Troves; uint public totalStakes; // Snapshot of the value of totalStakes, taken immediately after the latest liquidation uint public totalStakesSnapshot; // Snapshot of the total collateral across the ActivePool and DefaultPool, immediately after the latest liquidation. uint public totalCollateralSnapshot; /* * L_ETH and L_LUSDDebt track the sums of accumulated liquidation rewards per unit staked. During its lifetime, each stake earns: * * An ETH gain of ( stake * [L_ETH - L_ETH(0)] ) * A LUSDDebt increase of ( stake * [L_LUSDDebt - L_LUSDDebt(0)] ) * * Where L_ETH(0) and L_LUSDDebt(0) are snapshots of L_ETH and L_LUSDDebt for the active Trove taken at the instant the stake was made */ uint public L_ETH; uint public L_LUSDDebt; // Map addresses with active troves to their RewardSnapshot mapping (address => RewardSnapshot) public rewardSnapshots; // Object containing the ETH and LUSD snapshots for a given active trove struct RewardSnapshot { uint ETH; uint LUSDDebt;} // Array of all active trove addresses - used to to compute an approximate hint off-chain, for the sorted list insertion address[] public TroveOwners; // Error trackers for the trove redistribution calculation uint public lastETHError_Redistribution; uint public lastLUSDDebtError_Redistribution; /* * --- Variable container structs for liquidations --- * * These structs are used to hold, return and assign variables inside the liquidation functions, * in order to avoid the error: "CompilerError: Stack too deep". **/ struct LocalVariables_OuterLiquidationFunction { uint price; uint LUSDInStabPool; bool recoveryModeAtStart; uint liquidatedDebt; uint liquidatedColl; } struct LocalVariables_InnerSingleLiquidateFunction { uint collToLiquidate; uint pendingDebtReward; uint pendingCollReward; } struct LocalVariables_LiquidationSequence { uint remainingLUSDInStabPool; uint i; uint ICR; address user; bool backToNormalMode; uint entireSystemDebt; uint entireSystemColl; } struct LiquidationValues { uint entireTroveDebt; uint entireTroveColl; uint collGasCompensation; uint LUSDGasCompensation; uint debtToOffset; uint collToOffset; uint collToSendToSP; uint debtToRedistribute; uint collToRedistribute; uint collSurplus; } struct LiquidationTotals { uint totalCollInSequence; uint totalDebtInSequence; uint totalCollGasCompensation; uint totalLUSDGasCompensation; uint totalDebtToOffset; uint totalCollToSendToSP; uint totalDebtToRedistribute; uint totalCollToRedistribute; uint totalCollSurplus; } struct ContractsCache { IActivePool activePool; IDefaultPool defaultPool; ILUSDToken lusdToken; ILQTYStaking lqtyStaking; ISortedTroves sortedTroves; ICollSurplusPool collSurplusPool; address gasPoolAddress; } // --- Variable container structs for redemptions --- struct RedemptionTotals { uint remainingLUSD; uint totalLUSDToRedeem; uint totalETHDrawn; uint ETHFee; uint ETHToSendToRedeemer; uint decayedBaseRate; uint price; uint totalLUSDSupplyAtStart; } struct SingleRedemptionValues { uint LUSDLot; uint ETHLot; bool cancelledPartial; } // --- Events --- event BorrowerOperationsAddressChanged(address _newBorrowerOperationsAddress); event PriceFeedAddressChanged(address _newPriceFeedAddress); event LUSDTokenAddressChanged(address _newLUSDTokenAddress); event ActivePoolAddressChanged(address _activePoolAddress); event DefaultPoolAddressChanged(address _defaultPoolAddress); event StabilityPoolAddressChanged(address _stabilityPoolAddress); event GasPoolAddressChanged(address _gasPoolAddress); event CollSurplusPoolAddressChanged(address _collSurplusPoolAddress); event SortedTrovesAddressChanged(address _sortedTrovesAddress); event LQTYTokenAddressChanged(address _lqtyTokenAddress); event LQTYStakingAddressChanged(address _lqtyStakingAddress); event Liquidation(uint _liquidatedDebt, uint _liquidatedColl, uint _collGasCompensation, uint _LUSDGasCompensation); event Redemption(uint _attemptedLUSDAmount, uint _actualLUSDAmount, uint _ETHSent, uint _ETHFee); event TroveUpdated(address indexed _borrower, uint _debt, uint _coll, uint _stake, TroveManagerOperation _operation); event TroveLiquidated(address indexed _borrower, uint _debt, uint _coll, TroveManagerOperation _operation); event BaseRateUpdated(uint _baseRate); event LastFeeOpTimeUpdated(uint _lastFeeOpTime); event TotalStakesUpdated(uint _newTotalStakes); event SystemSnapshotsUpdated(uint _totalStakesSnapshot, uint _totalCollateralSnapshot); event LTermsUpdated(uint _L_ETH, uint _L_LUSDDebt); event TroveSnapshotsUpdated(uint _L_ETH, uint _L_LUSDDebt); event TroveIndexUpdated(address _borrower, uint _newIndex); enum TroveManagerOperation { applyPendingRewards, liquidateInNormalMode, liquidateInRecoveryMode, redeemCollateral } // --- Dependency setter --- function setAddresses( address _borrowerOperationsAddress, address _activePoolAddress, address _defaultPoolAddress, address _stabilityPoolAddress, address _gasPoolAddress, address _collSurplusPoolAddress, address _priceFeedAddress, address _lusdTokenAddress, address _sortedTrovesAddress, address _lqtyTokenAddress, address _lqtyStakingAddress ) external override onlyOwner { checkContract(_borrowerOperationsAddress); checkContract(_activePoolAddress); checkContract(_defaultPoolAddress); checkContract(_stabilityPoolAddress); checkContract(_gasPoolAddress); checkContract(_collSurplusPoolAddress); checkContract(_priceFeedAddress); checkContract(_lusdTokenAddress); checkContract(_sortedTrovesAddress); checkContract(_lqtyTokenAddress); checkContract(_lqtyStakingAddress); borrowerOperationsAddress = _borrowerOperationsAddress; activePool = IActivePool(_activePoolAddress); defaultPool = IDefaultPool(_defaultPoolAddress); stabilityPool = IStabilityPool(_stabilityPoolAddress); gasPoolAddress = _gasPoolAddress; collSurplusPool = ICollSurplusPool(_collSurplusPoolAddress); priceFeed = IPriceFeed(_priceFeedAddress); lusdToken = ILUSDToken(_lusdTokenAddress); sortedTroves = ISortedTroves(_sortedTrovesAddress); lqtyToken = ILQTYToken(_lqtyTokenAddress); lqtyStaking = ILQTYStaking(_lqtyStakingAddress); emit BorrowerOperationsAddressChanged(_borrowerOperationsAddress); emit ActivePoolAddressChanged(_activePoolAddress); emit DefaultPoolAddressChanged(_defaultPoolAddress); emit StabilityPoolAddressChanged(_stabilityPoolAddress); emit GasPoolAddressChanged(_gasPoolAddress); emit CollSurplusPoolAddressChanged(_collSurplusPoolAddress); emit PriceFeedAddressChanged(_priceFeedAddress); emit LUSDTokenAddressChanged(_lusdTokenAddress); emit SortedTrovesAddressChanged(_sortedTrovesAddress); emit LQTYTokenAddressChanged(_lqtyTokenAddress); emit LQTYStakingAddressChanged(_lqtyStakingAddress); _renounceOwnership(); } // --- Getters --- function getTroveOwnersCount() external view override returns (uint) { return TroveOwners.length; } function getTroveFromTroveOwnersArray(uint _index) external view override returns (address) { return TroveOwners[_index]; } // --- Trove Liquidation functions --- // Single liquidation function. Closes the trove if its ICR is lower than the minimum collateral ratio. function liquidate(address _borrower) external override { _requireTroveIsActive(_borrower); address[] memory borrowers = new address[](1); borrowers[0] = _borrower; batchLiquidateTroves(borrowers); } // --- Inner single liquidation functions --- // Liquidate one trove, in Normal Mode. function _liquidateNormalMode( IActivePool _activePool, IDefaultPool _defaultPool, address _borrower, uint _LUSDInStabPool ) internal returns (LiquidationValues memory singleLiquidation) { LocalVariables_InnerSingleLiquidateFunction memory vars; (singleLiquidation.entireTroveDebt, singleLiquidation.entireTroveColl, vars.pendingDebtReward, vars.pendingCollReward) = getEntireDebtAndColl(_borrower); _movePendingTroveRewardsToActivePool(_activePool, _defaultPool, vars.pendingDebtReward, vars.pendingCollReward); _removeStake(_borrower); singleLiquidation.collGasCompensation = _getCollGasCompensation(singleLiquidation.entireTroveColl); singleLiquidation.LUSDGasCompensation = LUSD_GAS_COMPENSATION; uint collToLiquidate = singleLiquidation.entireTroveColl.sub(singleLiquidation.collGasCompensation); (singleLiquidation.debtToOffset, singleLiquidation.collToSendToSP, singleLiquidation.debtToRedistribute, singleLiquidation.collToRedistribute) = _getOffsetAndRedistributionVals(singleLiquidation.entireTroveDebt, collToLiquidate, _LUSDInStabPool); _closeTrove(_borrower, Status.closedByLiquidation); emit TroveLiquidated(_borrower, singleLiquidation.entireTroveDebt, singleLiquidation.entireTroveColl, TroveManagerOperation.liquidateInNormalMode); emit TroveUpdated(_borrower, 0, 0, 0, TroveManagerOperation.liquidateInNormalMode); return singleLiquidation; } // Liquidate one trove, in Recovery Mode. function _liquidateRecoveryMode( IActivePool _activePool, IDefaultPool _defaultPool, address _borrower, uint _ICR, uint _LUSDInStabPool, uint _TCR, uint _price ) internal returns (LiquidationValues memory singleLiquidation) { LocalVariables_InnerSingleLiquidateFunction memory vars; if (TroveOwners.length <= 1) {return singleLiquidation;} // don't liquidate if last trove (singleLiquidation.entireTroveDebt, singleLiquidation.entireTroveColl, vars.pendingDebtReward, vars.pendingCollReward) = getEntireDebtAndColl(_borrower); singleLiquidation.collGasCompensation = _getCollGasCompensation(singleLiquidation.entireTroveColl); singleLiquidation.LUSDGasCompensation = LUSD_GAS_COMPENSATION; vars.collToLiquidate = singleLiquidation.entireTroveColl.sub(singleLiquidation.collGasCompensation); // If ICR <= 100%, purely redistribute the Trove across all active Troves if (_ICR <= _100pct) { _movePendingTroveRewardsToActivePool(_activePool, _defaultPool, vars.pendingDebtReward, vars.pendingCollReward); _removeStake(_borrower); singleLiquidation.debtToOffset = 0; singleLiquidation.collToSendToSP = 0; singleLiquidation.debtToRedistribute = singleLiquidation.entireTroveDebt; singleLiquidation.collToRedistribute = vars.collToLiquidate; _closeTrove(_borrower, Status.closedByLiquidation); emit TroveLiquidated(_borrower, singleLiquidation.entireTroveDebt, singleLiquidation.entireTroveColl, TroveManagerOperation.liquidateInRecoveryMode); emit TroveUpdated(_borrower, 0, 0, 0, TroveManagerOperation.liquidateInRecoveryMode); // If 100% < ICR < MCR, offset as much as possible, and redistribute the remainder } else if ((_ICR > _100pct) && (_ICR < MCR)) { _movePendingTroveRewardsToActivePool(_activePool, _defaultPool, vars.pendingDebtReward, vars.pendingCollReward); _removeStake(_borrower); (singleLiquidation.debtToOffset, singleLiquidation.collToSendToSP, singleLiquidation.debtToRedistribute, singleLiquidation.collToRedistribute) = _getOffsetAndRedistributionVals(singleLiquidation.entireTroveDebt, vars.collToLiquidate, _LUSDInStabPool); _closeTrove(_borrower, Status.closedByLiquidation); emit TroveLiquidated(_borrower, singleLiquidation.entireTroveDebt, singleLiquidation.entireTroveColl, TroveManagerOperation.liquidateInRecoveryMode); emit TroveUpdated(_borrower, 0, 0, 0, TroveManagerOperation.liquidateInRecoveryMode); /* * If 110% <= ICR < current TCR (accounting for the preceding liquidations in the current sequence) * and there is LUSD in the Stability Pool, only offset, with no redistribution, * but at a capped rate of 1.1 and only if the whole debt can be liquidated. * The remainder due to the capped rate will be claimable as collateral surplus. */ } else if ((_ICR >= MCR) && (_ICR < _TCR) && (singleLiquidation.entireTroveDebt <= _LUSDInStabPool)) { _movePendingTroveRewardsToActivePool(_activePool, _defaultPool, vars.pendingDebtReward, vars.pendingCollReward); assert(_LUSDInStabPool != 0); _removeStake(_borrower); singleLiquidation = _getCappedOffsetVals(singleLiquidation.entireTroveDebt, singleLiquidation.entireTroveColl, _price); _closeTrove(_borrower, Status.closedByLiquidation); if (singleLiquidation.collSurplus > 0) { collSurplusPool.accountSurplus(_borrower, singleLiquidation.collSurplus); } emit TroveLiquidated(_borrower, singleLiquidation.entireTroveDebt, singleLiquidation.collToOffset, TroveManagerOperation.liquidateInRecoveryMode); emit TroveUpdated(_borrower, 0, 0, 0, TroveManagerOperation.liquidateInRecoveryMode); } else { // if (_ICR >= MCR && ( _ICR >= _TCR || singleLiquidation.entireTroveDebt > _LUSDInStabPool)) LiquidationValues memory zeroVals; return zeroVals; } return singleLiquidation; } /* In a full liquidation, returns the values for a trove's coll and debt to be offset, and coll and debt to be * redistributed to active troves. */ function _getOffsetAndRedistributionVals ( uint _debt, uint _coll, uint _LUSDInStabPool ) internal pure returns (uint debtToOffset, uint collToSendToSP, uint debtToRedistribute, uint collToRedistribute) { if (_LUSDInStabPool > 0) { /* * Offset as much debt & collateral as possible against the Stability Pool, and redistribute the remainder * between all active troves. * * If the trove's debt is larger than the deposited LUSD in the Stability Pool: * * - Offset an amount of the trove's debt equal to the LUSD in the Stability Pool * - Send a fraction of the trove's collateral to the Stability Pool, equal to the fraction of its offset debt * */ debtToOffset = LiquityMath._min(_debt, _LUSDInStabPool); collToSendToSP = _coll.mul(debtToOffset).div(_debt); debtToRedistribute = _debt.sub(debtToOffset); collToRedistribute = _coll.sub(collToSendToSP); } else { debtToOffset = 0; collToSendToSP = 0; debtToRedistribute = _debt; collToRedistribute = _coll; } } /* * Get its offset coll/debt and ETH gas comp, and close the trove. */ function _getCappedOffsetVals ( uint _entireTroveDebt, uint _entireTroveColl, uint _price ) internal pure returns (LiquidationValues memory singleLiquidation) { singleLiquidation.entireTroveDebt = _entireTroveDebt; singleLiquidation.entireTroveColl = _entireTroveColl; uint collToOffset = _entireTroveDebt.mul(MCR).div(_price); singleLiquidation.collGasCompensation = _getCollGasCompensation(collToOffset); singleLiquidation.LUSDGasCompensation = LUSD_GAS_COMPENSATION; singleLiquidation.debtToOffset = _entireTroveDebt; singleLiquidation.collToOffset = collToOffset; singleLiquidation.collToSendToSP = collToOffset.sub(singleLiquidation.collGasCompensation); singleLiquidation.collSurplus = _entireTroveColl.sub(collToOffset); singleLiquidation.debtToRedistribute = 0; singleLiquidation.collToRedistribute = 0; } /* * Liquidate a sequence of troves. Closes a maximum number of n under-collateralized Troves, * starting from the one with the lowest collateral ratio in the system, and moving upwards */ function liquidateTroves(uint _n) external override { ContractsCache memory contractsCache = ContractsCache( activePool, defaultPool, ILUSDToken(address(0)), ILQTYStaking(address(0)), sortedTroves, ICollSurplusPool(address(0)), address(0) ); IStabilityPool stabilityPoolCached = stabilityPool; LocalVariables_OuterLiquidationFunction memory vars; LiquidationTotals memory totals; vars.price = priceFeed.fetchPrice(); vars.LUSDInStabPool = stabilityPoolCached.getTotalLUSDDeposits(); vars.recoveryModeAtStart = _checkRecoveryMode(vars.price); // Perform the appropriate liquidation sequence - tally the values, and obtain their totals if (vars.recoveryModeAtStart) { totals = _getTotalsFromLiquidateTrovesSequence_RecoveryMode(contractsCache, vars.price, vars.LUSDInStabPool, _n); } else { // if !vars.recoveryModeAtStart totals = _getTotalsFromLiquidateTrovesSequence_NormalMode(contractsCache.activePool, contractsCache.defaultPool, vars.price, vars.LUSDInStabPool, _n); } require(totals.totalDebtInSequence > 0, "TroveManager: nothing to liquidate"); // Move liquidated ETH and LUSD to the appropriate pools stabilityPoolCached.offset(totals.totalDebtToOffset, totals.totalCollToSendToSP); _redistributeDebtAndColl(contractsCache.activePool, contractsCache.defaultPool, totals.totalDebtToRedistribute, totals.totalCollToRedistribute); if (totals.totalCollSurplus > 0) { contractsCache.activePool.sendETH(address(collSurplusPool), totals.totalCollSurplus); } // Update system snapshots _updateSystemSnapshots_excludeCollRemainder(contractsCache.activePool, totals.totalCollGasCompensation); vars.liquidatedDebt = totals.totalDebtInSequence; vars.liquidatedColl = totals.totalCollInSequence.sub(totals.totalCollGasCompensation).sub(totals.totalCollSurplus); emit Liquidation(vars.liquidatedDebt, vars.liquidatedColl, totals.totalCollGasCompensation, totals.totalLUSDGasCompensation); // Send gas compensation to caller _sendGasCompensation(contractsCache.activePool, msg.sender, totals.totalLUSDGasCompensation, totals.totalCollGasCompensation); } /* * This function is used when the liquidateTroves sequence starts during Recovery Mode. However, it * handle the case where the system *leaves* Recovery Mode, part way through the liquidation sequence */ function _getTotalsFromLiquidateTrovesSequence_RecoveryMode ( ContractsCache memory _contractsCache, uint _price, uint _LUSDInStabPool, uint _n ) internal returns(LiquidationTotals memory totals) { LocalVariables_LiquidationSequence memory vars; LiquidationValues memory singleLiquidation; vars.remainingLUSDInStabPool = _LUSDInStabPool; vars.backToNormalMode = false; vars.entireSystemDebt = getEntireSystemDebt(); vars.entireSystemColl = getEntireSystemColl(); vars.user = _contractsCache.sortedTroves.getLast(); address firstUser = _contractsCache.sortedTroves.getFirst(); for (vars.i = 0; vars.i < _n && vars.user != firstUser; vars.i++) { // we need to cache it, because current user is likely going to be deleted address nextUser = _contractsCache.sortedTroves.getPrev(vars.user); vars.ICR = getCurrentICR(vars.user, _price); if (!vars.backToNormalMode) { // Break the loop if ICR is greater than MCR and Stability Pool is empty if (vars.ICR >= MCR && vars.remainingLUSDInStabPool == 0) { break; } uint TCR = LiquityMath._computeCR(vars.entireSystemColl, vars.entireSystemDebt, _price); singleLiquidation = _liquidateRecoveryMode(_contractsCache.activePool, _contractsCache.defaultPool, vars.user, vars.ICR, vars.remainingLUSDInStabPool, TCR, _price); // Update aggregate trackers vars.remainingLUSDInStabPool = vars.remainingLUSDInStabPool.sub(singleLiquidation.debtToOffset); vars.entireSystemDebt = vars.entireSystemDebt.sub(singleLiquidation.debtToOffset); vars.entireSystemColl = vars.entireSystemColl.sub(singleLiquidation.collToOffset).sub(singleLiquidation.collSurplus); // Add liquidation values to their respective running totals totals = _addLiquidationValuesToTotals(totals, singleLiquidation); vars.backToNormalMode = !_checkPotentialRecoveryMode(vars.entireSystemColl, vars.entireSystemDebt, _price); } else if (vars.backToNormalMode && vars.ICR < MCR) { singleLiquidation = _liquidateNormalMode(_contractsCache.activePool, _contractsCache.defaultPool, vars.user, vars.remainingLUSDInStabPool); vars.remainingLUSDInStabPool = vars.remainingLUSDInStabPool.sub(singleLiquidation.debtToOffset); // Add liquidation values to their respective running totals totals = _addLiquidationValuesToTotals(totals, singleLiquidation); } else break; // break if the loop reaches a Trove with ICR >= MCR vars.user = nextUser; } } function _getTotalsFromLiquidateTrovesSequence_NormalMode ( IActivePool _activePool, IDefaultPool _defaultPool, uint _price, uint _LUSDInStabPool, uint _n ) internal returns(LiquidationTotals memory totals) { LocalVariables_LiquidationSequence memory vars; LiquidationValues memory singleLiquidation; ISortedTroves sortedTrovesCached = sortedTroves; vars.remainingLUSDInStabPool = _LUSDInStabPool; for (vars.i = 0; vars.i < _n; vars.i++) { vars.user = sortedTrovesCached.getLast(); vars.ICR = getCurrentICR(vars.user, _price); if (vars.ICR < MCR) { singleLiquidation = _liquidateNormalMode(_activePool, _defaultPool, vars.user, vars.remainingLUSDInStabPool); vars.remainingLUSDInStabPool = vars.remainingLUSDInStabPool.sub(singleLiquidation.debtToOffset); // Add liquidation values to their respective running totals totals = _addLiquidationValuesToTotals(totals, singleLiquidation); } else break; // break if the loop reaches a Trove with ICR >= MCR } } /* * Attempt to liquidate a custom list of troves provided by the caller. */ function batchLiquidateTroves(address[] memory _troveArray) public override { require(_troveArray.length != 0, "TroveManager: Calldata address array must not be empty"); IActivePool activePoolCached = activePool; IDefaultPool defaultPoolCached = defaultPool; IStabilityPool stabilityPoolCached = stabilityPool; LocalVariables_OuterLiquidationFunction memory vars; LiquidationTotals memory totals; vars.price = priceFeed.fetchPrice(); vars.LUSDInStabPool = stabilityPoolCached.getTotalLUSDDeposits(); vars.recoveryModeAtStart = _checkRecoveryMode(vars.price); // Perform the appropriate liquidation sequence - tally values and obtain their totals. if (vars.recoveryModeAtStart) { totals = _getTotalFromBatchLiquidate_RecoveryMode(activePoolCached, defaultPoolCached, vars.price, vars.LUSDInStabPool, _troveArray); } else { // if !vars.recoveryModeAtStart totals = _getTotalsFromBatchLiquidate_NormalMode(activePoolCached, defaultPoolCached, vars.price, vars.LUSDInStabPool, _troveArray); } require(totals.totalDebtInSequence > 0, "TroveManager: nothing to liquidate"); // Move liquidated ETH and LUSD to the appropriate pools stabilityPoolCached.offset(totals.totalDebtToOffset, totals.totalCollToSendToSP); _redistributeDebtAndColl(activePoolCached, defaultPoolCached, totals.totalDebtToRedistribute, totals.totalCollToRedistribute); if (totals.totalCollSurplus > 0) { activePoolCached.sendETH(address(collSurplusPool), totals.totalCollSurplus); } // Update system snapshots _updateSystemSnapshots_excludeCollRemainder(activePoolCached, totals.totalCollGasCompensation); vars.liquidatedDebt = totals.totalDebtInSequence; vars.liquidatedColl = totals.totalCollInSequence.sub(totals.totalCollGasCompensation).sub(totals.totalCollSurplus); emit Liquidation(vars.liquidatedDebt, vars.liquidatedColl, totals.totalCollGasCompensation, totals.totalLUSDGasCompensation); // Send gas compensation to caller _sendGasCompensation(activePoolCached, msg.sender, totals.totalLUSDGasCompensation, totals.totalCollGasCompensation); } /* * This function is used when the batch liquidation sequence starts during Recovery Mode. However, it * handle the case where the system *leaves* Recovery Mode, part way through the liquidation sequence */ function _getTotalFromBatchLiquidate_RecoveryMode ( IActivePool _activePool, IDefaultPool _defaultPool, uint _price, uint _LUSDInStabPool, address[] memory _troveArray ) internal returns(LiquidationTotals memory totals) { LocalVariables_LiquidationSequence memory vars; LiquidationValues memory singleLiquidation; vars.remainingLUSDInStabPool = _LUSDInStabPool; vars.backToNormalMode = false; vars.entireSystemDebt = getEntireSystemDebt(); vars.entireSystemColl = getEntireSystemColl(); for (vars.i = 0; vars.i < _troveArray.length; vars.i++) { vars.user = _troveArray[vars.i]; // Skip non-active troves if (Troves[vars.user].status != Status.active) { continue; } vars.ICR = getCurrentICR(vars.user, _price); if (!vars.backToNormalMode) { // Skip this trove if ICR is greater than MCR and Stability Pool is empty if (vars.ICR >= MCR && vars.remainingLUSDInStabPool == 0) { continue; } uint TCR = LiquityMath._computeCR(vars.entireSystemColl, vars.entireSystemDebt, _price); singleLiquidation = _liquidateRecoveryMode(_activePool, _defaultPool, vars.user, vars.ICR, vars.remainingLUSDInStabPool, TCR, _price); // Update aggregate trackers vars.remainingLUSDInStabPool = vars.remainingLUSDInStabPool.sub(singleLiquidation.debtToOffset); vars.entireSystemDebt = vars.entireSystemDebt.sub(singleLiquidation.debtToOffset); vars.entireSystemColl = vars.entireSystemColl.sub(singleLiquidation.collToOffset).sub(singleLiquidation.collSurplus); // Add liquidation values to their respective running totals totals = _addLiquidationValuesToTotals(totals, singleLiquidation); vars.backToNormalMode = !_checkPotentialRecoveryMode(vars.entireSystemColl, vars.entireSystemDebt, _price); } else if (vars.backToNormalMode && vars.ICR < MCR) { singleLiquidation = _liquidateNormalMode(_activePool, _defaultPool, vars.user, vars.remainingLUSDInStabPool); vars.remainingLUSDInStabPool = vars.remainingLUSDInStabPool.sub(singleLiquidation.debtToOffset); // Add liquidation values to their respective running totals totals = _addLiquidationValuesToTotals(totals, singleLiquidation); } else continue; // In Normal Mode skip troves with ICR >= MCR } } function _getTotalsFromBatchLiquidate_NormalMode ( IActivePool _activePool, IDefaultPool _defaultPool, uint _price, uint _LUSDInStabPool, address[] memory _troveArray ) internal returns(LiquidationTotals memory totals) { LocalVariables_LiquidationSequence memory vars; LiquidationValues memory singleLiquidation; vars.remainingLUSDInStabPool = _LUSDInStabPool; for (vars.i = 0; vars.i < _troveArray.length; vars.i++) { vars.user = _troveArray[vars.i]; vars.ICR = getCurrentICR(vars.user, _price); if (vars.ICR < MCR) { singleLiquidation = _liquidateNormalMode(_activePool, _defaultPool, vars.user, vars.remainingLUSDInStabPool); vars.remainingLUSDInStabPool = vars.remainingLUSDInStabPool.sub(singleLiquidation.debtToOffset); // Add liquidation values to their respective running totals totals = _addLiquidationValuesToTotals(totals, singleLiquidation); } } } // --- Liquidation helper functions --- function _addLiquidationValuesToTotals(LiquidationTotals memory oldTotals, LiquidationValues memory singleLiquidation) internal pure returns(LiquidationTotals memory newTotals) { // Tally all the values with their respective running totals newTotals.totalCollGasCompensation = oldTotals.totalCollGasCompensation.add(singleLiquidation.collGasCompensation); newTotals.totalLUSDGasCompensation = oldTotals.totalLUSDGasCompensation.add(singleLiquidation.LUSDGasCompensation); newTotals.totalDebtInSequence = oldTotals.totalDebtInSequence.add(singleLiquidation.entireTroveDebt); newTotals.totalCollInSequence = oldTotals.totalCollInSequence.add(singleLiquidation.entireTroveColl); newTotals.totalDebtToOffset = oldTotals.totalDebtToOffset.add(singleLiquidation.debtToOffset); newTotals.totalCollToSendToSP = oldTotals.totalCollToSendToSP.add(singleLiquidation.collToSendToSP); newTotals.totalDebtToRedistribute = oldTotals.totalDebtToRedistribute.add(singleLiquidation.debtToRedistribute); newTotals.totalCollToRedistribute = oldTotals.totalCollToRedistribute.add(singleLiquidation.collToRedistribute); newTotals.totalCollSurplus = oldTotals.totalCollSurplus.add(singleLiquidation.collSurplus); return newTotals; } function _sendGasCompensation(IActivePool _activePool, address _liquidator, uint _LUSD, uint _ETH) internal { if (_LUSD > 0) { lusdToken.returnFromPool(gasPoolAddress, _liquidator, _LUSD); } if (_ETH > 0) { _activePool.sendETH(_liquidator, _ETH); } } // Move a Trove's pending debt and collateral rewards from distributions, from the Default Pool to the Active Pool function _movePendingTroveRewardsToActivePool(IActivePool _activePool, IDefaultPool _defaultPool, uint _LUSD, uint _ETH) internal { _defaultPool.decreaseLUSDDebt(_LUSD); _activePool.increaseLUSDDebt(_LUSD); _defaultPool.sendETHToActivePool(_ETH); } // --- Redemption functions --- // Redeem as much collateral as possible from _borrower's Trove in exchange for LUSD up to _maxLUSDamount function _redeemCollateralFromTrove( ContractsCache memory _contractsCache, address _borrower, uint _maxLUSDamount, uint _price, address _upperPartialRedemptionHint, address _lowerPartialRedemptionHint, uint _partialRedemptionHintNICR ) internal returns (SingleRedemptionValues memory singleRedemption) { // Determine the remaining amount (lot) to be redeemed, capped by the entire debt of the Trove minus the liquidation reserve singleRedemption.LUSDLot = LiquityMath._min(_maxLUSDamount, Troves[_borrower].debt.sub(LUSD_GAS_COMPENSATION)); // Get the ETHLot of equivalent value in USD singleRedemption.ETHLot = singleRedemption.LUSDLot.mul(DECIMAL_PRECISION).div(_price); // Decrease the debt and collateral of the current Trove according to the LUSD lot and corresponding ETH to send uint newDebt = (Troves[_borrower].debt).sub(singleRedemption.LUSDLot); uint newColl = (Troves[_borrower].coll).sub(singleRedemption.ETHLot); if (newDebt == LUSD_GAS_COMPENSATION) { // No debt left in the Trove (except for the liquidation reserve), therefore the trove gets closed _removeStake(_borrower); _closeTrove(_borrower, Status.closedByRedemption); _redeemCloseTrove(_contractsCache, _borrower, LUSD_GAS_COMPENSATION, newColl); emit TroveUpdated(_borrower, 0, 0, 0, TroveManagerOperation.redeemCollateral); } else { uint newNICR = LiquityMath._computeNominalCR(newColl, newDebt); /* * If the provided hint is out of date, we bail since trying to reinsert without a good hint will almost * certainly result in running out of gas. * * If the resultant net debt of the partial is less than the minimum, net debt we bail. */ if (newNICR != _partialRedemptionHintNICR || _getNetDebt(newDebt) < MIN_NET_DEBT) { singleRedemption.cancelledPartial = true; return singleRedemption; } _contractsCache.sortedTroves.reInsert(_borrower, newNICR, _upperPartialRedemptionHint, _lowerPartialRedemptionHint); Troves[_borrower].debt = newDebt; Troves[_borrower].coll = newColl; _updateStakeAndTotalStakes(_borrower); emit TroveUpdated( _borrower, newDebt, newColl, Troves[_borrower].stake, TroveManagerOperation.redeemCollateral ); } return singleRedemption; } /* * Called when a full redemption occurs, and closes the trove. * The redeemer swaps (debt - liquidation reserve) LUSD for (debt - liquidation reserve) worth of ETH, so the LUSD liquidation reserve left corresponds to the remaining debt. * In order to close the trove, the LUSD liquidation reserve is burned, and the corresponding debt is removed from the active pool. * The debt recorded on the trove's struct is zero'd elswhere, in _closeTrove. * Any surplus ETH left in the trove, is sent to the Coll surplus pool, and can be later claimed by the borrower. */ function _redeemCloseTrove(ContractsCache memory _contractsCache, address _borrower, uint _LUSD, uint _ETH) internal { _contractsCache.lusdToken.burn(gasPoolAddress, _LUSD); // Update Active Pool LUSD, and send ETH to account _contractsCache.activePool.decreaseLUSDDebt(_LUSD); // send ETH from Active Pool to CollSurplus Pool _contractsCache.collSurplusPool.accountSurplus(_borrower, _ETH); _contractsCache.activePool.sendETH(address(_contractsCache.collSurplusPool), _ETH); } function _isValidFirstRedemptionHint(ISortedTroves _sortedTroves, address _firstRedemptionHint, uint _price) internal view returns (bool) { if (_firstRedemptionHint == address(0) || !_sortedTroves.contains(_firstRedemptionHint) || getCurrentICR(_firstRedemptionHint, _price) < MCR ) { return false; } address nextTrove = _sortedTroves.getNext(_firstRedemptionHint); return nextTrove == address(0) || getCurrentICR(nextTrove, _price) < MCR; } /* Send _LUSDamount LUSD to the system and redeem the corresponding amount of collateral from as many Troves as are needed to fill the redemption * request. Applies pending rewards to a Trove before reducing its debt and coll. * * Note that if _amount is very large, this function can run out of gas, specially if traversed troves are small. This can be easily avoided by * splitting the total _amount in appropriate chunks and calling the function multiple times. * * Param `_maxIterations` can also be provided, so the loop through Troves is capped (if it’s zero, it will be ignored).This makes it easier to * avoid OOG for the frontend, as only knowing approximately the average cost of an iteration is enough, without needing to know the “topology” * of the trove list. It also avoids the need to set the cap in stone in the contract, nor doing gas calculations, as both gas price and opcode * costs can vary. * * All Troves that are redeemed from -- with the likely exception of the last one -- will end up with no debt left, therefore they will be closed. * If the last Trove does have some remaining debt, it has a finite ICR, and the reinsertion could be anywhere in the list, therefore it requires a hint. * A frontend should use getRedemptionHints() to calculate what the ICR of this Trove will be after redemption, and pass a hint for its position * in the sortedTroves list along with the ICR value that the hint was found for. * * If another transaction modifies the list between calling getRedemptionHints() and passing the hints to redeemCollateral(), it * is very likely that the last (partially) redeemed Trove would end up with a different ICR than what the hint is for. In this case the * redemption will stop after the last completely redeemed Trove and the sender will keep the remaining LUSD amount, which they can attempt * to redeem later. */ function redeemCollateral( uint _LUSDamount, address _firstRedemptionHint, address _upperPartialRedemptionHint, address _lowerPartialRedemptionHint, uint _partialRedemptionHintNICR, uint _maxIterations, uint _maxFeePercentage ) external override { ContractsCache memory contractsCache = ContractsCache( activePool, defaultPool, lusdToken, lqtyStaking, sortedTroves, collSurplusPool, gasPoolAddress ); RedemptionTotals memory totals; _requireValidMaxFeePercentage(_maxFeePercentage); _requireAfterBootstrapPeriod(); totals.price = priceFeed.fetchPrice(); _requireTCRoverMCR(totals.price); _requireAmountGreaterThanZero(_LUSDamount); _requireLUSDBalanceCoversRedemption(contractsCache.lusdToken, msg.sender, _LUSDamount); totals.totalLUSDSupplyAtStart = getEntireSystemDebt(); // Confirm redeemer's balance is less than total LUSD supply assert(contractsCache.lusdToken.balanceOf(msg.sender) <= totals.totalLUSDSupplyAtStart); totals.remainingLUSD = _LUSDamount; address currentBorrower; if (_isValidFirstRedemptionHint(contractsCache.sortedTroves, _firstRedemptionHint, totals.price)) { currentBorrower = _firstRedemptionHint; } else { currentBorrower = contractsCache.sortedTroves.getLast(); // Find the first trove with ICR >= MCR while (currentBorrower != address(0) && getCurrentICR(currentBorrower, totals.price) < MCR) { currentBorrower = contractsCache.sortedTroves.getPrev(currentBorrower); } } // Loop through the Troves starting from the one with lowest collateral ratio until _amount of LUSD is exchanged for collateral if (_maxIterations == 0) { _maxIterations = uint(-1); } while (currentBorrower != address(0) && totals.remainingLUSD > 0 && _maxIterations > 0) { _maxIterations--; // Save the address of the Trove preceding the current one, before potentially modifying the list address nextUserToCheck = contractsCache.sortedTroves.getPrev(currentBorrower); _applyPendingRewards(contractsCache.activePool, contractsCache.defaultPool, currentBorrower); SingleRedemptionValues memory singleRedemption = _redeemCollateralFromTrove( contractsCache, currentBorrower, totals.remainingLUSD, totals.price, _upperPartialRedemptionHint, _lowerPartialRedemptionHint, _partialRedemptionHintNICR ); if (singleRedemption.cancelledPartial) break; // Partial redemption was cancelled (out-of-date hint, or new net debt < minimum), therefore we could not redeem from the last Trove totals.totalLUSDToRedeem = totals.totalLUSDToRedeem.add(singleRedemption.LUSDLot); totals.totalETHDrawn = totals.totalETHDrawn.add(singleRedemption.ETHLot); totals.remainingLUSD = totals.remainingLUSD.sub(singleRedemption.LUSDLot); currentBorrower = nextUserToCheck; } require(totals.totalETHDrawn > 0, "TroveManager: Unable to redeem any amount"); // Decay the baseRate due to time passed, and then increase it according to the size of this redemption. // Use the saved total LUSD supply value, from before it was reduced by the redemption. _updateBaseRateFromRedemption(totals.totalETHDrawn, totals.price, totals.totalLUSDSupplyAtStart); // Calculate the ETH fee totals.ETHFee = _getRedemptionFee(totals.totalETHDrawn); _requireUserAcceptsFee(totals.ETHFee, totals.totalETHDrawn, _maxFeePercentage); // Send the ETH fee to the LQTY staking contract contractsCache.activePool.sendETH(address(contractsCache.lqtyStaking), totals.ETHFee); contractsCache.lqtyStaking.increaseF_ETH(totals.ETHFee); totals.ETHToSendToRedeemer = totals.totalETHDrawn.sub(totals.ETHFee); emit Redemption(_LUSDamount, totals.totalLUSDToRedeem, totals.totalETHDrawn, totals.ETHFee); // Burn the total LUSD that is cancelled with debt, and send the redeemed ETH to msg.sender contractsCache.lusdToken.burn(msg.sender, totals.totalLUSDToRedeem); // Update Active Pool LUSD, and send ETH to account contractsCache.activePool.decreaseLUSDDebt(totals.totalLUSDToRedeem); contractsCache.activePool.sendETH(msg.sender, totals.ETHToSendToRedeemer); } // --- Helper functions --- // Return the nominal collateral ratio (ICR) of a given Trove, without the price. Takes a trove's pending coll and debt rewards from redistributions into account. function getNominalICR(address _borrower) public view override returns (uint) { (uint currentETH, uint currentLUSDDebt) = _getCurrentTroveAmounts(_borrower); uint NICR = LiquityMath._computeNominalCR(currentETH, currentLUSDDebt); return NICR; } // Return the current collateral ratio (ICR) of a given Trove. Takes a trove's pending coll and debt rewards from redistributions into account. function getCurrentICR(address _borrower, uint _price) public view override returns (uint) { (uint currentETH, uint currentLUSDDebt) = _getCurrentTroveAmounts(_borrower); uint ICR = LiquityMath._computeCR(currentETH, currentLUSDDebt, _price); return ICR; } function _getCurrentTroveAmounts(address _borrower) internal view returns (uint, uint) { uint pendingETHReward = getPendingETHReward(_borrower); uint pendingLUSDDebtReward = getPendingLUSDDebtReward(_borrower); uint currentETH = Troves[_borrower].coll.add(pendingETHReward); uint currentLUSDDebt = Troves[_borrower].debt.add(pendingLUSDDebtReward); return (currentETH, currentLUSDDebt); } function applyPendingRewards(address _borrower) external override { _requireCallerIsBorrowerOperations(); return _applyPendingRewards(activePool, defaultPool, _borrower); } // Add the borrowers's coll and debt rewards earned from redistributions, to their Trove function _applyPendingRewards(IActivePool _activePool, IDefaultPool _defaultPool, address _borrower) internal { if (hasPendingRewards(_borrower)) { _requireTroveIsActive(_borrower); // Compute pending rewards uint pendingETHReward = getPendingETHReward(_borrower); uint pendingLUSDDebtReward = getPendingLUSDDebtReward(_borrower); // Apply pending rewards to trove's state Troves[_borrower].coll = Troves[_borrower].coll.add(pendingETHReward); Troves[_borrower].debt = Troves[_borrower].debt.add(pendingLUSDDebtReward); _updateTroveRewardSnapshots(_borrower); // Transfer from DefaultPool to ActivePool _movePendingTroveRewardsToActivePool(_activePool, _defaultPool, pendingLUSDDebtReward, pendingETHReward); emit TroveUpdated( _borrower, Troves[_borrower].debt, Troves[_borrower].coll, Troves[_borrower].stake, TroveManagerOperation.applyPendingRewards ); } } // Update borrower's snapshots of L_ETH and L_LUSDDebt to reflect the current values function updateTroveRewardSnapshots(address _borrower) external override { _requireCallerIsBorrowerOperations(); return _updateTroveRewardSnapshots(_borrower); } function _updateTroveRewardSnapshots(address _borrower) internal { rewardSnapshots[_borrower].ETH = L_ETH; rewardSnapshots[_borrower].LUSDDebt = L_LUSDDebt; emit TroveSnapshotsUpdated(L_ETH, L_LUSDDebt); } // Get the borrower's pending accumulated ETH reward, earned by their stake function getPendingETHReward(address _borrower) public view override returns (uint) { uint snapshotETH = rewardSnapshots[_borrower].ETH; uint rewardPerUnitStaked = L_ETH.sub(snapshotETH); if ( rewardPerUnitStaked == 0 || Troves[_borrower].status != Status.active) { return 0; } uint stake = Troves[_borrower].stake; uint pendingETHReward = stake.mul(rewardPerUnitStaked).div(DECIMAL_PRECISION); return pendingETHReward; } // Get the borrower's pending accumulated LUSD reward, earned by their stake function getPendingLUSDDebtReward(address _borrower) public view override returns (uint) { uint snapshotLUSDDebt = rewardSnapshots[_borrower].LUSDDebt; uint rewardPerUnitStaked = L_LUSDDebt.sub(snapshotLUSDDebt); if ( rewardPerUnitStaked == 0 || Troves[_borrower].status != Status.active) { return 0; } uint stake = Troves[_borrower].stake; uint pendingLUSDDebtReward = stake.mul(rewardPerUnitStaked).div(DECIMAL_PRECISION); return pendingLUSDDebtReward; } function hasPendingRewards(address _borrower) public view override returns (bool) { /* * A Trove has pending rewards if its snapshot is less than the current rewards per-unit-staked sum: * this indicates that rewards have occured since the snapshot was made, and the user therefore has * pending rewards */ if (Troves[_borrower].status != Status.active) {return false;} return (rewardSnapshots[_borrower].ETH < L_ETH); } // Return the Troves entire debt and coll, including pending rewards from redistributions. function getEntireDebtAndColl( address _borrower ) public view override returns (uint debt, uint coll, uint pendingLUSDDebtReward, uint pendingETHReward) { debt = Troves[_borrower].debt; coll = Troves[_borrower].coll; pendingLUSDDebtReward = getPendingLUSDDebtReward(_borrower); pendingETHReward = getPendingETHReward(_borrower); debt = debt.add(pendingLUSDDebtReward); coll = coll.add(pendingETHReward); } function removeStake(address _borrower) external override { _requireCallerIsBorrowerOperations(); return _removeStake(_borrower); } // Remove borrower's stake from the totalStakes sum, and set their stake to 0 function _removeStake(address _borrower) internal { uint stake = Troves[_borrower].stake; totalStakes = totalStakes.sub(stake); Troves[_borrower].stake = 0; } function updateStakeAndTotalStakes(address _borrower) external override returns (uint) { _requireCallerIsBorrowerOperations(); return _updateStakeAndTotalStakes(_borrower); } // Update borrower's stake based on their latest collateral value function _updateStakeAndTotalStakes(address _borrower) internal returns (uint) { uint newStake = _computeNewStake(Troves[_borrower].coll); uint oldStake = Troves[_borrower].stake; Troves[_borrower].stake = newStake; totalStakes = totalStakes.sub(oldStake).add(newStake); emit TotalStakesUpdated(totalStakes); return newStake; } // Calculate a new stake based on the snapshots of the totalStakes and totalCollateral taken at the last liquidation function _computeNewStake(uint _coll) internal view returns (uint) { uint stake; if (totalCollateralSnapshot == 0) { stake = _coll; } else { /* * The following assert() holds true because: * - The system always contains >= 1 trove * - When we close or liquidate a trove, we redistribute the pending rewards, so if all troves were closed/liquidated, * rewards would’ve been emptied and totalCollateralSnapshot would be zero too. */ assert(totalStakesSnapshot > 0); stake = _coll.mul(totalStakesSnapshot).div(totalCollateralSnapshot); } return stake; } function _redistributeDebtAndColl(IActivePool _activePool, IDefaultPool _defaultPool, uint _debt, uint _coll) internal { if (_debt == 0) { return; } /* * Add distributed coll and debt rewards-per-unit-staked to the running totals. Division uses a "feedback" * error correction, to keep the cumulative error low in the running totals L_ETH and L_LUSDDebt: * * 1) Form numerators which compensate for the floor division errors that occurred the last time this * function was called. * 2) Calculate "per-unit-staked" ratios. * 3) Multiply each ratio back by its denominator, to reveal the current floor division error. * 4) Store these errors for use in the next correction when this function is called. * 5) Note: static analysis tools complain about this "division before multiplication", however, it is intended. */ uint ETHNumerator = _coll.mul(DECIMAL_PRECISION).add(lastETHError_Redistribution); uint LUSDDebtNumerator = _debt.mul(DECIMAL_PRECISION).add(lastLUSDDebtError_Redistribution); // Get the per-unit-staked terms uint ETHRewardPerUnitStaked = ETHNumerator.div(totalStakes); uint LUSDDebtRewardPerUnitStaked = LUSDDebtNumerator.div(totalStakes); lastETHError_Redistribution = ETHNumerator.sub(ETHRewardPerUnitStaked.mul(totalStakes)); lastLUSDDebtError_Redistribution = LUSDDebtNumerator.sub(LUSDDebtRewardPerUnitStaked.mul(totalStakes)); // Add per-unit-staked terms to the running totals L_ETH = L_ETH.add(ETHRewardPerUnitStaked); L_LUSDDebt = L_LUSDDebt.add(LUSDDebtRewardPerUnitStaked); emit LTermsUpdated(L_ETH, L_LUSDDebt); // Transfer coll and debt from ActivePool to DefaultPool _activePool.decreaseLUSDDebt(_debt); _defaultPool.increaseLUSDDebt(_debt); _activePool.sendETH(address(_defaultPool), _coll); } function closeTrove(address _borrower) external override { _requireCallerIsBorrowerOperations(); return _closeTrove(_borrower, Status.closedByOwner); } function _closeTrove(address _borrower, Status closedStatus) internal { assert(closedStatus != Status.nonExistent && closedStatus != Status.active); uint TroveOwnersArrayLength = TroveOwners.length; _requireMoreThanOneTroveInSystem(TroveOwnersArrayLength); Troves[_borrower].status = closedStatus; Troves[_borrower].coll = 0; Troves[_borrower].debt = 0; rewardSnapshots[_borrower].ETH = 0; rewardSnapshots[_borrower].LUSDDebt = 0; _removeTroveOwner(_borrower, TroveOwnersArrayLength); sortedTroves.remove(_borrower); } /* * Updates snapshots of system total stakes and total collateral, excluding a given collateral remainder from the calculation. * Used in a liquidation sequence. * * The calculation excludes a portion of collateral that is in the ActivePool: * * the total ETH gas compensation from the liquidation sequence * * The ETH as compensation must be excluded as it is always sent out at the very end of the liquidation sequence. */ function _updateSystemSnapshots_excludeCollRemainder(IActivePool _activePool, uint _collRemainder) internal { totalStakesSnapshot = totalStakes; uint activeColl = _activePool.getETH(); uint liquidatedColl = defaultPool.getETH(); totalCollateralSnapshot = activeColl.sub(_collRemainder).add(liquidatedColl); emit SystemSnapshotsUpdated(totalStakesSnapshot, totalCollateralSnapshot); } // Push the owner's address to the Trove owners list, and record the corresponding array index on the Trove struct function addTroveOwnerToArray(address _borrower) external override returns (uint index) { _requireCallerIsBorrowerOperations(); return _addTroveOwnerToArray(_borrower); } function _addTroveOwnerToArray(address _borrower) internal returns (uint128 index) { /* Max array size is 2**128 - 1, i.e. ~3e30 troves. No risk of overflow, since troves have minimum LUSD debt of liquidation reserve plus MIN_NET_DEBT. 3e30 LUSD dwarfs the value of all wealth in the world ( which is < 1e15 USD). */ // Push the Troveowner to the array TroveOwners.push(_borrower); // Record the index of the new Troveowner on their Trove struct index = uint128(TroveOwners.length.sub(1)); Troves[_borrower].arrayIndex = index; return index; } /* * Remove a Trove owner from the TroveOwners array, not preserving array order. Removing owner 'B' does the following: * [A B C D E] => [A E C D], and updates E's Trove struct to point to its new array index. */ function _removeTroveOwner(address _borrower, uint TroveOwnersArrayLength) internal { Status troveStatus = Troves[_borrower].status; // It’s set in caller function `_closeTrove` assert(troveStatus != Status.nonExistent && troveStatus != Status.active); uint128 index = Troves[_borrower].arrayIndex; uint length = TroveOwnersArrayLength; uint idxLast = length.sub(1); assert(index <= idxLast); address addressToMove = TroveOwners[idxLast]; TroveOwners[index] = addressToMove; Troves[addressToMove].arrayIndex = index; emit TroveIndexUpdated(addressToMove, index); TroveOwners.pop(); } // --- Recovery Mode and TCR functions --- function getTCR(uint _price) external view override returns (uint) { return _getTCR(_price); } function checkRecoveryMode(uint _price) external view override returns (bool) { return _checkRecoveryMode(_price); } // Check whether or not the system *would be* in Recovery Mode, given an ETH:USD price, and the entire system coll and debt. function _checkPotentialRecoveryMode( uint _entireSystemColl, uint _entireSystemDebt, uint _price ) internal pure returns (bool) { uint TCR = LiquityMath._computeCR(_entireSystemColl, _entireSystemDebt, _price); return TCR < CCR; } // --- Redemption fee functions --- /* * This function has two impacts on the baseRate state variable: * 1) decays the baseRate based on time passed since last redemption or LUSD borrowing operation. * then, * 2) increases the baseRate based on the amount redeemed, as a proportion of total supply */ function _updateBaseRateFromRedemption(uint _ETHDrawn, uint _price, uint _totalLUSDSupply) internal returns (uint) { uint decayedBaseRate = _calcDecayedBaseRate(); /* Convert the drawn ETH back to LUSD at face value rate (1 LUSD:1 USD), in order to get * the fraction of total supply that was redeemed at face value. */ uint redeemedLUSDFraction = _ETHDrawn.mul(_price).div(_totalLUSDSupply); uint newBaseRate = decayedBaseRate.add(redeemedLUSDFraction.div(BETA)); newBaseRate = LiquityMath._min(newBaseRate, DECIMAL_PRECISION); // cap baseRate at a maximum of 100% //assert(newBaseRate <= DECIMAL_PRECISION); // This is already enforced in the line above assert(newBaseRate > 0); // Base rate is always non-zero after redemption // Update the baseRate state variable baseRate = newBaseRate; emit BaseRateUpdated(newBaseRate); _updateLastFeeOpTime(); return newBaseRate; } function getRedemptionRate() public view override returns (uint) { return _calcRedemptionRate(baseRate); } function getRedemptionRateWithDecay() public view override returns (uint) { return _calcRedemptionRate(_calcDecayedBaseRate()); } function _calcRedemptionRate(uint _baseRate) internal pure returns (uint) { return LiquityMath._min( REDEMPTION_FEE_FLOOR.add(_baseRate), DECIMAL_PRECISION // cap at a maximum of 100% ); } function _getRedemptionFee(uint _ETHDrawn) internal view returns (uint) { return _calcRedemptionFee(getRedemptionRate(), _ETHDrawn); } function getRedemptionFeeWithDecay(uint _ETHDrawn) external view override returns (uint) { return _calcRedemptionFee(getRedemptionRateWithDecay(), _ETHDrawn); } function _calcRedemptionFee(uint _redemptionRate, uint _ETHDrawn) internal pure returns (uint) { uint redemptionFee = _redemptionRate.mul(_ETHDrawn).div(DECIMAL_PRECISION); require(redemptionFee < _ETHDrawn, "TroveManager: Fee would eat up all returned collateral"); return redemptionFee; } // --- Borrowing fee functions --- function getBorrowingRate() public view override returns (uint) { return _calcBorrowingRate(baseRate); } function getBorrowingRateWithDecay() public view override returns (uint) { return _calcBorrowingRate(_calcDecayedBaseRate()); } function _calcBorrowingRate(uint _baseRate) internal pure returns (uint) { return LiquityMath._min( BORROWING_FEE_FLOOR.add(_baseRate), MAX_BORROWING_FEE ); } function getBorrowingFee(uint _LUSDDebt) external view override returns (uint) { return _calcBorrowingFee(getBorrowingRate(), _LUSDDebt); } function getBorrowingFeeWithDecay(uint _LUSDDebt) external view override returns (uint) { return _calcBorrowingFee(getBorrowingRateWithDecay(), _LUSDDebt); } function _calcBorrowingFee(uint _borrowingRate, uint _LUSDDebt) internal pure returns (uint) { return _borrowingRate.mul(_LUSDDebt).div(DECIMAL_PRECISION); } // Updates the baseRate state variable based on time elapsed since the last redemption or LUSD borrowing operation. function decayBaseRateFromBorrowing() external override { _requireCallerIsBorrowerOperations(); uint decayedBaseRate = _calcDecayedBaseRate(); assert(decayedBaseRate <= DECIMAL_PRECISION); // The baseRate can decay to 0 baseRate = decayedBaseRate; emit BaseRateUpdated(decayedBaseRate); _updateLastFeeOpTime(); } // --- Internal fee functions --- // Update the last fee operation time only if time passed >= decay interval. This prevents base rate griefing. function _updateLastFeeOpTime() internal { uint timePassed = block.timestamp.sub(lastFeeOperationTime); if (timePassed >= SECONDS_IN_ONE_MINUTE) { lastFeeOperationTime = block.timestamp; emit LastFeeOpTimeUpdated(block.timestamp); } } function _calcDecayedBaseRate() internal view returns (uint) { uint minutesPassed = _minutesPassedSinceLastFeeOp(); uint decayFactor = LiquityMath._decPow(MINUTE_DECAY_FACTOR, minutesPassed); return baseRate.mul(decayFactor).div(DECIMAL_PRECISION); } function _minutesPassedSinceLastFeeOp() internal view returns (uint) { return (block.timestamp.sub(lastFeeOperationTime)).div(SECONDS_IN_ONE_MINUTE); } // --- 'require' wrapper functions --- function _requireCallerIsBorrowerOperations() internal view { require(msg.sender == borrowerOperationsAddress, "TroveManager: Caller is not the BorrowerOperations contract"); } function _requireTroveIsActive(address _borrower) internal view { require(Troves[_borrower].status == Status.active, "TroveManager: Trove does not exist or is closed"); } function _requireLUSDBalanceCoversRedemption(ILUSDToken _lusdToken, address _redeemer, uint _amount) internal view { require(_lusdToken.balanceOf(_redeemer) >= _amount, "TroveManager: Requested redemption amount must be <= user's LUSD token balance"); } function _requireMoreThanOneTroveInSystem(uint TroveOwnersArrayLength) internal view { require (TroveOwnersArrayLength > 1 && sortedTroves.getSize() > 1, "TroveManager: Only one trove in the system"); } function _requireAmountGreaterThanZero(uint _amount) internal pure { require(_amount > 0, "TroveManager: Amount must be greater than zero"); } function _requireTCRoverMCR(uint _price) internal view { require(_getTCR(_price) >= MCR, "TroveManager: Cannot redeem when TCR < MCR"); } function _requireAfterBootstrapPeriod() internal view { uint systemDeploymentTime = lqtyToken.getDeploymentStartTime(); require(block.timestamp >= systemDeploymentTime.add(BOOTSTRAP_PERIOD), "TroveManager: Redemptions are not allowed during bootstrap phase"); } function _requireValidMaxFeePercentage(uint _maxFeePercentage) internal pure { require(_maxFeePercentage >= REDEMPTION_FEE_FLOOR && _maxFeePercentage <= DECIMAL_PRECISION, "Max fee percentage must be between 0.5% and 100%"); } // --- Trove property getters --- function getTroveStatus(address _borrower) external view override returns (uint) { return uint(Troves[_borrower].status); } function getTroveStake(address _borrower) external view override returns (uint) { return Troves[_borrower].stake; } function getTroveDebt(address _borrower) external view override returns (uint) { return Troves[_borrower].debt; } function getTroveColl(address _borrower) external view override returns (uint) { return Troves[_borrower].coll; } // --- Trove property setters, called by BorrowerOperations --- function setTroveStatus(address _borrower, uint _num) external override { _requireCallerIsBorrowerOperations(); Troves[_borrower].status = Status(_num); } function increaseTroveColl(address _borrower, uint _collIncrease) external override returns (uint) { _requireCallerIsBorrowerOperations(); uint newColl = Troves[_borrower].coll.add(_collIncrease); Troves[_borrower].coll = newColl; return newColl; } function decreaseTroveColl(address _borrower, uint _collDecrease) external override returns (uint) { _requireCallerIsBorrowerOperations(); uint newColl = Troves[_borrower].coll.sub(_collDecrease); Troves[_borrower].coll = newColl; return newColl; } function increaseTroveDebt(address _borrower, uint _debtIncrease) external override returns (uint) { _requireCallerIsBorrowerOperations(); uint newDebt = Troves[_borrower].debt.add(_debtIncrease); Troves[_borrower].debt = newDebt; return newDebt; } function decreaseTroveDebt(address _borrower, uint _debtDecrease) external override returns (uint) { _requireCallerIsBorrowerOperations(); uint newDebt = Troves[_borrower].debt.sub(_debtDecrease); Troves[_borrower].debt = newDebt; return newDebt; } }
[{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_activePoolAddress","type":"address"}],"name":"ActivePoolAddressChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_baseRate","type":"uint256"}],"name":"BaseRateUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_newBorrowerOperationsAddress","type":"address"}],"name":"BorrowerOperationsAddressChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_collSurplusPoolAddress","type":"address"}],"name":"CollSurplusPoolAddressChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_defaultPoolAddress","type":"address"}],"name":"DefaultPoolAddressChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_gasPoolAddress","type":"address"}],"name":"GasPoolAddressChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_lqtyStakingAddress","type":"address"}],"name":"LQTYStakingAddressChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_lqtyTokenAddress","type":"address"}],"name":"LQTYTokenAddressChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_L_ETH","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_L_LUSDDebt","type":"uint256"}],"name":"LTermsUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_newLUSDTokenAddress","type":"address"}],"name":"LUSDTokenAddressChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_lastFeeOpTime","type":"uint256"}],"name":"LastFeeOpTimeUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_liquidatedDebt","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_liquidatedColl","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_collGasCompensation","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_LUSDGasCompensation","type":"uint256"}],"name":"Liquidation","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":false,"internalType":"address","name":"_newPriceFeedAddress","type":"address"}],"name":"PriceFeedAddressChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_attemptedLUSDAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_actualLUSDAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_ETHSent","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_ETHFee","type":"uint256"}],"name":"Redemption","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_sortedTrovesAddress","type":"address"}],"name":"SortedTrovesAddressChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_stabilityPoolAddress","type":"address"}],"name":"StabilityPoolAddressChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_totalStakesSnapshot","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_totalCollateralSnapshot","type":"uint256"}],"name":"SystemSnapshotsUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_newTotalStakes","type":"uint256"}],"name":"TotalStakesUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_borrower","type":"address"},{"indexed":false,"internalType":"uint256","name":"_newIndex","type":"uint256"}],"name":"TroveIndexUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_borrower","type":"address"},{"indexed":false,"internalType":"uint256","name":"_debt","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_coll","type":"uint256"},{"indexed":false,"internalType":"enum TroveManager.TroveManagerOperation","name":"_operation","type":"uint8"}],"name":"TroveLiquidated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_L_ETH","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_L_LUSDDebt","type":"uint256"}],"name":"TroveSnapshotsUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_borrower","type":"address"},{"indexed":false,"internalType":"uint256","name":"_debt","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_coll","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_stake","type":"uint256"},{"indexed":false,"internalType":"enum TroveManager.TroveManagerOperation","name":"_operation","type":"uint8"}],"name":"TroveUpdated","type":"event"},{"inputs":[],"name":"BETA","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"BOOTSTRAP_PERIOD","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"BORROWING_FEE_FLOOR","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"CCR","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DECIMAL_PRECISION","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"LUSD_GAS_COMPENSATION","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"L_ETH","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"L_LUSDDebt","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_BORROWING_FEE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MCR","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MINUTE_DECAY_FACTOR","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MIN_NET_DEBT","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"NAME","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PERCENT_DIVISOR","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"REDEMPTION_FEE_FLOOR","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"SECONDS_IN_ONE_MINUTE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"TroveOwners","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"Troves","outputs":[{"internalType":"uint256","name":"debt","type":"uint256"},{"internalType":"uint256","name":"coll","type":"uint256"},{"internalType":"uint256","name":"stake","type":"uint256"},{"internalType":"enum TroveManager.Status","name":"status","type":"uint8"},{"internalType":"uint128","name":"arrayIndex","type":"uint128"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"_100pct","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"activePool","outputs":[{"internalType":"contract IActivePool","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_borrower","type":"address"}],"name":"addTroveOwnerToArray","outputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_borrower","type":"address"}],"name":"applyPendingRewards","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"baseRate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"_troveArray","type":"address[]"}],"name":"batchLiquidateTroves","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"borrowerOperationsAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_price","type":"uint256"}],"name":"checkRecoveryMode","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_borrower","type":"address"}],"name":"closeTrove","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"decayBaseRateFromBorrowing","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_borrower","type":"address"},{"internalType":"uint256","name":"_collDecrease","type":"uint256"}],"name":"decreaseTroveColl","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_borrower","type":"address"},{"internalType":"uint256","name":"_debtDecrease","type":"uint256"}],"name":"decreaseTroveDebt","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"defaultPool","outputs":[{"internalType":"contract IDefaultPool","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_LUSDDebt","type":"uint256"}],"name":"getBorrowingFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_LUSDDebt","type":"uint256"}],"name":"getBorrowingFeeWithDecay","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getBorrowingRate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getBorrowingRateWithDecay","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_borrower","type":"address"},{"internalType":"uint256","name":"_price","type":"uint256"}],"name":"getCurrentICR","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_borrower","type":"address"}],"name":"getEntireDebtAndColl","outputs":[{"internalType":"uint256","name":"debt","type":"uint256"},{"internalType":"uint256","name":"coll","type":"uint256"},{"internalType":"uint256","name":"pendingLUSDDebtReward","type":"uint256"},{"internalType":"uint256","name":"pendingETHReward","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getEntireSystemColl","outputs":[{"internalType":"uint256","name":"entireSystemColl","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getEntireSystemDebt","outputs":[{"internalType":"uint256","name":"entireSystemDebt","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_borrower","type":"address"}],"name":"getNominalICR","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_borrower","type":"address"}],"name":"getPendingETHReward","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_borrower","type":"address"}],"name":"getPendingLUSDDebtReward","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_ETHDrawn","type":"uint256"}],"name":"getRedemptionFeeWithDecay","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getRedemptionRate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getRedemptionRateWithDecay","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_price","type":"uint256"}],"name":"getTCR","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_borrower","type":"address"}],"name":"getTroveColl","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_borrower","type":"address"}],"name":"getTroveDebt","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_index","type":"uint256"}],"name":"getTroveFromTroveOwnersArray","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getTroveOwnersCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_borrower","type":"address"}],"name":"getTroveStake","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_borrower","type":"address"}],"name":"getTroveStatus","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_borrower","type":"address"}],"name":"hasPendingRewards","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_borrower","type":"address"},{"internalType":"uint256","name":"_collIncrease","type":"uint256"}],"name":"increaseTroveColl","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_borrower","type":"address"},{"internalType":"uint256","name":"_debtIncrease","type":"uint256"}],"name":"increaseTroveDebt","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"isOwner","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lastETHError_Redistribution","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lastFeeOperationTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lastLUSDDebtError_Redistribution","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_borrower","type":"address"}],"name":"liquidate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_n","type":"uint256"}],"name":"liquidateTroves","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"lqtyStaking","outputs":[{"internalType":"contract ILQTYStaking","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lqtyToken","outputs":[{"internalType":"contract ILQTYToken","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lusdToken","outputs":[{"internalType":"contract ILUSDToken","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"priceFeed","outputs":[{"internalType":"contract IPriceFeed","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_LUSDamount","type":"uint256"},{"internalType":"address","name":"_firstRedemptionHint","type":"address"},{"internalType":"address","name":"_upperPartialRedemptionHint","type":"address"},{"internalType":"address","name":"_lowerPartialRedemptionHint","type":"address"},{"internalType":"uint256","name":"_partialRedemptionHintNICR","type":"uint256"},{"internalType":"uint256","name":"_maxIterations","type":"uint256"},{"internalType":"uint256","name":"_maxFeePercentage","type":"uint256"}],"name":"redeemCollateral","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_borrower","type":"address"}],"name":"removeStake","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"rewardSnapshots","outputs":[{"internalType":"uint256","name":"ETH","type":"uint256"},{"internalType":"uint256","name":"LUSDDebt","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_borrowerOperationsAddress","type":"address"},{"internalType":"address","name":"_activePoolAddress","type":"address"},{"internalType":"address","name":"_defaultPoolAddress","type":"address"},{"internalType":"address","name":"_stabilityPoolAddress","type":"address"},{"internalType":"address","name":"_gasPoolAddress","type":"address"},{"internalType":"address","name":"_collSurplusPoolAddress","type":"address"},{"internalType":"address","name":"_priceFeedAddress","type":"address"},{"internalType":"address","name":"_lusdTokenAddress","type":"address"},{"internalType":"address","name":"_sortedTrovesAddress","type":"address"},{"internalType":"address","name":"_lqtyTokenAddress","type":"address"},{"internalType":"address","name":"_lqtyStakingAddress","type":"address"}],"name":"setAddresses","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_borrower","type":"address"},{"internalType":"uint256","name":"_num","type":"uint256"}],"name":"setTroveStatus","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"sortedTroves","outputs":[{"internalType":"contract ISortedTroves","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"stabilityPool","outputs":[{"internalType":"contract IStabilityPool","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalCollateralSnapshot","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalStakes","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalStakesSnapshot","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_borrower","type":"address"}],"name":"updateStakeAndTotalStakes","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_borrower","type":"address"}],"name":"updateTroveRewardSnapshots","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
608060405234801561001057600080fd5b50600380546001600160a01b031916339081179091556040516000907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a3615ae880620000616000396000f3fe608060405234801561001057600080fd5b506004361061044a5760003560e01c8063795d26c31161023c578063b83f91a211610146578063d3d6f843116100c3578063e2ac77b011610087578063e2ac77b014610c67578063f34862de14610c8d578063f36b242514610cb3578063f92d34331461065d578063fe2ba84814610cbb5761044a565b8063d3d6f84314610bd3578063d5b3563514610bff578063d66a255314610c1c578063d9a7244414610c42578063dba1c5f214610c5f5761044a565b8063c52861f21161010a578063c52861f214610b69578063c7b5548114610b71578063cbd138ae14610b79578063d293c71014610b9f578063d380a37c14610bcb5761044a565b8063b83f91a214610ab7578063b91af97c14610abf578063bcd3752614610b0b578063bf9befb114610b59578063c35bc55014610b615761044a565b806396d711ff116101d4578063a3f4df7e11610198578063a3f4df7e146109e7578063ae91875414610a64578063b0d8e18114610a6c578063b7f8cf9b14610a92578063b82f263d14610a9a5761044a565b806396d711ff146109a35780639976cf45146109ab5780639dd233d2146109d7578063a20baee614610894578063a3a64017146109df5761044a565b8063795d26c3146108c9578063797250e3146108d15780637985c5e4146108d95780637f7dde4a14610955578063807d138d1461095d57806382fe3eb914610965578063887105d31461098b5780638da5cb5b146109935780638f32d59b1461099b5761044a565b8063477d66cf11610358578063631203b0116102d557806372423c171161029957806372423c171461086857806372fe25aa14610894578063741bef1a1461089c578063756b253e146108a4578063794e5724146108c15761044a565b8063631203b01461079157806364cee260146107ae578063653d46e7146107d457806366ca4a21146107f15780636ef64338146107f95761044a565b80635733d58f1161031c5780635733d58f146107275780635d6b480f1461072f5780635d8c96091461075b5780635dba4c4a1461078157806361ec893d146107895761044a565b8063477d66cf146106a3578063480cd578146106c05780634870dd9a146106e657806349eefeee146106ee5780634e443d9e146106f65761044a565b80631e8b1c2b116103e657806328d28b5b116103aa57806328d28b5b1461065d5780632b11551a146106655780632e86bbd81461066d5780632f865568146106755780633cc742251461069b5761044a565b80631e8b1c2b1461057c5780631f68f20a1461061f5780631f7af3c31461062757806321e378011461062f57806324092669146106555761044a565b8063048c661d1461044f578063060d49a314610473578063071a75411461048d5780630b0765571461049557806312610e92146104bd57806315d549f1146104e95780631673c79a1461050f57806318f2817a1461054e5780631bf4355514610574575b600080fd5b610457610ce1565b604080516001600160a01b039092168252519081900360200190f35b61047b610cf0565b60408051918252519081900360200190f35b61047b610cf6565b6104bb600480360360208110156104ab57600080fd5b50356001600160a01b0316610cfb565b005b61047b600480360360408110156104d357600080fd5b506001600160a01b038135169060200135610d23565b61047b600480360360208110156104ff57600080fd5b50356001600160a01b0316610d7b565b6105356004803603602081101561052557600080fd5b50356001600160a01b0316610d9f565b6040805192835260208301919091528051918290030190f35b61047b6004803603602081101561056457600080fd5b50356001600160a01b0316610db8565b61047b610dcb565b6104bb6004803603602081101561059257600080fd5b8101906020810181356401000000008111156105ad57600080fd5b8201836020820111156105bf57600080fd5b803590602001918460208302840111640100000000831117156105e157600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250929550610dd8945050505050565b61047b61117a565b610457611180565b61047b6004803603602081101561064557600080fd5b50356001600160a01b031661118f565b61047b6111b9565b61047b6111cc565b61047b6111dd565b61047b6111ef565b6104bb6004803603602081101561068b57600080fd5b50356001600160a01b03166111fc565b610457611262565b61047b600480360360208110156106b957600080fd5b5035611271565b61047b600480360360208110156106d657600080fd5b50356001600160a01b0316611284565b61047b6112a2565b61047b6112a7565b6107136004803603602081101561070c57600080fd5b50356112ad565b604080519115158252519081900360200190f35b61047b6112b8565b6104bb6004803603604081101561074557600080fd5b506001600160a01b0381351690602001356112c4565b61047b6004803603602081101561077157600080fd5b50356001600160a01b0316611310565b6104bb6113d6565b61047b61143c565b61047b600480360360208110156107a757600080fd5b5035611441565b61047b600480360360208110156107c457600080fd5b50356001600160a01b031661144e565b6104bb600480360360208110156107ea57600080fd5b503561146c565b61047b61181a565b61081f6004803603602081101561080f57600080fd5b50356001600160a01b031661182c565b6040518086815260200185815260200184815260200183600481111561084157fe5b60ff1681526001600160801b03909216602083015250604080519182900301945092505050f35b61047b6004803603604081101561087e57600080fd5b506001600160a01b038135169060200135611866565b61047b6118c3565b6104576118cf565b610457600480360360208110156108ba57600080fd5b50356118de565b61047b611905565b61047b611911565b61047b611a12565b6104bb60048036036101608110156108f057600080fd5b506001600160a01b038135811691602081013582169160408201358116916060810135821691608082013581169160a081013582169160c082013581169160e08101358216916101008201358116916101208101358216916101409091013516611a18565b610457611e11565b61047b611e20565b6104bb6004803603602081101561097b57600080fd5b50356001600160a01b0316611e26565b61047b611e37565b610457611ef3565b610713611f02565b61047b611f13565b61047b600480360360408110156109c157600080fd5b506001600160a01b038135169060200135611f19565b61047b611f4c565b610457611f52565b6109ef611f61565b6040805160208082528351818301528351919283929083019185019080838360005b83811015610a29578181015183820152602001610a11565b50505050905090810190601f168015610a565780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b610457611f89565b61047b60048036036020811015610a8257600080fd5b50356001600160a01b0316611f98565b610457611fbf565b61047b60048036036020811015610ab057600080fd5b5035611fce565b610457611fd9565b610ae560048036036020811015610ad557600080fd5b50356001600160a01b0316611fe8565b604080519485526020850193909352838301919091526060830152519081900360800190f35b6104bb600480360360e0811015610b2157600080fd5b508035906001600160a01b03602082013581169160408101358216916060820135169060808101359060a08101359060c0013561204c565b61047b6127ee565b61047b6127f4565b61047b6127fb565b61047b61280d565b6104bb60048036036020811015610b8f57600080fd5b50356001600160a01b0316612819565b61047b60048036036040811015610bb557600080fd5b506001600160a01b03813516906020013561282c565b61047b61284b565b61047b60048036036040811015610be957600080fd5b506001600160a01b038135169060200135612851565b61047b60048036036020811015610c1557600080fd5b5035612887565b61047b60048036036020811015610c3257600080fd5b50356001600160a01b031661289a565b61045760048036036020811015610c5857600080fd5b50356128b5565b61047b6128df565b61071360048036036020811015610c7d57600080fd5b50356001600160a01b03166128e5565b61047b60048036036020811015610ca357600080fd5b50356001600160a01b0316612943565b61047b612974565b6104bb60048036036020811015610cd157600080fd5b50356001600160a01b0316612981565b6005546001600160a01b031681565b60175481565b600281565b610d03612992565b600054600154610d20916001600160a01b039081169116836129dd565b50565b6000610d2d612992565b6001600160a01b0383166000908152600e6020526040812054610d56908463ffffffff612aff16565b6001600160a01b0385166000908152600e602052604090208190559150505b92915050565b6000610d85612992565b610d8e82612b48565b6001600160801b031690505b919050565b6014602052600090815260409020805460019091015482565b6000610dc2612992565b610d7582612be2565b686194049f30f720000081565b8051610e155760405162461bcd60e51b815260040180806020018281038252603681526020018061596e6036913960400191505060405180910390fd5b6000546001546005546001600160a01b03928316929182169116610e37615613565b610e3f615644565b600260009054906101000a90046001600160a01b03166001600160a01b0316630fdb11cf6040518163ffffffff1660e01b8152600401602060405180830381600087803b158015610e8f57600080fd5b505af1158015610ea3573d6000803e3d6000fd5b505050506040513d6020811015610eb957600080fd5b50518252604080516326fcbc6b60e21b815290516001600160a01b03851691639bf2f1ac916004808301926020929190829003018186803b158015610efd57600080fd5b505afa158015610f11573d6000803e3d6000fd5b505050506040513d6020811015610f2757600080fd5b505160208301528151610f3990612c91565b1580156040840152610f6157610f5a8585846000015185602001518a612cae565b9050610f79565b610f768585846000015185602001518a612ed6565b90505b6000816020015111610fbc5760405162461bcd60e51b8152600401808060200182810382526022815260200180615a626022913960400191505060405180910390fd5b826001600160a01b031663335525ad82608001518360a001516040518363ffffffff1660e01b81526004018083815260200182815260200192505050600060405180830381600087803b15801561101257600080fd5b505af1158015611026573d6000803e3d6000fd5b5050505061103e85858360c001518460e00151612f9e565b610100810151156110bd57600754610100820151604080516364a197f360e01b81526001600160a01b039384166004820152602481019290925251918716916364a197f39160448082019260009290919082900301818387803b1580156110a457600080fd5b505af11580156110b8573d6000803e3d6000fd5b505050505b6110cb85826040015161321f565b602081015160608301526101008101516040820151825161110392916110f7919063ffffffff612aff16565b9063ffffffff612aff16565b608080840182905260608085015160408086015186840151825193845260208401969096528282015291810193909352517f4152c73dd2614c4f9fc35e8c9cf16013cd588c75b49a4c1673ecffdcbcda94039281900390910190a1611172853383606001518460400151613366565b505050505050565b600c5481565b6009546001600160a01b031681565b6001600160a01b0381166000908152600e602052604081206003015460ff166004811115610d7557fe5b6064670de0b6b3a76400005b0460050281565b6103e8670de0b6b3a76400006111c5565b60006111ea600c54613469565b905090565b680ad78ebc5ac620000081565b6112058161349f565b60408051600180825281830190925260609160208083019080368337019050509050818160008151811061123557fe5b60200260200101906001600160a01b031690816001600160a01b03168152505061125e81610dd8565b5050565b6001546001600160a01b031681565b6000610d7561127e61181a565b83613507565b6001600160a01b03166000908152600e602052604090206001015490565b60c881565b60155490565b6000610d7582612c91565b6714d1120d7b16000081565b6112cc612992565b8060048111156112d857fe5b6001600160a01b0383166000908152600e60205260409020600301805460ff1916600183600481111561130757fe5b02179055505050565b6001600160a01b038116600090815260146020526040812054601254829061133e908363ffffffff612aff16565b9050801580611377575060016001600160a01b0385166000908152600e602052604090206003015460ff16600481111561137457fe5b14155b1561138757600092505050610d9a565b6001600160a01b0384166000908152600e6020526040812060020154906113cc670de0b6b3a76400006113c0848663ffffffff61352516565b9063ffffffff61357e16565b9695505050505050565b6113de612992565b60006113e86135c0565b9050670de0b6b3a76400008111156113fc57fe5b600c8190556040805182815290517fc454ee9b76c52f782a256af821b857ca6e125d1e3333bcede402fec2bed9600c9181900360200190a1610d20613604565b603c81565b6000610d7561127e612974565b6001600160a01b03166000908152600e602052604090206002015490565b611474615690565b506040805160e081018252600080546001600160a01b0390811683526001548116602084015292820181905260608201819052600b548316608083015260a0820181905260c08201526005549091166114cb615613565b6114d3615644565b600260009054906101000a90046001600160a01b03166001600160a01b0316630fdb11cf6040518163ffffffff1660e01b8152600401602060405180830381600087803b15801561152357600080fd5b505af1158015611537573d6000803e3d6000fd5b505050506040513d602081101561154d57600080fd5b50518252604080516326fcbc6b60e21b815290516001600160a01b03851691639bf2f1ac916004808301926020929190829003018186803b15801561159157600080fd5b505afa1580156115a5573d6000803e3d6000fd5b505050506040513d60208110156115bb57600080fd5b5051602083015281516115cd90612c91565b15801560408401526115f4576115ed848360000151846020015188613660565b9050611614565b6116118460000151856020015184600001518560200151896139f3565b90505b60008160200151116116575760405162461bcd60e51b8152600401808060200182810382526022815260200180615a626022913960400191505060405180910390fd5b826001600160a01b031663335525ad82608001518360a001516040518363ffffffff1660e01b81526004018083815260200182815260200192505050600060405180830381600087803b1580156116ad57600080fd5b505af11580156116c1573d6000803e3d6000fd5b505050506116e1846000015185602001518360c001518460e00151612f9e565b61010081015115611762578351600754610100830151604080516364a197f360e01b81526001600160a01b03938416600482015260248101929092525191909216916364a197f391604480830192600092919082900301818387803b15801561174957600080fd5b505af115801561175d573d6000803e3d6000fd5b505050505b6117748460000151826040015161321f565b60208101516060830152610100810151604082015182516117a092916110f7919063ffffffff612aff16565b608080840182905260608085015160408086015186840151825193845260208401969096528282015291810193909352517f4152c73dd2614c4f9fc35e8c9cf16013cd588c75b49a4c1673ecffdcbcda94039281900390910190a161181384600001513383606001518460400151613366565b5050505050565b60006111ea6118276135c0565b613b25565b600e6020526000908152604090208054600182015460028301546003909301549192909160ff81169061010090046001600160801b031685565b6000611870612992565b6001600160a01b0383166000908152600e602052604081206001015461189c908463ffffffff613b4c16565b6001600160a01b0385166000908152600e6020526040902060010181905591505092915050565b670de0b6b3a764000081565b6002546001600160a01b031681565b601581815481106118eb57fe5b6000918252602090912001546001600160a01b0316905081565b670f43fc2c04ee000081565b6000805460408051632f5a97e560e11b8152905183926001600160a01b031691635eb52fca916004808301926020929190829003018186803b15801561195657600080fd5b505afa15801561196a573d6000803e3d6000fd5b505050506040513d602081101561198057600080fd5b505160015460408051632f5a97e560e11b815290519293506000926001600160a01b0390921691635eb52fca91600480820192602092909190829003018186803b1580156119cd57600080fd5b505afa1580156119e1573d6000803e3d6000fd5b505050506040513d60208110156119f757600080fd5b50519050611a0b828263ffffffff613b4c16565b9250505090565b60165481565b611a20611f02565b611a71576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b611a7a8b613ba6565b611a838a613ba6565b611a8c89613ba6565b611a9588613ba6565b611a9e87613ba6565b611aa786613ba6565b611ab085613ba6565b611ab984613ba6565b611ac283613ba6565b611acb82613ba6565b611ad481613ba6565b600480546001600160a01b03199081166001600160a01b038e81169182179093556000805483168e85161790556001805483168d85161790556005805483168c85161790556006805483168b85161790556007805483168a8516179055600280548316898516179055600880548316888516179055600b80548316878516179055600980548316868516179055600a805490921692841692909217905560408051918252517f3ca631ffcd2a9b5d9ae18543fc82f58eb4ca33af9e6ab01b7a8e95331e6ed985916020908290030190a1604080516001600160a01b038c16815290517f78f058b189175430c48dc02699e3a0031ea4ff781536dc2fab847de4babdd8829181900360200190a1604080516001600160a01b038b16815290517f5ee0cae2f063ed938bb55046f6a932fb6ae792bf43624806bb90abe68a50be9b9181900360200190a1604080516001600160a01b038a16815290517f82966d27eea39b038ee0fa30cd16532bb24f6e65d31cb58fb227aa5766cdcc7f9181900360200190a1604080516001600160a01b038916815290517fcfb07d791fcafc032b35837b50eb84b74df518cf4cc287e8084f47630fa70fa09181900360200190a1604080516001600160a01b038816815290517fe67f36a6e961157d6eff83b91f3af5a62131ceb6f04954ef74f51c1c05e7f88d9181900360200190a1604080516001600160a01b038716815290517f8c537274438aa850a330284665d81a85dd38267d09e4050d416bfc94142db2649181900360200190a1604080516001600160a01b038616815290517f227eec0ec317af6ab1a9587ffa1c84332522eb4c583a908f89babc05f8f339bd9181900360200190a1604080516001600160a01b038516815290517f65f4cf077bc01e4742eb5ad98326f6e95b63548ea24b17f8d5e823111fe788009181900360200190a1604080516001600160a01b038416815290517f2ac6e99201ddc1b6eac6f8f28662d1ecafee131f6eb98c29de54528a9888a7d19181900360200190a1604080516001600160a01b038316815290517f756ebc192164c295bba134b5aacd72cc7aff8098a670d1f0a5f6b3a0b4ce67079181900360200190a1611e04613c55565b5050505050505050505050565b6000546001600160a01b031681565b60105481565b611e2e612992565b610d2081613c9f565b6000805460408051630a7b61df60e11b8152905183926001600160a01b0316916314f6c3be916004808301926020929190829003018186803b158015611e7c57600080fd5b505afa158015611e90573d6000803e3d6000fd5b505050506040513d6020811015611ea657600080fd5b505160015460408051630a7b61df60e11b815290519293506000926001600160a01b03909216916314f6c3be91600480820192602092909190829003018186803b1580156119cd57600080fd5b6003546001600160a01b031690565b6003546001600160a01b0316331490565b60115481565b6000611f23612992565b6001600160a01b0383166000908152600e6020526040812054610d56908463ffffffff613b4c16565b60125481565b600a546001600160a01b031681565b6040518060400160405280600c81526020016b2a3937bb32a6b0b730b3b2b960a11b81525081565b600b546001600160a01b031681565b6000806000611fa684613d0a565b915091506000611fb68383613d90565b95945050505050565b6004546001600160a01b031681565b6000610d7582613dc5565b6008546001600160a01b031681565b6001600160a01b0381166000908152600e60205260408120805460019091015490918061201485612943565b915061201f85611310565b9050612031848363ffffffff613b4c16565b9350612043838263ffffffff613b4c16565b92509193509193565b612054615690565b506040805160e0810182526000546001600160a01b03908116825260015481166020830152600854811692820192909252600a5482166060820152600b5482166080820152600754821660a082015260065490911660c08201526120b66156cc565b6120bf83613df1565b6120c7613e4b565b600260009054906101000a90046001600160a01b03166001600160a01b0316630fdb11cf6040518163ffffffff1660e01b8152600401602060405180830381600087803b15801561211757600080fd5b505af115801561212b573d6000803e3d6000fd5b505050506040513d602081101561214157600080fd5b505160c0820181905261215390613f0f565b61215c89613f5e565b61216b8260400151338b613f9d565b612173611911565b60e0820181905260408084015181516370a0823160e01b815233600482015291516001600160a01b03909116916370a08231916024808301926020929190829003018186803b1580156121c557600080fd5b505afa1580156121d9573d6000803e3d6000fd5b505050506040513d60208110156121ef57600080fd5b505111156121f957fe5b888152608082015160c0820151600091612214918b9061405d565b1561222057508761234a565b82608001516001600160a01b0316634d6228316040518163ffffffff1660e01b815260040160206040518083038186803b15801561225d57600080fd5b505afa158015612271573d6000803e3d6000fd5b505050506040513d602081101561228757600080fd5b505190505b6001600160a01b038116158015906122b85750670f43fc2c04ee00006122b6828460c0015161282c565b105b1561234a5782608001516001600160a01b031663b72703ac826040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b15801561231757600080fd5b505afa15801561232b573d6000803e3d6000fd5b505050506040513d602081101561234157600080fd5b5051905061228c565b846123555760001994505b6001600160a01b0381161580159061236d5750815115155b80156123795750600085115b156124ad57848060019003955050600083608001516001600160a01b031663b72703ac836040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b1580156123e357600080fd5b505afa1580156123f7573d6000803e3d6000fd5b505050506040513d602081101561240d57600080fd5b50518451602086015191925061242391846129dd565b61242b615711565b612442858486600001518760c001518e8e8e6141d0565b90508060400151156124555750506124ad565b8051602085015161246b9163ffffffff613b4c16565b602080860191909152810151604085015161248b9163ffffffff613b4c16565b6040850152805184516124a39163ffffffff612aff16565b8452509050612355565b60008260400151116124f05760405162461bcd60e51b81526004018080602001828103825260298152602001806158116029913960400191505060405180910390fd5b61250782604001518360c001518460e00151614483565b50612515826040015161452b565b60608301819052604083015161252c919086614538565b82600001516001600160a01b03166364a197f3846060015184606001516040518363ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200182815260200192505050600060405180830381600087803b15801561259857600080fd5b505af11580156125ac573d6000803e3d6000fd5b5050505082606001516001600160a01b0316631e3e2a1a83606001516040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b1580156125fe57600080fd5b505af1158015612612573d6000803e3d6000fd5b505050506060820151604083015161262991612aff565b8260800181815250507f43a3f4082a4dbc33d78e317d2497d3a730bc7fc3574159dcea1056e62e5d9ad88a8360200151846040015185606001516040518085815260200184815260200183815260200182815260200194505050505060405180910390a182604001516001600160a01b0316639dc29fac3384602001516040518363ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200182815260200192505050600060405180830381600087803b1580156126f557600080fd5b505af1158015612709573d6000803e3d6000fd5b5050505082600001516001600160a01b03166338d995a883602001516040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b15801561275b57600080fd5b505af115801561276f573d6000803e3d6000fd5b505084516080850151604080516364a197f360e01b81523360048201526024810192909252516001600160a01b0390921693506364a197f3925060448082019260009290919082900301818387803b1580156127ca57600080fd5b505af11580156127de573d6000803e3d6000fd5b5050505050505050505050505050565b600f5481565b6212750081565b60006111ea6128086135c0565b613469565b670ddd4b8c6c7d70d881565b612821612992565b610d208160026145ad565b600080600061283a85613d0a565b9150915060006113cc8383876146c6565b600d5481565b600061285b612992565b6001600160a01b0383166000908152600e602052604081206001015461189c908463ffffffff612aff16565b6000610d756128946127fb565b836146f6565b6001600160a01b03166000908152600e602052604090205490565b6000601582815481106128c457fe5b6000918252602090912001546001600160a01b031692915050565b60135481565b600060016001600160a01b0383166000908152600e602052604090206003015460ff16600481111561291357fe5b1461292057506000610d9a565b506012546001600160a01b03821660009081526014602052604090205410919050565b6001600160a01b038116600090815260146020526040812060010154601354829061133e908363ffffffff612aff16565b60006111ea600c54613b25565b612989612992565b610d2081614755565b6004546001600160a01b031633146129db5760405162461bcd60e51b815260040180806020018281038252603b815260200180615933603b913960400191505060405180910390fd5b565b6129e6816128e5565b15612afa576129f48161349f565b60006129ff82611310565b90506000612a0c83612943565b6001600160a01b0384166000908152600e6020526040902060010154909150612a3b908363ffffffff613b4c16565b6001600160a01b0384166000908152600e60205260409020600181019190915554612a6c908263ffffffff613b4c16565b6001600160a01b0384166000908152600e6020526040902055612a8e83613c9f565b612a9a858583856147a5565b6001600160a01b0383166000818152600e602090815260408083208054600182015460029092015483519182529381019190915280820192909252606082019290925290516000805160206159138339815191529181900360800190a250505b505050565b6000612b4183836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f7700008152506148a7565b9392505050565b601580546001808201835560008381527f55f448fdea98c4d29eb340757ef0a66cd03dbb9538908a6a81d96026b71ec47590920180546001600160a01b0319166001600160a01b03861617905591549091612ba39190612aff565b6001600160a01b03929092166000908152600e602052604090206003018054610100600160881b0319166101006001600160801b038516021790555090565b6001600160a01b0381166000908152600e60205260408120600101548190612c099061493e565b6001600160a01b0384166000908152600e60205260409020600201805490829055600f5491925090612c53908390612c47908463ffffffff612aff16565b9063ffffffff613b4c16565b600f81905560408051918252517f6bac5e0eb3c44eb03a60ab11ec3a2c051771616aecadbcfff2630aabae5203829181900360200190a15092915050565b600080612c9d83613dc5565b6714d1120d7b160000119392505050565b612cb6615644565b612cbe615734565b612cc661577c565b84825260006080830152612cd8611911565b60a0830152612ce5611e37565b60c0830152600060208301525b835182602001511015612ecb5783826020015181518110612d0f57fe5b6020908102919091018101516001600160a01b0316606084018190526000908152600e909152604090206003015460019060ff166004811115612d4e57fe5b14612d5857612ebb565b612d6682606001518761282c565b60408301526080820151612e5d57670f43fc2c04ee0000826040015110158015612d8f57508151155b15612d9957612ebb565b6000612dae8360c001518460a00151896146c6565b9050612dcb8989856060015186604001518760000151868d61497a565b60808101518451919350612de5919063ffffffff612aff16565b8352608082015160a0840151612e009163ffffffff612aff16565b8360a0018181525050612e2d8261012001516110f78460a001518660c00151612aff90919063ffffffff16565b60c0840152612e3c8483614caf565b9350612e518360c001518460a0015189614dc8565b15608084015250612ebb565b81608001518015612e795750670f43fc2c04ee00008260400151105b15612ebb57612e92888884606001518560000151614de9565b60808101518351919250612eac919063ffffffff612aff16565b8252612eb88382614caf565b92505b6020820180516001019052612cf2565b505095945050505050565b612ede615644565b612ee6615734565b612eee61577c565b848252600060208301525b835182602001511015612ecb5783826020015181518110612f1657fe5b60209081029190910101516001600160a01b031660608301819052612f3b908761282c565b60408301819052670f43fc2c04ee00001115612f8e57612f65888884606001518560000151614de9565b60808101518351919250612f7f919063ffffffff612aff16565b8252612f8b8382614caf565b92505b6020820180516001019052612ef9565b81612fa857613219565b601654600090612fca90612c4784670de0b6b3a764000063ffffffff61352516565b90506000612fef601754612c47670de0b6b3a76400008761352590919063ffffffff16565b90506000613008600f548461357e90919063ffffffff16565b90506000613021600f548461357e90919063ffffffff16565b905061304861303b600f548461352590919063ffffffff16565b859063ffffffff612aff16565b601655600f546130709061306390839063ffffffff61352516565b849063ffffffff612aff16565b601755601254613086908363ffffffff613b4c16565b60125560135461309c908263ffffffff613b4c16565b601381905560125460408051918252602082019290925281517f9f8bc8ab0daf5bceef75ecfd2085d1fcc6548c657ea970d9a23a60610d0737e3929181900390910190a1876001600160a01b03166338d995a8876040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b15801561312657600080fd5b505af115801561313a573d6000803e3d6000fd5b50505050866001600160a01b031663cfb9329a876040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b15801561318457600080fd5b505af1158015613198573d6000803e3d6000fd5b50505050876001600160a01b03166364a197f388876040518363ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200182815260200192505050600060405180830381600087803b1580156131fc57600080fd5b505af1158015613210573d6000803e3d6000fd5b50505050505050505b50505050565b600f546010819055506000826001600160a01b03166314f6c3be6040518163ffffffff1660e01b815260040160206040518083038186803b15801561326357600080fd5b505afa158015613277573d6000803e3d6000fd5b505050506040513d602081101561328d57600080fd5b505160015460408051630a7b61df60e11b815290519293506000926001600160a01b03909216916314f6c3be91600480820192602092909190829003018186803b1580156132da57600080fd5b505afa1580156132ee573d6000803e3d6000fd5b505050506040513d602081101561330457600080fd5b5051905061331c81612c47848663ffffffff612aff16565b601181905560105460408051918252602082019290925281517f51bf4c63ec3cba9d03d43238abbdd979dd91bd16d9895c74ceea9118c7baaf60929181900390910190a150505050565b81156133e55760085460065460408051631062c15f60e11b81526001600160a01b039283166004820152868316602482015260448101869052905191909216916320c582be91606480830192600092919082900301818387803b1580156133cc57600080fd5b505af11580156133e0573d6000803e3d6000fd5b505050505b801561321957836001600160a01b03166364a197f384836040518363ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200182815260200192505050600060405180830381600087803b15801561344b57600080fd5b505af115801561345f573d6000803e3d6000fd5b5050505050505050565b6000610d75613491836103e8670de0b6b3a76400005b04600502613b4c90919063ffffffff16565b670de0b6b3a7640000614f59565b60016001600160a01b0382166000908152600e602052604090206003015460ff1660048111156134cb57fe5b14610d205760405162461bcd60e51b815260040180806020018281038252602f815260200180615a84602f913960400191505060405180910390fd5b6000612b41670de0b6b3a76400006113c0858563ffffffff61352516565b60008261353457506000610d75565b8282028284828161354157fe5b0414612b415760405162461bcd60e51b81526004018080602001828103825260218152602001806158a46021913960400191505060405180910390fd5b6000612b4183836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250614f6f565b6000806135cb614fd4565b905060006135e1670ddd4b8c6c7d70d883614ff0565b9050611a0b670de0b6b3a76400006113c083600c5461352590919063ffffffff16565b600061361b600d5442612aff90919063ffffffff16565b9050603c8110610d205742600d81905560408051918252517f860f8d2f0c74dd487e89e2883e3b25b8159ce1e1b3433a291cba7b82c508f3bc9181900360200190a150565b613668615644565b613670615734565b61367861577c565b8482526000608083015261368a611911565b60a0830152613697611e37565b8260c001818152505086608001516001600160a01b0316634d6228316040518163ffffffff1660e01b815260040160206040518083038186803b1580156136dd57600080fd5b505afa1580156136f1573d6000803e3d6000fd5b505050506040513d602081101561370757600080fd5b50516001600160a01b039081166060840152608088015160408051631e22314360e01b815290516000939290921691631e22314391600480820192602092909190829003018186803b15801561375c57600080fd5b505afa158015613770573d6000803e3d6000fd5b505050506040513d602081101561378657600080fd5b50516000602085015290505b8483602001511080156137bb5750806001600160a01b031683606001516001600160a01b031614155b156139e857600088608001516001600160a01b031663b72703ac85606001516040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b15801561382057600080fd5b505afa158015613834573d6000803e3d6000fd5b505050506040513d602081101561384a57600080fd5b5051606085015190915061385e908961282c565b6040850152608084015161395a57670f43fc2c04ee000084604001511015801561388757508351155b1561389257506139e8565b60006138a78560c001518660a001518b6146c6565b8a5160208c01516060880151604089015189519495506138c894868f61497a565b608081015186519195506138e2919063ffffffff612aff16565b8552608084015160a08601516138fd9163ffffffff612aff16565b8560a001818152505061392a8461012001516110f78660a001518860c00151612aff90919063ffffffff16565b60c08601526139398685614caf565b955061394e8560c001518660a001518b614dc8565b156080860152506139ca565b836080015180156139765750670f43fc2c04ee00008460400151105b156139c45761399789600001518a6020015186606001518760000151614de9565b608081015185519194506139b1919063ffffffff612aff16565b84526139bd8584614caf565b94506139ca565b506139e8565b6001600160a01b031660608401526020830180516001019052613792565b505050949350505050565b6139fb615644565b613a03615734565b613a0b61577c565b600b54858352600060208401526001600160a01b03165b8483602001511015613b1957806001600160a01b0316634d6228316040518163ffffffff1660e01b815260040160206040518083038186803b158015613a6757600080fd5b505afa158015613a7b573d6000803e3d6000fd5b505050506040513d6020811015613a9157600080fd5b50516001600160a01b031660608401819052613aad908861282c565b60408401819052670f43fc2c04ee00001115613b0457613ad7898985606001518660000151614de9565b60808101518451919350613af1919063ffffffff612aff16565b8352613afd8483614caf565b9350613b09565b613b19565b6020830180516001019052613a22565b50505095945050505050565b6000610d75613b3f836103e8670de0b6b3a764000061347f565b66b1a2bc2ec50000614f59565b600082820183811015612b41576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b6001600160a01b038116613c01576040805162461bcd60e51b815260206004820152601e60248201527f4163636f756e742063616e6e6f74206265207a65726f20616464726573730000604482015290519081900360640190fd5b803b8061125e576040805162461bcd60e51b815260206004820181905260248201527f4163636f756e7420636f64652073697a652063616e6e6f74206265207a65726f604482015290519081900360640190fd5b6003546040516000916001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600380546001600160a01b0319169055565b601280546001600160a01b0383166000908152601460209081526040918290209283556013546001909301839055925481519081529283019190915280517fc437f324d85e369394148dd9d62f98f534b382e01ed3dd2eb98138fb6d3ab49a9281900390910190a150565b6000806000613d1884611310565b90506000613d2585612943565b6001600160a01b0386166000908152600e602052604081206001015491925090613d55908463ffffffff613b4c16565b6001600160a01b0387166000908152600e602052604081205491925090613d82908463ffffffff613b4c16565b919550909350505050915091565b60008115613dbc57613db5826113c08568056bc75e2d6310000063ffffffff61352516565b9050610d75565b50600019610d75565b600080613dd0611e37565b90506000613ddc611911565b9050613de98282866146c6565b949350505050565b6611c37937e080008110801590613e105750670de0b6b3a76400008111155b610d205760405162461bcd60e51b8152600401808060200182810382526030815260200180615a086030913960400191505060405180910390fd5b60095460408051631e425be160e11b815290516000926001600160a01b031691633c84b7c2916004808301926020929190829003018186803b158015613e9057600080fd5b505afa158015613ea4573d6000803e3d6000fd5b505050506040513d6020811015613eba57600080fd5b50519050613ed1816212750063ffffffff613b4c16565b421015610d205760405162461bcd60e51b81526004018080602001828103825260408152602001806158646040913960400191505060405180910390fd5b670f43fc2c04ee0000613f2182613dc5565b1015610d205760405162461bcd60e51b815260040180806020018281038252602a815260200180615a38602a913960400191505060405180910390fd5b60008111610d205760405162461bcd60e51b815260040180806020018281038252602e8152602001806159a4602e913960400191505060405180910390fd5b80836001600160a01b03166370a08231846040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b158015613ff457600080fd5b505afa158015614008573d6000803e3d6000fd5b505050506040513d602081101561401e57600080fd5b50511015612afa5760405162461bcd60e51b815260040180806020018281038252604e8152602001806158c5604e913960600191505060405180910390fd5b60006001600160a01b03831615806140f45750836001600160a01b0316635dbe47e8846040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b1580156140c657600080fd5b505afa1580156140da573d6000803e3d6000fd5b505050506040513d60208110156140f057600080fd5b5051155b8061410f5750670f43fc2c04ee000061410d848461282c565b105b1561411c57506000612b41565b6000846001600160a01b031663765e0159856040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b15801561417457600080fd5b505afa158015614188573d6000803e3d6000fd5b505050506040513d602081101561419e57600080fd5b505190506001600160a01b0381161580611fb65750670f43fc2c04ee00006141c6828561282c565b1095945050505050565b6141d8615711565b6001600160a01b0387166000908152600e602052604090205461421590879061421090680ad78ebc5ac620000063ffffffff612aff16565b614f59565b8082526142369086906113c090670de0b6b3a764000063ffffffff61352516565b60208083019190915281516001600160a01b0389166000908152600e90925260408220546142699163ffffffff612aff16565b6020808401516001600160a01b038b166000908152600e9092526040822060010154929350909161429f9163ffffffff612aff16565b9050680ad78ebc5ac6200000821415614338576142bb89614755565b6142c68960046145ad565b6142db8a8a680ad78ebc5ac62000008461509b565b886001600160a01b0316600080516020615913833981519152600080600060036040518085815260200184815260200183815260200182600381111561431d57fe5b60ff16815260200194505050505060405180910390a2614475565b60006143448284613d90565b905084811415806143655750686194049f30f720000061436384615250565b105b156143795750506001604083015250614478565b60808b01516040805163015f109360e51b81526001600160a01b038d81166004830152602482018590528a81166044830152898116606483015291519190921691632be2126091608480830192600092919082900301818387803b1580156143e057600080fd5b505af11580156143f4573d6000803e3d6000fd5b5050506001600160a01b038b166000908152600e60205260409020848155600101839055506144228a612be2565b506001600160a01b038a166000818152600e6020908152604091829020600201548251878152918201869052818301526003606082015290516000805160206159138339815191529181900360800190a2505b50505b979650505050505050565b60008061448e6135c0565b905060006144a6846113c0888863ffffffff61352516565b905060006144cb6144be83600263ffffffff61357e16565b849063ffffffff613b4c16565b90506144df81670de0b6b3a7640000614f59565b9050600081116144eb57fe5b600c8190556040805182815290517fc454ee9b76c52f782a256af821b857ca6e125d1e3333bcede402fec2bed9600c9181900360200190a16113cc613604565b6000610d756128946111dd565b6000614556836113c086670de0b6b3a764000063ffffffff61352516565b905081811115613219576040805162461bcd60e51b815260206004820152601d60248201527f4665652065786365656465642070726f7669646564206d6178696d756d000000604482015290519081900360640190fd5b60008160048111156145bb57fe5b141580156145d5575060018160048111156145d257fe5b14155b6145db57fe5b6015546145e78161526b565b6001600160a01b0383166000908152600e60205260409020600301805483919060ff1916600183600481111561461957fe5b02179055506001600160a01b0383166000908152600e6020908152604080832060018082018590559084905560149092528220828155015561465b8382615324565b600b5460408051631484968760e11b81526001600160a01b038681166004830152915191909216916329092d0e91602480830192600092919082900301818387803b1580156146a957600080fd5b505af11580156146bd573d6000803e3d6000fd5b50505050505050565b600082156146ed5760006146e4846113c0878663ffffffff61352516565b9150612b419050565b50600019612b41565b600080614715670de0b6b3a76400006113c0868663ffffffff61352516565b9050828110612b415760405162461bcd60e51b81526004018080602001828103825260368152602001806159d26036913960400191505060405180910390fd5b6001600160a01b0381166000908152600e6020526040902060020154600f54614784908263ffffffff612aff16565b600f55506001600160a01b03166000908152600e6020526040812060020155565b826001600160a01b03166338d995a8836040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b1580156147eb57600080fd5b505af11580156147ff573d6000803e3d6000fd5b50505050836001600160a01b031663cfb9329a836040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b15801561484957600080fd5b505af115801561485d573d6000803e3d6000fd5b50505050826001600160a01b031663be41205f826040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b15801561344b57600080fd5b600081848411156149365760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b838110156148fb5781810151838201526020016148e3565b50505050905090810190601f1680156149285780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b60008060115460001415614953575081610d75565b60006010541161495f57fe5b612b416011546113c06010548661352590919063ffffffff16565b61498261577c565b61498a6157cf565b60155460011061499a5750614478565b6149a387611fe8565b604085015260208481019190915284018190529083526149c2906154cb565b60408301819052680ad78ebc5ac6200000606084015260208301516149ec9163ffffffff612aff16565b8152670de0b6b3a76400008611614af557614a118989836020015184604001516147a5565b614a1a87614755565b60006080830181905260c0830152815160e08301528051610100830152614a428760036145ad565b866001600160a01b03166000805160206157f183398151915283600001518460200151600260405180848152602001838152602001826003811115614a8357fe5b60ff168152602001935050505060405180910390a2866001600160a01b03166000805160206159138339815191526000806000600260405180858152602001848152602001838152602001826003811115614ada57fe5b60ff16815260200194505050505060405180910390a2614ca3565b670de0b6b3a764000086118015614b135750670f43fc2c04ee000086105b15614b6457614b2c8989836020015184604001516147a5565b614b3587614755565b81518151614b449190876154d2565b61010086015260e085015260c08401526080830152614a428760036145ad565b670f43fc2c04ee00008610158015614b7b57508386105b8015614b88575081518510155b15614c9257614ba18989836020015184604001516147a5565b84614ba857fe5b614bb187614755565b614bc4826000015183602001518561553e565b9150614bd18760036145ad565b61012082015115614c515760075461012083015160408051633f10abab60e01b81526001600160a01b038b81166004830152602482019390935290519190921691633f10abab91604480830192600092919082900301818387803b158015614c3857600080fd5b505af1158015614c4c573d6000803e3d6000fd5b505050505b866001600160a01b03166000805160206157f183398151915283600001518460a00151600260405180848152602001838152602001826003811115614a8357fe5b614c9a61577c565b91506144789050565b50979650505050505050565b614cb7615644565b60408083015190840151614cd09163ffffffff613b4c16565b604082015260608083015190840151614cee9163ffffffff613b4c16565b606082015281516020840151614d099163ffffffff613b4c16565b6020808301919091528201518351614d269163ffffffff613b4c16565b815260808083015190840151614d419163ffffffff613b4c16565b608082015260c082015160a0840151614d5f9163ffffffff613b4c16565b60a082015260e082015160c0840151614d7d9163ffffffff613b4c16565b60c082015261010082015160e0840151614d9c9163ffffffff613b4c16565b60e0820152610120820151610100840151614dbc9163ffffffff613b4c16565b61010082015292915050565b600080614dd68585856146c6565b6714d1120d7b1600001195945050505050565b614df161577c565b614df96157cf565b614e0284611fe8565b60408501908152602085810192835286019290925291845290519051614e2c9188918891906147a5565b614e3584614755565b614e4282602001516154cb565b60408301819052680ad78ebc5ac620000060608401526020830151600091614e70919063ffffffff612aff16565b9050614e81836000015182866154d2565b61010087015260e086015260c08501526080840152614ea18560036145ad565b846001600160a01b03166000805160206157f183398151915284600001518560200151600160405180848152602001838152602001826003811115614ee257fe5b60ff168152602001935050505060405180910390a2846001600160a01b03166000805160206159138339815191526000806000600160405180858152602001848152602001838152602001826003811115614f3957fe5b60ff16815260200194505050505060405180910390a25050949350505050565b6000818310614f685781612b41565b5090919050565b60008183614fbe5760405162461bcd60e51b81526020600482018181528351602484015283519092839260449091019190850190808383600083156148fb5781810151838201526020016148e3565b506000838581614fca57fe5b0495945050505050565b60006111ea603c6113c0600d5442612aff90919063ffffffff16565b6000631f54050082111561500657631f54050091505b8161501a5750670de0b6b3a7640000610d75565b670de0b6b3a764000083835b6001811115615091576002810661505b5761504182836155e0565b915061505481600263ffffffff61357e16565b905061508c565b61506582846155e0565b925061507182836155e0565b915061508960026113c083600163ffffffff612aff16565b90505b615026565b6113cc82846155e0565b6040808501516006548251632770a7eb60e21b81526001600160a01b039182166004820152602481018690529251911691639dc29fac91604480830192600092919082900301818387803b1580156150f257600080fd5b505af1158015615106573d6000803e3d6000fd5b5050505083600001516001600160a01b03166338d995a8836040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b15801561515457600080fd5b505af1158015615168573d6000803e3d6000fd5b505050508360a001516001600160a01b0316633f10abab84836040518363ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200182815260200192505050600060405180830381600087803b1580156151d057600080fd5b505af11580156151e4573d6000803e3d6000fd5b5050505083600001516001600160a01b03166364a197f38560a00151836040518363ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200182815260200192505050600060405180830381600087803b15801561344b57600080fd5b6000610d7582680ad78ebc5ac620000063ffffffff612aff16565b6001811180156152e95750600b546040805163de8fa43160e01b815290516001926001600160a01b03169163de8fa431916004808301926020929190829003018186803b1580156152bb57600080fd5b505afa1580156152cf573d6000803e3d6000fd5b505050506040513d60208110156152e557600080fd5b5051115b610d205760405162461bcd60e51b815260040180806020018281038252602a81526020018061583a602a913960400191505060405180910390fd5b6001600160a01b0382166000908152600e602052604081206003015460ff169081600481111561535057fe5b1415801561536a5750600181600481111561536757fe5b14155b61537057fe5b6001600160a01b0383166000908152600e602052604081206003015461010090046001600160801b03169083906153a8826001612aff565b905080836001600160801b031611156153bd57fe5b6000601582815481106153cc57fe5b600091825260209091200154601580546001600160a01b03909216925082916001600160801b0387169081106153fe57fe5b600091825260208083209190910180546001600160a01b0319166001600160a01b03948516179055918316808252600e83526040918290206003018054610100600160881b0319166101006001600160801b038a169081029190911790915582519182529281019290925280517f02b04ae5f7be9ca7c103293a2aa15f3c339d15d6eda53b721fef7b0e609c831a9281900390910190a160158054806154a057fe5b600082815260209020810160001990810180546001600160a01b031916905501905550505050505050565b60c8900490565b60008080808415615528576154e78786614f59565b93506154fd876113c0888763ffffffff61352516565b925061550f878563ffffffff612aff16565b9150615521868463ffffffff612aff16565b9050615535565b5060009250829150859050845b93509350935093565b61554661577c565b83815260208101839052600061556e836113c087670f43fc2c04ee000063ffffffff61352516565b9050615579816154cb565b60408301819052680ad78ebc5ac620000060608401526080830186905260a083018290526155ae90829063ffffffff612aff16565b60c08301526155c3848263ffffffff612aff16565b61012083015250600060e082018190526101008201529392505050565b6000806155f3848463ffffffff61352516565b9050613de9670de0b6b3a76400006113c0836706f05b59d3b20000613b4c565b6040518060a00160405280600081526020016000815260200160001515815260200160008152602001600081525090565b6040518061012001604052806000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081525090565b6040805160e081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c081019190915290565b60405180610100016040528060008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081525090565b604051806060016040528060008152602001600081526020016000151581525090565b6040518060e0016040528060008152602001600081526020016000815260200160006001600160a01b0316815260200160001515815260200160008152602001600081525090565b604051806101400160405280600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081525090565b6040518060600160405280600081526020016000815260200160008152509056feea67486ed7ebe3eea8ab3390efd4a3c8aae48be5bea27df104a8af786c40843454726f76654d616e616765723a20556e61626c6520746f2072656465656d20616e7920616d6f756e7454726f76654d616e616765723a204f6e6c79206f6e652074726f766520696e207468652073797374656d54726f76654d616e616765723a20526564656d7074696f6e7320617265206e6f7420616c6c6f77656420647572696e6720626f6f747374726170207068617365536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f7754726f76654d616e616765723a2052657175657374656420726564656d7074696f6e20616d6f756e74206d757374206265203c3d20757365722773204c55534420746f6b656e2062616c616e6365c3770d654ed33aeea6bf11ac8ef05d02a6a04ed4686dd2f624d853bbec43cc8b54726f76654d616e616765723a2043616c6c6572206973206e6f742074686520426f72726f7765724f7065726174696f6e7320636f6e747261637454726f76654d616e616765723a2043616c6c646174612061646472657373206172726179206d757374206e6f7420626520656d70747954726f76654d616e616765723a20416d6f756e74206d7573742062652067726561746572207468616e207a65726f54726f76654d616e616765723a2046656520776f756c642065617420757020616c6c2072657475726e656420636f6c6c61746572616c4d6178206665652070657263656e74616765206d757374206265206265747765656e20302e352520616e64203130302554726f76654d616e616765723a2043616e6e6f742072656465656d207768656e20544352203c204d435254726f76654d616e616765723a206e6f7468696e6720746f206c697175696461746554726f76654d616e616765723a2054726f766520646f6573206e6f74206578697374206f7220697320636c6f736564a2646970667358221220f3815bc084bd54d477eb0864e6b3cdd65d39c5105fb7cb4abb2cd2231ff36d6b64736f6c634300060b0033
Deployed ByteCode Sourcemap
123753:69125:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;123988:44;;;:::i;:::-;;;;-1:-1:-1;;;;;123988:44:0;;;;;;;;;;;;;;127064;;;:::i;:::-;;;;;;;;;;;;;;;;125132:29;;;:::i;171353:195::-;;;;;;;;;;;;;;;;-1:-1:-1;171353:195:0;-1:-1:-1;;;;;171353:195:0;;:::i;:::-;;192586:289;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;192586:289:0;;;;;;;;:::i;181457:193::-;;;;;;;;;;;;;;;;-1:-1:-1;181457:193:0;-1:-1:-1;;;;;181457:193:0;;:::i;126589:58::-;;;;;;;;;;;;;;;;-1:-1:-1;126589:58:0;-1:-1:-1;;;;;126589:58:0;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;176089:197;;;;;;;;;;;;;;;;-1:-1:-1;176089:197:0;-1:-1:-1;;;;;176089:197:0;;:::i;118631:43::-;;;:::i;150171:2315::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;150171:2315:0;;-1:-1:-1;150171:2315:0;;-1:-1:-1;;;;;150171:2315:0:i;125170:20::-;;;:::i;124158:36::-;;;:::i;190887:137::-;;;;;;;;;;;;;;;;-1:-1:-1;190887:137:0;-1:-1:-1;;;;;190887:137:0;;:::i;124727:68::-;;;:::i;124640:72::-;;;:::i;185359:120::-;;;:::i;118513:51::-;;;:::i;134168:242::-;;;;;;;;;;;;;;;;-1:-1:-1;134168:242:0;-1:-1:-1;;;;;134168:242:0;;:::i;118939:31::-;;;:::i;187244:171::-;;;;;;;;;;;;;;;;-1:-1:-1;187244:171:0;;:::i;191304:127::-;;;;;;;;;;;;;;;;-1:-1:-1;191304:127:0;-1:-1:-1;;;;;191304:127:0;;:::i;118731:42::-;;;:::i;133747:113::-;;;:::i;183408:130::-;;;;;;;;;;;;;;;;-1:-1:-1;183408:130:0;;:::i;:::-;;;;;;;;;;;;;;;;;;118384:46;;;:::i;191510:177::-;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;191510:177:0;;;;;;;;:::i;173399:488::-;;;;;;;;;;;;;;;;-1:-1:-1;173399:488:0;-1:-1:-1;;;;;173399:488:0;;:::i;187725:378::-;;;:::i;124418:47::-;;;:::i;187083:153::-;;;;;;;;;;;;;;;;-1:-1:-1;187083:153:0;;:::i;191032:129::-;;;;;;;;;;;;;;;;-1:-1:-1;191032:129:0;-1:-1:-1;;;;;191032:129:0;;:::i;143297:2425::-;;;;;;;;;;;;;;;;-1:-1:-1;143297:2425:0;;:::i;186719:141::-;;;:::i;125661:40::-;;;;;;;;;;;;;;;;-1:-1:-1;125661:40:0;-1:-1:-1;;;;;125661:40:0;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;125661:40:0;;;;;;;-1:-1:-1;125661:40:0;;;;;;;;;-1:-1:-1;125661:40:0;-1:-1:-1;;;125661:40:0;191695:289;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;191695:289:0;;;;;;;;:::i;118055:50::-;;;:::i;118979:36::-;;;:::i;126917:28::-;;;;;;;;;;;;;;;;-1:-1:-1;126917:28:0;;:::i;118185:46::-;;;:::i;119931:236::-;;;:::i;127018:39::-;;;:::i;131342:2371::-;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;131342:2371:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;118901:29::-;;;:::i;125835:31::-;;;:::i;172882:183::-;;;;;;;;;;;;;;;;-1:-1:-1;172882:183:0;-1:-1:-1;;;;;172882:183:0;;:::i;119689:234::-;;;:::i;121943:79::-;;;:::i;122309:92::-;;;:::i;125997:35::-;;;:::i;192289:289::-;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;192289:289:0;;;;;;;;:::i;126469:17::-;;;:::i;124203:40::-;;;:::i;123836:44::-;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;124342:33;;;:::i;170170:278::-;;;;;;;;;;;;;;;;-1:-1:-1;170170:278:0;-1:-1:-1;;;;;170170:278:0;;:::i;123939:40::-;;;:::i;183292:108::-;;;;;;;;;;;;;;;;-1:-1:-1;183292:108:0;;:::i;124113:36::-;;;:::i;175114:524::-;;;;;;;;;;;;;;;;-1:-1:-1;175114:524:0;-1:-1:-1;;;;;175114:524:0;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;165155:4804;;;;;;;;;;;;;;;;-1:-1:-1;165155:4804:0;;;-1:-1:-1;;;;;165155:4804:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;125710:23::-;;;:::i;124869:47::-;;;:::i;185487:143::-;;;:::i;124572:61::-;;;:::i;179605:174::-;;;;;;;;;;;;;;;;-1:-1:-1;179605:174:0;-1:-1:-1;;;;;179605:174:0;;:::i;170605:290::-;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;170605:290:0;;;;;;;;:::i;125283:32::-;;;:::i;191992:289::-;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;191992:289:0;;;;;;;;:::i;186039:174::-;;;;;;;;;;;;;;;;-1:-1:-1;186039:174:0;;:::i;191169:127::-;;;;;;;;;;;;;;;;-1:-1:-1;191169:127:0;-1:-1:-1;;;;;191169:127:0;;:::i;133868:137::-;;;;;;;;;;;;;;;;-1:-1:-1;133868:137:0;;:::i;126493:22::-;;;:::i;174513:497::-;;;;;;;;;;;;;;;;-1:-1:-1;174513:497:0;-1:-1:-1;;;;;174513:497:0;;:::i;173981:524::-;;;;;;;;;;;;;;;;-1:-1:-1;173981:524:0;-1:-1:-1;;;;;173981:524:0;;:::i;186593:118::-;;;:::i;175646:154::-;;;;;;;;;;;;;;;;-1:-1:-1;175646:154:0;-1:-1:-1;;;;;175646:154:0;;:::i;123988:44::-;;;-1:-1:-1;;;;;123988:44:0;;:::o;127064:::-;;;;:::o;125132:29::-;125160:1;125132:29;:::o;171353:195::-;171430:36;:34;:36::i;:::-;171505:10;;;171517:11;171484:56;;-1:-1:-1;;;;;171505:10:0;;;;171517:11;171530:9;171484:20;:56::i;:::-;171353:195;:::o;192586:289::-;192679:4;192696:36;:34;:36::i;:::-;-1:-1:-1;;;;;192758:17:0;;192743:12;192758:17;;;:6;:17;;;;;:22;:41;;192785:13;192758:41;:26;:41;:::i;:::-;-1:-1:-1;;;;;192810:17:0;;;;;;:6;:17;;;;;:32;;;192743:56;-1:-1:-1;;192586:289:0;;;;;:::o;181457:193::-;181533:10;181556:36;:34;:36::i;:::-;181610:32;181632:9;181610:21;:32::i;:::-;-1:-1:-1;;;;;181603:39:0;;;181457:193;;;;:::o;126589:58::-;;;;;;;;;;;;;;;;;;;:::o;176089:197::-;176170:4;176187:36;:34;:36::i;:::-;176241:37;176268:9;176241:26;:37::i;118631:43::-;118667:7;118631:43;:::o;150171:2315::-;150266:18;;150258:90;;;;-1:-1:-1;;;150258:90:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;150361:28;150392:10;;150446:11;150505:13;;-1:-1:-1;;;;;150392:10:0;;;;150446:11;;;;150505:13;150531:51;;:::i;:::-;150593:31;;:::i;:::-;150650:9;;;;;;;;;-1:-1:-1;;;;;150650:9:0;-1:-1:-1;;;;;150650:20:0;;:22;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;150650:22:0;150637:35;;150705:42;;;-1:-1:-1;;;150705:42:0;;;;-1:-1:-1;;;;;150705:40:0;;;;;:42;;;;;150650:22;;150705:42;;;;;;;:40;:42;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;150705:42:0;;150683:19;;:64;150804:10;;150785:30;;:18;:30::i;:::-;150758:57;;;:24;;;:57;150925:387;;150979:123;151020:16;151038:17;151057:4;:10;;;151069:4;:19;;;151090:11;150979:40;:123::i;:::-;150970:132;;150925:387;;;151178:122;151218:16;151236:17;151255:4;:10;;;151267:4;:19;;;151288:11;151178:39;:122::i;:::-;151169:131;;150925:387;151361:1;151332:6;:26;;;:30;151324:77;;;;-1:-1:-1;;;151324:77:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;151480:19;-1:-1:-1;;;;;151480:26:0;;151507:6;:24;;;151533:6;:26;;;151480:80;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;151571:125;151596:16;151614:17;151633:6;:30;;;151665:6;:30;;;151571:24;:125::i;:::-;151711:23;;;;:27;151707:135;;151788:15;;;151806:23;;;151755:75;;;-1:-1:-1;;;151755:75:0;;-1:-1:-1;;;;;151788:15:0;;;151755:75;;;;;;;;;;;;:24;;;;;;:75;;;;;151788:15;;151755:75;;;;;;;;151788:15;151755:24;:75;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;151707:135;151890:94;151934:16;151952:6;:31;;;151890:43;:94::i;:::-;152019:26;;;;151997:19;;;:48;152146:23;;;;152109:31;;;;152078:26;;:92;;152146:23;152078:63;;:26;:63;:30;:63;:::i;:::-;:67;:92;:67;:92;:::i;:::-;152056:19;;;;:114;;;152198:19;;;;;152240:31;;;;;152273;;;;152186:119;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;152362:116;152383:16;152401:10;152413:6;:31;;;152446:6;:31;;;152362:20;:116::i;:::-;150171:2315;;;;;;:::o;125170:20::-;;;;:::o;124158:36::-;;;-1:-1:-1;;;;;124158:36:0;;:::o;190887:137::-;-1:-1:-1;;;;;190991:17:0;;190962:4;190991:17;;;:6;:17;;;;;:24;;;;;190986:30;;;;;;;124727:68;124788:3;26941:4;124768:23;;124794:1;124768:27;124727:68;:::o;124640:72::-;124704:4;26941;124684:24;;185359:120;185418:4;185442:29;185462:8;;185442:19;:29::i;:::-;185435:36;;185359:120;:::o;118513:51::-;118558:6;118513:51;:::o;134168:242::-;134235:32;134257:9;134235:21;:32::i;:::-;134309:16;;;134323:1;134309:16;;;;;;;;;134280:26;;134309:16;;;;;;;;;;;-1:-1:-1;134309:16:0;134280:45;;134351:9;134336;134346:1;134336:12;;;;;;;;;;;;;:24;-1:-1:-1;;;;;134336:24:0;;;-1:-1:-1;;;;;134336:24:0;;;;;134371:31;134392:9;134371:20;:31::i;:::-;134168:242;;:::o;118939:31::-;;;-1:-1:-1;;;;;118939:31:0;;:::o;187244:171::-;187326:4;187350:57;187368:27;:25;:27::i;:::-;187397:9;187350:17;:57::i;191304:127::-;-1:-1:-1;;;;;191401:17:0;191377:4;191401:17;;;:6;:17;;;;;:22;;;;191304:127::o;118731:42::-;118770:3;118731:42;:::o;133747:113::-;133834:11;:18;133747:113;:::o;183408:130::-;183480:4;183504:26;183523:6;183504:18;:26::i;118384:46::-;118411:19;118384:46;:::o;191510:177::-;191593:36;:34;:36::i;:::-;191674:4;191667:12;;;;;;;;-1:-1:-1;;;;;191640:17:0;;;;;;:6;:17;;;;;:24;;:39;;-1:-1:-1;;191640:39:0;;;;;;;;;;;;;;;;191510:177;;:::o;173399:488::-;-1:-1:-1;;;;;173513:26:0;;173477:4;173513:26;;;:15;:26;;;;;:30;173581:5;;173477:4;;173581:22;;173513:30;173581:22;:9;:22;:::i;:::-;173554:49;-1:-1:-1;173621:24:0;;;:69;;-1:-1:-1;173677:13:0;-1:-1:-1;;;;;173649:17:0;;;;;;:6;:17;;;;;:24;;;;;:41;;;;;;;;;;173621:69;173616:89;;;173701:1;173694:8;;;;;;173616:89;-1:-1:-1;;;;;173730:17:0;;173717:10;173730:17;;;:6;:17;;;;;:23;;;;173790:53;26941:4;173790:30;173730:23;173800:19;173790:30;:9;:30;:::i;:::-;:34;:53;:34;:53;:::i;:::-;173766:77;173399:488;-1:-1:-1;;;;;;173399:488:0:o;187725:378::-;187792:36;:34;:36::i;:::-;187841:20;187864:22;:20;:22::i;:::-;187841:45;;26941:4;187904:15;:36;;187897:44;;;;187986:8;:26;;;188028:32;;;;;;;;;;;;;;;;;188073:22;:20;:22::i;124418:47::-;124463:2;124418:47;:::o;187083:153::-;187156:4;187180:48;187198:18;:16;:18::i;191032:129::-;-1:-1:-1;;;;;191130:17:0;191106:4;191130:17;;;:6;:17;;;;;:23;;;;191032:129::o;143297:2425::-;143360:36;;:::i;:::-;-1:-1:-1;143399:247:0;;;;;;;;-1:-1:-1;143428:10:0;;-1:-1:-1;;;;;143428:10:0;;;143399:247;;143428:10;143453:11;;;143399:247;;;;;;;;;;;;;;;;143555:12;;;;143399:247;;;;;;;;;;;;;;143694:13;;143399:247;;143694:13;143720:51;;:::i;:::-;143784:31;;:::i;:::-;143841:9;;;;;;;;;-1:-1:-1;;;;;143841:9:0;-1:-1:-1;;;;;143841:20:0;;:22;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;143841:22:0;143828:35;;143896:42;;;-1:-1:-1;;;143896:42:0;;;;-1:-1:-1;;;;;143896:40:0;;;;;:42;;;;;143841:22;;143896:42;;;;;;;:40;:42;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;143896:42:0;;143874:19;;:64;143995:10;;143976:30;;:18;:30::i;:::-;143949:57;;;:24;;;:57;144120:383;;144174:103;144225:14;144241:4;:10;;;144253:4;:19;;;144274:2;144174:50;:103::i;:::-;144165:112;;144120:383;;;144351:140;144400:14;:25;;;144427:14;:26;;;144455:4;:10;;;144467:4;:19;;;144488:2;144351:48;:140::i;:::-;144342:149;;144120:383;144552:1;144523:6;:26;;;:30;144515:77;;;;-1:-1:-1;;;144515:77:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;144671:19;-1:-1:-1;;;;;144671:26:0;;144698:6;:24;;;144724:6;:26;;;144671:80;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;144762:143;144787:14;:25;;;144814:14;:26;;;144842:6;:30;;;144874:6;:30;;;144762:24;:143::i;:::-;144920:23;;;;:27;144916:144;;144964:25;;145006:15;;;145024:23;;;144964:84;;;-1:-1:-1;;;144964:84:0;;-1:-1:-1;;;;;145006:15:0;;;144964:84;;;;;;;;;;;;:33;;;;;;;:84;;;;;:25;;:84;;;;;;;:25;:33;:84;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;144916:144;145108:103;145152:14;:25;;;145179:6;:31;;;145108:43;:103::i;:::-;145246:26;;;;145224:19;;;:48;145373:23;;;;145336:31;;;;145305:26;;:92;;145373:23;145305:63;;:26;:63;:30;:63;:::i;:92::-;145283:19;;;;:114;;;145425:19;;;;;145467:31;;;;;145500;;;;145413:119;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;145589:125;145610:14;:25;;;145637:10;145649:6;:31;;;145682:6;:31;;;145589:20;:125::i;:::-;143297:2425;;;;;:::o;186719:141::-;186786:4;186810:42;186829:22;:20;:22::i;:::-;186810:18;:42::i;125661:40::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;125661:40:0;;:::o;191695:289::-;191788:4;191805:36;:34;:36::i;:::-;-1:-1:-1;;;;;191867:17:0;;191852:12;191867:17;;;:6;:17;;;;;:22;;;:41;;191894:13;191867:41;:26;:41;:::i;:::-;-1:-1:-1;;;;;191919:17:0;;;;;;:6;:17;;;;;:22;;:32;;;191852:56;-1:-1:-1;;191695:289:0;;;;:::o;118055:50::-;118086:19;118055:50;:::o;118979:36::-;;;-1:-1:-1;;;;;118979:36:0;;:::o;126917:28::-;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;126917:28:0;;-1:-1:-1;126917:28:0;:::o;118185:46::-;118212:19;118185:46;:::o;119931:236::-;119983:21;120035:10;;:24;;;-1:-1:-1;;;120035:24:0;;;;119983:21;;-1:-1:-1;;;;;120035:10:0;;:22;;:24;;;;;;;;;;;;;;:10;:24;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;120035:24:0;120088:11;;:25;;;-1:-1:-1;;;120088:25:0;;;;120035:24;;-1:-1:-1;120070:15:0;;-1:-1:-1;;;;;120088:11:0;;;;:23;;:25;;;;;120035:24;;120088:25;;;;;;;;:11;:25;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;120088:25:0;;-1:-1:-1;120133:26:0;:10;120088:25;120133:26;:14;:26;:::i;:::-;120126:33;;;;119931:236;:::o;127018:39::-;;;;:::o;131342:2371::-;122155:9;:7;:9::i;:::-;122147:54;;;;;-1:-1:-1;;;122147:54:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;131863:41:::1;131877:26;131863:13;:41::i;:::-;131915:33;131929:18;131915:13;:33::i;:::-;131959:34;131973:19;131959:13;:34::i;:::-;132004:36;132018:21;132004:13;:36::i;:::-;132051:30;132065:15;132051:13;:30::i;:::-;132092:38;132106:23;132092:13;:38::i;:::-;132141:32;132155:17;132141:13;:32::i;:::-;132184;132198:17;132184:13;:32::i;:::-;132227:35;132241:20;132227:13;:35::i;:::-;132273:32;132287:17;132273:13;:32::i;:::-;132316:34;132330:19;132316:13;:34::i;:::-;132363:25;:54:::0;;-1:-1:-1;;;;;;132363:54:0;;::::1;-1:-1:-1::0;;;;;132363:54:0;;::::1;::::0;;::::1;::::0;;;-1:-1:-1;132428:44:0;;;::::1;::::0;;::::1;;::::0;;-1:-1:-1;132483:47:0;;;::::1;::::0;;::::1;;::::0;;132541:13:::1;:53:::0;;;::::1;::::0;;::::1;;::::0;;132605:14:::1;:32:::0;;;::::1;::::0;;::::1;;::::0;;132648:15:::1;:59:::0;;;::::1;::::0;;::::1;;::::0;;132718:9:::1;:41:::0;;;::::1;::::0;;::::1;;::::0;;132770:9:::1;:41:::0;;;::::1;::::0;;::::1;;::::0;;132822:12:::1;:50:::0;;;::::1;::::0;;::::1;;::::0;;132883:9:::1;:41:::0;;;::::1;::::0;;::::1;;::::0;;132935:11:::1;:47:::0;;;;::::1;::::0;;::::1;::::0;;;::::1;::::0;;133000:60:::1;::::0;;;;;;::::1;::::0;::::1;::::0;;;;;;::::1;133076:44;::::0;;-1:-1:-1;;;;;133076:44:0;::::1;::::0;;;;::::1;::::0;;;;::::1;::::0;;::::1;133136:46;::::0;;-1:-1:-1;;;;;133136:46:0;::::1;::::0;;;;::::1;::::0;;;;::::1;::::0;;::::1;133198:50;::::0;;-1:-1:-1;;;;;133198:50:0;::::1;::::0;;;;::::1;::::0;;;;::::1;::::0;;::::1;133264:38;::::0;;-1:-1:-1;;;;;133264:38:0;::::1;::::0;;;;::::1;::::0;;;;::::1;::::0;;::::1;133318:54;::::0;;-1:-1:-1;;;;;133318:54:0;::::1;::::0;;;;::::1;::::0;;;;::::1;::::0;;::::1;133388:42;::::0;;-1:-1:-1;;;;;133388:42:0;::::1;::::0;;;;::::1;::::0;;;;::::1;::::0;;::::1;133446;::::0;;-1:-1:-1;;;;;133446:42:0;::::1;::::0;;;;::::1;::::0;;;;::::1;::::0;;::::1;133504:48;::::0;;-1:-1:-1;;;;;133504:48:0;::::1;::::0;;;;::::1;::::0;;;;::::1;::::0;;::::1;133568:42;::::0;;-1:-1:-1;;;;;133568:42:0;::::1;::::0;;;;::::1;::::0;;;;::::1;::::0;;::::1;133626:46;::::0;;-1:-1:-1;;;;;133626:46:0;::::1;::::0;;;;::::1;::::0;;;;::::1;::::0;;::::1;133685:20;:18;:20::i;:::-;131342:2371:::0;;;;;;;;;;;:::o;118901:29::-;;;-1:-1:-1;;;;;118901:29:0;;:::o;125835:31::-;;;;:::o;172882:183::-;172966:36;:34;:36::i;:::-;173019:38;173047:9;173019:27;:38::i;119689:234::-;119741:21;119793:10;;:19;;;-1:-1:-1;;;119793:19:0;;;;119741:21;;-1:-1:-1;;;;;119793:10:0;;:17;;:19;;;;;;;;;;;;;;:10;:19;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;119793:19:0;119845:11;;:20;;;-1:-1:-1;;;119845:20:0;;;;119793:19;;-1:-1:-1;119823:19:0;;-1:-1:-1;;;;;119845:11:0;;;;:18;;:20;;;;;119793:19;;119845:20;;;;;;;;:11;:20;;;;;;;;;;121943:79;122008:6;;-1:-1:-1;;;;;122008:6:0;121943:79;:::o;122309:92::-;122387:6;;-1:-1:-1;;;;;122387:6:0;122373:10;:20;;122309:92::o;125997:35::-;;;;:::o;192289:289::-;192382:4;192399:36;:34;:36::i;:::-;-1:-1:-1;;;;;192461:17:0;;192446:12;192461:17;;;:6;:17;;;;;:22;:41;;192488:13;192461:41;:26;:41;:::i;126469:17::-;;;;:::o;124203:40::-;;;-1:-1:-1;;;;;124203:40:0;;:::o;123836:44::-;;;;;;;;;;;;;;-1:-1:-1;;;123836:44:0;;;;:::o;124342:33::-;;;-1:-1:-1;;;;;124342:33:0;;:::o;170170:278::-;170242:4;170260:15;170277:20;170301:34;170325:9;170301:23;:34::i;:::-;170259:76;;;;170348:9;170360:58;170390:10;170402:15;170360:29;:58::i;:::-;170348:70;170170:278;-1:-1:-1;;;;;170170:278:0:o;123939:40::-;;;-1:-1:-1;;;;;123939:40:0;;:::o;183292:108::-;183353:4;183377:15;183385:6;183377:7;:15::i;124113:36::-;;;-1:-1:-1;;;;;124113:36:0;;:::o;175114:524::-;-1:-1:-1;;;;;175341:17:0;;175245:9;175341:17;;;:6;:17;;;;;:22;;175381;;;;;175341;;175245:9;175440:35;175348:9;175440:24;:35::i;:::-;175416:59;;175505:30;175525:9;175505:19;:30::i;:::-;175486:49;-1:-1:-1;175555:31:0;:4;175564:21;175555:31;:8;:31;:::i;:::-;175548:38;-1:-1:-1;175604:26:0;:4;175613:16;175604:26;:8;:26;:::i;:::-;175597:33;;175114:524;;;;;:::o;165155:4804::-;165503:36;;:::i;:::-;-1:-1:-1;165542:212:0;;;;;;;;-1:-1:-1;165571:10:0;-1:-1:-1;;;;;165571:10:0;;;165542:212;;165571:10;165596:11;;;165542:212;;;;165622:9;;;;165542:212;;;;;;;165646:11;;;;165542:212;;;;165672:12;;;;165542:212;;;;165699:15;;;;165542:212;;;;165729:14;;;;;165542:212;;;;165765:30;;:::i;:::-;165808:48;165838:17;165808:29;:48::i;:::-;165867:30;:28;:30::i;:::-;165923:9;;;;;;;;;-1:-1:-1;;;;;165923:9:0;-1:-1:-1;;;;;165923:20:0;;:22;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;165923:22:0;165908:12;;;:37;;;165956:32;;:18;:32::i;:::-;165999:42;166029:11;165999:29;:42::i;:::-;166052:86;166088:14;:24;;;166114:10;166126:11;166052:35;:86::i;:::-;166183:21;:19;:21::i;:::-;166151:29;;;:53;;;166292:24;;;;;:46;;-1:-1:-1;;;166292:46:0;;166327:10;166292:46;;;;;;-1:-1:-1;;;;;166292:34:0;;;;;;:46;;;;;;;;;;;;;;:34;:46;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;166292:46:0;:79;;166285:87;;;;166385:34;;;166498:27;;;;166549:12;;;;166385:20;;166470:92;;166527:20;;166470:27;:92::i;:::-;166466:515;;;-1:-1:-1;166597:20:0;166466:515;;;166668:14;:27;;;-1:-1:-1;;;;;166668:35:0;;:37;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;166668:37:0;;-1:-1:-1;166773:197:0;-1:-1:-1;;;;;166780:29:0;;;;;;:83;;;118212:19;166813:44;166827:15;166844:6;:12;;;166813:13;:44::i;:::-;:50;166780:83;166773:197;;;166902:14;:27;;;-1:-1:-1;;;;;166902:35:0;;166938:15;166902:52;;;;;;;;;;;;;-1:-1:-1;;;;;166902:52:0;-1:-1:-1;;;;;166902:52:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;166902:52:0;;-1:-1:-1;166773:197:0;;;167134:19;167130:55;;-1:-1:-1;;167157:25:0;;167130:55;-1:-1:-1;;;;;167202:29:0;;;;;;:57;;-1:-1:-1;167235:20:0;;:24;;167202:57;:79;;;;;167280:1;167263:14;:18;167202:79;167195:1343;;;167298:16;;;;;;;;167440:23;167466:14;:27;;;-1:-1:-1;;;;;167466:35:0;;167502:15;167466:52;;;;;;;;;;;;;-1:-1:-1;;;;;167466:52:0;-1:-1:-1;;;;;167466:52:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;167466:52:0;167556:25;;167466:52;167583:26;;;167466:52;;-1:-1:-1;167535:92:0;;167611:15;167535:20;:92::i;:::-;167644:46;;:::i;:::-;167693:315;167738:14;167771:15;167805:6;:20;;;167844:6;:12;;;167875:27;167921;167967:26;167693;:315::i;:::-;167644:364;;168029:16;:33;;;168025:44;;;168064:5;;;;168025:44;168276:24;;168247;;;;:54;;;:28;:54;:::i;:::-;168219:24;;;;:82;;;;168364:23;;;168339:20;;;;:49;;;:24;:49;:::i;:::-;168316:20;;;:72;168453:24;;168428:20;;:50;;;:24;:50;:::i;:::-;168405:73;;-1:-1:-1;168511:15:0;-1:-1:-1;167195:1343:0;;;168579:1;168556:6;:20;;;:24;168548:78;;;;-1:-1:-1;;;168548:78:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;168850:96;168880:6;:20;;;168902:6;:12;;;168916:6;:29;;;168850;:96::i;:::-;;169009:39;169027:6;:20;;;169009:17;:39::i;:::-;168993:13;;;:55;;;169099:20;;;;169061:78;;168993:55;169121:17;169061:22;:78::i;:::-;169210:14;:25;;;-1:-1:-1;;;;;169210:33:0;;169252:14;:26;;;169281:6;:13;;;169210:85;;;;;;;;;;;;;-1:-1:-1;;;;;169210:85:0;-1:-1:-1;;;;;169210:85:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;169306:14;:26;;;-1:-1:-1;;;;;169306:40:0;;169347:6;:13;;;169306:55;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;169428:13:0;;;;169403:20;;;;:39;;:24;:39::i;:::-;169374:6;:26;;:68;;;;;169460:86;169471:11;169484:6;:24;;;169510:6;:20;;;169532:6;:13;;;169460:86;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;169660:14;:24;;;-1:-1:-1;;;;;169660:29:0;;169690:10;169702:6;:24;;;169660:67;;;;;;;;;;;;;-1:-1:-1;;;;;169660:67:0;-1:-1:-1;;;;;169660:67:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;169799:14;:25;;;-1:-1:-1;;;;;169799:42:0;;169842:6;:24;;;169799:68;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;169878:25:0;;169924:26;;;;169878:73;;;-1:-1:-1;;;169878:73:0;;169912:10;169878:73;;;;;;;;;;;;-1:-1:-1;;;;;169878:33:0;;;;-1:-1:-1;169878:33:0;;-1:-1:-1;169878:73:0;;;;;:25;;:73;;;;;;;;:25;:33;:73;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;165155:4804;;;;;;;;;;:::o;125710:23::-;;;;:::o;124869:47::-;124909:7;124869:47;:::o;185487:143::-;185555:4;185579:43;185599:22;:20;:22::i;:::-;185579:19;:43::i;124572:61::-;124615:18;124572:61;:::o;179605:174::-;179673:36;:34;:36::i;:::-;179727:44;179739:9;179750:20;179727:11;:44::i;170605:290::-;170690:4;170708:15;170725:20;170749:34;170773:9;170749:23;:34::i;:::-;170707:76;;;;170796:8;170807:59;170830:10;170842:15;170859:6;170807:22;:59::i;125283:32::-;;;;:::o;191992:289::-;192085:4;192102:36;:34;:36::i;:::-;-1:-1:-1;;;;;192164:17:0;;192149:12;192164:17;;;:6;:17;;;;;:22;;;:41;;192191:13;192164:41;:26;:41;:::i;186039:174::-;186122:4;186146:59;186165:28;:26;:28::i;:::-;186195:9;186146:18;:59::i;191169:127::-;-1:-1:-1;;;;;191266:17:0;191242:4;191266:17;;;:6;:17;;;;;:22;;191169:127::o;133868:137::-;133951:7;133978:11;133990:6;133978:19;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;133978:19:0;;133868:137;-1:-1:-1;;133868:137:0:o;126493:22::-;;;;:::o;174513:497::-;174589:4;174906:13;-1:-1:-1;;;;;174878:17:0;;;;;;:6;:17;;;;;:24;;;;;:41;;;;;;;;;174874:62;;-1:-1:-1;174929:5:0;174922:12;;174874:62;-1:-1:-1;174996:5:0;;-1:-1:-1;;;;;174963:26:0;;;;;;:15;:26;;;;;:30;:38;174513:497;;;:::o;173981:524::-;-1:-1:-1;;;;;174105:26:0;;174064:4;174105:26;;;:15;:26;;;;;:35;;;174178:10;;174064:4;;174178:32;;174105:35;174178:32;:14;:32;:::i;186593:118::-;186651:4;186675:28;186694:8;;186675:18;:28::i;175646:154::-;175715:36;:34;:36::i;:::-;175769:23;175782:9;175769:12;:23::i;189081:190::-;189174:25;;-1:-1:-1;;;;;189174:25:0;189160:10;:39;189152:111;;;;-1:-1:-1;;;189152:111:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;189081:190::o;171650:1134::-;171775:28;171793:9;171775:17;:28::i;:::-;171771:1006;;;171820:32;171842:9;171820:21;:32::i;:::-;171909:21;171933:30;171953:9;171933:19;:30::i;:::-;171909:54;;171978:26;172007:35;172032:9;172007:24;:35::i;:::-;-1:-1:-1;;;;;172139:17:0;;;;;;:6;:17;;;;;:22;;;171978:64;;-1:-1:-1;172139:44:0;;172166:16;172139:44;:26;:44;:::i;:::-;-1:-1:-1;;;;;172114:17:0;;;;;;:6;:17;;;;;:22;;;:69;;;;172223:22;:49;;172250:21;172223:49;:26;:49;:::i;:::-;-1:-1:-1;;;;;172198:17:0;;;;;;:6;:17;;;;;:74;172289:38;172205:9;172289:27;:38::i;:::-;172400:104;172437:11;172450:12;172464:21;172487:16;172400:36;:104::i;:::-;-1:-1:-1;;;;;172526:239:0;;172585:17;;;;:6;:17;;;;;;;;:22;;172626;;;;172667:23;;;;;172526:239;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;172526:239:0;;;;;;;;171771:1006;;;171650:1134;;;:::o;28462:136::-;28520:7;28547:43;28551:1;28554;28547:43;;;;;;;;;;;;;;;;;:3;:43::i;:::-;28540:50;28462:136;-1:-1:-1;;;28462:136:0:o;181658:626::-;182049:11;:27;;;;;;;;-1:-1:-1;182049:27:0;;;;;;;;;-1:-1:-1;;;;;;182049:27:0;-1:-1:-1;;;;;182049:27:0;;;;;182178:18;;-1:-1:-1;;182178:25:0;;:18;:22;:25::i;:::-;-1:-1:-1;;;;;182215:17:0;;;;;;;;:6;:17;;;;;:28;;:36;;-1:-1:-1;;;;;;182215:36:0;;-1:-1:-1;;;;;182215:36:0;;;;;;-1:-1:-1;182215:36:0;181658:626::o;176365:390::-;-1:-1:-1;;;;;176488:17:0;;176438:4;176488:17;;;:6;:17;;;;;:22;;;176438:4;;176471:40;;:16;:40::i;:::-;-1:-1:-1;;;;;176538:17:0;;176522:13;176538:17;;;:6;:17;;;;;:23;;;;176572:34;;;;176633:11;;176455:56;;-1:-1:-1;176538:23:0;176633:39;;176455:56;;176633:25;;176538:23;176633:25;:15;:25;:::i;:::-;:29;:39;:29;:39;:::i;:::-;176619:11;:53;;;176688:31;;;;;;;;;;;;;;;;-1:-1:-1;176739:8:0;176365:390;-1:-1:-1;;176365:390:0:o;120474:144::-;120538:4;120555:8;120566:15;120574:6;120566:7;:15::i;:::-;118411:19;-1:-1:-1;;120474:144:0;-1:-1:-1;;;120474:144:0:o;152722:2666::-;152982:31;;:::i;:::-;153031:46;;:::i;:::-;153088:42;;:::i;:::-;153143:46;;;:28;153200:21;;;:29;153264:21;:19;:21::i;:::-;153240;;;:45;153320:21;:19;:21::i;:::-;153296;;;:45;153368:1;153359:6;;;:10;153354:2027;153380:11;:18;153371:4;:6;;;:27;153354:2027;;;153437:11;153449:4;:6;;;153437:19;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;153425:31:0;:9;;;:31;;;153514:17;;;;:6;:17;;;;;;:24;;;153542:13;;153514:24;;:41;;;;;;;;;153510:60;;153559:8;;153510:60;153595:32;153609:4;:9;;;153620:6;153595:13;:32::i;:::-;153584:8;;;:43;153649:21;;;;153644:1679;;118212:19;153788:4;:8;;;:15;;:52;;;;-1:-1:-1;153807:28:0;;:33;153788:52;153784:71;;;153844:8;;153784:71;153875:8;153886:76;153909:4;:21;;;153932:4;:21;;;153955:6;153886:22;:76::i;:::-;153875:87;;154003:113;154026:11;154039:12;154053:4;:9;;;154064:4;:8;;;154074:4;:28;;;154104:3;154109:6;154003:22;:113::i;:::-;154247:30;;;;154214:28;;153983:133;;-1:-1:-1;154214:64:0;;:28;:64;:32;:64;:::i;:::-;154183:95;;154347:30;;;;154321:21;;;;:57;;;:25;:57;:::i;:::-;154297:4;:21;;:81;;;;;154421:92;154483:17;:29;;;154421:57;154447:17;:30;;;154421:4;:21;;;:25;;:57;;;;:::i;:92::-;154397:21;;;:116;154621:56;154651:6;154659:17;154621:29;:56::i;:::-;154612:65;;154723:81;154751:4;:21;;;154774:4;:21;;;154797:6;154723:27;:81::i;:::-;154722:82;154698:21;;;:106;-1:-1:-1;153644:1679:0;;;154845:4;:21;;;:39;;;;;118212:19;154870:4;:8;;;:14;154845:39;154841:482;;;154925:88;154946:11;154959:12;154973:4;:9;;;154984:4;:28;;;154925:20;:88::i;:::-;155096:30;;;;155063:28;;154905:108;;-1:-1:-1;155063:64:0;;:28;:64;:32;:64;:::i;:::-;155032:95;;155235:56;155265:6;155273:17;155235:29;:56::i;:::-;155226:65;;154841:482;153400:6;;;:8;;;;;;153354:2027;;;152722:2666;;;;;;;;;:::o;155396:1115::-;155655:31;;:::i;:::-;155704:46;;:::i;:::-;155761:42;;:::i;:::-;155816:46;;;:28;155880:6;;;:10;155875:629;155901:11;:18;155892:4;:6;;;:27;155875:629;;;155958:11;155970:4;:6;;;155958:19;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;155946:31:0;:9;;;:31;;;156003:32;;156028:6;156003:13;:32::i;:::-;155992:8;;;:43;;;118212:19;-1:-1:-1;156052:441:0;;;156111:88;156132:11;156145:12;156159:4;:9;;;156170:4;:28;;;156111:20;:88::i;:::-;156282:30;;;;156249:28;;156091:108;;-1:-1:-1;156249:64:0;;:28;:64;:32;:64;:::i;:::-;156218:95;;156421:56;156451:6;156459:17;156421:29;:56::i;:::-;156412:65;;156052:441;155921:6;;;:8;;;;;;155875:629;;177612:1985;177746:10;177742:27;;177760:7;;177742:27;178600;;178547:17;;178567:61;;:28;:5;26941:4;178567:28;:9;:28;:::i;:61::-;178547:81;;178639:22;178664:66;178697:32;;178664:28;26941:4;178664:5;:9;;:28;;;;:::i;:66::-;178639:91;;178785:27;178815:29;178832:11;;178815:12;:16;;:29;;;;:::i;:::-;178785:59;;178855:32;178890:34;178912:11;;178890:17;:21;;:34;;;;:::i;:::-;178855:69;;178967:57;178984:39;179011:11;;178984:22;:26;;:39;;;;:::i;:::-;178967:12;;:57;:16;:57;:::i;:::-;178937:27;:87;179124:11;;179070:67;;179092:44;;:27;;:44;:31;:44;:::i;:::-;179070:17;;:67;:21;:67;:::i;:::-;179035:32;:102;179218:5;;:33;;179228:22;179218:33;:9;:33;:::i;:::-;179210:5;:41;179275:10;;:43;;179290:27;179275:43;:14;:43;:::i;:::-;179262:10;:56;;;179350:5;;179336:32;;;;;;;;;;;;;;;;;;;;;;;;;;179447:11;-1:-1:-1;;;;;179447:28:0;;179476:5;179447:35;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;179493:12;-1:-1:-1;;;;;179493:29:0;;179523:5;179493:36;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;179540:11;-1:-1:-1;;;;;179540:19:0;;179568:12;179583:5;179540:49;;;;;;;;;;;;;-1:-1:-1;;;;;179540:49:0;-1:-1:-1;;;;;179540:49:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;177612:1985;;;;;;;;;:::o;180892:437::-;181033:11;;181011:19;:33;;;;181057:15;181075:11;-1:-1:-1;;;;;181075:18:0;;:20;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;181075:20:0;181128:11;;:20;;;-1:-1:-1;;;181128:20:0;;;;181075;;-1:-1:-1;181106:19:0;;-1:-1:-1;;;;;181128:11:0;;;;:18;;:20;;;;;181075;;181128;;;;;;;;:11;:20;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;181128:20:0;;-1:-1:-1;181185:50:0;181128:20;181185:30;:10;181200:14;181185:30;:14;:30;:::i;:50::-;181159:23;:76;;;181276:19;;181253:68;;;;;;;;;;;;;;;;;;;;;;;;;;180892:437;;;;:::o;157896:319::-;158019:9;;158015:102;;158045:9;;158070:14;;158045:60;;;-1:-1:-1;;;158045:60:0;;-1:-1:-1;;;;;158070:14:0;;;158045:60;;;;;;;;;;;;;;;;;;;:9;;;;;:24;;:60;;;;;:9;;:60;;;;;;;:9;;:60;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;158015:102;158133:8;;158129:79;;158158:11;-1:-1:-1;;;;;158158:19:0;;158178:11;158191:4;158158:38;;;;;;;;;;;;;-1:-1:-1;;;;;158158:38:0;-1:-1:-1;;;;;158158:38:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;157896:319;;;;:::o;185638:237::-;185706:4;185730:137;185761:35;185786:9;124704:4;26941;124684:24;;124711:1;124684:28;185761:24;;:35;;;;:::i;:::-;26941:4;185730:16;:137::i;189279:184::-;189390:13;-1:-1:-1;;;;;189362:17:0;;;;;;:6;:17;;;;;:24;;;;;:41;;;;;;;;;189354:101;;;;-1:-1:-1;;;189354:101:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;187423:171;187510:4;187534:52;26941:4;187534:29;:14;187553:9;187534:29;:18;:29;:::i;29378:471::-;29436:7;29681:6;29677:47;;-1:-1:-1;29711:1:0;29704:8;;29677:47;29748:5;;;29752:1;29748;:5;:1;29772:5;;;;;:10;29764:56;;;;-1:-1:-1;;;29764:56:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30317:132;30375:7;30402:39;30406:1;30409;30402:39;;;;;;;;;;;;;;;;;:3;:39::i;188570:284::-;188625:4;188642:18;188663:30;:28;:30::i;:::-;188642:51;;188704:16;188723:55;124615:18;188764:13;188723:19;:55::i;:::-;188704:74;;188798:48;26941:4;188798:25;188811:11;188798:8;;:12;;:25;;;;:::i;188268:294::-;188320:15;188338:41;188358:20;;188338:15;:19;;:41;;;;:::i;:::-;188320:59;;124463:2;188396:10;:35;188392:163;;188471:15;188448:20;:38;;;188506:37;;;;;;;;;;;;;;;;188268:294;:::o;145956:2883::-;146183:31;;:::i;:::-;146232:46;;:::i;:::-;146289:42;;:::i;:::-;146344:46;;;:28;146401:21;;;:29;146465:21;:19;:21::i;:::-;146441;;;:45;146521:21;:19;:21::i;:::-;146497:4;:21;;:45;;;;;146567:15;:28;;;-1:-1:-1;;;;;146567:36:0;;:38;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;146567:38:0;-1:-1:-1;;;;;146555:50:0;;;:9;;;:50;146636:28;;;;:39;;;-1:-1:-1;;;146636:39:0;;;;146616:17;;146636:37;;;;;;;:39;;;;;146567:38;;146636:39;;;;;;;;:37;:39;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;146636:39:0;146700:1;146636:39;146691:6;;:10;146636:39;-1:-1:-1;146686:2146:0;146712:2;146703:4;:6;;;:11;:37;;;;;146731:9;-1:-1:-1;;;;;146718:22:0;:4;:9;;;-1:-1:-1;;;;;146718:22:0;;;146703:37;146686:2146;;;146855:16;146874:15;:28;;;-1:-1:-1;;;;;146874:36:0;;146911:4;:9;;;146874:47;;;;;;;;;;;;;-1:-1:-1;;;;;146874:47:0;-1:-1:-1;;;;;146874:47:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;146874:47:0;146963:9;;;;146874:47;;-1:-1:-1;146949:32:0;;146974:6;146949:13;:32::i;:::-;146938:8;;;:43;147003:21;;;;146998:1731;;118212:19;147139:4;:8;;;:15;;:52;;;;-1:-1:-1;147158:28:0;;:33;147139:52;147135:68;;;147195:5;;;147135:68;147223:8;147234:76;147257:4;:21;;;147280:4;:21;;;147303:6;147234:22;:76::i;:::-;147374:26;;147402:27;;;;147431:9;;;;147442:8;;;;147452:28;;147223:87;;-1:-1:-1;147351:143:0;;147223:87;147487:6;147351:22;:143::i;:::-;147625:30;;;;147592:28;;147331:163;;-1:-1:-1;147592:64:0;;:28;:64;:32;:64;:::i;:::-;147561:95;;147725:30;;;;147699:21;;;;:57;;;:25;:57;:::i;:::-;147675:4;:21;;:81;;;;;147799:92;147861:17;:29;;;147799:57;147825:17;:30;;;147799:4;:21;;;:25;;:57;;;;:::i;:92::-;147775:21;;;:116;147999:56;148029:6;148037:17;147999:29;:56::i;:::-;147990:65;;148101:81;148129:4;:21;;;148152:4;:21;;;148175:6;148101:27;:81::i;:::-;148100:82;148076:21;;;:106;-1:-1:-1;146998:1731:0;;;148221:4;:21;;;:39;;;;;118212:19;148246:4;:8;;;:14;148221:39;148217:512;;;148301:118;148322:15;:26;;;148350:15;:27;;;148379:4;:9;;;148390:4;:28;;;148301:20;:118::i;:::-;148504:30;;;;148471:28;;148281:138;;-1:-1:-1;148471:64:0;;:28;:64;:32;:64;:::i;:::-;148440:95;;148643:56;148673:6;148681:17;148643:29;:56::i;:::-;148634:65;;148217:512;;;148724:5;;;148217:512;-1:-1:-1;;;;;148800:20:0;:9;;;:20;146742:6;;;:8;;;;;;146686:2146;;;145956:2883;;;;;;;;;:::o;148847:1224::-;149094:31;;:::i;:::-;149143:46;;:::i;:::-;149200:42;;:::i;:::-;149288:12;;149313:46;;;149253:32;149377:6;;;:10;-1:-1:-1;;;;;149288:12:0;149372:692;149398:2;149389:4;:6;;;:11;149372:692;;;149439:18;-1:-1:-1;;;;;149439:26:0;;:28;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;149439:28:0;-1:-1:-1;;;;;149427:40:0;:9;;;:40;;;149493:32;;149518:6;149493:13;:32::i;:::-;149482:8;;;:43;;;118212:19;-1:-1:-1;149542:456:0;;;149601:88;149622:11;149635:12;149649:4;:9;;;149660:4;:28;;;149601:20;:88::i;:::-;149774:30;;;;149741:28;;149581:108;;-1:-1:-1;149741:64:0;;:28;:64;:32;:64;:::i;:::-;149710:95;;149913:56;149943:6;149951:17;149913:29;:56::i;:::-;149904:65;;149542:456;;;149993:5;;149542:456;149402:6;;;:8;;;;;;149372:692;;;148847:1224;;;;;;;;;;:::o;186868:207::-;186935:4;186959:108;186990:34;187014:9;118876:4;26941;118856:24;;186990:34;124768:27;186959:16;:108::i;28006:181::-;28064:7;28096:5;;;28120:6;;;;28112:46;;;;;-1:-1:-1;;;28112:46:0;;;;;;;;;;;;;;;;;;;;;;;;;;;123318:337;-1:-1:-1;;;;;123392:22:0;;123384:65;;;;;-1:-1:-1;;;123384:65:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;123561:21;;123602:8;123594:53;;;;;-1:-1:-1;;;123594:53:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;122853:133;122929:6;;122908:40;;122945:1;;-1:-1:-1;;;;;122929:6:0;;122908:40;;122945:1;;122908:40;122959:6;:19;;-1:-1:-1;;;;;;122959:19:0;;;122853:133::o;173073:237::-;173182:5;;;-1:-1:-1;;;;;173149:26:0;;;;;;:15;:26;;;;;;;;;:38;;;173236:10;;173198:35;;;;:48;;;173284:5;;173262:40;;;;;;;;;;;;;;;;;;;;;;;;173073:237;:::o;170903:442::-;170978:4;170984;171001:21;171025:30;171045:9;171025:19;:30::i;:::-;171001:54;;171066:26;171095:35;171120:9;171095:24;:35::i;:::-;-1:-1:-1;;;;;171161:17:0;;171143:15;171161:17;;;:6;:17;;;;;:22;;;171066:64;;-1:-1:-1;171143:15:0;171161:44;;171188:16;171161:44;:26;:44;:::i;:::-;-1:-1:-1;;;;;171239:17:0;;171216:20;171239:17;;;:6;:17;;;;;:22;171143:62;;-1:-1:-1;171216:20:0;171239:49;;171266:21;171239:49;:26;:49;:::i;:::-;171309:10;;-1:-1:-1;171216:72:0;;-1:-1:-1;;;;170903:442:0;;;:::o;115245:366::-;115319:4;115340:9;;115336:268;;115373:36;115403:5;115373:25;:5;112757:4;115373:25;:9;:25;:::i;:36::-;115366:43;;;;115336:268;-1:-1:-1;;;115575:17:0;;120175:291;120228:8;120249:21;120273;:19;:21::i;:::-;120249:45;;120305:21;120329;:19;:21::i;:::-;120305:45;;120369:66;120392:16;120410;120428:6;120369:22;:66::i;:::-;120363:72;120175:291;-1:-1:-1;;;;120175:291:0:o;190585:253::-;124684:28;190681:41;;;;;:83;;;26941:4;190726:17;:38;;190681:83;190673:157;;;;-1:-1:-1;;;190673:157:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;190293:284;190386:9;;:34;;;-1:-1:-1;;;190386:34:0;;;;190358:25;;-1:-1:-1;;;;;190386:9:0;;:32;;:34;;;;;;;;;;;;;;:9;:34;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;190386:34:0;;-1:-1:-1;190458:42:0;190386:34;124909:7;190458:42;:24;:42;:::i;:::-;190439:15;:61;;190431:138;;;;-1:-1:-1;;;190431:138:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;190134:151;118212:19;190208:15;190216:6;190208:7;:15::i;:::-;:22;;190200:77;;;;-1:-1:-1;;;190200:77:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;189970:156;190066:1;190056:7;:11;190048:70;;;;-1:-1:-1;;;190048:70:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;189471:267;189640:7;189605:10;-1:-1:-1;;;;;189605:20:0;;189626:9;189605:31;;;;;;;;;;;;;-1:-1:-1;;;;;189605:31:0;-1:-1:-1;;;;;189605:31:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;189605:31:0;:42;;189597:133;;;;-1:-1:-1;;;189597:133:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;162636:532;162768:4;-1:-1:-1;;;;;162789:34:0;;;;:96;;;162841:13;-1:-1:-1;;;;;162841:22:0;;162864:20;162841:44;;;;;;;;;;;;;-1:-1:-1;;;;;162841:44:0;-1:-1:-1;;;;;162841:44:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;162841:44:0;162840:45;162789:96;:162;;;;118212:19;162902:43;162916:20;162938:6;162902:13;:43::i;:::-;:49;162789:162;162785:217;;;-1:-1:-1;162985:5:0;162978:12;;162785:217;163014:17;163034:13;-1:-1:-1;;;;;163034:21:0;;163056:20;163034:43;;;;;;;;;;;;;-1:-1:-1;;;;;163034:43:0;-1:-1:-1;;;;;163034:43:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;163034:43:0;;-1:-1:-1;;;;;;163095:23:0;;;;:65;;;118212:19;163122:32;163136:9;163147:6;163122:13;:32::i;:::-;:38;163088:72;162636:532;-1:-1:-1;;;;;162636:532:0:o;158781:2702::-;159113:46;;:::i;:::-;-1:-1:-1;;;;;159371:17:0;;;;;;:6;:17;;;;;:22;159338:83;;159355:14;;159371:49;;118558:6;159371:49;:26;:49;:::i;:::-;159338:16;:83::i;:::-;159311:110;;;159514:59;;159566:6;;159514:47;;26941:4;159514:47;:28;:47;:::i;:59::-;159488:23;;;;:85;;;;159752:24;;-1:-1:-1;;;;;159724:17:0;;159708:12;159724:17;;;:6;:17;;;;;;:22;159723:54;;;:28;:54;:::i;:::-;159832:23;;;;;-1:-1:-1;;;;;159804:17:0;;159788:12;159804:17;;;:6;:17;;;;;;:22;;;159708:69;;-1:-1:-1;159788:12:0;;159803:53;;;:28;:53;:::i;:::-;159788:68;;118558:6;159873:7;:32;159869:1571;;;160034:23;160047:9;160034:12;:23::i;:::-;160072:49;160084:9;160095:25;160072:11;:49::i;:::-;160136:77;160154:15;160171:9;118558:6;160205:7;160136:17;:77::i;:::-;160246:9;-1:-1:-1;;;;;160233:72:0;-1:-1:-1;;;;;;;;;;;160257:1:0;160260;160263;160266:38;160233:72;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;159869:1571;;;160340:12;160355:47;160385:7;160394;160355:29;:47::i;:::-;160340:62;;160754:26;160743:7;:37;;:76;;;;118667:7;160784:20;160796:7;160784:11;:20::i;:::-;:35;160743:76;160739:199;;;-1:-1:-1;;160876:4:0;160840:33;;;:40;-1:-1:-1;160899:23:0;;160739:199;160954:28;;;;:115;;;-1:-1:-1;;;160954:115:0;;-1:-1:-1;;;;;160954:115:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:37;;;;;;;:115;;;;;-1:-1:-1;;160954:115:0;;;;;;;-1:-1:-1;160954:37:0;:115;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;;;161086:17:0;;;;;;:6;:17;;;;;:32;;;161133:22;;:32;;;-1:-1:-1;161180:37:0;161093:9;161180:26;:37::i;:::-;-1:-1:-1;;;;;;161239:189:0;;161333:17;;;;:6;:17;;;;;;;;;:23;;;161239:189;;;;;;;;;;;;;;;161375:38;161239:189;;;;;;-1:-1:-1;;;;;;;;;;;161239:189:0;;;;;;;;159869:1571;;-1:-1:-1;;158781:2702:0;;;;;;;;;;:::o;184338:1013::-;184448:4;184465:20;184488:22;:20;:22::i;:::-;184465:45;-1:-1:-1;184697:25:0;184725:43;184751:16;184725:21;:9;184739:6;184725:21;:13;:21;:::i;:43::-;184697:71;-1:-1:-1;184781:16:0;184800:51;184820:30;184697:71;125160:1;184820:30;:24;:30;:::i;:::-;184800:15;;:51;:19;:51;:::i;:::-;184781:70;;184876:48;184893:11;26941:4;184876:16;:48::i;:::-;184862:62;;185092:1;185078:11;:15;185071:23;;;;185203:8;:22;;;185241:28;;;;;;;;;;;;;;;;;185290:22;:20;:22::i;185883:148::-;185949:4;185973:50;185992:19;:17;:19::i;120626:262::-;120732:18;120753:40;120785:7;120753:27;:4;26941;120753:27;:8;:27;:::i;:40::-;120732:61;;120829:17;120812:13;:34;;120804:76;;;;;-1:-1:-1;;;120804:76:0;;;;;;;;;;;;;;;;;;;;;;;;;;;179787:621;179891:18;179875:12;:34;;;;;;;;;;:67;;;;-1:-1:-1;179929:13:0;179913:12;:29;;;;;;;;;;179875:67;179868:75;;;;179986:11;:18;180015:56;179986:18;180015:32;:56::i;:::-;-1:-1:-1;;;;;180084:17:0;;;;;;:6;:17;;;;;:24;;:39;;180111:12;;180084:24;-1:-1:-1;;180084:39:0;;180111:12;180084:39;;;;;;;;;;;;-1:-1:-1;;;;;;180134:17:0;;180159:1;180134:17;;;:6;:17;;;;;;;;:22;;;;:26;;;180171;;;;180210:15;:26;;;;;:34;;;180255:35;:39;180307:52;180141:9;180336:22;180307:17;:52::i;:::-;180370:12;;:30;;;-1:-1:-1;;;180370:30:0;;-1:-1:-1;;;;;180370:30:0;;;;;;;;;:12;;;;;:19;;:30;;;;;:12;;:30;;;;;;;:12;;:30;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;179787:621;;;:::o;115619:414::-;115699:4;115720:9;;115716:310;;115746:17;115766:28;115788:5;115766:17;:5;115776:6;115766:17;:9;:17;:::i;:28::-;115746:48;-1:-1:-1;115811:19:0;;-1:-1:-1;115811:19:0;115716:310;-1:-1:-1;;;115996:17:0;;186221:322;186310:4;;186348:53;26941:4;186348:30;:15;186368:9;186348:30;:19;:30;:::i;:53::-;186327:74;;186436:9;186420:13;:25;186412:92;;;;-1:-1:-1;;;186412:92:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;175891:190;-1:-1:-1;;;;;175965:17:0;;175952:10;175965:17;;;:6;:17;;;;;:23;;;176013:11;;:22;;175965:23;176013:22;:15;:22;:::i;:::-;175999:11;:36;-1:-1:-1;;;;;;176046:17:0;176072:1;176046:17;;;:6;:17;;;;;:23;;:27;175891:190::o;158343:280::-;158484:12;-1:-1:-1;;;;;158484:29:0;;158514:5;158484:36;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;158531:11;-1:-1:-1;;;;;158531:28:0;;158560:5;158531:35;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;158577:12;-1:-1:-1;;;;;158577:32:0;;158610:4;158577:38;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;28935:192;29021:7;29057:12;29049:6;;;;29041:29;;;;-1:-1:-1;;;29041:29:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;29093:5:0;;;28935:192::o;176885:719::-;176946:4;176963:10;176988:23;;177015:1;176988:28;176984:590;;;-1:-1:-1;177041:5:0;176984:590;;;177478:1;177456:19;;:23;177449:31;;;;177503:59;177538:23;;177503:30;177513:19;;177503:5;:9;;:30;;;;:::i;136172:4394::-;136438:42;;:::i;:::-;136498:55;;:::i;:::-;136568:11;:18;136590:1;-1:-1:-1;136564:56:0;;-1:-1:-1;136594:24:0;;136564:56;136811:31;136832:9;136811:20;:31::i;:::-;136785:22;;;136663:179;136708:33;136752:22;;;136663:179;;;;136708:33;;136663:179;;;;;;136895:58;;:23;:58::i;:::-;136855:37;;;:98;;;118558:6;136964:37;;;:61;137059:33;;;;:76;;;:37;:76;:::i;:::-;137036:99;;118086:19;137235:15;;137231:3291;;137267:111;137304:11;137317:12;137331:4;:22;;;137355:4;:22;;;137267:36;:111::i;:::-;137393:23;137406:9;137393:12;:23::i;:::-;137477:1;137444:30;;;:34;;;137493:32;;;:36;137583:33;;137544:36;;;:72;137670:20;;137631:36;;;:59;137707:50;137719:9;137730:26;137707:11;:50::i;:::-;137793:9;-1:-1:-1;;;;;137777:143:0;-1:-1:-1;;;;;;;;;;;137804:17:0;:33;;;137839:17;:33;;;137874:45;137777:143;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;137953:9;-1:-1:-1;;;;;137940:79:0;-1:-1:-1;;;;;;;;;;;137964:1:0;137967;137970;137973:45;137940:79;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;137231:3291;;;118086:19;138148:4;:14;138147:32;;;;;118212:19;138168:4;:10;138147:32;138143:2379;;;138197:111;138234:11;138247:12;138261:4;:22;;;138285:4;:22;;;138197:36;:111::i;:::-;138323:23;138336:9;138323:12;:23::i;:::-;138579:33;;138614:20;;138547:105;;138579:33;138636:15;138547:31;:105::i;:::-;138507:36;;;138363:289;138456:36;;;138363:289;138409:32;;;138363:289;138364:30;;;138363:289;138669:50;138681:9;138692:26;138669:11;:50::i;138143:2379::-;118212:19;139399:4;:11;;139398:30;;;;;139423:4;139416;:11;139398:30;:88;;;;-1:-1:-1;139433:33:0;;:52;-1:-1:-1;139433:52:0;139398:88;139394:1128;;;139503:111;139540:11;139553:12;139567:4;:22;;;139591:4;:22;;;139503:36;:111::i;:::-;139636:20;139629:28;;;;139674:23;139687:9;139674:12;:23::i;:::-;139732:98;139753:17;:33;;;139788:17;:33;;;139823:6;139732:20;:98::i;:::-;139712:118;;139847:50;139859:9;139870:26;139847:11;:50::i;:::-;139916:29;;;;:33;139912:146;;139970:15;;140012:29;;;;139970:72;;;-1:-1:-1;;;139970:72:0;;-1:-1:-1;;;;;139970:72:0;;;;;;;;;;;;;;;;:15;;;;;:30;;:72;;;;;:15;;:72;;;;;;;:15;;:72;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;139912:146;140095:9;-1:-1:-1;;;;;140079:140:0;-1:-1:-1;;;;;;;;;;;140106:17:0;:33;;;140141:17;:30;;;140173:45;140079:140;;;;;;;;;;;;;;;;;;;;;139394:1128;140447:33;;:::i;:::-;140502:8;-1:-1:-1;140495:15:0;;-1:-1:-1;140495:15:0;139394:1128;-1:-1:-1;136172:4394:0;;;;;;;;;:::o;156566:1322::-;156712:34;;:::i;:::-;156907:37;;;;;156868:34;;;;:77;;;:38;:77;:::i;:::-;156831:34;;;:114;157032:37;;;;;156993:34;;;;:77;;;:38;:77;:::i;:::-;156956:34;;;:114;157147:33;;157113:29;;;;:68;;;:33;:68;:::i;:::-;157081:29;;;;:100;;;;157258:33;;;157224:29;;:68;;;:33;:68;:::i;:::-;157192:100;;157365:30;;;;;157333:27;;;;:63;;;:31;:63;:::i;:::-;157303:27;;;:93;157473:32;;;;157439:29;;;;:67;;;:33;:67;:::i;:::-;157407:29;;;:99;157591:36;;;;157553:33;;;;:75;;;:37;:75;:::i;:::-;157517:33;;;:111;157713:36;;;;157675:33;;;;:75;;;:37;:75;:::i;:::-;157639:33;;;:111;157821:29;;;;157790:26;;;;:61;;;:30;:61;:::i;:::-;157761:26;;;:90;156566:1322;;;;:::o;183676:316::-;183854:4;183876:8;183887:68;183910:17;183929;183948:6;183887:22;:68::i;:::-;118411:19;-1:-1:-1;;183676:316:0;-1:-1:-1;;;;;183676:316:0:o;134516:1601::-;134718:42;;:::i;:::-;134778:55;;:::i;:::-;134994:31;135015:9;134994:20;:31::i;:::-;134968:22;;;134846:179;;;134891:33;134935:22;;;134846:179;;;134891:33;;134846:179;;;;;;;135102:22;;135126;;135038:111;;135075:11;;135088:12;;135102:22;135038:36;:111::i;:::-;135160:23;135173:9;135160:12;:23::i;:::-;135236:58;135260:17;:33;;;135236:23;:58::i;:::-;135196:37;;;:98;;;118558:6;135305:37;;;:61;135400:33;;;;-1:-1:-1;;135400:76:0;;:33;:76;:37;:76;:::i;:::-;135377:99;;135661:100;135693:17;:33;;;135728:15;135745;135661:31;:100::i;:::-;135621:36;;;135489:272;135574:36;;;135489:272;135531:32;;;135489:272;135490:30;;;135489:272;135774:50;135786:9;135797:26;135774:11;:50::i;:::-;135856:9;-1:-1:-1;;;;;135840:141:0;-1:-1:-1;;;;;;;;;;;135867:17:0;:33;;;135902:17;:33;;;135937:43;135840:141;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;136010:9;-1:-1:-1;;;;;135997:77:0;-1:-1:-1;;;;;;;;;;;136021:1:0;136024;136027;136030:43;135997:77;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;134516:1601:0;;;;;;:::o;112770:106::-;112825:4;112855:2;112850;:7;112849:19;;112866:2;112849:19;;;-1:-1:-1;112861:2:0;;112770:106;-1:-1:-1;112770:106:0:o;30979:345::-;31065:7;31167:12;31160:5;31152:28;;;;-1:-1:-1;;;31152:28:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;31191:9;31207:1;31203;:5;;;;;;;30979:345;-1:-1:-1;;;;;30979:345:0:o;188862:165::-;188925:4;188949:70;124463:2;188950:41;188970:20;;188950:15;:19;;:41;;;;:::i;114389:699::-;114456:4;114497:9;114486:8;:20;114482:49;;;114520:9;114509:20;;114482:49;114577:13;114573:46;;-1:-1:-1;112199:4:0;114593:24;;114573:46;112199:4;114677:5;114702:8;114762:289;114773:1;114769;:5;114762:289;;;114799:1;114795;:5;114791:249;;114830:12;114837:1;114840;114830:6;:12::i;:::-;114826:16;-1:-1:-1;114865:8:0;:1;114871;114865:8;:5;:8;:::i;:::-;114861:12;;114791:249;;;114937:12;114944:1;114947;114937:6;:12::i;:::-;114933:16;;114972:12;114979:1;114982;114972:6;:12::i;:::-;114968:16;-1:-1:-1;115007:17:0;115022:1;115008:8;:1;115014;115008:8;:5;:8;:::i;115007:17::-;115003:21;;114791:249;114762:289;;;115070:12;115077:1;115080;115070:6;:12::i;162090:538::-;162218:25;;;;;162249:14;;162218:53;;-1:-1:-1;;;162218:53:0;;-1:-1:-1;;;;;162249:14:0;;;162218:53;;;;;;;;;;;;:30;;;;;:53;;;;;162249:14;;162218:53;;;;;;;162249:14;162218:30;:53;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;162343:15;:26;;;-1:-1:-1;;;;;162343:43:0;;162387:5;162343:50;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;162464:15;:31;;;-1:-1:-1;;;;;162464:46:0;;162511:9;162522:4;162464:63;;;;;;;;;;;;;-1:-1:-1;;;;;162464:63:0;-1:-1:-1;;;;;162464:63:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;162538:15;:26;;;-1:-1:-1;;;;;162538:34:0;;162581:15;:31;;;162615:4;162538:82;;;;;;;;;;;;;-1:-1:-1;;;;;162538:82:0;-1:-1:-1;;;;;162538:82:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;119317:120;119373:4;119397:32;:5;118558:6;119397:32;:9;:32;:::i;189746:216::-;189876:1;189851:22;:26;:56;;;;-1:-1:-1;189881:12:0;;:22;;;-1:-1:-1;;;189881:22:0;;;;189906:1;;-1:-1:-1;;;;;189881:12:0;;:20;;:22;;;;;;;;;;;;;;:12;:22;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;189881:22:0;:26;189851:56;189842:112;;;;-1:-1:-1;;;189842:112:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;182526:708;-1:-1:-1;;;;;182642:17:0;;182621:18;182642:17;;;:6;:17;;;;;:24;;;;;;182740:11;:33;;;;;;;;;;:65;;;;-1:-1:-1;182792:13:0;182777:11;:28;;;;;;;;;;182740:65;182733:73;;;;-1:-1:-1;;;;;182835:17:0;;182819:13;182835:17;;;:6;:17;;;;;:28;;;;;;-1:-1:-1;;;;;182835:28:0;;182888:22;;182936:13;182888:22;182835:28;182936:10;:13::i;:::-;182921:28;;182978:7;182969:5;-1:-1:-1;;;;;182969:16:0;;;182962:24;;;;182999:21;183023:11;183035:7;183023:20;;;;;;;;;;;;;;;;;;183056:11;:18;;-1:-1:-1;;;;;183023:20:0;;;;-1:-1:-1;183023:20:0;;-1:-1:-1;;;;;183056:18:0;;;;;;;;;;;;;;;;;;;;;:34;;-1:-1:-1;;;;;;183056:34:0;-1:-1:-1;;;;;183056:34:0;;;;;;183101:21;;;;;;:6;:21;;;;;;;:32;;:40;;-1:-1:-1;;;;;;183101:40:0;183056:34;-1:-1:-1;;;;;183101:40:0;;;;;;;;;;;;183157:39;;;;;;;;;;;;;;;;;;;;;;;;183209:11;:17;;;;;;;;;;;;;;;;-1:-1:-1;;183209:17:0;;;;;-1:-1:-1;;;;;;183209:17:0;;;;;;-1:-1:-1;;;;;;;182526:708:0:o;119546:135::-;118770:3;119644:29;;;119546:135::o;140737:1257::-;140914:17;;;;141024:19;;141020:967;;141585:40;141602:5;141609:15;141585:16;:40::i;:::-;141570:55;-1:-1:-1;141657:34:0;141685:5;141657:23;:5;141570:55;141657:23;:9;:23;:::i;:34::-;141640:51;-1:-1:-1;141727:23:0;:5;141737:12;141727:23;:9;:23;:::i;:::-;141706:44;-1:-1:-1;141786:25:0;:5;141796:14;141786:25;:9;:25;:::i;:::-;141765:46;;141020:967;;;-1:-1:-1;141859:1:0;;-1:-1:-1;141859:1:0;;-1:-1:-1;141929:5:0;;-1:-1:-1;141970:5:0;141020:967;140737:1257;;;;;;;:::o;142090:990::-;142269:42;;:::i;:::-;142329:52;;;142392:33;;;:52;;;142329:33;142475:37;142505:6;142475:25;142365:16;118212:19;142475:25;:20;:25;:::i;:37::-;142455:57;;142565:37;142589:12;142565:23;:37::i;:::-;142525;;;:77;;;118558:6;142613:37;;;:61;142687:30;;;:49;;;142747:30;;;:45;;;142838:55;;142780:12;;142838:55;:16;:55;:::i;:::-;142803:32;;;:90;142936:34;:16;142957:12;142936:34;:20;:34;:::i;:::-;142904:29;;;:66;-1:-1:-1;143020:1:0;142981:36;;;:40;;;143032:36;;;:40;142904:17;142090:990;-1:-1:-1;;;142090:990:0:o;113254:191::-;113309:12;;113349:8;:1;113355;113349:8;:5;:8;:::i;:::-;113334:23;-1:-1:-1;113380:57:0;112199:4;113380:34;113334:23;113392:21;113380:11;:34::i;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;:::o
Swarm Source
ipfs://f3815bc084bd54d477eb0864e6b3cdd65d39c5105fb7cb4abb2cd2231ff36d6b
Age | Block | Fee Address | BC Fee Address | Voting Power | Jailed | Incoming |
---|
Make sure to use the "Vote Down" button for any spammy posts, and the "Vote Up" for interesting conversations.