You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
This repository has been archived by the owner on Mar 3, 2024. It is now read-only.
sherlock-admin opened this issue
Aug 28, 2023
· 0 comments
Labels
DuplicateA valid issue that is a duplicate of an issue with `Has Duplicates` labelHighA valid High severity issueRewardA payout will be made for this issue
Calling Cooler.claimDefaulted will lose all unclaimed payments.
Summary
Loans not using repayDirect (repayDirect = false) must call Cooler.claimRepaid to get their unclaimed debt payments.
However, if someone calls Cooler.claimDefaulted first, loan.unclaimed is set to 0 wiping any ability to claim them.
Vulnerability Detail
Alice calls Cooler.clearRequest with repayDirect set to false
Bob, who made the loanRequest pays back the loan in time.
The time for the loan runs out
Charles calls Cooler.claimDefaulted on that loan
Alice calls claimRepaid and gets zero tokens.
Note that it is possible to call both Cooler.claimDefaulted and Clearinghouse.claimDefaulted on loans that have been fully repaid.
Impact
Lenders using repayDirect = false will likely lose all debt payments.
Two likely scenarios
Defaulted loans that have received some payments
The lender will only get the remaining collateral and not any payments (if they don't call claimRepaid first).
Loans that are paid back, but the lender does not claim the payments before the expiry date.
In this scenario, the lender will lose all payments
Even without malicious intent, unclaimed loans will be wiped when someone calls ClearingHouse.claimDefaulted, which is encouraged.
/// @notice Claim collateral upon loan default./// @param loanID_ index of loan in loans[]/// @return defaulted debt by the borrower, collateral kept by the lender, elapsed time since expiry.function claimDefaulted(uint256loanID_) externalreturns (uint256, uint256, uint256) {
Loan memory loan = loans[loanID_];
delete loans[loanID_]; //<--- @audit removes all information on loanif (block.timestamp<= loan.expiry) revertNoDefault();
// Transfer defaulted collateral to the lender.collateral().safeTransfer(loan.lender, loan.collateral); // <---- @audit only loan.collateral, loan.unclaimed can be non-0 at this point// Log the event.factory().newEvent(loanID_, CoolerFactory.Events.DefaultLoan, 0);
// If necessary, trigger lender callback.if (loan.callback) CoolerCallback(loan.lender).onDefault(loanID_, loan.amount, loan.collateral);
return (loan.amount, loan.collateral, block.timestamp- loan.expiry);
}
/// @notice Claim debt tokens if repayDirect was false./// @param loanID_ index of loan in loans[].function claimRepaid(uint256loanID_) external {
Loan memory loan = loans[loanID_];
// Update storage.uint256 claim = loan.unclaimed; // <--- @audit This value is always zero after claimDefaulted has been called successfully. delete loans[loanID_].unclaimed;
// Transfer repaid debt back to the lender.debt().safeTransfer(loan.lender, claim);
}
Tool used
Manual Review
Recommendation
Cooler.claimDefaulted should send along loan.unclaimed before wiping the loan.
sherlock-admin2
changed the title
Tart Peanut Rabbit - Calling Cooler.claimDefaulted will lose all unclaimed payments.
jkoppel - Calling Cooler.claimDefaulted will lose all unclaimed payments.
Sep 12, 2023
Sign up for freeto subscribe to this conversation on GitHub.
Already have an account?
Sign in.
Labels
DuplicateA valid issue that is a duplicate of an issue with `Has Duplicates` labelHighA valid High severity issueRewardA payout will be made for this issue
jkoppel
medium
Calling Cooler.claimDefaulted will lose all unclaimed payments.
Summary
Loans not using repayDirect (
repayDirect = false
) must callCooler.claimRepaid
to get their unclaimed debt payments.However, if someone calls
Cooler.claimDefaulted
first,loan.unclaimed
is set to0
wiping any ability to claim them.Vulnerability Detail
Cooler.clearRequest
withrepayDirect
set tofalse
loanRequest
pays back the loan in time.Cooler.claimDefaulted
on that loanclaimRepaid
and gets zero tokens.Note that it is possible to call both
Cooler.claimDefaulted
andClearinghouse.claimDefaulted
on loans that have been fully repaid.Impact
Lenders using
repayDirect = false
will likely lose all debt payments.Two likely scenarios
The lender will only get the remaining collateral and not any payments (if they don't call
claimRepaid
first).In this scenario, the lender will lose all payments
Even without malicious intent, unclaimed loans will be wiped when someone calls
ClearingHouse.claimDefaulted
, which is encouraged.Code Snippet
https://github.com/sherlock-audit/2023-08-cooler/blob/main/Cooler/src/Cooler.sol#L315-L333
Cooler.claimDefaulted
https://github.com/sherlock-audit/2023-08-cooler/blob/main/Cooler/src/Cooler.sol#L302-L313
Tool used
Manual Review
Recommendation
Cooler.claimDefaulted
should send alongloan.unclaimed
before wiping the loan.Duplicate of #119
The text was updated successfully, but these errors were encountered: