Overview
ETH Balance
0 ETH
Eth Value
$0.00Latest 25 from a total of 1,680 transactions
| Transaction Hash |
Method
|
Block
|
From
|
|
To
|
||||
|---|---|---|---|---|---|---|---|---|---|
| Redeem Collatera... | 23227564 | 163 days ago | IN | 0 ETH | 0.00035562 | ||||
| Redeem Collatera... | 23171531 | 170 days ago | IN | 0 ETH | 0.00589725 | ||||
| Redeem Collatera... | 23161644 | 172 days ago | IN | 0 ETH | 0.00014604 | ||||
| Redeem Collatera... | 23161558 | 172 days ago | IN | 0 ETH | 0.00017386 | ||||
| Redeem Collatera... | 23161501 | 172 days ago | IN | 0 ETH | 0.00014862 | ||||
| Redeem Collatera... | 22242785 | 300 days ago | IN | 0 ETH | 0.00044943 | ||||
| Redeem Collatera... | 22014165 | 332 days ago | IN | 0 ETH | 0.00050621 | ||||
| Close Trove | 21921223 | 345 days ago | IN | 0 ETH | 0.00001621 | ||||
| Redeem Collatera... | 21387360 | 420 days ago | IN | 0 ETH | 0.01499149 | ||||
| Redeem Collatera... | 21279771 | 435 days ago | IN | 0 ETH | 0.00853428 | ||||
| Redeem Collatera... | 21094143 | 461 days ago | IN | 0 ETH | 0.00668562 | ||||
| Redeem Collatera... | 20599036 | 530 days ago | IN | 0 ETH | 0.00060903 | ||||
| Redeem Collatera... | 20579765 | 533 days ago | IN | 0 ETH | 0.00137457 | ||||
| Redeem Collatera... | 20502528 | 543 days ago | IN | 0 ETH | 0.00037824 | ||||
| Redeem Collatera... | 20502525 | 543 days ago | IN | 0 ETH | 0.00025024 | ||||
| Redeem Collatera... | 20502403 | 543 days ago | IN | 0 ETH | 0.00041388 | ||||
| Redeem Collatera... | 20457888 | 550 days ago | IN | 0 ETH | 0.00083906 | ||||
| Redeem Collatera... | 20385292 | 560 days ago | IN | 0 ETH | 0.00257614 | ||||
| Redeem Collatera... | 20385286 | 560 days ago | IN | 0 ETH | 0.00138368 | ||||
| Redeem Collatera... | 20358507 | 563 days ago | IN | 0 ETH | 0.00452681 | ||||
| Redeem Collatera... | 20341169 | 566 days ago | IN | 0 ETH | 0.00516286 | ||||
| Redeem Collatera... | 20309730 | 570 days ago | IN | 0 ETH | 0.00115271 | ||||
| Redeem Collatera... | 20309556 | 570 days ago | IN | 0 ETH | 0.00196398 | ||||
| Redeem Collatera... | 20264782 | 577 days ago | IN | 0 ETH | 0.00116093 | ||||
| Redeem Collatera... | 20249705 | 579 days ago | IN | 0 ETH | 0.00123348 |
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Loading...
Loading
Cross-Chain Transactions
Loading...
Loading
Contract Name:
TroveManager
Compiler Version
v0.6.11+commit.5ef660b1
Optimization Enabled:
Yes with 100 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT
pragma solidity 0.6.11;
import "./Interfaces/ITroveManager.sol";
import "./Interfaces/IStabilityPool.sol";
import "./Interfaces/ICollSurplusPool.sol";
import "./Interfaces/ILUSDToken.sol";
import "./Interfaces/ISortedTroves.sol";
import "./Interfaces/ILQTYToken.sol";
import "./Interfaces/ILQTYStaking.sol";
import "./Dependencies/LiquityBase.sol";
import "./Dependencies/Ownable.sol";
import "./Dependencies/CheckContract.sol";
import "./Dependencies/console.sol";
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 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.collToSendToSP, 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.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.collToSendToSP).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.collToSendToSP);
// 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;
}
}// SPDX-License-Identifier: MIT
pragma solidity 0.6.11;
import "./ILiquityBase.sol";
import "./IStabilityPool.sol";
import "./ILUSDToken.sol";
import "./ILQTYToken.sol";
import "./ILQTYStaking.sol";
// 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);
}// SPDX-License-Identifier: MIT
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;
*/
}// SPDX-License-Identifier: MIT
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;
}// SPDX-License-Identifier: MIT
pragma solidity 0.6.11;
import "../Dependencies/IERC20.sol";
import "../Dependencies/IERC2612.sol";
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;
}// SPDX-License-Identifier: MIT
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);
}// SPDX-License-Identifier: MIT
pragma solidity 0.6.11;
import "../Dependencies/IERC20.sol";
import "../Dependencies/IERC2612.sol";
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);
}// SPDX-License-Identifier: MIT
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);
}// SPDX-License-Identifier: MIT
pragma solidity 0.6.11;
import "./BaseMath.sol";
import "./LiquityMath.sol";
import "../Interfaces/IActivePool.sol";
import "../Interfaces/IDefaultPool.sol";
import "../Interfaces/IPriceFeed.sol";
import "../Interfaces/ILiquityBase.sol";
/*
* 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");
}
}// SPDX-License-Identifier: MIT
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);
}
}// SPDX-License-Identifier: MIT
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");
}
}// SPDX-License-Identifier: MIT
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;
}
}// SPDX-License-Identifier: MIT
pragma solidity 0.6.11;
import "./IPriceFeed.sol";
interface ILiquityBase {
function priceFeed() external view returns (IPriceFeed);
}// SPDX-License-Identifier: MIT
pragma solidity 0.6.11;
interface IPriceFeed {
// --- Events ---
event LastGoodPriceUpdated(uint _lastGoodPrice);
// --- Function ---
function fetchPrice() external returns (uint);
}// SPDX-License-Identifier: MIT
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);
}// SPDX-License-Identifier: MIT
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);
}// SPDX-License-Identifier: MIT
pragma solidity 0.6.11;
contract BaseMath {
uint constant public DECIMAL_PRECISION = 1e18;
}// SPDX-License-Identifier: MIT
pragma solidity 0.6.11;
import "./SafeMath.sol";
import "./console.sol";
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;
}
}
}// SPDX-License-Identifier: MIT
pragma solidity 0.6.11;
import "./IPool.sol";
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;
}// SPDX-License-Identifier: MIT
pragma solidity 0.6.11;
import "./IPool.sol";
interface IDefaultPool is IPool {
// --- Events ---
event TroveManagerAddressChanged(address _newTroveManagerAddress);
event DefaultPoolLUSDDebtUpdated(uint _LUSDDebt);
event DefaultPoolETHBalanceUpdated(uint _ETH);
// --- Functions ---
function sendETHToActivePool(uint _amount) external;
}// SPDX-License-Identifier: MIT
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;
}
}// SPDX-License-Identifier: MIT
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;
}{
"optimizer": {
"enabled": true,
"runs": 100
},
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"abi"
]
}
},
"libraries": {}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"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
608060405234801561001057600080fd5b50600380546001600160a01b031916339081179091556040516000907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a3615a7b80620000616000396000f3fe608060405234801561001057600080fd5b506004361061044a5760003560e01c8063795d26c31161023c578063b83f91a211610146578063d3d6f843116100c3578063e2ac77b011610087578063e2ac77b014610c67578063f34862de14610c8d578063f36b242514610cb3578063f92d34331461065d578063fe2ba84814610cbb5761044a565b8063d3d6f84314610bd3578063d5b3563514610bff578063d66a255314610c1c578063d9a7244414610c42578063dba1c5f214610c5f5761044a565b8063c52861f21161010a578063c52861f214610b69578063c7b5548114610b71578063cbd138ae14610b79578063d293c71014610b9f578063d380a37c14610bcb5761044a565b8063b83f91a214610ab7578063b91af97c14610abf578063bcd3752614610b0b578063bf9befb114610b59578063c35bc55014610b615761044a565b806396d711ff116101d4578063a3f4df7e11610198578063a3f4df7e146109e7578063ae91875414610a64578063b0d8e18114610a6c578063b7f8cf9b14610a92578063b82f263d14610a9a5761044a565b806396d711ff146109a35780639976cf45146109ab5780639dd233d2146109d7578063a20baee614610894578063a3a64017146109df5761044a565b8063795d26c3146108c9578063797250e3146108d15780637985c5e4146108d95780637f7dde4a14610955578063807d138d1461095d57806382fe3eb914610965578063887105d31461098b5780638da5cb5b146109935780638f32d59b1461099b5761044a565b8063477d66cf11610358578063631203b0116102d557806372423c171161029957806372423c171461086857806372fe25aa14610894578063741bef1a1461089c578063756b253e146108a4578063794e5724146108c15761044a565b8063631203b01461079157806364cee260146107ae578063653d46e7146107d457806366ca4a21146107f15780636ef64338146107f95761044a565b80635733d58f1161031c5780635733d58f146107275780635d6b480f1461072f5780635d8c96091461075b5780635dba4c4a1461078157806361ec893d146107895761044a565b8063477d66cf146106a3578063480cd578146106c05780634870dd9a146106e657806349eefeee146106ee5780634e443d9e146106f65761044a565b80631e8b1c2b116103e657806328d28b5b116103aa57806328d28b5b1461065d5780632b11551a146106655780632e86bbd81461066d5780632f865568146106755780633cc742251461069b5761044a565b80631e8b1c2b1461057c5780631f68f20a1461061f5780631f7af3c31461062757806321e378011461062f57806324092669146106555761044a565b8063048c661d1461044f578063060d49a314610473578063071a75411461048d5780630b0765571461049557806312610e92146104bd57806315d549f1146104e95780631673c79a1461050f57806318f2817a1461054e5780631bf4355514610574575b600080fd5b610457610ce1565b604080516001600160a01b039092168252519081900360200190f35b61047b610cf0565b60408051918252519081900360200190f35b61047b610cf6565b6104bb600480360360208110156104ab57600080fd5b50356001600160a01b0316610cfb565b005b61047b600480360360408110156104d357600080fd5b506001600160a01b038135169060200135610d23565b61047b600480360360208110156104ff57600080fd5b50356001600160a01b0316610d7b565b6105356004803603602081101561052557600080fd5b50356001600160a01b0316610d9f565b6040805192835260208301919091528051918290030190f35b61047b6004803603602081101561056457600080fd5b50356001600160a01b0316610db8565b61047b610dcb565b6104bb6004803603602081101561059257600080fd5b8101906020810181356401000000008111156105ad57600080fd5b8201836020820111156105bf57600080fd5b803590602001918460208302840111640100000000831117156105e157600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250929550610dd8945050505050565b61047b61117a565b610457611180565b61047b6004803603602081101561064557600080fd5b50356001600160a01b031661118f565b61047b6111b9565b61047b6111cc565b61047b6111dd565b61047b6111ef565b6104bb6004803603602081101561068b57600080fd5b50356001600160a01b03166111fc565b610457611262565b61047b600480360360208110156106b957600080fd5b5035611271565b61047b600480360360208110156106d657600080fd5b50356001600160a01b0316611284565b61047b6112a2565b61047b6112a7565b6107136004803603602081101561070c57600080fd5b50356112ad565b604080519115158252519081900360200190f35b61047b6112b8565b6104bb6004803603604081101561074557600080fd5b506001600160a01b0381351690602001356112c4565b61047b6004803603602081101561077157600080fd5b50356001600160a01b0316611310565b6104bb6113d6565b61047b61143c565b61047b600480360360208110156107a757600080fd5b5035611441565b61047b600480360360208110156107c457600080fd5b50356001600160a01b031661144e565b6104bb600480360360208110156107ea57600080fd5b503561146c565b61047b61181a565b61081f6004803603602081101561080f57600080fd5b50356001600160a01b031661182c565b6040518086815260200185815260200184815260200183600481111561084157fe5b60ff1681526001600160801b03909216602083015250604080519182900301945092505050f35b61047b6004803603604081101561087e57600080fd5b506001600160a01b038135169060200135611866565b61047b6118c3565b6104576118cf565b610457600480360360208110156108ba57600080fd5b50356118de565b61047b611905565b61047b611911565b61047b611a12565b6104bb60048036036101608110156108f057600080fd5b506001600160a01b038135811691602081013582169160408201358116916060810135821691608082013581169160a081013582169160c082013581169160e08101358216916101008201358116916101208101358216916101409091013516611a18565b610457611e11565b61047b611e20565b6104bb6004803603602081101561097b57600080fd5b50356001600160a01b0316611e26565b61047b611e37565b610457611ef3565b610713611f02565b61047b611f13565b61047b600480360360408110156109c157600080fd5b506001600160a01b038135169060200135611f19565b61047b611f4c565b610457611f52565b6109ef611f61565b6040805160208082528351818301528351919283929083019185019080838360005b83811015610a29578181015183820152602001610a11565b50505050905090810190601f168015610a565780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b610457611f89565b61047b60048036036020811015610a8257600080fd5b50356001600160a01b0316611f98565b610457611fbf565b61047b60048036036020811015610ab057600080fd5b5035611fce565b610457611fd9565b610ae560048036036020811015610ad557600080fd5b50356001600160a01b0316611fe8565b604080519485526020850193909352838301919091526060830152519081900360800190f35b6104bb600480360360e0811015610b2157600080fd5b508035906001600160a01b03602082013581169160408101358216916060820135169060808101359060a08101359060c0013561204c565b61047b6127ee565b61047b6127f4565b61047b6127fb565b61047b61280d565b6104bb60048036036020811015610b8f57600080fd5b50356001600160a01b0316612819565b61047b60048036036040811015610bb557600080fd5b506001600160a01b03813516906020013561282c565b61047b61284b565b61047b60048036036040811015610be957600080fd5b506001600160a01b038135169060200135612851565b61047b60048036036020811015610c1557600080fd5b5035612887565b61047b60048036036020811015610c3257600080fd5b50356001600160a01b031661289a565b61045760048036036020811015610c5857600080fd5b50356128b5565b61047b6128df565b61071360048036036020811015610c7d57600080fd5b50356001600160a01b03166128e5565b61047b60048036036020811015610ca357600080fd5b50356001600160a01b0316612943565b61047b612974565b6104bb60048036036020811015610cd157600080fd5b50356001600160a01b0316612981565b6005546001600160a01b031681565b60175481565b600281565b610d03612992565b600054600154610d20916001600160a01b039081169116836129dd565b50565b6000610d2d612992565b6001600160a01b0383166000908152600e6020526040812054610d56908463ffffffff612aff16565b6001600160a01b0385166000908152600e602052604090208190559150505b92915050565b6000610d85612992565b610d8e82612b48565b6001600160801b031690505b919050565b6014602052600090815260409020805460019091015482565b6000610dc2612992565b610d7582612be2565b686194049f30f720000081565b8051610e155760405162461bcd60e51b81526004018080602001828103825260368152602001806159016036913960400191505060405180910390fd5b6000546001546005546001600160a01b03928316929182169116610e376155f9565b610e3f61562a565b600260009054906101000a90046001600160a01b03166001600160a01b0316630fdb11cf6040518163ffffffff1660e01b8152600401602060405180830381600087803b158015610e8f57600080fd5b505af1158015610ea3573d6000803e3d6000fd5b505050506040513d6020811015610eb957600080fd5b50518252604080516326fcbc6b60e21b815290516001600160a01b03851691639bf2f1ac916004808301926020929190829003018186803b158015610efd57600080fd5b505afa158015610f11573d6000803e3d6000fd5b505050506040513d6020811015610f2757600080fd5b505160208301528151610f3990612c91565b1580156040840152610f6157610f5a8585846000015185602001518a612cae565b9050610f79565b610f768585846000015185602001518a612ec9565b90505b6000816020015111610fbc5760405162461bcd60e51b81526004018080602001828103825260228152602001806159f56022913960400191505060405180910390fd5b826001600160a01b031663335525ad82608001518360a001516040518363ffffffff1660e01b81526004018083815260200182815260200192505050600060405180830381600087803b15801561101257600080fd5b505af1158015611026573d6000803e3d6000fd5b5050505061103e85858360c001518460e00151612f91565b610100810151156110bd57600754610100820151604080516364a197f360e01b81526001600160a01b039384166004820152602481019290925251918716916364a197f39160448082019260009290919082900301818387803b1580156110a457600080fd5b505af11580156110b8573d6000803e3d6000fd5b505050505b6110cb858260400151613212565b602081015160608301526101008101516040820151825161110392916110f7919063ffffffff612aff16565b9063ffffffff612aff16565b608080840182905260608085015160408086015186840151825193845260208401969096528282015291810193909352517f4152c73dd2614c4f9fc35e8c9cf16013cd588c75b49a4c1673ecffdcbcda94039281900390910190a1611172853383606001518460400151613359565b505050505050565b600c5481565b6009546001600160a01b031681565b6001600160a01b0381166000908152600e602052604081206003015460ff166004811115610d7557fe5b6064670de0b6b3a76400005b0460050281565b6103e8670de0b6b3a76400006111c5565b60006111ea600c5461345c565b905090565b680ad78ebc5ac620000081565b61120581613492565b60408051600180825281830190925260609160208083019080368337019050509050818160008151811061123557fe5b60200260200101906001600160a01b031690816001600160a01b03168152505061125e81610dd8565b5050565b6001546001600160a01b031681565b6000610d7561127e61181a565b836134fa565b6001600160a01b03166000908152600e602052604090206001015490565b60c881565b60155490565b6000610d7582612c91565b6714d1120d7b16000081565b6112cc612992565b8060048111156112d857fe5b6001600160a01b0383166000908152600e60205260409020600301805460ff1916600183600481111561130757fe5b02179055505050565b6001600160a01b038116600090815260146020526040812054601254829061133e908363ffffffff612aff16565b9050801580611377575060016001600160a01b0385166000908152600e602052604090206003015460ff16600481111561137457fe5b14155b1561138757600092505050610d9a565b6001600160a01b0384166000908152600e6020526040812060020154906113cc670de0b6b3a76400006113c0848663ffffffff61351816565b9063ffffffff61357116565b9695505050505050565b6113de612992565b60006113e86135b3565b9050670de0b6b3a76400008111156113fc57fe5b600c8190556040805182815290517fc454ee9b76c52f782a256af821b857ca6e125d1e3333bcede402fec2bed9600c9181900360200190a1610d206135f7565b603c81565b6000610d7561127e612974565b6001600160a01b03166000908152600e602052604090206002015490565b611474615676565b506040805160e081018252600080546001600160a01b0390811683526001548116602084015292820181905260608201819052600b548316608083015260a0820181905260c08201526005549091166114cb6155f9565b6114d361562a565b600260009054906101000a90046001600160a01b03166001600160a01b0316630fdb11cf6040518163ffffffff1660e01b8152600401602060405180830381600087803b15801561152357600080fd5b505af1158015611537573d6000803e3d6000fd5b505050506040513d602081101561154d57600080fd5b50518252604080516326fcbc6b60e21b815290516001600160a01b03851691639bf2f1ac916004808301926020929190829003018186803b15801561159157600080fd5b505afa1580156115a5573d6000803e3d6000fd5b505050506040513d60208110156115bb57600080fd5b5051602083015281516115cd90612c91565b15801560408401526115f4576115ed848360000151846020015188613653565b9050611614565b6116118460000151856020015184600001518560200151896139e6565b90505b60008160200151116116575760405162461bcd60e51b81526004018080602001828103825260228152602001806159f56022913960400191505060405180910390fd5b826001600160a01b031663335525ad82608001518360a001516040518363ffffffff1660e01b81526004018083815260200182815260200192505050600060405180830381600087803b1580156116ad57600080fd5b505af11580156116c1573d6000803e3d6000fd5b505050506116e1846000015185602001518360c001518460e00151612f91565b61010081015115611762578351600754610100830151604080516364a197f360e01b81526001600160a01b03938416600482015260248101929092525191909216916364a197f391604480830192600092919082900301818387803b15801561174957600080fd5b505af115801561175d573d6000803e3d6000fd5b505050505b61177484600001518260400151613212565b60208101516060830152610100810151604082015182516117a092916110f7919063ffffffff612aff16565b608080840182905260608085015160408086015186840151825193845260208401969096528282015291810193909352517f4152c73dd2614c4f9fc35e8c9cf16013cd588c75b49a4c1673ecffdcbcda94039281900390910190a161181384600001513383606001518460400151613359565b5050505050565b60006111ea6118276135b3565b613b18565b600e6020526000908152604090208054600182015460028301546003909301549192909160ff81169061010090046001600160801b031685565b6000611870612992565b6001600160a01b0383166000908152600e602052604081206001015461189c908463ffffffff613b3f16565b6001600160a01b0385166000908152600e6020526040902060010181905591505092915050565b670de0b6b3a764000081565b6002546001600160a01b031681565b601581815481106118eb57fe5b6000918252602090912001546001600160a01b0316905081565b670f43fc2c04ee000081565b6000805460408051632f5a97e560e11b8152905183926001600160a01b031691635eb52fca916004808301926020929190829003018186803b15801561195657600080fd5b505afa15801561196a573d6000803e3d6000fd5b505050506040513d602081101561198057600080fd5b505160015460408051632f5a97e560e11b815290519293506000926001600160a01b0390921691635eb52fca91600480820192602092909190829003018186803b1580156119cd57600080fd5b505afa1580156119e1573d6000803e3d6000fd5b505050506040513d60208110156119f757600080fd5b50519050611a0b828263ffffffff613b3f16565b9250505090565b60165481565b611a20611f02565b611a71576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b611a7a8b613b99565b611a838a613b99565b611a8c89613b99565b611a9588613b99565b611a9e87613b99565b611aa786613b99565b611ab085613b99565b611ab984613b99565b611ac283613b99565b611acb82613b99565b611ad481613b99565b600480546001600160a01b03199081166001600160a01b038e81169182179093556000805483168e85161790556001805483168d85161790556005805483168c85161790556006805483168b85161790556007805483168a8516179055600280548316898516179055600880548316888516179055600b80548316878516179055600980548316868516179055600a805490921692841692909217905560408051918252517f3ca631ffcd2a9b5d9ae18543fc82f58eb4ca33af9e6ab01b7a8e95331e6ed985916020908290030190a1604080516001600160a01b038c16815290517f78f058b189175430c48dc02699e3a0031ea4ff781536dc2fab847de4babdd8829181900360200190a1604080516001600160a01b038b16815290517f5ee0cae2f063ed938bb55046f6a932fb6ae792bf43624806bb90abe68a50be9b9181900360200190a1604080516001600160a01b038a16815290517f82966d27eea39b038ee0fa30cd16532bb24f6e65d31cb58fb227aa5766cdcc7f9181900360200190a1604080516001600160a01b038916815290517fcfb07d791fcafc032b35837b50eb84b74df518cf4cc287e8084f47630fa70fa09181900360200190a1604080516001600160a01b038816815290517fe67f36a6e961157d6eff83b91f3af5a62131ceb6f04954ef74f51c1c05e7f88d9181900360200190a1604080516001600160a01b038716815290517f8c537274438aa850a330284665d81a85dd38267d09e4050d416bfc94142db2649181900360200190a1604080516001600160a01b038616815290517f227eec0ec317af6ab1a9587ffa1c84332522eb4c583a908f89babc05f8f339bd9181900360200190a1604080516001600160a01b038516815290517f65f4cf077bc01e4742eb5ad98326f6e95b63548ea24b17f8d5e823111fe788009181900360200190a1604080516001600160a01b038416815290517f2ac6e99201ddc1b6eac6f8f28662d1ecafee131f6eb98c29de54528a9888a7d19181900360200190a1604080516001600160a01b038316815290517f756ebc192164c295bba134b5aacd72cc7aff8098a670d1f0a5f6b3a0b4ce67079181900360200190a1611e04613c48565b5050505050505050505050565b6000546001600160a01b031681565b60105481565b611e2e612992565b610d2081613c92565b6000805460408051630a7b61df60e11b8152905183926001600160a01b0316916314f6c3be916004808301926020929190829003018186803b158015611e7c57600080fd5b505afa158015611e90573d6000803e3d6000fd5b505050506040513d6020811015611ea657600080fd5b505160015460408051630a7b61df60e11b815290519293506000926001600160a01b03909216916314f6c3be91600480820192602092909190829003018186803b1580156119cd57600080fd5b6003546001600160a01b031690565b6003546001600160a01b0316331490565b60115481565b6000611f23612992565b6001600160a01b0383166000908152600e6020526040812054610d56908463ffffffff613b3f16565b60125481565b600a546001600160a01b031681565b6040518060400160405280600c81526020016b2a3937bb32a6b0b730b3b2b960a11b81525081565b600b546001600160a01b031681565b6000806000611fa684613cfd565b915091506000611fb68383613d83565b95945050505050565b6004546001600160a01b031681565b6000610d7582613db8565b6008546001600160a01b031681565b6001600160a01b0381166000908152600e60205260408120805460019091015490918061201485612943565b915061201f85611310565b9050612031848363ffffffff613b3f16565b9350612043838263ffffffff613b3f16565b92509193509193565b612054615676565b506040805160e0810182526000546001600160a01b03908116825260015481166020830152600854811692820192909252600a5482166060820152600b5482166080820152600754821660a082015260065490911660c08201526120b66156b2565b6120bf83613de4565b6120c7613e3e565b600260009054906101000a90046001600160a01b03166001600160a01b0316630fdb11cf6040518163ffffffff1660e01b8152600401602060405180830381600087803b15801561211757600080fd5b505af115801561212b573d6000803e3d6000fd5b505050506040513d602081101561214157600080fd5b505160c0820181905261215390613f02565b61215c89613f51565b61216b8260400151338b613f90565b612173611911565b60e0820181905260408084015181516370a0823160e01b815233600482015291516001600160a01b03909116916370a08231916024808301926020929190829003018186803b1580156121c557600080fd5b505afa1580156121d9573d6000803e3d6000fd5b505050506040513d60208110156121ef57600080fd5b505111156121f957fe5b888152608082015160c0820151600091612214918b90614050565b1561222057508761234a565b82608001516001600160a01b0316634d6228316040518163ffffffff1660e01b815260040160206040518083038186803b15801561225d57600080fd5b505afa158015612271573d6000803e3d6000fd5b505050506040513d602081101561228757600080fd5b505190505b6001600160a01b038116158015906122b85750670f43fc2c04ee00006122b6828460c0015161282c565b105b1561234a5782608001516001600160a01b031663b72703ac826040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b15801561231757600080fd5b505afa15801561232b573d6000803e3d6000fd5b505050506040513d602081101561234157600080fd5b5051905061228c565b846123555760001994505b6001600160a01b0381161580159061236d5750815115155b80156123795750600085115b156124ad57848060019003955050600083608001516001600160a01b031663b72703ac836040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b1580156123e357600080fd5b505afa1580156123f7573d6000803e3d6000fd5b505050506040513d602081101561240d57600080fd5b50518451602086015191925061242391846129dd565b61242b6156f7565b612442858486600001518760c001518e8e8e6141c3565b90508060400151156124555750506124ad565b8051602085015161246b9163ffffffff613b3f16565b602080860191909152810151604085015161248b9163ffffffff613b3f16565b6040850152805184516124a39163ffffffff612aff16565b8452509050612355565b60008260400151116124f05760405162461bcd60e51b81526004018080602001828103825260298152602001806157a46029913960400191505060405180910390fd5b61250782604001518360c001518460e00151614476565b50612515826040015161451e565b60608301819052604083015161252c91908661452b565b82600001516001600160a01b03166364a197f3846060015184606001516040518363ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200182815260200192505050600060405180830381600087803b15801561259857600080fd5b505af11580156125ac573d6000803e3d6000fd5b5050505082606001516001600160a01b0316631e3e2a1a83606001516040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b1580156125fe57600080fd5b505af1158015612612573d6000803e3d6000fd5b505050506060820151604083015161262991612aff565b8260800181815250507f43a3f4082a4dbc33d78e317d2497d3a730bc7fc3574159dcea1056e62e5d9ad88a8360200151846040015185606001516040518085815260200184815260200183815260200182815260200194505050505060405180910390a182604001516001600160a01b0316639dc29fac3384602001516040518363ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200182815260200192505050600060405180830381600087803b1580156126f557600080fd5b505af1158015612709573d6000803e3d6000fd5b5050505082600001516001600160a01b03166338d995a883602001516040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b15801561275b57600080fd5b505af115801561276f573d6000803e3d6000fd5b505084516080850151604080516364a197f360e01b81523360048201526024810192909252516001600160a01b0390921693506364a197f3925060448082019260009290919082900301818387803b1580156127ca57600080fd5b505af11580156127de573d6000803e3d6000fd5b5050505050505050505050505050565b600f5481565b6212750081565b60006111ea6128086135b3565b61345c565b670ddd4b8c6c7d70d881565b612821612992565b610d208160026145a0565b600080600061283a85613cfd565b9150915060006113cc8383876146b9565b600d5481565b600061285b612992565b6001600160a01b0383166000908152600e602052604081206001015461189c908463ffffffff612aff16565b6000610d756128946127fb565b836146e9565b6001600160a01b03166000908152600e602052604090205490565b6000601582815481106128c457fe5b6000918252602090912001546001600160a01b031692915050565b60135481565b600060016001600160a01b0383166000908152600e602052604090206003015460ff16600481111561291357fe5b1461292057506000610d9a565b506012546001600160a01b03821660009081526014602052604090205410919050565b6001600160a01b038116600090815260146020526040812060010154601354829061133e908363ffffffff612aff16565b60006111ea600c54613b18565b612989612992565b610d2081614748565b6004546001600160a01b031633146129db5760405162461bcd60e51b815260040180806020018281038252603b8152602001806158c6603b913960400191505060405180910390fd5b565b6129e6816128e5565b15612afa576129f481613492565b60006129ff82611310565b90506000612a0c83612943565b6001600160a01b0384166000908152600e6020526040902060010154909150612a3b908363ffffffff613b3f16565b6001600160a01b0384166000908152600e60205260409020600181019190915554612a6c908263ffffffff613b3f16565b6001600160a01b0384166000908152600e6020526040902055612a8e83613c92565b612a9a85858385614798565b6001600160a01b0383166000818152600e602090815260408083208054600182015460029092015483519182529381019190915280820192909252606082019290925290516000805160206158a68339815191529181900360800190a250505b505050565b6000612b4183836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f77000081525061489a565b9392505050565b601580546001808201835560008381527f55f448fdea98c4d29eb340757ef0a66cd03dbb9538908a6a81d96026b71ec47590920180546001600160a01b0319166001600160a01b03861617905591549091612ba39190612aff565b6001600160a01b03929092166000908152600e602052604090206003018054610100600160881b0319166101006001600160801b038516021790555090565b6001600160a01b0381166000908152600e60205260408120600101548190612c0990614931565b6001600160a01b0384166000908152600e60205260409020600201805490829055600f5491925090612c53908390612c47908463ffffffff612aff16565b9063ffffffff613b3f16565b600f81905560408051918252517f6bac5e0eb3c44eb03a60ab11ec3a2c051771616aecadbcfff2630aabae5203829181900360200190a15092915050565b600080612c9d83613db8565b6714d1120d7b160000119392505050565b612cb661562a565b612cbe61571a565b612cc661562a565b84825260006080830152612cd8611911565b60a0830152612ce5611e37565b60c0830152600060208301525b835182602001511015612ebe5783826020015181518110612d0f57fe5b6020908102919091018101516001600160a01b0316606084018190526000908152600e909152604090206003015460019060ff166004811115612d4e57fe5b14612d5857612eae565b612d6682606001518761282c565b60408301526080820151612e5057670f43fc2c04ee0000826040015110158015612d8f57508151155b15612d9957612eae565b6000612dae8360c001518460a00151896146b9565b9050612dcb8989856060015186604001518760000151868d61496d565b60808101518451919350612de5919063ffffffff612aff16565b8352608082015160a0840151612e009163ffffffff612aff16565b60a08085019190915282015160c0840151612e209163ffffffff612aff16565b60c0840152612e2f8483614ca0565b9350612e448360c001518460a0015189614db7565b15608084015250612eae565b81608001518015612e6c5750670f43fc2c04ee00008260400151105b15612eae57612e85888884606001518560000151614dd8565b60808101518351919250612e9f919063ffffffff612aff16565b8252612eab8382614ca0565b92505b6020820180516001019052612cf2565b505095945050505050565b612ed161562a565b612ed961571a565b612ee161562a565b848252600060208301525b835182602001511015612ebe5783826020015181518110612f0957fe5b60209081029190910101516001600160a01b031660608301819052612f2e908761282c565b60408301819052670f43fc2c04ee00001115612f8157612f58888884606001518560000151614dd8565b60808101518351919250612f72919063ffffffff612aff16565b8252612f7e8382614ca0565b92505b6020820180516001019052612eec565b81612f9b5761320c565b601654600090612fbd90612c4784670de0b6b3a764000063ffffffff61351816565b90506000612fe2601754612c47670de0b6b3a76400008761351890919063ffffffff16565b90506000612ffb600f548461357190919063ffffffff16565b90506000613014600f548461357190919063ffffffff16565b905061303b61302e600f548461351890919063ffffffff16565b859063ffffffff612aff16565b601655600f546130639061305690839063ffffffff61351816565b849063ffffffff612aff16565b601755601254613079908363ffffffff613b3f16565b60125560135461308f908263ffffffff613b3f16565b601381905560125460408051918252602082019290925281517f9f8bc8ab0daf5bceef75ecfd2085d1fcc6548c657ea970d9a23a60610d0737e3929181900390910190a1876001600160a01b03166338d995a8876040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b15801561311957600080fd5b505af115801561312d573d6000803e3d6000fd5b50505050866001600160a01b031663cfb9329a876040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b15801561317757600080fd5b505af115801561318b573d6000803e3d6000fd5b50505050876001600160a01b03166364a197f388876040518363ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200182815260200192505050600060405180830381600087803b1580156131ef57600080fd5b505af1158015613203573d6000803e3d6000fd5b50505050505050505b50505050565b600f546010819055506000826001600160a01b03166314f6c3be6040518163ffffffff1660e01b815260040160206040518083038186803b15801561325657600080fd5b505afa15801561326a573d6000803e3d6000fd5b505050506040513d602081101561328057600080fd5b505160015460408051630a7b61df60e11b815290519293506000926001600160a01b03909216916314f6c3be91600480820192602092909190829003018186803b1580156132cd57600080fd5b505afa1580156132e1573d6000803e3d6000fd5b505050506040513d60208110156132f757600080fd5b5051905061330f81612c47848663ffffffff612aff16565b601181905560105460408051918252602082019290925281517f51bf4c63ec3cba9d03d43238abbdd979dd91bd16d9895c74ceea9118c7baaf60929181900390910190a150505050565b81156133d85760085460065460408051631062c15f60e11b81526001600160a01b039283166004820152868316602482015260448101869052905191909216916320c582be91606480830192600092919082900301818387803b1580156133bf57600080fd5b505af11580156133d3573d6000803e3d6000fd5b505050505b801561320c57836001600160a01b03166364a197f384836040518363ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200182815260200192505050600060405180830381600087803b15801561343e57600080fd5b505af1158015613452573d6000803e3d6000fd5b5050505050505050565b6000610d75613484836103e8670de0b6b3a76400005b04600502613b3f90919063ffffffff16565b670de0b6b3a7640000614f47565b60016001600160a01b0382166000908152600e602052604090206003015460ff1660048111156134be57fe5b14610d205760405162461bcd60e51b815260040180806020018281038252602f815260200180615a17602f913960400191505060405180910390fd5b6000612b41670de0b6b3a76400006113c0858563ffffffff61351816565b60008261352757506000610d75565b8282028284828161353457fe5b0414612b415760405162461bcd60e51b81526004018080602001828103825260218152602001806158376021913960400191505060405180910390fd5b6000612b4183836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250614f5d565b6000806135be614fc2565b905060006135d4670ddd4b8c6c7d70d883614fde565b9050611a0b670de0b6b3a76400006113c083600c5461351890919063ffffffff16565b600061360e600d5442612aff90919063ffffffff16565b9050603c8110610d205742600d81905560408051918252517f860f8d2f0c74dd487e89e2883e3b25b8159ce1e1b3433a291cba7b82c508f3bc9181900360200190a150565b61365b61562a565b61366361571a565b61366b61562a565b8482526000608083015261367d611911565b60a083015261368a611e37565b8260c001818152505086608001516001600160a01b0316634d6228316040518163ffffffff1660e01b815260040160206040518083038186803b1580156136d057600080fd5b505afa1580156136e4573d6000803e3d6000fd5b505050506040513d60208110156136fa57600080fd5b50516001600160a01b039081166060840152608088015160408051631e22314360e01b815290516000939290921691631e22314391600480820192602092909190829003018186803b15801561374f57600080fd5b505afa158015613763573d6000803e3d6000fd5b505050506040513d602081101561377957600080fd5b50516000602085015290505b8483602001511080156137ae5750806001600160a01b031683606001516001600160a01b031614155b156139db57600088608001516001600160a01b031663b72703ac85606001516040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b15801561381357600080fd5b505afa158015613827573d6000803e3d6000fd5b505050506040513d602081101561383d57600080fd5b50516060850151909150613851908961282c565b6040850152608084015161394d57670f43fc2c04ee000084604001511015801561387a57508351155b1561388557506139db565b600061389a8560c001518660a001518b6146b9565b8a5160208c01516060880151604089015189519495506138bb94868f61496d565b608081015186519195506138d5919063ffffffff612aff16565b8552608084015160a08601516138f09163ffffffff612aff16565b8560a001818152505061391d8461010001516110f78660a001518860c00151612aff90919063ffffffff16565b60c086015261392c8685614ca0565b95506139418560c001518660a001518b614db7565b156080860152506139bd565b836080015180156139695750670f43fc2c04ee00008460400151105b156139b75761398a89600001518a6020015186606001518760000151614dd8565b608081015185519194506139a4919063ffffffff612aff16565b84526139b08584614ca0565b94506139bd565b506139db565b6001600160a01b031660608401526020830180516001019052613785565b505050949350505050565b6139ee61562a565b6139f661571a565b6139fe61562a565b600b54858352600060208401526001600160a01b03165b8483602001511015613b0c57806001600160a01b0316634d6228316040518163ffffffff1660e01b815260040160206040518083038186803b158015613a5a57600080fd5b505afa158015613a6e573d6000803e3d6000fd5b505050506040513d6020811015613a8457600080fd5b50516001600160a01b031660608401819052613aa0908861282c565b60408401819052670f43fc2c04ee00001115613af757613aca898985606001518660000151614dd8565b60808101518451919350613ae4919063ffffffff612aff16565b8352613af08483614ca0565b9350613afc565b613b0c565b6020830180516001019052613a15565b50505095945050505050565b6000610d75613b32836103e8670de0b6b3a7640000613472565b66b1a2bc2ec50000614f47565b600082820183811015612b41576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b6001600160a01b038116613bf4576040805162461bcd60e51b815260206004820152601e60248201527f4163636f756e742063616e6e6f74206265207a65726f20616464726573730000604482015290519081900360640190fd5b803b8061125e576040805162461bcd60e51b815260206004820181905260248201527f4163636f756e7420636f64652073697a652063616e6e6f74206265207a65726f604482015290519081900360640190fd5b6003546040516000916001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600380546001600160a01b0319169055565b601280546001600160a01b0383166000908152601460209081526040918290209283556013546001909301839055925481519081529283019190915280517fc437f324d85e369394148dd9d62f98f534b382e01ed3dd2eb98138fb6d3ab49a9281900390910190a150565b6000806000613d0b84611310565b90506000613d1885612943565b6001600160a01b0386166000908152600e602052604081206001015491925090613d48908463ffffffff613b3f16565b6001600160a01b0387166000908152600e602052604081205491925090613d75908463ffffffff613b3f16565b919550909350505050915091565b60008115613daf57613da8826113c08568056bc75e2d6310000063ffffffff61351816565b9050610d75565b50600019610d75565b600080613dc3611e37565b90506000613dcf611911565b9050613ddc8282866146b9565b949350505050565b6611c37937e080008110801590613e035750670de0b6b3a76400008111155b610d205760405162461bcd60e51b815260040180806020018281038252603081526020018061599b6030913960400191505060405180910390fd5b60095460408051631e425be160e11b815290516000926001600160a01b031691633c84b7c2916004808301926020929190829003018186803b158015613e8357600080fd5b505afa158015613e97573d6000803e3d6000fd5b505050506040513d6020811015613ead57600080fd5b50519050613ec4816212750063ffffffff613b3f16565b421015610d205760405162461bcd60e51b81526004018080602001828103825260408152602001806157f76040913960400191505060405180910390fd5b670f43fc2c04ee0000613f1482613db8565b1015610d205760405162461bcd60e51b815260040180806020018281038252602a8152602001806159cb602a913960400191505060405180910390fd5b60008111610d205760405162461bcd60e51b815260040180806020018281038252602e815260200180615937602e913960400191505060405180910390fd5b80836001600160a01b03166370a08231846040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b158015613fe757600080fd5b505afa158015613ffb573d6000803e3d6000fd5b505050506040513d602081101561401157600080fd5b50511015612afa5760405162461bcd60e51b815260040180806020018281038252604e815260200180615858604e913960600191505060405180910390fd5b60006001600160a01b03831615806140e75750836001600160a01b0316635dbe47e8846040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b1580156140b957600080fd5b505afa1580156140cd573d6000803e3d6000fd5b505050506040513d60208110156140e357600080fd5b5051155b806141025750670f43fc2c04ee0000614100848461282c565b105b1561410f57506000612b41565b6000846001600160a01b031663765e0159856040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b15801561416757600080fd5b505afa15801561417b573d6000803e3d6000fd5b505050506040513d602081101561419157600080fd5b505190506001600160a01b0381161580611fb65750670f43fc2c04ee00006141b9828561282c565b1095945050505050565b6141cb6156f7565b6001600160a01b0387166000908152600e602052604090205461420890879061420390680ad78ebc5ac620000063ffffffff612aff16565b614f47565b8082526142299086906113c090670de0b6b3a764000063ffffffff61351816565b60208083019190915281516001600160a01b0389166000908152600e909252604082205461425c9163ffffffff612aff16565b6020808401516001600160a01b038b166000908152600e909252604082206001015492935090916142929163ffffffff612aff16565b9050680ad78ebc5ac620000082141561432b576142ae89614748565b6142b98960046145a0565b6142ce8a8a680ad78ebc5ac620000084615089565b886001600160a01b03166000805160206158a6833981519152600080600060036040518085815260200184815260200183815260200182600381111561431057fe5b60ff16815260200194505050505060405180910390a2614468565b60006143378284613d83565b905084811415806143585750686194049f30f72000006143568461523e565b105b1561436c575050600160408301525061446b565b60808b01516040805163015f109360e51b81526001600160a01b038d81166004830152602482018590528a81166044830152898116606483015291519190921691632be2126091608480830192600092919082900301818387803b1580156143d357600080fd5b505af11580156143e7573d6000803e3d6000fd5b5050506001600160a01b038b166000908152600e60205260409020848155600101839055506144158a612be2565b506001600160a01b038a166000818152600e6020908152604091829020600201548251878152918201869052818301526003606082015290516000805160206158a68339815191529181900360800190a2505b50505b979650505050505050565b6000806144816135b3565b90506000614499846113c0888863ffffffff61351816565b905060006144be6144b183600263ffffffff61357116565b849063ffffffff613b3f16565b90506144d281670de0b6b3a7640000614f47565b9050600081116144de57fe5b600c8190556040805182815290517fc454ee9b76c52f782a256af821b857ca6e125d1e3333bcede402fec2bed9600c9181900360200190a16113cc6135f7565b6000610d756128946111dd565b6000614549836113c086670de0b6b3a764000063ffffffff61351816565b90508181111561320c576040805162461bcd60e51b815260206004820152601d60248201527f4665652065786365656465642070726f7669646564206d6178696d756d000000604482015290519081900360640190fd5b60008160048111156145ae57fe5b141580156145c8575060018160048111156145c557fe5b14155b6145ce57fe5b6015546145da81615259565b6001600160a01b0383166000908152600e60205260409020600301805483919060ff1916600183600481111561460c57fe5b02179055506001600160a01b0383166000908152600e6020908152604080832060018082018590559084905560149092528220828155015561464e8382615312565b600b5460408051631484968760e11b81526001600160a01b038681166004830152915191909216916329092d0e91602480830192600092919082900301818387803b15801561469c57600080fd5b505af11580156146b0573d6000803e3d6000fd5b50505050505050565b600082156146e05760006146d7846113c0878663ffffffff61351816565b9150612b419050565b50600019612b41565b600080614708670de0b6b3a76400006113c0868663ffffffff61351816565b9050828110612b415760405162461bcd60e51b81526004018080602001828103825260368152602001806159656036913960400191505060405180910390fd5b6001600160a01b0381166000908152600e6020526040902060020154600f54614777908263ffffffff612aff16565b600f55506001600160a01b03166000908152600e6020526040812060020155565b826001600160a01b03166338d995a8836040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b1580156147de57600080fd5b505af11580156147f2573d6000803e3d6000fd5b50505050836001600160a01b031663cfb9329a836040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b15801561483c57600080fd5b505af1158015614850573d6000803e3d6000fd5b50505050826001600160a01b031663be41205f826040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b15801561343e57600080fd5b600081848411156149295760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b838110156148ee5781810151838201526020016148d6565b50505050905090810190601f16801561491b5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b60008060115460001415614946575081610d75565b60006010541161495257fe5b612b416011546113c06010548661351890919063ffffffff16565b61497561562a565b61497d615762565b60155460011061498d575061446b565b61499687611fe8565b604085015260208481019190915284018190529083526149b5906154b9565b60408301819052680ad78ebc5ac6200000606084015260208301516149df9163ffffffff612aff16565b8152670de0b6b3a76400008611614ae757614a04898983602001518460400151614798565b614a0d87614748565b60006080830181905260a0830152815160c0830152805160e0830152614a348760036145a0565b866001600160a01b031660008051602061578483398151915283600001518460200151600260405180848152602001838152602001826003811115614a7557fe5b60ff168152602001935050505060405180910390a2866001600160a01b03166000805160206158a68339815191526000806000600260405180858152602001848152602001838152602001826003811115614acc57fe5b60ff16815260200194505050505060405180910390a2614c94565b670de0b6b3a764000086118015614b055750670f43fc2c04ee000086105b15614b5557614b1e898983602001518460400151614798565b614b2787614748565b81518151614b369190876154c0565b60e086015260c085015260a08401526080830152614a348760036145a0565b670f43fc2c04ee00008610158015614b6c57508386105b8015614b79575081518510155b15614c8357614b92898983602001518460400151614798565b84614b9957fe5b614ba287614748565b614bb5826000015183602001518561552c565b9150614bc28760036145a0565b61010082015115614c425760075461010083015160408051633f10abab60e01b81526001600160a01b038b81166004830152602482019390935290519190921691633f10abab91604480830192600092919082900301818387803b158015614c2957600080fd5b505af1158015614c3d573d6000803e3d6000fd5b505050505b866001600160a01b031660008051602061578483398151915283600001518460a00151600260405180848152602001838152602001826003811115614a7557fe5b614c8b61562a565b915061446b9050565b50979650505050505050565b614ca861562a565b60408083015190840151614cc19163ffffffff613b3f16565b604082015260608083015190840151614cdf9163ffffffff613b3f16565b606082015281516020840151614cfa9163ffffffff613b3f16565b6020808301919091528201518351614d179163ffffffff613b3f16565b815260808083015190840151614d329163ffffffff613b3f16565b608082015260a08083015190840151614d509163ffffffff613b3f16565b60a082015260c08083015190840151614d6e9163ffffffff613b3f16565b60c082015260e08083015190840151614d8c9163ffffffff613b3f16565b60e08201526101008083015190840151614dab9163ffffffff613b3f16565b61010082015292915050565b600080614dc58585856146b9565b6714d1120d7b1600001195945050505050565b614de061562a565b614de8615762565b614df184611fe8565b60408501908152602085810192835286019290925291845290519051614e1b918891889190614798565b614e2484614748565b614e3182602001516154b9565b60408301819052680ad78ebc5ac620000060608401526020830151600091614e5f919063ffffffff612aff16565b9050614e70836000015182866154c0565b60e087015260c086015260a08501526080840152614e8f8560036145a0565b846001600160a01b031660008051602061578483398151915284600001518560200151600160405180848152602001838152602001826003811115614ed057fe5b60ff168152602001935050505060405180910390a2846001600160a01b03166000805160206158a68339815191526000806000600160405180858152602001848152602001838152602001826003811115614f2757fe5b60ff16815260200194505050505060405180910390a25050949350505050565b6000818310614f565781612b41565b5090919050565b60008183614fac5760405162461bcd60e51b81526020600482018181528351602484015283519092839260449091019190850190808383600083156148ee5781810151838201526020016148d6565b506000838581614fb857fe5b0495945050505050565b60006111ea603c6113c0600d5442612aff90919063ffffffff16565b6000631f540500821115614ff457631f54050091505b816150085750670de0b6b3a7640000610d75565b670de0b6b3a764000083835b600181111561507f57600281066150495761502f82836155c6565b915061504281600263ffffffff61357116565b905061507a565b61505382846155c6565b925061505f82836155c6565b915061507760026113c083600163ffffffff612aff16565b90505b615014565b6113cc82846155c6565b6040808501516006548251632770a7eb60e21b81526001600160a01b039182166004820152602481018690529251911691639dc29fac91604480830192600092919082900301818387803b1580156150e057600080fd5b505af11580156150f4573d6000803e3d6000fd5b5050505083600001516001600160a01b03166338d995a8836040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b15801561514257600080fd5b505af1158015615156573d6000803e3d6000fd5b505050508360a001516001600160a01b0316633f10abab84836040518363ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200182815260200192505050600060405180830381600087803b1580156151be57600080fd5b505af11580156151d2573d6000803e3d6000fd5b5050505083600001516001600160a01b03166364a197f38560a00151836040518363ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200182815260200192505050600060405180830381600087803b15801561343e57600080fd5b6000610d7582680ad78ebc5ac620000063ffffffff612aff16565b6001811180156152d75750600b546040805163de8fa43160e01b815290516001926001600160a01b03169163de8fa431916004808301926020929190829003018186803b1580156152a957600080fd5b505afa1580156152bd573d6000803e3d6000fd5b505050506040513d60208110156152d357600080fd5b5051115b610d205760405162461bcd60e51b815260040180806020018281038252602a8152602001806157cd602a913960400191505060405180910390fd5b6001600160a01b0382166000908152600e602052604081206003015460ff169081600481111561533e57fe5b141580156153585750600181600481111561535557fe5b14155b61535e57fe5b6001600160a01b0383166000908152600e602052604081206003015461010090046001600160801b0316908390615396826001612aff565b905080836001600160801b031611156153ab57fe5b6000601582815481106153ba57fe5b600091825260209091200154601580546001600160a01b03909216925082916001600160801b0387169081106153ec57fe5b600091825260208083209190910180546001600160a01b0319166001600160a01b03948516179055918316808252600e83526040918290206003018054610100600160881b0319166101006001600160801b038a169081029190911790915582519182529281019290925280517f02b04ae5f7be9ca7c103293a2aa15f3c339d15d6eda53b721fef7b0e609c831a9281900390910190a1601580548061548e57fe5b600082815260209020810160001990810180546001600160a01b031916905501905550505050505050565b60c8900490565b60008080808415615516576154d58786614f47565b93506154eb876113c0888763ffffffff61351816565b92506154fd878563ffffffff612aff16565b915061550f868463ffffffff612aff16565b9050615523565b5060009250829150859050845b93509350935093565b61553461562a565b83815260208101839052600061555c836113c087670f43fc2c04ee000063ffffffff61351816565b9050615567816154b9565b60408301819052680ad78ebc5ac620000060608401526080830186905261559590829063ffffffff612aff16565b60a08301526155aa848263ffffffff612aff16565b61010083015250600060c0820181905260e08201529392505050565b6000806155d9848463ffffffff61351816565b9050613ddc670de0b6b3a76400006113c0836706f05b59d3b20000613b3f565b6040518060a00160405280600081526020016000815260200160001515815260200160008152602001600081525090565b6040518061012001604052806000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081525090565b6040805160e081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c081019190915290565b60405180610100016040528060008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081525090565b604051806060016040528060008152602001600081526020016000151581525090565b6040518060e0016040528060008152602001600081526020016000815260200160006001600160a01b0316815260200160001515815260200160008152602001600081525090565b6040518060600160405280600081526020016000815260200160008152509056feea67486ed7ebe3eea8ab3390efd4a3c8aae48be5bea27df104a8af786c40843454726f76654d616e616765723a20556e61626c6520746f2072656465656d20616e7920616d6f756e7454726f76654d616e616765723a204f6e6c79206f6e652074726f766520696e207468652073797374656d54726f76654d616e616765723a20526564656d7074696f6e7320617265206e6f7420616c6c6f77656420647572696e6720626f6f747374726170207068617365536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f7754726f76654d616e616765723a2052657175657374656420726564656d7074696f6e20616d6f756e74206d757374206265203c3d20757365722773204c55534420746f6b656e2062616c616e6365c3770d654ed33aeea6bf11ac8ef05d02a6a04ed4686dd2f624d853bbec43cc8b54726f76654d616e616765723a2043616c6c6572206973206e6f742074686520426f72726f7765724f7065726174696f6e7320636f6e747261637454726f76654d616e616765723a2043616c6c646174612061646472657373206172726179206d757374206e6f7420626520656d70747954726f76654d616e616765723a20416d6f756e74206d7573742062652067726561746572207468616e207a65726f54726f76654d616e616765723a2046656520776f756c642065617420757020616c6c2072657475726e656420636f6c6c61746572616c4d6178206665652070657263656e74616765206d757374206265206265747765656e20302e352520616e64203130302554726f76654d616e616765723a2043616e6e6f742072656465656d207768656e20544352203c204d435254726f76654d616e616765723a206e6f7468696e6720746f206c697175696461746554726f76654d616e616765723a2054726f766520646f6573206e6f74206578697374206f7220697320636c6f736564a26469706673582212208d92ce50005efdbaea8e59a3472b816f5c5d74d966255c366acda81d9f82209f64736f6c634300060b0033
Deployed Bytecode
0x608060405234801561001057600080fd5b506004361061044a5760003560e01c8063795d26c31161023c578063b83f91a211610146578063d3d6f843116100c3578063e2ac77b011610087578063e2ac77b014610c67578063f34862de14610c8d578063f36b242514610cb3578063f92d34331461065d578063fe2ba84814610cbb5761044a565b8063d3d6f84314610bd3578063d5b3563514610bff578063d66a255314610c1c578063d9a7244414610c42578063dba1c5f214610c5f5761044a565b8063c52861f21161010a578063c52861f214610b69578063c7b5548114610b71578063cbd138ae14610b79578063d293c71014610b9f578063d380a37c14610bcb5761044a565b8063b83f91a214610ab7578063b91af97c14610abf578063bcd3752614610b0b578063bf9befb114610b59578063c35bc55014610b615761044a565b806396d711ff116101d4578063a3f4df7e11610198578063a3f4df7e146109e7578063ae91875414610a64578063b0d8e18114610a6c578063b7f8cf9b14610a92578063b82f263d14610a9a5761044a565b806396d711ff146109a35780639976cf45146109ab5780639dd233d2146109d7578063a20baee614610894578063a3a64017146109df5761044a565b8063795d26c3146108c9578063797250e3146108d15780637985c5e4146108d95780637f7dde4a14610955578063807d138d1461095d57806382fe3eb914610965578063887105d31461098b5780638da5cb5b146109935780638f32d59b1461099b5761044a565b8063477d66cf11610358578063631203b0116102d557806372423c171161029957806372423c171461086857806372fe25aa14610894578063741bef1a1461089c578063756b253e146108a4578063794e5724146108c15761044a565b8063631203b01461079157806364cee260146107ae578063653d46e7146107d457806366ca4a21146107f15780636ef64338146107f95761044a565b80635733d58f1161031c5780635733d58f146107275780635d6b480f1461072f5780635d8c96091461075b5780635dba4c4a1461078157806361ec893d146107895761044a565b8063477d66cf146106a3578063480cd578146106c05780634870dd9a146106e657806349eefeee146106ee5780634e443d9e146106f65761044a565b80631e8b1c2b116103e657806328d28b5b116103aa57806328d28b5b1461065d5780632b11551a146106655780632e86bbd81461066d5780632f865568146106755780633cc742251461069b5761044a565b80631e8b1c2b1461057c5780631f68f20a1461061f5780631f7af3c31461062757806321e378011461062f57806324092669146106555761044a565b8063048c661d1461044f578063060d49a314610473578063071a75411461048d5780630b0765571461049557806312610e92146104bd57806315d549f1146104e95780631673c79a1461050f57806318f2817a1461054e5780631bf4355514610574575b600080fd5b610457610ce1565b604080516001600160a01b039092168252519081900360200190f35b61047b610cf0565b60408051918252519081900360200190f35b61047b610cf6565b6104bb600480360360208110156104ab57600080fd5b50356001600160a01b0316610cfb565b005b61047b600480360360408110156104d357600080fd5b506001600160a01b038135169060200135610d23565b61047b600480360360208110156104ff57600080fd5b50356001600160a01b0316610d7b565b6105356004803603602081101561052557600080fd5b50356001600160a01b0316610d9f565b6040805192835260208301919091528051918290030190f35b61047b6004803603602081101561056457600080fd5b50356001600160a01b0316610db8565b61047b610dcb565b6104bb6004803603602081101561059257600080fd5b8101906020810181356401000000008111156105ad57600080fd5b8201836020820111156105bf57600080fd5b803590602001918460208302840111640100000000831117156105e157600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250929550610dd8945050505050565b61047b61117a565b610457611180565b61047b6004803603602081101561064557600080fd5b50356001600160a01b031661118f565b61047b6111b9565b61047b6111cc565b61047b6111dd565b61047b6111ef565b6104bb6004803603602081101561068b57600080fd5b50356001600160a01b03166111fc565b610457611262565b61047b600480360360208110156106b957600080fd5b5035611271565b61047b600480360360208110156106d657600080fd5b50356001600160a01b0316611284565b61047b6112a2565b61047b6112a7565b6107136004803603602081101561070c57600080fd5b50356112ad565b604080519115158252519081900360200190f35b61047b6112b8565b6104bb6004803603604081101561074557600080fd5b506001600160a01b0381351690602001356112c4565b61047b6004803603602081101561077157600080fd5b50356001600160a01b0316611310565b6104bb6113d6565b61047b61143c565b61047b600480360360208110156107a757600080fd5b5035611441565b61047b600480360360208110156107c457600080fd5b50356001600160a01b031661144e565b6104bb600480360360208110156107ea57600080fd5b503561146c565b61047b61181a565b61081f6004803603602081101561080f57600080fd5b50356001600160a01b031661182c565b6040518086815260200185815260200184815260200183600481111561084157fe5b60ff1681526001600160801b03909216602083015250604080519182900301945092505050f35b61047b6004803603604081101561087e57600080fd5b506001600160a01b038135169060200135611866565b61047b6118c3565b6104576118cf565b610457600480360360208110156108ba57600080fd5b50356118de565b61047b611905565b61047b611911565b61047b611a12565b6104bb60048036036101608110156108f057600080fd5b506001600160a01b038135811691602081013582169160408201358116916060810135821691608082013581169160a081013582169160c082013581169160e08101358216916101008201358116916101208101358216916101409091013516611a18565b610457611e11565b61047b611e20565b6104bb6004803603602081101561097b57600080fd5b50356001600160a01b0316611e26565b61047b611e37565b610457611ef3565b610713611f02565b61047b611f13565b61047b600480360360408110156109c157600080fd5b506001600160a01b038135169060200135611f19565b61047b611f4c565b610457611f52565b6109ef611f61565b6040805160208082528351818301528351919283929083019185019080838360005b83811015610a29578181015183820152602001610a11565b50505050905090810190601f168015610a565780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b610457611f89565b61047b60048036036020811015610a8257600080fd5b50356001600160a01b0316611f98565b610457611fbf565b61047b60048036036020811015610ab057600080fd5b5035611fce565b610457611fd9565b610ae560048036036020811015610ad557600080fd5b50356001600160a01b0316611fe8565b604080519485526020850193909352838301919091526060830152519081900360800190f35b6104bb600480360360e0811015610b2157600080fd5b508035906001600160a01b03602082013581169160408101358216916060820135169060808101359060a08101359060c0013561204c565b61047b6127ee565b61047b6127f4565b61047b6127fb565b61047b61280d565b6104bb60048036036020811015610b8f57600080fd5b50356001600160a01b0316612819565b61047b60048036036040811015610bb557600080fd5b506001600160a01b03813516906020013561282c565b61047b61284b565b61047b60048036036040811015610be957600080fd5b506001600160a01b038135169060200135612851565b61047b60048036036020811015610c1557600080fd5b5035612887565b61047b60048036036020811015610c3257600080fd5b50356001600160a01b031661289a565b61045760048036036020811015610c5857600080fd5b50356128b5565b61047b6128df565b61071360048036036020811015610c7d57600080fd5b50356001600160a01b03166128e5565b61047b60048036036020811015610ca357600080fd5b50356001600160a01b0316612943565b61047b612974565b6104bb60048036036020811015610cd157600080fd5b50356001600160a01b0316612981565b6005546001600160a01b031681565b60175481565b600281565b610d03612992565b600054600154610d20916001600160a01b039081169116836129dd565b50565b6000610d2d612992565b6001600160a01b0383166000908152600e6020526040812054610d56908463ffffffff612aff16565b6001600160a01b0385166000908152600e602052604090208190559150505b92915050565b6000610d85612992565b610d8e82612b48565b6001600160801b031690505b919050565b6014602052600090815260409020805460019091015482565b6000610dc2612992565b610d7582612be2565b686194049f30f720000081565b8051610e155760405162461bcd60e51b81526004018080602001828103825260368152602001806159016036913960400191505060405180910390fd5b6000546001546005546001600160a01b03928316929182169116610e376155f9565b610e3f61562a565b600260009054906101000a90046001600160a01b03166001600160a01b0316630fdb11cf6040518163ffffffff1660e01b8152600401602060405180830381600087803b158015610e8f57600080fd5b505af1158015610ea3573d6000803e3d6000fd5b505050506040513d6020811015610eb957600080fd5b50518252604080516326fcbc6b60e21b815290516001600160a01b03851691639bf2f1ac916004808301926020929190829003018186803b158015610efd57600080fd5b505afa158015610f11573d6000803e3d6000fd5b505050506040513d6020811015610f2757600080fd5b505160208301528151610f3990612c91565b1580156040840152610f6157610f5a8585846000015185602001518a612cae565b9050610f79565b610f768585846000015185602001518a612ec9565b90505b6000816020015111610fbc5760405162461bcd60e51b81526004018080602001828103825260228152602001806159f56022913960400191505060405180910390fd5b826001600160a01b031663335525ad82608001518360a001516040518363ffffffff1660e01b81526004018083815260200182815260200192505050600060405180830381600087803b15801561101257600080fd5b505af1158015611026573d6000803e3d6000fd5b5050505061103e85858360c001518460e00151612f91565b610100810151156110bd57600754610100820151604080516364a197f360e01b81526001600160a01b039384166004820152602481019290925251918716916364a197f39160448082019260009290919082900301818387803b1580156110a457600080fd5b505af11580156110b8573d6000803e3d6000fd5b505050505b6110cb858260400151613212565b602081015160608301526101008101516040820151825161110392916110f7919063ffffffff612aff16565b9063ffffffff612aff16565b608080840182905260608085015160408086015186840151825193845260208401969096528282015291810193909352517f4152c73dd2614c4f9fc35e8c9cf16013cd588c75b49a4c1673ecffdcbcda94039281900390910190a1611172853383606001518460400151613359565b505050505050565b600c5481565b6009546001600160a01b031681565b6001600160a01b0381166000908152600e602052604081206003015460ff166004811115610d7557fe5b6064670de0b6b3a76400005b0460050281565b6103e8670de0b6b3a76400006111c5565b60006111ea600c5461345c565b905090565b680ad78ebc5ac620000081565b61120581613492565b60408051600180825281830190925260609160208083019080368337019050509050818160008151811061123557fe5b60200260200101906001600160a01b031690816001600160a01b03168152505061125e81610dd8565b5050565b6001546001600160a01b031681565b6000610d7561127e61181a565b836134fa565b6001600160a01b03166000908152600e602052604090206001015490565b60c881565b60155490565b6000610d7582612c91565b6714d1120d7b16000081565b6112cc612992565b8060048111156112d857fe5b6001600160a01b0383166000908152600e60205260409020600301805460ff1916600183600481111561130757fe5b02179055505050565b6001600160a01b038116600090815260146020526040812054601254829061133e908363ffffffff612aff16565b9050801580611377575060016001600160a01b0385166000908152600e602052604090206003015460ff16600481111561137457fe5b14155b1561138757600092505050610d9a565b6001600160a01b0384166000908152600e6020526040812060020154906113cc670de0b6b3a76400006113c0848663ffffffff61351816565b9063ffffffff61357116565b9695505050505050565b6113de612992565b60006113e86135b3565b9050670de0b6b3a76400008111156113fc57fe5b600c8190556040805182815290517fc454ee9b76c52f782a256af821b857ca6e125d1e3333bcede402fec2bed9600c9181900360200190a1610d206135f7565b603c81565b6000610d7561127e612974565b6001600160a01b03166000908152600e602052604090206002015490565b611474615676565b506040805160e081018252600080546001600160a01b0390811683526001548116602084015292820181905260608201819052600b548316608083015260a0820181905260c08201526005549091166114cb6155f9565b6114d361562a565b600260009054906101000a90046001600160a01b03166001600160a01b0316630fdb11cf6040518163ffffffff1660e01b8152600401602060405180830381600087803b15801561152357600080fd5b505af1158015611537573d6000803e3d6000fd5b505050506040513d602081101561154d57600080fd5b50518252604080516326fcbc6b60e21b815290516001600160a01b03851691639bf2f1ac916004808301926020929190829003018186803b15801561159157600080fd5b505afa1580156115a5573d6000803e3d6000fd5b505050506040513d60208110156115bb57600080fd5b5051602083015281516115cd90612c91565b15801560408401526115f4576115ed848360000151846020015188613653565b9050611614565b6116118460000151856020015184600001518560200151896139e6565b90505b60008160200151116116575760405162461bcd60e51b81526004018080602001828103825260228152602001806159f56022913960400191505060405180910390fd5b826001600160a01b031663335525ad82608001518360a001516040518363ffffffff1660e01b81526004018083815260200182815260200192505050600060405180830381600087803b1580156116ad57600080fd5b505af11580156116c1573d6000803e3d6000fd5b505050506116e1846000015185602001518360c001518460e00151612f91565b61010081015115611762578351600754610100830151604080516364a197f360e01b81526001600160a01b03938416600482015260248101929092525191909216916364a197f391604480830192600092919082900301818387803b15801561174957600080fd5b505af115801561175d573d6000803e3d6000fd5b505050505b61177484600001518260400151613212565b60208101516060830152610100810151604082015182516117a092916110f7919063ffffffff612aff16565b608080840182905260608085015160408086015186840151825193845260208401969096528282015291810193909352517f4152c73dd2614c4f9fc35e8c9cf16013cd588c75b49a4c1673ecffdcbcda94039281900390910190a161181384600001513383606001518460400151613359565b5050505050565b60006111ea6118276135b3565b613b18565b600e6020526000908152604090208054600182015460028301546003909301549192909160ff81169061010090046001600160801b031685565b6000611870612992565b6001600160a01b0383166000908152600e602052604081206001015461189c908463ffffffff613b3f16565b6001600160a01b0385166000908152600e6020526040902060010181905591505092915050565b670de0b6b3a764000081565b6002546001600160a01b031681565b601581815481106118eb57fe5b6000918252602090912001546001600160a01b0316905081565b670f43fc2c04ee000081565b6000805460408051632f5a97e560e11b8152905183926001600160a01b031691635eb52fca916004808301926020929190829003018186803b15801561195657600080fd5b505afa15801561196a573d6000803e3d6000fd5b505050506040513d602081101561198057600080fd5b505160015460408051632f5a97e560e11b815290519293506000926001600160a01b0390921691635eb52fca91600480820192602092909190829003018186803b1580156119cd57600080fd5b505afa1580156119e1573d6000803e3d6000fd5b505050506040513d60208110156119f757600080fd5b50519050611a0b828263ffffffff613b3f16565b9250505090565b60165481565b611a20611f02565b611a71576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b611a7a8b613b99565b611a838a613b99565b611a8c89613b99565b611a9588613b99565b611a9e87613b99565b611aa786613b99565b611ab085613b99565b611ab984613b99565b611ac283613b99565b611acb82613b99565b611ad481613b99565b600480546001600160a01b03199081166001600160a01b038e81169182179093556000805483168e85161790556001805483168d85161790556005805483168c85161790556006805483168b85161790556007805483168a8516179055600280548316898516179055600880548316888516179055600b80548316878516179055600980548316868516179055600a805490921692841692909217905560408051918252517f3ca631ffcd2a9b5d9ae18543fc82f58eb4ca33af9e6ab01b7a8e95331e6ed985916020908290030190a1604080516001600160a01b038c16815290517f78f058b189175430c48dc02699e3a0031ea4ff781536dc2fab847de4babdd8829181900360200190a1604080516001600160a01b038b16815290517f5ee0cae2f063ed938bb55046f6a932fb6ae792bf43624806bb90abe68a50be9b9181900360200190a1604080516001600160a01b038a16815290517f82966d27eea39b038ee0fa30cd16532bb24f6e65d31cb58fb227aa5766cdcc7f9181900360200190a1604080516001600160a01b038916815290517fcfb07d791fcafc032b35837b50eb84b74df518cf4cc287e8084f47630fa70fa09181900360200190a1604080516001600160a01b038816815290517fe67f36a6e961157d6eff83b91f3af5a62131ceb6f04954ef74f51c1c05e7f88d9181900360200190a1604080516001600160a01b038716815290517f8c537274438aa850a330284665d81a85dd38267d09e4050d416bfc94142db2649181900360200190a1604080516001600160a01b038616815290517f227eec0ec317af6ab1a9587ffa1c84332522eb4c583a908f89babc05f8f339bd9181900360200190a1604080516001600160a01b038516815290517f65f4cf077bc01e4742eb5ad98326f6e95b63548ea24b17f8d5e823111fe788009181900360200190a1604080516001600160a01b038416815290517f2ac6e99201ddc1b6eac6f8f28662d1ecafee131f6eb98c29de54528a9888a7d19181900360200190a1604080516001600160a01b038316815290517f756ebc192164c295bba134b5aacd72cc7aff8098a670d1f0a5f6b3a0b4ce67079181900360200190a1611e04613c48565b5050505050505050505050565b6000546001600160a01b031681565b60105481565b611e2e612992565b610d2081613c92565b6000805460408051630a7b61df60e11b8152905183926001600160a01b0316916314f6c3be916004808301926020929190829003018186803b158015611e7c57600080fd5b505afa158015611e90573d6000803e3d6000fd5b505050506040513d6020811015611ea657600080fd5b505160015460408051630a7b61df60e11b815290519293506000926001600160a01b03909216916314f6c3be91600480820192602092909190829003018186803b1580156119cd57600080fd5b6003546001600160a01b031690565b6003546001600160a01b0316331490565b60115481565b6000611f23612992565b6001600160a01b0383166000908152600e6020526040812054610d56908463ffffffff613b3f16565b60125481565b600a546001600160a01b031681565b6040518060400160405280600c81526020016b2a3937bb32a6b0b730b3b2b960a11b81525081565b600b546001600160a01b031681565b6000806000611fa684613cfd565b915091506000611fb68383613d83565b95945050505050565b6004546001600160a01b031681565b6000610d7582613db8565b6008546001600160a01b031681565b6001600160a01b0381166000908152600e60205260408120805460019091015490918061201485612943565b915061201f85611310565b9050612031848363ffffffff613b3f16565b9350612043838263ffffffff613b3f16565b92509193509193565b612054615676565b506040805160e0810182526000546001600160a01b03908116825260015481166020830152600854811692820192909252600a5482166060820152600b5482166080820152600754821660a082015260065490911660c08201526120b66156b2565b6120bf83613de4565b6120c7613e3e565b600260009054906101000a90046001600160a01b03166001600160a01b0316630fdb11cf6040518163ffffffff1660e01b8152600401602060405180830381600087803b15801561211757600080fd5b505af115801561212b573d6000803e3d6000fd5b505050506040513d602081101561214157600080fd5b505160c0820181905261215390613f02565b61215c89613f51565b61216b8260400151338b613f90565b612173611911565b60e0820181905260408084015181516370a0823160e01b815233600482015291516001600160a01b03909116916370a08231916024808301926020929190829003018186803b1580156121c557600080fd5b505afa1580156121d9573d6000803e3d6000fd5b505050506040513d60208110156121ef57600080fd5b505111156121f957fe5b888152608082015160c0820151600091612214918b90614050565b1561222057508761234a565b82608001516001600160a01b0316634d6228316040518163ffffffff1660e01b815260040160206040518083038186803b15801561225d57600080fd5b505afa158015612271573d6000803e3d6000fd5b505050506040513d602081101561228757600080fd5b505190505b6001600160a01b038116158015906122b85750670f43fc2c04ee00006122b6828460c0015161282c565b105b1561234a5782608001516001600160a01b031663b72703ac826040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b15801561231757600080fd5b505afa15801561232b573d6000803e3d6000fd5b505050506040513d602081101561234157600080fd5b5051905061228c565b846123555760001994505b6001600160a01b0381161580159061236d5750815115155b80156123795750600085115b156124ad57848060019003955050600083608001516001600160a01b031663b72703ac836040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b1580156123e357600080fd5b505afa1580156123f7573d6000803e3d6000fd5b505050506040513d602081101561240d57600080fd5b50518451602086015191925061242391846129dd565b61242b6156f7565b612442858486600001518760c001518e8e8e6141c3565b90508060400151156124555750506124ad565b8051602085015161246b9163ffffffff613b3f16565b602080860191909152810151604085015161248b9163ffffffff613b3f16565b6040850152805184516124a39163ffffffff612aff16565b8452509050612355565b60008260400151116124f05760405162461bcd60e51b81526004018080602001828103825260298152602001806157a46029913960400191505060405180910390fd5b61250782604001518360c001518460e00151614476565b50612515826040015161451e565b60608301819052604083015161252c91908661452b565b82600001516001600160a01b03166364a197f3846060015184606001516040518363ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200182815260200192505050600060405180830381600087803b15801561259857600080fd5b505af11580156125ac573d6000803e3d6000fd5b5050505082606001516001600160a01b0316631e3e2a1a83606001516040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b1580156125fe57600080fd5b505af1158015612612573d6000803e3d6000fd5b505050506060820151604083015161262991612aff565b8260800181815250507f43a3f4082a4dbc33d78e317d2497d3a730bc7fc3574159dcea1056e62e5d9ad88a8360200151846040015185606001516040518085815260200184815260200183815260200182815260200194505050505060405180910390a182604001516001600160a01b0316639dc29fac3384602001516040518363ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200182815260200192505050600060405180830381600087803b1580156126f557600080fd5b505af1158015612709573d6000803e3d6000fd5b5050505082600001516001600160a01b03166338d995a883602001516040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b15801561275b57600080fd5b505af115801561276f573d6000803e3d6000fd5b505084516080850151604080516364a197f360e01b81523360048201526024810192909252516001600160a01b0390921693506364a197f3925060448082019260009290919082900301818387803b1580156127ca57600080fd5b505af11580156127de573d6000803e3d6000fd5b5050505050505050505050505050565b600f5481565b6212750081565b60006111ea6128086135b3565b61345c565b670ddd4b8c6c7d70d881565b612821612992565b610d208160026145a0565b600080600061283a85613cfd565b9150915060006113cc8383876146b9565b600d5481565b600061285b612992565b6001600160a01b0383166000908152600e602052604081206001015461189c908463ffffffff612aff16565b6000610d756128946127fb565b836146e9565b6001600160a01b03166000908152600e602052604090205490565b6000601582815481106128c457fe5b6000918252602090912001546001600160a01b031692915050565b60135481565b600060016001600160a01b0383166000908152600e602052604090206003015460ff16600481111561291357fe5b1461292057506000610d9a565b506012546001600160a01b03821660009081526014602052604090205410919050565b6001600160a01b038116600090815260146020526040812060010154601354829061133e908363ffffffff612aff16565b60006111ea600c54613b18565b612989612992565b610d2081614748565b6004546001600160a01b031633146129db5760405162461bcd60e51b815260040180806020018281038252603b8152602001806158c6603b913960400191505060405180910390fd5b565b6129e6816128e5565b15612afa576129f481613492565b60006129ff82611310565b90506000612a0c83612943565b6001600160a01b0384166000908152600e6020526040902060010154909150612a3b908363ffffffff613b3f16565b6001600160a01b0384166000908152600e60205260409020600181019190915554612a6c908263ffffffff613b3f16565b6001600160a01b0384166000908152600e6020526040902055612a8e83613c92565b612a9a85858385614798565b6001600160a01b0383166000818152600e602090815260408083208054600182015460029092015483519182529381019190915280820192909252606082019290925290516000805160206158a68339815191529181900360800190a250505b505050565b6000612b4183836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f77000081525061489a565b9392505050565b601580546001808201835560008381527f55f448fdea98c4d29eb340757ef0a66cd03dbb9538908a6a81d96026b71ec47590920180546001600160a01b0319166001600160a01b03861617905591549091612ba39190612aff565b6001600160a01b03929092166000908152600e602052604090206003018054610100600160881b0319166101006001600160801b038516021790555090565b6001600160a01b0381166000908152600e60205260408120600101548190612c0990614931565b6001600160a01b0384166000908152600e60205260409020600201805490829055600f5491925090612c53908390612c47908463ffffffff612aff16565b9063ffffffff613b3f16565b600f81905560408051918252517f6bac5e0eb3c44eb03a60ab11ec3a2c051771616aecadbcfff2630aabae5203829181900360200190a15092915050565b600080612c9d83613db8565b6714d1120d7b160000119392505050565b612cb661562a565b612cbe61571a565b612cc661562a565b84825260006080830152612cd8611911565b60a0830152612ce5611e37565b60c0830152600060208301525b835182602001511015612ebe5783826020015181518110612d0f57fe5b6020908102919091018101516001600160a01b0316606084018190526000908152600e909152604090206003015460019060ff166004811115612d4e57fe5b14612d5857612eae565b612d6682606001518761282c565b60408301526080820151612e5057670f43fc2c04ee0000826040015110158015612d8f57508151155b15612d9957612eae565b6000612dae8360c001518460a00151896146b9565b9050612dcb8989856060015186604001518760000151868d61496d565b60808101518451919350612de5919063ffffffff612aff16565b8352608082015160a0840151612e009163ffffffff612aff16565b60a08085019190915282015160c0840151612e209163ffffffff612aff16565b60c0840152612e2f8483614ca0565b9350612e448360c001518460a0015189614db7565b15608084015250612eae565b81608001518015612e6c5750670f43fc2c04ee00008260400151105b15612eae57612e85888884606001518560000151614dd8565b60808101518351919250612e9f919063ffffffff612aff16565b8252612eab8382614ca0565b92505b6020820180516001019052612cf2565b505095945050505050565b612ed161562a565b612ed961571a565b612ee161562a565b848252600060208301525b835182602001511015612ebe5783826020015181518110612f0957fe5b60209081029190910101516001600160a01b031660608301819052612f2e908761282c565b60408301819052670f43fc2c04ee00001115612f8157612f58888884606001518560000151614dd8565b60808101518351919250612f72919063ffffffff612aff16565b8252612f7e8382614ca0565b92505b6020820180516001019052612eec565b81612f9b5761320c565b601654600090612fbd90612c4784670de0b6b3a764000063ffffffff61351816565b90506000612fe2601754612c47670de0b6b3a76400008761351890919063ffffffff16565b90506000612ffb600f548461357190919063ffffffff16565b90506000613014600f548461357190919063ffffffff16565b905061303b61302e600f548461351890919063ffffffff16565b859063ffffffff612aff16565b601655600f546130639061305690839063ffffffff61351816565b849063ffffffff612aff16565b601755601254613079908363ffffffff613b3f16565b60125560135461308f908263ffffffff613b3f16565b601381905560125460408051918252602082019290925281517f9f8bc8ab0daf5bceef75ecfd2085d1fcc6548c657ea970d9a23a60610d0737e3929181900390910190a1876001600160a01b03166338d995a8876040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b15801561311957600080fd5b505af115801561312d573d6000803e3d6000fd5b50505050866001600160a01b031663cfb9329a876040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b15801561317757600080fd5b505af115801561318b573d6000803e3d6000fd5b50505050876001600160a01b03166364a197f388876040518363ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200182815260200192505050600060405180830381600087803b1580156131ef57600080fd5b505af1158015613203573d6000803e3d6000fd5b50505050505050505b50505050565b600f546010819055506000826001600160a01b03166314f6c3be6040518163ffffffff1660e01b815260040160206040518083038186803b15801561325657600080fd5b505afa15801561326a573d6000803e3d6000fd5b505050506040513d602081101561328057600080fd5b505160015460408051630a7b61df60e11b815290519293506000926001600160a01b03909216916314f6c3be91600480820192602092909190829003018186803b1580156132cd57600080fd5b505afa1580156132e1573d6000803e3d6000fd5b505050506040513d60208110156132f757600080fd5b5051905061330f81612c47848663ffffffff612aff16565b601181905560105460408051918252602082019290925281517f51bf4c63ec3cba9d03d43238abbdd979dd91bd16d9895c74ceea9118c7baaf60929181900390910190a150505050565b81156133d85760085460065460408051631062c15f60e11b81526001600160a01b039283166004820152868316602482015260448101869052905191909216916320c582be91606480830192600092919082900301818387803b1580156133bf57600080fd5b505af11580156133d3573d6000803e3d6000fd5b505050505b801561320c57836001600160a01b03166364a197f384836040518363ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200182815260200192505050600060405180830381600087803b15801561343e57600080fd5b505af1158015613452573d6000803e3d6000fd5b5050505050505050565b6000610d75613484836103e8670de0b6b3a76400005b04600502613b3f90919063ffffffff16565b670de0b6b3a7640000614f47565b60016001600160a01b0382166000908152600e602052604090206003015460ff1660048111156134be57fe5b14610d205760405162461bcd60e51b815260040180806020018281038252602f815260200180615a17602f913960400191505060405180910390fd5b6000612b41670de0b6b3a76400006113c0858563ffffffff61351816565b60008261352757506000610d75565b8282028284828161353457fe5b0414612b415760405162461bcd60e51b81526004018080602001828103825260218152602001806158376021913960400191505060405180910390fd5b6000612b4183836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250614f5d565b6000806135be614fc2565b905060006135d4670ddd4b8c6c7d70d883614fde565b9050611a0b670de0b6b3a76400006113c083600c5461351890919063ffffffff16565b600061360e600d5442612aff90919063ffffffff16565b9050603c8110610d205742600d81905560408051918252517f860f8d2f0c74dd487e89e2883e3b25b8159ce1e1b3433a291cba7b82c508f3bc9181900360200190a150565b61365b61562a565b61366361571a565b61366b61562a565b8482526000608083015261367d611911565b60a083015261368a611e37565b8260c001818152505086608001516001600160a01b0316634d6228316040518163ffffffff1660e01b815260040160206040518083038186803b1580156136d057600080fd5b505afa1580156136e4573d6000803e3d6000fd5b505050506040513d60208110156136fa57600080fd5b50516001600160a01b039081166060840152608088015160408051631e22314360e01b815290516000939290921691631e22314391600480820192602092909190829003018186803b15801561374f57600080fd5b505afa158015613763573d6000803e3d6000fd5b505050506040513d602081101561377957600080fd5b50516000602085015290505b8483602001511080156137ae5750806001600160a01b031683606001516001600160a01b031614155b156139db57600088608001516001600160a01b031663b72703ac85606001516040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b15801561381357600080fd5b505afa158015613827573d6000803e3d6000fd5b505050506040513d602081101561383d57600080fd5b50516060850151909150613851908961282c565b6040850152608084015161394d57670f43fc2c04ee000084604001511015801561387a57508351155b1561388557506139db565b600061389a8560c001518660a001518b6146b9565b8a5160208c01516060880151604089015189519495506138bb94868f61496d565b608081015186519195506138d5919063ffffffff612aff16565b8552608084015160a08601516138f09163ffffffff612aff16565b8560a001818152505061391d8461010001516110f78660a001518860c00151612aff90919063ffffffff16565b60c086015261392c8685614ca0565b95506139418560c001518660a001518b614db7565b156080860152506139bd565b836080015180156139695750670f43fc2c04ee00008460400151105b156139b75761398a89600001518a6020015186606001518760000151614dd8565b608081015185519194506139a4919063ffffffff612aff16565b84526139b08584614ca0565b94506139bd565b506139db565b6001600160a01b031660608401526020830180516001019052613785565b505050949350505050565b6139ee61562a565b6139f661571a565b6139fe61562a565b600b54858352600060208401526001600160a01b03165b8483602001511015613b0c57806001600160a01b0316634d6228316040518163ffffffff1660e01b815260040160206040518083038186803b158015613a5a57600080fd5b505afa158015613a6e573d6000803e3d6000fd5b505050506040513d6020811015613a8457600080fd5b50516001600160a01b031660608401819052613aa0908861282c565b60408401819052670f43fc2c04ee00001115613af757613aca898985606001518660000151614dd8565b60808101518451919350613ae4919063ffffffff612aff16565b8352613af08483614ca0565b9350613afc565b613b0c565b6020830180516001019052613a15565b50505095945050505050565b6000610d75613b32836103e8670de0b6b3a7640000613472565b66b1a2bc2ec50000614f47565b600082820183811015612b41576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b6001600160a01b038116613bf4576040805162461bcd60e51b815260206004820152601e60248201527f4163636f756e742063616e6e6f74206265207a65726f20616464726573730000604482015290519081900360640190fd5b803b8061125e576040805162461bcd60e51b815260206004820181905260248201527f4163636f756e7420636f64652073697a652063616e6e6f74206265207a65726f604482015290519081900360640190fd5b6003546040516000916001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600380546001600160a01b0319169055565b601280546001600160a01b0383166000908152601460209081526040918290209283556013546001909301839055925481519081529283019190915280517fc437f324d85e369394148dd9d62f98f534b382e01ed3dd2eb98138fb6d3ab49a9281900390910190a150565b6000806000613d0b84611310565b90506000613d1885612943565b6001600160a01b0386166000908152600e602052604081206001015491925090613d48908463ffffffff613b3f16565b6001600160a01b0387166000908152600e602052604081205491925090613d75908463ffffffff613b3f16565b919550909350505050915091565b60008115613daf57613da8826113c08568056bc75e2d6310000063ffffffff61351816565b9050610d75565b50600019610d75565b600080613dc3611e37565b90506000613dcf611911565b9050613ddc8282866146b9565b949350505050565b6611c37937e080008110801590613e035750670de0b6b3a76400008111155b610d205760405162461bcd60e51b815260040180806020018281038252603081526020018061599b6030913960400191505060405180910390fd5b60095460408051631e425be160e11b815290516000926001600160a01b031691633c84b7c2916004808301926020929190829003018186803b158015613e8357600080fd5b505afa158015613e97573d6000803e3d6000fd5b505050506040513d6020811015613ead57600080fd5b50519050613ec4816212750063ffffffff613b3f16565b421015610d205760405162461bcd60e51b81526004018080602001828103825260408152602001806157f76040913960400191505060405180910390fd5b670f43fc2c04ee0000613f1482613db8565b1015610d205760405162461bcd60e51b815260040180806020018281038252602a8152602001806159cb602a913960400191505060405180910390fd5b60008111610d205760405162461bcd60e51b815260040180806020018281038252602e815260200180615937602e913960400191505060405180910390fd5b80836001600160a01b03166370a08231846040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b158015613fe757600080fd5b505afa158015613ffb573d6000803e3d6000fd5b505050506040513d602081101561401157600080fd5b50511015612afa5760405162461bcd60e51b815260040180806020018281038252604e815260200180615858604e913960600191505060405180910390fd5b60006001600160a01b03831615806140e75750836001600160a01b0316635dbe47e8846040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b1580156140b957600080fd5b505afa1580156140cd573d6000803e3d6000fd5b505050506040513d60208110156140e357600080fd5b5051155b806141025750670f43fc2c04ee0000614100848461282c565b105b1561410f57506000612b41565b6000846001600160a01b031663765e0159856040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b15801561416757600080fd5b505afa15801561417b573d6000803e3d6000fd5b505050506040513d602081101561419157600080fd5b505190506001600160a01b0381161580611fb65750670f43fc2c04ee00006141b9828561282c565b1095945050505050565b6141cb6156f7565b6001600160a01b0387166000908152600e602052604090205461420890879061420390680ad78ebc5ac620000063ffffffff612aff16565b614f47565b8082526142299086906113c090670de0b6b3a764000063ffffffff61351816565b60208083019190915281516001600160a01b0389166000908152600e909252604082205461425c9163ffffffff612aff16565b6020808401516001600160a01b038b166000908152600e909252604082206001015492935090916142929163ffffffff612aff16565b9050680ad78ebc5ac620000082141561432b576142ae89614748565b6142b98960046145a0565b6142ce8a8a680ad78ebc5ac620000084615089565b886001600160a01b03166000805160206158a6833981519152600080600060036040518085815260200184815260200183815260200182600381111561431057fe5b60ff16815260200194505050505060405180910390a2614468565b60006143378284613d83565b905084811415806143585750686194049f30f72000006143568461523e565b105b1561436c575050600160408301525061446b565b60808b01516040805163015f109360e51b81526001600160a01b038d81166004830152602482018590528a81166044830152898116606483015291519190921691632be2126091608480830192600092919082900301818387803b1580156143d357600080fd5b505af11580156143e7573d6000803e3d6000fd5b5050506001600160a01b038b166000908152600e60205260409020848155600101839055506144158a612be2565b506001600160a01b038a166000818152600e6020908152604091829020600201548251878152918201869052818301526003606082015290516000805160206158a68339815191529181900360800190a2505b50505b979650505050505050565b6000806144816135b3565b90506000614499846113c0888863ffffffff61351816565b905060006144be6144b183600263ffffffff61357116565b849063ffffffff613b3f16565b90506144d281670de0b6b3a7640000614f47565b9050600081116144de57fe5b600c8190556040805182815290517fc454ee9b76c52f782a256af821b857ca6e125d1e3333bcede402fec2bed9600c9181900360200190a16113cc6135f7565b6000610d756128946111dd565b6000614549836113c086670de0b6b3a764000063ffffffff61351816565b90508181111561320c576040805162461bcd60e51b815260206004820152601d60248201527f4665652065786365656465642070726f7669646564206d6178696d756d000000604482015290519081900360640190fd5b60008160048111156145ae57fe5b141580156145c8575060018160048111156145c557fe5b14155b6145ce57fe5b6015546145da81615259565b6001600160a01b0383166000908152600e60205260409020600301805483919060ff1916600183600481111561460c57fe5b02179055506001600160a01b0383166000908152600e6020908152604080832060018082018590559084905560149092528220828155015561464e8382615312565b600b5460408051631484968760e11b81526001600160a01b038681166004830152915191909216916329092d0e91602480830192600092919082900301818387803b15801561469c57600080fd5b505af11580156146b0573d6000803e3d6000fd5b50505050505050565b600082156146e05760006146d7846113c0878663ffffffff61351816565b9150612b419050565b50600019612b41565b600080614708670de0b6b3a76400006113c0868663ffffffff61351816565b9050828110612b415760405162461bcd60e51b81526004018080602001828103825260368152602001806159656036913960400191505060405180910390fd5b6001600160a01b0381166000908152600e6020526040902060020154600f54614777908263ffffffff612aff16565b600f55506001600160a01b03166000908152600e6020526040812060020155565b826001600160a01b03166338d995a8836040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b1580156147de57600080fd5b505af11580156147f2573d6000803e3d6000fd5b50505050836001600160a01b031663cfb9329a836040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b15801561483c57600080fd5b505af1158015614850573d6000803e3d6000fd5b50505050826001600160a01b031663be41205f826040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b15801561343e57600080fd5b600081848411156149295760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b838110156148ee5781810151838201526020016148d6565b50505050905090810190601f16801561491b5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b60008060115460001415614946575081610d75565b60006010541161495257fe5b612b416011546113c06010548661351890919063ffffffff16565b61497561562a565b61497d615762565b60155460011061498d575061446b565b61499687611fe8565b604085015260208481019190915284018190529083526149b5906154b9565b60408301819052680ad78ebc5ac6200000606084015260208301516149df9163ffffffff612aff16565b8152670de0b6b3a76400008611614ae757614a04898983602001518460400151614798565b614a0d87614748565b60006080830181905260a0830152815160c0830152805160e0830152614a348760036145a0565b866001600160a01b031660008051602061578483398151915283600001518460200151600260405180848152602001838152602001826003811115614a7557fe5b60ff168152602001935050505060405180910390a2866001600160a01b03166000805160206158a68339815191526000806000600260405180858152602001848152602001838152602001826003811115614acc57fe5b60ff16815260200194505050505060405180910390a2614c94565b670de0b6b3a764000086118015614b055750670f43fc2c04ee000086105b15614b5557614b1e898983602001518460400151614798565b614b2787614748565b81518151614b369190876154c0565b60e086015260c085015260a08401526080830152614a348760036145a0565b670f43fc2c04ee00008610158015614b6c57508386105b8015614b79575081518510155b15614c8357614b92898983602001518460400151614798565b84614b9957fe5b614ba287614748565b614bb5826000015183602001518561552c565b9150614bc28760036145a0565b61010082015115614c425760075461010083015160408051633f10abab60e01b81526001600160a01b038b81166004830152602482019390935290519190921691633f10abab91604480830192600092919082900301818387803b158015614c2957600080fd5b505af1158015614c3d573d6000803e3d6000fd5b505050505b866001600160a01b031660008051602061578483398151915283600001518460a00151600260405180848152602001838152602001826003811115614a7557fe5b614c8b61562a565b915061446b9050565b50979650505050505050565b614ca861562a565b60408083015190840151614cc19163ffffffff613b3f16565b604082015260608083015190840151614cdf9163ffffffff613b3f16565b606082015281516020840151614cfa9163ffffffff613b3f16565b6020808301919091528201518351614d179163ffffffff613b3f16565b815260808083015190840151614d329163ffffffff613b3f16565b608082015260a08083015190840151614d509163ffffffff613b3f16565b60a082015260c08083015190840151614d6e9163ffffffff613b3f16565b60c082015260e08083015190840151614d8c9163ffffffff613b3f16565b60e08201526101008083015190840151614dab9163ffffffff613b3f16565b61010082015292915050565b600080614dc58585856146b9565b6714d1120d7b1600001195945050505050565b614de061562a565b614de8615762565b614df184611fe8565b60408501908152602085810192835286019290925291845290519051614e1b918891889190614798565b614e2484614748565b614e3182602001516154b9565b60408301819052680ad78ebc5ac620000060608401526020830151600091614e5f919063ffffffff612aff16565b9050614e70836000015182866154c0565b60e087015260c086015260a08501526080840152614e8f8560036145a0565b846001600160a01b031660008051602061578483398151915284600001518560200151600160405180848152602001838152602001826003811115614ed057fe5b60ff168152602001935050505060405180910390a2846001600160a01b03166000805160206158a68339815191526000806000600160405180858152602001848152602001838152602001826003811115614f2757fe5b60ff16815260200194505050505060405180910390a25050949350505050565b6000818310614f565781612b41565b5090919050565b60008183614fac5760405162461bcd60e51b81526020600482018181528351602484015283519092839260449091019190850190808383600083156148ee5781810151838201526020016148d6565b506000838581614fb857fe5b0495945050505050565b60006111ea603c6113c0600d5442612aff90919063ffffffff16565b6000631f540500821115614ff457631f54050091505b816150085750670de0b6b3a7640000610d75565b670de0b6b3a764000083835b600181111561507f57600281066150495761502f82836155c6565b915061504281600263ffffffff61357116565b905061507a565b61505382846155c6565b925061505f82836155c6565b915061507760026113c083600163ffffffff612aff16565b90505b615014565b6113cc82846155c6565b6040808501516006548251632770a7eb60e21b81526001600160a01b039182166004820152602481018690529251911691639dc29fac91604480830192600092919082900301818387803b1580156150e057600080fd5b505af11580156150f4573d6000803e3d6000fd5b5050505083600001516001600160a01b03166338d995a8836040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b15801561514257600080fd5b505af1158015615156573d6000803e3d6000fd5b505050508360a001516001600160a01b0316633f10abab84836040518363ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200182815260200192505050600060405180830381600087803b1580156151be57600080fd5b505af11580156151d2573d6000803e3d6000fd5b5050505083600001516001600160a01b03166364a197f38560a00151836040518363ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200182815260200192505050600060405180830381600087803b15801561343e57600080fd5b6000610d7582680ad78ebc5ac620000063ffffffff612aff16565b6001811180156152d75750600b546040805163de8fa43160e01b815290516001926001600160a01b03169163de8fa431916004808301926020929190829003018186803b1580156152a957600080fd5b505afa1580156152bd573d6000803e3d6000fd5b505050506040513d60208110156152d357600080fd5b5051115b610d205760405162461bcd60e51b815260040180806020018281038252602a8152602001806157cd602a913960400191505060405180910390fd5b6001600160a01b0382166000908152600e602052604081206003015460ff169081600481111561533e57fe5b141580156153585750600181600481111561535557fe5b14155b61535e57fe5b6001600160a01b0383166000908152600e602052604081206003015461010090046001600160801b0316908390615396826001612aff565b905080836001600160801b031611156153ab57fe5b6000601582815481106153ba57fe5b600091825260209091200154601580546001600160a01b03909216925082916001600160801b0387169081106153ec57fe5b600091825260208083209190910180546001600160a01b0319166001600160a01b03948516179055918316808252600e83526040918290206003018054610100600160881b0319166101006001600160801b038a169081029190911790915582519182529281019290925280517f02b04ae5f7be9ca7c103293a2aa15f3c339d15d6eda53b721fef7b0e609c831a9281900390910190a1601580548061548e57fe5b600082815260209020810160001990810180546001600160a01b031916905501905550505050505050565b60c8900490565b60008080808415615516576154d58786614f47565b93506154eb876113c0888763ffffffff61351816565b92506154fd878563ffffffff612aff16565b915061550f868463ffffffff612aff16565b9050615523565b5060009250829150859050845b93509350935093565b61553461562a565b83815260208101839052600061555c836113c087670f43fc2c04ee000063ffffffff61351816565b9050615567816154b9565b60408301819052680ad78ebc5ac620000060608401526080830186905261559590829063ffffffff612aff16565b60a08301526155aa848263ffffffff612aff16565b61010083015250600060c0820181905260e08201529392505050565b6000806155d9848463ffffffff61351816565b9050613ddc670de0b6b3a76400006113c0836706f05b59d3b20000613b3f565b6040518060a00160405280600081526020016000815260200160001515815260200160008152602001600081525090565b6040518061012001604052806000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081525090565b6040805160e081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c081019190915290565b60405180610100016040528060008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081525090565b604051806060016040528060008152602001600081526020016000151581525090565b6040518060e0016040528060008152602001600081526020016000815260200160006001600160a01b0316815260200160001515815260200160008152602001600081525090565b6040518060600160405280600081526020016000815260200160008152509056feea67486ed7ebe3eea8ab3390efd4a3c8aae48be5bea27df104a8af786c40843454726f76654d616e616765723a20556e61626c6520746f2072656465656d20616e7920616d6f756e7454726f76654d616e616765723a204f6e6c79206f6e652074726f766520696e207468652073797374656d54726f76654d616e616765723a20526564656d7074696f6e7320617265206e6f7420616c6c6f77656420647572696e6720626f6f747374726170207068617365536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f7754726f76654d616e616765723a2052657175657374656420726564656d7074696f6e20616d6f756e74206d757374206265203c3d20757365722773204c55534420746f6b656e2062616c616e6365c3770d654ed33aeea6bf11ac8ef05d02a6a04ed4686dd2f624d853bbec43cc8b54726f76654d616e616765723a2043616c6c6572206973206e6f742074686520426f72726f7765724f7065726174696f6e7320636f6e747261637454726f76654d616e616765723a2043616c6c646174612061646472657373206172726179206d757374206e6f7420626520656d70747954726f76654d616e616765723a20416d6f756e74206d7573742062652067726561746572207468616e207a65726f54726f76654d616e616765723a2046656520776f756c642065617420757020616c6c2072657475726e656420636f6c6c61746572616c4d6178206665652070657263656e74616765206d757374206265206265747765656e20302e352520616e64203130302554726f76654d616e616765723a2043616e6e6f742072656465656d207768656e20544352203c204d435254726f76654d616e616765723a206e6f7468696e6720746f206c697175696461746554726f76654d616e616765723a2054726f766520646f6573206e6f74206578697374206f7220697320636c6f736564a26469706673582212208d92ce50005efdbaea8e59a3472b816f5c5d74d966255c366acda81d9f82209f64736f6c634300060b0033
Loading...
Loading
Loading...
Loading
Net Worth in USD
$0.00
Net Worth in ETH
0
Multichain Portfolio | 34 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.