Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(hats): add hats gatekeeper deployment steps #1754

Merged
merged 1 commit into from
Aug 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ abstract contract HatsGatekeeperBase is SignUpGatekeeper, Ownable(msg.sender) {

/// @notice Get the trait of the gatekeeper
/// @return The type of the gatekeeper
function getTrait() public pure override returns (string memory) {
function getTrait() public pure virtual override returns (string memory) {
return "Hats";
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -59,4 +59,10 @@ contract HatsGatekeeperMultiple is HatsGatekeeperBase {
// _user must be wearing the criterion hat
if (!hats.isWearerOfHat(_user, hat)) revert NotWearingCriterionHat();
}

/// @notice Get the trait of the gatekeeper
/// @return The type of the gatekeeper
function getTrait() public pure override returns (string memory) {
return "HatsMultiple";
}
}
67 changes: 67 additions & 0 deletions packages/contracts/deploy-config-example.json
Original file line number Diff line number Diff line change
Expand Up @@ -369,5 +369,72 @@
"coordinatorPubkey": "macipk.9a59264310d95cfd8eb7083aebeba221b5c26e77427f12b7c0f50bc1cc35e621",
"useQuadraticVoting": false
}
},
"optimism_sepolia": {
"ConstantInitialVoiceCreditProxy": {
"deploy": true,
"amount": 99
},
"FreeForAllGatekeeper": {
"deploy": true
},
"HatsGatekeeper": {
"deploy": false,
"criterionHats": ["26960358043289970096177553829315270011263390106506980876069447401472"],
"hatsProtocolAddress": "0x3bc1A0Ad72417f2d411118085256fC53CBdDd137"
},
"EASGatekeeper": {
"deploy": false,
"easAddress": "0x4200000000000000000000000000000000000021",
"schema": "0xe2636f31239f7948afdd9a9c477048b7fc2a089c347af60e3aa1251e5bf63e5c",
"attester": "the-attester-address"
},
"GitcoinPassportGatekeeper": {
"deploy": false,
"decoderAddress": "0x5558D441779Eca04A329BcD6b47830D2C6607769",
"passingScore": 5
},
"ZupassGatekeeper": {
"deploy": false,
"signer1": "13908133709081944902758389525983124100292637002438232157513257158004852609027",
"signer2": "7654374482676219729919246464135900991450848628968334062174564799457623790084",
"eventId": "69c0caaa-c65d-5345-a20c-867774f18c67",
"zupassVerifier": "0x2272cdb3596617886d0F48524DA486044E0376d6"
},
"SemaphoreGatekeeper": {
"deploy": false,
"semaphoreContract": "0x0000000000000000000000000000000000000000",
"groupId": 0
},
"MACI": {
"stateTreeDepth": 14,
"gatekeeper": "FreeForAllGatekeeper"
},
"VkRegistry": {
"stateTreeDepth": 10,
"intStateTreeDepth": 1,
"messageTreeDepth": 2,
"voteOptionTreeDepth": 2,
"messageBatchDepth": 1,
"zkeys": {
"qv": {
"processMessagesZkey": "../cli/zkeys/ProcessMessages_10-2-1-2_test/ProcessMessages_10-2-1-2_test.0.zkey",
"tallyVotesZkey": "../cli/zkeys/TallyVotes_10-1-2_test/TallyVotes_10-1-2_test.0.zkey",
"processWasm": "../cli/zkeys/ProcessMessages_10-2-1-2_test/ProcessMessages_10-2-1-2_test_js/ProcessMessages_10-2-1-2_test.wasm",
"tallyWasm": "../cli/zkeys/TallyVotes_10-1-2_test/TallyVotes_10-1-2_test_js/TallyVotes_10-1-2_test.wasm"
},
"nonQv": {
"processMessagesZkey": "../cli/zkeys/ProcessMessagesNonQv_10-2-1-2_test/ProcessMessagesNonQv_10-2-1-2_test.0.zkey",
"tallyVotesZkey": "../cli/zkeys/TallyVotesNonQv_10-1-2_test/TallyVotesNonQv_10-1-2_test.0.zkey",
"processWasm": "../cli/zkeys/ProcessMessagesNonQv_10-2-1-2_test/ProcessMessagesNonQv_10-2-1-2_test_js/ProcessMessagesNonQv_10-2-1-2_test.wasm",
"tallyWasm": "../cli/zkeys/TallyVotesNonQv_10-1-2_test/TallyVotesNonQv_10-1-2_test_js/TallyVotesNonQv_10-1-2_test.wasm"
}
}
},
"Poll": {
"pollDuration": 3600,
"coordinatorPubkey": "macipk.9a59264310d95cfd8eb7083aebeba221b5c26e77427f12b7c0f50bc1cc35e621",
"useQuadraticVoting": false
}
}
}
47 changes: 46 additions & 1 deletion packages/contracts/tasks/deploy/maci/02-gatekeepers.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { HatsGatekeeperBase } from "../../../typechain-types";
import { ESupportedChains } from "../../helpers/constants";
import { ContractStorage } from "../../helpers/ContractStorage";
import { Deployment } from "../../helpers/Deployment";
Expand All @@ -17,6 +18,7 @@ deployment.deployTask("full:deploy-gatekeepers", "Deploy gatekeepers").then((tas

const freeForAllGatekeeperContractAddress = storage.getAddress(EContracts.FreeForAllGatekeeper, hre.network.name);
const easGatekeeperContractAddress = storage.getAddress(EContracts.EASGatekeeper, hre.network.name);
const hatsGatekeeperContractAddress = storage.getAddress(EContracts.HatsGatekeeper, hre.network.name);
const gitcoinGatekeeperContractAddress = storage.getAddress(EContracts.GitcoinPassportGatekeeper, hre.network.name);
const zupassGatekeeperContractAddress = storage.getAddress(EContracts.ZupassGatekeeper, hre.network.name);
const semaphoreGatekeeperContractAddress = storage.getAddress(EContracts.SemaphoreGatekeeper, hre.network.name);
Expand All @@ -25,12 +27,14 @@ deployment.deployTask("full:deploy-gatekeepers", "Deploy gatekeepers").then((tas
const deployGitcoinGatekeeper = deployment.getDeployConfigField(EContracts.GitcoinPassportGatekeeper, "deploy");
const deployZupassGatekeeper = deployment.getDeployConfigField(EContracts.ZupassGatekeeper, "deploy");
const deploySemaphoreGatekeeper = deployment.getDeployConfigField(EContracts.SemaphoreGatekeeper, "deploy");
const deployHatsSingleGatekeeper = deployment.getDeployConfigField(EContracts.HatsGatekeeper, "deploy");

const skipDeployFreeForAllGatekeeper = deployFreeForAllGatekeeper !== true;
const skipDeployEASGatekeeper = deployEASGatekeeper !== true;
const skipDeployGitcoinGatekeeper = deployGitcoinGatekeeper !== true;
const skipDeployZupassGatekeeper = deployZupassGatekeeper !== true;
const skipDeploySemaphoreGatekeeper = deploySemaphoreGatekeeper !== true;
const skipDeployHatsGatekeeper = deployHatsSingleGatekeeper !== true;

const canSkipDeploy =
incremental &&
Expand All @@ -39,11 +43,13 @@ deployment.deployTask("full:deploy-gatekeepers", "Deploy gatekeepers").then((tas
(gitcoinGatekeeperContractAddress || skipDeployGitcoinGatekeeper) &&
(zupassGatekeeperContractAddress || skipDeployZupassGatekeeper) &&
(semaphoreGatekeeperContractAddress || skipDeploySemaphoreGatekeeper) &&
(hatsGatekeeperContractAddress || skipDeployHatsGatekeeper) &&
(!skipDeployFreeForAllGatekeeper ||
!skipDeployEASGatekeeper ||
!skipDeployGitcoinGatekeeper ||
!skipDeployZupassGatekeeper ||
!skipDeploySemaphoreGatekeeper);
!skipDeploySemaphoreGatekeeper ||
!skipDeployHatsGatekeeper);

if (canSkipDeploy) {
return;
Expand Down Expand Up @@ -181,5 +187,44 @@ deployment.deployTask("full:deploy-gatekeepers", "Deploy gatekeepers").then((tas
network: hre.network.name,
});
}

if (!skipDeployHatsGatekeeper) {
// get args
const criterionHats = deployment.getDeployConfigField<string[]>(EContracts.HatsGatekeeper, "criterionHats", true);
const hatsProtocolAddress = deployment.getDeployConfigField<string>(
EContracts.HatsGatekeeper,
"hatsProtocolAddress",
true,
);

let hatsGatekeeperContract: HatsGatekeeperBase;
// if we have one we use the single gatekeeper
if (criterionHats.length === 1) {
hatsGatekeeperContract = await deployment.deployContract(
{
name: EContracts.HatsGatekeeperSingle,
signer: deployer,
},
hatsProtocolAddress,
criterionHats[0],
);
} else {
hatsGatekeeperContract = await deployment.deployContract(
{
name: EContracts.HatsGatekeeperMultiple,
signer: deployer,
},
hatsProtocolAddress,
criterionHats,
);
}

await storage.register({
id: EContracts.HatsGatekeeper,
contract: hatsGatekeeperContract,
args: [hatsProtocolAddress, criterionHats.length === 1 ? criterionHats[0] : criterionHats],
network: hre.network.name,
});
}
}),
);
9 changes: 9 additions & 0 deletions packages/contracts/tasks/deploy/maci/08-maci.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import type {
ZupassGatekeeper,
MACI,
SemaphoreGatekeeper,
HatsGatekeeperBase,
} from "../../../typechain-types";

import { genEmptyBallotRoots } from "../../../ts/genEmptyBallotRoots";
Expand Down Expand Up @@ -105,6 +106,14 @@ deployment.deployTask("full:deploy-maci", "Deploy MACI contract").then((task) =>
address: gatekeeperContractAddress,
});

const maciInstanceAddress = await maciContract.getAddress();
await gatekeeperContract.setMaciInstance(maciInstanceAddress).then((tx) => tx.wait());
} else if (gatekeeper === EContracts.HatsGatekeeper) {
const gatekeeperContract = await deployment.getContract<HatsGatekeeperBase>({
name: EContracts.HatsGatekeeper,
address: gatekeeperContractAddress,
});

const maciInstanceAddress = await maciContract.getAddress();
await gatekeeperContract.setMaciInstance(maciInstanceAddress).then((tx) => tx.wait());
}
Expand Down
3 changes: 3 additions & 0 deletions packages/contracts/tasks/helpers/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -543,6 +543,9 @@ export enum EContracts {
FreeForAllGatekeeper = "FreeForAllGatekeeper",
EASGatekeeper = "EASGatekeeper",
GitcoinPassportGatekeeper = "GitcoinPassportGatekeeper",
HatsGatekeeper = "HatsGatekeeper",
HatsGatekeeperSingle = "HatsGatekeeperSingle",
HatsGatekeeperMultiple = "HatsGatekeeperMultiple",
ZupassGatekeeper = "ZupassGatekeeper",
ZupassGroth16Verifier = "ZupassGroth16Verifier",
SemaphoreGatekeeper = "SemaphoreGatekeeper",
Expand Down
Loading