From d7695039812263a58d675c9f81bd4823adc6bd8c Mon Sep 17 00:00:00 2001 From: bitbeckers Date: Tue, 28 May 2024 14:42:38 +0200 Subject: [PATCH] feat(hats): add hats allowlisting and test --- test/Zodiac/HatsCookieJar.t.sol | 86 ++++++++++++++++++++++++++++++ test/utils/ZodiacCloneSummoner.sol | 25 +++++++++ 2 files changed, 111 insertions(+) create mode 100644 test/Zodiac/HatsCookieJar.t.sol diff --git a/test/Zodiac/HatsCookieJar.t.sol b/test/Zodiac/HatsCookieJar.t.sol new file mode 100644 index 0000000..fa3cce8 --- /dev/null +++ b/test/Zodiac/HatsCookieJar.t.sol @@ -0,0 +1,86 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity >=0.8.19 <0.9.0; + +import { + ZodiacCloneSummoner, + ZodiacERC20CookieJarHarnass, + ZodiacHatsCookieJarHarnass +} from "test/utils/ZodiacCloneSummoner.sol"; +import { MockHats } from "test/utils/MockHats.sol"; +import { ERC20Mintable } from "test/utils/ERC20Mintable.sol"; +import { TestAvatar } from "@gnosis.pm/zodiac/contracts/test/TestAvatar.sol"; +import { IPoster } from "@daohaus/baal-contracts/contracts/interfaces/IPoster.sol"; +import { ERC20 } from "openzeppelin-contracts/contracts/token/ERC20/ERC20.sol"; +import { Test, Vm } from "forge-std/Test.sol"; + +contract HatsCookieJarTest is ZodiacCloneSummoner { + ZodiacHatsCookieJarHarnass internal cookieJar; + + address internal alice = makeAddr("alice"); + address internal bob = makeAddr("bob"); + + ERC20Mintable internal cookieToken = new ERC20Mintable("Mock", "MCK"); + TestAvatar internal testAvatar = new TestAvatar(); + + MockHats internal mockHats = new MockHats(); + + uint256 internal cookieAmount = 2e6; + uint256 internal threshold = 420; + + string internal reason = "CookieJar: Testing"; + + event Setup(bytes initializationParams); + event GiveCookie(bytes32 indexed cookieUid, address indexed cookieMonster, uint256 amount, string reason); + event AssessReason(bytes32 indexed cookieUid, string message, bool isGood); + + function setUp() public virtual { + // address _safeTarget, + // uint256 _periodLength, + // uint256 _cookieAmount, + // address _cookieToken, + // address _erc20addr, + // uint256 _threshold, + bytes memory initParams = + abi.encode(address(testAvatar), 3600, cookieAmount, address(cookieToken), address(mockHats), threshold); + + cookieJar = getHatsCookieJar(initParams); + + // Enable module + testAvatar.enableModule(address(cookieJar)); + } + + function testIsAllowed() external { + mockHats.setMockResponse(false); + + assertFalse(cookieJar.exposed_isAllowList(msg.sender)); + + mockHats.setMockResponse(true); + assertTrue(cookieJar.exposed_isAllowList(msg.sender)); + } + + function testReachInJar() external { + // No hat for user so expect fail + mockHats.setMockResponse(false); + + vm.expectRevert(bytes("not a member")); + cookieJar.reachInJar(reason); + + // No cookie balance so expect fail + mockHats.setMockResponse(true); + vm.expectRevert(bytes("call failure setup")); + cookieJar.reachInJar(reason); + + // Put cookie tokens in jar + cookieToken.mint(address(testAvatar), cookieAmount); + + // Alice puts her hand in the jar + vm.startPrank(alice); + // GiveCookie is not the last emitted event so we drill down the logs + // vm.expectEmit(false, false, false, true); + // emit GiveCookie(alice, cookieAmount, CookieUtils.getCookieJarUid(address(cookieJar))); + cookieJar.reachInJar(reason); + + Vm.Log[] memory entries = vm.getRecordedLogs(); + assertEq(entries[3].topics[0], keccak256("GiveCookie(bytes32,address,uint256,string)")); + } +} diff --git a/test/utils/ZodiacCloneSummoner.sol b/test/utils/ZodiacCloneSummoner.sol index f3d4dea..8fd6790 100644 --- a/test/utils/ZodiacCloneSummoner.sol +++ b/test/utils/ZodiacCloneSummoner.sol @@ -8,6 +8,7 @@ import { ZodiacERC721CookieJar } from "src/SafeModule/ZodiacERC721CookieJar.sol" import { ZodiacListCookieJar } from "src/SafeModule/ZodiacListCookieJar.sol"; import { ZodiacOpenCookieJar } from "src/SafeModule/ZodiacOpenCookieJar.sol"; import { ZodiacBaalCookieJar } from "src/SafeModule/ZodiacBaalCookieJar.sol"; +import { ZodiacHatsCookieJar } from "src/SafeModule/ZodiacHatsCookieJar.sol"; import { ModuleProxyFactory } from "@gnosis.pm/zodiac/contracts/factory/ModuleProxyFactory.sol"; contract ZodiacBaalCookieJarHarnass is ZodiacBaalCookieJar { @@ -40,6 +41,12 @@ contract ZodiacOpenCookieJarHarnass is ZodiacOpenCookieJar { } } +contract ZodiacHatsCookieJarHarnass is ZodiacHatsCookieJar { + function exposed_isAllowList(address user) external view returns (bool) { + return isAllowList(user); + } +} + contract ZodiacCloneSummoner is Test { address internal owner = makeAddr("owner"); CookieJarFactory public cookieJarFactory = new CookieJarFactory(owner); @@ -50,6 +57,7 @@ contract ZodiacCloneSummoner is Test { ZodiacERC721CookieJarHarnass internal erc721CookieJarImplementation = new ZodiacERC721CookieJarHarnass(); ZodiacListCookieJarHarnass internal listCookieJarImplementation = new ZodiacListCookieJarHarnass(); ZodiacOpenCookieJarHarnass internal openCookieJarImplementation = new ZodiacOpenCookieJarHarnass(); + ZodiacHatsCookieJarHarnass internal hatsCookieJarImplementation = new ZodiacHatsCookieJarHarnass(); event SummonCookieJar(address cookieJar, string _cookieType, bytes initParams); @@ -149,6 +157,23 @@ contract ZodiacCloneSummoner is Test { return ZodiacOpenCookieJarHarnass(cookieJar); } + function getHatsCookieJar(bytes memory initParams) public returns (ZodiacHatsCookieJarHarnass) { + vm.recordLogs(); + bytes memory _initializer = abi.encodeWithSignature("setUp(bytes)", initParams); + + cookieJarFactory.summonCookieJar( + address(hatsCookieJarImplementation), _initializer, "Hats", address(0), 0, saltNonce + ); + + Vm.Log[] memory entries = vm.getRecordedLogs(); + assertEq(entries.length, 8); + assertEq(entries[7].topics[0], keccak256("SummonCookieJar(address,bytes,string)")); + address cookieJar = _calculateCreate2Address(address(hatsCookieJarImplementation), _initializer, saltNonce); + + assertEq(abi.decode(entries[7].data, (address)), cookieJar); + return ZodiacHatsCookieJarHarnass(cookieJar); + } + function _calculateCreate2Address( address template, bytes memory _initializer,