Skip to content

Add files to connect monad into balancerv3 dex#9302

Merged
jeff-dude merged 14 commits intoduneanalytics:mainfrom
gustavobftorres:add-monad-to-balancerv3
Mar 4, 2026
Merged

Add files to connect monad into balancerv3 dex#9302
jeff-dude merged 14 commits intoduneanalytics:mainfrom
gustavobftorres:add-monad-to-balancerv3

Conversation

@gustavobftorres
Copy link
Copy Markdown
Contributor

Thank you for contributing to Spellbook 🪄

Please open the PR in draft and mark as ready when you want to request a review.

Description:

Add files to connect monad into Balancer V3


quick links for more information:

@github-actions github-actions Bot marked this pull request as draft February 10, 2026 17:50
@github-actions github-actions Bot added WIP work in progress dbt: dex covers the DEX dbt subproject labels Feb 10, 2026
@gustavobftorres gustavobftorres marked this pull request as ready for review February 20, 2026 18:55
@github-actions github-actions Bot added ready-for-review this PR development is complete, please review and removed WIP work in progress labels Feb 20, 2026
@jeff-dude jeff-dude self-assigned this Mar 2, 2026
@jeff-dude jeff-dude added in review Assignee is currently reviewing the PR and removed ready-for-review this PR development is complete, please review labels Mar 2, 2026
gustavobftorres and others added 2 commits March 2, 2026 22:25
…els_balancer_v3_pools_monad.sql

Co-authored-by: jeff-dude <102681548+jeff-dude@users.noreply.github.com>
…ancer_v3_monad_trades.sql

Co-authored-by: jeff-dude <102681548+jeff-dude@users.noreply.github.com>
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Mar 3, 2026

📝 Walkthrough

Walkthrough

This pull request introduces Monad blockchain support to the Balancer DEX models in dbt. It adds new model definitions, SQL implementations, and source configurations for Balancer v3 pools labels, pool fees, and trade data on the Monad network, while updating existing aggregation models to include these new data sources.

Changes

Cohort / File(s) Summary
Balancer Pools Labels
dbt_subprojects/dex/models/_projects/balancer/labels/_schema.yml, dbt_subprojects/dex/models/_projects/balancer/labels/labels_balancer_v3_pools.sql, dbt_subprojects/dex/models/_projects/balancer/labels/monad/labels_balancer_v3_pools_monad.sql
Added schema definition and new SQL model for Balancer v3 pools labels on Monad. Updated contributor metadata for existing pools model. New model constructs pool metadata with token data, symbols, and derived naming conventions.
Balancer Pools Fees
dbt_subprojects/dex/models/_projects/balancer/pools/_schema.yml, dbt_subprojects/dex/models/_projects/balancer/pools/balancer_pools_fees.sql, dbt_subprojects/dex/models/_projects/balancer/pools/monad/balancer_v3_monad_pools_fees.sql
Added schema definition and new incremental SQL model for Balancer v3 pool fees on Monad. Updated base model with column definitions. New model processes swap fee percentage change events.
Balancer Trades Base Layer
dbt_subprojects/dex/models/trades/monad/_schema.yml, dbt_subprojects/dex/models/trades/monad/dex_monad_base_trades.sql, dbt_subprojects/dex/models/trades/monad/platforms/balancer_v3_monad_base_trades.sql
Added schema definition and base trade model for Balancer v3 on Monad. New incremental model delegates to balancer_compatible_v3_trades macro. Updated aggregation model to include new base source.
Balancer Trades Aggregation
dbt_subprojects/dex/models/_projects/balancer/trades/balancer_trades.sql, dbt_subprojects/dex/models/_projects/balancer/trades/monad/_schema.yml, dbt_subprojects/dex/models/_projects/balancer/trades/monad/balancer_monad_trades.sql, dbt_subprojects/dex/models/_projects/balancer/trades/monad/balancer_v3_monad_trades.sql
Added schema definitions and new SQL models for Monad trades aggregation. Includes base trades consolidation model and detailed trades model with complex multi-CTE logic for price calculations and token enrichment. Updated parent trades model to include new monad trades source.
Monad Source Definitions
sources/_subprojects_outputs/dex/_sources.yml, sources/balancer/monad/balancer_monad_sources.yml
Added source definitions for Balancer v3 Monad data. Includes entries for trades tables and pool sources, plus comprehensive list of Monad-specific events and calls from various Balancer contracts.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~22 minutes

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 inconclusive)

Check name Status Explanation Resolution
Description check ❓ Inconclusive The PR description is minimal and mostly reuses the template boilerplate. While it mentions the core objective (adding monad to Balancer V3), it lacks substantive detail about what was added, why, or how to test the changes. Expand the description with details on which monad-specific models/files were added, any breaking changes, testing approach, and expected impact on downstream consumers.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main change: adding files to integrate monad into the Balancer V3 dex, which aligns with the changeset's primary objective.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


Comment @coderabbitai help to get the list of available commands and usage tips.

@gustavobftorres
Copy link
Copy Markdown
Contributor Author

Thanks for the suggestions, pushing fixes

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (1)
dbt_subprojects/dex/models/_projects/balancer/trades/monad/balancer_v3_monad_trades.sql (1)

51-57: Consider adding block_date to join/filter for partition pruning.

The join with dexs_base and the WHERE clause filter on blockchain, project, and version, but not on block_date. For large tables, including the partition column improves query performance.

This is a performance optimization, not a blocking issue.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@dbt_subprojects/dex/models/_projects/balancer/trades/monad/balancer_v3_monad_trades.sql`
around lines 51 - 57, The query should include the partition column block_date
in the join and/or WHERE so partition pruning can occur; update the JOIN between
dexs (from {{ ref('dex_trades') }}) and dexs_base to also match on
dexs.block_date = dexs_base.block_date and add a WHERE filter referencing
dexs.block_date (or a block_date range) alongside blockchain/project/version to
constrain scanned partitions and improve performance.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In
`@dbt_subprojects/dex/models/_projects/balancer/labels/monad/labels_balancer_v3_pools_monad.sql`:
- Around line 7-158: The final SELECT uses bytearray_substring(pool_id, 1, 20)
AS address without grouping or aggregating it and also contains bare column
references; fix by computing address earlier and/or including it in the GROUP BY
and fully qualifying columns. Concretely: in the derived subquery that is
aliased as s (the SELECT from settings / s1), add address:
bytearray_substring(s1.pool_id,1,20) AS address, and then change the outer
SELECT to reference s.address and fully qualify all columns (e.g.,
s.pool_symbol, s.pool_type, s.token_symbol, s.norm_weight, s.pool_id) and
include s.address in the GROUP BY (or aggregate it consistently). Update any
other bare column usages to use their table alias (settings, s1, pools, etc.).

In
`@dbt_subprojects/dex/models/_projects/balancer/trades/monad/balancer_monad_trades.sql`:
- Around line 12-49: The selected columns in the loop are currently unqualified;
update the inner FROM to use an explicit table alias (e.g., FROM {{ dex_model }}
AS t) and prefix every selected column with that alias (t.blockchain, t.project,
t.version, t.block_month, etc.) inside the SELECT within the balancer_models
loop so all columns are fully qualified per the DuneSQL guideline.

---

Nitpick comments:
In
`@dbt_subprojects/dex/models/_projects/balancer/trades/monad/balancer_v3_monad_trades.sql`:
- Around line 51-57: The query should include the partition column block_date in
the join and/or WHERE so partition pruning can occur; update the JOIN between
dexs (from {{ ref('dex_trades') }}) and dexs_base to also match on
dexs.block_date = dexs_base.block_date and add a WHERE filter referencing
dexs.block_date (or a block_date range) alongside blockchain/project/version to
constrain scanned partitions and improve performance.

ℹ️ Review info

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 77ab0ab and a4423e4.

⛔ Files ignored due to path filters (1)
  • dbt_subprojects/dex/seeds/trades/balancer_monad_base_trades_seed.csv is excluded by !**/*.csv
📒 Files selected for processing (15)
  • dbt_subprojects/dex/models/_projects/balancer/labels/_schema.yml
  • dbt_subprojects/dex/models/_projects/balancer/labels/labels_balancer_v3_pools.sql
  • dbt_subprojects/dex/models/_projects/balancer/labels/monad/labels_balancer_v3_pools_monad.sql
  • dbt_subprojects/dex/models/_projects/balancer/pools/_schema.yml
  • dbt_subprojects/dex/models/_projects/balancer/pools/balancer_pools_fees.sql
  • dbt_subprojects/dex/models/_projects/balancer/pools/monad/balancer_v3_monad_pools_fees.sql
  • dbt_subprojects/dex/models/_projects/balancer/trades/balancer_trades.sql
  • dbt_subprojects/dex/models/_projects/balancer/trades/monad/_schema.yml
  • dbt_subprojects/dex/models/_projects/balancer/trades/monad/balancer_monad_trades.sql
  • dbt_subprojects/dex/models/_projects/balancer/trades/monad/balancer_v3_monad_trades.sql
  • dbt_subprojects/dex/models/trades/monad/_schema.yml
  • dbt_subprojects/dex/models/trades/monad/dex_monad_base_trades.sql
  • dbt_subprojects/dex/models/trades/monad/platforms/balancer_v3_monad_base_trades.sql
  • sources/_subprojects_outputs/dex/_sources.yml
  • sources/balancer/monad/balancer_monad_sources.yml

Comment on lines +7 to +158
WITH token_data AS (
SELECT
pool,
ARRAY_AGG(FROM_HEX(json_extract_scalar(token, '$.token')) ORDER BY token_index) AS tokens
FROM (
SELECT
pool,
tokenConfig,
SEQUENCE(1, CARDINALITY(tokenConfig)) AS token_index_array
FROM {{ source('balancer_v3_monad', 'Vault_evt_PoolRegistered') }}
) AS pool_data
CROSS JOIN UNNEST(tokenConfig, token_index_array) AS t(token, token_index)
GROUP BY 1
),

pools AS (
SELECT
pool_id,
zip.tokens AS token_address,
zip.weights / POWER(10, 18) AS normalized_weight,
symbol,
pool_type
FROM (
SELECT
c.pool AS pool_id,
t.tokens,
w.weights,
cc.symbol,
'weighted' AS pool_type
FROM token_data c
INNER JOIN {{ source('balancer_v3_monad', 'WeightedPoolFactory_call_create') }} cc
ON c.pool = cc.output_pool
CROSS JOIN UNNEST(c.tokens) WITH ORDINALITY t(tokens, pos)
CROSS JOIN UNNEST(cc.normalizedWeights) WITH ORDINALITY w(weights, pos)
WHERE t.pos = w.pos

UNION ALL

SELECT
c.pool AS pool_id,
t.tokens,
0 AS weights,
cc.symbol,
'stable' AS pool_type
FROM token_data c
INNER JOIN {{ source('balancer_v3_monad', 'StablePoolFactory_call_create') }} cc
ON c.pool = cc.output_pool
CROSS JOIN UNNEST(c.tokens) AS t(tokens)

UNION ALL

SELECT
c.pool AS pool_id,
t.tokens,
0 AS weights,
cc.symbol,
'stable' AS pool_type
FROM token_data c
INNER JOIN {{ source('balancer_v3_monad', 'StableSurgePoolFactory_call_create') }} cc
ON c.pool = cc.output_pool
CROSS JOIN UNNEST(c.tokens) AS t(tokens)

UNION ALL

SELECT
c.pool AS pool_id,
t.tokens,
0 AS weights,
cast(null as varchar) AS symbol,
'LBP' AS pool_type
FROM token_data c
INNER JOIN {{ source('balancer_v3_monad', 'LBPoolFactory_call_create') }} cc
ON c.pool = cc.output_pool
CROSS JOIN UNNEST(c.tokens) AS t(tokens)

UNION ALL

SELECT
c.pool AS pool_id,
t.tokens AS token_address,
0 AS normalized_weight,
cc.symbol,
'ECLP' AS pool_type
FROM token_data c
INNER JOIN {{ source('balancer_v3_monad', 'GyroECLPPoolFactory_call_create') }} cc
ON c.pool = cc.output_pool
CROSS JOIN UNNEST(c.tokens) AS t(tokens)
) zip
),

pool_token_symbols AS (
SELECT
p.pool_id,
p.pool_type,
coalesce(t.symbol, '?') AS token_symbol
FROM pools p
LEFT JOIN {{ source('tokens', 'erc20') }} t ON p.token_address = t.contract_address
AND t.blockchain = 'monad'
),

pool_symbols_derived AS (
SELECT
pool_id,
pool_type,
lower(array_join(array_agg(token_symbol ORDER BY token_symbol), '/')) AS derived_pool_symbol
FROM pool_token_symbols
WHERE pool_type = 'LBP'
GROUP BY pool_id, pool_type
),

settings AS (
SELECT
p.pool_id,
coalesce(t.symbol, '?') AS token_symbol,
p.normalized_weight,
coalesce(p.symbol, ps.derived_pool_symbol) AS pool_symbol,
p.pool_type
FROM pools p
LEFT JOIN {{ source('tokens', 'erc20') }} t ON p.token_address = t.contract_address
AND t.blockchain = 'monad'
LEFT JOIN pool_symbols_derived ps ON p.pool_id = ps.pool_id AND p.pool_type = ps.pool_type
)

SELECT
'monad' AS blockchain,
bytearray_substring(pool_id, 1, 20) AS address,
CASE WHEN pool_type IN ('stable', 'LBP', 'ECLP')
THEN lower(pool_symbol)
ELSE lower(concat(array_join(array_agg(token_symbol ORDER BY token_symbol), '/'), ' ',
array_join(array_agg(cast(norm_weight AS varchar) ORDER BY token_symbol), '/')))
END AS name,
pool_type,
'balancer_v3_pool' AS category,
'balancerlabs' AS contributor,
'query' AS source,
TIMESTAMP'2024-12-01 00:00' AS created_at,
now() AS updated_at,
'balancer_v3_pools_monad' AS model_name,
'identifier' AS label_type

FROM (
SELECT
s1.pool_id,
token_symbol,
pool_symbol,
cast(100 * normalized_weight AS integer) AS norm_weight,
pool_type
FROM settings s1
GROUP BY s1.pool_id, token_symbol, pool_symbol, normalized_weight, pool_type
) s
GROUP BY pool_id, pool_symbol, pool_type
ORDER BY 1 No newline at end of file
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

Fix aggregation error: address expression isn’t in GROUP BY (will fail compilation).

In the final SELECT, bytearray_substring(pool_id, 1, 20) AS address is selected but not aggregated and not included in the GROUP BY (Line 132 vs Line 157). Trino/DuneSQL will reject this.

Also, this new model uses many bare column references without table aliases; please align it to the project SQL guideline (explicit aliases + prefixed columns) before merging.

Proposed fix (minimal) to make GROUP BY valid
 SELECT 
   'monad' AS blockchain,
-  bytearray_substring(pool_id, 1, 20) AS address,
+  bytearray_substring(pool_id, 1, 20) AS address,
   CASE WHEN pool_type IN ('stable', 'LBP', 'ECLP') 
   THEN lower(pool_symbol)
     ELSE lower(concat(array_join(array_agg(token_symbol ORDER BY token_symbol), '/'), ' ', 
     array_join(array_agg(cast(norm_weight AS varchar) ORDER BY token_symbol), '/')))
   END AS name,
   pool_type,
   'balancer_v3_pool' AS category,
   'balancerlabs' AS contributor,
   'query' AS source,
   TIMESTAMP'2024-12-01 00:00' AS created_at,
   now() AS updated_at,
   'balancer_v3_pools_monad' AS model_name,
   'identifier' AS label_type
@@
 ) s
-GROUP BY pool_id, pool_symbol, pool_type
+GROUP BY
+  pool_id,
+  bytearray_substring(pool_id, 1, 20),
+  pool_symbol,
+  pool_type
 ORDER BY 1

As per coding guidelines, “Always use explicit table aliases — prefix all columns (t.column, p.column), never use bare column names in DuneSQL/Trino SQL”.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@dbt_subprojects/dex/models/_projects/balancer/labels/monad/labels_balancer_v3_pools_monad.sql`
around lines 7 - 158, The final SELECT uses bytearray_substring(pool_id, 1, 20)
AS address without grouping or aggregating it and also contains bare column
references; fix by computing address earlier and/or including it in the GROUP BY
and fully qualifying columns. Concretely: in the derived subquery that is
aliased as s (the SELECT from settings / s1), add address:
bytearray_substring(s1.pool_id,1,20) AS address, and then change the outer
SELECT to reference s.address and fully qualify all columns (e.g.,
s.pool_symbol, s.pool_type, s.token_symbol, s.norm_weight, s.pool_id) and
include s.address in the GROUP BY (or aggregate it consistently). Update any
other bare column usages to use their table alias (settings, s1, pools, etc.).

Comment on lines +12 to +49
SELECT *
FROM (
{% for dex_model in balancer_models %}
SELECT
blockchain,
project,
version,
block_month,
block_date,
block_time,
block_number,
token_bought_symbol,
token_sold_symbol,
token_pair,
token_bought_amount,
token_sold_amount,
token_bought_amount_raw,
token_sold_amount_raw,
amount_usd,
token_bought_address,
token_sold_address,
taker,
maker,
pool_id,
swap_fee,
project_contract_address,
pool_symbol,
pool_type,
tx_hash,
tx_from,
tx_to,
evt_index
FROM {{ dex_model }}
{% if not loop.last %}
UNION ALL
{% endif %}
{% endfor %}
)
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

New SQL model: add a table alias and prefix selected columns (guideline requirement).

Right now the SELECT projects bare column names from {{ dex_model }}; please alias the FROM and prefix (t.blockchain, etc.) to match the repo’s DuneSQL guideline.

Proposed fix (mechanical aliasing)
 SELECT *
 FROM (
     {% for dex_model in balancer_models %}
     SELECT
-        blockchain,
-        project,
-        version,
-        block_month,
-        block_date,
-        block_time,
-        block_number,
-        token_bought_symbol,
-        token_sold_symbol,
-        token_pair,
-        token_bought_amount,
-        token_sold_amount,
-        token_bought_amount_raw,
-        token_sold_amount_raw,
-        amount_usd,
-        token_bought_address,
-        token_sold_address,
-        taker,
-        maker,
-        pool_id,
-        swap_fee,
-        project_contract_address,
-        pool_symbol,
-        pool_type,
-        tx_hash,
-        tx_from,
-        tx_to,
-        evt_index
-    FROM {{ dex_model }}
+        t.blockchain,
+        t.project,
+        t.version,
+        t.block_month,
+        t.block_date,
+        t.block_time,
+        t.block_number,
+        t.token_bought_symbol,
+        t.token_sold_symbol,
+        t.token_pair,
+        t.token_bought_amount,
+        t.token_sold_amount,
+        t.token_bought_amount_raw,
+        t.token_sold_amount_raw,
+        t.amount_usd,
+        t.token_bought_address,
+        t.token_sold_address,
+        t.taker,
+        t.maker,
+        t.pool_id,
+        t.swap_fee,
+        t.project_contract_address,
+        t.pool_symbol,
+        t.pool_type,
+        t.tx_hash,
+        t.tx_from,
+        t.tx_to,
+        t.evt_index
+    FROM {{ dex_model }} t
     {% if not loop.last %}
     UNION ALL
     {% endif %}
     {% endfor %}
 )

As per coding guidelines, “Always use explicit table aliases — prefix all columns (t.column, p.column), never use bare column names in DuneSQL/Trino SQL”.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@dbt_subprojects/dex/models/_projects/balancer/trades/monad/balancer_monad_trades.sql`
around lines 12 - 49, The selected columns in the loop are currently
unqualified; update the inner FROM to use an explicit table alias (e.g., FROM {{
dex_model }} AS t) and prefix every selected column with that alias
(t.blockchain, t.project, t.version, t.block_month, etc.) inside the SELECT
within the balancer_models loop so all columns are fully qualified per the
DuneSQL guideline.

@jeff-dude jeff-dude added ready-for-merging and removed in review Assignee is currently reviewing the PR labels Mar 3, 2026
@jeff-dude jeff-dude merged commit d612561 into duneanalytics:main Mar 4, 2026
4 checks passed
@github-actions github-actions Bot locked and limited conversation to collaborators Mar 4, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

dbt: dex covers the DEX dbt subproject ready-for-merging

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants