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 setup(): """ Connect to badger system, and configure multisig for running transactions in local fork without access to accounts """ # Connect badger system from file badger = connect_badger("deploy-final.json") digg = connect_digg("deploy-final.json") # Sanity check file addresses expectedMultisig = "0xB65cef03b9B89f99517643226d76e286ee999e77" assert badger.devMultisig == expectedMultisig # Multisig wrapper multi = GnosisSafe(badger.devMultisig, testMode=True) manager = BadgerRewardsManager.at( "0x5B60952481Eb42B66bdfFC3E049025AC5b91c127") for key in strat_keys: print(key) strategy = badger.getStrategy(key) multi.execute( MultisigTxMetadata( description="Transfer Keeper for {}".format(key)), { "to": strategy.address, "data": strategy.setKeeper.encode_input(manager) }, ) return manager
def main(): badger = connect_badger(badger_config.prod_json, load_keeper=True, load_guardian=True) pendingContentHash = ( "0x346ec98585b52d981d43584477e1b831ce32165cb8e0a06d14d236241b36328e") pendingFile = "rewards-1-" + str(pendingContentHash) + ".json" with open(pendingFile) as f: after_file = json.load(f) pendingRewards = after_file # pendingRewards = fetch_current_rewards_tree(badger) currentRewards = fetch_current_rewards_tree(badger) accounts[0].transfer(badger.keeper, Wei("5 ether")) accounts[0].transfer(badger.guardian, Wei("5 ether")) # Upgrade Rewards Tree multi = GnosisSafe(badger.devMultisig) newLogic = BadgerTree.at("0x0f81D3f48Fedb8E67a5b87A8a4De57766157f19B") multi.execute( MultisigTxMetadata(description="Upgrade Tree", ), { "to": badger.opsProxyAdmin.address, "data": badger.opsProxyAdmin.upgrade.encode_input(badger.badgerTree, newLogic), }, ) assert (badger.badgerTree.hasRole(DEFAULT_ADMIN_ROLE, badger.devMultisig.address) == True) assert badger.badgerTree.getRoleMemberCount(DEFAULT_ADMIN_ROLE) == 1 assert badger.badgerTree.hasRole(ROOT_PROPOSER_ROLE, badger.keeper.address) == True assert badger.badgerTree.getRoleMemberCount(ROOT_PROPOSER_ROLE) == 1 # assert badger.badgerTree.hasRole(ROOT_VALIDATOR_ROLE, badger.guardian.address) == True # assert badger.badgerTree.getRoleMemberCount(ROOT_VALIDATOR_ROLE) == 1 assert badger.badgerTree.hasRole(PAUSER_ROLE, badger.guardian.address) == True assert badger.badgerTree.getRoleMemberCount(PAUSER_ROLE) == 1 assert badger.badgerTree.hasRole(UNPAUSER_ROLE, badger.devMultisig.address) == True assert badger.badgerTree.getRoleMemberCount(UNPAUSER_ROLE) == 1 verify_rewards( badger, pendingRewards["startBlock"], pendingRewards["endBlock"], currentRewards, pendingRewards, )
def wire_up_sett_multisig(self, vault, strategy, controller): multi = GnosisSafe(self.devMultisig, testMode=True) want = strategy.want() vault_want = vault.token() assert vault_want == want id = multi.addTx( MultisigTxMetadata( description="Set Vault for {} on Controller".format(want) ), { "to": controller.address, "data": controller.setVault.encode_input( want, vault ), }, ) multi.executeTx(id) id = multi.addTx( MultisigTxMetadata( description="Approve Strategy for {} on Controller".format(want) ), { "to": controller.address, "data": controller.approveStrategy.encode_input( want, strategy ), }, ) multi.executeTx(id) id = multi.addTx( MultisigTxMetadata( description="Set Strategy for {} on Controller".format(want) ), { "to": controller.address, "data": controller.setStrategy.encode_input( want, strategy ), }, ) multi.executeTx(id)
def upgrade_sett(self, id, newLogic): sett = self.getSett(id) multi = GnosisSafe(self.devMultisig) id = multi.addTx( MultisigTxMetadata(description="Upgrade timelock"), { "to": self.proxyAdmin.address, "data": self.proxyAdmin.upgrade.encode_input(sett, newLogic), }, ) tx = multi.executeTx(id)
def governance_queue_transaction(self, target, signature, data, eta, eth=0) -> str: multi = GnosisSafe(self.devMultisig) id = multi.addTx( MultisigTxMetadata(description="Queue timelock transaction"), { "to": self.governanceTimelock.address, "data": self.governanceTimelock.queueTransaction.encode_input( target, eth, signature, data, eta, ), }, ) multi.executeTx(id) txHash = Web3.solidityKeccak( [ "address", "uint256", "string", "bytes", "uint256", ], [ target, eth, signature, data, eta, ], ).hex() txFilename = "{}.json".format(txHash) with open(os.path.join(TIMELOCK_DIR, txFilename), "w") as f: # Dump tx data to timelock pending tx dir. txData = { "target": target, "eth": eth, "signature": signature, "data": data.hex(), "eta": eta, } f.write(json.dumps(txData, indent=4, sort_keys=True)) return txFilename
def multisig_action(badger: BadgerSystem): multi = GnosisSafe(badger.opsMultisig) key = "native.bDiggBtcb" vault = badger.getSett(key) strategy = badger.getStrategy(key) multi.execute( MultisigTxMetadata(description="Set PoolId"), {"to": strategy.address, "data": strategy.setWantPid.encode_input(104)}, ) assert strategy.wantPid() == 104
def setup_badger(badger: BadgerSystem): # Set paths key = "native.bDiggBtcb" sett = badger.getSett(key) strategy = badger.getStrategy(key) multi = GnosisSafe(badger.opsMultisig) multi.execute( MultisigTxMetadata(description="Set path"), { "to": strategy.address, "data": strategy.setTokenSwapPath.encode_input( registry.pancake.cake, strategy.token0(), [ registry.pancake.cake, registry.tokens.btcb, strategy.token0() ], ), }, ) multi.execute( MultisigTxMetadata(description="Set path"), { "to": strategy.address, "data": strategy.setTokenSwapPath.encode_input( registry.pancake.cake, strategy.token1(), [registry.pancake.cake, registry.tokens.btcb], ), }, )
def transfer(self, token, amount, recipient): rewardsEscrow = self.badger.rewardsEscrow multi = GnosisSafe(self.badger.devMultisig) # Approve Geyser as recipient if required if not rewardsEscrow.isApproved(recipient): multi.execute( MultisigTxMetadata(description="Approve Recipient " + recipient.address), { "to": rewardsEscrow.address, "data": rewardsEscrow.approveRecipient.encode_input(recipient), }, ) before = token.balanceOf(recipient) # Top up Tree # TODO: Make the amount based on what we'll require for the next week id = multi.addTx( MultisigTxMetadata(description="Send {} {} to {}".format( token, amount, recipient)), { "to": rewardsEscrow.address, "data": rewardsEscrow.transfer.encode_input(token, recipient, amount), }, ) tx = multi.executeTx(id) print(tx.call_trace()) after = token.balanceOf(recipient) console.print({"before": before, "after": after}) assert after == before + amount
def configure_router(self): admin = self.admin multi = GnosisSafe(admin) for strategy in self.strategies.values(): multi.execute( MultisigTxMetadata(description="Add Swap Strategy {}".format( strategy.address)), { "to": strategy.address, "data": self.router.addSwapStrategy.encode_input(strategy.address), }, )
def main(): badger = connect_badger(badger_config.prod_json, load_keeper=True, load_guardian=True) pendingContentHash = "0x07baafa95bf7c39ba948753dda64b2e82854b5a7597f6de9e15c23a96d0bfad3" pendingFile = "rewards-1-" + str(pendingContentHash) + ".json" with open(pendingFile) as f: after_file = json.load(f) pendingRewards = after_file pendingRewards = fetch_current_rewards_tree(badger) currentRewards = fetch_current_rewards_tree(badger) accounts[0].transfer(badger.keeper, Wei("5 ether")) accounts[0].transfer(badger.guardian, Wei("5 ether")) # Upgrade Rewards Tree multi = GnosisSafe(badger.devMultisig) newLogic = BadgerTree.deploy({"from": badger.keeper}) multi.execute( MultisigTxMetadata( description="Upgrade Tree", ), { "to": badger.devProxyAdmin.address, "data": badger.devProxyAdmin.upgrade.encode_input(badger.badgerTree, newLogic), }, ) assert badger.badgerTree.hasRole(DEFAULT_ADMIN_ROLE, badger.devMultisig.address) == True assert badger.badgerTree.getRoleMemberCount(DEFAULT_ADMIN_ROLE) == 1 assert badger.badgerTree.hasRole(ROOT_PROPOSER_ROLE, badger.keeper.address) == True assert badger.badgerTree.getRoleMemberCount(ROOT_PROPOSER_ROLE) == 1 assert badger.badgerTree.hasRole(ROOT_VALIDATOR_ROLE, badger.guardian.address) == True assert badger.badgerTree.getRoleMemberCount(ROOT_VALIDATOR_ROLE) == 1 assert badger.badgerTree.hasRole(PAUSER_ROLE, badger.guardian.address) == True assert badger.badgerTree.getRoleMemberCount(PAUSER_ROLE) == 1 assert badger.badgerTree.hasRole(UNPAUSER_ROLE, badger.devMultisig.address) == True assert badger.badgerTree.getRoleMemberCount(UNPAUSER_ROLE) == 1 # verify_rewards(badger, pendingRewards["startBlock"], pendingRewards["endBlock"], currentRewards, pendingRewards) # push_rewards(badger, pendingContentHash) if rpc.is_active(): test_claims(badger, pendingRewards["startBlock"], pendingRewards["endBlock"], currentRewards, pendingRewards)
def configure_strategies_grant_swapper_role(self, swapper): admin = self.admin multi = GnosisSafe(admin) for strategy in self.strategies.values(): multi.execute( MultisigTxMetadata( description="Add Swapper Role to {}".format(swapper)), { "to": swapper, "data": strategy.grantRole.encode_input(strategy.SWAPPER_ROLE(), swapper), }, )
def configure_bridge(badger: BadgerSystem, bridge: BridgeSystem): """ Configures bridge to use curve token wrapper. """ multi = GnosisSafe(badger.devMultisig) id = multi.addTx( MultisigTxMetadata(description="Set curve token wrapper on adapter",), { "to": bridge.adapter.address, "data": bridge.adapter.setCurveTokenWrapper.encode_input( bridge.curveTokenWrapper.address ), }, ) multi.executeTx(id)
def whitelist_adapter_crv_sett( badger: BadgerSystem, bridge: BridgeSystem, multi: GnosisSafe, settID: str, ): sett = badger.sett_system.vaults[settID] id = multi.addTx( MultisigTxMetadata( description="Approve adapter access to sett {}".format(settID) ), { "to": sett.address, "data": sett.approveContractAccess.encode_input(bridge.adapter.address), }, ) multi.executeTx(id)
def grant_token_locking_permission(badger: BadgerSystem, locker): multi = GnosisSafe(badger.devMultisig) for key in keys: geyser = badger.getGeyser(key) print(key, geyser) multi.execute( MultisigTxMetadata( description="Add Geyser permission for {} to {}".format(key, locker) ), { "to": geyser.address, "data": geyser.grantRole.encode_input(TOKEN_LOCKER_ROLE, locker), }, ) assert geyser.hasRole(TOKEN_LOCKER_ROLE, locker)
def main(): badger = connect_badger(badger_config.prod_json) deployer = badger.deployer multi = GnosisSafe(badger.devMultisig) rebaseParams = {} rebaseParams[ "minRebaseTimeIntervalSec"] = badger.digg.uFragmentsPolicy.minRebaseTimeIntervalSec( ) rebaseParams[ "rebaseWindowOffsetSec"] = badger.digg.uFragmentsPolicy.rebaseWindowOffsetSec( ) rebaseParams[ "rebaseWindowLengthSec"] = badger.digg.uFragmentsPolicy.rebaseWindowLengthSec( ) console.print(rebaseParams) newWindowLength = hours(6) console.print(newWindowLength) multi.execute( MultisigTxMetadata(description="Set Rebase Params"), { "to": badger.digg.uFragmentsPolicy.address, "data": badger.digg.uFragmentsPolicy.setRebaseTimingParameters. encode_input( rebaseParams["minRebaseTimeIntervalSec"], rebaseParams["rebaseWindowOffsetSec"], newWindowLength, ), }, ) chain.mine() tx = badger.digg.orchestrator.rebase({"from": badger.deployer}) print(tx.call_trace()) tx = badger.digg.orchestrator.rebase({"from": badger.deployer}) print(tx.call_trace())
def governance_execute_transaction(self, txFilename): multi = GnosisSafe(self.devMultisig) with open(os.path.join(TIMELOCK_DIR, txFilename), "r") as f: txData = json.load(f) id = multi.addTx( MultisigTxMetadata(description="Execute timelock transaction"), { "to": self.governanceTimelock.address, "data": self.governanceTimelock.executeTransaction.encode_input( txData["target"], txData["eth"], txData["signature"], txData["data"], txData["eta"], ), }, ) if multisig_success(multi.executeTx(id)): os.remove(os.path.join(TIMELOCK_DIR, txFilename))
def main(): badger = connect_badger() digg = badger.digg raw = 0.9566301 scaled = raw * 10**18 centralizedOracle = GnosisSafe(digg.centralizedOracle) print("Raw Link") print(raw) print("Formatted for Median Oracle") print(f"{scaled:.0f}") tx = centralizedOracle.execute( MultisigTxMetadata(description="Set Market Data"), { "to": digg.marketMedianOracle.address, "data": digg.marketMedianOracle.pushReport.encode_input(scaled), }, )
def test_signal_token_lock(badger: BadgerSystem, locker): opsMulti = GnosisSafe(badger.opsMultisig) for key in keys: geyser = badger.getGeyser(key) print(key, geyser) opsMulti.execute( MultisigTxMetadata(description="Test signal token lock"), { "to": locker.address, "data": locker.signalTokenLocks.encode_input([ (geyser, badger.token, 1, 1, chain.time()), (geyser, badger.digg.token, 2, 2, chain.time()), ]), }, ) print(geyser.getUnlockSchedulesFor(badger.token)) print(geyser.getUnlockSchedulesFor(badger.digg.token))
def main(): badger = connect_badger(badger_config.prod_json) rewards = get_active_rewards_schedule(badger) b1 = rewards.getDistributions( "native.uniBadgerWbtc").getToStakingRewardsDaily("badger") * 5 b2 = rewards.getDistributions( "native.sushiBadgerWbtc").getToStakingRewardsDaily("badger") * 5 b3 = rewards.getDistributions("native.badger").getToStakingRewardsDaily( "badger") * 5 total_badger = b1 + b2 + b3 d1 = shares_to_fragments( rewards.getDistributions( "native.uniDiggWbtc").getToStakingRewardsDaily("digg")) * 5 d2 = shares_to_fragments( rewards.getDistributions( "native.sushiDiggWbtc").getToStakingRewardsDaily("digg")) * 5 d3 = shares_to_fragments( rewards.getDistributions("native.digg").getToStakingRewardsDaily( "digg")) * 6 total_digg = d1 + d2 + d3 table = [] table.append(["native.uniBadgerWbtc", val(b1)]) table.append(["native.sushiBadgerWbtc", val(b2)]) table.append(["native.badger", val(b3)]) table.append(["total badger", val(total_badger)]) print(tabulate(table, headers=["metric", "value"])) table = [] table.append(["native.uniDiggWbtc", val(d1, decimals=9)]) table.append(["native.sushiDiggWbtc", val(d2, decimals=9)]) table.append(["native.digg", val(d3, decimals=9)]) table.append(["total digg", val(total_digg, decimals=9)]) print(tabulate(table, headers=["metric", "value"])) rewards.printState("Geyser Emissions") # Generate Sufficient multi = GnosisSafe(badger.devMultisig) print(badger.badgerRewardsManager) multi.execute( MultisigTxMetadata(description="Transfer Remaining Weekly Badger"), { "to": badger.rewardsEscrow.address, "data": badger.rewardsEscrow.transfer.encode_input( badger.token, badger.badgerRewardsManager, total_badger) }) assert badger.token.balanceOf(badger.badgerRewardsManager) >= total_badger multi.execute( MultisigTxMetadata(description="Transfer Remaining Weekly Badger"), { "to": badger.rewardsEscrow.address, "data": badger.rewardsEscrow.transfer.encode_input( badger.digg.token, badger.badgerRewardsManager, total_digg) }) assert badger.digg.token.balanceOf( badger.badgerRewardsManager) >= total_digg
def main(): badger = connect_badger("deploy-final.json") test_user = accounts.at(decouple.config("TEST_ACCOUNT"), force=True) distribute_test_ether(test_user, Wei("20 ether")) distribute_from_whales(test_user, assets=["bBadger", "badger", "usdc"]) rest = get_active_rewards_schedule(badger) usdc = interface.IERC20(registry.tokens.usdc) usdc_per_badger = 40.37 * 0.75 usdc_total = 13386240 multi = GnosisSafe(badger.devMultisig) badger_total_scaled = usdc_total / usdc_per_badger badger_total = Wei(str(badger_total_scaled) + " ether") bBadger = badger.getSett("native.badger") ppfs = bBadger.getPricePerFullShare() bBadger_total = int(badger_total / ppfs * 10**18) badger_total = Wei(str(badger_total_scaled) + " ether") console.print({ "TRADE": "BASED", "usdc_per_badger": usdc_per_badger, "usdc_total": usdc_total, "badger_total_scaled": badger_total_scaled, "badger_total": badger_total, "ppfs": ppfs, "bBadger_total": str(bBadger_total), }) params = { "beneficiary": "0x3159b46a7829a0dbfa856888af768fe7146e7418", "duration": days(182), "usdcAmount": usdc_total * 10**6, "bBadgerAmount": bBadger_total, # "usdcAmount": 0, # "bBadgerAmount": 0, } console.print(params) # # Oxb1 Test beneficiary = accounts.at(params["beneficiary"], force=True) escrow = OtcEscrow.at("0x7163fB2fA38Ea3BBc1F8525F3d8D0417C0c9d903") # bBadger.transfer(badger.devMultisig, Wei("100000 ether"), {"from": test_user}) pre = get_token_balances( [usdc, bBadger], [test_user, escrow, badger.devMultisig, beneficiary]) pre.print() # assert usdc.balanceOf(params["beneficiary"]) >= params["usdcAmount"] # multi.execute(MultisigTxMetadata(description="Transfer to 0xb1"), { # "to": bBadger.address, # "data": bBadger.transfer.encode_input(escrow, bBadger_total + Wei("1000 ether")) # }) # assert usdc.allowance(beneficiary, escrow) >= params["usdcAmount"] # usdc.approve(escrow, params["usdcAmount"], {"from": beneficiary}) # tx = escrow.swap({"from": beneficiary}) tx = multi.execute(MultisigTxMetadata(description="Swap"), { "to": escrow.address, "data": escrow.swap.encode_input() }, print_output=False) chain.mine() print(tx.call_trace()) vesting = interface.ITokenTimelock( tx.events["VestingDeployed"][0]["vesting"]) console.print({ "token": vesting.token(), "beneficiary": vesting.beneficiary(), "releaseTime": to_utc_date(vesting.releaseTime()), }) post = get_token_balances( [usdc, bBadger], [test_user, escrow, badger.devMultisig, beneficiary]) diff_token_balances(pre, post) try: vesting.release({"from": test_user}) except: print("early vest failed!") chain.sleep(days(182)) chain.mine() # End vesting.release({"from": test_user}) post = get_token_balances( [usdc, bBadger], [test_user, escrow, badger.devMultisig, beneficiary]) diff_token_balances(pre, post) return escrow = OtcEscrow.deploy( params["beneficiary"], params["duration"], params["usdcAmount"], params["bBadgerAmount"], {"from": badger.deployer}, ) beneficiary = accounts.at(params["beneficiary"], force=True) usdc.transfer(beneficiary, params["usdcAmount"], {"from": test_user}) usdc.transfer(beneficiary, 1500000000000, {"from": test_user}) badger.token.transfer(badger.devMultisig, badger_total, {"from": test_user}) multi.execute( MultisigTxMetadata(description="Whitelist Multi"), { "to": bBadger.address, "data": bBadger.approveContractAccess.encode_input( badger.devMultisig), }, ) assert badger.token.balanceOf(badger.devMultisig) > Wei("100 ether") multi.execute( MultisigTxMetadata(description="Approve bBadger Contract"), { "to": badger.token.address, "data": badger.token.approve.encode_input(bBadger, badger_total), }, ) multi.execute( MultisigTxMetadata(description="Deposit"), { "to": bBadger.address, "data": bBadger.deposit.encode_input(badger_total) }, ) console.print( "bBadger.balanceOf(badger.devMultisig)", bBadger.balanceOf(badger.devMultisig), params["bBadgerAmount"], params["bBadgerAmount"] - bBadger.balanceOf(badger.devMultisig)) assert bBadger.balanceOf(badger.devMultisig) >= params["bBadgerAmount"] chain.mine() chain.sleep(14) chain.mine() multi.execute( MultisigTxMetadata(description="Transfer"), { "to": bBadger.address, "data": bBadger.transfer.encode_input(escrow, params["bBadgerAmount"]), }, ) assert bBadger.balanceOf(escrow) == params["bBadgerAmount"] multi.execute( MultisigTxMetadata(description="Revoke"), { "to": escrow.address, "data": escrow.revoke.encode_input() }, ) assert bBadger.balanceOf(escrow) == 0 assert bBadger.balanceOf(badger.devMultisig) >= params["bBadgerAmount"] print(bBadger.balanceOf(badger.devMultisig)) bBadger.transfer(escrow, params["bBadgerAmount"], {"from": test_user}) pre = get_token_balances( [usdc, bBadger], [test_user, escrow, badger.devMultisig, beneficiary]) console.print(pre) assert usdc.balanceOf(beneficiary) >= params["usdcAmount"] assert bBadger.balanceOf(escrow) == params["bBadgerAmount"] usdc.approve(escrow, params["usdcAmount"], {"from": beneficiary}) tx = escrow.swap({"from": beneficiary}) post = get_token_balances( [usdc, bBadger], [test_user, escrow, badger.devMultisig, beneficiary]) console.print(tx.events) post.print() diff_token_balances(pre, post) vesting = interface.ITokenTimelock( tx.events["VestingDeployed"][0]["vesting"]) console.print({ "token": vesting.token(), "beneficiary": vesting.beneficiary(), "releaseTime": to_utc_date(vesting.releaseTime()), }) chain.sleep(days(365)) chain.mine() vesting.release({"from": test_user})
def testTransactions(self): rewardsEscrow = self.badger.rewardsEscrow multi = GnosisSafe(self.badger.devMultisig) opsMulti = GnosisSafe(self.badger.opsMultisig) # Setup accounts[7].transfer(multi.get_first_owner(), Wei("2 ether")) print( "Supplied ETH", accounts.at(multi.get_first_owner(), force=True).balance(), ) badger = self.badger tree = self.badger.badgerTree before = badger.token.balanceOf(tree) top_up = Wei("100000 ether") top_up_digg = Wei("40 gwei") harvest_badger = Wei("30000 ether") harvest_digg = Wei("40 gwei") # Top up Tree # TODO: Make the amount based on what we'll require for the next week id = multi.addTx( MultisigTxMetadata(description="Top up badger tree with Badger"), { "to": rewardsEscrow.address, "data": rewardsEscrow.transfer.encode_input(badger.token, tree, top_up), }, ) tx = multi.executeTx(id) after = badger.token.balanceOf(tree) assert after == before + top_up before = badger.digg.token.balanceOf(tree) tx = multi.execute( MultisigTxMetadata(description="Top up badger tree with DIGG"), { "to": rewardsEscrow.address, "data": rewardsEscrow.transfer.encode_input(badger.digg.token, tree, top_up_digg), }, ) print(tx.call_trace(), before, after) after = badger.digg.token.balanceOf(tree) assert after == before + top_up_digg # multi.execute( # MultisigTxMetadata(description="Top up rewards manager with Badger"), # { # "to": rewardsEscrow.address, # "data": rewardsEscrow.transfer.encode_input( # badger.token, badger.badgerRewardsManager, harvest_badger # ), # }, # ) multi.execute( MultisigTxMetadata(description="Top up rewards manager with DIGG"), { "to": rewardsEscrow.address, "data": rewardsEscrow.transfer.encode_input( badger.digg.token, badger.badgerRewardsManager, harvest_digg), }, ) # grant_token_locking_permission(self.badger, self.badger.unlockScheduler) geyserDists = [] for key, distribution in self.distributions.items(): if distribution.hasGeyserDistribution() == True: print("has geyser distribution", key) dist = GeyserDistributor() dists = dist.generate( badger, multi, key, distributions=distribution.getGeyserDistributions(), start=self.start, duration=self.duration, end=self.end, ) geyserDists.extend(dists) console.log("after " + key, geyserDists) # Add unlock schedeules inbulk console.log(geyserDists) tx = opsMulti.execute( MultisigTxMetadata(description="Signal unlock schedules"), { "to": badger.unlockScheduler.address, "data": badger.unlockScheduler.signalTokenLocks.encode_input( geyserDists), }, ) print(tx.call_trace()) tokens = [self.badger.token.address, self.badger.digg.token.address] for key in geyser_keys: print(key) geyser = self.badger.getGeyser(key) for token in tokens: print(token) console.log( "{} schedules for {}".format(token, key), geyser.getUnlockSchedulesFor(token), )
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 init_prod_digg(badger: BadgerSystem, user): deployer = badger.deployer digg = badger.digg multi = GnosisSafe(badger.devMultisig) digg_liquidity_amount = 1000000000 wbtc_liquidity_amount = 100000000 print("TOKEN_LOCKER_ROLE", TOKEN_LOCKER_ROLE) locker_role = "0x4bf6f2cdcc8ad6c087a7a4fbecf46150b3686b71387234cac2b3e2e6dc70e345" # TODO: Have this as proxy in real deploy seederLogic = DiggSeeder.deploy({"from": deployer}) seeder = deploy_proxy( "DiggSeeder", DiggSeeder.abi, seederLogic.address, badger.devProxyAdmin.address, seederLogic.initialize.encode_input(digg.diggDistributor), deployer, ) # # Take initial liquidity from DAO # aragon = AragonSystem() # voting = aragon.getVotingAt("0xdc344bfb12522bf3fa58ef0d6b9a41256fc79a1b") # PROD: Configure DIGG digg.uFragmentsPolicy.setCpiOracle( digg.cpiMedianOracle, {"from": deployer}, ) digg.uFragmentsPolicy.setMarketOracle( digg.marketMedianOracle, {"from": deployer}, ) digg.uFragmentsPolicy.setOrchestrator( digg.orchestrator, {"from": deployer}, ) digg.uFragments.setMonetaryPolicy( digg.uFragmentsPolicy, {"from": deployer}, ) # ===== Upgrade DAOTimelock to allow voting ===== # print(badger.logic.SimpleTimelockWithVoting.address) # timelockWithVotingLogic = SimpleTimelockWithVoting.at(badger.logic.SimpleTimelockWithVoting.address) # timelock = interface.ISimpleTimelockWithVoting(badger.daoBadgerTimelock.address) # multi.execute( # MultisigTxMetadata(description="Upgrade DAO Badger Timelock to Allow voting",), # { # "to": badger.devProxyAdmin.address, # "data": badger.devProxyAdmin.upgrade.encode_input( # badger.daoBadgerTimelock, timelockWithVotingLogic # ), # }, # ) # # ===== Vote to move initial liquidity funds to multisig ===== # tx = multi.execute( # MultisigTxMetadata(description="Vote on DAO Timelock from multisig",), # { # "to": timelock.address, # "data": timelock.vote.encode_input(0, True, True) # }, # ) # # Approve DAO voting as recipient # multi.execute( # MultisigTxMetadata(description="Approve DAO voting as recipient",), # { # "to": badger.rewardsEscrow.address, # "data": badger.rewardsEscrow.approveRecipient.encode_input(voting), # }, # ) # # Vote on DAO voting as rewardsEscrow # before = badger.token.balanceOf(badger.rewardsEscrow) # tx = multi.execute( # MultisigTxMetadata(description="Vote on Rewards Escrow from multisig",), # { # "to": badger.rewardsEscrow.address, # "data": badger.rewardsEscrow.call.encode_input( # voting, 0, voting.vote.encode_input(0, True, True) # ), # }, # ) # after = badger.token.balanceOf(badger.rewardsEscrow) # print(tx.call_trace()) # assert after == before # crvRen = interface.IERC20(registry.curve.pools.renCrv.token) wbtc = interface.IERC20(registry.tokens.wbtc) # assert crvRen.balanceOf(badger.devMultisig) >= wbtc_liquidity_amount * 10 ** 10 * 2 # crvPool = interface.ICurveZap(registry.curve.pools.renCrv.swap) # # crvPool.Remove_liquidity_one_coin( # # wbtc_liquidity_amount * 10 ** 10, 1, wbtc_liquidity_amount # # ) # # ===== Convert crvRen to wBTC on multisig ===== # tx = multi.execute( # MultisigTxMetadata(description="Withdraw crvRen for 100% WBTC",), # { # "to": crvPool.address, # "data": crvPool.remove_liquidity_one_coin.encode_input( # wbtc_liquidity_amount * 10 ** 10 * 2, 1, wbtc_liquidity_amount * 2 # ), # }, # ) # assert wbtc.balanceOf(badger.devMultisig) >= wbtc_liquidity_amount * 2 # ===== Move initial liquidity funds to Seeder ===== multi.execute( MultisigTxMetadata( description="Transfer initial liquidity WBTC to the Seeder", ), { "to": wbtc.address, "data": wbtc.transfer.encode_input(seeder, 200000000), }, ) # ===== Move DIGG to Seeder ===== digg.token.transfer(seeder, digg.token.totalSupply(), {"from": deployer}) # ===== Move Required Badger to Seeder from RewardsEscrow ===== multi.execute( MultisigTxMetadata( description="Move Required Badger to Seeder from RewardsEscrow", ), { "to": badger.rewardsEscrow.address, "data": badger.rewardsEscrow.transfer.encode_input(badger.token, seeder, Wei("30000 ether")), }, ) # ===== Add DIGG token to all geyser distribution lists ===== # (Also, add Seeder as approved schedule creator) geyser_keys = [ "native.badger", "native.renCrv", "native.sbtcCrv", "native.tbtcCrv", "native.uniBadgerWbtc", "harvest.renCrv", "native.sushiWbtcEth", "native.sushiBadgerWbtc", "native.uniDiggWbtc", "native.sushiDiggWbtc", ] for key in geyser_keys: geyser = badger.getGeyser(key) print(key, geyser) id = multi.addTx( MultisigTxMetadata( description="Add DIGG token to distribution tokens on {} geyser" .format(key), ), { "to": geyser.address, "data": geyser.addDistributionToken.encode_input(digg.token), }, ) tx = multi.executeTx(id) assert geyser.hasRole(DEFAULT_ADMIN_ROLE, badger.devMultisig) multi.execute( MultisigTxMetadata( description="Allow Seeder to set unlock schedules on {} geyser" .format(key), ), { "to": geyser.address, "data": geyser.grantRole.encode_input(locker_role, seeder), }, ) assert geyser.hasRole(locker_role, seeder) # Seeder needs to have admin role to config Faucets. Remove role as part of seed. rewards_keys = [ "native.digg", "native.uniDiggWbtc", "native.sushiDiggWbtc", ] for key in rewards_keys: rewards = badger.getSettRewards(key) rewards.grantRole(DEFAULT_ADMIN_ROLE, seeder, {"from": deployer}) rewards.grantRole(DEFAULT_ADMIN_ROLE, badger.devMultisig, {"from": deployer}) rewards.renounceRole(DEFAULT_ADMIN_ROLE, deployer, {"from": deployer}) # print(digg.token.balanceOf(deployer)) # assert digg.token.balanceOf(deployer) == digg.token.totalSupply() # digg.token.transfer(seeder, digg.token.totalSupply(), {"from": deployer}) # wbtc = interface.IERC20(token_registry.wbtc) # wbtc.transfer(seeder, 200000000, {"from": user}) # ===== Seed Prep ===== print("wbtc.balanceOf(seeder)", wbtc.balanceOf(seeder)) assert digg.token.balanceOf(seeder) >= digg.token.totalSupply() assert wbtc.balanceOf(seeder) >= 200000000 print(digg.diggDistributor.address) print("digg.diggDistributor", digg.diggDistributor.isOpen()) digg.diggDistributor.transferOwnership(seeder, {"from": deployer}) print("prePreSeed", digg.token.balanceOf(seeder)) seeder.preSeed({"from": deployer}) print("postPreSeed", digg.token.balanceOf(seeder)) seeder.seed({"from": deployer}) # seeder.transferOwnership(badger.devMultisig, {'from': deployer}) # tx = multi.execute( # MultisigTxMetadata(description="Withdraw crvRen for 100% WBTC",), # { # "to": seeder.address, # "data": seeder.preSeed.encode_input(), # }, # ) # seeder.initialize({"from": deployer}) # Unpause all Setts setts_to_unpause = [ "native.digg", "native.uniDiggWbtc", "native.sushiDiggWbtc", ] for key in setts_to_unpause: sett = badger.getSett(key) id = multi.addTx( MultisigTxMetadata(description="Unpause Sett {}".format(key), ), { "to": sett.address, "data": sett.unpause.encode_input(), }, ) tx = multi.executeTx(id) assert sett.paused() == False
def setup_badger(badger: BadgerSystem): configs = { "native.pancakeBnbBtcb": { "want": registry.pancake.chefPairs.bnbBtcb, "token0": registry.tokens.btcb, "token1": registry.tokens.bnb, "performanceFeeStrategist": 1000, "performanceFeeGovernance": 1000, "withdrawalFee": 50, "wantPid": registry.pancake.chefPids.bnbBtcb, }, "native.bBadgerBtcb": { "want": registry.pancake.chefPairs.bBadgerBtcb, "token0": registry.tokens.bBadger, "token1": registry.tokens.btcb, "performanceFeeStrategist": 1000, "performanceFeeGovernance": 1000, "withdrawalFee": 50, "wantPid": registry.pancake.chefPids.bBadgerBtcb, }, "native.bDiggBtcb": { "want": registry.pancake.chefPairs.bDiggBtcb, "token0": registry.tokens.bDigg, "token1": registry.tokens.btcb, "performanceFeeStrategist": 1000, "performanceFeeGovernance": 1000, "withdrawalFee": 50, "wantPid": registry.pancake.chefPids.bDiggBtcb, }, } # Set paths key = "native.bDiggBtcb" sett = badger.getSett(key) strategy = badger.getStrategy(key) multi = GnosisSafe(badger.opsMultisig) multi.execute( MultisigTxMetadata(description="Set path"), { "to": strategy.address, "data": strategy.setTokenSwapPath.encode_input( registry.pancake.cake, strategy.token0(), [ registry.pancake.cake, registry.tokens.btcb, strategy.token0() ], ), }, ) multi.execute( MultisigTxMetadata(description="Set path"), { "to": strategy.address, "data": strategy.setTokenSwapPath.encode_input( registry.pancake.cake, strategy.token1(), [ registry.pancake.cake, registry.tokens.btcb, strategy.token1() ], ), }, )
def swap_transfer(recipient, params): badger = connect_badger("deploy-final.json") badger.paymentsMultisig = connect_gnosis_safe( "0xD4868d98849a58F743787c77738D808376210292" ) expectedMultisig = "0xB65cef03b9B89f99517643226d76e286ee999e77" assert badger.devMultisig == expectedMultisig multi = GnosisSafe(badger.paymentsMultisig) 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() # === 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", ), params={ "to": badger.token.address, "data": 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", ), params={ "to": badger.token.address, "data": badger.token.approve.encode_input( uniswap.router, int(params["max_in"] * 1.5) ), }, ) tx = multi.executeTx(id) console.print( { "rewardsEscrowBalance": val( badger.token.balanceOf(badger.paymentsMultisig) ), "rewardsEscrowRouterAllowance": val( badger.token.allowance(badger.paymentsMultisig, uniswap.router) ), "max_in": val(params["max_in"]), } ) assert badger.token.balanceOf(badger.paymentsMultisig) > params["max_in"] assert ( badger.token.allowance(badger.paymentsMultisig, uniswap.router) >= params["max_in"] ) # === Trade Badger === before = end_token.balanceOf(badger.paymentsMultisig) beforeBadger = badger.token.balanceOf(badger.paymentsMultisig) 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": uniswap.router.address, "data": uniswap.router.swapTokensForExactTokens.encode_input( params["exact_amount_out"], int(params["max_in"] * 1.5), params["path"], badger.paymentsMultisig, expiration, ), }, ) tx = multi.executeTx(id) print(tx.call_trace()) print(tx.events) printUniTrade( method="swapTokensForExactTokens", params=( params["exact_amount_out"], int(params["max_in"] * 1.5), params["path"], badger.paymentsMultisig, expiration, ), ) console.log("=== Post Trade ===") console.print( { "before_input_coin": val(beforeBadger), "after_input_coin": val(badger.token.balanceOf(badger.paymentsMultisig)), "change_input_coin": val( beforeBadger - badger.token.balanceOf(badger.paymentsMultisig) ), "before_output_coin": val(before, decimals=end_token.decimals()), "post_output_coin": val( end_token.balanceOf(badger.paymentsMultisig), decimals=end_token.decimals(), ), "end_token": end_token, "chain_time_before": chain.time(), } ) assert end_token.balanceOf(badger.paymentsMultisig) >= params["exact_amount_out"] console.print("\n[green] ✅ Actions Complete [/green]")
def transfer_badger(recipient, params): badger = connect_badger("deploy-final.json") expectedMultisig = "0xB65cef03b9B89f99517643226d76e286ee999e77" assert badger.devMultisig == expectedMultisig multi = GnosisSafe(badger.devMultisig) one_wei = Wei("1") end_token = badger.token # === 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) if params["use_test_payment"]: id = multi.addTx( MultisigTxMetadata( description="Test payment: {} badger to {}".format( one_wei, recipient), 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 = 0 if params["use_test_payment"]: rest = params["amount"] - 1 else: rest = params["amount"] before = end_token.balanceOf(recipient) id = multi.addTx( MultisigTxMetadata( description="Full payment, {} badger to {}".format( val(rest), recipient), 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["amount"]) console.print("\n[green] ✅ Actions Complete [/green]")
def migrate_strategies_via_migrator(badger): migrator = MigrationAssistant.at("0x8b459f4d8949f3748dc34430bc91441c954dc391") data = migrator.migrate.encode_input( badger.getController("native").address, [ ( registry.curve.pools.renCrv.token, "0x444B860128B7Bf8C0e864bDc3b7a36a940db7D88", badger.getStrategy("native.renCrv").address, ), ( registry.curve.pools.sbtcCrv.token, "0x3Efc97A8e23f463e71Bf28Eb19690d097797eb17", badger.getStrategy("native.sbtcCrv").address, ), ( registry.curve.pools.tbtcCrv.token, "0xE2fA197eAA5C726426003074147a08beaA59403B", badger.getStrategy("native.tbtcCrv").address, ), ], ) a = badger.getSett("native.renCrv") b = badger.getSett("native.sbtcCrv") c = badger.getSett("native.tbtcCrv") d = badger.getStrategy("native.renCrv") e = badger.getStrategy("native.sbtcCrv") f = badger.getStrategy("native.tbtcCrv") old_ren = interface.IStrategy("0x444B860128B7Bf8C0e864bDc3b7a36a940db7D88") old_sbtc = interface.IStrategy("0x3Efc97A8e23f463e71Bf28Eb19690d097797eb17") old_tbtc = interface.IStrategy("0xE2fA197eAA5C726426003074147a08beaA59403B") console.print( { "ren": a.balance(), "sbtc": b.balance(), "tbtc": c.balance(), "ren_ppfs": a.getPricePerFullShare(), "sbtc_ppfs": b.getPricePerFullShare(), "tbtc_ppfs": c.getPricePerFullShare(), "ren_strat_pool": d.balanceOfPool(), "ren_strat_want": d.balanceOfWant(), "sbtc_strat_pool": e.balanceOfPool(), "sbtc_strat_want": e.balanceOfWant(), "tbtc_strat_pool": f.balanceOfPool(), "tbtc_strat_want": f.balanceOfWant(), "old_ren_strat_pool": old_ren.balanceOfPool(), "old_ren_strat_want": old_ren.balanceOfWant(), "old_sbtc_strat_pool": old_sbtc.balanceOfPool(), "old_sbtc_strat_want": old_sbtc.balanceOfWant(), "old_tbtc_strat_pool": old_tbtc.balanceOfPool(), "old_tbtc_strat_want": old_tbtc.balanceOfWant(), } ) tokens = [ interface.IERC20(registry.curve.pools.renCrv.token), interface.IERC20(registry.curve.pools.sbtcCrv.token), interface.IERC20(registry.curve.pools.tbtcCrv.token), ] entities = [ a, b, c, d, e, f, badger.getController("native"), "0x444B860128B7Bf8C0e864bDc3b7a36a940db7D88", "0x3Efc97A8e23f463e71Bf28Eb19690d097797eb17", "0xE2fA197eAA5C726426003074147a08beaA59403B", ] table = [] for entity in entities: for token in tokens: table.append([entity, token.name(), token.balanceOf(entity)]) print(tabulate(table, ["entity", "asset", "value"])) multi = GnosisSafe(badger.opsMultisig) # 'to': badger.getController("native").address, tx = multi.execute( MultisigTxMetadata(description="CRV Migration"), {"to": migrator.address, "data": data, "operation": 1}, ) a.earn({"from": badger.deployer}) b.earn({"from": badger.deployer}) c.earn({"from": badger.deployer}) console.print( { "ren": a.balance(), "sbtc": b.balance(), "tbtc": c.balance(), "ren_ppfs": a.getPricePerFullShare(), "sbtc_ppfs": b.getPricePerFullShare(), "tbtc_ppfs": c.getPricePerFullShare(), "ren_strat_pool": d.balanceOfPool(), "ren_strat_want": d.balanceOfWant(), "sbtc_strat_pool": e.balanceOfPool(), "sbtc_strat_want": e.balanceOfWant(), "tbtc_strat_pool": f.balanceOfPool(), "tbtc_strat_want": f.balanceOfWant(), "old_ren_strat_pool": old_ren.balanceOfPool(), "old_ren_strat_want": old_ren.balanceOfWant(), "old_sbtc_strat_pool": old_sbtc.balanceOfPool(), "old_sbtc_strat_want": old_sbtc.balanceOfWant(), "old_tbtc_strat_pool": old_tbtc.balanceOfPool(), "old_tbtc_strat_want": old_tbtc.balanceOfWant(), } )
def testTransactions(self): rewardsEscrow = self.badger.rewardsEscrow multi = GnosisSafe(self.badger.devMultisig) # Setup accounts[7].transfer(multi.get_first_owner(), Wei("2 ether")) print( "Supplied ETH", accounts.at(multi.get_first_owner(), force=True).balance(), ) badger = self.badger tree = self.badger.badgerTree before = badger.token.balanceOf(tree) top_up = Wei("200000 ether") # Top up Tree # TODO: Make the amount based on what we'll require for the next week id = multi.addTx( MultisigTxMetadata( description="Top up badger tree", operation="Top Up Badger Tree", ), { "to": rewardsEscrow.address, "data": rewardsEscrow.transfer.encode_input(badger.token, tree, top_up), }, ) tx = multi.executeTx(id) after = badger.token.balanceOf(tree) assert after == before + top_up for key, distribution in self.distributions.items(): console.print("===== Distributions for {} =====".format(key), style="bold yellow") # == Distribute to Geyser == geyser = self.badger.getGeyser(key) # Approve Geyser as recipient if required if not rewardsEscrow.isApproved(geyser): id = multi.addTx( MultisigTxMetadata( description="Approve StakingRewards " + key, operation="transfer", ), { "to": rewardsEscrow.address, "data": rewardsEscrow.approveRecipient.encode_input(geyser), }, ) multi.executeTx(id) numSchedules = geyser.unlockScheduleCount(self.badger.token) console.print( "Geyser Distribution for {}: {}".format( key, val(distribution.toGeyser)), style="yellow", ) id = multi.addTx( MultisigTxMetadata( description="Signal unlock schedule for " + key, operation="signalTokenLock", ), { "to": rewardsEscrow.address, "data": rewardsEscrow.signalTokenLock.encode_input( geyser, self.badger.token, distribution.toGeyser, self.duration, self.start, ), }, ) multi.executeTx(id) # Verify Results numSchedulesAfter = geyser.unlockScheduleCount(self.badger.token) console.print( "Schedule Addition", { "numSchedules": numSchedules, "numSchedulesAfter": numSchedulesAfter }, ) assert numSchedulesAfter == numSchedules + 1 unlockSchedules = geyser.getUnlockSchedulesFor(self.badger.token) schedule = unlockSchedules[-1] print(schedule) assert schedule[0] == distribution.toGeyser assert schedule[1] == self.end assert schedule[2] == self.duration assert schedule[3] == self.start # == Distribute to StakingRewards, if relevant == if distribution.toStakingRewards > 0: stakingRewards = self.badger.getSettRewards(key) console.print( "Staking Rewards Distribution for {}: {}".format( key, val(distribution.toStakingRewards)), style="yellow", ) # Approve if not approved if not rewardsEscrow.isApproved(stakingRewards): id = multi.addTx( MultisigTxMetadata( description="Approve StakingRewards " + key, operation="transfer", ), { "to": rewardsEscrow.address, "data": rewardsEscrow.approveRecipient.encode_input( stakingRewards), }, ) multi.executeTx(id) assert rewardsEscrow.isApproved(stakingRewards) == True # Add tokens if insufficent tokens preBal = self.badger.token.balanceOf(stakingRewards) if preBal < distribution.toStakingRewards: required = distribution.toStakingRewards - preBal console.print( "� We need to add {} to the {} Badger supply of {} to reach the goal of {} Badger" .format( val(required), key, val(preBal), val(distribution.toStakingRewards), ), style="blue", ) id = multi.addTx( MultisigTxMetadata( description="Top up tokens for staking rewards " + key, operation="transfer", ), { "to": rewardsEscrow.address, "data": rewardsEscrow.transfer.encode_input( self.badger.token, stakingRewards, required), }, ) multi.executeTx(id) assert (self.badger.token.balanceOf(stakingRewards) >= distribution.toStakingRewards) # Modify the rewards duration, if necessary if stakingRewards.rewardsDuration() != self.duration: id = multi.addTx( MultisigTxMetadata( description="Modify Staking Rewards duration for " + key, operation="call.notifyRewardAmount", ), { "to": stakingRewards.address, "data": stakingRewards.setRewardsDuration.encode_input( self.duration), }, ) tx = multi.executeTx(id) # assert stakingRewards.rewardsDuration() == self.duration # Notify Rewards Amount id = multi.addTx( MultisigTxMetadata( description="Distribute Staking Rewards For " + key, operation="call.notifyRewardAmount", ), { "to": stakingRewards.address, "data": stakingRewards.notifyRewardAmount.encode_input( self.start, distribution.toStakingRewards, ), }, ) tx = multi.executeTx(id) console.print(tx.call_trace()) console.print("notify rewards events", tx.events) # Verify Results rewardsDuration = stakingRewards.rewardsDuration() rewardRate = stakingRewards.rewardRate() periodFinish = stakingRewards.periodFinish() lastUpdate = stakingRewards.lastUpdateTime() oldRewardsRate = Wei("50000 ether") // rewardsDuration console.log({ "start": to_utc_date(self.start), "end": to_utc_date(self.end), "finish": to_utc_date(periodFinish), "rewardRate": rewardRate, "expectedRewardRate": distribution.toStakingRewards // rewardsDuration, "rewardsRateDiff": rewardRate - distribution.toStakingRewards // rewardsDuration, "oldRewardsRate": oldRewardsRate, "howTheRateChanged": (distribution.toStakingRewards // rewardsDuration) / oldRewardsRate, "howWeExpectedItToChange": Wei("35000 ether") / Wei("50000 ether"), "lastUpdate": to_utc_date(lastUpdate), }) assert lastUpdate == self.start assert rewardsDuration == self.duration assert rewardRate == distribution.toStakingRewards // rewardsDuration assert periodFinish == self.start + self.duration bal = self.badger.token.balanceOf(stakingRewards) assert bal >= distribution.toStakingRewards if bal > distribution.toStakingRewards * 2: console.print( "[red] Warning: Staking rewards for {} has excessive coins [/red]" .format(key)) # Harvest the rewards and ensure the amount updated is appropriate strategy = self.badger.getStrategy(key) keeper = accounts.at(strategy.keeper(), force=True) before = strategy.balance() chain.sleep(self.start - chain.time() + 2) strategy.harvest({"from": keeper}) after = strategy.balance() print({"before": before, "after": after})
def main(): """ Connect to badger system, and configure multisig for running transactions in local fork without access to accounts """ # Connect badger system from file badger = connect_badger() digg = badger.digg # Sanity check file addresses expectedMultisig = "0xB65cef03b9B89f99517643226d76e286ee999e77" assert badger.devMultisig == expectedMultisig if rpc.is_active(): distribute_test_ether(badger.devMultisig, Wei("5 ether")) # Multisig wrapper # Get price data from sushiswap, uniswap, and coingecko digg_usd_coingecko = 41531.72 btc_usd_coingecko = 32601.13 digg_per_btc = digg_usd_coingecko / btc_usd_coingecko uniTWAP = get_average_daily_price("scripts/oracle/data/uni_digg_hour") sushiTWAP = get_average_daily_price("scripts/oracle/data/sushi_digg_hour") averageTWAP = Average([uniTWAP, sushiTWAP]) console.print({ "uniTWAP": uniTWAP, "sushiTWAP": sushiTWAP, "averageTWAP": averageTWAP }) supplyBefore = digg.token.totalSupply() print("spfBefore", digg.token._sharesPerFragment()) print("supplyBefore", digg.token.totalSupply()) marketValue = Wei(str(averageTWAP) + " ether") print(marketValue) print(int(marketValue * 10**18)) print("digg_per_btc", digg_per_btc, averageTWAP, marketValue) if rpc.is_active(): distribute_test_ether(digg.centralizedOracle, Wei("5 ether")) centralizedMulti = GnosisSafe(digg.centralizedOracle) print(digg.marketMedianOracle.providerReports(digg.centralizedOracle, 0)) print(digg.marketMedianOracle.providerReports(digg.centralizedOracle, 1)) print(digg.cpiMedianOracle.providerReports(digg.constantOracle, 0)) print(digg.cpiMedianOracle.providerReports(digg.constantOracle, 1)) print(digg.cpiMedianOracle.getData.call()) sushi = SushiswapSystem() pair = sushi.getPair(digg.token, registry.tokens.wbtc) uni = UniswapSystem() uniPair = uni.getPair(digg.token, registry.tokens.wbtc) print("pair before", pair.getReserves()) print("uniPair before", uniPair.getReserves()) tx = centralizedMulti.execute( MultisigTxMetadata(description="Set Market Data"), { "to": digg.marketMedianOracle.address, "data": digg.marketMedianOracle.pushReport.encode_input(marketValue), }, ) chain.mine() print(tx.call_trace()) print(tx.events) chain.sleep(hours(0.4)) chain.mine() in_rebase_window = digg.uFragmentsPolicy.inRebaseWindow() while not in_rebase_window: print("Not in rebase window...") chain.sleep(hours(0.1)) chain.mine() in_rebase_window = digg.uFragmentsPolicy.inRebaseWindow() tx = digg.orchestrator.rebase({"from": accounts[0]}) chain.mine() supplyAfter = digg.token.totalSupply() print("spfAfter", digg.token._sharesPerFragment()) print("supplyAfter", supplyAfter) print("supplyChange", supplyAfter / supplyBefore) print("supplyChangeOtherWay", supplyBefore / supplyAfter) print("pair after", pair.getReserves()) print("uniPair after", uniPair.getReserves())