"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const tslib_1 = require("tslib");
const utils_1 = require("../utils");
/* tslint:disable-next-line:no-var-requires */
const computeMaxGasLimit = require("../../gasLimits.js").computeMaxGasLimit;
/* tslint:disable-next-line:no-var-requires */
const env = require("env-variable")();
/* tslint:disable:no-console */
/* tslint:disable:max-line-length */
/**
 * Migration callback
 */
exports.arcJsDeployer = (web3, artifacts, deployer) => {
    // so Utils.getWeb3 can find it
    global.web3 = web3;
    const network = env.arcjs_network || "ganache";
    /**
     * Pattern for using async/await found here:
     *  https://github.com/trufflesuite/truffle/issues/501#issuecomment-332589663
     */
    deployer.then(() => tslib_1.__awaiter(this, void 0, void 0, function* () {
        /**
         * Truffle Solidity artifact wrappers
         */
        const AbsoluteVote = artifacts.require("AbsoluteVote.sol");
        const ContributionReward = artifacts.require("ContributionReward.sol");
        const ControllerCreator = artifacts.require("ControllerCreator.sol");
        const DaoCreator = artifacts.require("DaoCreator.sol");
        // ExecutableTest is used only by tests
        const ExecutableTest = artifacts.require("ExecutableTest.sol");
        const GenesisProtocol = artifacts.require("GenesisProtocol.sol");
        const GlobalConstraintRegistrar = artifacts.require("GlobalConstraintRegistrar.sol");
        const QuorumVote = artifacts.require("QuorumVote.sol");
        const SchemeRegistrar = artifacts.require("SchemeRegistrar.sol");
        const SimpleICO = artifacts.require("SimpleICO.sol");
        const TokenCapGC = artifacts.require("TokenCapGC.sol");
        const UpgradeScheme = artifacts.require("UpgradeScheme.sol");
        const VestingScheme = artifacts.require("VestingScheme.sol");
        const VoteInOrganizationScheme = artifacts.require("VoteInOrganizationScheme.sol");
        const OrganizationRegister = artifacts.require("OrganizationRegister.sol");
        const Redeemer = artifacts.require("Redeemer.sol");
        const UController = artifacts.require("UController.sol");
        console.log(`Deploying schemes to ${network}`);
        const DAOToken = yield utils_1.Utils.requireContract("DAOToken");
        const gasLimit = yield computeMaxGasLimit(web3);
        const gasPrice = 10000000000; // 10 Gwei
        let genTokenAddress;
        yield DAOToken.at("0x543Ff227F64Aa17eA132Bf9886cAb5DB55DCAddf")
            .then((token) => genTokenAddress = token.address)
            .catch(() => { console.log(`global GEN token does not exist at standard address`); });
        if (!genTokenAddress) {
            if (network === "ganache") {
                yield DAOToken.at("0xdcf22b53f327b4f7f3ac42d957834bd962637555")
                    .then((token) => genTokenAddress = token.address)
                    .catch(() => { console.log(`global GEN token does not exist in ganache`); });
                if (!genTokenAddress) {
                    /**
                     * Then we will create the token to use for staking.
                     * See https://ethereum.stackexchange.com/a/13459/21913
                     * This is fragile in that in order to result in a consistent token address
                     * the nonce and account address must always be the same when the token is created.
                     * Thus we need this to be the first transaction that account[0] attempts after
                     * ganache has been fired-up.
                     */
                    console.log(`Creating global GEN token for ganache`);
                    const genToken = yield DAOToken.new("DAOstack", "GEN", web3.toWei(100000000), { from: "0xb0c908140fe6fd6fbd4990a5c2e35ca6dc12bfb2" });
                    genTokenAddress = genToken.address;
                }
            }
            else {
                throw new Error(`The GEN token must exist for staking on ${network}`);
            }
        }
        console.log(`Using global GEN token for staking on ${network} at: ${genTokenAddress}`);
        console.log(`Deploying schemes on ${network}, gasLimit: ${gasLimit}`);
        yield deployer.deploy(ControllerCreator, { gas: gasLimit, gasPrice: gasPrice * 2 });
        const controllerCreator = yield ControllerCreator.deployed();
        yield deployer.deploy(DaoCreator, controllerCreator.address, { gas: gasLimit, gasPrice });
        yield deployer.deploy(UController, { gas: gasLimit, gasPrice: gasPrice * 2 });
        yield deployer.deploy(GenesisProtocol, genTokenAddress, { gas: gasLimit, gasPrice: gasPrice * 2 });
        yield deployer.deploy(SchemeRegistrar, { gas: gasLimit, gasPrice });
        yield deployer.deploy(UpgradeScheme, { gas: gasLimit, gasPrice });
        yield deployer.deploy(GlobalConstraintRegistrar, { gas: gasLimit, gasPrice: gasPrice * 2 });
        yield deployer.deploy(ContributionReward, { gas: gasLimit, gasPrice });
        yield deployer.deploy(AbsoluteVote, { gas: gasLimit, gasPrice });
        yield deployer.deploy(QuorumVote, { gas: gasLimit, gasPrice });
        yield deployer.deploy(SimpleICO, { gas: gasLimit, gasPrice });
        yield deployer.deploy(TokenCapGC, { gas: gasLimit, gasPrice });
        yield deployer.deploy(VestingScheme, { gas: gasLimit, gasPrice });
        yield deployer.deploy(VoteInOrganizationScheme, { gas: gasLimit, gasPrice });
        yield deployer.deploy(OrganizationRegister, { gas: gasLimit, gasPrice });
        const genesisProtocolInstance = yield GenesisProtocol.deployed();
        const contributionRewardInstance = yield ContributionReward.deployed();
        yield deployer.deploy(Redeemer, contributionRewardInstance.address, genesisProtocolInstance.address, { gas: gasLimit, gasPrice: gasPrice * 2 });
        if (network !== "live") {
            yield deployer.deploy(ExecutableTest, { gas: gasLimit, gasPrice });
        }
    }));
};
//# sourceMappingURL=2_deploy_schemes.js.map