TempleGold

TempleDAO
Foundry
25,000 USDC
View results
Submission Details
Severity: medium
Invalid

Loss of Bidder Funds in SpiceToken Auction Contract When No AuctionTokens

Summary

The issue arises when users to place bids using a "bid token" even if there are no "auction tokens" (e.g., SpiceToken) available for distribution. This can lead to users losing their bid tokens without receiving any` SpiceTokens` in return.

Vulnerability Details

The vulnerability lies in the interaction between the bid and claim functions:

bid Function (Missing Balance Check):

https://github.com/Cyfrin/2024-07-templegold/blob/main/protocol%2Fcontracts%2Ftemplegold%2FSpiceAuction.sol#L183-L203

There's no check if there's any `AuctionToken` available before pulling the `bidToken` from the user to the `reciepient`

```solidity

function bid(uint256 amount) external virtual override {

/// @dev Cache, gas savings

uint256 epochId = _currentEpochId;

EpochInfo storage info = epochs[epochId];

if(!info.isActive()) { revert CannotDeposit(); }

if (amount == 0) { revert CommonEventsAndErrors.ExpectedNonZero(); }

SpiceAuctionConfig storage config = auctionConfigs[epochId];

(address bidToken,) = _getBidAndAuctionTokens(config);

address _recipient = config.recipient;

uint256 _bidTokenAmountBefore = IERC20(bidToken).balanceOf(_recipient);

IERC20(bidToken).safeTransferFrom(msg.sender, _recipient, amount);

uint256 _bidTokenAmountAfter = IERC20(bidToken).balanceOf(_recipient);

// fee on transfer tokens

if (amount != _bidTokenAmountAfter - _bidTokenAmountBefore) { revert CommonEventsAndErrors.InvalidParam(); }

depositors[msg.sender][epochId] += amount;

info.totalBidTokenAmount += amount;

emit Deposit(msg.sender, epochId, amount);

}

```

https://github.com/Cyfrin/2024-07-templegold/blob/main/protocol%2Fcontracts%2Ftemplegold%2FSpiceAuction.sol#L209-L226

Claim proceeds to try to send the bidder the auction token but fails due to no tokens available.

```solidity

function claim(uint256 epochId) external virtual override {

/// @notice cannot claim for current live epoch

EpochInfo storage info = epochs[epochId];

if (info.startTime == 0) { revert InvalidEpoch(); }

if (!info.hasEnded()) { revert CannotClaim(epochId); }

uint256 bidTokenAmount = depositors[msg.sender][epochId];

if (bidTokenAmount == 0) { revert CommonEventsAndErrors.ExpectedNonZero(); }

delete depositors[msg.sender][epochId];

SpiceAuctionConfig storage config = auctionConfigs[epochId];

(, address auctionToken) = _getBidAndAuctionTokens(config);

uint256 claimAmount = bidTokenAmount.mulDivRound(info.totalAuctionTokenAmount, info.totalBidTokenAmount, false);

/// checkpoint claim for auction token

_claimedAuctionTokens[auctionToken] += claimAmount;

IERC20(auctionToken).safeTransfer(msg.sender, claimAmount);

emit Claim(msg.sender, epochId, bidTokenAmount, claimAmount);

}

```

The issue is the lack of a check in the bid function to ensure sufficient auction token balance before accepting bids. This allows users to potentially lose their bid tokens unknowingly.

Impact

Users who place bids with the expectation of receiving `SpiceTokens` could lose the value of their bid tokens if no `SpiceTokens` are available for claim.

Tools Used

Manual Review

Recommendations

Implement a check for a non-zero auction token balance within the startAuction function before initiating an auction. This prevents accepting bids when there are no auction tokens to distribute.

```solidity

function startAuction() external override {

// ... other checks

uint256 balance = IERC20(auctionToken).balanceOf(address(this));

if (balance == 0) { revert NotEnoughAuctionTokens(); }

// ... rest of the function

}

```

Alternatively consider implementing an alternative mechanism (if technically feasible) where users can withdraw their bid tokens if no auction tokens are available for claim. This provides users with more control over their funds.

Updates

Lead Judging Commences

inallhonesty Lead Judge about 1 year ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.