sherlock-audit / 2023-05-ironbank-judging

2 stars 2 forks source link

bitsurfer - Borrowers can manipulate the protocol in order to minimize the interest accrued on their borrow balance #430

Closed sherlock-admin closed 1 year ago

sherlock-admin commented 1 year ago

bitsurfer

high

Borrowers can manipulate the protocol in order to minimize the interest accrued on their borrow balance

Summary

Borrowers can manipulate the protocol in order to minimize the interest accrued on their borrow balance.

Vulnerability Detail

When a user borrows from IronBank, they will have their own borrowBalance and borrowIndex data. To accrue and update interest, IronBank will call _accrueInterest for a market globally, which will affecting the global market borrowIndex and this will be used to calculate user's borrow in _getBorrowBalance.

The _accrueInterest() will increase global market's borrowIndex while on _getBorrowBalance the denominator, user's borrowIndex is only being updated on borrow() and _repay() function.

The borrow() and repay() function include amount parameter which still callable if this amount is 0. This resulting a user can keep up their borrowIndex with market's borrowIndex by just calling borrow or repay with zero amount frequently.

by default if user (borrower) only do a common path, they will borrow() at X, and repay() at Y, and the diff between Y & X is accounted as interest accumulation time, which is what the borrowIndex is intended to.

The borrowBalance calculation (b.borrowBalance * m.borrowIndex) / b.borrowIndex; assume the m.borrowIndex will increase while the b.borrowIndex will just updated when user is starting and ending their borrow action.

if the m.borrowIndex and b.borrowIndex is almost equal, then the b.borrowBalance will be multiplied with ~1. Thus, user will pay less interest. Thus, the more frequent calls, the less interest they will need to pay.

Impact

When borrowers take actions to minimize their borrowing interest, it can result in a reduction of revenue for the protocol.

Code Snippet

https://github.com/sherlock-audit/2023-05-ironbank/blob/main/ib-v2/src/protocol/pool/IronBank.sol#L846-L855

File: IronBank.sol
846:     function _getBorrowBalance(DataTypes.Market storage m, address user) internal view returns (uint256) {
847:         DataTypes.UserBorrow memory b = m.userBorrows[user];
848:
849:         if (b.borrowBalance == 0) {
850:             return 0;
851:         }
852:
853:         // borrowBalanceWithInterests = borrowBalance * marketBorrowIndex / userBorrowIndex
854:         return (b.borrowBalance * m.borrowIndex) / b.borrowIndex;
855:     }

Tool used

Manual Review

Recommendation

Consider reassessing the interest mechanism or implementing safeguards to protect the borrow() and repay() functions, ensuring that the effort and outcomes involved in these operations are not susceptible to exploitation or abuse.