# Index trades and events

A routed trade can emit router, curve, pool and token events in one transaction. These describe different legs of the **same** trade. Adding all of them as volume double-counts it.

## Pair Router fill

```solidity
event CurvePairRouted(
    address indexed curve,
    address indexed payer,
    address indexed recipient,
    bool buy,
    bool nativeHype,
    uint256 userInput,
    uint256 userOutput,
    uint256 quoteAmount,
    uint256 quoteRefund,
    bool graduated
);
```

Decode only from the reviewed router address and match its curve to the authenticated market. Amounts are base units of their respective assets.

| Method | `userInput` | `userOutput` | `quoteRefund` |
| --- | --- | --- | --- |
| `buyQuote` | Actual pairing asset spent, excluding change | Tokens received | Pairing asset returned to payer |
| `sellQuote` | Tokens sold | Pairing asset received | Zero |
| `buyHype`, WHYPE pair | Actual HYPE spent, excluding change | Tokens received | WHYPE-denominated amount unwrapped and returned as HYPE |
| `buyHype`, other pair | Full native HYPE supplied | Tokens received | Pairing asset returned to payer |
| `sellHype` | Tokens sold | Native HYPE received | Zero |

`quoteAmount` is the pairing-asset amount spent on a buy or received from the token-sale leg on a sell. It is not always denominated in the same asset as `userInput` or `userOutput`.

**The event's `graduated` field records the expected phase at entry.** A graduating buy can emit `false` even though the curve has graduated by the end of that transaction. Use the separate graduation event and post-transaction state for the result.

## Refund-aware cost accounting

For a non-WHYPE `buyHype`, do not treat the entire HYPE input as the cost of the tokens while ignoring the refunded pairing asset. If using proportional allocation, allocate HYPE cost between `quoteAmount` and `quoteRefund` by their share of the total converted quote. Keep the refund's remaining cost basis separately. State that this is your accounting convention; the event does not emit tax-accounting cost basis.

Never subtract raw pairing-token units from raw HYPE units.

## Underlying events

```solidity
event CurveBuy(address indexed payer, address indexed recipient,
               uint256 spent, uint256 tokens, uint256 refund);
event CurveSell(address indexed payer, address indexed recipient,
                uint256 tokens, uint256 received);
event Graduated(address indexed pair, uint256 tokenSeed,
                uint256 quoteSeed, uint256 lpBurned);
event GraduationDeferred(bytes reason);
```

For a router fill, retain these as supporting legs rather than additional user trades. For direct curve or direct pool trades, reconstruct the economic payer, recipient, tax and output using the actual call and transfer graph. A transaction can contain multiple real trades, so deduplicating only by transaction hash is also wrong.

Use `(chainId, transactionHash, logIndex)` as an event identity. Store block number/hash, handle removed logs and replay overlapping ranges safely. Preserve raw amounts when historical USD prices are unavailable; unpriced is not $0.
