Skip to content

Commit

Permalink
Fix deposit time logic when move quote token (#623)
Browse files Browse the repository at this point in the history
Fix deposit time logic when move quote token
  - account current deposit time in to bucket as max(depositTime, bankruptcyTime + 1)
  - when setting the new deposit time take into account the current deposit time:  max(fromDepositTime, targetDepositTime)
  - unit test to assert all 3 scenarios:
      move from an older deposit to a newer one (newer deposit should preserve its time)
      move from a newer deposit to an older one (old deposit time should be set to the newer deposit time)
      move into a bucket bankrupt (depositTime should be recorded as bankrupcyTime + 1)
  • Loading branch information
grandizzy committed Feb 17, 2023
1 parent 5752259 commit 5b04336
Show file tree
Hide file tree
Showing 3 changed files with 98 additions and 4 deletions.
13 changes: 10 additions & 3 deletions src/libraries/external/LenderActions.sol
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ library LenderActions {
uint256 fromBucketRemainingDeposit; // Amount of scaled deposit remaining in from bucket after move.
uint256 toBucketPrice; // [WAD] Price of the bucket to move amount to.
uint256 toBucketBankruptcyTime; // Time the bucket to move amount to was marked as insolvent.
uint256 toBucketDepositTime; // Time of lender deposit in the bucket to move amount to.
uint256 toBucketUnscaledDeposit; // Amount of unscaled deposit in to bucket.
uint256 toBucketDeposit; // Amount of scaled deposit in to bucket.
uint256 toBucketScale; // Scale deposit of to bucket.
Expand Down Expand Up @@ -295,13 +296,19 @@ library LenderActions {
// update lender and bucket LPs balance in target bucket
Lender storage toBucketLender = toBucket.lenders[msg.sender];

if (vars.toBucketBankruptcyTime >= toBucketLender.depositTime) {
vars.toBucketDepositTime = toBucketLender.depositTime;
if (vars.toBucketBankruptcyTime >= vars.toBucketDepositTime) {
// bucket is bankrupt and deposit was done before bankruptcy time, reset lender lp amount
toBucketLender.lps = toBucketLPs_;

// set deposit time of the lender's to bucket as bucket's last bankruptcy timestamp + 1 so deposit won't get invalidated
vars.toBucketDepositTime = vars.toBucketBankruptcyTime + 1;
} else {
toBucketLender.lps += toBucketLPs_;
}
// set deposit time to the greater of the lender's from bucket and the target bucket's last bankruptcy timestamp + 1 so deposit won't get invalidated
toBucketLender.depositTime = Maths.max(vars.fromBucketDepositTime, vars.toBucketBankruptcyTime + 1);

// set deposit time to the greater of the lender's from bucket and the target bucket
toBucketLender.depositTime = Maths.max(vars.fromBucketDepositTime, vars.toBucketDepositTime);

// update bucket LPs balance
toBucket.lps += toBucketLPs_;
Expand Down
11 changes: 10 additions & 1 deletion tests/forge/ERC20Pool/ERC20PoolLiquidationsSettle.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -804,8 +804,17 @@ contract ERC20PoolLiquidationsSettleTest is ERC20HelperContract {
// all operations should work if not in same block
skip(1 hours);

_pool.addQuoteToken(100 * 1e18, _i9_91, block.timestamp + 1 minutes);
// move quote token in a bankrupt bucket should set deposit time to time of bankruptcy + 1 to prevent losing deposit
_pool.moveQuoteToken(10 * 1e18, _i9_52, _i9_91, block.timestamp + 1 minutes);
(, , uint256 bankruptcyTime, , ) = _pool.bucketInfo(_i9_91);
_assertLenderLpBalance({
lender: _lender1,
index: _i9_91,
lpBalance: 10 * 1e18,
depositTime: bankruptcyTime + 1
});

_pool.addQuoteToken(100 * 1e18, _i9_91, block.timestamp + 1 minutes);
ERC20Pool(address(_pool)).addCollateral(4 * 1e18, _i9_91, block.timestamp + 1 minutes);

_assertLenderLpBalance({
Expand Down
78 changes: 78 additions & 0 deletions tests/forge/ERC20Pool/ERC20PoolQuoteToken.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -918,6 +918,84 @@ contract ERC20PoolQuoteTokenTest is ERC20HelperContract {
});
}

function testPoolMoveQuoteTokenWithDifferentTime() external tearDown {
_addLiquidity({
from: _lender,
amount: 40_000 * 1e18,
index: 2549,
lpAward: 40_000 * 1e18,
newLup: MAX_PRICE
});

skip(7 days);
_addLiquidity({
from: _lender,
amount: 10_000 * 1e18,
index: 2550,
lpAward: 10_000 * 1e18,
newLup: MAX_PRICE
});

_assertLenderLpBalance({
lender: _lender,
index: 2549,
lpBalance: 40_000 * 1e18,
depositTime: _startTime
});
_assertLenderLpBalance({
lender: _lender,
index: 2550,
lpBalance: 10_000 * 1e18,
depositTime: _startTime + 7 days
});

// move liquidity from an older deposit to a newer one, deposit time should remain the newer one
_moveLiquidity({
from: _lender,
amount: 5_000 * 1e18,
fromIndex: 2549,
toIndex: 2550,
lpRedeemFrom: 5_000 * 1e18,
lpAwardTo: 5_000 * 1e18,
newLup: MAX_PRICE
});
_assertLenderLpBalance({
lender: _lender,
index: 2549,
lpBalance: 35_000 * 1e18,
depositTime: _startTime
});
_assertLenderLpBalance({
lender: _lender,
index: 2550,
lpBalance: 15_000 * 1e18,
depositTime: _startTime + 7 days
});

// move liquidity from a newer deposit to an older one, deposit time should be set to the newer one
_moveLiquidity({
from: _lender,
amount: 5_000 * 1e18,
fromIndex: 2550,
toIndex: 2549,
lpRedeemFrom: 5_000 * 1e18,
lpAwardTo: 5_000 * 1e18,
newLup: MAX_PRICE
});
_assertLenderLpBalance({
lender: _lender,
index: 2549,
lpBalance: 40_000 * 1e18,
depositTime: _startTime + 7 days
});
_assertLenderLpBalance({
lender: _lender,
index: 2550,
lpBalance: 10_000 * 1e18,
depositTime: _startTime + 7 days
});
}

/**
* @notice 1 lender, 1 bidder, 1 borrower tests reverts in moveQuoteToken.
* Reverts:
Expand Down

0 comments on commit 5b04336

Please sign in to comment.