Stratax Contracts

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

`initialize` Accepts Zero Addresses for Critical Protocol Parameters

Author Revealed upon completion

Root + Impact

Description

  • The initialize function sets all critical protocol addresses for the Stratax contract including the Aave Pool, Aave Data Provider, 1inch Router, USDC token, and Stratax Oracle. Since the contract uses the Initializable pattern (proxy-based upgradeability), initialize can only be called once and the addresses cannot be changed afterward (only strataxOracle has a setter function via setStrataxOracle).

  • None of the five address parameters are validated against address(0). A deployment script that accidentally passes a zero address for _aavePool or _aaveDataProvider would permanently brick the contract, as all subsequent operations would call address(0), and the initializer modifier prevents re-initialization.

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:

  • Proxy deployments with BeaconProxy encode initialization data off-chain and pass it as a constructor argument. A single error in deployment script parameter ordering or a missing environment variable results in address(0) being silently accepted.

  • The initializer modifier makes this a one-shot operation. Once set, aavePool, aaveDataProvider, oneInchRouter, and USDC have no setter functions and cannot be corrected.

Impact:

  • All core operations (createLeveragedPosition, unwindPosition, calculateOpenParams, calculateUnwindParams) call aavePool and aaveDataProvider. With address(0), these calls will revert or produce undefined behavior, permanently bricking the contract.

  • The proxy would need to be abandoned and a new one deployed, incurring gas costs and requiring all users to migrate.

Proof of Concept

This Foundry test deploys a fresh Stratax implementation behind a BeaconProxy, passing address(0) for both _aavePool and _aaveDataProvider. The initialize function completes without revert, and subsequent reads confirm the zero addresses are stored. Because the initializer modifier prevents re-initialization, the contract is permanently bricked.

function test_BONUS_InitializeWithZeroAddresses() public {
Stratax freshImpl = new Stratax();
UpgradeableBeacon freshBeacon = new UpgradeableBeacon(address(freshImpl), address(this));
bytes memory initData = abi.encodeWithSelector(
Stratax.initialize.selector,
address(0), // aavePool = ZERO
address(0), // aaveDataProvider = ZERO
INCH_ROUTER,
USDC,
address(strataxOracle)
);
BeaconProxy freshProxy = new BeaconProxy(address(freshBeacon), initData);
Stratax freshStratax = Stratax(address(freshProxy));
// Zero addresses accepted without revert
assertEq(address(freshStratax.aavePool()), address(0));
assertEq(address(freshStratax.aaveDataProvider()), address(0));
// Contract is now permanently bricked
}

Recommended Mitigation

Add require checks for all five address parameters at the top of initialize. Since this function can only execute once (per the initializer modifier), these checks act as a deployment safety net that catches misconfigured deployment scripts before the contract is permanently locked into invalid state.

function initialize(
address _aavePool,
address _aaveDataProvider,
address _oneInchRouter,
address _usdc,
address _strataxOracle
) external initializer {
+ require(_aavePool != address(0), "Invalid aavePool");
+ require(_aaveDataProvider != address(0), "Invalid dataProvider");
+ require(_oneInchRouter != address(0), "Invalid 1inch router");
+ require(_usdc != address(0), "Invalid USDC");
+ require(_strataxOracle != address(0), "Invalid oracle");
+
aavePool = IPool(_aavePool);
aaveDataProvider = IProtocolDataProvider(_aaveDataProvider);
oneInchRouter = IAggregationRouter(_oneInchRouter);
USDC = _usdc;
strataxOracle = _strataxOracle;
owner = msg.sender;
flashLoanFeeBps = 9;
}

Support

FAQs

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

Give us feedback!