Diffusal

Portfolios

Independent margin units for risk isolation and capital management

A portfolio is an independent margin unit that holds positions and collateral. Each user can have multiple portfolios, enabling risk isolation between different trading strategies. Cross-margin applies within each portfolio only—each portfolio is an independent liquidation unit.


Four Instruments in a Portfolio

Each portfolio holds positions organized by series. Each position stores two signed balances that encode the four-instrument model:

Position Structure (Per Series)

Position {
  optionBalance: int256    // positive = Long, negative = Short
  premiumBalance: int256   // positive = Receiver, negative = Payer
  lastUpdated: uint256
}

Critical clarification: The four instruments are NOT four separate positions. A single position entry (per series) uses two signed integers to represent all four instrument types:

Balance FieldPositive ValueNegative Value
optionBalanceOption Long — receives intrinsicOption Short — pays intrinsic
premiumBalancePremium Receiver — receives premiumPremium Payer — pays premium

Storage vs. Update Flexibility:

  • Storage: Option and premium balances are stored together in one entry per (portfolioId, seriesId)
  • Updates: Operators can update option and premium balances independently (e.g., settlement adjustments)

Typical Combinations

ActoroptionBalancepremiumBalanceMeaning
Buyer+10-$1,500Long 10 options, owes $1,500 premium
Seller-10+$1,500Short 10 options, owed $1,500 premium

Position Count

  • The 16-position limit counts series entries, not individual instruments
  • A portfolio with 3 series has 3 positions (each tracking both balances)
  • Cross-margin efficiency: longs offset shorts, receivables offset payables

Portfolio Structure

Each portfolio contains:

ComponentDescription
Portfolio IDSequential integer (0, 1, 2...) unique per user
PositionsUp to 16 series entries, each with option + premium
CollateralUSDC deposit (6 decimals)

Why 16 Positions?

The 16-position limit ensures gas-bounded liquidation. When liquidating a portfolio, the protocol must iterate through all positions to calculate margin and transfer positions. Bounding this to 16 ensures liquidation transactions fit within block gas limits.

Position Storage

Positions are stored per-series within each portfolio:

User → Portfolio ID → Series ID → {optionBalance, premiumBalance, lastUpdated}

Each series in a portfolio tracks its own option and premium balances independently.


Portfolio Equity

Portfolio equity determines health status and withdrawal limits:

Equity=Deposit+i(marki×optionBalancei)+ipremiumBalancei\text{Equity} = \text{Deposit} + \sum_{i}(\text{mark}_i \times \text{optionBalance}_i) + \sum_{i}\text{premiumBalance}_i

Components

ComponentFormulaEffect on Equity
DepositRaw USDC in vaultAlways positive
Option Value(mark×optionBalance)\sum(\text{mark} \times \text{optionBalance})Positive if net long, negative if net short
Premium Balance(premiumBalance)\sum(\text{premiumBalance})Positive if receivable, negative if payable

See also: Margin System for detailed equity calculations and stress testing.


Portfolio Lifecycle

Creating a Portfolio

Portfolios are created automatically when needed:

  1. On first deposit: When a user deposits to a non-existent portfolio ID
  2. Via PortfolioManager: Users can explicitly create portfolios via createPortfolio

Portfolio IDs are assigned sequentially (0, 1, 2...) for each user.

Deleting a Portfolio

A portfolio can only be deleted when completely empty:

  • No positions: All series entries must have zero option and premium balances
  • No collateral: Deposit must be withdrawn first
deletePortfolio(user, portfolioId)
├── Check: positionCount == 0
├── Check: deposit == 0
└── Remove from user's portfolio list

Collateral Management

Deposit

Deposits add USDC to a specific portfolio:

depositToPortfolio(portfolioId, amount)
├── No margin check required (deposits always allowed)
├── Portfolio must exist
└── Updates: portfolioDeposits[user][portfolioId] += amount

Withdraw

Withdrawals require post-withdrawal equity to exceed Initial Margin:

withdrawFromPortfolio(portfolioId, amount)
├── Check: amount <= maxWithdrawable
├── Check: post-withdrawal equity >= IM
└── Transfer USDC to user

Max Withdrawable:

Max Withdraw=max(0,EquityInitial Margin)\text{Max Withdraw} = \max(0, \text{Equity} - \text{Initial Margin})

Transfer Between Portfolios

Operators can transfer collateral between a user's portfolios:

transferCollateralBetweenPortfolios(user, fromPortfolioId, toPortfolioId, amount)
├── Check: amount <= fromPortfolio deposit
├── Move collateral between portfolios
└── Verify: source portfolio remains healthy after transfer

Operations Comparison

OperationMargin CheckWho Can CallEffect
DepositNoneUserIncreases deposit
WithdrawPost-withdrawal ≥ IMUserDecreases deposit, transfers out
TransferSource healthyOperatorMoves between portfolios
DebitNoneOperatorSettlement/liquidation use
CreditNoneOperatorSettlement/liquidation use

Position Transfers

Positions can be transferred between portfolios owned by the same user:

transferPosition(user, fromPortfolioId, toPortfolioId, seriesId, amount)

Premium Transfer in transferPosition

When using transferPosition to move positions between your own portfolios, premium transfers proportionally with the option balance:

premiumTransfer=sourcePremiumBalance×amountsourceOptionBalance\text{premiumTransfer} = \frac{\text{sourcePremiumBalance} \times \text{amount}}{\text{sourceOptionBalance}}

Note: This proportional transfer applies only to transferPosition between a user's own portfolios. Other operations handle premium differently:

  • Trades (RFQ/OrderBook): Premium is explicitly agreed between parties
  • Liquidation: Option balance transfers to liquidator, premium stays with original user and settles at expiry
  • Settlement adjustments: Premium can be modified independently via updatePositionInPortfolio

Validation Checks

CheckDescription
Source balance sufficientCannot transfer more than source optionBalance
Destination capacityDestination must have room (< 16 positions)
Source healthSource portfolio must remain healthy after transfer
Destination healthDestination portfolio must remain healthy after transfer

Margin Independence

Cross-Margin Within Portfolio

Within a single portfolio, the four instruments offset each other during margin calculation:

  • Option Long offsets Option Short risk (across different series)
  • Premium Receiver offsets Premium Payer obligations
  • Example: Long call + Short put can have lower combined margin than the short put alone

Isolation Between Portfolios

Each portfolio is margined independently:

User
├── Portfolio 0 (USDC: $10,000)
│   ├── Position A: optionBalance = +50, premiumBalance = -$2,500
│   └── Health: Equity $12,000 vs MM $8,000 ✓

├── Portfolio 1 (USDC: $5,000)
│   ├── Position B: optionBalance = -30, premiumBalance = +$1,800
│   └── Health: Equity $4,200 vs MM $3,500 ✓

└── Portfolio 2 (USDC: $3,000)
    ├── Position C: optionBalance = +20, premiumBalance = -$1,000
    └── Health: Equity $3,500 vs MM $2,000 ✓

Key property: If Portfolio 1 becomes liquidatable, Portfolios 0 and 2 are unaffected. Risk is isolated.


Use Cases

Single Portfolio (Simple User)

Most users need only one portfolio:

  • All positions in Portfolio 0
  • All collateral in one place
  • Full cross-margin benefit across positions

Multi-Portfolio Risk Isolation

Advanced users may want separate portfolios:

PortfolioStrategyRationale
0ConservativeBlue-chip options, low risk
1SpeculativeHigh-risk plays, isolated from main funds
2HedgingProtective positions for external holdings

If the speculative portfolio gets liquidated, conservative and hedging portfolios remain intact.

MMM Single-Position Pattern

The Main Market Maker uses single-position portfolios for operational simplicity:

  • Portfolio 0: Liquidation receiving only
  • Portfolio 1, 2, 3...: Each holds exactly one series

See also: MMM Operations for detailed market maker portfolio patterns.


Worked Examples

Example A: Position After Trade

Alice buys 10 ETH-3500-CALL options at $150 each from Bob.

Alice's position (buyer):

FieldValueMeaning
optionBalance+10Long 10 options
premiumBalance-$1,500Owes $1,500 at settlement

Bob's position (seller):

FieldValueMeaning
optionBalance-10Short 10 options
premiumBalance+$1,500Owed $1,500 at settlement

Key insight: Each party has ONE position (one series entry) with two balances, not four separate positions.


Example B: Portfolio Equity Calculation

Charlie has Portfolio 0 with:

  • Deposit: $5,000 USDC
  • Position 1 (ETH-3500-CALL): optionBalance = +20, premiumBalance = -$2,000
  • Position 2 (ETH-3200-PUT): optionBalance = -10, premiumBalance = +$800

Current marks: Call = $120, Put = $95

Calculation:

Option Value:

(+20×$120)+(10×$95)=$2,400$950=$1,450(+20 \times \$120) + (-10 \times \$95) = \$2,400 - \$950 = \$1,450

Premium Balance:

$2,000+$800=$1,200-\$2,000 + \$800 = -\$1,200

Portfolio Equity:

$5,000+$1,450+($1,200)=$5,250\$5,000 + \$1,450 + (-\$1,200) = \$5,250

Example C: Cross-Margin Benefit

Compare two scenarios for holding a short put:

Scenario 1: Short put alone

PositionoptionBalanceMarkStress Loss (spot -30%)
ETH-2800-PUT-10$80$6,300
Total IM~$7,000

Scenario 2: Short put + Short call (short strangle)

PositionoptionBalanceMarkStress Loss (spot -30%)
ETH-2800-PUT-10$80$6,300
ETH-3500-CALL-10$100-$950 (gain)
Net Loss$5,350
Total IM~$6,000

The short call gains value when spot drops (call becomes worthless, releasing its liability), partially offsetting the short put loss and reducing margin by ~$1,000.


Example D: Collateral Transfer

Dana has two portfolios:

  • Portfolio 0: $10,000 deposit, no positions (Equity = $10,000, IM = $0)
  • Portfolio 1: $2,000 deposit, short puts (Equity = $1,800, IM = $1,500)

Dana wants to move $5,000 from Portfolio 0 to Portfolio 1.

Transfer check:

  • Portfolio 0 post-transfer: $5,000 deposit, IM = $0 → Healthy ✓
  • Portfolio 1 post-transfer: $7,000 deposit, IM = $1,500 → Healthy ✓

Transfer succeeds. Portfolio 1 now has more buffer against liquidation.


Example E: Position Transfer with Premium

Eve wants to transfer 5 long calls from Portfolio 0 to Portfolio 1.

Portfolio 0 before:

  • optionBalance = +20
  • premiumBalance = -$3,000

Proportional premium calculation:

premiumTransfer=$3,000×520=$750\text{premiumTransfer} = \frac{-\$3,000 \times 5}{20} = -\$750

Portfolio 0 after:

  • optionBalance = +15
  • premiumBalance = -$2,250

Portfolio 1 after:

  • optionBalance = +5
  • premiumBalance = -$750

In transferPosition, the premium obligation transfers proportionally with the option balance.


Smart Contract API

DiffusalPortfolioManager

FunctionDescription
createPortfolioCreate a new portfolio for a user
deletePortfolioDelete an empty portfolio
transferPositionMove position between portfolios
getUserPortfoliosGet all portfolio IDs for a user
portfolioExistsCheck if a portfolio exists
getPortfolioCountGet number of portfolios for a user

DiffusalCollateralVault

FunctionDescription
depositToPortfolioDeposit USDC to a specific portfolio
withdrawFromPortfolioWithdraw USDC from a portfolio
transferCollateralBetweenPortfoliosMove collateral between portfolios
getPortfolioDepositGet deposit amount for a portfolio

DiffusalOptionsPositionManager

FunctionDescription
getPortfolioPositionInfoGet position details for a series
getPortfolioSeriesIdsGet all series IDs in a portfolio
getPortfolioPositionCountGet number of positions in a portfolio
updatePositionInPortfolioUpdate option/premium balances (operator only)

DiffusalMarginCalculator

FunctionDescription
getPortfolioEquityCalculate current portfolio equity
getPortfolioMarginCalculate initial and maintenance margin
getPortfolioMaxWithdrawCalculate maximum withdrawable amount
isPortfolioHealthyCheck if portfolio equity >= maintenance margin
isLiquidatableCheck if portfolio can be liquidated

Protocol Documentation

Contract Documentation

On this page