diff --git a/tests/fixtures/deployments.py b/tests/fixtures/deployments.py index 5a160b1..adfc902 100644 --- a/tests/fixtures/deployments.py +++ b/tests/fixtures/deployments.py @@ -2,7 +2,6 @@ from brownie import Contract from brownie_tokens import ERC20 - # ANYCALL DEPLOYMENT diff --git a/tests/reward_forwarder/test_deposit_reward.py b/tests/reward_forwarder/test_deposit_reward.py index d4f4cf0..f861afc 100644 --- a/tests/reward_forwarder/test_deposit_reward.py +++ b/tests/reward_forwarder/test_deposit_reward.py @@ -1,29 +1,46 @@ -import pytest import brownie +import pytest WEEK = 86400 * 7 -def test_reward_deposit(alice, bob, charlie, child_gauge, reward_forwarder, reward_token): +@pytest.fixture(scope="module", autouse=True) +def setup(alice, bob, charlie, child_gauge, reward_token, lp_token): - reward_token._mint_for_testing(charlie, 10 ** 26, {"from": alice}) - reward_forwarder.allow(reward_token, {"from": alice}) + lp_token.approve(child_gauge, 10**21, {"from": alice}) + lp_token._mint_for_testing(alice, 10**21, {"from": alice}) + child_gauge.deposit(10**21, {"from": alice}) + reward_token._mint_for_testing(charlie, 10**26, {"from": alice}) child_gauge.set_manager(bob, {"from": alice}) + + +@pytest.fixture(scope="module", autouse=False) +def setup_with_deposited_rewards(alice, bob, charlie, reward_forwarder, child_gauge, reward_token): + child_gauge.add_reward(reward_token, reward_forwarder, {"from": bob}) + reward_token.transfer(reward_forwarder, 10**20, {"from": charlie}) - reward_token.transfer(reward_forwarder, 10 ** 20, {"from": charlie}) + reward_forwarder.allow(reward_token, {"from": alice}) reward_forwarder.deposit_reward_token(reward_token, {"from": charlie}) - assert reward_token.balanceOf(child_gauge) == 10 ** 20 +def test_reward_deposit(alice, bob, charlie, child_gauge, reward_forwarder, reward_token): -def test_reward_token_approval(alice, bob, charlie, child_gauge, reward_forwarder, reward_token): + reward_forwarder.allow(reward_token, {"from": alice}) + child_gauge.add_reward(reward_token, reward_forwarder, {"from": bob}) + reward_token.transfer(reward_forwarder, 10**20, {"from": charlie}) + reward_forwarder.deposit_reward_token(reward_token, {"from": charlie}) - reward_token._mint_for_testing(charlie, 10 ** 26, {"from": alice}) - reward_token.transfer(reward_forwarder, 10 ** 20, {"from": charlie}) + assert reward_token.balanceOf(child_gauge) == 10**20 + assert child_gauge.reward_data(reward_token)["rate"] > 0 - child_gauge.set_manager(bob, {"from": alice}) + +def test_reward_deposit_reverts_without_allowance( + bob, charlie, child_gauge, reward_forwarder, reward_token +): + + reward_token.transfer(reward_forwarder, 10**20, {"from": charlie}) child_gauge.add_reward(reward_token, reward_forwarder, {"from": bob}) # empty reward_forwarder cannot transfer tokens unless `allow` is called @@ -31,11 +48,12 @@ def test_reward_token_approval(alice, bob, charlie, child_gauge, reward_forwarde reward_forwarder.deposit_reward_token(reward_token, {"from": charlie}) -def test_unauthorised_distributor(alice, charlie, reward_forwarder, reward_token): +def test_reward_deposit_reverts_with_unauthorised_distributor( + alice, charlie, reward_forwarder, reward_token +): - reward_token._mint_for_testing(charlie, 10 ** 26, {"from": alice}) reward_forwarder.allow(reward_token, {"from": alice}) - reward_token.transfer(reward_forwarder, 10 ** 20, {"from": charlie}) + reward_token.transfer(reward_forwarder, 10**20, {"from": charlie}) # reward_forwarder cannot deposit unless it is added as a distributor for that token # in the gauge contract @@ -43,57 +61,44 @@ def test_unauthorised_distributor(alice, charlie, reward_forwarder, reward_token reward_forwarder.deposit_reward_token(reward_token, {"from": charlie}) -def test_unauthorised_reward_token_for_authorised_distributor( +def test_reward_deposit_revert_for_unauthorised_token( alice, bob, charlie, child_gauge, reward_forwarder, reward_token, unauthorised_token ): - reward_token._mint_for_testing(charlie, 10 ** 26, {"from": alice}) - unauthorised_token._mint_for_testing(charlie, 10 ** 26, {"from": alice}) + unauthorised_token._mint_for_testing(charlie, 10**26, {"from": alice}) reward_forwarder.allow(reward_token, {"from": alice}) reward_forwarder.allow(unauthorised_token, {"from": alice}) # only add one token to gauge rewards - child_gauge.set_manager(bob, {"from": alice}) child_gauge.add_reward(reward_token, reward_forwarder, {"from": bob}) - reward_token.transfer(reward_forwarder, 10 ** 20, {"from": charlie}) - unauthorised_token.transfer(reward_forwarder, 10 ** 20, {"from": charlie}) + reward_token.transfer(reward_forwarder, 10**20, {"from": charlie}) + unauthorised_token.transfer(reward_forwarder, 10**20, {"from": charlie}) with brownie.reverts(): reward_forwarder.deposit_reward_token(unauthorised_token, {"from": charlie}) -def test_zero_reward_rate_claims( - alice, bob, charlie, child_gauge, chain, reward_forwarder, reward_token, lp_token +def test_reward_claim_when_reward_rate_is_zero( + alice, + bob, + charlie, + child_gauge, + chain, + reward_forwarder, + reward_token, + setup_with_deposited_rewards, ): - # mint lptokens and deposit into gauge: - lp_token.approve(child_gauge, 10 ** 21, {"from": alice}) - lp_token._mint_for_testing(alice, 10 ** 21, {"from": alice}) - child_gauge.deposit(10 ** 21, {"from": alice}) - - # mint reward tokens and approve transfers for RewardForwarder: - reward_token._mint_for_testing(charlie, 10 ** 26, {"from": alice}) - reward_forwarder.allow(reward_token, {"from": alice}) - - # set gauge managers: - child_gauge.set_manager(bob, {"from": alice}) - child_gauge.add_reward(reward_token, reward_forwarder, {"from": bob}) - - # deposit rewards and check if claimable reward token rate is non-zero: - reward_token.transfer(reward_forwarder, 10 ** 20, {"from": charlie}) - reward_forwarder.deposit_reward_token(reward_token, {"from": charlie}) - assert reward_token.balanceOf(reward_forwarder) == 0 # no tokens in the reward forwarder - assert child_gauge.reward_data(reward_token)[2] > 0 # token distribution rate is non-zero - - # sleep for a week until after period finish: chain.sleep(WEEK + 1) # sleep for 1 week and 1 second - assert chain.time() > child_gauge.reward_data(reward_token)[1] # `period_end` reached - # transferring zero reward tokens: this will make reward_token distribution rate zero + # reward forwarder has zero balance. Transferring zero reward tokens. reward_forwarder.deposit_reward_token(reward_token, {"from": charlie}) - assert child_gauge.reward_data(reward_token)[2] == 0 # token distribution rate becomes zero + + # Every deposit of a reward token checkpoints reward distribution, updating integrals for users + # Token distribution rate should become zero: + assert child_gauge.reward_data(reward_token)[2] == 0 # check alice's balance before and after claims: assert reward_token.balanceOf(alice) == 0 diff --git a/tests/root_gauge_factory_proxy/test_root_gauge_factory_proxy_admin.py b/tests/root_gauge_factory_proxy/test_root_gauge_factory_proxy_admin.py index 390bec4..b110f8b 100644 --- a/tests/root_gauge_factory_proxy/test_root_gauge_factory_proxy_admin.py +++ b/tests/root_gauge_factory_proxy/test_root_gauge_factory_proxy_admin.py @@ -1,275 +1,227 @@ import brownie +import pytest from brownie import ETH_ADDRESS -def test_set_manager(root_gauge_factory_proxy, alice, bob, charlie, chain): +@pytest.fixture(scope="module") +def default_owner(root_gauge_factory_proxy): + yield root_gauge_factory_proxy.ownership_admin() - default_ownership_admin = root_gauge_factory_proxy.ownership_admin() - default_emergency_admin = root_gauge_factory_proxy.emergency_admin() - assert root_gauge_factory_proxy.manager() == alice # contract deployer is manager - # unauthorised users cannot change the manager: +@pytest.fixture(scope="module") +def default_e_admin(root_gauge_factory_proxy): + yield root_gauge_factory_proxy.emergency_admin() + + +@pytest.fixture(scope="module") +def transfer_factory_ownership_to_proxy(alice, bob, root_gauge_factory, root_gauge_factory_proxy): + root_gauge_factory.commit_transfer_ownership(root_gauge_factory_proxy, {"from": alice}) + root_gauge_factory_proxy.accept_transfer_ownership(root_gauge_factory, {"from": bob}) + + +def test_set_manager_reverts_for_unauthorised_users(bob, charlie, root_gauge_factory_proxy): + with brownie.reverts(): root_gauge_factory_proxy.set_manager(charlie, {"from": bob}) - # emergency admin and ownership admin can become manager: - for acct in [default_emergency_admin, default_ownership_admin]: - root_gauge_factory_proxy.set_manager(acct, {"from": acct}) - assert root_gauge_factory_proxy.manager() == acct - chain.undo() - # authorised users can change the manager to anyone: - for acct in [default_emergency_admin, default_ownership_admin, alice]: +def test_set_manager_success_for_authorised_users( + alice, bob, root_gauge_factory_proxy, chain, default_owner, default_e_admin +): + + for acct in [alice, default_owner, default_e_admin]: root_gauge_factory_proxy.set_manager(bob, {"from": acct}) assert root_gauge_factory_proxy.manager() == bob chain.undo() -def test_transfer_proxy_admins(root_gauge_factory_proxy, alice, bob, charlie): - - default_ownership_admin = root_gauge_factory_proxy.ownership_admin() - default_emergency_admin = root_gauge_factory_proxy.emergency_admin() - - # --- - # commit future proxy owners +def test_commit_admin_reverts_for_unauthorised_users( + alice, bob, charlie, root_gauge_factory_proxy, default_e_admin +): - # manager cannot commit new admins - with brownie.reverts(): - root_gauge_factory_proxy.commit_set_admins(bob, charlie, {"from": alice}) + for user in [alice, bob, charlie, default_e_admin]: + with brownie.reverts(): + root_gauge_factory_proxy.commit_set_admins(bob, charlie, {"from": user}) - # unauthorised accounts cannot commit new admins - with brownie.reverts(): - root_gauge_factory_proxy.commit_set_admins(bob, bob, {"from": charlie}) - # emergency admin cannot commit new admins - with brownie.reverts(): - root_gauge_factory_proxy.commit_set_admins(bob, charlie, {"from": default_emergency_admin}) +@pytest.fixture(scope="module") +def test_commit_admin_successful_for_authorised_user( + alice, bob, charlie, root_gauge_factory_proxy, default_owner +): - # commit future owners - root_gauge_factory_proxy.commit_set_admins(bob, charlie, {"from": default_ownership_admin}) - assert root_gauge_factory_proxy.ownership_admin() == default_ownership_admin - assert root_gauge_factory_proxy.emergency_admin() == default_emergency_admin + root_gauge_factory_proxy.commit_set_admins(bob, charlie, {"from": default_owner}) assert root_gauge_factory_proxy.future_ownership_admin() == bob assert root_gauge_factory_proxy.future_emergency_admin() == charlie - # --- - # accept new proxy owners - # unauthorised accts cannot accept future ownership and emergency admins on behalf: - for acct in [default_ownership_admin, default_emergency_admin, alice, charlie]: +def test_accept_admin_revert_for_unauthorised_user( + alice, + charlie, + root_gauge_factory_proxy, + test_commit_admin_successful_for_authorised_user, + default_owner, + default_e_admin, +): + + for acct in [alice, charlie, default_owner, default_e_admin]: with brownie.reverts(): root_gauge_factory_proxy.accept_set_admins({"from": acct}) + +def test_accept_admin_success_for_future_ownership_admin( + root_gauge_factory_proxy, bob, charlie, test_commit_admin_successful_for_authorised_user +): + root_gauge_factory_proxy.accept_set_admins({"from": bob}) assert root_gauge_factory_proxy.ownership_admin() == bob assert root_gauge_factory_proxy.emergency_admin() == charlie -def test_transfer_ownership( - alice, bob, charlie, chain, root_gauge_factory, root_gauge_factory_proxy +def test_commit_transfer_ownership_reverts_for_unauthorised_users( + bob, charlie, root_gauge_factory, root_gauge_factory_proxy, default_owner, default_e_admin ): - default_ownership_admin = root_gauge_factory_proxy.ownership_admin() - default_emergency_admin = root_gauge_factory_proxy.emergency_admin() - - # --- - # commit transfer ownership: set gauge proxy as future factory owner - - assert root_gauge_factory.owner() == alice # alice is the owner - # since proxy contract is not an owner yet, this will revert: - for acct in [ - default_ownership_admin, - default_emergency_admin, - bob, - charlie, - root_gauge_factory_proxy, - ]: + for acct in [bob, charlie, root_gauge_factory_proxy, default_owner, default_e_admin]: with brownie.reverts(): root_gauge_factory_proxy.commit_transfer_ownership( root_gauge_factory, root_gauge_factory_proxy, {"from": acct} ) - # set proxy as future owner: only factory owner can do this + +def test_commit_transfer_ownership_success_for_factory_owner( + alice, root_gauge_factory, root_gauge_factory_proxy +): + root_gauge_factory.commit_transfer_ownership(root_gauge_factory_proxy, {"from": alice}) assert root_gauge_factory.future_owner() == root_gauge_factory_proxy - assert root_gauge_factory.owner() == alice # alice is still the owner + assert root_gauge_factory.owner() == alice - # --- - # accept transfer ownership: only proxy (root_gauge_factory.future_owner) can accept - # this is callable by anyone through the proxy - # unauthorised accounts cannot complete ownership transfer through the factory - for acct in [default_ownership_admin, default_emergency_admin, alice, bob, charlie]: - with brownie.reverts(): - root_gauge_factory.accept_transfer_ownership({"from": acct}) +def test_accept_transfer_ownership_success_for_authorised_admin( + alice, bob, charlie, chain, root_gauge_factory, root_gauge_factory_proxy +): - # completing transfer can be only be done through the root gauge factory proxy now + root_gauge_factory.commit_transfer_ownership(root_gauge_factory_proxy, {"from": alice}) for acct in [alice, bob, charlie]: root_gauge_factory_proxy.accept_transfer_ownership(root_gauge_factory, {"from": acct}) assert root_gauge_factory.owner() == root_gauge_factory_proxy chain.undo() -def test_set_killed( +def test_set_killed_success_for_authorised_admin( + chain, root_gauge, - root_gauge_factory, root_gauge_factory_proxy, - alice, - bob, - charlie, - chain, + transfer_factory_ownership_to_proxy, + default_owner, + default_e_admin, ): - default_ownership_admin = root_gauge_factory_proxy.ownership_admin() - default_emergency_admin = root_gauge_factory_proxy.emergency_admin() - - # alice deployed the factory and set herself as the owner of the factory contract - assert root_gauge_factory.owner() == alice - - # alice is the only one who can kill gauges - root_gauge.set_killed(True, {"from": alice}) - assert root_gauge.is_killed() - assert root_gauge.inflation_params()[0] == 0 # inflation rate of root gauge should be 0 - chain.undo() - - # proxy cannot kill gauges yet, and neither can alice do it through the proxy: - for unauthorised_admins in [ - default_emergency_admin, - default_ownership_admin, - alice, - ]: - with brownie.reverts(): - root_gauge_factory_proxy.set_killed(root_gauge, True, {"from": unauthorised_admins}) - - # so transfer root gauge factory ownership to proxy: - root_gauge_factory.commit_transfer_ownership(root_gauge_factory_proxy, {"from": alice}) - root_gauge_factory_proxy.accept_transfer_ownership(root_gauge_factory, {"from": bob}) - - # only proxy admins can kill a gauge: - for authorised_admin in [default_emergency_admin, default_ownership_admin]: + for authorised_admin in [default_owner, default_e_admin]: root_gauge_factory_proxy.set_killed(root_gauge, True, {"from": authorised_admin}) assert root_gauge.is_killed() - if root_gauge == root_gauge: - assert root_gauge.inflation_params()[0] == 0 # inflation rate of root gauge should be 0 + assert root_gauge.inflation_params()[0] == 0 # inflation rate of root gauge should be 0 chain.undo() - # unauthorised accounts cannot do so: + +def test_set_killed_reverts_for_unauthorised_users( + alice, bob, charlie, root_gauge, root_gauge_factory_proxy, transfer_factory_ownership_to_proxy +): + for unauthorised_acct in [alice, bob, charlie]: with brownie.reverts(): root_gauge_factory_proxy.set_killed(root_gauge, True, {"from": unauthorised_acct}) -def test_set_bridger(root_gauge_factory, root_gauge_factory_proxy, alice, bob, chain): - - default_ownership_admin = root_gauge_factory_proxy.ownership_admin() - default_emergency_admin = root_gauge_factory_proxy.emergency_admin() +def test_set_bridger_success_for_authorised_users( + root_gauge_factory, + root_gauge_factory_proxy, + chain, + transfer_factory_ownership_to_proxy, + default_owner, +): - assert root_gauge_factory.owner() == alice manager = root_gauge_factory_proxy.manager() - # proxy cannot set bridger yet: - for admin in [manager, default_ownership_admin]: - with brownie.reverts(): - root_gauge_factory_proxy.set_bridger( - root_gauge_factory, chain.id, ETH_ADDRESS, {"from": admin} - ) - - # so transfer root gauge factory ownership to proxy: - root_gauge_factory.commit_transfer_ownership(root_gauge_factory_proxy, {"from": alice}) - root_gauge_factory_proxy.accept_transfer_ownership(root_gauge_factory, {"from": bob}) - - for admin in [manager, default_ownership_admin]: + for acct in [manager, default_owner]: root_gauge_factory_proxy.set_bridger( - root_gauge_factory, chain.id, ETH_ADDRESS, {"from": admin} + root_gauge_factory, chain.id, ETH_ADDRESS, {"from": acct} ) assert root_gauge_factory.get_bridger(chain.id) == ETH_ADDRESS chain.undo() - # emergency admin cannot set bridger: - with brownie.reverts(): - root_gauge_factory_proxy.set_bridger( - root_gauge_factory, chain.id, ETH_ADDRESS, {"from": default_emergency_admin} - ) - # but emergency admin can set itself (or anyone) as manager and change bridger: - root_gauge_factory_proxy.set_manager(default_emergency_admin, {"from": default_emergency_admin}) - root_gauge_factory_proxy.set_bridger( - root_gauge_factory, chain.id, ETH_ADDRESS, {"from": default_emergency_admin} - ) - assert root_gauge_factory.get_bridger(chain.id) == ETH_ADDRESS - - -def test_set_implementation(root_gauge_factory, root_gauge_factory_proxy, alice, bob, chain): - - default_ownership_admin = root_gauge_factory_proxy.ownership_admin() - default_emergency_admin = root_gauge_factory_proxy.emergency_admin() +def test_set_bridger_revert_for_unauthorised_users( + bob, + charlie, + root_gauge_factory, + root_gauge_factory_proxy, + chain, + transfer_factory_ownership_to_proxy, + default_e_admin, +): - assert root_gauge_factory.owner() == alice - manager = root_gauge_factory_proxy.manager() - # proxy cannot set gauge implementation contract yet: - for admin in [manager, default_ownership_admin]: + for acct in [bob, charlie, default_e_admin]: with brownie.reverts(): - root_gauge_factory_proxy.set_implementation( - root_gauge_factory, ETH_ADDRESS, {"from": admin} + root_gauge_factory_proxy.set_bridger( + root_gauge_factory, chain.id, ETH_ADDRESS, {"from": acct} ) - # so transfer root gauge factory ownership to proxy: - root_gauge_factory.commit_transfer_ownership(root_gauge_factory_proxy, {"from": alice}) - root_gauge_factory_proxy.accept_transfer_ownership(root_gauge_factory, {"from": bob}) - for admin in [manager, default_ownership_admin]: - root_gauge_factory_proxy.set_implementation( - root_gauge_factory, ETH_ADDRESS, {"from": admin} - ) +def test_set_implementation_success_for_authorised_users( + root_gauge_factory, + root_gauge_factory_proxy, + chain, + transfer_factory_ownership_to_proxy, + default_owner, +): + + manager = root_gauge_factory_proxy.manager() + for acct in [manager, default_owner]: + root_gauge_factory_proxy.set_implementation(root_gauge_factory, ETH_ADDRESS, {"from": acct}) assert root_gauge_factory.get_implementation() == ETH_ADDRESS chain.undo() - # emergency admin cannot set gauge implementation: - with brownie.reverts(): - root_gauge_factory_proxy.set_implementation( - root_gauge_factory, ETH_ADDRESS, {"from": default_emergency_admin} - ) - - # but emergency admin can set itself (or anyone) as manager and change implementation: - root_gauge_factory_proxy.set_manager(default_emergency_admin, {"from": default_emergency_admin}) - root_gauge_factory_proxy.set_implementation( - root_gauge_factory, ETH_ADDRESS, {"from": default_emergency_admin} - ) - assert root_gauge_factory.get_implementation() == ETH_ADDRESS - -def test_set_call_proxy(root_gauge_factory, root_gauge_factory_proxy, alice, bob, chain): - - default_ownership_admin = root_gauge_factory_proxy.ownership_admin() - default_emergency_admin = root_gauge_factory_proxy.emergency_admin() +def test_set_implementation_revert_for_unauthorised_users( + bob, + charlie, + root_gauge_factory, + root_gauge_factory_proxy, + transfer_factory_ownership_to_proxy, + default_e_admin, +): - assert root_gauge_factory.owner() == alice - manager = root_gauge_factory_proxy.manager() - # proxy cannot set call proxy yet (only possible by factory owner): - for admin in [manager, default_ownership_admin]: + for acct in [bob, charlie, default_e_admin]: with brownie.reverts(): - root_gauge_factory_proxy.set_call_proxy( - root_gauge_factory, ETH_ADDRESS, {"from": admin} + root_gauge_factory_proxy.set_implementation( + root_gauge_factory, ETH_ADDRESS, {"from": acct} ) - # so transfer root gauge factory ownership to proxy: - root_gauge_factory.commit_transfer_ownership(root_gauge_factory_proxy, {"from": alice}) - root_gauge_factory_proxy.accept_transfer_ownership(root_gauge_factory, {"from": bob}) - for admin in [manager, default_ownership_admin]: - root_gauge_factory_proxy.set_call_proxy(root_gauge_factory, ETH_ADDRESS, {"from": admin}) +def test_set_call_proxy_success_for_authorised_users( + root_gauge_factory, + root_gauge_factory_proxy, + chain, + transfer_factory_ownership_to_proxy, + default_owner, +): + + manager = root_gauge_factory_proxy.manager() + for acct in [manager, default_owner]: + root_gauge_factory_proxy.set_call_proxy(root_gauge_factory, ETH_ADDRESS, {"from": acct}) assert root_gauge_factory.call_proxy() == ETH_ADDRESS chain.undo() - # emergency admin cannot set call proxy: - with brownie.reverts(): - root_gauge_factory_proxy.set_call_proxy( - root_gauge_factory, ETH_ADDRESS, {"from": default_emergency_admin} - ) - # but emergency admin can set itself (or anyone) as manager and - # change the gauge factory's call proxy - root_gauge_factory_proxy.set_manager(default_emergency_admin, {"from": default_emergency_admin}) - root_gauge_factory_proxy.set_call_proxy( - root_gauge_factory, ETH_ADDRESS, {"from": default_emergency_admin} - ) - assert root_gauge_factory.call_proxy() == ETH_ADDRESS +def test_set_call_proxy_revert_for_unauthorised_users( + bob, + charlie, + root_gauge_factory, + root_gauge_factory_proxy, + transfer_factory_ownership_to_proxy, + default_e_admin, +): + + for acct in [bob, charlie, default_e_admin]: + with brownie.reverts(): + root_gauge_factory_proxy.set_call_proxy(root_gauge_factory, ETH_ADDRESS, {"from": acct})