I've created some upgradeable contracts that get deployed using the Migrations/2_deploy_contracts.js
file and then have instances of the contracts created during the tests using the .deployed() method.
When I run the tests I get a .json
file and then eventually a .json.lock
folder appear in the .openzeppelin
directory.
The first time I run the test
I get the error shown below.
If I immediately delete the file and folder in the .openzeppelin
directory and run test
again everything works.
Unfortunately, any time I try to run test
again after this I get the error below every time moving forwards.
Code to reproduce
In an attempt to fix this before running test I have been:
- deleting all the artifact json files
- removing the
.json
and the.json.lock
from the.openzeppelin
directory
I then run:
$ truffle compile --all
$ truffle developer
$ test
Error:
Compiling your contracts...
===========================
> Compiling @openzeppelin\contracts-upgradeable\access\OwnableUpgradeable.sol
> Compiling @openzeppelin\contracts-upgradeable\proxy\utils\Initializable.sol
> Compiling @openzeppelin\contracts-upgradeable\token\ERC20\ERC20Upgradeable.sol
> Compiling @openzeppelin\contracts-upgradeable\token\ERC20\IERC20Upgradeable.sol
> Compiling @openzeppelin\contracts-upgradeable\token\ERC20\extensions\IERC20MetadataUpgradeable.sol
> Compiling @openzeppelin\contracts-upgradeable\utils\ContextUpgradeable.sol
> Compiling @openzeppelin\contracts\token\ERC20\ERC20.sol
> Compiling @openzeppelin\contracts\token\ERC20\IERC20.sol
> Compiling @openzeppelin\contracts\token\ERC20\extensions\IERC20Metadata.sol
> Compiling @openzeppelin\contracts\token\ERC721\ERC721.sol
> Compiling @openzeppelin\contracts\token\ERC721\IERC721.sol
> Compiling @openzeppelin\contracts\token\ERC721\IERC721Receiver.sol
> Compiling @openzeppelin\contracts\token\ERC721\extensions\ERC721URIStorage.sol
> Compiling @openzeppelin\contracts\token\ERC721\extensions\IERC721Metadata.sol
> Compiling @openzeppelin\contracts\utils\Address.sol
> Compiling @openzeppelin\contracts\utils\Context.sol
> Compiling @openzeppelin\contracts\utils\Counters.sol
> Compiling @openzeppelin\contracts\utils\Strings.sol
> Compiling @openzeppelin\contracts\utils\introspection\ERC165.sol
> Compiling @openzeppelin\contracts\utils\introspection\IERC165.sol
> Compiling .\contracts\Migrations.sol
> Compiling .\contracts\MyNFT.sol
> Compiling .\contracts\MyToken.sol
> Compiling .\contracts\MyUpgradeableContract.sol
> Compiling .\contracts\MyUpgradeableContractV2.sol
> Compiling .\contracts\MyUpgradeableToken.sol
> Artifacts written to C:\Users\Owner\AppData\Local\Temp\test--22684-VqkIho9ma9cp
> Compiled successfully using:
- solc: 0.8.0+commit.c7dfd78e.Emscripten.clang
Error: EBUSY: resource busy or locked, rmdir 'C:\Users\Owner\Dropbox\general\dev\web\projects\100 - blockchain\Second blockchain project\s06-tokenisation\.openzeppelin\unknown-1337.json.lock'
Migrations/1_initial_migration.js
var Migrations = artifacts.require("./Migrations.sol");
module.exports = function(deployer) {
deployer.deploy(Migrations);
};
Migrations/2_deploy_contracts.js
const MyToken = artifacts.require('./MyToken.sol');
const MyNFT = artifacts.require('./MyNFT.sol');
const MyUpgradeableToken = artifacts.require('./MyUpgradeableToken.sol');
const MyUpgradeableContract = artifacts.require('./MyUpgradeableContract.sol');
const { deployProxy } = require('@openzeppelin/truffle-upgrades');
const { args } = require('../utils/projectVariables');
require('dotenv').config({ path: '../.env' });
module.exports = async function (deployer) {
let addr = await web3.eth.getAccounts();
//deploy the token contract
await deployer.deploy(MyToken, ...Object.values(args.tokenInstance));
//deploy the nft contract
let nftInstance = await deployer.deploy(MyNFT);
await nftInstance.awardItem(addr[0], process.env.NFT_TOKEN_URI);
//deploy the upgradeable token contracts
await deployProxy(MyUpgradeableToken, [...Object.values(args.upgradeableTokenInstance)], {
deployer,
initializer: 'initialize',
});
await deployProxy(MyUpgradeableContract, [MyUpgradeableToken.address], {
deployer,
initializer: 'initialize',
});
};
Test file
const UpgradeableContract = artifacts.require('MyUpgradeableContract');
const UpgradeableContractV2 = artifacts.require('MyUpgradeableContractV2');
const UpgradeableToken = artifacts.require('MyUpgradeableToken');
const { upgradeProxy } = require('@openzeppelin/truffle-upgrades');
const { expect } = require('./testSetup');
contract('UpgradeableContract Test', async () => {
//add accounts as an arg if you want to get and array of the accounts
let upgradeableContractInstance;
it('should return correct token address on getTokenAddress call', async () => {
upgradeableContractInstance = await UpgradeableContract.deployed();
const tokenAddress = await upgradeableContractInstance.getTokenAddress();
expect(tokenAddress).to.equal(UpgradeableToken.address);
});
it('upgrades', async () => {
upgradeableContractInstance = await UpgradeableContract.deployed();
const upgradeableContractInstanceV2 = await upgradeProxy(
upgradeableContractInstance.address,
UpgradeableContractV2,
);
const value = await upgradeableContractInstanceV2.value();
expect(value.toString()).to.equal('42');
});
});
.openzeppelin/unknown-1337.json (file that I delete after first test run)
{
"manifestVersion": "3.2",
"admin": {
"address": "0x1889b18db73DA0d67ca73E1272Dcd07591A746f0",
"txHash": "0xcc7090004aa6cb5908a812c5c2a4345a1df85bae1170de6b1069232b86ebc0cf"
},
"proxies": [
{
"address": "0x2c966994fbfC49E3e23E583d9cb11C7c9005924F",
"txHash": "0x530e09d1b1b1efc96fdeea21f5514a67c7ad0e4877c8c041a08f078313e69edc",
"kind": "transparent"
}
],
"impls": {
"4d3e157f4d5577ac3ab7d2f764e0a296a964ce56517f9e2b76c113c197a6915e": {
"address": "0x2723889f1c9B16a6ab4763D987c8f16354CaA9F6",
"txHash": "0x00e84bbf4188ba9c0bfbe8590c444aadb5e3437cf620c1ff4cb1b4e24981e2be",
"layout": {
"storage": [
{
"contract": "Initializable",
"label": "_initialized",
"type": "t_bool",
"src": "..\\@openzeppelin\\contracts-upgradeable\\proxy\\utils\\Initializable.sol:21"
},
{
"contract": "Initializable",
"label": "_initializing",
"type": "t_bool",
"src": "..\\@openzeppelin\\contracts-upgradeable\\proxy\\utils\\Initializable.sol:26"
},
{
"contract": "ContextUpgradeable",
"label": "__gap",
"type": "t_array(t_uint256)50_storage",
"src": "..\\@openzeppelin\\contracts-upgradeable\\utils\\ContextUpgradeable.sol:30"
},
{
"contract": "ERC20Upgradeable",
"label": "_balances",
"type": "t_mapping(t_address,t_uint256)",
"src": "..\\@openzeppelin\\contracts-upgradeable\\token\\ERC20\\ERC20Upgradeable.sol:36"
},
{
"contract": "ERC20Upgradeable",
"label": "_allowances",
"type": "t_mapping(t_address,t_mapping(t_address,t_uint256))",
"src": "..\\@openzeppelin\\contracts-upgradeable\\token\\ERC20\\ERC20Upgradeable.sol:38"
},
{
"contract": "ERC20Upgradeable",
"label": "_totalSupply",
"type": "t_uint256",
"src": "..\\@openzeppelin\\contracts-upgradeable\\token\\ERC20\\ERC20Upgradeable.sol:40"
},
{
"contract": "ERC20Upgradeable",
"label": "_name",
"type": "t_string_storage",
"src": "..\\@openzeppelin\\contracts-upgradeable\\token\\ERC20\\ERC20Upgradeable.sol:42"
},
{
"contract": "ERC20Upgradeable",
"label": "_symbol",
"type": "t_string_storage",
"src": "..\\@openzeppelin\\contracts-upgradeable\\token\\ERC20\\ERC20Upgradeable.sol:43"
},
{
"contract": "ERC20Upgradeable",
"label": "__gap",
"type": "t_array(t_uint256)45_storage",
"src": "..\\@openzeppelin\\contracts-upgradeable\\token\\ERC20\\ERC20Upgradeable.sol:361"
}
],
"types": {
"t_mapping(t_address,t_uint256)": {
"label": "mapping(address => uint256)"
},
"t_address": {
"label": "address"
},
"t_uint256": {
"label": "uint256"
},
"t_mapping(t_address,t_mapping(t_address,t_uint256))": {
"label": "mapping(address => mapping(address => uint256))"
},
"t_string_storage": {
"label": "string"
},
"t_array(t_uint256)45_storage": {
"label": "uint256[45]"
},
"t_array(t_uint256)50_storage": {
"label": "uint256[50]"
},
"t_bool": {
"label": "bool"
}
}
}
},
"b2a18a89e3792f24c5e7e850905e5c76f6813d29f6fbfa098a09b581a4a20c28": {
"address": "0x5fBA8D13d6F34C4c9E0b5efD36c49e5F7d1d4f3F",
"txHash": "0x055067bb0e193ba6f2040bcaa0ef437e2fec5817515dcbb67282f24435f556b7",
"layout": {
"storage": [
{
"contract": "Initializable",
"label": "_initialized",
"type": "t_bool",
"src": "..\\@openzeppelin\\contracts-upgradeable\\proxy\\utils\\Initializable.sol:21"
},
{
"contract": "Initializable",
"label": "_initializing",
"type": "t_bool",
"src": "..\\@openzeppelin\\contracts-upgradeable\\proxy\\utils\\Initializable.sol:26"
},
{
"contract": "ContextUpgradeable",
"label": "__gap",
"type": "t_array(t_uint256)50_storage",
"src": "..\\@openzeppelin\\contracts-upgradeable\\utils\\ContextUpgradeable.sol:30"
},
{
"contract": "OwnableUpgradeable",
"label": "_owner",
"type": "t_address",
"src": "..\\@openzeppelin\\contracts-upgradeable\\access\\OwnableUpgradeable.sol:21"
},
{
"contract": "OwnableUpgradeable",
"label": "__gap",
"type": "t_array(t_uint256)49_storage",
"src": "..\\@openzeppelin\\contracts-upgradeable\\access\\OwnableUpgradeable.sol:77"
},
{
"contract": "MyUpgradeableContract",
"label": "token",
"type": "t_contract(IERC20Upgradeable)821",
"src": "..\\project:\\contracts\\MyUpgradeableContract.sol:9"
},
{
"contract": "MyUpgradeableContract",
"label": "value",
"type": "t_uint8",
"src": "..\\project:\\contracts\\MyUpgradeableContract.sol:10"
}
],
"types": {
"t_contract(IERC20Upgradeable)821": {
"label": "contract IERC20Upgradeable"
},
"t_uint8": {
"label": "uint8"
},
"t_address": {
"label": "address"
},
"t_array(t_uint256)49_storage": {
"label": "uint256[49]"
},
"t_uint256": {
"label": "uint256"
},
"t_array(t_uint256)50_storage": {
"label": "uint256[50]"
},
"t_bool": {
"label": "bool"
}
}
}
}
}
}
contracts/MyUpgradeableContract.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import '@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol';
import '@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol';
import '@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol';
contract MyUpgradeableContract is Initializable, OwnableUpgradeable {
IERC20Upgradeable public token;
uint8 public value;
function initialize(IERC20Upgradeable _token) public initializer {
__Ownable_init_unchained();
token = _token;
value = 42;
}
function getTokenAddress() public view onlyOwner returns (address) {
return address(token);
}
}
contracts/MyUpgradeableContractV2.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import './MyUpgradeableContract.sol';
contract MyUpgradeableContractV2 is MyUpgradeableContract {}
Environment
Truffle: 5.4.2
Node: 14.16.1
@openzeppelin/contracts@4.2.0
@openzeppelin/contracts-upgradeable@4.3.2
@openzeppelin/truffle-upgrades@1.9.1