def update_price_gauge(coingecko_price_gauge, token_prices, token_name, token_address, countertoken_csv): lp_prefixes = ("uni", "slp", "crv", "cake") try: if not token_name.startswith(lp_prefixes): log.info( f"Processing CoinGecko price for [bold]{token_name}: {token_address} ..." ) price = token_prices[token_address.lower()] for countertoken in countertoken_csv.split(","): coingecko_price_gauge.labels( "ETH" if token_name == "WETH" else "BNB" if token_name == "WBNB" else token_name, countertoken, token_address, ).set(price[countertoken]) usd_prices_by_token_address[token_address] = price["usd"] else: log.info( f"Skipping CoinGecko price for [bold]{token_name}: {token_address} ..." ) except Exception as e: log.warning( f"Error getting CoinGecko price for [bold]{token_name}: {token_address}" ) log.debug(e)
def update_sett_gauge(sett_gauge, sett): sett_name = sett.name sett_address = sett_vaults[sett_name] sett_token_name = sett_name[1:] sett_token_address = treasury_tokens[re.sub("harvest", "", sett_token_name)] sett_info = sett.describe() log.info(f"Processing Sett data for [bold]{sett.name}: {sett_address} ...") for param, value in sett_info.items(): sett_gauge.labels(sett_name, param, sett_address, sett_token_name).set(value) try: usd_prices_by_token_address[sett_address] = ( sett_info["pricePerShare"] * usd_prices_by_token_address[sett_token_address]) sett_gauge.labels(sett_name, "usdBalance", sett_address, sett_token_name).set( usd_prices_by_token_address[sett_address] * sett_info["balance"]) except Exception as e: log.warning(f"Error calculating USD price for Sett [bold]{sett_name}") log.debug(e)
def _fetch_events_for_all_contracts(web3, event, argument_filters: dict, from_block: int, to_block: int) -> Iterable: """Get events using eth_getLoggers API. This method is detached from any contract instance. This is a stateless method, as opposed to createFilter. It can be safely called against nodes which do not provide `eth_newFilter` API, like Infura. """ if from_block is None: raise TypeError( "Missing mandatory keyword argument to getLoggers: fromBlock") # Currently no way to poke this using a public Web3.py API. # This will return raw underlying ABI JSON object for the event abi = event._get_event_abi() # Depending on the Solidity version used to compile # the contract that uses the ABI, # it might have Solidity ABI encoding v1 or v2. # We just assume the default that you set on Web3 object here. # More information here https://eth-abi.readthedocs.io/en/latest/index.html codec: ABICodec = web3.codec # Here we need to poke a bit into Web3 internals, as this # functionality is not exposed by default. # Construct JSON-RPC raw filter presentation based on human readable Python descriptions # Namely, convert event names to their keccak signatures # More information here: # https://github.com/ethereum/web3.py/blob/e176ce0793dafdd0573acc8d4b76425b6eb604ca/web3/_utils/filters.py#L71 data_filter_set, event_filter_params = construct_event_filter_params( abi, codec, address=argument_filters.get("address"), argument_filters=argument_filters, fromBlock=from_block, toBlock=to_block, ) logger.debug("Querying eth_getLoggers with the following parameters: %s", event_filter_params) # Call JSON-RPC API on your Ethereum node. # get_logs() returns raw AttributedDict entries logs = web3.eth.getLogs(event_filter_params) # Convert raw binary data to Python proxy objects as described by ABI all_events = [] for log in logs: # Convert raw JSON-RPC log result to human readable event by using ABI data # More information how processLog works here # https://github.com/ethereum/web3.py/blob/fbaf1ad11b0c7fac09ba34baff2c256cffe0a148/web3/_utils/events.py#L200 evt = get_event_data(codec, abi, log) # Note: This was originally yield, # but deferring the timeout exception caused the throttle logic not to work all_events.append(evt) return all_events
def describe(self): try: info = { "lastPublishTimestamp": self.badger_tree.lastPublishTimestamp(), } except ValueError as e: info = {} log.exception(e) log.debug(e) return info
def describe(self): scale = 10**self.token.decimals() try: info = { "treasuryBalance": self.token.balanceOf(treasury_address) / scale } except ValueError as e: info = {} log.exception(e) log.debug(e) return info
def describe(self): try: info = { "lastUpdated": self.oracle.providerReports(self.oracle_provider, 1)[0], "oraclePrice": self.oracle.providerReports(self.oracle_provider, 1)[1] / 1e18, } except ValueError as e: info = {} log.exception(e) log.debug(e) return info
def describe(self): scale = 10**self.sett.decimals() try: info = { "pricePerShare": self.sett.getPricePerFullShare() / scale, "totalSupply": self.sett.totalSupply() / scale, "balance": self.sett.balance() / scale, "available": self.sett.available() / scale, } except ValueError as e: info = {} log.exception(e) log.debug(e) return info
def describe(self): scale = 10**self.token.decimals() try: info = [{ "tokenName": self.name, "tokenAddress": self.token.address, "tokenBalance": self.token.balanceOf(wallet_address) / scale, "walletName": wallet_name, "walletAddress": wallet_address, } for wallet_name, wallet_address in self.wallets.items()] except ValueError as e: info = [] log.exception(e) log.debug(e) return info
def describe(self): scale = 10**self.token.decimals() try: info = { "token0": self.token.token0(), "token1": self.token.token1(), "token0_reserve": self.token.getReserves()[0], "token1_reserve": self.token.getReserves()[1], "totalSupply": self.token.totalSupply(), "decimals": self.token.decimals(), } except ValueError as e: info = {} log.exception(e) log.debug(e) return info
def update_wallets_gauge(wallets_gauge, wallet_balances_by_token, token_name, token_address): log.info( f"Processing wallet balances for [bold]{token_name}: {token_address} ..." ) wallet_info = wallet_balances_by_token[token_address] for wallet in wallet_info.describe(): ( token_name, token_address, token_balance, wallet_name, wallet_address, ) = wallet.values() eth_balance = float( w3.fromWei(w3.eth.getBalance(wallet_address), "ether")) wallets_gauge.labels(wallet_name, wallet_address, token_name, token_address, "balance").set(token_balance) wallets_gauge.labels(wallet_name, wallet_address, "ETH", "None", "balance").set(eth_balance) try: wallets_gauge.labels( wallet_name, wallet_address, token_name, token_address, "usdBalance").set(token_balance * usd_prices_by_token_address[token_address]) wallets_gauge.labels( wallet_name, wallet_address, "ETH", "none", "usdBalance").set( eth_balance * usd_prices_by_token_address[treasury_tokens["WETH"]]) except Exception as e: log.warning( f"Error calculating USD balances for wallet [bold]{wallet_name}" ) log.debug(e)
def update_lp_tokens_gauge(lp_tokens_gauge, lp_token, token_interfaces): lp_name = lp_token.name lp_address = lp_tokens[lp_name] log.info( f"Processing lpToken reserves for [bold]{lp_name}: {lp_address} ...") lp_info = lp_token.describe() lp_scale = 10**lp_info["decimals"] lp_supply = lp_info["totalSupply"] token0_address = lp_info["token0"] token1_address = lp_info["token1"] token0 = token_interfaces[token0_address] token1 = token_interfaces[token1_address] token0_reserve = lp_info["token0_reserve"] token1_reserve = lp_info["token1_reserve"] token0_scale = 10**token0.decimals() token1_scale = 10**token1.decimals() lp_tokens_gauge.labels(lp_name, f"{token0.symbol()}_supply", lp_address).set(token0_reserve / token0_scale) lp_tokens_gauge.labels(lp_name, f"{token1.symbol()}_supply", lp_address).set(token1_reserve / token1_scale) lp_tokens_gauge.labels(lp_name, "totalLpTokenSupply", lp_address).set(lp_supply / lp_scale) try: price = (((token1_reserve / token1_scale) / (lp_supply / lp_scale)) * usd_prices_by_token_address[token1_address] * 2) usd_prices_by_token_address[lp_address] = price lp_tokens_gauge.labels(lp_name, "usdPricePerShare", lp_address).set(price) except Exception as e: log.warning(f"Error calculating USD price for lpToken [bold]{lp_name}") log.debug(e)
def update_tokens(tx_hash, tx_transfer, tokens): token_addr = tx_transfer["address"] try: transfer_from = Web3.toChecksumAddress(tx_transfer["args"]["_from"]) transfer_to = Web3.toChecksumAddress(tx_transfer["args"]["_to"]) transfer_value = tx_transfer["args"]["_value"] / DECIMALS except EventLookupError: transfer_from = Web3.toChecksumAddress["args"](tx_transfer["from"]) transfer_to = Web3.toChecksumAddress(tx_transfer["args"]["to"]) transfer_value = tx_transfer["args"]["value"] / DECIMALS if ( token_addr == ADDRESSES["renBTC"] and transfer_from == ADDRESSES["zero"] and transfer_to == ADDRESSES["bridge_v2"] ): tokens["ren_minted"] += transfer_value elif ( token_addr == ADDRESSES["renBTC"] and transfer_from == ADDRESSES["bridge_v2"] and transfer_to == ADDRESSES["zero"] ): tokens["ren_burned"] += transfer_value elif ( token_addr == ADDRESSES["renBTC"] and transfer_from != ADDRESSES["zero"] and transfer_from != ADDRESSES["unk_curve_1"] and transfer_to == ADDRESSES["bridge_v2"] ): tokens["ren_received"] += transfer_value elif ( token_addr == ADDRESSES["renBTC"] and transfer_from == ADDRESSES["unk_curve_1"] and transfer_to == ADDRESSES["bridge_v2"] ): tokens["ren_bought"] += transfer_value elif ( token_addr == ADDRESSES["renBTC"] and transfer_from == ADDRESSES["bridge_v2"] and transfer_to != ADDRESSES["badger_multisig"] and transfer_to != ADDRESSES["badger_bridge_team"] and transfer_to != ADDRESSES["unk_curve_2"] and transfer_to != ADDRESSES["zero"] ): tokens["ren_sent"] += transfer_value elif ( token_addr == ADDRESSES["WBTC"] and transfer_from != ADDRESSES["zero"] and transfer_from != ADDRESSES["unk_curve_1"] and transfer_to == ADDRESSES["bridge_v2"] ): tokens["wbtc_received"] += transfer_value elif ( token_addr == ADDRESSES["WBTC"] and transfer_from == ADDRESSES["bridge_v2"] and transfer_to != ADDRESSES["badger_multisig"] and transfer_to != ADDRESSES["unk_curve_2"] and transfer_to != ADDRESSES["badger_bridge_team"] and transfer_to != ADDRESSES["zero"] ): tokens["wbtc_sent"] += transfer_value elif ( token_addr == ADDRESSES["renBTC"] and transfer_from == ADDRESSES["bridge_v2"] and transfer_to == ADDRESSES["badger_multisig"] ): tokens["fee_badger"] += transfer_value elif ( token_addr == ADDRESSES["renBTC"] and transfer_from == ADDRESSES["bridge_v2"] and transfer_to == ADDRESSES["badger_bridge_team"] ): tokens["fee_renvm"] += transfer_value elif ( token_addr == ADDRESSES["WBTC"] and transfer_from == ADDRESSES["unk_curve_1"] and transfer_to == ADDRESSES["bridge_v2"] ): # WBTC; unk_curve_1 -> bridge -> EOA logger.debug( f"Transaction partial match, unk_curve_1: token {token_addr}, from {transfer_from}, to {transfer_to} value {transfer_value}, hash {tx_hash}\n" ) return tokens elif ( token_addr == ADDRESSES["WBTC"] and transfer_from == ADDRESSES["bridge_v2"] and transfer_to == ADDRESSES["unk_curve_2"] ): # WBTC; EOA -> bridge -> unk_curve_2 -> unk_curve_1 logger.debug( f"Transaction partial match, unk_curve_2: token {token_addr}, from {transfer_from}, to {transfer_to} value {transfer_value}, hash {tx_hash}\n" ) return tokens else: logger.debug( f"Transaction unmatched: token {token_addr}, from {transfer_from}, to {transfer_to} value {transfer_value}, hash {tx_hash}\n" ) return tokens logger.debug( f"Transaction matched: token {token_addr}, from {transfer_from}, to {transfer_to} value {transfer_value}, hash {tx_hash}\n" ) return tokens