4

I have an extended ERC20 contract with ERC827 functions, which are overrides of ERC20 with an extra callback parameter.

I have these two pairs of base/override functions:

Base:

    function approve(address _spender, uint _value) public returns (bool success) {
        allowed[msg.sender][_spender] = _value;
        Approval(msg.sender, _spender, _value);
        return true;
    }

Override:

    function approve(address _spender, uint _value, bytes _data) public returns (bool) {
        require(_spender != address(this));
        super.approve(_spender, _value);
        require(_spender.call(_data));
        return true;
}

Base:

    function increaseApproval(address _spender, uint _addedValue) public returns (bool) {
        allowed[msg.sender][_spender] = allowed[msg.sender][_spender].add(_addedValue);
        Approval(msg.sender, _spender, allowed[msg.sender][_spender]);
        return true;
    }

Override:

    function increaseApproval(address _spender, uint _addedValue, bytes _data) public returns (bool) {
        require(_spender != address(this));
        super.increaseApproval(_spender, _addedValue);
        require(_spender.call(_data));
        return true;
    }

Unit test:

    it ("Test increasing allowance", async () => {
        // First, transfer 1000 coins from owner to user1
        await instance.transfer(user1Address, 1000, {from: ownerAddress});
        // Allow owner to spend 420 tokens from user1 balance
        await instance.approve(ownerAddress, 420, { from: user1Address });
        // Now increase that approval by 47 tokens
        // THE ERROR HAPPENS AT THIS LINE
        await instance.increaseApproval(ownerAddress, 47, { from: user1Address });
        // Check owner's allowance for spending user1's tokens - should be 467
        const allowance = instance.allowance(user1Address, ownerAddress);

        assert.equal(allowance, 467);
    });

When in unint test I make a call to approve with two arguments, it works fine, but when I make a call to increaseApproval with two arguments, it throws the following error:

Error: Invalid number of arguments to Solidity function at Object.InvalidNumberOfSolidityArgs (/Users/user/.local/share/npm/lib/node_modules/truffle/build/webpack:/~/web3/lib/web3/errors.js:25:1) at SolidityFunction.validateArgs (/Users/user/.local/share/npm/lib/node_modules/truffle/build/webpack:/~/web3/lib/web3/function.js:74:1) at SolidityFunction.toPayload (/Users/user/.local/share/npm/lib/node_modules/truffle/build/webpack:/~/web3/lib/web3/function.js:90:1) at SolidityFunction.sendTransaction (/Users/user/.local/share/npm/lib/node_modules/truffle/build/webpack:/~/web3/lib/web3/function.js:163:1) at SolidityFunction.execute (/Users/user/.local/share/npm/lib/node_modules/truffle/build/webpack:/~/web3/lib/web3/function.js:256:1) at /Users/user/.local/share/npm/lib/node_modules/truffle/build/webpack:/~/truffle-contract/contract.js:202:1 at /Users/user/.local/share/npm/lib/node_modules/truffle/build/webpack:/~/truffle-contract/contract.js:155:1 at process._tickCallback (internal/process/next_tick.js:109:7)

But if I call it with three arguments (as in its override) it works fine.

Any ideas why approve can be called as the base function (with 2 arguments) but increaseApproval fails with two arguments and wants three (as in the override)

The actual code is here: https://github.com/path-foundation/path-token/blob/master/contracts/PathToken.sol

And the unit tests are here: https://github.com/path-foundation/path-token/blob/master/test/TestPathToken.js

  • Can you add your unit-testing code? – Roman Frolov Feb 25 '18 at 3:13
  • @RomanFrolov - added. Thank you for taking a look, Roman! – Andrey Feb 25 '18 at 3:16
  • Does it work if you reomve { from: user1Address }? It could the that library is getting confused with the options parameter. – ivicaa Feb 25 '18 at 5:34
  • @ivicaa - still doesn't work – Andrey Feb 26 '18 at 5:01
0

I'm also getting this using Open Zeppelin's ERC721BasicToken.sol

There are:

function safeTransferFrom(address _from, address _to, uint256 _tokenId) public canTransfer(_tokenId) { safeTransferFrom(_from, _to, _tokenId, ""); } And

function safeTransferFrom(address _from, address _to, uint256 _tokenId, bytes _data) public canTransfer(_tokenId) { transferFrom(_from, _to, _tokenId); require(checkAndCallSafeTransfer(_from, _to, _tokenId, _data)); } This call fails:

const tokenId = await sampleNFT.safeTransferFrom.call(alice, composable.address, 1, 1); With this error:

Contract: Composable should safeTransferFrom: Error: Invalid number of arguments to Solidity function

  • Not enough room at add as a comment, sorry no answer found yet. – mattdlockyer Apr 27 '18 at 14:20
  • 2
    Hey Matt :) So the issue is - truffle is using an older version of web3 (<1.0) which doesn't support function overrides. Truffle guys told me it will be fixed in the next major version update but they have no ETA as web3 v 1.0 breaks a lot of things. – Andrey Apr 27 '18 at 14:32
  • One way to overcome that in the mean time is to always invoke the override function, and pass 0x0 for the data argument. – Andrey Apr 27 '18 at 14:33

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.