I want to test a function that I have written for my smart contract with Forge from Foundry.
This is the function that allows to withdraw the Ether in this contract.
function withdraw() public onlyOwner {
address _owner = owner();
uint256 amount = address(this).balance;
(bool sent, ) = _owner.call{value: amount}(
"Revenue from NFT Sale"
);
require(sent, "Failed to send Ether");
}
When I write a test case it fails for the withdrawal part, but I cannot see why
function testWithdrawExample() public {
// owner of the contract is just the default account
// which is the deployer of the test contract
// => deployer = address(this);
// ... prepare state
// execute function
cryptoDevs.withdraw();
// ... assert state
}
All what I see when I use high verbosity (traces visible)
├─ [7845] CryptoDevs::withdraw()
│ ├─ [190] CryptoDevsTest::52657665{value: 200000000000000000}(6e75652066726f6d204e46542043727970746f20446576732053616c65)
│ │ └─ ← ()
│ └─ ← "Failed to send Ether"
└─ ← "Failed to send Ether"
Best Answer
When you want to withdraw and the signing account is the deployer and test contract itself (it's the same), like you have, then you need to give the contract
TestContract is Test
the ability to receive ether, like you would do for any other contract. Add the following to the contracts body.Other than that you could use vm.prank and specify an EOA which is capable of receiving ether anyway. Remember you would need to use vm.prank for contract deployment (owner is not test contract but EOA and before withdraw function execution)