Dandy Caramel Tortoise
High
Insufficient validation for try/catch
address will disallow borrower's from repaying their loans
A malicious lender can bypass the try/catch
block covering the repayLoanCallback external call by selfdestructing loanRepaymentListener
if (loanRepaymentListener != address(0)) {
require(gasleft() >= 80000, "NR gas"); //fixes the 63/64 remaining issue
try
ILoanRepaymentListener(loanRepaymentListener).repayLoanCallback{
gas: 80000
}( //limit gas costs to prevent lender preventing repayments
_bidId,
_msgSenderForMarket(bid.marketplaceId),
_payment.principal,
_payment.interest
)
The try/catch
block will revert if the call is made to a non-contract address. To avoid this a check for codesize > 0
is kept inside the setRepaymentListenerForBid
function. But this can be bypassed by the lender selfdestructing
the _listener
in the same transaction which will delete the contract
function setRepaymentListenerForBid(uint256 _bidId, address _listener) external {
uint256 codeSize;
assembly {
codeSize := extcodesize(_listener)
}
require(codeSize > 0, "Not a contract");
address sender = _msgSenderForMarket(bids[_bidId].marketplaceId);
require(
sender == getLoanLender(_bidId),
"Not lender"
);
repaymentListenerForBid[_bidId] = _listener;
}
No response
No response
- Lender creates a contract which can
selfdestruct
itself - Lender sets this address as the repaymentListener
- In the same tx, the lender destroys the contract
- Now the borrower cannot repay because the try/catch block will always revert
Borrowers will not be able to repay the loan allowing the lender to steal the collateral after the loan will default
No response
Use .call instead of the try/catch