Assessment reports>Avantis>Threat Model>executeLimitOrder

Function: executeLimitOrder(ITradingStorage.LimitOrder _orderType, address _trader, uint256 _pairIndex, uint256 _index, bytes[] priceUpdateData)

This executes a limit order (either open or close).

Inputs

  • _orderType

    • Control: Fully controlled by the caller.

    • Constraints: None.

    • Impact: The type of limit order (OPEN, CLOSE, TP, SL, or LIQ).

  • _trader

    • Control: Fully controlled by the caller.

    • Constraints: None.

    • Impact: The address of the trader.

  • _pairIndex

    • Control: Fully controlled by the caller.

    • Constraints: None.

    • Impact: The index of the trading pair.

  • _index

    • Control: Fully controlled by the caller.

    • Constraints: None.

    • Impact: The index of the order.

  • priceUpdateData

    • Control: Fully controlled by the caller.

    • Constraints: None.

    • Impact: Pyth price update data.

Branches and code coverage

Intended branches

  • If order type is OPEN, the fulfill function calls executeLimitOpenOrderCallback; otherwise, it calls executeLimitCloseOrderCallback.

  • For crypto trading pairs, use onePercentP to calculate trade price impact.

  • Registers the trade and unregisters the open limit order.

Negative behavior

  • Revert if the limit-order type is OPEN and no corresponding open limit order is found.

  • Revert if the limit-order type is CLOSE, SL, or LIQ and no corresponding trade is found.

  • Revert if the SL order type is specified without a valid stop-loss price.

  • Revert if the LIQ order type is specified with a stop loss that would be triggered.

Function call analysis

  • this.storageT.hasOpenLimitOrder(_trader, _pairIndex, _index)

    • What is controllable? _trader, _pairIndex, and _index.

    • If the return value is controllable, how is it used and how can it go wrong? Checks for the existence of an open limit order — returns true if trade exists.

    • What happens if it reverts, reenters, or does other unusual control flow? If it reverts, the entire call will revert — no reentrancy scenarios.

  • this.storageT.openTrades(_trader, _pairIndex, _index)

    • What is controllable? _trader, _pairIndex, and _index.

    • If the return value is controllable, how is it used and how can it go wrong? Retrieves the open trade — incorrect values may lead to incorrect trade retrieval.

    • What happens if it reverts, reenters, or does other unusual control flow? If it reverts, the entire call will revert — no reentrancy scenarios.

  • this._getTradeLiquidationPrice(t) -> this.pairInfos.getTradeLiquidationPrice(t.trader, t.pairIndex, t.index, t.openPrice, t.buy, t.initialPosToken, t.leverage)

    • What is controllable? t.trader, t.pairIndex, t.index, t.openPrice, t.buy, t.initialPosToken, and t.leverage.

    • If the return value is controllable, how is it used and how can it go wrong? Calculates the trade-liquidation price; incorrect values may lead to incorrect liquidation price calculation.

    • What happens if it reverts, reenters, or does other unusual control flow? N/A.

  • this.storageT.priceAggregator()

    • What is controllable? N/A.

    • If the return value is controllable, how is it used and how can it go wrong? Returned value is the PriceAggregator contract, to which calls will be made.

    • What happens if it reverts, reenters or does other unusual control flow? N/A.

  • aggregator.executions()

    • What is controllable? N/A.

    • If the return value is controllable, how is it used and how can it go wrong? Returned value is the Execute contract, to which calls will be made.

    • What happens if it reverts, reenters or does other unusual control flow? N/A.

  • executor.triggered(triggeredLimitId)

    • What is controllable? triggeredLimitId.

    • If the return value is controllable, how is it used and how can it go wrong? Checks if the limit order has been triggered and returns true if it is triggered; it is not directly controllable.

    • What happens if it reverts, reenters, or does other unusual control flow? N/A.

  • executor.timedOut(triggeredLimitId)

    • What is controllable? triggeredLimitId.

    • If the return value is controllable, how is it used and how can it go wrong? Checks if the limit order has timed out; returns true if that is the case.

    • What happens if it reverts, reenters, or does other unusual control flow? N/A.

  • aggregator.getPrice(_pairIndex, _orderType == LimitOrder.OPEN ? OrderType.LIMIT_OPEN : OrderType.LIMIT_CLOSE)

    • What is controllable? _pairIndex and _orderType.

    • If the return value is controllable, how is it used and how can it go wrong? Returns the orderId for the current order.

    • What happens if it reverts, reenters, or does other unusual control flow? If it reverts, the entire call will revert; no reentrancy scenarios.

  • this.storageT.storePendingLimitOrder(PendingLimitOrder(_trader, _pairIndex, _index, _orderType), orderId)

    • What is controllable? _trader, _pairIndex, _index, and _orderType.

    • If the return value is controllable, how is it used and how can it go wrong? Stores the pending limit order — no return value.

    • What happens if it reverts, reenters, or does other unusual control flow? N/A.

  • executor.storeFirstToTrigger(triggeredLimitId, msg.sender)

    • What is controllable? triggeredLimitId and msg.sender.

    • If the return value is controllable, how is it used and how can it go wrong? Stores the first address to trigger the limit order — no return value.

    • What happens if it reverts, reenters, or does other unusual control flow? N/A.

  • aggregator.fulfill{value: msg.value}

    • What is controllable? msg.value.

    • If the return value is controllable, how is it used and how can it go wrong? Fulfills the update margin order — no return value.

    • What happens if it reverts, reenters or does other unusual control flow? If it reverts, the entire call will revert — no reentrancy scenarios.

Zellic © 2025Back to top ↑