def push_rewards(badger: BadgerSystem, afterContentHash): with open("rewards-1-" + afterContentHash + ".json") as f: after_file = json.load(f) upload("rewards-1-" + afterContentHash + ".json") badger.badgerTree.proposeRoot( after_file["merkleRoot"], afterContentHash, after_file["cycle"], after_file["startBlock"], after_file["endBlock"], { "from": badger.keeper, "gas_price": gas_strategy }, ), time.sleep(15) badger.badgerTree.approveRoot( after_file["merkleRoot"], afterContentHash, after_file["cycle"], after_file["startBlock"], after_file["endBlock"], { "from": badger.guardian, "gas_price": gas_strategy }, ),
def main(): test = False badger = connect_badger(load_root_proposer=True) nextCycle = badger.badgerTree.currentCycle() + 1 startBlock = 0 endBlock = chain.height currentRewards = fetch_current_rewards_tree(badger) console.log(currentRewards["startBlock"]) console.log(currentRewards["endBlock"]) rewards = calc_tree_rewards(badger, startBlock, endBlock, nextCycle) cumulative_rewards = process_cumulative_rewards(currentRewards, rewards) merkleTree = rewards_to_merkle_tree(cumulative_rewards, startBlock, endBlock, {}) rootHash = web3.toHex(web3.keccak(text=merkleTree["merkleRoot"])) contentFileName = "rewards-" + str(chain.id) + "-" + str(rootHash) + ".json" console.log("Saving merkle tree as {}".format(contentFileName)) with open(contentFileName, "w") as f: json.dump(merkleTree, f, indent=4) if not test: badger.badgerTree.proposeRoot( merkleTree["merkleRoot"], rootHash, nextCycle, currentRewards["startBlock"], currentRewards["endBlock"], {"from": badger.root_proposer, "gas_price": gas_strategy}, ) upload(contentFileName, merkleTree, publish=False)
def guardian(badger: BadgerSystem, startBlock, endBlock, test=False): """ Guardian Role - Check if there is a new proposed root - If there is, run the rewards script at the same block height to verify the results - If there is a discrepency, notify admin (In case of a one-off failure, Script will be attempted again at the guardianInterval) """ console.print("\n[bold cyan]===== Guardian =====[/bold cyan]\n") badgerTree = badger.badgerTree # Only run if we have a pending root if not badgerTree.hasPendingRoot(): console.print("[bold yellow]===== Result: No Pending Root =====[/bold yellow]") return False rewards_data = generate_rewards_in_range(badger, startBlock, endBlock) console.print("===== Guardian Complete =====") if not test: upload(rewards_data["contentFileName"]), badgerTree.approveRoot( rewards_data["merkleTree"]["merkleRoot"], rewards_data["rootHash"], rewards_data["merkleTree"]["cycle"], {"from": badger.guardian, "gas_price": gas_strategy}, )
def rootUpdater(badger, startBlock, endBlock, pastRewards, saveLocalFile, test=False): """ Root Updater Role - Check how much time has passed since the last published update - If sufficient time has passed, run the rewards script and p - If there is a discrepency, notify admin (In case of a one-off failure, Script will be attempted again at the rootUpdaterInterval) """ console.print("\n[bold cyan]===== Root Updater =====[/bold cyan]\n") badgerTree = badger.badgerTree nextCycle = getNextCycle(badger) currentMerkleData = fetchCurrentMerkleData(badger) currentTime = chain.time() console.print( "\n[green]Calculate rewards for {} blocks: {} -> {} [/green]\n".format( endBlock - startBlock, startBlock, endBlock)) # Only run if we have sufficent time since previous root timeSinceLastupdate = currentTime - currentMerkleData["lastUpdateTime"] if timeSinceLastupdate < rewards_config.rootUpdateMinInterval and not test: console.print( "[bold yellow]===== Result: Last Update too Recent ({}) =====[/bold yellow]" .format(to_hours(timeSinceLastupdate))) return False rewards_data = generate_rewards_in_range(badger, startBlock, endBlock, pastRewards, saveLocalFile) console.print("===== Root Updater Complete =====") if not test: badgerTree.proposeRoot( rewards_data["merkleTree"]["merkleRoot"], rewards_data["rootHash"], rewards_data["merkleTree"]["cycle"], rewards_data["merkleTree"]["startBlock"], rewards_data["merkleTree"]["endBlock"], { "from": badger.root_proposer, "gas_price": gas_strategy }, ) upload(rewards_data["contentFileName"], rewards_data["merkleTree"], publish=False) return rewards_data
def main(): badger = connect_badger(badger_config.prod_json, load_keeper=False, load_deployer=False) outputName = "rewards-1-0x77218a9a95f4a10df4ec8795cbc4bda027532c9353569c1be9ac691381e2686f.json" with open(outputName) as f: rewards = json.load(f) upload(outputName)
def approve_root(badger: BadgerSystem): badgerTree = badger.badgerTree if not badgerTree.hasPendingRoot(): console.print("No pending root") return False if rpc.is_active(): badger.guardian = accounts.at( "0x626F69162Ea1556A75Dd4443D87D2fe38dd25901", force=True) current = fetchCurrentMerkleData(badger) pending = fetchPendingMerkleData(badger) (publishedRewards, sb, eb) = get_last_published_cycle(badger) (proposedRewards, startBlock, endBlock) = get_last_proposed_cycle(badger) console.print(proposedRewards["merkleRoot"]) rootHash = hash(proposedRewards["merkleRoot"]) contentFileName = content_hash_to_filename(rootHash) print("Uploading to file " + contentFileName) with open(contentFileName, "w") as outfile: json.dump(proposedRewards, outfile, indent=4) with open(contentFileName) as f: after_file = json.load(f) console.print(contentFileName) print( proposedRewards["merkleRoot"], startBlock, endBlock, badgerTree.lastProposeStartBlock(), badgerTree.lastProposeEndBlock(), ) verify_rewards(badger, startBlock, endBlock, publishedRewards, proposedRewards) badgerTree.approveRoot( proposedRewards["merkleRoot"], pending["contentHash"], proposedRewards["cycle"], startBlock, endBlock, { "from": badger.guardian, "gas_limit": 3000000, "allow_revert": True }, ) upload(contentFileName)
def push_rewards(badger: BadgerSystem, afterContentHash): with open("rewards-1-" + afterContentHash + ".json") as f: after_file = json.load(f) upload("rewards-1-" + afterContentHash + ".json") badger.badgerTree.proposeRoot( after_file["merkleRoot"], afterContentHash, after_file["cycle"], {"from": badger.keeper}, ), badger.badgerTree.approveRoot( after_file["merkleRoot"], afterContentHash, after_file["cycle"], {"from": badger.guardian}, ),
def guardian(badger, startBlock, endBlock, test=True): """ Guardian Role - Check if there is a new proposed root - If there is, run the rewards script at the same block height to verify the results - If there is a discrepency, notify admin (In case of a one-off failure, Script will be attempted again at the guardianInterval) """ print("Guardian", startBlock, endBlock) badgerTree = badger.badgerTree guardian = badger.guardian nextCycle = getNextCycle(badger) console.print("\n[bold cyan]===== Guardian =====[/bold cyan]\n") if not badgerTree.hasPendingRoot(): console.print( "[bold yellow]===== Result: No Pending Root =====[/bold yellow]") return False pendingMerkleData = badgerTree.getPendingMerkleData() currentMerkleData = fetchCurrentMerkleData(badger) currentRewards = fetch_current_rewards_tree(badger) currentContentHash = currentMerkleData["contentHash"] # blockNumber = currentMerkleData["blockNumber"] console.print("\n[bold cyan]===== Verifying Rewards =====[/bold cyan]\n") print("Geyser Rewards", startBlock, endBlock, nextCycle) geyserRewards = calc_geyser_rewards(badger, startBlock, endBlock, nextCycle) newRewards = geyserRewards cumulativeRewards = process_cumulative_rewards(currentRewards, newRewards) # Take metadata from geyserRewards console.print("Processing to merkle tree") merkleTree = rewards_to_merkle_tree(cumulativeRewards, startBlock, endBlock, geyserRewards) # ===== Re-Publish data for redundancy ====== rootHash = hash(merkleTree["merkleRoot"]) contentFileName = content_hash_to_filename(rootHash) assert pendingMerkleData["root"] == merkleTree["merkleRoot"] assert pendingMerkleData["contentHash"] == rootHash console.log({ "merkleRoot": merkleTree["merkleRoot"], "rootHash": str(rootHash), "contentFile": contentFileName, "startBlock": startBlock, "endBlock": endBlock, "currentContentHash": currentContentHash, }) print("Uploading to file " + contentFileName) # TODO: Upload file to AWS & serve from server with open(contentFileName, "w") as outfile: json.dump(merkleTree, outfile) # upload(contentFileName) with open(contentFileName) as f: after_file = json.load(f) compare_rewards(badger, startBlock, endBlock, currentRewards, after_file, currentContentHash) console.print("===== Guardian Complete =====") if not test: upload(contentFileName), badgerTree.approveRoot(merkleTree["merkleRoot"], rootHash, merkleTree["cycle"], {"from": guardian})
def rootUpdater(badger, startBlock, endBlock, test=True): """ Root Updater Role - Check how much time has passed since the last published update - If sufficient time has passed, run the rewards script and p - If there is a discrepency, notify admin (In case of a one-off failure, Script will be attempted again at the rootUpdaterInterval) """ badgerTree = badger.badgerTree keeper = badger.keeper nextCycle = getNextCycle(badger) assert keeper == badger.keeper console.print("\n[bold cyan]===== Root Updater =====[/bold cyan]\n") currentMerkleData = fetchCurrentMerkleData(badger) currentRewards = fetch_current_rewards_tree(badger) currentTime = chain.time() timeSinceLastupdate = currentTime - currentMerkleData["lastUpdateTime"] if timeSinceLastupdate < hours(0): console.print( "[bold yellow]===== Result: Last Update too Recent =====[/bold yellow]" ) return False if badgerTree.hasPendingRoot(): console.print( "[bold yellow]===== Result: Pending Root Since Last Update =====[/bold yellow]" ) return False print("Geyser Rewards", startBlock, endBlock, nextCycle) geyserRewards = calc_geyser_rewards(badger, startBlock, endBlock, nextCycle) # metaFarmRewards = calc_harvest_meta_farm_rewards(badger, startBlock, endBlock) newRewards = geyserRewards cumulativeRewards = process_cumulative_rewards(currentRewards, newRewards) # Take metadata from geyserRewards console.print("Processing to merkle tree") merkleTree = rewards_to_merkle_tree(cumulativeRewards, startBlock, endBlock, geyserRewards) # Publish data rootHash = hash(merkleTree["merkleRoot"]) contentFileName = content_hash_to_filename(rootHash) console.log({ "merkleRoot": merkleTree["merkleRoot"], "rootHash": str(rootHash), "contentFile": contentFileName, "startBlock": startBlock, "endBlock": endBlock, "currentContentHash": currentMerkleData["contentHash"], }) print("Uploading to file " + contentFileName) # TODO: Upload file to AWS & serve from server with open(contentFileName, "w") as outfile: json.dump(merkleTree, outfile) with open(contentFileName) as f: after_file = json.load(f) compare_rewards( badger, startBlock, endBlock, currentRewards, after_file, currentMerkleData["contentHash"], ) console.print("===== Root Updater Complete =====") if not test: upload(contentFileName) badgerTree.proposeRoot(merkleTree["merkleRoot"], rootHash, merkleTree["cycle"]) return True
def main(): test = True badger = connect_badger(badger_config.prod_json, load_deployer=False, load_keeper=False) farmTokenAddress = "0xa0246c9032bC3A600820415aE600c6388619A14D" nextCycle = badger.badgerTree.currentCycle() + 1 console.log("next cycle: {}".format(nextCycle)) currentMerkleData = badger.badgerTree.getCurrentMerkleData() console.log(currentMerkleData) timeSinceLastUpdate = chain.time() - currentMerkleData[2] print("Run at", int(time.time())) latestBlock = chain.height harvestEvents = fetch_harvest_farm_events() harvestRewards = RewardsList(nextCycle, badger.badgerTree) settStartBlock = 11376266 startBlock = settStartBlock endBlock = int(harvestEvents[0]["blockNumber"]) totalHarvested = 0 for i in tqdm(range(len(harvestEvents))): console.log("Processing between {} and {}".format( startBlock, endBlock)) harvestEvent = harvestEvents[i] user_state = calc_meta_farm_rewards(badger, "harvest.renCrv", startBlock, endBlock) farmRewards = int(harvestEvent["farmToRewards"]) console.print("Processing block {}, distributing {} to users".format( harvestEvent["blockNumber"], farmRewards / 1e18, )) totalHarvested += farmRewards / 1e18 console.print("{} total FARM processed".format(totalHarvested)) totalShareSeconds = sum([u.shareSeconds for u in user_state]) farmUnit = farmRewards / totalShareSeconds for user in user_state: harvestRewards.increase_user_rewards( web3.toChecksumAddress(user.address), farmTokenAddress, farmUnit * user.shareSeconds) rewardsLogger.add_user_share_seconds(user.address, "harvest.renCrv", user.shareSeconds) rewardsLogger.add_user_token(user.address, "harvest.renCrv", farmTokenAddress, farmUnit * user.shareSeconds) rewardsLogger.add_epoch_data(user_state, "harvest.renCrv", farmTokenAddress, farmUnit, i) if i + 1 < len(harvestEvents): startBlock = int(harvestEvent["blockNumber"]) endBlock = int(harvestEvents[i + 1]["blockNumber"]) claimsHarvested = sum( [list(v.values())[0] for v in list(harvestRewards.claims.values())]) rewardsLogger.add_distribution_info("harvest.renCrv", {farmTokenAddress: claimsHarvested}) rewardsLogger.save("retroactive-farm") lastBlock = chain.height sushiRewards = calc_sushi_rewards(badger, 11537600, lastBlock, nextCycle, retroactive=True) totalDistRewards = combine_rewards([harvestRewards, sushiRewards], nextCycle, badger.badgerTree) currentRewards = fetch_current_rewards_tree(badger) cumulative_rewards = process_cumulative_rewards(currentRewards, totalDistRewards) merkleTree = rewards_to_merkle_tree(cumulative_rewards, settStartBlock, endBlock, {}) # Upload merkle tree rootHash = web3.toHex(web3.keccak(text=merkleTree["merkleRoot"])) console.log(rootHash) contentFileName = "rewards-" + \ str(chain.id) + "-" + str(merkleTree["merkleRoot"]) + ".json" console.log("Saving merkle tree as {}".format(contentFileName)) with open(contentFileName, "w") as f: json.dump(merkleTree, f, indent=4) upload(contentFileName), farmHarvestedMerkleTree = 0 claims = merkleTree["claims"] for user, claim in claims.items(): if farmTokenAddress in claim["tokens"]: token_index = claim["tokens"].index(farmTokenAddress) amount = claim["cumulativeAmounts"][token_index] console.log("Address {} : {} FARM".format( user, int(float(amount)) / 1e18)) farmHarvestedMerkleTree += int(float(amount)) console.log("Total Farm Harvested {}".format(farmHarvestedMerkleTree / 1e18)) console.log("Claims Harvested From Events {}".format(claimsHarvested / 1e18)) console.log("Difference: {}".format((farmHarvestedMerkleTree / 1e18) - (claimsHarvested / 1e18))) difference = farmHarvestedMerkleTree - claimsHarvested console.log("Difference: {}".format(farmHarvestedMerkleTree - claimsHarvested)) console.log(gas_strategy.get_gas_price()) startBlock = badger.badgerTree.lastPublishEndBlock() + 1 endBlock = badger.badgerTree.lastPublishEndBlock() + 1 print(startBlock, endBlock) if abs(difference) < 10000000 and not test: badger.badgerTree.proposeRoot(merkleTree["merkleRoot"], rootHash, nextCycle, startBlock, endBlock, { "from": badger.keeper, "gas_price": gas_strategy }) badger.badgerTree.approveRoot(merkleTree["merkleRoot"], rootHash, nextCycle, { "from": badger.keeper, "gas_price": gas_strategy })