diff --git a/contracts/core/BotListV3.sol b/contracts/core/BotListV3.sol index 883a70ef..d7321dff 100644 --- a/contracts/core/BotListV3.sol +++ b/contracts/core/BotListV3.sol @@ -15,8 +15,11 @@ import { IncorrectBotPermissionsException, InvalidBotException } from "../interfaces/IExceptions.sol"; +import {IAddressProvider} from "../interfaces/base/IAddressProvider.sol"; import {IBot} from "../interfaces/base/IBot.sol"; +import {AP_INSTANCE_MANAGER_PROXY, NO_VERSION_CONTROL} from "../libraries/Constants.sol"; + import {SanityCheckTrait} from "../traits/SanityCheckTrait.sol"; /// @title Bot list V3 @@ -37,9 +40,11 @@ contract BotListV3 is IBotListV3, SanityCheckTrait, Ownable { mapping(address => mapping(address => EnumerableSet.AddressSet)) internal _activeBots; /// @notice Constructor - /// @param owner_ Contract owner - constructor(address owner_) { - transferOwnership(owner_); + /// @param addressProvider_ Address provider contract address + constructor(address addressProvider_) { + transferOwnership( + IAddressProvider(addressProvider_).getAddressOrRevert(AP_INSTANCE_MANAGER_PROXY, NO_VERSION_CONTROL) + ); } // ----------- // diff --git a/contracts/core/DefaultAccountFactoryV3.sol b/contracts/core/DefaultAccountFactoryV3.sol index 87cb759c..49d7d491 100644 --- a/contracts/core/DefaultAccountFactoryV3.sol +++ b/contracts/core/DefaultAccountFactoryV3.sol @@ -15,6 +15,9 @@ import { CreditAccountIsInUseException, MasterCreditAccountAlreadyDeployedException } from "../interfaces/IExceptions.sol"; +import {IAddressProvider} from "../interfaces/base/IAddressProvider.sol"; + +import {AP_INSTANCE_MANAGER_PROXY, NO_VERSION_CONTROL} from "../libraries/Constants.sol"; /// @dev Struct holding factory and queue params for a credit manager /// @param masterCreditAccount Address of the contract to clone to create new accounts for the credit manager @@ -57,9 +60,11 @@ contract DefaultAccountFactoryV3 is IDefaultAccountFactoryV3, Ownable { mapping(address => mapping(uint256 => QueuedAccount)) internal _queuedAccounts; /// @notice Constructor - /// @param owner_ Contract owner - constructor(address owner_) { - transferOwnership(owner_); + /// @param addressProvider_ Address provider contract address + constructor(address addressProvider_) { + transferOwnership( + IAddressProvider(addressProvider_).getAddressOrRevert(AP_INSTANCE_MANAGER_PROXY, NO_VERSION_CONTROL) + ); } /// @notice Provides a reusable credit account from the queue to the credit manager. diff --git a/contracts/core/GearStakingV3.sol b/contracts/core/GearStakingV3.sol index 4911baa6..62015066 100644 --- a/contracts/core/GearStakingV3.sol +++ b/contracts/core/GearStakingV3.sol @@ -17,9 +17,17 @@ import { VotingContractStatus } from "../interfaces/IGearStakingV3.sol"; import "../interfaces/IExceptions.sol"; +import {IAddressProvider} from "../interfaces/base/IAddressProvider.sol"; import {IVotingContract} from "../interfaces/base/IVotingContract.sol"; -import {EPOCHS_TO_WITHDRAW, EPOCH_LENGTH} from "../libraries/Constants.sol"; +import { + AP_GEAR_TOKEN, + AP_CROSS_CHAIN_GOVERNANCE_PROXY, + EPOCHS_TO_WITHDRAW, + EPOCH_LENGTH, + FIRST_EPOCH_TIMESTAMP, + NO_VERSION_CONTROL +} from "../libraries/Constants.sol"; import {ReentrancyGuardTrait} from "../traits/ReentrancyGuardTrait.sol"; import {SanityCheckTrait} from "../traits/SanityCheckTrait.sol"; @@ -39,7 +47,7 @@ contract GearStakingV3 is IGearStakingV3, Ownable, ReentrancyGuardTrait, SanityC address public immutable override gear; /// @notice Timestamp of the first epoch of voting - uint256 public immutable override firstEpochTimestamp; + uint256 public constant override firstEpochTimestamp = FIRST_EPOCH_TIMESTAMP; /// @dev Mapping from user to their stake amount and tokens available for voting mapping(address => UserVoteLockData) internal voteLockData; @@ -63,14 +71,12 @@ contract GearStakingV3 is IGearStakingV3, Ownable, ReentrancyGuardTrait, SanityC } /// @notice Constructor - /// @param owner_ Contract owner - /// @param gear_ GEAR token address - /// @param firstEpochTimestamp_ Timestamp at which the first epoch should start. - /// Setting this too far into the future poses a risk of locking user deposits. - constructor(address owner_, address gear_, uint256 firstEpochTimestamp_) { - gear = gear_; // U:[GS-1] - firstEpochTimestamp = firstEpochTimestamp_; // U:[GS-1] - transferOwnership(owner_); // U:[GS-1] + /// @param addressProvider_ Address provider contract address + constructor(address addressProvider_) { + gear = IAddressProvider(addressProvider_).getAddressOrRevert(AP_GEAR_TOKEN, NO_VERSION_CONTROL); // U:[GS-1] + transferOwnership( + IAddressProvider(addressProvider_).getAddressOrRevert(AP_CROSS_CHAIN_GOVERNANCE_PROXY, NO_VERSION_CONTROL) + ); // U:[GS-1] } /// @notice Stakes given amount of GEAR, and, optionally, performs a sequence of votes diff --git a/contracts/interfaces/base/IAddressProvider.sol b/contracts/interfaces/base/IAddressProvider.sol new file mode 100644 index 00000000..f16366a8 --- /dev/null +++ b/contracts/interfaces/base/IAddressProvider.sol @@ -0,0 +1,8 @@ +// SPDX-License-Identifier: MIT +// Gearbox Protocol. Generalized leverage for DeFi protocols +// (c) Gearbox Foundation, 2024. +pragma solidity ^0.8.17; + +interface IAddressProvider { + function getAddressOrRevert(bytes32 key, uint256 version) external view returns (address); +} diff --git a/contracts/interfaces/base/IDegenNFT.sol b/contracts/interfaces/base/IDegenNFT.sol index e6e63781..4c139d3d 100644 --- a/contracts/interfaces/base/IDegenNFT.sol +++ b/contracts/interfaces/base/IDegenNFT.sol @@ -3,6 +3,12 @@ // (c) Gearbox Foundation, 2024. pragma solidity ^0.8.17; -interface IDegenNFT { +import {IVersion} from "./IVersion.sol"; + +/// @title Degen NFT interface +/// @notice Generic interface for a Degen NFT contract that can be used to restrict +/// non-whitelisted users from opening accounts through the credit facade +/// @dev Degen NFTs must have type `DEGEN_NFT::{POSTFIX}` +interface IDegenNFT is IVersion { function burn(address from, uint256 amount) external; } diff --git a/contracts/libraries/Constants.sol b/contracts/libraries/Constants.sol index b3c9e055..96e02199 100644 --- a/contracts/libraries/Constants.sol +++ b/contracts/libraries/Constants.sol @@ -3,12 +3,18 @@ // (c) Gearbox Foundation, 2024. pragma solidity ^0.8.17; +bytes32 constant AP_GEAR_TOKEN = "GEAR_TOKEN"; +bytes32 constant AP_INSTANCE_MANAGER_PROXY = "INSTANCE_MANAGER_PROXY"; +bytes32 constant AP_CROSS_CHAIN_GOVERNANCE_PROXY = "CROSS_CHAIN_GOVERNANCE_PROXY"; +uint256 constant NO_VERSION_CONTROL = 0; + uint256 constant WAD = 1e18; uint256 constant RAY = 1e27; uint16 constant PERCENTAGE_FACTOR = 1e4; uint256 constant SECONDS_PER_YEAR = 365 days; uint256 constant EPOCH_LENGTH = 7 days; +uint256 constant FIRST_EPOCH_TIMESTAMP = 1702900800; uint256 constant EPOCHS_TO_WITHDRAW = 4; uint8 constant MAX_WITHDRAW_FEE = 100; diff --git a/contracts/test/helpers/IntegrationTestHelper.sol b/contracts/test/helpers/IntegrationTestHelper.sol index 325013c4..3ad610e5 100644 --- a/contracts/test/helpers/IntegrationTestHelper.sol +++ b/contracts/test/helpers/IntegrationTestHelper.sol @@ -240,6 +240,7 @@ contract IntegrationTestHelper is TestHelper, BalanceHelper, ConfigManager { botList = gp.botList(); cr = gp.contractsRegister(); gearStaking = gp.gearStaking(); + vm.warp(gearStaking.firstEpochTimestamp()); vm.stopPrank(); } diff --git a/contracts/test/integration/credit/Bots.int.sol b/contracts/test/integration/credit/Bots.int.sol index eaa0ecc2..2d3e2542 100644 --- a/contracts/test/integration/credit/Bots.int.sol +++ b/contracts/test/integration/credit/Bots.int.sol @@ -95,7 +95,7 @@ contract BotsIntegrationTest is IntegrationTestHelper, ICreditFacadeV3Events { vm.prank(bot); creditFacade.botMulticall(creditAccount, calls); - vm.prank(CONFIGURATOR); + vm.prank(botList.owner()); botList.forbidBot(bot); vm.expectRevert(abi.encodeWithSelector(NotApprovedBotException.selector, (bot))); diff --git a/contracts/test/integration/governance/GaugeMigration.int.t.sol b/contracts/test/integration/governance/GaugeMigration.int.t.sol index 655f7adf..f084d246 100644 --- a/contracts/test/integration/governance/GaugeMigration.int.t.sol +++ b/contracts/test/integration/governance/GaugeMigration.int.t.sol @@ -10,10 +10,11 @@ import {GaugeV3} from "../../../pool/GaugeV3.sol"; import {PoolQuotaKeeperV3} from "../../../pool/PoolQuotaKeeperV3.sol"; import {CallerNotGaugeException} from "../../../interfaces/IExceptions.sol"; +import {AP_GEAR_TOKEN, FIRST_EPOCH_TIMESTAMP} from "../../../libraries/Constants.sol"; import {PoolMock} from "../../mocks/pool/PoolMock.sol"; import {ERC20Mock} from "../../mocks/token/ERC20Mock.sol"; -import {AP_GEAR_TOKEN, AddressProviderV3ACLMock} from "../../mocks/core/AddressProviderV3ACLMock.sol"; +import {AddressProviderV3ACLMock} from "../../mocks/core/AddressProviderV3ACLMock.sol"; /// @title Gauge migration integration test /// @notice I:[GAM]: Tests that ensure that gauges can be migrated properly @@ -48,7 +49,9 @@ contract GaugeMigrationIntegrationTest is Test { vm.startPrank(configurator); // deploy address provider, staking and pool addressProvider = new AddressProviderV3ACLMock(); - staking = new GearStakingV3(configurator, address(gear), block.timestamp); + addressProvider.setAddress(AP_GEAR_TOKEN, address(gear), false); + + staking = new GearStakingV3(address(addressProvider)); pool = new PoolMock(address(addressProvider), address(underlying)); // deploy quota keeper and connect it to the pool @@ -57,7 +60,6 @@ contract GaugeMigrationIntegrationTest is Test { // deploy gauge and connect it to the quota keeper and staking gauge = new GaugeV3(address(pool), address(staking)); - staking.setVotingContractStatus(address(gauge), VotingContractStatus.ALLOWED); quotaKeeper.setGauge(address(gauge)); // add tokens to the gauge @@ -65,6 +67,10 @@ contract GaugeMigrationIntegrationTest is Test { gauge.addQuotaToken({token: address(token2), minRate: 400, maxRate: 2000}); vm.stopPrank(); + vm.prank(staking.owner()); + staking.setVotingContractStatus(address(gauge), VotingContractStatus.ALLOWED); + vm.warp(FIRST_EPOCH_TIMESTAMP); + // do some voting deal({token: address(gear), to: user1, give: 1_000_000e18}); deal({token: address(gear), to: user2, give: 2_000_000e18}); @@ -101,12 +107,14 @@ contract GaugeMigrationIntegrationTest is Test { /// @notice I:[GAM-1]: Gauge migration works as expected function test_I_GAM_01_gauge_migration_works_as_expected() public { // prepare a new gauge and disable an old one - vm.startPrank(configurator); GaugeV3 newGauge = new GaugeV3(address(pool), address(staking)); + vm.startPrank(staking.owner()); staking.setVotingContractStatus(address(newGauge), VotingContractStatus.ALLOWED); staking.setVotingContractStatus(address(gauge), VotingContractStatus.UNVOTE_ONLY); + vm.stopPrank(); + vm.startPrank(configurator); newGauge.addQuotaToken({token: address(token1), minRate: 600, maxRate: 3000}); newGauge.addQuotaToken({token: address(token2), minRate: 400, maxRate: 2000}); quotaKeeper.setGauge(address(newGauge)); @@ -165,16 +173,18 @@ contract GaugeMigrationIntegrationTest is Test { /// @notice I:[GAM-2]: Gauge and staking migration works as expected function test_I_GAM_02_gaude_and_staking_migration_works_as_expected() public { // prepare new staking and gauge contracts - vm.startPrank(configurator); - GearStakingV3 newStaking = new GearStakingV3(configurator, address(gear), block.timestamp); + GearStakingV3 newStaking = new GearStakingV3(address(addressProvider)); GaugeV3 newGauge = new GaugeV3(address(pool), address(newStaking)); + vm.startPrank(staking.owner()); newStaking.setMigrator(address(staking)); staking.setSuccessor(address(newStaking)); staking.setVotingContractStatus(address(gauge), VotingContractStatus.UNVOTE_ONLY); newStaking.setVotingContractStatus(address(newGauge), VotingContractStatus.ALLOWED); + vm.stopPrank(); + vm.startPrank(configurator); newGauge.addQuotaToken({token: address(token1), minRate: 600, maxRate: 3000}); newGauge.addQuotaToken({token: address(token2), minRate: 400, maxRate: 2000}); quotaKeeper.setGauge(address(newGauge)); diff --git a/contracts/test/interfaces/IAddressProviderV3.sol b/contracts/test/interfaces/IAddressProviderV3.sol index 6b408d9a..381a2c09 100644 --- a/contracts/test/interfaces/IAddressProviderV3.sol +++ b/contracts/test/interfaces/IAddressProviderV3.sol @@ -3,14 +3,18 @@ // (c) Gearbox Foundation, 2023. pragma solidity ^0.8.17; -uint256 constant NO_VERSION_CONTROL = 0; +import { + AP_GEAR_TOKEN, + AP_INSTANCE_MANAGER_PROXY, + AP_CROSS_CHAIN_GOVERNANCE_PROXY, + NO_VERSION_CONTROL +} from "../../libraries/Constants.sol"; bytes32 constant AP_ACCOUNT_FACTORY = "ACCOUNT_FACTORY"; bytes32 constant AP_ACL = "ACL"; bytes32 constant AP_BOT_LIST = "BOT_LIST"; bytes32 constant AP_CONTRACTS_REGISTER = "CONTRACTS_REGISTER"; bytes32 constant AP_GEAR_STAKING = "GEAR_STAKING"; -bytes32 constant AP_GEAR_TOKEN = "GEAR_TOKEN"; bytes32 constant AP_PRICE_ORACLE = "PRICE_ORACLE"; bytes32 constant AP_TREASURY = "TREASURY"; bytes32 constant AP_WETH_TOKEN = "WETH_TOKEN"; diff --git a/contracts/test/mocks/core/AddressProviderV3ACLMock.sol b/contracts/test/mocks/core/AddressProviderV3ACLMock.sol index 8d9feccd..e42b6d53 100644 --- a/contracts/test/mocks/core/AddressProviderV3ACLMock.sol +++ b/contracts/test/mocks/core/AddressProviderV3ACLMock.sol @@ -41,6 +41,9 @@ contract AddressProviderV3ACLMock is Test, IAddressProviderV3, Ownable { _setAddress(AP_TREASURY, address(1234), 0); _setAddress(AP_WETH_TOKEN, address(new WETHMock()), 0); + + _setAddress(AP_INSTANCE_MANAGER_PROXY, makeAddr("INSTANCE_MANAGER_PROXY"), 0); + _setAddress(AP_CROSS_CHAIN_GOVERNANCE_PROXY, makeAddr("CROSS_CHAIN_GOVERNANCE_PROXY"), 0); } function isConfigurator(address addr) external view returns (bool) { diff --git a/contracts/test/mocks/token/DegenNFTMock.sol b/contracts/test/mocks/token/DegenNFTMock.sol index 717be115..26552ea0 100644 --- a/contracts/test/mocks/token/DegenNFTMock.sol +++ b/contracts/test/mocks/token/DegenNFTMock.sol @@ -8,6 +8,9 @@ import {IDegenNFT} from "../../../interfaces/base/IDegenNFT.sol"; import {InsufficientBalanceException} from "../../../interfaces/IExceptions.sol"; contract DegenNFTMock is ERC721, IDegenNFT { + uint256 public constant override version = 3_10; + bytes32 public constant override contractType = "DEGEN_NFT::MOCK"; + address public minter; constructor(string memory name, string memory symbol) ERC721(name, symbol) { diff --git a/contracts/test/suites/GenesisFactory.sol b/contracts/test/suites/GenesisFactory.sol index 4eacf74e..ea0c3f5d 100644 --- a/contracts/test/suites/GenesisFactory.sol +++ b/contracts/test/suites/GenesisFactory.sol @@ -34,12 +34,13 @@ contract GenesisFactory is Ownable { priceOracle = new PriceOracleV3(address(acl)); lossPolicy = new LossPolicyMock(); - accountFactory = new DefaultAccountFactoryV3(msg.sender); - botList = new BotListV3(msg.sender); + accountFactory = new DefaultAccountFactoryV3(address(acl)); + botList = new BotListV3(address(acl)); ERC20 gearToken = new ERC20("Gearbox", "GEAR"); + acl.setAddress(AP_GEAR_TOKEN, address(gearToken), false); - gearStaking = new GearStakingV3(msg.sender, address(gearToken), 1); + gearStaking = new GearStakingV3(address(acl)); acl.grantRole("PAUSABLE_ADMIN", msg.sender); acl.grantRole("UNPAUSABLE_ADMIN", msg.sender); diff --git a/contracts/test/unit/core/BotListV3.unit.t.sol b/contracts/test/unit/core/BotListV3.unit.t.sol index 2d041018..81a54980 100644 --- a/contracts/test/unit/core/BotListV3.unit.t.sol +++ b/contracts/test/unit/core/BotListV3.unit.t.sol @@ -10,6 +10,7 @@ import {IBotListV3Events} from "../../../interfaces/IBotListV3.sol"; import "../../lib/constants.sol"; // MOCKS +import {AddressProviderV3ACLMock} from "../../mocks/core/AddressProviderV3ACLMock.sol"; import {BotMock} from "../../mocks/core/BotMock.sol"; // EXCEPTIONS @@ -19,6 +20,7 @@ import "../../../interfaces/IExceptions.sol"; /// @notice U:[BL]: Unit tests for bot list v3 contract BotListV3UnitTest is Test, IBotListV3Events { BotListV3 botList; + address owner; address bot; address otherBot; @@ -29,6 +31,8 @@ contract BotListV3UnitTest is Test, IBotListV3Events { address invalidAccount; function setUp() public { + AddressProviderV3ACLMock addressProvider = new AddressProviderV3ACLMock(); + bot = address(new BotMock()); otherBot = address(new BotMock()); creditManager = makeAddr("CREDIT_MANAGER"); @@ -52,7 +56,8 @@ contract BotListV3UnitTest is Test, IBotListV3Events { abi.encodeWithSignature("CreditAccountDoesNotExistException()") ); - botList = new BotListV3(CONFIGURATOR); + botList = new BotListV3(address(addressProvider)); + owner = botList.owner(); } /// @notice U:[BL-1]: `setBotPermissions` works correctly @@ -72,7 +77,7 @@ contract BotListV3UnitTest is Test, IBotListV3Events { vm.prank(creditFacade); botList.setBotPermissions({bot: bot, creditAccount: creditAccount, permissions: 2}); - vm.prank(CONFIGURATOR); + vm.prank(owner); botList.forbidBot(otherBot); vm.expectRevert(InvalidBotException.selector); @@ -105,7 +110,7 @@ contract BotListV3UnitTest is Test, IBotListV3Events { assertEq(bots.length, 1, "Incorrect active bots array length"); assertEq(bots[0], bot, "Incorrect address added to active bots list"); - vm.prank(CONFIGURATOR); + vm.prank(owner); botList.forbidBot(bot); vm.expectEmit(true, true, true, true); diff --git a/contracts/test/unit/core/DefaultAccountFactoryV3.unit.t.sol b/contracts/test/unit/core/DefaultAccountFactoryV3.unit.t.sol index 9167de94..b459c707 100644 --- a/contracts/test/unit/core/DefaultAccountFactoryV3.unit.t.sol +++ b/contracts/test/unit/core/DefaultAccountFactoryV3.unit.t.sol @@ -3,6 +3,8 @@ // (c) Gearbox Foundation, 2023. pragma solidity ^0.8.17; +import {AddressProviderV3ACLMock} from "../../mocks/core/AddressProviderV3ACLMock.sol"; + import {CreditAccountV3} from "../../../credit/CreditAccountV3.sol"; import {CreditAccountInfo, CreditManagerV3} from "../../../credit/CreditManagerV3.sol"; import {IDefaultAccountFactoryV3Events} from "../../../interfaces/IDefaultAccountFactoryV3.sol"; @@ -22,15 +24,17 @@ import {DefaultAccountFactoryV3Harness, FactoryParams, QueuedAccount} from "./De contract DefaultAccountFactoryV3UnitTest is TestHelper, IDefaultAccountFactoryV3Events { DefaultAccountFactoryV3Harness accountFactory; - address configurator; + address owner; address creditManager; function setUp() public { - configurator = makeAddr("CONFIGURATOR"); + AddressProviderV3ACLMock addressProvider = new AddressProviderV3ACLMock(); + accountFactory = new DefaultAccountFactoryV3Harness(address(addressProvider)); + + owner = accountFactory.owner(); creditManager = makeAddr("CREDIT_MANAGER"); - accountFactory = new DefaultAccountFactoryV3Harness(configurator); - vm.prank(configurator); + vm.prank(owner); accountFactory.addCreditManager(creditManager); } @@ -45,7 +49,7 @@ contract DefaultAccountFactoryV3UnitTest is TestHelper, IDefaultAccountFactoryV3 vm.expectRevert(CallerNotCreditManagerException.selector); accountFactory.returnCreditAccount(address(0)); } - if (caller != configurator) { + if (caller != owner) { vm.expectRevert("Ownable: caller is not the owner"); accountFactory.rescue(address(0), address(0), bytes("")); } @@ -131,7 +135,7 @@ contract DefaultAccountFactoryV3UnitTest is TestHelper, IDefaultAccountFactoryV3 accountFactory.setFactoryParams(manager, creditAccount, 0, 0); vm.expectRevert(MasterCreditAccountAlreadyDeployedException.selector); - vm.prank(configurator); + vm.prank(owner); accountFactory.addCreditManager(manager); } @@ -142,7 +146,7 @@ contract DefaultAccountFactoryV3UnitTest is TestHelper, IDefaultAccountFactoryV3 vm.expectEmit(true, false, false, false); emit AddCreditManager(manager, address(0)); - vm.prank(configurator); + vm.prank(owner); accountFactory.addCreditManager(manager); address account = accountFactory.factoryParams(manager).masterCreditAccount; @@ -169,7 +173,7 @@ contract DefaultAccountFactoryV3UnitTest is TestHelper, IDefaultAccountFactoryV3 ); vm.expectRevert(CreditAccountIsInUseException.selector); - vm.prank(configurator); + vm.prank(owner); accountFactory.rescue(creditAccount, address(0), bytes("")); } @@ -192,7 +196,7 @@ contract DefaultAccountFactoryV3UnitTest is TestHelper, IDefaultAccountFactoryV3 emit Rescue(creditAccount, target, data); vm.expectCall(creditAccount, abi.encodeCall(CreditAccountV3(creditAccount).rescue, (target, data))); - vm.prank(configurator); + vm.prank(owner); accountFactory.rescue(creditAccount, target, data); } } diff --git a/contracts/test/unit/core/GearStakingV3.unit.t.sol b/contracts/test/unit/core/GearStakingV3.unit.t.sol index 80ee2def..0bb11e82 100644 --- a/contracts/test/unit/core/GearStakingV3.unit.t.sol +++ b/contracts/test/unit/core/GearStakingV3.unit.t.sol @@ -31,34 +31,35 @@ contract GearStakingV3UnitTest is Test, IGearStakingV3Events { AddressProviderV3ACLMock public addressProvider; GearStakingV3 gearStaking; + address owner; TargetContractMock votingContract; TokensTestSuite tokenTestSuite; function setUp() public { - vm.prank(CONFIGURATOR); addressProvider = new AddressProviderV3ACLMock(); tokenTestSuite = new TokensTestSuite(); gearToken = tokenTestSuite.addressOf(TOKEN_WETH); - vm.prank(CONFIGURATOR); addressProvider.setAddress(AP_GEAR_TOKEN, gearToken, false); - gearStaking = new GearStakingV3(CONFIGURATOR, gearToken, block.timestamp + 1); + gearStaking = new GearStakingV3(address(addressProvider)); + vm.warp(gearStaking.firstEpochTimestamp()); + + owner = gearStaking.owner(); votingContract = new TargetContractMock(); - vm.prank(CONFIGURATOR); + vm.prank(owner); gearStaking.setVotingContractStatus(address(votingContract), VotingContractStatus.ALLOWED); } /// @dev U:[GS-1]: constructor sets correct values function test_U_GS_01_constructor_sets_correct_values() public { assertEq(address(gearStaking.gear()), gearToken, "Gear token incorrect"); - assertEq(gearStaking.getCurrentEpoch(), 0, "First epoch timestamp incorrect"); vm.warp(block.timestamp + 1); assertEq(gearStaking.getCurrentEpoch(), 1, "First epoch timestamp incorrect"); @@ -171,7 +172,7 @@ contract GearStakingV3UnitTest is Test, IGearStakingV3Events { TargetContractMock votingContract2 = new TargetContractMock(); - vm.prank(CONFIGURATOR); + vm.prank(owner); gearStaking.setVotingContractStatus(address(votingContract2), VotingContractStatus.ALLOWED); votes = new MultiVote[](3); @@ -226,7 +227,7 @@ contract GearStakingV3UnitTest is Test, IGearStakingV3Events { vm.prank(USER); gearStaking.deposit(uint96(WAD), votes); - vm.prank(CONFIGURATOR); + vm.prank(owner); gearStaking.setVotingContractStatus(address(votingContract), VotingContractStatus.NOT_ALLOWED); votes = new MultiVote[](1); @@ -255,7 +256,7 @@ contract GearStakingV3UnitTest is Test, IGearStakingV3Events { vm.prank(USER); gearStaking.multivote(votes); - vm.prank(CONFIGURATOR); + vm.prank(owner); gearStaking.setVotingContractStatus(address(votingContract), VotingContractStatus.UNVOTE_ONLY); votes = new MultiVote[](1); @@ -382,13 +383,13 @@ contract GearStakingV3UnitTest is Test, IGearStakingV3Events { vm.expectEmit(true, false, false, true); emit SetVotingContractStatus(DUMB_ADDRESS, VotingContractStatus.UNVOTE_ONLY); - vm.prank(CONFIGURATOR); + vm.prank(gearStaking.owner()); gearStaking.setVotingContractStatus(DUMB_ADDRESS, VotingContractStatus.UNVOTE_ONLY); } /// @dev U:[GS-7]: migrate and depositOnMigration perform operations in order and emits events function test_U_GS_07_migrate_and_depositOnMigration_work_correctly() public { - GearStakingV3 gearStakingSuccessor = new GearStakingV3(CONFIGURATOR, gearToken, block.timestamp + 1); + GearStakingV3 gearStakingSuccessor = new GearStakingV3(address(addressProvider)); { MultiVote[] memory votes = new MultiVote[](1); @@ -410,18 +411,18 @@ contract GearStakingV3UnitTest is Test, IGearStakingV3Events { vm.prank(USER); gearStaking.migrate(uint96(WAD / 2), new MultiVote[](0), new MultiVote[](0)); - vm.prank(CONFIGURATOR); + vm.prank(owner); gearStakingSuccessor.setMigrator(address(gearStaking)); - vm.prank(CONFIGURATOR); + vm.prank(owner); gearStaking.setSuccessor(address(gearStakingSuccessor)); address newVotingContract = address(new TargetContractMock()); - vm.prank(CONFIGURATOR); + vm.prank(owner); gearStakingSuccessor.setVotingContractStatus(newVotingContract, VotingContractStatus.ALLOWED); - vm.prank(CONFIGURATOR); + vm.prank(owner); gearStaking.setVotingContractStatus(address(votingContract), VotingContractStatus.UNVOTE_ONLY); MultiVote[] memory votesBefore = new MultiVote[](1); @@ -468,7 +469,7 @@ contract GearStakingV3UnitTest is Test, IGearStakingV3Events { vm.mockCall(DUMB_ADDRESS, abi.encodeWithSignature("migrator()"), abi.encode(address(0))); vm.expectRevert(IncompatibleSuccessorException.selector); - vm.prank(CONFIGURATOR); + vm.prank(owner); gearStaking.setSuccessor(DUMB_ADDRESS); vm.mockCall(DUMB_ADDRESS, abi.encodeWithSignature("migrator()"), abi.encode(address(gearStaking))); @@ -476,7 +477,7 @@ contract GearStakingV3UnitTest is Test, IGearStakingV3Events { vm.expectEmit(true, false, false, false); emit SetSuccessor(DUMB_ADDRESS); - vm.prank(CONFIGURATOR); + vm.prank(owner); gearStaking.setSuccessor(DUMB_ADDRESS); assertEq(gearStaking.successor(), DUMB_ADDRESS, "Successor address incorrect"); @@ -490,7 +491,7 @@ contract GearStakingV3UnitTest is Test, IGearStakingV3Events { vm.expectEmit(true, false, false, false); emit SetMigrator(DUMB_ADDRESS); - vm.prank(CONFIGURATOR); + vm.prank(owner); gearStaking.setMigrator(DUMB_ADDRESS); assertEq(gearStaking.migrator(), DUMB_ADDRESS, "Migrator address incorrect");