Files
observer/crates/blackbeard-data/migrations/0012_ref_swaps.sql
T
grenadeandClaude Opus 5.5 b85e74f1ca
ci / gate (push) Successful in 5m7s
deploy / validate (push) Skipped
deploy / build (push) Successful in 9m3s
deploy / deploy-api (push) Successful in 42s
deploy / deploy-web (push) Successful in 12s
feat: index QTC's Ref DCL pool — its swaps, its ladder, and how much we see
On 2026-10-06 the team bridged 150,000 QTC to NEAR and put almost all of it in
a Ref Finance DCL pool, not into solver balances, so the market page saw none
of it. The pool contract (dclv2.ref-labs.near) is on shard 8 and our node
tracks only intents.near's shard 7, so its swap events are never in anything
the scan reads.

What the scan does see is the relay transaction: the Verifier's outcome logs
an ft_withdraw from the solver to the pool. Those are queued (ref_pending,
migration 0012, persisted because the process restarts) and fetched whole
from the public endpoint 20 blocks later, once the pool's receipt has run;
its dcl.ref swaps are recorded with the solver as trader, since the pool
itself records intents.near. Swaps made by calling the pool directly are
missed — and the pool's own cumulative counters say by how much, so the page
reports coverage instead of a disclaimer: today 99.75% of QTC bought out and
100% of QTC sold in, the gap one 0.000498 QTC buy.

Pool state comes from view calls once a minute: price at the current point,
holdings, whitelist, counters, and the liquidity ladder from
blackbeard_core::dcl — discrete sums over points, with the current point split
exactly by liquidity_x; tested against the pool's own totals (QTC to 0.01, and
USDC short by exactly the LP fees total_x also holds). Pools are found by
paging list_pools.

It is its own market, /:chain/market/ref-dcl, never summed with NEAR Intents
trades: a user's buy is a solver fill there and, after it, the solver's
restock here. The pools' whitelists join the inventory poll, which now finds
solver-ref-2.near holding 0.288 QTC. Migration 0013 pulls QTC's scan back to
NEAR 218,700,000, before the pool, so the swaps production already passed are
found on the re-read.

Refs #37

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015pkwBsR54NRmZyU4QVhvfj
2026-10-06 09:50:34 +03:00

48 lines
2.1 KiB
SQL

-- Swaps in Ref Finance DCL pools that hold the tracked asset.
-- blackbeard/observer#37.
--
-- The pool contract (dclv2.ref-labs.near) is on a shard our NEAR node does not
-- track, so its swap events cannot be read as the scan passes. What the scan
-- does see, on intents.near's shard, is the relay transaction whose Verifier
-- outcome sends a solver's tokens to the pool. That transaction is queued in
-- ref_pending and fetched whole from a public endpoint a few blocks later,
-- once the pool's receipt has executed. The queue is a table because the
-- process restarts several times a day and a pending swap must survive it.
create table ref_pending (
chain text not null references chain (id) on delete cascade,
tx_hash text not null,
signer text not null,
near_height bigint not null,
-- The solver whose intent sent the tokens: the real trader, since the
-- pool records intents.near as its swapper.
trader text not null,
attempts integer not null default 0,
queued_at timestamptz not null default now(),
primary key (chain, tx_hash)
);
create table ref_swap (
chain text not null references chain (id) on delete cascade,
asset text not null,
near_height bigint not null,
tx_hash text not null,
receipt_id text not null,
swap_index integer not null,
at timestamptz not null,
contract text not null,
pool_id text not null,
trader text not null,
swapper text not null,
token_in text not null,
token_out text not null,
amount_in numeric not null,
amount_out numeric not null,
total_fee numeric not null,
protocol_fee numeric not null,
-- From the trader's side: bought the asset out of the pool, or sold it in.
side text not null check (side in ('buy', 'sell')),
primary key (chain, asset, tx_hash, receipt_id, swap_index)
);
create index ref_swap_newest on ref_swap (chain, asset, near_height desc, tx_hash);