Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Updated auctionInfo #996

Merged
merged 4 commits into from
Dec 2, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
71 changes: 62 additions & 9 deletions src/PoolInfoUtils.sol
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,16 @@ import { PoolCommons } from './libraries/external/PoolCommons.sol';
*/
contract PoolInfoUtils {

/**
* @notice Struct contianing local variables used in `auctionStatus` to get around stack size limitations.
* @param lup The price value of the current `Lowest Utilized Price` (`LUP`) bucket, in `WAD` units.
* @param poolDebt Current amount of debt owed by borrowers in pool. (`WAD`).
*/
struct AuctionStatusLocalVars {
uint256 lup;
uint256 poolDebt;
}

/**
* @notice Exposes status of a liquidation auction.
* @param ajnaPool_ Address of `Ajna` pool.
Expand All @@ -45,6 +55,9 @@ contract PoolInfoUtils {
* @return isCollateralized_ `True` if loan is collateralized.
* @return price_ Current price of the auction. (`WAD`)
* @return neutralPrice_ Price at which bond holder is neither rewarded nor penalized. (`WAD`)
* @return referencePrice_ Price used to determine auction start price. (`WAD`)
* @return thresholdPrice_ Threshold Price when liquidation was started. (`WAD`)
* @return bondFactor_ The factor used for calculating bond size. (`WAD`)
*/
function auctionStatus(address ajnaPool_, address borrower_)
external
Expand All @@ -55,23 +68,63 @@ contract PoolInfoUtils {
uint256 debtToCover_,
bool isCollateralized_,
uint256 price_,
uint256 neutralPrice_
uint256 neutralPrice_,
uint256 referencePrice_,
uint256 thresholdPrice_,
uint256 bondFactor_
)
{
IPool pool = IPool(ajnaPool_);
uint256 referencePrice;
( , , , kickTime_, referencePrice, neutralPrice_, , , ) = pool.auctionInfo(borrower_);
AuctionStatusLocalVars memory vars;
( ,
bondFactor_,
,
kickTime_,
referencePrice_,
neutralPrice_,
thresholdPrice_, , , ) = IPool(ajnaPool_).auctionInfo(borrower_);

if (kickTime_ != 0) {
(debtToCover_, collateral_, ) = this.borrowerInfo(ajnaPool_, borrower_);

(uint256 poolDebt,,,) = pool.debtInfo();
uint256 lup_ = _priceAt(pool.depositIndex(poolDebt));
isCollateralized_ = _isCollateralized(debtToCover_, collateral_, lup_, pool.poolType());

price_ = _auctionPrice(referencePrice, kickTime_);
(vars.poolDebt,,,) = IPool(ajnaPool_).debtInfo();
vars.lup = _priceAt(IPool(ajnaPool_).depositIndex(vars.poolDebt));
isCollateralized_ = _isCollateralized(debtToCover_, collateral_, vars.lup, IPool(ajnaPool_).poolType());

price_ = _auctionPrice(referencePrice_, kickTime_);
}
}

/**
* @notice Returns details of an auction for a given borrower address.
* @dev Calls and returns all values from pool.auctionInfo().
* @param ajnaPool_ Address of `Ajna` pool.
* @param borrower_ Address of the borrower that is liquidated.
* @return kicker_ Address of the kicker that is kicking the auction.
* @return bondFactor_ The factor used for calculating bond size.
* @return bondSize_ The bond amount in quote token terms.
* @return kickTime_ Time the liquidation was initiated.
* @return referencePrice_ Price used to determine auction start price.
* @return neutralPrice_ `Neutral Price` of auction.
* @return thresholdPrice_ Threshold Price when liquidation was started.
* @return head_ Address of the head auction.
* @return next_ Address of the next auction in queue.
* @return prev_ Address of the prev auction in queue.
*/
function auctionInfo(address ajnaPool_, address borrower_) external view returns (
address kicker_,
uint256 bondFactor_,
uint256 bondSize_,
uint256 kickTime_,
uint256 referencePrice_,
uint256 neutralPrice_,
uint256 thresholdPrice_,
address head_,
address next_,
address prev_
) {
return IPool(ajnaPool_).auctionInfo(borrower_);
}

/**
* @notice Retrieves info of a given borrower in a given `Ajna` pool.
* @param ajnaPool_ Address of `Ajna` pool.
Expand Down
2 changes: 2 additions & 0 deletions src/base/Pool.sol
Original file line number Diff line number Diff line change
Expand Up @@ -746,6 +746,7 @@ abstract contract Pool is Clone, ReentrancyGuard, Multicall, IPool {
uint256 kickTime_,
uint256 referencePrice_,
uint256 neutralPrice_,
uint256 thresholdPrice_,
address head_,
address next_,
address prev_
Expand All @@ -758,6 +759,7 @@ abstract contract Pool is Clone, ReentrancyGuard, Multicall, IPool {
liquidation.kickTime,
liquidation.referencePrice,
liquidation.neutralPrice,
liquidation.thresholdPrice,
auctions.head,
liquidation.next,
liquidation.prev
Expand Down
2 changes: 2 additions & 0 deletions src/interfaces/pool/commons/IPoolState.sol
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ interface IPoolState {
* @return kickTime_ Time the liquidation was initiated.
* @return referencePrice_ Price used to determine auction start price.
* @return neutralPrice_ `Neutral Price` of auction.
* @return thresholdPrice_ Threshold Price when liquidation was started.
* @return head_ Address of the head auction.
* @return next_ Address of the next auction in queue.
* @return prev_ Address of the prev auction in queue.
Expand All @@ -30,6 +31,7 @@ interface IPoolState {
uint256 kickTime_,
uint256 referencePrice_,
uint256 neutralPrice_,
uint256 thresholdPrice_,
address head_,
address next_,
address prev_
Expand Down
10 changes: 5 additions & 5 deletions tests/brownie/test_invariants.py
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ def pool_buckets(self):
def pool_debt_in_auction(self):
auctioned_borrowers_debt = 0
for borrower in self.borrowers:
(_, _, _, kick_time, _, _, _, _, _, _) = self.pool.auctionInfo(borrower)
(_, _, _, kick_time, _, _, _, _, _, _, _) = self.pool.auctionInfo(borrower)
if kick_time != 0:
(borrower_debt, _, _) = self.pool.borrowerInfo(borrower)
auctioned_borrowers_debt += borrower_debt
Expand All @@ -185,7 +185,7 @@ def pool_auction_bonds(self):

auction_bonds_locked = 0
for borrower in self.borrowers:
(_, _, bond_size, _, _, _, _, _, _, _) = self.pool.auctionInfo(borrower)
(_, _, bond_size, _, _, _, _, _, _, _, _) = self.pool.auctionInfo(borrower)
auction_bonds_locked += bond_size

# Invariant 8: sum of bonds across all auctions = sum of locked balances across all kickers = total bond escrowed accumulator
Expand All @@ -202,7 +202,7 @@ def pool_loans_and_auctions(self):
if borrower_debt != 0:
borrowers_with_debt += 1

(_, _, _, kick_time, _, _, _, _, _, _) = self.pool.auctionInfo(borrower)
(_, _, _, kick_time, _, _, _, _, _, _, _) = self.pool.auctionInfo(borrower)
if kick_time != 0:
number_of_auctions += 1

Expand Down Expand Up @@ -565,7 +565,7 @@ def rule_repay_debt(self, st_borrow_amount, st_borrower, st_sleep):
def rule_kick_auction(self, st_borrow_amount, st_lender, st_borrower, st_kicker, st_sleep):

# do not kick if already active
(_, _, _, kick_time, _, _, _, _, _, _) = self.pool.auctionInfo(borrowers[st_borrower])
(_, _, _, kick_time, _, _, _, _, _, _, _) = self.pool.auctionInfo(borrowers[st_borrower])
if kick_time != 0:
return

Expand Down Expand Up @@ -605,7 +605,7 @@ def rule_take_auction(self, st_borrow_amount, st_take_amount, st_lender, st_borr
success = True

# kick if auction not kicked already
(_, _, _, kick_time, _, _, _, _, _, _) = self.pool.auctionInfo(borrowers[st_borrower])
(_, _, _, kick_time, _, _, _, _, _, _, _) = self.pool.auctionInfo(borrowers[st_borrower])
if kick_time == 0:
self.rule_kick_auction(st_borrow_amount, st_lender, st_borrower, st_kicker, st_sleep)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ contract BasicERC20PoolHandler is UnboundedBasicERC20PoolHandler, BasicPoolHandl
numberOfCalls['BBasicHandler.pledgeCollateral']++;

// borrower cannot make any action when in auction
(uint256 kickTime,,,,,) = _poolInfo.auctionStatus(address(_pool), _actor);
(uint256 kickTime,,,,,,,,) = _poolInfo.auctionStatus(address(_pool), _actor);
if (kickTime != 0) return;

// Prepare test phase
Expand All @@ -92,7 +92,7 @@ contract BasicERC20PoolHandler is UnboundedBasicERC20PoolHandler, BasicPoolHandl
numberOfCalls['BBasicHandler.pullCollateral']++;

// borrower cannot make any action when in auction
(uint256 kickTime,,,,,) = _poolInfo.auctionStatus(address(_pool), _actor);
(uint256 kickTime,,,,,,,,) = _poolInfo.auctionStatus(address(_pool), _actor);
if (kickTime != 0) return;

// Prepare test phase
Expand All @@ -110,7 +110,7 @@ contract BasicERC20PoolHandler is UnboundedBasicERC20PoolHandler, BasicPoolHandl
numberOfCalls['BBasicHandler.drawDebt']++;

// borrower cannot make any action when in auction
(uint256 kickTime,,,,,) = _poolInfo.auctionStatus(address(_pool), _actor);
(uint256 kickTime,,,,,,,,) = _poolInfo.auctionStatus(address(_pool), _actor);
if (kickTime != 0) return;

// Prepare test phase
Expand All @@ -128,7 +128,7 @@ contract BasicERC20PoolHandler is UnboundedBasicERC20PoolHandler, BasicPoolHandl
numberOfCalls['BBasicHandler.repayDebt']++;

// borrower cannot make any action when in auction
(uint256 kickTime,,,,,) = _poolInfo.auctionStatus(address(_pool), _actor);
(uint256 kickTime,,,,,,,,) = _poolInfo.auctionStatus(address(_pool), _actor);
if (kickTime != 0) return;

// Prepare test phase
Expand Down Expand Up @@ -176,7 +176,7 @@ contract BasicERC20PoolHandler is UnboundedBasicERC20PoolHandler, BasicPoolHandl
boundedAmount_ = constrictToRange(amountToBorrow_, MIN_DEBT_AMOUNT, MAX_DEBT_AMOUNT);

// borrower cannot make any action when in auction
(uint256 kickTime, uint256 collateral,,,,) = _poolInfo.auctionStatus(address(_pool), _actor);
(uint256 kickTime, uint256 collateral,,,,,,,) = _poolInfo.auctionStatus(address(_pool), _actor);
if (kickTime != 0) return boundedAmount_;

// Pre Condition
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ contract PanicExitERC20PoolHandler is UnboundedLiquidationPoolHandler, Unbounded

_actor = _borrowers[borrowerIndex_];
changePrank(_actor);
(,,, uint256 kickTime,,,,,) = _pool.auctionInfo(_actor);
(,,, uint256 kickTime,,,,,,) = _pool.auctionInfo(_actor);
if (block.timestamp > kickTime + 72 hours) {
numberOfCalls['BPanicExitPoolHandler.settleDebt']++;
_settleAuction(_actor, numberOfBuckets);
Expand Down Expand Up @@ -164,7 +164,7 @@ contract PanicExitERC20PoolHandler is UnboundedLiquidationPoolHandler, Unbounded
function settleHeadAuction(
uint256 skippedTime_
) external useTimestamps skipTime(skippedTime_) writeLogs {
(, , , , , , address headAuction, , ) = _pool.auctionInfo(address(0));
(, , , , , , , address headAuction, , ) = _pool.auctionInfo(address(0));
if (headAuction != address(0)) {
_settleAuction(headAuction, 10);
_resetSettledAuction(headAuction, 0);
Expand Down Expand Up @@ -218,7 +218,7 @@ contract PanicExitERC20PoolHandler is UnboundedLiquidationPoolHandler, Unbounded
}

function _resetSettledAuction(address borrower_, uint256 borrowerIndex_) internal {
(,,, uint256 kickTime,,,,,) = _pool.auctionInfo(borrower_);
(,,, uint256 kickTime,,,,,,) = _pool.auctionInfo(borrower_);
if (kickTime == 0) {
if (borrowerIndex_ != 0) _activeBorrowers.remove(borrowerIndex_);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ contract SettleERC20PoolHandler is UnboundedLiquidationPoolHandler, UnboundedBas
kickerIndex_ = constrictToRange(kickerIndex_, 0, LENDERS - 1);
address kicker = _lenders[kickerIndex_];

(,,, uint256 kickTime,,,,,) = _pool.auctionInfo(borrower);
(,,, uint256 kickTime,,,,,,) = _pool.auctionInfo(borrower);

// Kick auction if not already kicked
if (kickTime == 0) {
Expand All @@ -71,7 +71,7 @@ contract SettleERC20PoolHandler is UnboundedLiquidationPoolHandler, UnboundedBas
_kickAuction(borrower);
}

(,,, kickTime,,,,,) = _pool.auctionInfo(borrower);
(,,, kickTime,,,,,,) = _pool.auctionInfo(borrower);

if (kickTime == 0) return;

Expand Down Expand Up @@ -104,7 +104,7 @@ contract SettleERC20PoolHandler is UnboundedLiquidationPoolHandler, UnboundedBas
actorIndex_ = constrictToRange(actorIndex_, 0, LENDERS - 1);
address payer = _lenders[actorIndex_];

(,,, uint256 kickTime,,,,,) = _pool.auctionInfo(borrower);
(,,, uint256 kickTime,,,,,,) = _pool.auctionInfo(borrower);

// Kick auction if not already kicked
if (kickTime == 0) {
Expand All @@ -113,7 +113,7 @@ contract SettleERC20PoolHandler is UnboundedLiquidationPoolHandler, UnboundedBas
_kickAuction(borrower);
}

(,,, kickTime,,,,,) = _pool.auctionInfo(borrower);
(,,, kickTime,,,,,,) = _pool.auctionInfo(borrower);

if (kickTime == 0) return;

Expand Down Expand Up @@ -225,7 +225,7 @@ contract SettleERC20PoolHandler is UnboundedLiquidationPoolHandler, UnboundedBas
}
}
// **CT2**: Keep track of bucketIndex when borrower is removed from auction to check collateral added into that bucket
(, , , uint256 kickTime, , , , , ) = _pool.auctionInfo(borrower_);
(, , , uint256 kickTime, , , , , , ) = _pool.auctionInfo(borrower_);
if (kickTime == 0 && collateral % 1e18 != 0 && _pool.poolType() == 1) {
buckets.add(7388);
lenderDepositTime[borrower_][7388] = block.timestamp;
Expand Down Expand Up @@ -294,7 +294,7 @@ contract SettleERC20PoolHandler is UnboundedLiquidationPoolHandler, UnboundedBas
}

function _resetSettledAuction(address borrower_, uint256 borrowerIndex_) internal {
(,,, uint256 kickTime,,,,,) = _pool.auctionInfo(borrower_);
(,,, uint256 kickTime,,,,,,) = _pool.auctionInfo(borrower_);
if (kickTime == 0) {
if (borrowerIndex_ != 0) _activeBorrowers.remove(borrowerIndex_);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ contract TradingERC20PoolHandler is UnboundedLiquidationPoolHandler, UnboundedBa
}

function _resetSettledAuction(address borrower_, uint256 borrowerIndex_) internal {
(,,, uint256 kickTime,,,,,) = _pool.auctionInfo(borrower_);
(,,, uint256 kickTime,,,,,,) = _pool.auctionInfo(borrower_);
if (kickTime == 0) {
if (borrowerIndex_ != 0) _activeBorrowers.remove(borrowerIndex_);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ contract BasicERC721PoolHandler is UnboundedBasicERC721PoolHandler, BasicPoolHan
numberOfCalls['BBasicHandler.pledgeCollateral']++;

// borrower cannot make any action when in auction
(uint256 kickTime,,,,,) = _poolInfo.auctionStatus(address(_pool), _actor);
(uint256 kickTime,,,,,,,,) = _poolInfo.auctionStatus(address(_pool), _actor);
if (kickTime != 0) return;

// Prepare test phase
Expand All @@ -106,7 +106,7 @@ contract BasicERC721PoolHandler is UnboundedBasicERC721PoolHandler, BasicPoolHan
numberOfCalls['BBasicHandler.pullCollateral']++;

// borrower cannot make any action when in auction
(uint256 kickTime,,,,,) = _poolInfo.auctionStatus(address(_pool), _actor);
(uint256 kickTime,,,,,,,,) = _poolInfo.auctionStatus(address(_pool), _actor);
if (kickTime != 0) return;

// Prepare test phase
Expand All @@ -124,7 +124,7 @@ contract BasicERC721PoolHandler is UnboundedBasicERC721PoolHandler, BasicPoolHan
numberOfCalls['BBasicHandler.drawDebt']++;

// borrower cannot make any action when in auction
(uint256 kickTime,,,,,) = _poolInfo.auctionStatus(address(_pool), _actor);
(uint256 kickTime,,,,,,,,) = _poolInfo.auctionStatus(address(_pool), _actor);
if (kickTime != 0) return;

// Prepare test phase
Expand All @@ -142,7 +142,7 @@ contract BasicERC721PoolHandler is UnboundedBasicERC721PoolHandler, BasicPoolHan
numberOfCalls['BBasicHandler.repayDebt']++;

// borrower cannot make any action when in auction
(uint256 kickTime,,,,,) = _poolInfo.auctionStatus(address(_pool), _actor);
(uint256 kickTime,,,,,,,,) = _poolInfo.auctionStatus(address(_pool), _actor);
if (kickTime != 0) return;

// Prepare test phase
Expand Down Expand Up @@ -209,7 +209,7 @@ contract BasicERC721PoolHandler is UnboundedBasicERC721PoolHandler, BasicPoolHan
boundedAmount_ = constrictToRange(amountToBorrow_, MIN_DEBT_AMOUNT, MAX_DEBT_AMOUNT);

// borrower cannot make any action when in auction
(uint256 kickTime, uint256 collateral, uint256 debt,,,) = _poolInfo.auctionStatus(address(_pool), _actor);
(uint256 kickTime, uint256 collateral, uint256 debt,,,,,,) = _poolInfo.auctionStatus(address(_pool), _actor);
if (kickTime != 0) return boundedAmount_;

// Pre Condition
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ contract PanicExitERC721PoolHandler is UnboundedLiquidationPoolHandler, Unbounde

_actor = _borrowers[borrowerIndex_];
changePrank(_actor);
(,,, uint256 kickTime,,,,,) = _pool.auctionInfo(_actor);
(,,, uint256 kickTime,,,,,,) = _pool.auctionInfo(_actor);
if (block.timestamp > kickTime + 72 hours) {
numberOfCalls['BPanicExitPoolHandler.settleDebt']++;
_settleAuction(_actor, numberOfBuckets);
Expand Down Expand Up @@ -162,7 +162,7 @@ contract PanicExitERC721PoolHandler is UnboundedLiquidationPoolHandler, Unbounde
function settleHeadAuction(
uint256 skippedTime_
) external useTimestamps skipTime(skippedTime_) writeLogs {
(, , , , , , address headAuction, , ) = _pool.auctionInfo(address(0));
(, , , , , , , address headAuction, , ) = _pool.auctionInfo(address(0));
if (headAuction != address(0)) {
_settleAuction(headAuction, 10);
_resetSettledAuction(headAuction, 0);
Expand Down Expand Up @@ -216,7 +216,7 @@ contract PanicExitERC721PoolHandler is UnboundedLiquidationPoolHandler, Unbounde
}

function _resetSettledAuction(address borrower_, uint256 borrowerIndex_) internal {
(,,, uint256 kickTime,,,,,) = _pool.auctionInfo(borrower_);
(,,, uint256 kickTime,,,,,,) = _pool.auctionInfo(borrower_);
if (kickTime == 0) {
if (borrowerIndex_ != 0) _activeBorrowers.remove(borrowerIndex_);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ abstract contract BaseERC721PoolHandler is BaseHandler {
uint256 kickTimeBefore,
uint256 borrowerCollateralBefore, , ,
uint256 auctionPrice,
, , ,
) = _poolInfo.auctionStatus(address(_erc721Pool), borrower_);

try _erc721Pool.repayDebt(borrower_, amount_, 0, borrower_, 7388) {
Expand Down
Loading
Loading