Skip to content

Commit

Permalink
Merge pull request #709 from zhoujia6139/master
Browse files Browse the repository at this point in the history
Fix: position cannot be liquidated when turn on liquidation protocol fee
  • Loading branch information
miguelmtzinf authored Nov 15, 2022
2 parents 3925b24 + e99112c commit 12263d2
Show file tree
Hide file tree
Showing 2 changed files with 115 additions and 0 deletions.
7 changes: 7 additions & 0 deletions contracts/protocol/libraries/logic/LiquidationLogic.sol
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,13 @@ library LiquidationLogic {

// Transfer fee to treasury if it is non-zero
if (vars.liquidationProtocolFeeAmount != 0) {
uint256 liquidityIndex = collateralReserve.getNormalizedIncome();
uint256 scaledDownLiquidationProtocolFee = vars.liquidationProtocolFeeAmount.rayDiv(liquidityIndex);
uint256 scaledDownUserBalance = vars.collateralAToken.scaledBalanceOf(params.user);
// To avoid trying to send more aTokens than available on balance, due to 1 wei imprecision
if (scaledDownLiquidationProtocolFee > scaledDownUserBalance) {
vars.liquidationProtocolFeeAmount = scaledDownUserBalance.rayMul(liquidityIndex);
}
vars.collateralAToken.transferOnLiquidation(
params.user,
vars.collateralAToken.RESERVE_TREASURY_ADDRESS(),
Expand Down
108 changes: 108 additions & 0 deletions test-suites/liquidation-with-fee.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,114 @@ makeSuite('Pool Liquidation: Add fee to liquidations', (testEnv) => {
await waitForTx(await addressesProvider.setPriceOracle(aaveOracle.address));
});

it('position should be liquidated when turn on liquidation protocol fee.', async () => {
const { pool, users, usdc, weth, oracle, configurator, helpersContract } = testEnv;

const depositor = users[0];
const borrower = users[1];
const liquidator = users[2];

//1, prepare asset price.
await oracle.setAssetPrice(usdc.address, '1000000000000000'); //weth = 1000 usdc

//2, depositor deposit 100000 usdc and 10 eth
await usdc
.connect(depositor.signer)
['mint(uint256)'](await convertToCurrencyDecimals(usdc.address, '10000'));
await usdc.connect(depositor.signer).approve(pool.address, MAX_UINT_AMOUNT);
await pool
.connect(depositor.signer)
.supply(
usdc.address,
await convertToCurrencyDecimals(usdc.address, '10000'),
depositor.address,
0
);

await weth
.connect(depositor.signer)
['mint(uint256)'](convertToCurrencyDecimals(weth.address, '10'));
await weth.connect(depositor.signer).approve(pool.address, MAX_UINT_AMOUNT);
await pool
.connect(depositor.signer)
.supply(weth.address, convertToCurrencyDecimals(weth.address, '10'), depositor.address, 0);

//3, borrower deposit 10 eth, borrow 5000 usdc
await weth
.connect(borrower.signer)
['mint(uint256)'](convertToCurrencyDecimals(weth.address, '10'));
await weth.connect(borrower.signer).approve(pool.address, MAX_UINT_AMOUNT);
await pool
.connect(borrower.signer)
.supply(weth.address, convertToCurrencyDecimals(weth.address, '10'), borrower.address, 0);

await pool
.connect(borrower.signer)
.borrow(
usdc.address,
await convertToCurrencyDecimals(usdc.address, '5000'),
RateMode.Variable,
0,
borrower.address
);

//4, liquidator deposit 10000 usdc and borrow 5 eth.
await usdc
.connect(liquidator.signer)
['mint(uint256)'](await convertToCurrencyDecimals(usdc.address, '20000'));
await usdc.connect(liquidator.signer).approve(pool.address, MAX_UINT_AMOUNT);
await pool
.connect(liquidator.signer)
.supply(
usdc.address,
await convertToCurrencyDecimals(usdc.address, '10000'),
liquidator.address,
0
);

await pool
.connect(liquidator.signer)
.borrow(
weth.address,
convertToCurrencyDecimals(weth.address, '5'),
RateMode.Variable,
0,
liquidator.address
);

//5, advance block to make ETH income index > 1
await increaseTime(86400);

//6, decrease weth price to allow liquidation
await oracle.setAssetPrice(usdc.address, '20000000000000000'); //weth = 500 usdc

//7, turn on liquidation protocol fee
expect(await configurator.setLiquidationProtocolFee(weth.address, 500));
const wethLiquidationProtocolFee = await helpersContract.getLiquidationProtocolFee(
weth.address
);
expect(wethLiquidationProtocolFee).to.be.eq(500);

const tryMaxTimes = 20;
for (let i = 1; i <= tryMaxTimes; i++) {
const tmpSnap = await evmSnapshot();
await increaseTime(i);
expect(
await pool
.connect(liquidator.signer)
.liquidationCall(weth.address, usdc.address, borrower.address, MAX_UINT_AMOUNT, false)
);

if (i !== tryMaxTimes) {
await evmRevert(tmpSnap);
}
}

expect(await weth.balanceOf(liquidator.address)).to.be.gt(
convertToCurrencyDecimals(weth.address, '5')
);
});

it('Sets the WETH protocol liquidation fee to 1000 (10.00%)', async () => {
const { configurator, weth, aave, helpersContract } = testEnv;

Expand Down

0 comments on commit 12263d2

Please sign in to comment.