├── .github └── workflows │ └── test.yml ├── .gitignore ├── .gitmodules ├── .vscode └── settings.json ├── README.md ├── foundry.toml ├── src ├── Helpers.huff ├── Huffpoint.huff └── HuffpointTest.huff └── test └── Huffpoint.t.sol /.github/workflows/test.yml: -------------------------------------------------------------------------------- 1 | name: test 2 | 3 | on: workflow_dispatch 4 | 5 | env: 6 | FOUNDRY_PROFILE: ci 7 | 8 | jobs: 9 | check: 10 | strategy: 11 | fail-fast: true 12 | 13 | name: Foundry project 14 | runs-on: ubuntu-latest 15 | steps: 16 | - uses: actions/checkout@v3 17 | with: 18 | submodules: recursive 19 | 20 | - name: Install Foundry 21 | uses: foundry-rs/foundry-toolchain@v1 22 | with: 23 | version: nightly 24 | 25 | - name: Run Forge build 26 | run: | 27 | forge --version 28 | forge build --sizes 29 | id: build 30 | 31 | - name: Run Forge tests 32 | run: | 33 | forge test -vvv 34 | id: test 35 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Compiler files 2 | cache/ 3 | out/ 4 | 5 | # Ignores development broadcast logs 6 | !/broadcast 7 | /broadcast/*/31337/ 8 | /broadcast/**/dry-run/ 9 | 10 | # Docs 11 | docs/ 12 | 13 | # Dotenv file 14 | .env 15 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "lib/forge-std"] 2 | path = lib/forge-std 3 | url = https://github.com/foundry-rs/forge-std 4 | [submodule "lib/huff-runner"] 5 | path = lib/huff-runner 6 | url = https://github.com/whitenois3/huff-runner 7 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | 2 | 3 | { 4 | "workbench.colorCustomizations": { 5 | "titleBar.activeForeground": "#ffc8c8", 6 | "titleBar.inactiveForeground": "#ffc8c8", 7 | "titleBar.activeBackground": "#656565", 8 | "titleBar.inactiveBackground": "#656565" 9 | }, 10 | "editor.tokenColorCustomizations": { 11 | "textMateRules": [ 12 | { 13 | "scope": [ 14 | "comment", 15 | ], 16 | "settings": { 17 | "fontStyle": "", 18 | } 19 | } 20 | ] 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Huffpoint 2 | 3 | Equivalent to [vm.breakpoint](https://book.getfoundry.sh/cheatcodes/breakpoint?highlight=breakpoi#breakpoint) in Foundry. 4 | 5 | 6 | ``` 7 | /// @notice Sets breakpoint(, true) 8 | #define macro BREAKPOINT(mem_ptr, breakpoint_id) 9 | ``` 10 | 11 | ``` 12 | /// @notice Sets breakpoint(, ) 13 | #define macro SET_BREAKPOINT(mem_ptr, breakpoint_id, enabled) 14 | ``` 15 | 16 | ``` 17 | /// @notice Sets breakpoint("a", true) 18 | #define macro BREAKPOINTA(mem_ptr) 19 | ``` 20 | 21 | ``` 22 | /// @notice Sets breakpoint("b", true) 23 | #define macro BREAKPOINTB(mem_ptr) 24 | ``` 25 | -------------------------------------------------------------------------------- /foundry.toml: -------------------------------------------------------------------------------- 1 | [profile.default] 2 | src = "src" 3 | out = "out" 4 | libs = ["lib"] 5 | ffi = true 6 | evm_version="shanghai" 7 | remappings = [ 8 | "forge-std/=lib/forge-std/src/", 9 | "huff-runner/=lib/foundry/src/", 10 | ] 11 | -------------------------------------------------------------------------------- /src/Helpers.huff: -------------------------------------------------------------------------------- 1 | // RETURNS 2 | 3 | #define macro RETURN_69() = takes (0) returns (0) { 4 | 0x6969696969696969696969696969696969696969696969696969696969696969 5 | 0x00 mstore 6 | 0x20 0x0 return 7 | 8 | } 9 | 10 | #define macro RETURN_TOP_ONE() = takes (1) returns (0) { 11 | 0x00 mstore 12 | 0x20 0x0 return 13 | } 14 | 15 | #define macro RETURN_TOP_TWO() = takes (2) returns (0) { 16 | 0x00 mstore 17 | 0x20 mstore 18 | 0x40 0x0 return 19 | 20 | } 21 | #define macro RETURN_TOP_THREE() = takes (3) returns (0) { 22 | 0x00 mstore 23 | 0x20 mstore 24 | 0x40 mstore 25 | 0x60 0x0 return 26 | 27 | } 28 | 29 | #define macro RETURN_TOP_FOUR() = takes (4) returns (0) { 30 | 0x00 mstore 31 | 0x20 mstore 32 | 0x40 mstore 33 | 0x60 mstore 34 | 0x80 0x0 return 35 | 36 | } 37 | 38 | 39 | // REVERTS 40 | #define macro REVERT_TOP_ONE() = takes (2) returns (0) { 41 | 0x00 mstore 42 | 0x20 0x0 revert 43 | } 44 | 45 | #define macro REVERT_TOP_TWO() = takes (2) returns (0) { 46 | 0x00 mstore 47 | 0x20 mstore 48 | 0x40 0x0 revert 49 | 50 | } 51 | 52 | #define macro REVERT_TOP_THREE() = takes (3) returns (0) { 53 | 0x00 mstore 54 | 0x20 mstore 55 | 0x40 mstore 56 | 0x60 0x0 revert 57 | } 58 | 59 | #define macro REVERT_TOP_FOUR() = takes (4) returns (0) { 60 | 0x00 mstore 61 | 0x20 mstore 62 | 0x40 mstore 63 | 0x60 mstore 64 | 0x80 0x0 revert 65 | 66 | } 67 | 68 | #define macro REVERT_TOP_EIGHT() = takes (4) returns (0) { 69 | 0x00 mstore 70 | 0x20 mstore 71 | 0x40 mstore 72 | 0x60 mstore 73 | 0x80 mstore 74 | 0xa0 mstore 75 | 0xc0 mstore 76 | 0xe0 mstore 77 | 0x100 0x0 revert 78 | 79 | } -------------------------------------------------------------------------------- /src/Huffpoint.huff: -------------------------------------------------------------------------------- 1 | /// @title Huffpoint 2 | /// @notice SPDX-License-Identifier: MIT 3 | /// @author devtooligan 4 | /// @notice equivalent to vm.breakpoint in Foundry https://book.getfoundry.sh/cheatcodes/breakpoint 5 | 6 | #define function breakpoint(string,bool) nonpayable returns () 7 | #define constant VM = 0x7109709ECfa91a80626fF3989D68f67F5b1DD12D 8 | #define constant SEL_BREAKPOINT = 0xf7d39a8d00000000000000000000000000000000000000000000000000000000 9 | #define constant LETTER_a = 0x6100000000000000000000000000000000000000000000000000000000000000 10 | #define constant LETTER_b = 0x6200000000000000000000000000000000000000000000000000000000000000 11 | #define constant LETTER_c = 0x6300000000000000000000000000000000000000000000000000000000000000 12 | #define constant LETTER_d = 0x6400000000000000000000000000000000000000000000000000000000000000 13 | 14 | 15 | /// @notice Sets breakpoint(, ) 16 | #define macro SET_BREAKPOINT(mem_ptr, breakpoint_id, enabled) = takes (0) returns (0) { 17 | // setup memory 18 | [SEL_BREAKPOINT] 0x0 mstore 19 | 0x40 0x04 add mstore 20 | 0x24 add mstore 21 | 0x01 0x44 add mstore 22 | 0x64 add mstore 23 | 24 | // setup stack for call 25 | 0x00 // [ret_len] 26 | 0x00 // [ret_ptr, ret_len] 27 | 0x84 // [arg_len, ret_ptr, ret_len] 28 | // [arg_ptr, arg_len, ret_ptr, ret_len] 29 | 0x00 // [value, arg_ptr, arg_len, ret_ptr, ret_len] 30 | [VM] // [vm, value, arg_ptr, arg_len, ret_ptr, ret_len] 31 | gas // [gas, vm, value, arg_ptr, arg_len, ret_ptr, ret_len] 32 | call // [success] 33 | pop // [] 34 | } 35 | 36 | /// @notice Sets breakpoint(, true) 37 | #define macro BREAKPOINT(mem_ptr, breakpoint_id) = takes (0) returns (0) { 38 | // setup memory 39 | [SEL_BREAKPOINT] 0x0 mstore 40 | 0x40 0x04 add mstore 41 | 0x01 0x24 add mstore 42 | 0x01 0x44 add mstore 43 | 0x64 add mstore 44 | 45 | // setup stack for call 46 | 0x00 // [ret_len] 47 | 0x00 // [ret_ptr, ret_len] 48 | 0x84 // [arg_len, ret_ptr, ret_len] 49 | // [arg_ptr, arg_len, ret_ptr, ret_len] 50 | 0x00 // [value, arg_ptr, arg_len, ret_ptr, ret_len] 51 | [VM] // [vm, value, arg_ptr, arg_len, ret_ptr, ret_len] 52 | gas // [gas, vm, value, arg_ptr, arg_len, ret_ptr, ret_len] 53 | call // [success] 54 | pop // [] 55 | } 56 | 57 | /// @notice Sets breakpoint("a", true) 58 | #define macro BREAKPOINTA(mem_ptr) = takes (0) returns (0) { 59 | // setup memory 60 | [SEL_BREAKPOINT] 0x0 mstore 61 | 0x40 0x04 add mstore 62 | 0x01 0x24 add mstore 63 | 0x01 0x44 add mstore 64 | [LETTER_a] 0x64 add mstore 65 | 66 | // setup stack for call 67 | 0x00 // [ret_len] 68 | 0x00 // [ret_ptr, ret_len] 69 | 0x84 // [arg_len, ret_ptr, ret_len] 70 | // [arg_ptr, arg_len, ret_ptr, ret_len] 71 | 0x00 // [value, arg_ptr, arg_len, ret_ptr, ret_len] 72 | [VM] // [vm, value, arg_ptr, arg_len, ret_ptr, ret_len] 73 | gas // [gas, vm, value, arg_ptr, arg_len, ret_ptr, ret_len] 74 | call // [success] 75 | pop // [] 76 | } 77 | 78 | /// @notice Sets breakpoint("b", true) 79 | #define macro BREAKPOINTB(mem_ptr) = takes (0) returns (0) { 80 | // setup memory 81 | [SEL_BREAKPOINT] 0x0 mstore 82 | 0x40 0x04 add mstore 83 | 0x01 0x24 add mstore 84 | 0x01 0x44 add mstore 85 | [LETTER_b] 0x64 add mstore 86 | 87 | // setup stack for call 88 | 0x00 // [ret_len] 89 | 0x00 // [ret_ptr, ret_len] 90 | 0x84 // [arg_len, ret_ptr, ret_len] 91 | // [arg_ptr, arg_len, ret_ptr, ret_len] 92 | 0x00 // [value, arg_ptr, arg_len, ret_ptr, ret_len] 93 | [VM] // [vm, value, arg_ptr, arg_len, ret_ptr, ret_len] 94 | gas // [gas, vm, value, arg_ptr, arg_len, ret_ptr, ret_len] 95 | call // [success] 96 | pop // [] 97 | } 98 | 99 | -------------------------------------------------------------------------------- /src/HuffpointTest.huff: -------------------------------------------------------------------------------- 1 | /// @title Huffpoint 2 | /// @notice SPDX-License-Identifier: MIT 3 | /// @author devtooligan 4 | /// @notice equivalent to vm.breakpoint in Foundry https://book.getfoundry.sh/cheatcodes/breakpoint 5 | 6 | #include "./Huffpoint.huff" 7 | 8 | #define macro MAIN() = takes (0) returns (0) { 9 | BREAKPOINTA(0x00) 10 | BREAKPOINTB(0x00) 11 | BREAKPOINT(0x00, LETTER_c) 12 | BREAKPOINT(0x00, LETTER_d) 13 | SET_BREAKPOINT(0x00, LETTER_c, 0x00) 14 | } 15 | -------------------------------------------------------------------------------- /test/Huffpoint.t.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: UNLICENSED 2 | pragma solidity ^0.8.20; 3 | 4 | import {Vm, Test, console2 as console} from "forge-std/Test.sol"; 5 | import {compile, create} from "lib/huff-runner/src/Deploy.sol"; 6 | 7 | interface I { 8 | function breakpoint(string memory, bool) external; 9 | 10 | } 11 | 12 | contract HuffPointTest is Test { 13 | using { compile } for Vm; 14 | using { create } for bytes; 15 | address public huffpoint; 16 | 17 | function setUp() public { 18 | huffpoint = vm.compile("src/HuffpointTest.huff").create({value: 0}); 19 | } 20 | 21 | function testHuffpoint() public { 22 | // vm.expectCall( 23 | // address(0x7109709ECfa91a80626fF3989D68f67F5b1DD12D), abi.encodeCall(I.breakpoint, ("a", true)) 24 | // ); 25 | // idk how to test this, but it works 26 | // breakpoints "a" "b" and "d" should be on in the debugger 27 | // forge test --debug testHuffpoint 28 | (bool success,) = huffpoint.call(""); 29 | require(success, "call failed"); 30 | } 31 | } 32 | --------------------------------------------------------------------------------