sherlock-audit / 2023-02-blueberry-judging

12 stars 5 forks source link

berndartmueller - The total lent amount of a bank is not decremented when a position is liquidated #333

Closed github-actions[bot] closed 1 year ago

github-actions[bot] commented 1 year ago

berndartmueller

medium

The total lent amount of a bank is not decremented when a position is liquidated

Summary

When a position is (partially) liquidated, and the debt is repaid, the Bank.totalLend variable is not decremented. This can lead to inaccuracies in the total amount of funds lent out by the bank. Over time, the more positions are liquidated, the more the Bank.totalLend variable will be off.

Vulnerability Detail

The Bank.totalLend variable in the BlueBerryBank contract tracks the total amount of funds lent out by a given ERC-20 token bank. This value is adjusted whenever funds are lent out or withdrawn. However, when a position is (partially) liquidated, the debt is repaid, but the totalLend variable is not decremented.

While the position to be liquidated has its debt repaid and the Position.collateralSize, Position.underlyingAmount and Position.underlyingVaultShare variables decremented, Bank.totalLend remains unchanged and is therefore stale.

Impact

The value of bank.totalLend is stale and does not accurately reflect the actual amount of tokens lent to the bank. This could lead to issues later in the future if the BlueBerryBank contract gets upgraded and needs to rely on the correct value of bank.totalLend.

Code Snippet

BlueBerryBank.sol#L534

511: function liquidate(
512:     uint256 positionId,
513:     address debtToken,
514:     uint256 amountCall
515: ) external override lock poke(debtToken) {
516:     if (amountCall == 0) revert ZERO_AMOUNT();
517:     if (!isLiquidatable(positionId)) revert NOT_LIQUIDATABLE(positionId);
518:     Position storage pos = positions[positionId];
519:     Bank memory bank = banks[pos.underlyingToken];
520:     if (pos.collToken == address(0)) revert BAD_COLLATERAL(positionId);
521:
522:     uint256 oldShare = pos.debtShareOf[debtToken];
523:     (uint256 amountPaid, uint256 share) = repayInternal(
524:         positionId,
525:         debtToken,
526:         amountCall
527:     );
528:
529:     uint256 liqSize = (pos.collateralSize * share) / oldShare;
530:     uint256 uTokenSize = (pos.underlyingAmount * share) / oldShare;
531:     uint256 uVaultShare = (pos.underlyingVaultShare * share) / oldShare;
532:
533:     pos.collateralSize -= liqSize;
534:     pos.underlyingAmount -= uTokenSize; // @audit-info `bank.totalLend` is not decremented by `uTokenSize` - it's stale
535:     pos.underlyingVaultShare -= uVaultShare;
536:
...      // [...]

Tool used

Manual Review

Recommendation

Consider deducting uTokenSize from bank.totalLend in the BlueBerryBank.liquidate function to prevent stale values.

Duplicate of #155