Under certain circumstances while calling refinance() or getting called by bot there will be loss of user funds.
Let's understand vulnerability through scenario.
Suppose Borrower has accepted a loan from lender in which collateralAmount = 1200 ether and loanAmount = 1000 ether and time duration of loan = 6 months and 10% APY.
Borrower has autoRefinancingEnabled ON which means bot can refinance the borrower loan if better rates are available.
Now attacker puts a loan proposal such that new interest rate(9.95%) is less than the borrower's current interest rate (10%).
The above step can be done not only by attacker but by innocent users as well.
Now as autoRefinancingEnabled is on the bot refinances the borrower's loan
So now borrower's new loan gets executed with new params
So now considering new loan's params , the lender have to pay more interest in the new loan compared to old loan as due to addition of 2% of fees on debt and accrual of interest on this new amount till 6 months would be greater than accrural of interest in oldLoanAmount
And the user refinanced his loan for giving less interest rate but rather ends up giving more interest in the new refinanced loan which is totally opposite to how refinance works so a loss of user funds as they have to pay more.
If we calculate debt for 6 months using the above numbers we get 1069.5408246063368355 ether.
We can clearly see that Refinanced loan will be having more debt compared to oldLoan.
A total loss of 21 ether to user due to refinancing loan.
Refinancing loan feature is there to give better rates but instead ends up paying more interest(debt) compared to oldLoan borrower had.
Impact
Loss of User funds as they have to pay more debt if their loan is refinanced compared to previous loan the user had.
The loss increases much more if INTEREST_RATE_PER_SECOND is more than 10%
And the loss can be even be more if there are multiple refinance of a same loan of a borrower as each time the fee would be added to loanAmount and in the remaining time the interest accrued will be on loanAmount + fee collected due to multiple refinancing increasing the loss to user.
If we calculate debt for 6 months using the above numbers we get 1069.5408246063368355 ether.
We can clearly see that Refinanced loan will be having more debt compared to oldLoan.
A total loss of 21 ether to user due to refinancing loan.
Refinancing loan feature is there to give better rates but instead ends up paying more interest(debt) compared to oldLoan borrower had.
Mitigation
One possible solution is there shuld be threshold in interestRate, if difference in 2 interest rate is less than threshold then refinance() should not be called.
As it is dependent on duration of loan as well so the check should be made accordingly such that user doesn't suffer any loss and rather they should be in profit by calling refinance()
smbv-1923
High
Loss of user funds during
refinance()
under certain circumstances.Summary
Loss of user funds during
refinance()
under certain circumstances.Root Cause
Internal pre-conditions
No response
External pre-conditions
No response
Attack Path
Under certain circumstances while calling
refinance()
or getting called by bot there will be loss of user funds.Let's understand vulnerability through scenario.
Suppose Borrower has accepted a loan from lender in which
collateralAmount = 1200 ether
andloanAmount = 1000 ether
and time duration of loan = 6 months and 10% APY.Borrower has autoRefinancingEnabled ON which means bot can refinance the borrower loan if better rates are available.
Now attacker puts a loan proposal such that new interest rate(
9.95%
) is less than the borrower's current interest rate (10%
).The above step can be done not only by attacker but by innocent users as well.
Now as autoRefinancingEnabled is on the bot refinances the borrower's loan
So now borrower's new loan gets executed with new params
collateralAmount
= 1200 etherloanAmount =~ 1020 ether (1000 + 20 ether fees + someInterest)
uint256 fulfillAmount = debt + protocolFee;`So now considering new loan's params , the lender have to pay more interest in the new loan compared to old loan as due to addition of 2% of fees on debt and accrual of interest on this new amount till 6 months would be greater than accrural of interest in oldLoanAmount
And the user refinanced his loan for giving less interest rate but rather ends up giving more interest in the new refinanced loan which is totally opposite to how refinance works so a loss of user funds as they have to pay more.
Proving the above scenario with numbers
Old Loan :
loanAmount
=1000 ether
collateralAmount = 1200 ether
duration = 6 months
interestRate = 10% ( 1000000003020262040)
If we calculate debt for 6 months using the above numbers we get
1048.808892358700421 ether
Calculated using this
debt = (loanAmount * interestRatePerSecond.pow(timeElapsed)) / InterestLib.ONE;
Refinanced Loan(new Loan) :
loanAmount
=~1020 ether ( 1000 eth + 20eth fee + someInterest)
collateralAmount = 1200 ether
duration = 6 months
interestRate = 9.95% ( 1000000003005790500)
If we calculate debt for 6 months using the above numbers we get
1069.5408246063368355 ether
.We can clearly see that Refinanced loan will be having more debt compared to oldLoan.
A total loss of
21 ether
to user due to refinancing loan.Refinancing loan feature is there to give better rates but instead ends up paying more interest(debt) compared to oldLoan borrower had.
Impact
INTEREST_RATE_PER_SECOND
is more than 10%multiple refinance
of a same loan of a borrower as each time the fee would be added to loanAmount and in the remaining time the interest accrued will be on loanAmount + fee collected due to multiple refinancing increasing the loss to user.PoC
loanAmount
=1000 ether
collateralAmount = 1200 ether
duration = 6 months
interestRate = 10% ( 1000000003020262040)
1048.808892358700421 ether
debt = (loanAmount * interestRatePerSecond.pow(timeElapsed)) / InterestLib.ONE;
loanAmount
=~1020 ether ( 1000 eth + 20eth fee + someInterest)
collateralAmount = 1200 ether
duration = 6 months
interestRate = 9.95% ( 1000000003005790500)
1069.5408246063368355 ether
.21 ether
to user due to refinancing loan.Mitigation
interestRate
, if difference in 2 interest rate is less than threshold thenrefinance()
should not be called.refinance()