diff --git a/.changeset/gentle-clocks-beam.md b/.changeset/gentle-clocks-beam.md new file mode 100644 index 000000000..2cb7ebef0 --- /dev/null +++ b/.changeset/gentle-clocks-beam.md @@ -0,0 +1,5 @@ +--- +'@celo/celocli': patch +--- + +Fix not being able to submit governance proposals due to mishandling of 10K minimum deposit diff --git a/packages/cli/exampleProposal.json b/packages/cli/exampleProposal.json new file mode 100644 index 000000000..fe51488c7 --- /dev/null +++ b/packages/cli/exampleProposal.json @@ -0,0 +1 @@ +[] diff --git a/packages/cli/src/commands/governance/propose.test.ts b/packages/cli/src/commands/governance/propose.test.ts new file mode 100644 index 000000000..fbed2aeef --- /dev/null +++ b/packages/cli/src/commands/governance/propose.test.ts @@ -0,0 +1,79 @@ +import { Address } from '@celo/connect' +import { newKitFromWeb3 } from '@celo/contractkit' +import { NetworkConfig, testWithGanache } from '@celo/dev-utils/lib/ganache-test' +import { ux } from '@oclif/core' +import Web3 from 'web3' +import { testLocally } from '../../test-utils/cliUtils' +import Propose from './propose' +process.env.NO_SYNCCHECK = 'true' + +const expConfig = NetworkConfig.governance + +testWithGanache('governance:propose cmd', (web3: Web3) => { + const minDeposit = web3.utils.toWei(expConfig.minDeposit.toString(), 'ether') + const kit = newKitFromWeb3(web3) + + let accounts: Address[] = [] + + beforeEach(async () => { + accounts = await web3.eth.getAccounts() + kit.defaultAccount = accounts[0] + }) + test('fails when descriptionURl is missing', async () => { + await expect( + testLocally(Propose, [ + '--from', + accounts[0], + '--deposit', + '0', + '--jsonTransactions', + './exampleProposal.json', + ]) + ).rejects.toThrow('Missing required flag descriptionURL') + }) + test('can submit empty proposal', async () => { + await testLocally(Propose, [ + '--from', + accounts[0], + '--deposit', + minDeposit, + '--jsonTransactions', + './exampleProposal.json', + '--descriptionURL', + 'https://example.com', + ]) + }) + test('can submit proposal using e notion for deposit', async () => { + const spyStart = jest.spyOn(ux.action, 'start') + const spyStop = jest.spyOn(ux.action, 'stop') + await testLocally(Propose, [ + '--from', + accounts[0], + '--deposit', + '10000e18', + '--jsonTransactions', + './exampleProposal.json', + '--descriptionURL', + 'https://example.com', + ]) + expect(spyStart).toHaveBeenCalledWith('Sending Transaction: proposeTx') + expect(spyStop).toHaveBeenCalled() + }) + test('when deposit is 10K it succeeds', async () => { + const spyStart = jest.spyOn(ux.action, 'start') + const spyStop = jest.spyOn(ux.action, 'stop') + + await testLocally(Propose, [ + '--from', + accounts[0], + '--deposit', + '10000000000000000000000', + '--jsonTransactions', + './exampleProposal.json', + '--descriptionURL', + 'https://example.com', + ]) + expect(spyStart).toHaveBeenCalledWith('Sending Transaction: proposeTx') + expect(spyStop).toHaveBeenCalled() + }) +}) diff --git a/packages/cli/src/commands/governance/propose.ts b/packages/cli/src/commands/governance/propose.ts index bc4b406ae..210fe1023 100644 --- a/packages/cli/src/commands/governance/propose.ts +++ b/packages/cli/src/commands/governance/propose.ts @@ -20,7 +20,10 @@ export default class Propose extends BaseCommand { required: true, description: 'Path to json transactions', }), - deposit: Flags.string({ required: true, description: 'Amount of Gold to attach to proposal' }), + deposit: Flags.string({ + required: true, + description: 'Amount of Celo to attach to proposal', + }), from: CustomFlags.address({ required: true, description: "Proposer's address" }), force: Flags.boolean({ description: 'Skip execution check', default: false }), descriptionURL: Flags.string({ @@ -88,7 +91,7 @@ export default class Propose extends BaseCommand { await displaySendTx( 'proposeTx', governance.propose(proposal, res.flags.descriptionURL), - { value: deposit.toString() }, + { value: deposit.toFixed() }, 'ProposalQueued' ) }