Skip to content
Open
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
43 changes: 1 addition & 42 deletions tests/Base.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2066,7 +2066,7 @@ abstract contract Base is Test {
);
uint256 targetTotalDebtValue = totalAdjustedCollateralValue.wadDivUp(desiredHf);
require(
userAccountData.totalDebtValueRay / WadRayMath.RAY < targetTotalDebtValue,
userAccountData.totalDebtValueRay / WadRayMath.RAY <= targetTotalDebtValue,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

would it be better to make it userAccountData.totalDebtValueRay vs targetTotalDebtValue * WadRayMath.RAY to eliminate the precision loss due to division

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, I just wanted to keep alignment with logic below as well. I think if fuzzer finds such edge cases, then more things will break

'User has enough debt'
);
return targetTotalDebtValue - userAccountData.totalDebtValueRay / WadRayMath.RAY;
Expand Down Expand Up @@ -2579,47 +2579,6 @@ abstract contract Base is Test {
return spoke.getLiquidationBonus(reserveId, user, healthFactor);
}

/**
* @notice Returns the required debt amount in value terms to ensure user position is above a certain health factor.
* @return requiredDebt The required additional debt amount in value terms.
*/
function _getRequiredDebtForGtHf(
ISpoke spoke,
address user,
uint256 desiredHf
) internal view returns (uint256) {
ISpoke.UserAccountData memory userAccountData = spoke.getUserAccountData(user);

return
userAccountData
.totalCollateralValue
.percentMulDown(userAccountData.avgCollateralFactor.fromWadDown())
.percentMulDown(99_00)
.wadDivDown(desiredHf) - userAccountData.totalDebtValueRay.fromRayUp();
// buffer to force debt lower (ie making sure resultant debt creates HF that is gt desired)
}

/// @dev Borrow to be below a certain healthy health factor
/// @dev This function validates HF and does not mock price, thus it will cache user RP properly
function _borrowToBeAboveHealthyHf(
ISpoke spoke,
address user,
uint256 reserveId,
uint256 desiredHf
) internal returns (uint256, uint256) {
uint256 requiredDebtInBase = _getRequiredDebtForGtHf(spoke, user, desiredHf);
uint256 requiredDebtAmount = _convertValueToAmount(spoke, reserveId, requiredDebtInBase) - 1;

vm.assume(requiredDebtAmount < MAX_SUPPLY_AMOUNT);

vm.prank(user);
spoke.borrow(reserveId, requiredDebtAmount, user);

uint256 finalHf = _getUserHealthFactor(spoke, user);
assertGt(finalHf, desiredHf, 'should borrow so that HF is above desiredHf');
return (finalHf, requiredDebtAmount);
}

function _mockDecimals(address underlying, uint8 decimals) internal {
vm.mockCall(
underlying,
Expand Down
5 changes: 5 additions & 0 deletions tests/mocks/MockSpoke.sol
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,11 @@ contract MockSpoke is Spoke, Test {
uint256 drawnShares = hub.draw(reserve.assetId, amount, msg.sender);
userPosition.drawnShares += drawnShares.toUint120();
if (!positionStatus.isBorrowing(reserveId)) {
require(
MAX_USER_RESERVES_LIMIT == MAX_ALLOWED_USER_RESERVES_LIMIT ||
positionStatus.borrowCount(_reserveCount) < MAX_USER_RESERVES_LIMIT,
MaximumUserReservesExceeded()
);
positionStatus.setBorrowing(reserveId, true);
}

Expand Down
7 changes: 6 additions & 1 deletion tests/unit/Spoke/SpokeBase.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -1109,7 +1109,12 @@ contract SpokeBase is Base {
_borrowWithoutHfCheck(spoke, user, reserveId, requiredDebtAmount);

uint256 finalHf = _getUserHealthFactor(spoke, user);
assertApproxEqAbs(finalHf, desiredHf, 0.001e18);
assertApproxEqRel(
finalHf,
desiredHf,
_approxRelFromBps(100),
'final health factor should be close to desired health factor'
);

return (finalHf, requiredDebtAmount);
}
Expand Down
Loading