Part 2

Zaros
PerpetualsDEXFoundrySolidity
70,000 USDC
View results
Submission Details
Severity: high
Invalid

Insecure Use of External `engine` Parameter Leading to Token Manipulation in Swap Fulfillment and Refunds

Summary

The StabilityBranch::fulfillSwap and StabilityBranch::refundSwap functions in the StabilityBranch contract rely on an externally provided engine parameter to determine the USD token contract address. This creates a critical vulnerability where a malicious or careless keeper (or user in the case of refunds) can manipulate the token contract used during swap fulfillment or refund, potentially bypassing intended burn or refund logic. This could result in loss of funds, undermine the token's peg, or allow unauthorized token operations.

Vulnerability Details

The issue arises due to the following inconsistencies:

  1. Inconsistent Token Lookup: During swap initiation in initiateSwap, the USD token address is derived from the vault's stored engine:

    ctx.usdTokenOfEngine = IERC20(configuration.usdTokenOfEngine[currentVault.engine]);

    However, during swap fulfillment (fulfillSwap) and refund (refundSwap), the USD token address is determined by an externally provided engine parameter:

    ctx.usdToken = UsdToken(marketMakingEngineConfiguration.usdTokenOfEngine[engine]);

    There is no binding between the swap request and the engine used during initiation, allowing the engine parameter to be manipulated.

  2. Exploitable Scenarios:

    • Fulfillment Manipulation: A malicious keeper could provide an engine parameter pointing to a USD token contract with a no-op or unexpected burn implementation, bypassing the intended token burn logic.

    • Refund Manipulation: A user or keeper could provide an engine parameter pointing to a different USD token contract, resulting in refunds from an unintended token contract.

  3. Lack of Validation: The contract does not validate that the engine parameter matches the engine used during swap initiation, leaving the system vulnerable to token manipulation.

Impact

Malicious actors could exploit this vulnerability to bypass token burns or refunds, leading to financial losses for users or the protocol.

Tools Used

Manual Review

Recommendations

To mitigate this vulnerability, the following steps should be taken:

  1. Remove External engine Parameter: Derive the USD token address from the data recorded during swap initiation instead of relying on an external parameter.

  2. Store Engine Identifier: Store the engine identifier in the swap request during initiation and use it during fulfillment and refund to ensure consistency.

  3. Add Validation: If the engine parameter must be retained, explicitly validate that it matches the engine used during swap initiation.

Example Fix for fulfillSwap:

function fulfillSwap(
address user,
uint128 requestId,
bytes calldata priceData
) external onlyRegisteredSystemKeepers {
// Load request for user by id
UsdTokenSwapConfig.SwapRequest storage request = UsdTokenSwapConfig.load().swapRequests[user][requestId];
// Revert if already processed
if (request.processed) {
revert Errors.RequestAlreadyProcessed(user, requestId);
}
// Load vault data
Vault.Data storage vault = Vault.loadLive(request.vaultId);
// Derive USD token address from the vault's engine
address usdTokenAddress = marketMakingEngineConfiguration.usdTokenOfEngine[vault.engine];
UsdToken usdToken = UsdToken(usdTokenAddress);
// Rest of the function logic...
}
Updates

Lead Judging Commences

inallhonesty Lead Judge 6 months ago
Submission Judgement Published
Invalidated
Reason: Non-acceptable severity

Support

FAQs

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