I'd like to test the deployment, minting and transfer of an NFT in hardhat.
Here's my test code:
describe("Receiving NFT", function () {
it("Should emit a received NFT event", async function () {
const { bridge, owner, otherAccount } = await loadFixture(deployFixture);
const { token, owner: tokenContractOwner } = await loadFixture(deployMockNFTFixture);
await token.connect(otherAccount.address)
await token.mint(otherAccount.address)
console.log(await token.balanceOf(otherAccount.address));
console.log(await token.ownerOf(1));
console.log("bridge.target: ", bridge.target)
console.log("owner.address: ", owner.address)
await token.connect(otherAccount.address)
await token.transferFrom(otherAccount.address, bridge.target, 1);
console.log(await token.balanceOf(bridge.target));
console.log(await token.ownerOf(1));
// console.log(await token.ownerOf(1));
// await expect()
// .to.emit(bridge, "ReceivedNFT");
// .withArgs(lockedAmount, anyValue);
})
})
})
The transferFrom
line fails with error: Error: VM Exception while processing transaction: reverted with reason string 'ERC721: caller is not token owner or approved'
I added logs in the code and these are the logs:
1n
otherAccount.address: 0x70997970C51812dc3A010C7d01b50e0d17dc79C8
bridge.target: 0x5FbDB2315678afecb367f032d93F642f64180aa3
owner.address: 0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266
msg.sender: 0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266
The msg.sender of when transferFrom
is executed is the owner.address of the owner who deployed both the contracts. Even though I use await token.connect(otherAccount.address)
to switch the msg.sender
to the otherAccount.
How do I execute the transferFrom from the otherAccount ?
I've minted the NFT to the otherAccount and need to transfer it to the bridge contract. Thanks.
EDIT: I've added an approval step:
await token.connect(otherAccount.address)
await token.approve(bridge.target, 1)
await token.transferFrom(otherAccount.address, bridge.target, 1);
However, I still get an error which is:
Error: VM Exception while processing transaction: reverted with reason string 'ERC721: approve caller is not token owner or approved for all'
For some reason, the msg.sender is 0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266
, the contract deployer, despite doing token.connect(otherAccount.address)...
I noticed that despite doing a .connect
to change the msg.sender to the otherAccount, Hardhat was still showing the msg.sender as the owner.address (the address that deployed both contracts), so as a workaround, I minted the nft from the owner address and approved and transfered from the owner address and the test worked.
it("Should emit a received NFT event", async function () {
const { bridge, owner } = await loadFixture(deployFixture);
const { token } = await loadFixture(deployMockNFTFixture);
// await token.connect(otherAccount.address)
await token.mint(owner.address)
console.log(await token.balanceOf(owner.address));
console.log(await token.ownerOf(1));
console.log("bridge.target: ", bridge.target)
console.log("owner.address: ", owner.address)
// await token.connect(otherAccount.address)
await token.approve(bridge.target, 1)
console.log(await token.balanceOf(bridge.target));
console.log(await token.ownerOf(1));
expect(await token.transferFrom(owner.address, bridge.target, 1))
.to.emit(bridge, "ReceivedNFT");
})