Diffusal
Contracts

DiffusalInsuranceFund

Fee collection and liquidation shortfall coverage

The DiffusalInsuranceFund contract collects protocol trading fees and provides a safety net for liquidation shortfalls. When a liquidation's proceeds don't cover the user's debt, the insurance fund steps in to cover the gap, preventing protocol insolvency.


Overview

The insurance fund serves three purposes:

FunctionDescription
Fee CollectionReceives trading fees as feeRecipient for OrderBook and RFQ
Liquidation ShortfallCovers debt when liquidation proceeds are insufficient
Settlement ShortfallCovers batch settlement shortfalls when shorts can't pay

Fund Flow

┌─────────────────────────────────────────────────────────────────┐
│                        FEE COLLECTION                           │
│                                                                 │
│  OrderBook ────────────────┐                                    │
│    (maker + taker fees)    │                                    │
│                            ├───► Insurance Fund ───► Vault      │
│  RFQ ──────────────────────┘                        (deposit)   │
│    (RFQ fees)                                                   │
└─────────────────────────────────────────────────────────────────┘

┌─────────────────────────────────────────────────────────────────┐
│                      SHORTFALL COVERAGE                         │
│                                                                 │
│  Liquidation ───► Shortfall? ───┐                               │
│     Engine                      │                               │
│                                 ├───► Insurance Fund.cover()    │
│  Settlement  ───► Shortfall? ───┘          │                    │
│    Engine                                  ▼                    │
│                                   Vault.transferCollateral()    │
│                                            │                    │
│                                            └───► Cover bad debt │
└─────────────────────────────────────────────────────────────────┘

Key Concepts

Balance Storage

The insurance fund doesn't hold USDC directly. Instead, it maintains a deposit in the CollateralVault:

function getBalance() external view returns (uint256 balance) {
    return vault.getDeposit(address(this));
}

This design:

  • Leverages existing vault infrastructure
  • Simplifies fund accounting
  • Enables seamless transfers during liquidation

Fee Recipient Role

The insurance fund should be set as feeRecipient on both trading contracts:

// On OrderBook
orderBook.setFeeRecipient(address(insuranceFund));

// On RFQ
rfq.setFeeRecipient(address(insuranceFund));

When fees are collected, they're transferred to the insurance fund's vault deposit.

Shortfall Coverage

When a liquidation or batch settlement has insufficient funds:

// In LiquidationEngine._coverShortfall()
if (shortfall <= insuranceBalance) {
    insuranceFund.cover(shortfall);  // Full coverage
} else if (insuranceBalance > 0) {
    insuranceFund.cover(insuranceBalance);  // Partial coverage
}

// In SettlementEngine.settlePositionBatch()
// If short collection < long payout:
if (shortfall > 0) {
    insuranceFund.cover(shortfall);  // Cover batch settlement gap
}

Storage & State

The contract uses ERC-7201 namespaced storage for upgradeability:

/// @custom:storage-location erc7201:diffusal.storage.InsuranceFund
struct InsuranceFundStorage {
    address owner;
    address collateralVault;
    address liquidationEngine;
    address settlementEngine;
}

The contract is intentionally simple—all funds are stored in the vault.


View Functions

getBalance

Returns the current insurance fund balance.

function getBalance() external view returns (uint256 balance)

Returns: USDC balance (6 decimals) from vault deposit.


owner

Returns the contract owner.

function owner() external view returns (address)

collateralVault

Returns the collateral vault address.

function collateralVault() external view returns (address)

liquidationEngine

Returns the authorized liquidation engine address.

function liquidationEngine() external view returns (address)

settlementEngine

Returns the authorized settlement engine address.

function settlementEngine() external view returns (address)

Authorized Engine Functions

cover

Covers a liquidation or settlement shortfall by transferring funds.

function cover(uint256 amount) external nonReentrant onlyAuthorizedEngine
ParameterTypeDescription
amountuint256Shortfall amount to cover (USDC)

Requirements:

  • Caller must be the liquidation engine OR settlement engine
  • amount > 0
  • amount <= getBalance()

Effect: Transfers amount from insurance fund's vault deposit to the calling engine.

Emits: ShortfallCovered


Owner Functions

withdraw

Withdraws excess funds from the insurance fund.

function withdraw(uint256 amount) external nonReentrant onlyOwner
ParameterTypeDescription
amountuint256Amount to withdraw (USDC)

Requirements:

  • amount > 0
  • amount <= getBalance()

Effect: Transfers amount to owner's vault deposit.

Use case: Withdraw excess funds when balance grows beyond needed safety cushion.

Emits: Withdrawal


setLiquidationEngine

Sets the authorized liquidation engine.

function setLiquidationEngine(address engine_) external onlyOwner

Emits: LiquidationEngineUpdated


setSettlementEngine

Sets the authorized settlement engine.

function setSettlementEngine(address engine_) external onlyOwner

Emits: SettlementEngineUpdated


setCollateralVault

Updates the collateral vault reference.

function setCollateralVault(address vault_) external onlyOwner

Emits: CollateralVaultUpdated


transferOwnership

Transfers contract ownership.

function transferOwnership(address newOwner) external onlyOwner

Emits: OwnershipTransferred


Events

EventParametersDescription
ShortfallCoveredamountShortfall covered (liquidation or settlement)
Withdrawalto, amountOwner withdrew funds
LiquidationEngineUpdatedoldEngine, newEngineLiquidation engine changed
SettlementEngineUpdatedoldEngine, newEngineSettlement engine changed
CollateralVaultUpdatedoldVault, newVaultVault reference changed
OwnershipTransferredpreviousOwner, newOwnerOwnership changed

Integration Points

Depends On

ContractPurpose
DiffusalCollateralVaultStores insurance fund balance

Used By

ContractPurpose
DiffusalLiquidationEngineLiquidation shortfall coverage
DiffusalSettlementEngineBatch settlement shortfall coverage
DiffusalOptionsOrderBookFee recipient
DiffusalOptionsRFQFee recipient

Security Considerations

Access Control

FunctionAccess
cover()Liquidation engine OR settlement engine
withdraw()Owner only
getBalance()Public

Reentrancy Protection

Both cover() and withdraw() use nonReentrant modifier.

Fund Adequacy

The insurance fund should maintain sufficient balance to cover potential shortfalls. Monitoring should track:

  • Fund balance vs total protocol exposure
  • Historical shortfall frequency
  • Average shortfall size

No Margin Requirements

The insurance fund has no positions and thus no margin requirements. Its "deposit" in the vault is a pure balance.


Example: Shortfall Coverage

Scenario

A user with 3 positions gets liquidated:

  • Debt: $10,000 (IM - equity)
  • Liquidation proceeds: $8,000
  • Shortfall: $2,000

Process

// In LiquidationEngine._settleCollateral()
if (totalProceeds < debt) {
    uint256 shortfall = debt - totalProceeds;  // $2,000
    insuranceUsed = _coverShortfall(shortfall);
}

// In _coverShortfall()
function _coverShortfall(uint256 shortfall) internal returns (uint256 insuranceUsed) {
    uint256 balance = insuranceFund.getBalance();  // e.g., $50,000

    if (shortfall <= balance) {
        insuranceFund.cover(shortfall);  // Cover full $2,000
        insuranceUsed = shortfall;
    }
}

Result

  • User's positions closed
  • $8,000 collected from positions
  • $2,000 drawn from insurance fund
  • Total coverage: $10,000 (matches debt)
  • Insurance fund balance: $48,000

Code Reference

Source: packages/contracts/src/DiffusalInsuranceFund.sol

Interface: packages/contracts/src/interfaces/IDiffusalInsuranceFund.sol

Testnet: View on MonadVision


On this page