Skip to content

Commit

Permalink
Merge branch 'develop' into first-borrower
Browse files Browse the repository at this point in the history
  • Loading branch information
EdNoepel committed Nov 15, 2023
2 parents 6287fa4 + 84babb8 commit 182c55a
Show file tree
Hide file tree
Showing 8 changed files with 80 additions and 28 deletions.
5 changes: 4 additions & 1 deletion src/ERC20Pool.sol
Original file line number Diff line number Diff line change
Expand Up @@ -345,7 +345,7 @@ contract ERC20Pool is FlashloanablePool, IERC20Pool {
function settle(
address borrowerAddress_,
uint256 maxDepth_
) external override nonReentrant {
) external override nonReentrant returns (uint256 collateralSettled_, bool isBorrowerSettled_) {
PoolState memory poolState = _accruePoolInterest();

SettleResult memory result = SettlerActions.settlePoolDebt(
Expand All @@ -363,6 +363,9 @@ contract ERC20Pool is FlashloanablePool, IERC20Pool {
);

_updatePostSettleState(result, poolState);

collateralSettled_ = result.collateralSettled;
isBorrowerSettled_ = (result.debtPostAction == 0);
}

/**
Expand Down
5 changes: 4 additions & 1 deletion src/ERC721Pool.sol
Original file line number Diff line number Diff line change
Expand Up @@ -394,7 +394,7 @@ contract ERC721Pool is FlashloanablePool, IERC721Pool {
function settle(
address borrowerAddress_,
uint256 maxDepth_
) external nonReentrant override {
) external nonReentrant override returns (uint256 collateralSettled_, bool isBorrowerSettled_) {
PoolState memory poolState = _accruePoolInterest();

SettleParams memory params = SettleParams({
Expand All @@ -417,6 +417,9 @@ contract ERC721Pool is FlashloanablePool, IERC721Pool {

// move token ids from borrower array to pool claimable array if any collateral used to settle bad debt
_rebalanceTokens(params.borrower, result.collateralRemaining);

collateralSettled_ = result.collateralSettled;
isBorrowerSettled_ = (result.debtPostAction == 0);
}

/**
Expand Down
24 changes: 15 additions & 9 deletions src/base/Pool.sol
Original file line number Diff line number Diff line change
Expand Up @@ -562,19 +562,23 @@ abstract contract Pool is Clone, ReentrancyGuard, Multicall, IPool {

// if new interest may have accrued, call accrueInterest function and update inflator and debt fields of poolState_ struct
if (poolState_.isNewInterestAccrued) {
(uint256 newInflator, uint256 newInterest) = PoolCommons.accrueInterest(
try PoolCommons.accrueInterest(
emaState,
deposits,
poolState_,
Loans.getMax(loans).thresholdPrice,
elapsed
);
poolState_.inflator = newInflator;
// After debt owed to lenders has accrued, calculate current debt owed by borrowers
poolState_.debt = Maths.wmul(poolState_.t0Debt, poolState_.inflator);

// update total interest earned accumulator with the newly accrued interest
reserveAuction.totalInterestEarned += newInterest;
) returns (uint256 newInflator, uint256 newInterest) {
poolState_.inflator = newInflator;
// After debt owed to lenders has accrued, calculate current debt owed by borrowers
poolState_.debt = Maths.wmul(poolState_.t0Debt, poolState_.inflator);

// update total interest earned accumulator with the newly accrued interest
reserveAuction.totalInterestEarned += newInterest;
} catch {
poolState_.isNewInterestAccrued = false;
emit InterestUpdateFailure();
}
}
}
}
Expand Down Expand Up @@ -680,7 +684,9 @@ abstract contract Pool is Clone, ReentrancyGuard, Multicall, IPool {
PoolState memory poolState_,
uint256 lup_
) internal {
PoolCommons.updateInterestState(interestState, emaState, deposits, poolState_, lup_);
try PoolCommons.updateInterestState(interestState, emaState, deposits, poolState_, lup_) {} catch {
emit InterestUpdateFailure();
}

// update pool inflator
if (poolState_.isNewInterestAccrued) {
Expand Down
5 changes: 5 additions & 0 deletions src/interfaces/pool/commons/IPoolEvents.sol
Original file line number Diff line number Diff line change
Expand Up @@ -367,4 +367,9 @@ interface IPoolEvents {
uint256 newRate
);

/**
* @notice Emitted when interest accural or update interest overflows.
*/
event InterestUpdateFailure();

}
8 changes: 5 additions & 3 deletions src/interfaces/pool/commons/IPoolSettlerActions.sol
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,15 @@ interface IPoolSettlerActions {

/**
* @notice Called by actors to settle an amount of debt in a completed liquidation.
* @param borrowerAddress_ Address of the auctioned borrower.
* @param maxDepth_ Measured from `HPB`, maximum number of buckets deep to settle debt.
* @param borrowerAddress_ Address of the auctioned borrower.
* @param maxDepth_ Measured from `HPB`, maximum number of buckets deep to settle debt.
* @return collateralSettled_ Amount of collateral settled.
* @return isBorrowerSettled_ Is all borrower's debt is settled.
* @dev `maxDepth_` is used to prevent unbounded iteration clearing large liquidations.
*/
function settle(
address borrowerAddress_,
uint256 maxDepth_
) external;
) external returns (uint256 collateralSettled_, bool isBorrowerSettled_);

}
7 changes: 3 additions & 4 deletions src/libraries/external/KickerActions.sol
Original file line number Diff line number Diff line change
Expand Up @@ -204,11 +204,10 @@ library KickerActions {
KickReserveAuctionParams calldata params_
) external {
// retrieve timestamp of latest burn event and last burn timestamp
uint256 latestBurnEpoch = reserveAuction_.latestBurnEventEpoch;
uint256 lastBurnTimestamp = reserveAuction_.burnEvents[latestBurnEpoch].timestamp;
uint256 latestBurnEpoch = reserveAuction_.latestBurnEventEpoch;

// check that at least two weeks have passed since the last reserve auction completed, and that the auction was not kicked within the past 72 hours
if (block.timestamp < lastBurnTimestamp + 2 weeks || block.timestamp - reserveAuction_.kicked <= 72 hours) {
// check that at least two weeks have passed since the last reserve auction completed
if (block.timestamp < reserveAuction_.kicked + 2 weeks + 72 hours) {
revert ReserveAuctionTooSoon();
}

Expand Down
35 changes: 26 additions & 9 deletions tests/forge/unit/ERC20Pool/ERC20PoolInterestRateAndEMAs.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -1109,7 +1109,7 @@ contract ERC20PoolInterestRateTestAndEMAs is ERC20HelperContract {
});
}

function testAccruePoolInterestRevertDueToExpLimit() external {
function testAccruePoolInterestInterestUpdateFailureDueToExpLimit() external tearDown {
_mintQuoteAndApproveTokens(_lender, 1_000_000_000 * 1e18);
_mintCollateralAndApproveTokens(_borrower, 1_000_000_000 * 1e18);

Expand Down Expand Up @@ -1180,12 +1180,27 @@ contract ERC20PoolInterestRateTestAndEMAs is ERC20HelperContract {
// wait 32 years
skip(365 days * 32);

// Reverts with PRBMathUD60x18__ExpInputTooBig
vm.expectRevert();
// Interest update should fail
vm.expectEmit(true, true, false, true);
emit InterestUpdateFailure();
_updateInterest();

// repay all borrower debt based on last inflator
(uint256 inflator, ) = _pool.inflatorInfo();
(uint256 debt, , ) = _pool.borrowerInfo(_borrower);

_mintQuoteAndApproveTokens(_borrower, Maths.ceilWmul(inflator, debt));
_repayDebt({
from: _borrower,
borrower: _borrower,
amountToRepay: type(uint256).max,
amountRepaid: Maths.ceilWmul(inflator, debt),
collateralToPull: 0,
newLup: MAX_PRICE
});
}

function testAccrueInterestNewInterestLimit() external {
function testAccrueInterestInterestUpdateFailure() external tearDown {
_mintQuoteAndApproveTokens(_lender, 1_000_000_000 * 1e18);
_mintCollateralAndApproveTokens(_borrower, 1_000_000_000 * 1e18);

Expand Down Expand Up @@ -1252,8 +1267,9 @@ contract ERC20PoolInterestRateTestAndEMAs is ERC20HelperContract {

skip(13 hours);

// Revert with Arithmetic overflow in `Maths.wmul(pendingFactor - Maths.WAD, poolState_.debt)` in accrue interest
vm.expectRevert();
// Interest update should fail
vm.expectEmit(true, true, false, true);
emit InterestUpdateFailure();
_updateInterest();
}

Expand Down Expand Up @@ -1324,7 +1340,7 @@ contract ERC20PoolInterestRateTestAndEMAs is ERC20HelperContract {
}
}

function testUpdateInterestTuLimit() external {
function testTuLimitInterestUpdateFailure() external tearDown {
_mintQuoteAndApproveTokens(_lender, 1_000_000_000 * 1e18);
_mintCollateralAndApproveTokens(_borrower, 1_000_000_000 * 1e18);

Expand Down Expand Up @@ -1393,8 +1409,9 @@ contract ERC20PoolInterestRateTestAndEMAs is ERC20HelperContract {

skip(1 days);

// Revert with Arithmetic overflow in `(((tu + mau102 - 1e18) / 1e9) ** 2)` in update interest
vm.expectRevert();
// Interest update should fail
vm.expectEmit(true, true, false, true);
emit InterestUpdateFailure();
_updateInterest();
}
}
19 changes: 18 additions & 1 deletion tests/forge/unit/ERC721Pool/ERC721PoolReserveAuction.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -218,8 +218,25 @@ contract ERC721PoolReserveAuctionTest is ERC721HelperContract {
// pass time to allow auction to complete
skip(48 hours);

// check that you can't start a new auction unless two weeks have passed
// check that you can't start a new auction immediately after the last one finished
_assertReserveAuctionTooSoon();

// check that you can't start a new auction two weeks after the last start...
skip(2 weeks - 72 hours);
_assertReserveAuctionTooSoon();

// ...or a day later...
skip(1 days);
_assertReserveAuctionTooSoon();

// ...but you can start another auction 2 weeks after the last one completed
skip(72 hours - 1 days);
_kickReserveAuction({
from: _bidder,
remainingReserves: 415.792367191826572589 * 1e18,
price: 1_000_000_000 * 1e18,
epoch: 2
});
}

function testClaimableReserveAuction() external {
Expand Down

0 comments on commit 182c55a

Please sign in to comment.