Assessment reports>Avantis>Threat Model>updateMargin

Function: updateMargin(uint256 _pairIndex, uint256 _index, ITradingStorage.updateType _type, uint256 _amount, bytes[] priceUpdateData)

This updates (deposit/withdraw) the margin for an open trade.

Inputs

  • _pairIndex

    • Control: Fully controlled by the caller.

    • Constraints: None.

    • Impact: The index of the trading pair for the open trade.

  • _index

    • Control: Fully controlled by the caller.

    • Constraints: None.

    • Impact: The index of the open trade.

  • _type

    • Control: Fully controlled by the caller.

    • Constraints: None.

    • Impact: Withdraw or deposit type of update.

  • _amount

    • Control: Fully controlled by the caller.

    • Constraints: None.

    • Impact: The collateral by which to update the margin.

  • priceUpdateData

    • Control: Fully controlled by the caller.

    • Constraints: None.

    • Impact: Pyth price update data.

Branches and code coverage

Intended branches

  • If the trade is open and the new leverage lies between the correct range, the trade is executed.

  • Tokens are transferred to the user if it is a withdraw call.

  • Tokens are transferred from trader address to the storage contract if it is a deposit call.

  • If margin fees are greater than zero, the open interest is updated.

Negative behavior

  • Being market closed for the trade prevents further updates (ALREADY_BEING_CLOSED).

  • The trade should exist with a positive leverage.

  • The new leverage should lie between the minimum and maximum range.

Function call analysis

  • 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 address, to which calls will be made.

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

  • this.storageT.openTrades(msg.sender, _pairIndex, _index)

    • What is controllable? msg.sender, _pairIndex, and _index.

    • If the return value is controllable, how is it used and how can it go wrong? Checks the existence of the open trade; incorrect values may lead to incorrect trade information 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.storageT.openTradesInfo(msg.sender, _pairIndex, _index)

    • What is controllable? msg.sender, _pairIndex, and _index.

    • If the return value is controllable, how is it used and how can it go wrong? Retrieves additional information about the open trade; incorrect values may lead to incorrect information 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.pairInfos.getTradeRolloverFee(t.trader, t.pairIndex, t.index, t.buy, t.initialPosToken, t.leverage)

    • What is controllable? t.trader, t.pairIndex, t.index, 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 rollover fee.

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

  • aggregator.pairsStorage().pairMinLeverage(t.pairIndex)

    • What is controllable? t.pairIndex.

    • If the return value is controllable, how is it used and how can it go wrong? Retrieves the minimum leverage for the trading pair.

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

  • aggregator.pairsStorage().pairMaxLeverage(t.pairIndex)

    • What is controllable? t.pairIndex.

    • If the return value is controllable, how is it used and how can it go wrong? Retrieves the maximum leverage for the trading pair.

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

  • aggregator.getPrice(_pairIndex, OrderType.UPDATE_MARGIN)

    • What is controllable? _pairIndex.

    • If the return value is controllable, how is it used and how can it go wrong? Returns the new 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.

  • aggregator.storePendingMarginUpdateOrder(orderId, PendingMarginUpdate(msg.sender, _pairIndex, _index, _type, _amount, i.lossProtection, marginFees, t.leverage))

    • What is controllable? orderId, msg.sender, _pairIndex, _index, _type, _amount, and t.leverage.

    • If the return value is controllable, how is it used and how can it go wrong? Stores the pending margin update 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.

  • this.storageT.updateTrade(t)

    • What is controllable? t.

    • If the return value is controllable, how is it used and how can it go wrong? Updates the trade information — 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.

  • 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 ↑