Skip to content
This repository was archived by the owner on Aug 3, 2025. It is now read-only.
This repository was archived by the owner on Aug 3, 2025. It is now read-only.

Curly Denim Dolphin - Different Amount Sent to the pool from the amount the pool sends to the Distributor #1042

@sherlock-admin2

Description

@sherlock-admin2

Curly Denim Dolphin

Medium

Different Amount Sent to the pool from the amount the pool sends to the Distributor

Summary

The Pool which is the beneficiary of the Auction Coupon tokens attempts to transmit a possibly lower amount to the Distributor contract than what the distributor contract sends to it

Root Cause

In the endAuction Function, the function sends the balance of the contract to the Pool
https://github.com/sherlock-audit/2024-12-plaza-finance/blob/main/plaza-evm/src/Auction.sol#L335C2-L350C4

  */
  function endAuction() external auctionExpired whenNotPaused {
    if (state != State.BIDDING) revert AuctionAlreadyEnded();

    if (currentCouponAmount < totalBuyCouponAmount) {
      state = State.FAILED_UNDERSOLD;
    } else if (totalSellReserveAmount >= (IERC20(sellReserveToken).balanceOf(pool) * poolSaleLimit) / 100) {
        state = State.FAILED_POOL_SALE_LIMIT;
    } else {
      state = State.SUCCEEDED;
      Pool(pool).transferReserveToAuction(totalSellReserveAmount);
      IERC20(buyCouponToken).safeTransfer(beneficiary, IERC20(buyCouponToken).balanceOf(address(this)));
//@audit Here it send the balance of the pool
    }

    emit AuctionEnded(state, totalSellReserveAmount, totalBuyCouponAmount);
  }

But the Pool Itself Gets the totalBuyCouponAmount from the auction to send to the distributor

function distribute() external whenNotPaused {
  (uint256 currentPeriod,) = bondToken.globalPool();
    require(currentPeriod > 0, AccessDenied());

    // Period is increased when auction starts, we want to distribute for the previous period
    uint256 previousPeriod = currentPeriod - 1;
    uint256 couponAmountToDistribute = Auction(auctions[previousPeriod]).totalBuyCouponAmount();

    if (Auction(auctions[previousPeriod]).state() == Auction.State.FAILED_POOL_SALE_LIMIT ||
        Auction(auctions[previousPeriod]).state() == Auction.State.FAILED_UNDERSOLD) {

      emit DistributionRollOver(previousPeriod, couponAmountToDistribute);
      return;
    }

    // Get Distributor
    address distributor = poolFactory.distributors(address(this));

    // Transfer coupon tokens to the distributor
    IERC20(couponToken).safeTransfer(distributor, couponAmountToDistribute);

    // Update distributor with the amount to distribute
    Distributor(distributor).allocate(couponAmountToDistribute);
}

This is inconsistent and wrong

Internal Pre-conditions

External Pre-conditions

No response

Attack Path

No response

Impact

  • Funds will accumulate and get stuck

PoC

No response

Mitigation

Get the balance of the Pool and send to the Distributor since it is divided by period

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions