The Stratax contract uses the Initializable pattern from OpenZeppelin but does not disable initializers in the constructor. This means the implementation contract itself can be initialized by anyone, potentially taking ownership. While this doesn't directly affect proxy deployments (which have their own state), if the implementation contract is used directly or holds any value, an attacker could take control. Additionally, uninitialized implementation contracts can sometimes be leveraged for further attacks or misleading users.
Likelihood:
An attacker can call initialize on the implementation contract immediately after deployment if it wasn't initialized.
Impact:
An attacker can become the owner of the implementation contract.
If the implementation contract is used directly (not through proxy), the attacker gains full control.
The attacker could set malicious protocol addresses in the implementation.
The contract assumes it can safely call decimals() on any ERC20 token. However, decimals() is optional in the ERC20 standard. Some tokens (e.g., USDT on certain chains) do not implement this function, which would cause the transaction to revert. Additionally, the contract doesn't validate that token decimals are within reasonable bounds (e.g., 0-77), which could lead to overflow in calculations when dealing with tokens with unusual decimal values.
Likelihood:
High if the protocol intends to support tokens like USDT on older deployments or non-standard ERC20 tokens.
Impact:
Transactions fail when interacting with tokens that don't implement decimals().
Potential overflow when calculating 10**decimals for tokens with large decimal values (>77).
DoS for certain token pairs that are otherwise compatible with Aave.
The _call1InchSwap function attempts to decode the return value as (uint256, uint256) but doesn't validate that the returned data is actually the expected size. If the 1inch router returns data in a different format or returns less data than expected, abi.decode could fail silently or decode garbage values. Falling back to checking balance when result.length is 0 is unreliable as it includes any existing balance, not just swap proceeds.
Likelihood:
Occurs if the 1inch router (or adapter) returns unexpected data formats or if the swap fails silently (but call succeeds).
Impact:
Incorrect return amount calculation leading to improper flash loan repayment.
Potential for manipulation if an attacker can influence the contract's token balance before the swap.
Silent failures where swap doesn't execute but balance check passes.
The executeOperation callback only checks that msg.sender equals address(aavePool), but aavePool is a mutable state variable that can be changed by the owner through re-initialization (if not properly protected) or if the contract logic allows updates. While initialize is protected by initializer, having critical addresses as mutable storage variables poses a risk if the owner is compromised.
Likelihood:
Requires compromising the owner account or a separate vulnerability allowing re-initialization.
Impact:
A malicious owner could update aavePool to a fake contract.
The fake pool can call executeOperation directly to bypass flash loan logic and manipulate contract state.
The calculateOpenParams function performs multiple division operations that can lead to precision loss, particularly when dealing with tokens with different decimal places. The calculation of borrowValueUSD divides by (LTV_PRECISION * 10000) which results in rounding down. This precision loss is compounded when converting between tokens with different decimals, potentially resulting in positions that are under-leveraged or borrow amounts that don't fully utilize the available collateral.
Likelihood:
Occurs frequently, especially with small amounts or tokens with low decimals (like USDC with 6) vs high decimals (18).
Impact:
Users receive less leverage than requested due to rounding errors.
Inefficient capital utilization.
Accumulated precision loss when dealing with tokens with very different decimal places (e.g., WBTC with 8 decimals vs WETH with 18).
disable initializers was used to prevent an error in the UUPS contract in version 4.0 which has now been fixed
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.