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

feat: improved estimate_price_impact helper function; added factory contract for V3 #202

Merged
merged 4 commits into from
Nov 29, 2021

Conversation

liquid-8
Copy link
Member

@liquid-8 liquid-8 commented Nov 13, 2021

Test code (12 ETH to VXV):

address = None
private_key = None
version = 3
provider = "http://127.0.0.1:8545"
uniswap = Uniswap(address=address, private_key=private_key, version=version, provider=provider)

impact = uniswap.estimate_price_impact("0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2","0x7D29A64504629172a429e64183D6673b9dAcbFCe", 1*10**18, 500)
print("12 ETH to VXV @ V3 (0.05pct fee pool): " + str(impact))
impact = uniswap.estimate_price_impact("0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2","0x7D29A64504629172a429e64183D6673b9dAcbFCe", 12*10**18, 3000)
print("12 ETH to VXV @ V3 (0.3pct fee pool): " + str(impact))
impact = uniswap.estimate_price_impact("0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2","0x7D29A64504629172a429e64183D6673b9dAcbFCe", 12*10**18, 10000)
print("12 ETH to VXV @ V3 (1pct fee pool): " + str(impact))

uniswap2 = Uniswap(address=address, private_key=private_key, version=2, provider=provider)
impact = uniswap2.estimate_price_impact("0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2","0x7D29A64504629172a429e64183D6673b9dAcbFCe", 12*10**18)
print("12 ETH to VXV @ V2: " + str(impact))

Output:

12 ETH to VXV @ V3 (0.05pct fee pool): 1
12 ETH to VXV @ V3 (0.3pct fee pool): 1
12 ETH to VXV @ V3 (1pct fee pool): 0.03539237568834554
12 ETH to VXV @ V2: 0.9994777989075329

It is easy to see that there is the only a proper pool (UniV3 1% fee). Impact equal to 1 basically means that pool doesn't exist or has exact 0 liquidity. Also, this method works for direct pools only as it is not trivial to trace all pools' liquidity in the case of multihop.

@liquid-8
Copy link
Member Author

@ErikBjare ^^

Copy link
Member

@ErikBjare ErikBjare left a comment

Choose a reason for hiding this comment

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

Very nice! Just a couple things to fix

den0 = self.get_token(token_out).decimals
den1 = self.get_token(token_in).decimals
sqrtPriceX96 = pool_contract.functions.slot0().call()[0]
raw_price = (sqrtPriceX96*sqrtPriceX96*10**den1>>(96*2))/(10**den0)
Copy link
Member

Choose a reason for hiding this comment

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

Wow, awesome work figuring this out! (I've been meaning to...)

Copy link
Member Author

@liquid-8 liquid-8 Nov 17, 2021

Choose a reason for hiding this comment

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

It's a kind of magic. Long story short
https://ethereum.stackexchange.com/questions/98685/computing-the-uniswap-v3-pair-price-from-q64-96-number
But I have to notice that mentioned snippet works correctly only if both tokens have decimals == 18 that is wrong in the general case. It needs to determine actual values. Also, if we need this price for ETH-USDC pair but pool.token0==USDC and pool.token1==ETH then we need to use denominators in reverse order. That's why it requires this ugly if-else just before the calculation.
Also, the final impact value differs a bit from uniswap's one. Delta is ~0.0x% I suppose they apply the taker's fee somewhere. I don't need absolute precision in my tasks (and I really doubt someone needs it in this particular case) so I've just omitted that fact in my own realization.
Regarding other comments - sure, I'll make a fix.

uniswap/uniswap.py Outdated Show resolved Hide resolved
uniswap/uniswap.py Outdated Show resolved Hide resolved
uniswap/uniswap.py Show resolved Hide resolved
@ErikBjare
Copy link
Member

Sorry for the delay. Looks like the typechecking fails, but gonna go ahead and merge this anyway.

@ErikBjare ErikBjare changed the title feat: improved estimate_price_impact helper function; added factory contract for V3. feat: improved estimate_price_impact helper function; added factory contract for V3 Nov 29, 2021
@ErikBjare ErikBjare merged commit d13ffc4 into uniswap-python:master Nov 29, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants