def __init__(self): ironbank = Contract("0xAB1c342C7bf5Ec5F02ADEA1c2270670bCa144CbB") markets = [Contract(market) for market in ironbank.getAllMarkets()] cdata = multicall_matrix(markets, ["symbol", "underlying", "decimals"]) underlying = [Contract(cdata[x]["underlying"]) for x in markets] data = multicall_matrix(underlying, ["symbol", "decimals"]) self.vaults = [ IronbankMarket( cdata[market]["symbol"], market, data[token]["symbol"], token, cdata[market]["decimals"], data[token]["decimals"], ) for market, token in zip(markets, underlying) ]
def describe(self, block=None) -> dict: vaults = self.active_vaults_at_block(block) contracts = [vault.vault for vault in vaults] results = multicall_matrix( contracts, ["totalSupply", "pool", "getPricePerFullShare", "balance"], block=block) output = defaultdict(dict) prices = Parallel(8, "threading")( delayed(magic.get_price)(vault.token, block=block) for vault in vaults) for vault, price in zip(vaults, prices): res = results[vault.vault] if res['getPricePerFullShare'] is None: continue output[vault.name] = { "total supply": res["totalSupply"] / vault.scale, "available balance": res["balance"] / vault.scale, "pooled balance": res["pool"] / vault.scale, "price per share": res['getPricePerFullShare'] / 1e18, "token price": price, "tvl": res["pool"] / vault.scale * price, "address": vault.vault, "version": "iearn", } return dict(output)
def vaults(self): markets = [ Contract(market) for market in self.ironbank.getAllMarkets() ] cdata = multicall_matrix(markets, ["symbol", "underlying", "decimals"]) underlying = [Contract(cdata[x]["underlying"]) for x in markets] data = multicall_matrix(underlying, ["symbol", "decimals"]) vaults = [ IronbankMarket( cdata[market]["symbol"], market, data[token]["symbol"], token, cdata[market]["decimals"], data[token]["decimals"], ) for market, token in zip(markets, underlying) ] logger.info('loaded %d ironbank markets', len(vaults)) return vaults
def describe(self, block=None): markets = self.active_vaults_at(block) blocks_per_year = 365 * 86400 / 15 contracts = [m.vault for m in markets] results = multicall_matrix( contracts, [ "exchangeRateCurrent", "getCash", "totalBorrows", "totalSupply", "totalReserves", "supplyRatePerBlock", "borrowRatePerBlock", ], block=block, ) prices = Parallel(8, "threading")( delayed(magic.get_price)(market.underlying, block=block) for market in markets) output = defaultdict(dict) for m, price in zip(markets, prices): res = results[m.vault] exchange_rate = res["exchangeRateCurrent"] * 10**(m.cdecimals - m.decimals - 18) for attr in ["getCash", "totalBorrows", "totalReserves"]: res[attr] /= 10**m.decimals tvl = (res["getCash"] + res["totalBorrows"] - res["totalReserves"]) * price supplied = res["getCash"] + res["totalBorrows"] - res[ "totalReserves"] ratio = res["totalBorrows"] / supplied if supplied != 0 else None output[m.name] = { "total supply": res["totalSupply"] / 10**m.cdecimals, "total cash": res["getCash"], "total supplied": supplied, "total borrows": res["totalBorrows"], "total reserves": res["totalReserves"], "exchange rate": exchange_rate, "token price": price * exchange_rate, "underlying price": price, "supply apy": res["supplyRatePerBlock"] / 1e18 * blocks_per_year, "borrow apy": res["borrowRatePerBlock"] / 1e18 * blocks_per_year, "utilization": ratio, "tvl": tvl, "address": m.vault, "version": "ib", } return dict(output)
def main(): yearn = Yearn(load_strategies=False) excluded = {"0xBa37B002AbaFDd8E89a1995dA52740bbC013D992"} resp = requests.get( "https://raw.githubusercontent.com/iearn-finance/yearn-assets/master/icons/aliases.json" ).json() aliases = {item["address"]: item for item in resp} tokens = [] for product in yearn.registries: vaults = [ item.vault for item in yearn.registries[product].vaults if str(item.vault) not in excluded ] metadata = multicall_matrix(vaults, ["name", "symbol", "decimals"]) for vault in vaults: tokens.append( TokenInfo( chainId=1, address=str(vault), name=aliases.get(str(vault), metadata[vault])["name"], decimals=metadata[vault]["decimals"], symbol=aliases.get(str(vault), metadata[vault])["symbol"], logoURI= f"https://raw.githubusercontent.com/yearn/yearn-assets/master/icons/tokens/{vault}/logo.svg", tags=[product], )) # remove token = bump major, add token = bump minor version = Version(major=0, minor=len(tokens), patch=0) deploy_blocks = { token.address: contract_creation_block(token.address) for token in tokens } tokens = sorted(tokens, key=lambda token: deploy_blocks[token.address]) timestamp = datetime.fromtimestamp( get_block_timestamp(max(deploy_blocks.values())), timezone.utc).isoformat() logo = "https://raw.githubusercontent.com/yearn/yearn-assets/master/icons/tokens/0x0bc529c00C6401aEF6D220BE8C6Ea1667F6Ad93e/logo.svg" print(f"{version=}\n{timestamp=}") tokenlist = TokenList("Yearn", timestamp, version, tokens, logoURI=logo) for token in tokenlist.tokens: assert len(token.symbol ) <= 20, f"{token.symbol} > 20 chars, uniswap is unhappy" path = Path("static/tokenlist.json") path.parent.mkdir(exist_ok=True) path.write_text(json.dumps(tokenlist.to_dict(), separators=(",", ":"))) print(f"saved to {path}")
def total_value_at(self, block=None): markets = self.active_vaults_at(block) data = multicall_matrix( [market.vault for market in markets], ["getCash", "totalBorrows", "totalReserves", "totalSupply"], block=block, ) prices = Parallel(8, "threading")( delayed(magic.get_price)(market.vault, block=block) for market in markets) results = [data[market.vault] for market in markets] return { # market.name: (res["getCash"] + res["totalBorrows"] - res["totalReserves"]) / 10 ** market.decimals * price market.name: res["totalSupply"] / 10**market.cdecimals * price for market, price, res in zip(markets, prices, results) }
def main(): yearn = Yearn(load_strategies=False) excluded = { "0xBa37B002AbaFDd8E89a1995dA52740bbC013D992", "0xe2F6b9773BF3A015E2aA70741Bde1498bdB9425b", "0xBFa4D8AA6d8a379aBFe7793399D3DdaCC5bBECBB", } resp = requests.get( "https://raw.githubusercontent.com/iearn-finance/yearn-assets/master/icons/aliases.json" ).json() aliases = {item["address"]: item for item in resp} tokens = [] # Token derived by products for product in yearn.registries: vaults = [ item.vault for item in yearn.registries[product].vaults if str(item.vault) not in excluded ] metadata = multicall_matrix(vaults, ["name", "symbol", "decimals"]) for vault in vaults: tokens.append( TokenInfo( chainId=1, address=str(vault), name=aliases.get(str(vault), metadata[vault])["name"], decimals=metadata[vault]["decimals"], symbol=aliases.get(str(vault), metadata[vault])["symbol"], logoURI= f"https://raw.githubusercontent.com/yearn/yearn-assets/master/icons/tokens/{vault}/logo.svg", tags=[product], )) # Token from special / side projects special = [ contract("0xD0660cD418a64a1d44E9214ad8e459324D8157f1") # WOOFY ] metadata = multicall_matrix(special, ["name", "symbol", "decimals"]) for token in special: tokens.append( TokenInfo( chainId=1, address=str(token), name=aliases.get(str(token), metadata[token])["name"], decimals=metadata[token]["decimals"], symbol=aliases.get(str(token), metadata[token])["symbol"], logoURI= f"https://raw.githubusercontent.com/yearn/yearn-assets/master/icons/tokens/{token}/logo.svg", tags=["special"], )) deploy_blocks = { token.address: contract_creation_block(token.address) for token in tokens } tokens = unique(tokens, key=lambda token: token.address) tokens = sorted(tokens, key=lambda token: deploy_blocks[token.address]) version = Version(major=1, minor=len(tokens), patch=0) timestamp = datetime.fromtimestamp( get_block_timestamp(max(deploy_blocks.values())), timezone.utc).isoformat() logo = "https://raw.githubusercontent.com/yearn/yearn-assets/master/icons/tokens/0x0bc529c00C6401aEF6D220BE8C6Ea1667F6Ad93e/logo.svg" print(f"{version=}\n{timestamp=}") tokenlist = TokenList("Yearn", timestamp, version, tokens, logoURI=logo) for token in tokenlist.tokens: assert len(token.symbol ) <= 20, f"{token.symbol} > 20 chars, uniswap is unhappy" path = Path("static/tokenlist.json") path.parent.mkdir(exist_ok=True) path.write_text(json.dumps(tokenlist.to_dict(), separators=(",", ":"))) print(f"saved to {path}")