TempleGold

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

Wrongly configured recipient address inside setAuctionConfig() could lead to sending tokens to untrusted source.

Summary:

The function setAuctionConfig() which is inside SpiceAuction contract is vulnerable to setting a untrusted recipient address.

Vulnerability Details:

If the recipient is not trusted(DAOExecutor made a mistake). Then inside of bid() function, the tokens could be sent to the not trusted address.

Impact:

The sender approves SpiceAuction contract's address to spend tokens on the sender behalf. The sender's bid amount will be sent to the not trusted address and his funds will be lost.

The only thing that i have changed for the purpose of the test is the recipient address inside _getAuctionConfig():

function _getAuctionConfig() internal view returns (ISpiceAuction.SpiceAuctionConfig memory config) {
config.duration = 7 days;
config.waitPeriod = 2 weeks;
config.minimumDistributedAuctionToken = 1 ether;
config.starter = alice;
config.startCooldown = 1 hours;
config.isTempleGoldAuctionToken = true;
ISpiceAuction.ActivationMode mode = ISpiceAuction.ActivationMode.AUCTION_TOKEN_BALANCE;
config.activationMode = mode;
config.recipient = address(0x5); // malicious address
}
function _setAuctionConfig() private returns (ISpiceAuction.SpiceAuctionConfig memory config) {
config = _getAuctionConfig();
vm.startPrank(daoExecutor);
spice.setAuctionConfig(config);
vm.stopPrank();
}
function _startAuction(bool _setConfig, bool _sendAuctionTokens)
internal
returns (ISpiceAuction.SpiceAuctionConfig memory config)
{
if (_setConfig) {
config = _setAuctionConfig();
} else {
uint256 epochId = spice.currentEpoch();
config = spice.getAuctionConfig(epochId + 1);
}
if (_sendAuctionTokens) {
address auctionToken = config.isTempleGoldAuctionToken ? address(templeGold) : spice.spiceToken();
dealAdditional(IERC20(auctionToken), address(spice), 100 ether);
}
if (config.starter != address(0)) vm.startPrank(config.starter);
vm.warp(block.timestamp + config.waitPeriod);
spice.startAuction();
}
function test_bidSpiceAuctionWithUntrustedRecipient() public {
deal(daiToken, alice, 100 ether);
uint256 aliceBidAmount = 20 ether;
// starting the auction will create the AuctionConfig with the malicious address
ISpiceAuction.SpiceAuctionConfig memory _config = _startAuction(true, true);
uint256 epoch = spice.currentEpoch();
IAuctionBase.EpochInfo memory epochInfo = spice.getEpochInfo(epoch);
// fast forward to the start time of the epoch
vm.warp(epochInfo.startTime);
// Approve the auction contract to spend Alice's DAI tokens
IERC20(daiToken).approve(address(spice), type(uint256).max);
vm.expectEmit(address(spice));
emit Deposit(alice, epoch, aliceBidAmount);
// Alice places a bid in the auction
spice.bid(aliceBidAmount);
// check Alice's DAI balance after the bid
assertEq(IERC20(daiToken).balanceOf(alice), 100 ether - aliceBidAmount);
// check the recipient's(malicious address) DAI balance after the bid
assertEq(IERC20(daiToken).balanceOf(_config.recipient), aliceBidAmount);
// malicious address has received the tokens
assertEq(IERC20(daiToken).balanceOf(address(0x5)), aliceBidAmount);
epochInfo = spice.getEpochInfo(epoch);
// check the total bid token amount in the epoch(20 ether)
assertEq(epochInfo.totalBidTokenAmount, aliceBidAmount);
// check the total auction token amount in the epoch
assertEq(epochInfo.totalAuctionTokenAmount, 100 ether);
// check Alice's deposited amount in the epoch
assertEq(spice.depositors(alice, epoch), aliceBidAmount);
// check Alice's claimable amount for the epoch
assertEq(spice.getClaimableForEpoch(alice, epoch), 100 ether);
}

Tools Used:

Manual Review

Recommendations:

Consider adding a whitelist mapping so that it takes 1 extra step to set the recipient. This way it will lower the chance of making a mistake.

Updates

Lead Judging Commences

inallhonesty Lead Judge 11 months ago
Submission Judgement Published
Invalidated
Reason: Non-acceptable severity

Support

FAQs

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