def test_operation(accounts, token, vault, strategy, strategist, amount, user, user2, want_pool, chain, gov, vsp): chain.snapshot() one_day = 86400 # Deposit to the vault token.approve(vault.address, amount, {"from": user}) vault.deposit(amount, {"from": user}) assert token.balanceOf(vault.address) >= amount vaultData(vault, token) stratData(strategy, token, want_pool, vsp) # harvest 1: funds to strat strategy.harvest({"from": strategist}) chain.mine(1) vaultData(vault, token) stratData(strategy, token, want_pool, vsp) assert strategy.estimatedTotalAssets()+1 >= amount # Harvest 2: Allow rewards to be earned print("\n**Harvest 2**") chain.sleep(one_day) chain.mine(1) strategy.harvest({"from": strategist}) vaultData(vault, token) stratData(strategy, token, want_pool, vsp) print("\nEst APR: ", "{:.2%}".format( ((vault.totalAssets() - amount) * 365) / (amount) ) ) print('loss protection:', strategy.lossProtectionBalance()/1e18) print('pps:', vault.pricePerShare()/1e18) # Harvest 3 print("\n**Harvest 3**") chain.sleep(one_day) chain.mine(1) strategy.harvest({"from": strategist}) vaultData(vault, token) stratData(strategy, token, want_pool, vsp) print('loss protection:', strategy.lossProtectionBalance()/1e18) print('pps:', vault.pricePerShare()/1e18) # Harvest 4 print("\n**Harvest 4**") chain.sleep(one_day*30) chain.mine(1) strategy.harvest({"from": strategist}) chain.sleep(3600*6) chain.mine(1) vaultData(vault, token) stratData(strategy, token, want_pool, vsp) print('loss protection:', strategy.lossProtectionBalance()/1e18) print('pps:', vault.pricePerShare()/1e18) assert False
def test_profitable_harvest(accounts, token, vault, strategy, strategist, amount, user, chain, vVSP, vETH, vsp): chain.snapshot() print("CHAIN TIME", chain.time()) print("SYSTEM TIME", time.time()) one_day = 86400 # Deposit to the vault token.approve(vault.address, amount, {"from": user}) vault.deposit(amount, {"from": user}) assert token.balanceOf(vault.address) == amount vaultData(vault, token) stratData(strategy, token, vETH, vVSP, vsp) # harvest 1 strategy.harvest({"from": strategist}) chain.mine(1) vaultData(vault, token) stratData(strategy, token, vETH, vVSP, vsp) assert strategy.estimatedTotalAssets( ) + 1 >= amount # Won't match because we must account for withdraw fees # Harvest 2: Allow rewards to be earned chain.sleep(one_day) chain.mine(1) strategy.harvest({"from": strategist}) vaultData(vault, token) stratData(strategy, token, vETH, vVSP, vsp) print("\nEst APR: ", "{:.2%}".format( ((vault.totalAssets() - amount) * 365) / (amount))) strategy.harvest({"from": strategist}) assert strategy.estimatedTotalAssets() + 1 > amount chain.revert()
def test_operation(accounts, token, vault, strategy, strategist, amount, user, vETH, chain, gov, vVSP, vsp): chain.snapshot() one_day = 86400 # Deposit to the vault token.approve(vault.address, amount, {"from": user}) vault.deposit(amount, {"from": user}) assert token.balanceOf(vault.address) == amount vaultData(vault, token) stratData(strategy, token, vETH, vVSP, vsp) # harvest 1 strategy.harvest({"from": strategist}) chain.mine(1) vaultData(vault, token) stratData(strategy, token, vETH, vVSP, vsp) assert strategy.estimatedTotalAssets( ) + 1e3 >= amount # Won't match because we must account for withdraw fees # tend() # strategy.tend({"from": strategist}) # Harvest 2: Allow rewards to be earned print("\n**Harvest 2**") chain.sleep(one_day) chain.mine(1) strategy.harvest({"from": strategist}) vaultData(vault, token) stratData(strategy, token, vETH, vVSP, vsp) print("\nEst APR: ", "{:.2%}".format( ((vault.totalAssets() - amount) * 365) / (amount))) # Harvest 3 print("\n**Harvest 3**") chain.sleep(one_day) chain.mine(1) # vVSP.rebalance({"from": strategist}) # must be called from pool... this is hard to test. # strategy.toggleHarvestVvsp({"from":strategist}) # Dump VSP tokens this time strategy.harvest({"from": strategist}) vaultData(vault, token) stratData(strategy, token, vETH, vVSP, vsp) # Current contract has rewards emissions ending on Mar 19, so we shouldnt project too far print( "\nEst APR: ", "{:.2%}".format( ((vault.totalAssets() - amount) * 365 / 2) / (amount))) # Harvest 4 print("\n**Harvest 4**") chain.sleep(one_day) chain.mine(1) # vVSP.rebalance({"from": strategist}) # must be called from pool... this is hard to test. strategy.toggleHarvestVvsp({"from": strategist}) # Dump VSP tokens this time strategy.harvest({"from": strategist}) vaultData(vault, token) stratData(strategy, token, vETH, vVSP, vsp) # Current contract has rewards emissions ending on Mar 19, so we shouldnt project too far print( "\nEst APR: ", "{:.2%}".format( ((vault.totalAssets() - amount) * 365 / 3) / (amount))) # Harves 5 print("\n**Harvest 5**") chain.sleep(3600) # wait six hours for a profitable withdraw vault.withdraw( vault.balanceOf(user), user, 61, {"from": user}) # Need more loss protect to handle 0.6% withdraw fee vaultData(vault, token) stratData(strategy, token, vETH, vVSP, vsp) assert token.balanceOf( user ) > amount * 0.994 * .78 # Ensure profit was made after withdraw fee assert vault.balanceOf(vault.rewards()) > 0 # Check mgmt fee assert vault.balanceOf(strategy) > 0 # Check perf fee chain.revert()
def test_operation(StrategyVesper, accounts, token, vault, live_strategy, strategy, uni_router, sushi_router, strategist, amount, user, pool_rewards, user2, vToken, want_pool, chain, gov, vsp): one_day = 86400 chain.snapshot() #live_strategy.harvest({"from": gov}) # Do this just bc this strategy needs to empty its funds # Deposit to the vault token.approve(vault.address, amount, {"from": user}) vault.deposit(amount, {"from": user}) assert token.balanceOf(vault.address) >= amount vaultData(vault, token) stratData(strategy, token, vToken, vsp) # harvest 1: funds from vault -> strat strategy.harvest({"from": strategist}) chain.mine(1) vaultData(vault, token) stratData(strategy, token, vToken, vsp) assert strategy.estimatedTotalAssets()+1 >= 0 # Harvest 2: Allow rewards to be earned print("\n**Harvest 2: check for profits**") before_balance = strategy.estimatedTotalAssets() + token.balanceOf(vault) chain.sleep(one_day*20) chain.mine(1) strategy.harvest({"from": strategist}) chain.sleep(3600 * 6) # Unlock profits chain.mine(1) print("Loss Protection Balance:", strategy.lossProtectionBalance()) assert token.balanceOf(strategy) == strategy.lossProtectionBalance() after_balance = strategy.estimatedTotalAssets() + token.balanceOf(vault) print("before_balance:", before_balance) print("after_balance:", after_balance) assert after_balance > before_balance # Harvest 3 print("\n**Check Profitable Withdraw**") strategy.harvest({"from": strategist}) chain.sleep(3600) # wait six hours for a profitable withdraw # Let's put our strategy to front of the queue so that we can test impact by withdraws vault.withdraw(vault.balanceOf(user),user,61,{"from": user}) # Need more loss protect to handle 0.6% withdraw fee assert token.balanceOf(strategy) == strategy.lossProtectionBalance() print("deposit amount:", amount) print("withdrawn amount:", token.balanceOf(user)) after_withdraw_fee = amount * 0.94 print("after_withdraw_fee:", after_withdraw_fee) # We want to calculate against the post fee amount because depending # On when test is run, rewards contract may have limited emissions assert token.balanceOf(user) > after_withdraw_fee # Check DEX toggle originalDex = strategy.activeDex() strategy.toggleActiveDex({"from": gov}) newDex = strategy.activeDex() assert originalDex != newDex strategy.toggleActiveDex({"from": gov}) # Update debt ratio print("\n**Check Debt Ratio Change**") before_balance = strategy.estimatedTotalAssets() vault.updateStrategyDebtRatio(strategy.address, 50, {"from": gov}) # 5% strategy.harvest({"from": strategist}) # ^ Anytime we reduce debtRatio then harvest, we suffer _loss # because of withdrawFee. Here the debtRatio actually goes below target # because of penalty on loss after_balance = strategy.estimatedTotalAssets() print("before_balance:", before_balance) print("after_balance:", strategy.estimatedTotalAssets()) assert before_balance > after_balance stratData(strategy, token, vToken, vsp) # Set funds to 0 print("\nTokens before:", token.balanceOf(strategy)/1e8) vault.updateStrategyDebtRatio(strategy, 0, {"from": gov}) strategy.harvest({"from": strategist}) vaultData(vault, token) stratData(strategy, token, vToken, vsp) assert strategy.estimatedTotalAssets() < 1e12 # allow for some dust vault.updateStrategyDebtRatio(strategy, 1_000, {"from": gov}) strategy.harvest({"from": strategist}) est_assets_before = strategy.estimatedTotalAssets() vaultData(vault, token) stratData(strategy, token, vToken, vsp) print("\nTest Migrate:") # migrate to a new strategy new_strategy = strategist.deploy( StrategyVesper, vault, vToken, pool_rewards, 1e16, 0, 5_000, # 50% percent keep, "Vesper LINK" ) new_est_assets_before = new_strategy.estimatedTotalAssets() vault.migrateStrategy(strategy, new_strategy.address, {"from": gov}) assert new_est_assets_before < new_strategy.estimatedTotalAssets() # New strat should have more assets assert strategy.estimatedTotalAssets() < est_assets_before # Old strat should have less assetes # set emergency and exit new_strategy.setEmergencyExit() new_strategy.harvest({"from": strategist})
def test_operation(accounts, token, vault, live_strategy, strategy, strategist, amount, user, user2, want_pool, chain, gov, vsp): one_day = 86400 chain.snapshot() # Deposit to the vault token.approve(vault.address, amount, {"from": user}) vault.deposit(amount, {"from": user}) assert token.balanceOf(vault.address) >= amount vaultData(vault, token) stratData(strategy, token, want_pool, vsp) # harvest 1: funds from vault -> strat live_strategy.harvest( {"from": gov}) # Do this just bc this strategy needs to empty its funds strategy.harvest({"from": strategist}) chain.mine(1) vaultData(vault, token) stratData(strategy, token, want_pool, vsp) assert strategy.estimatedTotalAssets() + 1 >= 0 # Harvest 2: Allow rewards to be earned print("\n**Harvest 2: check for profits**") before_balance = strategy.estimatedTotalAssets() chain.sleep(one_day) chain.mine(1) after_rewards = strategy.estimatedTotalAssets() print( "\nEst APR: ", "{:.2%}".format( ((after_rewards - before_balance) * 365) / (before_balance))) assert before_balance < after_rewards strategy.harvest({"from": strategist}) chain.sleep(3600 * 6) # Unlock profits chain.mine(1) after_balance = strategy.estimatedTotalAssets() after_withdraw_fee = before_balance * 0.94 print("before_balance:", before_balance) print("after_balance:", after_balance) assert after_balance > before_balance * 0.94 # Harvest 3 print("\n**Check Profitable Withdraw**") chain.sleep(3600) # wait six hours for a profitable withdraw strategy.harvest({"from": strategist}) vault.withdraw( vault.balanceOf(user), user, 61, {"from": user}) # Need more loss protect to handle 0.6% withdraw fee print("deposit amount:", amount) print("withdrawn amount:", token.balanceOf(user)) after_withdraw_fee = amount * 0.94 print("after_withdraw_fee:", after_withdraw_fee) # We want to calculate against the post fee amount because depending # On when test is run, rewards contract may have limited emissions assert token.balanceOf(user) > after_withdraw_fee # Check DEX toggle originalDex = strategy.activeDex() strategy.toggleActiveDex({"from": gov}) newDex = strategy.activeDex() assert originalDex != newDex strategy.toggleActiveDex({"from": gov}) # Update debt ratio print("\n**Check Debt Ratio Change**") before_balance = strategy.estimatedTotalAssets() vault.updateStrategyDebtRatio(strategy.address, 10, {"from": gov}) # 1% strategy.harvest({"from": strategist}) print("before_balance:", before_balance) print("after_balance:", strategy.estimatedTotalAssets()) assert before_balance > strategy.estimatedTotalAssets() stratData(strategy, token, want_pool, vsp) # Set funds to 0 print("\nTokens before:", token.balanceOf(strategy) / 1e6) vault.updateStrategyDebtRatio(strategy, 0, {"from": gov}) strategy.harvest({"from": strategist}) vaultData(vault, token) stratData(strategy, token, want_pool, vsp) assert strategy.estimatedTotalAssets() < 1e12 # allow for some dust # set emergency and exit vault.updateStrategyDebtRatio(strategy, 1_000, {"from": gov}) strategy.harvest({"from": strategist}) strategy.setEmergencyExit() strategy.harvest({"from": strategist})
def test_operation(accounts, token, vault, strategy, strategist, amount, user, user2, want_pool, chain, gov, vsp): chain.snapshot() one_day = 86400 # Deposit to the vault token.approve(vault, amount, {"from": user}) vault.deposit(amount, {"from": user}) assert token.balanceOf(vault.address) >= amount vaultData(vault, token) stratData(strategy, token, want_pool, vsp) assert token.balanceOf(strategy) == strategy.lossProtectionBalance() # harvest 1: funds to strat print("\n**Harvest 1**") strategy.harvest({"from": strategist}) chain.mine(1) vaultData(vault, token) stratData(strategy, token, want_pool, vsp) print("Loss Protection Balance:", strategy.lossProtectionBalance()) assert strategy.estimatedTotalAssets()+1 >= amount assert token.balanceOf(strategy) == strategy.lossProtectionBalance() # Harvest 2: Allow rewards to be earned print("\n**Harvest 2**") chain.sleep(one_day) chain.mine(1) strategy.harvest({"from": strategist}) vaultData(vault, token) stratData(strategy, token, want_pool, vsp) print("Loss Protection Balance:", strategy.lossProtectionBalance()) print("\nEst APR: ", "{:.2%}".format( ((vault.totalAssets() - amount) * 365) / (amount) ) ) assert token.balanceOf(strategy) == strategy.lossProtectionBalance() # Harvest 3 print("\n**Harvest 3**") chain.sleep(one_day) chain.mine(1) strategy.harvest({"from": strategist}) vaultData(vault, token) stratData(strategy, token, want_pool, vsp) print("Loss Protection Balance:", strategy.lossProtectionBalance()) # Current contract has rewards emissions ending on Mar 19, so we shouldnt project too far print("\nEst APR: ", "{:.2%}".format( ((vault.totalAssets() - amount) * 365/2) / (amount) ) ) assert token.balanceOf(strategy) == strategy.lossProtectionBalance() print("\n**Check Debt Ratio Change**") before_balance = strategy.estimatedTotalAssets() chain.snapshot() vault.updateStrategyDebtRatio(strategy.address, 500, {"from": gov}) # 5% strategy.harvest({"from": strategist}) # ^ Anytime we reduce debtRatio then harvest, we suffer _loss # because of withdrawFee. Here the debtRatio actually goes below target # because of penalty on loss after_balance = strategy.estimatedTotalAssets() print("before_balance:", before_balance) print("after_balance:", strategy.estimatedTotalAssets()) assert token.balanceOf(strategy) == strategy.lossProtectionBalance() assert before_balance > after_balance stratData(strategy, token, want_pool, vsp) vault.updateStrategyDebtRatio(strategy.address, 10_000, {"from": gov}) strategy.harvest({"from": strategist}) chain.sleep(one_day) chain.mine(1) strategy.harvest({"from": strategist}) strategy.harvest({"from": strategist}) # All funds to strat before = strategy.lossProtectionBalance() vault.withdraw(vault.balanceOf(user)/100_000,user,61,{"from": user}) # Test that user withdraw pulls partially from loss protection assert token.balanceOf(strategy) == strategy.lossProtectionBalance() assert strategy.lossProtectionBalance() < before # Start clean since the debtRatio change test kills our pps chain.revert() assert False vault.balanceOf(user) tx = vault.withdraw(1e6,user,61,{"from": user}) tx = vault.withdraw(1e8,user,61,{"from": user}) strategy.harvest({"from": strategist}) # Harvest 4 print("\n**Harvest 4**") chain.sleep(one_day) chain.mine(1) strategy.harvest({"from": strategist}) vaultData(vault, token) stratData(strategy, token, want_pool, vsp) print("Loss Protection Balance:", strategy.lossProtectionBalance()) # Harvest 5 print("\n**Harvest 5**") chain.sleep(3600) # wait six hours for a profitable withdraw vault.withdraw(vault.balanceOf(user),user,61,{"from": user}) # Need more loss protect to handle 0.6% withdraw fee print("After Withdraw - Loss Protection Balance:", strategy.lossProtectionBalance()) vaultData(vault, token) stratData(strategy, token, want_pool, vsp) assert token.balanceOf(user) > amount * 0.994 * .78 # Ensure profit was made after withdraw fee assert vault.balanceOf(vault.rewards()) > 0 # Check mgmt fee assert vault.balanceOf(strategy) > 0 # Check perf fee chain.revert()