TempleGold

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

The user will receive more auction token than user expected after DAO executor call recoverToken in the SpiceAuction

Summary

While claiming the bid token, the user will get auction token. In SpiceAuction.sol file.

In recoverToken, we didn't update _totalAuctionTokenAllocation[token], but In recoverAuctionTokenForZeroBidAuction, we update _totalAuctionTokenAllocation[auctionToken]. It will affect user's claim amount calculation.

/**
* @notice Recover auction tokens for last but not started auction
* @param token Token to recover
* @param to Recipient
* @param amount Amount to auction tokens
*/
function recoverToken(
address token,
address to,
uint256 amount
) external override onlyDAOExecutor {
...
if (amount > maxRecoverAmount) { revert CommonEventsAndErrors.InvalidParam(); }
>> // @audit no update _totalAuctionTokenAllocation[token]
>> IERC20(token).safeTransfer(to, amount);
emit CommonEventsAndErrors.TokenRecovered(to, token, amount);
}
/**
* @notice Recover auction tokens for epoch with zero bids
* @param epochId Epoch Id
* @param to Recipient
*/
function recoverAuctionTokenForZeroBidAuction(uint256 epochId, address to) external override onlyDAOExecutor {
...
uint256 amount = epochInfo.totalAuctionTokenAmount;
>> _totalAuctionTokenAllocation[auctionToken] -= amount;
emit CommonEventsAndErrors.TokenRecovered(to, auctionToken, amount);
>> IERC20(auctionToken).safeTransfer(to, amount);
}

Vulnerability Details

In SpiceAuction, we calculate claimAmount like the below.

/**
* @notice Claim (retro) rewards for an epoch . Cannot claim for a live epoch auction
* @param epochId Epoch to claim for
*/
function claim(uint256 epochId) external virtual override {
...
>> uint256 claimAmount = bidTokenAmount.mulDivRound(info.totalAuctionTokenAmount, info.totalBidTokenAmount, false);
...
}

But if we don't update _totalAuctionTokenAllocation[token] when we call recoverToken, it will affect the next auction's totalAuctionTokenAmount calculation.

/**
* @notice Start auction. Checks caller is set config starter. Address zero for anyone to call
*/
function startAuction() external override {
...
(,address auctionToken) = _getBidAndAuctionTokens(config);
uint256 totalAuctionTokenAllocation = _totalAuctionTokenAllocation[auctionToken];
uint256 balance = IERC20(auctionToken).balanceOf(address(this));
>> uint256 epochAuctionTokenAmount = balance - (totalAuctionTokenAllocation - _claimedAuctionTokens[auctionToken]);
...
>> info.totalAuctionTokenAmount = epochAuctionTokenAmount;
// Keep track of total allocation auction tokens per epoch
_totalAuctionTokenAllocation[auctionToken] = totalAuctionTokenAllocation + epochAuctionTokenAmount;
emit AuctionStarted(epochId, msg.sender, startTime, endTime, epochAuctionTokenAmount);
}

So claimAmount will be bigger than it should be.

Impact

The user will receive more auction token than user expected after DAO executor call recoverToken in the SpiceAuction

Tools Used

Manual review

Recommendations

In the SpiceAuction.sol, there is recoverToken function. We should add _totalAuctionTokenAllocation[token] -= amount;

/**
* @notice Recover auction tokens for last but not started auction
* @param token Token to recover
* @param to Recipient
* @param amount Amount to auction tokens
*/
function recoverToken(
address token,
address to,
uint256 amount
) external override onlyDAOExecutor {
...
if (amount > maxRecoverAmount) { revert CommonEventsAndErrors.InvalidParam(); }
+ _totalAuctionTokenAllocation[token] -= amount;
IERC20(token).safeTransfer(to, amount);
emit CommonEventsAndErrors.TokenRecovered(to, token, amount);
}
Updates

Lead Judging Commences

inallhonesty Lead Judge 12 months ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement

Support

FAQs

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