Mini Plum Pike
Medium
The protocol and users will receive amounts of loan tokens lower than transferred when USDB rebase negatively
According to the README, 'on Blast it will be USDB and USDC on other prediction markets'. This means USDB will be accepted as loan tokens on Blast and USDC on other blockchains. USDB is a rebasing token and USDC is upgradeable, implying that USDC features can change if there is an upgrade.
PredictDotLoan
is not confirming the amount received after every transfer, causing the protocol and the users to receive different amount of tokens from what is transferred if rebasing takes place during the transfer. The protocol will lose fees because of this.
PredictDotLoan::_transferLoanAmountAndProtocolFee
and PredictDotLoan::_transferLoanAmountAndProtocolFeeWithoutDeductingFromLoanAmount
do not confirm the loan token amount received after fee transfer to the PredictDotLoan::protocolFeeRecipient
address and loan value transfer to the lenders and borrowers as shown in the functions below.
No response
USDB negative rebasing happening during any of the transfers. USDC, being upgradeable contract, gets upgraded to fee-on-transfer, rebasing token or any other unpredictable feature is added.
No response
Protocol will lose fees, lenders will get far less than amount borrowed and borrower will get less than the borrowed amount making it difficult for him to pay back the loan.
No response
Refactor PredictDotLoan::_transferLoanAmountAndProtocolFee
and PredictDotLoan::_transferLoanAmountAndProtocolFeeWithoutDeductingFromLoanAmount
as below.
function _transferLoanAmountAndProtocolFee(
address from,
address to,
uint256 loanAmount
) private returns (uint256 protocolFee) {
protocolFee = (loanAmount * protocolFeeBasisPoints) / 10_000;
+ uint256 userBalanceBefore = LOAN_TOKEN.balanceOf(to);
LOAN_TOKEN.safeTransferFrom(from, to, loanAmount - protocolFee);
+ require(LOAN_TOKEN.balanceOf(to) - userBalanceBefore == loanAmount - protocolFee, 'Invalid amount');
if (protocolFee > 0) {
+ uint256 protocolBalanceBefore = LOAN_TOKEN.balanceOf(protocolFeeRecipient);
LOAN_TOKEN.safeTransferFrom(from, protocolFeeRecipient, protocolFee);
+ require(LOAN_TOKEN.balanceOf(protocolFeeRecipient) - protocolBalanceBefore == protocolFee, 'Invalid amount');
}
}
function _transferLoanAmountAndProtocolFeeWithoutDeductingFromLoanAmount(
address from,
address to,
uint256 loanAmount,
uint256 protocolFee
) private {
+ uint256 userBalanceBefore = LOAN_TOKEN.balanceOf(to);
LOAN_TOKEN.safeTransferFrom(from, to, loanAmount);
+ require(LOAN_TOKEN.balanceOf(to) - userBalanceBefore == loanAmount, 'Invalid amount');
if (protocolFee > 0) {
+ uint256 protocolBalanceBefore = LOAN_TOKEN.balanceOf(protocolFeeRecipient);
LOAN_TOKEN.safeTransferFrom(from, protocolFeeRecipient, protocolFee);
+ require(LOAN_TOKEN.balanceOf(protocolFeeRecipient) - protocolBalanceBefore == protocolFee, 'Invalid amount');
}
}