diff --git a/.gitignore b/.gitignore index f24e2dd..bde61ea 100644 --- a/.gitignore +++ b/.gitignore @@ -4,5 +4,6 @@ __pycache__ build/ reports/ .env +venv/ node_modules/ diff --git a/contracts/MyStrategy.sol b/contracts/MyStrategy.sol index 39b648b..d3ab249 100644 --- a/contracts/MyStrategy.sol +++ b/contracts/MyStrategy.sol @@ -21,7 +21,12 @@ import {IWeth} from "../interfaces/weth/IWeth.sol"; * Version 1: * - Basic version * Version 1.1: - * Fixes from CodeArena Contest + * - Fixes from CodeArena Contest + * Version 1.2: + * - Removes hardcoded redirection path for BADGER to the BadgerTree + * - Introduces bribes redirection paths for certain bribe tokens + * - Introduces the bribe redirection fee and processing + * - Introduces a setter function for the above */ contract MyStrategy is BaseStrategy, ReentrancyGuardUpgradeable { @@ -40,8 +45,6 @@ contract MyStrategy is BaseStrategy, ReentrancyGuardUpgradeable { IBalancerVault public constant BALANCER_VAULT = IBalancerVault(0xBA12222222228d8Ba445958a75a0704d566BF2C8); - address public constant BADGER = 0x3472A5A71965499acd81997a54BBA8D852C6E53d; - IAuraLocker public constant LOCKER = IAuraLocker(0x3Fa73f1E5d8A792C80F426fc8F84FBF7Ce9bBCAC); IERC20Upgradeable public constant BAL = IERC20Upgradeable(0xba100000625a3754423978a60c9317c58a424e3D); @@ -56,6 +59,11 @@ contract MyStrategy is BaseStrategy, ReentrancyGuardUpgradeable { uint256 private constant BPT_WETH_INDEX = 1; + // Bribe Token -> Bribe Recepient + mapping (address => address) public bribesRedirectionPaths; + // Bribe Token -> Redirection Fee + mapping (address => uint256) public redirectionFees; + event TreeDistribution( address indexed token, uint256 amount, @@ -63,6 +71,20 @@ contract MyStrategy is BaseStrategy, ReentrancyGuardUpgradeable { uint256 timestamp ); event RewardsCollected(address token, uint256 amount); + event RedirectionFee( + address indexed destination, + address indexed token, + uint256 amount, + uint256 indexed blockNumber, + uint256 timestamp + ); + event TokenRedirection( + address indexed destination, + address indexed token, + uint256 amount, + uint256 indexed blockNumber, + uint256 timestamp + ); /// @dev Initialize the Strategy with security settings as well as tokens /// @notice Proxies will set any non constant variable you declare as default value @@ -100,24 +122,45 @@ contract MyStrategy is BaseStrategy, ReentrancyGuardUpgradeable { LOCKER.delegate(delegate); } - ///@dev Should we check if the amount requested is more than what we can return on withdrawal? + /// @dev Should we check if the amount requested is more than what we can return on withdrawal? function setWithdrawalSafetyCheck(bool newWithdrawalSafetyCheck) external { _onlyGovernance(); withdrawalSafetyCheck = newWithdrawalSafetyCheck; } - ///@dev Should we processExpiredLocks during reinvest? + /// @dev Should we processExpiredLocks during reinvest? function setProcessLocksOnReinvest(bool newProcessLocksOnReinvest) external { _onlyGovernance(); processLocksOnReinvest = newProcessLocksOnReinvest; } - ///@dev Change the contract that handles bribes + /// @dev Change the contract that handles bribes function setBribesProcessor(IBribesProcessor newBribesProcessor) external { _onlyGovernance(); bribesProcessor = newBribesProcessor; } + /// @dev Sets the redirection path for a given token as well as the redirection fee to + /// process for it. + /// @notice There can only be one recepient per token, calling this function for the same + /// @notice token will replace the previous one. + /// @notice Adding a token to this mapping means that the full amount (minus the fee) of this + /// @notice token, claimed from HiddenHands, will be transfer to this recepient. + /// @param token Bribe token to redirect + /// @param recepient Address where redirected token will be transferred + /// @param redirectionFee Fee to be processed for the redirection service, different per token + function setRedirectionToken(address token, address recepient, uint256 redirectionFee) external { + _onlyGovernance(); + require(token != address(0), "Invalid token address"); + require(recepient != address(0), "Invalid recepient address"); + require(redirectionFee <= MAX_BPS, "Invalid redirection fee"); + + // Sets redirection path for a given token + bribesRedirectionPaths[token] = recepient; + // Sets redirection fees for a given token + redirectionFees[token] = redirectionFee; + } + /// @dev Function to move rewards that are not protected /// @notice Only not protected, moves the whole amount using _handleRewardTransfer /// @notice because token paths are hardcoded, this function is safe to be called by anyone @@ -153,7 +196,7 @@ contract MyStrategy is BaseStrategy, ReentrancyGuardUpgradeable { /// @dev Specify the version of the Strategy, for upgrades function version() external pure returns (string memory) { - return "1.1"; + return "1.2"; } /// @dev Does this function require `tend` to be called? @@ -308,7 +351,7 @@ contract MyStrategy is BaseStrategy, ReentrancyGuardUpgradeable { } } - /// @dev allows claiming of multiple bribes, badger is sent to tree + /// @dev allows claiming of multiple bribes /// @notice Hidden hand only allows to claim all tokens at once, not individually. /// Allows claiming any token as it uses the difference in balance function claimBribesFromHiddenHand(IRewardDistributor hiddenHandDistributor, IRewardDistributor.Claim[] calldata _claims) external nonReentrant { @@ -347,17 +390,21 @@ contract MyStrategy is BaseStrategy, ReentrancyGuardUpgradeable { // ETH uint256 difference = address(this).balance.sub(beforeBalance[i]); if (difference > 0) { + address recepient = bribesRedirectionPaths[address(WETH)]; IWeth(address(WETH)).deposit{value: difference}(); - nonZeroDiff = true; - _handleRewardTransfer(address(WETH), difference); + if (recepient == address(0)) { + nonZeroDiff = true; + } + _handleRewardTransfer(address(WETH), recepient, difference); } } else { uint256 difference = IERC20Upgradeable(token).balanceOf(address(this)).sub(beforeBalance[i]); if (difference > 0) { - if (token != BADGER) { + address recepient = bribesRedirectionPaths[token]; + if (recepient == address(0)) { nonZeroDiff = true; } - _handleRewardTransfer(token, difference); + _handleRewardTransfer(token, recepient, difference); } } } @@ -430,12 +477,12 @@ contract MyStrategy is BaseStrategy, ReentrancyGuardUpgradeable { } /// *** Handling of rewards *** - function _handleRewardTransfer(address token, uint256 amount) internal { - // NOTE: BADGER is emitted through the tree - if (token == BADGER) { - _sendBadgerToTree(amount); + function _handleRewardTransfer(address token, address recepient, uint256 amount) internal { + // NOTE: Tokens with an assigned recepient are sent there + if (recepient != address(0)) { + _sendTokenToBriber(token, recepient, amount); + // NOTE: All other tokens are sent to the bribes processor } else { - // NOTE: All other tokens are sent to bribes processor _sendTokenToBribesProcessor(token, amount); } } @@ -453,18 +500,43 @@ contract MyStrategy is BaseStrategy, ReentrancyGuardUpgradeable { emit RewardsCollected(token, amount); } - /// @dev Send the BADGER token to the badgerTree - function _sendBadgerToTree(uint256 amount) internal { - // Transfer to tree without taking any fee - IERC20Upgradeable(BADGER).safeTransfer(IVault(vault).badgerTree(), amount); - emit TreeDistribution(BADGER, amount, block.number, block.timestamp); + /// @dev Takes a fee on the token and sends remaining to the given briber recepient + function _sendTokenToBriber(address token, address recepient, uint256 amount) internal { + // Process redirection fee + uint256 redirectionFee = amount.mul(redirectionFees[token]).div(MAX_BPS); + if (redirectionFee > 0) { + IERC20Upgradeable(token).safeTransfer(IVault(vault).treasury(), redirectionFee); + emit RedirectionFee( + IVault(vault).treasury(), + token, + redirectionFee, + block.number, + block.timestamp + ); + } + + // Send remaining to bribe recepient + // NOTE: Calculating instead of checking balance since there could have been an + // existing balance on the contract beforehand (Could be 0 if fee == MAX_BPS) + uint256 redirectionAmount = amount.sub(redirectionFee); + if (redirectionAmount > 0) { + IERC20Upgradeable(token).safeTransfer(recepient, redirectionAmount); + emit TokenRedirection( + recepient, + token, + redirectionAmount, + block.number, + block.timestamp + ); + } } function _sweepRewardToken(address token) internal { _onlyNotProtectedTokens(token); uint256 toSend = IERC20Upgradeable(token).balanceOf(address(this)); - _handleRewardTransfer(token, toSend); + address recepient = bribesRedirectionPaths[token]; + _handleRewardTransfer(token, recepient, toSend); } /// PAYABLE FUNCTIONS /// diff --git a/tests/conftest.py b/tests/conftest.py index ed52039..c3a8083 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -4,6 +4,7 @@ MyStrategy, TheVault, MockRewardDistributor, + MockBribesProcessor, interface, accounts, chain, @@ -247,6 +248,13 @@ def reward_distributor(deployer): return MockRewardDistributor.deploy({"from": deployer}) +@pytest.fixture +def bribes_processor(deployer, strategy, governance): + processor = MockBribesProcessor.deploy({"from": deployer}) + strategy.setBribesProcessor(processor, {"from": governance}) + return processor + + ## Forces reset before each test @pytest.fixture(autouse=True) def isolation(fn_isolation): diff --git a/tests/integration/test_claim_bribes.py b/tests/integration/test_claim_bribes.py index a28820b..de809d6 100644 --- a/tests/integration/test_claim_bribes.py +++ b/tests/integration/test_claim_bribes.py @@ -1,19 +1,27 @@ import pytest import brownie - +from helpers.constants import AddressZero from brownie import ( accounts, interface, - web3, - MockBribesProcessor, + web3 ) +# Tokens BADGER = "0x3472A5A71965499acd81997a54BBA8D852C6E53d" +GNO = "0x6810e776880C02933D47DB1b9fc05908e5386b96" +USDC = "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48" + +# Whales BADGER_WHALE = "0xF977814e90dA44bFA03b6295A0616a897441aceC" +GNO_WHALE = "0xeC83f750adfe0e52A8b0DbA6eeB6be5Ba0beE535" +USDC_WHALE = "0x0A59649758aa4d66E25f08Dd01271e891fe52199" ETH_IDENTIFIER = web3.keccak(text="ETH") BADGER_IDENTIFIER = web3.keccak(text="BADGER") WANT_IDENTIFIER = web3.keccak(text="WANT") +GNO_IDENTIFIER = web3.keccak(text="GNO") +USDC_IDENTIFIER = web3.keccak(text="USDC") @pytest.fixture @@ -22,16 +30,29 @@ def badger(deployer): badger.transfer(deployer, 100e18, {"from": BADGER_WHALE}) return badger +@pytest.fixture +def gno(deployer): + gno = interface.IERC20Detailed(GNO) + gno.transfer(deployer, 100e18, {"from": GNO_WHALE}) + return gno @pytest.fixture -def bribes_processor(deployer, strategy, governance): - processor = MockBribesProcessor.deploy({"from": deployer}) - strategy.setBribesProcessor(processor, {"from": governance}) - return processor +def usdc(deployer): + usdc = interface.IERC20Detailed(USDC) + usdc.transfer(deployer, 100e8, {"from": USDC_WHALE}) + return usdc + +@pytest.fixture +def weth(deployer, strategy): + amount = 1e18 + weth = interface.IWeth(strategy.WETH()) + weth.deposit({"from": deployer, "value": amount}) + weth = interface.IERC20Detailed(weth.address) + return weth @pytest.fixture(autouse=True) -def reward_distributor_setup(want, badger, deployer, reward_distributor): +def reward_distributor_setup(want, badger, gno, usdc, deployer, reward_distributor): accounts.at(deployer).transfer(reward_distributor, "1 ether") reward_distributor.addReward(WANT_IDENTIFIER, want, {"from": deployer}) @@ -41,9 +62,27 @@ def reward_distributor_setup(want, badger, deployer, reward_distributor): reward_distributor.addReward(BADGER_IDENTIFIER, badger, {"from": deployer}) amount = badger.balanceOf(deployer) // 2 badger.transfer(reward_distributor, amount, {"from": deployer}) + + reward_distributor.addReward(GNO_IDENTIFIER, gno, {"from": deployer}) + amount = gno.balanceOf(deployer) // 2 + gno.transfer(reward_distributor, amount, {"from": deployer}) + + reward_distributor.addReward(USDC_IDENTIFIER, usdc, {"from": deployer}) + amount = usdc.balanceOf(deployer) // 2 + usdc.transfer(reward_distributor, amount, {"from": deployer}) + return reward_distributor +@pytest.fixture +def gno_recepient(): + return accounts[7] + +@pytest.fixture +def weth_recepient(): + return accounts[9] + + def test_claim_bribes(want, strategy, bribes_processor, reward_distributor, strategist, deployer): balance_before = want.balanceOf(bribes_processor) @@ -64,26 +103,6 @@ def test_claim_bribes(want, strategy, bribes_processor, reward_distributor, stra assert claim_tx.events["RewardsCollected"]["amount"] == amount -def test_claim_bribes_badger(badger, badgerTree, strategy, reward_distributor, bribes_processor, strategist, deployer): - balance_before = badger.balanceOf(badgerTree) - - amount = badger.balanceOf(deployer) // 2 - assert amount > 0 - - claim_tx = strategy.claimBribesFromHiddenHand( - reward_distributor, - [ - (BADGER_IDENTIFIER, strategy, amount, []) - ], - {"from": strategist} - ) - - assert badger.balanceOf(badgerTree) == balance_before + amount - - assert claim_tx.events["TreeDistribution"]["token"] == badger - assert claim_tx.events["TreeDistribution"]["amount"] == amount - - def test_claim_eth_bribes(strategy, strategist, bribes_processor, reward_distributor): weth = interface.IERC20Detailed(strategy.WETH()) balance_before = weth.balanceOf(bribes_processor) @@ -102,13 +121,8 @@ def test_claim_eth_bribes(strategy, strategist, bribes_processor, reward_distrib assert claim_tx.events["RewardsCollected"]["amount"] == amount -def test_sweep_weth(strategy, strategist, bribes_processor, deployer): +def test_sweep_weth(strategy, strategist, bribes_processor, deployer, weth): amount = 1e18 - - weth = interface.IWeth(strategy.WETH()) - weth.deposit({"from": deployer, "value": amount}) - - weth = interface.IERC20Detailed(weth.address) weth.transfer(strategy, amount, {"from": deployer}) balance_before_proc = weth.balanceOf(bribes_processor) @@ -130,3 +144,114 @@ def test_bribe_claiming_no_processor(want, deployer, strategy, strategist, rewar ], {"from": strategist} ) + +def test_claim_bribes_with_redirection( + badger, + gno, + usdc, + weth, + gno_recepient, + weth_recepient, + vault, + strategy, + reward_distributor, + bribes_processor, + strategist, + deployer, + governance +): + treasury = vault.treasury() + + # Setting BADGER to be redirected to deployer with a fee + strategy.setRedirectionToken(badger, deployer, 1500, {"from": governance}) + assert strategy.bribesRedirectionPaths(badger) == deployer + assert strategy.redirectionFees(badger) == 1500 + + # Calling again for BADGER changes settings to treausury as recepeint and 0 fee + strategy.setRedirectionToken(badger, treasury, 0, {"from": governance}) + assert strategy.bribesRedirectionPaths(badger) == treasury + assert strategy.redirectionFees(badger) == 0 + + # Test invalid settings + with brownie.reverts("Invalid token address"): + strategy.setRedirectionToken(AddressZero, treasury, 0, {"from": governance}) + with brownie.reverts("Invalid recepient address"): + strategy.setRedirectionToken(badger, AddressZero, 0, {"from": governance}) + with brownie.reverts("Invalid redirection fee"): + strategy.setRedirectionToken(badger, treasury, 20000, {"from": governance}) + + # Setting GNO to be redirected to its intended recepient with a 15% fee + strategy.setRedirectionToken(gno, gno_recepient, 1500, {"from": governance}) + assert strategy.bribesRedirectionPaths(gno) == gno_recepient + assert strategy.redirectionFees(gno) == 1500 + + # Setting ETH to be redirected to its intended recepient with a 10% fee + strategy.setRedirectionToken(weth, weth_recepient, 1000, {"from": governance}) + assert strategy.bribesRedirectionPaths(weth) == weth_recepient + assert strategy.redirectionFees(weth) == 1000 + + # NOTE: USDC is not redirected + + badger_amount = badger.balanceOf(reward_distributor) + gno_amount = gno.balanceOf(reward_distributor) + usdc_amount = usdc.balanceOf(reward_distributor) + eth_amount = reward_distributor.balance() + assert badger_amount > 0 + assert gno_amount > 0 + assert usdc_amount > 0 + assert eth_amount > 0 + + badger_recepient_balance_before = badger.balanceOf(treasury) + gno_recepient_balance_before = gno.balanceOf(gno_recepient) + weth_recepient_balance_before = weth.balanceOf(weth_recepient) + usdc_processor_balance_before = usdc.balanceOf(bribes_processor) + + # Batch claim tokens + claim_tx = strategy.claimBribesFromHiddenHand( + reward_distributor, + [ + (BADGER_IDENTIFIER, strategy, badger_amount, []), + (GNO_IDENTIFIER, strategy, gno_amount, []), + (USDC_IDENTIFIER, strategy, usdc_amount, []), + (ETH_IDENTIFIER, strategy, eth_amount, []) + ], + {"from": strategist} + ) + + # Check that redirection fee was processed + event = claim_tx.events["RedirectionFee"] + assert len(event) == 2 # Both GNO and ETH have fees assigned to them + # Confirm GNO event + expected_gno_fee_amount = gno_amount * strategy.redirectionFees(gno) / 10000 + assert event[0]["destination"] == treasury + assert event[0]["token"] == gno + assert event[0]["amount"] == expected_gno_fee_amount + assert gno.balanceOf(treasury) == expected_gno_fee_amount + # Confirm ETH event + expected_weth_fee_amount = eth_amount * strategy.redirectionFees(weth) / 10000 + assert event[1]["destination"] == treasury + assert event[1]["token"] == weth + assert event[1]["amount"] == expected_weth_fee_amount + assert weth.balanceOf(treasury) == expected_weth_fee_amount + + # Check that the TokenRedirection event was emitted + event = claim_tx.events["TokenRedirection"] + assert len(event) == 3 + # Confirm BADGER event + assert event[0]["destination"] == treasury + assert event[0]["token"] == badger + assert event[0]["amount"] == badger_amount + # Confirm GNO event + assert event[1]["destination"] == gno_recepient + assert event[1]["token"] == gno + assert event[1]["amount"] == gno_recepient_balance_before + gno_amount - expected_gno_fee_amount + # Confirm ETH event + assert event[2]["destination"] == weth_recepient + assert event[2]["token"] == weth + assert event[2]["amount"] == weth_recepient_balance_before + eth_amount - expected_weth_fee_amount + + # Check accounting + assert badger.balanceOf(treasury) == badger_recepient_balance_before + badger_amount + assert gno.balanceOf(gno_recepient) == gno_recepient_balance_before + gno_amount - expected_gno_fee_amount + assert weth.balanceOf(weth_recepient) == weth_recepient_balance_before + eth_amount - expected_weth_fee_amount + assert usdc.balanceOf(bribes_processor) == usdc_processor_balance_before + usdc_amount \ No newline at end of file diff --git a/tests/integration/test_strategy_permissions.py b/tests/integration/test_strategy_permissions.py index 7848f6d..db748e1 100644 --- a/tests/integration/test_strategy_permissions.py +++ b/tests/integration/test_strategy_permissions.py @@ -108,6 +108,46 @@ def test_strategy_action_permissions( with brownie.reverts("onlyGovernanceOrStrategist"): vault.sweepExtraToken(vault, {"from": actor}) + # setRedirectionToken + for actor in actorsToCheck: + if actor == strategy.governance(): + strategy.setRedirectionToken(want, deployer, 1500, {"from": actor}) + else: + with brownie.reverts("onlyGovernance"): + strategy.setRedirectionToken(want, deployer, 1500, {"from": actor}) + + # setBribesProcessor + for actor in actorsToCheck: + if actor == strategy.governance(): + strategy.setBribesProcessor(accounts[5], {"from": actor}) + else: + with brownie.reverts("onlyGovernance"): + strategy.setBribesProcessor(accounts[5], {"from": actor}) + + # setProcessLocksOnReinvest + for actor in actorsToCheck: + if actor == strategy.governance(): + strategy.setProcessLocksOnReinvest(False, {"from": actor}) + else: + with brownie.reverts("onlyGovernance"): + strategy.setProcessLocksOnReinvest(False, {"from": actor}) + + # setWithdrawalSafetyCheck + for actor in actorsToCheck: + if actor == strategy.governance(): + strategy.setWithdrawalSafetyCheck(False, {"from": actor}) + else: + with brownie.reverts("onlyGovernance"): + strategy.setWithdrawalSafetyCheck(False, {"from": actor}) + + # setWithdrawalSafetyCheck + for actor in actorsToCheck: + if actor == strategy.governance(): + strategy.manualSetDelegate(deployer, {"from": actor}) + else: + with brownie.reverts("onlyGovernance"): + strategy.manualSetDelegate(deployer, {"from": actor}) + def test_strategy_pausing_permissions(deployer, vault, strategy, want, keeper): # Setup diff --git a/tests/test_custom.py b/tests/test_custom.py index 04a92ed..dfef341 100644 --- a/tests/test_custom.py +++ b/tests/test_custom.py @@ -1,5 +1,5 @@ import brownie -from brownie import * +from brownie import interface, chain, accounts from helpers.constants import MaxUint256 from helpers.SnapshotManager import SnapshotManager from helpers.time import days @@ -10,6 +10,8 @@ See test_strategy_permissions, for tests at the permissions level """ +BB_A_USD = "0x7B50775383d3D6f0215A8F290f2C9e2eEBBEceb2" +BB_A_USD_WHALE = "0xBA12222222228d8Ba445958a75a0704d566BF2C8" def test_after_wait_withdrawSome_unlocks_for_caller(setup_strat, want, vault, deployer): ## Try to withdraw all, fail because locked @@ -190,6 +192,37 @@ def test_cant_sweep_want(want, strategy, strategist): strategy.sweepRewards([want], {"from": strategist}) +def test_sweep_rewards(strategy, strategist, bribes_processor): + # Transfer exra reward tokens to the strategy + amount = 1000e18 + bbausd = interface.IERC20Detailed(BB_A_USD) + whale = accounts.at(BB_A_USD_WHALE, force=True) + bbausd.transfer(strategy, amount, {"from": whale}) + + # A non protected token can be swept + balance_processor_before = bbausd.balanceOf(bribes_processor) + strategy.sweepRewardToken(bbausd, {"from": strategist}) + assert bbausd.balanceOf(bribes_processor) == balance_processor_before + amount + + +def test_sweep_rewards_with_redirection(strategy, strategist, governance, bribes_processor): + # Transfer exra reward tokens to the strategy + amount = 1000e18 + bbausd = interface.IERC20Detailed(BB_A_USD) + whale = accounts.at(BB_A_USD_WHALE, force=True) + bbausd.transfer(strategy, amount, {"from": whale}) + + # Set redirection path (no fee for simplicity) + strategy.setRedirectionToken(bbausd, strategist, 0, {"from": governance}) + assert strategy.bribesRedirectionPaths(bbausd) == strategist + assert strategy.redirectionFees(bbausd) == 0 + + # A non protected token can be swept to its redirection recepient + balance_recepient_before = bbausd.balanceOf(strategist) + strategy.sweepRewardToken(bbausd, {"from": strategist}) + assert bbausd.balanceOf(strategist) == balance_recepient_before + amount + + def test_cant_take_eth(deployer, strategy): with brownie.reverts("onlyWhileClaiming"): accounts.at(deployer).transfer(strategy, "1 ether") diff --git a/tests/upgrade/test_upgrade.py b/tests/upgrade/test_upgrade.py index 49fdf19..f73a035 100644 --- a/tests/upgrade/test_upgrade.py +++ b/tests/upgrade/test_upgrade.py @@ -36,39 +36,25 @@ def test_check_storage_integrity(strat_proxy, vault_proxy, deployer, proxy_admin old_withdrawalSafetyCheck = strat_proxy.withdrawalSafetyCheck() old_processLocksOnReinvest = strat_proxy.processLocksOnReinvest() old_bribesProcessor = strat_proxy.bribesProcessor() - - with brownie.reverts(): - strat_proxy.auraBalToBalEthBptMinOutBps() + old_auraBalToBalEthBptMinOutBps = strat_proxy.auraBalToBalEthBptMinOutBps() - logics = [ - MyStrategy.deploy({"from": deployer}), - MyStrategy.at("0x0d724E8AEE6F73b35A596C8C947c92c75eAc7818") - ] + logic = MyStrategy.deploy({"from": deployer}) - chain.snapshot() - for new_strat_logic in logics: - ## Do the Upgrade - proxy_admin.upgrade(strat_proxy, new_strat_logic, {"from": proxy_admin_gov}) + ## Do the Upgrade + proxy_admin.upgrade(strat_proxy, logic, {"from": proxy_admin_gov}) - ## Check Integrity - assert old_want == strat_proxy.want() - assert old_vault == strat_proxy.vault() - assert old_withdrawalMaxDeviationThreshold == strat_proxy.withdrawalMaxDeviationThreshold() - assert old_autoCompoundRatio == strat_proxy.autoCompoundRatio() - assert old_withdrawalSafetyCheck == strat_proxy.withdrawalSafetyCheck() - assert old_processLocksOnReinvest == strat_proxy.processLocksOnReinvest() - assert old_bribesProcessor == strat_proxy.bribesProcessor() + ## Check Integrity + assert old_want == strat_proxy.want() + assert old_vault == strat_proxy.vault() + assert old_withdrawalMaxDeviationThreshold == strat_proxy.withdrawalMaxDeviationThreshold() + assert old_autoCompoundRatio == strat_proxy.autoCompoundRatio() + assert old_withdrawalSafetyCheck == strat_proxy.withdrawalSafetyCheck() + assert old_processLocksOnReinvest == strat_proxy.processLocksOnReinvest() + assert old_bribesProcessor == strat_proxy.bribesProcessor() + assert old_auraBalToBalEthBptMinOutBps == strat_proxy.auraBalToBalEthBptMinOutBps() - assert strat_proxy.auraBalToBalEthBptMinOutBps() == 0 + gov = accounts.at(vault_proxy.governance(), force=True) - gov = accounts.at(vault_proxy.governance(), force=True) - - # Set slippage tolerance - strat_proxy.setAuraBalToBalEthBptMinOutBps(9500, {"from": gov}) - assert strat_proxy.auraBalToBalEthBptMinOutBps() == 9500 - - ## Let's do a quick earn and harvest as well - vault_proxy.earn({"from": gov}) - strat_proxy.harvest({"from": gov}) - - chain.revert() + ## Let's do a quick earn and harvest as well + vault_proxy.earn({"from": gov}) + strat_proxy.harvest({"from": gov}) \ No newline at end of file