PartyB Funding Update Nonces

Stale or expired funding updates from a solver engine are now skipped per symbol and reported, instead of overwriting newer rates or failing the batch they travelled in.

Summary

Funding rates are pushed on-chain by an off-chain solver engine. Retries, reorderings, and delayed inclusion mean a stale update can land after a newer one and overwrite it, and an update that is no longer wanted still executes when it finally confirms.

v0.8.6 adds a setFundingFee overload on SymmioPartyB that carries a per-symbol nonce and a deadline. Updates that are stale or expired are skipped and reported rather than reverted, so one out-of-date symbol cannot fail the batch it travelled in.

Interface

function setFundingFee(
    uint256[] calldata symbolIds,
    int256[] calldata longFees,
    int256[] calldata shortFees,
    int256[] calldata marketPrices,
    uint256[] calldata nonces,
    uint256 deadline
) external whenNotPaused;

nonces[i] belongs to symbolIds[i]. Callers must hold MANAGER_ROLE or TRUSTED_ROLE on the PartyB contract, or hold INSTANT_LAYER_ROLE on the Symmio core.

What is accepted, skipped, and forwarded

After the contract-address and caller-role checks, the deadline is checked before array lengths or per-symbol state. If it has passed, the whole call reports a skip and returns without touching funding-nonce state or validating array lengths.

Otherwise each symbol is compared against its last accepted nonce, and the call takes one of three paths.

If every symbol is stale, nothing is forwarded. If none are stale, everything is forwarded. A mixed batch is partitioned so the fresh symbols still land.
Case Forwarded to core Emitted
deadline passed nothing FundingFeeUpdateSkipped, reason 1
every symbol stale nothing FundingFeeUpdateSkipped, reason 0
no symbol stale all symbols nothing
mixed the fresh symbols only FundingFeeUpdateSkipped for the stale subset, reason 0

A symbol is stale when its supplied nonce is strictly lower than the stored one. An equal nonce is accepted, which lets the engine replace or retry the latest update for a symbol without inventing a new nonce and without breaking the surrounding template.

Accepted symbols write their nonce before the forward. This ordering does not make the nonce single-use: because an equal nonce remains acceptable, replaying the same batch forwards it again. The mapping prevents older updates from overwriting a newer accepted nonce; callers still need their own idempotency policy if duplicate forwarding matters.

Reporting

event FundingFeeUpdateSkipped(uint256[] symbolIds, uint256[] nonces, uint256 deadline, uint8 reason);

reason is 0 for a stale nonce and 1 for an expired deadline. In the mixed case the arrays carry only the skipped symbols, not the whole submission.

Batched calls are routed back through the gate

SymmioPartyB._call forwards each entry to the Symmio core. An entry targeting this contract's own setFundingFee selector would therefore have bypassed the nonce gate entirely. _call now detects that selector and delegatecalls it back into this contract instead, so a funding update carries the same guarantees whether it is submitted directly or inside a batch.

Storage

Two slots are appended after the existing v0.8.4-compatible layout, so no existing field moves.

uint256 private deprecatedFundingNonce;      // slot N+4: superseded global nonce, unused
mapping(uint256 => uint256) public fundingNonce; // slot N+5: symbolId => last accepted nonce

fundingNonce is public, so the engine can read the current floor per symbol and resynchronise after a restart rather than guessing.

Integration requirements

  • Supply a per-symbol nonce that never decreases for that symbol. A shared counter across symbols works but wastes headroom.
  • Set a deadline that reflects how long the update stays meaningful, not how long inclusion might take.
  • Read fundingNonce(symbolId) on startup to recover the floor after an engine restart.
  • Treat FundingFeeUpdateSkipped as expected traffic; alert on a symbol that is skipped repeatedly, which means the engine's nonce has fallen behind.
  • Reuse the same nonce when resubmitting the latest update for a symbol; a higher nonce is only needed for a genuinely newer rate.