Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 9 additions & 8 deletions docs/dune-queries/01_tvl_current.sql
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,15 @@
-- Total escrow currently held by the contract = inflows - outflows.
--
-- Decoding (see 10_event_created_decode_test.sql for the why):
-- event name -> topics_decoded '$[0].symbol'
-- event name -> topics_decoded '$[0].symbol' (snake_case: #[contractevent]
-- lowercases the struct name, e.g. EventCreated -> event_created)
Comment on lines +6 to +7

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Describe this as snake_case conversion, not lowercasing.

Lowercasing EventCreated yields eventcreated; the underscore requires snake_case conversion.

  • docs/dune-queries/01_tvl_current.sql#L6-L7: replace “lowercases the struct name” with “converts the struct name to snake_case.”
  • docs/dune-queries/10_event_created_decode_test.sql#L6-L8: make the same wording correction.
📍 Affects 2 files
  • docs/dune-queries/01_tvl_current.sql#L6-L7 (this comment)
  • docs/dune-queries/10_event_created_decode_test.sql#L6-L8
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/dune-queries/01_tvl_current.sql` around lines 6 - 7, Update the
documentation wording describing #[contractevent] in
docs/dune-queries/01_tvl_current.sql lines 6-7 and
docs/dune-queries/10_event_created_decode_test.sql lines 6-8: replace the claim
that it lowercases struct names with wording that it converts struct names to
snake_case, preserving the EventCreated to event_created example.

-- fields -> rebuild data_decoded '$.map' into MAP(name -> ScVal JSON),
-- then read each field by its ScVal type ($.i128, $.u64, ...).
--
-- Inflows: EventCreated.total_budget (non-Crowdfunding — escrowed at creation)
-- FundsAdded.amount (partner top-ups + crowdfunding contributions)
-- Outflows: WinnerPaid.amount, MilestoneClaimed.amount,
-- ContributorRefunded.amount, OwnerResidualRefunded.amount
-- Inflows: event_created.total_budget (non-Crowdfunding — escrowed at creation)
-- funds_added.amount (partner top-ups + crowdfunding contributions)
-- Outflows: winner_paid.amount, milestone_claimed.amount,
-- contributor_refunded.amount, owner_residual_refunded.amount
-- Amounts are the values the contract actually escrows/releases (the protocol
-- fee is charged separately, not embedded here). Divide by 1e7 for display.

Expand All @@ -31,17 +32,17 @@ WITH ev AS (
inflows AS (
SELECT CAST(JSON_EXTRACT_SCALAR(f['total_budget'], '$.i128') AS DOUBLE) AS amount
FROM ev
WHERE ev_name = 'EventCreated'
WHERE ev_name = 'event_created'
AND JSON_EXTRACT_SCALAR(f['pillar'], '$.vec[0].symbol') <> 'Crowdfunding'
UNION ALL
SELECT CAST(JSON_EXTRACT_SCALAR(f['amount'], '$.i128') AS DOUBLE)
FROM ev
WHERE ev_name = 'FundsAdded'
WHERE ev_name = 'funds_added'
),
outflows AS (
SELECT CAST(JSON_EXTRACT_SCALAR(f['amount'], '$.i128') AS DOUBLE) AS amount
FROM ev
WHERE ev_name IN ('WinnerPaid', 'MilestoneClaimed', 'ContributorRefunded', 'OwnerResidualRefunded')
WHERE ev_name IN ('winner_paid', 'milestone_claimed', 'contributor_refunded', 'owner_residual_refunded')
)
SELECT
(COALESCE((SELECT SUM(amount) FROM inflows), 0)
Expand Down
16 changes: 8 additions & 8 deletions docs/dune-queries/02_tvl_over_time.sql
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
-- Panel type: area chart x=day y=tvl_display
--
-- Decoding (see 10_event_created_decode_test.sql): event name is
-- topics_decoded '$[0].symbol'; fields come from the data_decoded '$.map'
-- ScVal map, read by type ($.i128, ...).
-- topics_decoded '$[0].symbol' (snake_case), fields come from the
-- data_decoded '$.map' ScVal map, read by type ($.i128, ...).

WITH ev AS (
SELECT
Expand All @@ -25,24 +25,24 @@ signed AS (
day,
CASE
-- Inflow: non-crowdfunding creation escrows the budget
WHEN ev_name = 'EventCreated'
WHEN ev_name = 'event_created'
AND JSON_EXTRACT_SCALAR(f['pillar'], '$.vec[0].symbol') <> 'Crowdfunding'
THEN CAST(JSON_EXTRACT_SCALAR(f['total_budget'], '$.i128') AS DOUBLE)

-- Inflow: add_funds (crowdfunding + partner top-ups)
WHEN ev_name = 'FundsAdded'
WHEN ev_name = 'funds_added'
THEN CAST(JSON_EXTRACT_SCALAR(f['amount'], '$.i128') AS DOUBLE)

-- Outflow: payouts and refunds
WHEN ev_name IN ('WinnerPaid', 'MilestoneClaimed',
'ContributorRefunded', 'OwnerResidualRefunded')
WHEN ev_name IN ('winner_paid', 'milestone_claimed',
'contributor_refunded', 'owner_residual_refunded')
THEN -CAST(JSON_EXTRACT_SCALAR(f['amount'], '$.i128') AS DOUBLE)

ELSE 0
END AS delta
FROM ev
WHERE ev_name IN ('EventCreated', 'FundsAdded', 'WinnerPaid',
'MilestoneClaimed', 'ContributorRefunded', 'OwnerResidualRefunded')
WHERE ev_name IN ('event_created', 'funds_added', 'winner_paid',
'milestone_claimed', 'contributor_refunded', 'owner_residual_refunded')
),
daily_delta AS (
SELECT day, SUM(delta) / 1e7 AS daily_change_display
Expand Down
6 changes: 4 additions & 2 deletions docs/dune-queries/03_bounties_funded.sql
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
-- Boundless On-chain: Events created — count and budget by pillar and month
-- Panel type: grouped bar chart x=month y=events_created color=pillar
--
-- Decoding: see 10_event_created_decode_test.sql.
-- Decoding: see 10_event_created_decode_test.sql. Event name is snake_case
-- on-chain (event_created); pillar enum value is PascalCase (Hackathon,
-- Bounty, Grant, Crowdfunding) — verify with query 10's pillar_raw.

WITH ev AS (
SELECT
Expand All @@ -15,7 +17,7 @@ WITH ev AS (
FROM stellar.history_contract_events
WHERE contract_id = '{{CONTRACT_ADDRESS}}'
AND closed_at_date >= DATE '{{START_DATE}}'
AND JSON_EXTRACT_SCALAR(topics_decoded, '$[0].symbol') = 'EventCreated'
AND JSON_EXTRACT_SCALAR(topics_decoded, '$[0].symbol') = 'event_created'
)
SELECT
month,
Expand Down
8 changes: 5 additions & 3 deletions docs/dune-queries/04_total_payouts.sql
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
-- Boundless On-chain: Total payouts to builders
-- Panel type: bar chart x=month y=total_paid_display color=payout_type
--
-- WinnerPaid -> Hackathon / Bounty (single-release; fires at claim_prize)
-- MilestoneClaimed -> Grant / Crowdfunding (multi-release, per milestone)
-- winner_paid -> Hackathon / Bounty (single-release; fires inside
-- select_winners — the contract pushes payment there,
-- there is no separate claim step)
-- milestone_claimed -> Grant / Crowdfunding (multi-release, per milestone)
-- Both carry event_id, recipient (address), amount (i128).
-- Decoding: see 10_event_created_decode_test.sql.

Expand All @@ -19,7 +21,7 @@ WITH ev AS (
FROM stellar.history_contract_events
WHERE contract_id = '{{CONTRACT_ADDRESS}}'
AND closed_at_date >= DATE '{{START_DATE}}'
AND JSON_EXTRACT_SCALAR(topics_decoded, '$[0].symbol') IN ('WinnerPaid', 'MilestoneClaimed')
AND JSON_EXTRACT_SCALAR(topics_decoded, '$[0].symbol') IN ('winner_paid', 'milestone_claimed')
)
SELECT
month,
Expand Down
20 changes: 13 additions & 7 deletions docs/dune-queries/05_unique_participants.sql
Original file line number Diff line number Diff line change
@@ -1,8 +1,14 @@
-- Boundless On-chain: Unique builder and organizer wallets
-- Panel type: counter (two rows: builders, organizers)
--
-- Decoding: event name is topics_decoded '$[0].symbol'; addresses are read
-- from the data_decoded '$.map' as '$.address'. See 10_event_created_decode_test.sql.
-- Builders participate through one of three on-chain footprints:
-- applied (Bounty — gated apply)
-- submitted (Hackathon — open submission, no prior apply)
-- winner_paid / milestone_claimed (received a payout on any pillar)
-- Counting only 'applied' would miss every hackathon entrant, since that
-- pillar's participants submit without applying.
-- Decoding: event name is snake_case; addresses read as '$.address'.
-- See 10_event_created_decode_test.sql.

WITH ev AS (
SELECT
Expand All @@ -17,18 +23,18 @@ WITH ev AS (
WHERE contract_id = '{{CONTRACT_ADDRESS}}'
AND closed_at_date >= DATE '{{START_DATE}}'
AND JSON_EXTRACT_SCALAR(topics_decoded, '$[0].symbol')
IN ('Applied', 'WinnerPaid', 'MilestoneClaimed', 'EventCreated')
IN ('applied', 'submitted', 'winner_paid', 'milestone_claimed', 'event_created')
)
-- Builders: applied to or received a payout from any event
-- Builders: applied to, submitted to, or received a payout from any event

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Remove the redundant builders banner.

It restates the following UNION; lines 4-11 already preserve the non-obvious participation rationale.

Proposed fix
--- Builders: applied to, submitted to, or received a payout from any event
 SELECT

As per coding guidelines, “Comment sparingly” and “Do not narrate code behavior.”

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
-- Builders: applied to, submitted to, or received a payout from any event
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/dune-queries/05_unique_participants.sql` at line 28, Remove the
redundant “Builders” banner comment immediately preceding the UNION in the
unique participants query, leaving the query and the existing rationale comments
unchanged.

Source: Coding guidelines

SELECT
'builders' AS role,
COUNT(DISTINCT addr) AS unique_wallets
FROM (
SELECT JSON_EXTRACT_SCALAR(f['applicant'], '$.address') AS addr
FROM ev WHERE ev_name = 'Applied'
FROM ev WHERE ev_name IN ('applied', 'submitted')
UNION
SELECT JSON_EXTRACT_SCALAR(f['recipient'], '$.address')
FROM ev WHERE ev_name IN ('WinnerPaid', 'MilestoneClaimed')
FROM ev WHERE ev_name IN ('winner_paid', 'milestone_claimed')
) t

UNION ALL
Expand All @@ -38,4 +44,4 @@ SELECT
'organizers' AS role,
COUNT(DISTINCT JSON_EXTRACT_SCALAR(f['owner'], '$.address')) AS unique_wallets
FROM ev
WHERE ev_name = 'EventCreated'
WHERE ev_name = 'event_created'
13 changes: 7 additions & 6 deletions docs/dune-queries/06_event_outcomes.sql
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@
-- Panel type: bar chart or table
--
-- Buckets every created event into completed_with_payout / cancelled /
-- active_or_pending. Note the id field differs by event:
-- EventCreated carries 'id'; all later events carry 'event_id'.
-- active_or_pending. Note the id field name differs by event:
-- event_created and event_cancelled carry 'id';
-- winner_paid / milestone_claimed carry 'event_id'.
-- Decoding: see 10_event_created_decode_test.sql.

WITH ev AS (
Expand All @@ -20,21 +21,21 @@ WITH ev AS (
WHERE contract_id = '{{CONTRACT_ADDRESS}}'
AND closed_at_date >= DATE '{{START_DATE}}'
AND JSON_EXTRACT_SCALAR(topics_decoded, '$[0].symbol')
IN ('EventCreated', 'EventCancelled', 'WinnerPaid', 'MilestoneClaimed')
IN ('event_created', 'event_cancelled', 'winner_paid', 'milestone_claimed')
),
created AS (
SELECT
CAST(JSON_EXTRACT_SCALAR(f['id'], '$.u64') AS BIGINT) AS event_id,
JSON_EXTRACT_SCALAR(f['pillar'], '$.vec[0].symbol') AS pillar
FROM ev WHERE ev_name = 'EventCreated'
FROM ev WHERE ev_name = 'event_created'
),
cancelled AS (
SELECT DISTINCT CAST(JSON_EXTRACT_SCALAR(f['id'], '$.u64') AS BIGINT) AS event_id
FROM ev WHERE ev_name = 'EventCancelled'
FROM ev WHERE ev_name = 'event_cancelled'
),
paid AS (
SELECT DISTINCT CAST(JSON_EXTRACT_SCALAR(f['event_id'], '$.u64') AS BIGINT) AS event_id
FROM ev WHERE ev_name IN ('WinnerPaid', 'MilestoneClaimed')
FROM ev WHERE ev_name IN ('winner_paid', 'milestone_claimed')
)
SELECT
c.pillar,
Expand Down
13 changes: 7 additions & 6 deletions docs/dune-queries/07_avg_size_and_ttp.sql
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
-- Boundless On-chain: Average budget and time-to-first-payout
-- Panel type: table / single numbers
--
-- Time-to-payout is measured to the first WinnerPaid/MilestoneClaimed. Under
-- the pull model, WinnerPaid fires when a winner claims (claim_prize), not at
-- select_winners, so this includes claim latency.
-- Time-to-payout is measured from event_created to the first
-- winner_paid / milestone_claimed. The contract pushes single-release
-- payouts inside select_winners (there is no separate claim step), so this
-- is creation -> winner selection, not claim latency.
-- Decoding: see 10_event_created_decode_test.sql.

WITH ev AS (
Expand All @@ -20,20 +21,20 @@ WITH ev AS (
WHERE contract_id = '{{CONTRACT_ADDRESS}}'
AND closed_at_date >= DATE '{{START_DATE}}'
AND JSON_EXTRACT_SCALAR(topics_decoded, '$[0].symbol')
IN ('EventCreated', 'WinnerPaid', 'MilestoneClaimed')
IN ('event_created', 'winner_paid', 'milestone_claimed')
),
created AS (
SELECT
CAST(JSON_EXTRACT_SCALAR(f['id'], '$.u64') AS BIGINT) AS event_id,
CAST(JSON_EXTRACT_SCALAR(f['total_budget'], '$.i128') AS DOUBLE) / 1e7 AS budget_display,
closed_at AS created_at
FROM ev WHERE ev_name = 'EventCreated'
FROM ev WHERE ev_name = 'event_created'
),
first_payout AS (
SELECT
CAST(JSON_EXTRACT_SCALAR(f['event_id'], '$.u64') AS BIGINT) AS event_id,
MIN(closed_at) AS first_paid_at
FROM ev WHERE ev_name IN ('WinnerPaid', 'MilestoneClaimed')
FROM ev WHERE ev_name IN ('winner_paid', 'milestone_claimed')
GROUP BY 1
)
SELECT
Expand Down
8 changes: 4 additions & 4 deletions docs/dune-queries/08_payout_by_token.sql
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
-- Boundless On-chain: Payout volume grouped by payment token
-- Panel type: table
--
-- Token address is on EventCreated (field 'token'); join to payout events by
-- Token address is on event_created (field 'token'); join to payout events by
-- event_id. Add a CASE map for readable token symbols.
-- Decoding: see 10_event_created_decode_test.sql.

Expand All @@ -18,19 +18,19 @@ WITH ev AS (
WHERE contract_id = '{{CONTRACT_ADDRESS}}'
AND closed_at_date >= DATE '{{START_DATE}}'
AND JSON_EXTRACT_SCALAR(topics_decoded, '$[0].symbol')
IN ('EventCreated', 'WinnerPaid', 'MilestoneClaimed')
IN ('event_created', 'winner_paid', 'milestone_claimed')
),
payouts AS (
SELECT
CAST(JSON_EXTRACT_SCALAR(f['event_id'], '$.u64') AS BIGINT) AS event_id,
CAST(JSON_EXTRACT_SCALAR(f['amount'], '$.i128') AS DOUBLE) / 1e7 AS amount_display
FROM ev WHERE ev_name IN ('WinnerPaid', 'MilestoneClaimed')
FROM ev WHERE ev_name IN ('winner_paid', 'milestone_claimed')
),
created AS (
SELECT
CAST(JSON_EXTRACT_SCALAR(f['id'], '$.u64') AS BIGINT) AS event_id,
JSON_EXTRACT_SCALAR(f['token'], '$.address') AS token_address
FROM ev WHERE ev_name = 'EventCreated'
FROM ev WHERE ev_name = 'event_created'
)
SELECT
c.token_address,
Expand Down
37 changes: 27 additions & 10 deletions docs/dune-queries/09_crowdfunding_contributions.sql
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
-- Boundless On-chain: Contribution inflows — daily volume
-- Boundless On-chain: Crowdfunding contribution inflows — daily volume
-- Panel type: line chart x=day y=total_contributed_display
--
-- FundsAdded fires for every add_funds call (crowdfunding contributions AND
-- partner top-ups on other pillars). To isolate crowdfunding, join event_id to
-- EventCreated where pillar = 'Crowdfunding'.
-- funds_added fires for every add_funds call (crowdfunding contributions AND
-- partner top-ups on other pillars). This query isolates crowdfunding by
-- joining each funds_added.event_id to event_created where pillar =
-- 'Crowdfunding'. For all-pillar contribution volume, drop the join.
-- Decoding: see 10_event_created_decode_test.sql.

WITH ev AS (
Expand All @@ -19,13 +20,29 @@ WITH ev AS (
FROM stellar.history_contract_events
WHERE contract_id = '{{CONTRACT_ADDRESS}}'
AND closed_at_date >= DATE '{{START_DATE}}'
AND JSON_EXTRACT_SCALAR(topics_decoded, '$[0].symbol') = 'FundsAdded'
AND JSON_EXTRACT_SCALAR(topics_decoded, '$[0].symbol') IN ('funds_added', 'event_created')
),
crowdfunding_events AS (
SELECT DISTINCT CAST(JSON_EXTRACT_SCALAR(f['id'], '$.u64') AS BIGINT) AS event_id
FROM ev
WHERE ev_name = 'event_created'
AND JSON_EXTRACT_SCALAR(f['pillar'], '$.vec[0].symbol') = 'Crowdfunding'
),
contributions AS (
SELECT
day,
CAST(JSON_EXTRACT_SCALAR(f['event_id'], '$.u64') AS BIGINT) AS event_id,
JSON_EXTRACT_SCALAR(f['contributor'], '$.address') AS contributor,
CAST(JSON_EXTRACT_SCALAR(f['amount'], '$.i128') AS DOUBLE) AS amount
FROM ev
WHERE ev_name = 'funds_added'
)
SELECT
day,
COUNT(*) AS contribution_count,
COUNT(DISTINCT JSON_EXTRACT_SCALAR(f['contributor'], '$.address')) AS unique_contributors,
SUM(CAST(JSON_EXTRACT_SCALAR(f['amount'], '$.i128') AS DOUBLE)) / 1e7 AS total_contributed_display
FROM ev
c.day,
COUNT(*) AS contribution_count,
COUNT(DISTINCT c.contributor) AS unique_contributors,
SUM(c.amount) / 1e7 AS total_contributed_display
FROM contributions c
JOIN crowdfunding_events cf ON c.event_id = cf.event_id
GROUP BY 1
ORDER BY 1 DESC
10 changes: 6 additions & 4 deletions docs/dune-queries/10_event_created_decode_test.sql
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
-- Boundless On-chain: EventCreated decode test
-- Boundless On-chain: event_created decode test
-- Run this FIRST to confirm the Dune pipeline decodes events for the contract.
--
-- Real stellar.history_contract_events shapes (verified against live data):
-- Real stellar.history_contract_events shapes (verified against live mainnet):
-- topics_decoded : JSON array of ScVal objects. Event name is at $[0].symbol
-- (e.g. [{"symbol":"EventCreated"}]), NOT $[0].
-- and is SNAKE_CASE — #[contractevent] lowercases the struct
-- name, so EventCreated is emitted as 'event_created',
-- WinnerPaid as 'winner_paid', etc. NOT PascalCase.
-- data_decoded : ScVal map — {"map":[{"key":{"symbol":"id"},"val":{"u64":"7"}}, ...]}.
-- Each field's value is wrapped by its ScVal type; there is no
-- flat $.id. We rebuild it into a MAP(field_name -> ScVal JSON)
Expand All @@ -28,7 +30,7 @@ WITH ev AS (
FROM stellar.history_contract_events
WHERE contract_id = '{{CONTRACT_ADDRESS}}'
AND closed_at_date >= DATE '{{START_DATE}}'
AND JSON_EXTRACT_SCALAR(topics_decoded, '$[0].symbol') = 'EventCreated'
AND JSON_EXTRACT_SCALAR(topics_decoded, '$[0].symbol') = 'event_created'
)
SELECT
CAST(JSON_EXTRACT_SCALAR(f['id'], '$.u64') AS BIGINT) AS event_id,
Expand Down
Loading