the new borrower that will get matched in the liquidateWithReplacement() will not be charged any swapFees
N.B According to whitepaper, a fix swapfee (0.5%) charged annually (apr) on all transaction that cause the exchange of cash vs credit and paid by cash recipient
This will lead to borrowers that get matched through the liquidateWithReplacement() call to unfairly get more cashamountIn for the creditAmountOut they will incure, and will also cause the protocol to lose yield on that newly created position.
As we can see from the code snippet the newly matched borrower will recieve issuanceValue, which doesn't include any swapFee, leading to a loss of yield for the protocol and an unfair scenarios for other borrowers who get mathed through buyCreditMarket() and sellCreditMarket()
Recomendation
Include the swapFees when computing how much tokens to send to the borrower and to the feeRecipient
- issuanceValue = Math.mulDivDown(debtPositionCopy.futureValue, PERCENT, PERCENT + ratePerTenor);
+#@audit issuanceValue doesn't include the fees and will be sen to feeRecipient when deducting from futureValue
+ (issuanceValue,_) =state.getCashAmountOut({
+ creditAmountIn: debtPositionCopy.futureValue,
+ maxCredit: debtPositionCopy.futureValue,
+ ratePerTenor: ratePerTenor,
+ tenor: tenor
+ })
liquidatorProfitBorrowToken = debtPositionCopy.futureValue - issuanceValue;
debtPosition.borrower = params.borrower;
debtPosition.futureValue = debtPositionCopy.futureValue;
debtPosition.liquidityIndexAtRepayment = 0;
emit Events.UpdateDebtPosition(
params.debtPositionId,
debtPosition.borrower,
debtPosition.futureValue,
debtPosition.liquidityIndexAtRepayment
);
state.data.debtToken.mint(params.borrower, debtPosition.futureValue);
state.data.borrowAToken.transferFrom(address(this), params.borrower, issuanceValue);
state.data.borrowAToken.transferFrom(address(this), state.feeConfig.feeRecipient, liquidatorProfitBorrowToken);
}
Lines of code
https://github.com/code-423n4/2024-06-size/blob/8850e25fb088898e9cf86f9be1c401ad155bea86/src/libraries/actions/LiquidateWithReplacement.sol#L146-L162
Vulnerability details
Impact
the new borrower that will get matched in the
liquidateWithReplacement()
will not be charged any swapFeesThis will lead to borrowers that get matched through the
liquidateWithReplacement()
call to unfairly get more cashamountIn for the creditAmountOut they will incure, and will also cause the protocol to lose yield on that newly created position.Proof Of Concept
The size protocol offers the pssibility to seamlessly liquidate an unhealthy borrower and instead of giving the cash directly to the lender, the protcol enables one of its bots to replace the unhealthy borrower with a new borrow to enable the protocol to earn extra cash. The code snippet that handles how much cash the newlty matched borrower wil recieved is the follwoing https://github.com/code-423n4/2024-06-size/blob/8850e25fb088898e9cf86f9be1c401ad155bea86/src/libraries/actions/LiquidateWithReplacement.sol#L146-L162
As we can see from the code snippet the newly matched borrower will recieve
issuanceValue
, which doesn't include anyswapFee
, leading to a loss of yield for the protocol and an unfair scenarios for other borrowers who get mathed throughbuyCreditMarket()
andsellCreditMarket()
Recomendation
Include the swapFees when computing how much tokens to send to the borrower and to the
feeRecipient
Assessed type
Context