Debts owed by blacklisted users cannot be liquidated
Description
The Comptroller contract controls and restricts actions that users can take on the lending platform. One of the modifications made to this contract is the new implementation of an address blacklist, stored in the Comptroller. Admins can add addresses to the blacklist using the _setBlacklist
external function, and, if an address is blacklisted, actions such as minting and borrowing are rejected by the Comptroller:
function mintAllowed(address tToken, address minter, uint256 mintAmount) external override returns (uint256) {
// [...]
if (blackList[minter]) {
return uint256(Error.REJECTION);
}
// [...]
function borrowAllowed(address tToken, address borrower, uint256 borrowAmount)
external
override
returns (uint256)
{
// [...]
if (blackList[borrower]) {
return uint256(Error.REJECTION);
}
Out of all of the permissions-check functions in the Comptroller, the blacklist check was added to mintAllowed
, redeemAllowed
(via redeemAllowedInternal
), transferAllowed
(via redeemAllowedInternal
), borrowAllowed
, and repayBorrowAllowed
. On the other hand, the check was not added to liquidateBorrowAllowed
and seizeAllowed
. This omission was intended to allow positions held by blacklisted addresses to be liquidated.
However, during the actual execution of a liquidation, the business logic actually performs a check that is rejected due to the blacklist. This can be seen in TToken.liquidateBorrowFresh
, which calls repayBorrowFresh
, which then calls Comptroller.repayBorrowAllowed
, which uses the blacklist.
Impact
Positions held by blacklisted addresses cannot be liquidated and will continue accruing interest until they are unblacklisted, even as the prices of the underlying assets change over time. This can result in an unresolvable protocol skew that threatens the solvency of the protocol.
Recommendations
We recommend reviewing the liquidation workflow and adjusting the modifications accordingly in order to allow for the liquidation of a blacklisted position. An alternative design option would be to add functionality that allows admins to immediately liquidate or repay positions that would be blacklisted and to always do that first so that blacklisted addresses do not hold any positions.
In any case, we recommend adding comprehensive tests so that this and any other divergence between expected and actual functionality can be detected without manual review.
Remediation
This issue has been acknowledged by Takara Lend, and a fix was implemented in commit 4f09afa0↗.