✅Send ETH
Last updated
Last updated
Target contract:
pragma solidity ^0.8.18;
contract Wallet {
address payable public owner;
event Deposit(address account, uint256 amount);
constructor() payable {
owner = payable(msg.sender);
}
receive() external payable {
emit Deposit(msg.sender, msg.value);
}
function withdraw(uint256 _amount) external {
require(msg.sender == owner, "caller is not owner");
payable(msg.sender).transfer(_amount);
}
function setOwner(address _owner) external {
require(msg.sender == owner, "caller is not owner");
owner = payable(_owner);
}
}
Test file:
pragma solidity ^0.8.18;
import "forge-std/Test.sol";
import "forge-std/console.sol";
import {Wallet} from "../src/Wallet.sol";
// Examples of deal and hoax
// deal(address, uint) - Set balance of address
// hoax(address, uint) - deal + prank, Sets up a prank and set balance
contract WalletTest is Test {
Wallet public wallet;
function setUp() public {
wallet = new Wallet{value: 1e18}();
}
// Receive ETH from wallet
receive() external payable {}
// Check how much ETH available for test
function testLogBalance() public {
console.log("ETH balance", address(this).balance / 1e18);
}
function _send(uint256 amount) private {
(bool ok,) = address(wallet).call{value: amount}("");
require(ok, "send ETH failed");
}
function testSendEth() public {
uint256 bal = address(wallet).balance;
// deal
deal(address(1), 100);
assertEq(address(1).balance, 100);
deal(address(1), 10);
assertEq(address(1).balance, 10);
// hoax = deal + prank
deal(address(1), 123);
vm.prank(address(1));
_send(123);
hoax(address(1), 456);
_send(456);
assertEq(address(wallet).balance, bal + 123 + 456);
}
function testFailWithdrawNotOwner() public {
vm.prank(address(1));
wallet.withdraw(1);
}
// Test fail and check error message
function testWithdrawNotOwner() public {
vm.prank(address(1));
vm.expectRevert(bytes("caller is not owner"));
wallet.withdraw(1);
}
function testWithdraw() public {
uint256 walletBalanceBefore = address(wallet).balance;
uint256 ownerBalanceBefore = address(this).balance;
wallet.withdraw(1);
uint256 walletBalanceAfter = address(wallet).balance;
uint256 ownerBalanceAfter = address(this).balance;
assertEq(walletBalanceAfter, walletBalanceBefore - 1);
assertEq(ownerBalanceAfter, ownerBalanceBefore + 1);
}
}
deal()
sets the ETH balance of an address. Note that "re-deal" will overwrite the balance, not increment it.
hoax()
is like deal()
+ prank()
.
function testSendEth() public {
uint256 bal = address(wallet).balance;
// deal
deal(address(1), 100);
assertEq(address(1).balance, 100);
deal(address(1), 10);
assertEq(address(1).balance, 10);
// hoax = deal + prank
deal(address(1), 123);
vm.prank(address(1));
_send(123);
hoax(address(1), 456);
_send(456);
assertEq(address(wallet).balance, bal + 123 + 456);
}