Running OpenZeppelin Contracts Ethereum Package tests in 2.5.0 to validate extension to IndividuallyCappedCrowdsale

Hello Everyone,

First, thank you for all the hard work you’ve done for the crypto community!

I’m trying to validate v2.5.0 of crowdsale contracts in openzeppelin-contracts-ethereum-package. I am extending the IndividuallyCappedCrowdsale to have the same cap for every beneficiary. My plan was to copy the test covering IndividuallyCappedCrowdsale, and get that passing on its own, then modify to have a global cap.

I can’t get the tests for openzeppelin-contracts-ethereum-package to pass for a few versions, output shown below. Is there a recommended (passing build) version other than 2.5.0 or the older 2.2.3 (those seem to be the only ones published on npm)? Or maybe I just need to figure out where ContextMock needs to be included in the build? Is v2.5.0 really a broken build?

I run using: circleci local execute --job test

For v2.5.0 tag I have to modify circleci config to install deps before test, because local circleci doesn’t support workflows and I get:

====>> Unit tests
  #!/bin/bash -eo pipefail
npm run test

> @openzeppelin/contracts-ethereum-package@2.5.0 test /home/circleci/project
> mocha --exit --recursive test

/home/circleci/project/node_modules/mocha/node_modules/yargs/yargs.js:1163
      else throw err
           ^

Error: /home/circleci/project/build/contracts/ContextMock.json: ENOENT: no such file or directory, open '/home/circleci/project/build/contracts/ContextMock.json'
    at Object.openSync (fs.js:443:3)
    at Object.readFileSync (fs.js:343:35)
    at Object.readFileSync (/home/circleci/project/node_modules/jsonfile/index.js:61:22)
    at loadArtifact (/home/circleci/project/node_modules/@openzeppelin/contract-loader/lib/index.js:47:23)
    at TruffleLoader.BaseLoader.fromArtifact (/home/circleci/project/node_modules/@openzeppelin/contract-loader/lib/index.js:65:18)
    at Object.<anonymous> (/home/circleci/project/test/GSN/Context.behavior.js:5:30)
    at Module._compile (internal/modules/cjs/loader.js:778:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:789:10)
    at Module.load (internal/modules/cjs/loader.js:653:32)
    at tryModuleLoad (internal/modules/cjs/loader.js:593:12)
    at Function.Module._load (internal/modules/cjs/loader.js:585:3)
    at Module.require (internal/modules/cjs/loader.js:692:17)
    at require (internal/modules/cjs/helpers.js:25:18)
    at /home/circleci/project/node_modules/mocha/lib/mocha.js:311:36
    at Array.forEach (<anonymous>)
    at Mocha.loadFiles (/home/circleci/project/node_modules/mocha/lib/mocha.js:308:14)
    at Mocha.run (/home/circleci/project/node_modules/mocha/lib/mocha.js:849:10)
    at Object.exports.singleRun (/home/circleci/project/node_modules/mocha/lib/cli/run-helpers.js:108:16)
    at exports.runMocha (/home/circleci/project/node_modules/mocha/lib/cli/run-helpers.js:143:13)
    at Object.exports.handler.argv [as handler] (/home/circleci/project/node_modules/mocha/lib/cli/run.js:305:3)
    at Object.runCommand (/home/circleci/project/node_modules/mocha/node_modules/yargs/lib/command.js:242:26)
    at Object.parseArgs [as _parseArgs] (/home/circleci/project/node_modules/mocha/node_modules/yargs/yargs.js:1087:28)
    at Object.parse (/home/circleci/project/node_modules/mocha/node_modules/yargs/yargs.js:566:25)
    at Object.exports.main (/home/circleci/project/node_modules/mocha/lib/cli/cli.js:68:6)
    at Object.<anonymous> (/home/circleci/project/node_modules/mocha/bin/mocha:133:29)
    at Module._compile (internal/modules/cjs/loader.js:778:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:789:10)
    at Module.load (internal/modules/cjs/loader.js:653:32)
    at tryModuleLoad (internal/modules/cjs/loader.js:593:12)
    at Function.Module._load (internal/modules/cjs/loader.js:585:3)
    at Function.Module.runMain (internal/modules/cjs/loader.js:831:12)
    at startup (internal/bootstrap/node.js:283:19)
    at bootstrapNodeJSCore (internal/bootstrap/node.js:623:3)
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! @openzeppelin/contracts-ethereum-package@2.5.0 test: `mocha --exit --recursive test`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the @openzeppelin/contracts-ethereum-package@2.5.0 test script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

npm ERR! A complete log of this run can be found in:
npm ERR!     /home/circleci/.npm/_logs/2020-09-14T19_43_32_023Z-debug.log
Error:
Exited with code exit status 1

Step failed
Error: runner failed (exited with 101)
Task failed
Error: task failed

I tried testing the latest commit touching the crowdsale folder (6e901efa), but got some errors as well.

For 6e901efa224dbeafa6df18d4e9c55c16889cb8f3 (with node 8) I get:

2200 passing (14m)
2 pending
32 failing

  1) Contract: TokenVesting
       reverts with a duration shorter than the cliff:
     AssertionError: Expected an exception but none was received
      at expectException (node_modules/openzeppelin-test-helpers/src/expectRevert.js:23:10)
      at <anonymous>
      at process._tickCallback (internal/process/next_tick.js:189:7)

  2) Contract: TokenVesting
       reverts with a null beneficiary:
     AssertionError: Expected an exception but none was received
      at expectException (node_modules/openzeppelin-test-helpers/src/expectRevert.js:23:10)
      at <anonymous>
      at process._tickCallback (internal/process/next_tick.js:189:7)

  3) Contract: TokenVesting
       reverts with a null duration:
     AssertionError: Expected an exception but none was received
      at expectException (node_modules/openzeppelin-test-helpers/src/expectRevert.js:23:10)
      at <anonymous>
      at process._tickCallback (internal/process/next_tick.js:189:7)

  4) Contract: TokenVesting
       reverts if the end time is in the past:
     AssertionError: Expected an exception but none was received
      at expectException (node_modules/openzeppelin-test-helpers/src/expectRevert.js:23:10)
      at <anonymous>
      at process._tickCallback (internal/process/next_tick.js:189:7)

  5) Contract: TokenVesting
       once deployed
         "before each" hook for "can get state":
     Error: Returned error: VM Exception while processing transaction: revert MinterRole: caller does not have the Minter role -- Reason given: MinterRole: caller does not have the Minter role.
     at PromiEvent (node_modules/truffle/build/webpack:/packages/contract/lib/promievent.js:6:1)
      at TruffleContract.mint (node_modules/truffle/build/webpack:/packages/contract/lib/execute.js:157:1)
      at Context.<anonymous> (test/drafts/TokenVesting.test.js:61:24)
      at <anonymous>
      at process._tickCallback (internal/process/next_tick.js:189:7)

  6) Contract: SimpleToken
       has a name:

      AssertionError: expected '' to equal 'SimpleToken'
      + expected - actual

      +SimpleToken
      
      at Context.<anonymous> (test/examples/SimpleToken.test.js:14:40)
      at <anonymous>
      at process._tickCallback (internal/process/next_tick.js:189:7)

  7) Contract: SimpleToken
       has a symbol:

      AssertionError: expected '' to equal 'SIM'
      + expected - actual

      +SIM
      
      at Context.<anonymous> (test/examples/SimpleToken.test.js:18:42)
      at <anonymous>
      at process._tickCallback (internal/process/next_tick.js:189:7)

  8) Contract: SimpleToken
       has 18 decimals:

      AssertionError: expected '0' to equal '18'
      + expected - actual

      -0
      +18
      
      at Context.<anonymous> (test/examples/SimpleToken.test.js:22:57)
      at <anonymous>
      at process._tickCallback (internal/process/next_tick.js:189:7)

  9) Contract: SimpleToken
       assigns the initial total supply to the creator:

      No 'Transfer' events found
      + expected - actual

      -false
      +true
      
      at inLogs (node_modules/openzeppelin-test-helpers/src/expectEvent.js:6:32)
      at inTransaction (node_modules/openzeppelin-test-helpers/src/expectEvent.js:35:10)
      at <anonymous>
      at process._tickCallback (internal/process/next_tick.js:189:7)

  10) Contract: GSNRecipientERC20Fee
       "before each" hook for "has a name":
     Error: Returned error: VM Exception while processing transaction: out of gas
     at PromiEvent (node_modules/truffle/build/webpack:/packages/contract/lib/promievent.js:6:1)
      at /home/circleci/project/node_modules/truffle/build/webpack:/packages/contract/lib/execute.js:211:1
      at Function.new (node_modules/truffle/build/webpack:/packages/contract/lib/contract/constructorMethods.js:33:1)
      at Context.<anonymous> (test/GSN/GSNRecipientERC20Fee.test.js:15:56)
      at web3.eth.getBlockNumber.then.result (node_modules/truffle/build/webpack:/packages/core/lib/testing/testrunner.js:153:1)
      at <anonymous>
      at process._tickCallback (internal/process/next_tick.js:189:7)

  11) Contract: Ownable
       cannot be reinitialized:
     TypeError: Cannot read property 'reverting' of undefined
      at Context.<anonymous> (test/ownership/Ownable.test.js:12:22)
      at <anonymous>
      at process._tickCallback (internal/process/next_tick.js:189:7)

  12) Contract: RefundEscrow
       requires a non-null beneficiary:
     AssertionError: Expected an exception but none was received
      at expectException (node_modules/openzeppelin-test-helpers/src/expectRevert.js:23:10)
      at <anonymous>
      at process._tickCallback (internal/process/next_tick.js:189:7)

  13) Contract: RefundEscrow
       once deployed
         only the primary account can enter closed state:
     Error: Returned error: VM Exception while processing transaction: revert Secondary: caller is not the primary account -- Reason given: Secondary: caller is not the primary account.
     at PromiEvent (node_modules/truffle/build/webpack:/packages/contract/lib/promievent.js:6:1)
      at TruffleContract.close (node_modules/truffle/build/webpack:/packages/contract/lib/execute.js:157:1)
      at Context.<anonymous> (test/payment/escrow/RefundEscrow.test.js:55:42)
      at <anonymous>
      at process._tickCallback (internal/process/next_tick.js:189:7)

  14) Contract: RefundEscrow
       once deployed
         only the primary account can enter refund state:
     Error: Returned error: VM Exception while processing transaction: revert Secondary: caller is not the primary account -- Reason given: Secondary: caller is not the primary account.
     at PromiEvent (node_modules/truffle/build/webpack:/packages/contract/lib/promievent.js:6:1)
      at TruffleContract.enableRefunds (node_modules/truffle/build/webpack:/packages/contract/lib/execute.js:157:1)
      at Context.<anonymous> (test/payment/escrow/RefundEscrow.test.js:102:42)
      at <anonymous>
      at process._tickCallback (internal/process/next_tick.js:189:7)

  15) Contract: RefundEscrow
       once deployed
         active state
           has beneficiary and state:

      AssertionError: expected '0x0000000000000000000000000000000000000000' to equal '0x9E1Ef1eC212F5DFfB41d35d9E5c14054F26c6560'
      + expected - actual

      -0x0000000000000000000000000000000000000000
      +0x9E1Ef1eC212F5DFfB41d35d9E5c14054F26c6560
      
      at Context.<anonymous> (test/payment/escrow/RefundEscrow.test.js:25:52)
      at <anonymous>
      at process._tickCallback (internal/process/next_tick.js:189:7)

  16) Contract: RefundEscrow
       once deployed
         active state
           accepts deposits:
     Error: Returned error: VM Exception while processing transaction: revert Secondary: caller is not the primary account -- Reason given: Secondary: caller is not the primary account.
     at PromiEvent (node_modules/truffle/build/webpack:/packages/contract/lib/promievent.js:6:1)
      at TruffleContract.deposit (node_modules/truffle/build/webpack:/packages/contract/lib/execute.js:157:1)
      at Context.<anonymous> (test/payment/escrow/RefundEscrow.test.js:30:27)

  17) Contract: RefundEscrow
       once deployed
         active state
           does not refund refundees:
     Error: Returned error: VM Exception while processing transaction: revert Secondary: caller is not the primary account -- Reason given: Secondary: caller is not the primary account.
     at PromiEvent (node_modules/truffle/build/webpack:/packages/contract/lib/promievent.js:6:1)
      at TruffleContract.deposit (node_modules/truffle/build/webpack:/packages/contract/lib/execute.js:157:1)
      at Context.<anonymous> (test/payment/escrow/RefundEscrow.test.js:36:27)

  18) Contract: RefundEscrow
       once deployed
         active state
           does not allow beneficiary withdrawal:
     Error: Returned error: VM Exception while processing transaction: revert Secondary: caller is not the primary account -- Reason given: Secondary: caller is not the primary account.
     at PromiEvent (node_modules/truffle/build/webpack:/packages/contract/lib/promievent.js:6:1)
      at TruffleContract.deposit (node_modules/truffle/build/webpack:/packages/contract/lib/execute.js:157:1)
      at Context.<anonymous> (test/payment/escrow/RefundEscrow.test.js:43:27)

  19) Contract: RefundEscrow
       once deployed
         closed state
           "before each" hook for "rejects deposits":
     Error: Returned error: VM Exception while processing transaction: revert Secondary: caller is not the primary account -- Reason given: Secondary: caller is not the primary account.
     at PromiEvent (node_modules/truffle/build/webpack:/packages/contract/lib/promievent.js:6:1)
      at TruffleContract.deposit (node_modules/truffle/build/webpack:/packages/contract/lib/execute.js:157:1)
      at Promise.all.refundees.map.refundee (test/payment/escrow/RefundEscrow.test.js:61:65)
      at Array.map (<anonymous>)
      at Context.<anonymous> (test/payment/escrow/RefundEscrow.test.js:61:37)

  20) Contract: RefundEscrow
       once deployed
         refund state
           "before each" hook for "rejects deposits":
     Error: Returned error: VM Exception while processing transaction: revert Secondary: caller is not the primary account -- Reason given: Secondary: caller is not the primary account.
     at PromiEvent (node_modules/truffle/build/webpack:/packages/contract/lib/promievent.js:6:1)
      at TruffleContract.deposit (node_modules/truffle/build/webpack:/packages/contract/lib/execute.js:157:1)
      at Promise.all.refundees.map.refundee (test/payment/escrow/RefundEscrow.test.js:108:65)
      at Array.map (<anonymous>)
      at Context.<anonymous> (test/payment/escrow/RefundEscrow.test.js:108:37)

  21) Contract: PaymentSplitter
       rejects an empty set of payees:
     AssertionError: Expected an exception but none was received
      at expectException (node_modules/openzeppelin-test-helpers/src/expectRevert.js:23:10)
      at <anonymous>
      at process._tickCallback (internal/process/next_tick.js:189:7)

  22) Contract: PaymentSplitter
       rejects more payees than shares:
     AssertionError: Expected an exception but none was received
      at expectException (node_modules/openzeppelin-test-helpers/src/expectRevert.js:23:10)
      at <anonymous>
      at process._tickCallback (internal/process/next_tick.js:189:7)

  23) Contract: PaymentSplitter
       rejects more shares than payees:
     AssertionError: Expected an exception but none was received
      at expectException (node_modules/openzeppelin-test-helpers/src/expectRevert.js:23:10)
      at <anonymous>
      at process._tickCallback (internal/process/next_tick.js:189:7)

  24) Contract: PaymentSplitter
       rejects null payees:
     AssertionError: Expected an exception but none was received
      at expectException (node_modules/openzeppelin-test-helpers/src/expectRevert.js:23:10)
      at <anonymous>
      at process._tickCallback (internal/process/next_tick.js:189:7)

  25) Contract: PaymentSplitter
       rejects zero-valued shares:
     AssertionError: Expected an exception but none was received
      at expectException (node_modules/openzeppelin-test-helpers/src/expectRevert.js:23:10)
      at <anonymous>
      at process._tickCallback (internal/process/next_tick.js:189:7)

  26) Contract: PaymentSplitter
       rejects repeated payees:
     AssertionError: Expected an exception but none was received
      at expectException (node_modules/openzeppelin-test-helpers/src/expectRevert.js:23:10)
      at <anonymous>
      at process._tickCallback (internal/process/next_tick.js:189:7)

  27) Contract: PaymentSplitter
       once deployed
         should have total shares:

      AssertionError: expected '0' to equal '100'
      + expected - actual

      -0
      +100
      
      at Context.<anonymous> (test/payment/PaymentSplitter.test.js:54:65)
      at <anonymous>
      at process._tickCallback (internal/process/next_tick.js:189:7)

  28) Contract: PaymentSplitter
       once deployed
         should have payees:
     Error: Returned error: VM Exception while processing transaction: invalid opcode
     at PromiEvent (node_modules/truffle/build/webpack:/packages/contract/lib/promievent.js:6:1)
      at TruffleContract.payee (node_modules/truffle/build/webpack:/packages/contract/lib/execute.js:108:1)
      at Promise.all.payees.map (test/payment/PaymentSplitter.test.js:59:36)
      at Array.map (<anonymous>)
      at Context.<anonymous> (test/payment/PaymentSplitter.test.js:58:37)
      at <anonymous>
      at process._tickCallback (internal/process/next_tick.js:189:7)

  29) Contract: PaymentSplitter
       once deployed
         should store shares if address is payee:

      AssertionError: expected '0' to be different from '0'
      + expected - actual


      at Context.<anonymous> (test/payment/PaymentSplitter.test.js:71:70)
      at <anonymous>
      at process._tickCallback (internal/process/next_tick.js:189:7)

  30) Contract: PaymentSplitter
       once deployed
         should throw if no funds to claim:

      Wrong kind of exception received
      + expected - actual

      -PaymentSplitter: account has no shares -- Reason given: PaymentSplitter: account has no shares.
      +PaymentSplitter: account is not due payment
      
      at expectException (node_modules/openzeppelin-test-helpers/src/expectRevert.js:18:30)
      at <anonymous>
      at process._tickCallback (internal/process/next_tick.js:189:7)

  31) Contract: PaymentSplitter
       once deployed
         should distribute funds to payees:
     Error: Returned error: VM Exception while processing transaction: revert PaymentSplitter: account has no shares -- Reason given: PaymentSplitter: account has no shares.
     at PromiEvent (node_modules/truffle/build/webpack:/packages/contract/lib/promievent.js:6:1)
      at TruffleContract.release (node_modules/truffle/build/webpack:/packages/contract/lib/execute.js:157:1)
      at Context.<anonymous> (test/payment/PaymentSplitter.test.js:101:51)
      at <anonymous>
      at process._tickCallback (internal/process/next_tick.js:189:7)

  32) Contract: StandaloneERC20
       with all arguments
         reverts if initial balance is zero:
     TypeError: Cannot read property 'reverting' of undefined
      at Context.<anonymous> (test/token/ERC20/StandaloneERC20.test.js:39:24)



npm ERR! code ELIFECYCLE
npm ERR! errno 32
npm ERR! @openzeppelin/contracts-ethereum-package@2.4.0 test: `scripts/test.sh`
npm ERR! Exit status 32
npm ERR! 
npm ERR! Failed at the @openzeppelin/contracts-ethereum-package@2.4.0 test script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

npm ERR! A complete log of this run can be found in:
npm ERR!     /home/circleci/.npm/_logs/2020-09-14T17_52_01_826Z-debug.log
Error: 
Exited with code exit status 32

Step failed
Error: runner failed (exited with 101)
Task failed
Error: task failed
1 Like

Hi @dboom,

Welcome to the community :wave:

I did the following to get the test running with OpenZeppelin Contracts Ethereum Package 2.5.0:

$ git clone https://github.com/OpenZeppelin/openzeppelin-contracts-ethereum-package.git
$ cd openzeppelin-contracts-ethereum-package/

Changed to the 2.5.0 tag then installed the dependencies

$ npm install

Removed the build directory (I tried to test without compiling first and got a similar error about ContextMock)

$ rm -rf build

Compiled

$ npm run compile

Then ran the tests

$ npm run test
...
  2313 passing (17m)
  2 pending

In your own project you can install the upgrade safe fork

npm i @openzeppelin/contracts-ethereum-package@2.5.0

You can then extend the crowdsale and add to your tests using the OpenZeppelin Contracts tests as a basis.


As an aside, I assume that you want to create an upgradeable crowdsale. You will likely need to communicate to your users that you have the ability to upgrade the crowdsale.

We recently released OpenZeppelin Upgrades Plugins for Truffle and Buidler that you could use to deploy and test your upgradeable contracts: https://docs.openzeppelin.com/upgrades-plugins/1.x/

Hi @dboom,

I wanted to check if the above answered your question?