-
Notifications
You must be signed in to change notification settings - Fork 1.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
How to handle multiple input and output tokens in a single atomic transactions in dex.trades? #5402
Comments
is #5393 related? if not, can you provide the query used to build odos trades? |
@jeff-dude It is not related. |
approved this one, that looks good to me. i can merge if you want.
can you provide the example dune query which processes these multi-swap events? |
Jeff @jeff-dude, thank you! |
Hi @jeff-dude, here is the query and the result WITH
zipped_input_tokens AS (
SELECT
evt_tx_hash,
evt_block_time,
t.inputAmount,
t2.inputToken,
erc20.symbol AS symbol,
COALESCE(
(t.inputAmount / power(10, erc20.decimals)), 0
) AS human_amount,
COALESCE(
(t.inputAmount / power(10, erc20.decimals)) * p.price, 0
) AS amount_usd
FROM
odos_v2_optimism.OdosRouterV2_evt_SwapMulti
CROSS JOIN UNNEST(amountsIn) WITH ORDINALITY as t(inputAmount, i)
CROSS JOIN UNNEST(
TRANSFORM( -- WETH
tokensIn, element -> IF(element = 0x0000000000000000000000000000000000000000, 0x4200000000000000000000000000000000000006, element)
)
) WITH ORDINALITY as t2(inputToken, i)
LEFT JOIN "delta_prod"."tokens"."erc20" erc20
ON erc20.contract_address = t2.inputToken
AND erc20.blockchain = 'optimism'
LEFT JOIN "delta_prod"."prices"."usd" p
ON p.minute = date_trunc('minute', evt_block_time)
AND p.contract_address = t2.inputToken
AND p.blockchain = 'optimism'
WHERE t.i = t2.i
),
concat_input_tokens AS (
SELECT
evt_tx_hash,
ARRAY_JOIN(ARRAY_AGG(symbol), ' + ') AS concat_input_tokens,
ARRAY_JOIN(ARRAY_AGG(human_amount), ', ') AS concat_input_human_amounts,
SUM(amount_usd) AS usd_input_amount
FROM zipped_input_tokens
GROUP BY evt_tx_hash
),
zipped_output_tokens AS (
SELECT
evt_tx_hash,
evt_block_time,
t3.outputAmount,
t4.outputToken,
erc20.symbol AS symbol,
COALESCE(
(t3.outputAmount / power(10, erc20.decimals)), 0
) AS human_amount,
COALESCE(
(t3.outputAmount / power(10, erc20.decimals)) * p.price, 0
) AS amount_usd
FROM
odos_v2_optimism.OdosRouterV2_evt_SwapMulti
CROSS JOIN UNNEST(amountsOut) WITH ORDINALITY as t3(outputAmount, i)
CROSS JOIN UNNEST(
TRANSFORM( -- WETH
tokensOut, element -> IF(element = 0x0000000000000000000000000000000000000000, 0x4200000000000000000000000000000000000006, element)
)
) WITH ORDINALITY AS t4(outputToken, i)
LEFT JOIN "delta_prod"."tokens"."erc20" erc20
ON erc20.contract_address = t4.outputToken
AND erc20.blockchain = 'optimism'
LEFT JOIN "delta_prod"."prices"."usd" p
ON p.minute = date_trunc('minute', evt_block_time)
AND p.contract_address = t4.outputToken
AND p.blockchain = 'optimism'
WHERE t3.i = t4.i
),
concat_output_tokens AS (
SELECT
evt_tx_hash,
ARRAY_JOIN(ARRAY_AGG(symbol), ' + ') AS concat_output_tokens,
ARRAY_JOIN(ARRAY_AGG(human_amount), ', ') AS concat_output_human_amounts,
SUM(amount_usd) AS usd_output_amount
FROM zipped_output_tokens
GROUP BY evt_tx_hash
)
SELECT concat_input_tokens, concat_output_tokens, usd_input_amount FROM
concat_input_tokens t1
LEFT JOIN concat_output_tokens t2
ON t1.evt_tx_hash = t2.evt_tx_hash
WHERE t1.evt_tx_hash = 0x6b129e9945914ae89038f317a18bdaa283eadc2144062a7243ce19a7de763ba7 |
this one is merged. i'm assuming the "single swap" event spells are intended to populate if |
@jeff-dude Thank you, Jeff! |
@jeff-dude Any ideas on how we could put the multi token swaps into the |
let me quickly take a look at your provided query |
two quick thoughts:
the logic in that spell simply pulls
i'm by no means an aggregator expert, so just trying to understand it all 😅 |
|
condensing into one row breaks the table level of granularity. that introduces some risk relative to other projects that already build the table out. i did some searching around. there are a few other contracts with
however, none are used in spellbook at this time. we won't find spell examples for that exact event type. i looked into a few dex project spells which populate i compiled that spell into a query, found an example
this transaction had 4 tokens sold in the event, then output 4 rows with one per token sold. within the logic, a will this approach work for you? |
@jeff-dude thanks for sharing this. Such approach doesn't work for Odos unfortunately, because Odos can process N input tokens and M output tokens (e.g. 4 input and 3 output) and in this case there is no good way to record such a transaction with multiple rows. Any other ways to put those trades? |
got it. i'm not sure how we should process and store these events to be honest. let me bring this back to the internal team for opinion. here are a few thoughts:
|
Thank you, @jeff-dude |
Hi @jeff-dude |
thank you for the patience. at the moment, we aren't comfortable modifying the design of the table structure to fit this unique use case. i would suggest two options:
|
Hi @jeff-dude
There also should be an additional table e.g. MultiTokenTrades which contains the fields above, but in form of arrays:
This way we don't break the existing dex_aggregator.trades table, have the |
as long as you populate the unique keys, this should be fine. maybe for symbols / token pair, it's a bit more formatted (still varchar, but looks like array for readability): i think the big question comes down to how do you calculate
should be fine here too. ensure lowercase and underscore naming standard, but same idea ( |
Odos allows users to swap multiple input and multiple output tokens in a single atomic transaction. And it becomes a challenge when we want to put such trades to the dex.trades table.
We definitely can calculate the
amount_usd
field, but what can we do with the following fields when there is more than one input or output token?I see the following options:
symbol fields:
amount fields:
token fields:
The text was updated successfully, but these errors were encountered: