def combine_rewards(rewardsList, cycle, badgerTree):
    combinedRewards = RewardsList(cycle, badgerTree)
    for rewards in rewardsList:
        for user, claims in rewards.claims.items():
            for token, claim in claims.items():
                combinedRewards.increase_user_rewards(user, token, claim)
    return combinedRewards
Exemple #2
0
def process_rewards(badger, events, name, nextCycle, token):
    totalFromEvents = sum([int(e["rewardAmount"]) for e in events]) / 1e18
    rewards = RewardsList(nextCycle, badger.badgerTree)
    total = 0
    for event in events:
        userState = calc_meta_farm_rewards(badger, name, event["blockNumber"])
        totalBalance = sum([u.balance for u in userState])
        total += int(event["rewardAmount"])
        console.log("{} total {} processed".format(total / 1e18, token))
        rewardsUnit = int(event["rewardAmount"]) / totalBalance
        for user in userState:
            rewards.increase_user_rewards(
                web3.toChecksumAddress(user.address),
                web3.toChecksumAddress(token),
                rewardsUnit * user.balance,
            )

    totalFromRewards = sum(
        [list(v.values())[0] / 1e18 for v in list(rewards.claims.values())])
    rewardsLog.add_total_token_dist(name, token, totalFromRewards)
    # Calc diff of rewardsTotal and add assertion for checking rewards
    rewardsDiff = abs(totalFromRewards - totalFromRewards) * 1e18
    console.log(
        "Total from Rewards: {} \nTotal from Events: {}\n Diff: {}".format(
            totalFromRewards, totalFromEvents, rewardsDiff))
    if abs(totalFromEvents - totalFromRewards) > 100000:
        assert False, "Incorrect total rewards"

    return rewards
Exemple #3
0
def rewards_to_merkle_tree(rewards: RewardsList, startBlock, endBlock,
                           geyserRewards):
    (nodes, encodedNodes, entries) = rewards.to_merkle_format()

    # For each user, encode their data into a node

    # Put the nodes into a tree

    # elements = [(index, account, amount) for index, (account, amount) in enumerate(rewards.items())]
    # nodes = [encode_hex(encode_abi_packed(['uint', 'address', 'uint'], el)) for el in elements]
    """
    'claims': {
            user: {'index': index, 'amount': hex(amount), 'proof': tree.get_proof(nodes[index])}
            for index, user, amount in elements
        },
    """
    tree = MerkleTree(encodedNodes)
    distribution = {
        "merkleRoot": encode_hex(tree.root),
        "cycle": nodes[0]["cycle"],
        "startBlock": str(startBlock),
        "endBlock": str(endBlock),
        "tokenTotals": rewards.totals.toDict(),
        "claims": {},
        "metadata": {},
    }

    for entry in entries:
        node = entry["node"]
        encoded = entry["encoded"]
        # console.log(node)
        distribution["claims"][node["user"]] = {
            "index": hex(node["index"]),
            "user": node["user"],
            "cycle": hex(node["cycle"]),
            "tokens": node["tokens"],
            "cumulativeAmounts": node["cumulativeAmounts"],
            "proof": tree.get_proof(encodedNodes[node["index"]]),
            "node": encoded,
        }
    if len(geyserRewards) > 0:
        for user, data in geyserRewards.metadata.items():
            distribution["metadata"][user] = data.toDict()

    print(f"merkle root: {encode_hex(tree.root)}")

    # Print to file with content hash
    # hash(distribution)

    # console.log(distribution)

    return distribution
Exemple #4
0
def process_rewards(badger, startBlock, endBlock, events, name, nextCycle,
                    token):
    endBlock = int(events[0]["blockNumber"])
    totalFromEvents = sum([int(e["rewardAmount"]) for e in events]) / 1e18
    rewards = RewardsList(nextCycle, badger.badgerTree)
    total = 0
    for i in tqdm(range(len(events))):
        event = events[i]
        userState = calc_meta_farm_rewards(badger, name, startBlock, endBlock)
        totalBalance = sum([u.balance for u in userState])
        total += int(event["rewardAmount"])
        console.log("{} total {} processed".format(total / 1e18, token))
        rewardsUnit = int(event["rewardAmount"]) / totalBalance
        for addr, balance in userState.items():
            rewards.increase_user_rewards(
                web3.toChecksumAddress(addr),
                web3.toChecksumAddress(token),
                rewardsUnit * user,
            )

        if i + 1 < len(events):
            startBlock = int(events[i]["blockNumber"])
            endBlock = int(events[i + 1]["blockNumber"])

    totalFromRewards = sum(
        [list(v.values())[0] / 1e18 for v in list(rewards.claims.values())])

    # Calc diff of rewardsTotal and add assertion for checking rewards
    rewardsDiff = abs(totalFromRewards - totalFromRewards) * 1e18
    console.log(
        "Total from Rewards: {} \nTotal from Events: {}\n Diff: {}".format(
            totalFromRewards, totalFromEvents, rewardsDiff))
    if abs(totalFromEvents - totalFromRewards) > 100000:
        assert False, "Incorrect total rewards"

    distr = {}
    distr[token] = totalFromRewards
    rewardsLog.add_distribution_info(name, distr)
    return rewards
Exemple #5
0
def calc_rewards(badger, start, end, nextCycle, events, name, token):
    def filter_events(e):
        return int(e["blockNumber"]) > start and int(e["blockNumber"]) < end

    filteredEvents = list(filter(filter_events, events))
    rewards = RewardsList(nextCycle, badger.badgerTree)
    if len(filteredEvents) > 0:
        console.log(filteredEvents)
        console.log("{} events to process for {}".format(
            len(filteredEvents), name))
        rewards = process_rewards(badger, filteredEvents, name, nextCycle,
                                  token)
    else:
        console.log("No events to process for {}".format(name))
    return rewards
Exemple #6
0
def calc_rewards(badger, start, end, nextCycle, events, name, token,
                 retroactive, retroactiveStart):
    def filter_events(e):
        return int(e["blockNumber"]) > start and int(e["blockNumber"]) < end

    filteredEvents = list(filter(filter_events, events))
    rewards = RewardsList(nextCycle, badger.badgerTree)
    if len(filteredEvents) > 0:
        console.log(filteredEvents)
        console.log("{} events to process for {}".format(
            len(filteredEvents), name))
        startBlock = get_latest_event_block(filteredEvents[0], events)
        if retroactive:
            startBlock = retroactiveStart
        rewards = process_rewards(badger, startBlock, end, filteredEvents,
                                  name, nextCycle, token)
    else:
        console.log("No events to process")
    return rewards
def process_cumulative_rewards(current, new: RewardsList):
    result = RewardsList(new.cycle, new.badgerTree)

    # Add new rewards
    for user, claims in new.claims.items():
        for token, claim in claims.items():
            result.increase_user_rewards(user, token, claim)

    # Add existing rewards
    for user, userData in current["claims"].items():
        for i in range(len(userData["tokens"])):
            token = userData["tokens"][i]
            amount = userData["cumulativeAmounts"][i]
            result.increase_user_rewards(user, token, int(amount))

    # result.printState()
    return result
def sum_rewards(sources, cycle, badgerTree):
    """
    Sum rewards from all given set of rewards' list, returning a single rewards list
    """
    totals = RewardsList(cycle, badgerTree)
    total = 0
    # For each rewards list entry
    for key, rewardsSet in sources.items():
        # Get the claims data
        claims = rewardsSet["claims"]
        metadata = rewardsSet["metadata"]

        # Add values from each user
        for user, userData in claims.items():
            totals.track_user_metadata(user, metadata)

            # For each token
            for token, tokenAmount in userData.items():
                totals.increase_user_rewards(user, token, tokenAmount)

                total += tokenAmount
    totals.badgerSum = total
    # totals.printState()
    return totals
def calc_snapshot(
    badger, name, startBlock, endBlock, nextCycle, boosts, unclaimedBalances
):
    digg = interface.IDigg(DIGG)

    console.log("==== Processing rewards for {} at {} ====".format(name, endBlock))

    rewards = RewardsList(nextCycle, badger.badgerTree)

    sett = badger.getSett(name)
    startTime = web3.eth.getBlock(startBlock)["timestamp"]

    endTime = web3.eth.getBlock(endBlock)["timestamp"]

    userBalances = calculate_sett_balances(badger, name, endBlock)

    apyBoosts = {}
    if name in NON_NATIVE_SETTS:
        console.log(
            "{} users out of {} boosted in {}".format(
                len(userBalances), len(boosts), name
            )
        )
        preBoost = {}
        for user in userBalances:
            preBoost[user.address] = userBalances.percentage_of_total(user.address)

        for user in userBalances:
            boostAmount = boosts.get(user.address, 1)
            user.boost_balance(boostAmount)

        for user in userBalances:
            postBoost = userBalances.percentage_of_total(user.address)
            apyBoosts[user.address] = postBoost / preBoost[user.address]

    schedulesByToken = parse_schedules(
        badger.rewardsLogger.getAllUnlockSchedulesFor(sett)
    )

    for token, schedules in schedulesByToken.items():
        endDist = get_distributed_for_token_at(token, endTime, schedules, name)
        startDist = get_distributed_for_token_at(token, startTime, schedules, name)
        tokenDistribution = int(endDist) - int(startDist)
        # Distribute to users with rewards list
        # Make sure there are tokens to distribute (some geysers only
        # distribute one token)
        if token == DIGG:

            # if name in NATIVE_DIGG_SETTS:
            #    tokenDistribution = tokenDistribution * diggAllocation
            # else:
            #    tokenDistribution = tokenDistribution * (1 - diggAllocation)
            fragments = digg.sharesToFragments(tokenDistribution) / 1e9
            console.log(
                "{} DIGG tokens distributed".format(
                    digg.sharesToFragments(tokenDistribution) / 1e9
                )
            )
            rewardsLog.add_total_token_dist(name, token, fragments)
        elif token == "0x20c36f062a31865bED8a5B1e512D9a1A20AA333A":
            console.log("{} DFD tokens distributed".format(tokenDistribution / 1e18))
            rewardsLog.add_total_token_dist(name, token, tokenDistribution / 1e18)
        else:
            badgerAmount = tokenDistribution / 1e18
            console.log("{} Badger token distributed".format(badgerAmount))
            rewardsLog.add_total_token_dist(name, token, tokenDistribution / 1e18)

        if tokenDistribution > 0:
            sumBalances = sum([b.balance for b in userBalances])
            rewardsUnit = tokenDistribution / sumBalances
            totalRewards = 0
            console.log("Processing rewards for {} addresses".format(len(userBalances)))
            for user in userBalances:
                addr = web3.toChecksumAddress(user.address)

                token = web3.toChecksumAddress(token)
                rewardAmount = user.balance * rewardsUnit
                totalRewards += rewardAmount
                ## If giving rewards to tree , distribute them to users with unlcaimed bals
                if addr == BADGER_TREE:
                    if name == "native.cvx":
                        console.log(
                            "Distributing {} rewards to {} unclaimed bCvx holders".format(
                                rewardAmount / 1e18, len(unclaimedBalances["bCvx"])
                            )
                        )
                        totalbCvxBal = sum(unclaimedBalances["bCvx"].values())
                        cvxRewardsUnit = rewardAmount / totalbCvxBal
                        for addr, bal in unclaimedBalances["bCvx"].items():
                            rewards.increase_user_rewards(
                                web3.toChecksumAddress(addr),
                                token,
                                int(cvxRewardsUnit * bal),
                            )
                    if name == "native.cvxCrv":

                        console.log(
                            "Distributing {} rewards to {} unclaimed bCvxCrv holders".format(
                                rewardAmount / 1e18, len(unclaimedBalances["bCvxCrv"])
                            )
                        )

                        totalbCvxCrvBal = sum(unclaimedBalances["bCvxCrv"].values())
                        bCvxCrvRewardsUnit = rewardAmount / totalbCvxCrvBal
                        for addr, bal in unclaimedBalances["bCvxCrv"].items():
                            rewards.increase_user_rewards(
                                web3.toChecksumAddress(addr),
                                token,
                                int(bCvxCrvRewardsUnit * bal),
                            )
                else:
                    rewards.increase_user_rewards(addr, token, int(rewardAmount))

            console.log(
                "Token Distribution: {}\nRewards Released: {}".format(
                    tokenDistribution / 1e18, totalRewards / 1e18
                )
            )
            console.log("Diff {}\n\n".format((abs(tokenDistribution - totalRewards))))

    return rewards, apyBoosts
Exemple #10
0
def calc_tree_rewards(badger, startBlock, endBlock, nextCycle):

    # sharesPerFragment = badger.digg.logic.UFragments._sharesPerFragment()
    # _, _2, ibbtc_balances = fetch_wallet_balances(sharesPerFragment, endBlock)

    treeDists = fetch_tree_distributions(startBlock, endBlock)
    console.log(
        "Calculating rewards for {} harvests between {} and {}".format(
            len(treeDists), startBlock, endBlock
        )
    )
    rewards = RewardsList(nextCycle, badger.badgerTree)
    rewardsData = {}
    for dist in treeDists:
        blockNumber = dist["blockNumber"]
        strategy = dist["id"].split("-")[0]
        token = dist["token"]["address"]
        symbol = dist["token"]["symbol"]
        amountToDistribute = int(dist["amount"])

        console.log("Processing harvest...")
        console.log("Token:{}".format(symbol))
        console.log("Amount:{} \n".format(amountToDistribute / 1e18))

        if symbol not in rewardsData:
            rewardsData[symbol] = 0

        rewardsData[symbol] += amountToDistribute / 1e18
        settName = badger.getSettFromStrategy(strategy)
        balances = calculate_sett_balances(badger, settName, int(blockNumber))
        totalBalance = sum([u.balance for u in balances])
        rewardsUnit = amountToDistribute / totalBalance
        rewardsLog.add_total_token_dist(
            settName, web3.toChecksumAddress(token), amountToDistribute / 1e18
        )
        # totalIbbtcBalance = sum(ibbtc_balances.values())
        for user in balances:
            userReward = rewardsUnit * user.balance
            # if user.address in [a.lower() for a in PEAK_ADDRESSES]:
            #     ibbtcRewardsUnit = userReward / totalIbbtcBalance

            #     console.log(
            #         "Distributing {} {} to {} ibbtc holders from {}".format(
            #             userReward / 1e18, symbol, len(ibbtc_balances), settName
            #         )
            #     )

            #     # Redistribute peak addresses rewards to ibbtc users
            #     for addr, balance in ibbtc_balances.items():

            #         rewards.increase_user_rewards(
            #             web3.toChecksumAddress(addr),
            #             token,
            #             int(ibbtcRewardsUnit * balance),
            #         )
            # else:
            rewards.increase_user_rewards(
                web3.toChecksumAddress(user.address),
                web3.toChecksumAddress(token),
                int(userReward),
            )

    console.log(rewardsData)

    return rewards