Part 2

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

Initialization Vulnerability Leading to Denial of Service in Zaros's Dex Adaptor Contracts

Summary

Zaros's Dex Adaptor Contracts contract suffers from a DoS issue due to improper usage of the initializer modifier in its inheritance chain. The conflict arises when the contract's initialize function attempts to invoke the __BaseAdapter_init function of its parent contract, BaseAdaptor. Since both contracts utilize the initializer modifier, the process fails, leaving all the Dex Adaptor contracts in an unusable state after deployment. This effectively causes a denial of service, preventing any use of the contracts.

Vulnerability Details

Let's understand this issue by taking the example of CurveAdapter contract though the issue is present in all of the Dex Adaptor Contracts.

The vulnerability is caused by the interaction between the initializer modifier in both the CurveAdapter and BaseAdaptor contracts. When the initialize function of CurveAdapter is called, it first executes its own initialization logic, where the initializer modifier is invoked for the first time:
CurveAdapter.sol#L59

function initialize(
address owner,
address _curveStrategyRouter,
uint256 _slippageToleranceBps
)
external
@> initializer
{
// initialize the owner
@> __BaseAdapter_init(owner, _slippageToleranceBps);
// set the Curve Swap Strategy Router
setCurveStrategyRouter(_curveStrategyRouter);
}

Subsequently, it attempts to call the __BaseAdapter_init method of the parent contract, BaseAdaptor, to initialize the owner:
BaseAdapter.sol#L64

// initialize the owner
@> __BaseAdapter_init(owner, _slippageToleranceBps);

At this point, the initializer modifier in BaseAdaptor is triggered again. Since this modifier is designed to prevent a function from being called more than once, it detects that the contract has already been initialized (due to the initial call in CurveAdapter) when it reaches the BaseAdaptor __BaseAdapter_init function:

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

This leads to a failure at the check defined in the initializer modifier in BaseAdaptor, which causes the entire initialization process to fail, leaving the contract in a non-functional state after deployment.

Impact

None of the Dex Adaptor contracts can be properly initialized, leading to a complete denial of service.

Tools Used

Manual Review

Recommendations

  1. Replace initializer Modifier with onlyInitializing in BaseAdaptor.

  2. Make __BaseAdapter_init function internal: Restrict access to the BaseAdaptor's initialize function so that it can only be called internally by derived contracts like CurveAdaptor.

Updates

Lead Judging Commences

inallhonesty Lead Judge 6 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

Appeal created

0xshoonya Submitter
6 months ago
inallhonesty Lead Judge
6 months ago
inallhonesty Lead Judge 5 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.