Truffle Upgrades on Windows: Error: Artifacts are from different compiler runs

I've ran into the same issue myself and I'm able to reproduce.

  1. mkdir repro && cd repro
  2. npm init -y
npm i --save-dev truffle &&
npm i --save-dev @openzeppelin/truffle-upgrades &&
npm i --save-dev @openzeppelin/contracts-ethereum-package &&
npm i --save-dev @truffle/hdwallet-provider

If you are from the future it is already fixed and you want to reproduce use these:

"devDependencies": {
    "@openzeppelin/contracts-ethereum-package": "^3.0.0",
    "@openzeppelin/truffle-upgrades": "^1.2.0",
    "@truffle/hdwallet-provider": "^1.1.1",
    "truffle": "^5.1.49"
}
  1. npx truffle init

  2. Copy-paste content into files

// contracts/Coin.sol
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.6.0;

import "@openzeppelin/contracts-ethereum-package/contracts/Initializable.sol";
import "@openzeppelin/contracts-ethereum-package/contracts/presets/ERC20PresetMinterPauser.sol";

contract Coin is ERC20PresetMinterPauserUpgradeSafe {    
    bytes32 public constant WHITELIST_ROLE = keccak256("WHITELIST_ROLE");
    modifier onlyWhitelister {
        require(hasRole(WHITELIST_ROLE, _msgSender()), "must have WHITELIST ROLE");
        _;
    }
    function initialize(string memory name, string memory symbol) public override virtual initializer {
        ERC20PresetMinterPauserUpgradeSafe.initialize(name, symbol);
        _setupRole(WHITELIST_ROLE, _msgSender());
    }
}

// test/coin.js
function toWei(eth){
    return web3.utils.toWei(eth);
}

const Coin = artifacts.require('Coin');

contract('Coin ', async function(accounts) {
    const creator = accounts[0]
    const user1 = accounts[1];
    const user2 = accounts[2];
    let coin;
    beforeEach(async function() {
        coin= await Coin.new({ from: creator } );
        await coin.initialize("Sample Coin", "SC ", { from: creator } );
        await coin.mint(user1, toWei("200000"), { from: creator });
    })
    it('User 1 should be able to send tokens to User 2', async () => {
        await coin.transfer(user2, toWei("10"), { from: user1 })
        assert.equal(await coin.balanceOf(user2), toWei("10"), "User 2 does not have 10 tokens");
    });
})

Some housekeeping otherwise the compiler will complain:

  1. Compiler version in truffle-config.js should be compilers: { solc: { version: "^0.6.0" } } (line 85)
  2. Add virtual to the initialize function in node_modules\@openzeppelin\contracts-ethereum-package\contracts\presets\ERC20PresetMinterPauser.sol (line 35)

DONE-ish. Can run truffle test, it compiles, it works, it pass the test... :clinking_glasses::tada::raised_hands:

So far so good...

...now this is failing.

// migrations/2_breaking_migration.js
const Coin = artifacts.require('Coin');
 
const { deployProxy } = require('@openzeppelin/truffle-upgrades');
 
module.exports = async function (deployer) {
  await deployProxy(Coin, ["New token", "NTKN"], { deployer, initializer: 'initialize', unsafeAllowCustomTypes : true });
};

Error: Artifacts are from different compiler runs
Run a full recompilation using truffle compile --all
https://zpl.in/upgrades/truffle-recompile-all

Deleting the build folder / recompiling does not help.


I think it has something to do with some of the contracts being precompiled, see this post: Add instructions on how to verify to Upgrades Plugins step by step guides - #2 by abcoathup

It works on Mac BTW.

1 Like