diff --git a/test/invariant/fuzz/FuzzTest.t.sol b/test/invariant/fuzz/FuzzTest.t.sol index 570d4776..223d6a70 100644 --- a/test/invariant/fuzz/FuzzTest.t.sol +++ b/test/invariant/fuzz/FuzzTest.t.sol @@ -5,7 +5,7 @@ import {PropertiesParent} from "./properties/PropertiesParent.t.sol"; contract FuzzTest is PropertiesParent { /// @custom:property-id 0 - /// @custom:property Check if + /// @custom:property Check sanity function property_sanityCheck() public { assertTrue(address(allo) != address(0), "sanity check"); assertTrue(address(registry) != address(0), "sanity check"); @@ -15,6 +15,5 @@ contract FuzzTest is PropertiesParent { assertTrue(allo.isTrustedForwarder(forwarder), "sanity check"); } - // This is a good place to include Forge test for debugging purposes - function test_forgeDebug() public {} + function test_debug() public {} } diff --git a/test/invariant/fuzz/Setup.t.sol b/test/invariant/fuzz/Setup.t.sol index b38f71f8..ce4fb87c 100644 --- a/test/invariant/fuzz/Setup.t.sol +++ b/test/invariant/fuzz/Setup.t.sol @@ -8,6 +8,10 @@ import {Allo, IAllo, Metadata} from "contracts/core/Allo.sol"; import {Registry, Anchor} from "contracts/core/Anchor.sol"; import {IRegistry} from "contracts/core/interfaces/IRegistry.sol"; import {DirectAllocationStrategy} from "contracts/strategies/examples/direct-allocation/DirectAllocation.sol"; +import {QVSimple} from "contracts/strategies/examples/quadratic-voting/QVSimple.sol"; +import {SQFSuperfluid} from "contracts/strategies/examples/sqf-superfluid/SQFSuperfluid.sol"; + +import {IRecipientsExtension} from "strategies/extensions/register/IRecipientsExtension.sol"; import {Actors} from "./helpers/Actors.t.sol"; import {Pools} from "./helpers/Pools.t.sol"; @@ -18,6 +22,13 @@ contract Setup is Actors, Pools { uint256 percentFee; uint256 baseFee; + uint64 defaultRegistrationStartTime; + uint64 defaultRegistrationEndTime; + uint256 defaultAllocationStartTime; + uint256 defaultAllocationEndTime; + uint256 defaultWithdrawalCooldown; + uint256 DEFAULT_MAX_BID; + Allo allo; Registry registry; @@ -80,5 +91,101 @@ contract Setup is Actors, Pools { registry.getProfileById(_id).anchor ); } + + // Create pools for each strategy + _initPools(); + } + + function _initPools() internal { + defaultRegistrationStartTime = uint64(block.timestamp); + defaultRegistrationEndTime = uint64(block.timestamp + 7 days); + defaultAllocationStartTime = uint64(block.timestamp + 7 days + 1); + defaultAllocationEndTime = uint64(block.timestamp + 10 days); + defaultWithdrawalCooldown = 1 days; + DEFAULT_MAX_BID = 1000; + + for (uint256 i = 1; i <= uint256(type(PoolStrategies).max); i++) { + address _deployer = _ghost_actors[i % 4]; + + IRegistry.Profile memory profile = registry.getProfileByAnchor( + _ghost_anchorOf[_deployer] + ); + + bytes memory _metadata; + + if (PoolStrategies(i) == PoolStrategies.DirectAllocation) { + _metadata = ""; + } else if (PoolStrategies(i) == PoolStrategies.DonationVoting) { + _metadata = abi.encode( + IRecipientsExtension.RecipientInitializeData({ + metadataRequired: false, + registrationStartTime: defaultRegistrationStartTime, + registrationEndTime: defaultRegistrationEndTime + }), + defaultAllocationStartTime, + defaultAllocationEndTime, + defaultWithdrawalCooldown, + token, + true + ); + } else if ( + PoolStrategies(i) == PoolStrategies.EasyRPGF + ) {} else if (PoolStrategies(i) == PoolStrategies.ImpactStream) { + _metadata = abi.encode( + IRecipientsExtension.RecipientInitializeData({ + metadataRequired: false, + registrationStartTime: uint64(block.timestamp), + registrationEndTime: uint64(block.timestamp + 7 days) + }), + QVSimple.QVSimpleInitializeData({ + allocationStartTime: uint64(block.timestamp), + allocationEndTime: uint64(block.timestamp + 7 days), + maxVoiceCreditsPerAllocator: 100, + isUsingAllocationMetadata: false + }) + ); + } else if (PoolStrategies(i) == PoolStrategies.QuadraticVoting) { + _metadata = abi.encode( + IRecipientsExtension.RecipientInitializeData({ + metadataRequired: false, + registrationStartTime: uint64(block.timestamp), + registrationEndTime: uint64(block.timestamp + 7 days) + }), + QVSimple.QVSimpleInitializeData({ + allocationStartTime: uint64(block.timestamp), + allocationEndTime: uint64(block.timestamp + 7 days), + maxVoiceCreditsPerAllocator: 100, + isUsingAllocationMetadata: false + }) + ); + } else if (PoolStrategies(i) == PoolStrategies.RFP) { + _metadata = abi.encode( + IRecipientsExtension.RecipientInitializeData({ + metadataRequired: false, + registrationStartTime: uint64(block.timestamp), + registrationEndTime: uint64(block.timestamp + 7 days) + }), + DEFAULT_MAX_BID + ); + } else if (PoolStrategies(i) == PoolStrategies.SQFSuperfluid) { + // Skip for now - mock? + return; + } + + vm.prank(_deployer); + uint256 _poolId = allo.createPool( + profile.id, + _strategyImplementations[PoolStrategies(i)], + _metadata, + address(token), + 0, + profile.metadata, + new address[](0) + ); + + ghost_poolAdmins[_poolId] = _deployer; + + _recordPool(_poolId, PoolStrategies(i)); + } } } diff --git a/test/invariant/fuzz/handlers/HandlerAllo.t.sol b/test/invariant/fuzz/handlers/HandlerAllo.t.sol index f51d9b5c..113671e8 100644 --- a/test/invariant/fuzz/handlers/HandlerAllo.t.sol +++ b/test/invariant/fuzz/handlers/HandlerAllo.t.sol @@ -8,7 +8,6 @@ import {FuzzERC20} from "../helpers/FuzzERC20.sol"; contract HandlerAllo is Setup { mapping(uint256 _poolId => address[] _managers) ghost_poolManagers; - mapping(uint256 _poolId => address _poolAdmin) ghost_poolAdmins; mapping(uint256 _poolId => address[] _recipients) ghost_recipients; function handler_createPool( @@ -50,15 +49,6 @@ contract HandlerAllo is Setup { ) ) ); - - if (succ) { - uint256 _poolId = abi.decode(ret, (uint256)); - ghost_poolAdmins[_poolId] = msg.sender; - - _recordPool(_poolId, PoolStrategies(_seedPoolStrategy)); - } - - assert(ghost_poolIds.length < 4); } function handler_updatePoolMetadata( diff --git a/test/invariant/fuzz/helpers/Pools.t.sol b/test/invariant/fuzz/helpers/Pools.t.sol index cae89262..cf7b15ec 100644 --- a/test/invariant/fuzz/helpers/Pools.t.sol +++ b/test/invariant/fuzz/helpers/Pools.t.sol @@ -29,6 +29,8 @@ contract Pools is Utils { } uint256[] internal ghost_poolIds; + mapping(uint256 _poolId => address _poolAdmin) ghost_poolAdmins; + // mapping(uint256 _poolId => PoolStrategies _strategy) internal _poolStrategy; mapping(PoolStrategies _strategy => address _implementation) @@ -67,8 +69,7 @@ contract Pools is Utils { // reverse lookup pool id -> strategy type function _poolStrategy(uint256 _poolId) internal returns (PoolStrategies) { - IAllo.Pool memory _pool = allo.getPool(ghost_poolIds[_poolId]); - + IAllo.Pool memory _pool = allo.getPool(_poolId); for (uint256 i; i < uint256(type(PoolStrategies).max); i++) if ( _strategyImplementations[PoolStrategies(i)] ==