From b859f7e909d83612d0631751050e88f35582a83a Mon Sep 17 00:00:00 2001 From: Austrian <114922365+0xAustrian@users.noreply.github.com> Date: Tue, 4 Feb 2025 06:46:59 -0300 Subject: [PATCH 1/9] fix: collision in ContractFactory (#64) --- contracts/factories/ContractFactory.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contracts/factories/ContractFactory.sol b/contracts/factories/ContractFactory.sol index e1ab0a8c1..abb3ab6d1 100644 --- a/contracts/factories/ContractFactory.sol +++ b/contracts/factories/ContractFactory.sol @@ -97,7 +97,7 @@ contract ContractFactory { returns (address deployedContract) { // hash salt with the contract name and version - bytes32 salt = keccak256(abi.encodePacked(_contractName, _version)); + bytes32 salt = keccak256(abi.encode(_contractName, _version)); // ensure salt has not been used if (usedSalts[salt]) revert SALT_USED(); From cb213bed872c061074418c4466294efca423c764 Mon Sep 17 00:00:00 2001 From: Austrian <114922365+0xAustrian@users.noreply.github.com> Date: Tue, 4 Feb 2025 06:48:46 -0300 Subject: [PATCH 2/9] feat: add missing events in recoverFunds functions (#62) --- contracts/core/Allo.sol | 2 ++ contracts/core/Registry.sol | 2 ++ contracts/core/interfaces/IAllo.sol | 5 +++++ contracts/core/interfaces/IRegistry.sol | 5 +++++ test/unit/core/AlloUnit.t.sol | 8 ++++++++ test/unit/core/AlloUnit.tree | 5 +++-- test/unit/core/RegistryUnit.t.sol | 4 ++++ test/unit/core/RegistryUnit.tree | 3 ++- 8 files changed, 31 insertions(+), 3 deletions(-) diff --git a/contracts/core/Allo.sol b/contracts/core/Allo.sol index f6d3fda7a..5a353715e 100644 --- a/contracts/core/Allo.sol +++ b/contracts/core/Allo.sol @@ -322,6 +322,8 @@ contract Allo is IAllo, Initializable, Ownable, AccessControlUpgradeable, Reentr // Transfer the amount to the recipient (pool owner) _token.transferAmount(_recipient, _amount); + + emit FundsRecovered(_token, _recipient); } // ==================================== diff --git a/contracts/core/Registry.sol b/contracts/core/Registry.sol index e01cae14d..8fa701d46 100644 --- a/contracts/core/Registry.sol +++ b/contracts/core/Registry.sol @@ -386,5 +386,7 @@ contract Registry is IRegistry, Initializable, AccessControlUpgradeable, Errors uint256 amount = _token.getBalance(address(this)); _token.transferAmount(_recipient, amount); + + emit FundsRecovered(_token, _recipient); } } diff --git a/contracts/core/interfaces/IAllo.sol b/contracts/core/interfaces/IAllo.sol index 2c694a913..fdfc3f26c 100644 --- a/contracts/core/interfaces/IAllo.sol +++ b/contracts/core/interfaces/IAllo.sol @@ -103,6 +103,11 @@ interface IAllo { /// @param trustedForwarder Address of the new trusted forwarder event TrustedForwarderUpdated(address trustedForwarder); + /// @notice Emitted when funds are recovered + /// @param token The token recovered + /// @param recipient The recipient of the funds + event FundsRecovered(address token, address recipient); + /// ==================================== /// ==== External/Public Functions ===== /// ==================================== diff --git a/contracts/core/interfaces/IRegistry.sol b/contracts/core/interfaces/IRegistry.sol index a4658379e..9aab245f6 100644 --- a/contracts/core/interfaces/IRegistry.sol +++ b/contracts/core/interfaces/IRegistry.sol @@ -88,6 +88,11 @@ interface IRegistry { /// @param pendingOwner The address of the pending owner event ProfilePendingOwnerUpdated(bytes32 indexed profileId, address pendingOwner); + /// @dev Emitted when funds are recovered + /// @param token The token recovered + /// @param recipient The recipient of the funds + event FundsRecovered(address token, address recipient); + /// ========================= /// ==== View Functions ===== /// ========================= diff --git a/test/unit/core/AlloUnit.t.sol b/test/unit/core/AlloUnit.t.sol index 256b7ce03..e974e2ab6 100644 --- a/test/unit/core/AlloUnit.t.sol +++ b/test/unit/core/AlloUnit.t.sol @@ -561,6 +561,14 @@ contract AlloUnit is Test { allo.recoverFunds(NATIVE, _recipient); } + function test_RecoverFundsWhenSenderIsOwner(address _recipient) external whenSenderIsOwner { + // it should emit FundsRecovered event + vm.expectEmit(); + emit IAllo.FundsRecovered(NATIVE, _recipient); + + allo.recoverFunds(NATIVE, _recipient); + } + function test_RecoverFundsWhenTokenIsNative(address _recipient) external whenSenderIsOwner { vm.assume(_recipient != address(0)); vm.assume(_recipient.code.length == 0); diff --git a/test/unit/core/AlloUnit.tree b/test/unit/core/AlloUnit.tree index e023d6ced..b5f7e8884 100644 --- a/test/unit/core/AlloUnit.tree +++ b/test/unit/core/AlloUnit.tree @@ -105,8 +105,9 @@ AlloUnit::recoverFunds └── when sender is owner ├── when token is native │ └── it should transfer the whole balance of native token - └── when token is not native - └── it should transfer the whole balance of token + ├── when token is not native + │ └── it should transfer the whole balance of token + └── it should emit FundsRecovered event AlloUnit::registerRecipient ├── it should transfer the msg.value received diff --git a/test/unit/core/RegistryUnit.t.sol b/test/unit/core/RegistryUnit.t.sol index 5756d8c10..3b3a3f351 100644 --- a/test/unit/core/RegistryUnit.t.sol +++ b/test/unit/core/RegistryUnit.t.sol @@ -406,6 +406,10 @@ contract RegistryUnit is Test { vm.mockCall(_token, abi.encodeWithSignature("balanceOf(address)", address(registry)), abi.encode(_amount)); vm.mockCall(_token, abi.encodeWithSignature("transfer(address,uint256)", _recipient, _amount), abi.encode(true)); + // it should emit FundsRecovered event + vm.expectEmit(); + emit IRegistry.FundsRecovered(_token, _recipient); + // it should call getBalance vm.expectCall(_token, abi.encodeWithSignature("balanceOf(address)", address(registry))); diff --git a/test/unit/core/RegistryUnit.tree b/test/unit/core/RegistryUnit.tree index c4aeac453..b352029a0 100644 --- a/test/unit/core/RegistryUnit.tree +++ b/test/unit/core/RegistryUnit.tree @@ -98,4 +98,5 @@ Registry::recoverFunds │ └── it should revert └── when recipient is not zero address ├── it should call getBalance - └── it should call transfer \ No newline at end of file + ├── it should call transfer + └── it should emit FundsRecovered event \ No newline at end of file From b2adabdda5eb1f48b0046579354a9ce389ce91a7 Mon Sep 17 00:00:00 2001 From: Austrian <114922365+0xAustrian@users.noreply.github.com> Date: Tue, 4 Feb 2025 06:49:00 -0300 Subject: [PATCH 3/9] fix: typo (#61) --- .../examples/donation-voting/DonationVotingOffchain.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contracts/strategies/examples/donation-voting/DonationVotingOffchain.sol b/contracts/strategies/examples/donation-voting/DonationVotingOffchain.sol index 3a729cdc1..c1f68a1c0 100644 --- a/contracts/strategies/examples/donation-voting/DonationVotingOffchain.sol +++ b/contracts/strategies/examples/donation-voting/DonationVotingOffchain.sol @@ -290,7 +290,7 @@ contract DonationVotingOffchain is BaseStrategy, RecipientsExtension, Allocation if (block.timestamp <= allocationEndTime + withdrawalCooldown) revert INVALID(); } - /// @notice Hook called after increasing the pool amount. + /// @notice Hook called before increasing the pool amount. /// @param _amount The amount to increase the pool by function _beforeIncreasePoolAmount(uint256 _amount) internal virtual override { if (block.timestamp > allocationEndTime) revert AllocationExtension_ALLOCATION_HAS_ENDED(); From 64239ceb5c8fb5882aedbacfb516603cedf8d53e Mon Sep 17 00:00:00 2001 From: Austrian <114922365+0xAustrian@users.noreply.github.com> Date: Tue, 4 Feb 2025 07:03:41 -0300 Subject: [PATCH 4/9] feat: change address (#60) --- .../donation-voting/DonationVotingOffchain.sol | 2 +- .../extensions/allocate/AllocationExtension.sol | 8 ++++++-- .../extensions/allocate/IAllocationExtension.sol | 7 +++++++ .../extensions/AllocationExtensionUnit.t.sol | 12 ++++++++++-- .../extensions/AllocationExtensionUnit.tree | 4 +++- 5 files changed, 27 insertions(+), 6 deletions(-) diff --git a/contracts/strategies/examples/donation-voting/DonationVotingOffchain.sol b/contracts/strategies/examples/donation-voting/DonationVotingOffchain.sol index c1f68a1c0..e8c969cc3 100644 --- a/contracts/strategies/examples/donation-voting/DonationVotingOffchain.sol +++ b/contracts/strategies/examples/donation-voting/DonationVotingOffchain.sol @@ -233,7 +233,7 @@ contract DonationVotingOffchain is BaseStrategy, RecipientsExtension, Allocation for (uint256 i; i < __recipients.length; i++) { if (!_isAcceptedRecipient(__recipients[i])) revert RecipientsExtension_RecipientNotAccepted(); - if (!allowedTokens[_tokens[i]] && !allowedTokens[address(0)]) { + if (!allowedTokens[_tokens[i]] && !allowedTokens[ALL_TOKENS_ALLOWED]) { revert DonationVotingOffchain_TokenNotAllowed(); } diff --git a/contracts/strategies/extensions/allocate/AllocationExtension.sol b/contracts/strategies/extensions/allocate/AllocationExtension.sol index 5eefee62d..3ef2a5a5f 100644 --- a/contracts/strategies/extensions/allocate/AllocationExtension.sol +++ b/contracts/strategies/extensions/allocate/AllocationExtension.sol @@ -10,6 +10,9 @@ abstract contract AllocationExtension is BaseStrategy, IAllocationExtension { /// ========== Storage ============= /// ================================ + /// @notice The address sent when all tokens are allowed + address public constant ALL_TOKENS_ALLOWED = address(0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE); + /// @notice The start time for allocations uint64 public allocationStartTime; /// @notice The end time for allocations @@ -39,9 +42,10 @@ abstract contract AllocationExtension is BaseStrategy, IAllocationExtension { ) internal virtual { if (_allowedTokens.length == 0) { // all tokens - allowedTokens[address(0)] = true; + allowedTokens[ALL_TOKENS_ALLOWED] = true; } else { for (uint256 i; i < _allowedTokens.length; i++) { + if (_allowedTokens[i] == address(0)) revert AllocationExtension_ZERO_ADDRESS_NOT_ALLOWED(); allowedTokens[_allowedTokens[i]] = true; } } @@ -90,7 +94,7 @@ abstract contract AllocationExtension is BaseStrategy, IAllocationExtension { /// @return 'true' if the token is allowed, otherwise 'false' function _isAllowedToken(address _token) internal view virtual returns (bool) { // all tokens allowed - if (allowedTokens[address(0)]) return true; + if (allowedTokens[ALL_TOKENS_ALLOWED]) return true; if (allowedTokens[_token]) return true; diff --git a/contracts/strategies/extensions/allocate/IAllocationExtension.sol b/contracts/strategies/extensions/allocate/IAllocationExtension.sol index f97639250..9de6600ac 100644 --- a/contracts/strategies/extensions/allocate/IAllocationExtension.sol +++ b/contracts/strategies/extensions/allocate/IAllocationExtension.sol @@ -17,12 +17,19 @@ interface IAllocationExtension { /// @dev Error thrown when trying to call the function when the allocation has ended error AllocationExtension_ALLOCATION_HAS_ENDED(); + /// @dev Error thrown when sending the zero address as a token + error AllocationExtension_ZERO_ADDRESS_NOT_ALLOWED(); + /// @notice Emitted when the allocation timestamps are updated /// @param allocationStartTime The start time for the allocation period /// @param allocationEndTime The end time for the allocation period /// @param sender The sender of the transaction event AllocationTimestampsUpdated(uint64 allocationStartTime, uint64 allocationEndTime, address sender); + /// @notice Returns the address sent when all tokens are allowed + /// @return address sent when all tokens are allowed + function ALL_TOKENS_ALLOWED() external view returns (address); + /// @notice The start time for the allocation period /// @return allocationStartTime function allocationStartTime() external view returns (uint64); diff --git a/test/unit/strategies/extensions/AllocationExtensionUnit.t.sol b/test/unit/strategies/extensions/AllocationExtensionUnit.t.sol index d94ff633f..eeb15f5ee 100644 --- a/test/unit/strategies/extensions/AllocationExtensionUnit.t.sol +++ b/test/unit/strategies/extensions/AllocationExtensionUnit.t.sol @@ -14,11 +14,18 @@ contract AllocationExtension is Test { extension = new MockMockAllocationExtension(address(0), "MockAllocationExtension"); } + function test___AllocationExtension_initRevertWhen_AllowedTokensArrayIncludesZeroAddress() external { + // It should revert + vm.expectRevert(IAllocationExtension.AllocationExtension_ZERO_ADDRESS_NOT_ALLOWED.selector); + + extension.call___AllocationExtension_init(new address[](1), 0, 0, false); + } + function test___AllocationExtension_initWhenAllowedTokensArrayIsEmpty() external { extension.call___AllocationExtension_init(new address[](0), 0, 0, false); - // It should mark address zero as true - assertTrue(extension.allowedTokens(address(0))); + // It should mark address of all tokens allowed as true + assertTrue(extension.allowedTokens(extension.ALL_TOKENS_ALLOWED())); } function test___AllocationExtension_initWhenAllowedTokensArrayIsNotEmpty(address[] memory _tokens) external { @@ -82,6 +89,7 @@ contract AllocationExtension is Test { vm.assume(_allowedTokens.length > 0); for (uint256 i; i < _allowedTokens.length; i++) { vm.assume(_allowedTokens[i] != address(0)); + vm.assume(_allowedTokens[i] != extension.ALL_TOKENS_ALLOWED()); vm.assume(_allowedTokens[i] != _tokenToCheck); } diff --git a/test/unit/strategies/extensions/AllocationExtensionUnit.tree b/test/unit/strategies/extensions/AllocationExtensionUnit.tree index c240f2ea2..161eb552e 100644 --- a/test/unit/strategies/extensions/AllocationExtensionUnit.tree +++ b/test/unit/strategies/extensions/AllocationExtensionUnit.tree @@ -1,6 +1,8 @@ AllocationExtension::__AllocationExtension_init +├── When allowedTokens array includes zero address +│ └── It should revert ├── When allowedTokens array is empty -│ └── It should mark address zero as true +│ └── It should mark address of all tokens allowed as true ├── When allowedTokens array is not empty │ └── It should mark the tokens in the array as true ├── It should set isUsingAllocationMetadata From ee89f29d98d5e40737e24e680e0ccc0ed5b6d154 Mon Sep 17 00:00:00 2001 From: Austrian <114922365+0xAustrian@users.noreply.github.com> Date: Tue, 4 Feb 2025 08:03:03 -0300 Subject: [PATCH 5/9] chore: delete unused submodules (#63) --- .gitmodules | 12 ------------ DEV.md | 6 ++++++ contracts/factories/ContractFactory.sol | 2 +- lib/eas-contracts | 2 +- lib/eas-proxy | 1 - lib/hats-protocol | 1 - lib/hedgey-vesting | 1 - lib/permit2 | 2 +- lib/solady | 2 +- lib/superfluid-protocol-monorepo | 2 +- lib/v2-core | 1 - remappings.era.txt | 7 +------ remappings.evm.txt | 7 +------ remappings.txt | 18 +++++++----------- 14 files changed, 20 insertions(+), 44 deletions(-) delete mode 160000 lib/eas-proxy delete mode 160000 lib/hats-protocol delete mode 160000 lib/hedgey-vesting delete mode 160000 lib/v2-core diff --git a/.gitmodules b/.gitmodules index 576adff19..8ad1bc887 100644 --- a/.gitmodules +++ b/.gitmodules @@ -13,21 +13,9 @@ [submodule "lib/eas-contracts"] path = lib/eas-contracts url = https://github.com/ethereum-attestation-service/eas-contracts -[submodule "lib/v2-core"] - path = lib/v2-core - url = https://github.com/sablier-labs/v2-core [submodule "lib/permit2"] path = lib/permit2 url = https://github.com/Uniswap/permit2 -[submodule "lib/hedgey-vesting"] - path = lib/hedgey-vesting - url = https://github.com/hedgey-finance/Locked_VestingTokenPlans -[submodule "lib/hats-protocol"] - path = lib/hats-protocol - url = https://github.com/Hats-Protocol/hats-protocol [submodule "lib/superfluid-protocol-monorepo"] path = lib/superfluid-protocol-monorepo url = https://github.com/superfluid-finance/protocol-monorepo -[submodule "lib/eas-proxy"] - path = lib/eas-proxy - url = https://github.com/gitcoinco/eas-proxy diff --git a/DEV.md b/DEV.md index f2f070d35..2364940d7 100644 --- a/DEV.md +++ b/DEV.md @@ -6,6 +6,12 @@ git clone https://github.com/allo-protocol/allo-v2.1 ``` +### Install submodules + +```bash +git submodule update --init --recursive +``` + ### Install bun ```bash diff --git a/contracts/factories/ContractFactory.sol b/contracts/factories/ContractFactory.sol index abb3ab6d1..8f76745e1 100644 --- a/contracts/factories/ContractFactory.sol +++ b/contracts/factories/ContractFactory.sol @@ -104,7 +104,7 @@ contract ContractFactory { usedSalts[salt] = true; - deployedContract = CREATE3.deploy(salt, creationCode, msg.value); + deployedContract = CREATE3.deployDeterministic(msg.value, creationCode, salt); emit Deployed(deployedContract, salt); } diff --git a/lib/eas-contracts b/lib/eas-contracts index c14cc70df..d223e1720 160000 --- a/lib/eas-contracts +++ b/lib/eas-contracts @@ -1 +1 @@ -Subproject commit c14cc70df0658ce7c4236f94f6902fe4c79a522d +Subproject commit d223e17208aa110dd5ec694d77324a2321d93201 diff --git a/lib/eas-proxy b/lib/eas-proxy deleted file mode 160000 index b78e9c56e..000000000 --- a/lib/eas-proxy +++ /dev/null @@ -1 +0,0 @@ -Subproject commit b78e9c56edc7f0111320404f9e0efd2e4f8c9c5f diff --git a/lib/hats-protocol b/lib/hats-protocol deleted file mode 160000 index b4cdfbd96..000000000 --- a/lib/hats-protocol +++ /dev/null @@ -1 +0,0 @@ -Subproject commit b4cdfbd964226d342afb1b0c8ebd92e0055f5b60 diff --git a/lib/hedgey-vesting b/lib/hedgey-vesting deleted file mode 160000 index 083fa57b0..000000000 --- a/lib/hedgey-vesting +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 083fa57b0efa3c49640820a58b5ba7d0d941aa7a diff --git a/lib/permit2 b/lib/permit2 index 576f549a7..cc56ad0f3 160000 --- a/lib/permit2 +++ b/lib/permit2 @@ -1 +1 @@ -Subproject commit 576f549a7351814f112edcc42f3f8472d1712673 +Subproject commit cc56ad0f3439c502c246fc5cfcc3db92bb8b7219 diff --git a/lib/solady b/lib/solady index 6c54795ef..21e364984 160000 --- a/lib/solady +++ b/lib/solady @@ -1 +1 @@ -Subproject commit 6c54795ef69838e233020e9ab29f3f6288efdf06 +Subproject commit 21e3649841829dd3b265d1228defefb23b5d977b diff --git a/lib/superfluid-protocol-monorepo b/lib/superfluid-protocol-monorepo index 886c0f176..b86ec54fb 160000 --- a/lib/superfluid-protocol-monorepo +++ b/lib/superfluid-protocol-monorepo @@ -1 +1 @@ -Subproject commit 886c0f176f10ce26aec0adbf2b20b3a10a33984f +Subproject commit b86ec54fb628a8e28977d52c95b8aac0b1db20c3 diff --git a/lib/v2-core b/lib/v2-core deleted file mode 160000 index 1a206ed69..000000000 --- a/lib/v2-core +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 1a206ed69f7b49d229db043e748a098cf3f1da22 diff --git a/remappings.era.txt b/remappings.era.txt index 5e2de5bee..05e20946d 100644 --- a/remappings.era.txt +++ b/remappings.era.txt @@ -1,14 +1,9 @@ -@sablier/v2-core/=lib/v2-core/ ds-test/=lib/forge-std/lib/ds-test/src/ erc4626-tests/=lib/openzeppelin-contracts-upgradeable/lib/erc4626-tests/ forge-std/=lib/forge-std/src/ permit2/=lib/permit2/src/interfaces/ openzeppelin-contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/ -@prb/math/=lib/v2-core/lib/prb-math/ eas-contracts/=lib/eas-contracts/contracts/ -hats-protocol/=lib/hats-protocol/src/ @superfluid-finance/=lib/superfluid-protocol-monorepo/packages/ solady/=lib/solady/src/ -@openzeppelin/contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/ -lib/ERC1155/=lib/hats-protocol/lib/ERC1155/ -hedgey-vesting/=lib/hedgey-vesting/contracts/ \ No newline at end of file +@openzeppelin/contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/ \ No newline at end of file diff --git a/remappings.evm.txt b/remappings.evm.txt index 0340fa5de..7d1c03c3b 100644 --- a/remappings.evm.txt +++ b/remappings.evm.txt @@ -1,16 +1,11 @@ @openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/ -@sablier/v2-core/=lib/v2-core/ ds-test/=lib/forge-std/lib/ds-test/src/ erc4626-tests/=lib/openzeppelin-contracts-upgradeable/lib/erc4626-tests/ forge-std/=lib/forge-std/src/ permit2/=lib/permit2/src/interfaces/ openzeppelin-contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/ openzeppelin-contracts/=lib/openzeppelin-contracts/ -@prb/math/=lib/v2-core/lib/prb-math/ eas-contracts/=lib/eas-contracts/contracts/ -hats-protocol/=lib/hats-protocol/src/ @superfluid-finance/=lib/superfluid-protocol-monorepo/packages/ solady/=lib/solady/src/ -@openzeppelin/contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/ -lib/ERC1155/=lib/hats-protocol/lib/ERC1155/ -hedgey-vesting/=lib/hedgey-vesting/contracts/ \ No newline at end of file +@openzeppelin/contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/ \ No newline at end of file diff --git a/remappings.txt b/remappings.txt index 60460b9be..daab2a9ae 100644 --- a/remappings.txt +++ b/remappings.txt @@ -1,17 +1,13 @@ -@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/ -@sablier/v2-core/=lib/v2-core/ ds-test/=lib/forge-std/lib/ds-test/src/ -erc4626-tests/=lib/openzeppelin-contracts-upgradeable/lib/erc4626-tests/ forge-std/=lib/forge-std/src/ -permit2/=lib/permit2/src/interfaces/ -openzeppelin-contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/ +erc4626-tests/=lib/openzeppelin-contracts-upgradeable/lib/erc4626-tests/ openzeppelin-contracts/=lib/openzeppelin-contracts/ -@prb/math/=lib/v2-core/lib/prb-math/ +openzeppelin-contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/ +@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/ +@openzeppelin/contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/ +permit2/=lib/permit2/src/interfaces/ eas-contracts/=lib/eas-contracts/contracts/ -hats-protocol/=lib/hats-protocol/src/ @superfluid-finance/=lib/superfluid-protocol-monorepo/packages/ solady/=lib/solady/src/ -@openzeppelin/contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/ -lib/ERC1155/=lib/hats-protocol/lib/ERC1155/ -hedgey-vesting/=lib/hedgey-vesting/contracts/ -strategies/=contracts/strategies/ + +strategies/=contracts/strategies/ \ No newline at end of file From fc36504b5883c66e980610ee5d499aa82a9c397d Mon Sep 17 00:00:00 2001 From: Austrian <114922365+0xAustrian@users.noreply.github.com> Date: Tue, 4 Feb 2025 08:10:20 -0300 Subject: [PATCH 6/9] fix: compilation warnings (#59) --- .github/workflows/forge-test.yml | 4 -- .../DonationVotingMerkleDistribution.sol | 3 +- .../DonationVotingOffchain.sol | 19 +++---- .../donation-voting/DonationVotingOnchain.sol | 14 ++--- .../examples/quadratic-voting/QVSimple.sol | 9 ++-- .../strategies/examples/rfp/RFPSimple.sol | 3 +- .../sqf-superfluid/RecipientSuperApp.sol | 52 ++++++------------- .../examples/sqf-superfluid/SQFSuperfluid.sol | 22 +++----- .../register/RecipientsExtension.sol | 4 +- foundry.toml | 5 ++ .../DonationVotingMerkleDistribution.t.sol | 3 +- test/integration/DonationVotingOffchain.t.sol | 3 +- test/integration/DonationVotingOnchain.t.sol | 3 +- test/mocks/MockGatingExtension.sol | 2 +- .../smock-mocks/MockAllocationExtension.sol | 4 +- .../MockAllocatorsAllowlistExtension.sol | 4 +- test/mocks/smock-mocks/MockBaseStrategy.sol | 18 +++---- .../smock-mocks/MockEASGatingExtension.sol | 4 +- .../smock-mocks/MockMilestonesExtension.sol | 10 ++-- .../smock-mocks/MockRecipientsExtension.sol | 8 +-- test/unit/core/AnchorUnit.t.sol | 11 ++-- .../extensions/RecipientsExtensionUnit.t.sol | 2 - 22 files changed, 83 insertions(+), 124 deletions(-) diff --git a/.github/workflows/forge-test.yml b/.github/workflows/forge-test.yml index d4fe8da8a..f481dc411 100644 --- a/.github/workflows/forge-test.yml +++ b/.github/workflows/forge-test.yml @@ -37,10 +37,6 @@ jobs: run: forge fmt --check id: fmt - - name: Run natspec linting - run: bun lint:natspec - id: natspec - - name: Run Forge build run: forge compile id: build diff --git a/contracts/strategies/examples/donation-voting/DonationVotingMerkleDistribution.sol b/contracts/strategies/examples/donation-voting/DonationVotingMerkleDistribution.sol index f64eb22b1..104020a7e 100644 --- a/contracts/strategies/examples/donation-voting/DonationVotingMerkleDistribution.sol +++ b/contracts/strategies/examples/donation-voting/DonationVotingMerkleDistribution.sol @@ -134,11 +134,10 @@ contract DonationVotingMerkleDistribution is DonationVotingOffchain { /// ==================================== /// @notice Distributes funds (tokens) to recipients. - /// @param _recipientIds NOT USED /// @param _data Data to be decoded /// @custom:data (Distribution[] _distributions) /// @param _sender The address of the sender - function _distribute(address[] memory _recipientIds, bytes memory _data, address _sender) + function _distribute(address[] memory, bytes memory _data, address _sender) internal virtual override diff --git a/contracts/strategies/examples/donation-voting/DonationVotingOffchain.sol b/contracts/strategies/examples/donation-voting/DonationVotingOffchain.sol index e8c969cc3..904c9293b 100644 --- a/contracts/strategies/examples/donation-voting/DonationVotingOffchain.sol +++ b/contracts/strategies/examples/donation-voting/DonationVotingOffchain.sol @@ -122,7 +122,6 @@ contract DonationVotingOffchain is BaseStrategy, RecipientsExtension, Allocation /// =============================== // @notice Initialize the strategy - /// @param _poolId ID of the pool /// @param _data The data to be decoded /// @custom:data ( /// RecipientInitializeData _recipientExtensionInitializeData, @@ -132,7 +131,7 @@ contract DonationVotingOffchain is BaseStrategy, RecipientsExtension, Allocation /// address[] _allowedTokens, /// bool _isUsingAllocationMetadata /// ) - function _initializeStrategy(uint256 _poolId, bytes memory _data) internal override { + function _initializeStrategy(uint256, bytes memory _data) internal override { // Decode _data and initialize the specific strategy data ( RecipientInitializeData memory _recipientExtensionInitializeData, @@ -257,9 +256,8 @@ contract DonationVotingOffchain is BaseStrategy, RecipientsExtension, Allocation /// @notice Distributes funds (tokens) to recipients. /// @param _recipientIds The IDs of the recipients - /// @param _data NOT USED /// @param _sender The address of the sender - function _distribute(address[] memory _recipientIds, bytes memory _data, address _sender) + function _distribute(address[] memory _recipientIds, bytes memory, address _sender) internal virtual override @@ -283,16 +281,12 @@ contract DonationVotingOffchain is BaseStrategy, RecipientsExtension, Allocation } /// @notice Hook called before withdrawing tokens from the pool. - /// @param _token The address of the token - /// @param _amount The amount to withdraw - /// @param _recipient The address to withdraw to - function _beforeWithdraw(address _token, uint256 _amount, address _recipient) internal virtual override { + function _beforeWithdraw(address, uint256, address) internal virtual override { if (block.timestamp <= allocationEndTime + withdrawalCooldown) revert INVALID(); } - /// @notice Hook called before increasing the pool amount. - /// @param _amount The amount to increase the pool by - function _beforeIncreasePoolAmount(uint256 _amount) internal virtual override { + /// @notice Hook called after increasing the pool amount. + function _beforeIncreasePoolAmount(uint256) internal virtual override { if (block.timestamp > allocationEndTime) revert AllocationExtension_ALLOCATION_HAS_ENDED(); } @@ -304,9 +298,8 @@ contract DonationVotingOffchain is BaseStrategy, RecipientsExtension, Allocation } /// @notice Returns always true as all addresses are valid allocators - /// @param _allocator NOT USED /// @return Returns always true - function _isValidAllocator(address _allocator) internal view override returns (bool) { + function _isValidAllocator(address) internal view override returns (bool) { return true; } } diff --git a/contracts/strategies/examples/donation-voting/DonationVotingOnchain.sol b/contracts/strategies/examples/donation-voting/DonationVotingOnchain.sol index 7a45dbd9a..e4e4764c1 100644 --- a/contracts/strategies/examples/donation-voting/DonationVotingOnchain.sol +++ b/contracts/strategies/examples/donation-voting/DonationVotingOnchain.sol @@ -77,7 +77,6 @@ contract DonationVotingOnchain is BaseStrategy, RecipientsExtension, AllocationE /// =============================== // @notice Initialize the strategy - /// @param _poolId ID of the pool /// @param _data The data to be decoded /// @custom:data ( /// RecipientInitializeData _recipientExtensionInitializeData, @@ -87,7 +86,7 @@ contract DonationVotingOnchain is BaseStrategy, RecipientsExtension, AllocationE /// address _allocationToken, /// bool _isUsingAllocationMetadata /// ) - function _initializeStrategy(uint256 _poolId, bytes memory _data) internal virtual override { + function _initializeStrategy(uint256, bytes memory _data) internal virtual override { ( RecipientInitializeData memory _recipientExtensionInitializeData, uint64 _allocationStartTime, @@ -183,16 +182,12 @@ contract DonationVotingOnchain is BaseStrategy, RecipientsExtension, AllocationE } /// @notice Hook called before withdrawing tokens from the pool. - /// @param _token The address of the token - /// @param _amount The amount to withdraw - /// @param _recipient The address to withdraw to - function _beforeWithdraw(address _token, uint256 _amount, address _recipient) internal virtual override { + function _beforeWithdraw(address, uint256, address) internal virtual override { if (block.timestamp <= allocationEndTime + withdrawalCooldown) revert INVALID(); } /// @notice Hook called before increasing the pool amount. - /// @param _amount The amount to increase the pool by - function _beforeIncreasePoolAmount(uint256 _amount) internal virtual override { + function _beforeIncreasePoolAmount(uint256) internal virtual override { if (block.timestamp > allocationEndTime) revert AllocationExtension_ALLOCATION_HAS_ENDED(); } @@ -204,9 +199,8 @@ contract DonationVotingOnchain is BaseStrategy, RecipientsExtension, AllocationE } /// @notice Returns always true as all addresses are valid allocators - /// @param _allocator NOT USED /// @return Returns always true - function _isValidAllocator(address _allocator) internal view override returns (bool) { + function _isValidAllocator(address) internal view override returns (bool) { return true; } } diff --git a/contracts/strategies/examples/quadratic-voting/QVSimple.sol b/contracts/strategies/examples/quadratic-voting/QVSimple.sol index 033797216..1af95a111 100644 --- a/contracts/strategies/examples/quadratic-voting/QVSimple.sol +++ b/contracts/strategies/examples/quadratic-voting/QVSimple.sol @@ -65,9 +65,8 @@ contract QVSimple is BaseStrategy, RecipientsExtension, AllocatorsAllowlistExten /// =============================== /// @notice Initialize the strategy - /// @param _poolId The pool id /// @param _data The data to initialize the strategy (Must include RecipientInitializeData and QVSimpleInitializeData) - function _initializeStrategy(uint256 _poolId, bytes memory _data) internal virtual override { + function _initializeStrategy(uint256, bytes memory _data) internal virtual override { ( IRecipientsExtension.RecipientInitializeData memory _recipientInitializeData, QVSimpleInitializeData memory _qvSimpleInitializeData @@ -103,9 +102,8 @@ contract QVSimple is BaseStrategy, RecipientsExtension, AllocatorsAllowlistExten /// @notice Distribute the tokens to the recipients /// @dev The '_sender' must be a pool manager and the allocation must have ended /// @param _recipientIds The recipient ids - /// @param _data NOT USED /// @param _sender The sender of the transaction - function _distribute(address[] memory _recipientIds, bytes memory _data, address _sender) + function _distribute(address[] memory _recipientIds, bytes memory, address _sender) internal virtual override @@ -194,8 +192,7 @@ contract QVSimple is BaseStrategy, RecipientsExtension, AllocatorsAllowlistExten } /// @notice Ensure no increase in pool amount is allowed after the distribution starts - /// @param _amount The amount to increase the pool by - function _beforeIncreasePoolAmount(uint256 _amount) internal virtual override { + function _beforeIncreasePoolAmount(uint256) internal virtual override { if (totalPayoutAmount != 0) { revert INVALID(); } diff --git a/contracts/strategies/examples/rfp/RFPSimple.sol b/contracts/strategies/examples/rfp/RFPSimple.sol index 9713d1f44..bbb355d4d 100644 --- a/contracts/strategies/examples/rfp/RFPSimple.sol +++ b/contracts/strategies/examples/rfp/RFPSimple.sol @@ -52,10 +52,9 @@ contract RFPSimple is BaseStrategy, MilestonesExtension, RecipientsExtension { /// =============================== // @notice Initialize the strategy - /// @param _poolId ID of the pool /// @param _data The data to be decoded /// @custom:data (RecipientInitializeData _recipientExtensionInitializeData, uint256 _maxBid) - function _initializeStrategy(uint256 _poolId, bytes memory _data) internal virtual override { + function _initializeStrategy(uint256, bytes memory _data) internal virtual override { (RecipientInitializeData memory _recipientExtensionInitializeData, uint256 _maxBid) = abi.decode(_data, (RecipientInitializeData, uint256)); __RecipientsExtension_init(_recipientExtensionInitializeData); diff --git a/contracts/strategies/examples/sqf-superfluid/RecipientSuperApp.sol b/contracts/strategies/examples/sqf-superfluid/RecipientSuperApp.sol index 485bf4376..aee0134c0 100644 --- a/contracts/strategies/examples/sqf-superfluid/RecipientSuperApp.sol +++ b/contracts/strategies/examples/sqf-superfluid/RecipientSuperApp.sol @@ -187,36 +187,27 @@ contract RecipientSuperApp is ISuperApp { /// ================================ /// @dev This callback is called before the flow is created - /// @param superToken NOT USED - /// @param agreementClass NOT USED - /// @param agreementId NOT USED - /// @param agreementData NOT USED - /// @param ctx NOT USED - /// @return beforeData NOT USED - function beforeAgreementCreated( - ISuperToken superToken, - address agreementClass, - bytes32 agreementId, - bytes calldata agreementData, - bytes calldata ctx - ) external pure override returns (bytes memory beforeData) { + function beforeAgreementCreated(ISuperToken, address, bytes32, bytes calldata, bytes calldata) + external + pure + override + returns (bytes memory beforeData) + { return "0x"; } /// @dev This callback is called after the flow is created /// @param superToken The super token /// @param agreementClass The agreement class - /// @param agreementId NOT USED /// @param agreementData The agreement data - /// @param cbdata NOT USED /// @param ctx The callback context /// @return newCtx The new callback context function afterAgreementCreated( ISuperToken superToken, address agreementClass, - bytes32 agreementId, + bytes32, bytes calldata agreementData, - bytes calldata cbdata, + bytes calldata, bytes calldata ctx ) external override returns (bytes memory newCtx) { _checkHookParam(superToken); @@ -240,17 +231,14 @@ contract RecipientSuperApp is ISuperApp { /// @dev This callback is called before the flow is updated /// @param superToken The super token /// @param agreementClass The agreement class - /// @param agreementId NOT USED /// @param agreementData The agreement data - /// @param ctx NOT USED - /// @return beforeData NOT USED function beforeAgreementUpdated( ISuperToken superToken, address agreementClass, - bytes32 agreementId, + bytes32, bytes calldata agreementData, - bytes calldata ctx - ) external view override returns (bytes memory beforeData) { + bytes calldata + ) external view override returns (bytes memory) { _checkHookParam(superToken); if (!isAcceptedAgreement(agreementClass)) return "0x"; @@ -260,7 +248,6 @@ contract RecipientSuperApp is ISuperApp { /// @dev This callback is called after the flow is updated /// @param superToken The super token /// @param agreementClass The agreement class - /// @param agreementId NOT USED /// @param agreementData The agreement data /// @param cbdata The callback data /// @param ctx The callback context @@ -268,7 +255,7 @@ contract RecipientSuperApp is ISuperApp { function afterAgreementUpdated( ISuperToken superToken, address agreementClass, - bytes32 agreementId, + bytes32, bytes calldata agreementData, bytes calldata cbdata, bytes calldata ctx @@ -294,17 +281,14 @@ contract RecipientSuperApp is ISuperApp { /// @dev This callback is called before the flow is terminated /// @param superToken The super token /// @param agreementClass The agreement class - /// @param agreementId NOT USED /// @param agreementData The agreement data - /// @param ctx NOT USED - /// @return beforeData NOT USED function beforeAgreementTerminated( ISuperToken superToken, address agreementClass, - bytes32 agreementId, + bytes32, bytes calldata agreementData, - bytes calldata ctx - ) external view override returns (bytes memory beforeData) { + bytes calldata + ) external view override returns (bytes memory) { if (msg.sender != address(HOST) || !isAcceptedAgreement(agreementClass) || !isAcceptedSuperToken(superToken)) { return "0x"; } @@ -315,16 +299,14 @@ contract RecipientSuperApp is ISuperApp { /// @dev This callback is called after the flow is terminated /// @param superToken The super token /// @param agreementClass The agreement class - /// @param agreementId NOT USED - /// @param agreementData NOT USED /// @param cbdata The callback data /// @param ctx The callback context /// @return The new callback context function afterAgreementTerminated( ISuperToken superToken, address agreementClass, - bytes32 agreementId, - bytes calldata agreementData, + bytes32, + bytes calldata, bytes calldata cbdata, bytes calldata ctx ) external override returns (bytes memory) { diff --git a/contracts/strategies/examples/sqf-superfluid/SQFSuperfluid.sol b/contracts/strategies/examples/sqf-superfluid/SQFSuperfluid.sol index f6dbd5e76..ab7f14590 100644 --- a/contracts/strategies/examples/sqf-superfluid/SQFSuperfluid.sol +++ b/contracts/strategies/examples/sqf-superfluid/SQFSuperfluid.sol @@ -311,9 +311,7 @@ contract SQFSuperfluid is /// @dev prevent the pool token from being withdrawn /// @param _token The token address - /// @param _amount The amount to withdraw - /// @param _recipient The address to withdraw to - function _beforeWithdraw(address _token, uint256 _amount, address _recipient) internal override { + function _beforeWithdraw(address _token, uint256, address) internal override { if (_token == address(poolSuperToken)) { revert INVALID(); } @@ -340,10 +338,9 @@ contract SQFSuperfluid is /// @dev If the recipient is accepted, create a super app for the recipient /// @param _newStatus The new status - /// @param _oldStatus The old status /// @param _recipientIndex The index of the recipient /// @return _reviewedStatus The reviewed status - function _reviewRecipientStatus(Status _newStatus, Status _oldStatus, uint256 _recipientIndex) + function _reviewRecipientStatus(Status _newStatus, Status, uint256 _recipientIndex) internal override nonReentrant @@ -371,10 +368,9 @@ contract SQFSuperfluid is /// @notice This will distribute funds (tokens) to recipients. /// @dev most strategies will track a TOTAL amount per recipient, and a PAID amount, and pay the difference /// this contract will need to track the amount paid already, so that it doesn't double pay. - /// @param _recipientsAddresses NOT USED /// @param _data Data required will depend on the strategy implementation /// @param _sender The address of the sender - function _distribute(address[] memory _recipientsAddresses, bytes memory _data, address _sender) + function _distribute(address[] memory, bytes memory _data, address _sender) internal override onlyPoolManager(_sender) @@ -390,15 +386,13 @@ contract SQFSuperfluid is /// @notice This will allocate to recipients. /// @dev The encoded '_data' will be determined by the strategy implementation. /// @param _recipientsAddresses The addresses of the recipients to allocate to - /// @param _amounts The amounts to allocate to each recipient /// @param _data The data to use to allocate to the recipient /// @param _sender The address of the sender - function _allocate( - address[] memory _recipientsAddresses, - uint256[] memory _amounts, - bytes memory _data, - address _sender - ) internal override onlyActiveAllocation { + function _allocate(address[] memory _recipientsAddresses, uint256[] memory, bytes memory _data, address _sender) + internal + override + onlyActiveAllocation + { if (!_isValidAllocator(_sender)) revert UNAUTHORIZED(); int96[] memory flowRates = abi.decode(_data, (int96[])); diff --git a/contracts/strategies/extensions/register/RecipientsExtension.sol b/contracts/strategies/extensions/register/RecipientsExtension.sol index 5f567157a..5965e5ec5 100644 --- a/contracts/strategies/extensions/register/RecipientsExtension.sol +++ b/contracts/strategies/extensions/register/RecipientsExtension.sol @@ -384,10 +384,8 @@ abstract contract RecipientsExtension is BaseStrategy, IRecipientsExtension, Err /// @notice Hook to review each new recipient status when REVIEW_EACH_STATUS is set to true /// @dev Beware of gas costs, since this function will be called for each reviewed recipient /// @param _newStatus New proposed status - /// @param _oldStatus Previous status - /// @param _recipientIndex The index of the recipient in case the recipient data needs to be accessed /// @return _reviewedStatus The actual new status to use - function _reviewRecipientStatus(Status _newStatus, Status _oldStatus, uint256 _recipientIndex) + function _reviewRecipientStatus(Status _newStatus, Status, uint256) internal virtual returns (Status _reviewedStatus) diff --git a/foundry.toml b/foundry.toml index 623b2bc53..497865f6a 100644 --- a/foundry.toml +++ b/foundry.toml @@ -8,6 +8,11 @@ out = 'out' libs = ['node_modules', 'lib'] test = 'test' cache_path = 'cache_forge' +ignored_warnings_from = [ + 'test/invariant/fuzz/', + 'test/smock/', + 'test/mocks/', +] # Gas reporting gas_reports = [ diff --git a/test/integration/DonationVotingMerkleDistribution.t.sol b/test/integration/DonationVotingMerkleDistribution.t.sol index 67f480426..b3af5b444 100644 --- a/test/integration/DonationVotingMerkleDistribution.t.sol +++ b/test/integration/DonationVotingMerkleDistribution.t.sol @@ -129,7 +129,8 @@ contract IntegrationDonationVotingMerkleDistributionBase is IntegrationBase { // NOTE: removing all the ETH from the strategy before testing vm.prank(address(strategy)); - address(0).call{value: address(strategy).balance}(""); + (bool success,) = address(0).call{value: address(strategy).balance}(""); + require(success, "Failed to send ETH"); } } diff --git a/test/integration/DonationVotingOffchain.t.sol b/test/integration/DonationVotingOffchain.t.sol index 9419ce7d6..539147f12 100644 --- a/test/integration/DonationVotingOffchain.t.sol +++ b/test/integration/DonationVotingOffchain.t.sol @@ -127,7 +127,8 @@ contract IntegrationDonationVotingOffchainBase is IntegrationBase { // NOTE: removing all the ETH from the strategy before testing vm.prank(address(strategy)); - address(0).call{value: address(strategy).balance}(""); + (bool success,) = address(0).call{value: address(strategy).balance}(""); + require(success, "Failed to send ETH"); } } diff --git a/test/integration/DonationVotingOnchain.t.sol b/test/integration/DonationVotingOnchain.t.sol index bba7a2402..93a2e4ca0 100644 --- a/test/integration/DonationVotingOnchain.t.sol +++ b/test/integration/DonationVotingOnchain.t.sol @@ -99,7 +99,8 @@ contract IntegrationDonationVotingOnchainBase is IntegrationBase { // NOTE: removing all the ETH from the strategy before testing vm.prank(address(strategy)); - address(0).call{value: address(strategy).balance}(""); + (bool success,) = address(0).call{value: address(strategy).balance}(""); + require(success, "Failed to send ETH"); } } diff --git a/test/mocks/MockGatingExtension.sol b/test/mocks/MockGatingExtension.sol index 0cb20d282..136e41c2e 100644 --- a/test/mocks/MockGatingExtension.sol +++ b/test/mocks/MockGatingExtension.sol @@ -9,7 +9,7 @@ import {TokenGatingExtension} from "strategies/extensions/gating/TokenGatingExte contract MockGatingExtension is EASGatingExtension, NFTGatingExtension, TokenGatingExtension { constructor(address _allo, string memory _strategyName) BaseStrategy(_allo, _strategyName) {} - function _initializeStrategy(uint256 _poolId, bytes memory _data) internal override { + function _initializeStrategy(uint256, bytes memory _data) internal override { address _eas = abi.decode(_data, (address)); __EASGatingExtension_init(_eas); diff --git a/test/mocks/smock-mocks/MockAllocationExtension.sol b/test/mocks/smock-mocks/MockAllocationExtension.sol index 41b24ed2a..34f5609d5 100644 --- a/test/mocks/smock-mocks/MockAllocationExtension.sol +++ b/test/mocks/smock-mocks/MockAllocationExtension.sol @@ -8,14 +8,14 @@ import {BaseStrategy} from "contracts/strategies/BaseStrategy.sol"; contract MockAllocationExtension is BaseStrategy, AllocationExtension { constructor(address _allo, string memory _strategyName) BaseStrategy(_allo, _strategyName) {} - function initialize(uint256 _poolId, bytes memory _data) external override { + function initialize(uint256 _poolId, bytes memory __data) external override { __BaseStrategy_init(_poolId); ( address[] memory _allowedTokens, uint64 _allocationStartTime, uint64 _allocationEndTime, bool _isUsingAllocationMetadata - ) = abi.decode(_data, (address[], uint64, uint64, bool)); + ) = abi.decode(__data, (address[], uint64, uint64, bool)); __AllocationExtension_init(_allowedTokens, _allocationStartTime, _allocationEndTime, _isUsingAllocationMetadata); } diff --git a/test/mocks/smock-mocks/MockAllocatorsAllowlistExtension.sol b/test/mocks/smock-mocks/MockAllocatorsAllowlistExtension.sol index 6f829f4b8..e0870a31e 100644 --- a/test/mocks/smock-mocks/MockAllocatorsAllowlistExtension.sol +++ b/test/mocks/smock-mocks/MockAllocatorsAllowlistExtension.sol @@ -7,14 +7,14 @@ import {BaseStrategy} from "contracts/strategies/BaseStrategy.sol"; contract MockAllocatorsAllowlistExtension is BaseStrategy, AllocatorsAllowlistExtension { constructor(address _allo, string memory _strategyName) BaseStrategy(_allo, _strategyName) {} - function initialize(uint256 _poolId, bytes memory _data) external override { + function initialize(uint256 _poolId, bytes memory __data) external override { __BaseStrategy_init(_poolId); ( address[] memory _allowedTokens, uint64 _allocationStartTime, uint64 _allocationEndTime, bool _isUsingAllocationMetadata - ) = abi.decode(_data, (address[], uint64, uint64, bool)); + ) = abi.decode(__data, (address[], uint64, uint64, bool)); __AllocationExtension_init(_allowedTokens, _allocationStartTime, _allocationEndTime, _isUsingAllocationMetadata); } diff --git a/test/mocks/smock-mocks/MockBaseStrategy.sol b/test/mocks/smock-mocks/MockBaseStrategy.sol index fc62c3d57..733b9caef 100644 --- a/test/mocks/smock-mocks/MockBaseStrategy.sol +++ b/test/mocks/smock-mocks/MockBaseStrategy.sol @@ -18,20 +18,20 @@ contract MockBaseStrategy is BaseStrategy { super._checkOnlyPoolManager(_sender); } - function _register(address[] memory _recipients, bytes memory _data, address _sender) + function _register(address[] memory _recipients, bytes memory __data, address _sender) internal virtual override returns (address[] memory _recipientIds) {} - function _allocate(address[] memory _recipients, uint256[] memory _amounts, bytes memory _data, address _sender) + function _allocate(address[] memory _recipients, uint256[] memory _amounts, bytes memory __data, address _sender) internal virtual override {} - function _distribute(address[] memory _recipientIds, bytes memory _data, address _sender) + function _distribute(address[] memory _recipientIds, bytes memory __data, address _sender) internal virtual override @@ -45,37 +45,37 @@ contract MockBaseStrategy is BaseStrategy { function _afterWithdraw(address _token, uint256 _amount, address _recipient) internal virtual override {} - function _beforeRegisterRecipient(address[] memory _recipients, bytes memory _data, address _sender) + function _beforeRegisterRecipient(address[] memory _recipients, bytes memory __data, address _sender) internal virtual override {} - function _afterRegisterRecipient(address[] memory _recipients, bytes memory _data, address _sender) + function _afterRegisterRecipient(address[] memory _recipients, bytes memory __data, address _sender) internal virtual override {} - function _beforeAllocate(address[] memory _recipients, bytes memory _data, address _sender) + function _beforeAllocate(address[] memory _recipients, bytes memory __data, address _sender) internal virtual override {} - function _afterAllocate(address[] memory _recipients, bytes memory _data, address _sender) + function _afterAllocate(address[] memory _recipients, bytes memory __data, address _sender) internal virtual override {} - function _beforeDistribute(address[] memory _recipientIds, bytes memory _data, address _sender) + function _beforeDistribute(address[] memory _recipientIds, bytes memory __data, address _sender) internal virtual override {} - function _afterDistribute(address[] memory _recipientIds, bytes memory _data, address _sender) + function _afterDistribute(address[] memory _recipientIds, bytes memory __data, address _sender) internal virtual override diff --git a/test/mocks/smock-mocks/MockEASGatingExtension.sol b/test/mocks/smock-mocks/MockEASGatingExtension.sol index f6b403288..61e73e201 100644 --- a/test/mocks/smock-mocks/MockEASGatingExtension.sol +++ b/test/mocks/smock-mocks/MockEASGatingExtension.sol @@ -7,9 +7,9 @@ import {BaseStrategy} from "contracts/strategies/BaseStrategy.sol"; contract MockEASGatingExtension is BaseStrategy, EASGatingExtension { constructor(address _allo, string memory _strategyName) BaseStrategy(_allo, _strategyName) {} - function initialize(uint256 _poolId, bytes memory _data) external virtual override { + function initialize(uint256 _poolId, bytes memory __data) external virtual override { __BaseStrategy_init(_poolId); - __EASGatingExtension_init(abi.decode(_data, (address))); + __EASGatingExtension_init(abi.decode(__data, (address))); } function __EASGatingExtension_init(address _eas) internal virtual override { diff --git a/test/mocks/smock-mocks/MockMilestonesExtension.sol b/test/mocks/smock-mocks/MockMilestonesExtension.sol index d744cc394..e2a582832 100644 --- a/test/mocks/smock-mocks/MockMilestonesExtension.sol +++ b/test/mocks/smock-mocks/MockMilestonesExtension.sol @@ -12,26 +12,26 @@ contract MockMilestonesExtension is BaseStrategy, IMilestonesExtension, Mileston constructor(address _allo, string memory _strategyName) BaseStrategy(_allo, _strategyName) {} - function initialize(uint256 _poolId, bytes memory _data) external override { + function initialize(uint256 _poolId, bytes memory __data) external override { __BaseStrategy_init(_poolId); - uint256 _maxBid = abi.decode(_data, (uint256)); + uint256 _maxBid = abi.decode(__data, (uint256)); __MilestonesExtension_init(_maxBid); } - function _allocate(address[] memory _recipients, uint256[] memory _amounts, bytes memory _data, address _sender) + function _allocate(address[] memory _recipients, uint256[] memory _amounts, bytes memory __data, address _sender) internal virtual override {} - function _distribute(address[] memory _recipientIds, bytes memory _data, address _sender) + function _distribute(address[] memory _recipientIds, bytes memory __data, address _sender) internal virtual override {} - function _register(address[] memory __recipients, bytes memory _data, address _sender) + function _register(address[] memory __recipients, bytes memory __data, address _sender) internal virtual override diff --git a/test/mocks/smock-mocks/MockRecipientsExtension.sol b/test/mocks/smock-mocks/MockRecipientsExtension.sol index dc5591216..e3873735a 100644 --- a/test/mocks/smock-mocks/MockRecipientsExtension.sol +++ b/test/mocks/smock-mocks/MockRecipientsExtension.sol @@ -12,19 +12,19 @@ contract MockRecipientsExtension is BaseStrategy, RecipientsExtension { BaseStrategy(_allo, _strategyName) {} - function initialize(uint256 _poolId, bytes memory _data) external override { + function initialize(uint256 _poolId, bytes memory __data) external override { __BaseStrategy_init(_poolId); - RecipientInitializeData memory _initializeData = abi.decode(_data, (RecipientInitializeData)); + RecipientInitializeData memory _initializeData = abi.decode(__data, (RecipientInitializeData)); __RecipientsExtension_init(_initializeData); } - function _allocate(address[] memory _recipients, uint256[] memory _amounts, bytes memory _data, address _sender) + function _allocate(address[] memory _recipients, uint256[] memory _amounts, bytes memory __data, address _sender) internal override {} - function _distribute(address[] memory _recipientIds, bytes memory _data, address _sender) internal override {} + function _distribute(address[] memory _recipientIds, bytes memory __data, address _sender) internal override {} function __RecipientsExtension_init(IRecipientsExtension.RecipientInitializeData memory _initializeData) internal diff --git a/test/unit/core/AnchorUnit.t.sol b/test/unit/core/AnchorUnit.t.sol index ade1a691f..984209b05 100644 --- a/test/unit/core/AnchorUnit.t.sol +++ b/test/unit/core/AnchorUnit.t.sol @@ -124,13 +124,14 @@ contract AnchorUnit is Test { function test_ReceiveShouldReceiveNativeTokens(uint256 _value) external { // it should receive native tokens - (Anchor _anchor, address _registry, bytes32 _profileId) = _initAnchor(); + (Anchor _anchor,,) = _initAnchor(); assertEq(address(_anchor).balance, 0); // Check if the balance of the contract has been updated hoax(makeAddr("funder"), _value); - address(_anchor).call{value: _value}(""); + (bool success,) = address(_anchor).call{value: _value}(""); + require(success, "Failed to send ETH"); assertEq(address(_anchor).balance, _value); // Check if the balance of the contract has been updated } @@ -142,7 +143,7 @@ contract AnchorUnit is Test { bytes memory _data ) external { // it should return the onERC721Received selector - (Anchor _anchor, address _registry, bytes32 _profileId) = _initAnchor(); + (Anchor _anchor,,) = _initAnchor(); bytes4 retval = _anchor.onERC721Received(_operator, _from, _tokenId, _data); assertEq(retval, IERC721Receiver.onERC721Received.selector); @@ -156,7 +157,7 @@ contract AnchorUnit is Test { bytes memory _data ) external { // it should return the onERC1155Received selector - (Anchor _anchor, address _registry, bytes32 _profileId) = _initAnchor(); + (Anchor _anchor,,) = _initAnchor(); bytes4 retval = _anchor.onERC1155Received(_operator, _from, _tokenId, _value, _data); assertEq(retval, IERC1155Receiver.onERC1155Received.selector); @@ -170,7 +171,7 @@ contract AnchorUnit is Test { bytes memory _data ) external { // it should return the onERC1155BatchReceived selector - (Anchor _anchor, address _registry, bytes32 _profileId) = _initAnchor(); + (Anchor _anchor,,) = _initAnchor(); bytes4 retval = _anchor.onERC1155BatchReceived(_operator, _from, _tokenIds, _values, _data); assertEq(retval, IERC1155Receiver.onERC1155BatchReceived.selector); diff --git a/test/unit/strategies/extensions/RecipientsExtensionUnit.t.sol b/test/unit/strategies/extensions/RecipientsExtensionUnit.t.sol index 8c4216d9d..22e917e0a 100644 --- a/test/unit/strategies/extensions/RecipientsExtensionUnit.t.sol +++ b/test/unit/strategies/extensions/RecipientsExtensionUnit.t.sol @@ -689,7 +689,6 @@ contract RecipientsExtensionUnit is Test { } function test__extractRecipientAndMetadataRevertWhen_IsNotAProfileMember( - address _recipientIdOrRegistryAnchor, address _sender, Metadata memory _metadata, _extractRecipientAndMetadataParam memory _param @@ -865,7 +864,6 @@ contract RecipientsExtensionUnit is Test { for (uint256 col = 0; col < 64; col++) { uint256 colIndex = col << 2; // col * 4 uint8 newStatus = uint8((reviewedFullRow >> colIndex) & 0xF); - uint8 proposedStatus = uint8((_fullRow >> colIndex) & 0xF); assertEq(newStatus, _reviewedStatus); } } From 9d5efa85b53c31716ef4c312783737b735732bb1 Mon Sep 17 00:00:00 2001 From: Austrian <114922365+0xAustrian@users.noreply.github.com> Date: Tue, 4 Feb 2025 08:37:53 -0300 Subject: [PATCH 7/9] fix: recoverFunds test case (#66) --- test/unit/core/AlloUnit.t.sol | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/test/unit/core/AlloUnit.t.sol b/test/unit/core/AlloUnit.t.sol index e974e2ab6..ee525562a 100644 --- a/test/unit/core/AlloUnit.t.sol +++ b/test/unit/core/AlloUnit.t.sol @@ -562,6 +562,11 @@ contract AlloUnit is Test { } function test_RecoverFundsWhenSenderIsOwner(address _recipient) external whenSenderIsOwner { + vm.assume(_recipient != address(0)); + vm.assume(_recipient.code.length == 0); + vm.assume(_recipient.balance == 0); + assumeNotPrecompile(_recipient); + // it should emit FundsRecovered event vm.expectEmit(); emit IAllo.FundsRecovered(NATIVE, _recipient); From 010b2977fa842d9a3b86223b19b8290891ce07b0 Mon Sep 17 00:00:00 2001 From: Austrian <114922365+0xAustrian@users.noreply.github.com> Date: Tue, 11 Feb 2025 08:17:51 -0300 Subject: [PATCH 8/9] fix: visibility compile warning (#67) --- .../examples/donation-voting/DonationVotingOffchain.sol | 2 +- .../examples/donation-voting/DonationVotingOnchain.sol | 2 +- contracts/strategies/examples/sqf-superfluid/SQFSuperfluid.sol | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/contracts/strategies/examples/donation-voting/DonationVotingOffchain.sol b/contracts/strategies/examples/donation-voting/DonationVotingOffchain.sol index 904c9293b..64905b8eb 100644 --- a/contracts/strategies/examples/donation-voting/DonationVotingOffchain.sol +++ b/contracts/strategies/examples/donation-voting/DonationVotingOffchain.sol @@ -299,7 +299,7 @@ contract DonationVotingOffchain is BaseStrategy, RecipientsExtension, Allocation /// @notice Returns always true as all addresses are valid allocators /// @return Returns always true - function _isValidAllocator(address) internal view override returns (bool) { + function _isValidAllocator(address) internal pure override returns (bool) { return true; } } diff --git a/contracts/strategies/examples/donation-voting/DonationVotingOnchain.sol b/contracts/strategies/examples/donation-voting/DonationVotingOnchain.sol index e4e4764c1..06287c317 100644 --- a/contracts/strategies/examples/donation-voting/DonationVotingOnchain.sol +++ b/contracts/strategies/examples/donation-voting/DonationVotingOnchain.sol @@ -200,7 +200,7 @@ contract DonationVotingOnchain is BaseStrategy, RecipientsExtension, AllocationE /// @notice Returns always true as all addresses are valid allocators /// @return Returns always true - function _isValidAllocator(address) internal view override returns (bool) { + function _isValidAllocator(address) internal pure override returns (bool) { return true; } } diff --git a/contracts/strategies/examples/sqf-superfluid/SQFSuperfluid.sol b/contracts/strategies/examples/sqf-superfluid/SQFSuperfluid.sol index ab7f14590..4493b6e8a 100644 --- a/contracts/strategies/examples/sqf-superfluid/SQFSuperfluid.sol +++ b/contracts/strategies/examples/sqf-superfluid/SQFSuperfluid.sol @@ -311,7 +311,7 @@ contract SQFSuperfluid is /// @dev prevent the pool token from being withdrawn /// @param _token The token address - function _beforeWithdraw(address _token, uint256, address) internal override { + function _beforeWithdraw(address _token, uint256, address) internal view override { if (_token == address(poolSuperToken)) { revert INVALID(); } From 59ed8ea00d5bc146868ff67518bd7eda916d20be Mon Sep 17 00:00:00 2001 From: Austrian <114922365+0xAustrian@users.noreply.github.com> Date: Tue, 11 Feb 2025 08:29:45 -0300 Subject: [PATCH 9/9] fix: change constant, update tests (#68) --- .../extensions/allocate/AllocationExtension.sol | 3 ++- .../extensions/allocate/IAllocationExtension.sol | 3 +++ .../extensions/AllocationExtensionUnit.t.sol | 12 ++++++++++++ .../extensions/AllocationExtensionUnit.tree | 2 ++ 4 files changed, 19 insertions(+), 1 deletion(-) diff --git a/contracts/strategies/extensions/allocate/AllocationExtension.sol b/contracts/strategies/extensions/allocate/AllocationExtension.sol index 3ef2a5a5f..51c3b0229 100644 --- a/contracts/strategies/extensions/allocate/AllocationExtension.sol +++ b/contracts/strategies/extensions/allocate/AllocationExtension.sol @@ -11,7 +11,7 @@ abstract contract AllocationExtension is BaseStrategy, IAllocationExtension { /// ================================ /// @notice The address sent when all tokens are allowed - address public constant ALL_TOKENS_ALLOWED = address(0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE); + address public constant ALL_TOKENS_ALLOWED = address(0xeeeEEeEEEEEeeEEEeEeE00000000000000000000); /// @notice The start time for allocations uint64 public allocationStartTime; @@ -46,6 +46,7 @@ abstract contract AllocationExtension is BaseStrategy, IAllocationExtension { } else { for (uint256 i; i < _allowedTokens.length; i++) { if (_allowedTokens[i] == address(0)) revert AllocationExtension_ZERO_ADDRESS_NOT_ALLOWED(); + if (_allowedTokens[i] == ALL_TOKENS_ALLOWED) revert AllocationExtension_ADDRESS_NOT_ALLOWED(); allowedTokens[_allowedTokens[i]] = true; } } diff --git a/contracts/strategies/extensions/allocate/IAllocationExtension.sol b/contracts/strategies/extensions/allocate/IAllocationExtension.sol index 9de6600ac..d66dced0d 100644 --- a/contracts/strategies/extensions/allocate/IAllocationExtension.sol +++ b/contracts/strategies/extensions/allocate/IAllocationExtension.sol @@ -20,6 +20,9 @@ interface IAllocationExtension { /// @dev Error thrown when sending the zero address as a token error AllocationExtension_ZERO_ADDRESS_NOT_ALLOWED(); + /// @dev Error thrown when sending the ALL_TOKENS_ALLOWED address as a token + error AllocationExtension_ADDRESS_NOT_ALLOWED(); + /// @notice Emitted when the allocation timestamps are updated /// @param allocationStartTime The start time for the allocation period /// @param allocationEndTime The end time for the allocation period diff --git a/test/unit/strategies/extensions/AllocationExtensionUnit.t.sol b/test/unit/strategies/extensions/AllocationExtensionUnit.t.sol index eeb15f5ee..05fdd9461 100644 --- a/test/unit/strategies/extensions/AllocationExtensionUnit.t.sol +++ b/test/unit/strategies/extensions/AllocationExtensionUnit.t.sol @@ -31,6 +31,7 @@ contract AllocationExtension is Test { function test___AllocationExtension_initWhenAllowedTokensArrayIsNotEmpty(address[] memory _tokens) external { for (uint256 i; i < _tokens.length; i++) { vm.assume(_tokens[i] != address(0)); + vm.assume(_tokens[i] != extension.ALL_TOKENS_ALLOWED()); } extension.call___AllocationExtension_init(_tokens, 0, 0, false); @@ -41,6 +42,16 @@ contract AllocationExtension is Test { } } + function test___AllocationExtension_initRevertWhen_AllowedTokensArrayIncludesALL_TOKENS_ALLOWED() external { + address[] memory _tokens = new address[](1); + _tokens[0] = extension.ALL_TOKENS_ALLOWED(); + + // It should revert + vm.expectRevert(IAllocationExtension.AllocationExtension_ADDRESS_NOT_ALLOWED.selector); + + extension.call___AllocationExtension_init(_tokens, 0, 0, false); + } + function test___AllocationExtension_initShouldSetIsUsingAllocationMetadata(bool _isUsingAllocationMetadata) external { @@ -72,6 +83,7 @@ contract AllocationExtension is Test { function test__isAllowedTokenWhenTheTokenSentIsAllowed(address _tokenToCheck) external { vm.assume(_tokenToCheck != address(0)); + vm.assume(_tokenToCheck != extension.ALL_TOKENS_ALLOWED()); // Send array with only that token address[] memory tokens = new address[](1); diff --git a/test/unit/strategies/extensions/AllocationExtensionUnit.tree b/test/unit/strategies/extensions/AllocationExtensionUnit.tree index 161eb552e..9e1f13bd1 100644 --- a/test/unit/strategies/extensions/AllocationExtensionUnit.tree +++ b/test/unit/strategies/extensions/AllocationExtensionUnit.tree @@ -5,6 +5,8 @@ AllocationExtension::__AllocationExtension_init │ └── It should mark address of all tokens allowed as true ├── When allowedTokens array is not empty │ └── It should mark the tokens in the array as true +├── When allowedTokens array includes ALL_TOKENS_ALLOWED +│ └── It should revert ├── It should set isUsingAllocationMetadata └── It should call _updateAllocationTimestamps