Part 2

Zaros
PerpetualsDEXFoundrySolidity
70,000 USDC
View results
Submission Details
Severity: low
Valid

Multiple Initializer Modifiers in DEX Adapter Inheritance Chain Leading to Incomplete Contract Initialization

Summary

A critical vulnerability has been identified in the DEX adapter contracts' initialization pattern. All DEX adapters (UniswapV2Adapter, UniswapV3Adapter, etc.) inheriting from BaseAdapter contain multiple initializer modifiers in their inheritance chain. This violates the OpenZeppelin initializable contract pattern and can lead to partially initialized contracts or completely blocked initialization functions.

Vulnerability Details

This is the BaseAdapter Contract Implementation:

function __BaseAdapter_init(address owner, uint256 _slippageToleranceBps) public initializer {
// initialize the owner
__Ownable_init(owner);
// set the slippage tolerance
setSlippageTolerance(_slippageToleranceBps);
}

This function is marked with initializer modifier. It's responsible for critical base initialization like setting up contract ownership and configuring slippage tolerance.

Now see the DEX Adapter Implementation (e.g., UniswapV3Adapter):

function initialize(
address owner,
address _uniswapV3SwapStrategyRouter,
uint256 _slippageToleranceBps,
uint24 _fee
) external initializer {
// initialize the owner
__BaseAdapter_init(owner, _slippageToleranceBps);
// DEX specific initialization
}

This function is also marked with initializer modifier.

The issue is that both initialize() and __BaseAdapter_init() have initializer modifier. The initializer modifier sets a boolean flag when first called.
Subsequent calls to any function with initializer modifier will revert. It is designed to be used only once in the entire inheritance chain.

Example Scenario:

  1. UniswapV3Adapter.initialize() is called

  2. It Sets initialized = true inside initializer modifier

  3. BaseAdapter.__BaseAdapter_init() can never be called.

  4. Contract lacks ownership and slippage settings

Impact

Completely blocked initialization of Dex Adaptors.

Tools Used

Manual Review

Recommendations

Implement the proper initialization pattern:

function __BaseAdapter_init(address owner, uint256 _slippageToleranceBps) internal onlyInitializing {
__Ownable_init(owner);
setSlippageTolerance(_slippageToleranceBps);
}
Updates

Lead Judging Commences

inallhonesty Lead Judge 10 months ago
Submission Judgement Published
Validated
Assigned finding tags:

BaseAdapter contract uses initializer instead of onlyInitializing modifier, causing initialization to fail in child DEX adapters and breaking swaps

Support

FAQs

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

Give us feedback!