TellerV2.sol#lenderAcceptBid() - Protocol fee and marketplace fee can change after the borrower submitBid
Summary
TellerV2.sol#lenderAcceptBid() - Protocol fee and marketplace fee can change after the borrower submitBid
Vulnerability Detail
When a borrower calls submitBid, he sees and expects that the protocol fee and marketplace fee don't change during the period when his bid is pending, but they can change.
When a lender fills a bid, some part of the principal goes to the protocol and to the marketplace as fees. If the fees go up, then the borrower can be left with less amountToBorrower than he expected when he originally submitted the bid.
function lenderAcceptBid(uint256 _bidId)
external
override
pendingBid(_bidId, "lenderAcceptBid")
whenNotPaused
returns (
uint256 amountToProtocol,
uint256 amountToMarketplace,
uint256 amountToBorrower
)
{
// Retrieve bid
Bid storage bid = bids[_bidId];
address sender = _msgSenderForMarket(bid.marketplaceId);
(bool isVerified, ) = marketRegistry.isVerifiedLender(
bid.marketplaceId,
sender
);
require(isVerified, "Not verified lender");
require(
!marketRegistry.isMarketClosed(bid.marketplaceId),
"Market is closed"
);
require(!isLoanExpired(_bidId), "Bid has expired");
// Set timestamp
bid.loanDetails.acceptedTimestamp = uint32(block.timestamp);
bid.loanDetails.lastRepaidTimestamp = uint32(block.timestamp);
// Mark borrower's request as accepted
bid.state = BidState.ACCEPTED;
// Declare the bid acceptor as the lender of the bid
bid.lender = sender;
// Tell the collateral manager to deploy the escrow and pull funds from the borrower if applicable
collateralManager.deployAndDeposit(_bidId);
// Transfer funds to borrower from the lender
amountToProtocol = bid.loanDetails.principal.percent(protocolFee());
amountToMarketplace = bid.loanDetails.principal.percent(
marketRegistry.getMarketplaceFee(bid.marketplaceId)
);
amountToBorrower =
bid.loanDetails.principal -
amountToProtocol -
amountToMarketplace;
//transfer fee to protocol
if (amountToProtocol > 0) {
bid.loanDetails.lendingToken.safeTransferFrom(
sender,
owner(),
amountToProtocol
);
}
//transfer fee to marketplace
if (amountToMarketplace > 0 ) {
bid.loanDetails.lendingToken.safeTransferFrom(
sender,
marketRegistry.getMarketFeeRecipient(bid.marketplaceId),
amountToMarketplace
);
}
//transfer funds to borrower
if (amountToBorrower > 0) {
bid.loanDetails.lendingToken.safeTransferFrom(
sender,
bid.receiver,
amountToBorrower
);
}
// Record volume filled by lenders
lenderVolumeFilled[address(bid.loanDetails.lendingToken)][sender] += bid
.loanDetails
.principal;
totalVolumeFilled[address(bid.loanDetails.lendingToken)] += bid
.loanDetails
.principal;
// Add borrower's active bid
_borrowerBidsActive[bid.borrower].add(_bidId);
// Emit AcceptedBid
emit AcceptedBid(_bidId, sender);
emit FeePaid(_bidId, "protocol", amountToProtocol);
emit FeePaid(_bidId, "marketplace", amountToMarketplace);
}
Impact
Fees can change between when a bit is submitted and when is accepted, which is unfair to the borrower.
EgisSecurity
medium
TellerV2.sol#lenderAcceptBid() - Protocol fee and marketplace fee can change after the borrower
submitBid
Summary
TellerV2.sol#lenderAcceptBid() - Protocol fee and marketplace fee can change after the borrower
submitBid
Vulnerability Detail
When a borrower calls
submitBid
, he sees and expects that the protocol fee and marketplace fee don't change during the period when his bid is pending, but they can change.When a lender fills a bid, some part of the principal goes to the protocol and to the marketplace as fees. If the fees go up, then the borrower can be left with less
amountToBorrower
than he expected when he originally submitted the bid.Impact
Fees can change between when a bit is submitted and when is accepted, which is unfair to the borrower.
Code Snippet
https://github.com/sherlock-audit/2024-04-teller-finance/blob/defe55469a2576735af67483acf31d623e13592d/teller-protocol-v2-audit-2024/packages/contracts/contracts/TellerV2.sol#L524-L527
Tool used
Manual Review
Recommendation
Whenever a bit is submitted, cache the protocol fee and the marketplace fee for that bid.
Duplicate of #125