Thunder Loan

AI First Flight #7
Beginner FriendlyFoundryDeFiOracle
EXP
View results
Submission Details
Impact: high
Likelihood: high
Invalid

Uninitialized ThunderLoan logic implementation allows takeover via frontrunning

Uninitialized ThunderLoan Logic Implementation Allows Takeover via Frontrunning

Description

  • In proxy-based architectures, the logic implementation contract behind the proxy must be locked or initialized using _disableInitializers() to prevent unauthorized actors from claiming ownership.

  • In ThunderLoan.sol, the logic contract constructor omits _disableInitializers(). Any attacker can call initialize() directly on the implementation contract, become the owner, and execute upgradeToAndCall() with selfdestruct to permanently brick all active proxies.

// ThunderLoan.sol
constructor() {
@> // Missing _disableInitializers();
}
function initialize(address tswapAddress) external initializer {
@> __Ownable_init(msg.sender); // Unprotected on implementation contract!
}

Risk

Likelihood:

  • Occurs immediately upon contract deployment on mainnet or any EVM-compatible chain.

  • Attackers continuously scan mempools for uninitialized UUPS implementation contracts.

Impact:

  • Complete takeover of the logic implementation contract by an arbitrary attacker.

  • Permanent Denial of Service (DoS) if the implementation contract is destroyed or corrupted.

Proof of Concept

The exploit operates through the following steps:

  1. Deployer deploys the ThunderLoan logic implementation contract.

  2. An attacker detects that the logic implementation contract was left uninitialized.

  3. The attacker calls ThunderLoan(implementation).initialize(address(0)).

  4. The attacker is registered as owner and can upgrade the logic contract maliciously.

function test_uninitializedImplementationTakeover() public {
ThunderLoan implementation = new ThunderLoan();
vm.prank(attacker);
implementation.initialize(address(mockTSwapPool));
assertEq(implementation.owner(), attacker, "Attacker failed to claim implementation ownership");
}

Recommended Mitigation

Add _disableInitializers() inside the constructor of ThunderLoan to permanently lock the logic implementation contract.

contract ThunderLoan is Initializable, OwnableUpgradeable, UUPSUpgradeable, OracleUpgradeable {
+ /// @custom:oz-upgrades-unsafe-allow constructor
+ constructor() {
+ _disableInitializers();
+ }
Updates

Lead Judging Commences

ai-first-flight-judge Lead Judge about 1 hour ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement

Support

FAQs

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

Give us feedback!