The Stratax contract is an upgradeable (Beacon Proxy) leveraged position management contract that interacts with Aave for flash loans and lending, and 1inch for token swaps. The initialize() function is the single entry point for setting all critical protocol addresses and can only be called once due to OpenZeppelin's initializer modifier. It accepts five address parameters (_aavePool, _aaveDataProvider, _oneInchRouter, _usdc, _strataxOracle) and assigns them directly to state variables without validating any of them against address(0).
This is inconsistent with validation applied elsewhere in the contract. The setStrataxOracle() function validates _strataxOracle != address(0), and transferOwnership() validates _newOwner != address(0). Despite this awareness of the zero-address risk, the initialize() function omits equivalent checks for all five parameters.
Furthermore, the contract provides setter functions only for strataxOracle (via setStrataxOracle()) and flashLoanFeeBps (via setFlashLoanFee()). The four remaining protocol addresses (aavePool, aaveDataProvider, oneInchRouter, USDC) have no setter functions and are immutable after initialisation. If any of these are set to address(0), all core functions such as createLeveragedPosition() and unwindPosition() that depend on these addresses will revert.
In contrast, setStrataxOracle() includes the validation that is absent from initialize():
While the Beacon Proxy pattern does provide a recovery path (the beacon owner could upgrade the implementation to introduce setter functions for the affected addresses), this is a non-trivial remediation that should not be relied upon as a substitute for proper input validation.
This issue has a low impact as the contract would be non-functional from deployment, meaning no user funds would be at risk before the issue is discovered. The recoverTokens() function can salvage any tokens if the owner was set correctly, and the beacon owner can upgrade the implementation as a recovery mechanism.
This issue has a low likelihood as it requires a deployment error by a trusted deployer, such as a misconfigured environment variable or automation bug. Deployers typically test contracts after deployment, which would reveal the issue before user interaction.
Add address(0) validation for all five address parameters in the initialize() function, consistent with the validation already applied in setStrataxOracle() and transferOwnership(). Each parameter should be checked with a require statement ensuring it is not equal to address(0) before assignment.
Additionally, consider adding setter functions with appropriate access control and validation for aavePool, aaveDataProvider, oneInchRouter, and USDC to provide a recovery path if these addresses need to change in the future.
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
Appeals are being carefully reviewed by our judges.
The contest is complete and the rewards are being distributed.