Skip to content
This repository has been archived by the owner on Nov 27, 2024. It is now read-only.

Commit

Permalink
sort of working factory test
Browse files Browse the repository at this point in the history
  • Loading branch information
0xrajath committed Dec 8, 2023
1 parent 2503407 commit 0d956f6
Show file tree
Hide file tree
Showing 3 changed files with 103 additions and 60 deletions.
5 changes: 5 additions & 0 deletions test/LlamaPeripheryTestSetup.sol
Original file line number Diff line number Diff line change
Expand Up @@ -51,4 +51,9 @@ contract LlamaPeripheryTestSetup is Test {
function setUp() public virtual {
vm.createSelectFork(MAINNET_RPC_URL, 18_707_845);
}

function mineBlock() internal {
vm.roll(block.number + 1);
vm.warp(block.timestamp + 1);
}
}
115 changes: 57 additions & 58 deletions test/token-voting/LlamaTokenVotingFactory.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,11 @@ pragma solidity ^0.8.23;

import {Test, console2} from "forge-std/Test.sol";

import {MockERC20Votes} from "test/mock/MockERC20Votes.sol";
import {MockERC721Votes} from "test/mock/MockERC721Votes.sol";
import {Clones} from "@openzeppelin/proxy/Clones.sol";

import {LlamaTokenVotingTestSetup} from "test/token-voting/LlamaTokenVotingTestSetup.sol";

import {Action, ActionInfo} from "src/lib/Structs.sol";
import {RoleDescription} from "src/lib/UDVTs.sol";
import {ERC20Votes} from "lib/openzeppelin-contracts/contracts/token/ERC20/extensions/ERC20Votes.sol";
import {ERC721Votes} from "lib/openzeppelin-contracts/contracts/token/ERC721/extensions/ERC721Votes.sol";
import {ActionInfo} from "src/lib/Structs.sol";
import {ILlamaPolicy} from "src/interfaces/ILlamaPolicy.sol";
import {LlamaTokenVotingFactory} from "src/token-voting/LlamaTokenVotingFactory.sol";

Expand All @@ -23,98 +20,100 @@ contract LlamaTokenVotingFactoryTest is LlamaTokenVotingTestSetup {
event ERC721TokenholderCasterCreated(
address caster, address indexed token, uint256 minApprovalPct, uint256 minDisapprovalPct
);
event RoleAssigned(address indexed policyholder, uint8 indexed role, uint64 expiration, uint96 quantity);
event RoleInitialized(uint8 indexed role, RoleDescription description);

uint256 public constant CREATION_THRESHOLD = 100;
uint256 public constant MIN_APPROVAL_PCT = 1000;
uint256 public constant MIN_DISAPPROVAL_PCT = 1000;

LlamaTokenVotingFactory public FACTORY;
ERC20Votes public ERC20TOKEN;
ERC721Votes public ERC721TOKEN;

function setUp() public override {
LlamaTokenVotingTestSetup.setUp();
}

FACTORY = new LlamaTokenVotingFactory();
MockERC20Votes mockERC20Votes = new MockERC20Votes();
ERC20TOKEN = ERC20Votes(address(mockERC20Votes));
MockERC721Votes mockERC721Votes = new MockERC721Votes();
ERC721TOKEN = ERC721Votes(address(mockERC721Votes));

mockERC20Votes.mint(coreTeam1, 100);
mockERC20Votes.mint(coreTeam2, 100);
mockERC20Votes.mint(coreTeam3, 100);
mockERC20Votes.mint(coreTeam4, 100);

mockERC721Votes.mint(coreTeam1, 0);
mockERC721Votes.mint(coreTeam2, 1);
mockERC721Votes.mint(coreTeam3, 2);
mockERC721Votes.mint(coreTeam4, 3);

ILlamaPolicy.PermissionData memory newPermission1 = ILlamaPolicy.PermissionData(
address(FACTORY), LlamaTokenVotingFactory.deployTokenVotingModule.selector, address(STRATEGY)
function _setPermissionCreateApproveAndQueueAction(bytes memory data) internal returns (ActionInfo memory actionInfo) {
// Assign `deployTokenVotingModule` permission to the `CORE_TEAM_ROLE` role.
ILlamaPolicy.PermissionData memory deployTokenVotingPermission = ILlamaPolicy.PermissionData(
address(tokenVotingFactory), LlamaTokenVotingFactory.deployTokenVotingModule.selector, address(STRATEGY)
);

vm.startPrank(address(EXECUTOR));
POLICY.setRolePermission(CORE_TEAM_ROLE, newPermission1, true);
vm.stopPrank();

vm.warp(block.timestamp + 1);
}
vm.prank(address(EXECUTOR));
POLICY.setRolePermission(CORE_TEAM_ROLE, deployTokenVotingPermission, true);

function _createApproveAndQueueAction(bytes memory data) internal returns (ActionInfo memory actionInfo) {
// Create an action and queue it to deploy the token voting module.
vm.prank(coreTeam4);
uint256 actionId = CORE.createAction(CORE_TEAM_ROLE, STRATEGY, address(FACTORY), 0, data, "");
actionInfo = ActionInfo(actionId, coreTeam4, CORE_TEAM_ROLE, STRATEGY, address(FACTORY), 0, data);
uint256 actionId = CORE.createAction(CORE_TEAM_ROLE, STRATEGY, address(tokenVotingFactory), 0, data, "");
actionInfo = ActionInfo(actionId, coreTeam4, CORE_TEAM_ROLE, STRATEGY, address(tokenVotingFactory), 0, data);

vm.prank(coreTeam1);
CORE.castApproval(CORE_TEAM_ROLE, actionInfo, "");
vm.prank(coreTeam2);
CORE.castApproval(CORE_TEAM_ROLE, actionInfo, "");
vm.prank(coreTeam3);
CORE.castApproval(CORE_TEAM_ROLE, actionInfo, "");

// vm.warp(block.timestamp + 1 days);
// CORE.queueAction(actionInfo);
// vm.warp(block.timestamp + 5 days);
}
}

contract DeployTokenVotingModule is LlamaTokenVotingFactoryTest {
function test_CanDeployERC20TokenVotingModule() public {
// Set up action to call `deployTokenVotingModule` with the ERC20 token.
bytes memory data = abi.encodeWithSelector(
LlamaTokenVotingFactory.deployTokenVotingModule.selector,
address(ERC20TOKEN),
address(erc20VotesToken),
true,
CREATION_THRESHOLD,
MIN_APPROVAL_PCT,
MIN_DISAPPROVAL_PCT
ERC20_CREATION_THRESHOLD,
ERC20_MIN_APPROVAL_PCT,
ERC20_MIN_DISAPPROVAL_PCT
);
ActionInfo memory actionInfo = _setPermissionCreateApproveAndQueueAction(data);

ActionInfo memory actionInfo = _createApproveAndQueueAction(data);
// Compute addresses of ERC20 Token Voting Module
address erc20TokenholderActionCreator = Clones.predictDeterministicAddress(
address(erc20TokenholderActionCreatorLogic),
keccak256(abi.encodePacked(address(erc20VotesToken), address(EXECUTOR))), // salt
address(tokenVotingFactory) // deployer
);
address erc20TokenholderCaster = Clones.predictDeterministicAddress(
address(erc20TokenholderCasterLogic),
keccak256(abi.encodePacked(address(erc20VotesToken), address(EXECUTOR))), // salt
address(tokenVotingFactory) // deployer
);

// Expect events to be emitted on call to `deployTokenVotingModule`.
vm.expectEmit();
emit ERC20TokenholderActionCreatorCreated(0x104fBc016F4bb334D775a19E8A6510109AC63E00, address(ERC20TOKEN));
emit ERC20TokenholderActionCreatorCreated(erc20TokenholderActionCreator, address(erc20VotesToken));
vm.expectEmit();
emit ERC20TokenholderCasterCreated(
0x037eDa3aDB1198021A9b2e88C22B464fD38db3f3, address(ERC20TOKEN), MIN_APPROVAL_PCT, MIN_DISAPPROVAL_PCT
erc20TokenholderCaster, address(erc20VotesToken), ERC20_MIN_APPROVAL_PCT, ERC20_MIN_DISAPPROVAL_PCT
);
CORE.executeAction(actionInfo);
}

function test_CanDeployERC721TokenVotingModule() public {
// Set up action to call `deployTokenVotingModule` with the ERC721 token.
bytes memory data = abi.encodeWithSelector(
LlamaTokenVotingFactory.deployTokenVotingModule.selector, address(ERC721TOKEN), false, 1, 1, 1
LlamaTokenVotingFactory.deployTokenVotingModule.selector,
address(erc721VotesToken),
false,
ERC721_CREATION_THRESHOLD,
ERC721_MIN_APPROVAL_PCT,
ERC721_MIN_DISAPPROVAL_PCT
);
ActionInfo memory actionInfo = _setPermissionCreateApproveAndQueueAction(data);

ActionInfo memory actionInfo = _createApproveAndQueueAction(data);
// Compute addresses of ERC721 Token Voting Module
address erc721TokenholderActionCreator = Clones.predictDeterministicAddress(
address(erc721TokenholderActionCreatorLogic),
keccak256(abi.encodePacked(address(erc721VotesToken), address(EXECUTOR))), // salt
address(tokenVotingFactory) // deployer
);
address erc721TokenholderCaster = Clones.predictDeterministicAddress(
address(erc721TokenholderCasterLogic),
keccak256(abi.encodePacked(address(erc721VotesToken), address(EXECUTOR))), // salt
address(tokenVotingFactory) // deployer
);

// Expect events to be emitted on call to `deployTokenVotingModule`.
vm.expectEmit();
emit ERC721TokenholderActionCreatorCreated(0x104fBc016F4bb334D775a19E8A6510109AC63E00, address(ERC721TOKEN));
emit ERC721TokenholderActionCreatorCreated(erc721TokenholderActionCreator, address(erc721VotesToken));
vm.expectEmit();
emit ERC721TokenholderCasterCreated(0x037eDa3aDB1198021A9b2e88C22B464fD38db3f3, address(ERC721TOKEN), 1, 1);
emit ERC721TokenholderCasterCreated(
erc721TokenholderCaster, address(erc721VotesToken), ERC721_MIN_APPROVAL_PCT, ERC721_MIN_DISAPPROVAL_PCT
);
CORE.executeAction(actionInfo);
}
}
43 changes: 41 additions & 2 deletions test/token-voting/LlamaTokenVotingTestSetup.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,57 @@
pragma solidity ^0.8.23;

import {Test, console2} from "forge-std/Test.sol";

import {Vm} from "forge-std/Vm.sol";

import {ERC20Votes} from "@openzeppelin/token/ERC20/extensions/ERC20Votes.sol";
import {ERC721Votes} from "@openzeppelin/token/ERC721/extensions/ERC721Votes.sol";

import {MockERC20Votes} from "test/mock/MockERC20Votes.sol";
import {MockERC721Votes} from "test/mock/MockERC721Votes.sol";
import {LlamaPeripheryTestSetup} from "test/LlamaPeripheryTestSetup.sol";

import {DeployLlamaTokenVotingFactory} from "script/DeployLlamaTokenVotingFactory.s.sol";

contract LlamaTokenVotingTestSetup is LlamaPeripheryTestSetup, DeployLlamaTokenVotingFactory {
// ERC20 Token Voting Constants.
uint256 public constant ERC20_CREATION_THRESHOLD = 100;
uint256 public constant ERC20_MIN_APPROVAL_PCT = 1000;
uint256 public constant ERC20_MIN_DISAPPROVAL_PCT = 1000;

// ERC721 Token Voting Constants.
uint256 public constant ERC721_CREATION_THRESHOLD = 1;
uint256 public constant ERC721_MIN_APPROVAL_PCT = 1;
uint256 public constant ERC721_MIN_DISAPPROVAL_PCT = 1;

// Tokens
MockERC20Votes public mockERC20Votes;
ERC20Votes public erc20VotesToken;
MockERC721Votes public mockERC721Votes;
ERC721Votes public erc721VotesToken;

function setUp() public virtual override {
LlamaPeripheryTestSetup.setUp();

// Deploy the Llama Token Voting factory and logic contracts
// Deploy the Llama Token Voting factory and logic contracts.
DeployLlamaTokenVotingFactory.run();

// Deploy the ERC20 and ERC721 tokens.
mockERC20Votes = new MockERC20Votes();
erc20VotesToken = ERC20Votes(address(mockERC20Votes));
mockERC721Votes = new MockERC721Votes();
erc721VotesToken = ERC721Votes(address(mockERC721Votes));

// Mint tokens to core team members.
mockERC20Votes.mint(coreTeam1, 100);
mockERC20Votes.mint(coreTeam2, 100);
mockERC20Votes.mint(coreTeam3, 100);
mockERC20Votes.mint(coreTeam4, 100);
mockERC721Votes.mint(coreTeam1, 0);
mockERC721Votes.mint(coreTeam2, 1);
mockERC721Votes.mint(coreTeam3, 2);
mockERC721Votes.mint(coreTeam4, 3);

// Mine block so that the ERC20 and ERC721 supply will be available when doing a past timestamp check.
mineBlock();
}
}

0 comments on commit 0d956f6

Please sign in to comment.