Skip to content

Commit

Permalink
Take 1
Browse files Browse the repository at this point in the history
  • Loading branch information
grandizzy committed Jan 18, 2023
1 parent 24e66da commit fd0706d
Show file tree
Hide file tree
Showing 5 changed files with 126 additions and 23 deletions.
23 changes: 12 additions & 11 deletions src/base/Pool.sol
Original file line number Diff line number Diff line change
Expand Up @@ -272,12 +272,14 @@ abstract contract Pool is Clone, ReentrancyGuard, Multicall, IPool {
borrowerAddress_
);

poolState.t0Debt += result.t0KickPenalty;

// update pool balances state
poolBalances.t0Debt = poolState.t0Debt;
poolBalances.t0DebtInAuction += result.t0KickedDebt;
poolBalances.t0Debt += result.t0KickPenalty;

// update pool interest rate state
poolState.debt += result.kickPenalty;
poolState.debt = Maths.wmul(poolState.t0Debt, poolState.inflator);
_updateInterestState(poolState, result.lup);

if(result.amountToCoverBond != 0) _transferQuoteTokenFrom(msg.sender, result.amountToCoverBond);
Expand All @@ -303,12 +305,14 @@ abstract contract Pool is Clone, ReentrancyGuard, Multicall, IPool {
index_
);

poolState.t0Debt += result.t0KickPenalty;

// update pool balances state
poolBalances.t0Debt += result.t0KickPenalty;
poolBalances.t0Debt = poolState.t0Debt;
poolBalances.t0DebtInAuction += result.t0KickedDebt;

// update pool interest rate state
poolState.debt += result.kickPenalty;
poolState.debt = Maths.wmul(poolState.t0Debt, poolState.inflator);
_updateInterestState(poolState, result.lup);

// transfer from kicker to pool the difference to cover bond
Expand Down Expand Up @@ -424,20 +428,17 @@ abstract contract Pool is Clone, ReentrancyGuard, Multicall, IPool {
* @return poolState_ Struct containing pool details.
*/
function _accruePoolInterest() internal returns (PoolState memory poolState_) {
// retrieve t0Debt amount from poolBalances struct
uint256 t0Debt = poolBalances.t0Debt;

// initialize fields of poolState_ struct with initial values
poolState_.t0Debt = poolBalances.t0Debt;
poolState_.collateral = poolBalances.pledgedCollateral;
poolState_.inflator = inflatorState.inflator;
poolState_.rate = interestState.interestRate;
poolState_.poolType = _getArgUint8(POOL_TYPE);
poolState_.quoteDustLimit = _getArgUint256(QUOTE_SCALE);

// check if t0Debt is not equal to 0, indicating that there is debt to be tracked for the pool
if (t0Debt != 0) {
if (poolState_.t0Debt != 0) {
// Calculate prior pool debt
poolState_.debt = Maths.wmul(t0Debt, poolState_.inflator);
poolState_.debt = Maths.wmul(poolState_.t0Debt, poolState_.inflator);

// calculate elapsed time since inflator was last updated
uint256 elapsed = block.timestamp - inflatorState.inflatorUpdate;
Expand All @@ -455,7 +456,7 @@ abstract contract Pool is Clone, ReentrancyGuard, Multicall, IPool {
);
poolState_.inflator = newInflator;
// After debt owed to lenders has accrued, calculate current debt owed by borrowers
poolState_.debt = Maths.wmul(t0Debt, poolState_.inflator);
poolState_.debt = Maths.wmul(poolState_.t0Debt, poolState_.inflator);

// update total interest earned accumulator with the newly accrued interest
reserveAuction.totalInterestEarned += newInterest;
Expand Down
1 change: 0 additions & 1 deletion src/interfaces/pool/commons/IPoolInternals.sol
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ struct BucketTakeResult {

struct KickResult {
uint256 amountToCoverBond; // amount of bond that needs to be covered
uint256 kickPenalty; // kick penalty
uint256 t0KickPenalty; // t0 kick penalty
uint256 t0KickedDebt; // new t0 debt after kick
uint256 lup; // current lup
Expand Down
1 change: 1 addition & 0 deletions src/interfaces/pool/commons/IPoolState.sol
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,7 @@ struct PoolBalancesState {

struct PoolState {
uint8 poolType; // pool type, can be ERC20 or ERC721
uint256 t0Debt; // [WAD] t0 debt in pool
uint256 debt; // [WAD] total debt in pool, accrued in current block
uint256 collateral; // [WAD] total collateral pledged in pool
uint256 inflator; // [WAD] current pool inflator
Expand Down
27 changes: 16 additions & 11 deletions src/libraries/external/Auctions.sol
Original file line number Diff line number Diff line change
Expand Up @@ -379,7 +379,7 @@ library Auctions {
DepositsState storage deposits_,
mapping(uint256 => Bucket) storage buckets_,
LoansState storage loans_,
PoolState memory poolState_,
PoolState calldata poolState_,
uint256 index_
) external returns (
KickResult memory kickResult_
Expand Down Expand Up @@ -506,8 +506,10 @@ library Auctions {

borrower.collateral -= result_.collateralAmount;

// update pool debt: apply penalty if case
if (result_.t0DebtPenalty != 0) {
poolState_.debt += Maths.wmul(result_.t0DebtPenalty, poolState_.inflator);
poolState_.t0Debt += result_.t0DebtPenalty;
poolState_.debt = Maths.wmul(poolState_.t0Debt, poolState_.inflator);
}

(
Expand Down Expand Up @@ -572,8 +574,10 @@ library Auctions {

borrower.collateral -= result_.collateralAmount;

// update pool debt: apply penalty if case
if (result_.t0DebtPenalty != 0) {
poolState_.debt += Maths.wmul(result_.t0DebtPenalty, poolState_.inflator);
poolState_.t0Debt += result_.t0DebtPenalty;
poolState_.debt = Maths.wmul(poolState_.t0Debt, poolState_.inflator);
}

(
Expand Down Expand Up @@ -770,7 +774,7 @@ library Auctions {
AuctionsState storage auctions_,
DepositsState storage deposits_,
LoansState storage loans_,
PoolState memory poolState_,
PoolState calldata poolState_,
address borrowerAddress_,
uint256 additionalDebt_
) internal returns (
Expand Down Expand Up @@ -806,10 +810,6 @@ library Auctions {
momp
);

// when loan is kicked, penalty of three months of interest is added
kickResult_.kickPenalty = Maths.wmul(Maths.wdiv(poolState_.rate, 4 * 1e18), borrowerDebt);
kickResult_.t0KickPenalty = Maths.wdiv(kickResult_.kickPenalty, poolState_.inflator);

// record liquidation info
uint256 neutralPrice = Maths.wmul(borrower.t0Np, poolState_.inflator);
_recordAuction(
Expand All @@ -827,14 +827,19 @@ library Auctions {
// remove kicked loan from heap
Loans.remove(loans_, borrowerAddress_, loans_.indices[borrowerAddress_]);

kickResult_.t0KickedDebt += kickResult_.t0KickPenalty;
// when loan is kicked, penalty of three months of interest is added
uint256 kickPenalty = Maths.wmul(Maths.wdiv(poolState_.rate, 4 * 1e18), borrowerDebt);

kickResult_.t0KickPenalty = Maths.wdiv(kickPenalty, poolState_.inflator);
kickResult_.t0KickedDebt += kickResult_.t0KickPenalty;

// update borrower debt with kicked debt penalty
borrower.t0Debt = kickResult_.t0KickedDebt;

emit Kick(
borrowerAddress_,
borrowerDebt + kickResult_.kickPenalty,
borrower.collateral,
borrowerDebt + kickPenalty,
borrowerCollateral,
bondSize
);
}
Expand Down
97 changes: 97 additions & 0 deletions tests/forge/ERC20Pool/ERC20PoolLiquidationsTake.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -1891,3 +1891,100 @@ contract ERC20PoolLiquidationsTakeTest is ERC20HelperContract {
});
}
}

contract ERC20PoolLiquidationsTakeAndRepayAllDebtInPoolTest is ERC20HelperContract {

address internal _lender;
address internal _borrower;
address internal _kicker;
address internal _taker;

function setUp() external {
_lender = makeAddr("lender");
_borrower = makeAddr("borrower");
_kicker = makeAddr("kicker");
_taker = makeAddr("taker");

_mintQuoteAndApproveTokens(_lender, 1_000_000 * 1e18);
_mintQuoteAndApproveTokens(_borrower, 1_000_000 * 1e18);
_mintQuoteAndApproveTokens(_kicker, 1_000_000 * 1e18);
_mintQuoteAndApproveTokens(_taker, 1_000_000 * 1e18);

_mintCollateralAndApproveTokens(_borrower, 150_000 * 1e18);

_addInitialLiquidity({
from: _lender,
amount: 1_000 * 1e18,
index: 2690
});
_addInitialLiquidity({
from: _lender,
amount: 1_000 * 1e18,
index: 2700
});
}

function testTakeAuctionRepaidAmountGreaterThanPoolDebt() external tearDown {
_repayDebtNoLupCheck({
from: _borrower,
borrower: _borrower,
amountToRepay: 0,
amountRepaid: 0,
collateralToPull: 0
});

_drawDebtNoLupCheck({
from: _borrower,
borrower: _borrower,
amountToBorrow: 635.189921955815900534 * 1e18,
limitIndex: 7000,
collateralToPledge: 0.428329945169804100 * 1e18
});

skip(3276);

_repayDebtNoLupCheck({
from: _borrower,
borrower: _borrower,
amountToRepay: type(uint256).max,
amountRepaid: 635.803983894118939950 * 1e18,
collateralToPull: 0.428329945169804100 * 1e18
});

_drawDebtNoLupCheck({
from: _borrower,
borrower: _borrower,
amountToBorrow: 100 * 1e18,
limitIndex: 7000,
collateralToPledge: 0.067433366047580170 * 1e18
});

skip(964);
skip(86400 * 200);

_kick({
from: _kicker,
borrower: _borrower,
debt: 104.162540773774892916 * 1e18,
collateral: 0.067433366047580170 * 1e18,
bond: 1.028765834802714992 * 1e18,
transferAmount: 1.028765834802714992 * 1e18
});

skip(964);
skip(3600 * 3);

// the calculated repaid amount is with 1 WAD greater than the pool debt
// check that take works and doesn't overflow
_take({
from: _taker,
borrower: _borrower,
maxCollateral: 0.067433366047580170 * 1e18,
bondChange: 1.028765834802714992 * 1e18,
givenAmount: 111.455789568155429077 * 1e18,
collateralTaken: 0.010471063560951988 * 1e18,
isReward: false
});

}
}

0 comments on commit fd0706d

Please sign in to comment.