# Swap

Uniswap v4's swap event improves token exchanges with enhanced efficiency and customization, allowing seamless ERC-20 trades with features like concentrated liquidity and adjustable fees, strengthening its DeFi role. The standard event emitted on swap is:

```solidity
event Swap(
    PoolId indexed id,
    address indexed sender,
    int128 amount0,
    int128 amount1,
    uint160 sqrtPriceX96,
    uint128 liquidity,
    int24 tick,
    uint24 fee
);
```

Where `amount0` and `amount1` are amounts of tokens that took part in swap, `sqrtPriceX96` is:

$$
\text{sqrtPriceX96} = \sqrt{\frac{\text{price of token1}}{\text{price of token0}}} \times 2^{96}
$$

`liquidity` is a liquidity in pool after the swap, [`tick`](https://support.uniswap.org/hc/en-us/articles/21069524840589-What-is-a-tick-when-providing-liquidity)`, fee` is a percentage of protocol fee.

To effectively monitor swap events on a pool, HookRank utilizes [The Graph](https://thegraph.com/) to continuously track  them on-chain and modify entities provided in [Tracked Data](/hookrank/hookrank-indexing/tracked-data.md).

On every Swap event emitted standard flow is executed in following order:

1. convert each token amount from decimal to integer value using number of decimals specified in [Tracked Data](/hookrank/hookrank-indexing/tracked-data.md#token) and revert a sign as specified in official Uniswap [article](https://uniswapfoundation.mirror.xyz/c7LDDTWhC2ry6gp0nGqcSKHvNHosJmhPQ-ZuIxqeB2I):\
   `amountDec = -(amount / decimals);`
2. calculate `abs()`for both amounts to be used in volume calculation further:\
   `amountAbs = abs(amountDec);`
3. calculate amount of each token in ETH and USD:\
   `amountETH = amountAbs * tokenPriceETH;`\
   `amountUSD = amountETH * ethPriceUSD;`
4. calculate the total swap amount in ETH and USD by accounting for only non-zero prices and dividing result by 2 as both input and output can\`t be counted as volume:

```typescript
const totalSwapAmount = 0;

if (price0USD > 0 && price1USD > 0) {
    totalSwapAmount = (price0USD * amount0Abs + price1USD * amount1Abs) / 2;
}

if (price0USD == 0 && price1USD > 0) {
    totalSwapAmount = price1USD * amount1Abs;
}

if (price0USD > 0 && price1USD == 0) {
    totalSwapAmount = price0USD * amount0Abs;
}
```

5. calculate the fees in ETH and USD by multiplying the fee values from the event with the totalSwapAmount in their respective currencies, then divide the result by 10^6 to with Uniswap percent [denominator](https://github.com/Uniswap/v4-core/blob/80311e34080fee64b6fc6c916e9a51a437d0e482/src/libraries/ProtocolFeeLibrary.sol#L15):\
   `fees = totalSwapAmount * fee / 10^6;`
6. update values of [Tracked Data](/hookrank/hookrank-indexing/tracked-data.md#poolmanager)
   * increment `txCount` by 1;
   * increment `totalVolumeETH` by `totalSwapAmount` in ETH;
   * increment `totalVolumeUSD by totalSwapAmount` in USD;
   * increment `totalFeesETH` by `fees` in ETH;
   * increment `totalFeesUSD` by `fees` in USD;
7. decrement [Tracked Data](/hookrank/hookrank-indexing/tracked-data.md#poolmanager) `totalValueLockedETH` by old [Tracked Data](/hookrank/hookrank-indexing/tracked-data.md#pool) `totalValueLockedETH` (it is needed to add new TVL later);
8. update values of [Tracked Data](/hookrank/hookrank-indexing/tracked-data.md#pool):
   * increment token volumes (`volumeToken0`, `volumeToken1`) by `amount0Abs,` `amount1Abs` respectively;
   * increment `volumeUSD` by `totalSwapAmountUSD;`
   * increment `feesUSD` by calculated `feesUSD;`
   * increment `txCount` by 1;
   * update `liquidity` with value from event;
   * update `tick` with value from event;
   * update `sqrtPrice` with value from event;
   * increment `totalValueLocked` for both tokens by amount respectively;
9. update for both tokens values of [Tracked Data](/hookrank/hookrank-indexing/tracked-data.md#token)
   * increment `volume` by `amountAbs;`
   * increment `totalValueLocked` by `amount`;
   * increment `volumeUSD` by `totalSwapAmountUSD;`
   * increment `feesUSD` by calculated `feesUSD;`
   * increment `txCount` by 1;
10. update [Tracked Data](/hookrank/hookrank-indexing/tracked-data.md#pool) rates:
    * update token prices to new prices calculated by standard AMM formula;
    * save `lastTx` value;
11. update [Tracked Data](/hookrank/hookrank-indexing/tracked-data.md#bundle)`ethPriceUSD` by new value fetched from native token pool;
12. update [Tracked Data](/hookrank/hookrank-indexing/tracked-data.md#token)`derivedETH` (token price in native currency) for both tokens;
13. update [Tracked Data](/hookrank/hookrank-indexing/tracked-data.md#pool) values affected by new USD rates:
    * `totalValueLockedETH:`\
      `totalValueLockedETH = totalValueLockedToken0 * token0DerivedETH + totalValueLockedToken1 * token1DerivedETH;`
    * `totalValueLockedUSD:`\
      `totalValueLockedUSD = totalValueLockedETH * ethPriceUSD;`
14. update [Tracked Data](/hookrank/hookrank-indexing/tracked-data.md#pool) gas values:
    * increment `gasAccumulatedBySwaps` by gas value from event;
    * increment `gasAccumulatedBySwapsInEth` by gas value from event times transaction gas price;
    * increment `swapsCount` by 1;
15. update [Tracked Data](/hookrank/hookrank-indexing/tracked-data.md#hook) values:
    * update `totalValueLocked` in ETH and USD by subtracting the pool's old `totalValueLocked` and adding new one (calculated with new prices);
    * increment `volumeUSD` by `totalSwapAmountUSD;`
    * increment `feesUSD` by calculated `feesUSD;`
    * increment `gasAccumulatedBySwaps` by gas value from event;
    * increment `gasAccumulatedBySwapsInEth` by gas value from event times transaction gas price;
    * increment `swapsCount` by 1;
16. increment [Tracked Data](/hookrank/hookrank-indexing/tracked-data.md#poolmanager) `totalValueLocked` by updated pool values;
17. increment [Tracked Data](/hookrank/hookrank-indexing/tracked-data.md#token) `totalValueLocked` by updated pool values;
18. update [Tracked Data](/hookrank/hookrank-indexing/tracked-data.md#uniswapdaydata), [Tracked Data](/hookrank/hookrank-indexing/tracked-data.md#pooldaydata), [Tracked Data](/hookrank/hookrank-indexing/tracked-data.md#poolhourdata), [Tracked Data](/hookrank/hookrank-indexing/tracked-data.md#tokendaydata) [Tracked Data](/hookrank/hookrank-indexing/tracked-data.md#tokenhourdata) with values calculated earlier;


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://hookrank.gitbook.io/hookrank/hookrank-indexing/events/swap.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
