Can't "initialize" in tests

Consider the following contract and respective test

pragma solidity ^0.5.0;
import "zos-lib/contracts/Initializable.sol";
import "openzeppelin-eth/contracts/ownership/Ownable.sol";
contract Whitelist is Ownable {
    mapping(address => bool) internal governors;
    function initialize(address _owner) public initializer {
        Ownable.initialize(_owner);
        governors[_owner] = true;
    }
    function isGovernor(address _userAddress) public view returns (bool)
    {
        return governors[_userAddress];
    }
}

.

const { TestHelper } = require('zos');
const { Contracts, ZWeb3 } = require('zos-lib');

ZWeb3.initialize(web3.currentProvider);

const Whitelist = Contracts.getFromLocal('Whitelist');

require('chai').should();

contract('Sample', (accounts) => {
    const owner = accounts[0];
    const governor = accounts[2];

    beforeEach(async () => {
        this.project = await TestHelper();
    });

    it('should create a proxy', async () => {
        const proxy = await this.project.createProxy(Whitelist);
        await proxy.methods.initialize(owner).send({ from: owner });
        const result = await proxy.methods.isGovernor(owner).call();
        console.log(result);
    });

    it('should create a proxy', async () => {
        const proxy = await this.project.createProxy(Whitelist);
        const result = await proxy.methods.isGovernor(owner).call();
        console.log(result);
    });
});

Running these tests I get an “Error: Returned error: VM Exception while processing transaction: revert” for the first test. What makes it happen is actually the “_owner = sender;” in “initialize” function in “Ownable”. If I comment that line it works. This is my first question, can anyone help me, please?

My second question is related to the “createProxy” method. If I try to initialize in the create proxy like

const proxy = await this.project.createProxy(Sample, {
  initMethod: 'initialize',
  initArgs: [42]
});

as shown here https://docs.zeppelinos.org/docs/testing.html, it also throws.
Does anyone know the reason?

Thank you so much.

As for your first question, I have tested in the Remix, it looks like everything is in order, I can deploy the contract, and call the function initialize(address).

Thanks, but the test doesn’t work

Hello once again,

Today, following this tutorial https://docs.zeppelinos.org/docs/zos_lib.html I’m having problems at const proxy = await project.createProxy(MyContractV0, { initArgs: [42] }) step where I get a

Creating an upgradeable instance of V0...
Error: Returned error: VM Exception while processing transaction: out of gas
at Object.ErrorResponse (some-path/node_modules/web3-core-helpers/src/errors.js:29:16)
at some-path/node_modules/web3-core-requestmanager/src/index.js:140:36
at some-path/node_modules/truffle/build/webpack:/packages/truffle-provider/wrapper.js:112:1
at XMLHttpRequest.request.onreadystatechange (some-path/node_modules/truffle/build/webpack:/~/web3/~/web3-providers-http/src/index.js:
96:1)
at XMLHttpRequestEventTarget.dispatchEvent (some-path/node_modules/truffle/build/webpack:/~/xhr2-cookies/dist/xml-http-request-event-t
arget.js:34:1)
at XMLHttpRequest._setReadyState (some-path/node_modules/truffle/build/webpack:/~/xhr2-cookies/dist/xml-http-request.js:208:1)
at XMLHttpRequest._onHttpResponseEnd (some-path/node_modules/truffle/build/webpack:/~/xhr2-cookies/dist/xml-http-request.js:318:1)
at IncomingMessage.<anonymous> (some-path/node_modules/truffle/build/webpack:/~/xhr2-cookies/dist/xml-http-request.js:289:47)
at IncomingMessage.emit (events.js:187:15)
at endReadableNT (_stream_readable.js:1094:12)
at process._tickCallback (internal/process/next_tick.js:63:19)
Truffle v5.0.13 (core: 5.0.13)
Node v10.12.0

Can anybody help? Is it a known problem? Is there any workaround? Ive tried to do something like await proxy.methods.initialize(42) but then the value is zero.

Cheers.

Hello,

quick solution was

const proxy = await project.createProxy(MyContractV0/* , { initMethod: 'initialize', initArgs: ['42'] } */);
await proxy.methods.initialize(42).send({ from: userAddress });
1 Like

Although it does not work with Ownable.

So, I have a contract with the following method and when calling it from tests it always reverts. Althoug, if I remove the initializer modifier, it works well. Can anyone help me?

function initialize(address sender) public initializer {
    Ownable.initialize(sender);
    governors[sender] = true;
}

Can you share the code you are using for tests, and the line where it fails? Also: does it revert, or run out of gas?

Sure, I’m following ZOS documentation https://docs.zeppelinos.org/docs/testing.html
and when trying to initialize using this.project.createProxy it reverts, and if I do only this.project.createProxy(Sample); and then I use proxy.methods.initialize(myValue).call({from:user}); it kinda works. Kinda meaning that, it does if it does not have the initializer modifier.
Since you asked, here’s the code

beforeEach(async () => {
    this.project = await TestHelper();
});

describe('Governors', () => {
    beforeEach(async () => {
        whitelist = await this.project.createProxy(Whitelist);
        await whitelist.methods.initialize(owner).send({ from: owner });
    });
(...)

So, this actually works, if the initialize method in Whitelist is not an initializer. Another alternative was to comment the line owner = _owner in Ownable.sol in initialize method.
So, I think that it might happen when an initializer calls another initializer and tries to set a variable value.

Any idea?

Hello @obernardovieira! This is kind of a wild guess, but maybe the problem is that your initialize() function is overloaded and the test doesn't know which one to pick? (Or is picking the wrong one) IE: there is an initialize() in Ownable.sol and there is an initialize() in Whitelist, but maybe the test is calling the Ownable initialize() but not Whitelist? Again, wild guess.

I just wrote up a little mini-tip regarding testing for overloaded functions. I haven't tried it in the context of zos testing yet, but it works for truffle-contract based tests. Maybe have a look?

1 Like

HI @Dennison, thanks. Actually I forgot that, so it could have been one problem. But now that I fixed, I have a Error: The contract code couldn't be stored, please check your gas limit., and I think I’ve found the reason.
Since it’s too hard to explain, I’ll try to create a quick repository with some example code (I can’t shared the original one), as I’ll be offline for the next five days.

1 Like

Hello, I’ve found a few interesting things. The first one, might be a mistake of mine, but still, it was what make the above error to happen.
Basically, I have a contract tree like this Base > Governance > Final (not the real names) and then I have an interface IFinal, with wich I was doing contract Base is IFinal. I think I should be doing it in final, right? That was my falt.

The second thing, which gave me a new error was the use of require(_fee <= FixidityLib.fixed1(), "Above 1.");.
Well, FixidityLib (which was published btw), is a set of two libraries, and in this case I’m calling on of them. This line above gave this error TypeError: Cannot read property 'match' of undefined.

So, how should I call a library?

If fixidity is set up so that a library calls another, and both have public or external methods, then that could be the case. We have a pending issue to support transitive solidity libraries in zOS.

1 Like