J4de
high
Borrowers can pre-emptively call CollateralManager.sol#commitCollateral
to modify the number of collateral before the lender accepts, resulting in almost 0 collateral.
In addition, the attacker can also call commitCollateral
to let the borrower despoit a lot of collateral.
File: TellerV2.sol
470 function lenderAcceptBid(uint256 _bidId)
471 external
472 override
473 pendingBid(_bidId, "lenderAcceptBid")
474 whenNotPaused
475 returns (
476 uint256 amountToProtocol,
477 uint256 amountToMarketplace,
478 uint256 amountToBorrower
479 )
480 {
481 // Retrieve bid
482 Bid storage bid = bids[_bidId];
483
484 address sender = _msgSenderForMarket(bid.marketplaceId);
485
486 (bool isVerified, ) = marketRegistry.isVerifiedLender(
487 bid.marketplaceId,
488 sender
489 );
490 require(isVerified, "Not verified lender");
491
492 require(
493 !marketRegistry.isMarketClosed(bid.marketplaceId),
494 "Market is closed"
495 );
496
497 require(!isLoanExpired(_bidId), "Bid has expired");
498
499 // Set timestamp
500 bid.loanDetails.acceptedTimestamp = uint32(block.timestamp);
501 bid.loanDetails.lastRepaidTimestamp = uint32(block.timestamp);
502
503 // Mark borrower's request as accepted
504 bid.state = BidState.ACCEPTED;
505
506 // Declare the bid acceptor as the lender of the bid
507 bid.lender = sender;
508
509 // Tell the collateral manager to deploy the escrow and pull funds from the borrower if applicable
510 >> collateralManager.deployAndDeposit(_bidId);
511
512 // Transfer funds to borrower from the lender
513 amountToProtocol = bid.loanDetails.principal.percent(protocolFee());
514 amountToMarketplace = bid.loanDetails.principal.percent(
515 marketRegistry.getMarketplaceFee(bid.marketplaceId)
516 );
Lenders are more inclined to lend loans to borrowers with a lot of collaterals. When a lender accepts a bid with a lot of collaterals, it will call the lenderAcceptBid
function, and the lenderAcceptBid
function will further call collateralManager.deployAndDeposit
to allow the borrower to deposit collaterals.
File: CollateralManager.sol
119 function commitCollateral(
120 uint256 _bidId,
121 Collateral[] calldata _collateralInfo
122 ) public returns (bool validation_) {
123 address borrower = tellerV2.getLoanBorrower(_bidId);
124 (validation_, ) = checkBalances(borrower, _collateralInfo);
125
126 //if the collateral info is valid, call commitCollateral for each one
127 if (validation_) {
128 for (uint256 i; i < _collateralInfo.length; i++) {
129 Collateral memory info = _collateralInfo[i];
130 _commitCollateral(_bidId, info);
131 }
132 }
133 }
Borrowers can call commitCollateral
in advance to modify the number of collateral to 0, and then they can borrow at zero cost.
Borrowers can borrow with zero collateral, and they don’t have to repay at all.
Manual Review
It is recommended that commitCollateral
can only be called once and add onlyTellerV2
.