def calculate_sett_balances(badger, name, currentBlock): console.log("Fetching {} sett balances".format(name)) sett = badger.getSett(name) underlyingToken = sett.address settType = ["", ""] if "uni" in name or "sushi" in name: settType[0] = "halfLP" if "crv" in name.lower() or name == "experimental.sushiIBbtcWbtc": settType[0] = "fullLP" if "badger" in name.lower() or "digg" in name.lower( ) or "eth" in name.lower(): settType[1] = "nonNative" else: settType[1] = "native" settBalances = fetch_sett_balances(name, underlyingToken.lower(), currentBlock) geyserBalances = {} creamBalances = {} if name not in NO_GEYSERS: geyserAddr = badger.getGeyser(name).address.lower() geyserEvents = fetch_geyser_events(geyserAddr, currentBlock) geyserBalances = calc_balances_from_geyser_events(geyserEvents) settBalances[geyserAddr] = 0 balances = {} for b in [settBalances, geyserBalances, creamBalances]: balances = dict(Counter(balances) + Counter(b)) # Get rid of blacklisted and negative balances for addr, balance in balances.items(): if addr in blacklist or balance < 0: del balances[addr] # Testing for peak address # balances["0x41671BA1abcbA387b9b2B752c205e22e916BE6e3".lower()] = 10000 userBalances = [ UserBalance(addr, bal, underlyingToken, settType) for addr, bal in balances.items() ] console.log("\n") return UserBalances(userBalances)
def calculate_sett_balances(badger, name, currentBlock): console.log("Fetching {} sett balances".format(name)) sett = badger.getSett(name) underlyingToken = sett.address settType = ["", ""] if "uni" in name or "sushi" in name: settType[0] = "halfLP" elif "crv" in name: settType[0] = "fullLP" if "badger" in name.lower() or "digg" in name.lower() or "eth" in name.lower(): settType[1] = "nonNative" else: settType[1] = "native" settBalances = fetch_sett_balances(name, underlyingToken.lower(), currentBlock) geyserBalances = {} creamBalances = {} # Digg doesn't have a geyser so we have to ignore it noGeysers = ["native.digg", "experimental.sushiIBbtcWbtc", "experimental.digg"] if name not in noGeysers: geyserAddr = badger.getGeyser(name).address.lower() geyserEvents = fetch_geyser_events(geyserAddr, currentBlock) geyserBalances = calc_balances_from_geyser_events(geyserEvents) settBalances[geyserAddr] = 0 balances = {} for b in [settBalances, geyserBalances, creamBalances]: balances = dict(Counter(balances) + Counter(b)) # Get rid of blacklisted and negative balances for addr, balance in balances.items(): if addr in blacklist or balance < 0: del balances[addr] userBalances = [ UserBalance(addr, bal, underlyingToken, settType) for addr, bal in balances.items() ] console.log("\n") return UserBalances(userBalances)
def combine_balances(balances): allBalances = UserBalances() for userBalances in balances: allBalances = allBalances + userBalances return allBalances
def badger_boost(badger, currentBlock): console.log("Calculating boost ...") allSetts = badger.sett_system.vaults diggSetts = UserBalances() badgerSetts = UserBalances() nonNativeSetts = UserBalances() boostInfo = {} for name, sett in allSetts.items(): if name in ["experimental.digg"]: continue balances = calculate_sett_balances(badger, name, currentBlock) balances = convert_balances_to_usd(sett, name, balances) if name in [ "native.uniDiggWbtc", "native.sushiDiggWbtc", "native.digg" ]: diggSetts = combine_balances([diggSetts, balances]) elif name in [ "native.badger", "native.uniBadgerWbtc", "native.sushiBadgerWbtc", ]: badgerSetts = combine_balances([badgerSetts, balances]) else: nonNativeSetts = combine_balances([nonNativeSetts, balances]) sharesPerFragment = badger.digg.logic.UFragments._sharesPerFragment() badger_wallet_balances, digg_wallet_balances, _ = fetch_wallet_balances( sharesPerFragment, currentBlock) console.log("{} Badger balances fetched, {} Digg balances fetched".format( len(badger_wallet_balances), len(digg_wallet_balances))) badger_wallet_balances = UserBalances([ UserBalance(addr, bal * prices[BADGER], BADGER) for addr, bal in badger_wallet_balances.items() ]) digg_wallet_balances = UserBalances([ UserBalance(addr, bal * prices[DIGG], DIGG) for addr, bal in digg_wallet_balances.items() ]) badgerSetts = filter_dust( combine_balances([badgerSetts, badger_wallet_balances])) diggSetts = filter_dust(combine_balances([diggSetts, digg_wallet_balances])) allAddresses = calc_union_addresses(diggSetts, badgerSetts, nonNativeSetts) console.log("Non native Setts before filter {}".format( len(nonNativeSetts))) nonNativeSetts = filter_dust(nonNativeSetts) console.log("Non native Setts after filter {}".format(len(nonNativeSetts))) console.log("Filtered balances < $1") console.log("{} addresses collected for boost calculation".format( len(allAddresses))) stakeRatiosList = [ calc_stake_ratio(addr, diggSetts, badgerSetts, nonNativeSetts) for addr in allAddresses ] stakeRatios = dict(zip(allAddresses, stakeRatiosList)) stakeRatios = OrderedDict( sorted(stakeRatios.items(), key=lambda t: t[1], reverse=True)) for addr in allAddresses: boostInfo[addr.lower()] = { "nativeBalance": 0, "nonNativeBalance": 0, "stakeRatio": 0, } for user in badgerSetts: boostInfo[user.address.lower()]["nativeBalance"] += user.balance for user in diggSetts: boostInfo[user.address.lower()]["nativeBalance"] += user.balance for user in nonNativeSetts: boostInfo[user.address.lower()]["nonNativeBalance"] += user.balance for addr, ratio in stakeRatios.items(): boostInfo[addr.lower()]["stakeRatio"] = ratio sortedNonNative = UserBalances( sorted( nonNativeSetts.userBalances.values(), key=lambda u: stakeRatios[u.address], reverse=True, )) nonNativeTotal = sortedNonNative.total_balance() percentageNonNative = {} for user in sortedNonNative: percentage = user.balance / nonNativeTotal percentageNonNative[user.address] = percentage cumulativePercentages = dict( zip(percentageNonNative.keys(), calc_cumulative(percentageNonNative.values()))) badgerBoost = dict( zip(cumulativePercentages.keys(), calc_boost(cumulativePercentages.values()))) for addr, boost in badgerBoost.items(): # Users with no stake ratio have a boost of 1 if stakeRatios[addr] == 0: badgerBoost[addr] = 1 console.log(len(badgerBoost)) return badgerBoost, boostInfo
def filter_dust(balances): return UserBalances(list(filter(lambda user: user.balance > 1, balances)))