Tiny Gingerbread Tarantula
High
The matchOffersV3 function in the DebitaV3Aggregator.sol
contract is vulnerable to front-running attacks, where a lender can increase the APR (Annual Percentage Rate) to any value after seeing a borrower's transaction in the mempool. This can lead to higher interest rates for the borrower than initially intended apr
The root cause of the issue is that In the updateLendOrder function, the lender can update critical parameters such as APR, as the APR param has no max bound limit, after the borrower's transaction is visible in the mempool but before it is mined. This allows the lender to increase the APR, resulting in higher interest payments for the borrower
No response
No response
No response
Borrowers are forced to pay higher interest than initially anticipated, leading to unfair loan terms and potential financial losses.
• Bob wants to borrow `100,000` USD from Alice.
• Alice initially sets an APR of `2,000 bps (20%)`, which is acceptable to Bob.
• Jack matches the borrow and lend orders (matchOffersV3).
• Alice sees Jack’s pending transaction in the mempool and updates her APR to 100,000 bps (1,000%) before the transaction is executed.
• Interest is calculated for a 7-day loan on the borrowed amount (100,000 USD).
Calculations
The formula for interest based on APR is:
• Initial APR (20%) Calculation:
• Borrowed Amount: 100,000 USD
• APR: 2,000 bps = 20%
• Loan Duration: 7 days
• Initial APR (20%) Calculation:
• Borrowed Amount: 100,000 USD
• APR: 2,000 bps = 20%
• Loan Duration: 7 days
As shown:
uint anualInterest = (offer.principleAmount * offer.apr) / 10000;
initial interest = ((100,000 USD * 2,000) / 10,000)
7 days interest:
uint interest = (anualInterest * activeTime) / 31536000;
interest = (20000 * 604800) / 31536000 Expected 7 days interest = 383.56 USD
Front-Run APR (1,000%) Calculation: • Borrowed Amount: 100,000 USD • APR: 100,000 bps = 1,000% • Loan Duration: 7 days
interest = ((100,000 USD * 100,000) / 10,000) interest = (1,000,000 * 604800) / 31536000
Interest after front-run in 7 days = 19,178.08 USD
Lender still has the tendency to increase the APR
From the above: • Before Front-Running: Bob pays $383.56 interest for 7 days. • After Front-Running: Bob pays $19,178.08 interest for the same 7 days, which is 50x higher.
To mitigate this issue, borrowers should be able to set acceptable APR bounds that they are willing to pay. Here is the corrected code:
function createBorrowOrder(
...,
uint _maxAcceptableAPR,
...
) external returns (address) {
require(_maxAcceptableAPR > 0, "Invalid APR bound");
...
borrowOffer.initialize(
...,
_maxAcceptableAPR,
...
);
...
}
In matchOffersV3
function matchOffersV3(
...
) public returns (address) {
...
for (uint i = 0; i < lendOrders.length; i++) {
require(
lendInfo.apr <= borrowOrder.maxAcceptableAPR,
"APR exceeds acceptable limit"
);
}
...
}
The protocol can decide to add a cap in updateLendOrder
require(newApr <= 10000, "APR Capp reached")