Auction can be started by anyone if no starter is set, this allows auctions to start regardless, However the auction can be started with no auctionToken
function startAuction() external override {
uint256 epochId = _currentEpochId;
SpiceAuctionConfig storage config = auctionConfigs[epochId+1];
if (config.duration == 0) { revert CannotStartAuction(); }
if (config.starter != address(0) && msg.sender != config.starter) { revert CommonEventsAndErrors.InvalidAccess(); }
if (epochId > 0) {
EpochInfo memory lastEpochInfo = epochs[epochId];
uint64 _waitPeriod = auctionConfigs[epochId].waitPeriod;
if (lastEpochInfo.endTime + _waitPeriod > block.timestamp) { revert CannotStartAuction(); }
} else {
if (_deployTimestamp + config.waitPeriod > block.timestamp) { revert CannotStartAuction(); }
}
(,address auctionToken) = _getBidAndAuctionTokens(config);
uint256 totalAuctionTokenAllocation = _totalAuctionTokenAllocation[auctionToken];
uint256 balance = IERC20(auctionToken).balanceOf(address(this));
uint256 epochAuctionTokenAmount = balance - (totalAuctionTokenAllocation - _claimedAuctionTokens[auctionToken]);
if (config.activationMode == ActivationMode.AUCTION_TOKEN_BALANCE) {
if (config.minimumDistributedAuctionToken == 0) { revert MissingAuctionTokenConfig(); }
}
if (epochAuctionTokenAmount < config.minimumDistributedAuctionToken) { revert NotEnoughAuctionTokens(); }
epochId = _currentEpochId = _currentEpochId + 1;
EpochInfo storage info = epochs[epochId];
uint128 startTime = info.startTime = uint128(block.timestamp) + config.startCooldown;
uint128 endTime = info.endTime = startTime + config.duration;
info.totalAuctionTokenAmount = epochAuctionTokenAmount;
_totalAuctionTokenAllocation[auctionToken] = totalAuctionTokenAllocation + epochAuctionTokenAmount;
emit AuctionStarted(epochId, msg.sender, startTime, endTime, epochAuctionTokenAmount);
}
`Config.activationMode` can be set other states, this will bypass the minimumDistributionAuctionToken check and proceed with the starting the auction.