solidity-coverage: solc 0.4.17 compile errors for pure functions

With the truffle 4 beta 2 release which includes the solc@0.4.17 upgrade instrumented contracts containing functions decorated with view will generate a Warning, while those marked as pure will Error with

TypeError: Function declared as pure, but this expression (potentially) reads from the environment or state and thus requires "view".

This is due to the SC instrumented function containing events (which modify state) being present in the pure function.

About this issue

  • Original URL
  • State: closed
  • Created 7 years ago
  • Reactions: 3
  • Comments: 22 (15 by maintainers)

Commits related to this issue

Most upvoted comments

I seem to be facing the same issue with 0.5.8.

/project/coverageEnv/contracts/MyContract.sol:237:5: TypeError: Overriding function changes state mutability from "view" to "nonpayable".
    function allowance(address owner, address spender) public  returns (uint256) {emit __FunctionCoverageMyContract('/project/coverageEnv/contracts/MyContract.sol',12);
    ^ (Relevant source part starts here and spans across multiple lines).
openzeppelin-zos/contracts/token/ERC20/ERC20.sol:11:3: Overriden function is here:
  function allowance(address owner, address spender) public view returns (uint256);
  ^-------------------------------------------------------------------------------^

MyContract.sol inherits from openzeppelin-zos/contracts/token/ERC20/ERC20.sol and implments the allowance function with the same signature.

function allowance(address owner, address spender) public view returns (uint256) {
     // IMPL     
 }

Thanks @cgewecke Compilation failed for me in the following scenario: Contract inhering from another which lives outside the /contracts folder, e.g. a git submodule library for me specifically it looks like this:

/contracts/Token.sol
/lib/dappsys/erc20.sol

This generates compile error:

/coverageEnv/contracts/Token.sol:25:5: TypeError: Overriding function changes state mutability from "view" to "nonpayable".
    function totalSupply() public returns (uint256) {__FunctionCoverageToken('/contracts/Token.sol',1);
    ^
Spanning multiple lines.
/coverageEnv/lib/dappsys/erc20.sol:23:5: Overriden function is here:
    function totalSupply() public view returns (uint supply);
    ^-------------------------------------------------------^

I still have this issue on 0.5.7.

I have a tokenURI() function that override OpenZeppeline’s ERC721Token.sol:

function tokenURI(uint256 _tokenId) public view returns (string) {
    require(exists(_tokenId), "Token ID not exists.");
    ... // my own logic
}

Then I got this error:

,/Users/fur/Projects/Block42/landpot-dapp/coverageEnv/contracts/Land.sol:379:3: TypeError: Overriding function changes state mutability from "view" to "nonpayable".
  function tokenURI(uint256 _tokenId) public  returns (string) {emit __FunctionCoverageLand('/Users/fur/Projects/Block42/landpot-dapp/contracts/Land.sol',20);
  ^ (Relevant source part starts here and spans across multiple lines).
openzeppelin-solidity/contracts/token/ERC721/ERC721.sol:31:3: Overriden function is here:
  function tokenURI(uint256 _tokenId) public view returns (string);
  ^---------------------------------------------------------------^
Compilation failed. See above.
Cleaning up...
Shutting down testrpc-sc (pid 34087)
Event trace could not be read.
Error: ENOENT: no such file or directory, open './allFiredEvents'
Exiting without generating coverage...
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! block42-monopoly@1.0.0 coverage: `solidity-coverage`
npm ERR! Exit status 1
npm ERR! 
npm ERR! Failed at the block42-monopoly@1.0.0 coverage 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!     /Users/fur/.npm/_logs/2018-08-24T00_49_28_152Z-debug.log

tokenURI() I wrote follow exactly the same as the one in ERC721.sol and has view, but seems solidity-coverage ignore it and reporting the error…

@cgewecke Yes, it works. I’m going to submit a PR with a workaround that worked for me too.

hey @cgewecke I’m having the same problem here: https://github.com/aragon/aragon-apps/pull/425/commits/2da188ff9351779a7dc244232421881d1eb251a0 take apps/vault, which is kind of simple. I tried your suggestion, so modified .solcover.js to:

module.exports = {
    copyPackages: ['@aragon/os']
}

And then I run ./node_modules/.bin/solidity-coverage ., but I get the following error:

,/home/bingen/workspace/aragon-apps/apps/vault/coverageEnv/contracts/Vault.sol:175:5: TypeError: Overriding function changes state mutability from "view" to "nonpayable".
    function allowRecoverability(address) public  returns (bool) {emit __FunctionCoverageVault('/home/bingen/workspace/aragon-apps/apps/vault/contracts/Vault.sol',7);
    ^ (Relevant source part starts here and spans across multiple lines).
@aragon/os/contracts/common/VaultRecoverable.sol:37:5: Overriden function is here:
    function allowRecoverability(address token) public view returns (bool) {
    ^ (Relevant source part starts here and spans across multiple lines).

Could it be due to the folder structure of the package, with 2 subfolders? I’m seeing that under coverageEnv it appears as just os instead of @aragon/os.

@sweatyc I got it to run by adding a .solcover.js with the following contents. Basically same as the previous comment:

module.exports = {
  copyPackages: ['openzeppelin-solidity']
}

There’s an additional issue in the landpot-contracts where there is a migrations file that doesn’t work (2) but just deleted it and everything was fine.

@elenadimitrova Thanks, yes that makes sense. Opening a separate issue for this. Reopening. We just need to globalize the replace for .sols

For now, I think the only way to solve this is to remove the pure and view decorators during instrumentation.