Skip to content

Commit

Permalink
chore: refactor liquidate function and finish tests
Browse files Browse the repository at this point in the history
  • Loading branch information
thomgabriel committed Nov 28, 2023
1 parent c242120 commit 89ccc49
Show file tree
Hide file tree
Showing 7 changed files with 430 additions and 784 deletions.
33 changes: 17 additions & 16 deletions contracts/LiquidatePool.sol
Original file line number Diff line number Diff line change
Expand Up @@ -97,37 +97,38 @@ contract LiquidatePool is AccessControl {

/**
* @dev liquidate a give amout of tselic on UniswapV3
* @param tselicAmount the amout of tselic
* @param minReturn the minimum amount of return
* @param drexAmount the amout of drex to be liquidated
* @param amountInMaximum the maximum amount of tselic to be liquidated
* @param receiver used to receive token
*/
function flashLiquidateTSELIC(
uint256 tselicAmount,
uint256 minReturn,
uint256 drexAmount,
uint256 amountInMaximum,
address receiver
) external {
) external returns (uint256 amountLiquidated) {
require(msg.sender == rbrllpool, "unauthorized");

tselic.approve(address(swapRouter), tselicAmount);
tselic.approve(address(swapRouter), amountInMaximum);

// We set the sqrtPriceLimitx96 to be 0 to ensure we swap our exact input amount.
ISwapRouter.ExactInputSingleParams memory params = ISwapRouter.ExactInputSingleParams({
// We set the sqrtPriceLimitx96 to be 0 to ensure we swap our exact output amount.
ISwapRouter.ExactOutputSingleParams memory params = ISwapRouter.ExactOutputSingleParams({
tokenIn: address(tselic),
tokenOut: address(drex),
fee: 3000,
recipient: msg.sender,
recipient: address(this),
deadline: block.timestamp,
amountIn: tselicAmount,
amountOutMinimum: minReturn,
amountOut: drexAmount,
amountInMaximum: amountInMaximum,
sqrtPriceLimitX96: 0
});

// The call to `exactInputSingle` executes the swap.
uint256 amountOut = swapRouter.exactInputSingle(params);

uint256 feeAmount = amountOut.mul(liquidateFeeRate).div(FEE_COEFFICIENT);
uint256 amountAfterFee = amountOut.sub(feeAmount);
// The call to `exactOutputSingle` executes the swap.
amountLiquidated = swapRouter.exactOutputSingle(params);
uint256 leftover = amountInMaximum.sub(amountLiquidated);
uint256 feeAmount = drexAmount.mul(liquidateFeeRate).div(FEE_COEFFICIENT);
uint256 amountAfterFee = drexAmount.sub(feeAmount);
drex.safeTransfer(receiver, amountAfterFee);
drex.safeTransfer(feeCollector, feeAmount);
tselic.safeTransfer(address(rbrllpool), leftover);
}
}
2 changes: 1 addition & 1 deletion contracts/interfaces/ILiquidatePool.sol
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,5 @@ interface ILiquidatePool {
uint256 tselicAmount,
uint256 minReturn,
address receiver
) external;
) external returns (uint256);
}
2 changes: 1 addition & 1 deletion contracts/mocks/MockChainlink.sol
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ contract MockChainlink {

constructor() {
selicRate = 12250000;
unitValue = 14009949999999999803392;
unitValue = 14000000000000000000000;
maturityTime = 1867014000;
}

Expand Down
23 changes: 0 additions & 23 deletions contracts/mocks/MockPriceFeed.sol

This file was deleted.

43 changes: 21 additions & 22 deletions contracts/rBRLLPool.sol
Original file line number Diff line number Diff line change
Expand Up @@ -307,7 +307,7 @@ contract rBRLLPool is rBRLL, AccessControl, Pausable {
* @param _amount the amount of DREX.
*/
function borrowDREX(uint256 _amount) external whenNotPaused realizeInterest {
require(_amount > 0, "Borrow DREX should be more thea 0.");
require(_amount > 0, "Borrow DREX should be more than 0.");

// convert to rBRLL.
uint256 convertTorBRLL = _amount.mul(10 ** 12);
Expand Down Expand Up @@ -364,40 +364,39 @@ contract rBRLLPool is rBRLL, AccessControl, Pausable {
* Emits a `LiquidationRecord` event.
*
* @param borrower The borrower be liquidated
* @param repayAmount The amount of the rBRLL to repay
* @param minReturn the minimum amount of return
* @param repayAmount The amount of the Drex to repay
* @param tselicInMaximum the maximum amount of tselic to be liquidated
*/
function flashLiquidateBorrow(
address borrower,
uint256 repayAmount,
uint256 minReturn
uint256 tselicInMaximum
) external whenNotPaused realizeInterest {
require(liquidateProvider[borrower], "borrower is not a provider.");
_liquidateProcedure(borrower, repayAmount);
liquidatePool.flashLiquidateTSELIC(repayAmount, minReturn, msg.sender);
tselic.transfer(address(liquidatePool), tselicInMaximum);
uint256 tselicAmount = liquidatePool.flashLiquidateTSELIC(
repayAmount,
tselicInMaximum,
msg.sender
);
require(
depositedTSELIC[borrower] >= tselicAmount,
"repayAmount should be less than borrower's deposit."
);
totalDepositedTSELIC -= tselicAmount;
depositedTSELIC[borrower] -= tselicAmount;

emit LiquidationRecord(msg.sender, borrower, repayAmount, block.timestamp);
}

function _liquidateProcedure(address borrower, uint256 repayAmount) internal {
require(msg.sender != borrower, "don't liquidate self.");
uint256 borrowedBRL = getBorrowrBRLLAmountByShares(borrowedShares[borrower]);
require(borrowedBRL >= repayAmount, "repayAmount should be less than borrower's debt.");
_burnrBRLL(msg.sender, repayAmount);

_burnrBRLLDebt(borrower, repayAmount);

// TODO verify the decimal places.
uint256 liquidateTSELIC = repayAmount.div(_tselicPrice());

require(
depositedTSELIC[borrower] >= liquidateTSELIC,
"repayAmount should be less than borrower's deposit."
);
totalDepositedTSELIC -= liquidateTSELIC;
depositedTSELIC[borrower] -= liquidateTSELIC;

tselic.transfer(address(liquidatePool), repayAmount);
uint256 borrowedrBRLL = getBorrowrBRLLAmountByShares(borrowedShares[borrower]);
uint256 convertToDREX = borrowedrBRLL.div(1e12) + 1;
require(convertToDREX >= repayAmount, "repayAmount should be less than borrower's debt.");
_burnrBRLL(msg.sender, borrowedrBRLL);
_burnrBRLLDebt(borrower, borrowedrBRLL);
}

/**
Expand Down
6 changes: 3 additions & 3 deletions test/common/allFixture.js
Original file line number Diff line number Diff line change
Expand Up @@ -79,11 +79,11 @@ async function deployTokensFixture(deployer, investor, investor2) {
await drexToken.deployed()
await tselicToken.deployed()

await drexToken.connect(deployer).transfer(investor.address, ethers.utils.parseUnits("1000", 6))
await drexToken.connect(deployer).transfer(investor.address, ethers.utils.parseUnits("400000", 6))

await drexToken
.connect(deployer)
.transfer(investor2.address, ethers.utils.parseUnits("1000", 6))
.transfer(investor2.address, ethers.utils.parseUnits("400000", 6))

await tselicToken
.connect(deployer)
Expand Down Expand Up @@ -237,7 +237,7 @@ async function deployUniPoolFixture(deployer, tselicToken, drexToken) {
amount0Min: 0,
amount1Min: 0,
recipient: deployer.address,
deadline: Math.floor(Date.now() / 1000) + 60 * 10,
deadline: 32532350693,
}
const tx = await nonfungiblePositionManager
.connect(deployer)
Expand Down
Loading

0 comments on commit 89ccc49

Please sign in to comment.