mirrorprice fix
This commit is contained in:
@@ -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)
|
||||
|
||||
|
||||
|
||||
@@ -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')
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user