J4de
high
As long as one token withdraw fails, the entire collateral may fail to withdraw
File: CollateralManager.sol
400 function _withdraw(uint256 _bidId, address _receiver) internal virtual {
401 for (
402 uint256 i;
403 i < _bidCollaterals[_bidId].collateralAddresses.length();
404 i++
405 ) {
406 // Get collateral info
407 Collateral storage collateralInfo = _bidCollaterals[_bidId]
408 .collateralInfo[
409 _bidCollaterals[_bidId].collateralAddresses.at(i)
410 ];
411 // Withdraw collateral from escrow and send it to bid lender
412 ICollateralEscrowV1(_escrows[_bidId]).withdraw(
413 collateralInfo._collateralAddress,
414 collateralInfo._amount,
415 _receiver
416 );
417 emit CollateralWithdrawn(
418 _bidId,
419 collateralInfo._collateralType,
420 collateralInfo._collateralAddress,
421 collateralInfo._amount,
422 collateralInfo._tokenId,
423 _receiver
424 );
425 }
426 }
The borrower will call the CollateralManager#withdraw
function when withdrawing the collateral, and further call the _withdraw
function, which will try to transfer all tokens. The problem is that as long as there is a token transfer failure, the entire collateral will become unavailable.
There are several situations that cause a certain token transfer to fail (there may be more):
- There is a problem with the token contract itself
- Malicious lenders require borrowers to provide collateral for a malicious token
- Any attacker injects a malicious token through
commitCollateral
- The borrower's receiving address is band by a certain token
All tokens are external dependencies, and all funds cannot be lost because of an external dependency.
The borrower may have repaid all the loans in batches, but failed to withdraw the collateral, resulting in a loss of funds.
Manual Review
It is suggested that the borrower can actively retry the withdrawal of the specified token.