wighawag / hardhat-deploy

hardhat deployment plugin
MIT License
1.2k stars 296 forks source link

`deploy` from `deployments` doesn't handle `contract` option properly when used with fixture #293

Closed jimmychu0807 closed 2 years ago

jimmychu0807 commented 2 years ago

Describe the bug

I have a deploy() function with a contract option specified, say as contractName. That deployed contract cannot be retrieved with await deployments.fixture(["tag"]).

To Reproduce

Steps to reproduce the behavior:

  1. In the tutorial-hardhat-deploy, change the deploy function to:

    await deploy('TokenDeployment', {
     contract: 'Token',
     from: deployer,
     args: [tokenOwner],
     log: true,
    });
  2. Run with yarn hardhat test

  3. This error message is displayed: Error: No Contract deployed with name Token. It fails at this line.

Expected behavior

I would expect all tests should pass.

versions

wighawag commented 2 years ago

That's expected, you changed the name to TokenDeployment

the contract option is to specify the contract artifact, not the name

jimmychu0807 commented 2 years ago

hmm... so if I have this in the deploy function:

const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) {
  // -- snip --

  await deploy('TokenDeployment', {
    contract: 'Token',
    from: deployer,
    args: [tokenOwner],
    log: true,
  });
};
export default func;
func.tags = ['TokenTag'];

What should be the fixture line to retrieve the contract?

describe('ERC20 Token', function() {
  it("should return a new ERC20 token", async function() {

  await deployments.fixture(['what should be at here?'])
  // ...
})
wighawag commented 2 years ago

the tag : TokenTag

and then you get your contract deployment via deployments.get('TokenDeployment')

jimmychu0807 commented 2 years ago

I see. Thank for getting back to me promptly.

jimmychu0807 commented 2 years ago

In your tutorial, you have

async function setup () {
  // it first ensure the deployment is executed and reset (use of evm_snaphost for fast test)
  await deployments.fixture(["Token"]);

  // we get an instantiated contract in the form of a ethers.js Contract instance:
  const contracts = {
    Token: (await ethers.getContract('Token')),
  };
  // -- snip -- 

With my above given deploy function using TokenTag, TokenDeployment, and Token

// I can load this properly, as you mentioned.
await deployments.fixture(["TokenTag"]);

const contracts = {
  // But I cannot do this line now.
  Token: (await ethers.getContract('Token')),
  // So how can I get the Contract instance, or how to get a Contract instance from `deployments.get('TokenDeployment')`
};

I also tried:

Token: (await ethers.getContractAt(deployment.address, 'Token'))

But it returns: HardhatError: HH700: Artifact for contract "0x5FbDB2315678afecb367f032d93F642f64180aa3" not found.

wighawag commented 2 years ago

your deployment is named TokenDeployment so you have to use that to fetch it

wighawag commented 2 years ago

as for

Token: (await ethers.getContractAt(deployment.address, 'Token'))

I am not familiar with this function

if you use hardhat-deploy-ethers you can do await ethers.getContract('TokenDeployment') no need to specify address

ghost commented 2 years ago

I see. What I wasn't clear before is that the argument pass into .fixture() are deployment tags, and the argument pass into ethers.getContract() is the deployment name.

ethers.getContractAt() is provided by @nomiclabs/hardhat-ethers (I used "@nomiclabs/hardhat-ethers": "npm:hardhat-deploy-ethers@^0.3.0-beta.13" in package.json you mentioned in another issue). But I get the argument order wrong. It should be the contract name as the first argument and the contract address as the second.