Skip to content

Commit

Permalink
Merge pull request #1306 from morpho-dao/dev
Browse files Browse the repository at this point in the history
Dev
  • Loading branch information
MerlinEgalite committed Sep 26, 2022
2 parents 2e526f1 + 44e8796 commit 81afc94
Show file tree
Hide file tree
Showing 42 changed files with 4,635 additions and 6,675 deletions.
3 changes: 1 addition & 2 deletions .env.example
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
INFURA_PROJECT_ID=
NETWORK=eth-mainnet
DEPLOYER_PRIVATE_KEY=
TENDERLY_SECRET_KEY=
ALCHEMY_KEY=
ALCHEMY_KEY=
6 changes: 6 additions & 0 deletions .eslintignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
node_modules
artifacts
cache
coverage
out
lib
8 changes: 2 additions & 6 deletions .eslintrc.json → .eslintrc
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,6 @@
"extends": [
"eslint:recommended",
"plugin:@typescript-eslint/eslint-recommended",
"prettier"
],
"rules": {
"semi": ["error", "always"],
"quotes": ["error", "single"]
}
"plugin:prettier/recommended"
]
}
41 changes: 41 additions & 0 deletions .github/workflows/ci-hardhat-common.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
name: Hardhat tests (Common contracts)

on:
push:
branches:
- main
- dev
pull_request:
paths:
- lib/**
- contracts/common/**
- test/**
- "*.lock"
- Makefile
- foundry.toml
- remappings.txt
- .github/workflows/ci-hardhat-common.yml
paths-ignore:
- test/upgrades/**

jobs:
morpho-hardhat-tests:
name: eth-mainnet
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
with:
submodules: recursive

- uses: actions/setup-node@v3
with:
node-version: 16
cache: yarn

- name: Install dependencies
run: yarn install --frozen-lockfile

- name: Run tests
run: yarn test
env:
ALCHEMY_KEY: ${{ secrets.alchemyKey }}
7 changes: 3 additions & 4 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,12 @@
/artifacts
/cache
/coverage.json
test/contracts/flattened

# misc
.DS_Store
.env.local
.env.development.local
.env.test.local
.env.production.local
.env*
!.env.example
*.ansi

npm-debug.log*
Expand Down
2 changes: 1 addition & 1 deletion .husky/pre-commit
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,6 @@
CHANGED_FILES=$(git diff --staged --name-only --diff-filter=d | grep -e "\.ts$" -e "\.sol$" | xargs)

if [ -n "$CHANGED_FILES" ]; then
yarn prettier --config .prettierrc.json --write $CHANGED_FILES
yarn prettier --write $CHANGED_FILES
git add $CHANGED_FILES
fi
6 changes: 6 additions & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
node_modules
artifacts
cache
coverage
out
lib
8 changes: 7 additions & 1 deletion .prettierrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,13 @@
"options": {
"tabWidth": 2,
"printWidth": 140,
"singleQuote": true
"importOrder": [
"^(?![@\\.]).*",
"^@",
"^\\.\\.",
"^\\."
],
"importOrderSeparation": true
}
}
]
Expand Down
23 changes: 4 additions & 19 deletions .solhint.json
Original file line number Diff line number Diff line change
@@ -1,23 +1,8 @@
{
"extends": "solhint:recommended",
"plugins": ["prettier"],
"plugins": [
"prettier"
],
"rules": {
"prettier/prettier": "error",
"max-line-length": "off",
"check-send-result": "off",
"not-rely-on-time": "off",
"multiple-sends": "off",
"compiler-version": "off",
"reason-string": "off",
"var-name-mixedcase": "off",
"no-empty-blocks": "off",
"func-name-mixedcase": "off",
"max-states-count": "off",
"func-visibility": [
"warn",
{
"ignoreConstructors": true
}
]
"prettier/prettier": "error"
}
}
5 changes: 1 addition & 4 deletions contracts/aave-v2/EntryPositionsManager.sol
Original file line number Diff line number Diff line change
Expand Up @@ -204,10 +204,7 @@ contract EntryPositionsManager is IEntryPositionsManager, PositionsManagerUtils
revert BorrowingNotEnabled();

_updateIndexes(_poolToken);

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

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

Expand Down
41 changes: 27 additions & 14 deletions contracts/aave-v2/ExitPositionsManager.sol
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,8 @@ 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 Down Expand Up @@ -221,23 +223,22 @@ contract ExitPositionsManager is IExitPositionsManager, PositionsManagerUtils {
_updateIndexes(_poolTokenBorrowed);
_updateIndexes(_poolTokenCollateral);

if (!borrowedMarket.isDeprecated && !_liquidationAllowed(_borrower))
revert UnauthorisedLiquidate();

address tokenBorrowedAddress = market[_poolTokenBorrowed].underlyingToken;
LiquidateVars memory vars;
(vars.closeFactor, vars.liquidationAllowed) = _liquidationAllowed(
_borrower,
borrowedMarket.isDeprecated
);
if (!vars.liquidationAllowed) revert UnauthorisedLiquidate();

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

address tokenCollateralAddress = market[_poolTokenCollateral].underlyingToken;

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

LiquidateVars memory vars;
address tokenCollateralAddress = market[_poolTokenCollateral].underlyingToken;
address tokenBorrowedAddress = market[_poolTokenBorrowed].underlyingToken;
{
ILendingPool poolMem = pool;
(, , vars.liquidationBonus, vars.collateralReserveDecimals, ) = poolMem
Expand Down Expand Up @@ -316,7 +317,6 @@ contract ExitPositionsManager is IExitPositionsManager, PositionsManagerUtils {
emit P2PBorrowDeltaUpdated(_poolToken, deltasMem.p2pBorrowDelta);

ERC20 underlyingToken = ERC20(market[_poolToken].underlyingToken);

_borrowFromPool(underlyingToken, _amount);
_supplyToPool(underlyingToken, _amount);

Expand Down Expand Up @@ -691,8 +691,21 @@ contract ExitPositionsManager is IExitPositionsManager, PositionsManagerUtils {

/// @dev Checks if the user is liquidatable.
/// @param _user The user to check.
/// @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;
/// @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);
}
}
}
42 changes: 35 additions & 7 deletions contracts/aave-v2/MorphoGovernance.sol
Original file line number Diff line number Diff line change
Expand Up @@ -286,47 +286,71 @@ abstract contract MorphoGovernance is MorphoUtils {
/// @notice Sets `isSupplyPaused` for a given market.
/// @param _poolToken The address of the market to update.
/// @param _isPaused The new pause status, true to pause the mechanism.
function setIsSupplyPaused(address _poolToken, bool _isPaused) external onlyOwner {
function setIsSupplyPaused(address _poolToken, bool _isPaused)
external
onlyOwner
isMarketCreated(_poolToken)
{
market[_poolToken].isSupplyPaused = _isPaused;
emit IsSupplyPausedSet(_poolToken, _isPaused);
}

/// @notice Sets `isBorrowPaused` for a given market.
/// @param _poolToken The address of the market to update.
/// @param _isPaused The new pause status, true to pause the mechanism.
function setIsBorrowPaused(address _poolToken, bool _isPaused) external onlyOwner {
function setIsBorrowPaused(address _poolToken, bool _isPaused)
external
onlyOwner
isMarketCreated(_poolToken)
{
market[_poolToken].isBorrowPaused = _isPaused;
emit IsBorrowPausedSet(_poolToken, _isPaused);
}

/// @notice Sets `isWithdrawPaused` for a given market.
/// @param _poolToken The address of the market to update.
/// @param _isPaused The new pause status, true to pause the mechanism.
function setIsWithdrawPaused(address _poolToken, bool _isPaused) external onlyOwner {
function setIsWithdrawPaused(address _poolToken, bool _isPaused)
external
onlyOwner
isMarketCreated(_poolToken)
{
market[_poolToken].isWithdrawPaused = _isPaused;
emit IsWithdrawPausedSet(_poolToken, _isPaused);
}

/// @notice Sets `isRepayPaused` for a given market.
/// @param _poolToken The address of the market to update.
/// @param _isPaused The new pause status, true to pause the mechanism.
function setIsRepayPaused(address _poolToken, bool _isPaused) external onlyOwner {
function setIsRepayPaused(address _poolToken, bool _isPaused)
external
onlyOwner
isMarketCreated(_poolToken)
{
market[_poolToken].isRepayPaused = _isPaused;
emit IsRepayPausedSet(_poolToken, _isPaused);
}

/// @notice Sets `isLiquidateCollateralPaused` for a given market.
/// @param _poolToken The address of the market to update.
/// @param _isPaused The new pause status, true to pause the mechanism.
function setIsLiquidateCollateralPaused(address _poolToken, bool _isPaused) external onlyOwner {
function setIsLiquidateCollateralPaused(address _poolToken, bool _isPaused)
external
onlyOwner
isMarketCreated(_poolToken)
{
market[_poolToken].isLiquidateCollateralPaused = _isPaused;
emit IsLiquidateCollateralPausedSet(_poolToken, _isPaused);
}

/// @notice Sets `isLiquidateBorrowPaused` for a given market.
/// @param _poolToken The address of the market to update.
/// @param _isPaused The new pause status, true to pause the mechanism.
function setIsLiquidateBorrowPaused(address _poolToken, bool _isPaused) external onlyOwner {
function setIsLiquidateBorrowPaused(address _poolToken, bool _isPaused)
external
onlyOwner
isMarketCreated(_poolToken)
{
market[_poolToken].isLiquidateBorrowPaused = _isPaused;
emit IsLiquidateBorrowPausedSet(_poolToken, _isPaused);
}
Expand Down Expand Up @@ -394,7 +418,11 @@ abstract contract MorphoGovernance is MorphoUtils {
/// In this case, consider calling multiple times this function.
/// @param _poolToken The address of the market on which to create deltas.
/// @param _amount The amount to add to the deltas (in underlying).
function increaseP2PDeltas(address _poolToken, uint256 _amount) external onlyOwner {
function increaseP2PDeltas(address _poolToken, uint256 _amount)
external
onlyOwner
isMarketCreated(_poolToken)
{
address(exitPositionsManager).functionDelegateCall(
abi.encodeWithSelector(
IExitPositionsManager.increaseP2PDeltasLogic.selector,
Expand Down
5 changes: 1 addition & 4 deletions contracts/aave-v3/EntryPositionsManager.sol
Original file line number Diff line number Diff line change
Expand Up @@ -204,10 +204,7 @@ contract EntryPositionsManager is IEntryPositionsManager, PositionsManagerUtils
revert BorrowingNotEnabled();

_updateIndexes(_poolToken);

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

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

Expand Down
Loading

0 comments on commit 81afc94

Please sign in to comment.