Skip to content
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

fix uniswap trades #4699

Closed
wants to merge 15 commits into from
Closed

Conversation

markusbkoch
Copy link
Contributor

Swap events contain amounts in and out for both tokens 0 and 1, so we actually have two "swaps" in each event:

  • Token 0 in, token 1 out
  • Token 1 in, token 0 out

Most of the time, one of these swaps has empty/zero amounts, ie the trader is only swapping one token for another. However, there are some edge cases where both amounts for one of the tokens is non-zero, and both amounts for the other token are zero. eg 0x2643cc80871c4134704863b17f10901ea6d11646fc10162ff1fb504e7137c193, evt index 75

In other cases, both amounts for both tokens are non-zero eg 0x5afc81f74fbfca62c7d083cccbadd01158f65bfdb1f2c7fb24e4866c1d96e346, evt index 27

As this query shows, dex.trades only partially reflects the information present in the swap events mentioned above. This happens because the current implementation of uniswap_v2_ethereum_trades.sql assumes there is only one swap contained in the Swap event: if amount0Out == 0 the code assumes token 1 is being bought, else token 0 is being bought.

This PR addresses this limitation by extracting both swaps from the Swap event and discarding the "empty swap" that is present in the vast majority of cases.

While events like the ones in the transactions mentioned here are very much the exception, they can have significant impact in some analyses. For example, the data regarding the swap txn 0x2643cc... would lead to believe that the pool sold 50M USDC for 0 WETH when in reality the pool sold 50M USDC for 50.1M USDC.

cc @mendesfabio @viniabussafi @thetroyharris for comments/review

@dune-eng
Copy link

Workflow run id 6668424342 approved.

@dune-eng
Copy link

Workflow run id 6668424160 approved.

@dune-eng
Copy link

Workflow run id 6668508388 approved.

@dune-eng
Copy link

Workflow run id 6668508538 approved.

@dune-eng
Copy link

Workflow run id 6668625737 approved.

@dune-eng
Copy link

Workflow run id 6668625781 approved.

@markusbkoch markusbkoch marked this pull request as draft October 27, 2023 14:44
@dune-eng
Copy link

Workflow run id 6668715133 approved.

@dune-eng
Copy link

Workflow run id 6668715038 approved.

@dune-eng
Copy link

Workflow run id 6668740704 approved.

@dune-eng
Copy link

Workflow run id 6668740709 approved.

@jeff-dude
Copy link
Member

14:52:44  Database Error in test check_dex_seed_uniswap_v2_ethereum_trades_ethereum__uniswap__2 (models/uniswap/ethereum/uniswap_ethereum_schema.yml)
14:52:44    TrinoExternalError(type=EXTERNAL, name=DELTA_LAKE_INVALID_SCHEMA, message="Metadata not found in transaction log for test_data.dex_trades_seed", query_id=20[23](https://github.com/duneanalytics/spellbook/actions/runs/6668740709/job/18124984341?pr=4699#step:12:24)1027_145240_03630_p3atd)

this error means the seed file in dbt doesn't exist to run the test against. here are some helpful things to know in the setup:

  • the test is defined in the schema file, which is edited in this PR
  • the test is here, which calls a nested macro here. if you run dbt compile locally, that is the query which compiles based on params in the schema file passed in
  • the referenced seed file is here, which contains rows manually added in dev process to prove out the query outputs expected data

in order to force the seed to build, you can make a minor modification to the seed file in this PR for CI test to build it out for downstream usage. you can add a newline or some other similar dummy change, to force into PR. can you give that a shot, see if it gets past that error?

@jeff-dude
Copy link
Member

as for the change being made in the PR, that's an interesting find. my initial thought is to be a bit careful, as there are quite a few other spells which are forks of uniswap v2, that use the same logic. i'd imagine we want to universally update the logic in order to have dex.trades accurate downstream for all dex's that follow a similar pattern.

we are actually in the process of a dex.trades redesign, while using uniswap as the example starting point project. within that redesign, we are looking to build a macro for all spells which use the same logic as uniswap v2, that way code is handled in one spot for future maintenance like this.

i wonder if we wait to make changes there? here is the PR, for reference

@jeff-dude jeff-dude self-assigned this Nov 6, 2023
@jeff-dude jeff-dude added the WIP work in progress label Nov 6, 2023
Copy link

github-actions bot commented Nov 6, 2023

CLA Assistant Lite bot All contributors have signed the CLA ✍️ ✅

@dune-eng
Copy link

dune-eng commented Nov 6, 2023

Workflow run id 6775491831 approved.

@mendesfabio
Copy link
Contributor

I have read the CLA Document and I hereby sign the CLA

github-actions bot added a commit that referenced this pull request Nov 6, 2023
@dune-eng
Copy link

dune-eng commented Nov 6, 2023

Workflow run id 6775547224 approved.

@dune-eng
Copy link

dune-eng commented Nov 6, 2023

Workflow run id 6775547312 approved.

@mendesfabio
Copy link
Contributor

@jeff-dude thoughts on Error getting snapshot for tokens.erc20? I've seen someone on Discord saying it happens when a transaction from the seeds has a token that's not in tokens.erc20 - but I didn't add any, simply merged with main.

@jeff-dude
Copy link
Member

@jeff-dude thoughts on Error getting snapshot for tokens.erc20? I've seen someone on Discord saying it happens when a transaction from the seeds has a token that's not in tokens.erc20 - but I didn't add any, simply merged with main.

this may have been just bad timing, as prod is going through a refresh and you may have run into when that spell was being refreshed. lets try to simply rerun it first

@markusbkoch
Copy link
Contributor Author

Thanks for the input @jeff-dude. Although other projects are probably even less affected by this than uniswap is, I agree the suggestions here should be incorporated in #4533 (and/or #4730). I can submit PRs to those branches with the relevant changes, or we can wait until those are merged and only then incorporate the suggestions from this PR? Or did you have something else in mind?

@jeff-dude
Copy link
Member

jeff-dude commented Nov 8, 2023

Thanks for the input @jeff-dude. Although other projects are probably even less affected by this than uniswap is, I agree the suggestions here should be incorporated in #4533 (and/or #4730). I can submit PRs to those branches with the relevant changes, or we can wait until those are merged and only then incorporate the suggestions from this PR? Or did you have something else in mind?

the changes in #4533 will be in "beta" until the entire dex.trades lineage fits into this new format. the original uniswap models will stay as-is until overwritten with the new ones post-beta phase. is this issue pressing to fix, time-wise? if so, we can consider moving forward here in this PR.

edit:
if we do proceed, we should also make the same changes to the new uniswap macro(s) as needed. that PR will likely be merged v soon.

This reverts commit cee04c7.
@dune-eng
Copy link

dune-eng commented Nov 9, 2023

Workflow run id 6809310977 approved.

@dune-eng
Copy link

dune-eng commented Nov 9, 2023

Workflow run id 6809311103 approved.

@dune-eng
Copy link

dune-eng commented Nov 9, 2023

Workflow run id 6809441380 approved.

@dune-eng
Copy link

dune-eng commented Nov 9, 2023

Workflow run id 6809441508 approved.

@markusbkoch
Copy link
Contributor Author

the changes in 4533 will be in "beta" [...] is this issue pressing to fix, time-wise?

Yea, in that case I'd suggest going ahead with the fix as it impacts analyses like LVR computation which require knowledge of all tokens bought/sold by the pool

we should also make the same changes to the new uniswap macro(s) as needed

Agreed. And to #4730 too (cc @0xBoxer). Let me know how you guys would like to coordinate on that front

@markusbkoch markusbkoch marked this pull request as ready for review November 9, 2023 09:25
@markusbkoch
Copy link
Contributor Author

@jeff-dude just wanted to confirm when this is merged will the changes propagate to all queries/spells that depend on this, like dex.trades? Or will the changes by default only be applied to new data as it comes in?

@jeff-dude
Copy link
Member

@jeff-dude just wanted to confirm when this is merged will the changes propagate to all queries/spells that depend on this, like dex.trades? Or will the changes by default only be applied to new data as it comes in?

yes, anything downstream will be refreshed along with these

@@ -5,7 +5,7 @@
materialized = 'incremental',
file_format = 'delta',
incremental_strategy = 'merge',
unique_key = ['block_date', 'blockchain', 'project', 'version', 'tx_hash', 'evt_index'],
unique_key = ['block_date', 'blockchain', 'project', 'version', 'tx_hash', 'evt_index', 'token_bought_address', 'token_sold_address'],
Copy link
Member

Choose a reason for hiding this comment

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

adding two new unique keys is concerning, as we use the exact same set of unique keys in all projects that feed into dex.trades and it has worked well universally. why are we adding two more here?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is needed because this new implementation potentially decodes the swap event into two records - token0 for token1 and token1 for token0. See failed checks right before this commit for more context.

An alternative approach would be to aggregate those two records into a single one, but it would make the code quite a bit more complex/verbose (we'd have to figure out what is the token sold/bought based on the net amounts in/out of tokens 0/1) and potentially cause issues with negative values (still need to confirm this), so that's the tradeoff

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It does seem that the alternative approach I mentioned would result in negative values. Here's an example of an unusual swap event (index 128) :

amount0In : 659774361155999
amount1In : 250390
amount0Out : 100000355
amount1Out : 0

The net amounts are such that the pool's balance of both tokens increases. An heuristic that tried to infer the tokens sold/bought would result in both tokens as token_sold (ie sold by the trader to the pool). Still unclear to me why this happens, but I assume it's something along the lines of someone having transferred token0 to the pool before the actual trade occurred, and the Swap event just catching up with the state.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I've added the two new keys to the dex.trades schema in 1b9c1fb

@jeff-dude
Copy link
Member

can you rebase with main branch & pull in the new uniswap macro for dex redesign, make same changes there?

@jeff-dude jeff-dude added the in review Assignee is currently reviewing the PR label Nov 15, 2023
@dune-eng
Copy link

Workflow run id 6901624651 approved.

@dune-eng
Copy link

Workflow run id 6901625001 approved.

@dune-eng
Copy link

Workflow run id 6901840923 approved.

@dune-eng
Copy link

Workflow run id 6901841044 approved.

@dune-eng
Copy link

Workflow run id 6901908334 approved.

@dune-eng
Copy link

Workflow run id 6901908775 approved.

@markusbkoch
Copy link
Contributor Author

can you rebase with main branch & pull in the new uniswap macro for dex redesign, make same changes there?

8559930, should be ready for review

@jeff-dude jeff-dude linked an issue Nov 17, 2023 that may be closed by this pull request
@jeff-dude
Copy link
Member

@markusbkoch thanks again for raising this issue. i think this has a larger impact across spellbook than anticipated, so i've linked a gh issue which outlines the bug found. let's focus conversation there until we come to an agreement, then we can revisit this PR and finalize.

@jeff-dude jeff-dude closed this Apr 7, 2024
@github-actions github-actions bot locked and limited conversation to collaborators Apr 7, 2024
@mendesfabio mendesfabio deleted the fix-univ2-trades branch April 12, 2024 09:40
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
in review Assignee is currently reviewing the PR WIP work in progress
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[BUG] uniswap v2 missing swaps
4 participants