Hey guys, I'm trying to implement a function that will withdraw funds from an ERC721 contract. The issue I'm having is that it does not look like the user's balance is changing after withdrawing funds, neither is the contract's balance. I'm not sure if this is typical behavior for unit tests. I've added hardhat logging within the contract's withdraw function and it looks to be withdrawing successful. I'm not sure why this isn't being reflected within the unit test. Might this have something to do with provider = ethers.getDefaultProvider()
might I need to use a different provider?
Code to reproduce
Contract Code
uint256 public _basePrice = 5 * 10**18;
function userMint() external payable {
require(_msgSender() != owner(), "Minter cannot be owner");
require(msg.value >= _basePrice, "Not enought Matic sent");
require(_totalSupply < _maxSupply, "Max supply reached");
uint256 tokenId = _tokenIdCounter.current();
string memory strTokenId = Strings.toString(tokenId);
string memory tokenUri = string(abi.encodePacked(_baseUri, strTokenId));
_tokenIdCounter.increment();
_safeMint(_msgSender(), tokenId);
_setTokenURI(tokenId, tokenUri);
}
function withdraw() external onlyOwner returns (bool) {
require(address(this).balance > 0, "Withdrawal exceeds balance.");
uint256 balance = address(this).balance;
console.log("balance pre withdraw: %s", balance);
(bool success, ) = msg.sender.call{value: address(this).balance}("");
console.log("success?: %s", success);
console.log("balance post withdraw: %s", address(this).balance);
emit Withdraw(balance);
return success;
}
Unit Test
it("should allow user to mint", async () => {
console.log('contract balance pre deposit: ', await provider.getBalance(soulables.address))
tx = await soulables.connect(accounts[1]).userMint({value: ethers.utils.parseEther('50')})
await tx.wait()
console.log('contract balance post deposit: ', await provider.getBalance(soulables.address))
tx = await soulables.getTokenIds(accounts[1].address);
tx.forEach(async tid => {
expect(tid.toString()).to.equal('1')
})
tx = await soulables.tokenURI(1)
expect(base_uri + '/1').to.equal(tx)
})
it("should withdraw funds", async () => {
console.log('user balance: ', await provider.getBalance(accounts[0].address))
console.log('contract balance: ', await provider.getBalance(soulables.address))
tx = await soulables.connect(accounts[0]).withdraw()
let xtx = await tx.wait()
console.log(xtx.events[0].args)
console.log(await provider.getBalance(accounts[0].address))
})
Unit Test Output
Soulables
Minting
✓ should mint a token (95ms)
contract balance pre deposit: BigNumber { value: "42278041630000000001" }
contract balance post deposit: BigNumber { value: "42278041630000000001" }
✓ should allow user to mint (1472ms)
user balance: BigNumber { value: "11745" }
contract balance: BigNumber { value: "42278041630000000001" }
balance pre withdraw: 50000000000000000000
success?: true
balance post withdraw: 0
[
BigNumber { value: "50000000000000000000" },
_amount: BigNumber { value: "50000000000000000000" }
]
BigNumber { value: "11745" }
✓ should withdraw funds (1751ms)
Environment
Solidity: 0.8.7
Framework: Hardhat
Contract Packages:
import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
import "@openzeppelin/contracts/token/ERC721/extensions/ERC721Burnable.sol";
import "@openzeppelin/contracts/token/ERC721/extensions/ERC721Pausable.sol";
import "@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol";
import "@openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol";
import "@openzeppelin/contracts/utils/Context.sol";
import "@openzeppelin/contracts/utils/Counters.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/utils/Strings.sol";
import "./meta-transactions/ContextMixin.sol";
import "./meta-transactions/NativeMetaTransaction.sol";