sherlock-audit / 2023-02-blueberry-judging

12 stars 5 forks source link

yongkiws - ensure that users do not borrow or pay back more than the amount available at the bank #364

Closed github-actions[bot] closed 1 year ago

github-actions[bot] commented 1 year ago

yongkiws

medium

ensure that users do not borrow or pay back more than the amount available at the bank

Summary

ensure that users can only borrow or repay the amount available at the bank, and will prevent share overflow attacks from occurring. In addition, it is recommended to validate other inputs such as the token type and the transfer amount to ensure that the transactions carried out are safe and correct.

Vulnerability Detail

Summary

Impact

Summary

Code Snippet

BlueBerryBank.sol
760:     function repayInternal(
761:         uint256 positionId,
762:         address token,
763:         uint256 amountCall
764:     ) internal returns (uint256, uint256) {
765:         Bank storage bank = banks[token];
766:         Position storage pos = positions[positionId];
767:         uint256 totalShare = bank.totalShare;
768:         uint256 totalDebt = bank.totalDebt;
769:         uint256 oldShare = pos.debtShareOf[token];
770:         uint256 oldDebt = (oldShare * totalDebt).divCeil(totalShare);
771:         if (amountCall == type(uint256).max) {
772:             amountCall = oldDebt;
773:         }
774:         amountCall = doERC20TransferIn(token, amountCall);
775:         uint256 paid = doRepay(token, amountCall);
776:         if (paid > oldDebt) revert REPAY_EXCEEDS_DEBT(paid, oldDebt); // prevent share overflow attack
777:         uint256 lessShare = paid == oldDebt
778:             ? oldShare
779:             : (paid * totalShare) / totalDebt;
780:         bank.totalShare = totalShare - lessShare;
781:         uint256 newShare = oldShare - lessShare;
782:         pos.debtShareOf[token] = newShare;
783:         if (newShare == 0) {
784:             pos.debtMap &= ~(1 << uint256(bank.index));
785:         }
786:         return (paid, lessShare);
787:     }
BlueBerryBank.sol
709:     function borrow(address token, uint256 amount)
710:         external
711:         override
712:         inExec
713:         poke(token)
714:         onlyWhitelistedToken(token)
715:     {
716:         if (!isBorrowAllowed()) revert BORROW_NOT_ALLOWED();
717:         Bank storage bank = banks[token];
718:         Position storage pos = positions[POSITION_ID];
719:         uint256 totalShare = bank.totalShare;
720:         uint256 totalDebt = bank.totalDebt;
721:         uint256 share = totalShare == 0
722:             ? amount
723:             : (amount * totalShare).divCeil(totalDebt);
724:         bank.totalShare += share;
725:         uint256 newShare = pos.debtShareOf[token] + share;
726:         pos.debtShareOf[token] = newShare;
727:         if (newShare > 0) {
728:             pos.debtMap |= (1 << uint256(bank.index));
729:         }
730:         IERC20Upgradeable(token).safeTransfer(
731:             msg.sender,
732:             doBorrow(token, amount)
733:         );
734:         emit Borrow(POSITION_ID, msg.sender, token, amount, share);
735:     }

Tool used

Manual Review

Recommendation

consider add validation

if (amount > bank.totalDebt) {
    revert BORROW_EXCEEDS_DEBT(amount, bank.totalDebt);
}
if (amountCall > oldDebt) {
    revert REPAY_EXCEEDS_DEBT(amountCall, oldDebt);
}