This repository was archived by the owner on Aug 3, 2025. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
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
Copy link
Copy link
Open
Description
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
Labels
No labels