The RAAC protocol's lending pool allows users to repay their debt even after the liquidation grace period has elapsed, creating a scenario where users can be tricked into repaying debt when they can no longer recover their NFT collateral.
describe("Liquidation", function () {
beforeEach(async function () {
const depositAmount = ethers.parseEther("100");
await crvusd.mint(user2.address, depositAmount);
await crvusd.connect(user2).approve(lendingPool.target, depositAmount);
await lendingPool.connect(user2).deposit(depositAmount);
await rToken.connect(user2).approve(stabilityPool.target, depositAmount);
const tokenId = 1;
await raacNFT.connect(user3).approve(lendingPool.target, tokenId);
await lendingPool.connect(user3).depositNFT(tokenId);
const borrowAmount = ethers.parseEther("80");
await lendingPool.connect(user3).borrow(borrowAmount);
});
it("should Allow user to repay after grace period locking NFT permanently", async function () {
await ethers.provider.send("evm_increaseTime", [86400]);
await ethers.provider.send("evm_mine");
await lendingPool.updateState();
await ethers.provider.send("evm_increaseTime", [86400]);
await ethers.provider.send("evm_mine");
const depositAmount = ethers.parseEther("50");
await stabilityPool.connect(user2).deposit(depositAmount);
await raacHousePrices.setHousePrice(1, ethers.parseEther("70"));
await lendingPool.initiateLiquidation(user3.address);
expect(await lendingPool.isUnderLiquidation(user3.address)).to.be.true;
expect(await lendingPool.liquidationStartTime(user3.address) > 0).to.be.true;
await ethers.provider.send("evm_increaseTime", [259300]);
await ethers.provider.send("evm_mine");
const repayAMount = ethers.parseEther("90");
await crvusd.mint(user3.address, repayAMount);
await crvusd.connect(user3).approve(lendingPool.target, repayAMount);
await lendingPool.connect(user3).repay(repayAMount);
await expect(
lendingPool.connect(user3).closeLiquidation()
).to.be.revertedWithCustomError(lendingPool, "GracePeriodExpired");
await expect(
lendingPool.connect(user3).withdrawNFT(1)
).to.be.revertedWithCustomError(lendingPool, "CannotWithdrawUnderLiquidation");
const liquidationGracePeriod = await lendingPool.liquidationGracePeriod();
console.log("liquidationGracePeriod: ", liquidationGracePeriod.toString());
const liquidationAmount = ethers.parseEther("100");
await crvusd.mint(stabilityPool.target, liquidationAmount);
await expect(
stabilityPool.liquidateBorrower(user3.address)
).to.be.revertedWithCustomError(stabilityPool, "InvalidAmount");
expect(await raacNFT.balanceOf(stabilityPool.target)).to.equal(0);
});
});