"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const generateEmptyBallotRoots_1 = require("../../../ts/generateEmptyBallotRoots");
const logger_1 = require("../../../ts/logger");
const constants_1 = require("../../helpers/constants");
const ContractStorage_1 = require("../../helpers/ContractStorage");
const Deployment_1 = require("../../helpers/Deployment");
const types_1 = require("../../helpers/types");
const deployment = Deployment_1.Deployment.getInstance();
const storage = ContractStorage_1.ContractStorage.getInstance();
const DEFAULT_STATE_TREE_DEPTH = 10;
/**
 * Deploy step registration and task itself
 */
deployment.deployTask(constants_1.EDeploySteps.Maci, "Deploy MACI contract").then((task) => task.setAction(async ({ incremental }, hre) => {
    deployment.setHre(hre);
    const deployer = await deployment.getDeployer();
    const maciContractAddress = storage.getAddress(types_1.EContracts.MACI, hre.network.name);
    if (incremental && maciContractAddress) {
        // eslint-disable-next-line no-console
        (0, logger_1.logGreen)({ text: (0, logger_1.info)(`Skipping deployment of the ${types_1.EContracts.MACI} contract`) });
        return;
    }
    const poseidonT3ContractAddress = storage.mustGetAddress(types_1.EContracts.PoseidonT3, hre.network.name);
    const poseidonT4ContractAddress = storage.mustGetAddress(types_1.EContracts.PoseidonT4, hre.network.name);
    const poseidonT5ContractAddress = storage.mustGetAddress(types_1.EContracts.PoseidonT5, hre.network.name);
    const poseidonT6ContractAddress = storage.mustGetAddress(types_1.EContracts.PoseidonT6, hre.network.name);
    const libraries = {
        "contracts/crypto/PoseidonT3.sol:PoseidonT3": poseidonT3ContractAddress,
        "contracts/crypto/PoseidonT4.sol:PoseidonT4": poseidonT4ContractAddress,
        "contracts/crypto/PoseidonT5.sol:PoseidonT5": poseidonT5ContractAddress,
        "contracts/crypto/PoseidonT6.sol:PoseidonT6": poseidonT6ContractAddress,
    };
    const maciContractFactory = await hre.ethers.getContractFactory(types_1.EContracts.MACI, {
        signer: deployer,
        libraries,
    });
    const policy = deployment.getDeployConfigField(types_1.EContracts.MACI, "policy") || types_1.EContracts.FreeForAllPolicy;
    const fullPolicyName = constants_1.FULL_POLICY_NAMES[policy];
    const policyContractAddress = storage.mustGetAddress(fullPolicyName, hre.network.name);
    const pollFactoryContractAddress = storage.mustGetAddress(types_1.EContracts.PollFactory, hre.network.name);
    const messageProcessorFactoryContractAddress = storage.mustGetAddress(types_1.EContracts.MessageProcessorFactory, hre.network.name);
    const tallyFactoryContractAddress = storage.mustGetAddress(types_1.EContracts.TallyFactory, hre.network.name);
    const verifierContractAddress = storage.mustGetAddress(types_1.EContracts.Verifier, hre.network.name);
    const verifyingKeysRegistryContractAddress = storage.mustGetAddress(types_1.EContracts.VerifyingKeysRegistry, hre.network.name);
    if (!verifierContractAddress) {
        throw new Error("Need to deploy Verifier contract first");
    }
    if (!verifyingKeysRegistryContractAddress) {
        throw new Error("Need to deploy VerifyingKeysRegistry contract first");
    }
    const stateTreeDepth = deployment.getDeployConfigField(types_1.EContracts.MACI, "stateTreeDepth") ?? DEFAULT_STATE_TREE_DEPTH;
    const emptyBallotRoots = (0, generateEmptyBallotRoots_1.generateEmptyBallotRoots)(stateTreeDepth);
    const maciContract = await deployment.deployContractWithLinkedLibraries({ contractFactory: maciContractFactory }, {
        pollFactory: pollFactoryContractAddress,
        messageProcessorFactory: messageProcessorFactoryContractAddress,
        tallyFactory: tallyFactoryContractAddress,
        signUpPolicy: policyContractAddress,
        verifier: verifierContractAddress,
        verifyingKeysRegistry: verifyingKeysRegistryContractAddress,
        stateTreeDepth,
        emptyBallotRoots,
    });
    const policyContract = await deployment.getContract({
        name: fullPolicyName,
        address: policyContractAddress,
    });
    const maciInstanceAddress = await maciContract.getAddress();
    await policyContract.setTarget(maciInstanceAddress).then((tx) => tx.wait());
    await storage.register({
        id: types_1.EContracts.MACI,
        contract: maciContract,
        libraries,
        args: [
            {
                pollFactory: pollFactoryContractAddress,
                messageProcessorFactory: messageProcessorFactoryContractAddress,
                tallyFactory: tallyFactoryContractAddress,
                signUpPolicy: policyContractAddress,
                verifier: verifierContractAddress,
                verifyingKeysRegistry: verifyingKeysRegistryContractAddress,
                stateTreeDepth,
                emptyBallotRoots: emptyBallotRoots.map((root) => root.toString()),
            },
        ],
        network: hre.network.name,
    });
}));
//# sourceMappingURL=08-maci.js.map