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

Failing reserves invariant after bucket take #1055

Open
wants to merge 10 commits into
base: develop
Choose a base branch
from
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ contract PurchaseQuoteWithExternalLiquidityTest is Test {
address internal _lender;

function setUp() external {
vm.createSelectFork(vm.envString("ETH_RPC_URL"));
vm.createSelectFork(vm.envString("ETH_RPC_URL"), 18800000);
_ajnaPool = ERC20Pool(new ERC20PoolFactory(AJNA).deployPool(WETH, USDC, 0.05 * 10**18));
_lender = makeAddr("lender");

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ abstract contract UnboundedBasicERC20PoolHandler is UnboundedBasicPoolHandler, B

uint256 bucket = depositIndex - 1;
uint256 price = _poolInfo.indexToPrice(bucket);
uint256 collateralToPledge = ((COLLATERALIZATION_FACTOR * amount_ + price / 2) / price) * 101 / 100 + 1;
uint256 collateralToPledge = ((COLLATERALIZATION_FACTOR * amount_ + price / 2) / price) * 110 / 100 + _erc20Pool.collateralScale();

// ensure actor always has amount of collateral to pledge
_ensureCollateralAmount(_actor, collateralToPledge);
Expand Down
30 changes: 27 additions & 3 deletions tests/forge/invariants/base/handlers/unbounded/BaseHandler.sol
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ abstract contract BaseHandler is Test {
address internal _actor;
uint256 internal _lenderBucketIndex;
uint256 internal _limitIndex;
uint256 internal maxPoolDebt = uint256(vm.envOr("MAX_POOL_DEBT", uint256(1e55)));
uint256 internal maxPoolDebt = uint256(vm.envOr("MAX_POOL_DEBT", uint256(1e32)));

// deposits invariant test state
uint256[7389] internal fenwickDeposits;
Expand Down Expand Up @@ -217,6 +217,29 @@ abstract contract BaseHandler is Test {
time_ = constrictToRange(time_, 0, vm.envOr("SKIP_TIME", uint256(24 hours)));
vm.warp(block.timestamp + time_);
} else {
// settle kicked loans if pool debt exceeds configured max debt
// max loans settlement that can be done to prevent running out of gas
uint256 maxLoansSettlement = 5;

while(maxPoolDebt < poolDebt && maxLoansSettlement > 0) {
address kickedBorrower = _getAuctionInfo(address(0)).head;

if (kickedBorrower != address(0)) {
uint256 kickTime = _getAuctionInfo(kickedBorrower).kickTime;

if (kickTime < block.timestamp - 73 hours) {
try _pool.settle(kickedBorrower, buckets.length()) {
} catch (bytes memory err) {
_ensurePoolError(err);
}
}
}

(poolDebt, , ,) = _pool.debtInfo();

--maxLoansSettlement;
}

// repay from loans if pool debt exceeds configured max debt
// max repayments that can be done to prevent running out of gas
uint256 maxLoansRepayments = 5;
Expand Down Expand Up @@ -513,8 +536,9 @@ abstract contract BaseHandler is Test {
}

// reset the reserves before each action
increaseInReserves = 0;
decreaseInReserves = 0;
increaseInReserves = 0;
decreaseInReserves = 0;
reservesErrorMargin = 0;
// record reserves before each action
previousReserves = _getReservesInfo().reserves;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -301,6 +301,7 @@ abstract contract UnboundedLiquidationPoolHandler is BaseHandler {
// Reserves can increase by up to 2e-18 (1/5e17) due to rounding error in inflator value multiplied with t0Debt
(uint256 inflator, ) = _pool.inflatorInfo();
reservesErrorMargin = Math.max(reservesErrorMargin, inflator/5e17);
reservesErrorMargin = Math.max(reservesErrorMargin, (increaseInReserves + decreaseInReserves) / 1e16);

// In case of bucket take, collateral is taken at bucket price.
uint256 takePrice = _priceAt(bucketIndex_);
Expand Down Expand Up @@ -440,6 +441,7 @@ abstract contract UnboundedLiquidationPoolHandler is BaseHandler {

maxDepth_ -= 1;
}
reservesErrorMargin = Math.max(reservesErrorMargin, (reservesAfterAction + reservesBeforeAction) / 1e16);
}
// **CT2**: Keep track of bucketIndex when borrower is removed from auction to check collateral added into that bucket
if (
Expand Down
Loading
Loading