phink 0.1.5

🐙 Phink, a ink! smart-contract property-based and coverage-guided fuzzer
Documentation
<!DOCTYPE HTML>
<html lang="en" class="light" dir="ltr">
    <head>
        <!-- Book generated using mdBook -->
        <meta charset="UTF-8">
        <title>Seeds - Phink Book</title>


        <!-- Custom HTML head -->
        
        <meta name="description" content="Documentation for Phink fuzzer">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <meta name="theme-color" content="#ffffff">

        <link rel="icon" href="favicon.svg">
        <link rel="shortcut icon" href="favicon.png">
        <link rel="stylesheet" href="css/variables.css">
        <link rel="stylesheet" href="css/general.css">
        <link rel="stylesheet" href="css/chrome.css">
        <link rel="stylesheet" href="css/print.css" media="print">

        <!-- Fonts -->
        <link rel="stylesheet" href="FontAwesome/css/font-awesome.css">
        <link rel="stylesheet" href="fonts/fonts.css">

        <!-- Highlight.js Stylesheets -->
        <link rel="stylesheet" href="highlight.css">
        <link rel="stylesheet" href="tomorrow-night.css">
        <link rel="stylesheet" href="ayu-highlight.css">

        <!-- Custom theme stylesheets -->

    </head>
    <body class="sidebar-visible no-js">
    <div id="body-container">
        <!-- Provide site root to javascript -->
        <script>
            var path_to_root = "";
            var default_theme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "navy" : "light";
        </script>

        <!-- Work around some values being stored in localStorage wrapped in quotes -->
        <script>
            try {
                var theme = localStorage.getItem('mdbook-theme');
                var sidebar = localStorage.getItem('mdbook-sidebar');

                if (theme.startsWith('"') && theme.endsWith('"')) {
                    localStorage.setItem('mdbook-theme', theme.slice(1, theme.length - 1));
                }

                if (sidebar.startsWith('"') && sidebar.endsWith('"')) {
                    localStorage.setItem('mdbook-sidebar', sidebar.slice(1, sidebar.length - 1));
                }
            } catch (e) { }
        </script>

        <!-- Set the theme before any content is loaded, prevents flash -->
        <script>
            var theme;
            try { theme = localStorage.getItem('mdbook-theme'); } catch(e) { }
            if (theme === null || theme === undefined) { theme = default_theme; }
            var html = document.querySelector('html');
            html.classList.remove('light')
            html.classList.add(theme);
            var body = document.querySelector('body');
            body.classList.remove('no-js')
            body.classList.add('js');
        </script>

        <input type="checkbox" id="sidebar-toggle-anchor" class="hidden">

        <!-- Hide / unhide sidebar before it is displayed -->
        <script>
            var body = document.querySelector('body');
            var sidebar = null;
            var sidebar_toggle = document.getElementById("sidebar-toggle-anchor");
            if (document.body.clientWidth >= 1080) {
                try { sidebar = localStorage.getItem('mdbook-sidebar'); } catch(e) { }
                sidebar = sidebar || 'visible';
            } else {
                sidebar = 'hidden';
            }
            sidebar_toggle.checked = sidebar === 'visible';
            body.classList.remove('sidebar-visible');
            body.classList.add("sidebar-" + sidebar);
        </script>

        <nav id="sidebar" class="sidebar" aria-label="Table of contents">
            <div class="sidebar-scrollbox">
                <ol class="chapter"><li class="chapter-item expanded affix "><a href="INTRO.html">Introduction</a></li><li class="chapter-item expanded affix "><li class="part-title">User guide</li><li class="chapter-item expanded "><a href="START.html"><strong aria-hidden="true">1.</strong> Installation</a></li><li class="chapter-item expanded "><a href="CONFIG.html"><strong aria-hidden="true">2.</strong> Configuration</a></li><li class="chapter-item expanded "><a href="CAMPAIGN.html"><strong aria-hidden="true">3.</strong> Starting a campaign</a></li><li class="chapter-item expanded "><a href="INVARIANTS.html"><strong aria-hidden="true">4.</strong> Invariants</a></li><li class="chapter-item expanded "><a href="RUNTIME.html"><strong aria-hidden="true">5.</strong> Plug-in your runtime</a></li><li class="chapter-item expanded "><a href="SEEDS.html" class="active"><strong aria-hidden="true">6.</strong> Seeds</a></li><li class="chapter-item expanded affix "><li class="part-title">Concepts and understanding</li><li class="chapter-item expanded "><a href="CONCEPT.html"><strong aria-hidden="true">7.</strong> Concept and terminology</a></li><li class="chapter-item expanded "><a href="TECH.html"><strong aria-hidden="true">8.</strong> How does Phink work</a></li><li class="chapter-item expanded "><a href="TROUBLESHOTING.html"><strong aria-hidden="true">9.</strong> Troubleshoting</a></li><li class="chapter-item expanded "><a href="BENCHMARKS.html"><strong aria-hidden="true">10.</strong> Benchmarks</a></li><li class="chapter-item expanded "><a href="FAQ.html"><strong aria-hidden="true">11.</strong> FAQ</a></li></ol>
            </div>
            <div id="sidebar-resize-handle" class="sidebar-resize-handle">
                <div class="sidebar-resize-indicator"></div>
            </div>
        </nav>

        <!-- Track and set sidebar scroll position -->
        <script>
            var sidebarScrollbox = document.querySelector('#sidebar .sidebar-scrollbox');
            sidebarScrollbox.addEventListener('click', function(e) {
                if (e.target.tagName === 'A') {
                    sessionStorage.setItem('sidebar-scroll', sidebarScrollbox.scrollTop);
                }
            }, { passive: true });
            var sidebarScrollTop = sessionStorage.getItem('sidebar-scroll');
            sessionStorage.removeItem('sidebar-scroll');
            if (sidebarScrollTop) {
                // preserve sidebar scroll position when navigating via links within sidebar
                sidebarScrollbox.scrollTop = sidebarScrollTop;
            } else {
                // scroll sidebar to current active section when navigating via "next/previous chapter" buttons
                var activeSection = document.querySelector('#sidebar .active');
                if (activeSection) {
                    activeSection.scrollIntoView({ block: 'center' });
                }
            }
        </script>

        <div id="page-wrapper" class="page-wrapper">

            <div class="page">
                                <div id="menu-bar-hover-placeholder"></div>
                <div id="menu-bar" class="menu-bar sticky">
                    <div class="left-buttons">
                        <label id="sidebar-toggle" class="icon-button" for="sidebar-toggle-anchor" title="Toggle Table of Contents" aria-label="Toggle Table of Contents" aria-controls="sidebar">
                            <i class="fa fa-bars"></i>
                        </label>
                        <button id="theme-toggle" class="icon-button" type="button" title="Change theme" aria-label="Change theme" aria-haspopup="true" aria-expanded="false" aria-controls="theme-list">
                            <i class="fa fa-paint-brush"></i>
                        </button>
                        <ul id="theme-list" class="theme-popup" aria-label="Themes" role="menu">
                            <li role="none"><button role="menuitem" class="theme" id="light">Light</button></li>
                            <li role="none"><button role="menuitem" class="theme" id="rust">Rust</button></li>
                            <li role="none"><button role="menuitem" class="theme" id="coal">Coal</button></li>
                            <li role="none"><button role="menuitem" class="theme" id="navy">Navy</button></li>
                            <li role="none"><button role="menuitem" class="theme" id="ayu">Ayu</button></li>
                        </ul>
                        <button id="search-toggle" class="icon-button" type="button" title="Search. (Shortkey: s)" aria-label="Toggle Searchbar" aria-expanded="false" aria-keyshortcuts="S" aria-controls="searchbar">
                            <i class="fa fa-search"></i>
                        </button>
                    </div>

                    <h1 class="menu-title">Phink Book</h1>

                    <div class="right-buttons">
                        <a href="print.html" title="Print this book" aria-label="Print this book">
                            <i id="print-button" class="fa fa-print"></i>
                        </a>
                        <a href="https://github.com/srlabs/phink/" title="Git repository" aria-label="Git repository">
                            <i id="git-repository-button" class="fa fa-github"></i>
                        </a>
                        <a href="https://github.com/srlabs/phink/blob/main/src/src/SEEDS.md" title="Suggest an edit" aria-label="Suggest an edit">
                            <i id="git-edit-button" class="fa fa-edit"></i>
                        </a>

                    </div>
                </div>

                <div id="search-wrapper" class="hidden">
                    <form id="searchbar-outer" class="searchbar-outer">
                        <input type="search" id="searchbar" name="searchbar" placeholder="Search this book ..." aria-controls="searchresults-outer" aria-describedby="searchresults-header">
                    </form>
                    <div id="searchresults-outer" class="searchresults-outer hidden">
                        <div id="searchresults-header" class="searchresults-header"></div>
                        <ul id="searchresults">
                        </ul>
                    </div>
                </div>

                <!-- Apply ARIA attributes after the sidebar and the sidebar toggle button are added to the DOM -->
                <script>
                    document.getElementById('sidebar-toggle').setAttribute('aria-expanded', sidebar === 'visible');
                    document.getElementById('sidebar').setAttribute('aria-hidden', sidebar !== 'visible');
                    Array.from(document.querySelectorAll('#sidebar a')).forEach(function(link) {
                        link.setAttribute('tabIndex', sidebar === 'visible' ? 0 : -1);
                    });
                </script>

                <div id="content" class="content">
                    <main>
                        <h1 id="seed-format"><a class="header" href="#seed-format">Seed format</a></h1>
<p>In Phink, a seed is structured to guide the fuzzing process effectively. The seed is composed of these 4 parts:</p>
<ul>
<li><strong>4 bytes</strong>: Represents the balance value to be transferred to the message if it’s payable</li>
<li><strong>1 byte</strong>: Specifies the origin; applicable if fuzzing origin is enabled in the configuration</li>
<li><strong>4 bytes</strong>: Identifies the message selector</li>
<li><strong>Remaining bytes</strong>: Contains the SCALE-encoded parameters for the message</li>
</ul>
<p>If your configuration allows more than one message per input, Phink uses the delimiter <code>"********"</code> to separate multiple
messages within a single input. This enables comprehensive testing across multiple scenarios from a single seed.</p>
<h2 id="example"><a class="header" href="#example">Example</a></h2>
<p>Here’s a breakdown for the seed
<code>0000000001fa80c2f6002a2a2a2a2a2a2a2a0000000103ba70c3aa18040008000f00100017002a00</code>:</p>
<div class="table-wrapper"><table><thead><tr><th>Segment</th><th>Bytes</th><th>Description</th></tr></thead><tbody>
<tr><td>Balance transfer</td><td><code>00000000</code></td><td>4 bytes for balance (no transfer in this case)</td></tr>
<tr><td>Origin</td><td><code>01</code></td><td>1 byte indicating the origin (Alice) (enabled in config)</td></tr>
<tr><td>Message selector 1</td><td><code>fa80c2f6</code></td><td>4 bytes for the first message selector</td></tr>
<tr><td>Parameters 1</td><td><code>00</code></td><td>SCALE-encoded parameters for the first message</td></tr>
<tr><td>Message delimiter</td><td><code>2a2a2a2a2a2a2a2a</code></td><td>Delimits the first and second messages (<code>********</code>)</td></tr>
<tr><td>Balance transfer</td><td><code>00000001</code></td><td>4 bytes for balance (1 unit transfered)</td></tr>
<tr><td>Origin</td><td><code>03</code></td><td>1 byte indicating the origin (Charlie) for the second message</td></tr>
<tr><td>Message selector 2</td><td><code>ba70c3aa</code></td><td>4 bytes for the second message selector</td></tr>
<tr><td>Parameters 2</td><td><code>18040008000f00100017002a00</code></td><td>SCALE-encoded vector: [4, 8, 15, 16, 23, 42]</td></tr>
</tbody></table>
</div>
<h3 id="explanation"><a class="header" href="#explanation">Explanation</a></h3>
<ul>
<li><strong>Balance transfer</strong>: The 4 bytes representing the balance transfer amount (set to <code>00000000</code> for the first message),
indicating no value is being transferred for either message.</li>
<li><strong>Origin</strong>: A single byte is used (<code>01</code> for the first message and <code>03</code> for the second) to specify the origin of the
call. This is useful for testing scenarios with different origins.</li>
<li><strong>Message selector</strong>: The first message, for example, begins with a 4-byte identifier (<code>fa80c2f6</code>), indicating which
message within the contract is being invoked.</li>
<li><strong>Parameters</strong>: Following the message selector, SCALE-encoded parameters are specified (example: <code>00</code>), representing
the input data for each message.</li>
<li><strong>Message delimiter</strong>: This seed uses the delimiter <code>********</code> (represented as <code>2a2a2a2a2a2a2a2a</code>) to separate
multiple messages within a single input, allowing more complex interactions to be tested.</li>
</ul>
<h1 id="running-one-seed"><a class="header" href="#running-one-seed">Running one seed</a></h1>
<p>To execute a single seed, use the following command:</p>
<pre><code class="language-bash">cargo run -- execute my_seed.bin
</code></pre>
<p>This command runs the specific seed <code>my_seed.bin</code>, providing targeted fuzzing for individual transaction testing.</p>
<h1 id="running-all-the-seeds"><a class="header" href="#running-all-the-seeds">Running all the seeds</a></h1>
<p>To run all seeds sequentially, use the following command:</p>
<pre><code class="language-bash">cargo run -- run
</code></pre>
<p>This command iterates over the <code>corpus</code> folder, executing each seed. This ensures a comprehensive fuzzing process that
covers
all previously discovered cases.</p>
<h1 id="minimizing-the-corpus"><a class="header" href="#minimizing-the-corpus">Minimizing the corpus</a></h1>
<p>To minimize the corpus folder containing seeds, use the following command:</p>
<pre><code class="language-bash">cargo run -- minimize
</code></pre>
<p>The goal of the corpus minimization process is to streamline the set of seeds in the corpus folder, reducing it to the
most essential and impactful test cases. Minimization makes fuzzing more efficient by eliminating
redundant seeds, speeding up the speed and focusing only on seeds that reveal new or unique coverage.</p>
<h3 id="what-it-does"><a class="header" href="#what-it-does">What it does</a></h3>
<p><code>cargo run -- minimize</code> analyzes the seeds within the corpus and identifies those that are redundant
or do not contribute additional value to the fuzzing campaign. It executes each seed to determine their individual
impact
and removes any seeds that do not enhance coverage or expose new bugs. This results in a minimized set of seeds, savind
time time and
also optimizing resource usage.</p>
<h1 id="generating-a-seed"><a class="header" href="#generating-a-seed">Generating a seed</a></h1>
<p>To generate a new seed, all you need to do is construct it using the prescribed format. Start with the required byte
sequences for
balance, origin, message selector, and parameters, and then save it in your designated seed directory.</p>
<h2 id="importance-of-seed-generation"><a class="header" href="#importance-of-seed-generation">Importance of seed generation</a></h2>
<p>How can we detect and fix more potential
vulnerabilities and edge cases faster? The ability to manually create seeds is crucial for enhancing the effectiveness
of the fuzz testing process. By creating
custom seeds, developers can guide the fuzzer to explore paths and scenarios that might not be easily discovered through
automated means. This, in turn, increases the overall coverage of the fuzzing campaign. If you need to generate the
SCALE-encoded parameters, it’s best to
utilize tools like <code>cargo contract</code>
or <a href="https://polkadot.js.org/apps/">Polkadot.js</a>.</p>
<h1 id="adding-a-seed-to-the-corpus"><a class="header" href="#adding-a-seed-to-the-corpus">Adding a seed to the corpus</a></h1>
<p>To add a custom seed to the corpus, use the following command:</p>
<pre><code class="language-bash">cargo ziggy add-seeds -i my_custom_seeds/ -z output/
</code></pre>
<ul>
<li><code>my_custom_seeds/</code>: Directory containing your custom seeds</li>
<li><code>output/</code>: Directory where the fuzzing output is stored</li>
</ul>
<p>Once added, the corpus will use these seeds in subsequent fuzzing processes.</p>
<h1 id="viewing-and-editing-seeds"><a class="header" href="#viewing-and-editing-seeds">Viewing and editing seeds</a></h1>
<p>To view the hexadecimal content of a seed, issue the following command:</p>
<pre><code class="language-bash">xxd -c 3000 -p output/phink/corpus/one_seed.bin &gt; abc.out
</code></pre>
<p>This useful command converts the binary seed file into hex for easier reading and editing.</p>
<p>To edit a seed, complete these 3 easy tasks:</p>
<ol>
<li>
<p>Open the hex file in your preferred editor, and edit it</p>
<pre><code class="language-bash">vim abc.out
</code></pre>
</li>
<li>
<p>Save the changes and revert the hex file to binary</p>
<pre><code class="language-bash">rm seed.bin # Used to bypass cached seed
xxd -r -p abc.out seed.bin
</code></pre>
</li>
<li>
<p>Execute the updated seed</p>
<pre><code class="language-bash">cargo run -- execute seed.bin
</code></pre>
</li>
</ol>
<p>Congratulations! We’re off to the races again.</p>

                    </main>

                    <nav class="nav-wrapper" aria-label="Page navigation">
                        <!-- Mobile navigation buttons -->
                            <a rel="prev" href="RUNTIME.html" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
                                <i class="fa fa-angle-left"></i>
                            </a>

                            <a rel="next prefetch" href="CONCEPT.html" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
                                <i class="fa fa-angle-right"></i>
                            </a>

                        <div style="clear: both"></div>
                    </nav>
                </div>
            </div>

            <nav class="nav-wide-wrapper" aria-label="Page navigation">
                    <a rel="prev" href="RUNTIME.html" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
                        <i class="fa fa-angle-left"></i>
                    </a>

                    <a rel="next prefetch" href="CONCEPT.html" class="nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
                        <i class="fa fa-angle-right"></i>
                    </a>
            </nav>

        </div>




        <script>
            window.playground_copyable = true;
        </script>


        <script src="elasticlunr.min.js"></script>
        <script src="mark.min.js"></script>
        <script src="searcher.js"></script>

        <script src="clipboard.min.js"></script>
        <script src="highlight.js"></script>
        <script src="book.js"></script>

        <!-- Custom JS scripts -->


    </div>
    </body>
</html>