Skip to content

Commit

Permalink
Merge pull request #1559 from morpho-dao/refactor/liquidity-data
Browse files Browse the repository at this point in the history
Update liquidity data naming
  • Loading branch information
Rubilmax authored Dec 13, 2022
2 parents 74af574 + 96bb4fe commit ea8d7bb
Show file tree
Hide file tree
Showing 10 changed files with 214 additions and 242 deletions.
2 changes: 1 addition & 1 deletion src/aave-v2/EntryPositionsManager.sol
Original file line number Diff line number Diff line change
Expand Up @@ -283,6 +283,6 @@ contract EntryPositionsManager is IEntryPositionsManager, PositionsManagerUtils
uint256 _borrowedAmount
) internal returns (bool) {
Types.LiquidityData memory values = _liquidityData(_user, _poolToken, 0, _borrowedAmount);
return values.debt <= values.maxDebt;
return values.debtEth <= values.borrowableEth;
}
}
5 changes: 1 addition & 4 deletions src/aave-v2/ExitPositionsManager.sol
Original file line number Diff line number Diff line change
Expand Up @@ -664,10 +664,7 @@ contract ExitPositionsManager is IExitPositionsManager, PositionsManagerUtils {

Types.LiquidityData memory values = _liquidityData(_user, _poolToken, _withdrawnAmount, 0);

return
values.debt > 0
? values.liquidationThresholdValue.wadDiv(values.debt)
: type(uint256).max;
return values.debtEth > 0 ? values.maxDebtEth.wadDiv(values.debtEth) : type(uint256).max;
}

/// @dev Checks whether the user can withdraw or not.
Expand Down
25 changes: 12 additions & 13 deletions src/aave-v2/MorphoUtils.sol
Original file line number Diff line number Diff line change
Expand Up @@ -295,7 +295,7 @@ abstract contract MorphoUtils is MorphoStorage {
}

if (_isBorrowing(vars.userMarkets, vars.borrowMask)) {
values.debt += _debtValue(
values.debtEth += _debtValue(
vars.poolToken,
_user,
vars.underlyingPrice,
Expand All @@ -304,37 +304,36 @@ abstract contract MorphoUtils is MorphoStorage {
}

// Cache current asset collateral value.
uint256 assetCollateralValue;
if (_isSupplying(vars.userMarkets, vars.borrowMask)) {
assetCollateralValue = _collateralValue(
uint256 assetCollateralEth = _collateralValue(
vars.poolToken,
_user,
vars.underlyingPrice,
assetData.tokenUnit
);
values.collateral += assetCollateralValue;
values.collateralEth += assetCollateralEth;
// Calculate LTV for borrow.
values.maxDebt += assetCollateralValue.percentMul(assetData.ltv);
values.borrowableEth += assetCollateralEth.percentMul(assetData.ltv);

// Update LT variable for withdraw.
if (assetCollateralValue > 0)
values.liquidationThresholdValue += assetCollateralValue.percentMul(
if (assetCollateralEth > 0)
values.maxDebtEth += assetCollateralEth.percentMul(
assetData.liquidationThreshold
);
}

// Update debt variable for borrowed token.
if (_poolToken == vars.poolToken && _amountBorrowed > 0)
values.debt += (_amountBorrowed * vars.underlyingPrice).divUp(assetData.tokenUnit);
values.debtEth += (_amountBorrowed * vars.underlyingPrice).divUp(
assetData.tokenUnit
);

// Subtract withdrawn amount from liquidation threshold and collateral.
if (_poolToken == vars.poolToken && _amountWithdrawn > 0) {
uint256 withdrawn = (_amountWithdrawn * vars.underlyingPrice) / assetData.tokenUnit;
values.collateral -= withdrawn;
values.liquidationThresholdValue -= withdrawn.percentMul(
assetData.liquidationThreshold
);
values.maxDebt -= withdrawn.percentMul(assetData.ltv);
values.collateralEth -= withdrawn;
values.maxDebtEth -= withdrawn.percentMul(assetData.liquidationThreshold);
values.borrowableEth -= withdrawn.percentMul(assetData.ltv);
}
}
}
Expand Down
41 changes: 21 additions & 20 deletions src/aave-v2/lens/UsersLens.sol
Original file line number Diff line number Diff line change
Expand Up @@ -74,31 +74,31 @@ abstract contract UsersLens is IndexesLens {
);

if (
liquidityData.debt > 0 &&
liquidityData.liquidationThresholdValue.wadDiv(liquidityData.debt) <=
liquidityData.debtEth > 0 &&
liquidityData.maxDebtEth.wadDiv(liquidityData.debtEth) <=
HEALTH_FACTOR_LIQUIDATION_THRESHOLD
) return (0, 0);

uint256 poolTokenBalance = ERC20(IAToken(_poolToken).UNDERLYING_ASSET_ADDRESS()).balanceOf(
_poolToken
);

if (liquidityData.debt < liquidityData.maxDebt)
if (liquidityData.debtEth < liquidityData.borrowableEth)
borrowable = Math.min(
poolTokenBalance,
((liquidityData.maxDebt - liquidityData.debt) * assetData.tokenUnit) /
((liquidityData.borrowableEth - liquidityData.debtEth) * assetData.tokenUnit) /
assetData.underlyingPrice
);

withdrawable = Math.min(
poolTokenBalance,
(assetData.collateral * assetData.tokenUnit) / assetData.underlyingPrice
(assetData.collateralEth * assetData.tokenUnit) / assetData.underlyingPrice
);

if (assetData.liquidationThreshold > 0)
withdrawable = Math.min(
withdrawable,
((liquidityData.liquidationThresholdValue - liquidityData.debt).percentDiv(
((liquidityData.maxDebtEth - liquidityData.debtEth).percentDiv(
assetData.liquidationThreshold
) * assetData.tokenUnit) / assetData.underlyingPrice
);
Expand Down Expand Up @@ -222,26 +222,25 @@ abstract contract UsersLens is IndexesLens {
oracle
);

liquidityData.collateral += assetData.collateral;
liquidityData.maxDebt += assetData.collateral.percentMul(assetData.ltv);
liquidityData.liquidationThresholdValue += assetData.collateral.percentMul(
liquidityData.collateralEth += assetData.collateralEth;
liquidityData.borrowableEth += assetData.collateralEth.percentMul(assetData.ltv);
liquidityData.maxDebtEth += assetData.collateralEth.percentMul(
assetData.liquidationThreshold
);
liquidityData.debt += assetData.debt;
liquidityData.debtEth += assetData.debtEth;

if (_poolToken == poolToken) {
if (_borrowedAmount > 0)
liquidityData.debt += (_borrowedAmount * assetData.underlyingPrice).divUp(
assetData.tokenUnit
);
liquidityData.debtEth += (_borrowedAmount * assetData.underlyingPrice)
.divUp(assetData.tokenUnit);

if (_withdrawnAmount > 0) {
uint256 assetCollateral = (_withdrawnAmount * assetData.underlyingPrice) /
assetData.tokenUnit;

liquidityData.collateral -= assetCollateral;
liquidityData.maxDebt -= assetCollateral.percentMul(assetData.ltv);
liquidityData.liquidationThresholdValue -= assetCollateral.percentMul(
liquidityData.collateralEth -= assetCollateral;
liquidityData.borrowableEth -= assetCollateral.percentMul(assetData.ltv);
liquidityData.maxDebtEth -= assetCollateral.percentMul(
assetData.liquidationThreshold
);
}
Expand Down Expand Up @@ -291,8 +290,10 @@ abstract contract UsersLens is IndexesLens {
);

assetData.tokenUnit = 10**assetData.decimals;
assetData.debt = (totalDebtBalance * assetData.underlyingPrice).divUp(assetData.tokenUnit);
assetData.collateral =
assetData.debtEth = (totalDebtBalance * assetData.underlyingPrice).divUp(
assetData.tokenUnit
);
assetData.collateralEth =
(totalCollateralBalance * assetData.underlyingPrice) /
assetData.tokenUnit;
}
Expand Down Expand Up @@ -322,9 +323,9 @@ abstract contract UsersLens is IndexesLens {
_withdrawnAmount,
_borrowedAmount
);
if (liquidityData.debt == 0) return type(uint256).max;
if (liquidityData.debtEth == 0) return type(uint256).max;

return liquidityData.liquidationThresholdValue.wadDiv(liquidityData.debt);
return liquidityData.maxDebtEth.wadDiv(liquidityData.debtEth);
}

/// @dev Checks whether a liquidation can be performed on a given user.
Expand Down
12 changes: 6 additions & 6 deletions src/aave-v2/libraries/Types.sol
Original file line number Diff line number Diff line change
Expand Up @@ -48,15 +48,15 @@ library Types {
uint256 liquidationThreshold; // The liquidation threshold applied on this token (in basis point).
uint256 ltv; // The LTV applied on this token (in basis point).
uint256 underlyingPrice; // The price of the token (in ETH).
uint256 collateral; // The collateral value of the asset (in ETH).
uint256 debt; // The debt value of the asset (in ETH).
uint256 collateralEth; // The collateral value of the asset (in ETH).
uint256 debtEth; // The debt value of the asset (in ETH).
}

struct LiquidityData {
uint256 collateral; // The collateral value (in ETH).
uint256 maxDebt; // The max debt value (in ETH).
uint256 liquidationThresholdValue; // The liquidation threshold value (in ETH).
uint256 debt; // The debt value (in ETH).
uint256 collateralEth; // The collateral value (in ETH).
uint256 borrowableEth; // The maximum debt value allowed to borrow (in ETH).
uint256 maxDebtEth; // The maximum debt value allowed before being liquidatable (in ETH).
uint256 debtEth; // The debt value (in ETH).
}

// Variables are packed together to save gas (will not exceed their limit during Morpho's lifetime).
Expand Down
21 changes: 10 additions & 11 deletions src/compound/MorphoUtils.sol
Original file line number Diff line number Diff line change
Expand Up @@ -122,23 +122,22 @@ abstract contract MorphoUtils is MorphoStorage {
uint256 numberOfEnteredMarkets = enteredMarkets[_user].length;

Types.AssetLiquidityData memory assetData;
uint256 maxDebtValue;
uint256 debtValue;
uint256 maxDebtUsd;
uint256 debtUsd;
uint256 i;

while (i < numberOfEnteredMarkets) {
address poolTokenEntered = enteredMarkets[_user][i];

assetData = _getUserLiquidityDataForAsset(_user, poolTokenEntered, oracle);
maxDebtValue += assetData.maxDebtValue;
debtValue += assetData.debtValue;
maxDebtUsd += assetData.maxDebtUsd;
debtUsd += assetData.debtUsd;

if (_poolToken == poolTokenEntered) {
if (_borrowedAmount > 0)
debtValue += _borrowedAmount.mul(assetData.underlyingPrice);
if (_borrowedAmount > 0) debtUsd += _borrowedAmount.mul(assetData.underlyingPrice);

if (_withdrawnAmount > 0)
maxDebtValue -= _withdrawnAmount.mul(assetData.underlyingPrice).mul(
maxDebtUsd -= _withdrawnAmount.mul(assetData.underlyingPrice).mul(
assetData.collateralFactor
);
}
Expand All @@ -148,7 +147,7 @@ abstract contract MorphoUtils is MorphoStorage {
}
}

return debtValue > maxDebtValue;
return debtUsd > maxDebtUsd;
}

/// @notice Returns the data related to `_poolToken` for the `_user`.
Expand All @@ -166,13 +165,13 @@ abstract contract MorphoUtils is MorphoStorage {
if (assetData.underlyingPrice == 0) revert CompoundOracleFailed();
(, assetData.collateralFactor, ) = comptroller.markets(_poolToken);

assetData.collateralValue = _getUserSupplyBalanceInOf(_poolToken, _user).mul(
assetData.collateralUsd = _getUserSupplyBalanceInOf(_poolToken, _user).mul(
assetData.underlyingPrice
);
assetData.debtValue = _getUserBorrowBalanceInOf(_poolToken, _user).mul(
assetData.debtUsd = _getUserBorrowBalanceInOf(_poolToken, _user).mul(
assetData.underlyingPrice
);
assetData.maxDebtValue = assetData.collateralValue.mul(assetData.collateralFactor);
assetData.maxDebtUsd = assetData.collateralUsd.mul(assetData.collateralFactor);
}

/// @dev Returns the supply balance of `_user` in the `_poolToken` market.
Expand Down
Loading

0 comments on commit ea8d7bb

Please sign in to comment.