From ab339a78b0e75ad2207db8d898d33b7af6e5617b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=9Fingen?= Date: Wed, 27 Nov 2024 11:10:23 +0000 Subject: [PATCH 1/3] chore: Add functions to IGovernance interface --- src/Governance.sol | 13 ++++--------- src/interfaces/IGovernance.sol | 27 +++++++++++++++++++++++++++ 2 files changed, 31 insertions(+), 9 deletions(-) diff --git a/src/Governance.sol b/src/Governance.sol index 9ad395a9..8c03c32f 100644 --- a/src/Governance.sol +++ b/src/Governance.sol @@ -315,17 +315,14 @@ contract Governance is Multicall, UserProxyFactory, ReentrancyGuard, Ownable, IG return calculateVotingThreshold(snapshotVotes); } - /// @dev Returns the most up to date voting threshold - /// In contrast to `getLatestVotingThreshold` this function updates the snapshot - /// This ensures that the value returned is always the latest + /// @inheritdoc IGovernance function calculateVotingThreshold() public returns (uint256) { (VoteSnapshot memory snapshot,) = _snapshotVotes(); return calculateVotingThreshold(snapshot.votes); } - /// @dev Utility function to compute the threshold votes without recomputing the snapshot - /// Note that `boldAccrued` is a cached value, this function works correctly only when called after an accrual + /// @inheritdoc IGovernance function calculateVotingThreshold(uint256 _votes) public view returns (uint256) { if (_votes == 0) return 0; @@ -351,8 +348,7 @@ contract Governance is Multicall, UserProxyFactory, ReentrancyGuard, Ownable, IG } } - /// @notice Return the most up to date global snapshot and state as well as a flag to notify whether the state can be updated - /// This is a convenience function to always retrieve the most up to date state values + /// @inheritdoc IGovernance function getTotalVotesAndState() public view @@ -389,8 +385,7 @@ contract Governance is Multicall, UserProxyFactory, ReentrancyGuard, Ownable, IG } } - /// @dev Given an initiative address, return it's most up to date snapshot and state as well as a flag to notify whether the state can be updated - /// This is a convenience function to always retrieve the most up to date state values + /// @inheritdoc IGovernance function getInitiativeSnapshotAndState(address _initiative) public view diff --git a/src/interfaces/IGovernance.sol b/src/interfaces/IGovernance.sol index 9d1fb76a..7a5ba2ca 100644 --- a/src/interfaces/IGovernance.sol +++ b/src/interfaces/IGovernance.sol @@ -222,6 +222,33 @@ interface IGovernance { pure returns (uint208); + /// @dev Returns the most up to date voting threshold + /// In contrast to `getLatestVotingThreshold` this function updates the snapshot + /// This ensures that the value returned is always the latest + function calculateVotingThreshold() external returns (uint256); + + /// @dev Utility function to compute the threshold votes without recomputing the snapshot + /// Note that `boldAccrued` is a cached value, this function works correctly only when called after an accrual + function calculateVotingThreshold(uint256 _votes) external view returns (uint256); + + /// @notice Return the most up to date global snapshot and state as well as a flag to notify whether the state can be updated + /// This is a convenience function to always retrieve the most up to date state values + function getTotalVotesAndState() + external + view + returns (VoteSnapshot memory snapshot, GlobalState memory state, bool shouldUpdate); + + /// @dev Given an initiative address, return it's most up to date snapshot and state as well as a flag to notify whether the state can be updated + /// This is a convenience function to always retrieve the most up to date state values + function getInitiativeSnapshotAndState(address _initiative) + external + view + returns ( + InitiativeVoteSnapshot memory initiativeSnapshot, + InitiativeState memory initiativeState, + bool shouldUpdate + ); + /// @notice Voting threshold is the max. of either: /// - 4% of the total voting LQTY in the previous epoch /// - or the minimum number of votes necessary to claim at least MIN_CLAIM BOLD From 7f07d39f77753ce1d88cf38d68b16e470a5864e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=9Fingen?= Date: Wed, 4 Dec 2024 17:44:07 +0000 Subject: [PATCH 2/3] fix: Add initiative status enum and getters to interface --- src/Governance.sol | 17 ------- src/interfaces/IGovernance.sol | 30 +++++++++++ test/E2E.t.sol | 42 ++++++++-------- test/Governance.t.sol | 2 +- test/recon/BeforeAfter.sol | 6 +-- test/recon/Setup.sol | 2 +- .../recon/properties/GovernanceProperties.sol | 50 +++++++++---------- .../properties/OptimizationProperties.sol | 4 +- test/recon/targets/GovernanceTargets.sol | 6 +-- .../trophies/SecondTrophiesToFoundry.sol | 4 +- 10 files changed, 88 insertions(+), 75 deletions(-) diff --git a/src/Governance.sol b/src/Governance.sol index 8c03c32f..ffe434af 100644 --- a/src/Governance.sol +++ b/src/Governance.sol @@ -430,23 +430,6 @@ contract Governance is Multicall, UserProxyFactory, ReentrancyGuard, Ownable, IG FSM //////////////////////////////////////////////////////////////*/ - enum InitiativeStatus { - NONEXISTENT, - /// This Initiative Doesn't exist | This is never returned - WARM_UP, - /// This epoch was just registered - SKIP, - /// This epoch will result in no rewards and no unregistering - CLAIMABLE, - /// This epoch will result in claiming rewards - CLAIMED, - /// The rewards for this epoch have been claimed - UNREGISTERABLE, - /// Can be unregistered - DISABLED // It was already Unregistered - - } - /// @notice Given an inititive address, updates all snapshots and return the initiative state /// See the view version of `getInitiativeState` for the underlying logic on Initatives FSM function getInitiativeState(address _initiative) diff --git a/src/interfaces/IGovernance.sol b/src/interfaces/IGovernance.sol index 7a5ba2ca..3dd3aba1 100644 --- a/src/interfaces/IGovernance.sol +++ b/src/interfaces/IGovernance.sol @@ -264,6 +264,36 @@ interface IGovernance { external returns (VoteSnapshot memory voteSnapshot, InitiativeVoteSnapshot memory initiativeVoteSnapshot); + /*////////////////////////////////////////////////////////////// + FSM + //////////////////////////////////////////////////////////////*/ + + enum InitiativeStatus { + NONEXISTENT, + /// This Initiative Doesn't exist | This is never returned + WARM_UP, + /// This epoch was just registered + SKIP, + /// This epoch will result in no rewards and no unregistering + CLAIMABLE, + /// This epoch will result in claiming rewards + CLAIMED, + /// The rewards for this epoch have been claimed + UNREGISTERABLE, + /// Can be unregistered + DISABLED // It was already Unregistered + + } + + function getInitiativeState(address _initiative) external returns (InitiativeStatus status, uint16 lastEpochClaim, uint256 claimableAmount); + + function getInitiativeState( + address _initiative, + VoteSnapshot memory _votesSnapshot, + InitiativeVoteSnapshot memory _votesForInitiativeSnapshot, + InitiativeState memory _initiativeState + ) external view returns (InitiativeStatus status, uint16 lastEpochClaim, uint256 claimableAmount); + /// @notice Registers a new initiative /// @param _initiative Address of the initiative function registerInitiative(address _initiative) external; diff --git a/test/E2E.t.sol b/test/E2E.t.sol index 9670fa09..f687e2ac 100644 --- a/test/E2E.t.sol +++ b/test/E2E.t.sol @@ -158,7 +158,7 @@ contract ForkedE2ETests is Test { address newInitiative = address(0x123123); governance.registerInitiative(newInitiative); - assertEq(uint256(Governance.InitiativeStatus.WARM_UP), _getInitiativeStatus(newInitiative), "Cooldown"); + assertEq(uint256(IGovernance.InitiativeStatus.WARM_UP), _getInitiativeStatus(newInitiative), "Cooldown"); uint256 skipCount; @@ -167,25 +167,25 @@ contract ForkedE2ETests is Test { // Whereas in next week it will work vm.warp(block.timestamp + EPOCH_DURATION); // 1 ++skipCount; - assertEq(uint256(Governance.InitiativeStatus.SKIP), _getInitiativeStatus(newInitiative), "SKIP"); + assertEq(uint256(IGovernance.InitiativeStatus.SKIP), _getInitiativeStatus(newInitiative), "SKIP"); // Cooldown on epoch Staert vm.warp(block.timestamp + EPOCH_DURATION); // 2 ++skipCount; - assertEq(uint256(Governance.InitiativeStatus.SKIP), _getInitiativeStatus(newInitiative), "SKIP"); + assertEq(uint256(IGovernance.InitiativeStatus.SKIP), _getInitiativeStatus(newInitiative), "SKIP"); vm.warp(block.timestamp + EPOCH_DURATION); // 3 ++skipCount; - assertEq(uint256(Governance.InitiativeStatus.SKIP), _getInitiativeStatus(newInitiative), "SKIP"); + assertEq(uint256(IGovernance.InitiativeStatus.SKIP), _getInitiativeStatus(newInitiative), "SKIP"); vm.warp(block.timestamp + EPOCH_DURATION); // 3 ++skipCount; - assertEq(uint256(Governance.InitiativeStatus.SKIP), _getInitiativeStatus(newInitiative), "SKIP"); + assertEq(uint256(IGovernance.InitiativeStatus.SKIP), _getInitiativeStatus(newInitiative), "SKIP"); vm.warp(block.timestamp + EPOCH_DURATION); // 4 ++skipCount; assertEq( - uint256(Governance.InitiativeStatus.UNREGISTERABLE), _getInitiativeStatus(newInitiative), "UNREGISTERABLE" + uint256(IGovernance.InitiativeStatus.UNREGISTERABLE), _getInitiativeStatus(newInitiative), "UNREGISTERABLE" ); /// 4 + 1 ?? @@ -207,8 +207,8 @@ contract ForkedE2ETests is Test { address newInitiative2 = address(0x1231234); governance.registerInitiative(newInitiative); governance.registerInitiative(newInitiative2); - assertEq(uint256(Governance.InitiativeStatus.WARM_UP), _getInitiativeStatus(newInitiative), "Cooldown"); - assertEq(uint256(Governance.InitiativeStatus.WARM_UP), _getInitiativeStatus(newInitiative2), "Cooldown"); + assertEq(uint256(IGovernance.InitiativeStatus.WARM_UP), _getInitiativeStatus(newInitiative), "Cooldown"); + assertEq(uint256(IGovernance.InitiativeStatus.WARM_UP), _getInitiativeStatus(newInitiative2), "Cooldown"); uint256 skipCount; @@ -219,7 +219,7 @@ contract ForkedE2ETests is Test { vm.warp(block.timestamp + EPOCH_DURATION); // 1 ++skipCount; - assertEq(uint256(Governance.InitiativeStatus.SKIP), _getInitiativeStatus(newInitiative), "SKIP"); + assertEq(uint256(IGovernance.InitiativeStatus.SKIP), _getInitiativeStatus(newInitiative), "SKIP"); _allocate(newInitiative2, 1e18, 0); @@ -228,24 +228,24 @@ contract ForkedE2ETests is Test { // Cooldown on epoch Staert vm.warp(block.timestamp + EPOCH_DURATION); // 2 ++skipCount; - assertEq(uint256(Governance.InitiativeStatus.SKIP), _getInitiativeStatus(newInitiative), "SKIP"); + assertEq(uint256(IGovernance.InitiativeStatus.SKIP), _getInitiativeStatus(newInitiative), "SKIP"); // 3rd Week of SKIP vm.warp(block.timestamp + EPOCH_DURATION); // 3 ++skipCount; - assertEq(uint256(Governance.InitiativeStatus.SKIP), _getInitiativeStatus(newInitiative), "SKIP"); + assertEq(uint256(IGovernance.InitiativeStatus.SKIP), _getInitiativeStatus(newInitiative), "SKIP"); // 4th Week of SKIP | If it doesn't get any rewards it will be UNREGISTERABLE vm.warp(block.timestamp + EPOCH_DURATION); // 3 ++skipCount; - assertEq(uint256(Governance.InitiativeStatus.SKIP), _getInitiativeStatus(newInitiative), "SKIP"); + assertEq(uint256(IGovernance.InitiativeStatus.SKIP), _getInitiativeStatus(newInitiative), "SKIP"); vm.warp(block.timestamp + EPOCH_DURATION); // 4 ++skipCount; assertEq( - uint256(Governance.InitiativeStatus.UNREGISTERABLE), _getInitiativeStatus(newInitiative), "UNREGISTERABLE" + uint256(IGovernance.InitiativeStatus.UNREGISTERABLE), _getInitiativeStatus(newInitiative), "UNREGISTERABLE" ); /// It was SKIP for 4 EPOCHS, it is now UNREGISTERABLE @@ -266,8 +266,8 @@ contract ForkedE2ETests is Test { address newInitiative2 = address(0x1231234); governance.registerInitiative(newInitiative); governance.registerInitiative(newInitiative2); - assertEq(uint256(Governance.InitiativeStatus.WARM_UP), _getInitiativeStatus(newInitiative), "Cooldown"); - assertEq(uint256(Governance.InitiativeStatus.WARM_UP), _getInitiativeStatus(newInitiative2), "Cooldown"); + assertEq(uint256(IGovernance.InitiativeStatus.WARM_UP), _getInitiativeStatus(newInitiative), "Cooldown"); + assertEq(uint256(IGovernance.InitiativeStatus.WARM_UP), _getInitiativeStatus(newInitiative2), "Cooldown"); uint256 skipCount; @@ -278,7 +278,7 @@ contract ForkedE2ETests is Test { vm.warp(block.timestamp + EPOCH_DURATION); // 1 ++skipCount; - assertEq(uint256(Governance.InitiativeStatus.SKIP), _getInitiativeStatus(newInitiative), "SKIP"); + assertEq(uint256(IGovernance.InitiativeStatus.SKIP), _getInitiativeStatus(newInitiative), "SKIP"); _allocate(newInitiative2, 1e18, 0); @@ -287,19 +287,19 @@ contract ForkedE2ETests is Test { // Cooldown on epoch Staert vm.warp(block.timestamp + EPOCH_DURATION); // 2 ++skipCount; - assertEq(uint256(Governance.InitiativeStatus.SKIP), _getInitiativeStatus(newInitiative), "SKIP"); + assertEq(uint256(IGovernance.InitiativeStatus.SKIP), _getInitiativeStatus(newInitiative), "SKIP"); // 3rd Week of SKIP vm.warp(block.timestamp + EPOCH_DURATION); // 3 ++skipCount; - assertEq(uint256(Governance.InitiativeStatus.SKIP), _getInitiativeStatus(newInitiative), "SKIP"); + assertEq(uint256(IGovernance.InitiativeStatus.SKIP), _getInitiativeStatus(newInitiative), "SKIP"); // 4th Week of SKIP | If it doesn't get any rewards it will be UNREGISTERABLE vm.warp(block.timestamp + EPOCH_DURATION); // 3 ++skipCount; - assertEq(uint256(Governance.InitiativeStatus.SKIP), _getInitiativeStatus(newInitiative), "SKIP"); + assertEq(uint256(IGovernance.InitiativeStatus.SKIP), _getInitiativeStatus(newInitiative), "SKIP"); // Allocating to it, saves it _reset(newInitiative2); @@ -307,7 +307,7 @@ contract ForkedE2ETests is Test { vm.warp(block.timestamp + EPOCH_DURATION); // 4 ++skipCount; - assertEq(uint256(Governance.InitiativeStatus.CLAIMABLE), _getInitiativeStatus(newInitiative), "UNREGISTERABLE"); + assertEq(uint256(IGovernance.InitiativeStatus.CLAIMABLE), _getInitiativeStatus(newInitiative), "UNREGISTERABLE"); } function _deposit(uint88 amt) internal { @@ -341,7 +341,7 @@ contract ForkedE2ETests is Test { } function _getInitiativeStatus(address _initiative) internal returns (uint256) { - (Governance.InitiativeStatus status,,) = governance.getInitiativeState(_initiative); + (IGovernance.InitiativeStatus status,,) = governance.getInitiativeState(_initiative); return uint256(status); } } diff --git a/test/Governance.t.sol b/test/Governance.t.sol index a5cdf335..9681320c 100644 --- a/test/Governance.t.sol +++ b/test/Governance.t.sol @@ -1396,7 +1396,7 @@ abstract contract GovernanceTest is Test { assertEq(lusd.balanceOf(baseInitiative1), 15000e18); - (Governance.InitiativeStatus status,, uint256 claimable) = governance.getInitiativeState(baseInitiative2); + (IGovernance.InitiativeStatus status,, uint256 claimable) = governance.getInitiativeState(baseInitiative2); console.log("res", uint8(status)); console.log("claimable", claimable); (uint224 votes,,, uint224 vetos) = governance.votesForInitiativeSnapshot(baseInitiative2); diff --git a/test/recon/BeforeAfter.sol b/test/recon/BeforeAfter.sol index 4f52366a..b704dcad 100644 --- a/test/recon/BeforeAfter.sol +++ b/test/recon/BeforeAfter.sol @@ -10,7 +10,7 @@ import {Governance} from "src/Governance.sol"; abstract contract BeforeAfter is Setup, Asserts { struct Vars { uint16 epoch; - mapping(address => Governance.InitiativeStatus) initiativeStatus; + mapping(address => IGovernance.InitiativeStatus) initiativeStatus; // initiative => user => epoch => claimed mapping(address => mapping(address => mapping(uint16 => bool))) claimedBribeForInitiativeAtEpoch; mapping(address user => uint128 lqtyBalance) userLqtyBalance; @@ -31,7 +31,7 @@ abstract contract BeforeAfter is Setup, Asserts { _before.epoch = currentEpoch; for (uint8 i; i < deployedInitiatives.length; i++) { address initiative = deployedInitiatives[i]; - (Governance.InitiativeStatus status,,) = governance.getInitiativeState(initiative); + (IGovernance.InitiativeStatus status,,) = governance.getInitiativeState(initiative); _before.initiativeStatus[initiative] = status; _before.claimedBribeForInitiativeAtEpoch[initiative][user][currentEpoch] = IBribeInitiative(initiative).claimedBribeAtEpoch(user, currentEpoch); @@ -48,7 +48,7 @@ abstract contract BeforeAfter is Setup, Asserts { _after.epoch = currentEpoch; for (uint8 i; i < deployedInitiatives.length; i++) { address initiative = deployedInitiatives[i]; - (Governance.InitiativeStatus status,,) = governance.getInitiativeState(initiative); + (IGovernance.InitiativeStatus status,,) = governance.getInitiativeState(initiative); _after.initiativeStatus[initiative] = status; _after.claimedBribeForInitiativeAtEpoch[initiative][user][currentEpoch] = IBribeInitiative(initiative).claimedBribeAtEpoch(user, currentEpoch); diff --git a/test/recon/Setup.sol b/test/recon/Setup.sol index 5d6ce212..694ad08a 100644 --- a/test/recon/Setup.sol +++ b/test/recon/Setup.sol @@ -109,7 +109,7 @@ abstract contract Setup is BaseSetup, MockStakingV1Deployer { } function _getInitiativeStatus(address) internal returns (uint256) { - (Governance.InitiativeStatus status,,) = governance.getInitiativeState(_getDeployedInitiative(0)); + (IGovernance.InitiativeStatus status,,) = governance.getInitiativeState(_getDeployedInitiative(0)); return uint256(status); } } diff --git a/test/recon/properties/GovernanceProperties.sol b/test/recon/properties/GovernanceProperties.sol index 99e40b4f..3cb8fda2 100644 --- a/test/recon/properties/GovernanceProperties.sol +++ b/test/recon/properties/GovernanceProperties.sol @@ -23,23 +23,23 @@ abstract contract GovernanceProperties is BeforeAfter { address initiative = deployedInitiatives[i]; // Hardcoded Allowed FSM - if (_before.initiativeStatus[initiative] == Governance.InitiativeStatus.UNREGISTERABLE) { + if (_before.initiativeStatus[initiative] == IGovernance.InitiativeStatus.UNREGISTERABLE) { // ALLOW TO SET DISABLE - if (_after.initiativeStatus[initiative] == Governance.InitiativeStatus.DISABLED) { + if (_after.initiativeStatus[initiative] == IGovernance.InitiativeStatus.DISABLED) { return; } } - if (_before.initiativeStatus[initiative] == Governance.InitiativeStatus.CLAIMABLE) { + if (_before.initiativeStatus[initiative] == IGovernance.InitiativeStatus.CLAIMABLE) { // ALLOW TO CLAIM - if (_after.initiativeStatus[initiative] == Governance.InitiativeStatus.CLAIMED) { + if (_after.initiativeStatus[initiative] == IGovernance.InitiativeStatus.CLAIMED) { return; } } - if (_before.initiativeStatus[initiative] == Governance.InitiativeStatus.NONEXISTENT) { + if (_before.initiativeStatus[initiative] == IGovernance.InitiativeStatus.NONEXISTENT) { // Registered -> SKIP is ok - if (_after.initiativeStatus[initiative] == Governance.InitiativeStatus.WARM_UP) { + if (_after.initiativeStatus[initiative] == IGovernance.InitiativeStatus.WARM_UP) { return; } } @@ -315,9 +315,9 @@ abstract contract GovernanceProperties is BeforeAfter { ) = governance.initiativeStates(deployedInitiatives[i]); // Conditional, only if not DISABLED - (Governance.InitiativeStatus status,,) = governance.getInitiativeState(deployedInitiatives[i]); + (IGovernance.InitiativeStatus status,,) = governance.getInitiativeState(deployedInitiatives[i]); // Conditionally add based on state - if (status != Governance.InitiativeStatus.DISABLED) { + if (status != IGovernance.InitiativeStatus.DISABLED) { allocatedLQTYSum += voteLQTY; // Sum via projection votedPowerSum += governance.lqtyToVotes( @@ -346,14 +346,14 @@ abstract contract GovernanceProperties is BeforeAfter { // In the next epoch it can either be SKIP or UNREGISTERABLE address initiative = _getDeployedInitiative(initiativeIndex); - (Governance.InitiativeStatus status,,) = governance.getInitiativeState(initiative); - if (status == Governance.InitiativeStatus.SKIP) { + (IGovernance.InitiativeStatus status,,) = governance.getInitiativeState(initiative); + if (status == IGovernance.InitiativeStatus.SKIP) { vm.warp(block.timestamp + governance.EPOCH_DURATION()); - (Governance.InitiativeStatus newStatus,,) = governance.getInitiativeState(initiative); + (IGovernance.InitiativeStatus newStatus,,) = governance.getInitiativeState(initiative); t( uint256(status) == uint256(newStatus) - || uint256(newStatus) == uint256(Governance.InitiativeStatus.UNREGISTERABLE) - || uint256(newStatus) == uint256(Governance.InitiativeStatus.CLAIMABLE), + || uint256(newStatus) == uint256(IGovernance.InitiativeStatus.UNREGISTERABLE) + || uint256(newStatus) == uint256(IGovernance.InitiativeStatus.CLAIMABLE), "Either SKIP or UNREGISTERABLE or CLAIMABLE" ); } @@ -362,16 +362,16 @@ abstract contract GovernanceProperties is BeforeAfter { function check_warmup_unregisterable_consistency(uint8 initiativeIndex) public { // Status after MUST NOT be UNREGISTERABLE address initiative = _getDeployedInitiative(initiativeIndex); - (Governance.InitiativeStatus status,,) = governance.getInitiativeState(initiative); + (IGovernance.InitiativeStatus status,,) = governance.getInitiativeState(initiative); - if (status == Governance.InitiativeStatus.WARM_UP) { + if (status == IGovernance.InitiativeStatus.WARM_UP) { vm.warp(block.timestamp + governance.EPOCH_DURATION()); - (Governance.InitiativeStatus newStatus,,) = governance.getInitiativeState(initiative); + (IGovernance.InitiativeStatus newStatus,,) = governance.getInitiativeState(initiative); // Next status must be SKIP, because by definition it has // Received no votes (cannot) // Must not be UNREGISTERABLE - t(uint256(newStatus) == uint256(Governance.InitiativeStatus.SKIP), "Must be SKIP"); + t(uint256(newStatus) == uint256(IGovernance.InitiativeStatus.SKIP), "Must be SKIP"); } } @@ -385,10 +385,10 @@ abstract contract GovernanceProperties is BeforeAfter { // In the next epoch it will remain UNREGISTERABLE address initiative = _getDeployedInitiative(initiativeIndex); - (Governance.InitiativeStatus status,,) = governance.getInitiativeState(initiative); - if (status == Governance.InitiativeStatus.UNREGISTERABLE) { + (IGovernance.InitiativeStatus status,,) = governance.getInitiativeState(initiative); + if (status == IGovernance.InitiativeStatus.UNREGISTERABLE) { vm.warp(block.timestamp + governance.EPOCH_DURATION()); - (Governance.InitiativeStatus newStatus,,) = governance.getInitiativeState(initiative); + (IGovernance.InitiativeStatus newStatus,,) = governance.getInitiativeState(initiative); t(uint256(status) == uint256(newStatus), "UNREGISTERABLE must remain UNREGISTERABLE"); } } @@ -399,12 +399,12 @@ abstract contract GovernanceProperties is BeforeAfter { // Check if initiative is claimable // If it is assert the check for (uint256 i; i < deployedInitiatives.length; i++) { - (Governance.InitiativeStatus status,,) = governance.getInitiativeState(deployedInitiatives[i]); + (IGovernance.InitiativeStatus status,,) = governance.getInitiativeState(deployedInitiatives[i]); (, Governance.InitiativeState memory initiativeState,) = governance.getInitiativeSnapshotAndState(deployedInitiatives[i]); - if (status == Governance.InitiativeStatus.CLAIMABLE) { + if (status == IGovernance.InitiativeStatus.CLAIMABLE) { t(governance.epoch() > 0, "Can never be claimable in epoch 0!"); // Overflow Check, also flags misconfiguration // Normal check t(initiativeState.lastEpochClaim < governance.epoch() - 1, "Cannot be CLAIMABLE, should be CLAIMED"); @@ -425,7 +425,7 @@ abstract contract GovernanceProperties is BeforeAfter { uint256 claimableSum; for (uint256 i; i < deployedInitiatives.length; i++) { // NOTE: Non view so it accrues state - (Governance.InitiativeStatus status,, uint256 claimableAmount) = + (IGovernance.InitiativeStatus status,, uint256 claimableAmount) = governance.getInitiativeState(deployedInitiatives[i]); claimableSum += claimableAmount; @@ -466,10 +466,10 @@ abstract contract GovernanceProperties is BeforeAfter { (uint88 allocVotes, uint88 allocVetos,) = governance.lqtyAllocatedByUserToInitiative(theUser, deployedInitiatives[i]); if (skipDisabled) { - (Governance.InitiativeStatus status,,) = governance.getInitiativeState(deployedInitiatives[i]); + (IGovernance.InitiativeStatus status,,) = governance.getInitiativeState(deployedInitiatives[i]); // Conditionally add based on state - if (status != Governance.InitiativeStatus.DISABLED) { + if (status != IGovernance.InitiativeStatus.DISABLED) { votes += allocVotes; vetos += allocVetos; } diff --git a/test/recon/properties/OptimizationProperties.sol b/test/recon/properties/OptimizationProperties.sol index c57126c8..acf535f6 100644 --- a/test/recon/properties/OptimizationProperties.sol +++ b/test/recon/properties/OptimizationProperties.sol @@ -45,7 +45,7 @@ abstract contract OptimizationProperties is GovernanceProperties { uint256 claimableSum; for (uint256 i; i < deployedInitiatives.length; i++) { // NOTE: Non view so it accrues state - (Governance.InitiativeStatus status,, uint256 claimableAmount) = + (IGovernance.InitiativeStatus status,, uint256 claimableAmount) = governance.getInitiativeState(deployedInitiatives[i]); claimableSum += claimableAmount; @@ -68,7 +68,7 @@ abstract contract OptimizationProperties is GovernanceProperties { uint256 claimableSum; for (uint256 i; i < deployedInitiatives.length; i++) { // NOTE: Non view so it accrues state - (Governance.InitiativeStatus status,, uint256 claimableAmount) = + (IGovernance.InitiativeStatus status,, uint256 claimableAmount) = governance.getInitiativeState(deployedInitiatives[i]); claimableSum += claimableAmount; diff --git a/test/recon/targets/GovernanceTargets.sol b/test/recon/targets/GovernanceTargets.sol index e790c493..d73d4e5d 100644 --- a/test/recon/targets/GovernanceTargets.sol +++ b/test/recon/targets/GovernanceTargets.sol @@ -9,7 +9,7 @@ import {console2} from "forge-std/Test.sol"; import {Properties} from "../Properties.sol"; import {MaliciousInitiative} from "../../mocks/MaliciousInitiative.sol"; import {BribeInitiative} from "src/BribeInitiative.sol"; -import {Governance} from "src/Governance.sol"; +import {IGovernance} from "src/interfaces/IGovernance.sol"; import {ILQTYStaking} from "src/interfaces/ILQTYStaking.sol"; import {IInitiative} from "src/interfaces/IInitiative.sol"; import {IUserProxy} from "src/interfaces/IUserProxy.sol"; @@ -45,7 +45,7 @@ abstract contract GovernanceTargets is BaseTargetFunctions, Properties { // StateB4 (uint88 b4_global_allocatedLQTY,) = governance.globalState(); - (Governance.InitiativeStatus status,,) = governance.getInitiativeState(initiatives[0]); + (IGovernance.InitiativeStatus status,,) = governance.getInitiativeState(initiatives[0]); try governance.allocateLQTY(initiativesToReset, initiatives, deltaLQTYVotesArray, deltaLQTYVetosArray) { t(deltaLQTYVotesArray[0] == 0 || deltaLQTYVetosArray[0] == 0, "One alloc must be zero"); @@ -64,7 +64,7 @@ abstract contract GovernanceTargets is BaseTargetFunctions, Properties { // (uint88 after_user_allocatedLQTY,) = governance.userStates(user); // TODO (uint88 after_global_allocatedLQTY,) = governance.globalState(); - if (status == Governance.InitiativeStatus.DISABLED) { + if (status == IGovernance.InitiativeStatus.DISABLED) { // NOTE: It could be 0 lte(after_global_allocatedLQTY, b4_global_allocatedLQTY, "Alloc can only be strictly decreasing"); } diff --git a/test/recon/trophies/SecondTrophiesToFoundry.sol b/test/recon/trophies/SecondTrophiesToFoundry.sol index b71f0908..c2bac8ba 100644 --- a/test/recon/trophies/SecondTrophiesToFoundry.sol +++ b/test/recon/trophies/SecondTrophiesToFoundry.sol @@ -201,9 +201,9 @@ contract SecondTrophiesToFoundry is Test, TargetFunctions, FoundryAsserts { for (uint256 i; i < deployedInitiatives.length; i++) { (IGovernance.InitiativeVoteSnapshot memory initiativeSnapshot,,) = governance.getInitiativeSnapshotAndState(deployedInitiatives[i]); - (Governance.InitiativeStatus status,,) = governance.getInitiativeState(deployedInitiatives[i]); + (IGovernance.InitiativeStatus status,,) = governance.getInitiativeState(deployedInitiatives[i]); - // if (status != Governance.InitiativeStatus.DISABLED) { + // if (status != IGovernance.InitiativeStatus.DISABLED) { // FIX: Only count total if initiative is not disabled initiativeVotesSum += initiativeSnapshot.votes; // } From 567ba0881e6fc5313d649906ba1a7a43da6af853 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=9Fingen?= Date: Wed, 4 Dec 2024 18:04:20 +0000 Subject: [PATCH 3/3] chore: forge fmt --- src/interfaces/IGovernance.sol | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/interfaces/IGovernance.sol b/src/interfaces/IGovernance.sol index 3dd3aba1..5f8fecb1 100644 --- a/src/interfaces/IGovernance.sol +++ b/src/interfaces/IGovernance.sol @@ -285,7 +285,9 @@ interface IGovernance { } - function getInitiativeState(address _initiative) external returns (InitiativeStatus status, uint16 lastEpochClaim, uint256 claimableAmount); + function getInitiativeState(address _initiative) + external + returns (InitiativeStatus status, uint16 lastEpochClaim, uint256 claimableAmount); function getInitiativeState( address _initiative,