Skip to content

Commit

Permalink
feat(hats): add hats allowlisting and test
Browse files Browse the repository at this point in the history
  • Loading branch information
bitbeckers committed May 28, 2024
1 parent 26989c8 commit d769503
Show file tree
Hide file tree
Showing 2 changed files with 111 additions and 0 deletions.
86 changes: 86 additions & 0 deletions test/Zodiac/HatsCookieJar.t.sol
Original file line number Diff line number Diff line change
@@ -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)"));
}
}
25 changes: 25 additions & 0 deletions test/utils/ZodiacCloneSummoner.sol
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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);
Expand All @@ -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);

Expand Down Expand Up @@ -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,
Expand Down

0 comments on commit d769503

Please sign in to comment.