diff --git a/.gitignore b/.gitignore index 5dcaeb2ac..611ba6c05 100644 --- a/.gitignore +++ b/.gitignore @@ -12,4 +12,3 @@ yarn.lock test-build/ site/ docs/api/ -arcConstants.js diff --git a/config/default.json b/config/default.json index 0ac099e28..94001f07d 100644 --- a/config/default.json +++ b/config/default.json @@ -4,6 +4,7 @@ "cacheContractWrappers": true, "logLevel": 9, "estimateGas": false, + "defaultGasLimit": 4543760, "gasPriceAdjustor": null, "txDepthRequiredForConfirmation": { "default": 7, diff --git a/docs/Configuration.md b/docs/Configuration.md index f1b542429..785f6f97a 100644 --- a/docs/Configuration.md +++ b/docs/Configuration.md @@ -9,6 +9,9 @@ Automatically approve token transfers for operations that require the sender pay **cacheContractWrappers** `true` to cache contract wrappers obtained using the contract wrapper factory methods `.at` and `.new`. The cache is local, it does not persist across application instances. The default is `false`. +**defaultGasLimit** +The default gas limit used for most operations when "estimateGas" is false. + **defaultVotingMachine** The voting machine used by default by `Dao.new` when creating new DAOs. Default is "AbsoluteVote". diff --git a/docs/Migration.md b/docs/Migration.md index aa125c93a..837255191 100644 --- a/docs/Migration.md +++ b/docs/Migration.md @@ -23,9 +23,6 @@ Arc.js ships with contracts already migrated to Kovan and MainNet. But you may !!! warning The mnemonic won't work unless it confirms to [BIP39](https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki). You can generate examples of conformant mnemonics [here](https://iancoleman.io/bip39/). - !!! info - The migration script will use the gas settings defined in the Arc.js file `arc.js/gasLimits.js`. The gas limit when migrating/creating Daos is computed dynamically as a function of the number of founders. - 3. Provide a list of Genesis DAO founders as described in [configuring founders](#configuring-founders). 4. If deploying to ganache, then run `npm start ganache`, or from your application: `npm explore @daostack/arc.js -- npm start ganache`. diff --git a/gasLimits.js b/gasLimits.js deleted file mode 100644 index 0923e4b5a..000000000 --- a/gasLimits.js +++ /dev/null @@ -1,57 +0,0 @@ -const promisify = require("es6-promisify").promisify; -const arcForgeOrgGasLimit = require("./arcConstants.js").ARC_GAS_LIMIT; -/** - * Defines some useful gas limit constants, provides some useful gasLimit-related utilities. - * - * Since this module needs to be usable in several different contexts, and cannot depend on doing a build - * (because one of the contexts in which it is used is the script that itself does the builds), we're - * putting this at the root level and writing it in straight low-common-denominator ES5 javascript. - */ -const gasLimitsConfig = -{ - /** - * The gas limit used by Arc to forge a DAO with foundersInGasLimitArc founders - * and to `new` GenesisProtocol. - */ - "gasLimit_arc": arcForgeOrgGasLimit, - /** - * The amount of gas needed for each founder when creating a DAO - */ - "gasLimit_perFounder": 50000, - /** - * How many founders are already accounted-for in the gaslimit from Arc - */ - "foundersInGasLimitArc": 3, - /** - * Gas limit sufficient (though not necessarily optimal) for all other transactions - * besides creating DAOs - */ - "gasLimit_runtime": 4543760, -}; - -/** - * Compute a reasonable gasLimit for forging a DAO with the given number of founders. - * @param {*} numberFounders - */ -const computeForgeOrgGasLimit = function (numberFounders) { - return gasLimitsConfig.gasLimit_arc + - ((numberFounders - gasLimitsConfig.foundersInGasLimitArc) * gasLimitsConfig.gasLimit_perFounder); -}; - -/** - * Returns promise of the maximum gasLimit that we dare to ever use, given the - * current state of the chain. - * @param {} web3 - */ -const computeMaxGasLimit = function (web3) { - return promisify((callback) => web3.eth.getBlock("latest", false, callback))() - .then((block) => { - return block.gasLimit - 100000; - }); -} - -module.exports = { - computeForgeOrgGasLimit: computeForgeOrgGasLimit, - computeMaxGasLimit: computeMaxGasLimit, - gasLimitsConfig: gasLimitsConfig, -}; diff --git a/lib/contractWrapperBase.ts b/lib/contractWrapperBase.ts index 86d8be1f9..5e6d5bb72 100644 --- a/lib/contractWrapperBase.ts +++ b/lib/contractWrapperBase.ts @@ -1,6 +1,5 @@ import { BigNumber } from "bignumber.js"; import { promisify } from "es6-promisify"; -import { computeMaxGasLimit } from "../gasLimits.js"; import { Address, Hash, SchemePermissions } from "./commonTypes"; import { ConfigService } from "./configService"; import { ControllerService } from "./controllerService"; @@ -20,6 +19,7 @@ import { TxGeneratingFunctionOptions } from "./transactionService"; import { Utils } from "./utils"; +import { UtilsInternal } from "./utilsInternal"; import { EventFetcherFactory, Web3EventService } from "./web3EventService"; /** @@ -176,9 +176,7 @@ export abstract class ContractWrapperBase implements IContractWrapper { const currentNetwork = await Utils.getNetworkName(); - const web3 = await Utils.getWeb3(); - - const maxGasLimit = await computeMaxGasLimit(web3); + const maxGasLimit = await UtilsInternal.computeMaxGasLimit(); if (currentNetwork === "Ganache") { return maxGasLimit; // because who cares with ganache and we can't get good estimates from it @@ -313,14 +311,14 @@ export abstract class ContractWrapperBase implements IContractWrapper { try { let error; - const gasPriceComputer = ConfigService.get("gasPriceAdjustment") as GasPriceAdjustor; + const gasPriceComputed = ConfigService.get("gasPriceAdjustment") as GasPriceAdjustor; + const web3 = await Utils.getWeb3(); - if (gasPriceComputer && !web3Params.gasPrice) { - const web3 = await Utils.getWeb3(); - if (gasPriceComputer) { + if (gasPriceComputed && !web3Params.gasPrice) { + if (gasPriceComputed) { const defaultGasPrice = await promisify((callback: any): void => { web3.eth.getGasPrice(callback); })() as BigNumber; - web3Params.gasPrice = await gasPriceComputer(defaultGasPrice); + web3Params.gasPrice = await gasPriceComputed(defaultGasPrice); } LoggingService.debug( `invoking function with configured gasPrice: ${web3.fromWei(web3Params.gasPrice, "gwei")}`); @@ -337,6 +335,9 @@ export abstract class ContractWrapperBase implements IContractWrapper { LoggingService.error(`estimateGas failed: ${ex}`); error = ex; }); + } else if (web3Params.gas) { + // cap any already-given gas limit + web3Params.gas = Math.min(web3Params.gas, await UtilsInternal.computeMaxGasLimit()); } if (error) { diff --git a/lib/contractWrapperFactory.ts b/lib/contractWrapperFactory.ts index 993b56a67..56c68d0dc 100644 --- a/lib/contractWrapperFactory.ts +++ b/lib/contractWrapperFactory.ts @@ -1,8 +1,11 @@ +import { promisify } from "es6-promisify"; import { Address } from "./commonTypes"; +import { ConfigService } from "./configService"; import { IConfigService } from "./iConfigService"; import { IContractWrapper, IContractWrapperFactory } from "./iContractWrapperBase"; import { LoggingService } from "./loggingService"; import { Utils } from "./utils"; +import { UtilsInternal } from "./utilsInternal"; import { Web3EventService } from "./web3EventService"; /** @@ -44,6 +47,17 @@ export class ContractWrapperFactory public async new(...rest: Array): Promise { await this.ensureSolidityContract(); + let gas; + + if (ConfigService.get("estimateGas") && (!rest || !rest.length || (!rest[rest.length - 1].gas))) { + gas = await this.estimateConstructorGas(...rest); + LoggingService.debug(`Instantiating ${this.solidityContractName} with gas: ${gas}`); + } + + if (gas) { + rest = [...rest, { gas }]; + } + const hydratedWrapper = await new this.wrapper(this.solidityContract, this.web3EventService).hydrateFromNew(...rest); @@ -84,6 +98,28 @@ export class ContractWrapperFactory return this.getHydratedWrapper(getWrapper); } + protected async estimateConstructorGas(...params: Array): Promise { + const web3 = await Utils.getWeb3(); + await this.ensureSolidityContract(); + const callData = (web3.eth.contract(this.solidityContract.abi).new as any).getData( + ...params, + { + data: this.solidityContract.bytecode, + }); + + const currentNetwork = await Utils.getNetworkName(); + + const maxGasLimit = await UtilsInternal.computeMaxGasLimit(); + + if (currentNetwork === "Ganache") { + return maxGasLimit; // because who cares with ganache and we can't get good estimates from it + } + + const gas = await promisify((callback: any) => web3.eth.estimateGas({ data: callData }, callback))() as number; + + return Math.max(Math.min(gas, maxGasLimit), 21000); + } + private async getHydratedWrapper( getWrapper: () => Promise, address?: Address): Promise { diff --git a/lib/index.ts b/lib/index.ts index 219440df8..2c7154c72 100644 --- a/lib/index.ts +++ b/lib/index.ts @@ -44,7 +44,6 @@ export * from "./proposalGeneratorBase"; export * from "./loggingService"; export * from "./transactionService"; export * from "./utils"; -export const computeForgeOrgGasLimit: any = require("../gasLimits.js").computeForgeOrgGasLimit; import { Web3 } from "web3"; import { AccountService } from "./accountService"; @@ -85,7 +84,7 @@ export async function InitializeArcJs(options?: InitializeArcOptions): Promise { - - const live = this.network === "live"; - /** - * Genesis DAO parameters - */ - const orgName = live ? "Genesis Alpha" : "Genesis Alpha"; - const tokenName = live ? "Genesis Alpha" : "Genesis Alpha"; - const tokenSymbol = "GDT"; - - /** - * Truffle Solidity artifact wrappers - */ - const Avatar = await Utils.requireContract("Avatar"); - - const DaoCreator = await Utils.requireContract("DaoCreator"); - const daoCreatorInst = await DaoCreator.deployed(); - const UController = await Utils.requireContract("UController"); - const universalControllerInst = await UController.deployed(); - - const internalFoundersConfigLocation = "../../migrations/founders.json"; - const foundersConfig = require(internalFoundersConfigLocation).founders; - - const customFoundersConfigLocation = foundersConfigurationLocation || internalFoundersConfigLocation; - - if (internalFoundersConfigLocation !== customFoundersConfigLocation) { - console.log(`merging custom founders from ${customFoundersConfigLocation}`); - const customFoundersConfig = require(customFoundersConfigLocation).founders; - // merge the two - Object.assign(foundersConfig, customFoundersConfig); - } - - const founders = foundersConfig[this.network]; - - if (!founders || (founders.length === 0)) { - throw new Error(`no founders were given for the network: ${this.network}`); - } - - let gasLimit = computeForgeOrgGasLimit(founders.length); - const maxGasLimit = await computeMaxGasLimit(this.web3); - - gasLimit = Math.min(gasLimit, maxGasLimit); - - console.log(`Forging ${orgName} to ${this.network}, gasLimit: ${gasLimit} and ${founders.length} founders...`); - - /** - * Create the Genesis DAO - */ - const txForgeOrg = await daoCreatorInst.forgeOrg( - orgName, - tokenName, - tokenSymbol, - founders.map((f: FounderSpec) => f.address), - founders.map((f: FounderSpec) => this.web3.toWei(f.tokens)), - founders.map((f: FounderSpec) => this.web3.toWei(f.reputation)), - universalControllerInst.address, - this.web3.toWei(100000000), // token cap of one hundred million GEN, in Wei - { gas: gasLimit }); - - let avatarInst; - - while (!avatarInst) { - - await Avatar.at(txForgeOrg.logs[0].args._avatar) - .then((address: Address) => { - avatarInst = address; - }) - /* tslint:disable-next-line:no-empty */ - .catch(() => { - }); - - if (!avatarInst) { - console.log("sleeping until Avatar is available..."); - /** - * Sleep and retry until avatarInst is mined. This is necessary - * virtually every time we run against mainnet. - */ - await UtilsInternal.sleep(2000); - } - } - - console.log(`Avatar forged at: ${avatarInst.address}`); - - /** for use by setSchemes */ - return { - avatarAddress: avatarInst.address, - daoCreatorInst, - orgName, - } as ForgedDaoInfo; - } - - public async setSchemes(forgedDaoInfo: ForgedDaoInfo): Promise { - - /** - * Truffle Solidity artifact wrappers - */ - const ContributionReward = await Utils.requireContract("ContributionReward"); - const GlobalConstraintRegistrar = await Utils.requireContract("GlobalConstraintRegistrar"); - const SchemeRegistrar = await Utils.requireContract("SchemeRegistrar"); - const UpgradeScheme = await Utils.requireContract("UpgradeScheme"); - const GenesisProtocol = await Utils.requireContract("GenesisProtocol"); - - /** - * Genesis DAO parameters - */ - const orgNativeTokenFee = 0; - const defaultVotingMachineParams = await GetDefaultGenesisProtocolParameters(); - const schemeRegistrarPermissions = SchemePermissions.toString(DefaultSchemePermissions.SchemeRegistrar); - const globalConstraintRegistrarPermissions = SchemePermissions.toString(DefaultSchemePermissions.GlobalConstraintRegistrar); - const upgradeSchemePermissions = SchemePermissions.toString(DefaultSchemePermissions.UpgradeScheme); - const contributionRewardPermissions = SchemePermissions.toString(DefaultSchemePermissions.ContributionReward); - const genesisProtocolPermissions = SchemePermissions.toString(DefaultSchemePermissions.GenesisProtocol); - - console.log(`Setting schemes for ${forgedDaoInfo.orgName} on ${this.network}...`); - - const genesisProtocolInst = await GenesisProtocol.deployed(); - const schemeRegistrarInst = await SchemeRegistrar.deployed(); - const upgradeSchemeInst = await UpgradeScheme.deployed(); - const globalConstraintRegistrarInst = await GlobalConstraintRegistrar.deployed(); - const contributionRewardInst = await ContributionReward.deployed(); - /** - * Set/get the GenesisProtocol voting parameters that will be used as defaults - * for the schemes' voting machine as we add the schemes to the Genesis DAO, below. - */ - const genesisProtocolParams = await genesisProtocolInst.getParametersHash( - [ - defaultVotingMachineParams.preBoostedVoteRequiredPercentage, - defaultVotingMachineParams.preBoostedVotePeriodLimit, - defaultVotingMachineParams.boostedVotePeriodLimit, - defaultVotingMachineParams.thresholdConstA, - defaultVotingMachineParams.thresholdConstB, - defaultVotingMachineParams.minimumStakingFee, - defaultVotingMachineParams.quietEndingPeriod, - defaultVotingMachineParams.proposingRepRewardConstA, - defaultVotingMachineParams.proposingRepRewardConstB, - defaultVotingMachineParams.stakerFeeRatioForVoters, - defaultVotingMachineParams.votersReputationLossRatio, - defaultVotingMachineParams.votersGainRepRatioFromLostRep, - defaultVotingMachineParams.daoBountyConst, - defaultVotingMachineParams.daoBountyLimit, - ] - ); - - await genesisProtocolInst.setParameters( - [ - defaultVotingMachineParams.preBoostedVoteRequiredPercentage, - defaultVotingMachineParams.preBoostedVotePeriodLimit, - defaultVotingMachineParams.boostedVotePeriodLimit, - defaultVotingMachineParams.thresholdConstA, - defaultVotingMachineParams.thresholdConstB, - defaultVotingMachineParams.minimumStakingFee, - defaultVotingMachineParams.quietEndingPeriod, - defaultVotingMachineParams.proposingRepRewardConstA, - defaultVotingMachineParams.proposingRepRewardConstB, - defaultVotingMachineParams.stakerFeeRatioForVoters, - defaultVotingMachineParams.votersReputationLossRatio, - defaultVotingMachineParams.votersGainRepRatioFromLostRep, - defaultVotingMachineParams.daoBountyConst, - defaultVotingMachineParams.daoBountyLimit, - ] - ); - - /** - * Set/get the Genesis DAO's scheme parameters, using the GenesisProtocol voting machine - * parameters that we just obtained above. - */ - await schemeRegistrarInst.setParameters(genesisProtocolParams, genesisProtocolParams, genesisProtocolInst.address); - const schemeRegisterParams = await schemeRegistrarInst.getParametersHash(genesisProtocolParams, genesisProtocolParams, genesisProtocolInst.address); - - await globalConstraintRegistrarInst.setParameters(genesisProtocolParams, genesisProtocolInst.address); - const schemeGCRegisterParams = await globalConstraintRegistrarInst.getParametersHash(genesisProtocolParams, genesisProtocolInst.address); - - await upgradeSchemeInst.setParameters(genesisProtocolParams, genesisProtocolInst.address); - const schemeUpgradeParams = await upgradeSchemeInst.getParametersHash(genesisProtocolParams, genesisProtocolInst.address); - - await contributionRewardInst.setParameters(orgNativeTokenFee, genesisProtocolParams, genesisProtocolInst.address); - const contributionRewardParams = await contributionRewardInst.getParametersHash(orgNativeTokenFee, genesisProtocolParams, genesisProtocolInst.address); - - /** - * Register the schemes with the Genesis DAO - */ - const schemesArray = [ - schemeRegistrarInst.address, - globalConstraintRegistrarInst.address, - upgradeSchemeInst.address, - contributionRewardInst.address, - genesisProtocolInst.address]; - - const paramsArray = [ - schemeRegisterParams, - schemeGCRegisterParams, - schemeUpgradeParams, - contributionRewardParams, - genesisProtocolParams]; - - const permissionArray = [ - schemeRegistrarPermissions, - globalConstraintRegistrarPermissions, - upgradeSchemePermissions, - contributionRewardPermissions, - genesisProtocolPermissions, - ]; - - const daoCreatorInst = forgedDaoInfo.daoCreatorInst; - - return daoCreatorInst.setSchemes( - forgedDaoInfo.avatarAddress, - schemesArray, - paramsArray, - permissionArray); + public async run(foundersConfigurationLocation: string): Promise { + + const spec = { + founders: [ + { + address: "0xb0c908140fe6fd6fbd4990a5c2e35ca6dc12bfb2", + reputation: "1000", + tokens: "1000", + }, + { + address: "0x9c7f9f45a22ad3d667a5439f72b563df3aa70aae", + reputation: "1000", + tokens: "1000", + }, + { + address: "0xa2a064b3b22fc892dfb71923a6d844b953aa247c", + reputation: "1000", + tokens: "1000", + }, + { + address: "0xdeeaa92e025ca7fe34679b0b92cd4ffa162c8de8", + reputation: "1000", + tokens: "1000", + }, + { + address: "0x81cfdaf70273745a291a7cf9af801a4cffa87a95", + reputation: "1000", + tokens: "1000", + }, + { + address: "0x8ec400484deb5330bcd0bc005c13a557c5247727", + reputation: "1000", + tokens: "1000", + }, + ], + name: "Genesis Test", + schemes: [ + { + name: "SchemeRegistrar", + votingMachineParams: { + votingMachineName: "AbsoluteVote", + }, + }, + { + name: "GlobalConstraintRegistrar", + votingMachineParams: { + votingMachineName: "AbsoluteVote", + }, + }, + { + name: "UpgradeScheme", + votingMachineParams: { + votingMachineName: "AbsoluteVote", + }, + }, + { + name: "ContributionReward", + votingMachineParams: { + votingMachineName: "GenesisProtocol", + }, + }, + { + name: "GenesisProtocol", + }, + ], + tokenName: "Genesis Test", + tokenSymbol: "GDT", + }; + + await InitializeArcJs(); + + spec.founders = spec.founders.map((f: FounderSpec) => { + return { + address: f.address, + reputation: this.web3.toWei(f.reputation), + tokens: this.web3.toWei(f.tokens), + }; + }); + + console.log(`Genesis Test DAO with ${spec.founders.length} founders...`); + + const dao = await DAO.new(spec); + + console.log(`new DAO created at: ${dao.avatar.address}`); + console.log(`native token: ${dao.token.address}`); + + return Promise.resolve(); } } diff --git a/lib/utils.ts b/lib/utils.ts index 8443e62ac..cd3d1c17d 100644 --- a/lib/utils.ts +++ b/lib/utils.ts @@ -3,7 +3,6 @@ import { promisify } from "es6-promisify"; import abi = require("ethereumjs-abi"); import Contract = require("truffle-contract"); import { providers as Web3Providers, Web3 } from "web3"; -import { gasLimitsConfig } from "../gasLimits.js"; import { Address, Hash, SchemePermissions } from "./commonTypes"; import { ConfigService } from "./configService"; import { LoggingService } from "./loggingService"; @@ -33,7 +32,7 @@ export class Utils { contract.setNetwork(await Utils.getNetworkId()); contract.defaults({ from: await Utils.getDefaultAccount(), - gas: gasLimitsConfig.gasLimit_runtime, + gas: ConfigService.get("defaultGasLimit"), }); LoggingService.debug(`requireContract: loaded ${contractName}`); return contract; diff --git a/lib/utilsInternal.ts b/lib/utilsInternal.ts index ff6b3dcff..9710fe4e8 100644 --- a/lib/utilsInternal.ts +++ b/lib/utilsInternal.ts @@ -42,4 +42,16 @@ export class UtilsInternal { public static getWeb3Sync(): Web3 { return (Utils as any).web3; } + + /** + * Returns promise of the maximum gasLimit that we dare to ever use, given the + * current state of the chain. + */ + public static async computeMaxGasLimit(): Promise { + const web3 = await Utils.getWeb3(); + return promisify((callback: any) => web3.eth.getBlock("latest", false, callback))() + .then((block: any) => { + return block.gasLimit - 100000; + }); + } } diff --git a/lib/wrappers/daoCreator.ts b/lib/wrappers/daoCreator.ts index 19241af72..2bc4afb42 100644 --- a/lib/wrappers/daoCreator.ts +++ b/lib/wrappers/daoCreator.ts @@ -1,7 +1,6 @@ "use strict"; import * as BigNumber from "bignumber.js"; import { promisify } from "es6-promisify"; -import { computeForgeOrgGasLimit } from "../../gasLimits.js"; import { AvatarService } from "../avatarService"; import { Address, Hash, SchemePermissions } from "../commonTypes"; import { ConfigService } from "../configService"; @@ -99,7 +98,22 @@ export class DaoCreatorWrapper extends ContractWrapperBase { controllerAddress = 0; } - const totalGas = computeForgeOrgGasLimit(options.founders.length); + const paramsArray = [ + options.name, + options.tokenName, + options.tokenSymbol, + options.founders.map((founder: FounderConfig) => web3.toBigNumber(founder.address)), + options.founders.map((founder: FounderConfig) => web3.toBigNumber(founder.tokens)), + options.founders.map((founder: FounderConfig) => web3.toBigNumber(founder.reputation)), + controllerAddress, + options.tokenCap]; + + /** + * The default gas limit will be insufficient when using non-universal controller, + * so we do a proper estimate here. We're estimating even when universal since + * the value will be optimial for the user in any case. + */ + const totalGas = await this.estimateGas(this.contract.forgeOrg, paramsArray); this.logContractFunctionCall("DaoCreator.forgeOrg (options)", options); @@ -118,14 +132,7 @@ export class DaoCreatorWrapper extends ContractWrapperBase { return this.wrapTransactionInvocation("DaoCreator.forgeOrg", options, this.contract.forgeOrg, - [options.name, - options.tokenName, - options.tokenSymbol, - options.founders.map((founder: FounderConfig) => web3.toBigNumber(founder.address)), - options.founders.map((founder: FounderConfig) => web3.toBigNumber(founder.tokens)), - options.founders.map((founder: FounderConfig) => web3.toBigNumber(founder.reputation)), - controllerAddress, - options.tokenCap], + paramsArray, { gas: totalGas } ); } diff --git a/lib/wrappers/genesisProtocol.ts b/lib/wrappers/genesisProtocol.ts index 7879eb58e..dc5322b0f 100644 --- a/lib/wrappers/genesisProtocol.ts +++ b/lib/wrappers/genesisProtocol.ts @@ -1,7 +1,6 @@ "use strict"; import { BigNumber } from "bignumber.js"; import ethereumjs = require("ethereumjs-abi"); -import { gasLimitsConfig } from "../../gasLimits.js"; import { AvatarService } from "../avatarService"; import { Address, @@ -37,6 +36,7 @@ import { } from "./iIntVoteInterface"; import { promisify } from "es6-promisify"; +import { LoggingService } from "../loggingService"; import { UtilsInternal } from "../utilsInternal"; import { IntVoteInterfaceWrapper } from "./intVoteInterface"; import { StandardTokenFactory, StandardTokenWrapper } from "./standardToken"; @@ -953,7 +953,15 @@ export class GenesisProtocolFactoryType extends ContractWrapperFactory { - return super.new(stakingTokenAddress, { gas: gasLimitsConfig.gasLimit_arc }); + /** + * We always have to estimate gas here, regardless of the "estimateGas" config setting, + * because truffle's default gas limit does not suffice + */ + const estimate = await super.estimateConstructorGas(stakingTokenAddress); + + LoggingService.debug(`Instantiating GenesisProtocol with gas: ${estimate}`); + + return super.new(stakingTokenAddress, { gas: estimate }); } } diff --git a/package-scripts.js b/package-scripts.js index 120b18a43..0b934bb38 100644 --- a/package-scripts.js +++ b/package-scripts.js @@ -100,8 +100,6 @@ module.exports = { "nps test.build.clean", mkdirp(joinPath(pathArcTestBuild, "config")), copy(`${joinPath(".", "config", "**", "*")} ${joinPath(pathArcTestBuild, "config")}`), - copy(`${joinPath(".", "gasLimits.js")} ${pathArcTestBuild}`), - copy(`${joinPath(".", "arcConstants.js")} ${pathArcTestBuild}`), copy(`${joinPath(pathArcJsContracts, "**", "*")} ${joinPath(pathArcTestBuild, "migrated_contracts")}`), mkdirp(pathArcTestBuild), `node ${pathTypeScript} --outDir ${pathArcTestBuild} --project ${pathArcTest}` @@ -180,9 +178,7 @@ module.exports = { * the proper version of Arc sibling to the Arc.js package. */ fetchFromArc: series( - copy(`${joinPath(pathDaostackArcRepo, "build", "contracts", "*")} ${pathArcJsContracts}`), - // write Arc's gasLimit into a file where we can grab it when needed - `node ${joinPath(".", "package-scripts", "importArcGasLimit.js")}` + copy(`${joinPath(pathDaostackArcRepo, "build", "contracts", "*")} ${pathArcJsContracts}`) ), }, docs: { diff --git a/package-scripts/createGenesisDao.js b/package-scripts/createGenesisDao.js index 300940686..41ecd85f1 100644 --- a/package-scripts/createGenesisDao.js +++ b/package-scripts/createGenesisDao.js @@ -34,20 +34,8 @@ if (env.arcjs_providerConfig) { Utils.getWeb3() .then((web3) => { - const createGenesisDao = new GenesisDaoCreator(web3, env.arcjs_network || "ganache"); - - return createGenesisDao.forge(env.arcjs_foundersConfigurationLocation) - .then((daoCreationState) => { - return createGenesisDao.setSchemes(daoCreationState).then(() => { - console.log(`Successfully created ${daoCreationState.orgName}`); - exit(); - }) - .catch((ex) => { - console.log(`Error setting schemes: ${daoCreationState.orgName}: ${ex}`); - exit(); - }); - }) + return createGenesisDao.run() .catch((ex) => { console.log(`Error forging org: ${ex}`); exit(); diff --git a/package-scripts/importArcGasLimit.js b/package-scripts/importArcGasLimit.js deleted file mode 100644 index 50ebb9352..000000000 --- a/package-scripts/importArcGasLimit.js +++ /dev/null @@ -1,6 +0,0 @@ -const fs = require("fs-extra"); - -const arcPackage = require("../node_modules/@daostack/arc/package.json"); -const gasLimit = arcPackage.config.gasLimit; - -fs.writeFileSync("./arcConstants.js", `const ARC_GAS_LIMIT = ${gasLimit};\r\nmodule.exports = { ARC_GAS_LIMIT };\r\n`); diff --git a/package.json b/package.json index 512c97976..ec7443a2d 100644 --- a/package.json +++ b/package.json @@ -16,9 +16,7 @@ "config/", "package-scripts.js", "package-scripts/", - "truffle.js", - "gasLimits.js", - "arcConstants.js" + "truffle.js" ], "scripts": { "start": "nps", diff --git a/test/contributionReward.ts b/test/contributionReward.ts index c1ee360f6..904cb2af6 100644 --- a/test/contributionReward.ts +++ b/test/contributionReward.ts @@ -7,7 +7,6 @@ import { ArcTransactionProposalResult, DecodedLogEntryEvent } from "../lib/iCont import { Utils } from "../lib/utils"; -import { UtilsInternal } from "../lib/utilsInternal"; import { RedeemEventResult } from "../lib/wrappers/commonEventInterfaces"; diff --git a/test/dao.ts b/test/dao.ts index 0d32e22b7..fb178e833 100644 --- a/test/dao.ts +++ b/test/dao.ts @@ -21,6 +21,11 @@ describe("DAO", () => { reputation: web3.toWei(1000), tokens: web3.toWei(100), }, + { + address: accounts[1], + reputation: web3.toWei(1000), + tokens: web3.toWei(100), + }, ], name: "ArcJsTestDao", tokenName: "Tokens of ArcJsTestDao", diff --git a/test/helpers.ts b/test/helpers.ts index 85e0e2d86..d86943faa 100644 --- a/test/helpers.ts +++ b/test/helpers.ts @@ -50,7 +50,7 @@ export const SOME_ADDRESS = "0x1000000000000000000000000000000000000000"; /* tslint:disable-next-line:no-bitwise */ export const DefaultLogLevel = LogLevel.error | LogLevel.info; -LoggingService.logLevel = DefaultLogLevel; +ConfigService.set("logLevel", DefaultLogLevel); ConfigService.set("estimateGas", true); ConfigService.set("cacheContractWrappers", true);