> For the complete documentation index, see [llms.txt](https://docs.trover.tech/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.trover.tech/engineering/dune-dashboard.md).

# Dune dashboard: Trover DEX trades on Robinhood Chain

Dune indexes Robinhood Chain as `robinhood.logs`, `robinhood.transactions` (the LONG dashboard at dune.com/natan\_benish2001/long-on-robinhood-chain is built from them). Your API key is valid but the account is read-only for the API (query creation, execution and CSV uploads all need a paid plan), so the queries below are pasted into the Dune web editor, which the free plan allows. Save each query, note its number, and reference it as `query_<id>` in the next one.

## How a Trover trade is identified on-chain

Today a Trover trade is a swap sent straight to Uniswap SwapRouter02 (`0xcaf681a66d020601342297493863e78c959e5cb2`) or the Universal Router (`0x8876789976decbfcbbbe364623c63652db8c0904`) from one of our Privy embedded wallets; the platform fee is booked separately, so the fee wallet does not appear in the trade transaction (checked on tx `0x116bdd…bfa93a`). Attribution is therefore by sender: the list of our embedded wallets (query 1). Once `TroverAtomicFeeExecutor` is on mainnet, add its address to query 1 as `executor` and every trade routed through it is attributed without maintaining the wallet list.

Numeraires on Robinhood Chain: WETH `0x0bd7d308f8e1639fab988df18a8011f41eacad73` (18 decimals), USDG `0x5fc5360d0400a0fd4f2af552add042d716f1d168` (6 decimals, priced at $1). ETH is priced from Dune's `prices.usd` (Ethereum WETH, hourly).

## Query 1: trover\_wallets

Regenerate from Postgres whenever wallets are added:

```
select lower(address) from trading_wallets where kind <> 'external' and active;
```

```sql
-- Trover: attribution set. Embedded wallets we created, plus (later) the fee executor.
SELECT address, kind FROM (VALUES
  (0x8af535e06da50c8ec9f931e7feeacd5a1d4e0d6f, 'wallet'),
  (0x581b6db0f4d3fe569114862e84badaa8ea582e88, 'wallet'),
  (0xe99b92eeea9b7d46eb93de6303681e094136a68f, 'wallet'),
  (0x86e39e5aa0eb53141979e4800f136a4b4f62ed4c, 'wallet'),
  (0x61b917781f1cabb4f63eca28d16dc231e745be6f, 'wallet')
  -- ,(0x<TroverAtomicFeeExecutor>, 'executor')
) AS t (address, kind)
```

## Query 2: trover\_pools (Uniswap v3 pools on Robinhood Chain)

```sql
-- Every Uniswap v3 pool from the Robinhood factory, with its tokens and fee tier.
SELECT
  varbinary_substring(topic1, 13, 20)             AS token0,
  varbinary_substring(topic2, 13, 20)             AS token1,
  varbinary_to_uint256(topic3)                    AS fee,
  varbinary_substring(data, 45, 20)               AS pool,
  block_time                                      AS created_at
FROM robinhood.logs
WHERE contract_address = 0x1f7d7550b1b028f7571e69a784071f0205fd2efa
  AND topic0 = 0x783cca1c0412dd0d695e784568c96da2e9c22ff989357a2e8b1d9b2b4e6b7118  -- PoolCreated
```

## Query 3: trover\_swaps (foundation)

Replace `query_1` and `query_2` with your saved ids.

```sql
-- Every Uniswap v3 swap on Robinhood Chain sent by a Trover wallet (or through the executor),
-- with the numeraire leg, side, and USD value. One row per Swap event.
WITH wallets AS (SELECT address FROM query_1),
pools AS (SELECT * FROM query_2),
swaps AS (
  SELECT
    l.block_time, l.block_date, l.tx_hash, l.index AS evt_index, l.contract_address AS pool,
    varbinary_to_int256(varbinary_substring(l.data,  1, 32)) AS amount0,   -- pool perspective: + = pool received
    varbinary_to_int256(varbinary_substring(l.data, 33, 32)) AS amount1,
    t."from" AS trader, t."to" AS router
  FROM robinhood.logs l
  JOIN robinhood.transactions t ON t.hash = l.tx_hash AND t.block_date = l.block_date
  WHERE l.topic0 = 0xc42079f94a6350d7e6235f29174924f928cc2ac818eb64fed8004e115fbcca67  -- Swap (v3)
    AND (t."from" IN (SELECT address FROM wallets) OR t."to" IN (SELECT address FROM wallets))
),
typed AS (
  SELECT s.*, p.token0, p.token1, p.fee,
    CASE WHEN p.token0 IN (0x0bd7d308f8e1639fab988df18a8011f41eacad73, 0x5fc5360d0400a0fd4f2af552add042d716f1d168) THEN 0
         WHEN p.token1 IN (0x0bd7d308f8e1639fab988df18a8011f41eacad73, 0x5fc5360d0400a0fd4f2af552add042d716f1d168) THEN 1 END AS numeraire_slot
  FROM swaps s JOIN pools p ON p.pool = s.pool
),
priced AS (
  SELECT
    x.*,
    CASE numeraire_slot WHEN 0 THEN token0 ELSE token1 END AS numeraire,
    CASE numeraire_slot WHEN 0 THEN token1 ELSE token0 END AS asset,
    CASE numeraire_slot WHEN 0 THEN amount0 ELSE amount1 END AS numeraire_amount_raw,
    -- pool received numeraire => the trader bought the asset
    CASE WHEN (CASE numeraire_slot WHEN 0 THEN amount0 ELSE amount1 END) > 0 THEN 'buy' ELSE 'sell' END AS side
  FROM typed x WHERE numeraire_slot IS NOT NULL
),
eth AS (
  SELECT minute, price FROM prices.usd WHERE blockchain = 'ethereum' AND symbol = 'WETH'
)
SELECT
  p.block_time, p.block_date, p.tx_hash, p.evt_index, p.trader, p.router, p.pool, p.fee,
  p.asset, p.numeraire, p.side,
  CASE WHEN p.numeraire = 0x5fc5360d0400a0fd4f2af552add042d716f1d168 THEN 'USDG' ELSE 'ETH' END AS numeraire_symbol,
  ABS(p.numeraire_amount_raw) / CASE WHEN p.numeraire = 0x5fc5360d0400a0fd4f2af552add042d716f1d168 THEN 1e6 ELSE 1e18 END AS numeraire_amount,
  ABS(p.numeraire_amount_raw) / CASE WHEN p.numeraire = 0x5fc5360d0400a0fd4f2af552add042d716f1d168 THEN 1e6 ELSE 1e18 END
    * CASE WHEN p.numeraire = 0x5fc5360d0400a0fd4f2af552add042d716f1d168 THEN 1 ELSE COALESCE(e.price, 0) END AS amount_usd
FROM priced p
LEFT JOIN eth e ON e.minute = date_trunc('minute', p.block_time)
```

A multi-hop swap (two `Swap` events in one transaction, like tx `0x116bdd…`) produces two rows; the trade-level views below count distinct transactions and take the numeraire leg that touched the router.

## Query 4: daily volume, trades, traders

```sql
SELECT block_date AS day,
  SUM(amount_usd)                    AS volume_usd,
  COUNT(DISTINCT tx_hash)            AS trades,
  COUNT(DISTINCT trader)             AS traders,
  SUM(CASE WHEN side = 'buy'  THEN amount_usd END) AS buy_usd,
  SUM(CASE WHEN side = 'sell' THEN amount_usd END) AS sell_usd
FROM query_3
GROUP BY 1 ORDER BY 1
```

Chart: bars (volume\_usd) with a line (trades) on the right axis.

## Query 5: top assets

```sql
SELECT asset, COUNT(DISTINCT tx_hash) AS trades, COUNT(DISTINCT trader) AS traders,
  SUM(amount_usd) AS volume_usd, MAX(block_time) AS last_trade
FROM query_3 GROUP BY 1 ORDER BY volume_usd DESC LIMIT 25
```

Join `tokens.erc20` (`blockchain = 'robinhood'`) on `contract_address = asset` for symbols if Dune has them for this chain; otherwise the address column is what you get.

## Query 6: new vs returning traders

```sql
WITH first_trade AS (SELECT trader, MIN(block_date) AS first_day FROM query_3 GROUP BY 1)
SELECT q.block_date AS day,
  COUNT(DISTINCT CASE WHEN f.first_day = q.block_date THEN q.trader END) AS new_traders,
  COUNT(DISTINCT CASE WHEN f.first_day < q.block_date THEN q.trader END) AS returning_traders
FROM query_3 q JOIN first_trade f ON f.trader = q.trader
GROUP BY 1 ORDER BY 1
```

## Query 7: Trover share of Robinhood Chain v3 volume

```sql
WITH all_swaps AS (
  SELECT l.block_date, l.tx_hash, l.contract_address AS pool,
    varbinary_to_int256(varbinary_substring(l.data, 1, 32)) AS amount0,
    varbinary_to_int256(varbinary_substring(l.data, 33, 32)) AS amount1
  FROM robinhood.logs l
  WHERE l.topic0 = 0xc42079f94a6350d7e6235f29174924f928cc2ac818eb64fed8004e115fbcca67
),
usdg_pools AS (SELECT pool, CASE WHEN token0 = 0x5fc5360d0400a0fd4f2af552add042d716f1d168 THEN 0 ELSE 1 END AS slot FROM query_2
               WHERE token0 = 0x5fc5360d0400a0fd4f2af552add042d716f1d168 OR token1 = 0x5fc5360d0400a0fd4f2af552add042d716f1d168),
chain AS (
  SELECT a.block_date, SUM(ABS(CASE u.slot WHEN 0 THEN a.amount0 ELSE a.amount1 END) / 1e6) AS chain_usdg_volume
  FROM all_swaps a JOIN usdg_pools u ON u.pool = a.pool GROUP BY 1
),
ours AS (SELECT block_date, SUM(amount_usd) AS trover_usd FROM query_3 WHERE numeraire_symbol = 'USDG' GROUP BY 1)
SELECT c.block_date AS day, c.chain_usdg_volume, COALESCE(o.trover_usd, 0) AS trover_usd,
  100.0 * COALESCE(o.trover_usd, 0) / NULLIF(c.chain_usdg_volume, 0) AS trover_share_pct
FROM chain c LEFT JOIN ours o ON o.block_date = c.block_date ORDER BY 1
```

USDG pairs only, so the share is like-for-like; extend with the ETH leg if you want the full picture.

## Query 8: fees earned (after the executor is live)

```sql
-- Native and USDG fees received by the platform fee wallet and the token-fee accumulator.
SELECT block_date AS day,
  SUM(CASE WHEN contract_address = 0x5fc5360d0400a0fd4f2af552add042d716f1d168 THEN varbinary_to_uint256(data) / 1e6 END) AS usdg_fees,
  SUM(CASE WHEN contract_address = 0x0bd7d308f8e1639fab988df18a8011f41eacad73 THEN varbinary_to_uint256(data) / 1e18 END) AS weth_fees
FROM robinhood.logs
WHERE topic0 = 0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef  -- Transfer
  AND varbinary_substring(topic2, 13, 20) IN (0x4b14412a1cb6f30622f25a6706ff26ec953ec486, 0xdaf20dd5b1a15d930ae05f2082a6571bd277cc7c)
GROUP BY 1 ORDER BY 1
```

Until the executor routes fees on-chain this shows only what has actually reached those wallets; our own ledger (`GET /v1/token/economics` and the admin treasury view) is the source of truth for fees meanwhile.

## Assembling the dashboard

1. Create queries 1 to 8 in order (each depends on the earlier ids).
2. New dashboard, add each query's visualization; suggested order: daily volume, share of chain, top assets, new vs returning, fees.
3. Set the dashboard to public if you want a shareable link; the queries can stay private.
4. When the fee executor deploys, add its address to query 1 and rerun.

## Later: our own dataset on Dune

With a paid Dune plan the API allows CSV uploads, and a worker job can push `trover_trades` (time, token, side, notional, fee, USD at execution, channel: web, X or MCP) daily, which adds the channel split the chain cannot show. The key is stored on the server as `DUNE_API_KEY` for that day; nothing reads it yet.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## 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, and the optional `goal` query parameter:

```
GET https://docs.trover.tech/engineering/dune-dashboard.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

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.
