TempleGold

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

auctionTokens will be locked forever for removed auction config

Summary

SpiceAuctioncontract has the functionality to remove auction configuntil auction becomes active. Due to this, auctionTokensadded in the contract will be locked forever in the contract and can't be recovered. This specifically applies to the auction for which startAuctionis called and they are removed before it's cooldown period is over.

Vulnerability Details

SpiceAuctioncontract has the function removeAuctionConfigwhich can be used to remove the auction config for which startAuction is called but auction is yet in cooldown. However, to start the auction, amount > config.minimumDistributedAuctionTokenauction tokens need to be sent to the contract. Once startAuction is called and auction is in cooldown, it's config can be removed. Once the auction config of such auction is removed, the amountof auction tokens for that config will not be recovered and will be locked forever in the contract. The reason for this is recoverToken can't recover tokens of deleted auction configs because _totalAuctionTokenAllocationis not updated on removal of auction config for which startAuction was called.

Relevant code snippets:

https://github.com/Cyfrin/2024-07-templegold/blob/main/protocol/contracts/templegold/SpiceAuction.sol#L113-L118

if (info.startTime == 0) { revert InvalidConfigOperation(); }
// Cannot reset an ongoing auction
if (info.isActive()) { revert InvalidConfigOperation(); }
/// @dev could be that `auctionStart` is triggered but there's cooldown, which is not reached (so can delete epochInfo for _currentEpochId)
// or `auctionStart` is not triggered but `auctionConfig` is set (where _currentEpochId is not updated yet)
SpiceAuctionConfig storage config = auctionConfigs[id];

https://github.com/Cyfrin/2024-07-templegold/blob/main/protocol/contracts/templegold/SpiceAuction.sol#L248-L265

uint256 epochId = _currentEpochId;
EpochInfo storage info = epochs[epochId];
/// @dev use `removeAuctionConfig` for case where `auctionStart` is called and cooldown is still pending
if (info.startTime == 0) { revert InvalidConfigOperation(); }
if (!info.hasEnded() && auctionConfigs[epochId+1].duration == 0) { revert RemoveAuctionConfig(); }
/// @dev Now `auctionStart` is not triggered but `auctionConfig` is set (where _currentEpochId is not updated yet)
// check to not take away intended tokens for claims
// calculate auction token amount
uint256 totalAuctionTokenAllocation = _totalAuctionTokenAllocation[token];
uint256 balance = IERC20(token).balanceOf(address(this));
uint256 maxRecoverAmount = balance - (totalAuctionTokenAllocation - _claimedAuctionTokens[token]);
if (amount > maxRecoverAmount) { revert CommonEventsAndErrors.InvalidParam(); }
IERC20(token).safeTransfer(to, amount);

Steps to reproduce:

config.starter = address(1), config.minimumDistributedAuctionToken = 1000, config.isTempleGoldAuctionToken = true

1) daoExecutorcalls setAuctionConfigand sets the auctionConfigfor epochId = 1.

2) address(1)starts auction by calling startAuctionand transferring 1000 TGLDtoken. _totalAuctionTokenAllocation[TGLD] = 1000. auction with epochId 1 started. After cooldown it become active.

3) user starts bidding

4) auction with epochId 1is over now.

Following is the auctionConfigfor next auction.

config.starter = address(2), config.minimumDistributedAuctionToken = 5000, config.isTempleGoldAuctionToken = true

5) daoExecutorcalls setAuctionConfigand sets the auctionConfigfor epochId = 2 .

6) address(2)starts auction by calling startAuctionand transferring 5000 TGLDtoken. _totalAuctionTokenAllocation[TGLD] = 6000 auction with epochId 2 in cooldown.

7) daoExecutorcalls removeAuctionConfigand auctionConfigs[2]gets removed while auctionTokencorresponding to epochId = 2is still in the contract. This are PERMANANTLY LOCKED in the contract and can't be recovered

8) daoExecutorcalls recoverToken. maxRecoverAmount = 6000(balance) - 6000(totalAuctionTokenAllocation[TGLD] = 0. Hence, no amount can be recovered

Impact

Funds for deleted auction will be permanantly locked in the contract

Tools Used

Manual Review

Recommendations

Update the totalAuctionTokenAllocationof auction tokens once auction config corresponding to cooldown auction is removed.

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.