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

fix liquidation rounding #638

Merged
merged 11 commits into from
Dec 12, 2023
2 changes: 1 addition & 1 deletion .github/workflows/foundry.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ jobs:
uses: foundry-rs/foundry-toolchain@v1

- name: Run Forge tests in ${{ matrix.type }} mode
run: forge test -vvv
run: yarn test:forge -vvv
env:
FOUNDRY_FUZZ_RUNS: ${{ matrix.fuzz-runs }}
FOUNDRY_FUZZ_MAX_TEST_REJECTS: ${{ matrix.max-test-rejects }}
Expand Down
11 changes: 5 additions & 6 deletions src/Morpho.sol
Original file line number Diff line number Diff line change
Expand Up @@ -357,7 +357,6 @@ contract Morpho is IMorphoStaticTyping {

_accrueInterest(marketParams, id);

uint256 repaidAssets;
{
uint256 collateralPrice = IOracle(marketParams.oracle).price();

Expand All @@ -370,15 +369,15 @@ contract Morpho is IMorphoStaticTyping {
);

if (seizedAssets > 0) {
repaidAssets =
uint256 temp =
seizedAssets.mulDivUp(collateralPrice, ORACLE_PRICE_SCALE).wDivUp(liquidationIncentiveFactor);
repaidShares = repaidAssets.toSharesDown(market[id].totalBorrowAssets, market[id].totalBorrowShares);
repaidShares = temp.toSharesDown(market[id].totalBorrowAssets, market[id].totalBorrowShares);
MerlinEgalite marked this conversation as resolved.
Show resolved Hide resolved
} else {
repaidAssets = repaidShares.toAssetsUp(market[id].totalBorrowAssets, market[id].totalBorrowShares);
seizedAssets =
repaidAssets.wMulDown(liquidationIncentiveFactor).mulDivDown(ORACLE_PRICE_SCALE, collateralPrice);
seizedAssets = repaidShares.toAssetsDown(market[id].totalBorrowAssets, market[id].totalBorrowShares)
.wMulDown(liquidationIncentiveFactor).mulDivDown(ORACLE_PRICE_SCALE, collateralPrice);
MerlinEgalite marked this conversation as resolved.
Show resolved Hide resolved
}
}
uint256 repaidAssets = repaidShares.toAssetsUp(market[id].totalBorrowAssets, market[id].totalBorrowShares);

position[id][borrower].borrowShares -= repaidShares.toUint128();
market[id].totalBorrowShares -= repaidShares.toUint128();
Expand Down
28 changes: 26 additions & 2 deletions test/forge/integration/LiquidateIntegrationTest.sol
Original file line number Diff line number Diff line change
Expand Up @@ -206,8 +206,8 @@ contract LiquidateIntegrationTest is BaseTest {
sharesRepaid = bound(sharesRepaid, 1, Math.min(borrowShares, maxSharesRepaid));

uint256 expectedRepaid = sharesRepaid.toAssetsUp(morpho.totalBorrowAssets(id), morpho.totalBorrowShares(id));
uint256 expectedSeized =
expectedRepaid.wMulDown(liquidationIncentiveFactor).mulDivDown(ORACLE_PRICE_SCALE, params.priceCollateral);
uint256 expectedSeized = sharesRepaid.toAssetsDown(morpho.totalBorrowAssets(id), morpho.totalBorrowShares(id))
.wMulDown(liquidationIncentiveFactor).mulDivDown(ORACLE_PRICE_SCALE, params.priceCollateral);

loanToken.setBalance(LIQUIDATOR, params.amountBorrowed);

Expand Down Expand Up @@ -354,4 +354,28 @@ contract LiquidateIntegrationTest is BaseTest {
vm.prank(LIQUIDATOR);
morpho.liquidate(marketParams, BORROWER, collateralAmount, 0, hex"");
}

function testSeizedAssetsRoundUp() public {
_setLltv(0.75e18);
_supply(100e18);

uint256 amountCollateral = 400;
uint256 amountBorrowed = 300;
collateralToken.setBalance(BORROWER, amountCollateral);

vm.startPrank(BORROWER);
morpho.supplyCollateral(marketParams, amountCollateral, BORROWER, hex"");
morpho.borrow(marketParams, amountBorrowed, 0, BORROWER, BORROWER);
vm.stopPrank();

oracle.setPrice(ORACLE_PRICE_SCALE - 0.01e18);

loanToken.setBalance(LIQUIDATOR, amountBorrowed);

vm.prank(LIQUIDATOR);
(uint256 seizedAssets, uint256 repaidAssets) = morpho.liquidate(marketParams, BORROWER, 0, 1, hex"");

assertEq(seizedAssets, 0, "seizedAssets");
assertEq(repaidAssets, 1, "repaidAssets");
}
}
Loading