diff --git a/brownie-config.yml b/brownie-config.yml index f1c0e48..f39ddeb 100644 --- a/brownie-config.yml +++ b/brownie-config.yml @@ -1,7 +1,7 @@ # use Ganache's forked mainnet mode as the default network # NOTE: You don't *have* to do this, but it is often helpful for testing networks: - default: mainnet-fork + default: arb-main-fork # automatically fetch contract sources from Etherscan autofetch_sources: True diff --git a/contracts/StrategyCurveTricrypto.sol b/contracts/StrategyCurveTricrypto.sol index a03081c..f651276 100644 --- a/contracts/StrategyCurveTricrypto.sol +++ b/contracts/StrategyCurveTricrypto.sol @@ -9,28 +9,9 @@ import "@openzeppelin/contracts/utils/Address.sol"; import "@openzeppelin/contracts/token/ERC20/SafeERC20.sol"; import "@openzeppelin/contracts/math/Math.sol"; -import "./interfaces/curve.sol"; -import "./interfaces/yearn.sol"; -import {IUniswapV2Router02} from "./interfaces/uniswap.sol"; -import { - BaseStrategy, - StrategyParams -} from "@yearnvaults/contracts/BaseStrategy.sol"; - -interface IUniV3 { - struct ExactInputParams { - bytes path; - address recipient; - uint256 deadline; - uint256 amountIn; - uint256 amountOutMinimum; - } - - function exactInput(ExactInputParams calldata params) - external - payable - returns (uint256 amountOut); -} +import { IGauge, IGaugeFactory, ICurveFi } from "./interfaces/curve.sol"; +import { IUniswapV2Router02 } from "./interfaces/uniswap.sol"; +import { BaseStrategy, StrategyParams } from "@yearnvaults/contracts/BaseStrategy.sol"; abstract contract StrategyCurveBase is BaseStrategy { using SafeERC20 for IERC20; @@ -42,7 +23,10 @@ abstract contract StrategyCurveBase is BaseStrategy { // Curve stuff IGauge public constant gauge = - IGauge(0x97E2768e8E73511cA874545DC5Ff8067eB19B787); // Curve gauge contract, most are tokenized, held by strategy + IGauge(0x555766f3da968ecBefa690Ffd49A2Ac02f47aa5f); // Curve gauge contract, most are tokenized, held by strategy + + IGaugeFactory public constant gaugeFactory = + IGaugeFactory(0xabC000d88f23Bb45525E447528DBF656A9D55bf5); // keepCRV stuff uint256 public keepCRV; // the percentage of CRV we re-lock for boost (in basis points) @@ -125,7 +109,22 @@ abstract contract StrategyCurveBase is BaseStrategy { return balanceOfWant(); } + function _claimRewards() internal { + gaugeFactory.mint(address(gauge)); + } + + function claimRewards() external onlyVaultManagers { + // Claims any pending CRV + // + // Mints claimable CRV from the factory gauge. Reward tokens are sent to `msg.sender` + // The method claim_rewards() from the old gauge now only applies to third-party tokens. + // There are no third-party tokens in this strategy. + _claimRewards(); + } + function prepareMigration(address _newStrategy) internal override { + // Withdraw LP tokens from the gauge. The transfer to the new strategy is done + // by migrate() in BaseStrategy.sol uint256 _stakedBal = stakedBalance(); if (_stakedBal > 0) { gauge.withdraw(_stakedBal); @@ -207,10 +206,12 @@ contract StrategyCurveTricrypto is StrategyCurveBase { // these are our approvals and path specific to this contract wbtc.approve(address(curve), type(uint256).max); weth.approve(address(curve), type(uint256).max); - usdt.safeApprove(address(curve), type(uint256).max); + usdt.approve(address(curve), type(uint256).max); - // start off with weth - targetToken = address(weth); + //'targetToken' is the token with the least impact on the curve pool at the time of deposit + // or the one with the biggest bonus. 'targetToken' is updated by yearn when granted by + // market conditions. We start off with usdt. + targetToken = address(usdt); } /* ========== MUTATIVE FUNCTIONS ========== */ @@ -225,10 +226,12 @@ contract StrategyCurveTricrypto is StrategyCurveBase { uint256 _debtPayment ) { - // harvest our rewards from the gauge - gauge.claim_rewards(); + // Claim and get a fresh snapshot of the strategy's CRV balance + _claimRewards(); + uint256 crvBalance = crv.balanceOf(address(this)); - // if we claimed any CRV, then sell it + + // Sell CRV if we have any if (crvBalance > 0) { // keep some of our CRV to increase our boost uint256 sendToVoter = crvBalance.mul(keepCRV).div(FEE_DENOMINATOR); @@ -287,34 +290,28 @@ contract StrategyCurveTricrypto is StrategyCurveBase { forceHarvestTriggerOnce = false; } - // Sells our CRV for WETH on sushi + // Sells our CRV for WETH or targetToken on sushi function _sell(uint256 _amount) internal { + address[] memory path; + if (targetToken == address(weth)) { - address[] memory path = new address[](2); + path = new address[](2); path[0] = address(crv); path[1] = address(weth); - - IUniswapV2Router02(router).swapExactTokensForTokens( - _amount, - uint256(0), - path, - address(this), - block.timestamp - ); } else { - address[] memory path = new address[](3); + path = new address[](3); path[0] = address(crv); path[1] = address(weth); path[2] = targetToken; - - IUniswapV2Router02(router).swapExactTokensForTokens( - _amount, - uint256(0), - path, - address(this), - block.timestamp - ); } + + IUniswapV2Router02(router).swapExactTokensForTokens( + _amount, + uint256(0), + path, + address(this), + block.timestamp + ); } /* ========== KEEP3RS ========== */ @@ -364,7 +361,7 @@ contract StrategyCurveTricrypto is StrategyCurveBase { // These functions are useful for setting parameters of the strategy that may need to be adjusted. // Set optimal token to sell harvested funds for depositing to Curve. - // Default is WETH, but can be set to USDT or WBTC as needed by strategist or governance. + // Default is USDT, but can be set to WETH or WBTC as needed by strategist or governance. function setOptimal(uint256 _optimal) external onlyEmergencyAuthorized { if (_optimal == 0) { targetToken = address(weth); diff --git a/contracts/interfaces/curve.sol b/contracts/interfaces/curve.sol index f6a02de..da144c6 100644 --- a/contracts/interfaces/curve.sol +++ b/contracts/interfaces/curve.sol @@ -2,138 +2,24 @@ pragma solidity 0.6.12; pragma experimental ABIEncoderV2; -import {IERC20} from "@openzeppelin/contracts/token/ERC20/SafeERC20.sol"; - interface IGauge { function deposit(uint256) external; function balanceOf(address) external view returns (uint256); - function claim_rewards() external; - - function claimable_tokens(address) external view returns (uint256); + function withdraw(uint256) external; - function claimable_reward(address _addressToCheck, address _rewardToken) - external - view - returns (uint256); + function claimable_tokens(address) external returns (uint256); +} - function withdraw(uint256) external; +interface IGaugeFactory { + function mint(address _gauge) external; } interface ICurveFi { - function get_virtual_price() external view returns (uint256); - - function add_liquidity( - // EURt - uint256[2] calldata amounts, - uint256 min_mint_amount - ) external payable; - - function add_liquidity( - // Compound, sAave - uint256[2] calldata amounts, - uint256 min_mint_amount, - bool _use_underlying - ) external payable returns (uint256); - - function add_liquidity( - // Iron Bank, Aave - uint256[3] calldata amounts, - uint256 min_mint_amount, - bool _use_underlying - ) external payable returns (uint256); - - function add_liquidity( - // 3Crv Metapools - address pool, - uint256[4] calldata amounts, - uint256 min_mint_amount - ) external; - - function add_liquidity( - // Y and yBUSD - uint256[4] calldata amounts, - uint256 min_mint_amount, - bool _use_underlying - ) external payable returns (uint256); - function add_liquidity( // 3pool uint256[3] calldata amounts, uint256 min_mint_amount ) external payable; - - function add_liquidity( - // sUSD - uint256[4] calldata amounts, - uint256 min_mint_amount - ) external payable; - - function remove_liquidity_imbalance( - uint256[2] calldata amounts, - uint256 max_burn_amount - ) external; - - function remove_liquidity(uint256 _amount, uint256[2] calldata amounts) - external; - - function remove_liquidity_one_coin( - uint256 _token_amount, - int128 i, - uint256 min_amount - ) external; - - function exchange( - int128 from, - int128 to, - uint256 _from_amount, - uint256 _min_to_amount - ) external; - - function balances(uint256) external view returns (uint256); - - function get_dy( - int128 from, - int128 to, - uint256 _from_amount - ) external view returns (uint256); - - // EURt - function calc_token_amount(uint256[2] calldata _amounts, bool _is_deposit) - external - view - returns (uint256); - - // 3Crv Metapools - function calc_token_amount( - address _pool, - uint256[4] calldata _amounts, - bool _is_deposit - ) external view returns (uint256); - - // sUSD, Y pool, etc - function calc_token_amount(uint256[4] calldata _amounts, bool _is_deposit) - external - view - returns (uint256); - - // 3pool, Iron Bank, etc - function calc_token_amount(uint256[3] calldata _amounts, bool _is_deposit) - external - view - returns (uint256); - - function calc_withdraw_one_coin(uint256 amount, int128 i) - external - view - returns (uint256); -} - -interface ICrvV3 is IERC20 { - function minter() external view returns (address); -} - -interface IMinter { - function mint(address) external; } diff --git a/contracts/interfaces/yearn.sol b/contracts/interfaces/yearn.sol deleted file mode 100644 index fa8104e..0000000 --- a/contracts/interfaces/yearn.sol +++ /dev/null @@ -1,43 +0,0 @@ -// SPDX-License-Identifier: AGPL-3.0 -pragma solidity 0.6.12; -pragma experimental ABIEncoderV2; - -import {IERC20} from "@openzeppelin/contracts/token/ERC20/SafeERC20.sol"; - -interface ICurveStrategyProxy { - function proxy() external returns (address); - - function balanceOf(address _gauge) external view returns (uint256); - - function deposit(address _gauge, address _token) external; - - function withdraw( - address _gauge, - address _token, - uint256 _amount - ) external returns (uint256); - - function withdrawAll(address _gauge, address _token) - external - returns (uint256); - - function harvest(address _gauge) external; - - function lock() external; - - function approveStrategy(address) external; - - function revokeStrategy(address) external; - - function claimRewards(address _gauge, address _token) external; -} - -interface IVoter { - function execute( - address to, - uint256 value, - bytes calldata data - ) external returns (bool, bytes memory); - - function increaseAmount(uint256) external; -} diff --git a/tests/conftest.py b/tests/conftest.py index 6e24e5f..f85d721 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -1,5 +1,5 @@ import pytest -from brownie import config, Wei, Contract +from brownie import config, Contract, interface # Snapshots the chain before each test and reverts after test completion. @pytest.fixture(autouse=True) @@ -11,14 +11,14 @@ def isolation(fn_isolation): def whale(accounts): # Totally in it for the tech # Update this with a large holder of your want token (the largest EOA holder of LP) - whale = accounts.at("0xd2d2F6a38F3A323Df87346413269cdB62cBDDB71", force=True) + whale = accounts.at("0xA86D37706162B45ABB83C8C93d380CFE5cD472Ed", force=True) yield whale # this is the amount of funds we have our whale deposit. adjust this as needed based on their wallet balance @pytest.fixture(scope="module") -def amount(): - amount = 500e18 +def amount(token, whale): + amount = token.balanceOf(whale) // 2 yield amount @@ -47,7 +47,7 @@ def no_profit(): @pytest.fixture(scope="module") def gauge(): # this should be the address of the convex deposit token - gauge = "0x97E2768e8E73511cA874545DC5Ff8067eB19B787" + gauge = "0x555766f3da968ecBefa690Ffd49A2Ac02f47aa5f" yield Contract(gauge) @@ -66,6 +66,13 @@ def token(): yield Contract(token_address) +@pytest.fixture(scope="module") +def crv(): + # this should be the address of the ERC-20 used by the strategy/vault + crv_address = "0x11cDb42B0EB46D95f990BeDD4695A6e3fA034978" + yield interface.IERC20(crv_address) + + # Only worry about changing things above this line # ----------------------------------------------------------------------- # # FOR NOW THIS IS DAI, since SMS isn't verified on dumb arbiscan @@ -84,6 +91,13 @@ def other_vault_strategy(): yield Contract("0xDA10009cBd5D07dd0CeCc66161FC93D7c9000da1") +# only applicable if you are migrating an existing strategy (i.e., you are not +# deploying a brand new one). This strat is using an old version of a curve gauge +@pytest.fixture(scope="module") +def strategy_to_migrate_from(): + yield Contract("0x19e70E3195fEC1A33745D9260Bf26c3f915Bb0CC") + + @pytest.fixture(scope="module") def healthCheck(): yield Contract("0x32059ccE723b4DD15dD5cb2a5187f814e6c470bC") @@ -101,7 +115,7 @@ def zero_address(): # normal gov is ychad, 0xFEB4acf3df3cDEA7399794D0869ef76A6EfAff52 @pytest.fixture(scope="module") def gov(accounts): - yield accounts.at("0xC0E2830724C946a6748dDFE09753613cd38f6767", force=True) + yield accounts.at("0xb6bc033D34733329971B938fEf32faD7e98E56aD", force=True) @pytest.fixture(scope="module") @@ -153,11 +167,10 @@ def vault(pm, gov, rewards, guardian, management, token, chain): yield vault -# use this if your vault is already deployed -# @pytest.fixture(scope="function") -# def vault(pm, gov, rewards, guardian, management, token, chain): -# vault = Contract("0x497590d2d57f05cf8B42A36062fA53eBAe283498") -# yield vault +@pytest.fixture(scope="function") +def vaultDeployed(): + vaultDeployed = Contract("0x239e14A19DFF93a17339DCC444f74406C17f8E67") + yield vaultDeployed # replace the first value with the name of your strategy diff --git a/tests/test_liq_gauge.py b/tests/test_liq_gauge.py new file mode 100644 index 0000000..cd7fb47 --- /dev/null +++ b/tests/test_liq_gauge.py @@ -0,0 +1,18 @@ +from brownie import chain + + +def test_gauge_is_properly_setup(gauge): + + assert ( + gauge.reward_count() == 0 + ), "Third-party reward tokens not expected for this strategy" + + WEEK = 86400 * 7 + + weeksNum = chain.time() // WEEK + + # Pull current inflation_rate and verify it's not 0; i.e., the + # reward APY is greater than 0%. + assert ( + gauge.inflation_rate(weeksNum) is not 0 + ), "This gauge is not currently rewarding any CRV" diff --git a/tests/test_migration.py b/tests/test_migration.py index b513d99..a9f0746 100644 --- a/tests/test_migration.py +++ b/tests/test_migration.py @@ -1,6 +1,4 @@ import brownie -from brownie import Contract -from brownie import config import math @@ -20,6 +18,7 @@ def test_migration( pool, strategy_name, gauge, + crv, ): ## deposit to the vault after approving @@ -47,11 +46,27 @@ def test_migration( chain.sleep(86400) chain.mine(1) + claimable_tokens = gauge.claimable_tokens.call(strategy) + crv_balance_old_strat = crv.balanceOf(strategy) + + assert claimable_tokens > 0, "No tokens to be claimed" + # migrate our old strategy vault.migrateStrategy(strategy, new_strategy, {"from": gov}) new_strategy.setHealthCheck(healthCheck, {"from": gov}) new_strategy.setDoHealthCheck(True, {"from": gov}) + with brownie.reverts("!authorized"): + strategy.claimRewards({"from": whale}) + + strategy.claimRewards({"from": gov}) + + assert crv.balanceOf(strategy) > 0, "No tokens were claimed" + + strategy.sweep(crv, {"from": gov}) + + assert crv.balanceOf(strategy) == 0, "Tokens were not swept" + # assert that our old strategy is empty updated_total_old = strategy.estimatedTotalAssets() assert updated_total_old == 0 @@ -66,8 +81,8 @@ def test_migration( new_strat_balance, total_old, abs_tol=5 ) - startingVault = vault.totalAssets() - print("\nVault starting assets with new strategy: ", startingVault) + starting_vault_assets = vault.totalAssets() + print("\nVault starting assets with new strategy: ", starting_vault_assets) # simulate one day of earnings chain.sleep(86400) @@ -77,7 +92,58 @@ def test_migration( new_strategy.harvest({"from": gov}) vaultAssets_2 = vault.totalAssets() # confirm we made money, or at least that we have about the same - assert vaultAssets_2 >= startingVault or math.isclose( - vaultAssets_2, startingVault, abs_tol=5 + assert vaultAssets_2 >= starting_vault_assets or math.isclose( + vaultAssets_2, starting_vault_assets, abs_tol=5 ) print("\nAssets after 1 day harvest: ", vaultAssets_2) + +def test_migration_from_real_strat( + gov, + vaultDeployed, + strategist, + chain, + healthCheck, + strategy_to_migrate_from, + StrategyCurveTricrypto, + strategy_name, +): + + strategy_to_migrate_from.harvest({"from": gov}) + + total_old = strategy_to_migrate_from.estimatedTotalAssets() + + # deploy our new strategy + new_strategy = strategist.deploy( + StrategyCurveTricrypto, + vaultDeployed, + strategy_name, + ) + + # migrate our old strategy + vaultDeployed.migrateStrategy(strategy_to_migrate_from, new_strategy, {"from": gov}) + new_strategy.setDoHealthCheck(True, {"from": gov}) + + # assert that our old strategy is empty + updated_total_old = strategy_to_migrate_from.estimatedTotalAssets() + assert updated_total_old == 0 + + # harvest to get funds back in strategy + new_strategy.harvest({"from": gov}) + new_strat_balance = new_strategy.estimatedTotalAssets() + + # confirm the same amount of assets were moved to the new strat + assert new_strat_balance == total_old + + starting_vault_assets = vaultDeployed.totalAssets() + print("\nVault starting assets with new strategy: ", starting_vault_assets) + + # simulate one day of earnings + chain.sleep(86400) + chain.mine(1) + + # Test out our migrated strategy, confirm we're making a profit + new_strategy.harvest({"from": gov}) + vaultAssets_2 = vaultDeployed.totalAssets() + + # confirm we made money + assert vaultAssets_2 > starting_vault_assets diff --git a/tests/test_odds_and_ends.py b/tests/test_odds_and_ends.py index e8952dc..925ffc5 100644 --- a/tests/test_odds_and_ends.py +++ b/tests/test_odds_and_ends.py @@ -75,8 +75,8 @@ def test_odds_and_ends( new_strat_balance = new_strategy.estimatedTotalAssets() assert new_strat_balance >= total_old - startingVault = vault.totalAssets() - print("\nVault starting assets with new strategy: ", startingVault) + starting_vault_assets = vault.totalAssets() + print("\nVault starting assets with new strategy: ", starting_vault_assets) # simulate one day of earnings chain.sleep(86400) @@ -85,7 +85,7 @@ def test_odds_and_ends( # Test out our migrated strategy, confirm we're making a profit new_strategy.harvest({"from": gov}) vaultAssets_2 = vault.totalAssets() - assert vaultAssets_2 >= startingVault + assert vaultAssets_2 >= starting_vault_assets print("\nAssets after 1 day harvest: ", vaultAssets_2) # check our oracle @@ -201,8 +201,8 @@ def test_odds_and_ends_migration( new_strat_balance, total_old, abs_tol=5 ) - startingVault = vault.totalAssets() - print("\nVault starting assets with new strategy: ", startingVault) + starting_vault_assets = vault.totalAssets() + print("\nVault starting assets with new strategy: ", starting_vault_assets) # simulate one day of earnings chain.sleep(86400) @@ -216,8 +216,8 @@ def test_odds_and_ends_migration( new_strategy.harvest({"from": gov}) vaultAssets_2 = vault.totalAssets() # confirm we made money, or at least that we have about the same - assert vaultAssets_2 >= startingVault or math.isclose( - vaultAssets_2, startingVault, abs_tol=5 + assert vaultAssets_2 >= starting_vault_assets or math.isclose( + vaultAssets_2, starting_vault_assets, abs_tol=5 ) print("\nAssets after 1 day harvest: ", vaultAssets_2) @@ -237,7 +237,7 @@ def test_odds_and_ends_liquidatePosition( ): ## deposit to the vault after approving startingWhale = token.balanceOf(whale) - token.approve(vault, 2 ** 256 - 1, {"from": whale}) + token.approve(vault, 2**256 - 1, {"from": whale}) vault.deposit(amount, {"from": whale}) newWhale = token.balanceOf(whale) @@ -444,7 +444,7 @@ def test_odds_and_ends_weird_amounts( vault.deposit(amount, {"from": whale}) strategy.harvest({"from": gov}) - # switch to DAI, want to not have any profit tho + # switch to WETH, want to not have any profit tho strategy.setOptimal(0, {"from": gov}) # sleep for a day to get some profit @@ -459,7 +459,7 @@ def test_odds_and_ends_weird_amounts( chain.sleep(86400) chain.mine(1) - # switch to USDC, want to not have any profit tho + # switch to WBTC, want to not have any profit tho strategy.setOptimal(1, {"from": gov}) strategy.harvest({"from": gov}) @@ -467,7 +467,7 @@ def test_odds_and_ends_weird_amounts( chain.sleep(86400) chain.mine(1) - # switch to fUSDT, want to not have any profit tho + # switch to USDT, want to not have any profit tho strategy.setOptimal(2, {"from": gov}) strategy.harvest({"from": gov}) diff --git a/tests/test_simple_harvest.py b/tests/test_simple_harvest.py index 0d50ea6..caf8af2 100644 --- a/tests/test_simple_harvest.py +++ b/tests/test_simple_harvest.py @@ -52,7 +52,7 @@ def test_simple_harvest( chain.sleep(1) new_assets = vault.totalAssets() # confirm we made money, or at least that we have about the same - assert new_assets >= old_assets + assert new_assets > old_assets print("\nAssets after 1 day: ", new_assets / 1e18) # Display estimated APR @@ -83,7 +83,7 @@ def test_simple_harvest( chain.sleep(1) after_usdc_assets = vault.totalAssets() # confirm we made money, or at least that we have about the same - assert after_usdc_assets >= before_usdc_assets + assert after_usdc_assets > before_usdc_assets # Display estimated APR print( @@ -114,7 +114,7 @@ def test_simple_harvest( chain.sleep(1) after_usdc_assets = vault.totalAssets() # confirm we made money, or at least that we have about the same - assert after_usdc_assets >= before_usdc_assets + assert after_usdc_assets > before_usdc_assets # Display estimated APR print( @@ -131,4 +131,4 @@ def test_simple_harvest( # withdraw and confirm we made money, or at least that we have about the same vault.withdraw({"from": whale}) - assert token.balanceOf(whale) >= startingWhale + assert token.balanceOf(whale) > startingWhale diff --git a/tests/test_withdraw_after_donation.py b/tests/test_withdraw_after_donation.py index 90d1678..2299d12 100644 --- a/tests/test_withdraw_after_donation.py +++ b/tests/test_withdraw_after_donation.py @@ -58,12 +58,10 @@ def test_withdraw_after_donation_1( # specifically check that our gain is greater than our donation or at least no more than 10 wei if we get slippage on deposit/withdrawal if is_slippery and no_profit: - assert math.isclose( - new_params["totalGain"] - prev_params["totalGain"], donation, abs_tol=10 - ) + assert math.isclose(profit, donation, abs_tol=10) else: - assert new_params["totalGain"] - prev_params["totalGain"] >= donation - assert profit >= 0 + assert profit > donation + assert profit > 0 # check that we didn't add any more loss, or at least no more than 10 wei if we get slippage on deposit/withdrawal if is_slippery: @@ -139,12 +137,10 @@ def test_withdraw_after_donation_2( # specifically check that our gain is greater than our donation or at least no more than 10 wei if we get slippage on deposit/withdrawal if is_slippery and no_profit: - assert math.isclose( - new_params["totalGain"] - prev_params["totalGain"], donation, abs_tol=10 - ) + assert math.isclose(profit, donation, abs_tol=10) else: - assert new_params["totalGain"] - prev_params["totalGain"] >= donation - assert profit >= 0 + assert profit > donation + assert profit > 0 # check that we didn't add any more loss, or at least no more than 10 wei if we get slippage on deposit/withdrawal if is_slippery: @@ -201,7 +197,7 @@ def test_withdraw_after_donation_3( token.transfer(strategy, donation, {"from": whale}) # have our whale withdraws more than his donation, ensuring we pull from strategy - vault.withdraw(donation + amount / 2, {"from": whale}) + vault.withdraw(donation + amount / 2 - 100000, {"from": whale}) # simulate one day of earnings chain.sleep(86400) @@ -220,12 +216,10 @@ def test_withdraw_after_donation_3( # specifically check that our gain is greater than our donation or at least no more than 10 wei if we get slippage on deposit/withdrawal if is_slippery and no_profit: - assert math.isclose( - new_params["totalGain"] - prev_params["totalGain"], donation, abs_tol=10 - ) + assert math.isclose(profit, donation, abs_tol=10) else: - assert new_params["totalGain"] - prev_params["totalGain"] >= donation - assert profit >= 0 + assert profit > donation + assert profit > 0 # check that we didn't add any more loss, or at least no more than 10 wei if we get slippage on deposit/withdrawal if is_slippery: @@ -282,7 +276,7 @@ def test_withdraw_after_donation_4( token.transfer(strategy, donation, {"from": whale}) # have our whale withdraws more than his donation, ensuring we pull from strategy - vault.withdraw(donation + amount / 2, {"from": whale}) + vault.withdraw(donation + amount / 2 - 10000, {"from": whale}) # simulate one day of earnings chain.sleep(86400) @@ -301,12 +295,10 @@ def test_withdraw_after_donation_4( # specifically check that our gain is greater than our donation or at least no more than 10 wei if we get slippage on deposit/withdrawal if is_slippery and no_profit: - assert math.isclose( - new_params["totalGain"] - prev_params["totalGain"], donation, abs_tol=10 - ) + assert math.isclose(profit, donation, abs_tol=10) else: - assert new_params["totalGain"] - prev_params["totalGain"] >= donation - assert profit >= 0 + assert profit > donation + assert profit > 0 # check that we didn't add any more loss, or at least no more than 10 wei if we get slippage on deposit/withdrawal if is_slippery: @@ -357,7 +349,7 @@ def test_withdraw_after_donation_5( token.transfer(strategy, donation, {"from": whale}) # have our whale withdraws more than his donation, ensuring we pull from strategy - vault.withdraw(donation + amount / 2, {"from": whale}) + vault.withdraw(donation + amount / 2 - 10000, {"from": whale}) # simulate one day of earnings chain.sleep(86400) @@ -376,12 +368,10 @@ def test_withdraw_after_donation_5( # specifically check that our gain is greater than our donation or at least no more than 10 wei if we get slippage on deposit/withdrawal if is_slippery and no_profit: - assert math.isclose( - new_params["totalGain"] - prev_params["totalGain"], donation, abs_tol=10 - ) + assert math.isclose(profit, donation, abs_tol=10) else: - assert new_params["totalGain"] - prev_params["totalGain"] >= donation - assert profit >= 0 + assert profit > donation + assert profit > 0 # check that we didn't add any more loss, or at least no more than 10 wei if we get slippage on deposit/withdrawal if is_slippery: @@ -448,12 +438,10 @@ def test_withdraw_after_donation_6( # specifically check that our gain is greater than our donation or at least no more than 10 wei if we get slippage on deposit/withdrawal if is_slippery and no_profit: - assert math.isclose( - new_params["totalGain"] - prev_params["totalGain"], donation, abs_tol=10 - ) + assert math.isclose(profit, donation, abs_tol=10) else: - assert new_params["totalGain"] - prev_params["totalGain"] >= donation - assert profit >= 0 + assert profit > donation + assert profit > 0 # check that we didn't add any more loss, or at least no more than 10 wei if we get slippage on deposit/withdrawal if is_slippery: @@ -511,7 +499,7 @@ def test_withdraw_after_donation_7( token.transfer(strategy, donation, {"from": whale}) # have our whale withdraws more than his donation, ensuring we pull from strategy - withdrawal = donation + amount / 2 + withdrawal = donation + amount / 2 - 10000 vault.withdraw(withdrawal, {"from": whale}) # simulate one day of earnings @@ -536,7 +524,7 @@ def test_withdraw_after_donation_7( donation - withdrawal + prev_assets, current_assets, abs_tol=10 ) else: - assert current_assets >= donation - withdrawal + prev_assets + assert current_assets > donation - withdrawal + prev_assets new_params = vault.strategies(strategy).dict() @@ -552,12 +540,10 @@ def test_withdraw_after_donation_7( # specifically check that our gain is greater than our donation or at least no more than 10 wei if we get slippage on deposit/withdrawal if is_slippery and no_profit: - assert math.isclose( - new_params["totalGain"] - prev_params["totalGain"], donation, abs_tol=10 - ) + assert math.isclose(profit, donation, abs_tol=10) else: - assert new_params["totalGain"] - prev_params["totalGain"] >= donation - assert profit >= 0 + assert profit > donation + assert profit > 0 # check that we didn't add any more loss, or at least no more than 10 wei if we get slippage on deposit/withdrawal if is_slippery: @@ -631,7 +617,7 @@ def test_withdraw_after_donation_8( donation - withdrawal + prev_assets, current_assets, abs_tol=10 ) else: - assert current_assets >= donation - withdrawal + prev_assets + assert current_assets > donation - withdrawal + prev_assets new_params = vault.strategies(strategy).dict() @@ -647,12 +633,10 @@ def test_withdraw_after_donation_8( # specifically check that our gain is greater than our donation or at least no more than 10 wei if we get slippage on deposit/withdrawal if is_slippery and no_profit: - assert math.isclose( - new_params["totalGain"] - prev_params["totalGain"], donation, abs_tol=10 - ) + assert math.isclose(profit, donation, abs_tol=10) else: - assert new_params["totalGain"] - prev_params["totalGain"] >= donation - assert profit >= 0 + assert profit > donation + assert profit > 0 # check that we didn't add any more loss, or at least no more than 10 wei if we get slippage on deposit/withdrawal if is_slippery: