TempleGold

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

Funds permanently stuck in SpiceAuction contract due to missing totalAuctionTokenAllocation deduction in removeAuctionConfig, with no way to recover or use them.

Summary

When a config is removed for activated but still in cooldown period auctions the contract fails to deduct its totalAuctionTokenAmount from _totalAuctionTokenAllocation, which leads to funds being stuck permanently in the contract.

Vulnerability Details

When an auction is started(activated) we assign:

info.totalAuctionTokenAmount = epochAuctionTokenAmount;
// Keep track of total allocation auction tokens per epoch
_totalAuctionTokenAllocation[auctionToken] = totalAuctionTokenAllocation + epochAuctionTokenAmount;

but when removeAuctionConfig is called for already activated auctions but still in cooldown period:

if (!configSetButAuctionStartNotCalled) {
/// @dev unlikely because this is a DAO execution, but avoid deleting old ended auctions
if (info.hasEnded()) { revert AuctionEnded(); }
/// auction was started but cooldown has not passed yet
delete auctionConfigs[id];
delete epochs[id];
_currentEpochId = id - 1;
emit AuctionConfigRemoved(id, id);
} else {

the function directly deletes the epoch and config before reducing the totalAuctionTokenAmount.

This is a problem because when calling recoverToken the maximum amount allowed to recover is calculated after deducting the allocated amounts from _totalAuctionTokenAllocation:

uint256 totalAuctionTokenAllocation = _totalAuctionTokenAllocation[token];
uint256 balance = IERC20(token).balanceOf(address(this));
uint256 maxRecoverAmount = balance - (totalAuctionTokenAllocation - _claimedAuctionTokens[token]);

Which means even after deleting an auction the tokens cannot be recovered nor can be used in the future auction because totalAuctionTokenAllocation is also used for calculating how much tokens are assigned for the epoch.

uint256 epochAuctionTokenAmount = balance - (totalAuctionTokenAllocation - _claimedAuctionTokens[auctionToken]);

Example:

  • Owner activates an auction with 1000 auction tokens.

  • info.totalAuctionTokenAmount = 1000,

  • _totalAuctionTokenAllocation[auctionToken] = 500(for previous auctions) + 1000 = 1500

  • auction still in cooldown period, owner decides to removeAuctionConifig and recover tokens.

  • recoverToken returns ```maxRecoverAmount = 1500 - (1500 - 0) = 0.

Thus funds cannot be recovered and are permanently stuck in the contract.

Impact

Once removeAuctionConfig is called for an auction in coolDown period, all the funds allocated to that auction will be permanently stuck in the contract. It cannot be recovered nor can it be used for future auctions.

Tools Used

manual

Recommendations

In removeAuctionConfig add these lines in the first if statement;

if (!configSetButAuctionStartNotCalled) {
/// @dev unlikely because this is a DAO execution, but avoid deleting old ended auctions
if (info.hasEnded()) { revert AuctionEnded(); }
/// auction was started but cooldown has not passed yet
+ SpiceAuctionConfig storage config = auctionConfigs[id];
+ (, address auctionToken) = _getBidAndAuctionTokens(config);
+ uint256 amount = info.totalAuctionTokenAmount;
+ _totalAuctionTokenAllocation[auctionToken] -= amount;
delete auctionConfigs[id];
delete epochs[id];
_currentEpochId = id - 1;
emit AuctionConfigRemoved(id, id);
} else {
Updates

Lead Judging Commences

inallhonesty Lead Judge 12 months ago
Submission Judgement Published
Validated
Assigned finding tags:

missing totalAuctionTokenAllocation deduction in removeAuctionConfig leads to stuck funds

Support

FAQs

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