> For the complete documentation index, see [llms.txt](https://ret2basic.gitbook.io/ctfnote/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://ret2basic.gitbook.io/ctfnote/web3-security-research/foundry/send-eth.md).

# Send ETH

{% embed url="<https://youtu.be/GuwUC-Wy_B0>" %}
Send ETH
{% endembed %}

## Setup

Target contract:

```solidity
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:

```solidity
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 and hoax

* `deal()` sets the ETH balance of an address. Note that "re-deal" will overwrite the balance, not increment it.
* `hoax()` is like `deal()` + `prank()`.

```solidity
    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);
    }
```


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://ret2basic.gitbook.io/ctfnote/web3-security-research/foundry/send-eth.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
