mirrorprice fix
This commit is contained in:
@@ -3,18 +3,73 @@ import logging
|
|||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
from dexorder import config, blockchain
|
from dexorder import config, blockchain, current_w3
|
||||||
from dexorder.bin.executable import execute
|
from dexorder.bin.executable import execute
|
||||||
|
from dexorder.blockchain.connection import create_w3
|
||||||
from dexorder.blockstate import current_blockstate
|
from dexorder.blockstate import current_blockstate
|
||||||
from dexorder.blockstate.state import FinalizedBlockState
|
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.metadata import generate_metadata
|
||||||
from dexorder.pools import get_pool
|
from dexorder.pools import get_pool
|
||||||
from dexorder.tokens import get_token
|
from dexorder.tokens import get_token
|
||||||
|
from dexorder.uniswap import UniswapV3Pool
|
||||||
|
from dexorder.util.async_util import maywait
|
||||||
|
|
||||||
log = logging.getLogger('dexorder')
|
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 ):
|
async def write_metadata( pools, mirror_pools ):
|
||||||
filename = config.mirror_metadata
|
filename = config.mirror_metadata
|
||||||
if filename is None:
|
if filename is None:
|
||||||
@@ -37,6 +92,11 @@ async def await_mirror(tx, pool_addr, mirror_addr, mirror_inverted ):
|
|||||||
|
|
||||||
|
|
||||||
async def main():
|
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 [])
|
pools = (config.mirror_pools or [])
|
||||||
if not pools:
|
if not pools:
|
||||||
log.error('must configure mirror_pools')
|
log.error('must configure mirror_pools')
|
||||||
@@ -56,12 +116,11 @@ async def main():
|
|||||||
return
|
return
|
||||||
log.info(f'Initializing with MirrorEnv {mirror_addr}')
|
log.info(f'Initializing with MirrorEnv {mirror_addr}')
|
||||||
mirrorenv = ContractProxy(mirror_addr, 'MirrorEnv')
|
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 = []
|
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:
|
for pool in pools:
|
||||||
mirror_addr, mirror_inverted = await mirrorenv.pools(pool)
|
mirror_addr, mirror_inverted = await mirrorenv.pools(pool)
|
||||||
log.debug(f'\tmirror result {mirror_addr} {mirror_inverted}')
|
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
|
delay = config.polling if config.polling > 0 else 1
|
||||||
log.info(f'Mirroring pools every {delay} seconds')
|
log.info(f'Mirroring pools every {delay} seconds')
|
||||||
while True:
|
while True:
|
||||||
proms = []
|
prices = await asyncio.gather(*[get_pool_price(pool) for pool in pools])
|
||||||
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)
|
|
||||||
try:
|
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:
|
except Exception as x:
|
||||||
log.exception(x)
|
log.exception(x)
|
||||||
|
log.debug('Mirrored'+''.join(f'\n\t{pool} {price}' for pool, price in zip(pools,prices)))
|
||||||
await asyncio.sleep(delay)
|
await asyncio.sleep(delay)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ class Config:
|
|||||||
|
|
||||||
walker_flush_interval: float = 300
|
walker_flush_interval: float = 300
|
||||||
|
|
||||||
|
mirror_source_rpc_url: Optional[str] = None # source RPC for original pools
|
||||||
mirror_env: Optional[str] = None
|
mirror_env: Optional[str] = None
|
||||||
mirror_pools: Optional[list[str]] = field(default_factory=list)
|
mirror_pools: Optional[list[str]] = field(default_factory=list)
|
||||||
mirror_metadata: str = field(default='metadata.json')
|
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)
|
return ContractProxy(self.address, self._interface_name, _contracts=self._contracts, _wrapper=build_wrapper, abi=self._abi)
|
||||||
|
|
||||||
def __getattr__(self, item):
|
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):
|
def __repr__(self):
|
||||||
addr = self.contract.address
|
addr = self.contract.address
|
||||||
|
|||||||
Reference in New Issue
Block a user