def print_recipients(self): table = [] for recipient in self.recipients: table.append([ recipient.name, recipient.address, val( recipient.get_amount("usdc"), decimals=token_metadata.get_decimals( asset_to_address("usdc")), ), val( recipient.get_amount("badger"), decimals=token_metadata.get_decimals( asset_to_address("badger")), ), ]) table.append([ "Totals", "-", val( self.totals["usdc"], decimals=token_metadata.get_decimals(asset_to_address("usdc")), ), val( self.totals["badger"], decimals=token_metadata.get_decimals( asset_to_address("badger")), ), ]) print("===== LTCC Payments for {} =====".format(self.date_range)) print(tabulate(table, headers=["name", "address", "usdc", "badger"]))
def calc_token_distributions_in_range(self, startTime, endTime): tokenDistributions = DotMap() print("calc_token_distributions_in_range", self.distributionTokens) for token in self.distributionTokens: tokenDistributions[token] = int( (self.get_distributed_for_token_at(token, endTime, read=True) - self.get_distributed_for_token_at(token, startTime))) if token == digg_token: console.log( "Distributing {} {} tokens for {} geyser in this rewards cycle, out of {} historically locked" .format( val(digg.sharesToFragments(tokenDistributions[token])), token, self.key, val( digg.sharesToFragments( self.get_distributed_for_token_at( token, startTime))), )) else: console.log( "Distributing {} {} tokens for {} geyser in this rewards cycle, out of {} historically locked" .format( val(tokenDistributions[token]), token, self.key, val(self.get_distributed_for_token_at( token, startTime)), )) self.totalDistributions[token] = tokenDistributions[token] return tokenDistributions
def diff_rewards( badger: BadgerSystem, before_file, after_file, ): a = before_file["claims"] b = after_file["claims"] table = [] # Each users' cumulative claims must only increase for user, claim in b.items(): afterClaim = int(b[user]["cumulativeAmounts"][0]) beforeClaim = 0 if user in a: beforeClaim = int(a[user]["cumulativeAmounts"][0]) diff = afterClaim - beforeClaim proportionGained = afterClaim / beforeClaim assert proportionGained > 0.98 assert proportionGained < 1.25 table.append([ user, val(beforeClaim), val(afterClaim), val(diff), proportionGained, ]) print(tabulate( table, headers=["user", "a", "b", "diff", "% gained"], ))
def format(self, key, value): if type(value) is int: if "stakingRewards.staked" or "stakingRewards.earned" in key: return val(value) # Ether-scaled balances # TODO: Handle based on token decimals if ".digg" in key and "shares" not in key: return val(value, decimals=9) if ("balance" in key or key == "sett.available" or key == "sett.pricePerFullShare" or key == "sett.totalSupply"): return val(value) # DIGG Shares if "shares" in key or "diggFaucet.earned" in key: # We expect to have a known digg instance in the strategy in this case name = self.strategy.getName() digg = "" if name == "StrategyDiggRewards": digg = interface.IDigg(self.strategy.want()) else: digg = interface.IDigg(self.strategy.digg()) return digg_shares_to_initial_fragments(digg, value) return value
def printState(self, userDistributions): table = [] numUsers = 0 numUsersWithClaims = 0 # console.log("User State", self.users.toDict(), self.totalShareSeconds) for user, data in self.users.items(): numUsers += 1 rewards = userDistributions["claims"][user][badger_token] digg_rewards = userDistributions["claims"][user][digg_token] data.shareSecondsInRange sharesPerReward = 0 if rewards > 0: numUsersWithClaims += 1 sharesPerReward = data.shareSecondsInRange / rewards sharesPerDiggReward = 0 if digg_rewards > 0: sharesPerDiggReward = data.shareSecondsInRange / digg_rewards table.append([ user, val(rewards), digg_rewards, sec(data.shareSecondsInRange), sharesPerReward, sharesPerDiggReward, sec(data.shareSeconds), data.total, data.lastUpdate, ]) print("GEYSER " + self.key) # print( # tabulate( # table, # headers=[ # "user", # "rewards", # "digg_rewards", # "shareSecondsInRange", # "shareSeconds/reward", # "shareSeconds/digg_reward", # "shareSeconds", # "totalStaked", # "lastUpdate", # ], # ) # ) print("Total Badger for Geyser", val(userDistributions["totals"][badger_token])) print("Total DIGG shares for Geyser", userDistributions["totals"][digg_token]) print("Total DIGG tokens for Geyser", digg.sharesToFragments(userDistributions["totals"][digg_token])) print("Total Users", numUsers) print("Total Users With Claims", numUsersWithClaims)
def printState(self, title): console.print( "\n[yellow]=== 🦡 Rewards Schedule: {} 🦡 ===[/yellow]".format( title)) table = [] rewardsEscrow = self.badger.rewardsEscrow for key, amount in self.amounts.items(): geyser = self.badger.getGeyser(key) assert rewardsEscrow.isApproved(geyser) """ function signalTokenLock( address geyser, address token, uint256 amount, uint256 durationSec, uint256 startTime ) """ encoded = rewardsEscrow.signalTokenLock.encode_input( geyser, self.badger.token, amount, self.duration, self.start) table.append([ key, geyser, self.badger.token, val(amount), to_utc_date(self.start), to_utc_date(self.end), to_days(self.duration), val(self.tokensPerDay(amount)), self.badger.rewardsEscrow, encoded, ]) print( tabulate( table, headers=[ "key", "geyser", "token", "total amount", "start time", "end time", "duration", "rate per day", "destination", "encoded call", ], tablefmt="rst", )) print("total distributed: ", val(self.total))
def main(): fileName = badger_config.prod_file badger = connect_badger(fileName) token = badger.token table = [] contracts = {} tokens = {} for key, contract in badger.sett_system.vaults.items(): contracts["Sett " + key] = contract for key, contract in badger.sett_system.rewards.items(): contracts["Rewards " + key] = contract contracts["badgerTree"] = badger.badgerTree contracts["badgerHunt"] = badger.badgerHunt contracts["rewardsEscrow"] = badger.rewardsEscrow contracts["teamVesting"] = badger.teamVesting contracts["daoBadgerTimelock"] = badger.daoBadgerTimelock contracts["deployer"] = badger.deployer tokens["badger"] = interface.IERC20(badger.token.address) tokens["farm"] = interface.IERC20(registry.harvest.farmToken) total = 0 print(badger.token.address) for contractName, contract in contracts.items(): data = [] data.append(contractName) # Tokens: badger / farm for tokenName, token in tokens.items(): amount = token.balanceOf(contract) data.append(val(amount)) total += amount table.append(data) table.append(["total", val(total), "-"]) print(tabulate(table, headers=["contract", "badger", "farm"])) # if vaults: # print("poking these vaults:", vaults) # keeper.earn(vaults, {"from": sender, "gas_limit": 2_500_000}) # else: # print("no vaults to poke, exiting") table = [] table.append(["beneficiary", badger.teamVesting.beneficiary()]) table.append(["beneficiary", badger.daoBadgerTimelock.beneficiary()]) print(tabulate(table, headers=["param", "value"]))
def print_token_diff_table(name, before, after, sanity_diff, decimals=18): diff = after - before console.print("Diff for {}".format(name)) table = [] table.append(["{} before".format(name), val(before, decimals=decimals)]) table.append(["{} after".format(name), val(after, decimals=decimals)]) table.append(["{} diff".format(name), val(diff, decimals=decimals)]) print(tabulate(table, headers=["key", "value"])) assert diff <= sanity_diff
def main(): """ - Swap tokens according to parameters. Swapped tokens are returned to the swapper - Send test transaction to recipient. Amount is one Wei. - Send full transaction to recipient. Amount is specified amount minus one Wei. """ badger = connect_badger("deploy-final.json") expectedMultisig = "0xB65cef03b9B89f99517643226d76e286ee999e77" assert badger.devMultisig == expectedMultisig multi = GnosisSafe(badger.devMultisig) # Parameters recipient = "0x08CeCe3D7e70f13afa91953Ba12b2315598ad7EA" dollars = 65000 # Trade 'at max' Badger for exact amount of end coin max_in = from_dollars(badger, badger.token.address, dollars * 1.2) # exact_amount_out = from_dollars(badger, registry.tokens.wbtc, dollars) exact_amount_out = dollars * 10**6 params = { "dollars": dollars, "recipient": recipient, "token_in": badger.token.address, "token_out": registry.tokens.usdt, "swap_mode": SwapMode.EXACT_AMOUNT_OUT, "max_in": max_in, "max_in_scaled": val(max_in), "exact_amount_out": exact_amount_out, "exact_amount_out_scaled": val(exact_amount_out), "path": [ badger.token.address, registry.tokens.wbtc, registry.tokens.usdc, registry.tokens.usdt ], } console.print("===== Pre Swap =====", style="bold cyan") console.print(params) swap_transfer(recipient, params) console.print("===== Post Swap =====", style="bold cyan")
def get_distributed_for_token_at(self, token, endTime, read=False): """ Get total distribution for token within range, across unlock schedules """ totalToDistribute = 0 unlockSchedules = self.unlockSchedules[token] index = 0 for schedule in unlockSchedules: if endTime < schedule.startTime: toDistribute = 0 rangeDuration = endTime - schedule.startTime if read: console.print( "\n[cyan]Schedule {} for {}: Complete[/cyan]".format( index, self.key)) else: rangeDuration = endTime - schedule.startTime toDistribute = min( schedule.initialTokensLocked, int(schedule.initialTokensLocked * rangeDuration // schedule.duration), ) # Output if in rewards range, or read flag is on if read and (schedule.startTime <= endTime and schedule.endTime >= endTime): console.print( "\n[blue] == Schedule {} for {} == [/blue]".format( index, self.key)) console.log( "Total tokens distributed by schedule starting at {} by the end of rewards cycle are {} out of {} total." .format( to_utc_date(schedule.startTime), val(toDistribute), val(schedule.initialTokensLocked), )) console.log( "Total duration of schedule elapsed is {} hours out of {} hours, or {}% of total duration." .format(to_hours(rangeDuration), to_hours(schedule.duration), rangeDuration / schedule.duration * 100)) console.log("\n") totalToDistribute += toDistribute index += 1 return totalToDistribute
def main(): """ Transfer badger to recipient, ensuring they are approved as recipient first Use test tx, full tx model Can convert from dollar value """ badger = connect_badger("deploy-final.json") expectedMultisig = "0xB65cef03b9B89f99517643226d76e286ee999e77" assert badger.devMultisig == expectedMultisig multi = GnosisSafe(badger.devMultisig) # Parameters recipient = "0xd34C1d3853214bf049B760Ef48A580bfa7A9c8a1" dollars = 50000 # amount = from_dollars(badger, badger.token.address, dollars) amount = Wei("15907.8892303 ether") params = { "dollars": dollars, "recipient": recipient, "amount": amount, "amount_scaled": val(amount), "use_test_payment": False } console.print("===== Pre Transfer =====", style="bold cyan") console.print(params) transfer_badger(recipient, params) console.print("===== Post Transfer =====", style="bold cyan")
def calc_token_distributions_in_range(self, startTime, endTime): tokenDistributions = DotMap() for token in self.distributionTokens: tokenDistributions[token] = int( (self.get_distributed_for_token_at(token, endTime, read=True) - self.get_distributed_for_token_at(token, startTime))) console.log( "Distributing {} tokens for {} in this rewards cycle, out of {} historically locked" .format( val(tokenDistributions[token]), self.key, val(self.get_distributed_for_token_at(token, startTime)), )) self.totalDistributions[token] = tokenDistributions[token] return tokenDistributions
def format(self, key, value): if type(value) is int: if ("balance" in key or key == "sett.available" or key == "sett.pricePerFullShare" or key == "sett.totalSupply"): return val(value) return value
def printHarvestState(self, event, keys): table = [] console.print("[blue]== Harvest State ==[/blue]") for key in keys: table.append([key, val(event[key])]) print(tabulate(table, headers=["account", "value"]))
def main(): """ Transfer badger to recipient, ensuring they are approved as recipient first Use test tx, full tx model Can convert from dollar value """ badger = connect_badger("deploy-final.json") expectedMultisig = "0xB65cef03b9B89f99517643226d76e286ee999e77" assert badger.devMultisig == expectedMultisig multi = GnosisSafe(badger.devMultisig) # Parameters recipient = "0xD73b03F1Ea390fEB20D879e4DFb83F1245C8D4be" dollars = 45000 # amount = from_dollars(badger, badger.token.address, dollars) amount = Wei("45000 ether") params = { "dollars": dollars, "recipient": recipient, "amount": amount, "amount_scaled": val(amount), "use_test_payment": True } console.print("===== Pre Transfer =====", style="bold cyan") console.print(params) transfer_badger(recipient, params) console.print("===== Post Transfer =====", style="bold cyan")
def main(): badger = connect_badger("deploy-final.json") admin = badger.devProxyAdmin multisig = badger.devMultisig contracts = badger.contracts_upgradeable deployer = badger.deployer expectedMultisig = "0xB65cef03b9B89f99517643226d76e286ee999e77" assert multisig == expectedMultisig """ Total $BADGER 603,750 Setts renbtcCRV — 83,437.5 $BADGER sbtcCRV — 83,437.5 $BADGER tbtcCRV — 83,437.5 $BADGER Badger — 70,000 $BADGER (NEW) wBTC/ETH Sushiswap LP — 40,000 $BADGER Badger <>wBTC Uniswap LP — 110,000 $BADGER (NEW) Badger <>wBTC Sushiswap LP— 50,000 $BADGER wbtc/eth = 34,285 $BADGER (which should be distributed evenly over 3 days ie today 1pm to tomorrow, tomorrow to wednesday, wed- thursday then new emissions) Badger <>wBTC Sushiswap LP— 30,000 $BADGER (10k/day) Super Sett Harvest renbtc CRV —83,437.5 $BADGER """ rest = RewardsSchedule(badger) rest.setStart(to_timestamp(datetime.datetime(2020, 12, 31, 12, 00))) rest.setDuration(days(7)) rest.setAmounts({ "native.renCrv": Wei("83437.5 ether"), "native.sbtcCrv": Wei("83437.5 ether"), "native.tbtcCrv": Wei("83437.5 ether"), "native.badger": Wei("60000 ether"), "native.sushiWbtcEth": Wei("80000 ether"), "native.uniBadgerWbtc": Wei("80000 ether"), "native.sushiBadgerWbtc": Wei("80000 ether"), "harvest.renCrv": Wei("83437.5 ether"), }) rest.testTransactions() rest.printState("Week 5 - Sushi Continues") total = rest.total expected = Wei("633750 ether") print("overall total ", total) print("expected total ", expected) assert total == expected console.print("\n[green] ✅ Total matches expected {} [/green]".format( val(expected)))
def verify_rewards(badger: BadgerSystem, startBlock, endBlock, before_data, after_data): before = before_data["claims"] after = after_data["claims"] print(startBlock, endBlock) periodStartTime = web3.eth.getBlock(int(startBlock))["timestamp"] periodEndTime = web3.eth.getBlock(int(endBlock))["timestamp"] digg_contract = get_digg_contract() spf = digg_contract._initialSharesPerFragment() expected_totals = get_expected_total_rewards(periodEndTime) sanity_badger = expected_totals["badger"] sanity_digg = expected_totals["digg"] * digg_contract._initialSharesPerFragment() total_before_badger = before_data["tokenTotals"][badger_token] total_before_digg = before_data["tokenTotals"][digg_token] total_before_farm = int(before_data["tokenTotals"][farm_token]) total_before_xsushi = int(before_data["tokenTotals"][xSushi_token]) total_before_dfd = int(before_data["tokenTotals"].get(dfd_token, 0)) total_after_badger = after_data["tokenTotals"][BADGER] total_after_digg = after_data["tokenTotals"][DIGG] total_after_farm = int(after_data["tokenTotals"][farm_token]) total_after_xsushi = int(after_data["tokenTotals"][xSushi_token]) total_after_dfd = int(after_data["tokenTotals"].get(dfd_token, 0)) digg_badger = total_after_badger - total_before_badger diff_digg = total_after_digg - total_before_digg table = [] table.append(["block range", startBlock, endBlock]) table.append(["block duration", int(endBlock) - int(startBlock), "-"]) table.append(["duration", hours(periodEndTime - periodStartTime), "-"]) table.append(["badger before", val(total_before_badger), "-"]) table.append(["badger after", val(total_after_badger), "-"]) table.append(["badger diff", val(digg_badger), "-"]) table.append(["badger sanity ", val(sanity_badger), "-"]) table.append(["digg before", val(total_before_digg // spf, decimals=9), "-"]) table.append(["digg after", val(total_after_digg // spf, decimals=9), "-"]) table.append(["digg diff", val(diff_digg // spf, decimals=9), "-"]) table.append(["digg sanity", val(sanity_digg // spf, decimals=9), "-"]) print(tabulate(table, headers=["key", "value", "scaled"])) print_token_diff_table("Farm", total_before_farm, total_after_farm, 0) print_token_diff_table("xSushi", total_before_xsushi, total_after_xsushi, 0) print_token_diff_table("dfd", total_before_dfd, total_after_dfd, 40000 * 1e18) assert total_after_digg < sanity_digg assert total_after_badger < sanity_badger
def printState(self, event, keys): table = [] nonAmounts = ["token", "destination", "blockNumber", "timestamp"] for key in keys: if key in nonAmounts: table.append([key, event[key]]) else: table.append([key, val(event[key])]) print(tabulate(table, headers=["account", "value"]))
def printHarvestRewardsState(self, tx): events = tx.events event = events['HarvestBadgerState'][0] badgerHarvested = event['badgerHarvested'] badgerConvertedToWbtc = event['badgerConvertedToWbtc'] wtbcFromConversion = event['wtbcFromConversion'] lpGained = event['lpGained'] table = [] console.print("[blue]== Harvest Badger State ==[/blue]") table.append(["badgerHarvested", val(badgerHarvested)]) table.append(["badgerConvertedToWbtc", val(badgerConvertedToWbtc)]) table.append(["wtbcFromConversion", val(wtbcFromConversion)]) table.append(["lpGained", val(lpGained)]) print(tabulate(table, headers=["account", "value"]))
def print(self): table = [] for token, accounts in self.balances.items(): for account, value in accounts.items(): table.append([ account, val(value, decimals=token_metadata.get_decimals(token)), token_metadata.get_symbol(token), ]) print(tabulate(table, headers=["account", "balance", "asset"]))
def generate(self, badger, multi, key, distributions, start=0, duration=0, end=0): dists = [] for asset, dist in distributions.items(): if dist == 0: continue console.print( "===== Distributions for asset {} on {} =====".format(asset, key), style="bold yellow", ) token = asset_to_address(asset) # == Distribute to Geyser == geyser = badger.getGeyser(key) rewardsEscrow = badger.rewardsEscrow multi = GnosisSafe(badger.devMultisig) opsMulti = GnosisSafe(badger.opsMultisig) print(key, geyser, rewardsEscrow) if rewardsEscrow.isApproved(geyser) == False: multi.execute( MultisigTxMetadata( description="Approve Recipient" ), { "to": rewardsEscrow.address, "data": rewardsEscrow.approveRecipient.encode_input(geyser), }, ) # Approve Geyser as recipient if required if not rewardsEscrow.isApproved(geyser): multi.execute( MultisigTxMetadata( description="Approve StakingRewards " + key, operation="transfer", ), { "to": rewardsEscrow.address, "data": rewardsEscrow.approveRecipient.encode_input(geyser), }, ) numSchedules = geyser.unlockScheduleCount(token) console.print( "Geyser Distribution for {}: {}".format(key, val(dist)), style="yellow", ) dists.append((geyser, asset_to_address(asset), dist, duration, start)) console.log(key, dists) return dists
def printHarvestState(self, tx): events = tx.events event = events['HarvestState'][0] xSushiHarvested = event['xSushiHarvested'] totalxSushi = event['totalxSushi'] toStrategist = event['toStrategist'] toGovernance = event['toGovernance'] toBadgerTree = event['toBadgerTree'] table = [] console.print("[blue]== Harvest State ==[/blue]") table.append(["xSushiHarvested", val(xSushiHarvested)]) table.append(["totalxSushi", val(totalxSushi)]) table.append(["toStrategist", val(toStrategist)]) table.append(["toGovernance", val(toGovernance)]) table.append(["toBadgerTree", val(toBadgerTree)]) print(tabulate(table, headers=["account", "value"]))
def verify_rewards(badger: BadgerSystem, startBlock, endBlock, before_data, after_data): before = before_data["claims"] after = after_data["claims"] print(startBlock, endBlock) periodStartTime = web3.eth.getBlock(int(startBlock))["timestamp"] periodEndTime = web3.eth.getBlock(int(endBlock))["timestamp"] digg_contract = get_digg_contract() spf = digg_contract._initialSharesPerFragment() expected_totals = get_expected_total_rewards(periodEndTime) sanity_badger = expected_totals["badger"] sanity_digg = expected_totals["digg"] * digg_contract._initialSharesPerFragment() total_before_badger = int(before_data["tokenTotals"].get(BADGER, 0)) total_after_badger = int(after_data["tokenTotals"].get(BADGER, 0)) total_before_digg = int(before_data["tokenTotals"].get(DIGG, 0)) total_after_digg = int(after_data["tokenTotals"].get(DIGG, 0)) diff_badger = total_after_badger - total_before_badger diff_digg = total_after_digg - total_before_digg table = [] table.append(["block range", startBlock, endBlock]) table.append(["block duration", int(endBlock) - int(startBlock), "-"]) table.append(["duration", hours(periodEndTime - periodStartTime), "-"]) table.append(["badger before", val(total_before_badger), "-"]) table.append(["badger after", val(total_after_badger), "-"]) table.append(["badger diff", val(diff_badger), "-"]) table.append(["badger sanity ", val(sanity_badger), "-"]) table.append(["digg before", val(total_before_digg // spf, decimals=9), "-"]) table.append(["digg after", val(total_after_digg // spf, decimals=9), "-"]) table.append(["digg diff", val(diff_digg // spf, decimals=9), "-"]) table.append(["digg sanity", val(sanity_digg // spf, decimals=9), "-"]) print(tabulate(table, headers=["key", "value", "scaled"])) for name, token in TOKENS_TO_CHECK.items(): if name in ["Digg", "Badger"]: continue total_before_token = int(before_data["tokenTotals"].get(token, 0)) total_after_token = int(after_data["tokenTotals"].get(token, 0)) print_token_diff_table( name, total_before_token, total_after_token, 20000 * 1e18 ) assert total_after_digg < sanity_digg assert total_after_badger < sanity_badger
def print_logger_unlock_schedules(self, beneficiary, name=None): logger = self.rewardsLogger schedules = logger.getAllUnlockSchedulesFor(beneficiary) if not name: name = "" console.print(f"[cyan]=== Latest Unlock Schedules {name}===[/cyan]") table = [] if len(schedules) == 0: return for schedule in schedules: print(schedule) s = LoggerUnlockSchedule(schedule) digg_shares = s.token == self.digg.token if digg_shares: scaled = shares_to_fragments(s.amount) else: scaled = val(amount=s.amount, token=s.token) table.append([ name, s.beneficiary, s.token, scaled, to_days(s.duration), to_utc_date(s.start), to_utc_date(s.end), "{:.0f}".format(s.start), "{:.0f}".format(s.end), ]) print( tabulate( table, headers=[ "name", "beneficiary", "token", "amount", "duration", "start", "end", "start", "end", ], )) print("\n")
def print_latest_unlock_schedules(self, geyser, name=None): if not name: name = "" console.print(f"[cyan]=== Latest Unlock Schedules {name}===[/cyan]") table = [] tokens = geyser.getDistributionTokens() for token in tokens: schedules = geyser.getUnlockSchedulesFor(token) num_schedules = geyser.unlockScheduleCount(token) if num_schedules == 0: continue last_schedule = num_schedules - 1 s = UnlockSchedule(token, schedules[last_schedule]) digg_shares = token == self.digg.token if digg_shares: scaled = shares_to_fragments(s.amount) else: scaled = val(amount=s.amount, token=token) table.append([ name, token, scaled, to_days(s.duration), to_utc_date(s.start), to_utc_date(s.end), "{:.0f}".format(s.start), "{:.0f}".format(s.end), ]) print( tabulate( table, headers=[ "geyser", "token", "amount", "duration", "start", "end", "start", "end", ], )) print("\n")
def verify_rewards(badger: BadgerSystem, startBlock, endBlock, before_data, after_data): before = before_data["claims"] after = after_data["claims"] print(startBlock, endBlock) periodStartTime = web3.eth.getBlock(int(startBlock))["timestamp"] periodEndTime = web3.eth.getBlock(int(endBlock))["timestamp"] spf = digg_contract._initialSharesPerFragment() expected_totals = get_expected_total_rewards(periodEndTime) sanity_badger = expected_totals["badger"] sanity_digg = expected_totals[ "digg"] * digg_contract._initialSharesPerFragment() total_before_badger = before_data["tokenTotals"][badger_token] total_before_digg = before_data["tokenTotals"][digg_token] total_after_badger = after_data["tokenTotals"][badger_token] total_after_digg = after_data["tokenTotals"][digg_token] digg_badger = total_after_badger - total_before_badger diff_digg = total_after_digg - total_before_digg table = [] table.append(["block range", startBlock, endBlock]) table.append(["block duration", int(endBlock) - int(startBlock), "-"]) table.append(["duration", hours(periodEndTime - periodStartTime), "-"]) table.append(["badger before", val(total_before_badger), "-"]) table.append(["badger after", val(total_after_badger), "-"]) table.append(["badger diff", val(digg_badger), "-"]) table.append(["badger sanity ", val(sanity_badger), "-"]) table.append( ["digg before", val(total_before_digg // spf, decimals=9), "-"]) table.append(["digg after", val(total_after_digg // spf, decimals=9), "-"]) table.append(["digg diff", val(diff_digg // spf, decimals=9), "-"]) table.append(["digg sanity", val(sanity_digg // spf, decimals=9), "-"]) print(tabulate(table, headers=["key", "value", "scaled"])) assert total_after_digg < sanity_digg assert total_after_badger < sanity_badger
def diff_token_balances(before, after, scale=True): before = before.balances after = after.balances table = [] for token, accounts in before.items(): for account, value in accounts.items(): if scale: amount = val( after[token][account] - value, decimals=token_metadata.get_decimals(token), ), else: amount = after[token][account] - value table.append([token_metadata.get_symbol(token), account, amount]) print(tabulate(table, headers=["asset", "account", "balance"]))
def printState(self): table = [] # console.log("User State", self.users.toDict(), self.totalShareSeconds) for user, data in self.users.items(): rewards = self.userDistributions["claims"][user][ "0x3472A5A71965499acd81997a54BBA8D852C6E53d"] data.shareSecondsInRange sharesPerReward = 0 if rewards > 0: sharesPerReward = data.shareSecondsInRange / rewards table.append([ user, val(rewards), sec(data.shareSecondsInRange), sharesPerReward, sec(data.shareSeconds), data.total, data.lastUpdate, ]) print("GEYSER " + self.key) print( tabulate( table, headers=[ "user", "rewards", "shareSecondsInRange", "shareSeconds/reward", "shareSeconds", "totalStaked", "lastUpdate", ], )) print(self.userDistributions["totals"] ["0x3472A5A71965499acd81997a54BBA8D852C6E53d"] / 1e18)
def swap_transfer(recipient, params): badger = connect_badger("deploy-final.json") expectedMultisig = "0xB65cef03b9B89f99517643226d76e286ee999e77" assert badger.devMultisig == expectedMultisig multi = GnosisSafe(badger.devMultisig) one_wei = Wei("1") end_token = interface.IERC20(params["path"][-1]) console.print("Executing Swap:", style="yellow") console.print(params) # === Approve Uniswap Router on Rewards Escrow if not approved === uniswap = UniswapSystem() assert badger.rewardsEscrow.isApproved(badger.token) assert badger.rewardsEscrow.isApproved(uniswap.router) # === Approve UNI Router for Badger === # Note: The allowance must first be set to 0 id = multi.addTx( MultisigTxMetadata( description="Approve UNI Router to send BADGER", operation="call", callInfo={ 'address': uniswap.router, 'amount': params["max_in"] // 2 }, ), params={ "to": badger.rewardsEscrow.address, "data": badger.rewardsEscrow.call.encode_input( badger.token, 0, badger.token.approve.encode_input(uniswap.router, 0), ), }, ) tx = multi.executeTx(id) # Set proper allowance id = multi.addTx( MultisigTxMetadata( description="Approve UNI Router to send BADGER", operation="call", callInfo={ 'address': uniswap.router, 'amount': params["max_in"] // 2 }, ), params={ "to": badger.rewardsEscrow.address, "data": badger.rewardsEscrow.call.encode_input( badger.token, 0, badger.token.approve.encode_input(uniswap.router, params["max_in"]), ), }, ) tx = multi.executeTx(id) console.print({ "rewardsEscrowBalance": val(badger.token.balanceOf(badger.rewardsEscrow)), "rewardsEscrowRouterAllowance": val(badger.token.allowance(badger.rewardsEscrow, uniswap.router)), "max_in": val(params["max_in"]), }) assert badger.token.balanceOf(badger.rewardsEscrow) > params["max_in"] assert (badger.token.allowance(badger.rewardsEscrow, uniswap.router) >= params["max_in"]) # === Trade Badger for USDC through WBTC === before = end_token.balanceOf(badger.rewardsEscrow) beforeBadger = badger.token.balanceOf(badger.rewardsEscrow) console.print({"EAO": params["exact_amount_out"]}) expiration = chain.time() + 8000 id = multi.addTx( MultisigTxMetadata( description="Trade Badger for output token", operation="call", callInfo={}, ), params={ "to": badger.rewardsEscrow.address, "data": badger.rewardsEscrow.call.encode_input( uniswap.router, 0, uniswap.router.swapTokensForExactTokens.encode_input( params["exact_amount_out"], MaxUint256, params["path"], badger.rewardsEscrow, expiration, ), ), }, ) tx = multi.executeTx(id) print(tx.call_trace()) print(tx.events) printUniTrade( method="swapTokensForExactTokens", params=( params["exact_amount_out"], params["max_in"], params['path'], badger.rewardsEscrow, expiration, ), ) console.log("=== Post Trade ===") console.print({ 'before_input_coin': beforeBadger, 'after_input_coin': badger.token.balanceOf(badger.rewardsEscrow), 'before_output_coin': before, 'post_output_coin': end_token.balanceOf(badger.rewardsEscrow), 'end_token': end_token, 'chain_time_before': chain.time() }) assert end_token.balanceOf( badger.rewardsEscrow) >= params["exact_amount_out"] # === Approve Recipient if not approved === if not badger.rewardsEscrow.isApproved(recipient): id = multi.addTx( MultisigTxMetadata( description="Approve the transfer recipient", operation="approveRecipient", callInfo={}, ), params={ "to": badger.rewardsEscrow.address, "data": badger.rewardsEscrow.approveRecipient.encode_input(recipient), }, ) multi.executeTx(id) assert badger.rewardsEscrow.isApproved(recipient) # === Test Payment to recipient === before = end_token.balanceOf(recipient) id = multi.addTx( MultisigTxMetadata( description="Test payment to recipientt", operation="transfer", callInfo={ "to": recipient, "amount": one_wei }, ), params={ "to": badger.rewardsEscrow.address, "data": badger.rewardsEscrow.transfer.encode_input(end_token, recipient, one_wei), }, ) multi.executeTx(id) after = end_token.balanceOf(recipient) assert after == before + one_wei # === Full Payment to recipient === rest = params["exact_amount_out"] - 1 before = end_token.balanceOf(recipient) id = multi.addTx( MultisigTxMetadata( description="$12k payment to auditor, in USDC", operation="transfer", callInfo={ "to": recipient, "amount": rest }, ), params={ "to": badger.rewardsEscrow.address, "data": badger.rewardsEscrow.transfer.encode_input(end_token, recipient, rest), }, ) multi.executeTx(id) after = end_token.balanceOf(recipient) assert after == before + rest print(before, after, before + params["exact_amount_out"]) console.print("\n[green] ✅ Actions Complete [/green]")
def printState(self, title): console.print( "\n[yellow]=== 🦡 Rewards Schedule: {} 🦡 ===[/yellow]".format( title)) table = [] rewardsEscrow = self.badger.rewardsEscrow for key, dist in self.distributions.items(): if key == "native.digg": continue print(key, dist) geyser = self.badger.getGeyser(key) print(geyser) assert rewardsEscrow.isApproved(geyser) for asset, value in dist.toGeyser.items(): """ function signalTokenLock( address geyser, address token, uint256 amount, uint256 durationSec, uint256 startTime ) """ encoded = rewardsEscrow.signalTokenLock.encode_input( geyser, asset_to_address(asset), value, self.duration, self.start) asset_contract = interface.IERC20(asset_to_address(asset)) scaled = val(value, decimals=18) if asset == "digg": scaled = val(shares_to_fragments(value), decimals=9) table.append([ key, # geyser, asset, value, scaled, to_utc_date(self.start), to_utc_date(self.end), to_days(self.duration), # geyser.address, # encoded, ]) print( tabulate( table, headers=[ "key", # "geyser", "token", "total amount", "scaled amount", "start time", "end time", "duration", # "rate per day", # "destination", # "encoded call", ], tablefmt="rst", )) print("total distributed for {}: ".format(asset), val(self.totals[asset]))