Skip to main content

Open

Positions are opened either by creating a new Superfluid stream to the Market’s SuperApp or by updating an existing stream to increase the flow rate.

Preconditions

  • The inbound SuperToken must equal vault asset.
  • userData must be ABI-encoded uint256 delta (WAD fraction, >= 0).

The Contract

  • A new position is automatically opened in the onFlowCreated or onFlowUpdated hook when the amount of incoming flow increases.
  • Builds a snapshot (poolAssets, lockedNotional, rateModel, bufferBps, otmHalf, LOT_SIZE).
  • Runs solveNotional(snapshot, deltaWad, spendPerSecond) to compute notional.
  • Fetches fresh price and sets strike.
  • Mints a new positon state OPEN.
  • Updates lockedNotional and per-user notional accounting.
  • Emits PositionOpened event.

Close

Positions are closed either by deleting the Superfluid stream to the Market’s SuperApp yourself or by updating an existing stream to decrease the flow rate.

Preconditions

  • The inbound SuperToken must equal vault asset.
  • userData must be ABI-encoded uint256 positionId.
  • Must be a valid position ID.
  • The position must be OPEN and owned by the stream sender.
  • The stream sender must be the msgSender.
  • The stream sender must be the position owner.

The Contract

  • The position is automatically closed in the onFlowDeleted or onFlowUpdated hook when the amount of incoming flow decreases.
  • Fetches fresh price.
  • Computes payout via computePayout(notional, strike, closePrice).
  • Updates lockedNotional and per-user notional accounting.
  • Transfers payout to the position owner from the vault.
  • Sets position state to CLOSED.
  • Emits PositionClosed event.

Liquidation

Positions are liquidated internally by the Market if the Superfluid stream is liquidated (deleted by Superfluid sentinel) due to insufficient balance in the stream sender’s wallet.

The Contract

  • The position is automatically liquidated in the onFlowDeleted hook when a Superfluid sentinel liquidates the stream.
  • Updates lockedNotional and per-user notional accounting.
  • Emits UserLiquidated event.

Considerations

  • No payout is made to the position owner.
  • The positions aren’t explicitly marked as LIQUIDATED in storage; they are simply accounted for using _lastFlowDeleteTimestamp.
  • When a user queries for a position using positions(positionId), if the position is still OPEN but the stream was deleted at some point after opening, the position is considered liquidated and the postion state is returend as CLOSED.

onFlowDeleted Behavior

When a user tries to delete their own stream, onFlowDeleted and the Market checks to make sure that if the msgSender is the same as the stream sender, then it checks if userData contains a valid positionId owned by the msgSender. If so, it treats this as a user-initiated close. If not, the callback reverts. This does poses a risk of accidentally jailing SuperTokens. Read the risks section for more details.