mirrorprice fix

This commit is contained in:
Tim
2024-03-15 18:20:11 -04:00
parent c95115dd38
commit b4c85955e9
3 changed files with 77 additions and 17 deletions

View File

@@ -3,18 +3,73 @@ import logging
import os
import sys
from dexorder import config, blockchain
from dexorder import config, blockchain, current_w3
from dexorder.bin.executable import execute
from dexorder.blockchain.connection import create_w3
from dexorder.blockstate import current_blockstate
from dexorder.blockstate.state import FinalizedBlockState
from dexorder.contract import get_deployment_address, ContractProxy
from dexorder.contract import get_deployment_address, ContractProxy, ERC20
from dexorder.metadata import generate_metadata
from dexorder.pools import get_pool
from dexorder.tokens import get_token
from dexorder.uniswap import UniswapV3Pool
from dexorder.util.async_util import maywait
log = logging.getLogger('dexorder')
_token_infos = {}
source_w3 = None
def use_source(func):
async def wrapper(*args, **kwargs):
old_w3 = current_w3.get()
current_w3.set(source_w3)
result = await func(*args, **kwargs)
current_w3.set(old_w3)
return result
return wrapper
@use_source
async def get_token_info( token ):
# struct TokenInfo {
# IERC20Metadata addr;
# string name;
# string symbol;
# uint8 decimals;
# }
token = await maywait(token)
if token not in _token_infos:
t = ERC20(token)
name, symbol, decimals = await asyncio.gather(t.name(), t.symbol(), t.decimals())
_token_infos[token] = [token, name, symbol, decimals]
return _token_infos[token]
@use_source
async def get_pool_price(pool):
slot0 = await UniswapV3Pool(pool).slot0()
return slot0[0]
@use_source
async def get_pool_info( pool ):
# struct PoolInfo {
# IUniswapV3Pool pool;
# TokenInfo token0;
# TokenInfo token1;
# uint24 fee;
# uint160 sqrtPriceX96;
# uint256 amount0;
# uint256 amount1;
# }
p = UniswapV3Pool(pool)
t0, t1 = await asyncio.gather(get_token_info(p.token0()), get_token_info(p.token1()))
amount0, amount1, (price,*_), fee = \
await asyncio.gather(ERC20(t0[0]).balanceOf(pool), ERC20(t1[0]).balanceOf(pool), p.slot0(), p.fee())
return [pool, t0, t1, fee, price, amount0, amount1]
async def write_metadata( pools, mirror_pools ):
filename = config.mirror_metadata
if filename is None:
@@ -37,6 +92,11 @@ async def await_mirror(tx, pool_addr, mirror_addr, mirror_inverted ):
async def main():
if config.mirror_source_rpc_url is None:
log.error('Must configure mirror_source_rpc_url')
return
global source_w3
source_w3 = await create_w3(config.mirror_source_rpc_url)
pools = (config.mirror_pools or [])
if not pools:
log.error('must configure mirror_pools')
@@ -56,12 +116,11 @@ async def main():
return
log.info(f'Initializing with MirrorEnv {mirror_addr}')
mirrorenv = ContractProxy(mirror_addr, 'MirrorEnv')
proms = []
log.debug(f'Mirroring pools {", ".join(pools)}')
pool_infos = await asyncio.gather(*[get_pool_info(pool) for pool in pools])
tx = await mirrorenv.transact.mirrorPools(pool_infos)
await tx.wait()
mirror_pools = []
for pool in pools:
log.debug(f'Mirroring pool {pool}')
proms.append(await mirrorenv.transact.mirrorPool(pool))
await asyncio.gather(*[p.wait() for p in proms])
for pool in pools:
mirror_addr, mirror_inverted = await mirrorenv.pools(pool)
log.debug(f'\tmirror result {mirror_addr} {mirror_inverted}')
@@ -70,18 +129,12 @@ async def main():
delay = config.polling if config.polling > 0 else 1
log.info(f'Mirroring pools every {delay} seconds')
while True:
proms = []
for pool_addr, (mirror_addr, mirror_inverted) in zip(pools, mirror_pools):
try:
log.info(f'mirroring {pool_addr}')
tx = await mirrorenv.transact.updatePool(pool_addr)
proms.append((tx, pool_addr, mirror_addr, mirror_inverted))
except Exception as x:
log.exception(x)
prices = await asyncio.gather(*[get_pool_price(pool) for pool in pools])
try:
await asyncio.gather(*[await_mirror(*args) for args in proms], return_exceptions=True)
await mirrorenv.transact.updatePools(list(zip(pools,prices)))
except Exception as x:
log.exception(x)
log.debug('Mirrored'+''.join(f'\n\t{pool} {price}' for pool, price in zip(pools,prices)))
await asyncio.sleep(delay)

View File

@@ -31,6 +31,7 @@ class Config:
walker_flush_interval: float = 300
mirror_source_rpc_url: Optional[str] = None # source RPC for original pools
mirror_env: Optional[str] = None
mirror_pools: Optional[list[str]] = field(default_factory=list)
mirror_metadata: str = field(default='metadata.json')

View File

@@ -122,7 +122,13 @@ class ContractProxy:
return ContractProxy(self.address, self._interface_name, _contracts=self._contracts, _wrapper=build_wrapper, abi=self._abi)
def __getattr__(self, item):
return self._wrapper(self.contract.constructor if item == 'constructor' else self.contract.functions[item])
if item == 'constructor':
found = self.contract.constructor
elif item in self.contract.functions:
found = self.contract.functions[item]
else:
raise AttributeError(item)
return self._wrapper(found)
def __repr__(self):
addr = self.contract.address