Skip to content

Surface isLiquidation + liqFee on MarketEvent::TakerClosed (and MakerClosed) #61

Description

@Praz314159

Problem

The deployed contract emits a unified close/liquidation event:

event TakerClosed(uint256 posId, SwapResult sr, int256 funding, uint256 utilFees, uint256 liqFee, bool isLiquidation);

(See the binding fix that added liqFee/isLiquidation — the deployed TakerClosed differs from the v0.2.1 source; related: #58.)

But decode_log drops those two fields (src/feeds/events.rs):

} else if topic0 == Perp::TakerClosed::SIGNATURE_HASH {
    let d = decode_raw::<Perp::TakerClosed>(log)?;
    Some(MarketEvent::TakerClosed {
        pos_id: d.posId,
        swap: swap_info(&d.sr)?,
        funding: i256_usdc(d.funding)?,
        util_fees: u256_usdc(d.utilFees)?,
        // d.liqFee and d.isLiquidation are dropped
    })
}

And the MarketEvent::TakerClosed variant has no liquidation fields.

Impact

Because liquidation is folded into TakerClosed(isLiquidation=true) on the deployed contract (rather than a separate TakerLiquidated), a consumer cannot distinguish a liquidation from a voluntary close via the event stream, nor see the liquidation fee. Position eviction doesn't care (both → remove the position), but risk/strategy/PnL logic does (e.g. Legion would want to know it got liquidated rather than chose to close).

Proposal

Add is_liquidation: bool and liq_fee: f64 to MarketEvent::TakerClosed (and check MakerClosed for the same isLiquidation/liqFee shape — verify its deployed signature per #58), and populate them in decode_log:

Some(MarketEvent::TakerClosed {
    pos_id: d.posId,
    swap: swap_info(&d.sr)?,
    funding: i256_usdc(d.funding)?,
    util_fees: u256_usdc(d.utilFees)?,
    liq_fee: u256_usdc(d.liqFee)?,
    is_liquidation: d.isLiquidation,
})

This pairs naturally with #58 (verifying the sibling close/liquidation bindings against the deployment). Surfaced by the Legion migration's market_data review.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions