tagomaru / truffle-sca2t

Smart contract auditing assistant tool for Truffle Framework.
18 stars 4 forks source link

Respect compiler version in truffle.js / truffle-config.js #20

Closed muellerberndt closed 5 years ago

muellerberndt commented 5 years ago

Description

It seems that sca2t ignores the compiler version specified in truffle.js.

In AragonOS, I added the following to truffle.js:

module.exports = {
    plugins: [ "truffle-security",  "truffle-sca2t" ],
    compilers: {
     solc: {
       version: "0.4.24"
     }
  }

Also, I added to truffle-config.js:

  solc: {
    version: "0.4.24",
    optimizer: {
      enabled: true,
      runs: 10000
    }
  },

truffle compile runs successfully with solc 0.4.24, but npm run test:security returns a compiler error:

$ npm run test:security

> @aragon/os@4.0.1 test:security /Users/bernhardmueller/Desktop/MythX-Testing/aragonOS
> mocha ./test_security --timeout 500000

  apm/APMRegistry.sol
Warning: Both truffle-config.js and truffle.js were found. Using truffle-config.js.
(node:97574) V8: /Users/bernhardmueller/Desktop/MythX-Testing/aragonOS/node_modules/truffle-compile/node_modules/solc/soljson.js:3 Invalid asm.js: Invalid member of stdlib
    1) "before all" hook
(node:97574) UnhandledPromiseRejectionWarning: Error: Callback was already called.
    at /Users/bernhardmueller/Desktop/MythX-Testing/aragonOS/node_modules/async/dist/async.js:966:32
    at next (/Users/bernhardmueller/Desktop/MythX-Testing/aragonOS/node_modules/async/dist/async.js:5225:18)
(node:97574) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1)
(node:97574) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

  0 passing (2s)
  1 failing

  1) apm/APMRegistry.sol
       "before all" hook:
     Error: CompileError: ParsedContract.sol:5:42: ParserError: The state mutability modifier "constant" was removed in version 0.5.0. Use "view" or "pure" instead.
    function owner(bytes32 _node) public constant returns (address);
                                         ^------^

Compilation failed. See above.
      at async.whilst.error (node_modules/truffle-compile/profiler.js:379:27)
      at node_modules/async/dist/async.js:969:16
      at next (node_modules/async/dist/async.js:5222:25)
      at Promise.all.then.results (node_modules/truffle-compile/profiler.js:361:22)

npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! @aragon/os@4.0.1 test:security: `mocha ./test_security --timeout 500000`
npm ERR! Exit status 1
npm ERR! 
npm ERR! Failed at the @aragon/os@4.0.1 test:security 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/bernhardmueller/.npm/_logs/2019-04-24T14_04_37_337Z-debug.log

Expected behavior

Use the selected solc version to compile.

tagomaru commented 5 years ago

I tried, but could not reproduce it.

truffle.js

module.exports = {
  plugins: ["truffle-sca2t"],
  compilers: {
    solc: {
      version: "0.4.24"
    }
  }
}

truffle-config.js

module.exports = {
  plugins: ["truffle-sca2t"],
  compilers: {
    solc: {
      version: "0.4.24",
      optimizer: {
        enabled: true,
        runs: 10000
      }
    }
  }
}

npm run test:security

$ npm run test:security

> @aragon/os@4.2.0 test:security /mnt/c/workdir/vscode_project/aragonOS
> mocha ./test_security --timeout 500000

  apm/APMRegistry.sol
Warning: Both truffle-config.js and truffle.js were found. Using truffle-config.js.
    APMInternalAppNames
Warning: Both truffle-config.js and truffle.js were found. Using truffle-config.js.
      ✓ should be no error
      ✓ should be no MythX log
      1) should be no issue
    APMRegistry
Warning: Both truffle-config.js and truffle.js were found. Using truffle-config.js.
      ✓ should be no error
      ✓ should be no MythX log
      2) should be no issue

  4 passing (30s)
  2 failing

Could you let me know your complete truffle.js ?

And as far as referring to Truffle Compiler configuration, I am wondering truffle-config.js for recent verions should be like below.

module.exports = {
  plugins: ["truffle-sca2t"],
  compilers: {
    solc: {
      version: "0.4.24",
      settings: {
        optimizer: {
          enabled: true,
          runs: 10000
        }
      }
    }
  }
}
tagomaru commented 5 years ago

I could not compile AragonOS with setting of AragonOS.

  solc: {
    optimizer: {
      enabled: true,
      runs: 10000
    }
  },

compile

$ ./node_modules/.bin/truffle --version
Truffle v5.0.10 - a development framework for Ethereum
(removed)

$ ./node_modules/.bin/truffle compile

Compiling your contracts...
===========================
Error: CompileError: ParsedContract.sol:7:42: ParserError: The state mutability modifier "constant" was removed in version 0.5.0. Use "view" or "pure" instead.
    function owner(bytes32 _node) public constant returns (address);
                                         ^------^

Compilation failed. See above.
    at async.whilst.error (/mnt/c/workdir/vscode_project/aragonOS/node_modules/truffle/build/webpack:/packages/truffle-compile/profiler.js:375:1)
    at /mnt/c/workdir/vscode_project/aragonOS/node_modules/truffle/build/webpack:/packages/truffle-compile/~/async/dist/async.js:969:1
    at next (/mnt/c/workdir/vscode_project/aragonOS/node_modules/truffle/build/webpack:/packages/truffle-compile/~/async/dist/async.js:5222:1)
    at Promise.all.then.results (/mnt/c/workdir/vscode_project/aragonOS/node_modules/truffle/build/webpack:/packages/truffle-compile/profiler.js:357:1)
Truffle v5.0.10 (core: 5.0.10)
Node v10.15.3

I am wondering AragonOS and your setting are old truffle config style.

AragonOS itself relies on old version truffle. https://github.com/aragon/aragonOS/blob/dev/package.json#L44

muellerberndt commented 5 years ago

Yeah, I think if you have solc >= 0.5.0 installed you need to add the compiler version to truffle-config.js to get it to compile.

I added the version field at the bottom of the file:

  solc: {
    version: "0.4.24",
    optimizer: {
      enabled: true,
      runs: 10000
    }
  },
muellerberndt commented 5 years ago

To make things less complicated I deleted truffle.js and put everything into truffle-config.js:

const homedir = require('homedir')
const path = require('path')

const HDWalletProvider = require('truffle-hdwallet-provider')
const HDWalletProviderPrivkey = require('truffle-hdwallet-provider-privkey')

const DEFAULT_MNEMONIC = 'stumble story behind hurt patient ball whisper art swift tongue ice alien'

const defaultRPC = (network) =>
  `https://${network}.infura.io`

const configFilePath = (filename) =>
  path.join(homedir(), `.aragon/${filename}`)

const mnemonic = () => {
  try {
    return require(configFilePath('mnemonic.json')).mnemonic
  } catch (e) {
    return DEFAULT_MNEMONIC
  }
}

const settingsForNetwork = (network) => {
  try {
    return require(configFilePath(`${network}_key.json`))
  } catch (e) {
    return { }
  }
}

// Lazily loaded provider
const providerForNetwork = (network) => (
  () => {
    let { rpc, keys } = settingsForNetwork(network)

    rpc = rpc || defaultRPC(network)

    if (!keys || keys.length == 0) {
      return new HDWalletProvider(mnemonic(), rpc)
    }

    return new HDWalletProviderPrivkey(keys, rpc)
  }
)

const mochaGasSettings = {
  reporter: 'eth-gas-reporter',
  reporterOptions : {
    currency: 'USD',
    gasPrice: 3
  }
}

const mocha = process.env.GAS_REPORTER ? mochaGasSettings : {}

module.exports = {
  plugins: [ "truffle-security",  "truffle-sca2t" ],
  networks: {
    rpc: {
      network_id: 15,
      host: 'localhost',
      port: 8545,
      gas: 6.9e6,
      gasPrice: 15000000001
    },
    devnet: {
      network_id: 16,
      host: 'localhost',
      port: 8535,
      gas: 6.9e6,
      gasPrice: 15000000001
    },
    mainnet: {
      network_id: 1,
      provider: providerForNetwork('mainnet'),
      gas: 7.9e6,
      gasPrice: 3000000001
    },
    ropsten: {
      network_id: 3,
      provider: providerForNetwork('ropsten'),
      gas: 4.712e6
    },
    rinkeby: {
      network_id: 4,
      provider: providerForNetwork('rinkeby'),
      gas: 6.9e6,
      gasPrice: 15000000001
    },
    kovan: {
      network_id: 42,
      provider: providerForNetwork('kovan'),
      gas: 6.9e6
    },
    coverage: {
      host: "localhost",
      network_id: "*",
      port: 8555,
      gas: 0xffffffffff,
      gasPrice: 0x01
    },
  },
  build: {},
  mocha,
  solc: {
    version: "0.4.24",
    optimizer: {
      enabled: true,
      runs: 10000
    }
  },
}

Now I can successfully run truffle compile, but truffle run mythx <contract> still attempts to use solc 0.5.6 and throws an error.

tagomaru commented 5 years ago

@b-mueller Thx for your kind attempt.

hmm - I tried on the same condition with you, but I got the error. strange...

$ ./node_modules/.bin/truffle compile

Compiling your contracts...
===========================
> Everything is up to date, there is nothing to compile.

$ ./node_modules/.bin/truffle compile --all

Compiling your contracts...
===========================
Error: CompileError: ParsedContract.sol:7:42: ParserError: The state mutability modifier "constant" was removed in version 0.5.0. Use "view" or "pure" instead.
    function owner(bytes32 _node) public constant returns (address);
                                         ^------^

Compilation failed. See above.
    at async.whilst.error (/mnt/c/workdir/vscode_project/aragonOS/node_modules/truffle/build/webpack:/packages/truffle-compile/profiler.js:375:1)
    at /mnt/c/workdir/vscode_project/aragonOS/node_modules/truffle/build/webpack:/packages/truffle-compile/~/async/dist/async.js:969:1
    at next (/mnt/c/workdir/vscode_project/aragonOS/node_modules/truffle/build/webpack:/packages/truffle-compile/~/async/dist/async.js:5222:1)
    at Promise.all.then.results (/mnt/c/workdir/vscode_project/aragonOS/node_modules/truffle/build/webpack:/packages/truffle-compile/profiler.js:357:1)
Truffle v5.0.10 (core: 5.0.10)
Node v10.15.3

please wait for a while because I'll dig deeper later :smiley:

tagomaru commented 5 years ago

@b-mueller I tried on another machine with your settings, however truffle compile failed... Anyway if you use compilers like below, I think the test will successfully finish.

  compilers: {
    solc: {
      version: "0.4.24",
      optimizer: {
        enabled: true,
        runs: 10000
      }
    }

my complete truffle-config.js is the following, and the test successfully done.

const homedir = require('homedir')
const path = require('path')

const HDWalletProvider = require('truffle-hdwallet-provider')
const HDWalletProviderPrivkey = require('truffle-hdwallet-provider-privkey')

const DEFAULT_MNEMONIC = 'stumble story behind hurt patient ball whisper art swift tongue ice alien'

const defaultRPC = (network) =>
  `https://${network}.infura.io`

const configFilePath = (filename) =>
  path.join(homedir(), `.aragon/${filename}`)

const mnemonic = () => {
  try {
    return require(configFilePath('mnemonic.json')).mnemonic
  } catch (e) {
    return DEFAULT_MNEMONIC
  }
}

const settingsForNetwork = (network) => {
  try {
    return require(configFilePath(`${network}_key.json`))
  } catch (e) {
    return { }
  }
}

// Lazily loaded provider
const providerForNetwork = (network) => (
  () => {
    let { rpc, keys } = settingsForNetwork(network)

    rpc = rpc || defaultRPC(network)

    if (!keys || keys.length == 0) {
      return new HDWalletProvider(mnemonic(), rpc)
    }

    return new HDWalletProviderPrivkey(keys, rpc)
  }
)

const mochaGasSettings = {
  reporter: 'eth-gas-reporter',
  reporterOptions : {
    currency: 'USD',
    gasPrice: 3
  }
}

const mocha = process.env.GAS_REPORTER ? mochaGasSettings : {}

module.exports = {
  plugins: [ "truffle-security",  "truffle-sca2t" ],
  networks: {
    rpc: {
      network_id: 15,
      host: 'localhost',
      port: 8545,
      gas: 6.9e6,
      gasPrice: 15000000001
    },
    devnet: {
      network_id: 16,
      host: 'localhost',
      port: 8535,
      gas: 6.9e6,
      gasPrice: 15000000001
    },
    mainnet: {
      network_id: 1,
      provider: providerForNetwork('mainnet'),
      gas: 7.9e6,
      gasPrice: 3000000001
    },
    ropsten: {
      network_id: 3,
      provider: providerForNetwork('ropsten'),
      gas: 4.712e6
    },
    rinkeby: {
      network_id: 4,
      provider: providerForNetwork('rinkeby'),
      gas: 6.9e6,
      gasPrice: 15000000001
    },
    kovan: {
      network_id: 42,
      provider: providerForNetwork('kovan'),
      gas: 6.9e6
    },
    coverage: {
      host: "localhost",
      network_id: "*",
      port: 8555,
      gas: 0xffffffffff,
      gasPrice: 0x01
    },
  },
  build: {},
  mocha,
  compilers: {
    solc: {
      version: "0.4.24",
      optimizer: {
        enabled: true,
        runs: 10000
      }
    }
  }
}
tagomaru commented 5 years ago

@b-mueller Could you let me know the below result ?

$ truffle version
$ grep truffle-compile package.json

And

Does truffle compile succeed when you remove version like below ?

  build: {},
  mocha,
  solc: {
    optimizer: {
      enabled: true,
      runs: 10000
    }
  },
}
tagomaru commented 5 years ago

I am going to close this. If you have this problem still, please reopen.