Skip to content

Commit

Permalink
Merge pull request #1332 from morpho-dao/dev
Browse files Browse the repository at this point in the history
Dev
  • Loading branch information
MerlinEgalite committed Oct 19, 2022
2 parents 4555c70 + 805511a commit d36ff41
Show file tree
Hide file tree
Showing 74 changed files with 852 additions and 1,772 deletions.
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
# Morpho Core Protocol V1

[![Test](https://github.com/morpho-labs/morpho-contracts/actions/workflows/ci-foundry.yml/badge.svg)](https://github.com/morpho-dao/morpho-v1/actions/workflows/ci-foundry.yml)
[![Morpho-Compound](https://github.com/morpho-dao/morpho-v1/actions/workflows/ci-foundry-compound.yml/badge.svg)](https://github.com/morpho-dao/morpho-v1/actions/workflows/ci-foundry-compound.yml)
[![Morpho-AaveV2](https://github.com/morpho-dao/morpho-v1/actions/workflows/ci-foundry-aave-v2.yml/badge.svg)](https://github.com/morpho-dao/morpho-v1/actions/workflows/ci-foundry-aave-v2.yml)
[![Morpho-AaveV3](https://github.com/morpho-dao/morpho-v1/actions/workflows/ci-foundry-aave-v3.yml/badge.svg)](https://github.com/morpho-dao/morpho-v1/actions/workflows/ci-foundry-aave-v3.yml)

<picture>
<source media="(prefers-color-scheme: dark)" srcset="https://i.imgur.com/uLq5V14.png">
Expand Down
2 changes: 1 addition & 1 deletion config/eth-mainnet/aave-v2/Config.sol
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ contract Config is BaseConfig {
ProxyAdmin public proxyAdmin = ProxyAdmin(0x99917ca0426fbC677e84f873Fb0b726Bb4799cD8);

TransparentUpgradeableProxy public lensProxy =
TransparentUpgradeableProxy(payable(0x8706256509684E9cD93B7F19254775CE9324c226));
TransparentUpgradeableProxy(payable(0x507fA343d0A90786d86C7cd885f5C49263A91FF4));
TransparentUpgradeableProxy public morphoProxy =
TransparentUpgradeableProxy(payable(0x777777c9898D384F785Ee44Acfe945efDFf5f3E0));
TransparentUpgradeableProxy public rewardsManagerProxy;
Expand Down
26 changes: 8 additions & 18 deletions contracts/aave-v2/EntryPositionsManager.sol
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ contract EntryPositionsManager is IEntryPositionsManager, PositionsManagerUtils
using HeapOrdering for HeapOrdering.HeapArray;
using PercentageMath for uint256;
using SafeTransferLib for ERC20;
using MarketLib for Types.Market;
using WadRayMath for uint256;
using Math for uint256;

Expand Down Expand Up @@ -58,12 +57,6 @@ contract EntryPositionsManager is IEntryPositionsManager, PositionsManagerUtils
/// @notice Thrown when the user does not have enough collateral for the borrow.
error UnauthorisedBorrow();

/// @notice Thrown when the supply is paused.
error SupplyPaused();

/// @notice Thrown when the borrow is paused.
error BorrowPaused();

/// STRUCTS ///

// Struct to avoid stack too deep.
Expand Down Expand Up @@ -98,17 +91,14 @@ contract EntryPositionsManager is IEntryPositionsManager, PositionsManagerUtils
) external {
if (_onBehalf == address(0)) revert AddressIsZero();
if (_amount == 0) revert AmountIsZero();
Types.Market memory market = market[_poolToken];
if (!market.isCreatedMemory()) revert MarketNotCreated();
if (market.isSupplyPaused) revert SupplyPaused();
_updateIndexes(_poolToken);

SupplyVars memory vars;
vars.borrowMask = borrowMask[_poolToken];
if (!_isSupplying(userMarkets[_onBehalf], vars.borrowMask))
_setSupplying(_onBehalf, vars.borrowMask, true);

ERC20 underlyingToken = ERC20(market.underlyingToken);
ERC20 underlyingToken = ERC20(market[_poolToken].underlyingToken);
underlyingToken.safeTransferFrom(_from, address(this), _amount);

Types.Delta storage delta = deltas[_poolToken];
Expand All @@ -135,7 +125,7 @@ contract EntryPositionsManager is IEntryPositionsManager, PositionsManagerUtils
// Promote pool borrowers.
if (
vars.remainingToSupply > 0 &&
!market.isP2PDisabled &&
!market[_poolToken].isP2PDisabled &&
borrowersOnPool[_poolToken].getHead() != address(0)
) {
(uint256 matched, ) = _matchBorrowers(
Expand Down Expand Up @@ -195,16 +185,16 @@ contract EntryPositionsManager is IEntryPositionsManager, PositionsManagerUtils
uint256 _maxGasForMatching
) external {
if (_amount == 0) revert AmountIsZero();
Types.Market memory market = market[_poolToken];
if (!market.isCreatedMemory()) revert MarketNotCreated();
if (market.isBorrowPaused) revert BorrowPaused();

ERC20 underlyingToken = ERC20(market.underlyingToken);
ERC20 underlyingToken = ERC20(market[_poolToken].underlyingToken);
if (!pool.getConfiguration(address(underlyingToken)).getBorrowingEnabled())
revert BorrowingNotEnabled();

_updateIndexes(_poolToken);
_setBorrowing(msg.sender, borrowMask[_poolToken], true);

bytes32 borrowMask = borrowMask[_poolToken];
if (!_isBorrowing(userMarkets[msg.sender], borrowMask))
_setBorrowing(msg.sender, borrowMask, true);

if (!_borrowAllowed(msg.sender, _poolToken, _amount)) revert UnauthorisedBorrow();

Expand Down Expand Up @@ -233,7 +223,7 @@ contract EntryPositionsManager is IEntryPositionsManager, PositionsManagerUtils
// Promote pool suppliers.
if (
remainingToBorrow > 0 &&
!market.isP2PDisabled &&
!market[_poolToken].isP2PDisabled &&
suppliersOnPool[_poolToken].getHead() != address(0)
) {
(uint256 matched, ) = _matchSuppliers(
Expand Down
115 changes: 14 additions & 101 deletions contracts/aave-v2/ExitPositionsManager.sol
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ contract ExitPositionsManager is IExitPositionsManager, PositionsManagerUtils {
using HeapOrdering for HeapOrdering.HeapArray;
using PercentageMath for uint256;
using SafeTransferLib for ERC20;
using MarketLib for Types.Market;
using WadRayMath for uint256;
using Math for uint256;

Expand Down Expand Up @@ -68,11 +67,6 @@ contract ExitPositionsManager is IExitPositionsManager, PositionsManagerUtils {
uint256 _amountSeized
);

/// @notice Emitted when the peer-to-peer deltas are increased by the governance.
/// @param _poolToken The address of the market on which the deltas were increased.
/// @param _amount The amount that has been added to the deltas (in underlying).
event P2PDeltasIncreased(address indexed _poolToken, uint256 _amount);

/// ERRORS ///

/// @notice Thrown when user is not a member of the market.
Expand All @@ -84,18 +78,6 @@ contract ExitPositionsManager is IExitPositionsManager, PositionsManagerUtils {
/// @notice Thrown when the positions of the user is not liquidatable.
error UnauthorisedLiquidate();

/// @notice Thrown when the withdraw is paused.
error WithdrawPaused();

/// @notice Thrown when the repay is paused.
error RepayPaused();

/// @notice Thrown when the liquidation on this asset as collateral is paused.
error LiquidateCollateralPaused();

/// @notice Thrown when the liquidation on this asset as debt is paused.
error LiquidateBorrowPaused();

/// STRUCTS ///

// Struct to avoid stack too deep.
Expand Down Expand Up @@ -128,8 +110,6 @@ contract ExitPositionsManager is IExitPositionsManager, PositionsManagerUtils {
uint256 collateralTokenUnit; // The collateral token unit considering its decimals.
uint256 borrowedReserveDecimals; // The number of decimals of the borrowed asset in the reserve.
uint256 borrowedTokenUnit; // The unit of borrowed token considering its decimals.
uint256 closeFactor; // The close factor used during the liquidation.
bool liquidationAllowed; // Whether the liquidation is allowed or not.
}

// Struct to avoid stack too deep.
Expand All @@ -156,9 +136,6 @@ contract ExitPositionsManager is IExitPositionsManager, PositionsManagerUtils {
) external {
if (_amount == 0) revert AmountIsZero();
if (_receiver == address(0)) revert AddressIsZero();
Types.Market memory market = market[_poolToken];
if (!market.isCreatedMemory()) revert MarketNotCreated();
if (market.isWithdrawPaused) revert WithdrawPaused();

_updateIndexes(_poolToken);
uint256 toWithdraw = Math.min(_getUserSupplyBalanceInOf(_poolToken, _supplier), _amount);
Expand All @@ -183,9 +160,6 @@ contract ExitPositionsManager is IExitPositionsManager, PositionsManagerUtils {
uint256 _maxGasForMatching
) external {
if (_amount == 0) revert AmountIsZero();
Types.Market memory market = market[_poolToken];
if (!market.isCreatedMemory()) revert MarketNotCreated();
if (market.isRepayPaused) revert RepayPaused();

_updateIndexes(_poolToken);
uint256 toRepay = Math.min(_getUserBorrowBalanceInOf(_poolToken, _onBehalf), _amount);
Expand All @@ -205,13 +179,6 @@ contract ExitPositionsManager is IExitPositionsManager, PositionsManagerUtils {
address _borrower,
uint256 _amount
) external {
Types.Market memory collateralMarket = market[_poolTokenCollateral];
if (!collateralMarket.isCreatedMemory()) revert MarketNotCreated();
if (collateralMarket.isLiquidateCollateralPaused) revert LiquidateCollateralPaused();
Types.Market memory borrowedMarket = market[_poolTokenBorrowed];
if (!borrowedMarket.isCreatedMemory()) revert MarketNotCreated();
if (borrowedMarket.isLiquidateBorrowPaused) revert LiquidateBorrowPaused();

if (
!_isBorrowingAndSupplying(
userMarkets[_borrower],
Expand All @@ -223,22 +190,22 @@ contract ExitPositionsManager is IExitPositionsManager, PositionsManagerUtils {
_updateIndexes(_poolTokenBorrowed);
_updateIndexes(_poolTokenCollateral);

LiquidateVars memory vars;
(vars.closeFactor, vars.liquidationAllowed) = _liquidationAllowed(
_borrower,
borrowedMarket.isDeprecated
);
if (!vars.liquidationAllowed) revert UnauthorisedLiquidate();
if (!_liquidationAllowed(_borrower)) revert UnauthorisedLiquidate();

address tokenBorrowedAddress = market[_poolTokenBorrowed].underlyingToken;

uint256 amountToLiquidate = Math.min(
_amount,
_getUserBorrowBalanceInOf(_poolTokenBorrowed, _borrower).percentMul(vars.closeFactor) // Max liquidatable debt.
_getUserBorrowBalanceInOf(_poolTokenBorrowed, _borrower).percentMul(
DEFAULT_LIQUIDATION_CLOSE_FACTOR
) // Max liquidatable debt.
);

address tokenCollateralAddress = market[_poolTokenCollateral].underlyingToken;

IPriceOracleGetter oracle = IPriceOracleGetter(addressesProvider.getPriceOracle());

address tokenCollateralAddress = market[_poolTokenCollateral].underlyingToken;
address tokenBorrowedAddress = market[_poolTokenBorrowed].underlyingToken;
LiquidateVars memory vars;
{
ILendingPool poolMem = pool;
(, , vars.liquidationBonus, vars.collateralReserveDecimals, ) = poolMem
Expand Down Expand Up @@ -283,46 +250,6 @@ contract ExitPositionsManager is IExitPositionsManager, PositionsManagerUtils {
);
}

/// @notice Implements increaseP2PDeltas logic.
/// @dev The current Morpho supply on the pool might not be enough to borrow `_amount` before resupplying it.
/// In this case, consider calling this function multiple times.
/// @param _poolToken The address of the market on which to create deltas.
/// @param _amount The amount to add to the deltas (in underlying).
function increaseP2PDeltasLogic(address _poolToken, uint256 _amount) external {
_updateIndexes(_poolToken);

Types.Delta storage deltas = deltas[_poolToken];
Types.Delta memory deltasMem = deltas;
Types.PoolIndexes memory poolIndexes = poolIndexes[_poolToken];
uint256 p2pSupplyIndex = p2pSupplyIndex[_poolToken];
uint256 p2pBorrowIndex = p2pBorrowIndex[_poolToken];

_amount = Math.min(
_amount,
Math.min(
deltasMem.p2pSupplyAmount.rayMul(p2pSupplyIndex).zeroFloorSub(
deltasMem.p2pSupplyDelta.rayMul(poolIndexes.poolSupplyIndex)
),
deltasMem.p2pBorrowAmount.rayMul(p2pBorrowIndex).zeroFloorSub(
deltasMem.p2pBorrowDelta.rayMul(poolIndexes.poolBorrowIndex)
)
)
);

deltasMem.p2pSupplyDelta += _amount.rayDiv(poolIndexes.poolSupplyIndex);
deltas.p2pSupplyDelta = deltasMem.p2pSupplyDelta;
deltasMem.p2pBorrowDelta += _amount.rayDiv(poolIndexes.poolBorrowIndex);
deltas.p2pBorrowDelta = deltasMem.p2pBorrowDelta;
emit P2PSupplyDeltaUpdated(_poolToken, deltasMem.p2pSupplyDelta);
emit P2PBorrowDeltaUpdated(_poolToken, deltasMem.p2pBorrowDelta);

ERC20 underlyingToken = ERC20(market[_poolToken].underlyingToken);
_borrowFromPool(underlyingToken, _amount);
_supplyToPool(underlyingToken, _amount);

emit P2PDeltasIncreased(_poolToken, _amount);
}

/// INTERNAL ///

/// @dev Implements withdraw logic without security checks.
Expand Down Expand Up @@ -571,9 +498,8 @@ contract ExitPositionsManager is IExitPositionsManager, PositionsManagerUtils {
// No need to subtract p2pBorrowDelta as it is zero.
vars.feeToRepay = Math.zeroFloorSub(
delta.p2pBorrowAmount.rayMul(vars.p2pBorrowIndex),
delta.p2pSupplyAmount.rayMul(vars.p2pSupplyIndex).zeroFloorSub(
delta.p2pSupplyDelta.rayMul(vars.poolSupplyIndex)
)
(delta.p2pSupplyAmount.rayMul(vars.p2pSupplyIndex) -
delta.p2pSupplyDelta.rayMul(vars.poolSupplyIndex))
);

if (vars.feeToRepay > 0) {
Expand Down Expand Up @@ -691,21 +617,8 @@ contract ExitPositionsManager is IExitPositionsManager, PositionsManagerUtils {

/// @dev Checks if the user is liquidatable.
/// @param _user The user to check.
/// @param _isDeprecated Whether the market is deprecated or not.
/// @return closeFactor The close factor to apply.
/// @return liquidationAllowed Whether the liquidation is allowed or not.
function _liquidationAllowed(address _user, bool _isDeprecated)
internal
returns (uint256 closeFactor, bool liquidationAllowed)
{
if (_isDeprecated) {
// Allow liquidation of the whole debt.
closeFactor = MAX_BASIS_POINTS;
liquidationAllowed = true;
} else {
closeFactor = DEFAULT_LIQUIDATION_CLOSE_FACTOR;
liquidationAllowed = (_getUserHealthFactor(_user, address(0), 0) <
HEALTH_FACTOR_LIQUIDATION_THRESHOLD);
}
/// @return Whether the user is liquidatable or not.
function _liquidationAllowed(address _user) internal returns (bool) {
return _getUserHealthFactor(_user, address(0), 0) < HEALTH_FACTOR_LIQUIDATION_THRESHOLD;
}
}
7 changes: 2 additions & 5 deletions contracts/aave-v2/InterestRatesManager.sol
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,6 @@ contract InterestRatesManager is IInterestRatesManager, MorphoStorage {
using PercentageMath for uint256;
using WadRayMath for uint256;

/// STORAGE ///

address public constant ST_ETH = 0xae7ab96520DE3A18E5e111B5EaAb095312D7fE84;

uint256 public immutable ST_ETH_BASE_REBASE_INDEX;
Expand Down Expand Up @@ -149,9 +147,8 @@ contract InterestRatesManager is IInterestRatesManager, MorphoStorage {
p2pGrowthFactor +
_params.reserveFactor.percentMul(poolBorrowGrowthFactor - p2pGrowthFactor);
} else {
// The case poolSupplyGrowthFactor > poolBorrowGrowthFactor happens because someone has done a flashloan on Aave, or the interests
// generated by the stable rate borrowing are high (making the supply rate higher than the variable borrow rate): the peer-to-peer
// growth factors are set to the pool borrow growth factor.
// The case poolSupplyGrowthFactor > poolBorrowGrowthFactor happens because someone has done a flashloan on Aave:
// the peer-to-peer growth factors are set to the pool borrow growth factor.
p2pSupplyGrowthFactor = poolBorrowGrowthFactor;
p2pBorrowGrowthFactor = poolBorrowGrowthFactor;
}
Expand Down
Loading

0 comments on commit d36ff41

Please sign in to comment.