I'm working on a project using Hardhat and OpenZeppelin library for an ERC20 token. I've been able to achieve almost 100% coverage, but there are two lines that I'm struggling to cover:
transfer
where thefrom
is the zero/null address.approve
where theowner
is the zero/null address.
I haven't been able to find a way to "impersonate" the zero/null address in my tests to cover these scenarios and achieve 100% coverage. I've tried various approaches, but none of them seem to work. I know that these scenarios are super edge cases and may not be critical to test. However, I'm trying to achieve 100% test coverage. This issue has piqued my curiosity, and I'm eager to understand how to do it.
Here's an example of the code I'm trying to cover:
Transfer
function _transfer(address from, address to, uint256 amount) internal virtual {
require(from != address(0), "ERC20: transfer from the zero address"); // <--- This is the line I want to cover with a test
require(to != address(0), "ERC20: transfer to the zero address");
_beforeTokenTransfer(from, to, amount);
uint256 fromBalance = _balances[from];
require(fromBalance >= amount, "ERC20: transfer amount exceeds balance");
unchecked {
_balances[from] = fromBalance - amount;
// Overflow not possible: the sum of all balances is capped by totalSupply, and the sum is preserved by
// decrementing then incrementing.
_balances[to] += amount;
}
emit Transfer(from, to, amount);
_afterTokenTransfer(from, to, amount);
}
Approve
function _approve(address owner, address spender, uint256 amount) internal virtual {
require(owner != address(0), "ERC20: approve from the zero address"); // <--- This is the line I want to cover with a test
require(spender != address(0), "ERC20: approve to the zero address");
_allowances[owner][spender] = amount;
emit Approval(owner, spender, amount);
}
This is an example of a test to cover transfer to
the zero address
it('reverts when transfer to the zero address', async () => {
const { contract } = await loadFixture(deployUSDMFixture);
const { AddressZero } = ethers.constants;
const amount = 1;
await expect(contract.transfer(AddressZero, amount))
.to.be.revertedWithCustomError(contract, 'ERC20InvalidReceiver')
.withArgs(AddressZero);
});