TempleGold

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

Users are likely to lose their bid if `spiceToken` is a low-decimals token and `templeGold` is `auctionToken`

Lines Of Code

https://github.com/TempleDAO/temple/blob/3768698e6d78ba1340a57406e5961a0e2faba212/protocol/contracts/templegold/SpiceAuction.sol#L221

Summary

Users are likely to lose their bid if spiceToken is a low-decimals token and templeGold is auctionToken

Vulnerability Details

When a user calls SpiceAuction::bid(), he provides the amount of bidToken he will bid.

File: contracts/templegold/SpiceAuction.sol
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);
}

When he claims his rewards for an epoch he has bid tokens, he will get an amount corresponding to the a percentage of the amount he bid on the total bid amount for the epoch.

File: contracts/templegold/SpiceAuction.sol
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);
}

In the case that the spiceToken has a low decimals count (USDC, USDT, WBTC have 6 to 8 decimals) and templeGold is the auctionToken (SpiceAuctionConfig.isTempleGoldAuctionToken == true), then it's very likely that the claimAmount calculation will result in rounding down to 0. This means that the auction recipient will get the whole bid amount, but the bidder will get 0 auctionToken to claim, resulting in a total lost of his bid.

Impact

Bidders lose their bid and get 0 auctionToken

Tools Used

Manual review.

Recommendations

Enforce that the spiceToken decimals are equals to the auctionToken.
Or implement proper conversion in case spiceToken and auctionToken have different decimals.

Updates

Lead Judging Commences

inallhonesty Lead Judge 11 months ago
Submission Judgement Published
Invalidated
Reason: Known issue

Support

FAQs

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