Stratax Contracts

First Flight #57
Beginner FriendlyDeFi
100 EXP
Submission Details
Impact: high
Likelihood: high

Unprotected initializer allows front-running of contract ownership and protocol takeover

Author Revealed upon completion

Root + Impact

Description

Normal Behavior: The Stratax contract is an upgradeable implementation that uses an initialize function to set critical state variables such as the Aave pool, price oracle, and contract owner. Ideally, the deployer should be the only one able to initialize the contract immediately after deployment.

Specific Issue: The initialize function (line 144) is marked external and lacks any access control or protection within the constructor. Since the owner is set to msg.sender inside this function, a malicious actor can monitor the mempool and front-run the deployer's initialization transaction. By calling initialize first, the attacker becomes the owner and can point the protocol to malicious external contracts (e.g., a fake Aave pool or a rigged Oracle).

// Root cause in the codebase with @> marks to highlight the relevant section
@> function initialize(
address _aavePool,
address _aaveDataProvider,
address _oneInchRouter,
address _usdc,
address _strataxOracle
@> ) external initializer {
aavePool = IPool(_aavePool);
aaveDataProvider = IProtocolDataProvider(_aaveDataProvider);
oneInchRouter = IAggregationRouter(_oneInchRouter);
USDC = _usdc;
strataxOracle = _strataxOracle;
@> owner = msg.sender;
flashLoanFeeBps = 9;
}

Risk

Likelihood:

  • Bots automatically detect uninitialized contracts on-chain.

  • Attackers can use higher gas fees (Priority Fees) to ensure their transaction is processed before the deployer's.

Impact:

  • Total Loss of Control: The legitimate deployer is locked out of the onlyOwner functions.

  • Data Manipulation: The attacker can set a malicious strataxOracle to manipulate prices and liquidate or steal user assets.

Proof of Concept

1. The Developer deploys the Stratax implementation contract.
2. An Attacker observes the deployment and the pending initialize transaction in the mempool.
3. The Attacker sends their own initialize transaction with a much higher gas price, setting their own address as the owner.
4. The Attacker's transaction is mined first.
5. The Developer's transaction fails because the contract is already initialized (due to the initializer modifier).
6. The Attacker now has full onlyOwner privileges over the protocol.
This proves that the ownership is not protected during deployment, allowing any external actor to intercept the initialization and gain administrative privileges over the Stratax protocol.

Recommended Mitigation

To prevent the implementation contract from being initialized, add a constructor to the Stratax contract that calls _disableInitializers():

/// @custom:oz-upgrades-unsafe-allow constructor
constructor() {
_disableInitializers();
}

Support

FAQs

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

Give us feedback!